PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 3.2.21
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v3.2.21
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.21, at js/wpoadmin.js

2,286 lines 68.6 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 if optimizing tables.
568 if (id == 'optimizetables' && data.optimization_table) {
569 if (queue.is_empty()) {
570 $('#optimization_spinner_' + id).hide();
571 $('#optimization_checkbox_' + id).show();
572 $('.optimization_button_' + id).prop('disabled', false);
573
574 $('#optimization_info_' + id).html(wpoptimize.optimization_complete + (optimization_logged_warnings ? (' ' + wpoptimize.with_warnings) : ''));
575 } else {
576 $('#optimization_checkbox_' + id).hide();
577 $('#optimization_spinner_' + id).show();
578 $('.optimization_button_' + id).prop('disabled', true);
579 }
580 }
581
582 // check if we need update unapproved comments count.
583 if (response.result.meta && response.result.meta.hasOwnProperty('awaiting_mod')) {
584 var awaiting_mod = response.result.meta.awaiting_mod;
585 if (awaiting_mod > 0) {
586 $('#adminmenu .awaiting-mod .pending-count').remove(awaiting_mod);
587 } else {
588 // if there is no unapproved comments then remove bullet.
589 $('#adminmenu .awaiting-mod').remove();
590 }
591 }
592 }
593 setTimeout(function () {
594 queue.unlock(); process_queue();
595 }, 500);
596 }, true, request_options);
597 }
598
599 /**
600 * Update UI of sites list based on which site is currently being optimizated
601 *
602 * @param {Number} blog_id - current site id being optimized
603 * @param {Number} prev_blog_id - previous site id
604 *
605 * @return void
606 */
607 function do_site_ui_update(blog_id, prev_blog_id) {
608 if (0 != prev_blog_id) {
609 $("#site-" + prev_blog_id).show();
610 $("#optimization_spinner_site-" + prev_blog_id).hide();
611 }
612 $("#site-" + blog_id).hide();
613 $("#optimization_spinner_site-" + blog_id).show();
614 }
615
616 /**
617 * Runs a specified optimization, displaying the progress and results in the optimization's row
618 *
619 * @param {string} id - The optimization ID
620 *
621 * @return void
622 */
623 function do_optimization(id) {
624 var $optimization_row = $('#wp-optimize-nav-tab-contents-optimize .wp-optimize-settings-' + id);
625
626 if (!$optimization_row) {
627 console.log("do_optimization: row corresponding to this optimization (" + id + ") not found");
628 }
629
630 // check if there any additional inputs checkboxes.
631 var additional_data = {},
632 additional_data_length = 0;
633
634 $('input[type="checkbox"]', $('#optimization_info_' + id)).each(function() {
635 var checkbox = $(this);
636
637 if (checkbox.is(':checked')) {
638 additional_data[checkbox.attr('name')] = checkbox.val();
639 additional_data_length++;
640 }
641 });
642
643 // don't run optimization if optimization active.
644 if (true == $('.optimization_button_' + id).prop('disabled')) return;
645
646 var no_queue_actions_added = false;
647
648 // Check if it is DB optimize.
649 if ('optimizetables' == id) {
650 var optimization_tables = $('#wpoptimize_table_list #the-list tr'),
651 filter_by_blog_id = $('#wpo_sitelist_moreoptions').length > 0 && $('#wpo_sitelist_moreoptions').is(':visible'),
652 selected_sites = [];
653
654 // Get list of selected sites.
655 if (filter_by_blog_id) {
656 selected_sites = $('#wpo_sitelist_moreoptions input[type="checkbox"]:checked').map(function() {
657 return parseInt($(this).val());
658 }).get();
659 }
660
661 no_queue_actions_added = true;
662
663 // Check if there are any tables to be optimized.
664 $(optimization_tables).each(function (index) {
665 // Get information from each td.
666 var $table_information = $(this).find('td');
667
668 // Get table type information.
669 var table_type = $(this).data('type');
670 var table = $(this).data('tablename');
671 var optimizable = $(this).data('optimizable');
672 var blog_id = $(this).data('blog_id') ? parseInt($(this).data('blog_id')) : 1;
673 var in_selected_sites = true;
674
675
676 // Check if table is in the list of selected sites (multisite mode).
677 if (filter_by_blog_id && -1 == selected_sites.indexOf(blog_id)) {
678 in_selected_sites = false;
679 }
680
681 // Make sure the table isnt blank.
682 if ('' != table && in_selected_sites) {
683 // Check if table is optimizable or optimization forced by user.
684 if (1 == parseInt(optimizable) || optimization_force) {
685 var data = {
686 optimization_id: id,
687 blog_id: blog_id,
688 optimization_table: table,
689 optimization_table_type: table_type,
690 optimization_force: optimization_force
691 };
692
693 queue.enqueue(data);
694
695 no_queue_actions_added = false;
696 }
697 }
698 });
699 } else if (additional_data_length > 0) {
700 // check if additional data passed for optimization.
701 data = {
702 optimization_id: id
703 };
704
705 for (var i in additional_data) {
706 if (!additional_data.hasOwnProperty(i)) continue;
707 data[i] = additional_data[i];
708 }
709
710 queue.enqueue(data);
711 } else {
712 queue.enqueue(id);
713 }
714
715 // if new actions was not added in tasks queue then we don't process queue.
716 if (no_queue_actions_added) return;
717
718 $('#optimization_checkbox_' + id).hide();
719 $('#optimization_spinner_' + id).show();
720 $('.optimization_button_' + id).prop('disabled', true);
721
722 $('#optimization_info_' + id).html('...');
723
724 process_queue();
725 }
726
727
728 /**
729 * Run action and save selected sites list options.
730 *
731 * @param {function} action - action to do after save.
732 *
733 * @return void
734 */
735 function save_sites_list_and_do_action(action) {
736 // if multisite mode then save sites list before action.
737 if ($('#wpo_settings_sites_list').length) {
738 // save wpo-sites settings.
739 send_command('save_site_settings', {'wpo-sites': get_selected_sites_list()}, function () {
740 // do action.
741 if (action) action();
742 });
743 } else {
744 // do action.
745 if (action) action();
746 }
747 }
748
749 /**
750 * Returns list of selected sites list.
751 *
752 * @return {Array}
753 */
754 function get_selected_sites_list() {
755 var wpo_sites = [];
756
757 $('#wpo_settings_sites_list input[type="checkbox"]').each(function () {
758 var checkbox = $(this);
759 if (checkbox.is(':checked')) {
760 wpo_sites.push(checkbox.attr('value'));
761 }
762 });
763
764 return wpo_sites;
765 }
766
767 /*
768 * Run single optimization click.
769 */
770 $('#wp-optimize-nav-tab-WP-Optimize-optimize-contents').on('click', 'button.wp-optimize-settings-optimization-run-button', function () {
771 var optimization_id = $(this).closest('.wp-optimize-settings').data('optimization_id');
772 if (!optimization_id) {
773 console.log("Optimization ID corresponding to pressed button not found");
774 return;
775 }
776 // if run button disabled then don't run this optimization.
777 if (true == $('.optimization_button_' + optimization_id).prop('disabled')) return;
778 // disable run button before save sites list.
779 $('.optimization_button_' + optimization_id).prop('disabled', true);
780
781 save_sites_list_and_do_action(function() {
782 $('.optimization_button_' + optimization_id).prop('disabled', false);
783 do_optimization(optimization_id);
784 });
785 });
786
787 /*
788 * Run all optimizations click.
789 */
790 $('#wp-optimize-nav-tab-WP-Optimize-optimize-contents').on('click', '#wp-optimize', function (e) {
791 var run_btn = $(this);
792
793 e.preventDefault();
794
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();
800 });
801 });
802
803 /**
804 * Sent command to run selected optimizations and auto backup if selected
805 *
806 * @return void
807 */
808 function run_optimizations() {
809 var auto_backup = false;
810
811 if ($('#enable-auto-backup').is(":checked")) {
812 auto_backup = true;
813 }
814
815 // Save the click option.
816 save_auto_backup_options();
817
818 // Only run the backup if tick box is checked.
819 if (auto_backup == true) {
820 take_a_backup_with_updraftplus(run_optimization);
821 } else {
822 // Run optimizations.
823 run_optimization();
824 }
825 }
826
827 /**
828 * Take a backup with UpdraftPlus if possible.
829 *
830 * @param {Function} callback
831 * @param {String} file_entities
832 *
833 * @return void
834 */
835 function take_a_backup_with_updraftplus(callback, file_entities) {
836 // Set default for file_entities to empty string
837 if ('undefined' == typeof file_entities) file_entities = '';
838 var exclude_files = file_entities ? 0 : 1;
839
840 if (typeof updraft_backupnow_inpage_go === 'function') {
841 updraft_backupnow_inpage_go(function () {
842 // Close the backup dialogue.
843 $('#updraft-backupnow-inpage-modal').dialog('close');
844
845 if (callback) callback();
846
847 }, file_entities, 'autobackup', 0, exclude_files, 0, wpoptimize.automatic_backup_before_optimizations);
848 } else {
849 if (callback) callback();
850 }
851 }
852
853 /**
854 * Save all auto backup options.
855 *
856 * @return void
857 */
858 function save_auto_backup_options() {
859 var options = gather_settings('object');
860 options['auto_backup'] = $('#enable-auto-backup').is(":checked");
861
862 send_command('save_auto_backup_option', options);
863 }
864
865 // Show/hide sites list for multi-site settings.
866 var wpo_settings_sites_list = $('#wpo_settings_sites_list'),
867 wpo_settings_sites_list_ul = wpo_settings_sites_list.find('ul').first(),
868 wpo_settings_sites_list_items = $('input[type="checkbox"]', wpo_settings_sites_list_ul),
869 wpo_settings_all_sites_checkbox = wpo_settings_sites_list.find('#wpo_all_sites'),
870 wpo_sitelist_show_moreoptions_link = $('#wpo_sitelist_show_moreoptions'),
871 wpo_sitelist_moreoptions_div = $('#wpo_sitelist_moreoptions'),
872
873 wpo_settings_sites_list_cron = $('#wpo_settings_sites_list_cron'),
874 wpo_settings_sites_list_cron_ul = wpo_settings_sites_list_cron.find('ul').first(),
875 wpo_settings_sites_list_cron_items = $('input[type="checkbox"]', wpo_settings_sites_list_cron_ul),
876 wpo_settings_all_sites_cron_checkbox = wpo_settings_sites_list_cron.find('#wpo_all_sites_cron'),
877 wpo_sitelist_show_moreoptions_cron_link = $('#wpo_sitelist_show_moreoptions_cron'),
878 wpo_sitelist_moreoptions_cron_div = $('#wpo_sitelist_moreoptions_cron');
879
880 // sites list for manual run.
881 define_moreoptions_settings(
882 wpo_sitelist_show_moreoptions_link,
883 wpo_sitelist_moreoptions_div,
884 wpo_settings_all_sites_checkbox,
885 wpo_settings_sites_list_items
886 );
887
888 var sites_list_clicked_count = 0;
889
890 $([wpo_settings_all_sites_checkbox, wpo_settings_sites_list_items]).each(function() {
891 $(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();
896 }, 1000);
897 });
898 });
899
900 // sites list for cron run.
901 define_moreoptions_settings(
902 wpo_sitelist_show_moreoptions_cron_link,
903 wpo_sitelist_moreoptions_cron_div,
904 wpo_settings_all_sites_cron_checkbox,
905 wpo_settings_sites_list_cron_items
906 );
907
908 /**
909 * Attach event handlers for more options list showed by clicking on show_moreoptions_link.
910 *
911 * @param show_moreoptions_link
912 * @param more_options_div
913 * @param all_items_checkbox
914 * @param items_list
915 *
916 * @return boolean
917 */
918 function define_moreoptions_settings(show_moreoptions_link, more_options_div, all_items_checkbox, items_list) {
919 // toggle show options on click.
920 show_moreoptions_link.on('click', function () {
921 if (!more_options_div.hasClass('wpo_always_visible')) more_options_div.toggleClass('wpo_hidden');
922 return false;
923 });
924
925 // if "all items" checked/unchecked then check/uncheck items in the list.
926 define_select_all_checkbox(all_items_checkbox, items_list);
927 }
928
929 /**
930 * Defines "select all" check box, where all_items_checkbox is a select all check box jQuery object
931 * and items_list is a list of checkboxes assigned with all_items_checkbox.
932 *
933 * @param {Object} all_items_checkbox
934 * @param {Object} items_list
935 *
936 * @return void
937 */
938 function define_select_all_checkbox(all_items_checkbox, items_list) {
939 // if "all items" checked/unchecked then check/uncheck items in the list.
940 all_items_checkbox.on('change', function () {
941 if (all_items_checkbox.is(':checked')) {
942 items_list.prop('checked', true);
943 } else {
944 items_list.prop('checked', false);
945 }
946
947 update_wpo_all_items_checkbox_state(all_items_checkbox, items_list);
948 });
949
950 items_list.on('change', function () {
951 update_wpo_all_items_checkbox_state(all_items_checkbox, items_list);
952 });
953
954 update_wpo_all_items_checkbox_state(all_items_checkbox, items_list);
955
956 }
957
958 /**
959 * Update state of "all items" checkbox depends on state all items in the list.
960 *
961 * @param all_items_checkbox
962 * @param all_items
963 *
964 * @return void
965 */
966 function update_wpo_all_items_checkbox_state(all_items_checkbox, all_items) {
967 var all_items_count = 0, checked_items_count = 0;
968
969 all_items.each(function () {
970 if ($(this).is(':checked')) {
971 checked_items_count++;
972 }
973 all_items_count++;
974 });
975
976 // update label text if need.
977 if (all_items_checkbox.next().is('label') && all_items_checkbox.next().data('label')) {
978 var label = all_items_checkbox.next(),
979 label_mask = label.data('label');
980
981 if (all_items_count == checked_items_count) {
982 label.text(label_mask);
983 } else {
984 label.text(label_mask.replace('all', [checked_items_count, ' of ', all_items_count].join('')));
985 }
986 }
987
988 if (all_items_count == checked_items_count) {
989 all_items_checkbox.prop('checked', true);
990 } else {
991 all_items_checkbox.prop('checked', false);
992 }
993 }
994
995 /**
996 * Running the optimizations for the selected options
997 *
998 * @return {[type]} optimizations
999 */
1000 function run_optimization() {
1001 $optimizations = $('#optimizations_list .optimization_checkbox:checked');
1002
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 }
1014 });
1015
1016 var optimization_options = {};
1017
1018 $optimizations.each(function (index) {
1019 var optimization_id = $(this).closest('.wp-optimize-settings').data('optimization_id');
1020 if (!optimization_id) {
1021 console.log("Optimization ID corresponding to pressed button not found");
1022 return;
1023 }
1024 // An empty object - in future, options may be implemented.
1025 optimization_options[optimization_id] = { active: 1 };
1026 do_optimization(optimization_id);
1027 });
1028
1029 send_command('save_manual_run_optimization_options', optimization_options);
1030 }
1031
1032 /**
1033 * Uptate the tables list
1034 *
1035 * @param {object} response
1036 */
1037 function update_tables_list(response) {
1038 if (response.hasOwnProperty('table_list')) {
1039 var resort = true,
1040 // add a callback, as desired
1041 callback = function(table) {
1042 $('#wpoptimize_table_list tbody').css('opacity', '1');
1043 };
1044
1045 // update body with new content.
1046 $("#wpoptimize_table_list tbody").remove();
1047 $("#wpoptimize_table_list thead").after(response.table_list);
1048
1049 $("#wpoptimize_table_list").trigger("updateAll", [resort, callback]);
1050 }
1051
1052 if (response.hasOwnProperty('total_size')) {
1053 $('#optimize_current_db_size').html(response.total_size);
1054 }
1055
1056 if (response.hasOwnProperty('show_innodb_force_optimize')) {
1057 $('.innodb_force_optimize--container').toggleClass('hidden', !response.show_innodb_force_optimize);
1058 }
1059
1060 change_actions_column_visibility();
1061 update_single_table_optimization_buttons(force_single_table_optimization);
1062 }
1063
1064 $('#wp_optimize_table_list_refresh').on('click', function (e) {
1065 e.preventDefault();
1066 var shade = $(this).closest('.wpo-tab-postbox').find('.wpo_shade');
1067 shade.removeClass('hidden');
1068 $('#wpoptimize_table_list tbody').css('opacity', '0.5');
1069 send_command('get_table_list', {refresh_plugin_json: true}, update_tables_list).always(function() {
1070 shade.addClass('hidden');
1071 });
1072 });
1073
1074 $('#database_settings_form, #settings_form').on('click', '.wpo-save-settings', function (e) {
1075 e.preventDefault();
1076 var form = $(this).closest('form');
1077 var spinner = form.find('.wpo-saving-settings');
1078 var form_data = gather_settings();
1079
1080 form.trigger('wpo-saving-form-data');
1081
1082 if (form.form_errors.has_errors()) return;
1083
1084 spinner.show();
1085 $.blockUI();
1086
1087 // when optimizations list in the document - send information about selected optimizations.
1088 if ($('#optimizations_list').length) {
1089 $('#optimizations_list .optimization_checkbox:checked').each(function() {
1090 var optimization_id = $(this).closest('.wp-optimize-settings').data('optimization_id');
1091 if (optimization_id) {
1092 form_data += '&optimization-options['+optimization_id+'][active]=1';
1093 }
1094 });
1095 }
1096
1097 if ($('#purge_cache_permissions').length) {
1098 if (!$('#purge_cache_permissions').val()) {
1099 form_data += '&purge_cache_permissions[]';
1100 }
1101 }
1102
1103 send_command('save_settings', form_data, function (resp) {
1104 spinner.closest('div').find('.save-done').show().delay(5000).fadeOut();
1105
1106 if (resp && resp.hasOwnProperty('save_results') && resp.save_results && resp.save_results.hasOwnProperty('errors')) {
1107 for (var i = 0, len = resp.save_results.errors.length; i < len; i++) {
1108 var new_html = '<div class="error">' + resp.errors[i] + '</div>';
1109 temporarily_display_notice(new_html, '#wp-optimize-settings-save-results');
1110 }
1111 }
1112 if (resp && resp.hasOwnProperty('status_box_contents')) {
1113 $(resp.status_box_contents).each(function(index, el) {
1114 if ($(el).is('#wp_optimize_status_box')) {
1115 $('#wp_optimize_status_box').replaceWith($(el));
1116 }
1117 });
1118 }
1119
1120 if (resp && resp.hasOwnProperty('optimizations_table')) {
1121 $('#optimizations_list').replaceWith(resp.optimizations_table);
1122 }
1123
1124 if (resp && resp.hasOwnProperty('settings_auto_cleanup_contents')) {
1125 $('#wpo_auto_cleanup').replaceWith(resp.settings_auto_cleanup_contents);
1126 }
1127
1128 if (resp && resp.hasOwnProperty('logging_settings_contents')) {
1129 $('#wpo_logging_settings').replaceWith(resp.logging_settings_contents);
1130 }
1131
1132 // Need to refresh the page if enable-admin-menu tick state has changed.
1133 if (resp.save_results.refresh) {
1134 location.reload();
1135 }
1136 }).always(function() {
1137 spinner.hide();
1138 $.unblockUI();
1139 });
1140 });
1141
1142 $('#database_settings_form').on('click', '.wpo_save_event', function() {
1143 setTimeout(function(){
1144 $('#wp-optimize-save-database-settings').trigger('click');
1145 }, 500);
1146 });
1147
1148 $('#settings_form').on('click', '.wpo_save_logging', function() {
1149 setTimeout(function(){
1150 $('#wp-optimize-save-main-settings').trigger('click');
1151 }, 500);
1152 });
1153
1154 /*
1155 * Handle Wipe Settings click.
1156 */
1157 $('#settings_form').on('click', '.wpo-wipe-settings', function() {
1158 var spinner = $(this).parent().find('.wpo_spinner');
1159
1160 spinner.show();
1161
1162 send_command('wipe_settings', {}, function() {
1163 spinner.next().removeClass('display-none').delay(5000).fadeOut();
1164 alert(wpoptimize.settings_have_been_deleted_successfully);
1165 location.replace(wpoptimize.settings_page_url);
1166 }).always(function() {
1167 spinner.hide();
1168 });
1169
1170 });
1171
1172 $('#wp-optimize-wrap').on('click', '#wp_optimize_status_box_refresh', function (e) {
1173 e.preventDefault();
1174 $('#wp_optimize_status_box').css('opacity', '0.5');
1175 send_command('get_status_box_contents', null, function (resp) {
1176 $('#wp_optimize_status_box').css('opacity', '1');
1177 $(resp).each(function(index, el) {
1178 if ($(el).is('#wp_optimize_status_box')) {
1179 $('#wp_optimize_status_box').replaceWith($(el));
1180 }
1181 });
1182
1183 });
1184 });
1185
1186 /**
1187 * Run single table optimization. Handle click on Optimize button.
1188 *
1189 * @param {Object} btn jQuery object clicked Optimize button
1190 *
1191 * @return {void}
1192 */
1193 function run_single_table_optimization(btn) {
1194 var spinner = btn.next(),
1195 action_done_icon = spinner.next(),
1196 table_name = btn.data('table'),
1197 table_type = btn.data('type'),
1198 data = {
1199 optimization_id: 'optimizetables',
1200 optimization_table: table_name,
1201 optimization_table_type: table_type
1202 };
1203 btn.hide();
1204 // if checked force button then send force value.
1205 if (force_single_table_optimization) {
1206 data['optimization_force'] = true;
1207 }
1208
1209 spinner.removeClass('visibility-hidden');
1210
1211 send_command('do_optimization', { optimization_id: 'optimizetables', data: data }, function (response) {
1212 if (response.result.meta.error) {
1213 btn.closest('tr').html('<td colspan="8" class="no-table"><p>' + response.result.meta.message + '</p></td>');
1214 setTimeout(function() {
1215 $('#wp_optimize_table_list_refresh').trigger('click');
1216 }, 2000);
1217 } else {
1218 if (response.result.meta.tableinfo) {
1219 var row = btn.closest('tr'),
1220 meta = response.result.meta,
1221 tableinfo = meta.tableinfo;
1222
1223 update_single_table_information(row, tableinfo);
1224
1225 // update total overhead.
1226 $('#wpoptimize_table_list > tbody:last th:eq(6)').html(['<span style="color:', meta.overhead > 0 ? '#0000FF' : '#004600', '">', meta.overhead_formatted,'</span>'].join(''));
1227 }
1228 }
1229
1230 btn.prop('disabled', false);
1231 spinner.addClass('visibility-hidden');
1232 action_done_icon.show().removeClass('visibility-hidden').delay(2500).fadeOut('fast', function() {
1233 btn.show();
1234 });
1235 });
1236 }
1237
1238 /**
1239 * Update information about single table in the database tables list.
1240 *
1241 * @param {Object} row jQuery object for TR html tag.
1242 * @param {Object} tableinfo
1243 *
1244 * @return {void}
1245 */
1246 function update_single_table_information(row, tableinfo) {
1247 // update table information in row.
1248 $('td:eq(2)', row).text(tableinfo.rows);
1249 $('td:eq(3)', row).text(tableinfo.data_size);
1250 $('td:eq(4)', row).text(tableinfo.index_size);
1251 $('td:eq(5)', row).text(tableinfo.type);
1252
1253 if (tableinfo.is_optimizable) {
1254 $('td:eq(6)', row).html(['<span style="color:', tableinfo.overhead > 0 ? '#0000FF' : '#004600', '">', tableinfo.overhead,'</span>'].join(''));
1255 } else {
1256 $('td:eq(6)', row).html('<span color="#0000FF">-</span>');
1257 }
1258
1259 }
1260
1261 /**
1262 * Update single table optimization buttons state depends on force_optimization value.
1263 *
1264 * @param {boolean} force_optimization See if we need to force optimization
1265 *
1266 * @return {void}
1267 */
1268 function update_single_table_optimization_buttons(force_optimization) {
1269 $('.run-single-table-optimization').each(function() {
1270 var btn = $(this);
1271
1272 if (btn.data('disabled')) {
1273 if (force_optimization) {
1274 btn.prop('disabled', false);
1275 } else {
1276 btn.prop('disabled', true);
1277 }
1278 }
1279 });
1280 }
1281
1282 /**
1283 * Returns true if single site mode or multisite and at least one site selected;
1284 *
1285 * @return {boolean}
1286 */
1287 function is_sites_selected() {
1288 return (0 == wpo_settings_sites_list.length || 0 != $('input[type="checkbox"]:checked', wpo_settings_sites_list).length);
1289 }
1290
1291 /**
1292 * Update optimizations info texts.
1293 *
1294 * @param {Object} response object returned by command get_optimizations_info.
1295 *
1296 * @return {void}
1297 */
1298 function update_optimizations_info_view(response) {
1299 var i, dom_id, info;
1300
1301 // @codingStandardsIgnoreLine
1302 if (!response) return;
1303
1304 for (i in response) {
1305 if (!response.hasOwnProperty(i)) continue;
1306
1307 dom_id = ['#wp-optimize-settings-', response[i].dom_id].join('');
1308 info = response[i].info ? response[i].info.join('<br>') : '';
1309
1310 $(dom_id + ' .wp-optimize-settings-optimization-info').html(info);
1311 }
1312 }
1313
1314 var get_optimizations_info_cache = {};
1315
1316 /**
1317 * Send command for get optimizations info and update view.
1318 *
1319 * @return {void}
1320 */
1321 function update_optimizations_info() {
1322 var cache_key = ['', get_selected_sites_list().join('_')].join('');
1323
1324 // if information saved in cache show it.
1325 if (get_optimizations_info_cache.hasOwnProperty(cache_key)) {
1326 update_optimizations_info_view(get_optimizations_info_cache[cache_key]);
1327 } else {
1328 // else send command update cache and update view.
1329 send_command('get_optimizations_info', {'wpo-sites':get_selected_sites_list()}, function(response) {
1330 // @codingStandardsIgnoreLine
1331 if (!response) return;
1332 get_optimizations_info_cache[cache_key] = response;
1333 update_optimizations_info_view(response);
1334 });
1335 }
1336 }
1337
1338 /*
1339 * Check if settings file selected for import.
1340 */
1341 $('#wpo_import_settings_btn').on('click', function(e) {
1342 var file_input = $('#wpo_import_settings_file'),
1343 filename = file_input.val(),
1344 wpo_import_file_file = file_input[0].files[0],
1345 wpo_import_file_reader = new FileReader();
1346
1347 $('#wpo_import_settings_btn').prop('disabled', true);
1348
1349 if (!/\.json$/.test(filename)) {
1350 e.preventDefault();
1351 $('#wpo_import_settings_btn').prop('disabled', false);
1352 $('#wpo_import_error_message').text(wpoptimize.please_select_settings_file).slideDown();
1353 return false;
1354 }
1355
1356 wpo_import_file_reader.onload = function() {
1357 import_settings(this.result);
1358 };
1359
1360 wpo_import_file_reader.readAsText(wpo_import_file_file);
1361
1362 return false;
1363 });
1364
1365 /**
1366 * Send import settings command.
1367 *
1368 * @param {string} settings encoded settings in json string.
1369 *
1370 * @return {void}
1371 */
1372 function import_settings(settings) {
1373 var loader = $('#wpo_import_spinner'),
1374 success_message = $('#wpo_import_success_message'),
1375 error_message = $('#wpo_import_error_message');
1376
1377 loader.show();
1378 send_command('import_settings', {'settings': settings}, function(response) {
1379 loader.hide();
1380 if (response && response.errors && response.errors.length) {
1381 error_message.text(response.errors.join('<br>'));
1382 error_message.slideDown();
1383 } else if (response && response.messages && response.messages.length) {
1384 success_message.text(response.messages.join('<br>'));
1385 success_message.slideDown();
1386 setTimeout(function() {
1387 window.location.reload();
1388 }, 500);
1389 }
1390
1391 $('#wpo_import_settings_btn').prop('disabled', false);
1392 });
1393 }
1394
1395 /*
1396 * Hide file validation message on change file field value.
1397 */
1398 $('#wpo_import_settings_file').on('change', function() {
1399 $('#wpo_import_error_message').slideUp();
1400 });
1401
1402 /*
1403 * Save settings to hidden form field, used for export.
1404 */
1405 $('#wpo_export_settings_btn').on('click', function(e) {
1406 wpo_download_json_file(gather_settings('object'));
1407 return false;
1408 });
1409
1410 /**
1411 * Force download json file with posted data.
1412 *
1413 * @param {Object} data data to put in a file.
1414 * @param {string} filename
1415 *
1416 * @return {void}
1417 */
1418 function wpo_download_json_file(data ,filename) {
1419 // Attach this data to an anchor on page
1420 var link = document.body.appendChild(document.createElement('a')),
1421 date = new Date(),
1422 year = date.getFullYear(),
1423 month = date.getMonth() < 10 ? ['0', date.getMonth()].join('') : date.getMonth(),
1424 day = date.getDay() < 10 ? ['0', date.getDay()].join('') : date.getDay();
1425
1426 filename = filename ? filename : ['wpo-settings-',year,'-',month,'-',day,'.json'].join('');
1427
1428 link.setAttribute('download', filename);
1429 link.setAttribute('style', "display:none;");
1430 link.setAttribute('href', 'data:text/json' + ';charset=UTF-8,' + encodeURIComponent(JSON.stringify(data)));
1431 link.click();
1432 }
1433
1434 /**
1435 * Make ajax request to get optimization info.
1436 *
1437 * @param {Object} optimization_info_container - jquery object obtimization info container.
1438 * @param {string} optimization_id - optimization id.
1439 * @param {Object} params - custom params posted to optimization get info.
1440 *
1441 * @return void
1442 */
1443 var optimization_get_info = function(optimization_info_container, optimization_id, params) {
1444 return send_command('get_optimization_info', {optimization_id: optimization_id, data: params}, function(resp) {
1445 var meta = (resp && resp.result && resp.result.meta) ? resp.result.meta : {},
1446 message = (resp && resp.result && resp.result.output) ? resp.result.output.join('<br>') : '...';
1447
1448 // trigger event about optimization get info in process.
1449 $(document).trigger(['optimization_get_info_', optimization_id].join(''), [message, meta]);
1450 // update status message in optimizations list.
1451 optimization_info_container.html(message);
1452
1453 if (!meta.finished) {
1454 setTimeout(function() {
1455 var xhr = optimization_get_info(optimization_info_container, optimization_id, meta);
1456 $(document).trigger(['optimization_get_info_xhr_', optimization_id].join(''), [xhr, meta]);
1457 }, 1);
1458 } else {
1459 // trigger event about optimization get info action done.
1460 $(document).trigger(['optimization_get_info_', optimization_id, '_done'].join(''), resp);
1461 }
1462 });
1463 };
1464
1465 /*
1466 * Handle ajax information for optimizations.
1467 *
1468 * @return void
1469 */
1470 jQuery(function() {
1471 $('.wp-optimize-optimization-info-ajax').each(function () {
1472 var optimization_info = $(this),
1473 optimization_info_container = optimization_info.parent(),
1474 optimization_id = optimization_info.data('id');
1475
1476 // trigger event about optimization get info action started.
1477 $(document).trigger(['optimization_get_info_', optimization_id, '_start'].join(''));
1478 optimization_get_info(optimization_info_container, optimization_id, {support_ajax_get_info: true});
1479 });
1480 });
1481
1482 // attach event handlers after database tables template loaded.
1483 // Handle single optimization click.
1484 $('#wpoptimize_table_list').on('click', '.run-single-table-optimization', function () {
1485 var take_backup_checkbox = $('#enable-auto-backup-1'),
1486 button = $(this);
1487
1488 // check if backup checkbox is checked for db tables
1489 if (take_backup_checkbox.is(':checked')) {
1490 take_a_backup_with_updraftplus(
1491 function () {
1492 run_single_table_optimization(button);
1493 }
1494 );
1495 } else {
1496 run_single_table_optimization(button);
1497 }
1498 });
1499
1500 // Handle repair table click
1501 $('#wpoptimize_table_list').on('click', '.run-single-table-repair', function () {
1502 var btn = $(this),
1503 spinner = btn.next(),
1504 action_done_icon = spinner.next(),
1505 table_name = btn.data('table'),
1506 data = {
1507 optimization_id: 'repairtables',
1508 optimization_table: table_name
1509 };
1510
1511 spinner.removeClass('visibility-hidden');
1512
1513 send_command('do_optimization', {optimization_id: 'repairtables', data: data}, function (response) {
1514 if (response.result.meta.success) {
1515 var row = btn.closest('tr'),
1516 tableinfo = response.result.meta.tableinfo;
1517
1518 btn.prop('disabled', false);
1519 spinner.addClass('visibility-hidden');
1520 action_done_icon.show().removeClass('visibility-hidden');
1521
1522 update_single_table_information(row, tableinfo);
1523
1524 // keep visible results from previous operation for one second and show optimize button if possible.
1525 setTimeout(function () {
1526 var parent_td = btn.closest('td'),
1527 btn_wrap = btn.closest('.wpo_button_wrap');
1528
1529 // remove Repair button and show Optimize button.
1530 btn_wrap.fadeOut('fast', function () {
1531 btn_wrap.closest('.wpo_button_wrap').remove();
1532
1533 // if table type is supported for optimization then show OPTIMIZE button.
1534 if (tableinfo.is_type_supported) {
1535 $('.wpo_button_wrap', parent_td).removeClass('wpo_hidden');
1536 }
1537 });
1538
1539 change_actions_column_visibility();
1540 }, 1000);
1541 } else {
1542 btn.prop('disabled', false);
1543 spinner.addClass('visibility-hidden');
1544 alert(wpoptimize.table_was_not_repaired.replace('%s', table_name));
1545 }
1546 });
1547 });
1548
1549 // Handle convert table click
1550 $('#wpoptimize_table_list').on('click', '.toinnodb', function () {
1551 convert_single_db_table($(this));
1552 });
1553
1554 var table_to_remove_btn;
1555
1556 // Handle delete table click
1557 $('#wpoptimize_table_list').on('click', '.run-single-table-delete', function () {
1558 table_to_remove_btn = $(this);
1559 var take_backup_checkbox = $('#enable-auto-backup-1');
1560 if ('' == wpoptimize.user_always_ignores_table_delete_warning || '1' !== wpoptimize.user_always_ignores_table_delete_warning) {
1561 wp_optimize.modal.open({
1562 className: 'wpo-confirm',
1563 events: {
1564 'click .wpo-modal--bg': 'close',
1565 'click .delete-table': 'deleteTable',
1566 'change #confirm_deletion_without_backup': 'changeConfirm',
1567 'change #confirm_table_deletion': 'changeConfirm'
1568 },
1569 content: function() {
1570 var content_template = wp.template('wpo-table-delete');
1571 // Get the plugins list
1572 var plugins_list = table_to_remove_btn.closest('tr').find('.table-plugins').html();
1573 return content_template({
1574 no_backup: !take_backup_checkbox.is(':checked'),
1575 plugins_list: plugins_list,
1576 table_name: table_to_remove_btn.data('table')
1577 });
1578 },
1579 changeConfirm: function() {
1580 var enable_button = true;
1581 var backup_input = this.$('#confirm_deletion_without_backup');
1582 var confirm_input = this.$('#confirm_table_deletion');
1583 if (backup_input.length && !backup_input.is(':checked')) {
1584 enable_button = false;
1585 }
1586 if (!confirm_input.is(':checked')) {
1587 enable_button = false;
1588 }
1589 this.$('.delete-table').prop('disabled', !enable_button);
1590 },
1591 deleteTable: function() {
1592 // check if user ignore table warning
1593 var ignores_table_detele_warning_checkbox = this.$('#ignores_table_delete_warning');
1594 if (ignores_table_detele_warning_checkbox.is(':checked')) {
1595 send_command('user_ignores_table_delete_warning', {}, function(response) {
1596 if (response.success) {
1597 wpoptimize.user_always_ignores_table_delete_warning = '1';
1598 }
1599 });
1600 }
1601 // check if backup checkbox is checked for db tables
1602 if (take_backup_checkbox.is(':checked')) {
1603 take_a_backup_with_updraftplus(remove_single_db_table);
1604 } else {
1605 remove_single_db_table();
1606 }
1607 this.close();
1608
1609 }
1610 });
1611 } else {
1612 // check if backup checkbox is checked for db tables
1613 if (take_backup_checkbox.is(':checked')) {
1614 take_a_backup_with_updraftplus(remove_single_db_table);
1615 } else {
1616 remove_single_db_table();
1617 }
1618 }
1619 });
1620
1621 /**
1622 * Send ajax command to convert single table to InnoDB.
1623 *
1624 * @param {Object} btn jQuery object of clicked "Convert to InnoDB" button.
1625 *
1626 * @return void
1627 */
1628 function convert_single_db_table(table_to_convert_btn) {
1629 var spinner = table_to_convert_btn.next(),
1630 action_done_icon = spinner.next(),
1631 table_name = table_to_convert_btn.data('table'),
1632 data = {
1633 optimization_id: 'orphanedtables',
1634 optimization_table: table_name,
1635 optimization_action: 'toinnodb'
1636 };
1637
1638 spinner.removeClass('visibility-hidden');
1639
1640 send_command('do_optimization', { optimization_id: 'orphanedtables', data: data }, function (response) {
1641 if (response.result.meta.error) {
1642 table_to_convert_btn.closest('tr').html('<td colspan="8" class="no-table"><p>' + response.result.meta.message + '</p></td>');
1643 setTimeout(function() {
1644 $('#wp_optimize_table_list_refresh').trigger('click');
1645 }, 2000);
1646 return;
1647 }
1648 if (response.result.meta.success) {
1649 var row = table_to_convert_btn.closest('tr');
1650
1651 action_done_icon.show().removeClass('visibility-hidden');
1652
1653 // remove convert to Innodb button.
1654 row.find(".toinnodb").remove();
1655
1656
1657 setTimeout(function() {
1658 action_done_icon.fadeOut('slow', function() {
1659 row.find("[data-colname='Type']").text("InnoDB");
1660 });
1661 }, 500);
1662 } else {
1663 var message = wpoptimize.table_was_not_converted.replace('%s', table_name);
1664
1665 if (response.result.meta.message) {
1666 message += '(' + response.result.meta.message + ')';
1667 }
1668
1669 alert(message);
1670 }
1671 }).always(function() {
1672 table_to_convert_btn.prop('disabled', false);
1673 spinner.addClass('visibility-hidden');
1674 });
1675 }
1676
1677
1678
1679 /**
1680 * Send ajax commant to remove single database table.
1681 *
1682 * @param {Object} btn jQuery object of clicked "Remove" button.
1683 *
1684 * @return void
1685 */
1686 function remove_single_db_table() {
1687 var spinner = table_to_remove_btn.next(),
1688 action_done_icon = spinner.next(),
1689 table_name = table_to_remove_btn.data('table'),
1690 data = {
1691 optimization_id: 'orphanedtables',
1692 optimization_table: table_name
1693 };
1694
1695 spinner.removeClass('visibility-hidden');
1696
1697 send_command('do_optimization', { optimization_id: 'orphanedtables', data: data }, function (response) {
1698 if (response.result.meta.success) {
1699 var row = table_to_remove_btn.closest('tr');
1700
1701 action_done_icon.show().removeClass('visibility-hidden');
1702
1703 // remove row for deleted table.
1704 setTimeout(function() {
1705 row.fadeOut('slow', function() {
1706 row.remove();
1707
1708 change_actions_column_visibility();
1709 });
1710 }, 500);
1711 } else {
1712 var message = wpoptimize.table_was_not_deleted.replace('%s', table_name);
1713
1714 if (response.result.meta.message) {
1715 message += '(' + response.result.meta.message + ')';
1716 }
1717
1718 alert(message);
1719 }
1720 }).always(function() {
1721 table_to_remove_btn.prop('disabled', false);
1722 spinner.addClass('visibility-hidden');
1723 });
1724 }
1725
1726 change_actions_column_visibility();
1727
1728 /**
1729 * Show or hide actions column if need.
1730 *
1731 * @return void
1732 */
1733 function change_actions_column_visibility() {
1734 var table = $('#wpoptimize_table_list'),
1735 hideLastColumn = true;
1736
1737 // check if any button exists in the actions column.
1738 $('tr', table).each(function() {
1739 var row = $(this);
1740
1741 if ($('button', row).length > 0) {
1742 hideLastColumn = false;
1743 return false;
1744 }
1745 });
1746
1747 // hide or show last column
1748 $('tr', table).each(function() {
1749 var row = $(this);
1750
1751 if (hideLastColumn) {
1752 $('td:last, th:last', row).hide();
1753 } else {
1754 $('td:last, th:last', row).show();
1755 }
1756 });
1757 }
1758
1759 /*
1760 * Validate general settings (loggers).
1761 */
1762 $('#wp-optimize-general-settings').on('wpo-saving-form-data', function() {
1763 var valid = true;
1764 var $form = $(this);
1765
1766 $('.wpo_logger_addition_option, .wpo_logger_type').each(function() {
1767 if (!validate_field($(this), true)) {
1768 valid = false;
1769 $(this).addClass('wpo_error_field');
1770 } else {
1771 $(this).removeClass('wpo_error_field');
1772 }
1773 });
1774
1775 if (!valid) {
1776 $form.form_errors.add('missing-fields', '');
1777 $('#wp-optimize-settings-save-results')
1778 .show()
1779 .addClass('wpo_alert_notice')
1780 .text(wpoptimize.fill_all_settings_fields)
1781 .delay(5000)
1782 .fadeOut(3000, function() {
1783 $(this).removeClass('wpo_alert_notice');
1784 });
1785 } else {
1786 $form.form_errors.remove('missing-fields');
1787 $('#wp-optimize-logger-settings .save_settings_reminder').slideUp();
1788 }
1789
1790 });
1791
1792 /**
1793 * Validate import field with data-validate attribute.
1794 *
1795 * @param {object} field jquery element
1796 * @param {boolean} required
1797 *
1798 * @return {boolean}
1799 */
1800 function validate_field(field, required) {
1801 var value = field.val(),
1802 validate = field.data('validate');
1803
1804 if (!validate && required) {
1805 return ('' != value.trim());
1806 }
1807
1808 if (validate && !required && '' == value.trim()) {
1809 return true;
1810 }
1811
1812 var valid = true;
1813
1814 switch (validate) {
1815 case 'email':
1816 var regex = /\S+@\S+\.\S+/,
1817 emails = value.split(","),
1818 email = '';
1819
1820 for (var i = 0; i < emails.length; i++) {
1821 email = emails[i].trim();
1822
1823 if ('' == email || !regex.test(email)) {
1824 valid = false;
1825 }
1826 }
1827 break;
1828
1829 case 'url':
1830 // https://gist.github.com/dperini/729294
1831 // @codingStandardsIgnoreLine
1832 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;
1833
1834 valid = regex.test(value);
1835 break;
1836 }
1837
1838 return valid;
1839 }
1840
1841 /**
1842 * Send check_overdue_crons command and output warning if need.
1843 */
1844 setTimeout(function() {
1845 send_command('check_overdue_crons', null, function (resp) {
1846 if (resp && resp.hasOwnProperty('m')) {
1847 $('#wpo_settings_warnings').append(resp.m);
1848 }
1849 });
1850 }, 11000);
1851
1852 /**
1853 * Hide introduction notice
1854 */
1855 $('.wpo-introduction-notice .notice-dismiss, .wpo-introduction-notice .close').on('click', function(e) {
1856 $('.wpo-introduction-notice').remove();
1857 send_command('dismiss_install_or_update_notice', null, function (resp) {
1858 if (resp && resp.hasOwnProperty('error')) {
1859 // there was an error.
1860 console.log('There was an error dismissing the install or update notice (dismiss_install_or_update_notice)', resp);
1861 }
1862 });
1863 });
1864
1865 $('#wpo-settings-export').on('click', export_settings);
1866
1867 $('#wpo-settings-import').on('click', function(e) {
1868 e.preventDefault();
1869
1870 block_ui();
1871
1872 var wpo_import_file_input = document.getElementById('import_settings');
1873 if (0 === wpo_import_file_input.files.length) {
1874 alert(wpoptimize.import_select_file);
1875 $.unblockUI();
1876 return;
1877 }
1878 read_settings_json_file(wpo_import_file_input.files[0]);
1879 });
1880
1881 /**
1882 * Blocks UI
1883 */
1884 function block_ui() {
1885 $.blockUI({
1886 css: {
1887 width: '300px',
1888 border: 'none',
1889 'border-radius': '10px',
1890 left: 'calc(50% - 150px)',
1891 padding: '20px'
1892 },
1893 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>'
1894 });
1895 }
1896
1897 /**
1898 * Export plugin settings as a JSON file
1899 *
1900 * @param {object} e - Event object
1901 *
1902 * @return {void}
1903 */
1904 function export_settings(e) {
1905 e.preventDefault();
1906
1907 var date_now = new Date();
1908
1909 form_data = JSON.stringify({
1910 epoch_date: date_now.getTime(),
1911 local_date: date_now.toLocaleString(),
1912 network_site_url: wpoptimize.network_site_url,
1913 data: {
1914 cache_settings: wp_optimize.cache_settings(),
1915 minify_settings: wp_optimize.minify_settings(),
1916 smush_settings: wp_optimize.smush_settings(),
1917 database_settings: gather_settings('string')
1918 }
1919 });
1920
1921 // Attach this data to an anchor on page
1922 var link = document.body.appendChild(document.createElement('a'));
1923 link.setAttribute('download', wpoptimize.export_settings_file_name);
1924 link.setAttribute('style', "display:none;");
1925 link.setAttribute('href', 'data:text/json' + ';charset=UTF-8,' + encodeURIComponent(form_data));
1926 link.click();
1927 }
1928
1929 /**
1930 * Read json settings file and import it
1931 *
1932 * @param {Blob} file - Settings file
1933 *
1934 * @return {void}
1935 */
1936 function read_settings_json_file(file) {
1937 var file_reader = new FileReader();
1938 file_reader.onload = function() {
1939 import_settings(this.result);
1940 };
1941 file_reader.readAsText(file);
1942 }
1943
1944 /**
1945 * Import json data and save it as plugin settings in database
1946 *
1947 * @param {json} json_data
1948 *
1949 * @return {void}
1950 */
1951 function import_settings(json_data) {
1952 var parsed;
1953 try {
1954 parsed = wpo_parse_json(json_data);
1955 } catch (e) {
1956 $.unblockUI();
1957 jQuery('#import_settings').val('');
1958 console.log(json_data);
1959 console.log(e);
1960 alert(wpoptimize.import_invalid_json_file);
1961 return;
1962 }
1963 if (window.confirm(wpoptimize.importing_data_from + ' ' + parsed['network_site_url'] + "\n" + wpoptimize.exported_on + ' ' + parsed['local_date'] + "\n" + wpoptimize.continue_import)) {
1964 // GET the settings back to the AJAX handler
1965 var stringified = JSON.stringify(parsed['data']);
1966 send_command('import_settings', {
1967 settings: stringified
1968 }, function(response) {
1969 $.unblockUI();
1970 if (response && response.errors) {
1971 alert(response.errors.join('<br />'));
1972 } else if (response && response.success) {
1973 alert(response.message);
1974 setTimeout(function() {
1975 window.location.reload();
1976 }, 200);
1977 }
1978 });
1979 } else {
1980 $.unblockUI();
1981 }
1982 }
1983
1984 return {
1985 send_command: send_command,
1986 optimization_get_info: optimization_get_info,
1987 take_a_backup_with_updraftplus: take_a_backup_with_updraftplus,
1988 save_auto_backup_options: save_auto_backup_options
1989 }
1990 }; // END function WP_Optimize()
1991
1992 jQuery(function ($) {
1993 /**
1994 * Show additional options section if optimization enabled
1995 *
1996 * @param {string} checkbox Logger settings jQuery checkbox object.
1997 *
1998 * @return {void}
1999 */
2000 function show_hide_additional_logger_options($checkbox) {
2001 var additional_section_id = ['#', $checkbox.data('additional')].join('');
2002
2003 if ($checkbox.is(':checked')) {
2004 $(additional_section_id).show();
2005 } else {
2006 $(additional_section_id).hide();
2007 }
2008 }
2009
2010 // Add events handler for each logger.
2011 $('.wp-optimize-logging-settings').each(function () {
2012 var $checkbox = $(this);
2013 show_hide_additional_logger_options($checkbox);
2014 $checkbox.on('change', function () {
2015 show_hide_additional_logger_options($checkbox);
2016 });
2017 });
2018
2019 var add_logging_btn = $('#settings_form');
2020
2021 /**
2022 * Handle add logging destination click.
2023 */
2024 add_logging_btn.on('click', '#wpo_add_logger_link', function(e) {
2025 e.preventDefault();
2026 $('#wp-optimize-logger-settings .save_settings_reminder').after(get_add_logging_form_html());
2027
2028 filter_select_destinations($('.wpo_logger_type').first());
2029 });
2030
2031 /**
2032 * Handle logging destination select change.
2033 */
2034 $('#wp-optimize-general-settings').on('change', '.wpo_logger_type', function() {
2035 var select = $(this),
2036 logger_id = select.val(),
2037 options_container = select.parent().find('.wpo_additional_logger_options');
2038
2039 options_container.html(get_logging_additional_options_html(logger_id));
2040
2041 if (select.val()) {
2042 show_logging_save_settings_reminder();
2043 }
2044 });
2045
2046 /**
2047 * Show save settings reminder for logging settings.
2048 *
2049 * @return {void}
2050 */
2051 function show_logging_save_settings_reminder() {
2052 var reminder = $('#wp-optimize-logger-settings .save_settings_reminder');
2053
2054 if (!reminder.is(':visible')) {
2055 reminder.slideDown('normal');
2056 }
2057 }
2058
2059 /**
2060 * Handle edit logger click.
2061 */
2062 $('#settings_form').on('click', '.wpo_logging_actions_row .wpo_edit_logger', function() {
2063
2064 var link = $(this),
2065 container = link.closest('.wpo_logging_row');
2066
2067 $('.wpo_additional_logger_options', container).removeClass('wpo_hidden');
2068 $('.wpo_logging_options_row', container).hide();
2069 $('.wpo_logging_status_row', container).hide();
2070 /*link.hide();
2071 link.next('.wpo_delete_logger').hide();*/
2072 link.parent('.wpo_logging_actions_row').hide();
2073 $(container).children('.wpo_logging_edit_row').show();
2074
2075 return false;
2076 });
2077
2078 /**
2079 * Handle cancel logger click.
2080 */
2081 $('#settings_form').on('click', '.wpo_logging_edit_row .wpo_cancel_logging', function() {
2082
2083 var cancel_btn = $(this),
2084 container = cancel_btn.closest('.wpo_logging_row');
2085
2086 $(container).children('.wpo_logging_edit_row').hide();
2087 $(container).children('.wpo_logging_options_row').show();
2088 $(container).children('.wpo_logging_status_row').show();
2089 $(container).children('.wpo_logging_actions_row').show();
2090 $(container).children('.wpo_additional_logger_options').addClass('wpo_hidden');
2091
2092 return false;
2093 });
2094
2095 $('#wp-optimize-logger-settings').on('change', '.wpo_logger_addition_option', function() {
2096 show_logging_save_settings_reminder();
2097 });
2098
2099 /**
2100 * Handle change of active/inactive status and update hidden field value.
2101 */
2102 $('#settings_form').on('change', '.wpo_logger_active_checkbox', function() {
2103 var checkbox = $(this),
2104 hidden_input = checkbox.closest('label').find('input[type="hidden"]');
2105
2106 hidden_input.val(checkbox.is(':checked') ? '1' : '0');
2107 });
2108
2109 /**
2110 * Handle delete logger destination click.
2111 */
2112 $('#wp-optimize-general-settings').on('click', '.wpo_delete_logger', function() {
2113
2114 if (!confirm(wpoptimize.are_you_sure_you_want_to_remove_logging_destination)) {
2115 return false;
2116 }
2117
2118 var btn = $(this);
2119 btn.closest('.wpo_logging_row, .wpo_add_logger_form').remove();
2120 filter_all_select_destinations();
2121
2122 if (0 == $('#wp-optimize-logging-options .wpo_logging_row').length) {
2123 $('#wp-optimize-logging-options').hide();
2124 }
2125
2126 setTimeout(function(){
2127 $('#wp-optimize-save-main-settings').trigger('click');
2128 }, 500);
2129
2130 return false;
2131 });
2132
2133 /**
2134 * Filter all selects with logger destinations, called after some destination deleted.
2135 *
2136 * @return {void}
2137 */
2138 function filter_all_select_destinations() {
2139 $('.wpo_logger_type').each(function() {
2140 filter_select_destinations($(this));
2141 });
2142 }
2143
2144 /**
2145 * Filter certain select options depending on currently selected values.
2146 *
2147 * @param {object} select
2148 *
2149 * @return {void}
2150 */
2151 function filter_select_destinations(select) {
2152 var i,
2153 destination,
2154 current_destinations = get_current_destinations();
2155
2156 for (i in current_destinations) {
2157 destination = current_destinations[i];
2158 if (wpoptimize.loggers_classes_info[destination].allow_multiple) {
2159 $('option[value="'+destination+'"]', select).show();
2160 } else {
2161 $('option[value="'+destination+'"]', select).hide();
2162 }
2163 }
2164 }
2165
2166 /**
2167 * Returns currently selected loggers destinations.
2168 *
2169 * @return {Array}
2170 */
2171 function get_current_destinations() {
2172 var destinations = [];
2173
2174 $('.wpo_logging_row, .wpo_logger_type').each(function() {
2175 var destination = $(this).is('select') ? $(this).val() : $(this).data('id');
2176
2177 if (destination) destinations.push(destination);
2178 });
2179
2180 return destinations;
2181 }
2182
2183 /**
2184 * Return add logging form.
2185 *
2186 * @return {string}
2187 */
2188 function get_add_logging_form_html() {
2189 var i,
2190 select_options = [
2191 '<option value="">' + wpoptimize.select_destination + '</option>'
2192 ];
2193
2194 for (i in wpoptimize.loggers_classes_info) {
2195 if (!wpoptimize.loggers_classes_info.hasOwnProperty(i)) continue;
2196
2197 if (!wpoptimize.loggers_classes_info[i].available) continue;
2198
2199 select_options.push(['<option value="',i,'">',wpoptimize.loggers_classes_info[i].description,'</option>'].join(''));
2200 }
2201
2202 return [
2203 '<div class="wpo_add_logger_form">',
2204 '<select class="wpo_logger_type" name="wpo-logger-type[]">',
2205 select_options.join(''),
2206 '</select>',
2207 '<div class="wpo_logging_edit_row" style="display:block;"><span class="wpo_delete_logger button button-secondary" title="'+wpoptimize.cancel+'">'+wpoptimize.cancel+'</span>',
2208 '<span class="wpo_save_logging button button-primary" title="'+wpoptimize.add+'">'+wpoptimize.add+'</span></div>',
2209 '<div class="wpo_additional_logger_options"></div>',
2210 '</div>'
2211 ].join('');
2212 }
2213
2214 /**
2215 * Returns logging options html.
2216 *
2217 * @param {string} logger_id
2218 *
2219 * @return {string}
2220 */
2221 function get_logging_additional_options_html(logger_id) {
2222 if (!wpoptimize.loggers_classes_info[logger_id].options) return '';
2223
2224 var i,
2225 options = wpoptimize.loggers_classes_info[logger_id].options,
2226 options_list = [],
2227 placeholder = '',
2228 validate = '';
2229
2230 for (i in options) {
2231 if (!options.hasOwnProperty(i)) continue;
2232
2233 if (Array.isArray(options[i])) {
2234 placeholder = options[i][0].trim();
2235 validate = options[i][1].trim();
2236 } else {
2237 placeholder = options[i].trim();
2238 validate = '';
2239 }
2240
2241 options_list.push([
2242 '<input class="wpo_logger_addition_option" type="text" name="wpo-logger-options[',i,'][]" value="" ',
2243 'placeholder="',placeholder,'" ',('' !== validate ? 'data-validate="'+validate+'"' : ''), '/>'
2244 ].join(''));
2245 }
2246
2247 // Add hidden field for active/inactive value.
2248 options_list.push('<input type="hidden" name="wpo-logger-options[active][]" value="1" />');
2249
2250 return options_list.join('');
2251 }
2252
2253 /**
2254 * Layout - Adds `is-scrolled` class to the body element when scrolled.
2255 */
2256 var is_scrolled = false;
2257 $(window).on('scroll', function(e) {
2258 window.requestAnimationFrame(function() {
2259 var threshold = $('.wpo-main-header').length ? $('.wpo-main-header')[0].offsetTop : 0;
2260 if ((window.pageYOffset > threshold - 20) != is_scrolled) {
2261 is_scrolled = !is_scrolled;
2262 $('body').toggleClass('is-scrolled', is_scrolled);
2263 }
2264 });
2265 });
2266
2267 // Opens the video preview / info popup
2268 $('.wpo-info__trigger').on('click', function(e) {
2269 e.preventDefault();
2270 var $container = $(this).closest('.wpo-info');
2271 $container.toggleClass('opened');
2272 });
2273
2274 // Embed videos when clicking the vimeo links
2275 $('.wpo-video-preview a').on('click', function(e) {
2276 var video_url = $(this).data('embed');
2277 if (video_url) {
2278 e.preventDefault();
2279 var $iframe = $('<iframe width="356" height="200" allowfullscreen webkitallowfullscreen mozallowfullscreen>').attr('src', video_url);
2280 $iframe.insertAfter($(this));
2281 $(this).remove();
2282 $iframe.focus();
2283 }
2284 });
2285 });
2286