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, 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 71qq.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 138qq.extend(qq.FileUploaderExtended.prototype, qq.FileUploader.prototype); 139 140qq.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 199qq.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 273qq.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