--- a/wp/wp-includes/js/plupload/wp-plupload.js Tue Oct 22 16:11:46 2019 +0200
+++ b/wp/wp-includes/js/plupload/wp-plupload.js Tue Dec 15 13:49:49 2020 +0100
@@ -33,13 +33,17 @@
*/
Uploader = function( options ) {
var self = this,
- isIE = navigator.userAgent.indexOf('Trident/') != -1 || navigator.userAgent.indexOf('MSIE ') != -1,
+ isIE, // Not used, back-compat.
elements = {
container: 'container',
browser: 'browse_button',
dropzone: 'drop_element'
},
- key, error;
+ tryAgainCount = {},
+ tryAgain,
+ key,
+ error,
+ fileUploaded;
this.supports = {
upload: Uploader.browser.supported
@@ -56,10 +60,12 @@
this.plupload = $.extend( true, { multipart_params: {} }, Uploader.defaults );
this.container = document.body; // Set default container.
- // Extend the instance with options.
- //
- // Use deep extend to allow options.plupload to override individual
- // default plupload keys.
+ /*
+ * Extend the instance with options.
+ *
+ * Use deep extend to allow options.plupload to override individual
+ * default plupload keys.
+ */
$.extend( true, this, options );
// Proxy all methods so this always refers to the current instance.
@@ -95,14 +101,6 @@
return;
}
- // Make sure flash sends cookies (seems in IE it does without switching to urlstream mode)
- if ( ! isIE && 'flash' === plupload.predictRuntime( this.plupload ) &&
- ( ! this.plupload.required_features || ! this.plupload.required_features.hasOwnProperty( 'send_binary_string' ) ) ) {
-
- this.plupload.required_features = this.plupload.required_features || {};
- this.plupload.required_features.send_binary_string = true;
- }
-
// Initialize the plupload instance.
this.uploader = new plupload.Uploader( this.plupload );
delete this.plupload;
@@ -112,16 +110,114 @@
delete this.params;
/**
+ * Attempt to create image sub-sizes when an image was uploaded successfully
+ * but the server responded with HTTP 5xx error.
+ *
+ * @since 5.3.0
+ *
+ * @param {string} message Error message.
+ * @param {object} data Error data from Plupload.
+ * @param {plupload.File} file File that was uploaded.
+ */
+ tryAgain = function( message, data, file ) {
+ var times, id;
+
+ if ( ! data || ! data.responseHeaders ) {
+ error( pluploadL10n.http_error_image, data, file, 'no-retry' );
+ return;
+ }
+
+ id = data.responseHeaders.match( /x-wp-upload-attachment-id:\s*(\d+)/i );
+
+ if ( id && id[1] ) {
+ id = id[1];
+ } else {
+ error( pluploadL10n.http_error_image, data, file, 'no-retry' );
+ return;
+ }
+
+ times = tryAgainCount[ file.id ];
+
+ if ( times && times > 4 ) {
+ /*
+ * The file may have been uploaded and attachment post created,
+ * but post-processing and resizing failed...
+ * Do a cleanup then tell the user to scale down the image and upload it again.
+ */
+ $.ajax({
+ type: 'post',
+ url: ajaxurl,
+ dataType: 'json',
+ data: {
+ action: 'media-create-image-subsizes',
+ _wpnonce: _wpPluploadSettings.defaults.multipart_params._wpnonce,
+ attachment_id: id,
+ _wp_upload_failed_cleanup: true,
+ }
+ });
+
+ error( message, data, file, 'no-retry' );
+ return;
+ }
+
+ if ( ! times ) {
+ tryAgainCount[ file.id ] = 1;
+ } else {
+ tryAgainCount[ file.id ] = ++times;
+ }
+
+ // Another request to try to create the missing image sub-sizes.
+ $.ajax({
+ type: 'post',
+ url: ajaxurl,
+ dataType: 'json',
+ data: {
+ action: 'media-create-image-subsizes',
+ _wpnonce: _wpPluploadSettings.defaults.multipart_params._wpnonce,
+ attachment_id: id,
+ }
+ }).done( function( response ) {
+ if ( response.success ) {
+ fileUploaded( self.uploader, file, response );
+ } else {
+ if ( response.data && response.data.message ) {
+ message = response.data.message;
+ }
+
+ error( message, data, file, 'no-retry' );
+ }
+ }).fail( function( jqXHR ) {
+ // If another HTTP 5xx error, try try again...
+ if ( jqXHR.status >= 500 && jqXHR.status < 600 ) {
+ tryAgain( message, data, file );
+ return;
+ }
+
+ error( message, data, file, 'no-retry' );
+ });
+ }
+
+ /**
* Custom error callback.
*
* Add a new error to the errors collection, so other modules can track
* and display errors. @see wp.Uploader.errors.
*
- * @param {string} message
- * @param {object} data
- * @param {plupload.File} file File that was uploaded.
+ * @param {string} message Error message.
+ * @param {object} data Error data from Plupload.
+ * @param {plupload.File} file File that was uploaded.
+ * @param {string} retry Whether to try again to create image sub-sizes. Passing 'no-retry' will prevent it.
*/
- error = function( message, data, file ) {
+ error = function( message, data, file, retry ) {
+ var isImage = file.type && file.type.indexOf( 'image/' ) === 0,
+ status = data && data.status;
+
+ // If the file is an image and the error is HTTP 5xx try to create sub-sizes again.
+ if ( retry !== 'no-retry' && isImage && status >= 500 && status < 600 ) {
+ tryAgain( message, data, file );
+ return;
+ }
+
if ( file.attachment ) {
file.attachment.destroy();
}
@@ -136,6 +232,36 @@
};
/**
+ * After a file is successfully uploaded, update its model.
+ *
+ * @param {plupload.Uploader} up Uploader instance.
+ * @param {plupload.File} file File that was uploaded.
+ * @param {Object} response Object with response properties.
+ */
+ fileUploaded = function( up, file, response ) {
+ var complete;
+
+ // Remove the "uploading" UI elements.
+ _.each( ['file','loaded','size','percent'], function( key ) {
+ file.attachment.unset( key );
+ } );
+
+ file.attachment.set( _.extend( response.data, { uploading: false } ) );
+
+ wp.media.model.Attachment.get( response.data.id, file.attachment );
+
+ complete = Uploader.queue.all( function( attachment ) {
+ return ! attachment.get( 'uploading' );
+ });
+
+ if ( complete ) {
+ Uploader.queue.reset();
+ }
+
+ self.success( file.attachment );
+ }
+
+ /**
* After the Uploader has been initialized, initialize some behaviors for the dropzone.
*
* @param {plupload.Uploader} uploader Uploader instance.
@@ -172,11 +298,13 @@
});
dropzone.bind('dragleave.wp-uploader, drop.wp-uploader', function() {
- // Using an instant timer prevents the drag-over class from
- // being quickly removed and re-added when elements inside the
- // dropzone are repositioned.
- //
- // @see https://core.trac.wordpress.org/ticket/21705
+ /*
+ * Using an instant timer prevents the drag-over class
+ * from being quickly removed and re-added when elements
+ * inside the dropzone are repositioned.
+ *
+ * @see https://core.trac.wordpress.org/ticket/21705
+ */
timer = setTimeout( function() {
active = false;
dropzone.trigger('dropzone:leave').removeClass('drag-over');
@@ -198,15 +326,21 @@
this.browser.on( 'mouseenter', this.refresh );
} else {
this.uploader.disableBrowse( true );
- // If HTML5 mode, hide the auto-created file container.
- $('#' + this.uploader.id + '_html5_container').hide();
}
+ $( self ).on( 'uploader:ready', function() {
+ $( '.moxie-shim-html5 input[type="file"]' )
+ .attr( {
+ tabIndex: '-1',
+ 'aria-hidden': 'true'
+ } );
+ } );
+
/**
* After files were filtered and added to the queue, create a model for each.
*
- * @param {plupload.Uploader} uploader Uploader instance.
- * @param {Array} files Array of file objects that were added to queue by the user.
+ * @param {plupload.Uploader} up Uploader instance.
+ * @param {Array} files Array of file objects that were added to queue by the user.
*/
this.uploader.bind( 'FilesAdded', function( up, files ) {
_.each( files, function( file ) {
@@ -217,6 +351,15 @@
return;
}
+ if ( file.type === 'image/heic' && up.settings.heic_upload_error ) {
+ // Show error but do not block uploading.
+ Uploader.errors.unshift({
+ message: pluploadL10n.unsupported_image,
+ data: {},
+ file: file
+ });
+ }
+
// Generate attributes for a new `Attachment` model.
attributes = _.extend({
file: file,
@@ -259,13 +402,12 @@
/**
* After a file is successfully uploaded, update its model.
*
- * @param {plupload.Uploader} uploader Uploader instance.
+ * @param {plupload.Uploader} up Uploader instance.
* @param {plupload.File} file File that was uploaded.
* @param {Object} response Object with response properties.
* @return {mixed}
*/
this.uploader.bind( 'FileUploaded', function( up, file, response ) {
- var complete;
try {
response = JSON.parse( response.response );
@@ -273,33 +415,21 @@
return error( pluploadL10n.default_error, e, file );
}
- if ( ! _.isObject( response ) || _.isUndefined( response.success ) )
+ if ( ! _.isObject( response ) || _.isUndefined( response.success ) ) {
return error( pluploadL10n.default_error, null, file );
- else if ( ! response.success )
+ } else if ( ! response.success ) {
return error( response.data && response.data.message, response.data, file );
-
- _.each(['file','loaded','size','percent'], function( key ) {
- file.attachment.unset( key );
- });
+ }
- file.attachment.set( _.extend( response.data, { uploading: false }) );
- wp.media.model.Attachment.get( response.data.id, file.attachment );
-
- complete = Uploader.queue.all( function( attachment ) {
- return ! attachment.get('uploading');
- });
-
- if ( complete )
- Uploader.queue.reset();
-
- self.success( file.attachment );
+ // Success. Update the UI with the new attachment.
+ fileUploaded( up, file, response );
});
/**
* When plupload surfaces an error, send it to the error handler.
*
- * @param {plupload.Uploader} uploader Uploader instance.
- * @param {Object} error Contains code, message and sometimes file and other details.
+ * @param {plupload.Uploader} up Uploader instance.
+ * @param {Object} pluploadError Contains code, message and sometimes file and other details.
*/
this.uploader.bind( 'Error', function( up, pluploadError ) {
var message = pluploadL10n.default_error,
@@ -338,12 +468,19 @@
'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,
'FILE_SIZE_ERROR': function( file ) {
- return pluploadL10n.file_exceeds_size_limit.replace('%s', file.name);
- }
+ return pluploadL10n.file_exceeds_size_limit.replace( '%s', file.name );
+ },
+
+ 'HTTP_ERROR': function( file ) {
+ if ( file.type && file.type.indexOf( 'image/' ) === 0 ) {
+ return pluploadL10n.http_error_image;
+ }
+
+ return pluploadL10n.http_error;
+ },
};
$.extend( Uploader.prototype, /** @lends wp.Uploader.prototype */{
@@ -396,9 +533,11 @@
node = node.parentNode;
}
- // If the browser node is not attached to the DOM, use a
- // temporary container to house it, as the browser button
- // shims require the button to exist in the DOM at all times.
+ /*
+ * If the browser node is not attached to the DOM,
+ * use a temporary container to house it, as the browser button shims
+ * require the button to exist in the DOM at all times.
+ */
if ( ! attached ) {
id = 'wp-uploader-browser-' + this.uploader.id;