PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 3.6.0
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v3.6.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 3.8.0 All 110 releases
wp-optimize / js / minify.js

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

685 lines 20.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function ($) {
2 var wp_optimize = window.wp_optimize || {};
3 var block_ui = wp_optimize.block_ui;
4 var send_command = wp_optimize.send_command;
5 var refresh_frequency = wpoptimize.refresh_frequency || 30000;
6 var heartbeat = WP_Optimize_Heartbeat();
7 var heartbeat_agents = [];
8
9 if (!send_command) {
10 console.error('WP-Optimize Minify: wp_optimize.send_command is required.');
11 return;
12 }
13
14 var minify = {};
15
16 /**
17 * Initializing the minify feature and events
18 */
19 minify.init = function () {
20
21 var minify = this;
22 this.enabled = false;
23
24 $(document).on('wp-optimize/minify/toggle-status', function(e, params) {
25 if (params.hasOwnProperty('enabled')) {
26 $('[data-whichpage="wpo_minify"]').toggleClass('is-enabled', params.enabled)
27 minify.enabled = params.enabled;
28 if (minify.enabled) minify.getFiles();
29 }
30 });
31
32 /**
33 * The standard handler for clearing the cache. Safe to use
34 */
35 $('.purge_minify_cache').on('click', function(e) {
36 e.preventDefault();
37 block_ui(wpoptimize.clearing_cache);
38 send_command('purge_minify_cache', null, function(response) {
39 if (response.hasOwnProperty('files')) {
40 minify.updateFilesLists(response.files);
41 minify.updateStats(response.files);
42 }
43 }).always(function() {
44 $.unblockUI();
45 });
46 });
47
48 /**
49 * Removes the entire cache dir.
50 * Use with caution, as cached html may still reference those files.
51 */
52 $('.purge_all_minify_cache').on('click', function() {
53 block_ui(wpoptimize.clearing_cache);
54 send_command('purge_all_minify_cache', null, function(response) {
55 if (response.hasOwnProperty('files')) {
56 minify.updateFilesLists(response.files);
57 minify.updateStats(response.files);
58 }
59 }).always(function() {
60 $.unblockUI();
61 });
62 });
63
64 /**
65 * Forces minify to create a new cache, safe to use
66 */
67 $('.minify_increment_cache').on('click', function() {
68 block_ui(wpoptimize.creating_cache);
69 send_command('minify_increment_cache', null, function(response) {
70 if (response.hasOwnProperty('files')) {
71 minify.updateFilesLists(response.files);
72 minify.updateStats(response.files);
73 }
74 }).always(function() {
75 $.unblockUI();
76 });
77 });
78
79
80 // ======= SLIDERS ========
81 // Generic slider save
82 $('#wp-optimize-nav-tab-wpo_minify-status-contents form :input, #wp-optimize-nav-tab-wpo_minify-js-contents form :input, #wp-optimize-nav-tab-wpo_minify-css-contents form :input, #wp-optimize-nav-tab-wpo_minify-font-contents form :input, #wp-optimize-nav-tab-wpo_minify-analytics-contents form :input, #wp-optimize-nav-tab-wpo_minify-settings-contents form :input, #wp-optimize-nav-tab-wpo_minify-advanced-contents form :input').on('change', function() {
83 $(this).closest('form').data('need_saving', true);
84 });
85
86 $('input[type=checkbox].wpo-save-setting').on('change', function(e) {
87 var input = $(this),
88 val = input.prop('checked'),
89 name = input.prop('name'),
90 data = {};
91 data[name] = val;
92 block_ui(wpoptimize.saving);
93 send_command('save_minify_settings', data, function(response) {
94 if (response.success) {
95 input.trigger('wp-optimize/minify/saved_setting');
96 if (response.hasOwnProperty('files')) {
97 minify.updateFilesLists(response.files);
98 minify.updateStats(response.files);
99 }
100 } else {
101 console.log('Settings not saved', data)
102 }
103 }).always(function() {
104 $.unblockUI();
105 });
106 });
107
108 // Slider enable minify
109 $('#wpo_min_enable_minify').on('wp-optimize/minify/saved_setting', function() {
110 this.enabled = $(this).prop('checked');
111 $(document).trigger('wp-optimize/minify/toggle-status', {enabled: this.enabled});
112 });
113
114 // Toggle wpo-feature-is-disabled class
115 $('#wpo_min_enable_minify').on('wp-optimize/minify/saved_setting', function() {
116
117 $(this).closest('.wpo_section').toggleClass('wpo-feature-is-disabled', !$(this).is(':checked'));
118 });
119
120 // Toggle wpo-feature-is-disabled class
121 $('#wpo_min_enable_minify_css, #wpo_min_enable_minify_js')
122 // Set value on status change
123 .on('wp-optimize/minify/saved_setting', function() {
124 $('#wp-optimize-nav-tab-wrapper__wpo_minify a[data-tab="' + $(this).data('tabname') + '"] span.disabled').toggleClass('hidden', $(this).is(':checked'));
125 $('#wpo_section_' + $(this).data('tabname')).toggleClass('wpo-disabled-section', $(this).is(':not(:checked)'));
126 })
127 // Set value on page load
128 .each(function() {
129 $('#wp-optimize-nav-tab-wrapper__wpo_minify a[data-tab="' + $(this).data('tabname') + '"] span.disabled').toggleClass('hidden', $(this).is(':checked'));
130 $('#wpo_section_' + $(this).data('tabname')).toggleClass('wpo-disabled-section', $(this).is(':not(:checked)'));
131 });
132
133 // slider enable Debug mode
134 $('#wpo_min_enable_minify_debug').on('wp-optimize/minify/saved_setting', function() {
135 // Refresh the page as it's needed to show the extra options
136 block_ui(wpoptimize.page_refresh);
137 location.href = $('#wp-optimize-nav-tab-wpo_minify-advanced').prop('href');
138 });
139
140 // Edit default exclusions
141 $('#wpo_min_edit_default_exclutions').on('wp-optimize/minify/saved_setting', function() {
142 // Show exclusions section
143 $('.wpo-minify-default-exclusions').toggleClass('hidden', !$(this).prop('checked'));
144 });
145
146 var disable_google_fonts_processing = $('#disable_google_fonts_processing');
147
148 function handle_disable_google_fonts_processing() {
149 $('#wp-optimize-nav-tab-wpo_minify-font-contents .google_fonts_option').prop('disabled', disable_google_fonts_processing.is(':checked'));
150 }
151
152 disable_google_fonts_processing.on('change', handle_disable_google_fonts_processing);
153
154 handle_disable_google_fonts_processing();
155
156 // Save settings
157 $('.wp-optimize-save-minify-settings').on('click', function(e) {
158 e.preventDefault();
159 var btn = $(this),
160 spinner = btn.next(),
161 success_icon = spinner.next(),
162 $need_refresh_btn = null;
163
164 spinner.show();
165 block_ui(wpoptimize.saving);
166
167 var data = {};
168
169 var tabs = $('[data-whichpage="wpo_minify"] .wp-optimize-nav-tab-contents form');
170 tabs.each(function() {
171 var tab = $(this);
172 if (true === tab.data('need_saving')) {
173 data = Object.assign(data, gather_data(tab));
174 tab.data('need_saving', false);
175 }
176 });
177
178 send_command('save_minify_settings', data, function(response) {
179 if (response.hasOwnProperty('error')) {
180 // show error
181 console.log(response.error);
182 wp_optimize.notices.show_notice(response.success, response.error);
183 } else {
184 $('.wpo-error__enabling-cache').addClass('wpo_hidden').find('p').text('');
185 }
186
187 if (response.hasOwnProperty('files')) {
188 minify.updateFilesLists(response.files);
189 minify.updateStats(response.files);
190 }
191
192 spinner.hide();
193 success_icon.show();
194 setTimeout(function() {
195 success_icon.fadeOut('slow', function() {
196 success_icon.hide();
197 });
198 }, 5000);
199 }).always(function() {
200 $.unblockUI();
201 });
202 })
203
204 // Dismiss information notice
205 $('.wp-optimize-minify-status-information-notice').on('click', '.notice-dismiss', function(e) {
206 e.preventDefault();
207 send_command('hide_minify_notice');
208 });
209
210 // Show logs
211 $('#wpo_min_jsprocessed, #wpo_min_cssprocessed').on('click', '.log', function(e) {
212 e.preventDefault();
213 $(this).nextAll('.wpo_min_log').slideToggle('fast');
214 var link_text = $(this).text().trim();
215 if (wpoptimize.show_information === link_text) {
216 $(this).text(wpoptimize.hide_information);
217 } else {
218 $(this).text(wpoptimize.show_information);
219 }
220 });
221
222 // Delete log file
223 $('#wpo_min_jsprocessed, #wpo_min_cssprocessed').on('click', '.delete-file', function(e) {
224 e.preventDefault();
225
226 var filename = $(this).data('filename');
227
228 if ('' === filename || undefined === filename) {
229 alert(wpoptimize.cache_file_not_found);
230 return false;
231 }
232
233 block_ui(wpoptimize.deleting);
234 send_command('delete_minify_cache_file', filename, function(response) {
235 if('' !== response.files) {
236 minify.updateFilesLists(response.files);
237 minify.updateStats(response.files);
238 }
239 if('' !== response.result) {
240 alert(response.result);
241 }
242 if('' !== response.error) {
243 alert(response.error);
244 }
245 }).always(function() {
246 $.unblockUI();
247 });
248 });
249
250 // Handle js excludes
251 $('#wpo_min_jsprocessed').on('click', '.exclude', function(e) {
252 e.preventDefault();
253 var el = $(this);
254 var excluded_file = get_excluded_file(el);
255 add_excluded_js_file(excluded_file);
256 tab_need_saving('js');
257 highlight_excluded_item(el);
258 });
259
260 // Handle css excludes
261 $('#wpo_min_cssprocessed').on('click', '.exclude', function(e) {
262 e.preventDefault();
263 var el = $(this);
264 var excluded_file = get_excluded_file(el);
265 add_excluded_css_file(excluded_file);
266 tab_need_saving('css');
267 highlight_excluded_item(el);
268 });
269
270 // Trigger combined meta.json file download
271 $('.wpo-minify-download-metas-button').on('click', function(e) {
272 e.preventDefault();
273 send_command('get_minify_meta_files', null, function(response) {
274 if (response.hasOwnProperty('error')) {
275 // show error
276 alert(response.error);
277 return;
278 }
279
280 var link = document.body.appendChild(document.createElement('a'));
281 link.setAttribute('download', 'combined_metas.json');
282 link.setAttribute('style', "display:none;");
283 link.setAttribute('href', 'data:text/json' + ';charset=UTF-8,' + encodeURIComponent(JSON.stringify(response.combined_metas)));
284 link.click();
285 })
286 });
287
288 /**
289 * Get excluded file url
290 *
291 * @param {HTMLElement} el
292 *
293 * @return {string}
294 */
295 function get_excluded_file(el) {
296 return el.data('url');
297 }
298
299 /**
300 * Exclude js file
301 *
302 * @param {string} excluded_file File url
303 */
304 function add_excluded_js_file(excluded_file) {
305 var $js_textarea = $('#exclude_js');
306 var list_of_excluded_files = $js_textarea.val();
307 list_of_excluded_files += excluded_file + '\n';
308 $js_textarea.val(list_of_excluded_files);
309 }
310
311 /**
312 * Exclude css file
313 *
314 * @param {string} excluded_file File url
315 */
316 function add_excluded_css_file(excluded_file) {
317 var $css_textarea = $('#exclude_css');
318 var list_of_excluded_files = $css_textarea.val();
319 list_of_excluded_files += excluded_file + '\n';
320 $css_textarea.val(list_of_excluded_files);
321 }
322
323 // Handle defer
324 $('#wpo_min_jsprocessed').on('click', '.defer', function(e) {
325 e.preventDefault();
326 add_deferred_file($(this));
327 });
328
329 // Handle async loading
330 $('#wpo_min_cssprocessed').on('click', '.async', function(e) {
331 e.preventDefault();
332 add_async_file($(this));
333 });
334
335 /**
336 * Add deferred file
337 *
338 * @param {HTMLElement} el target element
339 */
340 function add_deferred_file(el) {
341 var deferred_file = el.data('url');
342 var $async_js_textarea = $('#async_js');
343 var list_of_deferred_files = $async_js_textarea.val();
344 list_of_deferred_files += deferred_file + '\n';
345 $async_js_textarea.val(list_of_deferred_files);
346 tab_need_saving('js');
347 highlight_excluded_item(el);
348 }
349
350 /**
351 * Add asynchronously loading file
352 *
353 * @param {HTMLElement} el target element
354 */
355 function add_async_file(el) {
356 var async_file = el.data('url');
357 var $async_css_textarea = $('#async_css');
358 var list_of_async_files = $async_css_textarea.val();
359 list_of_async_files += async_file + '\n';
360 $async_css_textarea.val(list_of_async_files);
361 tab_need_saving('css');
362 highlight_excluded_item(el);
363 }
364
365 /**
366 *
367 * @param {string} tab_name Name of the tab that need saving
368 */
369 function tab_need_saving(tab_name) {
370 $('#wp-optimize-nav-tab-wpo_minify-' + tab_name + '-contents form').data('need_saving', true);
371 }
372
373 /**
374 * Update UI after excluding the file
375 *
376 * @param {HTMLElement} el Target element
377 */
378 function highlight_excluded_item(el) {
379 el.closest('.wpo_min_log').prev().removeClass('hidden').addClass('updated').slideDown();
380 el.text(wpoptimize.added_to_list);
381 el.removeClass('exclude');
382 el.parent().addClass('disable-list-item');
383 el.replaceWith($('<span>' + el.text() + '</span>'));
384 }
385
386 $('#wp-optimize-minify-advanced').on('click', '.save-exclusions', function(e) {
387 e.preventDefault();
388 $('.wp-optimize-save-minify-settings').first().trigger('click');
389 });
390
391 // Set the initial `enabled` value
392 this.enabled = $('#wpo_min_enable_minify').prop('checked');
393 $(document).trigger('wp-optimize/minify/toggle-status', {enabled: this.enabled});
394
395 // When loading the page and minify is disabled, make sure that the status tab is active.
396 if (!this.enabled && !$('#wp-optimize-nav-tab-wrapper__wpo_minify a[data-tab="status"]').is('.nav-tab-active')) {
397 $('#wp-optimize-nav-tab-wrapper__wpo_minify a[data-tab="status"]').trigger('click');
398 }
399
400 // Enable / disable defer_jquery
401 function check_defer_status( e ) {
402 $('input[name="enable_defer_js"]').each(function(index, element) {
403 $(element).closest('fieldset').removeClass('selected').find('.defer-js-settings').slideUp('fast');
404 });
405 $('input[name="enable_defer_js"]:checked').closest('fieldset').addClass('selected').find('.defer-js-settings').slideDown('fast');
406 }
407
408 $('input[name="enable_defer_js"]').on('change', check_defer_status);
409
410 check_defer_status();
411
412 /**
413 * Minify Preloader functionality
414 */
415 var run_minify_preload_btn = $('#wp_optimize_run_minify_preload'),
416 minify_preload_status_el = $('#wp_optimize_preload_minify_status');
417
418 run_minify_preload_btn.on('click', function() {
419 var btn = $(this),
420 is_running = btn.data('running'),
421 status = minify_preload_status_el.text();
422
423 btn.prop('disabled', true);
424
425 if (is_running) {
426 btn.data('running', false);
427
428 heartbeat.cancel_agents(heartbeat_agents);
429
430 send_command(
431 'cancel_minify_preload',
432 null,
433 function(response) {
434 if (response && response.hasOwnProperty('message')) {
435 minify_preload_status_el.text(response.message);
436 }
437 }
438 ).always(function() {
439 btn.val(wpoptimize.run_now);
440 btn.prop('disabled', false);
441 });
442 } else {
443 minify_preload_status_el.text(wpoptimize.starting_preload);
444 btn.data('running', true);
445 send_command(
446 'run_minify_preload',
447 null,
448 null,
449 true,
450 {
451 timeout: 3000 // set a timeout in case the server doesn't support our close browser connection function.
452 }
453 ).always(function(response) {
454 try {
455 var resp = wpo_parse_json(response);
456 } catch (e) {
457 }
458
459 if (resp && resp.error) {
460
461 var error_text = wpoptimize.error_unexpected_response;
462
463 if (typeof resp.error != 'function') {
464 error_text = resp.error;
465 } else if (resp.status) {
466 error_text = resp.status + ': ' + resp.statusText;
467 }
468
469 alert(error_text);
470
471 minify_preload_status_el.text(status);
472 btn.prop('disabled', false);
473 btn.data('running', false);
474
475 return;
476 }
477
478 minify_preload_status_el.text(wpoptimize.loading_urls);
479 btn.val(wpoptimize.cancel);
480 btn.prop('disabled', false);
481 run_update_minify_preload_status();
482 });
483 }
484 });
485
486 /**
487 * If already running then update status
488 */
489 if (run_minify_preload_btn.data('running')) {
490 run_update_minify_preload_status();
491 }
492
493 /**
494 * Create heartbeat agent action for update preloader status.
495 *
496 * @return void
497 */
498 function run_update_minify_preload_status() {
499 var agent = heartbeat.add_agent({
500 command: 'get_minify_preload_status',
501 callback: update_minify_preload_status,
502 _keep: false
503 });
504
505 if (null !== agent) heartbeat_agents.push(agent);
506 }
507
508 /**
509 * Update minify preload status ajax action.
510 *
511 * @return void
512 */
513 function update_minify_preload_status(response) {
514 if (response.done) {
515 run_minify_preload_btn.val(wpoptimize.run_now);
516 run_minify_preload_btn.data('running', false);
517 } else {
518 run_minify_preload_btn.val(wpoptimize.cancel);
519 run_minify_preload_btn.data('running', true);
520 run_update_minify_preload_status();
521 }
522 minify_preload_status_el.text(response.message);
523 update_minify_size_information(response);
524 }
525
526 /**
527 * Run update information about minify size.
528 *
529 * @return void
530 */
531 function update_minify_size_information(response) {
532 $('#wpo_min_cache_size').text(response.size);
533 $('#wpo_min_cache_total_size').text(response.total_size);
534 }
535
536 // switch for visibility (analytics setting tab).
537 var $analytics = $('#wpo-analytics-hidden-content');
538
539 $('#wpo_enable_analytics').on('change', function () {
540 $analytics.css('display', $(this).prop('checked') ? 'block' : 'none');
541 });
542
543 return this;
544 }
545
546 /**
547 * Get the list of files generated by Minify and update the markup.
548 */
549 minify.getFiles = function() {
550 // Only run if the feature is enabled
551 if (!this.enabled) return;
552
553 var data = {
554 stamp: new Date().getTime()
555 };
556
557 send_command('get_minify_cached_files', data, function(response) {
558 minify.updateFilesLists(response);
559 minify.updateStats(response);
560 });
561
562 if (refresh_frequency) setTimeout(minify.getFiles.bind(this), refresh_frequency);
563 }
564
565 minify.updateFilesLists = function(data) {
566 if (null === data) return;
567 // reset
568 var wpominarr = [];
569
570 // js
571 if (data.js.length > 0) {
572 $(data.js).each(function () {
573 wpominarr.push(this.uid);
574 if ($('#'+this.uid).length == 0) {
575 $('#wpo_min_jsprocessed ul.processed').append('\
576 <li id="'+this.uid+'">\
577 <span class="filename"><a href="'+this.file_url+'" target="_blank">'+this.filename+'</a> ('+this.fsize+')</span>\
578 <a href="#" class="log">' + wpoptimize.show_information + '</a>\
579 <a href="#" class="delete-file" data-filename="' + this.filename + '">' + wpoptimize.delete_file + '</a>\
580 <div class="hidden save_notice">\
581 <p>' + wpoptimize.added_notice + '</p>\
582 <p><button class="button button-primary save-exclusions">' + wpoptimize.save_notice + '</button></p>\
583 </div>\
584 <div class="hidden wpo_min_log">'+this.log+'</div>\
585 </li>\
586 ');
587 }
588 });
589 }
590
591 $('#wpo_min_jsprocessed ul.processed .no-files-yet').toggle(!data.js.length);
592
593 // css
594 if (data.css.length > 0) {
595 $(data.css).each(function () {
596 wpominarr.push(this.uid);
597 if ($('#'+this.uid).length == 0) {
598 $('#wpo_min_cssprocessed ul.processed').append('\
599 <li id="'+this.uid+'">\
600 <span class="filename"><a href="'+this.file_url+'" target="_blank">'+this.filename+'</a> ('+this.fsize+')</span>\
601 <a href="#" class="log">' + wpoptimize.show_information + '</a>\
602 <a href="#" class="delete-file" data-filename="' + this.filename + '">' + wpoptimize.delete_file + '</a>\
603 <div class="hidden save_notice">\
604 <p>' + wpoptimize.added_to_list + '</p>\
605 <p><button class="button button-primary save-exclusions">' + wpoptimize.save_notice + '</button></p>\
606 </div>\
607 <div class="hidden wpo_min_log">'+this.log+'</div>\
608 </li>\
609 ');
610 }
611 });
612 }
613 $('#wpo_min_cssprocessed ul.processed .no-files-yet').toggle(!data.css.length);
614
615 // Remove <li> if it's not in the files array
616 $('#wpo_min_jsprocessed ul.processed > li, #wpo_min_cssprocessed ul.processed > li').each(function () {
617 if (-1 == jQuery.inArray($(this).attr('id'), wpominarr)) {
618 if (!$(this).is('.no-files-yet')) {
619 $(this).remove();
620 }
621 }
622 });
623 };
624
625 minify.updateStats = function(data) {
626 if (data.cachesize.length > 0) {
627 $("#wpo_min_cache_size").html(this.enabled ? data.cachesize : wpoptimize.no_minified_assets);
628 $("#wpo_min_cache_total_size").html(this.enabled ? data.total_cache_size : wpoptimize.no_minified_assets);
629 $("#wpo_min_cache_time").html(this.enabled ? data.cacheTime : '-');
630 $("#wpo_min_cache_path").html(data.cachePath);
631 }
632 };
633
634 /**
635 * Gather data from the given form
636 *
637 * @param {HTMLFormElement} form
638 *
639 * @returns {Array} Array of collected data from the form
640 */
641 function gather_data(form) {
642 var data = $(form).serializeArray().reduce(form_serialize_reduce_cb, {});
643 $(form).find('input[type="checkbox"]').each(function (i) {
644 var name = $(this).prop("name");
645 if (name.includes('[]')) {
646 if (!$(this).is(':checked')) return;
647 var newName = name.replace('[]', '');
648 if (!data[newName]) data[newName] = [];
649 data[newName].push($(this).val());
650 } else {
651 data[name] = $(this).is(':checked') ? 'true' : 'false';
652 }
653 });
654 return data;
655 }
656
657 /**
658 * Reduces the form elements array into an object
659 *
660 * @param {Object} collection An empty object
661 * @param {*} item form input element as array element
662 *
663 * @returns {Object} collection An object of form data
664 */
665 function form_serialize_reduce_cb(collection, item) {
666 // Ignore items containing [], which we expect to be returned as arrays
667 if (item.name.includes('[]')) return collection;
668 collection[item.name] = item.value;
669 return collection;
670 }
671
672 // Gather minify settings from all tabs
673 wp_optimize.minify_settings = function() {
674 var tabs = $('[data-whichpage="wpo_minify"] .wp-optimize-nav-tab-contents form');
675 var data = {}
676 tabs.each(function() {
677 var tab = $(this);
678 data = Object.assign(data, gather_data(tab));
679 });
680 return data;
681 }
682
683 wp_optimize.minify = minify;
684
685 })(jQuery);