You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

657 lines
20 KiB

1 year ago
  1. /* global plupload, pluploadL10n, ajaxurl, post_id, wpUploaderInit, deleteUserSetting, setUserSetting, getUserSetting, shortform */
  2. var topWin = window.dialogArguments || opener || parent || top, uploader, uploader_init;
  3. // Progress and success handlers for media multi uploads.
  4. function fileQueued( fileObj ) {
  5. // Get rid of unused form.
  6. jQuery( '.media-blank' ).remove();
  7. var items = jQuery( '#media-items' ).children(), postid = post_id || 0;
  8. // Collapse a single item.
  9. if ( items.length == 1 ) {
  10. items.removeClass( 'open' ).find( '.slidetoggle' ).slideUp( 200 );
  11. }
  12. // Create a progress bar containing the filename.
  13. jQuery( '<div class="media-item">' )
  14. .attr( 'id', 'media-item-' + fileObj.id )
  15. .addClass( 'child-of-' + postid )
  16. .append( '<div class="progress"><div class="percent">0%</div><div class="bar"></div></div>',
  17. jQuery( '<div class="filename original">' ).text( ' ' + fileObj.name ) )
  18. .appendTo( jQuery( '#media-items' ) );
  19. // Disable submit.
  20. jQuery( '#insert-gallery' ).prop( 'disabled', true );
  21. }
  22. function uploadStart() {
  23. try {
  24. if ( typeof topWin.tb_remove != 'undefined' )
  25. topWin.jQuery( '#TB_overlay' ).unbind( 'click', topWin.tb_remove );
  26. } catch( e ){}
  27. return true;
  28. }
  29. function uploadProgress( up, file ) {
  30. var item = jQuery( '#media-item-' + file.id );
  31. jQuery( '.bar', item ).width( ( 200 * file.loaded ) / file.size );
  32. jQuery( '.percent', item ).html( file.percent + '%' );
  33. }
  34. // Check to see if a large file failed to upload.
  35. function fileUploading( up, file ) {
  36. var hundredmb = 100 * 1024 * 1024,
  37. max = parseInt( up.settings.max_file_size, 10 );
  38. if ( max > hundredmb && file.size > hundredmb ) {
  39. setTimeout( function() {
  40. if ( file.status < 3 && file.loaded === 0 ) { // Not uploading.
  41. wpFileError( file, pluploadL10n.big_upload_failed.replace( '%1$s', '<a class="uploader-html" href="#">' ).replace( '%2$s', '</a>' ) );
  42. up.stop(); // Stop the whole queue.
  43. up.removeFile( file );
  44. up.start(); // Restart the queue.
  45. }
  46. }, 10000 ); // Wait for 10 seconds for the file to start uploading.
  47. }
  48. }
  49. function updateMediaForm() {
  50. var items = jQuery( '#media-items' ).children();
  51. // Just one file, no need for collapsible part.
  52. if ( items.length == 1 ) {
  53. items.addClass( 'open' ).find( '.slidetoggle' ).show();
  54. jQuery( '.insert-gallery' ).hide();
  55. } else if ( items.length > 1 ) {
  56. items.removeClass( 'open' );
  57. // Only show Gallery/Playlist buttons when there are at least two files.
  58. jQuery( '.insert-gallery' ).show();
  59. }
  60. // Only show Save buttons when there is at least one file.
  61. if ( items.not( '.media-blank' ).length > 0 )
  62. jQuery( '.savebutton' ).show();
  63. else
  64. jQuery( '.savebutton' ).hide();
  65. }
  66. function uploadSuccess( fileObj, serverData ) {
  67. var item = jQuery( '#media-item-' + fileObj.id );
  68. // On success serverData should be numeric,
  69. // fix bug in html4 runtime returning the serverData wrapped in a <pre> tag.
  70. if ( typeof serverData === 'string' ) {
  71. serverData = serverData.replace( /^<pre>(\d+)<\/pre>$/, '$1' );
  72. // If async-upload returned an error message, place it in the media item div and return.
  73. if ( /media-upload-error|error-div/.test( serverData ) ) {
  74. item.html( serverData );
  75. return;
  76. }
  77. }
  78. item.find( '.percent' ).html( pluploadL10n.crunching );
  79. prepareMediaItem( fileObj, serverData );
  80. updateMediaForm();
  81. // Increment the counter.
  82. if ( post_id && item.hasClass( 'child-of-' + post_id ) ) {
  83. jQuery( '#attachments-count' ).text( 1 * jQuery( '#attachments-count' ).text() + 1 );
  84. }
  85. }
  86. function setResize( arg ) {
  87. if ( arg ) {
  88. if ( window.resize_width && window.resize_height ) {
  89. uploader.settings.resize = {
  90. enabled: true,
  91. width: window.resize_width,
  92. height: window.resize_height,
  93. quality: 100
  94. };
  95. } else {
  96. uploader.settings.multipart_params.image_resize = true;
  97. }
  98. } else {
  99. delete( uploader.settings.multipart_params.image_resize );
  100. }
  101. }
  102. function prepareMediaItem( fileObj, serverData ) {
  103. var f = ( typeof shortform == 'undefined' ) ? 1 : 2, item = jQuery( '#media-item-' + fileObj.id );
  104. if ( f == 2 && shortform > 2 )
  105. f = shortform;
  106. try {
  107. if ( typeof topWin.tb_remove != 'undefined' )
  108. topWin.jQuery( '#TB_overlay' ).click( topWin.tb_remove );
  109. } catch( e ){}
  110. if ( isNaN( serverData ) || !serverData ) {
  111. // Old style: Append the HTML returned by the server -- thumbnail and form inputs.
  112. item.append( serverData );
  113. prepareMediaItemInit( fileObj );
  114. } else {
  115. // New style: server data is just the attachment ID, fetch the thumbnail and form html from the server.
  116. item.load( 'async-upload.php', {attachment_id:serverData, fetch:f}, function(){prepareMediaItemInit( fileObj );updateMediaForm();});
  117. }
  118. }
  119. function prepareMediaItemInit( fileObj ) {
  120. var item = jQuery( '#media-item-' + fileObj.id );
  121. // Clone the thumbnail as a "pinkynail" -- a tiny image to the left of the filename.
  122. jQuery( '.thumbnail', item ).clone().attr( 'class', 'pinkynail toggle' ).prependTo( item );
  123. // Replace the original filename with the new (unique) one assigned during upload.
  124. jQuery( '.filename.original', item ).replaceWith( jQuery( '.filename.new', item ) );
  125. // Bind Ajax to the new Delete button.
  126. jQuery( 'a.delete', item ).on( 'click', function(){
  127. // Tell the server to delete it. TODO: Handle exceptions.
  128. jQuery.ajax({
  129. url: ajaxurl,
  130. type: 'post',
  131. success: deleteSuccess,
  132. error: deleteError,
  133. id: fileObj.id,
  134. data: {
  135. id : this.id.replace(/[^0-9]/g, '' ),
  136. action : 'trash-post',
  137. _ajax_nonce : this.href.replace(/^.*wpnonce=/,'' )
  138. }
  139. });
  140. return false;
  141. });
  142. // Bind Ajax to the new Undo button.
  143. jQuery( 'a.undo', item ).on( 'click', function(){
  144. // Tell the server to untrash it. TODO: Handle exceptions.
  145. jQuery.ajax({
  146. url: ajaxurl,
  147. type: 'post',
  148. id: fileObj.id,
  149. data: {
  150. id : this.id.replace(/[^0-9]/g,'' ),
  151. action: 'untrash-post',
  152. _ajax_nonce: this.href.replace(/^.*wpnonce=/,'' )
  153. },
  154. success: function( ){
  155. var type,
  156. item = jQuery( '#media-item-' + fileObj.id );
  157. if ( type = jQuery( '#type-of-' + fileObj.id ).val() )
  158. jQuery( '#' + type + '-counter' ).text( jQuery( '#' + type + '-counter' ).text()-0+1 );
  159. if ( post_id && item.hasClass( 'child-of-'+post_id ) )
  160. jQuery( '#attachments-count' ).text( jQuery( '#attachments-count' ).text()-0+1 );
  161. jQuery( '.filename .trashnotice', item ).remove();
  162. jQuery( '.filename .title', item ).css( 'font-weight','normal' );
  163. jQuery( 'a.undo', item ).addClass( 'hidden' );
  164. jQuery( '.menu_order_input', item ).show();
  165. item.css( {backgroundColor:'#ceb'} ).animate( {backgroundColor: '#fff'}, { queue: false, duration: 500, complete: function(){ jQuery( this ).css({backgroundColor:''}); } }).removeClass( 'undo' );
  166. }
  167. });
  168. return false;
  169. });
  170. // Open this item if it says to start open (e.g. to display an error).
  171. jQuery( '#media-item-' + fileObj.id + '.startopen' ).removeClass( 'startopen' ).addClass( 'open' ).find( 'slidetoggle' ).fadeIn();
  172. }
  173. // Generic error message.
  174. function wpQueueError( message ) {
  175. jQuery( '#media-upload-error' ).show().html( '<div class="error"><p>' + message + '</p></div>' );
  176. }
  177. // File-specific error messages.
  178. function wpFileError( fileObj, message ) {
  179. itemAjaxError( fileObj.id, message );
  180. }
  181. function itemAjaxError( id, message ) {
  182. var item = jQuery( '#media-item-' + id ), filename = item.find( '.filename' ).text(), last_err = item.data( 'last-err' );
  183. if ( last_err == id ) // Prevent firing an error for the same file twice.
  184. return;
  185. item.html( '<div class="error-div">' +
  186. '<a class="dismiss" href="#">' + pluploadL10n.dismiss + '</a>' +
  187. '<strong>' + pluploadL10n.error_uploading.replace( '%s', jQuery.trim( filename )) + '</strong> ' +
  188. message +
  189. '</div>' ).data( 'last-err', id );
  190. }
  191. function deleteSuccess( data ) {
  192. var type, id, item;
  193. if ( data == '-1' )
  194. return itemAjaxError( this.id, 'You do not have permission. Has your session expired?' );
  195. if ( data == '0' )
  196. return itemAjaxError( this.id, 'Could not be deleted. Has it been deleted already?' );
  197. id = this.id;
  198. item = jQuery( '#media-item-' + id );
  199. // Decrement the counters.
  200. if ( type = jQuery( '#type-of-' + id ).val() )
  201. jQuery( '#' + type + '-counter' ).text( jQuery( '#' + type + '-counter' ).text() - 1 );
  202. if ( post_id && item.hasClass( 'child-of-'+post_id ) )
  203. jQuery( '#attachments-count' ).text( jQuery( '#attachments-count' ).text() - 1 );
  204. if ( jQuery( 'form.type-form #media-items' ).children().length == 1 && jQuery( '.hidden', '#media-items' ).length > 0 ) {
  205. jQuery( '.toggle' ).toggle();
  206. jQuery( '.slidetoggle' ).slideUp( 200 ).siblings().removeClass( 'hidden' );
  207. }
  208. // Vanish it.
  209. jQuery( '.toggle', item ).toggle();
  210. jQuery( '.slidetoggle', item ).slideUp( 200 ).siblings().removeClass( 'hidden' );
  211. item.css( {backgroundColor:'#faa'} ).animate( {backgroundColor:'#f4f4f4'}, {queue:false, duration:500} ).addClass( 'undo' );
  212. jQuery( '.filename:empty', item ).remove();
  213. jQuery( '.filename .title', item ).css( 'font-weight','bold' );
  214. jQuery( '.filename', item ).append( '<span class="trashnotice"> ' + pluploadL10n.deleted + ' </span>' ).siblings( 'a.toggle' ).hide();
  215. jQuery( '.filename', item ).append( jQuery( 'a.undo', item ).removeClass( 'hidden' ) );
  216. jQuery( '.menu_order_input', item ).hide();
  217. return;
  218. }
  219. function deleteError() {
  220. }
  221. function uploadComplete() {
  222. jQuery( '#insert-gallery' ).prop( 'disabled', false );
  223. }
  224. function switchUploader( s ) {
  225. if ( s ) {
  226. deleteUserSetting( 'uploader' );
  227. jQuery( '.media-upload-form' ).removeClass( 'html-uploader' );
  228. if ( typeof( uploader ) == 'object' )
  229. uploader.refresh();
  230. } else {
  231. setUserSetting( 'uploader', '1' ); // 1 == html uploader.
  232. jQuery( '.media-upload-form' ).addClass( 'html-uploader' );
  233. }
  234. }
  235. function uploadError( fileObj, errorCode, message, up ) {
  236. var hundredmb = 100 * 1024 * 1024, max;
  237. switch ( errorCode ) {
  238. case plupload.FAILED:
  239. wpFileError( fileObj, pluploadL10n.upload_failed );
  240. break;
  241. case plupload.FILE_EXTENSION_ERROR:
  242. wpFileExtensionError( up, fileObj, pluploadL10n.invalid_filetype );
  243. break;
  244. case plupload.FILE_SIZE_ERROR:
  245. uploadSizeError( up, fileObj );
  246. break;
  247. case plupload.IMAGE_FORMAT_ERROR:
  248. wpFileError( fileObj, pluploadL10n.not_an_image );
  249. break;
  250. case plupload.IMAGE_MEMORY_ERROR:
  251. wpFileError( fileObj, pluploadL10n.image_memory_exceeded );
  252. break;
  253. case plupload.IMAGE_DIMENSIONS_ERROR:
  254. wpFileError( fileObj, pluploadL10n.image_dimensions_exceeded );
  255. break;
  256. case plupload.GENERIC_ERROR:
  257. wpQueueError( pluploadL10n.upload_failed );
  258. break;
  259. case plupload.IO_ERROR:
  260. max = parseInt( up.settings.filters.max_file_size, 10 );
  261. if ( max > hundredmb && fileObj.size > hundredmb ) {
  262. wpFileError( fileObj, pluploadL10n.big_upload_failed.replace( '%1$s', '<a class="uploader-html" href="#">' ).replace( '%2$s', '</a>' ) );
  263. } else {
  264. wpQueueError( pluploadL10n.io_error );
  265. }
  266. break;
  267. case plupload.HTTP_ERROR:
  268. wpQueueError( pluploadL10n.http_error );
  269. break;
  270. case plupload.INIT_ERROR:
  271. jQuery( '.media-upload-form' ).addClass( 'html-uploader' );
  272. break;
  273. case plupload.SECURITY_ERROR:
  274. wpQueueError( pluploadL10n.security_error );
  275. break;
  276. /* case plupload.UPLOAD_ERROR.UPLOAD_STOPPED:
  277. case plupload.UPLOAD_ERROR.FILE_CANCELLED:
  278. jQuery( '#media-item-' + fileObj.id ).remove();
  279. break;*/
  280. default:
  281. wpFileError( fileObj, pluploadL10n.default_error );
  282. }
  283. }
  284. function uploadSizeError( up, file ) {
  285. var message, errorDiv;
  286. message = pluploadL10n.file_exceeds_size_limit.replace( '%s', file.name );
  287. // Construct the error div.
  288. errorDiv = jQuery( '<div />' )
  289. .attr( {
  290. 'id': 'media-item-' + file.id,
  291. 'class': 'media-item error'
  292. } )
  293. .append(
  294. jQuery( '<p />' )
  295. .text( message )
  296. );
  297. // Append the error.
  298. jQuery( '#media-items' ).append( errorDiv );
  299. up.removeFile( file );
  300. }
  301. function wpFileExtensionError( up, file, message ) {
  302. jQuery( '#media-items' ).append( '<div id="media-item-' + file.id + '" class="media-item error"><p>' + message + '</p></div>' );
  303. up.removeFile( file );
  304. }
  305. /**
  306. * Copies the attachment URL to the clipboard.
  307. *
  308. * @since 5.8.0
  309. *
  310. * @param {MouseEvent} event A click event.
  311. *
  312. * @return {void}
  313. */
  314. function copyAttachmentUploadURLClipboard() {
  315. var clipboard = new ClipboardJS( '.copy-attachment-url' ),
  316. successTimeout;
  317. clipboard.on( 'success', function( event ) {
  318. var triggerElement = jQuery( event.trigger ),
  319. successElement = jQuery( '.success', triggerElement.closest( '.copy-to-clipboard-container' ) );
  320. // Clear the selection and move focus back to the trigger.
  321. event.clearSelection();
  322. // Handle ClipboardJS focus bug, see https://github.com/zenorocha/clipboard.js/issues/680
  323. triggerElement.trigger( 'focus' );
  324. // Show success visual feedback.
  325. clearTimeout( successTimeout );
  326. successElement.removeClass( 'hidden' );
  327. // Hide success visual feedback after 3 seconds since last success.
  328. successTimeout = setTimeout( function() {
  329. successElement.addClass( 'hidden' );
  330. }, 3000 );
  331. // Handle success audible feedback.
  332. wp.a11y.speak( pluploadL10n.file_url_copied );
  333. } );
  334. }
  335. jQuery( document ).ready( function( $ ) {
  336. copyAttachmentUploadURLClipboard();
  337. var tryAgainCount = {};
  338. var tryAgain;
  339. $( '.media-upload-form' ).on( 'click.uploader', function( e ) {
  340. var target = $( e.target ), tr, c;
  341. if ( target.is( 'input[type="radio"]' ) ) { // Remember the last used image size and alignment.
  342. tr = target.closest( 'tr' );
  343. if ( tr.hasClass( 'align' ) )
  344. setUserSetting( 'align', target.val() );
  345. else if ( tr.hasClass( 'image-size' ) )
  346. setUserSetting( 'imgsize', target.val() );
  347. } else if ( target.is( 'button.button' ) ) { // Remember the last used image link url.
  348. c = e.target.className || '';
  349. c = c.match( /url([^ '"]+)/ );
  350. if ( c && c[1] ) {
  351. setUserSetting( 'urlbutton', c[1] );
  352. target.siblings( '.urlfield' ).val( target.data( 'link-url' ) );
  353. }
  354. } else if ( target.is( 'a.dismiss' ) ) {
  355. target.parents( '.media-item' ).fadeOut( 200, function() {
  356. $( this ).remove();
  357. } );
  358. } else if ( target.is( '.upload-flash-bypass a' ) || target.is( 'a.uploader-html' ) ) { // Switch uploader to html4.
  359. $( '#media-items, p.submit, span.big-file-warning' ).css( 'display', 'none' );
  360. switchUploader( 0 );
  361. e.preventDefault();
  362. } else if ( target.is( '.upload-html-bypass a' ) ) { // Switch uploader to multi-file.
  363. $( '#media-items, p.submit, span.big-file-warning' ).css( 'display', '' );
  364. switchUploader( 1 );
  365. e.preventDefault();
  366. } else if ( target.is( 'a.describe-toggle-on' ) ) { // Show.
  367. target.parent().addClass( 'open' );
  368. target.siblings( '.slidetoggle' ).fadeIn( 250, function() {
  369. var S = $( window ).scrollTop(),
  370. H = $( window ).height(),
  371. top = $( this ).offset().top,
  372. h = $( this ).height(),
  373. b,
  374. B;
  375. if ( H && top && h ) {
  376. b = top + h;
  377. B = S + H;
  378. if ( b > B ) {
  379. if ( b - B < top - S )
  380. window.scrollBy( 0, ( b - B ) + 10 );
  381. else
  382. window.scrollBy( 0, top - S - 40 );
  383. }
  384. }
  385. } );
  386. e.preventDefault();
  387. } else if ( target.is( 'a.describe-toggle-off' ) ) { // Hide.
  388. target.siblings( '.slidetoggle' ).fadeOut( 250, function() {
  389. target.parent().removeClass( 'open' );
  390. } );
  391. e.preventDefault();
  392. }
  393. });
  394. // Attempt to create image sub-sizes when an image was uploaded successfully
  395. // but the server responded with an HTTP 5xx error.
  396. tryAgain = function( up, error ) {
  397. var file = error.file;
  398. var times;
  399. var id;
  400. if ( ! error || ! error.responseHeaders ) {
  401. wpQueueError( pluploadL10n.http_error_image );
  402. return;
  403. }
  404. id = error.responseHeaders.match( /x-wp-upload-attachment-id:\s*(\d+)/i );
  405. if ( id && id[1] ) {
  406. id = id[1];
  407. } else {
  408. wpQueueError( pluploadL10n.http_error_image );
  409. return;
  410. }
  411. times = tryAgainCount[ file.id ];
  412. if ( times && times > 4 ) {
  413. /*
  414. * The file may have been uploaded and attachment post created,
  415. * but post-processing and resizing failed...
  416. * Do a cleanup then tell the user to scale down the image and upload it again.
  417. */
  418. $.ajax({
  419. type: 'post',
  420. url: ajaxurl,
  421. dataType: 'json',
  422. data: {
  423. action: 'media-create-image-subsizes',
  424. _wpnonce: wpUploaderInit.multipart_params._wpnonce,
  425. attachment_id: id,
  426. _wp_upload_failed_cleanup: true,
  427. }
  428. });
  429. if ( error.message && ( error.status < 500 || error.status >= 600 ) ) {
  430. wpQueueError( error.message );
  431. } else {
  432. wpQueueError( pluploadL10n.http_error_image );
  433. }
  434. return;
  435. }
  436. if ( ! times ) {
  437. tryAgainCount[ file.id ] = 1;
  438. } else {
  439. tryAgainCount[ file.id ] = ++times;
  440. }
  441. // Try to create the missing image sizes.
  442. $.ajax({
  443. type: 'post',
  444. url: ajaxurl,
  445. dataType: 'json',
  446. data: {
  447. action: 'media-create-image-subsizes',
  448. _wpnonce: wpUploaderInit.multipart_params._wpnonce,
  449. attachment_id: id,
  450. _legacy_support: 'true',
  451. }
  452. }).done( function( response ) {
  453. var message;
  454. if ( response.success ) {
  455. uploadSuccess( file, response.data.id );
  456. } else {
  457. if ( response.data && response.data.message ) {
  458. message = response.data.message;
  459. }
  460. wpQueueError( message || pluploadL10n.http_error_image );
  461. }
  462. }).fail( function( jqXHR ) {
  463. // If another HTTP 5xx error, try try again...
  464. if ( jqXHR.status >= 500 && jqXHR.status < 600 ) {
  465. tryAgain( up, error );
  466. return;
  467. }
  468. wpQueueError( pluploadL10n.http_error_image );
  469. });
  470. }
  471. // Init and set the uploader.
  472. uploader_init = function() {
  473. uploader = new plupload.Uploader( wpUploaderInit );
  474. $( '#image_resize' ).on( 'change', function() {
  475. var arg = $( this ).prop( 'checked' );
  476. setResize( arg );
  477. if ( arg )
  478. setUserSetting( 'upload_resize', '1' );
  479. else
  480. deleteUserSetting( 'upload_resize' );
  481. });
  482. uploader.bind( 'Init', function( up ) {
  483. var uploaddiv = $( '#plupload-upload-ui' );
  484. setResize( getUserSetting( 'upload_resize', false ) );
  485. if ( up.features.dragdrop && ! $( document.body ).hasClass( 'mobile' ) ) {
  486. uploaddiv.addClass( 'drag-drop' );
  487. $( '#drag-drop-area' ).on( 'dragover.wp-uploader', function() { // dragenter doesn't fire right :(
  488. uploaddiv.addClass( 'drag-over' );
  489. }).on( 'dragleave.wp-uploader, drop.wp-uploader', function() {
  490. uploaddiv.removeClass( 'drag-over' );
  491. });
  492. } else {
  493. uploaddiv.removeClass( 'drag-drop' );
  494. $( '#drag-drop-area' ).off( '.wp-uploader' );
  495. }
  496. if ( up.runtime === 'html4' ) {
  497. $( '.upload-flash-bypass' ).hide();
  498. }
  499. });
  500. uploader.bind( 'postinit', function( up ) {
  501. up.refresh();
  502. });
  503. uploader.init();
  504. uploader.bind( 'FilesAdded', function( up, files ) {
  505. $( '#media-upload-error' ).empty();
  506. uploadStart();
  507. plupload.each( files, function( file ) {
  508. if ( file.type === 'image/heic' && up.settings.heic_upload_error ) {
  509. // Show error but do not block uploading.
  510. wpQueueError( pluploadL10n.unsupported_image );
  511. } else if ( file.type === 'image/webp' && up.settings.webp_upload_error ) {
  512. // Disallow uploading of WebP images if the server cannot edit them.
  513. wpQueueError( pluploadL10n.noneditable_image );
  514. up.removeFile( file );
  515. return;
  516. }
  517. fileQueued( file );
  518. });
  519. up.refresh();
  520. up.start();
  521. });
  522. uploader.bind( 'UploadFile', function( up, file ) {
  523. fileUploading( up, file );
  524. });
  525. uploader.bind( 'UploadProgress', function( up, file ) {
  526. uploadProgress( up, file );
  527. });
  528. uploader.bind( 'Error', function( up, error ) {
  529. var isImage = error.file && error.file.type && error.file.type.indexOf( 'image/' ) === 0;
  530. var status = error && error.status;
  531. // If the file is an image and the error is HTTP 5xx try to create sub-sizes again.
  532. if ( isImage && status >= 500 && status < 600 ) {
  533. tryAgain( up, error );
  534. return;
  535. }
  536. uploadError( error.file, error.code, error.message, up );
  537. up.refresh();
  538. });
  539. uploader.bind( 'FileUploaded', function( up, file, response ) {
  540. uploadSuccess( file, response.response );
  541. });
  542. uploader.bind( 'UploadComplete', function() {
  543. uploadComplete();
  544. });
  545. };
  546. if ( typeof( wpUploaderInit ) == 'object' ) {
  547. uploader_init();
  548. }
  549. });