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