PageSourceSearch

https://www.libriincantina.it/wp-includes/js/plupload/wp-plupload.js?ver=7.1.2

js libriincantina.it collected 2026-10-02 07:14:07 UTC 16,705 bytes, 581 lines download raw bytes

1/* global pluploadL10n, plupload, _wpPluploadSettings */
2
3/**
4 * @namespace wp
5 */
6window.wp = window.wp || {};
7
8( function( exports, $ ) {
9	var Uploader;
10
11	if ( typeof _wpPluploadSettings === 'undefined' ) {
12		return;
13	}
14
15	/**
16	 * A WordPress uploader.
17	 *
18	 * The Plupload library provides cross-browser uploader UI integration.
19	 * This object bridges the Plupload API to integrate uploads into the
20	 * WordPress back end and the WordPress media experience.
21	 *
22	 * @class
23	 * @memberOf wp
24	 * @alias wp.Uploader
25	 *
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.
33	 */
34	Uploader = function( options ) {
35		var self = this,
36			isIE, // Not used, back-compat.
37			elements = {
38				container: 'container',
39				browser:   'browse_button',
40				dropzone:  'drop_element'
41			},
42			tryAgainCount = {},
43			tryAgain,
44			key,
45			error,
46			fileUploaded;
47
48		this.supports = {
49			upload: Uploader.browser.supported
50		};
51
52		this.supported = this.supports.upload;
53
54		if ( ! this.supported ) {
55			return;
56		}
57
58		// Arguments to send to pluplad.Uploader().
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
63		/*
64		 * Extend the instance with options.
65		 *
66		 * Use deep extend to allow options.plupload to override individual
67		 * default plupload keys.
68		 */
69		$.extend( true, this, options );
70
71		// Proxy all methods so this always refers to the current instance.
72		for ( key in this ) {
73			if ( typeof this[ key ] === 'function' ) {
74				this[ key ] = $.proxy( this[ key ], this );
75			}
76		}
77
78		// Ensure all elements are jQuery elements and have id attributes,
79		// then set the proper plupload arguments to the ids.
80		for ( key in elements ) {
81			if ( ! this[ key ] ) {
82				continue;
83			}
84
85			this[ key ] = $( this[ key ] ).first();
86
87			if ( ! this[ key ].length ) {
88				delete this[ key ];
89				continue;
90			}
91
92			if ( ! this[ key ].prop('id') ) {
93				this[ key ].prop( 'id', '__wp-uploader-id-' + Uploader.uuid++ );
94			}
95
96			this.plupload[ elements[ key ] ] = this[ key ].prop('id');
97		}
98
99		// If the uploader has neither a browse button nor a dropzone, bail.
100		if ( ! ( this.browser && this.browser.length ) && ! ( this.dropzone && this.dropzone.length ) ) {
101			return;
102		}
103
104		// Initialize the plupload instance.
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
112		/**
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		/**
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		 *
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.
210		 */
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
221			if ( file.attachment ) {
222				file.attachment.destroy();
223			}
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
234		/**
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		/**
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;
272
273			dragdrop = self.supports.dragdrop = uploader.features.dragdrop && ! Uploader.browser.mobile;
274
275			// Generate drag/drop helper classes.
276			if ( ! dropzone ) {
277				return;
278			}
279
280			dropzone.toggleClass( 'supports-drag-drop', !! dragdrop );
281
282			if ( ! dragdrop ) {
283				return dropzone.unbind('.wp-uploader');
284			}
285
286			// 'dragenter' doesn't fire correctly, simulate it with a limited 'dragover'.
287			dropzone.on( 'dragover.wp-uploader', function() {
288				if ( timer ) {
289					clearTimeout( timer );
290				}
291
292				if ( active ) {
293					return;
294				}
295
296				dropzone.trigger('dropzone:enter').addClass('drag-over');
297				active = true;
298			});
299
300			dropzone.on('dragleave.wp-uploader, drop.wp-uploader', function() {
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				 */
308				timer = setTimeout( function() {
309					active = false;
310					dropzone.trigger('dropzone:leave').removeClass('drag-over');
311				}, 0 );
312			});
313
314			self.ready = true;
315			$(self).trigger( 'uploader:ready' );
316		});
317
318		this.uploader.bind( 'postinit', function( up ) {
319			up.refresh();
320			self.init();
321		});
322
323		this.uploader.init();
324
325		if ( this.browser ) {
326			this.browser.on( 'mouseenter', this.refresh );
327		} else {
328			this.uploader.disableBrowse( true );
329		}
330
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
339		/**
340		 * After files were filtered and added to the queue, create a model for each.
341		 *
342		 * @param {plupload.Uploader} up    Uploader instance.
343		 * @param {Array}             files Array of file objects that were added to queue by the user.
344		 */
345		this.uploader.bind( 'FilesAdded', function( up, files ) {
346			_.each( files, function( file ) {
347				var attributes, image;
348
349				// Ignore failed uploads.
350				if ( plupload.FAILED === file.status ) {
351					return;
352				}
353
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				} else if ( file.type === 'image/webp' && up.settings.webp_upload_error ) {
362					// Disallow uploading of WebP images if the server cannot edit them.
363					error( pluploadL10n.noneditable_image, {}, file, 'no-retry' );
364					up.removeFile( file );
365					return;
366				} else if ( file.type === 'image/avif' && up.settings.avif_upload_error ) {
367					// Disallow uploading of AVIF images if the server cannot edit them.
368					error( pluploadL10n.noneditable_image, {}, file, 'no-retry' );
369					up.removeFile( file );
370					return;
371				}
372
373				// Generate attributes for a new `Attachment` model.
374				attributes = _.extend({
375					file:      file,
376					uploading: true,
377					date:      new Date(),
378					filename:  file.name,
379					menuOrder: 0,
380					uploadedTo: wp.media.model.settings.post.id
381				}, _.pick( file, 'loaded', 'size', 'percent' ) );
382
383				// Handle early mime type scanning for images.
384				image = /(?:jpe?g|png|gif)$/i.exec( file.name );
385
386				// For images set the model's type and subtype attributes.
387				if ( image ) {
388					attributes.type = 'image';
389
390					// `jpeg`, `png` and `gif` are valid subtypes.
391					// `jpg` is not, so map it to `jpeg`.
392					attributes.subtype = ( 'jpg' === image[0] ) ? 'jpeg' : image[0];
393				}
394
395				// Create a model for the attachment, and add it to the Upload queue collection
396				// so listeners to the upload queue can track and display upload progress.
397				file.attachment = wp.media.model.Attachment.create( attributes );
398				Uploader.queue.add( file.attachment );
399
400				self.added( file.attachment );
401			});
402
403			up.refresh();
404			up.start();
405		});
406
407		this.uploader.bind( 'UploadProgress', function( up, file ) {
408			file.attachment.set( _.pick( file, 'loaded', 'percent' ) );
409			self.progress( file.attachment );
410		});
411
412		/**
413		 * After a file is successfully uploaded, update its model.
414		 *
415		 * @param {plupload.Uploader} up       Uploader instance.
416		 * @param {plupload.File}     file     File that was uploaded.
417		 * @param {Object}            response Object with response properties.
418		 * @return {mixed}
419		 */
420		this.uploader.bind( 'FileUploaded', function( up, file, response ) {
421
422			try {
423				response = JSON.parse( response.response );
424			} catch ( e ) {
425				return error( pluploadL10n.default_error, e, file );
426			}
427
428			if ( ! _.isObject( response ) || _.isUndefined( response.success ) ) {
429				return error( pluploadL10n.default_error, null, file );
430			} else if ( ! response.success ) {
431				return error( response.data && response.data.message, response.data, file );
432			}
433
434			// Success. Update the UI with the new attachment.
435			fileUploaded( up, file, response );
436		});
437
438		/**
439		 * When plupload surfaces an error, send it to the error handler.
440		 *
441		 * @param {plupload.Uploader} up            Uploader instance.
442		 * @param {Object}            pluploadError Contains code, message and sometimes file and other details.
443		 */
444		this.uploader.bind( 'Error', function( up, pluploadError ) {
445			var message = pluploadL10n.default_error,
446				key;
447
448			// Check for plupload errors.
449			for ( key in Uploader.errorMap ) {
450				if ( pluploadError.code === plupload[ key ] ) {
451					message = Uploader.errorMap[ key ];
452
453					if ( typeof message === 'function' ) {
454						message = message( pluploadError.file, pluploadError );
455					}
456
457					break;
458				}
459			}
460
461			error( message, pluploadError, pluploadError.file );
462			up.refresh();
463		});
464
465	};
466
467	// Adds the 'defaults' and 'browser' properties.
468	$.extend( Uploader, _wpPluploadSettings );
469
470	Uploader.uuid = 0;
471
472	// Map Plupload error codes to user friendly error messages.
473	Uploader.errorMap = {
474		'FAILED':                 pluploadL10n.upload_failed,
475		'FILE_EXTENSION_ERROR':   pluploadL10n.invalid_filetype,
476		'IMAGE_FORMAT_ERROR':     pluploadL10n.not_an_image,
477		'IMAGE_MEMORY_ERROR':     pluploadL10n.image_memory_exceeded,
478		'IMAGE_DIMENSIONS_ERROR': pluploadL10n.image_dimensions_exceeded,
479		'GENERIC_ERROR':          pluploadL10n.upload_failed,
480		'IO_ERROR':               pluploadL10n.io_error,
481		'SECURITY_ERROR':         pluploadL10n.security_error,
482
483		'FILE_SIZE_ERROR': function( file ) {
484			return pluploadL10n.file_exceeds_size_limit.replace( '%s', file.name );
485		},
486
487		'HTTP_ERROR': function( file ) {
488			if ( file.type && file.type.indexOf( 'image/' ) === 0 ) {
489				return pluploadL10n.http_error_image;
490			}
491
492			return pluploadL10n.http_error;
493		},
494	};
495
496	$.extend( Uploader.prototype, /** @lends wp.Uploader.prototype */{
497		/**
498		 * Acts as a shortcut to extending the uploader's multipart_params object.
499		 *
500		 * param( key )
501		 *    Returns the value of the key.
502		 *
503		 * param( key, value )
504		 *    Sets the value of a key.
505		 *
506		 * param( map )
507		 *    Sets values for a map of data.
508		 */
509		param: function( key, value ) {
510			if ( arguments.length === 1 && typeof key === 'string' ) {
511				return this.uploader.settings.multipart_params[ key ];
512			}
513
514			if ( arguments.length > 1 ) {
515				this.uploader.settings.multipart_params[ key ] = value;
516			} else {
517				$.extend( this.uploader.settings.multipart_params, key );
518			}
519		},
520
521		/**
522		 * Make a few internal event callbacks available on the wp.Uploader object
523		 * to change the Uploader internals if absolutely necessary.
524		 */
525		init:     function() {},
526		error:    function() {},
527		success:  function() {},
528		added:    function() {},
529		progress: function() {},
530		complete: function() {},
531		refresh:  function() {
532			var node, attached, container, id;
533
534			if ( this.browser ) {
535				node = this.browser[0];
536
537				// Check if the browser node is in the DOM.
538				while ( node ) {
539					if ( node === document.body ) {
540						attached = true;
541						break;
542					}
543					node = node.parentNode;
544				}
545
546				/*
547				 * If the browser node is not attached to the DOM,
548				 * use a temporary container to house it, as the browser button shims
549				 * require the button to exist in the DOM at all times.
550				 */
551				if ( ! attached ) {
552					id = 'wp-uploader-browser-' + this.uploader.id;
553
554					container = $( '#' + id );
555					if ( ! container.length ) {
556						container = $('<div class="wp-uploader-browser" />').css({
557							position: 'fixed',
558							top: '-1000px',
559							left: '-1000px',
560							height: 0,
561							width: 0
562						}).attr( 'id', 'wp-uploader-browser-' + this.uploader.id ).appendTo('body');
563					}
564
565					container.append( this.browser );
566				}
567			}
568
569			this.uploader.refresh();
570		}
571	});
572
573	// Create a collection of attachments in the upload queue,
574	// so that other modules can track and display upload progress.
575	Uploader.queue = new wp.media.model.Attachments( [], { query: false });
576
577	// Create a collection to collect errors incurred while attempting upload.
578	Uploader.errors = new Backbone.Collection();
579
580	exports.Uploader = Uploader;
581})( wp, jQuery );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.