author | ymh <ymh.work@gmail.com> |
Tue, 15 Dec 2020 13:49:49 +0100 | |
changeset 16 | a86126ab1dd4 |
parent 9 | 177826044cd9 |
child 18 | be944660c56a |
permissions | -rw-r--r-- |
5 | 1 |
/* global pluploadL10n, plupload, _wpPluploadSettings */ |
2 |
||
9 | 3 |
/** |
4 |
* @namespace wp |
|
5 |
*/ |
|
0 | 6 |
window.wp = window.wp || {}; |
7 |
||
5 | 8 |
( function( exports, $ ) { |
0 | 9 |
var Uploader; |
10 |
||
5 | 11 |
if ( typeof _wpPluploadSettings === 'undefined' ) { |
0 | 12 |
return; |
5 | 13 |
} |
0 | 14 |
|
5 | 15 |
/** |
16 |
* A WordPress uploader. |
|
0 | 17 |
* |
5 | 18 |
* The Plupload library provides cross-browser uploader UI integration. |
19 |
* This object bridges the Plupload API to integrate uploads into the |
|
7
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
5
diff
changeset
|
20 |
* WordPress back end and the WordPress media experience. |
0 | 21 |
* |
9 | 22 |
* @class |
23 |
* @memberOf wp |
|
24 |
* @alias wp.Uploader |
|
25 |
* |
|
5 | 26 |
* @param {object} options The options passed to the new plupload instance. |
27 |
* @param {object} options.container The id of uploader container. |
|
28 |
* @param {object} options.browser The id of button to trigger the file select. |
|
29 |
* @param {object} options.dropzone The id of file drop target. |
|
30 |
* @param {object} options.plupload An object of parameters to pass to the plupload instance. |
|
31 |
* @param {object} options.params An object of parameters to pass to $_POST when uploading the file. |
|
32 |
* Extends this.plupload.multipart_params under the hood. |
|
0 | 33 |
*/ |
34 |
Uploader = function( options ) { |
|
35 |
var self = this, |
|
16 | 36 |
isIE, // Not used, back-compat. |
0 | 37 |
elements = { |
38 |
container: 'container', |
|
39 |
browser: 'browse_button', |
|
40 |
dropzone: 'drop_element' |
|
41 |
}, |
|
16 | 42 |
tryAgainCount = {}, |
43 |
tryAgain, |
|
44 |
key, |
|
45 |
error, |
|
46 |
fileUploaded; |
|
0 | 47 |
|
48 |
this.supports = { |
|
49 |
upload: Uploader.browser.supported |
|
50 |
}; |
|
51 |
||
52 |
this.supported = this.supports.upload; |
|
53 |
||
5 | 54 |
if ( ! this.supported ) { |
0 | 55 |
return; |
5 | 56 |
} |
0 | 57 |
|
5 | 58 |
// Arguments to send to pluplad.Uploader(). |
0 | 59 |
// Use deep extend to ensure that multipart_params and other objects are cloned. |
60 |
this.plupload = $.extend( true, { multipart_params: {} }, Uploader.defaults ); |
|
61 |
this.container = document.body; // Set default container. |
|
62 |
||
16 | 63 |
/* |
64 |
* Extend the instance with options. |
|
65 |
* |
|
66 |
* Use deep extend to allow options.plupload to override individual |
|
67 |
* default plupload keys. |
|
68 |
*/ |
|
0 | 69 |
$.extend( true, this, options ); |
70 |
||
71 |
// Proxy all methods so this always refers to the current instance. |
|
72 |
for ( key in this ) { |
|
5 | 73 |
if ( $.isFunction( this[ key ] ) ) { |
0 | 74 |
this[ key ] = $.proxy( this[ key ], this ); |
5 | 75 |
} |
0 | 76 |
} |
77 |
||
5 | 78 |
// Ensure all elements are jQuery elements and have id attributes, |
79 |
// then set the proper plupload arguments to the ids. |
|
0 | 80 |
for ( key in elements ) { |
5 | 81 |
if ( ! this[ key ] ) { |
0 | 82 |
continue; |
5 | 83 |
} |
0 | 84 |
|
85 |
this[ key ] = $( this[ key ] ).first(); |
|
86 |
||
87 |
if ( ! this[ key ].length ) { |
|
88 |
delete this[ key ]; |
|
89 |
continue; |
|
90 |
} |
|
91 |
||
5 | 92 |
if ( ! this[ key ].prop('id') ) { |
0 | 93 |
this[ key ].prop( 'id', '__wp-uploader-id-' + Uploader.uuid++ ); |
5 | 94 |
} |
95 |
||
0 | 96 |
this.plupload[ elements[ key ] ] = this[ key ].prop('id'); |
97 |
} |
|
98 |
||
99 |
// If the uploader has neither a browse button nor a dropzone, bail. |
|
5 | 100 |
if ( ! ( this.browser && this.browser.length ) && ! ( this.dropzone && this.dropzone.length ) ) { |
0 | 101 |
return; |
5 | 102 |
} |
0 | 103 |
|
5 | 104 |
// Initialize the plupload instance. |
0 | 105 |
this.uploader = new plupload.Uploader( this.plupload ); |
106 |
delete this.plupload; |
|
107 |
||
108 |
// Set default params and remove this.params alias. |
|
109 |
this.param( this.params || {} ); |
|
110 |
delete this.params; |
|
111 |
||
5 | 112 |
/** |
16 | 113 |
* Attempt to create image sub-sizes when an image was uploaded successfully |
114 |
* but the server responded with HTTP 5xx error. |
|
115 |
* |
|
116 |
* @since 5.3.0 |
|
117 |
* |
|
118 |
* @param {string} message Error message. |
|
119 |
* @param {object} data Error data from Plupload. |
|
120 |
* @param {plupload.File} file File that was uploaded. |
|
121 |
*/ |
|
122 |
tryAgain = function( message, data, file ) { |
|
123 |
var times, id; |
|
124 |
||
125 |
if ( ! data || ! data.responseHeaders ) { |
|
126 |
error( pluploadL10n.http_error_image, data, file, 'no-retry' ); |
|
127 |
return; |
|
128 |
} |
|
129 |
||
130 |
id = data.responseHeaders.match( /x-wp-upload-attachment-id:\s*(\d+)/i ); |
|
131 |
||
132 |
if ( id && id[1] ) { |
|
133 |
id = id[1]; |
|
134 |
} else { |
|
135 |
error( pluploadL10n.http_error_image, data, file, 'no-retry' ); |
|
136 |
return; |
|
137 |
} |
|
138 |
||
139 |
times = tryAgainCount[ file.id ]; |
|
140 |
||
141 |
if ( times && times > 4 ) { |
|
142 |
/* |
|
143 |
* The file may have been uploaded and attachment post created, |
|
144 |
* but post-processing and resizing failed... |
|
145 |
* Do a cleanup then tell the user to scale down the image and upload it again. |
|
146 |
*/ |
|
147 |
$.ajax({ |
|
148 |
type: 'post', |
|
149 |
url: ajaxurl, |
|
150 |
dataType: 'json', |
|
151 |
data: { |
|
152 |
action: 'media-create-image-subsizes', |
|
153 |
_wpnonce: _wpPluploadSettings.defaults.multipart_params._wpnonce, |
|
154 |
attachment_id: id, |
|
155 |
_wp_upload_failed_cleanup: true, |
|
156 |
} |
|
157 |
}); |
|
158 |
||
159 |
error( message, data, file, 'no-retry' ); |
|
160 |
return; |
|
161 |
} |
|
162 |
||
163 |
if ( ! times ) { |
|
164 |
tryAgainCount[ file.id ] = 1; |
|
165 |
} else { |
|
166 |
tryAgainCount[ file.id ] = ++times; |
|
167 |
} |
|
168 |
||
169 |
// Another request to try to create the missing image sub-sizes. |
|
170 |
$.ajax({ |
|
171 |
type: 'post', |
|
172 |
url: ajaxurl, |
|
173 |
dataType: 'json', |
|
174 |
data: { |
|
175 |
action: 'media-create-image-subsizes', |
|
176 |
_wpnonce: _wpPluploadSettings.defaults.multipart_params._wpnonce, |
|
177 |
attachment_id: id, |
|
178 |
} |
|
179 |
}).done( function( response ) { |
|
180 |
if ( response.success ) { |
|
181 |
fileUploaded( self.uploader, file, response ); |
|
182 |
} else { |
|
183 |
if ( response.data && response.data.message ) { |
|
184 |
message = response.data.message; |
|
185 |
} |
|
186 |
||
187 |
error( message, data, file, 'no-retry' ); |
|
188 |
} |
|
189 |
}).fail( function( jqXHR ) { |
|
190 |
// If another HTTP 5xx error, try try again... |
|
191 |
if ( jqXHR.status >= 500 && jqXHR.status < 600 ) { |
|
192 |
tryAgain( message, data, file ); |
|
193 |
return; |
|
194 |
} |
|
195 |
||
196 |
error( message, data, file, 'no-retry' ); |
|
197 |
}); |
|
198 |
} |
|
199 |
||
200 |
/** |
|
5 | 201 |
* Custom error callback. |
202 |
* |
|
203 |
* Add a new error to the errors collection, so other modules can track |
|
204 |
* and display errors. @see wp.Uploader.errors. |
|
205 |
* |
|
16 | 206 |
* @param {string} message Error message. |
207 |
* @param {object} data Error data from Plupload. |
|
208 |
* @param {plupload.File} file File that was uploaded. |
|
209 |
* @param {string} retry Whether to try again to create image sub-sizes. Passing 'no-retry' will prevent it. |
|
5 | 210 |
*/ |
16 | 211 |
error = function( message, data, file, retry ) { |
212 |
var isImage = file.type && file.type.indexOf( 'image/' ) === 0, |
|
213 |
status = data && data.status; |
|
214 |
||
215 |
// If the file is an image and the error is HTTP 5xx try to create sub-sizes again. |
|
216 |
if ( retry !== 'no-retry' && isImage && status >= 500 && status < 600 ) { |
|
217 |
tryAgain( message, data, file ); |
|
218 |
return; |
|
219 |
} |
|
220 |
||
5 | 221 |
if ( file.attachment ) { |
0 | 222 |
file.attachment.destroy(); |
5 | 223 |
} |
0 | 224 |
|
225 |
Uploader.errors.unshift({ |
|
226 |
message: message || pluploadL10n.default_error, |
|
227 |
data: data, |
|
228 |
file: file |
|
229 |
}); |
|
230 |
||
231 |
self.error( message, data, file ); |
|
232 |
}; |
|
233 |
||
5 | 234 |
/** |
16 | 235 |
* After a file is successfully uploaded, update its model. |
236 |
* |
|
237 |
* @param {plupload.Uploader} up Uploader instance. |
|
238 |
* @param {plupload.File} file File that was uploaded. |
|
239 |
* @param {Object} response Object with response properties. |
|
240 |
*/ |
|
241 |
fileUploaded = function( up, file, response ) { |
|
242 |
var complete; |
|
243 |
||
244 |
// Remove the "uploading" UI elements. |
|
245 |
_.each( ['file','loaded','size','percent'], function( key ) { |
|
246 |
file.attachment.unset( key ); |
|
247 |
} ); |
|
248 |
||
249 |
file.attachment.set( _.extend( response.data, { uploading: false } ) ); |
|
250 |
||
251 |
wp.media.model.Attachment.get( response.data.id, file.attachment ); |
|
252 |
||
253 |
complete = Uploader.queue.all( function( attachment ) { |
|
254 |
return ! attachment.get( 'uploading' ); |
|
255 |
}); |
|
256 |
||
257 |
if ( complete ) { |
|
258 |
Uploader.queue.reset(); |
|
259 |
} |
|
260 |
||
261 |
self.success( file.attachment ); |
|
262 |
} |
|
263 |
||
264 |
/** |
|
5 | 265 |
* After the Uploader has been initialized, initialize some behaviors for the dropzone. |
266 |
* |
|
267 |
* @param {plupload.Uploader} uploader Uploader instance. |
|
268 |
*/ |
|
269 |
this.uploader.bind( 'init', function( uploader ) { |
|
270 |
var timer, active, dragdrop, |
|
271 |
dropzone = self.dropzone; |
|
0 | 272 |
|
5 | 273 |
dragdrop = self.supports.dragdrop = uploader.features.dragdrop && ! Uploader.browser.mobile; |
0 | 274 |
|
5 | 275 |
// Generate drag/drop helper classes. |
276 |
if ( ! dropzone ) { |
|
0 | 277 |
return; |
5 | 278 |
} |
0 | 279 |
|
5 | 280 |
dropzone.toggleClass( 'supports-drag-drop', !! dragdrop ); |
0 | 281 |
|
5 | 282 |
if ( ! dragdrop ) { |
0 | 283 |
return dropzone.unbind('.wp-uploader'); |
5 | 284 |
} |
0 | 285 |
|
5 | 286 |
// 'dragenter' doesn't fire correctly, simulate it with a limited 'dragover'. |
287 |
dropzone.bind( 'dragover.wp-uploader', function() { |
|
288 |
if ( timer ) { |
|
0 | 289 |
clearTimeout( timer ); |
5 | 290 |
} |
0 | 291 |
|
5 | 292 |
if ( active ) { |
0 | 293 |
return; |
5 | 294 |
} |
0 | 295 |
|
296 |
dropzone.trigger('dropzone:enter').addClass('drag-over'); |
|
297 |
active = true; |
|
298 |
}); |
|
299 |
||
5 | 300 |
dropzone.bind('dragleave.wp-uploader, drop.wp-uploader', function() { |
16 | 301 |
/* |
302 |
* Using an instant timer prevents the drag-over class |
|
303 |
* from being quickly removed and re-added when elements |
|
304 |
* inside the dropzone are repositioned. |
|
305 |
* |
|
306 |
* @see https://core.trac.wordpress.org/ticket/21705 |
|
307 |
*/ |
|
0 | 308 |
timer = setTimeout( function() { |
309 |
active = false; |
|
310 |
dropzone.trigger('dropzone:leave').removeClass('drag-over'); |
|
311 |
}, 0 ); |
|
312 |
}); |
|
5 | 313 |
|
314 |
self.ready = true; |
|
315 |
$(self).trigger( 'uploader:ready' ); |
|
316 |
}); |
|
317 |
||
7
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
5
diff
changeset
|
318 |
this.uploader.bind( 'postinit', function( up ) { |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
5
diff
changeset
|
319 |
up.refresh(); |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
5
diff
changeset
|
320 |
self.init(); |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
5
diff
changeset
|
321 |
}); |
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
5
diff
changeset
|
322 |
|
5 | 323 |
this.uploader.init(); |
0 | 324 |
|
325 |
if ( this.browser ) { |
|
326 |
this.browser.on( 'mouseenter', this.refresh ); |
|
327 |
} else { |
|
328 |
this.uploader.disableBrowse( true ); |
|
329 |
} |
|
330 |
||
16 | 331 |
$( self ).on( 'uploader:ready', function() { |
332 |
$( '.moxie-shim-html5 input[type="file"]' ) |
|
333 |
.attr( { |
|
334 |
tabIndex: '-1', |
|
335 |
'aria-hidden': 'true' |
|
336 |
} ); |
|
337 |
} ); |
|
338 |
||
5 | 339 |
/** |
340 |
* After files were filtered and added to the queue, create a model for each. |
|
341 |
* |
|
16 | 342 |
* @param {plupload.Uploader} up Uploader instance. |
343 |
* @param {Array} files Array of file objects that were added to queue by the user. |
|
5 | 344 |
*/ |
0 | 345 |
this.uploader.bind( 'FilesAdded', function( up, files ) { |
346 |
_.each( files, function( file ) { |
|
347 |
var attributes, image; |
|
348 |
||
349 |
// Ignore failed uploads. |
|
5 | 350 |
if ( plupload.FAILED === file.status ) { |
0 | 351 |
return; |
5 | 352 |
} |
0 | 353 |
|
16 | 354 |
if ( file.type === 'image/heic' && up.settings.heic_upload_error ) { |
355 |
// Show error but do not block uploading. |
|
356 |
Uploader.errors.unshift({ |
|
357 |
message: pluploadL10n.unsupported_image, |
|
358 |
data: {}, |
|
359 |
file: file |
|
360 |
}); |
|
361 |
} |
|
362 |
||
0 | 363 |
// Generate attributes for a new `Attachment` model. |
364 |
attributes = _.extend({ |
|
365 |
file: file, |
|
366 |
uploading: true, |
|
367 |
date: new Date(), |
|
368 |
filename: file.name, |
|
369 |
menuOrder: 0, |
|
370 |
uploadedTo: wp.media.model.settings.post.id |
|
371 |
}, _.pick( file, 'loaded', 'size', 'percent' ) ); |
|
372 |
||
373 |
// Handle early mime type scanning for images. |
|
374 |
image = /(?:jpe?g|png|gif)$/i.exec( file.name ); |
|
375 |
||
5 | 376 |
// For images set the model's type and subtype attributes. |
0 | 377 |
if ( image ) { |
378 |
attributes.type = 'image'; |
|
379 |
||
380 |
// `jpeg`, `png` and `gif` are valid subtypes. |
|
381 |
// `jpg` is not, so map it to `jpeg`. |
|
382 |
attributes.subtype = ( 'jpg' === image[0] ) ? 'jpeg' : image[0]; |
|
383 |
} |
|
384 |
||
5 | 385 |
// Create a model for the attachment, and add it to the Upload queue collection |
386 |
// so listeners to the upload queue can track and display upload progress. |
|
0 | 387 |
file.attachment = wp.media.model.Attachment.create( attributes ); |
388 |
Uploader.queue.add( file.attachment ); |
|
389 |
||
390 |
self.added( file.attachment ); |
|
391 |
}); |
|
392 |
||
393 |
up.refresh(); |
|
394 |
up.start(); |
|
395 |
}); |
|
396 |
||
397 |
this.uploader.bind( 'UploadProgress', function( up, file ) { |
|
398 |
file.attachment.set( _.pick( file, 'loaded', 'percent' ) ); |
|
399 |
self.progress( file.attachment ); |
|
400 |
}); |
|
401 |
||
5 | 402 |
/** |
403 |
* After a file is successfully uploaded, update its model. |
|
404 |
* |
|
16 | 405 |
* @param {plupload.Uploader} up Uploader instance. |
5 | 406 |
* @param {plupload.File} file File that was uploaded. |
407 |
* @param {Object} response Object with response properties. |
|
408 |
* @return {mixed} |
|
409 |
*/ |
|
0 | 410 |
this.uploader.bind( 'FileUploaded', function( up, file, response ) { |
411 |
||
412 |
try { |
|
413 |
response = JSON.parse( response.response ); |
|
414 |
} catch ( e ) { |
|
415 |
return error( pluploadL10n.default_error, e, file ); |
|
416 |
} |
|
417 |
||
16 | 418 |
if ( ! _.isObject( response ) || _.isUndefined( response.success ) ) { |
0 | 419 |
return error( pluploadL10n.default_error, null, file ); |
16 | 420 |
} else if ( ! response.success ) { |
0 | 421 |
return error( response.data && response.data.message, response.data, file ); |
16 | 422 |
} |
0 | 423 |
|
16 | 424 |
// Success. Update the UI with the new attachment. |
425 |
fileUploaded( up, file, response ); |
|
0 | 426 |
}); |
427 |
||
5 | 428 |
/** |
429 |
* When plupload surfaces an error, send it to the error handler. |
|
430 |
* |
|
16 | 431 |
* @param {plupload.Uploader} up Uploader instance. |
432 |
* @param {Object} pluploadError Contains code, message and sometimes file and other details. |
|
5 | 433 |
*/ |
0 | 434 |
this.uploader.bind( 'Error', function( up, pluploadError ) { |
435 |
var message = pluploadL10n.default_error, |
|
436 |
key; |
|
437 |
||
438 |
// Check for plupload errors. |
|
439 |
for ( key in Uploader.errorMap ) { |
|
440 |
if ( pluploadError.code === plupload[ key ] ) { |
|
441 |
message = Uploader.errorMap[ key ]; |
|
5 | 442 |
|
443 |
if ( _.isFunction( message ) ) { |
|
0 | 444 |
message = message( pluploadError.file, pluploadError ); |
5 | 445 |
} |
446 |
||
0 | 447 |
break; |
448 |
} |
|
449 |
} |
|
450 |
||
451 |
error( message, pluploadError, pluploadError.file ); |
|
452 |
up.refresh(); |
|
453 |
}); |
|
454 |
||
455 |
}; |
|
456 |
||
457 |
// Adds the 'defaults' and 'browser' properties. |
|
458 |
$.extend( Uploader, _wpPluploadSettings ); |
|
459 |
||
460 |
Uploader.uuid = 0; |
|
461 |
||
5 | 462 |
// Map Plupload error codes to user friendly error messages. |
0 | 463 |
Uploader.errorMap = { |
464 |
'FAILED': pluploadL10n.upload_failed, |
|
465 |
'FILE_EXTENSION_ERROR': pluploadL10n.invalid_filetype, |
|
466 |
'IMAGE_FORMAT_ERROR': pluploadL10n.not_an_image, |
|
467 |
'IMAGE_MEMORY_ERROR': pluploadL10n.image_memory_exceeded, |
|
468 |
'IMAGE_DIMENSIONS_ERROR': pluploadL10n.image_dimensions_exceeded, |
|
469 |
'GENERIC_ERROR': pluploadL10n.upload_failed, |
|
470 |
'IO_ERROR': pluploadL10n.io_error, |
|
471 |
'SECURITY_ERROR': pluploadL10n.security_error, |
|
472 |
||
473 |
'FILE_SIZE_ERROR': function( file ) { |
|
16 | 474 |
return pluploadL10n.file_exceeds_size_limit.replace( '%s', file.name ); |
475 |
}, |
|
476 |
||
477 |
'HTTP_ERROR': function( file ) { |
|
478 |
if ( file.type && file.type.indexOf( 'image/' ) === 0 ) { |
|
479 |
return pluploadL10n.http_error_image; |
|
480 |
} |
|
481 |
||
482 |
return pluploadL10n.http_error; |
|
483 |
}, |
|
0 | 484 |
}; |
485 |
||
7
cf61fcea0001
resynchronize code repo with production
ymh <ymh.work@gmail.com>
parents:
5
diff
changeset
|
486 |
$.extend( Uploader.prototype, /** @lends wp.Uploader.prototype */{ |
0 | 487 |
/** |
488 |
* Acts as a shortcut to extending the uploader's multipart_params object. |
|
489 |
* |
|
490 |
* param( key ) |
|
491 |
* Returns the value of the key. |
|
492 |
* |
|
493 |
* param( key, value ) |
|
494 |
* Sets the value of a key. |
|
495 |
* |
|
496 |
* param( map ) |
|
497 |
* Sets values for a map of data. |
|
498 |
*/ |
|
499 |
param: function( key, value ) { |
|
5 | 500 |
if ( arguments.length === 1 && typeof key === 'string' ) { |
0 | 501 |
return this.uploader.settings.multipart_params[ key ]; |
5 | 502 |
} |
0 | 503 |
|
504 |
if ( arguments.length > 1 ) { |
|
505 |
this.uploader.settings.multipart_params[ key ] = value; |
|
506 |
} else { |
|
507 |
$.extend( this.uploader.settings.multipart_params, key ); |
|
508 |
} |
|
509 |
}, |
|
510 |
||
5 | 511 |
/** |
512 |
* Make a few internal event callbacks available on the wp.Uploader object |
|
513 |
* to change the Uploader internals if absolutely necessary. |
|
514 |
*/ |
|
0 | 515 |
init: function() {}, |
516 |
error: function() {}, |
|
517 |
success: function() {}, |
|
518 |
added: function() {}, |
|
519 |
progress: function() {}, |
|
520 |
complete: function() {}, |
|
521 |
refresh: function() { |
|
522 |
var node, attached, container, id; |
|
523 |
||
524 |
if ( this.browser ) { |
|
525 |
node = this.browser[0]; |
|
526 |
||
527 |
// Check if the browser node is in the DOM. |
|
528 |
while ( node ) { |
|
529 |
if ( node === document.body ) { |
|
530 |
attached = true; |
|
531 |
break; |
|
532 |
} |
|
533 |
node = node.parentNode; |
|
534 |
} |
|
535 |
||
16 | 536 |
/* |
537 |
* If the browser node is not attached to the DOM, |
|
538 |
* use a temporary container to house it, as the browser button shims |
|
539 |
* require the button to exist in the DOM at all times. |
|
540 |
*/ |
|
0 | 541 |
if ( ! attached ) { |
542 |
id = 'wp-uploader-browser-' + this.uploader.id; |
|
543 |
||
544 |
container = $( '#' + id ); |
|
545 |
if ( ! container.length ) { |
|
546 |
container = $('<div class="wp-uploader-browser" />').css({ |
|
547 |
position: 'fixed', |
|
548 |
top: '-1000px', |
|
549 |
left: '-1000px', |
|
550 |
height: 0, |
|
551 |
width: 0 |
|
552 |
}).attr( 'id', 'wp-uploader-browser-' + this.uploader.id ).appendTo('body'); |
|
553 |
} |
|
554 |
||
555 |
container.append( this.browser ); |
|
556 |
} |
|
557 |
} |
|
558 |
||
559 |
this.uploader.refresh(); |
|
560 |
} |
|
561 |
}); |
|
562 |
||
5 | 563 |
// Create a collection of attachments in the upload queue, |
564 |
// so that other modules can track and display upload progress. |
|
0 | 565 |
Uploader.queue = new wp.media.model.Attachments( [], { query: false }); |
5 | 566 |
|
567 |
// Create a collection to collect errors incurred while attempting upload. |
|
0 | 568 |
Uploader.errors = new Backbone.Collection(); |
569 |
||
570 |
exports.Uploader = Uploader; |
|
571 |
})( wp, jQuery ); |