1 if(typeof wp==="undefined"){var wp={}}(function(a,b){var c;if(typeof _wpPluploadSettings==="undefined"){return}c=function(e){var d=this,g={container:"container",browser:"browse_button",dropzone:"drop_element"},f;this.supports={upload:c.browser.supported};this.supported=this.supports.upload;if(!this.supported){return}this.plupload=b.extend(true,{multipart_params:{}},c.defaults);this.container=document.body;b.extend(true,this,e);for(f in this){if(b.isFunction(this[f])){this[f]=b.proxy(this[f],this)}}for(f in g){if(!this[f]){continue}this[f]=b(this[f]).first();if(!this[f].length){delete this[f];continue}if(!this[f].prop("id")){this[f].prop("id","__wp-uploader-id-"+c.uuid++)}this.plupload[g[f]]=this[f].prop("id")}if(!(this.browser&&this.browser.length)&&!(this.dropzone&&this.dropzone.length)){return}this.uploader=new plupload.Uploader(this.plupload);delete this.plupload;this.param(this.params||{});delete this.params;this.uploader.init();this.supports.dragdrop=this.uploader.features.dragdrop&&!c.browser.mobile;(function(j,h){var i=50,k;if(!j){return}j.toggleClass("supports-drag-drop",!!h);if(!h){return j.unbind(".wp-uploader")}j.bind("dragover.wp-uploader",function(){if(k){return}j.addClass("drag-over");k=true});j.bind("dragleave.wp-uploader, drop.wp-uploader",function(){k=false;j.removeClass("drag-over")})}(this.dropzone,this.supports.dragdrop));if(this.browser){this.browser.on("mouseenter",this.refresh)}else{this.uploader.disableBrowse(true);b("#"+this.uploader.id+"_html5_container").hide()}this.uploader.bind("UploadProgress",this.progress);this.uploader.bind("FileUploaded",function(h,j,i){try{i=JSON.parse(i.response)}catch(k){return d.error(pluploadL10n.default_error,k)}if(!i||!i.type||!i.data){return d.error(pluploadL10n.default_error)}if("error"===i.type){return d.error(i.data.message,i.data)}if("success"===i.type){return d.success(i.data)}});this.uploader.bind("Error",function(h,i){var k=pluploadL10n.default_error,j;for(j in c.errorMap){if(i.code===plupload[j]){k=c.errorMap[j];break}}d.error(k,i);h.refresh()});this.uploader.bind("FilesAdded",function(h,i){b.each(i,function(){d.added(this)});h.refresh();h.start()});this.init()};b.extend(c,_wpPluploadSettings);c.uuid=0;c.errorMap={FAILED:pluploadL10n.upload_failed,FILE_EXTENSION_ERROR:pluploadL10n.invalid_filetype,IMAGE_FORMAT_ERROR:pluploadL10n.not_an_image,IMAGE_MEMORY_ERROR:pluploadL10n.image_memory_exceeded,IMAGE_DIMENSIONS_ERROR:pluploadL10n.image_dimensions_exceeded,GENERIC_ERROR:pluploadL10n.upload_failed,IO_ERROR:pluploadL10n.io_error,HTTP_ERROR:pluploadL10n.http_error,SECURITY_ERROR:pluploadL10n.security_error};b.extend(c.prototype,{param:function(d,e){if(arguments.length===1&&typeof d==="string"){return this.uploader.settings.multipart_params[d]}if(arguments.length>1){this.uploader.settings.multipart_params[d]=e}else{b.extend(this.uploader.settings.multipart_params,d)}},init:function(){},error:function(){},success:function(){},added:function(){},progress:function(){},complete:function(){},refresh:function(){this.uploader.refresh()}});a.Uploader=c})(wp,jQuery); |
1 window.wp = window.wp || {}; |
|
2 |
|
3 (function( exports, $ ) { |
|
4 var Uploader; |
|
5 |
|
6 if ( typeof _wpPluploadSettings === 'undefined' ) |
|
7 return; |
|
8 |
|
9 /* |
|
10 * An object that helps create a WordPress uploader using plupload. |
|
11 * |
|
12 * @param options - object - The options passed to the new plupload instance. |
|
13 * Accepts the following parameters: |
|
14 * - container - The id of uploader container. |
|
15 * - browser - The id of button to trigger the file select. |
|
16 * - dropzone - The id of file drop target. |
|
17 * - plupload - An object of parameters to pass to the plupload instance. |
|
18 * - params - An object of parameters to pass to $_POST when uploading the file. |
|
19 * Extends this.plupload.multipart_params under the hood. |
|
20 * |
|
21 * @param attributes - object - Attributes and methods for this specific instance. |
|
22 */ |
|
23 Uploader = function( options ) { |
|
24 var self = this, |
|
25 elements = { |
|
26 container: 'container', |
|
27 browser: 'browse_button', |
|
28 dropzone: 'drop_element' |
|
29 }, |
|
30 key, error; |
|
31 |
|
32 this.supports = { |
|
33 upload: Uploader.browser.supported |
|
34 }; |
|
35 |
|
36 this.supported = this.supports.upload; |
|
37 |
|
38 if ( ! this.supported ) |
|
39 return; |
|
40 |
|
41 // Use deep extend to ensure that multipart_params and other objects are cloned. |
|
42 this.plupload = $.extend( true, { multipart_params: {} }, Uploader.defaults ); |
|
43 this.container = document.body; // Set default container. |
|
44 |
|
45 // Extend the instance with options |
|
46 // |
|
47 // Use deep extend to allow options.plupload to override individual |
|
48 // default plupload keys. |
|
49 $.extend( true, this, options ); |
|
50 |
|
51 // Proxy all methods so this always refers to the current instance. |
|
52 for ( key in this ) { |
|
53 if ( $.isFunction( this[ key ] ) ) |
|
54 this[ key ] = $.proxy( this[ key ], this ); |
|
55 } |
|
56 |
|
57 // Ensure all elements are jQuery elements and have id attributes |
|
58 // Then set the proper plupload arguments to the ids. |
|
59 for ( key in elements ) { |
|
60 if ( ! this[ key ] ) |
|
61 continue; |
|
62 |
|
63 this[ key ] = $( this[ key ] ).first(); |
|
64 |
|
65 if ( ! this[ key ].length ) { |
|
66 delete this[ key ]; |
|
67 continue; |
|
68 } |
|
69 |
|
70 if ( ! this[ key ].prop('id') ) |
|
71 this[ key ].prop( 'id', '__wp-uploader-id-' + Uploader.uuid++ ); |
|
72 this.plupload[ elements[ key ] ] = this[ key ].prop('id'); |
|
73 } |
|
74 |
|
75 // If the uploader has neither a browse button nor a dropzone, bail. |
|
76 if ( ! ( this.browser && this.browser.length ) && ! ( this.dropzone && this.dropzone.length ) ) |
|
77 return; |
|
78 |
|
79 this.uploader = new plupload.Uploader( this.plupload ); |
|
80 delete this.plupload; |
|
81 |
|
82 // Set default params and remove this.params alias. |
|
83 this.param( this.params || {} ); |
|
84 delete this.params; |
|
85 |
|
86 error = function( message, data, file ) { |
|
87 if ( file.attachment ) |
|
88 file.attachment.destroy(); |
|
89 |
|
90 Uploader.errors.unshift({ |
|
91 message: message || pluploadL10n.default_error, |
|
92 data: data, |
|
93 file: file |
|
94 }); |
|
95 |
|
96 self.error( message, data, file ); |
|
97 }; |
|
98 |
|
99 this.uploader.init(); |
|
100 |
|
101 this.supports.dragdrop = this.uploader.features.dragdrop && ! Uploader.browser.mobile; |
|
102 |
|
103 // Generate drag/drop helper classes. |
|
104 (function( dropzone, supported ) { |
|
105 var timer, active; |
|
106 |
|
107 if ( ! dropzone ) |
|
108 return; |
|
109 |
|
110 dropzone.toggleClass( 'supports-drag-drop', !! supported ); |
|
111 |
|
112 if ( ! supported ) |
|
113 return dropzone.unbind('.wp-uploader'); |
|
114 |
|
115 // 'dragenter' doesn't fire correctly, |
|
116 // simulate it with a limited 'dragover' |
|
117 dropzone.bind( 'dragover.wp-uploader', function(){ |
|
118 if ( timer ) |
|
119 clearTimeout( timer ); |
|
120 |
|
121 if ( active ) |
|
122 return; |
|
123 |
|
124 dropzone.trigger('dropzone:enter').addClass('drag-over'); |
|
125 active = true; |
|
126 }); |
|
127 |
|
128 dropzone.bind('dragleave.wp-uploader, drop.wp-uploader', function(){ |
|
129 // Using an instant timer prevents the drag-over class from |
|
130 // being quickly removed and re-added when elements inside the |
|
131 // dropzone are repositioned. |
|
132 // |
|
133 // See http://core.trac.wordpress.org/ticket/21705 |
|
134 timer = setTimeout( function() { |
|
135 active = false; |
|
136 dropzone.trigger('dropzone:leave').removeClass('drag-over'); |
|
137 }, 0 ); |
|
138 }); |
|
139 }( this.dropzone, this.supports.dragdrop )); |
|
140 |
|
141 if ( this.browser ) { |
|
142 this.browser.on( 'mouseenter', this.refresh ); |
|
143 } else { |
|
144 this.uploader.disableBrowse( true ); |
|
145 // If HTML5 mode, hide the auto-created file container. |
|
146 $('#' + this.uploader.id + '_html5_container').hide(); |
|
147 } |
|
148 |
|
149 this.uploader.bind( 'FilesAdded', function( up, files ) { |
|
150 _.each( files, function( file ) { |
|
151 var attributes, image; |
|
152 |
|
153 // Ignore failed uploads. |
|
154 if ( plupload.FAILED === file.status ) |
|
155 return; |
|
156 |
|
157 // Generate attributes for a new `Attachment` model. |
|
158 attributes = _.extend({ |
|
159 file: file, |
|
160 uploading: true, |
|
161 date: new Date(), |
|
162 filename: file.name, |
|
163 menuOrder: 0, |
|
164 uploadedTo: wp.media.model.settings.post.id |
|
165 }, _.pick( file, 'loaded', 'size', 'percent' ) ); |
|
166 |
|
167 // Handle early mime type scanning for images. |
|
168 image = /(?:jpe?g|png|gif)$/i.exec( file.name ); |
|
169 |
|
170 // Did we find an image? |
|
171 if ( image ) { |
|
172 attributes.type = 'image'; |
|
173 |
|
174 // `jpeg`, `png` and `gif` are valid subtypes. |
|
175 // `jpg` is not, so map it to `jpeg`. |
|
176 attributes.subtype = ( 'jpg' === image[0] ) ? 'jpeg' : image[0]; |
|
177 } |
|
178 |
|
179 // Create the `Attachment`. |
|
180 file.attachment = wp.media.model.Attachment.create( attributes ); |
|
181 |
|
182 Uploader.queue.add( file.attachment ); |
|
183 |
|
184 self.added( file.attachment ); |
|
185 }); |
|
186 |
|
187 up.refresh(); |
|
188 up.start(); |
|
189 }); |
|
190 |
|
191 this.uploader.bind( 'UploadProgress', function( up, file ) { |
|
192 file.attachment.set( _.pick( file, 'loaded', 'percent' ) ); |
|
193 self.progress( file.attachment ); |
|
194 }); |
|
195 |
|
196 this.uploader.bind( 'FileUploaded', function( up, file, response ) { |
|
197 var complete; |
|
198 |
|
199 try { |
|
200 response = JSON.parse( response.response ); |
|
201 } catch ( e ) { |
|
202 return error( pluploadL10n.default_error, e, file ); |
|
203 } |
|
204 |
|
205 if ( ! _.isObject( response ) || _.isUndefined( response.success ) ) |
|
206 return error( pluploadL10n.default_error, null, file ); |
|
207 else if ( ! response.success ) |
|
208 return error( response.data && response.data.message, response.data, file ); |
|
209 |
|
210 _.each(['file','loaded','size','percent'], function( key ) { |
|
211 file.attachment.unset( key ); |
|
212 }); |
|
213 |
|
214 file.attachment.set( _.extend( response.data, { uploading: false }) ); |
|
215 wp.media.model.Attachment.get( response.data.id, file.attachment ); |
|
216 |
|
217 complete = Uploader.queue.all( function( attachment ) { |
|
218 return ! attachment.get('uploading'); |
|
219 }); |
|
220 |
|
221 if ( complete ) |
|
222 Uploader.queue.reset(); |
|
223 |
|
224 self.success( file.attachment ); |
|
225 }); |
|
226 |
|
227 this.uploader.bind( 'Error', function( up, pluploadError ) { |
|
228 var message = pluploadL10n.default_error, |
|
229 key; |
|
230 |
|
231 // Check for plupload errors. |
|
232 for ( key in Uploader.errorMap ) { |
|
233 if ( pluploadError.code === plupload[ key ] ) { |
|
234 message = Uploader.errorMap[ key ]; |
|
235 if ( _.isFunction( message ) ) |
|
236 message = message( pluploadError.file, pluploadError ); |
|
237 break; |
|
238 } |
|
239 } |
|
240 |
|
241 error( message, pluploadError, pluploadError.file ); |
|
242 up.refresh(); |
|
243 }); |
|
244 |
|
245 this.init(); |
|
246 }; |
|
247 |
|
248 // Adds the 'defaults' and 'browser' properties. |
|
249 $.extend( Uploader, _wpPluploadSettings ); |
|
250 |
|
251 Uploader.uuid = 0; |
|
252 |
|
253 Uploader.errorMap = { |
|
254 'FAILED': pluploadL10n.upload_failed, |
|
255 'FILE_EXTENSION_ERROR': pluploadL10n.invalid_filetype, |
|
256 'IMAGE_FORMAT_ERROR': pluploadL10n.not_an_image, |
|
257 'IMAGE_MEMORY_ERROR': pluploadL10n.image_memory_exceeded, |
|
258 'IMAGE_DIMENSIONS_ERROR': pluploadL10n.image_dimensions_exceeded, |
|
259 'GENERIC_ERROR': pluploadL10n.upload_failed, |
|
260 'IO_ERROR': pluploadL10n.io_error, |
|
261 'HTTP_ERROR': pluploadL10n.http_error, |
|
262 'SECURITY_ERROR': pluploadL10n.security_error, |
|
263 |
|
264 'FILE_SIZE_ERROR': function( file ) { |
|
265 return pluploadL10n.file_exceeds_size_limit.replace('%s', file.name); |
|
266 } |
|
267 }; |
|
268 |
|
269 $.extend( Uploader.prototype, { |
|
270 /** |
|
271 * Acts as a shortcut to extending the uploader's multipart_params object. |
|
272 * |
|
273 * param( key ) |
|
274 * Returns the value of the key. |
|
275 * |
|
276 * param( key, value ) |
|
277 * Sets the value of a key. |
|
278 * |
|
279 * param( map ) |
|
280 * Sets values for a map of data. |
|
281 */ |
|
282 param: function( key, value ) { |
|
283 if ( arguments.length === 1 && typeof key === 'string' ) |
|
284 return this.uploader.settings.multipart_params[ key ]; |
|
285 |
|
286 if ( arguments.length > 1 ) { |
|
287 this.uploader.settings.multipart_params[ key ] = value; |
|
288 } else { |
|
289 $.extend( this.uploader.settings.multipart_params, key ); |
|
290 } |
|
291 }, |
|
292 |
|
293 init: function() {}, |
|
294 error: function() {}, |
|
295 success: function() {}, |
|
296 added: function() {}, |
|
297 progress: function() {}, |
|
298 complete: function() {}, |
|
299 refresh: function() { |
|
300 var node, attached, container, id; |
|
301 |
|
302 if ( this.browser ) { |
|
303 node = this.browser[0]; |
|
304 |
|
305 // Check if the browser node is in the DOM. |
|
306 while ( node ) { |
|
307 if ( node === document.body ) { |
|
308 attached = true; |
|
309 break; |
|
310 } |
|
311 node = node.parentNode; |
|
312 } |
|
313 |
|
314 // If the browser node is not attached to the DOM, use a |
|
315 // temporary container to house it, as the browser button |
|
316 // shims require the button to exist in the DOM at all times. |
|
317 if ( ! attached ) { |
|
318 id = 'wp-uploader-browser-' + this.uploader.id; |
|
319 |
|
320 container = $( '#' + id ); |
|
321 if ( ! container.length ) { |
|
322 container = $('<div class="wp-uploader-browser" />').css({ |
|
323 position: 'fixed', |
|
324 top: '-1000px', |
|
325 left: '-1000px', |
|
326 height: 0, |
|
327 width: 0 |
|
328 }).attr( 'id', 'wp-uploader-browser-' + this.uploader.id ).appendTo('body'); |
|
329 } |
|
330 |
|
331 container.append( this.browser ); |
|
332 } |
|
333 } |
|
334 |
|
335 this.uploader.refresh(); |
|
336 } |
|
337 }); |
|
338 |
|
339 Uploader.queue = new wp.media.model.Attachments( [], { query: false }); |
|
340 Uploader.errors = new Backbone.Collection(); |
|
341 |
|
342 exports.Uploader = Uploader; |
|
343 })( wp, jQuery ); |