Version Description
[2018.12.03] = * added font-display, to ensure text remains visible during webfont load for inlined google fonts and font-awesome * added automatic removal of "source mappings" from JS files during merging or minification * added font awesome async and exclusion from PSI options, as well as merging and inlining when the url matches "font-awesome" (ie: cdnjs) * added automatically inline of small CSS code (up to 20KB) for any FVM CSS files in the footer (requests reduction) * added automatically inline of small CSS code (up to 20KB) for any FVM CSS files in the header, which are not of mediatype "all" * improved the cache purge button (no more redirect from frontend to backend) * updated PHP Minify and Path Converter from master * bug fixes related to "Exclude JS files from PSI" option
Release Info
Developer | Alignak |
Plugin | Fast Velocity Minify |
Version | 2.4.3 |
Comparing to | |
See all releases |
Code changes from version 2.4.2 to 2.4.3
- fvm.css +3 -1
- fvm.js +51 -127
- fvm.php +310 -107
- inc/functions.php +18 -11
- libs/matthiasmullie/minify/src/CSS.php +40 -27
- libs/matthiasmullie/minify/src/JS.php +19 -5
- libs/matthiasmullie/minify/src/Minify.php +1 -1
- libs/matthiasmullie/path-converter/src/Converter.php +6 -5
- readme.txt +11 -1
@@ -14,7 +14,7 @@
|
|
14 |
.fvm-settings span.note-info { font-size: 14px; margin-left: 8px; color: #666; font-style: italic; }
|
15 |
.fvm-settings p.description { font-size: 14px; color: #666; font-style: italic; font-size: 14px; }
|
16 |
#tab-info h4{font-size: 14px; margin-bottom:-10px; }
|
17 |
-
h3.hndle { background: #F7F7F7; color: #000;}
|
18 |
.fvm-hide { max-height: 1px; overflow: none; position: absolute; top: -9999px; left: -9999px; visibility: hidden; }
|
19 |
.fvm-warning { font-weight: 600; color: #AA0000; }
|
20 |
.fvm-bold-green { font-weight: 600; color: #1196A3; }
|
@@ -22,6 +22,8 @@ h3.hndle { background: #F7F7F7; color: #000;}
|
|
22 |
.fvm-label-pad { line-height: 21px; }
|
23 |
.fvm-rowintro { padding-bottom: 10px; }
|
24 |
|
|
|
|
|
25 |
@media screen and (max-width:520px) {
|
26 |
#fastvelocity-min .processed li .filename{width: 100%;float:none;}
|
27 |
#fastvelocity-min .processed li .actions{text-align: left;margin-top: 4px}
|
14 |
.fvm-settings span.note-info { font-size: 14px; margin-left: 8px; color: #666; font-style: italic; }
|
15 |
.fvm-settings p.description { font-size: 14px; color: #666; font-style: italic; font-size: 14px; }
|
16 |
#tab-info h4{font-size: 14px; margin-bottom:-10px; }
|
17 |
+
h3.hndle { background: #F7F7F7; color: #000; cursor: default !important; }
|
18 |
.fvm-hide { max-height: 1px; overflow: none; position: absolute; top: -9999px; left: -9999px; visibility: hidden; }
|
19 |
.fvm-warning { font-weight: 600; color: #AA0000; }
|
20 |
.fvm-bold-green { font-weight: 600; color: #1196A3; }
|
22 |
.fvm-label-pad { line-height: 21px; }
|
23 |
.fvm-rowintro { padding-bottom: 10px; }
|
24 |
|
25 |
+
|
26 |
+
|
27 |
@media screen and (max-width:520px) {
|
28 |
#fastvelocity-min .processed li .filename{width: 100%;float:none;}
|
29 |
#fastvelocity-min .processed li .actions{text-align: left;margin-top: 4px}
|
@@ -1,135 +1,59 @@
|
|
1 |
-
(function(
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
$('#fastvelocity_min_skip_html_minification').bind('click init', function() {
|
16 |
-
if( $(this).is(':checked')) {
|
17 |
-
$("#fastvelocity_min_strip_htmlcomments").prop("disabled", true).prop('checked', false);
|
18 |
-
} else {
|
19 |
-
$("#fastvelocity_min_strip_htmlcomments").prop("disabled", false);
|
20 |
-
}
|
21 |
-
}).trigger('init');
|
22 |
-
|
23 |
-
// disable some checkboxes when some other is on or off
|
24 |
-
$('#fastvelocity_min_disable_css_merge').bind('click init', function() {
|
25 |
-
if( $(this).is(':checked')) {
|
26 |
-
$("#fastvelocity_min_disable_css_minification, #fastvelocity_min_force_inline_css").prop("disabled", true);
|
27 |
-
$("#fastvelocity_min_force_inline_css_footer").prop("disabled", true);
|
28 |
-
$("#fastvelocity_min_skip_cssorder, #fastvelocity_min_remove_print_mediatypes").prop("disabled", true);
|
29 |
-
} else {
|
30 |
-
$("#fastvelocity_min_disable_css_minification, #fastvelocity_min_force_inline_css").prop("disabled", false);
|
31 |
-
$("#fastvelocity_min_force_inline_css_footer").prop("disabled", false);
|
32 |
-
$("#fastvelocity_min_skip_cssorder, #fastvelocity_min_remove_print_mediatypes").prop("disabled", false);
|
33 |
-
}
|
34 |
-
}).trigger('init');
|
35 |
-
|
36 |
-
// disable some checkboxes when some other is on or off
|
37 |
-
$('#fastvelocity_min_disable_js_merge').bind('click init', function() {
|
38 |
-
if( $(this).is(':checked')) {
|
39 |
-
$("#fastvelocity_min_use_yui, #fastvelocity_min_disable_js_minification").prop("disabled", true);
|
40 |
-
$("#fastvelocity_min_enable_defer_js, #fastvelocity_min_defer_for_pagespeed").prop("disabled", true);
|
41 |
-
$("#fastvelocity_min_exclude_defer_jquery, #fastvelocity_min_exclude_defer_login").prop("disabled", true);
|
42 |
-
} else {
|
43 |
-
$("#fastvelocity_min_use_yui, #fastvelocity_min_disable_js_minification").prop("disabled", false);
|
44 |
-
$("#fastvelocity_min_enable_defer_js, #fastvelocity_min_defer_for_pagespeed").prop("disabled", false);
|
45 |
-
$("#fastvelocity_min_exclude_defer_jquery, #fastvelocity_min_exclude_defer_login").prop("disabled", false);
|
46 |
-
}
|
47 |
-
}).trigger('init');
|
48 |
-
|
49 |
-
// disable some checkboxes when some other is on or off
|
50 |
-
$('#fastvelocity_min_fvm_removecss').bind('click init', function() {
|
51 |
-
if( $(this).is(':checked')) {
|
52 |
-
$("#fastvelocity_min_send_css_to_footer, #fastvelocity_min_critical_path_visibility").prop("disabled", true);
|
53 |
-
$("#fastvelocity_min_critical_css_tester").prop("disabled", true);
|
54 |
-
} else {
|
55 |
-
$("#fastvelocity_min_send_css_to_footer, #fastvelocity_min_critical_path_visibility").prop("disabled", false);
|
56 |
-
$("#fastvelocity_min_critical_css_tester").prop("disabled", false);
|
57 |
-
}
|
58 |
-
}).trigger('init');
|
59 |
-
|
60 |
-
// disable collapse
|
61 |
-
$('.postbox h3, .postbox .handlediv').unbind('click.postboxes');
|
62 |
|
63 |
-
|
64 |
-
var $fastvelocity_min_processed = $('#fastvelocity_min_processed'),
|
65 |
-
$fastvelocity_min_jsprocessed = $('#fastvelocity_min_jsprocessed',$fastvelocity_min_processed),
|
66 |
-
$fastvelocity_min_jsprocessed_ul = $('ul',$fastvelocity_min_jsprocessed),
|
67 |
-
$fastvelocity_min_cssprocessed = $('#fastvelocity_min_cssprocessed',$fastvelocity_min_processed),
|
68 |
-
$fastvelocity_min_cssprocessed_ul = $('ul',$fastvelocity_min_cssprocessed),
|
69 |
-
$fastvelocity_min_noprocessed = $('#fastvelocity_min_noprocessed'),
|
70 |
-
timeout = null,
|
71 |
-
stamp = null;
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
$(this).parent().nextAll('pre').slideToggle();
|
76 |
-
});
|
77 |
-
|
78 |
-
function getFiles(extra) {
|
79 |
-
stamp = new Date().getTime();
|
80 |
-
var data = {
|
81 |
-
'action': 'fastvelocity_min_files',
|
82 |
-
'stamp': stamp
|
83 |
-
};
|
84 |
-
if(extra) {
|
85 |
-
for (var attrname in extra) { data[attrname] = extra[attrname]; }
|
86 |
}
|
87 |
-
|
88 |
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
|
|
|
|
|
|
|
|
|
|
93 |
}
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
$li.find('pre').html(this.log);
|
104 |
-
}
|
105 |
-
} else {
|
106 |
-
$fastvelocity_min_jsprocessed_ul.append('<li class="'+this.hash+'"><span class="filename">'+this.filename+' ('+this.fsize+')</span> <span class="actions"><a href="#" class="log button button-primary">View Log</a></span><pre>'+this.log+'</pre></li><div class="clear"></div>');
|
107 |
-
}
|
108 |
-
});
|
109 |
-
|
110 |
-
}
|
111 |
-
if(response.css.length > 0) {
|
112 |
-
|
113 |
-
$(response.css).each(function(){
|
114 |
-
var $li = $fastvelocity_min_cssprocessed_ul.find('li.'+this.hash);
|
115 |
-
if($li.length > 0) {
|
116 |
-
if($li.find('pre').html() != this.log) {
|
117 |
-
$li.find('pre').html(this.log);
|
118 |
-
}
|
119 |
-
} else {
|
120 |
-
$fastvelocity_min_cssprocessed_ul.append('<li class="'+this.hash+'"><span class="filename">'+this.filename+' ('+this.fsize+')</span> <span class="actions"><a href="#" class="log button button-primary">View Log</a></span><pre>'+this.log+'</pre></li><div class="clear"></div>');
|
121 |
-
}
|
122 |
-
});
|
123 |
-
}
|
124 |
-
|
125 |
-
// check for new files
|
126 |
-
timeout = setTimeout(getFiles, 4000);
|
127 |
}
|
128 |
});
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
|
135 |
-
})
|
1 |
+
jQuery( document ).ready(function() {
|
2 |
+
|
3 |
+
// disable collapse
|
4 |
+
jQuery('.postbox h3, .postbox .handlediv').unbind('click.postboxes');
|
5 |
+
|
6 |
+
// show logs
|
7 |
+
jQuery('#fastvelocity_min_processed').on('click','.log',function(e){
|
8 |
+
e.preventDefault();
|
9 |
+
jQuery(this).parent().nextAll('pre').slideToggle();
|
10 |
+
});
|
11 |
+
|
12 |
+
function getFiles() {
|
13 |
+
stamp = new Date().getTime();
|
14 |
+
var data = { 'action': 'fastvelocity_min_files' };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
+
jQuery.post(ajaxurl, data, function(response) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
+
if(response.cachesize.length > 0) {
|
19 |
+
jQuery("#fvm_cache_size").html(response.cachesize);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
}
|
|
|
21 |
|
22 |
+
// reset
|
23 |
+
var fvmarr = [];
|
24 |
+
|
25 |
+
// js
|
26 |
+
if(response.js.length > 0) {
|
27 |
+
jQuery(response.js).each(function(){
|
28 |
+
fvmarr.push(this.uid);
|
29 |
+
if(jQuery('#'+this.uid).length == 0) {
|
30 |
+
jQuery('#fastvelocity_min_jsprocessed ul').append('<li id="'+this.uid+'"><span class="filename">'+this.filename+' ('+this.fsize+')</span> <span class="actions"><a href="#" class="log button button-primary">View Log</a></span><pre>'+this.log+'</pre></li><div class="clear"></div>');
|
31 |
}
|
32 |
+
});
|
33 |
+
}
|
34 |
+
|
35 |
+
// css
|
36 |
+
if(response.css.length > 0) {
|
37 |
+
jQuery(response.css).each(function(){
|
38 |
+
fvmarr.push(this.uid);
|
39 |
+
if(jQuery('#'+this.uid).length == 0) {
|
40 |
+
jQuery('#fastvelocity_min_cssprocessed ul').append('<li id="'+this.uid+'"><span class="filename">'+this.filename+' ('+this.fsize+')</span> <span class="actions"><a href="#" class="log button button-primary">View Log</a></span><pre>'+this.log+'</pre></li><div class="clear"></div>');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
}
|
42 |
});
|
43 |
+
}
|
44 |
+
|
45 |
+
// remove li, if not set (JS)
|
46 |
+
jQuery('#fastvelocity_min_jsprocessed ul li, #fastvelocity_min_cssprocessed ul li').each(function(){
|
47 |
+
if(jQuery.inArray(jQuery(this).attr('id'), fvmarr) == -1) {
|
48 |
+
jQuery('#' + jQuery(this).attr('id')).remove();
|
49 |
+
}
|
50 |
+
});
|
51 |
+
|
52 |
+
// check for new files
|
53 |
+
timeout = setTimeout(getFiles, 4000);
|
54 |
+
});
|
55 |
+
}
|
56 |
+
|
57 |
+
getFiles();
|
58 |
|
59 |
+
});
|
@@ -5,7 +5,7 @@ Plugin URI: http://fastvelocity.com
|
|
5 |
Description: Improve your speed score on GTmetrix, Pingdom Tools and Google PageSpeed Insights by merging and minifying CSS and JavaScript files into groups, compressing HTML and other speed optimizations.
|
6 |
Author: Raul Peixoto
|
7 |
Author URI: http://fastvelocity.com
|
8 |
-
Version: 2.4.
|
9 |
License: GPL2
|
10 |
|
11 |
------------------------------------------------------------------------
|
@@ -137,6 +137,7 @@ $fvm_remove_css = get_option('fastvelocity_min_fvm_removecss');
|
|
137 |
$fvm_cdn_url = get_option('fastvelocity_min_fvm_cdn_url');
|
138 |
$fvm_enabled_css_preload = get_option('fastvelocity_enabled_css_preload');
|
139 |
$fvm_enabled_js_preload = get_option('fastvelocity_enabled_css_preload');
|
|
|
140 |
|
141 |
# default options
|
142 |
$used_css_files = array();
|
@@ -230,6 +231,7 @@ if(is_admin()) {
|
|
230 |
|
231 |
# add the CSS async polyfil + LoadAsync JavaScript functions
|
232 |
add_action('wp_footer', 'fvm_add_loadcss', PHP_INT_MAX);
|
|
|
233 |
|
234 |
# remove query from static assets and process defering (if enabled)
|
235 |
add_filter('style_loader_src', 'fastvelocity_remove_cssjs_ver', 10, 2);
|
@@ -277,7 +279,7 @@ function fastvelocity_admintoolbar() {
|
|
277 |
$wp_admin_bar->add_node(array(
|
278 |
'id' => 'fvm',
|
279 |
'title' => '<span class="ab-icon"></span><span class="ab-label">' . __("FVM Purge",'fvm') . '</span>',
|
280 |
-
'href' =>
|
281 |
));
|
282 |
|
283 |
}
|
@@ -287,10 +289,10 @@ function fastvelocity_admintoolbar() {
|
|
287 |
# function to list all cache files
|
288 |
function fastvelocity_min_files_callback() {
|
289 |
global $cachedir;
|
290 |
-
|
291 |
# default
|
292 |
$size = fastvelocity_get_cachestats();
|
293 |
-
|
294 |
|
295 |
# inspect directory with opendir, since glob might not be available in some systems
|
296 |
clearstatcache();
|
@@ -298,27 +300,24 @@ function fastvelocity_min_files_callback() {
|
|
298 |
while (false !== ($file = readdir($handle))) {
|
299 |
$file = $cachedir.'/'.$file;
|
300 |
$ext = pathinfo($file, PATHINFO_EXTENSION);
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
$fsize = fastvelocity_format_filesize(filesize($file));
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
$hash = $info['1'];
|
313 |
-
array_push($return[$ext], array('hash' => $hash, 'filename' => $filename, 'log' => $log, 'fsize' => $fsize));
|
314 |
-
}
|
315 |
}
|
316 |
closedir($handle);
|
317 |
}
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
}
|
323 |
|
324 |
|
@@ -353,6 +352,7 @@ function fastvelocity_min_register_settings() {
|
|
353 |
register_setting('fvm-group', 'fastvelocity_min_force_inline_css');
|
354 |
register_setting('fvm-group', 'fastvelocity_min_remove_googlefonts');
|
355 |
register_setting('fvm-group', 'fastvelocity_gfonts_method');
|
|
|
356 |
register_setting('fvm-group', 'fastvelocity_min_defer_for_pagespeed');
|
357 |
register_setting('fvm-group', 'fastvelocity_min_defer_for_pagespeed_optimize');
|
358 |
register_setting('fvm-group', 'fastvelocity_min_exclude_defer_login');
|
@@ -398,6 +398,62 @@ return $links;
|
|
398 |
add_filter("plugin_action_links_".plugin_basename(__FILE__), 'fastvelocity_min_settings_link' );
|
399 |
|
400 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
401 |
|
402 |
# manage settings page
|
403 |
function fastvelocity_min_settings() {
|
@@ -413,19 +469,6 @@ $active_tab = isset($_GET['tab']) ? $_GET['tab'] : 'status';
|
|
413 |
<div class="wrap">
|
414 |
<h1>Fast Velocity Minify</h1>
|
415 |
|
416 |
-
<?php
|
417 |
-
|
418 |
-
# purge all caches
|
419 |
-
if(isset($_GET['page']) && $_GET['page'] == 'fastvelocity-min') {
|
420 |
-
if((isset($_POST['purgeall']) && $_POST['purgeall'] == 1) || isset($_GET['fvm_flush']) && $_GET['fvm_flush'] == 1) {
|
421 |
-
fvm_purge_all(); # purge all
|
422 |
-
echo __('<div class="notice notice-success is-dismissible"><p>All caches from <strong>FVM</strong> have been purged!</p></div>');
|
423 |
-
echo fastvelocity_purge_others(); # purge third party caches
|
424 |
-
}
|
425 |
-
}
|
426 |
-
|
427 |
-
?>
|
428 |
-
|
429 |
<h2 class="nav-tab-wrapper wp-clearfix">
|
430 |
<a href="?page=fastvelocity-min&tab=status" class="nav-tab <?php echo $active_tab == 'status' ? 'nav-tab-active' : ''; ?>">Status</a>
|
431 |
<a href="?page=fastvelocity-min&tab=set" class="nav-tab <?php echo $active_tab == 'set' ? 'nav-tab-active' : ''; ?>">Settings</a>
|
@@ -570,7 +613,7 @@ Cleanup Header <span class="note-info">[ Remove resource hints, generator tag, s
|
|
570 |
|
571 |
|
572 |
<tr>
|
573 |
-
<th scope="row">
|
574 |
<td>
|
575 |
<p class="fvm-bold-green fvm-rowintro">The default options are usually good for performance.</p>
|
576 |
<fieldset>
|
@@ -603,15 +646,35 @@ $a = ''; if($sel == 1 || empty($sel)) { $a = ' checked="checked"'; }
|
|
603 |
$b = ''; if($sel == 2) { $b = ' checked="checked"'; }
|
604 |
$c = ''; if($sel == 3) { $c = ' checked="checked"'; }
|
605 |
?>
|
606 |
-
<p class="fvm-bold-green fvm-rowintro">Choose how to include
|
607 |
<fieldset>
|
608 |
-
<label><input type="radio" name="fastvelocity_gfonts_method" value="1" <?php echo $a; ?>> Inline Google Fonts CSS</label> <span class="note-info">[ Will inline
|
609 |
<label><input type="radio" name="fastvelocity_gfonts_method" value="2"<?php echo $b; ?>> Async Google Fonts CSS files</label> <span class="note-info">[ Will use <a target="_blank" href="https://caniuse.com/#feat=link-rel-preload">preload</a> with <a href="https://github.com/filamentgroup/loadCSS">LoadCSS</a> polyfill ]</span><br>
|
610 |
-
<label><input type="radio" name="fastvelocity_gfonts_method" value="3"<?php echo $c; ?>> Async and exclude CSS from PSI</label> <span class="note-info">[ Will use JavaScript to load the fonts conditionally ] </span><br>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
611 |
</fieldset>
|
612 |
</td>
|
613 |
</tr>
|
614 |
|
|
|
615 |
<tr>
|
616 |
<th scope="row">CSS Options</th>
|
617 |
<td>
|
@@ -636,7 +699,7 @@ Remove the "Print" related stylesheets <span class="note-info">[ If selected, CS
|
|
636 |
<br />
|
637 |
<label for="fastvelocity_min_force_inline_css">
|
638 |
<input name="fastvelocity_min_force_inline_css" type="checkbox" id="fastvelocity_min_force_inline_css" value="1" <?php echo checked(1 == get_option('fastvelocity_min_force_inline_css'), true, false); ?>>
|
639 |
-
Inline all CSS files <span class="note-info">[ If selected, CSS will be inlined to avoid the "render blocking" on PSI ]</span></label>
|
640 |
<br />
|
641 |
</fieldset></td>
|
642 |
</tr>
|
@@ -645,7 +708,7 @@ Inline all CSS files <span class="note-info">[ If selected, CSS will be inlined
|
|
645 |
<tr>
|
646 |
<th scope="row">JavaScript Options</th>
|
647 |
<td>
|
648 |
-
<p class="fvm-bold-green fvm-rowintro">Try to disable minification (and purge the cache), if you have trouble with JavaScript in the frontend.</p>
|
649 |
<fieldset>
|
650 |
<label for="fastvelocity_min_disable_js_merge">
|
651 |
<input name="fastvelocity_min_disable_js_merge" type="checkbox" id="fastvelocity_min_disable_js_merge" value="1" <?php echo checked(1 == get_option('fastvelocity_min_disable_js_merge'), true, false); ?> >
|
@@ -1100,7 +1163,7 @@ if( $active_tab == 'help' ) { ?>
|
|
1100 |
# process header javascript ###############
|
1101 |
###########################################
|
1102 |
function fastvelocity_min_merge_header_scripts() {
|
1103 |
-
global $wp_scripts, $wp_domain, $wp_home, $wp_home_path, $cachedir, $cachedirurl, $ignore, $disable_js_merge, $disable_js_minification, $enable_defer_js, $exclude_defer_jquery, $fvm_debug;
|
1104 |
if(!is_object($wp_scripts)) { return false; }
|
1105 |
$scripts = wp_clone($wp_scripts);
|
1106 |
$scripts->all_deps($scripts->queue);
|
@@ -1125,6 +1188,24 @@ $is_footer = 0; if (isset($wp_scripts->registered[$handle]->extra["group"]) || i
|
|
1125 |
# get full url
|
1126 |
$hurl = fastvelocity_min_get_hurl($wp_scripts->registered[$handle]->src, $wp_domain, $wp_home);
|
1127 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1128 |
# IE only files don't increment things
|
1129 |
$ieonly = fastvelocity_ie_blacklist($hurl);
|
1130 |
if($ieonly == true) { continue; }
|
@@ -1240,8 +1321,7 @@ for($i=0,$l=count($header);$i<$l;$i++) {
|
|
1240 |
if(count($data) > 0) { $wp_scripts->registered["fvm-header-$i"]->extra['data'] = implode(PHP_EOL, $data); }
|
1241 |
|
1242 |
# enqueue file, if not empty
|
1243 |
-
$
|
1244 |
-
if(file_exists($file) && (!empty($check) || count($data) > 0)) {
|
1245 |
wp_enqueue_script("fvm-header-$i");
|
1246 |
}
|
1247 |
|
@@ -1263,7 +1343,7 @@ $wp_scripts->done = $done;
|
|
1263 |
# process js in the footer ################
|
1264 |
###########################################
|
1265 |
function fastvelocity_min_merge_footer_scripts() {
|
1266 |
-
global $wp_scripts, $wp_domain, $wp_home, $wp_home_path, $cachedir, $cachedirurl, $ignore, $disable_js_merge, $disable_js_minification, $enable_defer_js, $exclude_defer_jquery, $fvm_debug;
|
1267 |
if(!is_object($wp_scripts)) { return false; }
|
1268 |
$ctime = get_option('fvm-last-cache-update', '0');
|
1269 |
$scripts = wp_clone($wp_scripts);
|
@@ -1283,6 +1363,24 @@ foreach( $scripts->to_do as $handle ) :
|
|
1283 |
# get full url
|
1284 |
$hurl = fastvelocity_min_get_hurl($wp_scripts->registered[$handle]->src, $wp_domain, $wp_home);
|
1285 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1286 |
# IE only files don't increment things
|
1287 |
$ieonly = fastvelocity_ie_blacklist($hurl);
|
1288 |
if($ieonly == true) { continue; }
|
@@ -1381,10 +1479,6 @@ for($i=0,$l=count($footer);$i<$l;$i++) {
|
|
1381 |
# register minified file
|
1382 |
wp_register_script("fvm-footer-$i", $file_url, array(), null, false);
|
1383 |
|
1384 |
-
# associate generated file to current url so it can be send with preload later
|
1385 |
-
|
1386 |
-
|
1387 |
-
|
1388 |
# add all extra data from wp_localize_script
|
1389 |
$data = array();
|
1390 |
foreach($footer[$i]['handles'] as $handle) {
|
@@ -1393,8 +1487,7 @@ for($i=0,$l=count($footer);$i<$l;$i++) {
|
|
1393 |
if(count($data) > 0) { $wp_scripts->registered["fvm-footer-$i"]->extra['data'] = implode(PHP_EOL, $data); }
|
1394 |
|
1395 |
# enqueue file, if not empty
|
1396 |
-
$
|
1397 |
-
if(file_exists($file) && (!empty($check) || count($data) > 0)) {
|
1398 |
wp_enqueue_script("fvm-footer-$i");
|
1399 |
}
|
1400 |
|
@@ -1484,7 +1577,7 @@ return $tag;
|
|
1484 |
# process header css ######################
|
1485 |
###########################################
|
1486 |
function fastvelocity_min_merge_header_css() {
|
1487 |
-
global $wp_styles, $wp_domain, $wp_home, $wp_home_path, $cachedir, $cachedirurl, $ignore, $disable_css_merge, $disable_css_minification, $skip_google_fonts, $skip_cssorder, $remove_print_mediatypes, $force_inline_googlefonts, $css_hide_googlefonts, $min_async_googlefonts, $remove_googlefonts, $fvmloadcss, $fvm_remove_css, $fvmualist, $fvm_min_excludecsslist, $fvm_debug, $fvm_min_excludecsslist;
|
1488 |
if(!is_object($wp_styles)) { return false; }
|
1489 |
$ctime = get_option('fvm-last-cache-update', '0');
|
1490 |
$styles = wp_clone($wp_styles);
|
@@ -1519,8 +1612,9 @@ foreach( $styles->to_do as $handle):
|
|
1519 |
}
|
1520 |
|
1521 |
# mediatype
|
1522 |
-
$
|
1523 |
-
if ($
|
|
|
1524 |
|
1525 |
# full url or empty
|
1526 |
$hurl = fastvelocity_min_get_hurl($wp_styles->registered[$handle]->src, $wp_domain, $wp_home);
|
@@ -1540,6 +1634,23 @@ foreach( $styles->to_do as $handle):
|
|
1540 |
$done = array_merge($done, array($handle)); continue;
|
1541 |
}
|
1542 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1543 |
# array of info to save
|
1544 |
$arr = array('handle'=>$handle, 'url'=>$hurl, 'conditional'=>$conditional, 'mediatype'=>$mediatype);
|
1545 |
|
@@ -1615,6 +1726,12 @@ if(!$skip_google_fonts && count($google_fonts) > 0 || ($force_inline_googlefonts
|
|
1615 |
|
1616 |
# inline css or fail
|
1617 |
if($res['code'] !== false) {
|
|
|
|
|
|
|
|
|
|
|
|
|
1618 |
echo '<style type="text/css" media="all">'.$res['code'].'</style>'.PHP_EOL;
|
1619 |
} else {
|
1620 |
echo "<!-- GOOGLE FONTS REQUEST FAILED for $gfurl -->\n";
|
@@ -1648,8 +1765,10 @@ $mediatype = $process[$handle]['mediatype'];
|
|
1648 |
$ieonly = fastvelocity_ie_blacklist($hurl);
|
1649 |
if($ieonly == true) { continue; }
|
1650 |
|
1651 |
-
# skip ignore list, conditional css, external css
|
1652 |
-
if ((!fastvelocity_min_in_arrayi($hurl, $ignore) && !isset($conditional) && fvm_internal_url($hurl, $wp_home))
|
|
|
|
|
1653 |
|
1654 |
# colect inline css for this handle
|
1655 |
if(isset($wp_styles->registered[$handle]->extra['after']) && is_array($wp_styles->registered[$handle]->extra['after'])) {
|
@@ -1673,7 +1792,6 @@ $mediatype = $process[$handle]['mediatype'];
|
|
1673 |
}
|
1674 |
endforeach;
|
1675 |
|
1676 |
-
|
1677 |
# reorder CSS by mediatypes
|
1678 |
if(!$skip_cssorder) {
|
1679 |
if(count($header) > 0) {
|
@@ -1683,12 +1801,12 @@ if(!$skip_cssorder) {
|
|
1683 |
foreach($header as $array) {
|
1684 |
if(isset($array['media'])) { $allmedia[$array['media']] = ''; }
|
1685 |
}
|
1686 |
-
|
1687 |
# extract handles by mediatype
|
1688 |
$grouphandles = array();
|
1689 |
foreach ($allmedia as $md=>$var) {
|
1690 |
foreach($header as $array) {
|
1691 |
-
if (isset($array['media']) && $array['media']
|
1692 |
foreach($array['handles'] as $h) { $grouphandles[$md][] = $h; }
|
1693 |
}
|
1694 |
}
|
@@ -1792,13 +1910,16 @@ for($i=0,$l=count($header);$i<$l;$i++) {
|
|
1792 |
|
1793 |
# enqueue file, if not empty
|
1794 |
} else {
|
1795 |
-
$
|
1796 |
-
if(file_exists($file) && !empty($check)) {
|
1797 |
|
1798 |
-
#
|
1799 |
-
|
1800 |
-
|
1801 |
-
|
|
|
|
|
|
|
|
|
1802 |
}
|
1803 |
}
|
1804 |
}
|
@@ -1821,7 +1942,7 @@ $wp_styles->done = $done;
|
|
1821 |
# process css in the footer ###############
|
1822 |
###########################################
|
1823 |
function fastvelocity_min_merge_footer_css() {
|
1824 |
-
global $wp_styles, $wp_domain, $wp_home, $wp_home_path, $cachedir, $cachedirurl, $ignore, $disable_css_merge, $disable_css_minification, $skip_google_fonts, $skip_cssorder, $remove_print_mediatypes, $force_inline_googlefonts, $css_hide_googlefonts, $min_async_googlefonts, $remove_googlefonts, $fvmloadcss, $fvm_remove_css, $fvmualist, $fvm_debug;
|
1825 |
|
1826 |
if(!is_object($wp_styles)) { return false; }
|
1827 |
$ctime = get_option('fvm-last-cache-update', '0');
|
@@ -1849,8 +1970,10 @@ $ignore = fastvelocity_default_ignore($ignore);
|
|
1849 |
|
1850 |
# google fonts to the top
|
1851 |
foreach( $styles->to_do as $handle ) :
|
|
|
1852 |
# dequeue and get a list of google fonts, or requeue external
|
1853 |
$hurl = fastvelocity_min_get_hurl($wp_styles->registered[$handle]->src, $wp_domain, $wp_home);
|
|
|
1854 |
if (stripos($hurl, 'fonts.googleapis.com') !== false) {
|
1855 |
wp_dequeue_style($handle);
|
1856 |
if($remove_googlefonts != false) { $done = array_merge($done, array($handle)); continue; } # mark as done if to be removed
|
@@ -1862,6 +1985,7 @@ foreach( $styles->to_do as $handle ) :
|
|
1862 |
} else {
|
1863 |
wp_dequeue_style($handle); wp_enqueue_style($handle); # failsafe
|
1864 |
}
|
|
|
1865 |
endforeach;
|
1866 |
|
1867 |
|
@@ -1939,28 +2063,66 @@ if(!$skip_google_fonts && count($google_fonts) > 0 || ($force_inline_googlefonts
|
|
1939 |
|
1940 |
|
1941 |
# get groups of handles
|
|
|
1942 |
foreach( $styles->to_do as $handle ) :
|
1943 |
|
1944 |
# skip already processed google fonts
|
1945 |
if(isset($google_fonts[$handle])) { continue; }
|
1946 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1947 |
# get full url
|
1948 |
$hurl = fastvelocity_min_get_hurl($wp_styles->registered[$handle]->src, $wp_domain, $wp_home);
|
1949 |
-
|
1950 |
-
#
|
1951 |
-
|
|
|
|
|
|
|
1952 |
|
1953 |
# IE only files don't increment things
|
1954 |
$ieonly = fastvelocity_ie_blacklist($hurl);
|
1955 |
if($ieonly == true) { continue; }
|
1956 |
|
1957 |
-
|
1958 |
-
|
1959 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1960 |
}
|
1961 |
|
1962 |
-
# skip ignore list, conditional css, external css
|
1963 |
-
if ((!fastvelocity_min_in_arrayi($hurl, $ignore) && !isset($conditional) && fvm_internal_url($hurl, $wp_home))
|
|
|
|
|
1964 |
|
1965 |
# colect inline css for this handle
|
1966 |
if(isset($wp_styles->registered[$handle]->extra['after']) && is_array($wp_styles->registered[$handle]->extra['after'])) {
|
@@ -1970,7 +2132,7 @@ foreach( $styles->to_do as $handle ) :
|
|
1970 |
|
1971 |
# process
|
1972 |
if(isset($footer[count($footer)-1]['handle']) || count($footer) == 0 || $footer[count($footer)-1]['media'] != $wp_styles->registered[$handle]->args) {
|
1973 |
-
array_push($footer, array('handles'=>array(),'media'=>$
|
1974 |
}
|
1975 |
|
1976 |
# push it to the array get latest modified time
|
@@ -1999,7 +2161,7 @@ if(!$skip_cssorder) {
|
|
1999 |
$grouphandles = array();
|
2000 |
foreach ($allmedia as $md=>$var) {
|
2001 |
foreach($footer as $array) {
|
2002 |
-
if (isset($array['media']) && $array['media']
|
2003 |
foreach($array['handles'] as $h) { $grouphandles[$md][] = $h; }
|
2004 |
}
|
2005 |
}
|
@@ -2090,7 +2252,7 @@ for($i=0,$l=count($footer);$i<$l;$i++) {
|
|
2090 |
}
|
2091 |
|
2092 |
# register and enqueue minified file, consider excluding of mediatype "print" and inline css
|
2093 |
-
if ($remove_print_mediatypes != true || ($remove_print_mediatypes == true && $
|
2094 |
|
2095 |
# the developers tab, takes precedence
|
2096 |
|
@@ -2103,13 +2265,15 @@ for($i=0,$l=count($footer);$i<$l;$i++) {
|
|
2103 |
|
2104 |
# enqueue file, if not empty
|
2105 |
} else {
|
2106 |
-
$
|
2107 |
-
|
2108 |
-
|
2109 |
-
|
2110 |
-
|
2111 |
-
|
2112 |
-
|
|
|
|
|
2113 |
}
|
2114 |
}
|
2115 |
}
|
@@ -2136,8 +2300,6 @@ function fvm_add_loadcss() {
|
|
2136 |
|
2137 |
echo <<<EOF
|
2138 |
<script>
|
2139 |
-
/*! fvm load async scripts with clallback */
|
2140 |
-
function loadAsync(e,a){var t=document.createElement("script");t.src=e,null!==a&&(t.readyState?t.onreadystatechange=function(){"loaded"!=t.readyState&&"complete"!=t.readyState||(t.onreadystatechange=null,a())}:t.onload=function(){a()}),document.getElementsByTagName("head")[0].appendChild(t)}
|
2141 |
/*! loadCSS. [c]2017 Filament Group, Inc. MIT License */
|
2142 |
!function(n){"use strict";n.loadCSS||(n.loadCSS=function(){});var o=loadCSS.relpreload={};if(o.support=function(){var e;try{e=n.document.createElement("link").relList.supports("preload")}catch(t){e=!1}return function(){return e}}(),o.bindMediaToggle=function(t){var e=t.media||"all";function a(){t.media=e}t.addEventListener?t.addEventListener("load",a):t.attachEvent&&t.attachEvent("onload",a),setTimeout(function(){t.rel="stylesheet",t.media="only x"}),setTimeout(a,3e3)},o.poly=function(){if(!o.support())for(var t=n.document.getElementsByTagName("link"),e=0;e<t.length;e++){var a=t[e];"preload"!==a.rel||"style"!==a.getAttribute("as")||a.getAttribute("data-loadcss")||(a.setAttribute("data-loadcss",!0),o.bindMediaToggle(a))}},!o.support()){o.poly();var t=n.setInterval(o.poly,500);n.addEventListener?n.addEventListener("load",function(){o.poly(),n.clearInterval(t)}):n.attachEvent&&n.attachEvent("onload",function(){o.poly(),n.clearInterval(t)})}"undefined"!=typeof exports?exports.loadCSS=loadCSS:n.loadCSS=loadCSS}("undefined"!=typeof global?global:this);
|
2143 |
</script>
|
@@ -2145,6 +2307,14 @@ EOF;
|
|
2145 |
|
2146 |
}
|
2147 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2148 |
|
2149 |
|
2150 |
|
@@ -2217,10 +2387,10 @@ if($fvm_headers != false) {
|
|
2217 |
# optimize the ignore list for pagespeed insights + Exclude JS files from PSI (Async)
|
2218 |
###########################################
|
2219 |
function fastvelocity_min_defer_js_optimize($tag, $handle, $src) {
|
2220 |
-
global $defer_for_pagespeed, $defer_for_pagespeed_optimize, $fvm_fix_editor, $
|
2221 |
|
2222 |
# return if there are linebreaks (will break document.write)
|
2223 |
-
if (stripos($tag,
|
2224 |
|
2225 |
# fix page editors
|
2226 |
if($fvm_fix_editor == true && is_user_logged_in()) { return $tag; }
|
@@ -2233,21 +2403,6 @@ if (stripos($src, '?ver') !== false) {
|
|
2233 |
$src = stristr($src, '?ver', true);
|
2234 |
}
|
2235 |
|
2236 |
-
# Exclude JS files from PSI (Async) takes priority over defering the ignore list
|
2237 |
-
if($fvm_min_excludejslist != false || is_array($fvm_min_excludejslist)) {
|
2238 |
-
# check for string match
|
2239 |
-
foreach($fvm_min_excludejslist as $l) {
|
2240 |
-
if (stripos($src, $l) !== false) {
|
2241 |
-
|
2242 |
-
# print code if there are no linebreaks, or return
|
2243 |
-
echo '<script type="text/javascript">if(!navigator.userAgent.match(/'.implode('|', $fvmualist).'/i)){';
|
2244 |
-
echo "loadAsync('$src', null);";
|
2245 |
-
echo '}</script>';
|
2246 |
-
return false;
|
2247 |
-
}
|
2248 |
-
}
|
2249 |
-
}
|
2250 |
-
|
2251 |
# exclude ignored scripts
|
2252 |
if(substr($handle, 0, 4) != "fvm-" && $defer_for_pagespeed == true && $defer_for_pagespeed_optimize == true) {
|
2253 |
|
@@ -2278,7 +2433,7 @@ return $tag;
|
|
2278 |
|
2279 |
# inline css in place, instead of inlining the large file
|
2280 |
function fastvelocity_optimizecss($html, $handle, $href, $media){
|
2281 |
-
global $fvm_debug, $wp_domain, $wp_home, $force_inline_css, $fvmualist, $fvm_collect_google_fonts, $force_inline_googlefonts, $min_async_googlefonts, $remove_googlefonts, $skip_google_fonts, $css_hide_googlefonts, $remove_print_mediatypes, $ignore, $blacklist, $ignorelist, $wp_home, $fvmloadcss, $fvm_remove_css, $fvm_cdn_url, $disable_minification, $fvm_min_excludecsslist, $disable_css_minification, $fvm_fix_editor;
|
2282 |
|
2283 |
# current timestamp
|
2284 |
$ctime = get_option('fvm-last-cache-update', '0');
|
@@ -2310,7 +2465,7 @@ function fastvelocity_optimizecss($html, $handle, $href, $media){
|
|
2310 |
}
|
2311 |
|
2312 |
# mediatype fix for some plugins + remove print mediatypes
|
2313 |
-
if ($media == 'screen' || $media == 'screen, print') { $media = 'all'; }
|
2314 |
if($remove_print_mediatypes != false && $media == 'print') {
|
2315 |
return false;
|
2316 |
}
|
@@ -2335,7 +2490,6 @@ function fastvelocity_optimizecss($html, $handle, $href, $media){
|
|
2335 |
return false;
|
2336 |
}
|
2337 |
|
2338 |
-
|
2339 |
# handle google fonts here, when merging is disabled
|
2340 |
if(stripos($href, 'fonts.googleapis.com') !== false && $skip_google_fonts != false) {
|
2341 |
|
@@ -2357,6 +2511,52 @@ function fastvelocity_optimizecss($html, $handle, $href, $media){
|
|
2357 |
}
|
2358 |
}
|
2359 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2360 |
# inline google fonts, do not collect
|
2361 |
if(stripos($href, 'fonts.googleapis.com') !== false && $force_inline_googlefonts != false && $css_hide_googlefonts != true && $min_async_googlefonts != true) {
|
2362 |
|
@@ -2372,6 +2572,10 @@ function fastvelocity_optimizecss($html, $handle, $href, $media){
|
|
2372 |
# decode
|
2373 |
$res = json_decode($json, true);
|
2374 |
|
|
|
|
|
|
|
|
|
2375 |
# inline css or fail
|
2376 |
if($res['status'] != false) {
|
2377 |
echo '<style type="text/css" media="all">'.$res['code'].'</style>'.PHP_EOL;
|
@@ -2388,7 +2592,6 @@ function fastvelocity_optimizecss($html, $handle, $href, $media){
|
|
2388 |
return false;
|
2389 |
}
|
2390 |
|
2391 |
-
|
2392 |
# skip external scripts that are not specifically allowed
|
2393 |
if (fvm_internal_url($href, $wp_home) === false || empty($href)) {
|
2394 |
if($fvm_debug == true) { echo "<!-- FVM DEBUG: Skipped the next external enqueued CSS -->" . PHP_EOL; }
|
5 |
Description: Improve your speed score on GTmetrix, Pingdom Tools and Google PageSpeed Insights by merging and minifying CSS and JavaScript files into groups, compressing HTML and other speed optimizations.
|
6 |
Author: Raul Peixoto
|
7 |
Author URI: http://fastvelocity.com
|
8 |
+
Version: 2.4.3
|
9 |
License: GPL2
|
10 |
|
11 |
------------------------------------------------------------------------
|
137 |
$fvm_cdn_url = get_option('fastvelocity_min_fvm_cdn_url');
|
138 |
$fvm_enabled_css_preload = get_option('fastvelocity_enabled_css_preload');
|
139 |
$fvm_enabled_js_preload = get_option('fastvelocity_enabled_css_preload');
|
140 |
+
$fvm_fawesome_method = get_option("fastvelocity_fontawesome_method");
|
141 |
|
142 |
# default options
|
143 |
$used_css_files = array();
|
231 |
|
232 |
# add the CSS async polyfil + LoadAsync JavaScript functions
|
233 |
add_action('wp_footer', 'fvm_add_loadcss', PHP_INT_MAX);
|
234 |
+
add_action('wp_head', 'fvm_add_loadasync', 0);
|
235 |
|
236 |
# remove query from static assets and process defering (if enabled)
|
237 |
add_filter('style_loader_src', 'fastvelocity_remove_cssjs_ver', 10, 2);
|
279 |
$wp_admin_bar->add_node(array(
|
280 |
'id' => 'fvm',
|
281 |
'title' => '<span class="ab-icon"></span><span class="ab-label">' . __("FVM Purge",'fvm') . '</span>',
|
282 |
+
'href' => wp_nonce_url( add_query_arg('_fvmcache', 'clear'), 'fvm_clear_nonce')
|
283 |
));
|
284 |
|
285 |
}
|
289 |
# function to list all cache files
|
290 |
function fastvelocity_min_files_callback() {
|
291 |
global $cachedir;
|
292 |
+
|
293 |
# default
|
294 |
$size = fastvelocity_get_cachestats();
|
295 |
+
$return = array('js' => array(), 'css' => array(), 'stamp' => $_POST['stamp'], 'cachesize'=> $size);
|
296 |
|
297 |
# inspect directory with opendir, since glob might not be available in some systems
|
298 |
clearstatcache();
|
300 |
while (false !== ($file = readdir($handle))) {
|
301 |
$file = $cachedir.'/'.$file;
|
302 |
$ext = pathinfo($file, PATHINFO_EXTENSION);
|
303 |
+
if (in_array($ext, array('js', 'css'))) {
|
304 |
+
$log = file_get_contents($file.'.txt');
|
305 |
+
$mincss = substr($file, 0, -4).'.min.css';
|
306 |
+
$minjs = substr($file, 0, -3).'.min.js';
|
307 |
+
$filename = basename($file);
|
308 |
+
if ($ext == 'css' && file_exists($mincss)) { $filename = basename($mincss); }
|
309 |
+
if ($ext == 'js' && file_exists($minjs)) { $filename = basename($minjs); }
|
310 |
$fsize = fastvelocity_format_filesize(filesize($file));
|
311 |
+
$uid = hash('adler32', $filename);
|
312 |
+
array_push($return[$ext], array('uid'=>$uid, 'filename' => $filename, 'log' => $log, 'fsize' => $fsize));
|
313 |
+
}
|
|
|
|
|
|
|
314 |
}
|
315 |
closedir($handle);
|
316 |
}
|
317 |
+
|
318 |
+
header('Content-Type: application/json');
|
319 |
+
echo json_encode($return);
|
320 |
+
wp_die();
|
321 |
}
|
322 |
|
323 |
|
352 |
register_setting('fvm-group', 'fastvelocity_min_force_inline_css');
|
353 |
register_setting('fvm-group', 'fastvelocity_min_remove_googlefonts');
|
354 |
register_setting('fvm-group', 'fastvelocity_gfonts_method');
|
355 |
+
register_setting('fvm-group', 'fastvelocity_fontawesome_method');
|
356 |
register_setting('fvm-group', 'fastvelocity_min_defer_for_pagespeed');
|
357 |
register_setting('fvm-group', 'fastvelocity_min_defer_for_pagespeed_optimize');
|
358 |
register_setting('fvm-group', 'fastvelocity_min_exclude_defer_login');
|
398 |
add_filter("plugin_action_links_".plugin_basename(__FILE__), 'fastvelocity_min_settings_link' );
|
399 |
|
400 |
|
401 |
+
# purge all caches by request
|
402 |
+
add_action('init','fastvelocity_process_cache_purge_request');
|
403 |
+
function fastvelocity_process_cache_purge_request(){
|
404 |
+
if((isset($_POST['purgeall']) && $_POST['purgeall'] == 1) || isset($_GET['_fvmcache'])) {
|
405 |
+
|
406 |
+
# must be able to cleanup cache
|
407 |
+
if (!current_user_can('manage_options')) { wp_die( __('You do not have sufficient permissions to access this page.')); }
|
408 |
+
|
409 |
+
# validate nonce
|
410 |
+
if(isset($_GET['wordpress_fvmcache']) && (empty($_GET['_wpnonce']) || !wp_verify_nonce($_GET['_wpnonce'], 'fvm_clear_nonce'))) {
|
411 |
+
wp_die( __('Invalid or expired request... please go back and refresh before trying again!'));
|
412 |
+
}
|
413 |
+
|
414 |
+
if(is_admin()) {
|
415 |
+
fvm_purge_all(); # purge all
|
416 |
+
fastvelocity_purge_others(); # purge third party caches
|
417 |
+
$others = fastvelocity_purge_others(); # purge third party caches
|
418 |
+
$notice = array('All caches from <strong>FVM</strong> have been purged!', strip_tags($others, '<strong>'));
|
419 |
+
$notice = base64_encode(json_encode($notice)); # encode
|
420 |
+
setcookie('wordpress_fvmcache', $notice, time()+60, COOKIEPATH, COOKIE_DOMAIN );
|
421 |
+
wp_safe_redirect(remove_query_arg('_wpnonce', remove_query_arg('_fvmcache', wp_get_referer())));
|
422 |
+
} else {
|
423 |
+
fvm_purge_all(); # purge all
|
424 |
+
fastvelocity_purge_others(); # purge third party caches
|
425 |
+
wp_safe_redirect(remove_query_arg('_wpnonce', remove_query_arg('_fvmcache', wp_get_referer())));
|
426 |
+
}
|
427 |
+
}
|
428 |
+
}
|
429 |
+
|
430 |
+
# print admin notices after purging caches, if on wp-admin
|
431 |
+
add_action( 'admin_notices', 'fastvelocity_admin_notices' );
|
432 |
+
function fastvelocity_admin_notices() {
|
433 |
+
|
434 |
+
# cache purge notices
|
435 |
+
if(isset($_COOKIE['wordpress_fvmcache']) && !empty($_COOKIE['wordpress_fvmcache'])) {
|
436 |
+
|
437 |
+
# decode to array or null
|
438 |
+
$jsonarr = json_decode(base64_decode($_COOKIE['wordpress_fvmcache']), true);
|
439 |
+
if(!is_null($jsonarr) && is_array($jsonarr)){
|
440 |
+
|
441 |
+
# must be able to cleanup cache
|
442 |
+
if (!current_user_can('manage_options')) { wp_die( __('You do not have sufficient permissions to access this page.')); }
|
443 |
+
|
444 |
+
# print notices
|
445 |
+
foreach ($jsonarr as $notice) {
|
446 |
+
echo __('<div class="notice notice-success is-dismissible"><p>'.$notice.'</p></div>');
|
447 |
+
}
|
448 |
+
}
|
449 |
+
|
450 |
+
# remove
|
451 |
+
setcookie('wordpress_fvmcache', $notice, time()-3600, COOKIEPATH, COOKIE_DOMAIN );
|
452 |
+
}
|
453 |
+
}
|
454 |
+
|
455 |
+
|
456 |
+
|
457 |
|
458 |
# manage settings page
|
459 |
function fastvelocity_min_settings() {
|
469 |
<div class="wrap">
|
470 |
<h1>Fast Velocity Minify</h1>
|
471 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
472 |
<h2 class="nav-tab-wrapper wp-clearfix">
|
473 |
<a href="?page=fastvelocity-min&tab=status" class="nav-tab <?php echo $active_tab == 'status' ? 'nav-tab-active' : ''; ?>">Status</a>
|
474 |
<a href="?page=fastvelocity-min&tab=set" class="nav-tab <?php echo $active_tab == 'set' ? 'nav-tab-active' : ''; ?>">Settings</a>
|
613 |
|
614 |
|
615 |
<tr>
|
616 |
+
<th scope="row">Font Options</th>
|
617 |
<td>
|
618 |
<p class="fvm-bold-green fvm-rowintro">The default options are usually good for performance.</p>
|
619 |
<fieldset>
|
646 |
$b = ''; if($sel == 2) { $b = ' checked="checked"'; }
|
647 |
$c = ''; if($sel == 3) { $c = ' checked="checked"'; }
|
648 |
?>
|
649 |
+
<p class="fvm-bold-green fvm-rowintro">Choose how to include Google Fonts on your pages, when available:</p>
|
650 |
<fieldset>
|
651 |
+
<label><input type="radio" name="fastvelocity_gfonts_method" value="1" <?php echo $a; ?>> Inline Google Fonts CSS</label> <span class="note-info">[ Will inline the <a target="_blank" href="https://caniuse.com/#feat=woff">woof</a> format only (with font hinting) ]</span><br>
|
652 |
<label><input type="radio" name="fastvelocity_gfonts_method" value="2"<?php echo $b; ?>> Async Google Fonts CSS files</label> <span class="note-info">[ Will use <a target="_blank" href="https://caniuse.com/#feat=link-rel-preload">preload</a> with <a href="https://github.com/filamentgroup/loadCSS">LoadCSS</a> polyfill ]</span><br>
|
653 |
+
<label><input type="radio" name="fastvelocity_gfonts_method" value="3"<?php echo $c; ?>> Async and exclude Google Fonts CSS from PSI</label> <span class="note-info">[ Will use JavaScript to load the fonts conditionally ] </span><br>
|
654 |
+
</fieldset>
|
655 |
+
</td>
|
656 |
+
</tr>
|
657 |
+
|
658 |
+
<tr>
|
659 |
+
<th scope="row">Font Awesome</th>
|
660 |
+
<td>
|
661 |
+
<?php
|
662 |
+
# what to select
|
663 |
+
$sel = get_option('fastvelocity_fontawesome_method');
|
664 |
+
$a = ''; if($sel == 1 || empty($sel)) { $a = ' checked="checked"'; }
|
665 |
+
$b = ''; if($sel == 2) { $b = ' checked="checked"'; }
|
666 |
+
$c = ''; if($sel == 3) { $c = ' checked="checked"'; }
|
667 |
+
?>
|
668 |
+
<p class="fvm-bold-green fvm-rowintro">Only if available and if it has "font-awesome" in the url:</p>
|
669 |
+
<fieldset>
|
670 |
+
<label><input type="radio" name="fastvelocity_fontawesome_method" value="1" <?php echo $a; ?>> Merge or Inline Font Awesome CSS</label> <span class="note-info">[ Depends on if you have the Inline CSS option enabled or not ]</span><br>
|
671 |
+
<label><input type="radio" name="fastvelocity_fontawesome_method" value="2"<?php echo $b; ?>> Async Font Awesome CSS file</label> <span class="note-info">[ Will use <a target="_blank" href="https://caniuse.com/#feat=link-rel-preload">preload</a> with <a href="https://github.com/filamentgroup/loadCSS">LoadCSS</a> polyfill ]</span><br>
|
672 |
+
<label><input type="radio" name="fastvelocity_fontawesome_method" value="3"<?php echo $c; ?>> Async and exclude Font Awesome CSS from PSI</label> <span class="note-info">[ Will use JavaScript to load the fonts conditionally ] </span><br>
|
673 |
</fieldset>
|
674 |
</td>
|
675 |
</tr>
|
676 |
|
677 |
+
|
678 |
<tr>
|
679 |
<th scope="row">CSS Options</th>
|
680 |
<td>
|
699 |
<br />
|
700 |
<label for="fastvelocity_min_force_inline_css">
|
701 |
<input name="fastvelocity_min_force_inline_css" type="checkbox" id="fastvelocity_min_force_inline_css" value="1" <?php echo checked(1 == get_option('fastvelocity_min_force_inline_css'), true, false); ?>>
|
702 |
+
Inline all CSS files <span class="note-info">[ If selected, CSS will be inlined to avoid the "render blocking" on PSI... good for small CSS code ]</span></label>
|
703 |
<br />
|
704 |
</fieldset></td>
|
705 |
</tr>
|
708 |
<tr>
|
709 |
<th scope="row">JavaScript Options</th>
|
710 |
<td>
|
711 |
+
<p class="fvm-bold-green fvm-rowintro">Try to disable minification (and purge the cache) first, if you have trouble with JavaScript in the frontend.</p>
|
712 |
<fieldset>
|
713 |
<label for="fastvelocity_min_disable_js_merge">
|
714 |
<input name="fastvelocity_min_disable_js_merge" type="checkbox" id="fastvelocity_min_disable_js_merge" value="1" <?php echo checked(1 == get_option('fastvelocity_min_disable_js_merge'), true, false); ?> >
|
1163 |
# process header javascript ###############
|
1164 |
###########################################
|
1165 |
function fastvelocity_min_merge_header_scripts() {
|
1166 |
+
global $wp_scripts, $wp_domain, $wp_home, $wp_home_path, $cachedir, $cachedirurl, $ignore, $disable_js_merge, $disable_js_minification, $enable_defer_js, $exclude_defer_jquery, $fvm_debug, $fvm_min_excludejslist, $fvmualist;
|
1167 |
if(!is_object($wp_scripts)) { return false; }
|
1168 |
$scripts = wp_clone($wp_scripts);
|
1169 |
$scripts->all_deps($scripts->queue);
|
1188 |
# get full url
|
1189 |
$hurl = fastvelocity_min_get_hurl($wp_scripts->registered[$handle]->src, $wp_domain, $wp_home);
|
1190 |
|
1191 |
+
# Exclude JS files from PSI (Async) takes priority over the ignore list
|
1192 |
+
if($fvm_min_excludejslist != false || is_array($fvm_min_excludejslist)) {
|
1193 |
+
|
1194 |
+
# check for string match
|
1195 |
+
$skipjs = false;
|
1196 |
+
foreach($fvm_min_excludejslist as $l) {
|
1197 |
+
if (stripos($hurl, $l) !== false) {
|
1198 |
+
# print code if there are no linebreaks, or return
|
1199 |
+
echo '<script type="text/javascript">if(!navigator.userAgent.match(/'.implode('|', $fvmualist).'/i)){';
|
1200 |
+
echo "loadAsync('$hurl', null);";
|
1201 |
+
echo '}</script>';
|
1202 |
+
$skipjs = true;
|
1203 |
+
break;
|
1204 |
+
}
|
1205 |
+
}
|
1206 |
+
if($skipjs != false) { continue; }
|
1207 |
+
}
|
1208 |
+
|
1209 |
# IE only files don't increment things
|
1210 |
$ieonly = fastvelocity_ie_blacklist($hurl);
|
1211 |
if($ieonly == true) { continue; }
|
1321 |
if(count($data) > 0) { $wp_scripts->registered["fvm-header-$i"]->extra['data'] = implode(PHP_EOL, $data); }
|
1322 |
|
1323 |
# enqueue file, if not empty
|
1324 |
+
if(file_exists($file) && (filesize($file) > 0 || count($data) > 0)) {
|
|
|
1325 |
wp_enqueue_script("fvm-header-$i");
|
1326 |
}
|
1327 |
|
1343 |
# process js in the footer ################
|
1344 |
###########################################
|
1345 |
function fastvelocity_min_merge_footer_scripts() {
|
1346 |
+
global $wp_scripts, $wp_domain, $wp_home, $wp_home_path, $cachedir, $cachedirurl, $ignore, $disable_js_merge, $disable_js_minification, $enable_defer_js, $exclude_defer_jquery, $fvm_debug, $fvm_min_excludejslist, $fvmualist;
|
1347 |
if(!is_object($wp_scripts)) { return false; }
|
1348 |
$ctime = get_option('fvm-last-cache-update', '0');
|
1349 |
$scripts = wp_clone($wp_scripts);
|
1363 |
# get full url
|
1364 |
$hurl = fastvelocity_min_get_hurl($wp_scripts->registered[$handle]->src, $wp_domain, $wp_home);
|
1365 |
|
1366 |
+
# Exclude JS files from PSI (Async) takes priority over the ignore list
|
1367 |
+
if($fvm_min_excludejslist != false || is_array($fvm_min_excludejslist)) {
|
1368 |
+
|
1369 |
+
# check for string match
|
1370 |
+
$skipjs = false;
|
1371 |
+
foreach($fvm_min_excludejslist as $l) {
|
1372 |
+
if (stripos($hurl, $l) !== false) {
|
1373 |
+
# print code if there are no linebreaks, or return
|
1374 |
+
echo '<script type="text/javascript">if(!navigator.userAgent.match(/'.implode('|', $fvmualist).'/i)){';
|
1375 |
+
echo "loadAsync('$hurl', null);";
|
1376 |
+
echo '}</script>';
|
1377 |
+
$skipjs = true;
|
1378 |
+
break;
|
1379 |
+
}
|
1380 |
+
}
|
1381 |
+
if($skipjs != false) { continue; }
|
1382 |
+
}
|
1383 |
+
|
1384 |
# IE only files don't increment things
|
1385 |
$ieonly = fastvelocity_ie_blacklist($hurl);
|
1386 |
if($ieonly == true) { continue; }
|
1479 |
# register minified file
|
1480 |
wp_register_script("fvm-footer-$i", $file_url, array(), null, false);
|
1481 |
|
|
|
|
|
|
|
|
|
1482 |
# add all extra data from wp_localize_script
|
1483 |
$data = array();
|
1484 |
foreach($footer[$i]['handles'] as $handle) {
|
1487 |
if(count($data) > 0) { $wp_scripts->registered["fvm-footer-$i"]->extra['data'] = implode(PHP_EOL, $data); }
|
1488 |
|
1489 |
# enqueue file, if not empty
|
1490 |
+
if(file_exists($file) && (filesize($file) > 0 || count($data) > 0)) {
|
|
|
1491 |
wp_enqueue_script("fvm-footer-$i");
|
1492 |
}
|
1493 |
|
1577 |
# process header css ######################
|
1578 |
###########################################
|
1579 |
function fastvelocity_min_merge_header_css() {
|
1580 |
+
global $wp_styles, $wp_domain, $wp_home, $wp_home_path, $cachedir, $cachedirurl, $ignore, $disable_css_merge, $disable_css_minification, $skip_google_fonts, $skip_cssorder, $remove_print_mediatypes, $force_inline_googlefonts, $css_hide_googlefonts, $min_async_googlefonts, $remove_googlefonts, $fvmloadcss, $fvm_remove_css, $fvmualist, $fvm_min_excludecsslist, $fvm_debug, $fvm_min_excludecsslist, $fvm_fawesome_method;
|
1581 |
if(!is_object($wp_styles)) { return false; }
|
1582 |
$ctime = get_option('fvm-last-cache-update', '0');
|
1583 |
$styles = wp_clone($wp_styles);
|
1612 |
}
|
1613 |
|
1614 |
# mediatype
|
1615 |
+
$mt = isset($wp_styles->registered[$handle]->args) ? $wp_styles->registered[$handle]->args : 'all';
|
1616 |
+
if ($mt == 'screen' || $mt == 'screen, print' || empty($mt) || is_null($mt) || $mt == false) { $mt = 'all'; }
|
1617 |
+
$mediatype = $mt;
|
1618 |
|
1619 |
# full url or empty
|
1620 |
$hurl = fastvelocity_min_get_hurl($wp_styles->registered[$handle]->src, $wp_domain, $wp_home);
|
1634 |
$done = array_merge($done, array($handle)); continue;
|
1635 |
}
|
1636 |
|
1637 |
+
# font awesome processing, async css
|
1638 |
+
if($fvm_fawesome_method == 2 && stripos($hurl, 'font-awesome') !== false) {
|
1639 |
+
echo '<link rel="preload" href="'.$hurl.'" as="style" media="'.$mediatype.'" onload="this.onload=null;this.rel=\'stylesheet\'" />';
|
1640 |
+
echo '<noscript><link rel="stylesheet" href="'.$hurl.'" media="'.$mediatype.'" /></noscript>';
|
1641 |
+
echo '<!--[if IE]><link rel="stylesheet" href="'.$hurl.'" media="'.$mediatype.'" /><![endif]-->';
|
1642 |
+
$done = array_merge($done, array($handle)); continue;
|
1643 |
+
}
|
1644 |
+
|
1645 |
+
# font awesome processing, async and exclude from PSI
|
1646 |
+
if($fvm_fawesome_method == 3 && stripos($hurl, 'font-awesome') !== false) {
|
1647 |
+
$cssguid = 'fvm'.hash('adler32', $hurl);
|
1648 |
+
echo '<script type="text/javascript">if(!navigator.userAgent.match(/'.implode('|', $fvmualist).'/i)){';
|
1649 |
+
echo 'var '.$cssguid.'=document.createElement("link");'.$cssguid.'.rel="stylesheet",'.$cssguid.'.type="text/css",'.$cssguid.'.media="async",'.$cssguid.'.href="'.$hurl.'",'.$cssguid.'.onload=function(){'.$cssguid.'.media="'.$mediatype.'"},document.getElementsByTagName("head")[0].appendChild('.$cssguid.');';
|
1650 |
+
echo '}</script>';
|
1651 |
+
$done = array_merge($done, array($handle)); continue;
|
1652 |
+
}
|
1653 |
+
|
1654 |
# array of info to save
|
1655 |
$arr = array('handle'=>$handle, 'url'=>$hurl, 'conditional'=>$conditional, 'mediatype'=>$mediatype);
|
1656 |
|
1726 |
|
1727 |
# inline css or fail
|
1728 |
if($res['code'] !== false) {
|
1729 |
+
|
1730 |
+
# add font-display
|
1731 |
+
# https://developers.google.com/web/updates/2016/02/font-display
|
1732 |
+
$res['code'] = str_ireplace('font-style:normal;', 'font-display:block;font-style:normal;', $res['code']);
|
1733 |
+
|
1734 |
+
# inline
|
1735 |
echo '<style type="text/css" media="all">'.$res['code'].'</style>'.PHP_EOL;
|
1736 |
} else {
|
1737 |
echo "<!-- GOOGLE FONTS REQUEST FAILED for $gfurl -->\n";
|
1765 |
$ieonly = fastvelocity_ie_blacklist($hurl);
|
1766 |
if($ieonly == true) { continue; }
|
1767 |
|
1768 |
+
# skip ignore list, conditional css, external css, font-awesome merge
|
1769 |
+
if ( (!fastvelocity_min_in_arrayi($hurl, $ignore) && !isset($conditional) && fvm_internal_url($hurl, $wp_home))
|
1770 |
+
|| empty($hurl)
|
1771 |
+
|| ($fvm_fawesome_method == 1 && stripos($href, 'font-awesome') !== false)) {
|
1772 |
|
1773 |
# colect inline css for this handle
|
1774 |
if(isset($wp_styles->registered[$handle]->extra['after']) && is_array($wp_styles->registered[$handle]->extra['after'])) {
|
1792 |
}
|
1793 |
endforeach;
|
1794 |
|
|
|
1795 |
# reorder CSS by mediatypes
|
1796 |
if(!$skip_cssorder) {
|
1797 |
if(count($header) > 0) {
|
1801 |
foreach($header as $array) {
|
1802 |
if(isset($array['media'])) { $allmedia[$array['media']] = ''; }
|
1803 |
}
|
1804 |
+
|
1805 |
# extract handles by mediatype
|
1806 |
$grouphandles = array();
|
1807 |
foreach ($allmedia as $md=>$var) {
|
1808 |
foreach($header as $array) {
|
1809 |
+
if (isset($array['media']) && $array['media'] === $md) {
|
1810 |
foreach($array['handles'] as $h) { $grouphandles[$md][] = $h; }
|
1811 |
}
|
1812 |
}
|
1910 |
|
1911 |
# enqueue file, if not empty
|
1912 |
} else {
|
1913 |
+
if(file_exists($file) && filesize($file) > 0) {
|
|
|
1914 |
|
1915 |
+
# inline CSS if mediatype is not of type "all" (such as mobile only), if the file is smaller than 20KB
|
1916 |
+
if(filesize($file) < 20000 && $header[$i]['media'] != 'all') {
|
1917 |
+
echo '<style id="fvm-header-'.$i.'" media="'.$header[$i]['media'].'">'.file_get_contents($file).'</style>';
|
1918 |
+
} else {
|
1919 |
+
# enqueue it
|
1920 |
+
wp_enqueue_style("fvm-header-$i", $file_url, array(), null, $header[$i]['media']);
|
1921 |
+
}
|
1922 |
+
|
1923 |
}
|
1924 |
}
|
1925 |
}
|
1942 |
# process css in the footer ###############
|
1943 |
###########################################
|
1944 |
function fastvelocity_min_merge_footer_css() {
|
1945 |
+
global $wp_styles, $wp_domain, $wp_home, $wp_home_path, $cachedir, $cachedirurl, $ignore, $disable_css_merge, $disable_css_minification, $skip_google_fonts, $skip_cssorder, $remove_print_mediatypes, $force_inline_googlefonts, $css_hide_googlefonts, $min_async_googlefonts, $remove_googlefonts, $fvmloadcss, $fvm_remove_css, $fvmualist, $fvm_debug, $fvm_fawesome_method, $fvm_min_excludecsslist;
|
1946 |
|
1947 |
if(!is_object($wp_styles)) { return false; }
|
1948 |
$ctime = get_option('fvm-last-cache-update', '0');
|
1970 |
|
1971 |
# google fonts to the top
|
1972 |
foreach( $styles->to_do as $handle ) :
|
1973 |
+
|
1974 |
# dequeue and get a list of google fonts, or requeue external
|
1975 |
$hurl = fastvelocity_min_get_hurl($wp_styles->registered[$handle]->src, $wp_domain, $wp_home);
|
1976 |
+
|
1977 |
if (stripos($hurl, 'fonts.googleapis.com') !== false) {
|
1978 |
wp_dequeue_style($handle);
|
1979 |
if($remove_googlefonts != false) { $done = array_merge($done, array($handle)); continue; } # mark as done if to be removed
|
1985 |
} else {
|
1986 |
wp_dequeue_style($handle); wp_enqueue_style($handle); # failsafe
|
1987 |
}
|
1988 |
+
|
1989 |
endforeach;
|
1990 |
|
1991 |
|
2063 |
|
2064 |
|
2065 |
# get groups of handles
|
2066 |
+
$uniq = array();
|
2067 |
foreach( $styles->to_do as $handle ) :
|
2068 |
|
2069 |
# skip already processed google fonts
|
2070 |
if(isset($google_fonts[$handle])) { continue; }
|
2071 |
+
|
2072 |
+
# conditionals
|
2073 |
+
$conditional = NULL; if(isset($wp_styles->registered[$handle]->extra["conditional"])) {
|
2074 |
+
$conditional = $wp_styles->registered[$handle]->extra["conditional"]; # such as ie7, ie8, ie9, etc
|
2075 |
+
}
|
2076 |
+
|
2077 |
+
# mediatype
|
2078 |
+
$mt = isset($wp_styles->registered[$handle]->args) ? $wp_styles->registered[$handle]->args : 'all';
|
2079 |
+
if ($mt == 'screen' || $mt == 'screen, print' || empty($mt) || is_null($mt) || $mt == false) { $mt = 'all'; }
|
2080 |
+
$mediatype = $mt;
|
2081 |
+
|
2082 |
# get full url
|
2083 |
$hurl = fastvelocity_min_get_hurl($wp_styles->registered[$handle]->src, $wp_domain, $wp_home);
|
2084 |
+
|
2085 |
+
# mark duplicates as done and remove from the queue
|
2086 |
+
if(!empty($hurl)) {
|
2087 |
+
$key = hash('adler32', $hurl);
|
2088 |
+
if (isset($uniq[$key])) { $done = array_merge($done, array($handle)); continue; } else { $uniq[$key] = $handle; }
|
2089 |
+
}
|
2090 |
|
2091 |
# IE only files don't increment things
|
2092 |
$ieonly = fastvelocity_ie_blacklist($hurl);
|
2093 |
if($ieonly == true) { continue; }
|
2094 |
|
2095 |
+
|
2096 |
+
# Exclude specific CSS files from PSI?
|
2097 |
+
if($fvm_min_excludecsslist != false && is_array($fvm_min_excludecsslist) && fastvelocity_min_in_arrayi($hurl, $fvm_min_excludecsslist)) {
|
2098 |
+
$cssguid = 'fvm'.hash('adler32', $hurl);
|
2099 |
+
echo '<script type="text/javascript">if(!navigator.userAgent.match(/'.implode('|', $fvmualist).'/i)){';
|
2100 |
+
echo 'var '.$cssguid.'=document.createElement("link");'.$cssguid.'.rel="stylesheet",'.$cssguid.'.type="text/css",'.$cssguid.'.media="async",'.$cssguid.'.href="'.$hurl.'",'.$cssguid.'.onload=function(){'.$cssguid.'.media="'.$mediatype.'"},document.getElementsByTagName("head")[0].appendChild('.$cssguid.');';
|
2101 |
+
echo '}</script>';
|
2102 |
+
$done = array_merge($done, array($handle)); continue;
|
2103 |
+
}
|
2104 |
+
|
2105 |
+
# font awesome processing, async css
|
2106 |
+
if($fvm_fawesome_method == 2 && stripos($hurl, 'font-awesome') !== false) {
|
2107 |
+
echo '<link rel="preload" href="'.$hurl.'" as="style" media="'.$mediatype.'" onload="this.onload=null;this.rel=\'stylesheet\'" />';
|
2108 |
+
echo '<noscript><link rel="stylesheet" href="'.$hurl.'" media="'.$mediatype.'" /></noscript>';
|
2109 |
+
echo '<!--[if IE]><link rel="stylesheet" href="'.$hurl.'" media="'.$mediatype.'" /><![endif]-->';
|
2110 |
+
$done = array_merge($done, array($handle)); continue;
|
2111 |
+
}
|
2112 |
+
|
2113 |
+
# font awesome processing, async and exclude from PSI
|
2114 |
+
if($fvm_fawesome_method == 3 && stripos($hurl, 'font-awesome') !== false) {
|
2115 |
+
$cssguid = 'fvm'.hash('adler32', $hurl);
|
2116 |
+
echo '<script type="text/javascript">if(!navigator.userAgent.match(/'.implode('|', $fvmualist).'/i)){';
|
2117 |
+
echo 'var '.$cssguid.'=document.createElement("link");'.$cssguid.'.rel="stylesheet",'.$cssguid.'.type="text/css",'.$cssguid.'.media="async",'.$cssguid.'.href="'.$hurl.'",'.$cssguid.'.onload=function(){'.$cssguid.'.media="'.$mediatype.'"},document.getElementsByTagName("head")[0].appendChild('.$cssguid.');';
|
2118 |
+
echo '}</script>';
|
2119 |
+
$done = array_merge($done, array($handle)); continue;
|
2120 |
}
|
2121 |
|
2122 |
+
# skip ignore list, conditional css, external css, font-awesome merge
|
2123 |
+
if ( (!fastvelocity_min_in_arrayi($hurl, $ignore) && !isset($conditional) && fvm_internal_url($hurl, $wp_home))
|
2124 |
+
|| empty($hurl)
|
2125 |
+
|| ($fvm_fawesome_method == 1 && stripos($href, 'font-awesome') !== false)) {
|
2126 |
|
2127 |
# colect inline css for this handle
|
2128 |
if(isset($wp_styles->registered[$handle]->extra['after']) && is_array($wp_styles->registered[$handle]->extra['after'])) {
|
2132 |
|
2133 |
# process
|
2134 |
if(isset($footer[count($footer)-1]['handle']) || count($footer) == 0 || $footer[count($footer)-1]['media'] != $wp_styles->registered[$handle]->args) {
|
2135 |
+
array_push($footer, array('handles'=>array(),'media'=>$mediatype));
|
2136 |
}
|
2137 |
|
2138 |
# push it to the array get latest modified time
|
2161 |
$grouphandles = array();
|
2162 |
foreach ($allmedia as $md=>$var) {
|
2163 |
foreach($footer as $array) {
|
2164 |
+
if (isset($array['media']) && $array['media'] === $md) {
|
2165 |
foreach($array['handles'] as $h) { $grouphandles[$md][] = $h; }
|
2166 |
}
|
2167 |
}
|
2252 |
}
|
2253 |
|
2254 |
# register and enqueue minified file, consider excluding of mediatype "print" and inline css
|
2255 |
+
if ($remove_print_mediatypes != true || ($remove_print_mediatypes == true && $footer[$i]['media'] != 'print')) {
|
2256 |
|
2257 |
# the developers tab, takes precedence
|
2258 |
|
2265 |
|
2266 |
# enqueue file, if not empty
|
2267 |
} else {
|
2268 |
+
if(file_exists($file) && filesize($file) > 0) {
|
2269 |
+
|
2270 |
+
# inline if the file is smaller than 20KB
|
2271 |
+
if(filesize($file) < 20000) {
|
2272 |
+
echo '<style id="fvm-footer-'.$i.'" media="'.$footer[$i]['media'].'">'.file_get_contents($file).'</style>';
|
2273 |
+
} else {
|
2274 |
+
# enqueue it
|
2275 |
+
wp_enqueue_style("fvm-footer-$i", $file_url, array(), null, $footer[$i]['media']);
|
2276 |
+
}
|
2277 |
}
|
2278 |
}
|
2279 |
}
|
2300 |
|
2301 |
echo <<<EOF
|
2302 |
<script>
|
|
|
|
|
2303 |
/*! loadCSS. [c]2017 Filament Group, Inc. MIT License */
|
2304 |
!function(n){"use strict";n.loadCSS||(n.loadCSS=function(){});var o=loadCSS.relpreload={};if(o.support=function(){var e;try{e=n.document.createElement("link").relList.supports("preload")}catch(t){e=!1}return function(){return e}}(),o.bindMediaToggle=function(t){var e=t.media||"all";function a(){t.media=e}t.addEventListener?t.addEventListener("load",a):t.attachEvent&&t.attachEvent("onload",a),setTimeout(function(){t.rel="stylesheet",t.media="only x"}),setTimeout(a,3e3)},o.poly=function(){if(!o.support())for(var t=n.document.getElementsByTagName("link"),e=0;e<t.length;e++){var a=t[e];"preload"!==a.rel||"style"!==a.getAttribute("as")||a.getAttribute("data-loadcss")||(a.setAttribute("data-loadcss",!0),o.bindMediaToggle(a))}},!o.support()){o.poly();var t=n.setInterval(o.poly,500);n.addEventListener?n.addEventListener("load",function(){o.poly(),n.clearInterval(t)}):n.attachEvent&&n.attachEvent("onload",function(){o.poly(),n.clearInterval(t)})}"undefined"!=typeof exports?exports.loadCSS=loadCSS:n.loadCSS=loadCSS}("undefined"!=typeof global?global:this);
|
2305 |
</script>
|
2307 |
|
2308 |
}
|
2309 |
|
2310 |
+
# fvm load async scripts with callback
|
2311 |
+
function fvm_add_loadasync() {
|
2312 |
+
|
2313 |
+
echo <<<EOF
|
2314 |
+
<script>function loadAsync(e,a){var t=document.createElement("script");t.src=e,null!==a&&(t.readyState?t.onreadystatechange=function(){"loaded"!=t.readyState&&"complete"!=t.readyState||(t.onreadystatechange=null,a())}:t.onload=function(){a()}),document.getElementsByTagName("head")[0].appendChild(t)}</script>
|
2315 |
+
EOF;
|
2316 |
+
|
2317 |
+
}
|
2318 |
|
2319 |
|
2320 |
|
2387 |
# optimize the ignore list for pagespeed insights + Exclude JS files from PSI (Async)
|
2388 |
###########################################
|
2389 |
function fastvelocity_min_defer_js_optimize($tag, $handle, $src) {
|
2390 |
+
global $defer_for_pagespeed, $defer_for_pagespeed_optimize, $fvm_fix_editor, $fvmualist;
|
2391 |
|
2392 |
# return if there are linebreaks (will break document.write)
|
2393 |
+
if (stripos($tag, PHP_EOL) !== false) { return $tag; }
|
2394 |
|
2395 |
# fix page editors
|
2396 |
if($fvm_fix_editor == true && is_user_logged_in()) { return $tag; }
|
2403 |
$src = stristr($src, '?ver', true);
|
2404 |
}
|
2405 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2406 |
# exclude ignored scripts
|
2407 |
if(substr($handle, 0, 4) != "fvm-" && $defer_for_pagespeed == true && $defer_for_pagespeed_optimize == true) {
|
2408 |
|
2433 |
|
2434 |
# inline css in place, instead of inlining the large file
|
2435 |
function fastvelocity_optimizecss($html, $handle, $href, $media){
|
2436 |
+
global $fvm_debug, $wp_domain, $wp_home, $force_inline_css, $fvmualist, $fvm_collect_google_fonts, $force_inline_googlefonts, $min_async_googlefonts, $remove_googlefonts, $skip_google_fonts, $css_hide_googlefonts, $remove_print_mediatypes, $ignore, $blacklist, $ignorelist, $wp_home, $fvmloadcss, $fvm_remove_css, $fvm_cdn_url, $disable_minification, $fvm_min_excludecsslist, $disable_css_minification, $fvm_fix_editor, $fvm_fawesome_method;
|
2437 |
|
2438 |
# current timestamp
|
2439 |
$ctime = get_option('fvm-last-cache-update', '0');
|
2465 |
}
|
2466 |
|
2467 |
# mediatype fix for some plugins + remove print mediatypes
|
2468 |
+
if ($media == 'screen' || $media == 'screen, print' || empty($media) || is_null($media) || $media == false) { $media = 'all'; }
|
2469 |
if($remove_print_mediatypes != false && $media == 'print') {
|
2470 |
return false;
|
2471 |
}
|
2490 |
return false;
|
2491 |
}
|
2492 |
|
|
|
2493 |
# handle google fonts here, when merging is disabled
|
2494 |
if(stripos($href, 'fonts.googleapis.com') !== false && $skip_google_fonts != false) {
|
2495 |
|
2511 |
}
|
2512 |
}
|
2513 |
|
2514 |
+
# font awesome processing, async css
|
2515 |
+
if($fvm_fawesome_method == 2 && stripos($href, 'font-awesome') !== false) {
|
2516 |
+
echo '<link rel="preload" href="'.$href.'" as="style" media="'.$media.'" onload="this.onload=null;this.rel=\'stylesheet\'" />';
|
2517 |
+
echo '<noscript><link rel="stylesheet" href="'.$href.'" media="'.$media.'" /></noscript>';
|
2518 |
+
echo '<!--[if IE]><link rel="stylesheet" href="'.$href.'" media="'.$media.'" /><![endif]-->';
|
2519 |
+
return false;
|
2520 |
+
}
|
2521 |
+
|
2522 |
+
# font awesome processing, async and exclude from PSI
|
2523 |
+
if($fvm_fawesome_method == 3 && stripos($href, 'font-awesome') !== false) {
|
2524 |
+
$cssguid = 'fvm'.hash('adler32', $href);
|
2525 |
+
echo '<script type="text/javascript">if(!navigator.userAgent.match(/'.implode('|', $fvmualist).'/i)){';
|
2526 |
+
echo 'var '.$cssguid.'=document.createElement("link");'.$cssguid.'.rel="stylesheet",'.$cssguid.'.type="text/css",'.$cssguid.'.media="async",'.$cssguid.'.href="'.$href.'",'.$cssguid.'.onload=function(){'.$cssguid.'.media="'.$media.'"},document.getElementsByTagName("head")[0].appendChild('.$cssguid.');';
|
2527 |
+
echo '}</script>';
|
2528 |
+
return false;
|
2529 |
+
}
|
2530 |
+
|
2531 |
+
# font awesome processing, inline
|
2532 |
+
if($fvm_fawesome_method == 1 && stripos($href, 'font-awesome') !== false) {
|
2533 |
+
|
2534 |
+
# download, minify, cache
|
2535 |
+
$tkey = 'css-'.$ctime.'-'.hash('adler32', $handle.$href).'.css';
|
2536 |
+
$json = false; $json = fvm_get_transient($tkey);
|
2537 |
+
if ( $json === false) {
|
2538 |
+
$json = fvm_download_and_minify($href, null, $disable_css_minification, 'css', $handle);
|
2539 |
+
if($fvm_debug == true) { echo "<!-- FVM DEBUG: Uncached file processing now for $handle / $href -->" . PHP_EOL; }
|
2540 |
+
fvm_set_transient($tkey, $json);
|
2541 |
+
}
|
2542 |
+
|
2543 |
+
# decode
|
2544 |
+
$res = json_decode($json, true);
|
2545 |
+
|
2546 |
+
# add font-display
|
2547 |
+
# https://developers.google.com/web/updates/2016/02/font-display
|
2548 |
+
$res['code'] = str_ireplace('font-style:normal;', 'font-display:block;font-style:normal;', $res['code']);
|
2549 |
+
|
2550 |
+
# inline css or fail
|
2551 |
+
if($res['status'] != false) {
|
2552 |
+
echo '<style type="text/css" media="all">'.$res['code'].'</style>'.PHP_EOL;
|
2553 |
+
return false;
|
2554 |
+
} else {
|
2555 |
+
if($fvm_debug == true) { echo "<!-- FVM DEBUG: Font Awesome request failed for $href -->" . PHP_EOL; }
|
2556 |
+
return $html;
|
2557 |
+
}
|
2558 |
+
}
|
2559 |
+
|
2560 |
# inline google fonts, do not collect
|
2561 |
if(stripos($href, 'fonts.googleapis.com') !== false && $force_inline_googlefonts != false && $css_hide_googlefonts != true && $min_async_googlefonts != true) {
|
2562 |
|
2572 |
# decode
|
2573 |
$res = json_decode($json, true);
|
2574 |
|
2575 |
+
# add font-display
|
2576 |
+
# https://developers.google.com/web/updates/2016/02/font-display
|
2577 |
+
$res['code'] = str_ireplace('font-style:normal;', 'font-display:block;font-style:normal;', $res['code']);
|
2578 |
+
|
2579 |
# inline css or fail
|
2580 |
if($res['status'] != false) {
|
2581 |
echo '<style type="text/css" media="all">'.$res['code'].'</style>'.PHP_EOL;
|
2592 |
return false;
|
2593 |
}
|
2594 |
|
|
|
2595 |
# skip external scripts that are not specifically allowed
|
2596 |
if (fvm_internal_url($href, $wp_home) === false || empty($href)) {
|
2597 |
if($fvm_debug == true) { echo "<!-- FVM DEBUG: Skipped the next external enqueued CSS -->" . PHP_EOL; }
|
@@ -7,7 +7,7 @@ if(function_exists('mb_internal_encoding')) { mb_internal_encoding('UTF-8'); }
|
|
7 |
@ini_set('pcre.backtrack_limit',5000000);
|
8 |
@ini_set('pcre.recursion_limit',5000000);
|
9 |
|
10 |
-
# Consider fallback to PHP Minify [
|
11 |
$path = $plugindir . 'libs/matthiasmullie';
|
12 |
require_once $path . '/minify/src/Minify.php';
|
13 |
require_once $path . '/minify/src/CSS.php';
|
@@ -66,7 +66,7 @@ function fastvelocity_plugin_activate() {
|
|
66 |
fvm_cache_increment();
|
67 |
|
68 |
# default blacklist
|
69 |
-
$exc = array('/html5shiv.js', '/html5shiv-printshiv.min.js', '/excanvas.js', '/avada-ie9.js', '/respond.js', '/respond.min.js', '/selectivizr.js', '/Avada/assets/css/ie.css', '/html5.js', '/IE9.js', '/fusion-ie9.js', '/vc_lte_ie9.min.css', '/old-ie.css', '/ie.css', '/vc-ie8.min.css', '/mailchimp-for-wp/assets/js/third-party/placeholders.min.js', '/assets/js/plugins/wp-enqueue/min/webfontloader.js', '/a.optnmstr.com/app/js/api.min.js', '/pixelyoursite/js/public.js');
|
70 |
update_option('fastvelocity_min_blacklist', implode(PHP_EOL, $exc));
|
71 |
|
72 |
# default ignore list
|
@@ -273,6 +273,11 @@ if(!$disable_js_minification) {
|
|
273 |
$js = fvm_compat_urls($js);
|
274 |
}
|
275 |
|
|
|
|
|
|
|
|
|
|
|
276 |
# needed when merging js files
|
277 |
$js = trim($js);
|
278 |
if(substr($js, -1) != ';'){ $js = $js.';'; }
|
@@ -286,15 +291,17 @@ return $js . PHP_EOL;
|
|
286 |
# minify JS string with PHP Minify or YUI Compressors
|
287 |
function fastvelocity_min_minify_js_string($js) {
|
288 |
global $tmpdir, $plugindir;
|
289 |
-
|
290 |
-
# PHP Minify
|
291 |
-
$minifier = new Minify\JS($js);
|
292 |
-
$min = $minifier->minify();
|
293 |
-
if($min !== false && (strlen(trim($js)) == strlen(trim($min)) || strlen(trim($min)) > 0)) {
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
|
|
|
|
298 |
}
|
299 |
|
300 |
# functions, minify html
|
7 |
@ini_set('pcre.backtrack_limit',5000000);
|
8 |
@ini_set('pcre.recursion_limit',5000000);
|
9 |
|
10 |
+
# Consider fallback to PHP Minify [2018.12.03] from https://github.com/matthiasmullie/minify (must be defined on the outer scope)
|
11 |
$path = $plugindir . 'libs/matthiasmullie';
|
12 |
require_once $path . '/minify/src/Minify.php';
|
13 |
require_once $path . '/minify/src/CSS.php';
|
66 |
fvm_cache_increment();
|
67 |
|
68 |
# default blacklist
|
69 |
+
$exc = array('/html5shiv.js', '/html5shiv-printshiv.min.js', '/excanvas.js', '/avada-ie9.js', '/respond.js', '/respond.min.js', '/selectivizr.js', '/Avada/assets/css/ie.css', '/html5.js', '/IE9.js', '/fusion-ie9.js', '/vc_lte_ie9.min.css', '/old-ie.css', '/ie.css', '/vc-ie8.min.css', '/mailchimp-for-wp/assets/js/third-party/placeholders.min.js', '/assets/js/plugins/wp-enqueue/min/webfontloader.js', '/a.optnmstr.com/app/js/api.min.js', '/pixelyoursite/js/public.js', '/assets/js/wcdrip-drip.js');
|
70 |
update_option('fastvelocity_min_blacklist', implode(PHP_EOL, $exc));
|
71 |
|
72 |
# default ignore list
|
273 |
$js = fvm_compat_urls($js);
|
274 |
}
|
275 |
|
276 |
+
# try to remove source mapping files
|
277 |
+
$filename = basename($url);
|
278 |
+
$remove = array("//# sourceMappingURL=$filename.map", "//# sourceMappingURL = $filename.map");
|
279 |
+
$js = str_ireplace($remove, '', $js);
|
280 |
+
|
281 |
# needed when merging js files
|
282 |
$js = trim($js);
|
283 |
if(substr($js, -1) != ';'){ $js = $js.';'; }
|
291 |
# minify JS string with PHP Minify or YUI Compressors
|
292 |
function fastvelocity_min_minify_js_string($js) {
|
293 |
global $tmpdir, $plugindir;
|
294 |
+
|
295 |
+
# PHP Minify from https://github.com/matthiasmullie/minify
|
296 |
+
$minifier = new Minify\JS($js);
|
297 |
+
$min = $minifier->minify();
|
298 |
+
if($min !== false && (strlen(trim($js)) == strlen(trim($min)) || strlen(trim($min)) > 0)) {
|
299 |
+
return fvm_compat_urls($min);
|
300 |
+
}
|
301 |
+
|
302 |
+
# if we are here, something went wrong and minification didn't work
|
303 |
+
$js = "\n/*! FVM: Minification of the following section failed, so it has been merged instead. */\n".$js;
|
304 |
+
return fvm_compat_urls($js);
|
305 |
}
|
306 |
|
307 |
# functions, minify html
|
@@ -307,10 +307,11 @@ class CSS extends Minify
|
|
307 |
*/
|
308 |
$this->extractStrings();
|
309 |
$this->stripComments();
|
|
|
310 |
$css = $this->replace($css);
|
311 |
|
312 |
$css = $this->stripWhitespace($css);
|
313 |
-
$css = $this->
|
314 |
$css = $this->shortenZeroes($css);
|
315 |
$css = $this->shortenFontWeights($css);
|
316 |
$css = $this->stripEmptyTags($css);
|
@@ -481,12 +482,16 @@ class CSS extends Minify
|
|
481 |
*
|
482 |
* @return string
|
483 |
*/
|
484 |
-
protected function
|
485 |
{
|
486 |
-
$content = preg_replace('/(?<=[: ])#([0-9a-z])\\1([0-9a-z])\\2([0-9a-z])\\3(?=[; }])/i', '#$1$2$3', $content);
|
|
|
|
|
|
|
|
|
487 |
|
488 |
-
// we can shorten some even more by replacing them with their color name
|
489 |
$colors = array(
|
|
|
490 |
'#F0FFFF' => 'azure',
|
491 |
'#F5F5DC' => 'beige',
|
492 |
'#A52A2A' => 'brown',
|
@@ -514,6 +519,9 @@ class CSS extends Minify
|
|
514 |
'#FF6347' => 'tomato',
|
515 |
'#EE82EE' => 'violet',
|
516 |
'#F5DEB3' => 'wheat',
|
|
|
|
|
|
|
517 |
);
|
518 |
|
519 |
return preg_replace_callback(
|
@@ -559,11 +567,7 @@ class CSS extends Minify
|
|
559 |
// `5px - 0px` is valid, but `5px - 0` is not
|
560 |
// `10px * 0` is valid (equates to 0), and so is `10 * 0px`, but
|
561 |
// `10 * 0` is invalid
|
562 |
-
//
|
563 |
-
// (which is a whole other undertaking, where units & order of
|
564 |
-
// operations all need to be considered...)
|
565 |
-
$calcs = $this->findCalcs($content);
|
566 |
-
$content = str_replace($calcs, array_keys($calcs), $content);
|
567 |
|
568 |
// reusable bits of code throughout these regexes:
|
569 |
// before & after are used to make sure we don't match lose unintended
|
@@ -600,9 +604,6 @@ class CSS extends Minify
|
|
600 |
$content = preg_replace('/flex:([0-9]+\s[0-9]+\s)0([;\}])/', 'flex:${1}0%${2}', $content);
|
601 |
$content = preg_replace('/flex-basis:0([;\}])/', 'flex-basis:0%${1}', $content);
|
602 |
|
603 |
-
// restore `calc()` expressions
|
604 |
-
$content = str_replace(array_keys($calcs), $calcs, $content);
|
605 |
-
|
606 |
return $content;
|
607 |
}
|
608 |
|
@@ -626,6 +627,17 @@ class CSS extends Minify
|
|
626 |
*/
|
627 |
protected function stripComments()
|
628 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
629 |
$this->registerPattern('/\/\*.*?\*\//s', '');
|
630 |
}
|
631 |
|
@@ -648,8 +660,8 @@ class CSS extends Minify
|
|
648 |
// remove whitespace around meta characters
|
649 |
// inspired by stackoverflow.com/questions/15195750/minify-compress-css-with-regex
|
650 |
$content = preg_replace('/\s*([\*$~^|]?+=|[{};,>~]|!important\b)\s*/', '$1', $content);
|
651 |
-
$content = preg_replace('/([\[(
|
652 |
-
$content = preg_replace('/\s+([\]\)])/', '$1', $content);
|
653 |
$content = preg_replace('/\s+(:)(?![^\}]*\{)/', '$1', $content);
|
654 |
|
655 |
// whitespace around + and - can only be stripped inside some pseudo-
|
@@ -666,18 +678,13 @@ class CSS extends Minify
|
|
666 |
}
|
667 |
|
668 |
/**
|
669 |
-
*
|
670 |
-
*
|
671 |
-
* @param string $content The CSS content to find `calc()`s in.
|
672 |
-
*
|
673 |
-
* @return string[]
|
674 |
*/
|
675 |
-
protected function
|
676 |
{
|
677 |
-
$
|
678 |
-
|
679 |
-
|
680 |
-
foreach ($matches as $match) {
|
681 |
$length = strlen($match[1]);
|
682 |
$expr = '';
|
683 |
$opened = 0;
|
@@ -691,11 +698,17 @@ class CSS extends Minify
|
|
691 |
break;
|
692 |
}
|
693 |
}
|
|
|
|
|
694 |
|
695 |
-
$
|
696 |
-
|
|
|
|
|
|
|
|
|
697 |
|
698 |
-
|
699 |
}
|
700 |
|
701 |
/**
|
307 |
*/
|
308 |
$this->extractStrings();
|
309 |
$this->stripComments();
|
310 |
+
$this->extractCalcs();
|
311 |
$css = $this->replace($css);
|
312 |
|
313 |
$css = $this->stripWhitespace($css);
|
314 |
+
$css = $this->shortenColors($css);
|
315 |
$css = $this->shortenZeroes($css);
|
316 |
$css = $this->shortenFontWeights($css);
|
317 |
$css = $this->stripEmptyTags($css);
|
482 |
*
|
483 |
* @return string
|
484 |
*/
|
485 |
+
protected function shortenColors($content)
|
486 |
{
|
487 |
+
$content = preg_replace('/(?<=[: ])#([0-9a-z])\\1([0-9a-z])\\2([0-9a-z])\\3(?:([0-9a-z])\\4)?(?=[; }])/i', '#$1$2$3$4', $content);
|
488 |
+
|
489 |
+
// remove alpha channel if it's pointless...
|
490 |
+
$content = preg_replace('/(?<=[: ])#([0-9a-z]{6})ff?(?=[; }])/i', '#$1', $content);
|
491 |
+
$content = preg_replace('/(?<=[: ])#([0-9a-z]{3})f?(?=[; }])/i', '#$1', $content);
|
492 |
|
|
|
493 |
$colors = array(
|
494 |
+
// we can shorten some even more by replacing them with their color name
|
495 |
'#F0FFFF' => 'azure',
|
496 |
'#F5F5DC' => 'beige',
|
497 |
'#A52A2A' => 'brown',
|
519 |
'#FF6347' => 'tomato',
|
520 |
'#EE82EE' => 'violet',
|
521 |
'#F5DEB3' => 'wheat',
|
522 |
+
// or the other way around
|
523 |
+
'WHITE' => '#fff',
|
524 |
+
'BLACK' => '#000',
|
525 |
);
|
526 |
|
527 |
return preg_replace_callback(
|
567 |
// `5px - 0px` is valid, but `5px - 0` is not
|
568 |
// `10px * 0` is valid (equates to 0), and so is `10 * 0px`, but
|
569 |
// `10 * 0` is invalid
|
570 |
+
// we've extracted calcs earlier, so we don't need to worry about this
|
|
|
|
|
|
|
|
|
571 |
|
572 |
// reusable bits of code throughout these regexes:
|
573 |
// before & after are used to make sure we don't match lose unintended
|
604 |
$content = preg_replace('/flex:([0-9]+\s[0-9]+\s)0([;\}])/', 'flex:${1}0%${2}', $content);
|
605 |
$content = preg_replace('/flex-basis:0([;\}])/', 'flex-basis:0%${1}', $content);
|
606 |
|
|
|
|
|
|
|
607 |
return $content;
|
608 |
}
|
609 |
|
627 |
*/
|
628 |
protected function stripComments()
|
629 |
{
|
630 |
+
// PHP only supports $this inside anonymous functions since 5.4
|
631 |
+
$minifier = $this;
|
632 |
+
$callback = function ($match) use ($minifier) {
|
633 |
+
$count = count($minifier->extracted);
|
634 |
+
$placeholder = '/*'.$count.'*/';
|
635 |
+
$minifier->extracted[$placeholder] = $match[0];
|
636 |
+
|
637 |
+
return $placeholder;
|
638 |
+
};
|
639 |
+
$this->registerPattern('/\n?\/\*(!|.*?@license|.*?@preserve).*?\*\/\n?/s', $callback);
|
640 |
+
|
641 |
$this->registerPattern('/\/\*.*?\*\//s', '');
|
642 |
}
|
643 |
|
660 |
// remove whitespace around meta characters
|
661 |
// inspired by stackoverflow.com/questions/15195750/minify-compress-css-with-regex
|
662 |
$content = preg_replace('/\s*([\*$~^|]?+=|[{};,>~]|!important\b)\s*/', '$1', $content);
|
663 |
+
$content = preg_replace('/([\[(:>\+])\s+/', '$1', $content);
|
664 |
+
$content = preg_replace('/\s+([\]\)>\+])/', '$1', $content);
|
665 |
$content = preg_replace('/\s+(:)(?![^\}]*\{)/', '$1', $content);
|
666 |
|
667 |
// whitespace around + and - can only be stripped inside some pseudo-
|
678 |
}
|
679 |
|
680 |
/**
|
681 |
+
* Replace all `calc()` occurrences.
|
|
|
|
|
|
|
|
|
682 |
*/
|
683 |
+
protected function extractCalcs()
|
684 |
{
|
685 |
+
// PHP only supports $this inside anonymous functions since 5.4
|
686 |
+
$minifier = $this;
|
687 |
+
$callback = function ($match) use ($minifier) {
|
|
|
688 |
$length = strlen($match[1]);
|
689 |
$expr = '';
|
690 |
$opened = 0;
|
698 |
break;
|
699 |
}
|
700 |
}
|
701 |
+
$rest = str_replace($expr, '', $match[1]);
|
702 |
+
$expr = trim(substr($expr, 1, -1));
|
703 |
|
704 |
+
$count = count($minifier->extracted);
|
705 |
+
$placeholder = 'calc('.$count.')';
|
706 |
+
$minifier->extracted[$placeholder] = 'calc('.$expr.')';
|
707 |
+
|
708 |
+
return $placeholder.$rest;
|
709 |
+
};
|
710 |
|
711 |
+
$this->registerPattern('/calc(\(.+?)(?=$|;|calc\()/', $callback);
|
712 |
}
|
713 |
|
714 |
/**
|
@@ -195,11 +195,21 @@ class JS extends Minify
|
|
195 |
*/
|
196 |
protected function stripComments()
|
197 |
{
|
198 |
-
//
|
199 |
-
$this
|
|
|
|
|
|
|
|
|
200 |
|
|
|
|
|
201 |
// multi-line comments
|
|
|
202 |
$this->registerPattern('/\/\*.*?\*\//s', '');
|
|
|
|
|
|
|
203 |
}
|
204 |
|
205 |
/**
|
@@ -238,7 +248,7 @@ class JS extends Minify
|
|
238 |
// closing the regex)
|
239 |
// then also ignore bare `/` inside `[]`, where they don't need to be
|
240 |
// escaped: anything inside `[]` can be ignored safely
|
241 |
-
$pattern = '\\/(?:[^\\[\\/\\\\\n\r]
|
242 |
|
243 |
// a regular expression can only be followed by a few operators or some
|
244 |
// of the RegExp methods (a `\` followed by a variable or value is
|
@@ -335,7 +345,9 @@ class JS extends Minify
|
|
335 |
array(
|
336 |
'/('.implode('|', $operatorsBefore).')\s+/',
|
337 |
'/\s+('.implode('|', $operatorsAfter).')/',
|
338 |
-
),
|
|
|
|
|
339 |
);
|
340 |
|
341 |
// make sure + and - can't be mistaken for, or joined into ++ and --
|
@@ -343,7 +355,9 @@ class JS extends Minify
|
|
343 |
array(
|
344 |
'/(?<![\+\-])\s*([\+\-])(?![\+\-])/',
|
345 |
'/(?<![\+\-])([\+\-])\s*(?![\+\-])/',
|
346 |
-
),
|
|
|
|
|
347 |
);
|
348 |
|
349 |
// collapse whitespace around reserved words into single space
|
195 |
*/
|
196 |
protected function stripComments()
|
197 |
{
|
198 |
+
// PHP only supports $this inside anonymous functions since 5.4
|
199 |
+
$minifier = $this;
|
200 |
+
$callback = function ($match) use ($minifier) {
|
201 |
+
$count = count($minifier->extracted);
|
202 |
+
$placeholder = '/*'.$count.'*/';
|
203 |
+
$minifier->extracted[$placeholder] = $match[0];
|
204 |
|
205 |
+
return $placeholder;
|
206 |
+
};
|
207 |
// multi-line comments
|
208 |
+
$this->registerPattern('/\n?\/\*(!|.*?@license|.*?@preserve).*?\*\/\n?/s', $callback);
|
209 |
$this->registerPattern('/\/\*.*?\*\//s', '');
|
210 |
+
|
211 |
+
// single-line comments
|
212 |
+
$this->registerPattern('/\/\/.*$/m', '');
|
213 |
}
|
214 |
|
215 |
/**
|
248 |
// closing the regex)
|
249 |
// then also ignore bare `/` inside `[]`, where they don't need to be
|
250 |
// escaped: anything inside `[]` can be ignored safely
|
251 |
+
$pattern = '\\/(?!\*)(?:[^\\[\\/\\\\\n\r]++|(?:\\\\.)++|(?:\\[(?:[^\\]\\\\\n\r]++|(?:\\\\.)++)++\\])++)++\\/[gimuy]*';
|
252 |
|
253 |
// a regular expression can only be followed by a few operators or some
|
254 |
// of the RegExp methods (a `\` followed by a variable or value is
|
345 |
array(
|
346 |
'/('.implode('|', $operatorsBefore).')\s+/',
|
347 |
'/\s+('.implode('|', $operatorsAfter).')/',
|
348 |
+
),
|
349 |
+
'\\1',
|
350 |
+
$content
|
351 |
);
|
352 |
|
353 |
// make sure + and - can't be mistaken for, or joined into ++ and --
|
355 |
array(
|
356 |
'/(?<![\+\-])\s*([\+\-])(?![\+\-])/',
|
357 |
'/(?<![\+\-])([\+\-])\s*(?![\+\-])/',
|
358 |
+
),
|
359 |
+
'\\1',
|
360 |
+
$content
|
361 |
);
|
362 |
|
363 |
// collapse whitespace around reserved words into single space
|
@@ -241,7 +241,7 @@ abstract class Minify
|
|
241 |
|
242 |
// we can safely ignore patterns for positions we've unset earlier,
|
243 |
// because we know these won't show up anymore
|
244 |
-
if (
|
245 |
continue;
|
246 |
}
|
247 |
|
241 |
|
242 |
// we can safely ignore patterns for positions we've unset earlier,
|
243 |
// because we know these won't show up anymore
|
244 |
+
if (array_key_exists($i, $positions) == false) {
|
245 |
continue;
|
246 |
}
|
247 |
|
@@ -31,16 +31,17 @@ class Converter implements ConverterInterface
|
|
31 |
/**
|
32 |
* @param string $from The original base path (directory, not file!)
|
33 |
* @param string $to The new base path (directory, not file!)
|
|
|
34 |
*/
|
35 |
-
public function __construct($from, $to)
|
36 |
{
|
37 |
$shared = $this->shared($from, $to);
|
38 |
if ($shared === '') {
|
39 |
// when both paths have nothing in common, one of them is probably
|
40 |
// absolute while the other is relative
|
41 |
-
$
|
42 |
-
$from = strpos($from, $
|
43 |
-
$to = strpos($to, $
|
44 |
|
45 |
// or traveling the tree via `..`
|
46 |
// attempt to resolve path, or assume it's fine if it doesn't exist
|
@@ -155,7 +156,7 @@ class Converter implements ConverterInterface
|
|
155 |
$to = mb_substr($this->to, mb_strlen($shared));
|
156 |
|
157 |
// add .. for every directory that needs to be traversed to new path
|
158 |
-
$to = str_repeat('../',
|
159 |
|
160 |
return $to.ltrim($path, '/');
|
161 |
}
|
31 |
/**
|
32 |
* @param string $from The original base path (directory, not file!)
|
33 |
* @param string $to The new base path (directory, not file!)
|
34 |
+
* @param string $root Root directory (defaults to `getcwd`)
|
35 |
*/
|
36 |
+
public function __construct($from, $to, $root = '')
|
37 |
{
|
38 |
$shared = $this->shared($from, $to);
|
39 |
if ($shared === '') {
|
40 |
// when both paths have nothing in common, one of them is probably
|
41 |
// absolute while the other is relative
|
42 |
+
$root = $root ?: getcwd();
|
43 |
+
$from = strpos($from, $root) === 0 ? $from : preg_replace('/\/+/', '/', $root.'/'.$from);
|
44 |
+
$to = strpos($to, $root) === 0 ? $to : preg_replace('/\/+/', '/', $root.'/'.$to);
|
45 |
|
46 |
// or traveling the tree via `..`
|
47 |
// attempt to resolve path, or assume it's fine if it doesn't exist
|
156 |
$to = mb_substr($this->to, mb_strlen($shared));
|
157 |
|
158 |
// add .. for every directory that needs to be traversed to new path
|
159 |
+
$to = str_repeat('../', count(array_filter(explode('/', $to))));
|
160 |
|
161 |
return $to.ltrim($path, '/');
|
162 |
}
|
@@ -2,7 +2,7 @@
|
|
2 |
Contributors: Alignak
|
3 |
Tags: PHP Minify, Lighthouse, GTmetrix, Pingdom, Pagespeed, CSS Merging, JS Merging, CSS Minification, JS Minification, Speed Optimization, HTML Minification, Performance, Optimization, Speed, Fast
|
4 |
Requires at least: 4.5
|
5 |
-
Stable tag: 2.4.
|
6 |
Tested up to: 5.0
|
7 |
License: GPLv3 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
@@ -202,6 +202,16 @@ If you would like to donate any amount to the plugin author (thank you in advanc
|
|
202 |
|
203 |
== Changelog ==
|
204 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
= 2.4.2 [2018.11.29] =
|
206 |
* fixed a bug with the "Exclude JS files in the ignore list from PSI" option (it wasn't excluding properly)
|
207 |
* improved functionality with the "Exclude CSS files from PSI" option (now works with both inline and link stylesheets)
|
2 |
Contributors: Alignak
|
3 |
Tags: PHP Minify, Lighthouse, GTmetrix, Pingdom, Pagespeed, CSS Merging, JS Merging, CSS Minification, JS Minification, Speed Optimization, HTML Minification, Performance, Optimization, Speed, Fast
|
4 |
Requires at least: 4.5
|
5 |
+
Stable tag: 2.4.3
|
6 |
Tested up to: 5.0
|
7 |
License: GPLv3 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
202 |
|
203 |
== Changelog ==
|
204 |
|
205 |
+
= 2.4.3 [2018.12.03] =
|
206 |
+
* added font-display, to ensure text remains visible during webfont load for inlined google fonts and font-awesome
|
207 |
+
* added automatic removal of "source mappings" from JS files during merging or minification
|
208 |
+
* added font awesome async and exclusion from PSI options, as well as merging and inlining when the url matches "font-awesome" (ie: cdnjs)
|
209 |
+
* added automatically inline of small CSS code (up to 20KB) for any FVM CSS files in the footer (requests reduction)
|
210 |
+
* added automatically inline of small CSS code (up to 20KB) for any FVM CSS files in the header, which are not of mediatype "all"
|
211 |
+
* improved the cache purge button (no more redirect from frontend to backend)
|
212 |
+
* updated PHP Minify and Path Converter from master
|
213 |
+
* bug fixes related to "Exclude JS files from PSI" option
|
214 |
+
|
215 |
= 2.4.2 [2018.11.29] =
|
216 |
* fixed a bug with the "Exclude JS files in the ignore list from PSI" option (it wasn't excluding properly)
|
217 |
* improved functionality with the "Exclude CSS files from PSI" option (now works with both inline and link stylesheets)
|