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