Initial commit

This commit is contained in:
ayakael 2025-03-31 12:02:18 -04:00
commit 57a2089dd9
No known key found for this signature in database
GPG key ID: 70904985A46AF9AF
1541 changed files with 595392 additions and 0 deletions

View file

@ -0,0 +1,657 @@
/* global plupload, pluploadL10n, ajaxurl, post_id, wpUploaderInit, deleteUserSetting, setUserSetting, getUserSetting, shortform */
var topWin = window.dialogArguments || opener || parent || top, uploader, uploader_init;
// Progress and success handlers for media multi uploads.
function fileQueued( fileObj ) {
// Get rid of unused form.
jQuery( '.media-blank' ).remove();
var items = jQuery( '#media-items' ).children(), postid = post_id || 0;
// Collapse a single item.
if ( items.length == 1 ) {
items.removeClass( 'open' ).find( '.slidetoggle' ).slideUp( 200 );
}
// Create a progress bar containing the filename.
jQuery( '<div class="media-item">' )
.attr( 'id', 'media-item-' + fileObj.id )
.addClass( 'child-of-' + postid )
.append( '<div class="progress"><div class="percent">0%</div><div class="bar"></div></div>',
jQuery( '<div class="filename original">' ).text( ' ' + fileObj.name ) )
.appendTo( jQuery( '#media-items' ) );
// Disable submit.
jQuery( '#insert-gallery' ).prop( 'disabled', true );
}
function uploadStart() {
try {
if ( typeof topWin.tb_remove != 'undefined' )
topWin.jQuery( '#TB_overlay' ).unbind( 'click', topWin.tb_remove );
} catch( e ){}
return true;
}
function uploadProgress( up, file ) {
var item = jQuery( '#media-item-' + file.id );
jQuery( '.bar', item ).width( ( 200 * file.loaded ) / file.size );
jQuery( '.percent', item ).html( file.percent + '%' );
}
// Check to see if a large file failed to upload.
function fileUploading( up, file ) {
var hundredmb = 100 * 1024 * 1024,
max = parseInt( up.settings.max_file_size, 10 );
if ( max > hundredmb && file.size > hundredmb ) {
setTimeout( function() {
if ( file.status < 3 && file.loaded === 0 ) { // Not uploading.
wpFileError( file, pluploadL10n.big_upload_failed.replace( '%1$s', '<a class="uploader-html" href="#">' ).replace( '%2$s', '</a>' ) );
up.stop(); // Stop the whole queue.
up.removeFile( file );
up.start(); // Restart the queue.
}
}, 10000 ); // Wait for 10 seconds for the file to start uploading.
}
}
function updateMediaForm() {
var items = jQuery( '#media-items' ).children();
// Just one file, no need for collapsible part.
if ( items.length == 1 ) {
items.addClass( 'open' ).find( '.slidetoggle' ).show();
jQuery( '.insert-gallery' ).hide();
} else if ( items.length > 1 ) {
items.removeClass( 'open' );
// Only show Gallery/Playlist buttons when there are at least two files.
jQuery( '.insert-gallery' ).show();
}
// Only show Save buttons when there is at least one file.
if ( items.not( '.media-blank' ).length > 0 )
jQuery( '.savebutton' ).show();
else
jQuery( '.savebutton' ).hide();
}
function uploadSuccess( fileObj, serverData ) {
var item = jQuery( '#media-item-' + fileObj.id );
// On success serverData should be numeric,
// fix bug in html4 runtime returning the serverData wrapped in a <pre> tag.
if ( typeof serverData === 'string' ) {
serverData = serverData.replace( /^<pre>(\d+)<\/pre>$/, '$1' );
// If async-upload returned an error message, place it in the media item div and return.
if ( /media-upload-error|error-div/.test( serverData ) ) {
item.html( serverData );
return;
}
}
item.find( '.percent' ).html( pluploadL10n.crunching );
prepareMediaItem( fileObj, serverData );
updateMediaForm();
// Increment the counter.
if ( post_id && item.hasClass( 'child-of-' + post_id ) ) {
jQuery( '#attachments-count' ).text( 1 * jQuery( '#attachments-count' ).text() + 1 );
}
}
function setResize( arg ) {
if ( arg ) {
if ( window.resize_width && window.resize_height ) {
uploader.settings.resize = {
enabled: true,
width: window.resize_width,
height: window.resize_height,
quality: 100
};
} else {
uploader.settings.multipart_params.image_resize = true;
}
} else {
delete( uploader.settings.multipart_params.image_resize );
}
}
function prepareMediaItem( fileObj, serverData ) {
var f = ( typeof shortform == 'undefined' ) ? 1 : 2, item = jQuery( '#media-item-' + fileObj.id );
if ( f == 2 && shortform > 2 )
f = shortform;
try {
if ( typeof topWin.tb_remove != 'undefined' )
topWin.jQuery( '#TB_overlay' ).click( topWin.tb_remove );
} catch( e ){}
if ( isNaN( serverData ) || !serverData ) {
// Old style: Append the HTML returned by the server -- thumbnail and form inputs.
item.append( serverData );
prepareMediaItemInit( fileObj );
} else {
// New style: server data is just the attachment ID, fetch the thumbnail and form html from the server.
item.load( 'async-upload.php', {attachment_id:serverData, fetch:f}, function(){prepareMediaItemInit( fileObj );updateMediaForm();});
}
}
function prepareMediaItemInit( fileObj ) {
var item = jQuery( '#media-item-' + fileObj.id );
// Clone the thumbnail as a "pinkynail" -- a tiny image to the left of the filename.
jQuery( '.thumbnail', item ).clone().attr( 'class', 'pinkynail toggle' ).prependTo( item );
// Replace the original filename with the new (unique) one assigned during upload.
jQuery( '.filename.original', item ).replaceWith( jQuery( '.filename.new', item ) );
// Bind Ajax to the new Delete button.
jQuery( 'a.delete', item ).click( function(){
// Tell the server to delete it. TODO: Handle exceptions.
jQuery.ajax({
url: ajaxurl,
type: 'post',
success: deleteSuccess,
error: deleteError,
id: fileObj.id,
data: {
id : this.id.replace(/[^0-9]/g, '' ),
action : 'trash-post',
_ajax_nonce : this.href.replace(/^.*wpnonce=/,'' )
}
});
return false;
});
// Bind Ajax to the new Undo button.
jQuery( 'a.undo', item ).click( function(){
// Tell the server to untrash it. TODO: Handle exceptions.
jQuery.ajax({
url: ajaxurl,
type: 'post',
id: fileObj.id,
data: {
id : this.id.replace(/[^0-9]/g,'' ),
action: 'untrash-post',
_ajax_nonce: this.href.replace(/^.*wpnonce=/,'' )
},
success: function( ){
var type,
item = jQuery( '#media-item-' + fileObj.id );
if ( type = jQuery( '#type-of-' + fileObj.id ).val() )
jQuery( '#' + type + '-counter' ).text( jQuery( '#' + type + '-counter' ).text()-0+1 );
if ( post_id && item.hasClass( 'child-of-'+post_id ) )
jQuery( '#attachments-count' ).text( jQuery( '#attachments-count' ).text()-0+1 );
jQuery( '.filename .trashnotice', item ).remove();
jQuery( '.filename .title', item ).css( 'font-weight','normal' );
jQuery( 'a.undo', item ).addClass( 'hidden' );
jQuery( '.menu_order_input', item ).show();
item.css( {backgroundColor:'#ceb'} ).animate( {backgroundColor: '#fff'}, { queue: false, duration: 500, complete: function(){ jQuery( this ).css({backgroundColor:''}); } }).removeClass( 'undo' );
}
});
return false;
});
// Open this item if it says to start open (e.g. to display an error).
jQuery( '#media-item-' + fileObj.id + '.startopen' ).removeClass( 'startopen' ).addClass( 'open' ).find( 'slidetoggle' ).fadeIn();
}
// Generic error message.
function wpQueueError( message ) {
jQuery( '#media-upload-error' ).show().html( '<div class="error"><p>' + message + '</p></div>' );
}
// File-specific error messages.
function wpFileError( fileObj, message ) {
itemAjaxError( fileObj.id, message );
}
function itemAjaxError( id, message ) {
var item = jQuery( '#media-item-' + id ), filename = item.find( '.filename' ).text(), last_err = item.data( 'last-err' );
if ( last_err == id ) // Prevent firing an error for the same file twice.
return;
item.html( '<div class="error-div">' +
'<a class="dismiss" href="#">' + pluploadL10n.dismiss + '</a>' +
'<strong>' + pluploadL10n.error_uploading.replace( '%s', jQuery.trim( filename )) + '</strong> ' +
message +
'</div>' ).data( 'last-err', id );
}
function deleteSuccess( data ) {
var type, id, item;
if ( data == '-1' )
return itemAjaxError( this.id, 'You do not have permission. Has your session expired?' );
if ( data == '0' )
return itemAjaxError( this.id, 'Could not be deleted. Has it been deleted already?' );
id = this.id;
item = jQuery( '#media-item-' + id );
// Decrement the counters.
if ( type = jQuery( '#type-of-' + id ).val() )
jQuery( '#' + type + '-counter' ).text( jQuery( '#' + type + '-counter' ).text() - 1 );
if ( post_id && item.hasClass( 'child-of-'+post_id ) )
jQuery( '#attachments-count' ).text( jQuery( '#attachments-count' ).text() - 1 );
if ( jQuery( 'form.type-form #media-items' ).children().length == 1 && jQuery( '.hidden', '#media-items' ).length > 0 ) {
jQuery( '.toggle' ).toggle();
jQuery( '.slidetoggle' ).slideUp( 200 ).siblings().removeClass( 'hidden' );
}
// Vanish it.
jQuery( '.toggle', item ).toggle();
jQuery( '.slidetoggle', item ).slideUp( 200 ).siblings().removeClass( 'hidden' );
item.css( {backgroundColor:'#faa'} ).animate( {backgroundColor:'#f4f4f4'}, {queue:false, duration:500} ).addClass( 'undo' );
jQuery( '.filename:empty', item ).remove();
jQuery( '.filename .title', item ).css( 'font-weight','bold' );
jQuery( '.filename', item ).append( '<span class="trashnotice"> ' + pluploadL10n.deleted + ' </span>' ).siblings( 'a.toggle' ).hide();
jQuery( '.filename', item ).append( jQuery( 'a.undo', item ).removeClass( 'hidden' ) );
jQuery( '.menu_order_input', item ).hide();
return;
}
function deleteError() {
}
function uploadComplete() {
jQuery( '#insert-gallery' ).prop( 'disabled', false );
}
function switchUploader( s ) {
if ( s ) {
deleteUserSetting( 'uploader' );
jQuery( '.media-upload-form' ).removeClass( 'html-uploader' );
if ( typeof( uploader ) == 'object' )
uploader.refresh();
} else {
setUserSetting( 'uploader', '1' ); // 1 == html uploader.
jQuery( '.media-upload-form' ).addClass( 'html-uploader' );
}
}
function uploadError( fileObj, errorCode, message, up ) {
var hundredmb = 100 * 1024 * 1024, max;
switch ( errorCode ) {
case plupload.FAILED:
wpFileError( fileObj, pluploadL10n.upload_failed );
break;
case plupload.FILE_EXTENSION_ERROR:
wpFileExtensionError( up, fileObj, pluploadL10n.invalid_filetype );
break;
case plupload.FILE_SIZE_ERROR:
uploadSizeError( up, fileObj );
break;
case plupload.IMAGE_FORMAT_ERROR:
wpFileError( fileObj, pluploadL10n.not_an_image );
break;
case plupload.IMAGE_MEMORY_ERROR:
wpFileError( fileObj, pluploadL10n.image_memory_exceeded );
break;
case plupload.IMAGE_DIMENSIONS_ERROR:
wpFileError( fileObj, pluploadL10n.image_dimensions_exceeded );
break;
case plupload.GENERIC_ERROR:
wpQueueError( pluploadL10n.upload_failed );
break;
case plupload.IO_ERROR:
max = parseInt( up.settings.filters.max_file_size, 10 );
if ( max > hundredmb && fileObj.size > hundredmb ) {
wpFileError( fileObj, pluploadL10n.big_upload_failed.replace( '%1$s', '<a class="uploader-html" href="#">' ).replace( '%2$s', '</a>' ) );
} else {
wpQueueError( pluploadL10n.io_error );
}
break;
case plupload.HTTP_ERROR:
wpQueueError( pluploadL10n.http_error );
break;
case plupload.INIT_ERROR:
jQuery( '.media-upload-form' ).addClass( 'html-uploader' );
break;
case plupload.SECURITY_ERROR:
wpQueueError( pluploadL10n.security_error );
break;
/* case plupload.UPLOAD_ERROR.UPLOAD_STOPPED:
case plupload.UPLOAD_ERROR.FILE_CANCELLED:
jQuery( '#media-item-' + fileObj.id ).remove();
break;*/
default:
wpFileError( fileObj, pluploadL10n.default_error );
}
}
function uploadSizeError( up, file ) {
var message, errorDiv;
message = pluploadL10n.file_exceeds_size_limit.replace( '%s', file.name );
// Construct the error div.
errorDiv = jQuery( '<div />' )
.attr( {
'id': 'media-item-' + file.id,
'class': 'media-item error'
} )
.append(
jQuery( '<p />' )
.text( message )
);
// Append the error.
jQuery( '#media-items' ).append( errorDiv );
up.removeFile( file );
}
function wpFileExtensionError( up, file, message ) {
jQuery( '#media-items' ).append( '<div id="media-item-' + file.id + '" class="media-item error"><p>' + message + '</p></div>' );
up.removeFile( file );
}
/**
* Copies the attachment URL to the clipboard.
*
* @since 5.8.0
*
* @param {MouseEvent} event A click event.
*
* @return {void}
*/
function copyAttachmentUploadURLClipboard() {
var clipboard = new ClipboardJS( '.copy-attachment-url' ),
successTimeout;
clipboard.on( 'success', function( event ) {
var triggerElement = jQuery( event.trigger ),
successElement = jQuery( '.success', triggerElement.closest( '.copy-to-clipboard-container' ) );
// Clear the selection and move focus back to the trigger.
event.clearSelection();
// Handle ClipboardJS focus bug, see https://github.com/zenorocha/clipboard.js/issues/680
triggerElement.trigger( 'focus' );
// Show success visual feedback.
clearTimeout( successTimeout );
successElement.removeClass( 'hidden' );
// Hide success visual feedback after 3 seconds since last success.
successTimeout = setTimeout( function() {
successElement.addClass( 'hidden' );
}, 3000 );
// Handle success audible feedback.
wp.a11y.speak( pluploadL10n.file_url_copied );
} );
}
jQuery( document ).ready( function( $ ) {
copyAttachmentUploadURLClipboard();
var tryAgainCount = {};
var tryAgain;
$( '.media-upload-form' ).bind( 'click.uploader', function( e ) {
var target = $( e.target ), tr, c;
if ( target.is( 'input[type="radio"]' ) ) { // Remember the last used image size and alignment.
tr = target.closest( 'tr' );
if ( tr.hasClass( 'align' ) )
setUserSetting( 'align', target.val() );
else if ( tr.hasClass( 'image-size' ) )
setUserSetting( 'imgsize', target.val() );
} else if ( target.is( 'button.button' ) ) { // Remember the last used image link url.
c = e.target.className || '';
c = c.match( /url([^ '"]+)/ );
if ( c && c[1] ) {
setUserSetting( 'urlbutton', c[1] );
target.siblings( '.urlfield' ).val( target.data( 'link-url' ) );
}
} else if ( target.is( 'a.dismiss' ) ) {
target.parents( '.media-item' ).fadeOut( 200, function() {
$( this ).remove();
} );
} else if ( target.is( '.upload-flash-bypass a' ) || target.is( 'a.uploader-html' ) ) { // Switch uploader to html4.
$( '#media-items, p.submit, span.big-file-warning' ).css( 'display', 'none' );
switchUploader( 0 );
e.preventDefault();
} else if ( target.is( '.upload-html-bypass a' ) ) { // Switch uploader to multi-file.
$( '#media-items, p.submit, span.big-file-warning' ).css( 'display', '' );
switchUploader( 1 );
e.preventDefault();
} else if ( target.is( 'a.describe-toggle-on' ) ) { // Show.
target.parent().addClass( 'open' );
target.siblings( '.slidetoggle' ).fadeIn( 250, function() {
var S = $( window ).scrollTop(),
H = $( window ).height(),
top = $( this ).offset().top,
h = $( this ).height(),
b,
B;
if ( H && top && h ) {
b = top + h;
B = S + H;
if ( b > B ) {
if ( b - B < top - S )
window.scrollBy( 0, ( b - B ) + 10 );
else
window.scrollBy( 0, top - S - 40 );
}
}
} );
e.preventDefault();
} else if ( target.is( 'a.describe-toggle-off' ) ) { // Hide.
target.siblings( '.slidetoggle' ).fadeOut( 250, function() {
target.parent().removeClass( 'open' );
} );
e.preventDefault();
}
});
// Attempt to create image sub-sizes when an image was uploaded successfully
// but the server responded with an HTTP 5xx error.
tryAgain = function( up, error ) {
var file = error.file;
var times;
var id;
if ( ! error || ! error.responseHeaders ) {
wpQueueError( pluploadL10n.http_error_image );
return;
}
id = error.responseHeaders.match( /x-wp-upload-attachment-id:\s*(\d+)/i );
if ( id && id[1] ) {
id = id[1];
} else {
wpQueueError( pluploadL10n.http_error_image );
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: wpUploaderInit.multipart_params._wpnonce,
attachment_id: id,
_wp_upload_failed_cleanup: true,
}
});
if ( error.message && ( error.status < 500 || error.status >= 600 ) ) {
wpQueueError( error.message );
} else {
wpQueueError( pluploadL10n.http_error_image );
}
return;
}
if ( ! times ) {
tryAgainCount[ file.id ] = 1;
} else {
tryAgainCount[ file.id ] = ++times;
}
// Try to create the missing image sizes.
$.ajax({
type: 'post',
url: ajaxurl,
dataType: 'json',
data: {
action: 'media-create-image-subsizes',
_wpnonce: wpUploaderInit.multipart_params._wpnonce,
attachment_id: id,
_legacy_support: 'true',
}
}).done( function( response ) {
var message;
if ( response.success ) {
uploadSuccess( file, response.data.id );
} else {
if ( response.data && response.data.message ) {
message = response.data.message;
}
wpQueueError( message || pluploadL10n.http_error_image );
}
}).fail( function( jqXHR ) {
// If another HTTP 5xx error, try try again...
if ( jqXHR.status >= 500 && jqXHR.status < 600 ) {
tryAgain( up, error );
return;
}
wpQueueError( pluploadL10n.http_error_image );
});
}
// Init and set the uploader.
uploader_init = function() {
uploader = new plupload.Uploader( wpUploaderInit );
$( '#image_resize' ).bind( 'change', function() {
var arg = $( this ).prop( 'checked' );
setResize( arg );
if ( arg )
setUserSetting( 'upload_resize', '1' );
else
deleteUserSetting( 'upload_resize' );
});
uploader.bind( 'Init', function( up ) {
var uploaddiv = $( '#plupload-upload-ui' );
setResize( getUserSetting( 'upload_resize', false ) );
if ( up.features.dragdrop && ! $( document.body ).hasClass( 'mobile' ) ) {
uploaddiv.addClass( 'drag-drop' );
$( '#drag-drop-area' ).on( 'dragover.wp-uploader', function() { // dragenter doesn't fire right :(
uploaddiv.addClass( 'drag-over' );
}).on( 'dragleave.wp-uploader, drop.wp-uploader', function() {
uploaddiv.removeClass( 'drag-over' );
});
} else {
uploaddiv.removeClass( 'drag-drop' );
$( '#drag-drop-area' ).off( '.wp-uploader' );
}
if ( up.runtime === 'html4' ) {
$( '.upload-flash-bypass' ).hide();
}
});
uploader.bind( 'postinit', function( up ) {
up.refresh();
});
uploader.init();
uploader.bind( 'FilesAdded', function( up, files ) {
$( '#media-upload-error' ).empty();
uploadStart();
plupload.each( files, function( file ) {
if ( file.type === 'image/heic' && up.settings.heic_upload_error ) {
// Show error but do not block uploading.
wpQueueError( pluploadL10n.unsupported_image );
} else if ( file.type === 'image/webp' && up.settings.webp_upload_error ) {
// Disallow uploading of WebP images if the server cannot edit them.
wpQueueError( pluploadL10n.noneditable_image );
up.removeFile( file );
return;
}
fileQueued( file );
});
up.refresh();
up.start();
});
uploader.bind( 'UploadFile', function( up, file ) {
fileUploading( up, file );
});
uploader.bind( 'UploadProgress', function( up, file ) {
uploadProgress( up, file );
});
uploader.bind( 'Error', function( up, error ) {
var isImage = error.file && error.file.type && error.file.type.indexOf( 'image/' ) === 0;
var status = error && error.status;
// If the file is an image and the error is HTTP 5xx try to create sub-sizes again.
if ( isImage && status >= 500 && status < 600 ) {
tryAgain( up, error );
return;
}
uploadError( error.file, error.code, error.message, up );
up.refresh();
});
uploader.bind( 'FileUploaded', function( up, file, response ) {
uploadSuccess( file, response.response );
});
uploader.bind( 'UploadComplete', function() {
uploadComplete();
});
};
if ( typeof( wpUploaderInit ) == 'object' ) {
uploader_init();
}
});

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

