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/wpoadmin.js +673 -131 3.5.0 → 4.7.0 View file →
@@ -49,14 +49,38 @@
49 49 var optimization_force = false;
50 50 var optimization_logged_warnings = false;
51 51 var force_single_table_optimization = false;
52 52 var heartbeat = WP_Optimize_Heartbeat();
53 -
53 +
54 + // Dashboard refresh button
55 + $(document).on('click', '#wpo-dashboard-refresh', function(e) {
56 + e.preventDefault();
57 + var $btn = $(this);
58 + var $icon = $btn.find('.dashicons');
59 + $btn.prop('disabled', true);
60 + $icon.addClass('wpo-spinning');
61 + send_command('refresh_dashboard', {}, function(resp) {
62 + if (resp && resp.success) {
63 + if (resp.top_row) {
64 + $('.wpo-top-row').html(resp.top_row);
65 + }
66 + if (resp.mod_grid) {
67 + $('.wpo-mod-grid').html(resp.mod_grid);
68 + }
69 + }
70 + }).fail(function() {
71 + block_ui(wpoptimize.something_wrong_try_again, {}, 3000);
72 + }).always(function() {
73 + $btn.prop('disabled', false);
74 + $icon.removeClass('wpo-spinning');
75 + });
76 + });
77 +
54 78 /*
55 79 * Enable select all checkbox for optimizations list.
56 80 */
57 81 define_select_all_checkbox($('#select_all_optimizations'), $('#optimizations_list .optimization_checkbox'));
58 -
82 +
59 83 /**
60 84 * Either display normally, or grey-out, the scheduling options, depending on whether any schedule has been selected.
61 85 *
62 86 * @return {string}
@@ -77,28 +101,8 @@
77 101 $('#enable-schedule').on('change', function () {
78 102 enable_or_disable_schedule_options();
79 103 });
80 104
81 - // table sorter library.
82 - // This calls the tablesorter library in order to sort the table information correctly.
83 - // There is a fix below on line 172 to apply applyWidgets on load to avoid display hidden for tabs.
84 - // add parser through the tablesorter addParser method
85 - $.tablesorter.addParser({
86 - // set a unique id
87 - id: 'sizes',
88 - is: function(s) {
89 - // return false so this parser is not auto detected
90 - return false;
91 - },
92 - format: function(cell_content, table, cell) {
93 - var val = $(cell).data('raw_value');
94 - if (!val) val = 0;
95 - return parseInt(val);
96 - },
97 - // set type, either numeric or text
98 - type: 'numeric'
99 - });
100 -
101 105 /*
102 106 * Triggered when the database tabs are loaded.
103 107 */
104 108
@@ -106,52 +110,46 @@
106 110 /*
107 111 * Setup table events and tablesorter
108 112 */
109 113
110 - var table_list_filter = $('#wpoptimize_table_list_filter'),
111 - table_list = $('#wpoptimize_table_list'),
112 - table_footer_line = $('#wpoptimize_table_list tbody:last'),
113 - tables_not_found = $('#wpoptimize_table_list_tables_not_found');
114 + var elTable = document.getElementById('wpoptimize_table_list');
114 115
115 - table_list.tablesorter({
116 - theme: 'default',
117 - widgets: ['zebra', 'rows', 'filter'],
118 - cssInfoBlock: "tablesorter-no-sort",
119 - // This option is to specify with columns will be disabled for sorting
120 - headers: {
121 - 2: {sorter: 'digit'},
122 - 3: {sorter: 'sizes'},
123 - 4: {sorter: 'sizes'},
124 - // For Column Action
125 - 7: {sorter: false }
126 - },
127 - widgetOptions: {
128 - // filter_anyMatch replaced! Instead use the filter_external option
129 - // Set to use a jQuery selector (or jQuery object) pointing to the
130 - // external filter (column specific or any match)
131 - filter_external: table_list_filter,
132 - // add a default type search to the second table column
133 - filter_defaultFilter: { 2 : '~{query}' }
116 + if (null === elTable) return;
117 +
118 + enhanceSortableAccessibility([elTable]);
119 +
120 + document.getElementById('wpoptimize_table_list_filter').addEventListener('input', function () {
121 + var filter = this.value.toLowerCase();
122 + var regex = new RegExp(filter, 'i');
123 + var tbody = elTable.querySelector('tbody');
124 + var tfoot = elTable.querySelector('tfoot');
125 + var rows = tbody.getElementsByTagName('tr');
126 + var hidden = 0;
127 +
128 + for (var i = 0; i < rows.length; i++) {
129 + var cell = rows[i].getElementsByTagName('td')[1];
130 + if (cell) {
131 + var value = cell.getAttribute('data-tablename');
132 + if (regex.test(value)) {
133 + rows[i].style.display = "";
134 + } else {
135 + rows[i].style.display = "none";
136 + hidden++;
137 + }
138 + }
134 139 }
135 - });
136 140
137 - /*
138 - * After tables filtered check if we need show table footer and No tables message.
139 - */
140 - table_list.on('filterEnd', function() {
141 - var search_value = table_list_filter.val().trim();
142 -
143 - if ('' == search_value) {
144 - table_footer_line.show();
141 + if (tfoot) tfoot.style.display = hidden > 0 ? "none" : "";
142 +
143 + var tables_not_found = document.getElementById('wpoptimize_table_list_tables_not_found');
144 +
145 + // Check if rows are visible
146 + if (hidden === rows.length) {
147 + tables_not_found.style.display = 'block';
145 148 } else {
146 - table_footer_line.hide();
149 + tables_not_found.style.display = 'none';
147 150 }
148 -
149 - if (0 == $('#the-list tr:visible', table_list).length) {
150 - tables_not_found.show();
151 - } else {
152 - tables_not_found.hide();
153 - }
151 +
154 152 });
155 153
156 154 /*
157 155 * Setup force optimization checkboxes and associated events
@@ -187,8 +185,12 @@
187 185
188 186 // Update single table optimization buttons state on load.
189 187 update_single_table_optimization_buttons(force_single_table_optimization);
190 188
189 + // Attach warning events
190 + add_warning_for_delete_post_meta_action();
191 + add_warning_for_delete_orphaned_relationship_data_action();
192 +
191 193 });
192 194
193 195 /**
194 196 * Temporarily show a dashboard notice, and then remove it. The HTML will be prepended to the .wrap.wp-optimize-wrap element.
@@ -277,8 +279,10 @@
277 279 // Trigger the global tab change events when changing page
278 280 var active_tab = $('.wpo-page[data-whichpage='+params.page+']').find('.nav-tab-wrapper .nav-tab-active');
279 281 $('#wp-optimize-wrap').trigger('tab-change', { page: params.page, tab: active_tab.data('tab') });
280 282 $('#wp-optimize-wrap').trigger('tab-change/'+params.page+'/'+active_tab.data('tab'), { content: $('#' + active_tab.attr('id') + '-contents')});
283 +
284 + maybe_show_too_many_tables_popup(active_tab.attr('data-tab'));
281 285 });
282 286
283 287 // set a time out, as needs to be done once the rest is loaded
284 288 setTimeout(function() {
@@ -296,9 +300,9 @@
296 300 if (!clicked_tab_id) { return; }
297 301
298 302 toggle_mobile_menu(false);
299 303 // Mobile menu TABS toggle
300 - if ($(this).is('[role="toggle-menu"]')) {
304 + if ($(this).is('[id^="wp-optimize-nav-tab-menu-"]')) {
301 305 toggle_mobile_menu(true);
302 306 return;
303 307 }
304 308
@@ -357,22 +361,24 @@
357 361
358 362 var database_tabs_loading = false;
359 363 var database_tabs_loaded = false;
360 364 // When showing the tables tab
361 - $('#wp-optimize-wrap').on('tab-change/WP-Optimize/tables', function(e) {
365 + $('#wp-optimize-wrap').on('tab-change/wpo_database/tables', function(e) {
362 366 get_database_tabs();
363 367 });
364 368
365 369 // When showing the optimizations tab
366 - $('#wp-optimize-wrap').on('tab-change/WP-Optimize/optimize', function(event, data) {
370 + $('#wp-optimize-wrap').on('tab-change/wpo_database/optimize', function(event, data) {
367 371 get_database_tabs();
368 372 });
369 373
374 +
370 375 // When showing the settings tab
371 376 $('#wp-optimize-wrap').on('tab-change/wpo_settings/settings', function(event, data) {
372 377 // If the innodb_force_optimize--container is present, fetch the required data.
373 378 // We load the database tabs together, as they need the same processing.
374 379 if (data.content.find('.innodb_force_optimize--container').length) get_database_tabs();
380 + WPO_Status_Report();
375 381 });
376 382
377 383 /**
378 384 * Get the data for the database tabs. We get them at the same time, as they both need the same time consuming requests.
@@ -378,9 +384,9 @@
378 384 * Get the data for the database tabs. We get them at the same time, as they both need the same time consuming requests.
379 385 */
380 386 function get_database_tabs() {
381 387 if (database_tabs_loading || database_tabs_loaded) return;
382 - var container = $('.wpo-page[data-whichpage=WP-Optimize]');
388 + var container = $('.wpo-page[data-whichpage=wpo_database]');
383 389 var shade = container.find('.wpo_shade');
384 390 shade.removeClass('hidden');
385 391 database_tabs_loading = true;
386 392 send_command('get_database_tabs', {}, function(response) {
@@ -386,16 +392,71 @@
386 392 send_command('get_database_tabs', {}, function(response) {
387 393 // Set the status to true, to prevent loading again.
388 394 database_tabs_loaded = true;
389 395
390 - // Updtate the optimizations tab
396 + // Update the optimizations tab
391 397 if (response.hasOwnProperty('optimizations')) {
392 398 container.find('.wp-optimize-optimizations-table-placeholder').replaceWith(response.optimizations);
393 399 }
394 400
395 - // Updtate the optimizations tables list
396 - update_tables_list(response);
401 + // If the batch table scan hasn't finished yet, trigger the loading popup so it
402 + // runs automatically. The popup will reload the page once the scan completes.
403 + if (true === response.scan_pending) {
404 + // Add a scan-first notice beneath the disabled "Optimize database tables" info.
405 + var $optimizeDbInfo = $('#optimization_info_optimizetables');
406 + if ($optimizeDbInfo.length) {
407 + $optimizeDbInfo.append(
408 + '<br><span class="wpo-scan-pending-notice">' +
409 + wpoptimize.db_tables_scan_pending_optimize + ' ' +
410 + '<a href="#" id="wpo-optimizations-tab-scan-link">' + wpoptimize.db_tables_scan_button + '</a>' +
411 + '</span>'
412 + );
413 + $('#wpo-optimizations-tab-scan-link').on('click', function(e) {
414 + e.preventDefault();
415 + var scanBtn = document.getElementById('wpo-load-tables-in-batches');
416 + if (scanBtn) scanBtn.click();
417 + });
418 + }
397 419
420 + // Replace the spinner placeholder in the tables tab with a scan-first notice.
421 + $('#wpoptimize_table_list tbody').html(
422 + '<tr>' +
423 + '<td></td>' +
424 + '<td colspan="6" style="text-align:center;padding:1em;">' +
425 + wpoptimize.db_tables_scan_pending_list + ' ' +
426 + '<a href="#" id="wpo-tables-tab-scan-link">' + wpoptimize.db_tables_scan_button + '</a>' +
427 + '</td>' +
428 + '<td></td>' +
429 + '</tr>'
430 + );
431 + $('#wpo-tables-tab-scan-link').on('click', function(e) {
432 + e.preventDefault();
433 + var scanBtn = document.getElementById('wpo-load-tables-in-batches');
434 + if (scanBtn) scanBtn.click();
435 + });
436 +
437 + var scanBtn = document.getElementById('wpo-load-tables-in-batches');
438 + if (scanBtn) {
439 + // If the onboarding wizard modal is currently open in the DOM, wait for it
440 + // to close before auto-clicking — otherwise the thickbox would stack on top.
441 + var onboardingRoot = document.getElementById('onboarding-modal-root');
442 + if (onboardingRoot && onboardingRoot.querySelector('[data-state="open"]')) {
443 + var scanObserver = new MutationObserver(function(mutations, obs) {
444 + if (!onboardingRoot.querySelector('[data-state="open"]')) {
445 + obs.disconnect();
446 + scanBtn.click();
447 + }
448 + });
449 + scanObserver.observe(onboardingRoot, { childList: true, subtree: true, attributes: true, attributeFilter: ['data-state'] });
450 + } else {
451 + scanBtn.click();
452 + }
453 + }
454 + } else {
455 + // Update the optimizations tables list
456 + update_tables_list(response);
457 + }
458 +
398 459 $(document).trigger('wpo_database_tabs_loaded');
399 460
400 461 }).always(function() {
401 462 database_tabs_loading = false;
@@ -412,18 +473,18 @@
412 473 */
413 474 function gather_settings(output_format) {
414 475 var form_data = '',
415 476 output_format = ('undefined' === typeof output_format) ? 'string' : output_format,
416 - $form_elements = $("#wp-optimize-database-settings form input[name!='action'], #wp-optimize-database-settings form select, #wp-optimize-database-settings form textarea, #wp-optimize-general-settings form input[name!='action'], #wp-optimize-general-settings form textarea, #wp-optimize-general-settings form select, #wp-optimize-nav-tab-contents-optimize input[type='checkbox'], .wp-optimize-nav-tab-contents input[name^='enable-auto-backup-']");
477 + $form_elements = $("#wp-optimize-database-settings form input[name!='action'], #wp-optimize-database-settings form select, #wp-optimize-database-settings form textarea, #wp-optimize-general-settings form input[name!='action'], #wp-optimize-general-settings form textarea, #wp-optimize-general-settings form select, #wp-optimize-nav-tab-contents-optimize input[type='checkbox'], .wp-optimize-nav-tab-contents input[name^='enable-auto-backup-'], #wpo-404-detector-form input[type=checkbox]");
417 478
418 479 if ('object' == output_format) {
419 480 form_data = $form_elements.serializeJSON({useIntKeysAsArrayIndex: true});
420 481 } else {
421 - // Excluding the unnecessary 'action' input avoids triggering a very mis-conceived mod_security rule seen on one user's site.
482 + // Excluding the unnecessary 'action' input avoids triggering a very misconceived mod_security rule seen on one user's site.
422 483 form_data = $form_elements.serialize();
423 484
424 485 // Include unchecked checkboxes. user filter to only include unchecked boxes.
425 - $.each($('#wp-optimize-database-settings form input[type=checkbox], #wp-optimize-general-settings form input[type=checkbox], .wp-optimize-nav-tab-contents input[name^="enable-auto-backup-"]')
486 + $.each($('#wp-optimize-database-settings form input[type=checkbox], #wp-optimize-general-settings form input[type=checkbox], .wp-optimize-nav-tab-contents input[name^="enable-auto-backup-"], #wpo-404-detector-form input[type=checkbox]')
426 487 .filter(function (idx) {
427 488 return $(this).prop('checked') == false
428 489 }),
429 490 function (idx, el) {
@@ -565,19 +626,21 @@
565 626 if (response.hasOwnProperty('total_size')) {
566 627 $('#optimize_current_db_size').html(response.total_size);
567 628 }
568 629
569 - // Status check for optimizing tables.
570 - const optimizetables_id = "optimizetables";
571 - if (queue.contains_id(optimizetables_id)) {
572 - $('#optimization_checkbox_' + optimizetables_id).hide();
573 - $('#optimization_spinner_' + optimizetables_id).show();
574 - $('.optimization_button_' + optimizetables_id).prop('disabled', true);
575 - } else {
576 - $('#optimization_checkbox_' + optimizetables_id).show();
577 - $('#optimization_spinner_' + optimizetables_id).hide();
578 - $('.optimization_button_' + optimizetables_id).prop('disabled', false);
579 - $('#optimization_info_' + optimizetables_id).html(wpoptimize.optimization_complete + (optimization_logged_warnings ? (' ' + wpoptimize.with_warnings) : ''));
630 + if ('optimizetables' === id) {
631 + // Status check for optimizing tables.
632 + const optimizetables_id = "optimizetables";
633 + if (queue.contains_id(optimizetables_id)) {
634 + $('#optimization_checkbox_' + optimizetables_id).hide();
635 + $('#optimization_spinner_' + optimizetables_id).show();
636 + $('.optimization_button_' + optimizetables_id).prop('disabled', true);
637 + } else {
638 + $('#optimization_checkbox_' + optimizetables_id).show();
639 + $('#optimization_spinner_' + optimizetables_id).hide();
640 + $('.optimization_button_' + optimizetables_id).prop('disabled', false);
641 + $('#optimization_info_' + optimizetables_id).html(wpoptimize.optimization_complete + (optimization_logged_warnings ? (' ' + wpoptimize.with_warnings) : ''));
642 + }
580 643 }
581 644
582 645 // check if we need update unapproved comments count.
583 646 if (response.result.meta && response.result.meta.hasOwnProperty('awaiting_mod')) {
@@ -766,9 +829,9 @@
766 829
767 830 /*
768 831 * Run single optimization click.
769 832 */
770 - $('#wp-optimize-nav-tab-WP-Optimize-optimize-contents').on('click', 'button.wp-optimize-settings-optimization-run-button', function () {
833 + $('#wp-optimize-nav-tab-wpo_database-optimize-contents').on('click', 'button.wp-optimize-settings-optimization-run-button', function () {
771 834 var optimization_id = $(this).closest('.wp-optimize-settings').data('optimization_id');
772 835 if (!optimization_id) {
773 836 console.log("Optimization ID corresponding to pressed button not found");
774 837 return;
@@ -786,22 +849,247 @@
786 849
787 850 /*
788 851 * Run all optimizations click.
789 852 */
790 - $('#wp-optimize-nav-tab-WP-Optimize-optimize-contents').on('click', '#wp-optimize', function (e) {
791 - var run_btn = $(this);
853 + $('#wp-optimize-nav-tab-wpo_database-optimize-contents #wp-optimize').on('click', function (e) {
854 + e.preventDefault();
855 +
856 + if (null == tmpl_wpo_grouped_warnings_tpl) {
857 + tmpl_wpo_grouped_warnings_tpl = $('#tmpl-wpo-grouped-warnings').html().toString();
858 + }
792 859
793 - e.preventDefault();
860 + user_confirm_destructive_actions(function() {
861 + return function(run_btn) {
862 + // disable run button to avoid double click.
863 + $(run_btn).prop('disabled', true);
864 + save_sites_list_and_do_action(function() {
865 + $(run_btn).prop('disabled', false);
866 + run_optimizations();
867 + });
868 + };
869 + }(this));
870 + });
794 871
795 - // disable run button to avoid double click.
796 - run_btn.prop('disabled', true);
797 - save_sites_list_and_do_action(function() {
798 - run_btn.prop('disabled', false);
799 - run_optimizations();
872 + var tmpl_wpo_grouped_warnings_tpl = null;
873 +
874 + /**
875 + * Prepare the stack of optimizations that the user will need to actively confirm using the popup
876 + * Then show them in sequence
877 + */
878 + function user_confirm_destructive_actions(callback) {
879 + var optimizations = $('#optimizations_list .optimization_checkbox:checked');
880 +
881 + var confirmations_stack = [];
882 +
883 + optimizations.filter(function(i, optim) {
884 + var optimization_id = optim.id.replace('optimization_checkbox_', '');
885 + var destructive_action_popup = $('#tmpl-wpo-' + optimization_id);
886 + return 0 < destructive_action_popup.length;
887 + }).each(function(i, maybe_confirm) {
888 + var optimization_id = maybe_confirm.id.replace('optimization_checkbox_', '');
889 + if (should_user_confirm_action(optimization_id)) {
890 + confirmations_stack.push(optimization_id);
891 + }
800 892 });
801 - });
893 +
894 + user_confirm_destructive_actions_grouped(confirmations_stack, callback);
895 + }
802 896
803 897 /**
898 + * Show confirmation popups for user to accept, in sequence. When done, trigger callback
899 + */
900 + function user_confirm_destructive_actions_grouped(confirmations_stack, callback) {
901 + if (0 < confirmations_stack.length) {
902 + var warning_messages = [];
903 + confirmations_stack.forEach(function(optimization_id) {
904 + var str = $($('#tmpl-wpo-' + optimization_id).html()).children('p').html();
905 + warning_messages.push(str);
906 + });
907 +
908 + wp_optimize.modal.open(
909 + Object.assign(get_destructive_actions_confirm_popup('grouped-warnings'), {
910 + cancel: function() {
911 + // Nothing will be done
912 + },
913 + confirm: function() {
914 + this.close();
915 + callback();
916 + },
917 + content: function() {
918 + return tmpl_wpo_grouped_warnings_tpl.replace('[[warning_messages]]', "<ul><li>" + warning_messages.join("</li><li>") + "</li></ul>");
919 + }
920 + }
921 + ));
922 + } else {
923 + // No confirmations needed
924 + callback();
925 + }
926 + }
927 +
928 + /**
929 + * Pad a string to the left
930 + *
931 + * @param {string} string The string we want to pad
932 + * @param {string} pad Padding character
933 + * @param {int} length Padding length
934 + * @returns string
935 + */
936 + function str_pad_left(string, pad, length) {
937 + return (new Array(length + 1).join(pad) + string).slice(-length);
938 + }
939 +
940 + /**
941 + * Shared state for the "load database tables in batches" feature
942 + *
943 + * @var {object}
944 + */
945 + var wpoDBTableInfo = {
946 + progressText: [],
947 + startTime: null,
948 + updateTimeout: null,
949 + inProgress: false
950 + };
951 +
952 + /**
953 + * Call AJAX command to load table statuses in batches
954 + *
955 + * @param {int} offset Query offset
956 + * @param {bool} start_clean True when this is the first time the function is called
957 + * @param {function} callback Self referenced callback, recursively calls itself until the work is done
958 + * @returns void
959 + */
960 + function load_tables_in_batches(offset, start_clean, callback) {
961 + var e = $("#wpo-load-tables-in-batches-progress");
962 + var limit = parseInt(wpoptimize.high_table_count_threshold);
963 + var start = offset + 1;
964 + var end = offset + limit;
965 +
966 + var progress_text = wpoptimize.loading_tables_in_batches.replace('%1$s', start).replace('%2$s', end);
967 +
968 + if (start_clean || (-1 == wpoDBTableInfo.progressText.indexOf(progress_text))) {
969 + wpoDBTableInfo.progressText.push(progress_text);
970 + e.append($("<div>" + progress_text + "...</div>"));
971 + }
972 +
973 + if (5 < e.children().length) {
974 + e.children()[0].remove();
975 + }
976 +
977 + var spinner = '<img class="wpo-v-middle" height=16 src="'+wpoptimize.spinner_src+'">';
978 + var time_left_container = $('#wpo-load-tables-eta');
979 + if (true == start_clean) {
980 + time_left_container.html(spinner);
981 + }
982 +
983 + send_command('load_tables_in_batches', {offset: offset}, function(result) {
984 + var now = new Date();
985 +
986 + var time_left = 1 <= result.done ? parseInt(((now - wpoDBTableInfo.startTime) / 1000) / result.done * (result.total - result.done)) : 600;
987 + var minutesNum = Math.floor(time_left / 60);
988 + var minutes = str_pad_left(minutesNum, '0', 2);
989 + var seconds = str_pad_left(time_left - minutesNum * 60, '0', 2);
990 +
991 + time_left_container.html(wpoptimize.time_left.replace('%s', '<span id="wpo-load-tables-time-left" rel="' + time_left + '">' + minutes + ':' + seconds + '</span>') + ' ' + spinner);
992 +
993 + if (null != wpoDBTableInfo.updateTimeout) {
994 + clearTimeout(wpoDBTableInfo.updateTimeout);
995 + }
996 +
997 + if (true == result.continue) {
998 + wpoDBTableInfo.updateTimeout = setTimeout(load_tables_update_time_left, 1000);
999 +
1000 + callback(result.done, false, callback);
1001 + } else {
1002 + e.html(wpoptimize.done_reloading + '...');
1003 + time_left_container.html('');
1004 + clearTimeout(wpoDBTableInfo.updateTimeout);
1005 + location.reload();
1006 + }
1007 + }).fail(function() {
1008 + if (null != wpoDBTableInfo.updateTimeout) {
1009 + clearTimeout(wpoDBTableInfo.updateTimeout);
1010 + }
1011 + time_left_container.html('');
1012 + e.append($("<div>" + wpoptimize.something_wrong_try_again + "</div>"));
1013 +
1014 + wpoDBTableInfo.inProgress = false;
1015 + $('#wpo-load-tables-in-batches-button').prop('disabled', false);
1016 + });
1017 + }
1018 +
1019 + /**
1020 + * While AJAX operation runs in background, update time left every second in front-end
1021 + *
1022 + * @returns void
1023 + */
1024 + function load_tables_update_time_left() {
1025 + var time_left_container = $('#wpo-load-tables-time-left');
1026 + var current_time_left = Math.max(0, parseInt(time_left_container.attr('rel')) - 1);
1027 +
1028 + var minutesNum = Math.floor(current_time_left / 60);
1029 + var minutes = str_pad_left(minutesNum, '0', 2);
1030 + var seconds = str_pad_left(current_time_left - minutesNum * 60, '0', 2);
1031 +
1032 + time_left_container.html(minutes + ':' + seconds);
1033 + time_left_container.attr('rel', current_time_left);
1034 +
1035 + wpoDBTableInfo.updateTimeout = setTimeout(load_tables_update_time_left, 1000);
1036 + }
1037 +
1038 + /**
1039 + * Check if we need to show the table load popup and show it
1040 + * Skips auto-opening while the onboarding wizard is active.
1041 + *
1042 + * @param {string} active_tab Only show popup when active_tab='optimize'
1043 + * @returns void
1044 + */
1045 + function maybe_show_too_many_tables_popup(active_tab) {
1046 +
1047 + var $modal = $('#wpo-too-many-tables-popup');
1048 +
1049 + function openTooManyTablesModal(autoShown) {
1050 + // Move the modal to <body> so it isn't hidden by a display:none tab wrapper.
1051 + if (!$modal.parent().is('body')) {
1052 + $('body').append($modal);
1053 + }
1054 + $modal.show();
1055 + $('body').addClass('wpo-modal-is-opened');
1056 + var $closeBtn = $modal.find('.wpo-too-many-tables-close');
1057 + var $bg = $modal.find('.wpo-modal--bg');
1058 + $closeBtn.off('click.wpoModal');
1059 + $bg.off('click.wpoModal');
1060 + if (autoShown) {
1061 + $closeBtn.on('click.wpoModal', function() { location.href = 'plugins.php'; });
1062 + } else {
1063 + $closeBtn.add($bg).on('click.wpoModal', function() {
1064 + $modal.hide();
1065 + $('body').removeClass('wpo-modal-is-opened');
1066 + });
1067 + }
1068 + }
1069 +
1070 + if ('optimize' === active_tab && 'undefined' !== typeof wpo_too_many_tables && true === wpo_too_many_tables && 'undefined' !== typeof wpo_onboarding_active && true !== wpo_onboarding_active) {
1071 + $(document).ready(function() { openTooManyTablesModal(true); });
1072 + }
1073 +
1074 + $('#wpo-load-tables-in-batches').off('click.wpoLoadTablesModal').on('click.wpoLoadTablesModal', function() {
1075 + openTooManyTablesModal(false);
1076 + });
1077 +
1078 + $('#wpo-load-tables-in-batches-button').off('click.wpoLoadTablesInBatches').on('click.wpoLoadTablesInBatches', function() {
1079 + if (wpoDBTableInfo.inProgress) return;
1080 +
1081 + wpoDBTableInfo.inProgress = true;
1082 + $(this).prop('disabled', true);
1083 + wpoDBTableInfo.startTime = new Date();
1084 +
1085 + load_tables_in_batches(wpo_table_scan_offset, true, function() {
1086 + load_tables_in_batches.apply({}, arguments);
1087 + });
1088 + });
1089 + }
1090 +
1091 + /**
804 1092 * Sent command to run selected optimizations and auto backup if selected
805 1093 *
806 1094 * @return void
807 1095 */
@@ -884,16 +1172,15 @@
884 1172 wpo_settings_all_sites_checkbox,
885 1173 wpo_settings_sites_list_items
886 1174 );
887 1175
888 - var sites_list_clicked_count = 0;
1176 + var debounceTimer;
889 1177
890 1178 $([wpo_settings_all_sites_checkbox, wpo_settings_sites_list_items]).each(function() {
891 1179 $(this).on('change', function() {
892 - sites_list_clicked_count++;
893 - setTimeout(function() {
894 - sites_list_clicked_count--;
895 - if (sites_list_clicked_count == 0) update_optimizations_info();
1180 + clearTimeout(debounceTimer);
1181 + debounceTimer = setTimeout(function() {
1182 + update_optimizations_info();
896 1183 }, 1000);
897 1184 });
898 1185 });
899 1186
@@ -997,27 +1284,20 @@
997 1284 *
998 1285 * @return {[type]} optimizations
999 1286 */
1000 1287 function run_optimization() {
1001 - $optimizations = $('#optimizations_list .optimization_checkbox:checked');
1288 + var optimizations = $('#optimizations_list .optimization_checkbox:checked').toArray();
1002 1289
1003 - $optimizations.sort(function (a, b) {
1004 - // Convert to IDs.
1005 - a = $(a).closest('.wp-optimize-settings').data('optimization_run_sort_order');
1006 - b = $(b).closest('.wp-optimize-settings').data('optimization_run_sort_order');
1007 - if (a > b) {
1008 - return 1;
1009 - } else if (a < b) {
1010 - return -1;
1011 - } else {
1012 - return 0;
1013 - }
1290 + var sorted_optimizations = optimizations.sort(function (a, b) {
1291 + var aOrder = $(a).closest('.wp-optimize-settings').data('optimization_run_sort_order');
1292 + var bOrder = $(b).closest('.wp-optimize-settings').data('optimization_run_sort_order');
1293 + return aOrder - bOrder; // Ascending order - so all other optimizations will run before optimizetables
1014 1294 });
1015 1295
1016 1296 var optimization_options = {};
1017 1297
1018 - $optimizations.each(function (index) {
1019 - var optimization_id = $(this).closest('.wp-optimize-settings').data('optimization_id');
1298 + sorted_optimizations.forEach(function (element) {
1299 + var optimization_id = $(element).closest('.wp-optimize-settings').data('optimization_id');
1020 1300 if (!optimization_id) {
1021 1301 console.log("Optimization ID corresponding to pressed button not found");
1022 1302 return;
1023 1303 }
@@ -1043,8 +1323,9 @@
1043 1323 };
1044 1324
1045 1325 // update body with new content.
1046 1326 $("#wpoptimize_table_list tbody").remove();
1327 + $("#wpoptimize_table_list tfoot").remove();
1047 1328 $("#wpoptimize_table_list thead").after(response.table_list);
1048 1329
1049 1330 $("#wpoptimize_table_list").trigger("updateAll", [resort, callback]);
1050 1331 }
@@ -1062,8 +1343,14 @@
1062 1343 }
1063 1344
1064 1345 $('#wp_optimize_table_list_refresh').on('click', function (e) {
1065 1346 e.preventDefault();
1347 + // Tables are not available until the batch scan completes — open the scan popup instead.
1348 + if (true === wpo_too_many_tables) {
1349 + var scanBtn = document.getElementById('wpo-load-tables-in-batches');
1350 + if (scanBtn) scanBtn.click();
1351 + return;
1352 + }
1066 1353 var shade = $(this).closest('.wpo-tab-postbox').find('.wpo_shade');
1067 1354 shade.removeClass('hidden');
1068 1355 $('#wpoptimize_table_list tbody').css('opacity', '0.5');
1069 1356 send_command('get_table_list', {refresh_plugin_json: true}, update_tables_list).always(function() {
@@ -1070,10 +1357,26 @@
1070 1357 shade.addClass('hidden');
1071 1358 });
1072 1359 });
1073 1360
1074 - $('#database_settings_form, #settings_form').on('click', '.wpo-save-settings', function (e) {
1361 + $('#wpo-404-detector-form').on('click', '#wpo-404-clear-logs', function (e) {
1075 1362 e.preventDefault();
1363 + block_ui(wpoptimize.please_wait);
1364 + send_command('truncate_404_logs', {}, function (resp) {
1365 + if (resp && resp.hasOwnProperty('success') && resp.success) {
1366 + $('#wpo_404_detector_results').html('');
1367 + }
1368 + if (resp && resp.hasOwnProperty('message') && resp.message) {
1369 + block_ui(resp.message, {}, 3000);
1370 + }
1371 + }).fail(function() {
1372 + block_ui(wpoptimize.something_wrong_try_again, {}, 3000);
1373 + });
1374 + });
1375 +
1376 +
1377 + $('#database_settings_form, #settings_form, #wpo-404-detector-form').on('click', '.wpo-save-settings', function (e) {
1378 + e.preventDefault();
1076 1379 var form = $(this).closest('form');
1077 1380 var spinner = form.find('.wpo-saving-settings');
1078 1381 var form_data = gather_settings();
1079 1382
@@ -1122,8 +1425,9 @@
1122 1425 }
1123 1426
1124 1427 if (resp && resp.hasOwnProperty('settings_auto_cleanup_contents')) {
1125 1428 $('#wpo_auto_cleanup').replaceWith(resp.settings_auto_cleanup_contents);
1429 + WPO_Select2();
1126 1430 }
1127 1431
1128 1432 if (resp && resp.hasOwnProperty('logging_settings_contents')) {
1129 1433 $('#wpo_logging_settings').replaceWith(resp.logging_settings_contents);
@@ -1128,8 +1432,14 @@
1128 1432 if (resp && resp.hasOwnProperty('logging_settings_contents')) {
1129 1433 $('#wpo_logging_settings').replaceWith(resp.logging_settings_contents);
1130 1434 }
1131 1435
1436 + // switch for visibility (performance tab).
1437 + var $wpo_404_detector_btn = $('#wpo_404_detector');
1438 + $wpo_404_detector_btn.prop('checked', !$wpo_404_detector_btn.prop('checked'));
1439 + var $wpo_404_detector_results = $('#wpo_404_detector_results');
1440 + $wpo_404_detector_results.css('display', $wpo_404_detector_btn.prop('checked') ? 'block' : 'none');
1441 +
1132 1442 // Need to refresh the page if enable-admin-menu tick state has changed.
1133 1443 if (resp.save_results.refresh) {
1134 1444 location.reload();
1135 1445 }
@@ -1230,8 +1540,9 @@
1230 1540 btn.prop('disabled', false);
1231 1541 spinner.addClass('visibility-hidden');
1232 1542 action_done_icon.show().removeClass('visibility-hidden').delay(2500).fadeOut('fast', function() {
1233 1543 btn.show();
1544 + action_done_icon.show().addClass('visibility-hidden');
1234 1545 });
1235 1546 });
1236 1547 }
1237 1548
@@ -1304,9 +1615,9 @@
1304 1615 for (i in response) {
1305 1616 if (!response.hasOwnProperty(i)) continue;
1306 1617
1307 1618 dom_id = ['#wp-optimize-settings-', response[i].dom_id].join('');
1308 - info = response[i].info ? response[i].info.join('<br>') : '';
1619 + info = response[i].info ? response[i].info : '';
1309 1620
1310 1621 $(dom_id + ' .wp-optimize-settings-optimization-info').html(info);
1311 1622 }
1312 1623 }
@@ -1539,9 +1850,9 @@
1539 1850 // Handle delete table click
1540 1851 $('#wpoptimize_table_list').on('click', '.run-single-table-delete', function () {
1541 1852 table_to_remove_btn = $(this);
1542 1853 var take_backup_checkbox = $('#enable-auto-backup-1');
1543 - if ('' == wpoptimize.user_always_ignores_table_delete_warning || '1' !== wpoptimize.user_always_ignores_table_delete_warning) {
1854 + if ('' == wpoptimize.user_always_ignores_table_deletion_warning || '1' !== wpoptimize.user_always_ignores_table_deletion_warning) {
1544 1855 wp_optimize.modal.open({
1545 1856 className: 'wpo-confirm',
1546 1857 events: {
1547 1858 'click .wpo-modal--bg': 'close',
@@ -1572,13 +1883,13 @@
1572 1883 this.$('.delete-table').prop('disabled', !enable_button);
1573 1884 },
1574 1885 deleteTable: function() {
1575 1886 // check if user ignore table warning
1576 - var ignores_table_detele_warning_checkbox = this.$('#ignores_table_delete_warning');
1577 - if (ignores_table_detele_warning_checkbox.is(':checked')) {
1578 - send_command('user_ignores_table_delete_warning', {}, function(response) {
1887 + var ignores_table_deletion_warning_checkbox = this.$('#ignores_table_deletion_warning');
1888 + if (ignores_table_deletion_warning_checkbox.is(':checked')) {
1889 + send_command('user_ignores_table_deletion_warning', {}, function(response) {
1579 1890 if (response.success) {
1580 - wpoptimize.user_always_ignores_table_delete_warning = '1';
1891 + wpoptimize.user_always_ignores_table_deletion_warning = '1';
1581 1892 }
1582 1893 });
1583 1894 }
1584 1895 // check if backup checkbox is checked for db tables
@@ -1659,9 +1970,9 @@
1659 1970
1660 1971
1661 1972
1662 1973 /**
1663 - * Send ajax commant to remove single database table.
1974 + * Send ajax command to remove single database table.
1664 1975 *
1665 1976 * @param {Object} btn jQuery object of clicked "Remove" button.
1666 1977 *
1667 1978 * @return void
@@ -1834,9 +2145,9 @@
1834 2145
1835 2146 /**
1836 2147 * Hide introduction notice
1837 2148 */
1838 - $('.wpo-introduction-notice .notice-dismiss, .wpo-introduction-notice .close').on('click', function(e) {
2149 + $('#wp-optimize-wrap').on('click', '.wpo-introduction-notice .notice-dismiss, .wpo-introduction-notice .close', function(e) {
1839 2150 $('.wpo-introduction-notice').remove();
1840 2151 send_command('dismiss_install_or_update_notice', null, function (resp) {
1841 2152 if (resp && resp.hasOwnProperty('error')) {
1842 2153 // there was an error.
@@ -1861,20 +2172,16 @@
1861 2172 read_settings_json_file(wpo_import_file_input.files[0]);
1862 2173 });
1863 2174
1864 2175 /**
1865 - * Export plugin settings as a JSON file
2176 + * Pack WPO settings into a single object
1866 2177 *
1867 - * @param {object} e - Event object
1868 - *
1869 - * @return {void}
2178 + * @return {object}
1870 2179 */
1871 - function export_settings(e) {
1872 - e.preventDefault();
1873 -
2180 + function build_settings() {
1874 2181 var date_now = new Date();
1875 2182
1876 - form_data = JSON.stringify({
2183 + return {
1877 2184 epoch_date: date_now.getTime(),
1878 2185 local_date: date_now.toLocaleString(),
1879 2186 network_site_url: wpoptimize.network_site_url,
1880 2187 data: {
@@ -1882,10 +2189,23 @@
1882 2189 minify_settings: wp_optimize.minify_settings(),
1883 2190 smush_settings: wp_optimize.smush_settings(),
1884 2191 database_settings: gather_settings('string')
1885 2192 }
1886 - });
2193 + };
2194 + }
1887 2195
2196 + /**
2197 + * Export plugin settings as a JSON file
2198 + *
2199 + * @param {object} e - Event object
2200 + *
2201 + * @return {void}
2202 + */
2203 + function export_settings(e) {
2204 + e.preventDefault();
2205 +
2206 + form_data = JSON.stringify(build_settings());
2207 +
1888 2208 // Attach this data to an anchor on page
1889 2209 var link = document.body.appendChild(document.createElement('a'));
1890 2210 link.setAttribute('download', wpoptimize.export_settings_file_name);
1891 2211 link.setAttribute('style', "display:none;");
@@ -1947,8 +2267,173 @@
1947 2267 $.unblockUI();
1948 2268 }
1949 2269 }
1950 2270
2271 + /**
2272 + * Define popup for each optimization action that needs confirmation from user
2273 + */
2274 + function get_destructive_actions_confirm_popup(action) {
2275 + var popups = destructive_actions_confirm_popup = {
2276 + postmeta: {
2277 + className: 'wpo-confirm',
2278 + events: {
2279 + 'click .wpo-modal--bg': 'close',
2280 + 'click #confirm_post_meta_deletion': 'deleteConfirm',
2281 + 'click .cancel': 'cancel',
2282 + 'click #confirm-post-meta-delete-action': 'confirm'
2283 + },
2284 + content: function() {
2285 + var content_template = wp.template('wpo-postmeta');
2286 + return content_template({});
2287 + },
2288 + deleteConfirm: function() {
2289 + var enable_button = $('#confirm_post_meta_deletion').is(':checked');
2290 + $('.delete-post-meta').prop('disabled', !enable_button);
2291 + }
2292 + },
2293 + orphandata: {
2294 + className: 'wpo-confirm',
2295 + events: {
2296 + 'click .wpo-modal--bg': 'close',
2297 + 'click #confirm_orphaned_relationship_data_deletion': 'deleteConfirm',
2298 + 'click .cancel': 'cancel',
2299 + 'click #confirm-orphaned-relationship-data-delete-action': 'confirm'
2300 + },
2301 + content: function() {
2302 + var content_template = wp.template('wpo-orphandata');
2303 + return content_template({});
2304 + },
2305 + deleteConfirm: function() {
2306 + var enable_button = $('#confirm_orphaned_relationship_data_deletion').is(':checked');
2307 + $('.delete-orphaned-relationship-data').prop('disabled', !enable_button);
2308 + }
2309 + },
2310 + "grouped-warnings": {
2311 + className: 'wpo-confirm',
2312 + events: {
2313 + 'click .wpo-modal--bg': 'close',
2314 + 'click #confirm_grouped_warnings_data_deletion': 'deleteConfirm',
2315 + 'click .cancel': 'cancel',
2316 + 'click #confirm-grouped-warnings-data-delete-action': 'confirm'
2317 + },
2318 + deleteConfirm: function() {
2319 + var enable_button = $('#confirm_grouped_warnings_data_deletion').is(':checked');
2320 + $('.delete-grouped-warnings-data').prop('disabled', !enable_button);
2321 + }
2322 + }
2323 + }
2324 +
2325 + return popups[action];
2326 + }
2327 +
2328 + /**
2329 + * Attach click event to postmeta checkbox
2330 + */
2331 + function add_warning_for_delete_post_meta_action() {
2332 + $('#optimization_button_postmeta_big').on('click', function (evt) {
2333 + return function(this_button) {
2334 + var remove_post_meta_checkbox = $('#optimization_checkbox_postmeta');
2335 +
2336 + if (should_user_confirm_action('postmeta')) {
2337 + wp_optimize.modal.open(
2338 + Object.assign(get_destructive_actions_confirm_popup('postmeta'), {
2339 + cancel: function() {
2340 + $(remove_post_meta_checkbox).prop('checked', false);
2341 + },
2342 + confirm: function() {
2343 + maybe_dismiss_destructive_actions();
2344 + this.close();
2345 +
2346 + $(this_button).prop('bypass-confirm-box', true);
2347 + $(this_button).trigger('click');
2348 +
2349 + }
2350 + }
2351 + ));
2352 +
2353 + evt.preventDefault();
2354 + return false;
2355 + } else {
2356 + $(this_button).prop('bypass-confirm-box', false);
2357 + return true;
2358 + }
2359 + }(this);
2360 + });
2361 + }
2362 +
2363 + /**
2364 + * Check if dismiss future confirms checkbox is visible and selected, then save option in DB
2365 + */
2366 + function maybe_dismiss_destructive_actions() {
2367 + var ignores_orphaned_relationship_data_delete_warning_checkbox = $('#ignores_orphaned_relationship_data_deletion_warning');
2368 + if (ignores_orphaned_relationship_data_delete_warning_checkbox.is(':visible') && ignores_orphaned_relationship_data_delete_warning_checkbox.is(':checked')) {
2369 + send_command('user_ignores_orphaned_relationship_data_deletion_warning', {}, function(response) {
2370 + if (response.success) {
2371 + wpoptimize.user_always_ignores_orphaned_relationship_data_deletion_warning = '1';
2372 + }
2373 + });
2374 + }
2375 +
2376 + var ignores_post_meta_deletion_warning_checkbox = $('#ignores_post_meta_deletion_warning');
2377 + if (ignores_post_meta_deletion_warning_checkbox.is(':visible') && ignores_post_meta_deletion_warning_checkbox.is(':checked')) {
2378 + send_command('user_ignores_post_meta_deletion_warning', {}, function(response) {
2379 + if (response.success) {
2380 + wpoptimize.user_always_ignores_post_meta_deletion_warning = '1';
2381 + }
2382 + });
2383 + }
2384 + }
2385 +
2386 + /**
2387 + * Check if user dismissed confirms, or should they see the confirm popup
2388 + */
2389 + function should_user_confirm_action(action) {
2390 + if ('orphandata' == action) {
2391 + var bypass_confirm = $('#optimization_button_orphandata_big').prop('bypass-confirm-box') == true;
2392 +
2393 + return !bypass_confirm && ('' == wpoptimize.user_always_ignores_orphaned_relationship_data_deletion_warning || '1' !== wpoptimize.user_always_ignores_orphaned_relationship_data_deletion_warning);
2394 + } else if ('postmeta' == action) {
2395 + var bypass_confirm = $('#optimization_button_postmeta_big').prop('bypass-confirm-box') == true;
2396 +
2397 + return !bypass_confirm && ('' == wpoptimize.user_always_ignores_post_meta_deletion_warning || '1' !== wpoptimize.user_always_ignores_post_meta_deletion_warning);
2398 + }
2399 + }
2400 +
2401 + /**
2402 + * Attach click event to orphandata optimization checkbox
2403 + */
2404 + function add_warning_for_delete_orphaned_relationship_data_action() {
2405 + $('#optimization_button_orphandata_big').on('click', function (evt) {
2406 + return function(this_button) {
2407 + var remove_orphaned_relationship_data_checkbox = $('#optimization_checkbox_orphandata');
2408 +
2409 + if (should_user_confirm_action('orphandata')) {
2410 + wp_optimize.modal.open(
2411 + Object.assign(get_destructive_actions_confirm_popup('orphandata'), {
2412 + cancel: function() {
2413 + $(remove_orphaned_relationship_data_checkbox).prop('checked', false);
2414 + },
2415 + confirm: function() {
2416 + maybe_dismiss_destructive_actions();
2417 +
2418 + this.close();
2419 +
2420 + $(this_button).prop('bypass-confirm-box', true);
2421 + $(this_button).trigger('click');
2422 + }
2423 + }
2424 + ));
2425 +
2426 + evt.preventDefault();
2427 + return false;
2428 + } else {
2429 + $(this_button).prop('bypass-confirm-box', false);
2430 + return true;
2431 + }
2432 + }(this);
2433 + });
2434 + }
2435 +
1951 2436 // Attach heartbeat API events
1952 2437 heartbeat.setup();
1953 2438
1954 2439 return {
@@ -1954,13 +2439,62 @@
1954 2439 return {
1955 2440 send_command: send_command,
1956 2441 optimization_get_info: optimization_get_info,
1957 2442 take_a_backup_with_updraftplus: take_a_backup_with_updraftplus,
1958 - save_auto_backup_options: save_auto_backup_options
2443 + save_auto_backup_options: save_auto_backup_options,
2444 + build_settings: build_settings
1959 2445 }
1960 2446 }; // END function WP_Optimize()
1961 2447
2448 +/**
2449 + * Init Select2 Library
2450 + */
2451 +var WPO_Select2 = function () {
2452 + if ('function' === typeof jQuery.fn.select2) {
2453 + jQuery(".wpo-select2").not('.select2-hidden-accessible').select2();
2454 + }
2455 +}
2456 +
2457 +/**
2458 + * Init Tooltip Library
2459 + */
2460 +var WPO_Tooltip = function () {
2461 + if ('function' === typeof jQuery.fn.tooltip) {
2462 + jQuery(".wpo-tooltip").tooltip({
2463 + items: "[data-tooltip]",
2464 + content: function() {
2465 + return jQuery('<span>').text(jQuery(this).attr("data-tooltip"));
2466 + },
2467 + position: {
2468 + my: "center bottom",
2469 + at: "center top",
2470 + collision: "flipfit"
2471 + },
2472 + open: function(event, ui) {
2473 + jQuery(".wpo-tooltip").not(this).tooltip("close");
2474 + }
2475 + });
2476 +
2477 + // New: explicit outside-tap/click close, since jQuery UI has no touch equivalent of mouseleave/focusout
2478 + jQuery(document).on("touchstart click", function(e) {
2479 + if (!jQuery(e.target).closest("[data-tooltip], .ui-tooltip").length) {
2480 + jQuery(".wpo-tooltip").each(function() {
2481 + var $el = jQuery(this);
2482 + if ($el.data("ui-tooltip")) {
2483 + $el.tooltip("close");
2484 + }
2485 + });
2486 + }
2487 + });
2488 + }
2489 +}
2490 +
1962 2491 jQuery(function ($) {
2492 +
2493 + WPO_Tooltip();
2494 +
2495 + WPO_Select2();
2496 +
1963 2497 /**
1964 2498 * Show additional options section if optimization enabled
1965 2499 *
1966 2500 * @param {string} checkbox Logger settings jQuery checkbox object.
@@ -1995,8 +2529,10 @@
1995 2529 e.preventDefault();
1996 2530 $('#wp-optimize-logger-settings .save_settings_reminder').after(get_add_logging_form_html());
1997 2531
1998 2532 filter_select_destinations($('.wpo_logger_type').first());
2533 +
2534 + WPO_Select2();
1999 2535 });
2000 2536
2001 2537 /**
2002 2538 * Handle logging destination select change.
@@ -2170,9 +2706,9 @@
2170 2706 }
2171 2707
2172 2708 return [
2173 2709 '<div class="wpo_add_logger_form">',
2174 - '<select class="wpo_logger_type" name="wpo-logger-type[]">',
2710 + '<select class="wpo_logger_type wpo-select2" name="wpo-logger-type[]">',
2175 2711 select_options.join(''),
2176 2712 '</select>',
2177 2713 '<div class="wpo_logging_edit_row" style="display:block;"><span class="wpo_delete_logger button button-secondary" title="'+wpoptimize.cancel+'">'+wpoptimize.cancel+'</span>',
2178 2714 '<span class="wpo_save_logging button button-primary" title="'+wpoptimize.add+'">'+wpoptimize.add+'</span></div>',
@@ -2250,6 +2786,12 @@
2250 2786 $iframe.insertAfter($(this));
2251 2787 $(this).remove();
2252 2788 $iframe.focus();
2253 2789 }
2790 + });
2791 +
2792 + // Show/hide Enable the caching menu in the admin bar on cache/minify status change
2793 + $(document).on('wp-optimize/cache/toggle-status wp-optimize/minify/toggle-status', function() {
2794 + var minify_or_cache_enabled = $('#wpo_min_enable_minify').prop('checked') || $('#enable_page_caching').prop('checked');
2795 + $('#enable_cache_in_admin_bar_option').toggleClass('wpo_hidden', !minify_or_cache_enabled);
2254 2796 });
2255 2797 });