PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 3.4.0
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v3.4.0
4.7.0 4.6.1 4.6.0 4.5.5 4.5.4 4.5.3 4.5.2 3.2.20 3.2.21 3.2.22 3.2.3 3.2.5 3.2.6 3.2.7 3.2.9 3.3.0 3.3.1 3.3.2 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.7.0 3.7.1 All 111 releases
wp-optimize / js / minify.js

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

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