PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 4.7.0
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v4.7.0
4.7.0 4.6.1 4.6.0 4.5.5 4.5.4 4.5.3 4.5.2 3.2.20 3.2.21 3.2.22 3.2.3 3.2.5 3.2.6 3.2.7 3.2.9 3.3.0 3.3.1 3.3.2 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.7.0 3.7.1 All 111 releases
← All changes | js/wposmush.js +627 -361 3.2.3 → 4.7.0 View file →
@@ -5,17 +5,20 @@
5 5 var WP_Optimize_Smush = function() {
6 6
7 7 var $ = jQuery;
8 8
9 + var heartbeat = WP_Optimize_Heartbeat();
10 + var heartbeat_agents = [];
11 +
12 + var last_ui_update_agent_uid = null;
13 +
14 + var block_ui = wp_optimize.block_ui;
15 +
9 16 /**
10 17 * Variables for smushing.
11 18 */
12 - var smush_nav_tab = $('#wp-optimize-images-nav-tab-smush'),
13 - smush_images_grid = $('#wpo_smush_images_grid'),
19 + var smush_images_grid = $('#wpo_smush_images_grid'),
14 20 smush_images_optimization_message = $('#smush_info_images'),
15 - smush_images_pending_tasks_container = $('#wpo_smush_images_pending_tasks_container'),
16 - smush_images_pending_tasks_btn = $('#wpo_smush_images_pending_tasks_button'),
17 - smush_images_save_options_btn = $('.wpo-fieldgroup #wpo_smush_images_save_options_button'),
18 21 smush_images_refresh_btn = $('#wpo_smush_images_refresh'),
19 22 smush_images_select_all_btn = $('#wpo_smush_images_select_all'),
20 23 smush_images_select_none_btn = $('#wpo_smush_images_select_none'),
21 24 smush_images_stats_clear_btn = $('#wpo_smush_clear_stats_btn'),
@@ -20,15 +23,14 @@
20 23 smush_images_select_none_btn = $('#wpo_smush_images_select_none'),
21 24 smush_images_stats_clear_btn = $('#wpo_smush_clear_stats_btn'),
22 25 smush_selected_images_btn = $('#wpo_smush_images_btn'),
23 26 smush_mark_as_compressed_btn = $('#wpo_smush_mark_as_compressed'),
24 - smush_single_image_btn = $('.wpo_smush_single_image .button'),
25 - smush_single_restore_btn = $('.wpo_restore_single_image .button'),
26 27 smush_mark_all_as_uncompressed_btn = $('#wpo_smush_mark_all_as_uncompressed_btn'),
27 28 restore_all_compressed_images_btn = $('#wpo_smush_restore_all_compressed_images_btn'),
28 29 smush_view_logs_btn = $('.wpo_smush_get_logs'),
29 30 smush_delete_backup_images_btn = $('#wpo_smush_delete_backup_btn'),
30 31 compression_server_select = $('.compression_server'),
32 + reset_webp_serving_method_btn = $('#wpo_reset_webp_serving_method'),
31 33 smush_images_tab_loaded = false,
32 34 smush_service_features = [],
33 35 smush_total_seconds = 0,
34 36 smush_timer_locked = false,
@@ -34,16 +36,113 @@
34 36 smush_timer_locked = false,
35 37 smush_timer_handle = 0,
36 38 smush_image_list = [],
37 39 smush_completed = false,
40 + smush_from_media_library = false,
38 41 smush_mark_all_as_uncompressed = false,
39 42 smush_affected_images = {},
40 - pending_tasks_cancel_btn = $('#wpo_smush_images_pending_tasks_cancel_button');
43 + pending_tasks_cancel_btn = $('#wpo_smush_images_pending_tasks_cancel_button'),
44 + uncompressed_images_sites_select = $('#wpo_uncompressed_images_sites_select');
41 45
42 46 /**
47 + * These options used for block UI with custom content.
48 + */
49 + var block_ui_custom_options = {
50 + baseZ: 160001,
51 + css: {
52 + top: '50%',
53 + transform: 'translate(0, -50%)',
54 + width: '400px',
55 + padding: '20px',
56 + cursor: 'pointer'
57 + }
58 + }
59 +
60 + $('#doaction, #doaction2').on('click', function(e) {
61 + e.stopImmediatePropagation();
62 + var action = $(this).prev('select').val();
63 + if ('wp_optimize_bulk_compression' !== action && 'wp_optimize_bulk_restore' !== action ) return;
64 +
65 + var $selected_images = get_media_library_selected_images();
66 + if (0 === $selected_images.length) return;
67 + e.preventDefault();
68 + if ('wp_optimize_bulk_compression' === action) bulk_compression($selected_images);
69 + if ('wp_optimize_bulk_restore' === action) bulk_restore($selected_images);
70 + });
71 +
72 + /**
73 + * Handles bulk compression action from media library
74 + *
75 + * @param {Object} $selected_images
76 + */
77 + function bulk_compression($selected_images) {
78 + block_ui(wposmush.server_check);
79 +
80 + data = { 'server': wposmush.smush_settings.compression_server, skip_notice: true };
81 + smush_manager_send_command('check_server_status', data, function(resp) {
82 + if (resp.online) {
83 + $selected_images.each(function(index, element) {
84 + smush_image_list.push({
85 + 'attachment_id': parseInt(element.value),
86 + 'blog_id': wposmush.blog_id
87 + });
88 + });
89 +
90 + data = {
91 + optimization_id: 'smush',
92 + selected_images: smush_image_list,
93 + smush_options: {
94 + 'compression_server': wposmush.smush_settings.compression_server,
95 + 'image_quality': wposmush.smush_settings.image_quality,
96 + 'lossy_compression': wposmush.smush_settings.lossy_compression,
97 + 'back_up_original': wposmush.smush_settings.back_up_original,
98 + 'preserve_exif': wposmush.smush_settings.preserve_exif
99 + }
100 + }
101 + smush_from_media_library = true;
102 + smush_completed = false;
103 + if (smush_timer_locked) return;
104 + block_ui('', $.extend(block_ui_custom_options, {message: $('#wpo_smush_images_information_container')}), false, true);
105 + clear_smush_stats();
106 +
107 + smush_timer_handle = window.setInterval(smush_timer, 1000);
108 + smush_manager_send_command('process_bulk_smush', data);
109 + } else {
110 + error_message = resp.error ? resp.error + '<br>' + wposmush.server_error : wposmush.server_error;
111 + block_ui(error_message);
112 + }
113 + });
114 + }
115 +
116 + /**
117 + * Handles bulk restore action from media library
118 + *
119 + * @param {Object} $selected_images
120 + */
121 + function bulk_restore($selected_images) {
122 + smush_from_media_library = true;
123 +
124 + var processed_elements = [];
125 + var progress = function(element_id) {
126 + return function(callback) {
127 + processed_elements.push(element_id);
128 +
129 + if (1 < processed_elements.length && processed_elements.length === $selected_images.length) {
130 + callback(wposmush.images_restored_successfully);
131 + } else {
132 + callback();
133 + }
134 + }
135 + }
136 +
137 + $selected_images.each(function(index, element) {
138 + restore_selected_image(wposmush.blog_id, parseInt(element.value), progress(parseInt(element.value)));
139 + });
140 + }
141 +
142 + /**
43 143 * Handle Image Selection
44 144 */
45 -
46 145 smush_images_grid.on('click', '.thumbnail', function (e) {
47 146 $(this).closest('input[type="checkbox"]').prop('checked', true);
48 147 });
49 148
@@ -61,14 +160,36 @@
61 160 smush_images_grid.on('mouseup', '.thumbnail', function (e) {
62 161 ctrl_shift_on_image_held = e.shiftKey || e.ctrlKey;
63 162 });
64 163
164 + // Resets server rewrite capability
165 + reset_webp_serving_method_btn.on('click', function(e) {
166 + e.preventDefault();
167 + smush_manager_send_command('reset_webp_serving_method', { skip_notice: true }, function(resp) {
168 + if (!resp.success) {
169 + $('#enable_webp_conversion').prop("checked", false);
170 + $('#smush-information-modal .smush-information').text(resp.error_message);
171 + block_ui('', $.extend(block_ui_custom_options, {message: $('#smush-information-modal')}), false, true);
172 + } else {
173 + $('#wpo_reset_webp_serving_method_done').show().delay(3000).fadeOut();
174 + }
175 + });
176 + });
177 +
65 178 /**
179 + * Boolean flag to track whether uncompressed images have already been loaded,
180 + * preventing multiple unnecessary loads
181 + */
182 + var uncompressed_images_already_loaded = false;
183 +
184 + /**
66 185 * Checks if smush is active and loads images if yes - image tabs change.
67 186 */
68 187 $('#wp-optimize-nav-tab-wrapper__wpo_images .nav-tab').on('click', function() {
188 + if (uncompressed_images_already_loaded) return;
189 +
69 190 if ($(this).is('#wp-optimize-nav-tab-wpo_images-smush')) {
70 - get_info_from_smush_manager();
191 + get_info_from_smush_manager(false);
71 192 }
72 193 });
73 194
74 195 /**
@@ -74,11 +195,13 @@
74 195 /**
75 196 * Checks if smush is active and loads images if yes - main menu change.
76 197 */
77 198 $('#wp-optimize-wrap').on('page-change', function(e, params) {
199 + if (uncompressed_images_already_loaded) return;
200 +
78 201 if ('wpo_images' == params.page) {
79 202 if ($('#wp-optimize-nav-tab-wrapper__wpo_images .nav-tab-active').is('#wp-optimize-nav-tab-wpo_images-smush')) {
80 - get_info_from_smush_manager();
203 + get_info_from_smush_manager(false);
81 204 }
82 205 }
83 206 });
84 207
@@ -136,28 +259,21 @@
136 259 */
137 260 smush_selected_images_btn.off().on('click', function() {
138 261
139 262 if (0 == $('#wpo_smush_images_grid input[type="checkbox"]:checked').length) {
140 - $('#smush-information-modal .smush-information').text(wposmush.please_select_images)
141 - update_view_modal_message($('#smush-information-modal'), $.unblockUI);
263 + block_ui(wposmush.please_select_images);
142 264 return;
143 265 }
144 266
145 - $('#smush-information-modal .smush-information').text(wposmush.server_check);
146 - update_view_modal_message($('#smush-information-modal'));
267 + block_ui(wposmush.server_check);
147 268
148 - data = { 'server': $("input[name='compression_server']:checked").val() };
269 + data = { 'server': $("input[name='compression_server']:checked").val(), skip_notice: true };
149 270 smush_manager_send_command('check_server_status', data, function(resp) {
150 271 if (resp.online) {
151 272 bulk_smush_selected_images();
152 273 } else {
153 - if (resp.error) {
154 - error_message = resp.error + '<br>' + wposmush.server_error
155 - $('#smush-information-modal .smush-information').html(error_message);
156 - } else {
157 - $('#smush-information-modal .smush-information').text(wposmush.server_error);
158 - }
159 - update_view_modal_message($('#smush-information-modal'), $.unblockUI);
274 + error_message = resp.error ? resp.error + '<br>' + wposmush.server_error : wposmush.server_error;
275 + block_ui(error_message);
160 276 }
161 277 });
162 278 });
163 279
@@ -164,13 +280,8 @@
164 280 /**
165 281 * Mark as compressed
166 282 */
167 283 smush_mark_as_compressed_btn.off().on('click', function() {
168 - if (0 == $('#wpo_smush_images_grid input[type="checkbox"]:checked').length) {
169 - $('#smush-information-modal .smush-information').text(wposmush.please_select_compressed_images)
170 - update_view_modal_message($('#smush-information-modal'), $.unblockUI);
171 - return;
172 - }
173 284
174 285 var selected_images = [],
175 286 image;
176 287
@@ -181,15 +292,15 @@
181 292 };
182 293 selected_images.push(image);
183 294 });
184 295
185 - update_view_modal_message(wposmush.please_updating_images_info);
296 + block_ui(wposmush.please_updating_images_info);
186 297
187 298 smush_manager_send_command('mark_as_compressed', {selected_images: selected_images}, function(response) {
188 299 $('#smush-information-modal .smush-information').text(response.summary);
189 - update_view_modal_message($('#smush-information-modal'), $.unblockUI);
300 + block_ui('', $.extend(block_ui_custom_options, {message: $('#smush-information-modal')}));
190 301 // refresh images list.
191 - get_info_from_smush_manager();
302 + get_info_from_smush_manager(false);
192 303 });
193 304 });
194 305
195 306 /**
@@ -199,10 +310,9 @@
199 310 if (!confirm(wposmush.mark_all_images_uncompressed)) return;
200 311
201 312 var restore_backup = confirm(wposmush.restore_images_from_backup);
202 313
203 - update_view_modal_message($('#smush-information-modal-cancel-btn'));
204 - $('#smush-information-modal-cancel-btn .smush-information').text(wposmush.please_wait);
314 + block_ui(wposmush.please_wait);
205 315
206 316 smush_mark_all_as_uncompressed = true;
207 317 run_mark_all_as_uncompressed(restore_backup);
208 318 });
@@ -212,10 +322,9 @@
212 322 */
213 323 restore_all_compressed_images_btn.on('click', function() {
214 324 if (!confirm(wposmush.restore_all_compressed_images)) return;
215 325
216 - update_view_modal_message($('#smush-information-modal-cancel-btn'));
217 - $('#smush-information-modal-cancel-btn .smush-information').text(wposmush.please_wait);
326 + block_ui(wposmush.please_wait);
218 327
219 328 smush_mark_all_as_uncompressed = true;
220 329 run_mark_all_as_uncompressed(true, true);
221 330 });
@@ -232,17 +341,22 @@
232 341 /**
233 342 * Send command for mark all compressed images as uncompressed.
234 343 *
235 344 * @param {bool} restore_backup if set to true then images will restored from backup if possible.
345 + * @param {bool} delete_only_backups_meta if set to true the only backup meta will be deleted
236 346 */
237 347 function run_mark_all_as_uncompressed(restore_backup, delete_only_backups_meta) {
238 348 if (!smush_mark_all_as_uncompressed) return;
239 349
350 + restore_backup = restore_backup ? 1 : 0;
351 + delete_only_backups_meta = delete_only_backups_meta ? 1 : 0;
352 +
240 353 var info = $('#smush-information-modal-cancel-btn .smush-information');
241 354 smush_manager_send_command('mark_all_as_uncompressed',
242 355 {
243 - restore_backup: restore_backup ? 1 : 0,
244 - delete_only_backups_meta: delete_only_backups_meta ? 1 : 0
356 + restore_backup: restore_backup,
357 + delete_only_backups_meta: delete_only_backups_meta,
358 + skip_notice: true
245 359 },
246 360 function(resp) {
247 361 // if cancel button pressed then exit
248 362 if (!smush_mark_all_as_uncompressed) return;
@@ -248,10 +362,9 @@
248 362 if (!smush_mark_all_as_uncompressed) return;
249 363
250 364 // if we get an error then show it
251 365 if (resp.hasOwnProperty('error')) {
252 - update_view_modal_message($('#smush-information-modal'), $.unblockUI);
253 - $('#smush-information-modal .smush-information').text(resp.error);
366 + block_ui(resp.error);
254 367 get_info_from_smush_manager();
255 368 return;
256 369 }
257 370
@@ -256,14 +369,14 @@
256 369 }
257 370
258 371 // if completed then refresh uncompressed images list and show final message.
259 372 if (resp.completed) {
260 - update_view_modal_message($('#smush-information-modal'), $.unblockUI);
373 + block_ui('', $.extend(block_ui_custom_options, {message: $('#smush-information-modal')}));
261 374 $('#smush-information-modal .smush-information').text(resp.message);
262 375 get_info_from_smush_manager();
263 376 } else {
264 377 info.text(resp.message);
265 - run_mark_all_as_uncompressed(restore_backup);
378 + run_mark_all_as_uncompressed(restore_backup, delete_only_backups_meta);
266 379 }
267 380 }
268 381 );
269 382 }
@@ -271,9 +384,10 @@
271 384 /**
272 385 * Refresh image list
273 386 */
274 387 smush_images_refresh_btn.off().on('click', function() {
275 - get_info_from_smush_manager();
388 + // The refresh image list button should not fetch from cache but run the query
389 + get_info_from_smush_manager(false);
276 390 });
277 391
278 392 /**
279 393 * Bind select all / select none controls
@@ -294,9 +408,9 @@
294 408 update_smush_action_buttons_state();
295 409 });
296 410
297 411 /**
298 - * Diplays logs in a modal
412 + * Displays logs in a modal
299 413 */
300 414 smush_view_logs_btn.off().on('click', function() {
301 415 $("#log-panel").text("Please wait, fetching logs.");
302 416 smush_manager_send_command('get_smush_logs', {}, function(resp) {
@@ -335,15 +449,8 @@
335 449 });
336 450 });
337 451
338 452 /**
339 - * Saves options
340 - */
341 - smush_images_save_options_btn.off().on('click', function(e) {
342 - save_options();
343 - });
344 -
345 - /**
346 453 * Binds clear stats button
347 454 */
348 455 smush_images_stats_clear_btn.off().on('click', function(e) {
349 456 $('#wpo_smush_images_clear_stats_spinner').show().delay(3000).fadeOut();
@@ -354,44 +461,17 @@
354 461 });
355 462 });
356 463
357 464 /**
358 - * Binds pending tasks button
359 - */
360 - smush_images_pending_tasks_btn.off().on('click', function(e) {
361 - $('#smush-information-modal .smush-information').text(wposmush.server_check);
362 - update_view_modal_message($('#smush-information-modal'), $.unblockUI);
363 - data = { 'server': $("input[name='compression_server']:checked").val() };
364 - smush_manager_send_command('check_server_status', data, function(resp) {
365 - if (resp.online) {
366 - update_view_bulk_smush_start();
367 - smush_manager_send_command('process_pending_images', {}, function(resp) {
368 - handle_response_from_smush_manager(resp, update_view_bulk_smush_progress);
369 - });
370 - } else {
371 - if (resp.error) {
372 - error_message = resp.error + '<br>' + wposmush.server_error
373 - $('#smush-information-modal .smush-information').html(error_message);
374 - } else {
375 - $('#smush-information-modal .smush-information').text(wposmush.server_error);
376 - }
377 - update_view_modal_message($('#smush-information-modal'), $.unblockUI);
378 - }
379 - });
380 -
381 - });
382 -
383 -
384 - /**
385 465 * Binds smush cancel button
386 466 */
387 467 $('body').on('click', '#wpo_smush_images_pending_tasks_cancel_button', function(e) {
388 468
389 - if (wpoptimize.cancel === pending_tasks_cancel_btn.val()) {
390 - pending_tasks_cancel_btn.val(wpoptimize.cancelling);
469 + if (wposmush.cancel === pending_tasks_cancel_btn.val()) {
470 + pending_tasks_cancel_btn.val(wposmush.cancelling);
391 471 pending_tasks_cancel_btn.prop('disabled', true);
392 472 }
393 - smush_manager_send_command('clear_pending_images', {}, function(resp) {
473 + smush_manager_send_command('clear_pending_images', { restore_images: smush_image_list }, function(resp) {
394 474 $.unblockUI();
395 475 if (resp.status) {
396 476 get_info_from_smush_manager();
397 477 reset_view_bulk_smush();
@@ -397,14 +477,53 @@
397 477 reset_view_bulk_smush();
398 478 } else {
399 479 console.log('Cancelling pending images apparently failed.', resp);
400 480 }
401 - pending_tasks_cancel_btn.val(wpoptimize.cancel);
481 + pending_tasks_cancel_btn.val(wposmush.cancel);
402 482 pending_tasks_cancel_btn.prop('disabled', false);
403 483 });
404 484 });
405 485
406 486 /**
487 + * Handle the click on the 'Compress' button within the Media Library page and open a dialog for the image compression action.
488 + */
489 + $('.column-wpo_smush').on('click', '.wpo-smush-compress-popup-btn', function(e) {
490 + var attachment_id = $(this).data('id'),
491 + blog_id = $(this).data('blog');
492 +
493 + e.preventDefault();
494 +
495 + smush_manager_send_command('get_smush_settings_form', {
496 + attachment_id: attachment_id,
497 + blog_id: blog_id
498 + }, function(resp) {
499 + if (resp.success) {
500 + var html = [
501 + '<div class="wpo-smush-compress-popup-content">',
502 + '<h3>',wposmush.compress_image,'</h3>',
503 + resp.html,
504 + '</div>',
505 + '<div class="wpo_smush_single_image action_button" style="display:inline-block;">',
506 + '<input type="button" data-blog="',blog_id,'" data-id="',attachment_id,'" id="smush_compress_',attachment_id,'" class="button-primary button" value="',wposmush.compress,'">',
507 + '</div>',
508 + '&nbsp;&nbsp;',
509 + '<a href="#" class="button wpo-smush-popup-cancel-btn">',wposmush.close,'</a>'
510 + ].join('');
511 + block_ui('', $.extend(block_ui_custom_options, {message: html}));
512 + }
513 + });
514 +
515 + });
516 +
517 + /**
518 + * Handle the 'Cancel' button in the dialog for the image compression action.
519 + */
520 + $('body').on('click', '.wpo-smush-popup-cancel-btn', function(e) {
521 + e.preventDefault();
522 + $.unblockUI();
523 + });
524 +
525 + /**
407 526 * Single image compression
408 527 */
409 528 $('body').on('click', '.wpo_smush_single_image .button', function() {
410 529
@@ -414,14 +533,13 @@
414 533 };
415 534
416 535 if ($('#enable_custom_compression').is(":checked")) {
417 536 image_quality = $('#custom_compression_slider').val();
418 - lossy_compression = image_quality < 100 ? true : false;
419 537 } else {
420 - // The '90' here has to be kept in sync with WP_Optimize::admin_page_wpo_images_smush()
421 - image_quality = $('#enable_lossy_compression').is(":checked") ? 90 : 100;
422 - lossy_compression = image_quality < 100 ? true : false;
538 + // The '60' here has to be kept in sync with WP_Optimize::admin_page_wpo_images_smush()
539 + image_quality = $('#enable_lossy_compression').is(":checked") ? 60 : 92;
423 540 }
541 + lossy_compression = image_quality < 92 ? true : false;
424 542
425 543 smush_options = {
426 544 'compression_server': $("input[name='compression_server_" + image.attachment_id + "']:checked").val(),
427 545 'image_quality': image_quality,
@@ -430,20 +548,15 @@
430 548 'preserve_exif': $('#smush_exif_' + image.attachment_id).is(":checked")
431 549 }
432 550
433 551 data = { 'server': $("input[name='compression_server_" + $(this).attr('id').substring(15) + "']:checked").val() };
434 - update_view_modal_message(wposmush.server_check);
552 + block_ui(wposmush.server_check);
435 553 smush_manager_send_command('check_server_status', data, function(resp) {
436 554 if (resp.online) {
437 555 smush_selected_image(image, smush_options);
438 556 } else {
439 - if (resp.error) {
440 - error_message = resp.error + '<br>' + wposmush.server_error
441 -
442 - update_view_modal_message(error_message, $.unblockUI);
443 - } else {
444 - update_view_modal_message(wposmush.server_error, $.unblockUI);
445 - }
557 + error_message = resp.error ? resp.error + '<br>' + wposmush.server_error : wposmush.server_error;
558 + block_ui(error_message);
446 559 }
447 560 });
448 561 });
449 562
@@ -449,13 +562,15 @@
449 562
450 563 /**
451 564 * Single image restore
452 565 */
453 - $('body').on('click', '.wpo_restore_single_image .button', function() {
566 + $('body').on('click', '.wpo_restore_single_image .button, .wpo_restore_single_image a', function(e) {
454 567 var clicked_image = $(this);
455 568 blog_id = clicked_image.data('blog');
456 569 image_id = clicked_image.data('id');
457 570
571 + e.preventDefault();
572 +
458 573 if (!image_id || !blog_id) return;
459 574 restore_selected_image(blog_id, image_id);
460 575 });
461 576
@@ -461,58 +576,76 @@
461 576
462 577 /**
463 578 * Mark as compressed
464 579 */
465 - $('body').on('click', '.wpo_smush_mark_single_image .button', function() {
466 - var image = {
467 - 'attachment_id':$(this).data('id'),
468 - 'blog_id': $(this).data('blog')
469 - },
470 - wrapper = $(this).closest('#smush-metabox-inside-wrapper');
580 + $('body').on('click', '.wpo_smush_mark_single_image .button, .wpo_smush_mark_single_image a', function(e) {
581 + mark_unmark_as_compressed_handler($(this), e, true);
582 + });
471 583
472 - update_view_modal_message(wposmush.please_updating_images_info);
473 -
474 - smush_manager_send_command('mark_as_compressed', {selected_images: [ image ]}, function(response) {
475 - $('#smush-information-modal .smush-information').text(response.summary);
476 - update_view_modal_message($('#smush-information-modal'), $.unblockUI);
477 -
478 - if (response.status) {
479 - $('.wpo_smush_single_image', wrapper).hide();
480 - $('.wpo-toggle-advanced-options', wrapper).removeClass('opened');
481 - $('.wpo_smush_mark_single_image', wrapper).hide();
482 - $('.wpo_smush_unmark_single_image', wrapper).show();
483 - $('.wpo_restore_single_image', wrapper).show();
484 - $('#smush_info', wrapper).text(response.info);
485 - }
486 - });
584 + /**
585 + * Unmark as compressed
586 + */
587 + $('body').on('click', '.wpo_smush_unmark_single_image .button, .wpo_smush_unmark_single_image a', function(e) {
588 + mark_unmark_as_compressed_handler($(this), e, false);
487 589 });
488 590
489 591 /**
490 - * Unmark as uncompressed
592 + * Handler for Mark/Unmark as compressed event.
593 + *
594 + * @param {jQuery} target jQuery object for target element
595 + * @param {Event} e
596 + * @param {Boolean} mark True or false - mark / unmark
491 597 */
492 - $('body').on('click', '.wpo_smush_unmark_single_image .button', function() {
493 - var image = {
494 - 'attachment_id':$(this).data('id'),
495 - 'blog_id': $(this).data('blog')
598 + function mark_unmark_as_compressed_handler(target, e, mark) {
599 + var blog_id = target.data('blog'),
600 + attachment_id = target.data('id'),
601 + image = {
602 + 'attachment_id': attachment_id,
603 + 'blog_id': blog_id
496 604 },
497 - wrapper = $(this).closest('#smush-metabox-inside-wrapper');
605 + wrapper = target.closest('#smush-metabox-inside-wrapper')
606 + data = {selected_images: [ image ]};
498 607
499 - update_view_modal_message(wposmush.please_updating_images_info);
608 + if (mark === false) {
609 + data.unmark = true;
610 + }
611 +
612 + e.preventDefault();
613 +
614 + block_ui(wposmush.please_updating_images_info);
615 +
616 + smush_manager_send_command('mark_as_compressed', data, function(response) {
500 617
501 - smush_manager_send_command('mark_as_compressed', {selected_images: [ image ], unmark: true}, function(response) {
502 618 $('#smush-information-modal .smush-information').text(response.summary);
503 - update_view_modal_message($('#smush-information-modal'), $.unblockUI);
504 619
620 + block_ui('', $.extend(block_ui_custom_options, {message: $('#smush-information-modal')}));
621 +
505 622 if (response.status) {
506 - $('.wpo_smush_single_image', wrapper).show();
507 - $('.wpo_smush_mark_single_image', wrapper).show();
508 - $('.wpo_smush_unmark_single_image', wrapper).hide();
509 - $('.wpo_restore_single_image', wrapper).hide();
510 - $('#smush_info', wrapper).text('');
623 + if (wrapper.length) {
624 + if (mark) {
625 + $('.wpo_smush_single_image', wrapper).hide();
626 + $('.wpo-toggle-advanced-options', wrapper).removeClass('opened');
627 + $('.wpo_smush_mark_single_image', wrapper).hide();
628 + $('.wpo_smush_unmark_single_image', wrapper).show();
629 + $('.wpo_restore_single_image', wrapper).show();
630 + $('#smush_info', wrapper).text(response.info);
631 + } else {
632 + $('.wpo_smush_single_image', wrapper).show();
633 + $('.wpo_smush_mark_single_image', wrapper).show();
634 + $('.wpo_smush_unmark_single_image', wrapper).hide();
635 + $('.wpo_restore_single_image', wrapper).hide();
636 + $('#smush_info', wrapper).text(response.info);
637 + }
638 + }
639 +
640 + if (response.hasOwnProperty('media_column_html')) {
641 + update_smush_information_media_library_column(blog_id, attachment_id, response.media_column_html);
642 + }
511 643 }
512 644 });
513 - });
645 + }
514 646
647 +
515 648 $('body').on('click', '#wpo_smush_details .wpo-collapsible', toggle_smush_details);
516 649 $('body').on('click', '.column-wpo_smush .wpo-collapsible', toggle_smush_details);
517 650
518 651 function toggle_smush_details() {
@@ -525,14 +658,29 @@
525 658 }
526 659
527 660 $('body').on('click', '#smush-log-modal .close, #smush-information-modal .information-modal-close', function() {
528 661 $.unblockUI();
662 + if (smush_from_media_library) {
663 + reset_bulk_actions_dropdown();
664 + }
529 665 });
530 666
531 667 $('body').on('click', '.wpo_smush_stats_cta_btn, .wpo_smush_get_logs, #smush-complete-summary .close', function() {
532 668 $.unblockUI();
533 - get_info_from_smush_manager();
534 - setTimeout(reset_view_bulk_smush, 500);
669 + if (smush_from_media_library) {
670 + var selected_images_list = get_media_library_selected_images_list();
671 + smush_manager_send_command('get_smush_details', {selected_images: selected_images_list}, function(response) {
672 + if (response.success) {
673 + window.clearInterval(smush_timer_handle);
674 + update_media_library_screen(response.smush_details);
675 + } else {
676 + console.log(response)
677 + }
678 + });
679 + } else {
680 + get_info_from_smush_manager();
681 + setTimeout(reset_view_bulk_smush, 500);
682 + }
535 683 });
536 684
537 685 $('body').on('click', '.wpo-toggle-advanced-options', function(e) {
538 686 e.preventDefault();
@@ -538,9 +686,9 @@
538 686 e.preventDefault();
539 687 $(this).toggleClass('opened');
540 688 });
541 689
542 - $('.wpo-fieldgroup .autosmush input, .wpo-fieldgroup .compression_level, .wpo-fieldgroup .image_options, #smush-show-metabox, #enable_webp_conversion').on('change', function(e) {
690 + $('.wpo-fieldgroup .autosmush input, .wpo-fieldgroup .compression_level, .wpo-fieldgroup .image_options, #smush-show-metabox').on('change', function(e) {
543 691 save_options();
544 692 });
545 693
546 694 $('body').on('change', '.smush-options.compression_level', function() {
@@ -554,8 +702,61 @@
554 702 $('body').on('change', '.smush-advanced input[type="radio"]', function() {
555 703 update_view_available_options();
556 704 });
557 705
706 + $('#enable_webp_conversion').on('change', function(e) {
707 + // only save when changing the options on the wpo dashboard.
708 + if (!$('#wp-optimize-wrap').length) return;
709 +
710 + $('#wpo_smush_images_save_options_spinner').show().delay(3000).fadeOut();
711 + $('#enable_webp_conversion').prop("disabled", true);
712 +
713 + var smush_options = get_smush_options();
714 + // Skip default notice and use popup to show error messages
715 + smush_options.skip_notice = true;
716 +
717 + smush_manager_send_command('update_webp_options', smush_options, function(resp) {
718 + $('#wpo_smush_images_save_options_spinner').hide();
719 + if (resp.hasOwnProperty('saved') && resp.saved) {
720 + $('#wpo_smush_images_save_options_done').show().delay(3000).fadeOut();
721 + } else {
722 + $('#enable_webp_conversion').prop("checked", false);
723 + if ('update_failed_no_working_webp_converter' === resp.error_code) {
724 + var html_msg = '<p>'
725 + + wposmush.webp_conversion_tool_error
726 + + ' <a href="https://teamupdraft.com/documentation/wp-optimize/topics/image-compression/troubleshooting/the-webp-conversion-tool-is-not-working/" target="_blank">'
727 + + wposmush.webp_conversion_tool_how_to
728 + + '</a></p>';
729 + $('#smush-information-modal .smush-information').html(html_msg);
730 + } else {
731 + $('#smush-information-modal .smush-information').text(resp.error_message);
732 + }
733 + block_ui('', $.extend(block_ui_custom_options, {message: $('#smush-information-modal')}), false, true);
734 + }
735 + $('#enable_webp_conversion').prop("disabled", false);
736 + });
737 + });
738 +
739 + $('body').on('click', '.wpo_smush.column-wpo_smush .convert-to-webp', function(e){
740 + e.preventDefault();
741 + var $link = $(this);
742 + data = {
743 + 'attachment_id': $(this).data('attachment-id'),
744 + skip_notice: true
745 + };
746 + block_ui(wposmush.converting_to_webp, {}, 0, true);
747 + smush_manager_send_command('convert_to_webp_format', data, function(response) {
748 + if (response.success) {
749 + block_ui(response.success, {}, 2000);
750 + $link.next().remove();
751 + if ($link.prev().is('.wpo-action-separator')) $link.prev().remove();
752 + $link.remove();
753 + } else {
754 + block_ui(response.error || response.error_message || wposmush.server_error , {}, 2000);
755 + }
756 + });
757 + });
758 +
558 759 /**
559 760 * Load and show information about uncompressed images.
560 761 *
561 762 * @param {Boolean} use_cache Use the request cache
@@ -567,18 +768,25 @@
567 768 var use_cache = (typeof use_cache === 'undefined') ? true : use_cache;
568 769 var data = { 'use_cache': use_cache };
569 770
570 771 smush_images_optimization_message.html('...');
571 - smush_images_pending_tasks_container.hide();
572 772
573 773 disable_image_optimization_controls(true);
574 774
575 - smush_manager_send_command('get_ui_update', data, function(resp) {
576 - handle_response_from_smush_manager(resp, update_view_show_uncompressed_images);
577 - update_view_available_options();
578 - disable_image_optimization_controls(false);
579 - update_smush_action_buttons_state();
580 - });
775 + heartbeat_agents.push(heartbeat.add_agent({
776 + _wait: false,
777 + _keep: false,
778 + command: 'updraft_smush_ajax',
779 + command_data: {data: data, subaction: 'get_ui_update'},
780 + callback: function(resp) {
781 + handle_response_from_smush_manager(resp, update_view_show_uncompressed_images);
782 + update_view_available_options();
783 + disable_image_optimization_controls(false);
784 + update_smush_action_buttons_state();
785 + }
786 + }));
787 +
788 + uncompressed_images_already_loaded = true;
581 789 }
582 790
583 791
584 792 /**
@@ -608,9 +816,14 @@
608 816 }
609 817 }
610 818
611 819 update_view_bulk_smush_start();
612 - smush_manager_send_command('process_bulk_smush', data);
820 + heartbeat_agents.push(heartbeat.add_agent({
821 + _wait: false,
822 + _keep: false,
823 + command: 'updraft_smush_ajax',
824 + command_data: {data: data, subaction: 'process_bulk_smush'}
825 + }));
613 826 }
614 827
615 828 /**
616 829 * Save options in the DB
@@ -622,38 +835,16 @@
622 835 if (!$('#wp-optimize-wrap').length) return;
623 836
624 837 $('#wpo_smush_images_save_options_spinner').show().delay(3000).fadeOut();
625 838
626 - if ($('#enable_custom_compression').is(":checked")) {
627 - image_quality = $('#custom_compression_slider').val();
628 - lossy_compression = image_quality < 100 ? true : false;
629 - } else {
630 - // The '90' here has to be kept in sync with WP_Optimize::admin_page_wpo_images_smush()
631 - image_quality = $('#enable_lossy_compression').is(":checked") ? 90 : 100;
632 - lossy_compression = image_quality < 100 ? true : false;
633 - }
839 + var smush_options = get_smush_options();
634 840
635 - var smush_options = {
636 - 'compression_server': $("input[name='compression_server']:checked").val(),
637 - 'image_quality': image_quality,
638 - 'lossy_compression': lossy_compression,
639 - 'back_up_original': $('#smush-backup-original').is(":checked"),
640 - 'back_up_delete_after': $('#smush-backup-delete').is(":checked"),
641 - 'back_up_delete_after_days': $('#smush-backup-delete-days').val(),
642 - 'preserve_exif': $('#smush-preserve-exif').is(":checked"),
643 - 'autosmush': $('#smush-automatically').is(":checked"),
644 - 'show_smush_metabox': $('#smush-show-metabox').is(":checked"),
645 - 'webp_conversion': $('#enable_webp_conversion').is(":checked")
646 - }
647 -
648 841 smush_manager_send_command('update_smush_options', smush_options, function(resp) {
649 842 $('#wpo_smush_images_save_options_spinner').hide();
650 843 if (resp.hasOwnProperty('saved') && resp.saved) {
651 844 $('#wpo_smush_images_save_options_done').show().delay(3000).fadeOut();
652 - smush_images_save_options_btn.hide();
653 845 } else {
654 846 $('#wpo_smush_images_save_options_fail').show().delay(3000).fadeOut();
655 - smush_images_save_options_btn.show();
656 847 }
657 848 });
658 849 }
659 850
@@ -679,17 +870,26 @@
679 870 *
680 871 * @return void
681 872 */
682 873 function trigger_events(time_elapsed) {
683 -
684 874 if (0 == time_elapsed % 3) {
685 - update_smush_stats();
875 + update_smush_stats(time_elapsed);
686 876 }
687 877
688 878 if (0 == time_elapsed % 60) {
689 - smush_manager_send_command('process_pending_images', {}, function(resp) {
690 - handle_response_from_smush_manager(resp, update_view_bulk_smush_progress);
691 - });
879 + if (null != last_ui_update_agent_uid) {
880 + heartbeat.cancel_agent(last_ui_update_agent_uid);
881 + last_ui_update_agent_uid = null;
882 + }
883 +
884 + heartbeat_agents.push(heartbeat.add_agent({
885 + _wait: false,
886 + command: 'updraft_smush_ajax',
887 + command_data: {data: {}, subaction: 'process_pending_images'},
888 + callback: function(resp) {
889 + handle_response_from_smush_manager(resp, update_view_bulk_smush_progress);
890 + }
891 + }));
692 892 }
693 893 }
694 894
695 895 /**
@@ -694,30 +894,41 @@
694 894
695 895 /**
696 896 * Updates the UI with stats
697 897 *
698 - * @param {Boolean} use_cache Use the request cache
898 + * @param {Int} time_elapsed Elapsed time since process start
699 899 *
700 900 * @return void
701 901 */
702 - function update_smush_stats(use_cache) {
703 -
704 - var use_cache = (typeof use_cache === 'undefined') ? true : use_cache;
705 -
902 + function update_smush_stats(time_elapsed) {
706 903 data = {
707 904 update_ui: true,
708 905 use_cache: false
709 906 }
710 907
711 - smush_manager_send_command('get_ui_update', data, function(resp) {
712 - handle_response_from_smush_manager(resp, update_view_bulk_smush_progress);
908 + var initial_requests = time_elapsed < 5;
909 +
910 + var agent = heartbeat.add_agent({
911 + _wait: !initial_requests,
912 + _keep: false,
913 + command: 'updraft_smush_ajax',
914 + command_data: {data: data, subaction: 'get_ui_update'},
915 + callback: function(resp) {
916 + handle_response_from_smush_manager(resp, update_view_bulk_smush_progress);
917 + }
713 918 });
919 +
920 + if (null !== agent) {
921 + last_ui_update_agent_uid = agent;
922 +
923 + heartbeat_agents.push(agent);
924 + }
714 925 }
715 926
716 927 /**
717 928 * Update images optimization tab view with data returned from images optimization.
718 929 *
719 - * @param {Object} data - meta data returned from task manager
930 + * @param {Object} data - metadata returned from task manager
720 931 *
721 932 * @return void
722 933 */
723 934 function update_view_show_uncompressed_images(data) {
@@ -724,35 +935,52 @@
724 935 smush_images_grid.html('');
725 936
726 937 if (!data || !data.hasOwnProperty('unsmushed_images')) return;
727 938
728 - var unsmushed_images = data.unsmushed_images;
729 - var pending_tasks = data.pending_tasks;
939 + var unsmushed_images = data.unsmushed_images,
940 + pending_tasks = data.pending_tasks,
941 + blog_id = 0;
730 942
731 - if (0 == data.unsmushed_images.length && 0 == data.pending_tasks) {
943 + if (0 == unsmushed_images.length && 0 == pending_tasks) {
732 944 smush_images_grid.text(wposmush.all_images_compressed).wrapInner("<div class='wpo-fieldgroup'> </div>");
733 945 }
734 946
735 - if (0 != data.pending_tasks) {
736 - smush_images_pending_tasks_container.show().find('.red').text(data.pending);
947 + if (1 === data.is_multisite) {
948 + blog_id = uncompressed_images_sites_select.find(":selected").val();
949 + add_unsmushed_images_to_grid(blog_id, data);
950 + } else {
951 + for (blog_id in data.unsmushed_images) {
952 + add_unsmushed_images_to_grid(blog_id, data);
953 + }
737 954 }
955 + }
738 956
957 + function sort_unsmushed_images(a, b) {
958 + return a.id - b.id;
959 + }
960 +
961 + function add_unsmushed_images_to_grid(blog_id, data) {
739 962 // Used to have upload.php?item= on multisite (using data.is_multisite), and no suffix
740 - var admin_url_pre_id = 'post.php?post=';
741 - var admin_url_post_id = '&action=edit';
742 -
743 - for (blog_id in data.unsmushed_images) {
744 - data.unsmushed_images[blog_id].sort(function(a, b) {
745 - return a.id - b.id;
746 - });
747 - for (i in data.unsmushed_images[blog_id]) {
748 - if (!data.unsmushed_images[blog_id].hasOwnProperty(i)) continue;
749 - image = data.unsmushed_images[blog_id][i];
750 - add_image_to_grid(image, blog_id, data.admin_urls[blog_id] + admin_url_pre_id + image.id + admin_url_post_id);
751 - }
963 + var admin_url_pre_id = 'post.php?post=',
964 + admin_url_post_id = '&action=edit',
965 + admin_url = data.admin_urls[blog_id],
966 + unsmushed_images = data.unsmushed_images[blog_id];
967 +
968 + if ('undefined' !== typeof unsmushed_images) {
969 + unsmushed_images.sort(sort_unsmushed_images);
752 970 }
971 +
972 + for (i in unsmushed_images) {
973 + if (!unsmushed_images.hasOwnProperty(i)) continue;
974 + var image = unsmushed_images[i];
975 + add_image_to_grid(image, blog_id, admin_url + admin_url_pre_id + image.id + admin_url_post_id);
976 + }
753 977 }
754 978
979 + uncompressed_images_sites_select.on('change', function() {
980 + get_info_from_smush_manager();
981 + });
982 +
755 983 /**
756 984 * Updates the view when bulk smush starts
757 985 *
758 986 * @return void
@@ -758,22 +986,45 @@
758 986 * @return void
759 987 */
760 988 function update_view_bulk_smush_start() {
761 989 if (smush_timer_locked) return;
762 - update_view_modal_message($('#wpo_smush_images_information_container'));
763 990
764 - service = $('.compression_server input[type="radio"]:checked + label small').text();
765 - $('#wpo_smush_images_information_server').html(service);
991 + block_ui('', $.extend(block_ui_custom_options, {message: $('#wpo_smush_images_information_container')}), false, true);
766 992
767 - // Clear stats
993 + clear_smush_stats();
994 +
995 + smush_timer_handle = window.setInterval(smush_timer, 1000);
996 + disable_image_optimization_controls(true);
997 + }
998 +
999 + /**
1000 + * Clears the statistics for image smushing in popup.
1001 + *
1002 + * This function clears the statistics displayed on the popup for image smushing.
1003 + *
1004 + * @returns {void}
1005 + */
1006 + function clear_smush_stats() {
768 1007 $('#smush_stats_pending_images').html("...");
769 1008 $('#smush_stats_completed_images').html("...");
770 1009 $('#smush_stats_bytes_saved').html("...");
771 1010 $('#smush_stats_percent_saved').html("...");
772 1011 $('#smush_stats_timer').html("...");
1012 + }
773 1013
774 - smush_timer_handle = window.setInterval(smush_timer, 1000);
775 - disable_image_optimization_controls(true);
1014 + /**
1015 + * Updates the media library screen with the provided smush details.
1016 + *
1017 + * @param {Object} smush_details - The details of the smushed images
1018 + * @return {void}
1019 + */
1020 + function update_media_library_screen(smush_details) {
1021 + for (var image_id in smush_details) {
1022 + if(smush_details.hasOwnProperty(image_id)) {
1023 + $('#post-' + image_id + ' .column-wpo_smush').html(smush_details[image_id]);
1024 + }
1025 + }
1026 + reset_bulk_actions_dropdown();
776 1027 }
777 1028
778 1029 /**
779 1030 * Updates the view with progress related stats
@@ -792,9 +1043,11 @@
792 1043
793 1044 // Show summary and close the modal
794 1045 if (true == resp.smush_complete) {
795 1046 // Force a delay here to avoid stale data
796 - setTimeout(update_view_bulk_smush_complete, 1500);
1047 + setTimeout(function() {
1048 + update_view_bulk_smush_complete(function() { get_info_from_smush_manager(false); });
1049 + }, 1500);
797 1050 }
798 1051 }
799 1052
800 1053 /**
@@ -801,26 +1054,45 @@
801 1054 * Updates the view when bulk smush completes
802 1055 *
803 1056 * @return void
804 1057 */
805 - function update_view_bulk_smush_complete() {
1058 + function update_view_bulk_smush_complete(callback) {
806 1059
807 1060 data = {
808 1061 update_ui: true,
809 1062 use_cache: false,
810 1063 image_list: smush_image_list
811 - }
1064 + };
812 1065
813 - smush_manager_send_command('get_ui_update', data, function(resp) {
1066 + (function(single_callback) {
1067 + heartbeat_agents.push(heartbeat.add_agent({
1068 + // We have to use a non-unique agent in the complete action because the info update subactions
1069 + // have the same names, and the agent may not be added. This ensures that the "smush_complete" action will run.
1070 + _unique: false,
1071 + _wait: false,
1072 + _keep: false,
1073 + command: 'updraft_smush_ajax',
1074 + command_data: {data: data, subaction: 'get_ui_update'},
1075 + callback: function(resp) {
814 1076
815 - summary = resp.session_stats;
1077 + summary = resp.session_stats;
1078 + // Prevent pops with undefined headers
1079 + if (!resp.session_stats) {
1080 + return;
1081 + }
816 1082
817 - if (0 != resp.completed_task_count) {
818 - summary += '<hr>' + resp.summary;
1083 + if (0 != resp.completed_task_count) {
1084 + summary += '<hr>' + resp.summary;
1085 + }
1086 +
1087 + show_smush_summary(summary);
1088 +
1089 + if (single_callback instanceof Function) {
1090 + single_callback();
1091 + }
819 1092 }
820 -
821 - show_smush_summary(summary);
822 - });
1093 + }));
1094 + })(callback);
823 1095 }
824 1096
825 1097 /**
826 1098 * Displays a modal with compression data
@@ -834,10 +1106,12 @@
834 1106 if (smush_completed) return;
835 1107
836 1108 $('#summary-message').html(summary);
837 1109 reset_view_bulk_smush();
838 - update_view_modal_message($('#smush-complete-summary'));
1110 + block_ui('', $.extend(block_ui_custom_options, {message: $('#smush-complete-summary')}));
839 1111 smush_completed = true;
1112 +
1113 + heartbeat.cancel_agents(heartbeat_agents);
840 1114 }
841 1115
842 1116 /**
843 1117 * Updates the view when bulk smush completes
@@ -849,9 +1123,12 @@
849 1123 smush_total_seconds = 0;
850 1124 smush_timer_locked = false;
851 1125 smush_completed = false;
852 1126 smush_image_list = [];
853 - window.clearInterval(smush_timer_handle);
1127 +
1128 + heartbeat.cancel_agents(heartbeat_agents);
1129 + clearInterval(smush_timer_handle);
1130 +
854 1131 disable_image_optimization_controls(false);
855 1132 }
856 1133
857 1134 /**
@@ -913,11 +1190,9 @@
913 1190 $.each([
914 1191 smush_selected_images_btn,
915 1192 smush_images_select_all_btn,
916 1193 smush_images_select_none_btn,
917 - smush_images_save_options_btn,
918 1194 smush_images_refresh_btn,
919 - smush_images_pending_tasks_btn,
920 1195 smush_mark_as_compressed_btn,
921 1196 ], function(i, el) {
922 1197 el.prop('disabled', disable);
923 1198 });
@@ -945,12 +1220,13 @@
945 1220 if (0 == selected_image.length) return;
946 1221
947 1222 data = {
948 1223 selected_image: selected_image,
949 - smush_options: smush_options
1224 + smush_options: smush_options,
1225 + skip_notice: true
950 1226 }
951 1227
952 - update_view_modal_message(wposmush.compress_single_image_dialog);
1228 + block_ui(wposmush.compress_single_image_dialog, {}, false, true);
953 1229 smush_manager_send_command('compress_single_image', data, function(resp) {
954 1230 handle_response_from_smush_manager(resp, update_view_single_image_complete);
955 1231 });
956 1232 }
@@ -957,23 +1233,37 @@
957 1233
958 1234 /**
959 1235 * Get selected image and make an ajax request to compress it.
960 1236 *
961 - * @param {Number} blog_id - The blog id
962 - * @param {Number} selected_image - The image id
1237 + * @param {Number} blog_id - The blog id
1238 + * @param {Number} selected_image - The image id
1239 + * @param {Function} done_callback - Optional. It will be called when the AJAX command is done, used for multiple calls that need a single `done` action (like bulk_restore)
963 1240 *
964 1241 * @return void
965 1242 */
966 - function restore_selected_image(blog_id, selected_image) {
1243 + function restore_selected_image(blog_id, selected_image, done_callback) {
967 1244
968 1245 // if no selected images then exit.
969 1246 if (0 == selected_image.length) return;
970 1247
971 - update_view_modal_message(wposmush.please_wait, $.unblockUI);
972 - var data = { 'blog_id': blog_id, 'selected_image': selected_image };
973 - smush_manager_send_command('restore_single_image', data, function(resp) {
974 - handle_response_from_smush_manager(resp, update_view_single_image_complete);
975 - });
1248 + block_ui(wposmush.please_wait);
1249 + var data = { 'blog_id': blog_id, 'selected_image': selected_image, skip_notice: true };
1250 +
1251 + smush_manager_send_command.apply({unique: false}, ['restore_single_image', data, function(resp) {
1252 + var done = function(resp_summary_alt) {
1253 + if ('undefined' != typeof(resp_summary_alt)) {
1254 + resp.summary = resp_summary_alt;
1255 + }
1256 +
1257 + handle_response_from_smush_manager(resp, update_view_single_image_complete);
1258 + }
1259 +
1260 + if (done_callback instanceof Function) {
1261 + done_callback(done);
1262 + } else {
1263 + done();
1264 + }
1265 + }]);
976 1266 }
977 1267
978 1268 /**
979 1269 * Updates the view once a single image is compressed or restored.
@@ -985,9 +1275,9 @@
985 1275 function update_view_single_image_complete(resp) {
986 1276
987 1277 if (resp.hasOwnProperty('success') && resp.success) {
988 1278 $(".smush-information").text(resp.summary);
989 - update_view_modal_message($("#smush-information-modal"), $.unblockUI);
1279 + block_ui('', $.extend(block_ui_custom_options, {message: $("#smush-information-modal")}));
990 1280
991 1281 $('.wpo-toggle-advanced-options.wpo_smush_single_image').removeClass('opened');
992 1282
993 1283 update_view_singe_image_compress(resp.operation, resp.summary, resp.restore_possible, resp);
@@ -1000,8 +1290,12 @@
1000 1290
1001 1291 if (!smush_affected_images.hasOwnProperty(blog_id)) smush_affected_images[blog_id] = {};
1002 1292 if (!smush_affected_images[blog_id].hasOwnProperty(image_id)) smush_affected_images[blog_id][image_id] = {};
1003 1293
1294 + if (resp.hasOwnProperty('media_column_html')) {
1295 + update_smush_information_media_library_column(blog_id, image_id, resp.media_column_html);
1296 + }
1297 +
1004 1298 if ('compress' == resp.operation) {
1005 1299 smush_affected_images[blog_id][image_id] = {
1006 1300 operation: resp.operation,
1007 1301 summary: resp.summary,
@@ -1007,19 +1301,34 @@
1007 1301 summary: resp.summary,
1008 1302 restore_possible: resp.restore_possible
1009 1303 }
1010 1304 } else {
1305 + if (image_id) {
1306 + reset_bulk_actions_dropdown();
1307 + }
1011 1308 smush_affected_images[blog_id][image_id] = {
1012 1309 operation: resp.operation
1013 1310 }
1014 1311 }
1015 1312 } else {
1016 - $(".smush-information").text(resp.error_message);
1017 - update_view_modal_message($("#smush-information-modal"), $.unblockUI);
1313 + // Update the error message to be user-friendly
1314 + if (/exceeded_max_filesize/.test(resp.error_message)) resp.error_message = wposmush.exceeded_max_filesize
1315 + block_ui(resp.error_message, {}, 4000);
1018 1316 }
1019 1317 }
1020 1318
1021 1319 /**
1320 + * Update information for the WP-Optimize column in the Media Library.
1321 + *
1322 + * @param {number} blog_id
1323 + * @param {number} image_id
1324 + * @param {string} html
1325 + */
1326 + function update_smush_information_media_library_column(blog_id, image_id, html) {
1327 + $(['.wpo-smush-media-library-column[data-blog="',blog_id,'"][data-id="',image_id,'"]'].join('')).parent().html(html);
1328 + }
1329 +
1330 + /**
1022 1331 * Update metabox view depending on a command response.
1023 1332 *
1024 1333 * @param {string} operation
1025 1334 * @param {string} summary
@@ -1028,8 +1337,10 @@
1028 1337 */
1029 1338 function update_view_singe_image_compress(operation, summary, restore_possible, smush_image_data) {
1030 1339 var wrapper = $("#smush_info").closest('#smush-metabox-inside-wrapper');
1031 1340
1341 + if (0 === wrapper.length) return;
1342 +
1032 1343 if ('compress' == operation) {
1033 1344 $(".wpo_smush_single_image").hide();
1034 1345 $(".wpo_restore_single_image").show();
1035 1346
@@ -1076,30 +1387,8 @@
1076 1387 }
1077 1388 });
1078 1389
1079 1390 /**
1080 - * Display a modal message
1081 - *
1082 - * @param {string} message The message or element to display
1083 - * @param {Function} callback Called when the overlay is clicked
1084 - *
1085 - * @return void
1086 - */
1087 - function update_view_modal_message(message, callback) {
1088 -
1089 - $.blockUI({
1090 - message: message,
1091 - onOverlayClick: callback,
1092 - baseZ: 160001,
1093 - css: {
1094 - width: '400px',
1095 - padding: '20px',
1096 - cursor: 'pointer'
1097 - }
1098 - });
1099 - }
1100 -
1101 - /**
1102 1391 * Check returned response from the smush manager and call update view callback.
1103 1392 *
1104 1393 * @param {Object} resp - response from smush manager.
1105 1394 * @param {Function} update_view_callback - callback function to update view.
@@ -1113,8 +1402,41 @@
1113 1402 alert(wposmush.error_unexpected_response);
1114 1403 console.log(resp);
1115 1404 }
1116 1405 }
1406 +
1407 + /**
1408 + * Retrieves the selected images from the media library.
1409 + *
1410 + * @return {jQuery} - The selected images as a jQuery object.
1411 + */
1412 + function get_media_library_selected_images() {
1413 + return $('input[name="media[]"]:checked');
1414 + }
1415 +
1416 + /**
1417 + * Retrieves the list of selected images from the media library.
1418 + *
1419 + * @return {Array.<number>} The list of selected image IDs.
1420 + */
1421 + function get_media_library_selected_images_list() {
1422 + var selected_images_list = [];
1423 + var $selected_images = get_media_library_selected_images();
1424 + $selected_images.each(function(index, element) {
1425 + selected_images_list.push(parseInt(element.value));
1426 + });
1427 + return selected_images_list;
1428 + }
1429 +
1430 + /**
1431 + * Resets the bulk action dropdown by setting its value to "-1" and unchecking all the selected checkboxes.
1432 + *
1433 + * @returns {void}
1434 + */
1435 + function reset_bulk_actions_dropdown() {
1436 + $('#bulk-action-selector-top, #bulk-action-selector-bottom').val("-1");
1437 + $('input[name="media[]"]:checked, #cb-select-all-1, #cb-select-all-2').prop('checked', false);
1438 + }
1117 1439
1118 1440 /**
1119 1441 * Send an action to the task manager via admin-ajax.php.
1120 1442 *
@@ -1121,132 +1443,76 @@
1121 1443 * @param {string} action The action to send
1122 1444 * @param {[type]} data Data to send
1123 1445 * @param {Function} callback Will be called with the results
1124 1446 * @param {boolean} json_parse JSON parse the results
1447 + * @param {boolean} wait Wait for the response
1125 1448 *
1126 1449 * @return {JSON}
1127 1450 */
1128 - function smush_manager_send_command(action, data, callback, json_parse) {
1451 + function smush_manager_send_command(action, data, callback, json_parse, wait) {
1129 1452
1130 1453 json_parse = ('undefined' === typeof json_parse) ? true : json_parse;
1131 - data = $.isEmptyObject(data) ? {'use_cache' : false} : data;
1454 + var _wait = ('undefined' === typeof wait) ? false : wait;
1132 1455
1133 - var ajax_data = {
1134 - action: 'updraft_smush_ajax',
1135 - subaction: action,
1136 - nonce: wposmush.smush_ajax_nonce,
1137 - data: data
1138 - };
1456 + var skip_notice = data.hasOwnProperty('skip_notice');
1457 + var data_has_only_skip_notice = skip_notice && 1 === Object.keys(data).length;
1458 + var is_data_empty = $.isEmptyObject(data);
1139 1459
1140 - var ajax_opts = {
1141 - type: 'POST',
1142 - url: ajaxurl,
1143 - data: ajax_data,
1144 - success: function(response) {
1460 + data = is_data_empty ? {'use_cache' : false} : data;
1461 + if (data_has_only_skip_notice) data.use_cache = false;
1145 1462
1146 - if (json_parse) {
1147 - try {
1148 - var resp = wpo_parse_json(response);
1149 - } catch (e) {
1150 - console.log("smush_manager_send_command JSON parse error");
1151 - console.log(e);
1152 - console.log(response);
1153 - alert(wposmush.error_unexpected_response);
1463 + (function(single_callback, _keep, _unique) {
1464 + heartbeat_agents.push(heartbeat.add_agent({
1465 + _wait: _wait,
1466 + _keep: _keep,
1467 + _unique: _unique,
1468 + command: 'updraft_smush_ajax',
1469 + command_data: {data: data, subaction: action},
1470 + callback: function(response) {
1471 + if (json_parse) {
1472 + try {
1473 + var resp = wpo_parse_json(response);
1474 + } catch (e) {
1475 + console.log("smush_manager_send_command JSON parse error");
1476 + console.log(e);
1477 + console.log(response);
1478 + alert(wposmush.error_unexpected_response);
1479 + }
1480 + if ('undefined' !== typeof single_callback) single_callback(resp);
1481 + } else {
1482 + if ('undefined' !== typeof single_callback) single_callback(response);
1154 1483 }
1155 - if ('undefined' !== typeof callback) callback(resp);
1156 - } else {
1157 - if ('undefined' !== typeof callback) callback(response);
1158 1484 }
1159 - },
1160 - error: function(response, status, error_code) {
1161 - console.log("smush_manager_send_command AJAX parse error: "+status+" ("+error_code+")");
1162 - if ('undefined' !== typeof callback) {
1163 - callback(response);
1164 - } else {
1165 - console.log(response);
1166 - alert(wposmush.error_unexpected_response);
1167 - }
1168 - },
1169 - dataType: 'text'
1170 -
1171 - }
1172 -
1173 - $.ajax(ajax_opts);
1174 -
1485 + }));
1486 + })(callback, this.keep, this.unique);
1175 1487 };
1176 1488
1177 -} // END WP_Optimize_Smush
1489 + // Attach heartbeat API events
1490 + heartbeat.setup();
1178 1491
1179 -/**
1180 - * Parse JSON string, including automatically detecting unwanted extra input and skipping it
1181 - *
1182 - * @param {string|object} json_mix_str - JSON string which need to parse and convert to object
1183 - *
1184 - * @throws SyntaxError|String (including passing on what JSON.parse may throw) if a parsing error occurs.
1185 - *
1186 - * @return mixed parsed JSON object. Will only return if parsing is successful (otherwise, will throw)
1187 - */
1188 -function wpo_parse_json(json_mix_str) {
1189 - // When using wp_send_json to return the value, the format is already parsed.
1190 - if ('object' === typeof json_mix_str) return json_mix_str;
1492 + // Gather smush options
1493 + var get_smush_options = function() {
1494 + var image_quality = '';
1495 + if ($('#enable_custom_compression').is(":checked")) {
1496 + image_quality = $('#custom_compression_slider').val();
1497 + } else {
1498 + // The '90' here has to be kept in sync with WP_Optimize::admin_page_wpo_images_smush()
1499 + image_quality = $('#enable_lossy_compression').is(":checked") ? 60 : 92;
1500 + }
1501 + var lossy_compression = image_quality < 92 ? true : false;
1191 1502
1192 - // Just try it - i.e. the 'default' case where things work (which can include extra whitespace/line-feeds, and simple strings, etc.).
1193 - try {
1194 - var result = JSON.parse(json_mix_str);
1195 - return result;
1196 - } catch (e) {
1197 - console.log("WPO: Exception when trying to parse JSON (1) - will attempt to fix/re-parse");
1198 - console.log(json_mix_str);
1503 + return {
1504 + 'compression_server': $("input[name='compression_server']:checked").val(),
1505 + 'image_quality': image_quality,
1506 + 'lossy_compression': lossy_compression,
1507 + 'back_up_original': $('#smush-backup-original').is(":checked"),
1508 + 'back_up_delete_after': $('#smush-backup-delete').is(":checked"),
1509 + 'back_up_delete_after_days': $('#smush-backup-delete-days').val(),
1510 + 'preserve_exif': $('#smush-preserve-exif').is(":checked"),
1511 + 'autosmush': $('#smush-automatically').is(":checked"),
1512 + 'show_smush_metabox': $('#smush-show-metabox').is(":checked"),
1513 + 'webp_conversion': $('#enable_webp_conversion').is(":checked")
1514 + };
1199 1515 }
1516 + wp_optimize.smush_settings = get_smush_options;
1517 +} // END WP_Optimize_Smush
1200 1518
1201 - var json_start_pos = json_mix_str.indexOf('{');
1202 - var json_last_pos = json_mix_str.lastIndexOf('}');
1203 -
1204 - // Case where some php notice may be added after or before json string
1205 - if (json_start_pos > -1 && json_last_pos > -1) {
1206 - var json_str = json_mix_str.slice(json_start_pos, json_last_pos + 1);
1207 - try {
1208 - var parsed = JSON.parse(json_str);
1209 - return parsed;
1210 - } catch (e) {
1211 - console.log("WPO: Exception when trying to parse JSON (2) - will attempt to fix/re-parse based upon bracket counting");
1212 -
1213 - var cursor = json_start_pos;
1214 - var open_count = 0;
1215 - var last_character = '';
1216 - var inside_string = false;
1217 -
1218 - // Don't mistake this for a real JSON parser. Its aim is to improve the odds in real-world cases seen, not to arrive at universal perfection.
1219 - while ((open_count > 0 || cursor == json_start_pos) && cursor <= json_last_pos) {
1220 -
1221 - var current_character = json_mix_str.charAt(cursor);
1222 -
1223 - if (!inside_string && '{' == current_character) {
1224 - open_count++;
1225 - } else if (!inside_string && '}' == current_character) {
1226 - open_count--;
1227 - } else if ('"' == current_character && '\\' != last_character) {
1228 - inside_string = inside_string ? false : true;
1229 - }
1230 -
1231 - last_character = current_character;
1232 - cursor++;
1233 - }
1234 -
1235 - console.log("Started at cursor="+json_start_pos+", ended at cursor="+cursor+" with result following:");
1236 - console.log(json_mix_str.substring(json_start_pos, cursor));
1237 -
1238 - try {
1239 - var parsed = JSON.parse(json_mix_str.substring(json_start_pos, cursor));
1240 - // console.log('WPO: JSON re-parse successful');
1241 - return parsed;
1242 - } catch (e) {
1243 - // Throw it again, so that our function works just like JSON.parse() in its behaviour.
1244 - throw e;
1245 - }
1246 -
1247 - }
1248 - }
1249 -
1250 - throw "WPO: could not parse the JSON";
1251 -
1252 -}