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

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