PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 3.2.22
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v3.2.22
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
wp-optimize / js / wpoadmin.js

wpoadmin.js in WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance 3.2.22, at js/wpoadmin.js

2,267 lines 68.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 jQuery(function ($) {
2 WP_Optimize = WP_Optimize();
3 if ('undefined' != typeof WP_Optimize_Cache) WP_Optimize_Cache = WP_Optimize_Cache();
4 if ('undefined' != typeof wp_optimize.minify) WP_Optimize_Minify = wp_optimize.minify.init();
5 });
6
7 (function($) {
8 /*
9 * Form errors store
10 */
11 var errors = [];
12 $.fn.form_errors = function() {
13 return this;
14 }
15 $.fn.form_errors.add = function(type, message) {
16 if (false !== this.has_error((type))) return;
17 errors.push({type: type, message: message});
18 };
19 $.fn.form_errors.remove = function(type) {
20 var found_error = this.has_error(type);
21 if (found_error !== false) {
22 errors.splice(found_error, 1);
23 }
24 };
25 $.fn.form_errors.has_error = function(type) {
26 var has_error = false;
27 $.each(errors, function(index, error) {
28 console.log(index, error)
29 if (type == error.type) {
30 has_error = index;
31 }
32 }.bind(this));
33 return has_error;
34 };
35 $.fn.form_errors.has_errors = function() {
36 return errors.length > 0;
37 }
38 })(jQuery);
39
40 /**
41 * Main WP_Optimize - Function for sending communications.
42 */
43 var WP_Optimize = function () {
44 var $ = jQuery;
45 var debug_level = 0;
46 var queue = new Updraft_Queue();
47 var send_command = wp_optimize.send_command;
48 var optimization_force = false;
49 var optimization_logged_warnings = false;
50 var force_single_table_optimization = false;
51
52 /*
53 * Enable select all checkbox for optimizations list.
54 */
55 define_select_all_checkbox($('#select_all_optimizations'), $('#optimizations_list .optimization_checkbox'));
56
57 /**
58 * Either display normally, or grey-out, the scheduling options, depending on whether any schedule has been selected.
59 *
60 * @return {string}
61 */
62 function enable_or_disable_schedule_options() {
63 if ($('#enable-schedule').length) {
64 var schedule_enabled = $('#enable-schedule').is(':checked');
65 if (schedule_enabled) {
66 $('#wp-optimize-auto-options').css('opacity', '1');
67 } else {
68 $('#wp-optimize-auto-options').css('opacity', '0.5')
69 }
70 }
71 }
72
73 enable_or_disable_schedule_options();
74
75 $('#enable-schedule').on('change', function () {
76 enable_or_disable_schedule_options();
77 });
78
79 // table sorter library.
80 // This calls the tablesorter library in order to sort the table information correctly.
81 // There is a fix below on line 172 to apply applyWidgets on load to avoid display hidden for tabs.
82 // add parser through the tablesorter addParser method
83 $.tablesorter.addParser({
84 // set a unique id
85 id: 'sizes',
86 is: function(s) {
87 // return false so this parser is not auto detected
88 return false;
89 },
90 format: function(cell_content, table, cell) {
91 var val = $(cell).data('raw_value');
92 if (!val) val = 0;
93 return parseInt(val);
94 },
95 // set type, either numeric or text
96 type: 'numeric'
97 });
98
99 /*
100 * Triggered when the database tabs are loaded.
101 */
102
103 $(document).on('wpo_database_tabs_loaded', function() {
104 /*
105 * Setup table events and tablesorter
106 */
107
108 var table_list_filter = $('#wpoptimize_table_list_filter'),
109 table_list = $('#wpoptimize_table_list'),
110 table_footer_line = $('#wpoptimize_table_list tbody:last'),
111 tables_not_found = $('#wpoptimize_table_list_tables_not_found');
112
113 table_list.tablesorter({
114 theme: 'default',
115 widgets: ['zebra', 'rows', 'filter'],
116 cssInfoBlock: "tablesorter-no-sort",
117 // This option is to specify with columns will be disabled for sorting
118 headers: {
119 2: {sorter: 'digit'},
120 3: {sorter: 'sizes'},
121 4: {sorter: 'sizes'},
122 // For Column Action
123 7: {sorter: false }
124 },
125 widgetOptions: {
126 // filter_anyMatch replaced! Instead use the filter_external option
127 // Set to use a jQuery selector (or jQuery object) pointing to the
128 // external filter (column specific or any match)
129 filter_external: table_list_filter,
130 // add a default type search to the second table column
131 filter_defaultFilter: { 2 : '~{query}' }
132 }
133 });
134
135 /*
136 * After tables filtered check if we need show table footer and No tables message.
137 */
138 table_list.on('filterEnd', function() {
139 var search_value = table_list_filter.val().trim();
140
141 if ('' == search_value) {
142 table_footer_line.show();
143 } else {
144 table_footer_line.hide();
145 }
146
147 if (0 == $('#the-list tr:visible', table_list).length) {
148 tables_not_found.show();
149 } else {
150 tables_not_found.hide();
151 }
152 });
153
154 /*
155 * Setup force optimization checkboxes and associated events
156 */
157
158 var optimization_force_checkbox = $('#innodb_force_optimize');
159 var optimization_row = optimization_force_checkbox.closest('tr');
160 var single_table_optimization_force = $('#innodb_force_optimize_single');
161
162 optimization_force_checkbox.on('change', function() {
163 $('button, input[type="checkbox"]', optimization_row).each(function() {
164 optimization_force = optimization_force_checkbox.is(':checked');
165 var btn = $(this);
166 if (btn.data('disabled')) {
167 if (optimization_force) {
168 btn.prop('disabled', false);
169 } else {
170 btn.prop('disabled', true);
171 }
172 }
173 });
174 });
175
176 // Handle force optimization checkbox on table list tab.
177 single_table_optimization_force.on('change', function() {
178 force_single_table_optimization = $(this).is(':checked');
179 update_single_table_optimization_buttons(force_single_table_optimization);
180 });
181
182 // Set initial value
183 force_single_table_optimization = single_table_optimization_force.is(':checked');
184 optimization_force = optimization_force_checkbox.is(':checked');
185
186 // Update single table optimization buttons state on load.
187 update_single_table_optimization_buttons(force_single_table_optimization);
188
189 });
190
191 /**
192 * Temporarily show a dashboard notice, and then remove it. The HTML will be prepended to the .wrap.wp-optimize-wrap element.
193 *
194 * @param {String} html_contents HTML to display.
195 * @param {String} where CSS selector of where to prepend the HTML to.
196 * @param {Number} [delay=15] The number of seconds to wait before removing the message.
197 *
198 * @return {string}
199 */
200 function temporarily_display_notice(html_contents, where, delay) {
201 where = ('undefined' === typeof where) ? '#wp-optimize-wrap' : where;
202 delay = ('undefined' === typeof delay) ? 15 : delay;
203 $(html_contents).hide().prependTo(where).slideDown('fast').delay(delay * 1000).slideUp('fast', function () {
204 $(this).remove();
205 });
206 }
207
208 /**
209 * Send a request to disable or enable comments or trackbacks
210 *
211 * @param {string} type - either "comments" or "trackbacks"
212 * @param {boolean} enable - whether to enable, or, to disable
213 *
214 * @return {string}
215 */
216 function enable_or_disable_feature(type, enable) {
217 var data = {
218 type: type,
219 enable: enable ? 1 : 0
220 };
221
222 $('#' + type + '_spinner').show();
223
224 send_command('enable_or_disable_feature', data, function (resp) {
225 $('#' + type + '_spinner').hide();
226
227 if (resp && resp.hasOwnProperty('output')) {
228 for (var i = 0, len = resp.output.length; i < len; i++) {
229 var new_html = '<div class="updated"><p>' + resp.output[i] + '</p></div>';
230 temporarily_display_notice(new_html, '#' + type + '_notice');
231 }
232 }
233 if (resp && resp.hasOwnProperty('messages')) {
234 $('#' + type + '_actionmsg').html(resp.messages.join(' - '));
235 }
236 });
237 }
238
239 $('#wp-optimize-disable-enable-trackbacks-enable').on('click', function () {
240 enable_or_disable_feature('trackbacks', true);
241 });
242
243 $('#wp-optimize-disable-enable-trackbacks-disable').on('click', function () {
244 enable_or_disable_feature('trackbacks', false);
245 });
246
247 $('#wp-optimize-disable-enable-comments-enable').on('click', function () {
248 enable_or_disable_feature('comments', true);
249 });
250
251 $('#wp-optimize-disable-enable-comments-disable').on('click', function () {
252 enable_or_disable_feature('comments', false);
253 });
254
255 // Main menu
256 $('.wpo-pages-menu').on('click', 'a', function(e) {
257 e.preventDefault();
258 if (!$(this).is('.active')) {
259 $('.wpo-pages-menu a.active').removeClass('active');
260 $('.wpo-page.active').removeClass('active');
261 $(this).addClass('active');
262 $('.wpo-page[data-whichpage="' + $(this).data('menuslug') + '"]').addClass('active');
263 window.scroll(0, 0);
264
265 // Trigger a global event when changing page
266 $('#wp-optimize-wrap').trigger('page-change', { page: $(this).data('menuslug') });
267 }
268
269 // Close the menu on mobile
270 $('#wp-optimize-nav-page-menu').trigger('click');
271
272 });
273
274 $('#wp-optimize-wrap').on('page-change', function(e, params) {
275 // Trigger the global tab change events when changing page
276 var active_tab = $('.wpo-page[data-whichpage='+params.page+']').find('.nav-tab-wrapper .nav-tab-active');
277 $('#wp-optimize-wrap').trigger('tab-change', { page: params.page, tab: active_tab.data('tab') });
278 $('#wp-optimize-wrap').trigger('tab-change/'+params.page+'/'+active_tab.data('tab'), { content: $('#' + active_tab.attr('id') + '-contents')});
279 });
280
281 // set a time out, as needs to be done once the rest is loaded
282 setTimeout(function() {
283 // Trigger page-change event on load
284 $('#wp-optimize-wrap').trigger('page-change', { page: $('.wpo-pages-menu a.active').data('menuslug') });
285 }, 500);
286
287 // Tabs menu
288 $('.nav-tab-wrapper .nav-tab').on('click', function (e) {
289 e.preventDefault();
290
291 var clicked_tab_id = $(this).attr('id'),
292 container = $(this).closest('.nav-tab-wrapper');
293
294 if (!clicked_tab_id) { return; }
295
296 toggle_mobile_menu(false);
297 // Mobile menu TABS toggle
298 if ($(this).is('[role="toggle-menu"]')) {
299 toggle_mobile_menu(true);
300 return;
301 }
302
303 container.find('.nav-tab:not(#wp-optimize-nav-tab-' + clicked_tab_id + ')').removeClass('nav-tab-active');
304
305 $(this).addClass('nav-tab-active');
306 $(this).closest('.wpo-page').find('.wp-optimize-nav-tab-contents').hide();
307 $('#' + clicked_tab_id + '-contents').show();
308
309 // Trigger global events on tab change
310 $('#wp-optimize-wrap').trigger('tab-change', { page: $(this).data('page'), tab: $(this).data('tab') });
311 $('#wp-optimize-wrap').trigger('tab-change/'+$(this).data('page')+'/'+$(this).data('tab'), { content: $('#' + clicked_tab_id + '-contents')});
312
313 });
314
315 // Mobile menu toggle
316 $('#wp-optimize-nav-page-menu').on('click', function(e) {
317 e.preventDefault();
318 $(this).toggleClass('opened');
319 });
320
321 /*
322 * Setup a simple cross-pages/tabs navigation.
323 *
324 * Basic example: <button class="js--wpo-goto" data-page="wpo_minify" data-tab="status">Go to the minify page, status tab</button>
325 */
326 $('#wp-optimize-wrap').on('click', '.js--wpo-goto', function(e) {
327 e.preventDefault();
328 // get the page and tab
329 var page = $(this).data('page');
330 var tab = $(this).data('tab');
331 if (page) {
332 // Trigger a page change
333 $('.wpo-pages-menu a[data-menuslug="' + page + '"]').trigger('click');
334 }
335 if (tab) {
336 // Change tab change
337 $('.wpo-page.active .nav-tab-wrapper a[data-tab="' + tab + '"]').trigger('click');
338 }
339 });
340
341 /**
342 * Toggle Mobile menu
343 *
344 * @param {bool} open
345 *
346 * @return {void}
347 */
348 function toggle_mobile_menu(open) {
349 if (open) {
350 $('#wp-optimize-wrap').addClass('wpo-mobile-menu-opened');
351 } else {
352 $('#wp-optimize-wrap').removeClass('wpo-mobile-menu-opened');
353 }
354 }
355
356 var database_tabs_loading = false;
357 var database_tabs_loaded = false;
358 // When showing the tables tab
359 $('#wp-optimize-wrap').on('tab-change/WP-Optimize/tables', function(e) {
360 get_database_tabs();
361 });
362
363 // When showing the optimizations tab
364 $('#wp-optimize-wrap').on('tab-change/WP-Optimize/optimize', function(event, data) {
365 get_database_tabs();
366 });
367
368 // When showing the settings tab
369 $('#wp-optimize-wrap').on('tab-change/wpo_settings/settings', function(event, data) {
370 // If the innodb_force_optimize--container is present, fetch the required data.
371 // We load the database tabs together, as they need the same processing.
372 if (data.content.find('.innodb_force_optimize--container').length) get_database_tabs();
373 });
374
375 /**
376 * Get the data for the database tabs. We get them at the same time, as they both need the same time consuming requests.
377 */
378 function get_database_tabs() {
379 if (database_tabs_loading || database_tabs_loaded) return;
380 var container = $('.wpo-page[data-whichpage=WP-Optimize]');
381 var shade = container.find('.wpo_shade');
382 shade.removeClass('hidden');
383 database_tabs_loading = true;
384 send_command('get_database_tabs', {}, function(response) {
385 // Set the status to true, to prevent loading again.
386 database_tabs_loaded = true;
387
388 // Updtate the optimizations tab
389 if (response.hasOwnProperty('optimizations')) {
390 container.find('.wp-optimize-optimizations-table-placeholder').replaceWith(response.optimizations);
391 }
392
393 // Updtate the optimizations tables list
394 update_tables_list(response);
395
396 $(document).trigger('wpo_database_tabs_loaded');
397
398 }).always(function() {
399 database_tabs_loading = false;
400 shade.addClass('hidden');
401 });
402 }
403
404 /**
405 * Gathers the settings from the settings tab and return in selected format.
406 *
407 * @param {string} output_format optional param 'object' or 'string'.
408 *
409 * @return (string) - serialized settings.
410 */
411 function gather_settings(output_format) {
412 var form_data = '',
413 output_format = ('undefined' === typeof output_format) ? 'string' : output_format,
414 $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-']");
415
416 if ('object' == output_format) {
417 form_data = $form_elements.serializeJSON({useIntKeysAsArrayIndex: true});
418 } else {
419 // Excluding the unnecessary 'action' input avoids triggering a very mis-conceived mod_security rule seen on one user's site.
420 form_data = $form_elements.serialize();
421
422 // Include unchecked checkboxes. user filter to only include unchecked boxes.
423 $.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-"]')
424 .filter(function (idx) {
425 return $(this).prop('checked') == false
426 }),
427 function (idx, el) {
428 // Attach matched element names to the form_data with chosen value.
429 var empty_val = '0';
430 form_data += '&' + $(el).attr('name') + '=' + empty_val;
431 }
432 );
433 }
434
435 return form_data;
436 }
437
438 /**
439 * Runs after all queued commands done and sends optimizations_done command
440 *
441 * @return {string}
442 */
443 function process_done() {
444 send_command('optimizations_done', {}, function () {});
445 // Reset the warning flag
446 optimization_logged_warnings = false;
447 }
448
449 /**
450 * Processes the queue
451 *
452 * @return void
453 */
454 function process_queue() {
455 if (!queue.get_lock()) {
456 if (debug_level > 0) {
457 console.log("WP-Optimize: process_queue(): queue is currently locked - exiting");
458 }
459 return;
460 }
461
462 if (debug_level > 0) {
463 console.log("WP-Optimize: process_queue(): got queue lock");
464 }
465
466 var id = queue.peek();
467 var blog_id = 0;
468 var sites_container = $("#wpo_all_sites");
469 var active_site = sites_container.data('active_site');
470
471 // Check to see if an object has been returned.
472 if (typeof id == 'object') {
473 data = id;
474 id = id.optimization_id;
475 blog_id = data.blog_id;
476
477 if ("undefined" == typeof active_site) {
478 sites_container.data('active_site', blog_id);
479 do_site_ui_update(blog_id, 0);
480 } else if (active_site != blog_id) {
481 var prev_blog_id = active_site;
482 sites_container.data('active_site', blog_id);
483 do_site_ui_update(blog_id, prev_blog_id);
484 }
485
486 } else {
487 data = {};
488 }
489
490 if ('undefined' === typeof id) {
491 if (debug_level > 0) console.log("WP-Optimize: process_queue(): queue is apparently empty - exiting");
492 queue.unlock();
493 var prev_blog_id = sites_container.data('active_site');
494 do_site_ui_update(0, prev_blog_id);
495 process_done();
496 return;
497 }
498
499 if (debug_level > 0) console.log("WP-Optimize: process_queue(): processing item: " + id);
500
501 queue.dequeue();
502
503 $(document).trigger(['do_optimization_', id, '_start'].join(''));
504
505 if ('optimizetables' === id) {
506 // Display the table name being optimized
507 $('#optimization_info_' + id).html(wpoptimize.optimizing_table + ' ' + data.optimization_table);
508
509 // Set extra options for the request
510 var timeout = parseInt(wpoptimize.table_optimization_timeout) ? parseInt(wpoptimize.table_optimization_timeout) : 120000;
511 var request_options = {
512 timeout: timeout,
513 error: function(error, type) {
514 optimization_logged_warnings = true;
515 if ('timeout' === type) {
516 console.warn('The request to optimize the table ' + data.optimization_table + ' timed out after ' + (timeout / 1000) + ' seconds');
517 } else {
518 console.warn('There was an error when running the optimization "' + id + '".', type, error, data);
519 }
520 if (queue.is_empty()) {
521 var blog_id = sites_container.data('active_site');
522 do_site_ui_update(blog_id, 0);
523 $('#optimization_spinner_' + id).hide();
524 $('#optimization_checkbox_' + id).show();
525 $('.optimization_button_' + id).prop('disabled', false);
526 $('#optimization_info_' + id).html(wpoptimize.optimization_complete + ' ' + wpoptimize.with_warnings);
527 }
528
529 setTimeout(function () {
530 queue.unlock(); process_queue();
531 }, 500);
532 }
533 }
534 } else {
535 var request_options = {};
536 }
537
538 send_command('do_optimization', { optimization_id: id, data: data }, function (response) {
539 $('#optimization_spinner_' + id).hide();
540 $('#optimization_checkbox_' + id).show();
541 $('.optimization_button_' + id).prop('disabled', false);
542
543 $(document).trigger(['do_optimization_', id, '_done'].join(''), response);
544
545 if (response) {
546 var total_output = '';
547 for (var i = 0, len = response.errors.length; i < len; i++) {
548 total_output += '<span class="error">' + response.errors[i] + '</span><br>';
549 }
550 for (var i = 0, len = response.messages.length; i < len; i++) {
551 total_output += response.errors[i] + '<br>';
552 }
553 for (var i = 0, len = response.result.output.length; i < len; i++) {
554 total_output += response.result.output[i] + '<br>';
555 }
556 $('#optimization_info_' + id).html(total_output);
557 if (response.hasOwnProperty('status_box_contents')) {
558 $('#wp_optimize_status_box').css('opacity', '1').find('.inside').html(response.status_box_contents);
559 }
560 if (response.hasOwnProperty('table_list')) {
561 $('#wpoptimize_table_list tbody').html($(response.table_list).find('tbody').html());
562 }
563 if (response.hasOwnProperty('total_size')) {
564 $('#optimize_current_db_size').html(response.total_size);
565 }
566
567 // Status check for optimizing tables.
568 const optimizetables_id = "optimizetables";
569 if (queue.contains_id(optimizetables_id)) {
570 $('#optimization_checkbox_' + optimizetables_id).hide();
571 $('#optimization_spinner_' + optimizetables_id).show();
572 $('.optimization_button_' + optimizetables_id).prop('disabled', true);
573 } else {
574 $('#optimization_checkbox_' + optimizetables_id).show();
575 $('#optimization_spinner_' + optimizetables_id).hide();
576 $('.optimization_button_' + optimizetables_id).prop('disabled', false);
577 $('#optimization_info_' + optimizetables_id).html(wpoptimize.optimization_complete + (optimization_logged_warnings ? (' ' + wpoptimize.with_warnings) : ''));
578 }
579
580 // check if we need update unapproved comments count.
581 if (response.result.meta && response.result.meta.hasOwnProperty('awaiting_mod')) {
582 var awaiting_mod = response.result.meta.awaiting_mod;
583 if (awaiting_mod > 0) {
584 $('#adminmenu .awaiting-mod .pending-count').remove(awaiting_mod);
585 } else {
586 // if there is no unapproved comments then remove bullet.
587 $('#adminmenu .awaiting-mod').remove();
588 }
589 }
590 }
591 setTimeout(function () {
592 queue.unlock(); process_queue();
593 }, 500);
594 }, true, request_options);
595 }
596
597 /**
598 * Update UI of sites list based on which site is currently being optimizated
599 *
600 * @param {Number} blog_id - current site id being optimized
601 * @param {Number} prev_blog_id - previous site id
602 *
603 * @return void
604 */
605 function do_site_ui_update(blog_id, prev_blog_id) {
606 if (0 != prev_blog_id) {
607 $("#site-" + prev_blog_id).show();
608 $("#optimization_spinner_site-" + prev_blog_id).hide();
609 }
610 $("#site-" + blog_id).hide();
611 $("#optimization_spinner_site-" + blog_id).show();
612 }
613
614 /**
615 * Runs a specified optimization, displaying the progress and results in the optimization's row
616 *
617 * @param {string} id - The optimization ID
618 *
619 * @return void
620 */
621 function do_optimization(id) {
622 var $optimization_row = $('#wp-optimize-nav-tab-contents-optimize .wp-optimize-settings-' + id);
623
624 if (!$optimization_row) {
625 console.log("do_optimization: row corresponding to this optimization (" + id + ") not found");
626 }
627
628 // check if there any additional inputs checkboxes.
629 var additional_data = {},
630 additional_data_length = 0;
631
632 $('input[type="checkbox"]', $('#optimization_info_' + id)).each(function() {
633 var checkbox = $(this);
634
635 if (checkbox.is(':checked')) {
636 additional_data[checkbox.attr('name')] = checkbox.val();
637 additional_data_length++;
638 }
639 });
640
641 // don't run optimization if optimization active.
642 if (true == $('.optimization_button_' + id).prop('disabled')) return;
643
644 var no_queue_actions_added = false;
645
646 // Check if it is DB optimize.
647 if ('optimizetables' == id) {
648 var optimization_tables = $('#wpoptimize_table_list #the-list tr'),
649 filter_by_blog_id = $('#wpo_sitelist_moreoptions').length > 0 && $('#wpo_sitelist_moreoptions').is(':visible'),
650 selected_sites = [];
651
652 // Get list of selected sites.
653 if (filter_by_blog_id) {
654 selected_sites = $('#wpo_sitelist_moreoptions input[type="checkbox"]:checked').map(function() {
655 return parseInt($(this).val());
656 }).get();
657 }
658
659 no_queue_actions_added = true;
660
661 // Check if there are any tables to be optimized.
662 $(optimization_tables).each(function (index) {
663 // Get information from each td.
664 var $table_information = $(this).find('td');
665
666 // Get table type information.
667 var table_type = $(this).data('type');
668 var table = $(this).data('tablename');
669 var optimizable = $(this).data('optimizable');
670 var blog_id = $(this).data('blog_id') ? parseInt($(this).data('blog_id')) : 1;
671 var in_selected_sites = true;
672
673
674 // Check if table is in the list of selected sites (multisite mode).
675 if (filter_by_blog_id && -1 == selected_sites.indexOf(blog_id)) {
676 in_selected_sites = false;
677 }
678
679 // Make sure the table isnt blank.
680 if ('' != table && in_selected_sites) {
681 // Check if table is optimizable or optimization forced by user.
682 if (1 == parseInt(optimizable) || optimization_force) {
683 var data = {
684 optimization_id: id,
685 blog_id: blog_id,
686 optimization_table: table,
687 optimization_table_type: table_type,
688 optimization_force: optimization_force
689 };
690
691 queue.enqueue(data);
692
693 no_queue_actions_added = false;
694 }
695 }
696 });
697 } else if (additional_data_length > 0) {
698 // check if additional data passed for optimization.
699 data = {
700 optimization_id: id
701 };
702
703 for (var i in additional_data) {
704 if (!additional_data.hasOwnProperty(i)) continue;
705 data[i] = additional_data[i];
706 }
707
708 queue.enqueue(data);
709 } else {
710 queue.enqueue(id);
711 }
712
713 // if new actions was not added in tasks queue then we don't process queue.
714 if (no_queue_actions_added) return;
715
716 $('#optimization_checkbox_' + id).hide();
717 $('#optimization_spinner_' + id).show();
718 $('.optimization_button_' + id).prop('disabled', true);
719
720 $('#optimization_info_' + id).html('...');
721
722 process_queue();
723 }
724
725
726 /**
727 * Run action and save selected sites list options.
728 *
729 * @param {function} action - action to do after save.
730 *
731 * @return void
732 */
733 function save_sites_list_and_do_action(action) {
734 // if multisite mode then save sites list before action.
735 if ($('#wpo_settings_sites_list').length) {
736 // save wpo-sites settings.
737 send_command('save_site_settings', {'wpo-sites': get_selected_sites_list()}, function () {
738 // do action.
739 if (action) action();
740 });
741 } else {
742 // do action.
743 if (action) action();
744 }
745 }
746
747 /**
748 * Returns list of selected sites list.
749 *
750 * @return {Array}
751 */
752 function get_selected_sites_list() {
753 var wpo_sites = [];
754
755 $('#wpo_settings_sites_list input[type="checkbox"]').each(function () {
756 var checkbox = $(this);
757 if (checkbox.is(':checked')) {
758 wpo_sites.push(checkbox.attr('value'));
759 }
760 });
761
762 return wpo_sites;
763 }
764
765 /*
766 * Run single optimization click.
767 */
768 $('#wp-optimize-nav-tab-WP-Optimize-optimize-contents').on('click', 'button.wp-optimize-settings-optimization-run-button', function () {
769 var optimization_id = $(this).closest('.wp-optimize-settings').data('optimization_id');
770 if (!optimization_id) {
771 console.log("Optimization ID corresponding to pressed button not found");
772 return;
773 }
774 // if run button disabled then don't run this optimization.
775 if (true == $('.optimization_button_' + optimization_id).prop('disabled')) return;
776 // disable run button before save sites list.
777 $('.optimization_button_' + optimization_id).prop('disabled', true);
778
779 save_sites_list_and_do_action(function() {
780 $('.optimization_button_' + optimization_id).prop('disabled', false);
781 do_optimization(optimization_id);
782 });
783 });
784
785 /*
786 * Run all optimizations click.
787 */
788 $('#wp-optimize-nav-tab-WP-Optimize-optimize-contents').on('click', '#wp-optimize', function (e) {
789 var run_btn = $(this);
790
791 e.preventDefault();
792
793 // disable run button to avoid double click.
794 run_btn.prop('disabled', true);
795 save_sites_list_and_do_action(function() {
796 run_btn.prop('disabled', false);
797 run_optimizations();
798 });
799 });
800
801 /**
802 * Sent command to run selected optimizations and auto backup if selected
803 *
804 * @return void
805 */
806 function run_optimizations() {
807 var auto_backup = false;
808
809 if ($('#enable-auto-backup').is(":checked")) {
810 auto_backup = true;
811 }
812
813 // Save the click option.
814 save_auto_backup_options();
815
816 // Only run the backup if tick box is checked.
817 if (auto_backup == true) {
818 take_a_backup_with_updraftplus(run_optimization);
819 } else {
820 // Run optimizations.
821 run_optimization();
822 }
823 }
824
825 /**
826 * Take a backup with UpdraftPlus if possible.
827 *
828 * @param {Function} callback
829 * @param {String} file_entities
830 *
831 * @return void
832 */
833 function take_a_backup_with_updraftplus(callback, file_entities) {
834 // Set default for file_entities to empty string
835 if ('undefined' == typeof file_entities) file_entities = '';
836 var exclude_files = file_entities ? 0 : 1;
837
838 if (typeof updraft_backupnow_inpage_go === 'function') {
839 updraft_backupnow_inpage_go(function () {
840 // Close the backup dialogue.
841 $('#updraft-backupnow-inpage-modal').dialog('close');
842
843 if (callback) callback();
844
845 }, file_entities, 'autobackup', 0, exclude_files, 0, wpoptimize.automatic_backup_before_optimizations);
846 } else {
847 if (callback) callback();
848 }
849 }
850
851 /**
852 * Save all auto backup options.
853 *
854 * @return void
855 */
856 function save_auto_backup_options() {
857 var options = gather_settings('object');
858 options['auto_backup'] = $('#enable-auto-backup').is(":checked");
859
860 send_command('save_auto_backup_option', options);
861 }
862
863 // Show/hide sites list for multi-site settings.
864 var wpo_settings_sites_list = $('#wpo_settings_sites_list'),
865 wpo_settings_sites_list_ul = wpo_settings_sites_list.find('ul').first(),
866 wpo_settings_sites_list_items = $('input[type="checkbox"]', wpo_settings_sites_list_ul),
867 wpo_settings_all_sites_checkbox = wpo_settings_sites_list.find('#wpo_all_sites'),
868 wpo_sitelist_show_moreoptions_link = $('#wpo_sitelist_show_moreoptions'),
869 wpo_sitelist_moreoptions_div = $('#wpo_sitelist_moreoptions'),
870
871 wpo_settings_sites_list_cron = $('#wpo_settings_sites_list_cron'),
872 wpo_settings_sites_list_cron_ul = wpo_settings_sites_list_cron.find('ul').first(),
873 wpo_settings_sites_list_cron_items = $('input[type="checkbox"]', wpo_settings_sites_list_cron_ul),
874 wpo_settings_all_sites_cron_checkbox = wpo_settings_sites_list_cron.find('#wpo_all_sites_cron'),
875 wpo_sitelist_show_moreoptions_cron_link = $('#wpo_sitelist_show_moreoptions_cron'),
876 wpo_sitelist_moreoptions_cron_div = $('#wpo_sitelist_moreoptions_cron');
877
878 // sites list for manual run.
879 define_moreoptions_settings(
880 wpo_sitelist_show_moreoptions_link,
881 wpo_sitelist_moreoptions_div,
882 wpo_settings_all_sites_checkbox,
883 wpo_settings_sites_list_items
884 );
885
886 var sites_list_clicked_count = 0;
887
888 $([wpo_settings_all_sites_checkbox, wpo_settings_sites_list_items]).each(function() {
889 $(this).on('change', function() {
890 sites_list_clicked_count++;
891 setTimeout(function() {
892 sites_list_clicked_count--;
893 if (sites_list_clicked_count == 0) update_optimizations_info();
894 }, 1000);
895 });
896 });
897
898 // sites list for cron run.
899 define_moreoptions_settings(
900 wpo_sitelist_show_moreoptions_cron_link,
901 wpo_sitelist_moreoptions_cron_div,
902 wpo_settings_all_sites_cron_checkbox,
903 wpo_settings_sites_list_cron_items
904 );
905
906 /**
907 * Attach event handlers for more options list showed by clicking on show_moreoptions_link.
908 *
909 * @param show_moreoptions_link
910 * @param more_options_div
911 * @param all_items_checkbox
912 * @param items_list
913 *
914 * @return boolean
915 */
916 function define_moreoptions_settings(show_moreoptions_link, more_options_div, all_items_checkbox, items_list) {
917 // toggle show options on click.
918 show_moreoptions_link.on('click', function () {
919 if (!more_options_div.hasClass('wpo_always_visible')) more_options_div.toggleClass('wpo_hidden');
920 return false;
921 });
922
923 // if "all items" checked/unchecked then check/uncheck items in the list.
924 define_select_all_checkbox(all_items_checkbox, items_list);
925 }
926
927 /**
928 * Defines "select all" check box, where all_items_checkbox is a select all check box jQuery object
929 * and items_list is a list of checkboxes assigned with all_items_checkbox.
930 *
931 * @param {Object} all_items_checkbox
932 * @param {Object} items_list
933 *
934 * @return void
935 */
936 function define_select_all_checkbox(all_items_checkbox, items_list) {
937 // if "all items" checked/unchecked then check/uncheck items in the list.
938 all_items_checkbox.on('change', function () {
939 if (all_items_checkbox.is(':checked')) {
940 items_list.prop('checked', true);
941 } else {
942 items_list.prop('checked', false);
943 }
944
945 update_wpo_all_items_checkbox_state(all_items_checkbox, items_list);
946 });
947
948 items_list.on('change', function () {
949 update_wpo_all_items_checkbox_state(all_items_checkbox, items_list);
950 });
951
952 update_wpo_all_items_checkbox_state(all_items_checkbox, items_list);
953
954 }
955
956 /**
957 * Update state of "all items" checkbox depends on state all items in the list.
958 *
959 * @param all_items_checkbox
960 * @param all_items
961 *
962 * @return void
963 */
964 function update_wpo_all_items_checkbox_state(all_items_checkbox, all_items) {
965 var all_items_count = 0, checked_items_count = 0;
966
967 all_items.each(function () {
968 if ($(this).is(':checked')) {
969 checked_items_count++;
970 }
971 all_items_count++;
972 });
973
974 // update label text if need.
975 if (all_items_checkbox.next().is('label') && all_items_checkbox.next().data('label')) {
976 var label = all_items_checkbox.next(),
977 label_mask = label.data('label');
978
979 if (all_items_count == checked_items_count) {
980 label.text(label_mask);
981 } else {
982 label.text(label_mask.replace('all', [checked_items_count, ' of ', all_items_count].join('')));
983 }
984 }
985
986 if (all_items_count == checked_items_count) {
987 all_items_checkbox.prop('checked', true);
988 } else {
989 all_items_checkbox.prop('checked', false);
990 }
991 }
992
993 /**
994 * Running the optimizations for the selected options
995 *
996 * @return {[type]} optimizations
997 */
998 function run_optimization() {
999 $optimizations = $('#optimizations_list .optimization_checkbox:checked');
1000
1001 $optimizations.sort(function (a, b) {
1002 // Convert to IDs.
1003 a = $(a).closest('.wp-optimize-settings').data('optimization_run_sort_order');
1004 b = $(b).closest('.wp-optimize-settings').data('optimization_run_sort_order');
1005 if (a > b) {
1006 return 1;
1007 } else if (a < b) {
1008 return -1;
1009 } else {
1010 return 0;
1011 }
1012 });
1013
1014 var optimization_options = {};
1015
1016 $optimizations.each(function (index) {
1017 var optimization_id = $(this).closest('.wp-optimize-settings').data('optimization_id');
1018 if (!optimization_id) {
1019 console.log("Optimization ID corresponding to pressed button not found");
1020 return;
1021 }
1022 // An empty object - in future, options may be implemented.
1023 optimization_options[optimization_id] = { active: 1 };
1024 do_optimization(optimization_id);
1025 });
1026
1027 send_command('save_manual_run_optimization_options', optimization_options);
1028 }
1029
1030 /**
1031 * Uptate the tables list
1032 *
1033 * @param {object} response
1034 */
1035 function update_tables_list(response) {
1036 if (response.hasOwnProperty('table_list')) {
1037 var resort = true,
1038 // add a callback, as desired
1039 callback = function(table) {
1040 $('#wpoptimize_table_list tbody').css('opacity', '1');
1041 };
1042
1043 // update body with new content.
1044 $("#wpoptimize_table_list tbody").remove();
1045 $("#wpoptimize_table_list thead").after(response.table_list);
1046
1047 $("#wpoptimize_table_list").trigger("updateAll", [resort, callback]);
1048 }
1049
1050 if (response.hasOwnProperty('total_size')) {
1051 $('#optimize_current_db_size').html(response.total_size);
1052 }
1053
1054 if (response.hasOwnProperty('show_innodb_force_optimize')) {
1055 $('.innodb_force_optimize--container').toggleClass('hidden', !response.show_innodb_force_optimize);
1056 }
1057
1058 change_actions_column_visibility();
1059 update_single_table_optimization_buttons(force_single_table_optimization);
1060 }
1061
1062 $('#wp_optimize_table_list_refresh').on('click', function (e) {
1063 e.preventDefault();
1064 var shade = $(this).closest('.wpo-tab-postbox').find('.wpo_shade');
1065 shade.removeClass('hidden');
1066 $('#wpoptimize_table_list tbody').css('opacity', '0.5');
1067 send_command('get_table_list', {refresh_plugin_json: true}, update_tables_list).always(function() {
1068 shade.addClass('hidden');
1069 });
1070 });
1071
1072 $('#database_settings_form, #settings_form').on('click', '.wpo-save-settings', function (e) {
1073 e.preventDefault();
1074 var form = $(this).closest('form');
1075 var spinner = form.find('.wpo-saving-settings');
1076 var form_data = gather_settings();
1077
1078 form.trigger('wpo-saving-form-data');
1079
1080 if (form.form_errors.has_errors()) return;
1081
1082 spinner.show();
1083 $.blockUI();
1084
1085 // when optimizations list in the document - send information about selected optimizations.
1086 if ($('#optimizations_list').length) {
1087 $('#optimizations_list .optimization_checkbox:checked').each(function() {
1088 var optimization_id = $(this).closest('.wp-optimize-settings').data('optimization_id');
1089 if (optimization_id) {
1090 form_data += '&optimization-options['+optimization_id+'][active]=1';
1091 }
1092 });
1093 }
1094
1095 if ($('#purge_cache_permissions').length) {
1096 if (!$('#purge_cache_permissions').val()) {
1097 form_data += '&purge_cache_permissions[]';
1098 }
1099 }
1100
1101 send_command('save_settings', form_data, function (resp) {
1102 spinner.closest('div').find('.save-done').show().delay(5000).fadeOut();
1103
1104 if (resp && resp.hasOwnProperty('save_results') && resp.save_results && resp.save_results.hasOwnProperty('errors')) {
1105 for (var i = 0, len = resp.save_results.errors.length; i < len; i++) {
1106 var new_html = '<div class="error">' + resp.errors[i] + '</div>';
1107 temporarily_display_notice(new_html, '#wp-optimize-settings-save-results');
1108 }
1109 }
1110 if (resp && resp.hasOwnProperty('status_box_contents')) {
1111 $(resp.status_box_contents).each(function(index, el) {
1112 if ($(el).is('#wp_optimize_status_box')) {
1113 $('#wp_optimize_status_box').replaceWith($(el));
1114 }
1115 });
1116 }
1117
1118 if (resp && resp.hasOwnProperty('optimizations_table')) {
1119 $('#optimizations_list').replaceWith(resp.optimizations_table);
1120 }
1121
1122 if (resp && resp.hasOwnProperty('settings_auto_cleanup_contents')) {
1123 $('#wpo_auto_cleanup').replaceWith(resp.settings_auto_cleanup_contents);
1124 }
1125
1126 if (resp && resp.hasOwnProperty('logging_settings_contents')) {
1127 $('#wpo_logging_settings').replaceWith(resp.logging_settings_contents);
1128 }
1129
1130 // Need to refresh the page if enable-admin-menu tick state has changed.
1131 if (resp.save_results.refresh) {
1132 location.reload();
1133 }
1134 }).always(function() {
1135 spinner.hide();
1136 $.unblockUI();
1137 });
1138 });
1139
1140 $('#database_settings_form').on('click', '.wpo_save_event', function() {
1141 setTimeout(function(){
1142 $('#wp-optimize-save-database-settings').trigger('click');
1143 }, 500);
1144 });
1145
1146 $('#settings_form').on('click', '.wpo_save_logging', function() {
1147 setTimeout(function(){
1148 $('#wp-optimize-save-main-settings').trigger('click');
1149 }, 500);
1150 });
1151
1152 /*
1153 * Handle Wipe Settings click.
1154 */
1155 $('#settings_form').on('click', '.wpo-wipe-settings', function() {
1156 var spinner = $(this).parent().find('.wpo_spinner');
1157
1158 spinner.show();
1159
1160 send_command('wipe_settings', {}, function() {
1161 spinner.next().removeClass('display-none').delay(5000).fadeOut();
1162 alert(wpoptimize.settings_have_been_deleted_successfully);
1163 location.replace(wpoptimize.settings_page_url);
1164 }).always(function() {
1165 spinner.hide();
1166 });
1167
1168 });
1169
1170 $('#wp-optimize-wrap').on('click', '#wp_optimize_status_box_refresh', function (e) {
1171 e.preventDefault();
1172 $('#wp_optimize_status_box').css('opacity', '0.5');
1173 send_command('get_status_box_contents', null, function (resp) {
1174 $('#wp_optimize_status_box').css('opacity', '1');
1175 $(resp).each(function(index, el) {
1176 if ($(el).is('#wp_optimize_status_box')) {
1177 $('#wp_optimize_status_box').replaceWith($(el));
1178 }
1179 });
1180
1181 });
1182 });
1183
1184 /**
1185 * Run single table optimization. Handle click on Optimize button.
1186 *
1187 * @param {Object} btn jQuery object clicked Optimize button
1188 *
1189 * @return {void}
1190 */
1191 function run_single_table_optimization(btn) {
1192 var spinner = btn.next(),
1193 action_done_icon = spinner.next(),
1194 table_name = btn.data('table'),
1195 table_type = btn.data('type'),
1196 data = {
1197 optimization_id: 'optimizetables',
1198 optimization_table: table_name,
1199 optimization_table_type: table_type
1200 };
1201 btn.hide();
1202 // if checked force button then send force value.
1203 if (force_single_table_optimization) {
1204 data['optimization_force'] = true;
1205 }
1206
1207 spinner.removeClass('visibility-hidden');
1208
1209 send_command('do_optimization', { optimization_id: 'optimizetables', data: data }, function (response) {
1210 if (response.result.meta.error) {
1211 btn.closest('tr').html('<td colspan="8" class="no-table"><p>' + response.result.meta.message + '</p></td>');
1212 setTimeout(function() {
1213 $('#wp_optimize_table_list_refresh').trigger('click');
1214 }, 2000);
1215 } else {
1216 if (response.result.meta.tableinfo) {
1217 var row = btn.closest('tr'),
1218 meta = response.result.meta,
1219 tableinfo = meta.tableinfo;
1220
1221 update_single_table_information(row, tableinfo);
1222
1223 // update total overhead.
1224 $('#wpoptimize_table_list > tbody:last th:eq(6)').html(['<span style="color:', meta.overhead > 0 ? '#0000FF' : '#004600', '">', meta.overhead_formatted,'</span>'].join(''));
1225 }
1226 }
1227
1228 btn.prop('disabled', false);
1229 spinner.addClass('visibility-hidden');
1230 action_done_icon.show().removeClass('visibility-hidden').delay(2500).fadeOut('fast', function() {
1231 btn.show();
1232 });
1233 });
1234 }
1235
1236 /**
1237 * Update information about single table in the database tables list.
1238 *
1239 * @param {Object} row jQuery object for TR html tag.
1240 * @param {Object} tableinfo
1241 *
1242 * @return {void}
1243 */
1244 function update_single_table_information(row, tableinfo) {
1245 // update table information in row.
1246 $('td:eq(2)', row).text(tableinfo.rows);
1247 $('td:eq(3)', row).text(tableinfo.data_size);
1248 $('td:eq(4)', row).text(tableinfo.index_size);
1249 $('td:eq(5)', row).text(tableinfo.type);
1250
1251 if (tableinfo.is_optimizable) {
1252 $('td:eq(6)', row).html(['<span style="color:', tableinfo.overhead > 0 ? '#0000FF' : '#004600', '">', tableinfo.overhead,'</span>'].join(''));
1253 } else {
1254 $('td:eq(6)', row).html('<span color="#0000FF">-</span>');
1255 }
1256
1257 }
1258
1259 /**
1260 * Update single table optimization buttons state depends on force_optimization value.
1261 *
1262 * @param {boolean} force_optimization See if we need to force optimization
1263 *
1264 * @return {void}
1265 */
1266 function update_single_table_optimization_buttons(force_optimization) {
1267 $('.run-single-table-optimization').each(function() {
1268 var btn = $(this);
1269
1270 if (btn.data('disabled')) {
1271 if (force_optimization) {
1272 btn.prop('disabled', false);
1273 } else {
1274 btn.prop('disabled', true);
1275 }
1276 }
1277 });
1278 }
1279
1280 /**
1281 * Returns true if single site mode or multisite and at least one site selected;
1282 *
1283 * @return {boolean}
1284 */
1285 function is_sites_selected() {
1286 return (0 == wpo_settings_sites_list.length || 0 != $('input[type="checkbox"]:checked', wpo_settings_sites_list).length);
1287 }
1288
1289 /**
1290 * Update optimizations info texts.
1291 *
1292 * @param {Object} response object returned by command get_optimizations_info.
1293 *
1294 * @return {void}
1295 */
1296 function update_optimizations_info_view(response) {
1297 var i, dom_id, info;
1298
1299 // @codingStandardsIgnoreLine
1300 if (!response) return;
1301
1302 for (i in response) {
1303 if (!response.hasOwnProperty(i)) continue;
1304
1305 dom_id = ['#wp-optimize-settings-', response[i].dom_id].join('');
1306 info = response[i].info ? response[i].info.join('<br>') : '';
1307
1308 $(dom_id + ' .wp-optimize-settings-optimization-info').html(info);
1309 }
1310 }
1311
1312 var get_optimizations_info_cache = {};
1313
1314 /**
1315 * Send command for get optimizations info and update view.
1316 *
1317 * @return {void}
1318 */
1319 function update_optimizations_info() {
1320 var cache_key = ['', get_selected_sites_list().join('_')].join('');
1321
1322 // if information saved in cache show it.
1323 if (get_optimizations_info_cache.hasOwnProperty(cache_key)) {
1324 update_optimizations_info_view(get_optimizations_info_cache[cache_key]);
1325 } else {
1326 // else send command update cache and update view.
1327 send_command('get_optimizations_info', {'wpo-sites':get_selected_sites_list()}, function(response) {
1328 // @codingStandardsIgnoreLine
1329 if (!response) return;
1330 get_optimizations_info_cache[cache_key] = response;
1331 update_optimizations_info_view(response);
1332 });
1333 }
1334 }
1335
1336 /*
1337 * Check if settings file selected for import.
1338 */
1339 $('#wpo_import_settings_btn').on('click', function(e) {
1340 var file_input = $('#wpo_import_settings_file'),
1341 filename = file_input.val(),
1342 wpo_import_file_file = file_input[0].files[0],
1343 wpo_import_file_reader = new FileReader();
1344
1345 $('#wpo_import_settings_btn').prop('disabled', true);
1346
1347 if (!/\.json$/.test(filename)) {
1348 e.preventDefault();
1349 $('#wpo_import_settings_btn').prop('disabled', false);
1350 $('#wpo_import_error_message').text(wpoptimize.please_select_settings_file).slideDown();
1351 return false;
1352 }
1353
1354 wpo_import_file_reader.onload = function() {
1355 import_settings(this.result);
1356 };
1357
1358 wpo_import_file_reader.readAsText(wpo_import_file_file);
1359
1360 return false;
1361 });
1362
1363 /**
1364 * Send import settings command.
1365 *
1366 * @param {string} settings encoded settings in json string.
1367 *
1368 * @return {void}
1369 */
1370 function import_settings(settings) {
1371 var loader = $('#wpo_import_spinner'),
1372 success_message = $('#wpo_import_success_message'),
1373 error_message = $('#wpo_import_error_message');
1374
1375 loader.show();
1376 send_command('import_settings', {'settings': settings}, function(response) {
1377 loader.hide();
1378 if (response && response.errors && response.errors.length) {
1379 error_message.text(response.errors.join('<br>'));
1380 error_message.slideDown();
1381 } else if (response && response.messages && response.messages.length) {
1382 success_message.text(response.messages.join('<br>'));
1383 success_message.slideDown();
1384 setTimeout(function() {
1385 window.location.reload();
1386 }, 500);
1387 }
1388
1389 $('#wpo_import_settings_btn').prop('disabled', false);
1390 });
1391 }
1392
1393 /*
1394 * Hide file validation message on change file field value.
1395 */
1396 $('#wpo_import_settings_file').on('change', function() {
1397 $('#wpo_import_error_message').slideUp();
1398 });
1399
1400 /*
1401 * Save settings to hidden form field, used for export.
1402 */
1403 $('#wpo_export_settings_btn').on('click', function(e) {
1404 wpo_download_json_file(gather_settings('object'));
1405 return false;
1406 });
1407
1408 /**
1409 * Force download json file with posted data.
1410 *
1411 * @param {Object} data data to put in a file.
1412 * @param {string} filename
1413 *
1414 * @return {void}
1415 */
1416 function wpo_download_json_file(data ,filename) {
1417 // Attach this data to an anchor on page
1418 var link = document.body.appendChild(document.createElement('a')),
1419 date = new Date(),
1420 year = date.getFullYear(),
1421 month = date.getMonth() < 10 ? ['0', date.getMonth()].join('') : date.getMonth(),
1422 day = date.getDay() < 10 ? ['0', date.getDay()].join('') : date.getDay();
1423
1424 filename = filename ? filename : ['wpo-settings-',year,'-',month,'-',day,'.json'].join('');
1425
1426 link.setAttribute('download', filename);
1427 link.setAttribute('style', "display:none;");
1428 link.setAttribute('href', 'data:text/json' + ';charset=UTF-8,' + encodeURIComponent(JSON.stringify(data)));
1429 link.click();
1430 }
1431
1432 /**
1433 * Make ajax request to get optimization info.
1434 *
1435 * @param {Object} optimization_info_container - jquery object obtimization info container.
1436 * @param {string} optimization_id - optimization id.
1437 * @param {Object} params - custom params posted to optimization get info.
1438 *
1439 * @return void
1440 */
1441 var optimization_get_info = function(optimization_info_container, optimization_id, params) {
1442 return send_command('get_optimization_info', {optimization_id: optimization_id, data: params}, function(resp) {
1443 var meta = (resp && resp.result && resp.result.meta) ? resp.result.meta : {},
1444 message = (resp && resp.result && resp.result.output) ? resp.result.output.join('<br>') : '...';
1445
1446 // trigger event about optimization get info in process.
1447 $(document).trigger(['optimization_get_info_', optimization_id].join(''), [message, meta]);
1448 // update status message in optimizations list.
1449 optimization_info_container.html(message);
1450
1451 if (!meta.finished) {
1452 setTimeout(function() {
1453 var xhr = optimization_get_info(optimization_info_container, optimization_id, meta);
1454 $(document).trigger(['optimization_get_info_xhr_', optimization_id].join(''), [xhr, meta]);
1455 }, 1);
1456 } else {
1457 // trigger event about optimization get info action done.
1458 $(document).trigger(['optimization_get_info_', optimization_id, '_done'].join(''), resp);
1459 }
1460 });
1461 };
1462
1463 // attach event handlers after database tables template loaded.
1464 // Handle single optimization click.
1465 $('#wpoptimize_table_list').on('click', '.run-single-table-optimization', function () {
1466 var take_backup_checkbox = $('#enable-auto-backup-1'),
1467 button = $(this);
1468
1469 // check if backup checkbox is checked for db tables
1470 if (take_backup_checkbox.is(':checked')) {
1471 take_a_backup_with_updraftplus(
1472 function () {
1473 run_single_table_optimization(button);
1474 }
1475 );
1476 } else {
1477 run_single_table_optimization(button);
1478 }
1479 });
1480
1481 // Handle repair table click
1482 $('#wpoptimize_table_list').on('click', '.run-single-table-repair', function () {
1483 var btn = $(this),
1484 spinner = btn.next(),
1485 action_done_icon = spinner.next(),
1486 table_name = btn.data('table'),
1487 data = {
1488 optimization_id: 'repairtables',
1489 optimization_table: table_name
1490 };
1491
1492 spinner.removeClass('visibility-hidden');
1493
1494 send_command('do_optimization', {optimization_id: 'repairtables', data: data}, function (response) {
1495 if (response.result.meta.success) {
1496 var row = btn.closest('tr'),
1497 tableinfo = response.result.meta.tableinfo;
1498
1499 btn.prop('disabled', false);
1500 spinner.addClass('visibility-hidden');
1501 action_done_icon.show().removeClass('visibility-hidden');
1502
1503 update_single_table_information(row, tableinfo);
1504
1505 // keep visible results from previous operation for one second and show optimize button if possible.
1506 setTimeout(function () {
1507 var parent_td = btn.closest('td'),
1508 btn_wrap = btn.closest('.wpo_button_wrap');
1509
1510 // remove Repair button and show Optimize button.
1511 btn_wrap.fadeOut('fast', function () {
1512 btn_wrap.closest('.wpo_button_wrap').remove();
1513
1514 // if table type is supported for optimization then show OPTIMIZE button.
1515 if (tableinfo.is_type_supported) {
1516 $('.wpo_button_wrap', parent_td).removeClass('wpo_hidden');
1517 }
1518 });
1519
1520 change_actions_column_visibility();
1521 }, 1000);
1522 } else {
1523 btn.prop('disabled', false);
1524 spinner.addClass('visibility-hidden');
1525 alert(wpoptimize.table_was_not_repaired.replace('%s', table_name));
1526 }
1527 });
1528 });
1529
1530 // Handle convert table click
1531 $('#wpoptimize_table_list').on('click', '.toinnodb', function () {
1532 convert_single_db_table($(this));
1533 });
1534
1535 var table_to_remove_btn;
1536
1537 // Handle delete table click
1538 $('#wpoptimize_table_list').on('click', '.run-single-table-delete', function () {
1539 table_to_remove_btn = $(this);
1540 var take_backup_checkbox = $('#enable-auto-backup-1');
1541 if ('' == wpoptimize.user_always_ignores_table_delete_warning || '1' !== wpoptimize.user_always_ignores_table_delete_warning) {
1542 wp_optimize.modal.open({
1543 className: 'wpo-confirm',
1544 events: {
1545 'click .wpo-modal--bg': 'close',
1546 'click .delete-table': 'deleteTable',
1547 'change #confirm_deletion_without_backup': 'changeConfirm',
1548 'change #confirm_table_deletion': 'changeConfirm'
1549 },
1550 content: function() {
1551 var content_template = wp.template('wpo-table-delete');
1552 // Get the plugins list
1553 var plugins_list = table_to_remove_btn.closest('tr').find('.table-plugins').html();
1554 return content_template({
1555 no_backup: !take_backup_checkbox.is(':checked'),
1556 plugins_list: plugins_list,
1557 table_name: table_to_remove_btn.data('table')
1558 });
1559 },
1560 changeConfirm: function() {
1561 var enable_button = true;
1562 var backup_input = this.$('#confirm_deletion_without_backup');
1563 var confirm_input = this.$('#confirm_table_deletion');
1564 if (backup_input.length && !backup_input.is(':checked')) {
1565 enable_button = false;
1566 }
1567 if (!confirm_input.is(':checked')) {
1568 enable_button = false;
1569 }
1570 this.$('.delete-table').prop('disabled', !enable_button);
1571 },
1572 deleteTable: function() {
1573 // check if user ignore table warning
1574 var ignores_table_detele_warning_checkbox = this.$('#ignores_table_delete_warning');
1575 if (ignores_table_detele_warning_checkbox.is(':checked')) {
1576 send_command('user_ignores_table_delete_warning', {}, function(response) {
1577 if (response.success) {
1578 wpoptimize.user_always_ignores_table_delete_warning = '1';
1579 }
1580 });
1581 }
1582 // check if backup checkbox is checked for db tables
1583 if (take_backup_checkbox.is(':checked')) {
1584 take_a_backup_with_updraftplus(remove_single_db_table);
1585 } else {
1586 remove_single_db_table();
1587 }
1588 this.close();
1589
1590 }
1591 });
1592 } else {
1593 // check if backup checkbox is checked for db tables
1594 if (take_backup_checkbox.is(':checked')) {
1595 take_a_backup_with_updraftplus(remove_single_db_table);
1596 } else {
1597 remove_single_db_table();
1598 }
1599 }
1600 });
1601
1602 /**
1603 * Send ajax command to convert single table to InnoDB.
1604 *
1605 * @param {Object} btn jQuery object of clicked "Convert to InnoDB" button.
1606 *
1607 * @return void
1608 */
1609 function convert_single_db_table(table_to_convert_btn) {
1610 var spinner = table_to_convert_btn.next(),
1611 action_done_icon = spinner.next(),
1612 table_name = table_to_convert_btn.data('table'),
1613 data = {
1614 optimization_id: 'orphanedtables',
1615 optimization_table: table_name,
1616 optimization_action: 'toinnodb'
1617 };
1618
1619 spinner.removeClass('visibility-hidden');
1620
1621 send_command('do_optimization', { optimization_id: 'orphanedtables', data: data }, function (response) {
1622 if (response.result.meta.error) {
1623 table_to_convert_btn.closest('tr').html('<td colspan="8" class="no-table"><p>' + response.result.meta.message + '</p></td>');
1624 setTimeout(function() {
1625 $('#wp_optimize_table_list_refresh').trigger('click');
1626 }, 2000);
1627 return;
1628 }
1629 if (response.result.meta.success) {
1630 var row = table_to_convert_btn.closest('tr');
1631
1632 action_done_icon.show().removeClass('visibility-hidden');
1633
1634 // remove convert to Innodb button.
1635 row.find(".toinnodb").remove();
1636
1637
1638 setTimeout(function() {
1639 action_done_icon.fadeOut('slow', function() {
1640 row.find("[data-colname='Type']").text("InnoDB");
1641 });
1642 }, 500);
1643 } else {
1644 var message = wpoptimize.table_was_not_converted.replace('%s', table_name);
1645
1646 if (response.result.meta.message) {
1647 message += '(' + response.result.meta.message + ')';
1648 }
1649
1650 alert(message);
1651 }
1652 }).always(function() {
1653 table_to_convert_btn.prop('disabled', false);
1654 spinner.addClass('visibility-hidden');
1655 });
1656 }
1657
1658
1659
1660 /**
1661 * Send ajax commant to remove single database table.
1662 *
1663 * @param {Object} btn jQuery object of clicked "Remove" button.
1664 *
1665 * @return void
1666 */
1667 function remove_single_db_table() {
1668 var spinner = table_to_remove_btn.next(),
1669 action_done_icon = spinner.next(),
1670 table_name = table_to_remove_btn.data('table'),
1671 data = {
1672 optimization_id: 'orphanedtables',
1673 optimization_table: table_name
1674 };
1675
1676 spinner.removeClass('visibility-hidden');
1677
1678 send_command('do_optimization', { optimization_id: 'orphanedtables', data: data }, function (response) {
1679 if (response.result.meta.success) {
1680 var row = table_to_remove_btn.closest('tr');
1681
1682 action_done_icon.show().removeClass('visibility-hidden');
1683
1684 // remove row for deleted table.
1685 setTimeout(function() {
1686 row.fadeOut('slow', function() {
1687 row.remove();
1688
1689 change_actions_column_visibility();
1690 });
1691 }, 500);
1692 } else {
1693 var message = wpoptimize.table_was_not_deleted.replace('%s', table_name);
1694
1695 if (response.result.meta.message) {
1696 message += '(' + response.result.meta.message + ')';
1697 }
1698
1699 alert(message);
1700 }
1701 }).always(function() {
1702 table_to_remove_btn.prop('disabled', false);
1703 spinner.addClass('visibility-hidden');
1704 });
1705 }
1706
1707 change_actions_column_visibility();
1708
1709 /**
1710 * Show or hide actions column if need.
1711 *
1712 * @return void
1713 */
1714 function change_actions_column_visibility() {
1715 var table = $('#wpoptimize_table_list'),
1716 hideLastColumn = true;
1717
1718 // check if any button exists in the actions column.
1719 $('tr', table).each(function() {
1720 var row = $(this);
1721
1722 if ($('button', row).length > 0) {
1723 hideLastColumn = false;
1724 return false;
1725 }
1726 });
1727
1728 // hide or show last column
1729 $('tr', table).each(function() {
1730 var row = $(this);
1731
1732 if (hideLastColumn) {
1733 $('td:last, th:last', row).hide();
1734 } else {
1735 $('td:last, th:last', row).show();
1736 }
1737 });
1738 }
1739
1740 /*
1741 * Validate general settings (loggers).
1742 */
1743 $('#wp-optimize-general-settings').on('wpo-saving-form-data', function() {
1744 var valid = true;
1745 var $form = $(this);
1746
1747 $('.wpo_logger_addition_option, .wpo_logger_type').each(function() {
1748 if (!validate_field($(this), true)) {
1749 valid = false;
1750 $(this).addClass('wpo_error_field');
1751 } else {
1752 $(this).removeClass('wpo_error_field');
1753 }
1754 });
1755
1756 if (!valid) {
1757 $form.form_errors.add('missing-fields', '');
1758 $('#wp-optimize-settings-save-results')
1759 .show()
1760 .addClass('wpo_alert_notice')
1761 .text(wpoptimize.fill_all_settings_fields)
1762 .delay(5000)
1763 .fadeOut(3000, function() {
1764 $(this).removeClass('wpo_alert_notice');
1765 });
1766 } else {
1767 $form.form_errors.remove('missing-fields');
1768 $('#wp-optimize-logger-settings .save_settings_reminder').slideUp();
1769 }
1770
1771 });
1772
1773 /**
1774 * Validate import field with data-validate attribute.
1775 *
1776 * @param {object} field jquery element
1777 * @param {boolean} required
1778 *
1779 * @return {boolean}
1780 */
1781 function validate_field(field, required) {
1782 var value = field.val(),
1783 validate = field.data('validate');
1784
1785 if (!validate && required) {
1786 return ('' != value.trim());
1787 }
1788
1789 if (validate && !required && '' == value.trim()) {
1790 return true;
1791 }
1792
1793 var valid = true;
1794
1795 switch (validate) {
1796 case 'email':
1797 var regex = /\S+@\S+\.\S+/,
1798 emails = value.split(","),
1799 email = '';
1800
1801 for (var i = 0; i < emails.length; i++) {
1802 email = emails[i].trim();
1803
1804 if ('' == email || !regex.test(email)) {
1805 valid = false;
1806 }
1807 }
1808 break;
1809
1810 case 'url':
1811 // https://gist.github.com/dperini/729294
1812 // @codingStandardsIgnoreLine
1813 var regex = /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i;
1814
1815 valid = regex.test(value);
1816 break;
1817 }
1818
1819 return valid;
1820 }
1821
1822 /**
1823 * Send check_overdue_crons command and output warning if need.
1824 */
1825 setTimeout(function() {
1826 send_command('check_overdue_crons', null, function (resp) {
1827 if (resp && resp.hasOwnProperty('m')) {
1828 $('#wpo_settings_warnings').append(resp.m);
1829 }
1830 });
1831 }, 11000);
1832
1833 /**
1834 * Hide introduction notice
1835 */
1836 $('.wpo-introduction-notice .notice-dismiss, .wpo-introduction-notice .close').on('click', function(e) {
1837 $('.wpo-introduction-notice').remove();
1838 send_command('dismiss_install_or_update_notice', null, function (resp) {
1839 if (resp && resp.hasOwnProperty('error')) {
1840 // there was an error.
1841 console.log('There was an error dismissing the install or update notice (dismiss_install_or_update_notice)', resp);
1842 }
1843 });
1844 });
1845
1846 $('#wpo-settings-export').on('click', export_settings);
1847
1848 $('#wpo-settings-import').on('click', function(e) {
1849 e.preventDefault();
1850
1851 block_ui();
1852
1853 var wpo_import_file_input = document.getElementById('import_settings');
1854 if (0 === wpo_import_file_input.files.length) {
1855 alert(wpoptimize.import_select_file);
1856 $.unblockUI();
1857 return;
1858 }
1859 read_settings_json_file(wpo_import_file_input.files[0]);
1860 });
1861
1862 /**
1863 * Blocks UI
1864 */
1865 function block_ui() {
1866 $.blockUI({
1867 css: {
1868 width: '300px',
1869 border: 'none',
1870 'border-radius': '10px',
1871 left: 'calc(50% - 150px)',
1872 padding: '20px'
1873 },
1874 message: '<div style="margin: 8px; font-size:150%;" class="updraft_saving_popup"><img src="'+wpoptimize.spinner_src+'" height="80" width="80" style="padding-bottom:10px;"><br>'+wpoptimize.importing+'</div>'
1875 });
1876 }
1877
1878 /**
1879 * Export plugin settings as a JSON file
1880 *
1881 * @param {object} e - Event object
1882 *
1883 * @return {void}
1884 */
1885 function export_settings(e) {
1886 e.preventDefault();
1887
1888 var date_now = new Date();
1889
1890 form_data = JSON.stringify({
1891 epoch_date: date_now.getTime(),
1892 local_date: date_now.toLocaleString(),
1893 network_site_url: wpoptimize.network_site_url,
1894 data: {
1895 cache_settings: wp_optimize.cache_settings(),
1896 minify_settings: wp_optimize.minify_settings(),
1897 smush_settings: wp_optimize.smush_settings(),
1898 database_settings: gather_settings('string')
1899 }
1900 });
1901
1902 // Attach this data to an anchor on page
1903 var link = document.body.appendChild(document.createElement('a'));
1904 link.setAttribute('download', wpoptimize.export_settings_file_name);
1905 link.setAttribute('style', "display:none;");
1906 link.setAttribute('href', 'data:text/json' + ';charset=UTF-8,' + encodeURIComponent(form_data));
1907 link.click();
1908 }
1909
1910 /**
1911 * Read json settings file and import it
1912 *
1913 * @param {Blob} file - Settings file
1914 *
1915 * @return {void}
1916 */
1917 function read_settings_json_file(file) {
1918 var file_reader = new FileReader();
1919 file_reader.onload = function() {
1920 import_settings(this.result);
1921 };
1922 file_reader.readAsText(file);
1923 }
1924
1925 /**
1926 * Import json data and save it as plugin settings in database
1927 *
1928 * @param {json} json_data
1929 *
1930 * @return {void}
1931 */
1932 function import_settings(json_data) {
1933 var parsed;
1934 try {
1935 parsed = wpo_parse_json(json_data);
1936 } catch (e) {
1937 $.unblockUI();
1938 jQuery('#import_settings').val('');
1939 console.log(json_data);
1940 console.log(e);
1941 alert(wpoptimize.import_invalid_json_file);
1942 return;
1943 }
1944 if (window.confirm(wpoptimize.importing_data_from + ' ' + parsed['network_site_url'] + "\n" + wpoptimize.exported_on + ' ' + parsed['local_date'] + "\n" + wpoptimize.continue_import)) {
1945 // GET the settings back to the AJAX handler
1946 var stringified = JSON.stringify(parsed['data']);
1947 send_command('import_settings', {
1948 settings: stringified
1949 }, function(response) {
1950 $.unblockUI();
1951 if (response && response.errors) {
1952 alert(response.errors.join('<br />'));
1953 } else if (response && response.success) {
1954 alert(response.message);
1955 setTimeout(function() {
1956 window.location.reload();
1957 }, 200);
1958 }
1959 });
1960 } else {
1961 $.unblockUI();
1962 }
1963 }
1964
1965 return {
1966 send_command: send_command,
1967 optimization_get_info: optimization_get_info,
1968 take_a_backup_with_updraftplus: take_a_backup_with_updraftplus,
1969 save_auto_backup_options: save_auto_backup_options
1970 }
1971 }; // END function WP_Optimize()
1972
1973 jQuery(function ($) {
1974 /**
1975 * Show additional options section if optimization enabled
1976 *
1977 * @param {string} checkbox Logger settings jQuery checkbox object.
1978 *
1979 * @return {void}
1980 */
1981 function show_hide_additional_logger_options($checkbox) {
1982 var additional_section_id = ['#', $checkbox.data('additional')].join('');
1983
1984 if ($checkbox.is(':checked')) {
1985 $(additional_section_id).show();
1986 } else {
1987 $(additional_section_id).hide();
1988 }
1989 }
1990
1991 // Add events handler for each logger.
1992 $('.wp-optimize-logging-settings').each(function () {
1993 var $checkbox = $(this);
1994 show_hide_additional_logger_options($checkbox);
1995 $checkbox.on('change', function () {
1996 show_hide_additional_logger_options($checkbox);
1997 });
1998 });
1999
2000 var add_logging_btn = $('#settings_form');
2001
2002 /**
2003 * Handle add logging destination click.
2004 */
2005 add_logging_btn.on('click', '#wpo_add_logger_link', function(e) {
2006 e.preventDefault();
2007 $('#wp-optimize-logger-settings .save_settings_reminder').after(get_add_logging_form_html());
2008
2009 filter_select_destinations($('.wpo_logger_type').first());
2010 });
2011
2012 /**
2013 * Handle logging destination select change.
2014 */
2015 $('#wp-optimize-general-settings').on('change', '.wpo_logger_type', function() {
2016 var select = $(this),
2017 logger_id = select.val(),
2018 options_container = select.parent().find('.wpo_additional_logger_options');
2019
2020 options_container.html(get_logging_additional_options_html(logger_id));
2021
2022 if (select.val()) {
2023 show_logging_save_settings_reminder();
2024 }
2025 });
2026
2027 /**
2028 * Show save settings reminder for logging settings.
2029 *
2030 * @return {void}
2031 */
2032 function show_logging_save_settings_reminder() {
2033 var reminder = $('#wp-optimize-logger-settings .save_settings_reminder');
2034
2035 if (!reminder.is(':visible')) {
2036 reminder.slideDown('normal');
2037 }
2038 }
2039
2040 /**
2041 * Handle edit logger click.
2042 */
2043 $('#settings_form').on('click', '.wpo_logging_actions_row .wpo_edit_logger', function() {
2044
2045 var link = $(this),
2046 container = link.closest('.wpo_logging_row');
2047
2048 $('.wpo_additional_logger_options', container).removeClass('wpo_hidden');
2049 $('.wpo_logging_options_row', container).hide();
2050 $('.wpo_logging_status_row', container).hide();
2051 /*link.hide();
2052 link.next('.wpo_delete_logger').hide();*/
2053 link.parent('.wpo_logging_actions_row').hide();
2054 $(container).children('.wpo_logging_edit_row').show();
2055
2056 return false;
2057 });
2058
2059 /**
2060 * Handle cancel logger click.
2061 */
2062 $('#settings_form').on('click', '.wpo_logging_edit_row .wpo_cancel_logging', function() {
2063
2064 var cancel_btn = $(this),
2065 container = cancel_btn.closest('.wpo_logging_row');
2066
2067 $(container).children('.wpo_logging_edit_row').hide();
2068 $(container).children('.wpo_logging_options_row').show();
2069 $(container).children('.wpo_logging_status_row').show();
2070 $(container).children('.wpo_logging_actions_row').show();
2071 $(container).children('.wpo_additional_logger_options').addClass('wpo_hidden');
2072
2073 return false;
2074 });
2075
2076 $('#wp-optimize-logger-settings').on('change', '.wpo_logger_addition_option', function() {
2077 show_logging_save_settings_reminder();
2078 });
2079
2080 /**
2081 * Handle change of active/inactive status and update hidden field value.
2082 */
2083 $('#settings_form').on('change', '.wpo_logger_active_checkbox', function() {
2084 var checkbox = $(this),
2085 hidden_input = checkbox.closest('label').find('input[type="hidden"]');
2086
2087 hidden_input.val(checkbox.is(':checked') ? '1' : '0');
2088 });
2089
2090 /**
2091 * Handle delete logger destination click.
2092 */
2093 $('#wp-optimize-general-settings').on('click', '.wpo_delete_logger', function() {
2094
2095 if (!confirm(wpoptimize.are_you_sure_you_want_to_remove_logging_destination)) {
2096 return false;
2097 }
2098
2099 var btn = $(this);
2100 btn.closest('.wpo_logging_row, .wpo_add_logger_form').remove();
2101 filter_all_select_destinations();
2102
2103 if (0 == $('#wp-optimize-logging-options .wpo_logging_row').length) {
2104 $('#wp-optimize-logging-options').hide();
2105 }
2106
2107 setTimeout(function(){
2108 $('#wp-optimize-save-main-settings').trigger('click');
2109 }, 500);
2110
2111 return false;
2112 });
2113
2114 /**
2115 * Filter all selects with logger destinations, called after some destination deleted.
2116 *
2117 * @return {void}
2118 */
2119 function filter_all_select_destinations() {
2120 $('.wpo_logger_type').each(function() {
2121 filter_select_destinations($(this));
2122 });
2123 }
2124
2125 /**
2126 * Filter certain select options depending on currently selected values.
2127 *
2128 * @param {object} select
2129 *
2130 * @return {void}
2131 */
2132 function filter_select_destinations(select) {
2133 var i,
2134 destination,
2135 current_destinations = get_current_destinations();
2136
2137 for (i in current_destinations) {
2138 destination = current_destinations[i];
2139 if (wpoptimize.loggers_classes_info[destination].allow_multiple) {
2140 $('option[value="'+destination+'"]', select).show();
2141 } else {
2142 $('option[value="'+destination+'"]', select).hide();
2143 }
2144 }
2145 }
2146
2147 /**
2148 * Returns currently selected loggers destinations.
2149 *
2150 * @return {Array}
2151 */
2152 function get_current_destinations() {
2153 var destinations = [];
2154
2155 $('.wpo_logging_row, .wpo_logger_type').each(function() {
2156 var destination = $(this).is('select') ? $(this).val() : $(this).data('id');
2157
2158 if (destination) destinations.push(destination);
2159 });
2160
2161 return destinations;
2162 }
2163
2164 /**
2165 * Return add logging form.
2166 *
2167 * @return {string}
2168 */
2169 function get_add_logging_form_html() {
2170 var i,
2171 select_options = [
2172 '<option value="">' + wpoptimize.select_destination + '</option>'
2173 ];
2174
2175 for (i in wpoptimize.loggers_classes_info) {
2176 if (!wpoptimize.loggers_classes_info.hasOwnProperty(i)) continue;
2177
2178 if (!wpoptimize.loggers_classes_info[i].available) continue;
2179
2180 select_options.push(['<option value="',i,'">',wpoptimize.loggers_classes_info[i].description,'</option>'].join(''));
2181 }
2182
2183 return [
2184 '<div class="wpo_add_logger_form">',
2185 '<select class="wpo_logger_type" name="wpo-logger-type[]">',
2186 select_options.join(''),
2187 '</select>',
2188 '<div class="wpo_logging_edit_row" style="display:block;"><span class="wpo_delete_logger button button-secondary" title="'+wpoptimize.cancel+'">'+wpoptimize.cancel+'</span>',
2189 '<span class="wpo_save_logging button button-primary" title="'+wpoptimize.add+'">'+wpoptimize.add+'</span></div>',
2190 '<div class="wpo_additional_logger_options"></div>',
2191 '</div>'
2192 ].join('');
2193 }
2194
2195 /**
2196 * Returns logging options html.
2197 *
2198 * @param {string} logger_id
2199 *
2200 * @return {string}
2201 */
2202 function get_logging_additional_options_html(logger_id) {
2203 if (!wpoptimize.loggers_classes_info[logger_id].options) return '';
2204
2205 var i,
2206 options = wpoptimize.loggers_classes_info[logger_id].options,
2207 options_list = [],
2208 placeholder = '',
2209 validate = '';
2210
2211 for (i in options) {
2212 if (!options.hasOwnProperty(i)) continue;
2213
2214 if (Array.isArray(options[i])) {
2215 placeholder = options[i][0].trim();
2216 validate = options[i][1].trim();
2217 } else {
2218 placeholder = options[i].trim();
2219 validate = '';
2220 }
2221
2222 options_list.push([
2223 '<input class="wpo_logger_addition_option" type="text" name="wpo-logger-options[',i,'][]" value="" ',
2224 'placeholder="',placeholder,'" ',('' !== validate ? 'data-validate="'+validate+'"' : ''), '/>'
2225 ].join(''));
2226 }
2227
2228 // Add hidden field for active/inactive value.
2229 options_list.push('<input type="hidden" name="wpo-logger-options[active][]" value="1" />');
2230
2231 return options_list.join('');
2232 }
2233
2234 /**
2235 * Layout - Adds `is-scrolled` class to the body element when scrolled.
2236 */
2237 var is_scrolled = false;
2238 $(window).on('scroll', function(e) {
2239 window.requestAnimationFrame(function() {
2240 var threshold = $('.wpo-main-header').length ? $('.wpo-main-header')[0].offsetTop : 0;
2241 if ((window.pageYOffset > threshold - 20) != is_scrolled) {
2242 is_scrolled = !is_scrolled;
2243 $('body').toggleClass('is-scrolled', is_scrolled);
2244 }
2245 });
2246 });
2247
2248 // Opens the video preview / info popup
2249 $('.wpo-info__trigger').on('click', function(e) {
2250 e.preventDefault();
2251 var $container = $(this).closest('.wpo-info');
2252 $container.toggleClass('opened');
2253 });
2254
2255 // Embed videos when clicking the vimeo links
2256 $('.wpo-video-preview a').on('click', function(e) {
2257 var video_url = $(this).data('embed');
2258 if (video_url) {
2259 e.preventDefault();
2260 var $iframe = $('<iframe width="356" height="200" allowfullscreen webkitallowfullscreen mozallowfullscreen>').attr('src', video_url);
2261 $iframe.insertAfter($(this));
2262 $(this).remove();
2263 $iframe.focus();
2264 }
2265 });
2266 });
2267