1 qq.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, fileName);
56         this._find(item, 'size').style.display = 'none';
57 
58         // name suggestion (simplified cleanID)
59         var nameElement = this._find(item, 'nameInput');
60         fileName = fileName.toLowerCase();
61         fileName = fileName.replace(/([ !"#$%&\'()+,\/;<=>?@[\]^`{|}~:]+)/g, '_');
62         fileName = fileName.replace(/^_+/,'');
63         nameElement.value = fileName;
64         nameElement.id = 'mediamanager__upload_item'+id;
65 
66         this._listElement.appendChild(item);
67     }
68 
69 });
70 
71 qq.FileUploaderExtended = function(o){
72     // call parent constructor
73     qq.FileUploaderBasic.apply(this, arguments);
74 
75     qq.extend(this._options, {
76         element: null,
77         // if set, will be used instead of qq-upload-list in template
78         listElement: null,
79 
80         template: '<div class="qq-uploader">' +
81             '<div class="qq-upload-drop-area"><span>' + LANG.media_drop + '</span></div>' +
82             '<div class="qq-upload-button">' + LANG.media_select + '</div>' +
83             '<ul class="qq-upload-list"></ul>' +
84             '<div class="qq-action-container">' +
85             '  <button class="qq-upload-action" type="submit" id="mediamanager__upload_button">' + LANG.media_upload_btn + '</button>' +
86             '  <label class="qq-overwrite-check"><input type="checkbox" value="1" name="ow" class="dw__ow"> <span>' + LANG.media_overwrt + '</span></label>' +
87             '</div>' +
88             '</div>',
89 
90         // template for one item in file list
91         fileTemplate: '<li>' +
92               '<span class="qq-upload-file hidden"></span>' +
93             '  <input class="qq-upload-name-input edit" type="text" value="" />' +
94             '  <span class="qq-upload-spinner hidden"></span>' +
95             '  <span class="qq-upload-size"></span>' +
96             '  <a class="qq-upload-cancel" href="#">' + LANG.media_cancel + '</a>' +
97             '  <span class="qq-upload-failed-text error">Failed</span>' +
98             '</li>',
99 
100         classes: {
101             // used to get elements from templates
102             button: 'qq-upload-button',
103             drop: 'qq-upload-drop-area',
104             dropActive: 'qq-upload-drop-area-active',
105             list: 'qq-upload-list',
106             nameInput: 'qq-upload-name-input',
107             overwriteInput: 'qq-overwrite-check',
108             uploadButton: 'qq-upload-action',
109             file: 'qq-upload-file',
110 
111             spinner: 'qq-upload-spinner',
112             size: 'qq-upload-size',
113             cancel: 'qq-upload-cancel',
114 
115             // added to list item when upload completes
116             // used in css to hide progress spinner
117             success: 'qq-upload-success',
118             fail: 'qq-upload-fail',
119             failedText: 'qq-upload-failed-text'
120         }
121     });
122 
123     qq.extend(this._options, o);
124 
125     this._element = this._options.element;
126     this._element.innerHTML = this._options.template;
127     this._listElement = this._options.listElement || this._find(this._element, 'list');
128 
129     this._classes = this._options.classes;
130 
131     this._button = this._createUploadButton(this._find(this._element, 'button'));
132 
133     this._bindCancelEvent();
134     this._bindUploadEvent();
135     this._setupDragDrop();
136 };
137 
138 qq.extend(qq.FileUploaderExtended.prototype, qq.FileUploader.prototype);
139 
140 qq.extend(qq.FileUploaderExtended.prototype, {
141     _bindUploadEvent: function(){
142         var self = this,
143             list = this._listElement;
144 
145         qq.attach(document.getElementById('mediamanager__upload_button'), 'click', function(e){
146             e = e || window.event;
147             var target = e.target || e.srcElement;
148             qq.preventDefault(e);
149             self._handler._options.onUpload();
150 
151             jQuery(".qq-upload-name-input").each(function (i) {
152                 jQuery(this).prop('disabled', true);
153             });
154         });
155     },
156 
157     _onComplete: function(id, fileName, result){
158         this._filesInProgress--;
159 
160         // mark completed
161         var item = this._getItemByFileId(id);
162         qq.remove(this._find(item, 'cancel'));
163         qq.remove(this._find(item, 'spinner'));
164 
165         var nameInput = this._find(item, 'nameInput');
166         var fileElement = this._find(item, 'file');
167         qq.setText(fileElement, nameInput.value);
168         qq.removeClass(fileElement, 'hidden');
169         qq.remove(nameInput);
170         jQuery('.qq-upload-button, #mediamanager__upload_button').remove();
171         jQuery('.dw__ow').parent().hide();
172         jQuery('.qq-upload-drop-area').remove();
173 
174         if (result.success){
175             qq.addClass(item, this._classes.success);
176             $link = '<a href="' + result.link + '" id="h_:' + result.id + '" class="select">' + nameInput.value + '</a>';
177             jQuery(fileElement).html($link);
178 
179         } else {
180             qq.addClass(item, this._classes.fail);
181             var fail = this._find(item, 'failedText');
182             if (result.error) qq.setText(fail, result.error);
183         }
184 
185         if (document.getElementById('media__content') && !document.getElementById('mediamanager__done_form')) {
186             var action = document.location.href;
187             var i = action.indexOf('?');
188             if (i) action = action.substr(0, i);
189             var button = '<form method="post" action="' + action + '" id="mediamanager__done_form"><div>';
190             button += '<input type="hidden" value="' + result.ns + '" name="ns">';
191             button += '<input type="hidden" value="1" name="recent">';
192             button += '<button type="submit">' + LANG.media_done_btn + '</button></div></form>';
193             jQuery('#mediamanager__uploader').append(button);
194         }
195     }
196 
197 });
198 
199 qq.extend(qq.UploadHandlerForm.prototype, {
200     uploadAll: function(params){
201         this._uploadAll(params);
202     },
203 
204     getName: function(id){
205         var file = this._inputs[id];
206         var name = document.getElementById('mediamanager__upload_item'+id);
207         if (name != null) {
208             return name.value;
209         } else {
210             if (file != null) {
211                 // get input value and remove path to normalize
212                 return file.value.replace(/.*(\/|\\)/, "");
213             } else {
214                 return null;
215             }
216         }
217     },
218 
219     _uploadAll: function(params){
220          jQuery(".qq-upload-spinner").each(function (i) {
221             jQuery(this).removeClass('hidden');
222         });
223         for (key in this._inputs) {
224             this.upload(key, params);
225         }
226 
227     },
228 
229     _upload: function(id, params){
230         var input = this._inputs[id];
231 
232         if (!input){
233             throw new Error('file with passed id was not added, or already uploaded or cancelled');
234         }
235 
236         var fileName = this.getName(id);
237 
238         var iframe = this._createIframe(id);
239         var form = this._createForm(iframe, params);
240         form.appendChild(input);
241 
242         var nameInput = qq.toElement('<input name="mediaid" value="' + fileName + '" type="text">');
243         form.appendChild(nameInput);
244 
245         var checked = jQuery('.dw__ow').is(':checked');
246         var owCheckbox = jQuery('.dw__ow').clone();
247         owCheckbox.attr('checked', checked);
248         jQuery(form).append(owCheckbox);
249 
250         var self = this;
251         this._attachLoadEvent(iframe, function(){
252             self.log('iframe loaded');
253 
254             var response = self._getIframeContentJSON(iframe);
255 
256             self._options.onComplete(id, fileName, response);
257             self._dequeue(id);
258 
259             delete self._inputs[id];
260             // timeout added to fix busy state in FF3.6
261             setTimeout(function(){
262                 qq.remove(iframe);
263             }, 1);
264         });
265 
266         form.submit();
267         qq.remove(form);
268 
269         return id;
270     }
271 });
272 
273 qq.extend(qq.UploadHandlerXhr.prototype, {
274     uploadAll: function(params){
275         this._uploadAll(params);
276     },
277 
278     getName: function(id){
279         var file = this._files[id];
280         var name = document.getElementById('mediamanager__upload_item'+id);
281         if (name != null) {
282             return name.value;
283         } else {
284             if (file != null) {
285                 // fix missing name in Safari 4
286                 return file.fileName != null ? file.fileName : file.name;
287             } else {
288                 return null;
289             }
290         }
291     },
292 
293     getSize: function(id){
294         var file = this._files[id];
295         if (file == null) return null;
296         return file.fileSize != null ? file.fileSize : file.size;
297     },
298 
299     _upload: function(id, params){
300         var file = this._files[id],
301             name = this.getName(id),
302             size = this.getSize(id);
303         if (name == null || size == null) return;
304 
305         this._loaded[id] = 0;
306 
307         var xhr = this._xhrs[id] = new XMLHttpRequest();
308         var self = this;
309 
310         xhr.upload.onprogress = function(e){
311             if (e.lengthComputable){
312                 self._loaded[id] = e.loaded;
313                 self._options.onProgress(id, name, e.loaded, e.total);
314             }
315         };
316 
317         xhr.onreadystatechange = function(){
318             if (xhr.readyState == 4){
319                 self._onComplete(id, xhr);
320             }
321         };
322 
323         // build query string
324         params = params || {};
325         params['qqfile'] = name;
326         params['ow'] = jQuery('.dw__ow').is(':checked');
327         var queryString = qq.obj2url(params, this._options.action);
328 
329         xhr.open("POST", queryString, true);
330         xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
331         xhr.setRequestHeader("X-File-Name", encodeURIComponent(name));
332         xhr.setRequestHeader("Content-Type", "application/octet-stream");
333         xhr.send(file);
334     },
335 
336     _uploadAll: function(params){
337         jQuery(".qq-upload-spinner").each(function (i) {
338             jQuery(this).removeClass('hidden');
339         });
340         for (key in this._files) {
341             this.upload(key, params);
342         }
343 
344     }
345 });
346