1
wp-includes/js/plupload/moxie.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,576 @@
/* global pluploadL10n, plupload, _wpPluploadSettings */
/**
* @namespace wp
*/
window.wp = window.wp || {};
( function( exports, $ ) {
var Uploader;
if ( typeof _wpPluploadSettings === 'undefined' ) {
return;
}
/**
* A WordPress uploader.
*
* The Plupload library provides cross-browser uploader UI integration.
* This object bridges the Plupload API to integrate uploads into the
* WordPress back end and the WordPress media experience.
*
* @class
* @memberOf wp
* @alias wp.Uploader
*
* @param {object} options The options passed to the new plupload instance.
* @param {object} options.container The id of uploader container.
* @param {object} options.browser The id of button to trigger the file select.
* @param {object} options.dropzone The id of file drop target.
* @param {object} options.plupload An object of parameters to pass to the plupload instance.
* @param {object} options.params An object of parameters to pass to $_POST when uploading the file.
* Extends this.plupload.multipart_params under the hood.
*/
Uploader = function( options ) {
var self = this,
isIE, // Not used, back-compat.
elements = {
container: 'container',
browser: 'browse_button',
dropzone: 'drop_element'
},
tryAgainCount = {},
tryAgain,
key,
error,
fileUploaded;
this.supports = {
upload: Uploader.browser.supported
};
this.supported = this.supports.upload;
if ( ! this.supported ) {
return;
}
// Arguments to send to pluplad.Uploader().
// Use deep extend to ensure that multipart_params and other objects are cloned.
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( true, this, options );
// Proxy all methods so this always refers to the current instance.
for ( key in this ) {
if ( typeof this[ key ] === 'function' ) {
this[ key ] = $.proxy( this[ key ], this );
}
}
// Ensure all elements are jQuery elements and have id attributes,
// then set the proper plupload arguments to the ids.
for ( key in elements ) {
if ( ! this[ key ] ) {
continue;
}
this[ key ] = $( this[ key ] ).first();
if ( ! this[ key ].length ) {
delete this[ key ];
continue;
}
if ( ! this[ key ].prop('id') ) {
this[ key ].prop( 'id', '__wp-uploader-id-' + Uploader.uuid++ );
}
this.plupload[ elements[ key ] ] = this[ key ].prop('id');
}
// If the uploader has neither a browse button nor a dropzone, bail.
if ( ! ( this.browser && this.browser.length ) && ! ( this.dropzone && this.dropzone.length ) ) {
return;
}
// Initialize the plupload instance.
this.uploader = new plupload.Uploader( this.plupload );
delete this.plupload;
// Set default params and remove this.params alias.
this.param( this.params || {} );
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 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, 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();
}
Uploader.errors.unshift({
message: message || pluploadL10n.default_error,
data: data,
file: file
});
self.error( message, data, file );
};
/**
* 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.
*/
this.uploader.bind( 'init', function( uploader ) {
var timer, active, dragdrop,
dropzone = self.dropzone;
dragdrop = self.supports.dragdrop = uploader.features.dragdrop && ! Uploader.browser.mobile;
// Generate drag/drop helper classes.
if ( ! dropzone ) {
return;
}
dropzone.toggleClass( 'supports-drag-drop', !! dragdrop );
if ( ! dragdrop ) {
return dropzone.unbind('.wp-uploader');
}
// 'dragenter' doesn't fire correctly, simulate it with a limited 'dragover'.
dropzone.on( 'dragover.wp-uploader', function() {
if ( timer ) {
clearTimeout( timer );
}
if ( active ) {
return;
}
dropzone.trigger('dropzone:enter').addClass('drag-over');
active = true;
});
dropzone.on('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
*/
timer = setTimeout( function() {
active = false;
dropzone.trigger('dropzone:leave').removeClass('drag-over');
}, 0 );
});
self.ready = true;
$(self).trigger( 'uploader:ready' );
});
this.uploader.bind( 'postinit', function( up ) {
up.refresh();
self.init();
});
this.uploader.init();
if ( this.browser ) {
this.browser.on( 'mouseenter', this.refresh );
} else {
this.uploader.disableBrowse( true );
}
$( 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} 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 ) {
var attributes, image;
// Ignore failed uploads.
if ( plupload.FAILED === file.status ) {
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
});
} else if ( file.type === 'image/webp' && up.settings.webp_upload_error ) {
// Disallow uploading of WebP images if the server cannot edit them.
error( pluploadL10n.noneditable_image, {}, file, 'no-retry' );
up.removeFile( file );
return;
}
// Generate attributes for a new `Attachment` model.
attributes = _.extend({
file: file,
uploading: true,
date: new Date(),
filename: file.name,
menuOrder: 0,
uploadedTo: wp.media.model.settings.post.id
}, _.pick( file, 'loaded', 'size', 'percent' ) );
// Handle early mime type scanning for images.
image = /(?:jpe?g|png|gif)$/i.exec( file.name );
// For images set the model's type and subtype attributes.
if ( image ) {
attributes.type = 'image';
// `jpeg`, `png` and `gif` are valid subtypes.
// `jpg` is not, so map it to `jpeg`.
attributes.subtype = ( 'jpg' === image[0] ) ? 'jpeg' : image[0];
}
// Create a model for the attachment, and add it to the Upload queue collection
// so listeners to the upload queue can track and display upload progress.
file.attachment = wp.media.model.Attachment.create( attributes );
Uploader.queue.add( file.attachment );
self.added( file.attachment );
});
up.refresh();
up.start();
});
this.uploader.bind( 'UploadProgress', function( up, file ) {
file.attachment.set( _.pick( file, 'loaded', 'percent' ) );
self.progress( file.attachment );
});
/**
* 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.
* @return {mixed}
*/
this.uploader.bind( 'FileUploaded', function( up, file, response ) {
try {
response = JSON.parse( response.response );
} catch ( e ) {
return error( pluploadL10n.default_error, e, file );
}
if ( ! _.isObject( response ) || _.isUndefined( response.success ) ) {
return error( pluploadL10n.default_error, null, file );
} else if ( ! response.success ) {
return error( response.data && response.data.message, response.data, file );
}
// 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} 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,
key;
// Check for plupload errors.
for ( key in Uploader.errorMap ) {
if ( pluploadError.code === plupload[ key ] ) {
message = Uploader.errorMap[ key ];
if ( typeof message === 'function' ) {
message = message( pluploadError.file, pluploadError );
}
break;
}
}
error( message, pluploadError, pluploadError.file );
up.refresh();
});
};
// Adds the 'defaults' and 'browser' properties.
$.extend( Uploader, _wpPluploadSettings );
Uploader.uuid = 0;
// Map Plupload error codes to user friendly error messages.
Uploader.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,
'SECURITY_ERROR': pluploadL10n.security_error,
'FILE_SIZE_ERROR': function( file ) {
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 */{
/**
* Acts as a shortcut to extending the uploader's multipart_params object.
*
* param( key )
* Returns the value of the key.
*
* param( key, value )
* Sets the value of a key.
*
* param( map )
* Sets values for a map of data.
*/
param: function( key, value ) {
if ( arguments.length === 1 && typeof key === 'string' ) {
return this.uploader.settings.multipart_params[ key ];
}
if ( arguments.length > 1 ) {
this.uploader.settings.multipart_params[ key ] = value;
} else {
$.extend( this.uploader.settings.multipart_params, key );
}
},
/**
* Make a few internal event callbacks available on the wp.Uploader object
* to change the Uploader internals if absolutely necessary.
*/
init: function() {},
error: function() {},
success: function() {},
added: function() {},
progress: function() {},
complete: function() {},
refresh: function() {
var node, attached, container, id;
if ( this.browser ) {
node = this.browser[0];
// Check if the browser node is in the DOM.
while ( node ) {
if ( node === document.body ) {
attached = true;
break;
}
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 ( ! attached ) {
id = 'wp-uploader-browser-' + this.uploader.id;
container = $( '#' + id );
if ( ! container.length ) {
container = $('<div class="wp-uploader-browser" />').css({
position: 'fixed',
top: '-1000px',
left: '-1000px',
height: 0,
width: 0
}).attr( 'id', 'wp-uploader-browser-' + this.uploader.id ).appendTo('body');
}
container.append( this.browser );
}
}
this.uploader.refresh();
}
});
// Create a collection of attachments in the upload queue,
// so that other modules can track and display upload progress.
Uploader.queue = new wp.media.model.Attachments( [], { query: false });
// Create a collection to collect errors incurred while attempting upload.
Uploader.errors = new Backbone.Collection();
exports.Uploader = Uploader;
})( wp, jQuery );

File diff suppressed because one or more lines are too long