xref: /dokuwiki/lib/scripts/fileuploaderextended.js (revision 92c93223d0fce2c5de1f4d3d134be56d1d9f3bc0)
1qq.extend(qq.FileUploader.prototype, {
2    _createUploadHandler: function(){
3        var self = this,
4            handlerClass;
5
6        if(qq.UploadHandlerXhr.isSupported()){
7            handlerClass = 'UploadHandlerXhr';
8            //handlerClass = 'UploadHandlerForm';
9        } else {
10            handlerClass = 'UploadHandlerForm';
11        }
12
13        var handler = new qq[handlerClass]({
14            debug: this._options.debug,
15            action: this._options.action,
16            maxConnections: this._options.maxConnections,
17            onProgress: function(id, fileName, loaded, total){
18                self._onProgress(id, fileName, loaded, total);
19                self._options.onProgress(id, fileName, loaded, total);
20            },
21            onComplete: function(id, fileName, result){
22                self._onComplete(id, fileName, result);
23                self._options.onComplete(id, fileName, result);
24            },
25            onCancel: function(id, fileName){
26                self._onCancel(id, fileName);
27                self._options.onCancel(id, fileName);
28            },
29            onUpload: function(){
30                self._onUpload();
31            }
32        });
33
34        return handler;
35    },
36
37    _onUpload: function(){
38        this._handler.uploadAll(this._options.params);
39    },
40
41    _uploadFile: function(fileContainer){
42        var id = this._handler.add(fileContainer);
43        var fileName = this._handler.getName(id);
44
45        if (this._options.onSubmit(id, fileName) !== false){
46            this._onSubmit(id, fileName);
47        }
48    },
49
50    _addToList: function(id, fileName){
51        var item = qq.toElement(this._options.fileTemplate);
52        item.qqFileId = id;
53
54        var fileElement = this._find(item, 'file');
55        qq.setText(fileElement, this._formatFileName(fileName));
56        this._find(item, 'size').style.display = 'none';
57
58        var nameElement = this._find(item, 'nameInput');
59        nameElement.value = this._formatFileName(fileName);
60        nameElement.id = id;
61
62        this._listElement.appendChild(item);
63    }
64
65});
66
67qq.FileUploaderExtended = function(o){
68    // call parent constructor
69    qq.FileUploaderBasic.apply(this, arguments);
70
71    qq.extend(this._options, {
72        element: null,
73        // if set, will be used instead of qq-upload-list in template
74        listElement: null,
75
76        template: '<div class="qq-uploader">' +
77                '<div class="qq-upload-drop-area"><span>Drop files here to upload</span></div>' +
78                '<div class="qq-upload-button">Upload a file</div>' +
79                '<ul class="qq-upload-list"></ul>' +
80                '<input class="button" type="submit" value="Upload" id="mediamanager__upload_button">' +
81             '</div>',
82
83        // template for one item in file list
84        fileTemplate: '<li>' +
85                '<span class="qq-upload-file"></span>' +
86                '<label><span>Upload as (optional):</span><input class="qq-upload-name-input" type="text"></label>' +
87                '<span class="qq-upload-spinner-hidden"></span>' +
88                '<span class="qq-upload-size"></span>' +
89                '<a class="qq-upload-cancel" href="#">Cancel</a>' +
90                '<span class="qq-upload-failed-text">Failed</span>' +
91            '</li>',
92
93        classes: {
94            // used to get elements from templates
95            button: 'qq-upload-button',
96            drop: 'qq-upload-drop-area',
97            dropActive: 'qq-upload-drop-area-active',
98            list: 'qq-upload-list',
99            nameInput: 'qq-upload-name-input',
100            file: 'qq-upload-file',
101
102            spinner: 'qq-upload-spinner',
103            size: 'qq-upload-size',
104            cancel: 'qq-upload-cancel',
105
106            // added to list item when upload completes
107            // used in css to hide progress spinner
108            success: 'qq-upload-success',
109            fail: 'qq-upload-fail'
110        }
111    });
112
113    qq.extend(this._options, o);
114
115    this._element = this._options.element;
116    this._element.innerHTML = this._options.template;
117    this._listElement = this._options.listElement || this._find(this._element, 'list');
118
119    this._classes = this._options.classes;
120
121    this._button = this._createUploadButton(this._find(this._element, 'button'));
122
123    this._bindCancelEvent();
124    this._bindUploadEvent();
125    this._setupDragDrop();
126};
127
128qq.extend(qq.FileUploaderExtended.prototype, qq.FileUploader.prototype);
129
130qq.extend(qq.FileUploaderExtended.prototype, {
131    _bindUploadEvent: function(){
132        var self = this,
133            list = this._listElement;
134
135        qq.attach(document.getElementById('mediamanager__upload_button'), 'click', function(e){
136            e = e || window.event;
137            var target = e.target || e.srcElement;
138            qq.preventDefault(e);
139            self._handler._options.onUpload();
140
141        });
142    }
143
144});
145
146qq.extend(qq.UploadHandlerForm.prototype, {
147    uploadAll: function(params){
148        this._uploadAll(params);
149    },
150
151    _uploadAll: function(params){
152        for (key in this._inputs) {
153            this.upload(key, params);
154        }
155
156    }
157});
158
159qq.extend(qq.UploadHandlerXhr.prototype, {
160    uploadAll: function(params){
161        this._uploadAll(params);
162    },
163
164    getName: function(id){
165        var file = this._files[id];
166        var name = document.getElementById(id);
167        if (name != null) {
168            return name.value;
169        } else {
170            if (file != null) {
171                // fix missing name in Safari 4
172                return file.fileName != null ? file.fileName : file.name;
173            } else {
174                return null;
175            }
176        }
177    },
178
179    getSize: function(id){
180        var file = this._files[id];
181        if (file == null) return null;
182        return file.fileSize != null ? file.fileSize : file.size;
183    },
184
185    _upload: function(id, params){
186        var file = this._files[id],
187            name = this.getName(id),
188            size = this.getSize(id);
189        if (name == null || size == null) return;
190
191        this._loaded[id] = 0;
192
193        var xhr = this._xhrs[id] = new XMLHttpRequest();
194        var self = this;
195
196        xhr.upload.onprogress = function(e){
197            if (e.lengthComputable){
198                self._loaded[id] = e.loaded;
199                self._options.onProgress(id, name, e.loaded, e.total);
200            }
201        };
202
203        xhr.onreadystatechange = function(){
204            if (xhr.readyState == 4){
205                self._onComplete(id, xhr);
206            }
207        };
208
209        // build query string
210        params = params || {};
211        params['qqfile'] = name;
212        var queryString = qq.obj2url(params, this._options.action);
213
214        xhr.open("POST", queryString, true);
215        xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
216        xhr.setRequestHeader("X-File-Name", encodeURIComponent(name));
217        xhr.setRequestHeader("Content-Type", "application/octet-stream");
218        xhr.send(file);
219    },
220
221    _uploadAll: function(params){
222        jQuery(".qq-upload-spinner-hidden").each(function (i) {
223            jQuery(this).addClass('qq-upload-spinner');
224        });
225        for (key in this._files) {
226            this.upload(key, params);
227        }
228
229    }
230});
231