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

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