Version Description
[2018.12.03] * added option to inline CSS in the footer, while still preserving the merged file in the header * improvements for the google fonts merging option * fixed double notification, when purging caches without a cache plugin
Download this release
Release Info
Developer | Alignak |
Plugin | Fast Velocity Minify |
Version | 2.4.4 |
Comparing to | |
See all releases |
Code changes from version 2.4.1 to 2.4.4
- fvm.css +3 -1
- fvm.js +51 -127
- fvm.php +552 -121
- inc/functions.php +125 -81
- 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 +25 -1
fvm.css
CHANGED
@@ -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}
|
fvm.js
CHANGED
@@ -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 |
+
});
|
fvm.php
CHANGED
@@ -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 |
------------------------------------------------------------------------
|
@@ -61,7 +61,8 @@ add_action('admin_init', 'fvm_compat_checker');
|
|
61 |
|
62 |
|
63 |
# get plugin version
|
64 |
-
$
|
|
|
65 |
|
66 |
# get the plugin directory
|
67 |
$plugindir = plugin_dir_path( __FILE__ ); # prints with trailing slash
|
@@ -96,6 +97,8 @@ closedir($handle);
|
|
96 |
# default globals
|
97 |
$fastvelocity_min_global_js_done = array();
|
98 |
$fvm_collect_google_fonts = array();
|
|
|
|
|
99 |
$fvm_debug = get_option('fastvelocity_fvm_debug');
|
100 |
|
101 |
###########################################
|
@@ -124,6 +127,7 @@ $fvm_clean_header_one = get_option('fastvelocity_fvm_clean_header_one');
|
|
124 |
$enable_defer_js = get_option('fastvelocity_min_enable_defer_js');
|
125 |
$exclude_defer_jquery = get_option('fastvelocity_min_exclude_defer_jquery');
|
126 |
$force_inline_css = get_option('fastvelocity_min_force_inline_css');
|
|
|
127 |
$remove_googlefonts = get_option('fastvelocity_min_remove_googlefonts');
|
128 |
$defer_for_pagespeed = get_option('fastvelocity_min_defer_for_pagespeed');
|
129 |
$defer_for_pagespeed_optimize = get_option('fastvelocity_min_defer_for_pagespeed_optimize');
|
@@ -132,6 +136,9 @@ $fvm_fix_editor = get_option('fastvelocity_min_fvm_fix_editor');
|
|
132 |
$fvmloadcss = get_option('fastvelocity_min_loadcss');
|
133 |
$fvm_remove_css = get_option('fastvelocity_min_fvm_removecss');
|
134 |
$fvm_cdn_url = get_option('fastvelocity_min_fvm_cdn_url');
|
|
|
|
|
|
|
135 |
|
136 |
# default options
|
137 |
$used_css_files = array();
|
@@ -223,15 +230,14 @@ if(is_admin()) {
|
|
223 |
add_action('template_redirect', 'fastvelocity_min_html_compression_start', PHP_INT_MAX);
|
224 |
}
|
225 |
|
226 |
-
# add the CSS async polyfil
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
# remove query from static assets and process defering (if enabled)
|
232 |
add_filter('style_loader_src', 'fastvelocity_remove_cssjs_ver', 10, 2);
|
233 |
add_filter('script_loader_tag', 'fastvelocity_min_defer_js', 10, 3);
|
234 |
-
add_filter('script_loader_tag', '
|
235 |
|
236 |
}
|
237 |
}
|
@@ -250,7 +256,7 @@ global $fvm_fix_editor, $disable_js_merge, $disable_css_merge, $skip_emoji_remov
|
|
250 |
remove_action('template_redirect', 'fastvelocity_min_html_compression_start', PHP_INT_MAX);
|
251 |
remove_filter('style_loader_src', 'fastvelocity_remove_cssjs_ver', 10, 2);
|
252 |
remove_filter('script_loader_tag', 'fastvelocity_min_defer_js', 10, 3);
|
253 |
-
remove_filter('script_loader_tag', '
|
254 |
}
|
255 |
}
|
256 |
|
@@ -274,7 +280,7 @@ function fastvelocity_admintoolbar() {
|
|
274 |
$wp_admin_bar->add_node(array(
|
275 |
'id' => 'fvm',
|
276 |
'title' => '<span class="ab-icon"></span><span class="ab-label">' . __("FVM Purge",'fvm') . '</span>',
|
277 |
-
'href' =>
|
278 |
));
|
279 |
|
280 |
}
|
@@ -284,10 +290,10 @@ function fastvelocity_admintoolbar() {
|
|
284 |
# function to list all cache files
|
285 |
function fastvelocity_min_files_callback() {
|
286 |
global $cachedir;
|
287 |
-
|
288 |
# default
|
289 |
$size = fastvelocity_get_cachestats();
|
290 |
-
|
291 |
|
292 |
# inspect directory with opendir, since glob might not be available in some systems
|
293 |
clearstatcache();
|
@@ -295,27 +301,24 @@ function fastvelocity_min_files_callback() {
|
|
295 |
while (false !== ($file = readdir($handle))) {
|
296 |
$file = $cachedir.'/'.$file;
|
297 |
$ext = pathinfo($file, PATHINFO_EXTENSION);
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
$fsize = fastvelocity_format_filesize(filesize($file));
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
$hash = $info['1'];
|
310 |
-
array_push($return[$ext], array('hash' => $hash, 'filename' => $filename, 'log' => $log, 'fsize' => $fsize));
|
311 |
-
}
|
312 |
}
|
313 |
closedir($handle);
|
314 |
}
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
}
|
320 |
|
321 |
|
@@ -348,8 +351,10 @@ function fastvelocity_min_register_settings() {
|
|
348 |
register_setting('fvm-group', 'fastvelocity_min_enable_defer_js');
|
349 |
register_setting('fvm-group', 'fastvelocity_min_exclude_defer_jquery');
|
350 |
register_setting('fvm-group', 'fastvelocity_min_force_inline_css');
|
|
|
351 |
register_setting('fvm-group', 'fastvelocity_min_remove_googlefonts');
|
352 |
register_setting('fvm-group', 'fastvelocity_gfonts_method');
|
|
|
353 |
register_setting('fvm-group', 'fastvelocity_min_defer_for_pagespeed');
|
354 |
register_setting('fvm-group', 'fastvelocity_min_defer_for_pagespeed_optimize');
|
355 |
register_setting('fvm-group', 'fastvelocity_min_exclude_defer_login');
|
@@ -369,6 +374,8 @@ function fastvelocity_min_register_settings() {
|
|
369 |
|
370 |
# dev tab
|
371 |
register_setting('fvm-group-dev', 'fastvelocity_fvm_debug');
|
|
|
|
|
372 |
register_setting('fvm-group-dev', 'fastvelocity_min_hpreload');
|
373 |
register_setting('fvm-group-dev', 'fastvelocity_min_hpreconnect');
|
374 |
register_setting('fvm-group-dev', 'fastvelocity_min_loadcss');
|
@@ -393,6 +400,63 @@ return $links;
|
|
393 |
add_filter("plugin_action_links_".plugin_basename(__FILE__), 'fastvelocity_min_settings_link' );
|
394 |
|
395 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
396 |
|
397 |
# manage settings page
|
398 |
function fastvelocity_min_settings() {
|
@@ -408,19 +472,6 @@ $active_tab = isset($_GET['tab']) ? $_GET['tab'] : 'status';
|
|
408 |
<div class="wrap">
|
409 |
<h1>Fast Velocity Minify</h1>
|
410 |
|
411 |
-
<?php
|
412 |
-
|
413 |
-
# purge all caches
|
414 |
-
if(isset($_GET['page']) && $_GET['page'] == 'fastvelocity-min') {
|
415 |
-
if((isset($_POST['purgeall']) && $_POST['purgeall'] == 1) || isset($_GET['fvm_flush']) && $_GET['fvm_flush'] == 1) {
|
416 |
-
fvm_purge_all(); # purge all
|
417 |
-
echo __('<div class="notice notice-success is-dismissible"><p>All caches from <strong>FVM</strong> have been purged!</p></div>');
|
418 |
-
echo fastvelocity_purge_others(); # purge third party caches
|
419 |
-
}
|
420 |
-
}
|
421 |
-
|
422 |
-
?>
|
423 |
-
|
424 |
<h2 class="nav-tab-wrapper wp-clearfix">
|
425 |
<a href="?page=fastvelocity-min&tab=status" class="nav-tab <?php echo $active_tab == 'status' ? 'nav-tab-active' : ''; ?>">Status</a>
|
426 |
<a href="?page=fastvelocity-min&tab=set" class="nav-tab <?php echo $active_tab == 'set' ? 'nav-tab-active' : ''; ?>">Settings</a>
|
@@ -565,7 +616,7 @@ Cleanup Header <span class="note-info">[ Remove resource hints, generator tag, s
|
|
565 |
|
566 |
|
567 |
<tr>
|
568 |
-
<th scope="row">
|
569 |
<td>
|
570 |
<p class="fvm-bold-green fvm-rowintro">The default options are usually good for performance.</p>
|
571 |
<fieldset>
|
@@ -598,15 +649,35 @@ $a = ''; if($sel == 1 || empty($sel)) { $a = ' checked="checked"'; }
|
|
598 |
$b = ''; if($sel == 2) { $b = ' checked="checked"'; }
|
599 |
$c = ''; if($sel == 3) { $c = ' checked="checked"'; }
|
600 |
?>
|
601 |
-
<p class="fvm-bold-green fvm-rowintro">Choose how to include
|
602 |
<fieldset>
|
603 |
-
<label><input type="radio" name="fastvelocity_gfonts_method" value="1" <?php echo $a; ?>> Inline Google Fonts CSS</label> <span class="note-info">[ Will inline
|
604 |
<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>
|
605 |
-
<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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
606 |
</fieldset>
|
607 |
</td>
|
608 |
</tr>
|
609 |
|
|
|
610 |
<tr>
|
611 |
<th scope="row">CSS Options</th>
|
612 |
<td>
|
@@ -629,9 +700,13 @@ Preserve the order of CSS files <span class="note-info">[ If selected, you will
|
|
629 |
<input name="fastvelocity_min_remove_print_mediatypes" type="checkbox" id="fastvelocity_min_remove_print_mediatypes" value="1" <?php echo checked(1 == get_option('fastvelocity_min_remove_print_mediatypes'), true, false); ?> >
|
630 |
Remove the "Print" related stylesheets <span class="note-info">[ If selected, CSS files of mediatype "print" will be removed from the site ]</span></label>
|
631 |
<br />
|
|
|
|
|
|
|
|
|
632 |
<label for="fastvelocity_min_force_inline_css">
|
633 |
<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); ?>>
|
634 |
-
Inline all CSS files <span class="note-info">[ If selected,
|
635 |
<br />
|
636 |
</fieldset></td>
|
637 |
</tr>
|
@@ -640,7 +715,7 @@ Inline all CSS files <span class="note-info">[ If selected, CSS will be inlined
|
|
640 |
<tr>
|
641 |
<th scope="row">JavaScript Options</th>
|
642 |
<td>
|
643 |
-
<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>
|
644 |
<fieldset>
|
645 |
<label for="fastvelocity_min_disable_js_merge">
|
646 |
<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); ?> >
|
@@ -765,7 +840,8 @@ I know what I'm doing... <span class="note-info">[ Load my JS files from the CDN
|
|
765 |
|
766 |
<div style="height: 20px;"></div>
|
767 |
<h2 class="title">Special JS and CSS Exceptions</h2>
|
768 |
-
<p class="fvm-bold-green">You can use this section to edit or change our default exclusions, as well as to add your own.<br />
|
|
|
769 |
|
770 |
<div style="height: 20px;"></div>
|
771 |
<table class="form-table fvm-settings">
|
@@ -807,7 +883,7 @@ I know what I'm doing... <span class="note-info">[ Load my JS files from the CDN
|
|
807 |
<p>
|
808 |
<textarea name="fastvelocity_min_excludejslist" rows="7" cols="50" id="fastvelocity_min_excludejslist" class="large-text code" placeholder="ex: /pixelyoursite/js/public.js"><?php echo get_option('fastvelocity_min_excludejslist'); ?></textarea>
|
809 |
</p>
|
810 |
-
<p class="description">[ Any JS file that can load Async and
|
811 |
|
812 |
</fieldset></td>
|
813 |
</tr>
|
@@ -823,8 +899,7 @@ I know what I'm doing... <span class="note-info">[ Load my JS files from the CDN
|
|
823 |
<p>
|
824 |
<textarea name="fastvelocity_min_excludecsslist" rows="7" cols="50" id="fastvelocity_min_excludecsslist" class="large-text code" placeholder="ex: /wp-content/themes/my-theme/css/fontawesome.css"><?php echo get_option('fastvelocity_min_excludecsslist'); ?></textarea>
|
825 |
</p>
|
826 |
-
<p class="description">[ Any CSS file that can load
|
827 |
-
<p class="description">[ Note: Under development, currently only works when "Inline all CSS files" is enabled ]</p>
|
828 |
|
829 |
</fieldset></td>
|
830 |
</tr>
|
@@ -876,26 +951,40 @@ if( $active_tab == 'dev' ) { ?>
|
|
876 |
<?php settings_fields('fvm-group-dev'); do_settings_sections('fvm-group-dev'); ?>
|
877 |
|
878 |
<div style="height: 20px;"></div>
|
879 |
-
<h2 class="title">
|
880 |
-
<p class="fvm-bold-green">This
|
|
|
881 |
|
882 |
<table class="form-table fvm-settings">
|
883 |
<tbody>
|
884 |
<tr>
|
885 |
-
<th scope="row">
|
886 |
<td><fieldset>
|
887 |
<label for="fastvelocity_fvm_debug">
|
888 |
<input name="fastvelocity_fvm_debug" type="checkbox" id="fastvelocity_fvm_debug" value="1" <?php echo checked(1 == get_option('fastvelocity_fvm_debug'), true, false); ?>>
|
889 |
-
Enable FVM Debug Mode<span class="note-info">[ Add
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
890 |
|
891 |
</fieldset>
|
892 |
</td>
|
893 |
</tr>
|
894 |
-
|
895 |
</tbody></table>
|
896 |
|
897 |
|
898 |
|
|
|
|
|
|
|
899 |
<div style="height: 20px;"></div>
|
900 |
<h2 class="title">HTTP Headers</h2>
|
901 |
<p class="fvm-bold-green">Preconnect Headers: This will add link headers to your http response to instruct the browser to preconnect to other domains (ex: fonts, images, videos, etc)</p>
|
@@ -1081,7 +1170,7 @@ if( $active_tab == 'help' ) { ?>
|
|
1081 |
# process header javascript ###############
|
1082 |
###########################################
|
1083 |
function fastvelocity_min_merge_header_scripts() {
|
1084 |
-
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;
|
1085 |
if(!is_object($wp_scripts)) { return false; }
|
1086 |
$scripts = wp_clone($wp_scripts);
|
1087 |
$scripts->all_deps($scripts->queue);
|
@@ -1106,6 +1195,24 @@ $is_footer = 0; if (isset($wp_scripts->registered[$handle]->extra["group"]) || i
|
|
1106 |
# get full url
|
1107 |
$hurl = fastvelocity_min_get_hurl($wp_scripts->registered[$handle]->src, $wp_domain, $wp_home);
|
1108 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1109 |
# IE only files don't increment things
|
1110 |
$ieonly = fastvelocity_ie_blacklist($hurl);
|
1111 |
if($ieonly == true) { continue; }
|
@@ -1221,8 +1328,7 @@ for($i=0,$l=count($header);$i<$l;$i++) {
|
|
1221 |
if(count($data) > 0) { $wp_scripts->registered["fvm-header-$i"]->extra['data'] = implode(PHP_EOL, $data); }
|
1222 |
|
1223 |
# enqueue file, if not empty
|
1224 |
-
$
|
1225 |
-
if(file_exists($file) && (!empty($check) || count($data) > 0)) {
|
1226 |
wp_enqueue_script("fvm-header-$i");
|
1227 |
}
|
1228 |
|
@@ -1244,7 +1350,7 @@ $wp_scripts->done = $done;
|
|
1244 |
# process js in the footer ################
|
1245 |
###########################################
|
1246 |
function fastvelocity_min_merge_footer_scripts() {
|
1247 |
-
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;
|
1248 |
if(!is_object($wp_scripts)) { return false; }
|
1249 |
$ctime = get_option('fvm-last-cache-update', '0');
|
1250 |
$scripts = wp_clone($wp_scripts);
|
@@ -1264,6 +1370,24 @@ foreach( $scripts->to_do as $handle ) :
|
|
1264 |
# get full url
|
1265 |
$hurl = fastvelocity_min_get_hurl($wp_scripts->registered[$handle]->src, $wp_domain, $wp_home);
|
1266 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1267 |
# IE only files don't increment things
|
1268 |
$ieonly = fastvelocity_ie_blacklist($hurl);
|
1269 |
if($ieonly == true) { continue; }
|
@@ -1370,8 +1494,7 @@ for($i=0,$l=count($footer);$i<$l;$i++) {
|
|
1370 |
if(count($data) > 0) { $wp_scripts->registered["fvm-footer-$i"]->extra['data'] = implode(PHP_EOL, $data); }
|
1371 |
|
1372 |
# enqueue file, if not empty
|
1373 |
-
$
|
1374 |
-
if(file_exists($file) && (!empty($check) || count($data) > 0)) {
|
1375 |
wp_enqueue_script("fvm-footer-$i");
|
1376 |
}
|
1377 |
|
@@ -1434,11 +1557,13 @@ if($enable_defer_js == true) { return $tagdefer; }
|
|
1434 |
# return if no defer, and there's no defer for pagespeed... else pagespeed processing
|
1435 |
if ($defer_for_pagespeed != true) { return $tag; } else {
|
1436 |
|
|
|
|
|
|
|
1437 |
# return if external script url https://www.chromestatus.com/feature/5718547946799104
|
1438 |
if (fvm_is_local_domain($src) !== true) { return $tag; }
|
1439 |
|
1440 |
-
|
1441 |
-
if (stripos($tag, PHP_EOL) !== false) { return $tag; }
|
1442 |
|
1443 |
# print code if there are no linebreaks, or return
|
1444 |
if(!empty($tagdefer)) {
|
@@ -1459,7 +1584,7 @@ return $tag;
|
|
1459 |
# process header css ######################
|
1460 |
###########################################
|
1461 |
function fastvelocity_min_merge_header_css() {
|
1462 |
-
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;
|
1463 |
if(!is_object($wp_styles)) { return false; }
|
1464 |
$ctime = get_option('fvm-last-cache-update', '0');
|
1465 |
$styles = wp_clone($wp_styles);
|
@@ -1494,8 +1619,9 @@ foreach( $styles->to_do as $handle):
|
|
1494 |
}
|
1495 |
|
1496 |
# mediatype
|
1497 |
-
$
|
1498 |
-
if ($
|
|
|
1499 |
|
1500 |
# full url or empty
|
1501 |
$hurl = fastvelocity_min_get_hurl($wp_styles->registered[$handle]->src, $wp_domain, $wp_home);
|
@@ -1506,6 +1632,32 @@ foreach( $styles->to_do as $handle):
|
|
1506 |
if (isset($uniq[$key])) { $done = array_merge($done, array($handle)); continue; } else { $uniq[$key] = $handle; }
|
1507 |
}
|
1508 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1509 |
# array of info to save
|
1510 |
$arr = array('handle'=>$handle, 'url'=>$hurl, 'conditional'=>$conditional, 'mediatype'=>$mediatype);
|
1511 |
|
@@ -1581,6 +1733,12 @@ if(!$skip_google_fonts && count($google_fonts) > 0 || ($force_inline_googlefonts
|
|
1581 |
|
1582 |
# inline css or fail
|
1583 |
if($res['code'] !== false) {
|
|
|
|
|
|
|
|
|
|
|
|
|
1584 |
echo '<style type="text/css" media="all">'.$res['code'].'</style>'.PHP_EOL;
|
1585 |
} else {
|
1586 |
echo "<!-- GOOGLE FONTS REQUEST FAILED for $gfurl -->\n";
|
@@ -1614,8 +1772,10 @@ $mediatype = $process[$handle]['mediatype'];
|
|
1614 |
$ieonly = fastvelocity_ie_blacklist($hurl);
|
1615 |
if($ieonly == true) { continue; }
|
1616 |
|
1617 |
-
# skip ignore list, conditional css, external css
|
1618 |
-
if ((!fastvelocity_min_in_arrayi($hurl, $ignore) && !isset($conditional) && fvm_internal_url($hurl, $wp_home))
|
|
|
|
|
1619 |
|
1620 |
# colect inline css for this handle
|
1621 |
if(isset($wp_styles->registered[$handle]->extra['after']) && is_array($wp_styles->registered[$handle]->extra['after'])) {
|
@@ -1639,7 +1799,6 @@ $mediatype = $process[$handle]['mediatype'];
|
|
1639 |
}
|
1640 |
endforeach;
|
1641 |
|
1642 |
-
|
1643 |
# reorder CSS by mediatypes
|
1644 |
if(!$skip_cssorder) {
|
1645 |
if(count($header) > 0) {
|
@@ -1649,12 +1808,12 @@ if(!$skip_cssorder) {
|
|
1649 |
foreach($header as $array) {
|
1650 |
if(isset($array['media'])) { $allmedia[$array['media']] = ''; }
|
1651 |
}
|
1652 |
-
|
1653 |
# extract handles by mediatype
|
1654 |
$grouphandles = array();
|
1655 |
foreach ($allmedia as $md=>$var) {
|
1656 |
foreach($header as $array) {
|
1657 |
-
if (isset($array['media']) && $array['media']
|
1658 |
foreach($array['handles'] as $h) { $grouphandles[$md][] = $h; }
|
1659 |
}
|
1660 |
}
|
@@ -1758,10 +1917,16 @@ for($i=0,$l=count($header);$i<$l;$i++) {
|
|
1758 |
|
1759 |
# enqueue file, if not empty
|
1760 |
} else {
|
1761 |
-
$
|
1762 |
-
|
1763 |
-
|
1764 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1765 |
}
|
1766 |
}
|
1767 |
}
|
@@ -1784,7 +1949,7 @@ $wp_styles->done = $done;
|
|
1784 |
# process css in the footer ###############
|
1785 |
###########################################
|
1786 |
function fastvelocity_min_merge_footer_css() {
|
1787 |
-
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;
|
1788 |
|
1789 |
if(!is_object($wp_styles)) { return false; }
|
1790 |
$ctime = get_option('fvm-last-cache-update', '0');
|
@@ -1812,8 +1977,10 @@ $ignore = fastvelocity_default_ignore($ignore);
|
|
1812 |
|
1813 |
# google fonts to the top
|
1814 |
foreach( $styles->to_do as $handle ) :
|
|
|
1815 |
# dequeue and get a list of google fonts, or requeue external
|
1816 |
$hurl = fastvelocity_min_get_hurl($wp_styles->registered[$handle]->src, $wp_domain, $wp_home);
|
|
|
1817 |
if (stripos($hurl, 'fonts.googleapis.com') !== false) {
|
1818 |
wp_dequeue_style($handle);
|
1819 |
if($remove_googlefonts != false) { $done = array_merge($done, array($handle)); continue; } # mark as done if to be removed
|
@@ -1825,6 +1992,7 @@ foreach( $styles->to_do as $handle ) :
|
|
1825 |
} else {
|
1826 |
wp_dequeue_style($handle); wp_enqueue_style($handle); # failsafe
|
1827 |
}
|
|
|
1828 |
endforeach;
|
1829 |
|
1830 |
|
@@ -1902,28 +2070,66 @@ if(!$skip_google_fonts && count($google_fonts) > 0 || ($force_inline_googlefonts
|
|
1902 |
|
1903 |
|
1904 |
# get groups of handles
|
|
|
1905 |
foreach( $styles->to_do as $handle ) :
|
1906 |
|
1907 |
# skip already processed google fonts
|
1908 |
if(isset($google_fonts[$handle])) { continue; }
|
1909 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1910 |
# get full url
|
1911 |
$hurl = fastvelocity_min_get_hurl($wp_styles->registered[$handle]->src, $wp_domain, $wp_home);
|
1912 |
-
|
1913 |
-
#
|
1914 |
-
|
|
|
|
|
|
|
1915 |
|
1916 |
# IE only files don't increment things
|
1917 |
$ieonly = fastvelocity_ie_blacklist($hurl);
|
1918 |
if($ieonly == true) { continue; }
|
1919 |
|
1920 |
-
|
1921 |
-
|
1922 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1923 |
}
|
1924 |
|
1925 |
-
# skip ignore list, conditional css, external css
|
1926 |
-
if ((!fastvelocity_min_in_arrayi($hurl, $ignore) && !isset($conditional) && fvm_internal_url($hurl, $wp_home))
|
|
|
|
|
1927 |
|
1928 |
# colect inline css for this handle
|
1929 |
if(isset($wp_styles->registered[$handle]->extra['after']) && is_array($wp_styles->registered[$handle]->extra['after'])) {
|
@@ -1933,7 +2139,7 @@ foreach( $styles->to_do as $handle ) :
|
|
1933 |
|
1934 |
# process
|
1935 |
if(isset($footer[count($footer)-1]['handle']) || count($footer) == 0 || $footer[count($footer)-1]['media'] != $wp_styles->registered[$handle]->args) {
|
1936 |
-
array_push($footer, array('handles'=>array(),'media'=>$
|
1937 |
}
|
1938 |
|
1939 |
# push it to the array get latest modified time
|
@@ -1962,7 +2168,7 @@ if(!$skip_cssorder) {
|
|
1962 |
$grouphandles = array();
|
1963 |
foreach ($allmedia as $md=>$var) {
|
1964 |
foreach($footer as $array) {
|
1965 |
-
if (isset($array['media']) && $array['media']
|
1966 |
foreach($array['handles'] as $h) { $grouphandles[$md][] = $h; }
|
1967 |
}
|
1968 |
}
|
@@ -2053,7 +2259,7 @@ for($i=0,$l=count($footer);$i<$l;$i++) {
|
|
2053 |
}
|
2054 |
|
2055 |
# register and enqueue minified file, consider excluding of mediatype "print" and inline css
|
2056 |
-
if ($remove_print_mediatypes != true || ($remove_print_mediatypes == true && $
|
2057 |
|
2058 |
# the developers tab, takes precedence
|
2059 |
|
@@ -2066,10 +2272,15 @@ for($i=0,$l=count($footer);$i<$l;$i++) {
|
|
2066 |
|
2067 |
# enqueue file, if not empty
|
2068 |
} else {
|
2069 |
-
$
|
2070 |
-
|
2071 |
-
|
2072 |
-
|
|
|
|
|
|
|
|
|
|
|
2073 |
}
|
2074 |
}
|
2075 |
}
|
@@ -2103,6 +2314,14 @@ EOF;
|
|
2103 |
|
2104 |
}
|
2105 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2106 |
|
2107 |
|
2108 |
|
@@ -2156,15 +2375,26 @@ if(is_array($preconnect) && count($preconnect) > 0) {
|
|
2156 |
}
|
2157 |
}
|
2158 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2159 |
}
|
2160 |
|
2161 |
|
2162 |
|
2163 |
###########################################
|
2164 |
-
# optimize the ignore list for pagespeed insights
|
2165 |
###########################################
|
2166 |
-
function
|
2167 |
-
global $
|
2168 |
|
2169 |
# return if there are linebreaks (will break document.write)
|
2170 |
if (stripos($tag, PHP_EOL) !== false) { return $tag; }
|
@@ -2172,21 +2402,35 @@ if (stripos($tag, PHP_EOL) !== false) { return $tag; }
|
|
2172 |
# fix page editors
|
2173 |
if($fvm_fix_editor == true && is_user_logged_in()) { return $tag; }
|
2174 |
|
2175 |
-
# return if
|
2176 |
-
if($
|
2177 |
-
|
|
|
|
|
|
|
2178 |
}
|
2179 |
|
2180 |
-
#
|
2181 |
-
|
2182 |
-
|
2183 |
-
|
2184 |
-
|
2185 |
-
|
2186 |
-
|
2187 |
-
|
2188 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2189 |
}
|
|
|
2190 |
}
|
2191 |
|
2192 |
# fallback
|
@@ -2194,17 +2438,9 @@ return $tag;
|
|
2194 |
}
|
2195 |
|
2196 |
|
2197 |
-
|
2198 |
-
|
2199 |
-
|
2200 |
-
|
2201 |
-
|
2202 |
-
|
2203 |
-
|
2204 |
-
|
2205 |
# inline css in place, instead of inlining the large file
|
2206 |
function fastvelocity_optimizecss($html, $handle, $href, $media){
|
2207 |
-
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;
|
2208 |
|
2209 |
# current timestamp
|
2210 |
$ctime = get_option('fvm-last-cache-update', '0');
|
@@ -2236,7 +2472,7 @@ function fastvelocity_optimizecss($html, $handle, $href, $media){
|
|
2236 |
}
|
2237 |
|
2238 |
# mediatype fix for some plugins + remove print mediatypes
|
2239 |
-
if ($media == 'screen' || $media == 'screen, print') { $media = 'all'; }
|
2240 |
if($remove_print_mediatypes != false && $media == 'print') {
|
2241 |
return false;
|
2242 |
}
|
@@ -2261,7 +2497,6 @@ function fastvelocity_optimizecss($html, $handle, $href, $media){
|
|
2261 |
return false;
|
2262 |
}
|
2263 |
|
2264 |
-
|
2265 |
# handle google fonts here, when merging is disabled
|
2266 |
if(stripos($href, 'fonts.googleapis.com') !== false && $skip_google_fonts != false) {
|
2267 |
|
@@ -2283,6 +2518,52 @@ function fastvelocity_optimizecss($html, $handle, $href, $media){
|
|
2283 |
}
|
2284 |
}
|
2285 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2286 |
# inline google fonts, do not collect
|
2287 |
if(stripos($href, 'fonts.googleapis.com') !== false && $force_inline_googlefonts != false && $css_hide_googlefonts != true && $min_async_googlefonts != true) {
|
2288 |
|
@@ -2298,6 +2579,10 @@ function fastvelocity_optimizecss($html, $handle, $href, $media){
|
|
2298 |
# decode
|
2299 |
$res = json_decode($json, true);
|
2300 |
|
|
|
|
|
|
|
|
|
2301 |
# inline css or fail
|
2302 |
if($res['status'] != false) {
|
2303 |
echo '<style type="text/css" media="all">'.$res['code'].'</style>'.PHP_EOL;
|
@@ -2314,7 +2599,6 @@ function fastvelocity_optimizecss($html, $handle, $href, $media){
|
|
2314 |
return false;
|
2315 |
}
|
2316 |
|
2317 |
-
|
2318 |
# skip external scripts that are not specifically allowed
|
2319 |
if (fvm_internal_url($href, $wp_home) === false || empty($href)) {
|
2320 |
if($fvm_debug == true) { echo "<!-- FVM DEBUG: Skipped the next external enqueued CSS -->" . PHP_EOL; }
|
@@ -2422,3 +2706,150 @@ function fastvelocity_add_google_fonts_merged() {
|
|
2422 |
|
2423 |
}
|
2424 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.4
|
9 |
License: GPL2
|
10 |
|
11 |
------------------------------------------------------------------------
|
61 |
|
62 |
|
63 |
# get plugin version
|
64 |
+
$fastvelocity_plugin_version_get_data = get_file_data(__FILE__, array('Version' => 'Version'), false);
|
65 |
+
$fastvelocity_plugin_version = $fastvelocity_plugin_version_get_data['Version'];
|
66 |
|
67 |
# get the plugin directory
|
68 |
$plugindir = plugin_dir_path( __FILE__ ); # prints with trailing slash
|
97 |
# default globals
|
98 |
$fastvelocity_min_global_js_done = array();
|
99 |
$fvm_collect_google_fonts = array();
|
100 |
+
$collect_preload_css = array();
|
101 |
+
$collect_preload_js = array();
|
102 |
$fvm_debug = get_option('fastvelocity_fvm_debug');
|
103 |
|
104 |
###########################################
|
127 |
$enable_defer_js = get_option('fastvelocity_min_enable_defer_js');
|
128 |
$exclude_defer_jquery = get_option('fastvelocity_min_exclude_defer_jquery');
|
129 |
$force_inline_css = get_option('fastvelocity_min_force_inline_css');
|
130 |
+
$force_inline_css_footer = get_option('fastvelocity_min_force_inline_css_footer');
|
131 |
$remove_googlefonts = get_option('fastvelocity_min_remove_googlefonts');
|
132 |
$defer_for_pagespeed = get_option('fastvelocity_min_defer_for_pagespeed');
|
133 |
$defer_for_pagespeed_optimize = get_option('fastvelocity_min_defer_for_pagespeed_optimize');
|
136 |
$fvmloadcss = get_option('fastvelocity_min_loadcss');
|
137 |
$fvm_remove_css = get_option('fastvelocity_min_fvm_removecss');
|
138 |
$fvm_cdn_url = get_option('fastvelocity_min_fvm_cdn_url');
|
139 |
+
$fvm_enabled_css_preload = get_option('fastvelocity_enabled_css_preload');
|
140 |
+
$fvm_enabled_js_preload = get_option('fastvelocity_enabled_css_preload');
|
141 |
+
$fvm_fawesome_method = get_option("fastvelocity_fontawesome_method");
|
142 |
|
143 |
# default options
|
144 |
$used_css_files = array();
|
230 |
add_action('template_redirect', 'fastvelocity_min_html_compression_start', PHP_INT_MAX);
|
231 |
}
|
232 |
|
233 |
+
# add the CSS async polyfil + LoadAsync JavaScript functions
|
234 |
+
add_action('wp_footer', 'fvm_add_loadcss', PHP_INT_MAX);
|
235 |
+
add_action('wp_head', 'fvm_add_loadasync', 0);
|
236 |
+
|
|
|
237 |
# remove query from static assets and process defering (if enabled)
|
238 |
add_filter('style_loader_src', 'fastvelocity_remove_cssjs_ver', 10, 2);
|
239 |
add_filter('script_loader_tag', 'fastvelocity_min_defer_js', 10, 3);
|
240 |
+
add_filter('script_loader_tag', 'fastvelocity_min_defer_js_optimize', PHP_INT_MAX, 3);
|
241 |
|
242 |
}
|
243 |
}
|
256 |
remove_action('template_redirect', 'fastvelocity_min_html_compression_start', PHP_INT_MAX);
|
257 |
remove_filter('style_loader_src', 'fastvelocity_remove_cssjs_ver', 10, 2);
|
258 |
remove_filter('script_loader_tag', 'fastvelocity_min_defer_js', 10, 3);
|
259 |
+
remove_filter('script_loader_tag', 'fastvelocity_min_defer_js_optimize', 10, 3);
|
260 |
}
|
261 |
}
|
262 |
|
280 |
$wp_admin_bar->add_node(array(
|
281 |
'id' => 'fvm',
|
282 |
'title' => '<span class="ab-icon"></span><span class="ab-label">' . __("FVM Purge",'fvm') . '</span>',
|
283 |
+
'href' => wp_nonce_url( add_query_arg('_fvmcache', 'clear'), 'fvm_clear_nonce')
|
284 |
));
|
285 |
|
286 |
}
|
290 |
# function to list all cache files
|
291 |
function fastvelocity_min_files_callback() {
|
292 |
global $cachedir;
|
293 |
+
|
294 |
# default
|
295 |
$size = fastvelocity_get_cachestats();
|
296 |
+
$return = array('js' => array(), 'css' => array(), 'stamp' => $_POST['stamp'], 'cachesize'=> $size);
|
297 |
|
298 |
# inspect directory with opendir, since glob might not be available in some systems
|
299 |
clearstatcache();
|
301 |
while (false !== ($file = readdir($handle))) {
|
302 |
$file = $cachedir.'/'.$file;
|
303 |
$ext = pathinfo($file, PATHINFO_EXTENSION);
|
304 |
+
if (in_array($ext, array('js', 'css'))) {
|
305 |
+
$log = file_get_contents($file.'.txt');
|
306 |
+
$mincss = substr($file, 0, -4).'.min.css';
|
307 |
+
$minjs = substr($file, 0, -3).'.min.js';
|
308 |
+
$filename = basename($file);
|
309 |
+
if ($ext == 'css' && file_exists($mincss)) { $filename = basename($mincss); }
|
310 |
+
if ($ext == 'js' && file_exists($minjs)) { $filename = basename($minjs); }
|
311 |
$fsize = fastvelocity_format_filesize(filesize($file));
|
312 |
+
$uid = hash('adler32', $filename);
|
313 |
+
array_push($return[$ext], array('uid'=>$uid, 'filename' => $filename, 'log' => $log, 'fsize' => $fsize));
|
314 |
+
}
|
|
|
|
|
|
|
315 |
}
|
316 |
closedir($handle);
|
317 |
}
|
318 |
+
|
319 |
+
header('Content-Type: application/json');
|
320 |
+
echo json_encode($return);
|
321 |
+
wp_die();
|
322 |
}
|
323 |
|
324 |
|
351 |
register_setting('fvm-group', 'fastvelocity_min_enable_defer_js');
|
352 |
register_setting('fvm-group', 'fastvelocity_min_exclude_defer_jquery');
|
353 |
register_setting('fvm-group', 'fastvelocity_min_force_inline_css');
|
354 |
+
register_setting('fvm-group', 'fastvelocity_min_force_inline_css_footer');
|
355 |
register_setting('fvm-group', 'fastvelocity_min_remove_googlefonts');
|
356 |
register_setting('fvm-group', 'fastvelocity_gfonts_method');
|
357 |
+
register_setting('fvm-group', 'fastvelocity_fontawesome_method');
|
358 |
register_setting('fvm-group', 'fastvelocity_min_defer_for_pagespeed');
|
359 |
register_setting('fvm-group', 'fastvelocity_min_defer_for_pagespeed_optimize');
|
360 |
register_setting('fvm-group', 'fastvelocity_min_exclude_defer_login');
|
374 |
|
375 |
# dev tab
|
376 |
register_setting('fvm-group-dev', 'fastvelocity_fvm_debug');
|
377 |
+
register_setting('fvm-group-dev', 'fastvelocity_enabled_css_preload');
|
378 |
+
register_setting('fvm-group-dev', 'fastvelocity_enabled_js_preload');
|
379 |
register_setting('fvm-group-dev', 'fastvelocity_min_hpreload');
|
380 |
register_setting('fvm-group-dev', 'fastvelocity_min_hpreconnect');
|
381 |
register_setting('fvm-group-dev', 'fastvelocity_min_loadcss');
|
400 |
add_filter("plugin_action_links_".plugin_basename(__FILE__), 'fastvelocity_min_settings_link' );
|
401 |
|
402 |
|
403 |
+
# purge all caches by request
|
404 |
+
add_action('init','fastvelocity_process_cache_purge_request');
|
405 |
+
function fastvelocity_process_cache_purge_request(){
|
406 |
+
if((isset($_POST['purgeall']) && $_POST['purgeall'] == 1) || isset($_GET['_fvmcache'])) {
|
407 |
+
|
408 |
+
# must be able to cleanup cache
|
409 |
+
if (!current_user_can('manage_options')) { wp_die( __('You do not have sufficient permissions to access this page.')); }
|
410 |
+
|
411 |
+
# validate nonce
|
412 |
+
if(isset($_GET['wordpress_fvmcache']) && (empty($_GET['_wpnonce']) || !wp_verify_nonce($_GET['_wpnonce'], 'fvm_clear_nonce'))) {
|
413 |
+
wp_die( __('Invalid or expired request... please go back and refresh before trying again!'));
|
414 |
+
}
|
415 |
+
|
416 |
+
if(is_admin()) {
|
417 |
+
fvm_purge_all(); # purge all
|
418 |
+
fastvelocity_purge_others(); # purge third party caches
|
419 |
+
$others = fastvelocity_purge_others(); # purge third party caches
|
420 |
+
$notice = array('All caches from <strong>FVM</strong> have been purged!', strip_tags($others, '<strong>'));
|
421 |
+
$notice = array_filter($notice);
|
422 |
+
$notice = base64_encode(json_encode($notice)); # encode
|
423 |
+
setcookie('wordpress_fvmcache', $notice, time()+60, COOKIEPATH, COOKIE_DOMAIN );
|
424 |
+
wp_safe_redirect(remove_query_arg('_wpnonce', remove_query_arg('_fvmcache', wp_get_referer())));
|
425 |
+
} else {
|
426 |
+
fvm_purge_all(); # purge all
|
427 |
+
fastvelocity_purge_others(); # purge third party caches
|
428 |
+
wp_safe_redirect(remove_query_arg('_wpnonce', remove_query_arg('_fvmcache', wp_get_referer())));
|
429 |
+
}
|
430 |
+
}
|
431 |
+
}
|
432 |
+
|
433 |
+
# print admin notices after purging caches, if on wp-admin
|
434 |
+
add_action( 'admin_notices', 'fastvelocity_admin_notices' );
|
435 |
+
function fastvelocity_admin_notices() {
|
436 |
+
|
437 |
+
# cache purge notices
|
438 |
+
if(isset($_COOKIE['wordpress_fvmcache']) && !empty($_COOKIE['wordpress_fvmcache'])) {
|
439 |
+
|
440 |
+
# decode to array or null
|
441 |
+
$jsonarr = json_decode(base64_decode($_COOKIE['wordpress_fvmcache']), true);
|
442 |
+
if(!is_null($jsonarr) && is_array($jsonarr)){
|
443 |
+
|
444 |
+
# must be able to cleanup cache
|
445 |
+
if (!current_user_can('manage_options')) { wp_die( __('You do not have sufficient permissions to access this page.')); }
|
446 |
+
|
447 |
+
# print notices
|
448 |
+
foreach ($jsonarr as $notice) {
|
449 |
+
echo __('<div class="notice notice-success is-dismissible"><p>'.$notice.'</p></div>');
|
450 |
+
}
|
451 |
+
}
|
452 |
+
|
453 |
+
# remove
|
454 |
+
setcookie('wordpress_fvmcache', $notice, time()-3600, COOKIEPATH, COOKIE_DOMAIN );
|
455 |
+
}
|
456 |
+
}
|
457 |
+
|
458 |
+
|
459 |
+
|
460 |
|
461 |
# manage settings page
|
462 |
function fastvelocity_min_settings() {
|
472 |
<div class="wrap">
|
473 |
<h1>Fast Velocity Minify</h1>
|
474 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
475 |
<h2 class="nav-tab-wrapper wp-clearfix">
|
476 |
<a href="?page=fastvelocity-min&tab=status" class="nav-tab <?php echo $active_tab == 'status' ? 'nav-tab-active' : ''; ?>">Status</a>
|
477 |
<a href="?page=fastvelocity-min&tab=set" class="nav-tab <?php echo $active_tab == 'set' ? 'nav-tab-active' : ''; ?>">Settings</a>
|
616 |
|
617 |
|
618 |
<tr>
|
619 |
+
<th scope="row">Font Options</th>
|
620 |
<td>
|
621 |
<p class="fvm-bold-green fvm-rowintro">The default options are usually good for performance.</p>
|
622 |
<fieldset>
|
649 |
$b = ''; if($sel == 2) { $b = ' checked="checked"'; }
|
650 |
$c = ''; if($sel == 3) { $c = ' checked="checked"'; }
|
651 |
?>
|
652 |
+
<p class="fvm-bold-green fvm-rowintro">Choose how to include Google Fonts on your pages, when available:</p>
|
653 |
<fieldset>
|
654 |
+
<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>
|
655 |
<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>
|
656 |
+
<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>
|
657 |
+
</fieldset>
|
658 |
+
</td>
|
659 |
+
</tr>
|
660 |
+
|
661 |
+
<tr>
|
662 |
+
<th scope="row">Font Awesome</th>
|
663 |
+
<td>
|
664 |
+
<?php
|
665 |
+
# what to select
|
666 |
+
$sel = get_option('fastvelocity_fontawesome_method');
|
667 |
+
$a = ''; if($sel == 1 || empty($sel)) { $a = ' checked="checked"'; }
|
668 |
+
$b = ''; if($sel == 2) { $b = ' checked="checked"'; }
|
669 |
+
$c = ''; if($sel == 3) { $c = ' checked="checked"'; }
|
670 |
+
?>
|
671 |
+
<p class="fvm-bold-green fvm-rowintro">Only if available and if it has "font-awesome" in the url:</p>
|
672 |
+
<fieldset>
|
673 |
+
<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>
|
674 |
+
<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>
|
675 |
+
<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>
|
676 |
</fieldset>
|
677 |
</td>
|
678 |
</tr>
|
679 |
|
680 |
+
|
681 |
<tr>
|
682 |
<th scope="row">CSS Options</th>
|
683 |
<td>
|
700 |
<input name="fastvelocity_min_remove_print_mediatypes" type="checkbox" id="fastvelocity_min_remove_print_mediatypes" value="1" <?php echo checked(1 == get_option('fastvelocity_min_remove_print_mediatypes'), true, false); ?> >
|
701 |
Remove the "Print" related stylesheets <span class="note-info">[ If selected, CSS files of mediatype "print" will be removed from the site ]</span></label>
|
702 |
<br />
|
703 |
+
<label for="fastvelocity_min_force_inline_css_footer">
|
704 |
+
<input name="fastvelocity_min_force_inline_css_footer" type="checkbox" id="fastvelocity_min_force_inline_css_footer" value="1" <?php echo checked(1 == get_option('fastvelocity_min_force_inline_css_footer'), true, false); ?>>
|
705 |
+
Inline CSS in the footer <span class="note-info">[ If selected, any FVM generated CSS files in the footer, will be inlined ]</span></label>
|
706 |
+
<br />
|
707 |
<label for="fastvelocity_min_force_inline_css">
|
708 |
<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); ?>>
|
709 |
+
Inline all FVM generated CSS files <span class="note-info">[ If selected, any FVM generated CSS files (header + footer) will be inlined ]</span></label>
|
710 |
<br />
|
711 |
</fieldset></td>
|
712 |
</tr>
|
715 |
<tr>
|
716 |
<th scope="row">JavaScript Options</th>
|
717 |
<td>
|
718 |
+
<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>
|
719 |
<fieldset>
|
720 |
<label for="fastvelocity_min_disable_js_merge">
|
721 |
<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); ?> >
|
840 |
|
841 |
<div style="height: 20px;"></div>
|
842 |
<h2 class="title">Special JS and CSS Exceptions</h2>
|
843 |
+
<p class="fvm-bold-green">You can use this section to edit or change our default exclusions, as well as to add your own.<br />Make sure you understand the difference between Defer and Async.</p>
|
844 |
+
<p class="fvm-bold-green">When you use an option here that uses "Async", styles and scripts load "out of order" and completely independent from the others. That means, the files that end up loading later, will overwrite any previously loaded code. On the other hand, when you use the "ignore list" or when you select an option to "defer", the order of scripts and styles is preserved and should not overwrite previously loaded code, unless there is an higher specificy somewhere else.</p>
|
845 |
|
846 |
<div style="height: 20px;"></div>
|
847 |
<table class="form-table fvm-settings">
|
883 |
<p>
|
884 |
<textarea name="fastvelocity_min_excludejslist" rows="7" cols="50" id="fastvelocity_min_excludejslist" class="large-text code" placeholder="ex: /pixelyoursite/js/public.js"><?php echo get_option('fastvelocity_min_excludejslist'); ?></textarea>
|
885 |
</p>
|
886 |
+
<p class="description">[ Any JS file that can load Async and completely independent, such as analytics or pixel scripts ]</p>
|
887 |
|
888 |
</fieldset></td>
|
889 |
</tr>
|
899 |
<p>
|
900 |
<textarea name="fastvelocity_min_excludecsslist" rows="7" cols="50" id="fastvelocity_min_excludecsslist" class="large-text code" placeholder="ex: /wp-content/themes/my-theme/css/fontawesome.css"><?php echo get_option('fastvelocity_min_excludecsslist'); ?></textarea>
|
901 |
</p>
|
902 |
+
<p class="description">[ Any CSS file that can load completely independent, such as fontawesome or other icons ]</p>
|
|
|
903 |
|
904 |
</fieldset></td>
|
905 |
</tr>
|
951 |
<?php settings_fields('fvm-group-dev'); do_settings_sections('fvm-group-dev'); ?>
|
952 |
|
953 |
<div style="height: 20px;"></div>
|
954 |
+
<h2 class="title">Development</h2>
|
955 |
+
<p class="fvm-bold-green">This are handy things for the plugin author, but may be of use to you if you are looking to debug some issue.</p>
|
956 |
+
<p class="fvm-bold-green">Please note that the automatic headers, are only available after the first, uncached pageview (you may need to purge your cache to see them, or your server may not support this at all).</p>
|
957 |
|
958 |
<table class="form-table fvm-settings">
|
959 |
<tbody>
|
960 |
<tr>
|
961 |
+
<th scope="row">Dev Options</th>
|
962 |
<td><fieldset>
|
963 |
<label for="fastvelocity_fvm_debug">
|
964 |
<input name="fastvelocity_fvm_debug" type="checkbox" id="fastvelocity_fvm_debug" value="1" <?php echo checked(1 == get_option('fastvelocity_fvm_debug'), true, false); ?>>
|
965 |
+
Enable FVM Debug Mode<span class="note-info">[ Add extra info to the "status page" logs as well as some comments on the HTML frontend (beta) ]</span></label>
|
966 |
+
|
967 |
+
<br />
|
968 |
+
<label for="fastvelocity_enabled_css_preload">
|
969 |
+
<input name="fastvelocity_enabled_css_preload" type="checkbox" id="fastvelocity_enabled_css_preload" value="1" <?php echo checked(1 == get_option('fastvelocity_enabled_css_preload'), true, false); ?>>
|
970 |
+
Enable FVM CSS files Preload<span class="note-info">[ Automatically create http headers for FVM generated CSS files, when enqueued ]</span></label>
|
971 |
+
|
972 |
+
<br />
|
973 |
+
<label for="fastvelocity_enabled_js_preload">
|
974 |
+
<input name="fastvelocity_enabled_js_preload" type="checkbox" id="fastvelocity_enabled_js_preload" value="1" <?php echo checked(1 == get_option('fastvelocity_enabled_js_preload'), true, false); ?>>
|
975 |
+
Enable FVM JS files Preload<span class="note-info">[ Automatically create http headers for FVM generated JS files, when enqueued ]</span></label>
|
976 |
+
|
977 |
|
978 |
</fieldset>
|
979 |
</td>
|
980 |
</tr>
|
|
|
981 |
</tbody></table>
|
982 |
|
983 |
|
984 |
|
985 |
+
|
986 |
+
|
987 |
+
|
988 |
<div style="height: 20px;"></div>
|
989 |
<h2 class="title">HTTP Headers</h2>
|
990 |
<p class="fvm-bold-green">Preconnect Headers: This will add link headers to your http response to instruct the browser to preconnect to other domains (ex: fonts, images, videos, etc)</p>
|
1170 |
# process header javascript ###############
|
1171 |
###########################################
|
1172 |
function fastvelocity_min_merge_header_scripts() {
|
1173 |
+
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;
|
1174 |
if(!is_object($wp_scripts)) { return false; }
|
1175 |
$scripts = wp_clone($wp_scripts);
|
1176 |
$scripts->all_deps($scripts->queue);
|
1195 |
# get full url
|
1196 |
$hurl = fastvelocity_min_get_hurl($wp_scripts->registered[$handle]->src, $wp_domain, $wp_home);
|
1197 |
|
1198 |
+
# Exclude JS files from PSI (Async) takes priority over the ignore list
|
1199 |
+
if($fvm_min_excludejslist != false || is_array($fvm_min_excludejslist)) {
|
1200 |
+
|
1201 |
+
# check for string match
|
1202 |
+
$skipjs = false;
|
1203 |
+
foreach($fvm_min_excludejslist as $l) {
|
1204 |
+
if (stripos($hurl, $l) !== false) {
|
1205 |
+
# print code if there are no linebreaks, or return
|
1206 |
+
echo '<script type="text/javascript">if(!navigator.userAgent.match(/'.implode('|', $fvmualist).'/i)){';
|
1207 |
+
echo "loadAsync('$hurl', null);";
|
1208 |
+
echo '}</script>';
|
1209 |
+
$skipjs = true;
|
1210 |
+
break;
|
1211 |
+
}
|
1212 |
+
}
|
1213 |
+
if($skipjs != false) { continue; }
|
1214 |
+
}
|
1215 |
+
|
1216 |
# IE only files don't increment things
|
1217 |
$ieonly = fastvelocity_ie_blacklist($hurl);
|
1218 |
if($ieonly == true) { continue; }
|
1328 |
if(count($data) > 0) { $wp_scripts->registered["fvm-header-$i"]->extra['data'] = implode(PHP_EOL, $data); }
|
1329 |
|
1330 |
# enqueue file, if not empty
|
1331 |
+
if(file_exists($file) && (filesize($file) > 0 || count($data) > 0)) {
|
|
|
1332 |
wp_enqueue_script("fvm-header-$i");
|
1333 |
}
|
1334 |
|
1350 |
# process js in the footer ################
|
1351 |
###########################################
|
1352 |
function fastvelocity_min_merge_footer_scripts() {
|
1353 |
+
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;
|
1354 |
if(!is_object($wp_scripts)) { return false; }
|
1355 |
$ctime = get_option('fvm-last-cache-update', '0');
|
1356 |
$scripts = wp_clone($wp_scripts);
|
1370 |
# get full url
|
1371 |
$hurl = fastvelocity_min_get_hurl($wp_scripts->registered[$handle]->src, $wp_domain, $wp_home);
|
1372 |
|
1373 |
+
# Exclude JS files from PSI (Async) takes priority over the ignore list
|
1374 |
+
if($fvm_min_excludejslist != false || is_array($fvm_min_excludejslist)) {
|
1375 |
+
|
1376 |
+
# check for string match
|
1377 |
+
$skipjs = false;
|
1378 |
+
foreach($fvm_min_excludejslist as $l) {
|
1379 |
+
if (stripos($hurl, $l) !== false) {
|
1380 |
+
# print code if there are no linebreaks, or return
|
1381 |
+
echo '<script type="text/javascript">if(!navigator.userAgent.match(/'.implode('|', $fvmualist).'/i)){';
|
1382 |
+
echo "loadAsync('$hurl', null);";
|
1383 |
+
echo '}</script>';
|
1384 |
+
$skipjs = true;
|
1385 |
+
break;
|
1386 |
+
}
|
1387 |
+
}
|
1388 |
+
if($skipjs != false) { continue; }
|
1389 |
+
}
|
1390 |
+
|
1391 |
# IE only files don't increment things
|
1392 |
$ieonly = fastvelocity_ie_blacklist($hurl);
|
1393 |
if($ieonly == true) { continue; }
|
1494 |
if(count($data) > 0) { $wp_scripts->registered["fvm-footer-$i"]->extra['data'] = implode(PHP_EOL, $data); }
|
1495 |
|
1496 |
# enqueue file, if not empty
|
1497 |
+
if(file_exists($file) && (filesize($file) > 0 || count($data) > 0)) {
|
|
|
1498 |
wp_enqueue_script("fvm-footer-$i");
|
1499 |
}
|
1500 |
|
1557 |
# return if no defer, and there's no defer for pagespeed... else pagespeed processing
|
1558 |
if ($defer_for_pagespeed != true) { return $tag; } else {
|
1559 |
|
1560 |
+
# return if there are linebreaks (will break document.write)
|
1561 |
+
if (stripos($tag, PHP_EOL) !== false) { return $tag; }
|
1562 |
+
|
1563 |
# return if external script url https://www.chromestatus.com/feature/5718547946799104
|
1564 |
if (fvm_is_local_domain($src) !== true) { return $tag; }
|
1565 |
|
1566 |
+
|
|
|
1567 |
|
1568 |
# print code if there are no linebreaks, or return
|
1569 |
if(!empty($tagdefer)) {
|
1584 |
# process header css ######################
|
1585 |
###########################################
|
1586 |
function fastvelocity_min_merge_header_css() {
|
1587 |
+
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;
|
1588 |
if(!is_object($wp_styles)) { return false; }
|
1589 |
$ctime = get_option('fvm-last-cache-update', '0');
|
1590 |
$styles = wp_clone($wp_styles);
|
1619 |
}
|
1620 |
|
1621 |
# mediatype
|
1622 |
+
$mt = isset($wp_styles->registered[$handle]->args) ? $wp_styles->registered[$handle]->args : 'all';
|
1623 |
+
if ($mt == 'screen' || $mt == 'screen, print' || empty($mt) || is_null($mt) || $mt == false) { $mt = 'all'; }
|
1624 |
+
$mediatype = $mt;
|
1625 |
|
1626 |
# full url or empty
|
1627 |
$hurl = fastvelocity_min_get_hurl($wp_styles->registered[$handle]->src, $wp_domain, $wp_home);
|
1632 |
if (isset($uniq[$key])) { $done = array_merge($done, array($handle)); continue; } else { $uniq[$key] = $handle; }
|
1633 |
}
|
1634 |
|
1635 |
+
# Exclude specific CSS files from PSI?
|
1636 |
+
if($fvm_min_excludecsslist != false && is_array($fvm_min_excludecsslist) && fastvelocity_min_in_arrayi($hurl, $fvm_min_excludecsslist)) {
|
1637 |
+
$cssguid = 'fvm'.hash('adler32', $hurl);
|
1638 |
+
echo '<script type="text/javascript">if(!navigator.userAgent.match(/'.implode('|', $fvmualist).'/i)){';
|
1639 |
+
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.');';
|
1640 |
+
echo '}</script>';
|
1641 |
+
$done = array_merge($done, array($handle)); continue;
|
1642 |
+
}
|
1643 |
+
|
1644 |
+
# font awesome processing, async css
|
1645 |
+
if($fvm_fawesome_method == 2 && stripos($hurl, 'font-awesome') !== false) {
|
1646 |
+
echo '<link rel="preload" href="'.$hurl.'" as="style" media="'.$mediatype.'" onload="this.onload=null;this.rel=\'stylesheet\'" />';
|
1647 |
+
echo '<noscript><link rel="stylesheet" href="'.$hurl.'" media="'.$mediatype.'" /></noscript>';
|
1648 |
+
echo '<!--[if IE]><link rel="stylesheet" href="'.$hurl.'" media="'.$mediatype.'" /><![endif]-->';
|
1649 |
+
$done = array_merge($done, array($handle)); continue;
|
1650 |
+
}
|
1651 |
+
|
1652 |
+
# font awesome processing, async and exclude from PSI
|
1653 |
+
if($fvm_fawesome_method == 3 && stripos($hurl, 'font-awesome') !== false) {
|
1654 |
+
$cssguid = 'fvm'.hash('adler32', $hurl);
|
1655 |
+
echo '<script type="text/javascript">if(!navigator.userAgent.match(/'.implode('|', $fvmualist).'/i)){';
|
1656 |
+
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.');';
|
1657 |
+
echo '}</script>';
|
1658 |
+
$done = array_merge($done, array($handle)); continue;
|
1659 |
+
}
|
1660 |
+
|
1661 |
# array of info to save
|
1662 |
$arr = array('handle'=>$handle, 'url'=>$hurl, 'conditional'=>$conditional, 'mediatype'=>$mediatype);
|
1663 |
|
1733 |
|
1734 |
# inline css or fail
|
1735 |
if($res['code'] !== false) {
|
1736 |
+
|
1737 |
+
# add font-display
|
1738 |
+
# https://developers.google.com/web/updates/2016/02/font-display
|
1739 |
+
$res['code'] = str_ireplace('font-style:normal;', 'font-display:block;font-style:normal;', $res['code']);
|
1740 |
+
|
1741 |
+
# inline
|
1742 |
echo '<style type="text/css" media="all">'.$res['code'].'</style>'.PHP_EOL;
|
1743 |
} else {
|
1744 |
echo "<!-- GOOGLE FONTS REQUEST FAILED for $gfurl -->\n";
|
1772 |
$ieonly = fastvelocity_ie_blacklist($hurl);
|
1773 |
if($ieonly == true) { continue; }
|
1774 |
|
1775 |
+
# skip ignore list, conditional css, external css, font-awesome merge
|
1776 |
+
if ( (!fastvelocity_min_in_arrayi($hurl, $ignore) && !isset($conditional) && fvm_internal_url($hurl, $wp_home))
|
1777 |
+
|| empty($hurl)
|
1778 |
+
|| ($fvm_fawesome_method == 1 && stripos($href, 'font-awesome') !== false)) {
|
1779 |
|
1780 |
# colect inline css for this handle
|
1781 |
if(isset($wp_styles->registered[$handle]->extra['after']) && is_array($wp_styles->registered[$handle]->extra['after'])) {
|
1799 |
}
|
1800 |
endforeach;
|
1801 |
|
|
|
1802 |
# reorder CSS by mediatypes
|
1803 |
if(!$skip_cssorder) {
|
1804 |
if(count($header) > 0) {
|
1808 |
foreach($header as $array) {
|
1809 |
if(isset($array['media'])) { $allmedia[$array['media']] = ''; }
|
1810 |
}
|
1811 |
+
|
1812 |
# extract handles by mediatype
|
1813 |
$grouphandles = array();
|
1814 |
foreach ($allmedia as $md=>$var) {
|
1815 |
foreach($header as $array) {
|
1816 |
+
if (isset($array['media']) && $array['media'] === $md) {
|
1817 |
foreach($array['handles'] as $h) { $grouphandles[$md][] = $h; }
|
1818 |
}
|
1819 |
}
|
1917 |
|
1918 |
# enqueue file, if not empty
|
1919 |
} else {
|
1920 |
+
if(file_exists($file) && filesize($file) > 0) {
|
1921 |
+
|
1922 |
+
# inline CSS if mediatype is not of type "all" (such as mobile only), if the file is smaller than 20KB
|
1923 |
+
if(filesize($file) < 20000 && $header[$i]['media'] != 'all') {
|
1924 |
+
echo '<style id="fvm-header-'.$i.'" media="'.$header[$i]['media'].'">'.file_get_contents($file).'</style>';
|
1925 |
+
} else {
|
1926 |
+
# enqueue it
|
1927 |
+
wp_enqueue_style("fvm-header-$i", $file_url, array(), null, $header[$i]['media']);
|
1928 |
+
}
|
1929 |
+
|
1930 |
}
|
1931 |
}
|
1932 |
}
|
1949 |
# process css in the footer ###############
|
1950 |
###########################################
|
1951 |
function fastvelocity_min_merge_footer_css() {
|
1952 |
+
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, $force_inline_css_footer;
|
1953 |
|
1954 |
if(!is_object($wp_styles)) { return false; }
|
1955 |
$ctime = get_option('fvm-last-cache-update', '0');
|
1977 |
|
1978 |
# google fonts to the top
|
1979 |
foreach( $styles->to_do as $handle ) :
|
1980 |
+
|
1981 |
# dequeue and get a list of google fonts, or requeue external
|
1982 |
$hurl = fastvelocity_min_get_hurl($wp_styles->registered[$handle]->src, $wp_domain, $wp_home);
|
1983 |
+
|
1984 |
if (stripos($hurl, 'fonts.googleapis.com') !== false) {
|
1985 |
wp_dequeue_style($handle);
|
1986 |
if($remove_googlefonts != false) { $done = array_merge($done, array($handle)); continue; } # mark as done if to be removed
|
1992 |
} else {
|
1993 |
wp_dequeue_style($handle); wp_enqueue_style($handle); # failsafe
|
1994 |
}
|
1995 |
+
|
1996 |
endforeach;
|
1997 |
|
1998 |
|
2070 |
|
2071 |
|
2072 |
# get groups of handles
|
2073 |
+
$uniq = array();
|
2074 |
foreach( $styles->to_do as $handle ) :
|
2075 |
|
2076 |
# skip already processed google fonts
|
2077 |
if(isset($google_fonts[$handle])) { continue; }
|
2078 |
+
|
2079 |
+
# conditionals
|
2080 |
+
$conditional = NULL; if(isset($wp_styles->registered[$handle]->extra["conditional"])) {
|
2081 |
+
$conditional = $wp_styles->registered[$handle]->extra["conditional"]; # such as ie7, ie8, ie9, etc
|
2082 |
+
}
|
2083 |
+
|
2084 |
+
# mediatype
|
2085 |
+
$mt = isset($wp_styles->registered[$handle]->args) ? $wp_styles->registered[$handle]->args : 'all';
|
2086 |
+
if ($mt == 'screen' || $mt == 'screen, print' || empty($mt) || is_null($mt) || $mt == false) { $mt = 'all'; }
|
2087 |
+
$mediatype = $mt;
|
2088 |
+
|
2089 |
# get full url
|
2090 |
$hurl = fastvelocity_min_get_hurl($wp_styles->registered[$handle]->src, $wp_domain, $wp_home);
|
2091 |
+
|
2092 |
+
# mark duplicates as done and remove from the queue
|
2093 |
+
if(!empty($hurl)) {
|
2094 |
+
$key = hash('adler32', $hurl);
|
2095 |
+
if (isset($uniq[$key])) { $done = array_merge($done, array($handle)); continue; } else { $uniq[$key] = $handle; }
|
2096 |
+
}
|
2097 |
|
2098 |
# IE only files don't increment things
|
2099 |
$ieonly = fastvelocity_ie_blacklist($hurl);
|
2100 |
if($ieonly == true) { continue; }
|
2101 |
|
2102 |
+
|
2103 |
+
# Exclude specific CSS files from PSI?
|
2104 |
+
if($fvm_min_excludecsslist != false && is_array($fvm_min_excludecsslist) && fastvelocity_min_in_arrayi($hurl, $fvm_min_excludecsslist)) {
|
2105 |
+
$cssguid = 'fvm'.hash('adler32', $hurl);
|
2106 |
+
echo '<script type="text/javascript">if(!navigator.userAgent.match(/'.implode('|', $fvmualist).'/i)){';
|
2107 |
+
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.');';
|
2108 |
+
echo '}</script>';
|
2109 |
+
$done = array_merge($done, array($handle)); continue;
|
2110 |
+
}
|
2111 |
+
|
2112 |
+
# font awesome processing, async css
|
2113 |
+
if($fvm_fawesome_method == 2 && stripos($hurl, 'font-awesome') !== false) {
|
2114 |
+
echo '<link rel="preload" href="'.$hurl.'" as="style" media="'.$mediatype.'" onload="this.onload=null;this.rel=\'stylesheet\'" />';
|
2115 |
+
echo '<noscript><link rel="stylesheet" href="'.$hurl.'" media="'.$mediatype.'" /></noscript>';
|
2116 |
+
echo '<!--[if IE]><link rel="stylesheet" href="'.$hurl.'" media="'.$mediatype.'" /><![endif]-->';
|
2117 |
+
$done = array_merge($done, array($handle)); continue;
|
2118 |
+
}
|
2119 |
+
|
2120 |
+
# font awesome processing, async and exclude from PSI
|
2121 |
+
if($fvm_fawesome_method == 3 && stripos($hurl, 'font-awesome') !== false) {
|
2122 |
+
$cssguid = 'fvm'.hash('adler32', $hurl);
|
2123 |
+
echo '<script type="text/javascript">if(!navigator.userAgent.match(/'.implode('|', $fvmualist).'/i)){';
|
2124 |
+
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.');';
|
2125 |
+
echo '}</script>';
|
2126 |
+
$done = array_merge($done, array($handle)); continue;
|
2127 |
}
|
2128 |
|
2129 |
+
# skip ignore list, conditional css, external css, font-awesome merge
|
2130 |
+
if ( (!fastvelocity_min_in_arrayi($hurl, $ignore) && !isset($conditional) && fvm_internal_url($hurl, $wp_home))
|
2131 |
+
|| empty($hurl)
|
2132 |
+
|| ($fvm_fawesome_method == 1 && stripos($href, 'font-awesome') !== false)) {
|
2133 |
|
2134 |
# colect inline css for this handle
|
2135 |
if(isset($wp_styles->registered[$handle]->extra['after']) && is_array($wp_styles->registered[$handle]->extra['after'])) {
|
2139 |
|
2140 |
# process
|
2141 |
if(isset($footer[count($footer)-1]['handle']) || count($footer) == 0 || $footer[count($footer)-1]['media'] != $wp_styles->registered[$handle]->args) {
|
2142 |
+
array_push($footer, array('handles'=>array(),'media'=>$mediatype));
|
2143 |
}
|
2144 |
|
2145 |
# push it to the array get latest modified time
|
2168 |
$grouphandles = array();
|
2169 |
foreach ($allmedia as $md=>$var) {
|
2170 |
foreach($footer as $array) {
|
2171 |
+
if (isset($array['media']) && $array['media'] === $md) {
|
2172 |
foreach($array['handles'] as $h) { $grouphandles[$md][] = $h; }
|
2173 |
}
|
2174 |
}
|
2259 |
}
|
2260 |
|
2261 |
# register and enqueue minified file, consider excluding of mediatype "print" and inline css
|
2262 |
+
if ($remove_print_mediatypes != true || ($remove_print_mediatypes == true && $footer[$i]['media'] != 'print')) {
|
2263 |
|
2264 |
# the developers tab, takes precedence
|
2265 |
|
2272 |
|
2273 |
# enqueue file, if not empty
|
2274 |
} else {
|
2275 |
+
if(file_exists($file) && filesize($file) > 0) {
|
2276 |
+
|
2277 |
+
# inline if the file is smaller than 20KB or option has been enabled
|
2278 |
+
if(filesize($file) < 20000 || $force_inline_css_footer != false) {
|
2279 |
+
echo '<style id="fvm-footer-'.$i.'" media="'.$footer[$i]['media'].'">'.file_get_contents($file).'</style>';
|
2280 |
+
} else {
|
2281 |
+
# enqueue it
|
2282 |
+
wp_enqueue_style("fvm-footer-$i", $file_url, array(), null, $footer[$i]['media']);
|
2283 |
+
}
|
2284 |
}
|
2285 |
}
|
2286 |
}
|
2314 |
|
2315 |
}
|
2316 |
|
2317 |
+
# fvm load async scripts with callback
|
2318 |
+
function fvm_add_loadasync() {
|
2319 |
+
|
2320 |
+
echo <<<EOF
|
2321 |
+
<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>
|
2322 |
+
EOF;
|
2323 |
+
|
2324 |
+
}
|
2325 |
|
2326 |
|
2327 |
|
2375 |
}
|
2376 |
}
|
2377 |
|
2378 |
+
# fvm css and js generated files
|
2379 |
+
$fvm_headers = fastvelocity_get_preload_headers();
|
2380 |
+
if($fvm_headers != false) {
|
2381 |
+
$nh = array_map('trim', explode(PHP_EOL, $fvm_headers));
|
2382 |
+
foreach ($nh as $h) {
|
2383 |
+
if(!empty($h)) {
|
2384 |
+
header($h, false);
|
2385 |
+
}
|
2386 |
+
}
|
2387 |
+
}
|
2388 |
+
|
2389 |
}
|
2390 |
|
2391 |
|
2392 |
|
2393 |
###########################################
|
2394 |
+
# optimize the ignore list for pagespeed insights + Exclude JS files from PSI (Async)
|
2395 |
###########################################
|
2396 |
+
function fastvelocity_min_defer_js_optimize($tag, $handle, $src) {
|
2397 |
+
global $defer_for_pagespeed, $defer_for_pagespeed_optimize, $fvm_fix_editor, $fvmualist;
|
2398 |
|
2399 |
# return if there are linebreaks (will break document.write)
|
2400 |
if (stripos($tag, PHP_EOL) !== false) { return $tag; }
|
2402 |
# fix page editors
|
2403 |
if($fvm_fix_editor == true && is_user_logged_in()) { return $tag; }
|
2404 |
|
2405 |
+
# return if external script url https://www.chromestatus.com/feature/5718547946799104
|
2406 |
+
if (fvm_is_local_domain($src) !== true) { return $tag; }
|
2407 |
+
|
2408 |
+
# filter src for extra atributes
|
2409 |
+
if (stripos($src, '?ver') !== false) {
|
2410 |
+
$src = stristr($src, '?ver', true);
|
2411 |
}
|
2412 |
|
2413 |
+
# exclude ignored scripts
|
2414 |
+
if(substr($handle, 0, 4) != "fvm-" && $defer_for_pagespeed == true && $defer_for_pagespeed_optimize == true) {
|
2415 |
+
|
2416 |
+
# get available nodes and add create with defer tag (if not async)
|
2417 |
+
$dom = new DOMDocument();
|
2418 |
+
libxml_use_internal_errors(true);
|
2419 |
+
@$dom->loadHTML($tag);
|
2420 |
+
$nodes = $dom->getElementsByTagName('script');
|
2421 |
+
$tagdefer = '';
|
2422 |
+
if ($nodes->length != 0) {
|
2423 |
+
$node = $dom->getElementsByTagName('script')->item(0);
|
2424 |
+
if (!$node->hasAttribute('async')) { $node->setAttribute('defer','defer'); };
|
2425 |
+
$tagdefer = $dom->saveHTML($node);
|
2426 |
+
}
|
2427 |
+
|
2428 |
+
# print code if there are no linebreaks, or return
|
2429 |
+
if(!empty($tagdefer)) {
|
2430 |
+
$deferinsights = '<script type="text/javascript">if(!navigator.userAgent.match(/'.implode('|', $fvmualist).'/i)){document.write('.json_encode($tag).');}</script>';
|
2431 |
+
return preg_replace('#<script(.*?)>(.*?)</script>#is', $deferinsights, $tag);
|
2432 |
}
|
2433 |
+
|
2434 |
}
|
2435 |
|
2436 |
# fallback
|
2438 |
}
|
2439 |
|
2440 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2441 |
# inline css in place, instead of inlining the large file
|
2442 |
function fastvelocity_optimizecss($html, $handle, $href, $media){
|
2443 |
+
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;
|
2444 |
|
2445 |
# current timestamp
|
2446 |
$ctime = get_option('fvm-last-cache-update', '0');
|
2472 |
}
|
2473 |
|
2474 |
# mediatype fix for some plugins + remove print mediatypes
|
2475 |
+
if ($media == 'screen' || $media == 'screen, print' || empty($media) || is_null($media) || $media == false) { $media = 'all'; }
|
2476 |
if($remove_print_mediatypes != false && $media == 'print') {
|
2477 |
return false;
|
2478 |
}
|
2497 |
return false;
|
2498 |
}
|
2499 |
|
|
|
2500 |
# handle google fonts here, when merging is disabled
|
2501 |
if(stripos($href, 'fonts.googleapis.com') !== false && $skip_google_fonts != false) {
|
2502 |
|
2518 |
}
|
2519 |
}
|
2520 |
|
2521 |
+
# font awesome processing, async css
|
2522 |
+
if($fvm_fawesome_method == 2 && stripos($href, 'font-awesome') !== false) {
|
2523 |
+
echo '<link rel="preload" href="'.$href.'" as="style" media="'.$media.'" onload="this.onload=null;this.rel=\'stylesheet\'" />';
|
2524 |
+
echo '<noscript><link rel="stylesheet" href="'.$href.'" media="'.$media.'" /></noscript>';
|
2525 |
+
echo '<!--[if IE]><link rel="stylesheet" href="'.$href.'" media="'.$media.'" /><![endif]-->';
|
2526 |
+
return false;
|
2527 |
+
}
|
2528 |
+
|
2529 |
+
# font awesome processing, async and exclude from PSI
|
2530 |
+
if($fvm_fawesome_method == 3 && stripos($href, 'font-awesome') !== false) {
|
2531 |
+
$cssguid = 'fvm'.hash('adler32', $href);
|
2532 |
+
echo '<script type="text/javascript">if(!navigator.userAgent.match(/'.implode('|', $fvmualist).'/i)){';
|
2533 |
+
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.');';
|
2534 |
+
echo '}</script>';
|
2535 |
+
return false;
|
2536 |
+
}
|
2537 |
+
|
2538 |
+
# font awesome processing, inline
|
2539 |
+
if($fvm_fawesome_method == 1 && stripos($href, 'font-awesome') !== false) {
|
2540 |
+
|
2541 |
+
# download, minify, cache
|
2542 |
+
$tkey = 'css-'.$ctime.'-'.hash('adler32', $handle.$href).'.css';
|
2543 |
+
$json = false; $json = fvm_get_transient($tkey);
|
2544 |
+
if ( $json === false) {
|
2545 |
+
$json = fvm_download_and_minify($href, null, $disable_css_minification, 'css', $handle);
|
2546 |
+
if($fvm_debug == true) { echo "<!-- FVM DEBUG: Uncached file processing now for $handle / $href -->" . PHP_EOL; }
|
2547 |
+
fvm_set_transient($tkey, $json);
|
2548 |
+
}
|
2549 |
+
|
2550 |
+
# decode
|
2551 |
+
$res = json_decode($json, true);
|
2552 |
+
|
2553 |
+
# add font-display
|
2554 |
+
# https://developers.google.com/web/updates/2016/02/font-display
|
2555 |
+
$res['code'] = str_ireplace('font-style:normal;', 'font-display:block;font-style:normal;', $res['code']);
|
2556 |
+
|
2557 |
+
# inline css or fail
|
2558 |
+
if($res['status'] != false) {
|
2559 |
+
echo '<style type="text/css" media="all">'.$res['code'].'</style>'.PHP_EOL;
|
2560 |
+
return false;
|
2561 |
+
} else {
|
2562 |
+
if($fvm_debug == true) { echo "<!-- FVM DEBUG: Font Awesome request failed for $href -->" . PHP_EOL; }
|
2563 |
+
return $html;
|
2564 |
+
}
|
2565 |
+
}
|
2566 |
+
|
2567 |
# inline google fonts, do not collect
|
2568 |
if(stripos($href, 'fonts.googleapis.com') !== false && $force_inline_googlefonts != false && $css_hide_googlefonts != true && $min_async_googlefonts != true) {
|
2569 |
|
2579 |
# decode
|
2580 |
$res = json_decode($json, true);
|
2581 |
|
2582 |
+
# add font-display
|
2583 |
+
# https://developers.google.com/web/updates/2016/02/font-display
|
2584 |
+
$res['code'] = str_ireplace('font-style:normal;', 'font-display:block;font-style:normal;', $res['code']);
|
2585 |
+
|
2586 |
# inline css or fail
|
2587 |
if($res['status'] != false) {
|
2588 |
echo '<style type="text/css" media="all">'.$res['code'].'</style>'.PHP_EOL;
|
2599 |
return false;
|
2600 |
}
|
2601 |
|
|
|
2602 |
# skip external scripts that are not specifically allowed
|
2603 |
if (fvm_internal_url($href, $wp_home) === false || empty($href)) {
|
2604 |
if($fvm_debug == true) { echo "<!-- FVM DEBUG: Skipped the next external enqueued CSS -->" . PHP_EOL; }
|
2706 |
|
2707 |
}
|
2708 |
|
2709 |
+
|
2710 |
+
|
2711 |
+
# collect all fvm CSS files and save them to an headers file
|
2712 |
+
add_filter('style_loader_tag', 'fastvelocity_collect_css_preload_headers', PHP_INT_MAX, 4 );
|
2713 |
+
function fastvelocity_collect_css_preload_headers($html, $handle, $href, $media){
|
2714 |
+
global $collect_preload_css, $fvm_enabled_css_preload, $fvm_enabled_js_preload;
|
2715 |
+
|
2716 |
+
# return if disabled
|
2717 |
+
if ($fvm_enabled_css_preload != true) {
|
2718 |
+
return $html;
|
2719 |
+
}
|
2720 |
+
|
2721 |
+
# collect
|
2722 |
+
if (stripos($href, '/fvm/out/') !== false) {
|
2723 |
+
$collect_preload_css[] = $href;
|
2724 |
+
}
|
2725 |
+
return $html;
|
2726 |
+
}
|
2727 |
+
|
2728 |
+
add_filter('script_loader_tag', 'fastvelocity_collect_js_preload_headers', PHP_INT_MAX, 3 );
|
2729 |
+
function fastvelocity_collect_js_preload_headers($html, $handle, $src){
|
2730 |
+
global $collect_preload_js, $fvm_enabled_css_preload, $fvm_enabled_js_preload;
|
2731 |
+
|
2732 |
+
# return if disabled
|
2733 |
+
if ($fvm_enabled_js_preload != true) {
|
2734 |
+
return $html;
|
2735 |
+
}
|
2736 |
+
|
2737 |
+
# collect
|
2738 |
+
if (stripos($src, '/fvm/out/') !== false) {
|
2739 |
+
$collect_preload_js[] = $src;
|
2740 |
+
}
|
2741 |
+
return $html;
|
2742 |
+
}
|
2743 |
+
|
2744 |
+
# generate css headers file
|
2745 |
+
add_action('wp_footer', 'fastvelocity_generate_preload_headers', PHP_INT_MAX);
|
2746 |
+
function fastvelocity_generate_preload_headers(){
|
2747 |
+
global $collect_preload_css, $collect_preload_js, $fvm_enabled_css_preload, $fvm_enabled_js_preload;
|
2748 |
+
|
2749 |
+
# return if disabled
|
2750 |
+
if ($fvm_enabled_css_preload != true && $fvm_enabled_js_preload != true) {
|
2751 |
+
return false;
|
2752 |
+
}
|
2753 |
+
|
2754 |
+
# get host with multisite support and query strings
|
2755 |
+
$host = htmlentities($_SERVER['SERVER_NAME']);
|
2756 |
+
if(empty($hosts)) { $host = htmlentities($_SERVER['HTTP_HOST']); }
|
2757 |
+
$request_query = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_QUERY);
|
2758 |
+
$request_uri = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
|
2759 |
+
$is_admin = strpos( $request_uri, '/wp-admin/' );
|
2760 |
+
|
2761 |
+
# always false for admin pages
|
2762 |
+
if( false !== $is_admin){
|
2763 |
+
return false;
|
2764 |
+
}
|
2765 |
+
|
2766 |
+
# initialize headers
|
2767 |
+
$headers = array();
|
2768 |
+
|
2769 |
+
# css headers
|
2770 |
+
if ($fvm_enabled_css_preload != false && is_array($collect_preload_css) && count($collect_preload_css) > 0) {
|
2771 |
+
foreach($collect_preload_css as $u) {
|
2772 |
+
$headers[] = "Link: <$u>; rel=preload; as=style";
|
2773 |
+
}
|
2774 |
+
}
|
2775 |
+
|
2776 |
+
# js headers
|
2777 |
+
if ($fvm_enabled_js_preload != false && is_array($collect_preload_js) && count($collect_preload_js) > 0) {
|
2778 |
+
foreach($collect_preload_js as $u) {
|
2779 |
+
$headers[] = "Link: <$u>; rel=preload; as=script";
|
2780 |
+
}
|
2781 |
+
}
|
2782 |
+
|
2783 |
+
# must have something
|
2784 |
+
if(count($headers) == 0) {
|
2785 |
+
return false;
|
2786 |
+
} else {
|
2787 |
+
$headers = implode(PHP_EOL, $headers);
|
2788 |
+
}
|
2789 |
+
|
2790 |
+
# get cache path
|
2791 |
+
$cachepath = fvm_cachepath();
|
2792 |
+
$headerdir = $cachepath['headerdir'];
|
2793 |
+
$cachefilebase = $headerdir.'/';
|
2794 |
+
|
2795 |
+
# possible cache file locations
|
2796 |
+
$b = $cachefilebase . md5($host.'-'.$request_uri).'.header';
|
2797 |
+
$a = $cachefilebase . md5($host.'-'.$request_uri.$request_query).'.header';
|
2798 |
+
|
2799 |
+
# reset file cache
|
2800 |
+
clearstatcache();
|
2801 |
+
|
2802 |
+
# if there are no query strings
|
2803 |
+
if($b == $a) {
|
2804 |
+
if(!file_exists($a)) { file_put_contents($a, $headers); }
|
2805 |
+
return false;
|
2806 |
+
}
|
2807 |
+
|
2808 |
+
# b fallback
|
2809 |
+
if($b != $a && !file_exists($b)) {
|
2810 |
+
file_put_contents($b, $headers);
|
2811 |
+
}
|
2812 |
+
|
2813 |
+
return false;
|
2814 |
+
}
|
2815 |
+
|
2816 |
+
|
2817 |
+
# get current headers file for the url
|
2818 |
+
function fastvelocity_get_preload_headers(){
|
2819 |
+
global $fvm_enabled_css_preload, $fvm_enabled_js_preload;
|
2820 |
+
|
2821 |
+
# return if disabled
|
2822 |
+
if ($fvm_enabled_css_preload != true && $fvm_enabled_js_preload != true) {
|
2823 |
+
return false;
|
2824 |
+
}
|
2825 |
+
|
2826 |
+
# get host with multisite support and query strings
|
2827 |
+
$host = htmlentities($_SERVER['SERVER_NAME']);
|
2828 |
+
if(empty($hosts)) { $host = htmlentities($_SERVER['HTTP_HOST']); }
|
2829 |
+
$request_query = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_QUERY);
|
2830 |
+
$request_uri = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
|
2831 |
+
$is_admin = strpos( $request_uri, '/wp-admin/' );
|
2832 |
+
|
2833 |
+
# always false for admin pages
|
2834 |
+
if( false !== $is_admin){
|
2835 |
+
return false;
|
2836 |
+
}
|
2837 |
+
|
2838 |
+
# get cache path
|
2839 |
+
$cachepath = fvm_cachepath();
|
2840 |
+
$headerdir = $cachepath['headerdir'];
|
2841 |
+
$cachefilebase = $headerdir.'/';
|
2842 |
+
|
2843 |
+
# possible cache file locations
|
2844 |
+
$b = $cachefilebase . md5($host.'-'.$request_uri).'.header';
|
2845 |
+
$a = $cachefilebase . md5($host.'-'.$request_uri.$request_query).'.header';
|
2846 |
+
|
2847 |
+
# reset file cache
|
2848 |
+
clearstatcache();
|
2849 |
+
|
2850 |
+
# return header files or fallback
|
2851 |
+
if($b == $a && file_exists($a)) { return file_get_contents($a); }
|
2852 |
+
if($b != $a && file_exists($b)) { return file_get_contents($b); }
|
2853 |
+
|
2854 |
+
return false;
|
2855 |
+
}
|
inc/functions.php
CHANGED
@@ -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';
|
@@ -42,12 +42,14 @@ $cachebase = rtrim($upload['basedir'], '/').'/fvm';
|
|
42 |
$cachedir = rtrim($upload['basedir'], '/').'/fvm/out';
|
43 |
$tmpdir = rtrim($upload['basedir'], '/').'/fvm/tmp';
|
44 |
$cachedirurl = rtrim($upload['baseurl'], '/').'/fvm/out';
|
|
|
45 |
if(!is_dir($cachebase)) { mkdir($cachebase, 0755, true); }
|
46 |
if(!is_dir($cachedir)) { mkdir($cachedir, 0755, true); }
|
47 |
if(!is_dir($tmpdir)) { mkdir($tmpdir, 0755, true); }
|
|
|
48 |
|
49 |
# return
|
50 |
-
return array('cachebase'=>$cachebase,'tmpdir'=>$tmpdir, 'cachedir'=>$cachedir, 'cachedirurl'=>$cachedirurl);
|
51 |
}
|
52 |
|
53 |
|
@@ -64,7 +66,7 @@ function fastvelocity_plugin_activate() {
|
|
64 |
fvm_cache_increment();
|
65 |
|
66 |
# default blacklist
|
67 |
-
$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');
|
68 |
update_option('fastvelocity_min_blacklist', implode(PHP_EOL, $exc));
|
69 |
|
70 |
# default ignore list
|
@@ -255,6 +257,7 @@ function fvm_server_is_windows() {
|
|
255 |
|
256 |
# minify js on demand (one file at one time, for compatibility)
|
257 |
function fastvelocity_min_get_js($url, $js, $disable_js_minification) {
|
|
|
258 |
|
259 |
# exclude minification on already minified files + jquery (because minification might break those)
|
260 |
$excl = array('jquery.js', '.min.js', '-min.js', '/uploads/fusion-scripts/', '/min/', '.packed.js');
|
@@ -270,28 +273,35 @@ if(!$disable_js_minification) {
|
|
270 |
$js = fvm_compat_urls($js);
|
271 |
}
|
272 |
|
|
|
|
|
|
|
|
|
|
|
273 |
# needed when merging js files
|
274 |
$js = trim($js);
|
275 |
if(substr($js, -1) != ';'){ $js = $js.';'; }
|
276 |
-
$js = '/* info: ' . $url . ' */' . PHP_EOL . $js
|
277 |
|
278 |
# return html
|
279 |
-
return $js;
|
280 |
}
|
281 |
|
282 |
|
283 |
# minify JS string with PHP Minify or YUI Compressors
|
284 |
function fastvelocity_min_minify_js_string($js) {
|
285 |
global $tmpdir, $plugindir;
|
286 |
-
|
287 |
-
# PHP Minify
|
288 |
-
$minifier = new Minify\JS($js);
|
289 |
-
$min = $minifier->minify();
|
290 |
-
if($min !== false && (strlen(trim($js)) == strlen(trim($min)) || strlen(trim($min)) > 0)) {
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
|
|
|
|
295 |
}
|
296 |
|
297 |
# functions, minify html
|
@@ -355,7 +365,7 @@ function fastvelocity_get_cachestats() {
|
|
355 |
|
356 |
# minify css on demand (one file at one time, for compatibility)
|
357 |
function fastvelocity_min_get_css($url, $css, $disable_css_minification) {
|
358 |
-
global $wp_domain;
|
359 |
|
360 |
# remove BOM
|
361 |
$css = fastvelocity_min_remove_utf8_bom($css);
|
@@ -384,7 +394,8 @@ if(!empty($fvm_cdn_url)) {
|
|
384 |
}
|
385 |
|
386 |
# add css comment
|
387 |
-
$css =
|
|
|
388 |
|
389 |
# return html
|
390 |
return $css;
|
@@ -565,79 +576,112 @@ $printurl = str_ireplace(array(site_url(), home_url(), 'http:', 'https:'), '', $
|
|
565 |
# Concatenate Google Fonts tags (http://fonts.googleapis.com/css?...)
|
566 |
function fastvelocity_min_concatenate_google_fonts($array) {
|
567 |
|
568 |
-
# extract unique font families
|
569 |
-
$families = array();
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
$
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
$
|
583 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
584 |
|
585 |
-
# if no type or subset
|
586 |
-
if(stristr($font, ':') === FALSE) {
|
587 |
-
$fonts[] = array('name'=>$font, 'type'=>'', 'sub'=>'');
|
588 |
-
} else {
|
589 |
-
|
590 |
-
# get type and subset
|
591 |
-
$name = stristr($font, ':', true); # font name, before :
|
592 |
-
$ftype = trim(stristr($font, ':'), ':'); # second part of the string, after :
|
593 |
-
|
594 |
-
# get font types and subset
|
595 |
-
if(stristr($ftype, '&subset=') === FALSE) {
|
596 |
-
$fonts[] = array('name'=>$name, 'type'=>$ftype, 'sub'=>'');
|
597 |
-
} else {
|
598 |
-
$newftype = stristr($ftype, '&', true); # font type, before &
|
599 |
-
$subset = trim(str_ireplace('&subset=', '', stristr($ftype, '&'))); # second part of the string, after &
|
600 |
-
$fonts[] = array('name'=>$name, 'type'=>$newftype, 'sub'=>$subset);
|
601 |
}
|
602 |
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
$
|
609 |
-
|
610 |
-
|
611 |
-
$fonts_and_types = $ufonts;
|
612 |
-
|
613 |
-
# get unique types and subsets for each unique font name
|
614 |
-
foreach ($ufonts as $uf) {
|
615 |
-
|
616 |
-
# types
|
617 |
-
$utypes = array();
|
618 |
-
foreach ($fonts as $f) {
|
619 |
-
if($f['name'] == $uf && !empty($f['type'])) { $utypes = array_merge($utypes, explode(',', $f['type'])); }
|
620 |
}
|
621 |
-
|
622 |
-
# filter types
|
623 |
-
$utypes = array_unique($utypes);
|
624 |
-
sort($utypes);
|
625 |
-
$ntype = ''; if(count($utypes) > 0) { $ntype = ':'.implode(',', $utypes); } # types to append to the font name
|
626 |
-
|
627 |
-
# generate font url queries
|
628 |
-
$fonts_and_types[$uf] = str_ireplace(' ', '+', $uf).$ntype;
|
629 |
-
}
|
630 |
|
631 |
-
#
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
|
|
|
|
|
|
636 |
|
637 |
-
return
|
|
|
|
|
|
|
|
|
|
|
638 |
}
|
639 |
|
640 |
-
|
641 |
# remove emoji support
|
642 |
function fastvelocity_min_disable_wp_emojicons() {
|
643 |
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
|
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';
|
42 |
$cachedir = rtrim($upload['basedir'], '/').'/fvm/out';
|
43 |
$tmpdir = rtrim($upload['basedir'], '/').'/fvm/tmp';
|
44 |
$cachedirurl = rtrim($upload['baseurl'], '/').'/fvm/out';
|
45 |
+
$headerdir = rtrim($upload['basedir'], '/').'/fvm/header';
|
46 |
if(!is_dir($cachebase)) { mkdir($cachebase, 0755, true); }
|
47 |
if(!is_dir($cachedir)) { mkdir($cachedir, 0755, true); }
|
48 |
if(!is_dir($tmpdir)) { mkdir($tmpdir, 0755, true); }
|
49 |
+
if(!is_dir($headerdir)) { mkdir($headerdir, 0755, true); }
|
50 |
|
51 |
# return
|
52 |
+
return array('cachebase'=>$cachebase,'tmpdir'=>$tmpdir, 'cachedir'=>$cachedir, 'cachedirurl'=>$cachedirurl, 'headerdir'=>$headerdir);
|
53 |
}
|
54 |
|
55 |
|
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
|
257 |
|
258 |
# minify js on demand (one file at one time, for compatibility)
|
259 |
function fastvelocity_min_get_js($url, $js, $disable_js_minification) {
|
260 |
+
global $fvm_debug;
|
261 |
|
262 |
# exclude minification on already minified files + jquery (because minification might break those)
|
263 |
$excl = array('jquery.js', '.min.js', '-min.js', '/uploads/fusion-scripts/', '/min/', '.packed.js');
|
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.';'; }
|
284 |
+
if($fvm_debug == true) { $js = '/* info: ' . $url . ' */' . PHP_EOL . $js; }
|
285 |
|
286 |
# return html
|
287 |
+
return $js . PHP_EOL;
|
288 |
}
|
289 |
|
290 |
|
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
|
365 |
|
366 |
# minify css on demand (one file at one time, for compatibility)
|
367 |
function fastvelocity_min_get_css($url, $css, $disable_css_minification) {
|
368 |
+
global $wp_domain, $fvm_debug;
|
369 |
|
370 |
# remove BOM
|
371 |
$css = fastvelocity_min_remove_utf8_bom($css);
|
394 |
}
|
395 |
|
396 |
# add css comment
|
397 |
+
$css = trim($css);
|
398 |
+
if($fvm_debug == true) { $css = '/* info: ' . $url . ' */' . PHP_EOL . trim($css); }
|
399 |
|
400 |
# return html
|
401 |
return $css;
|
576 |
# Concatenate Google Fonts tags (http://fonts.googleapis.com/css?...)
|
577 |
function fastvelocity_min_concatenate_google_fonts($array) {
|
578 |
|
579 |
+
# extract unique font families
|
580 |
+
$families = array();
|
581 |
+
foreach ($array as $font) {
|
582 |
+
|
583 |
+
# get fonts name, type and subset, remove wp query strings
|
584 |
+
$font = explode('family=', htmlspecialchars_decode(rawurldecode(urldecode($font))));
|
585 |
+
$a = explode('&v', end($font));
|
586 |
+
$font = trim(trim(trim(current($a)), ','));
|
587 |
+
|
588 |
+
# reprocess if fonts are already concatenated in this url
|
589 |
+
if(stristr($font, '|') !== FALSE) {
|
590 |
+
$multiple = explode('|', $font);
|
591 |
+
if (count($multiple) > 0) {
|
592 |
+
foreach ($multiple as $f) {
|
593 |
+
$families[] = trim($f);
|
594 |
+
}
|
595 |
+
}
|
596 |
+
} else {
|
597 |
+
$families[] = $font;
|
598 |
+
}
|
599 |
+
}
|
600 |
+
|
601 |
+
# process names, types, subsets
|
602 |
+
$fonts = array();
|
603 |
+
$subsets = array();
|
604 |
+
foreach ($families as $font) {
|
605 |
+
|
606 |
+
# extract the subsets
|
607 |
+
if (stripos($font, 'subset') !== false) {
|
608 |
+
$sub = trim(str_ireplace('&subset=', '', stristr($font, '&'))); # second part of the string, after &
|
609 |
+
$font = stristr($font, '&', true); # font name, before &
|
610 |
+
|
611 |
+
# subsets to array, unique, trim
|
612 |
+
if (stripos($sub, ',') !== false) {
|
613 |
+
$ft = explode(',', $sub);
|
614 |
+
$ft = array_filter(array_map('trim', array_unique($ft)));
|
615 |
+
foreach ($ft as $s) {
|
616 |
+
$subsets[$s] = $s;
|
617 |
+
}
|
618 |
+
} else {
|
619 |
+
if (!empty($sub)) {
|
620 |
+
$subsets[$sub] = $sub;
|
621 |
+
}
|
622 |
+
}
|
623 |
+
|
624 |
+
}
|
625 |
+
|
626 |
+
# check for font name and weights
|
627 |
+
$ftypes = array();
|
628 |
+
$name = $font;
|
629 |
+
if (stripos($font, ':') !== false) {
|
630 |
+
$name = stristr($font, ':', true); # font name, before :
|
631 |
+
$fwe = trim(stristr($font, ':'), ':'); # second part of the string, after :
|
632 |
+
|
633 |
+
# ftypes to array, unique, trim
|
634 |
+
if (stripos($font, ',') !== false) {
|
635 |
+
$ft = explode(',', $fwe);
|
636 |
+
$ftypes = array_filter(array_map('trim', array_unique($ft)));
|
637 |
+
} else {
|
638 |
+
if (!empty($fwe)) {
|
639 |
+
$ftypes[] = $fwe;
|
640 |
+
}
|
641 |
+
}
|
642 |
+
|
643 |
+
}
|
644 |
+
|
645 |
+
# name filter
|
646 |
+
$name = str_ireplace(' ', '+', trim($name));
|
647 |
+
|
648 |
+
# save fonts list, merge fontweights
|
649 |
+
if(!isset($fonts[$name])) {
|
650 |
+
$fonts[$name] = array('name'=>$name, 'type'=>$ftypes);
|
651 |
+
} else {
|
652 |
+
$ftypes = array_merge($ftypes, $fonts[$name]['type']);
|
653 |
+
$fonts[$name] = array('name'=>$name, 'type'=>$ftypes);
|
654 |
+
}
|
655 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
656 |
}
|
657 |
|
658 |
+
# build font names with font weights
|
659 |
+
$build = array();
|
660 |
+
foreach($fonts as $farr) {
|
661 |
+
$f = $farr['name'];
|
662 |
+
if(count($farr['type']) > 0) {
|
663 |
+
$f.= ':'. implode(',', $farr['type']);
|
664 |
+
}
|
665 |
+
$build[] = $f;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
666 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
667 |
|
668 |
+
# merge, append subsets
|
669 |
+
$merge = '';
|
670 |
+
if(count($build) > 0) {
|
671 |
+
$merge = implode('|', $build);
|
672 |
+
if(count($subsets) > 0) {
|
673 |
+
$merge.= '&subset='.implode(',', $subsets);
|
674 |
+
}
|
675 |
+
}
|
676 |
|
677 |
+
# return
|
678 |
+
if(!empty($merge)) {
|
679 |
+
return 'https://fonts.googleapis.com/css?family='.$merge;
|
680 |
+
} else {
|
681 |
+
return false;
|
682 |
+
}
|
683 |
}
|
684 |
|
|
|
685 |
# remove emoji support
|
686 |
function fastvelocity_min_disable_wp_emojicons() {
|
687 |
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
|
libs/matthiasmullie/minify/src/CSS.php
CHANGED
@@ -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 |
/**
|
libs/matthiasmullie/minify/src/JS.php
CHANGED
@@ -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
|
libs/matthiasmullie/minify/src/Minify.php
CHANGED
@@ -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 |
|
libs/matthiasmullie/path-converter/src/Converter.php
CHANGED
@@ -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 |
}
|
readme.txt
CHANGED
@@ -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
|
@@ -111,6 +111,9 @@ The ignore list "is" working, just try to use partial paths (see wildcard help a
|
|
111 |
|
112 |
Please note, you must disable any features on your theme or cache plugins, which perform minification of css, html and js. Double minification not only slows the whole process, but also has the high potential of causing conflicts in javascript. The plugin will try to automatically purge several popular cache plugins, however if you have a cache on the server side (some hosting services have this) you may need to purge it manually, after you purge FVM. The automatic purge is active for the following plugins and hosting: W3 Total Cache, WP Supercache, WP Rocket, Wp Fastest Cache, Cachify, Comet Cache, Zen Cache, LiteSpeed Cache, Cache Enabler, SG Optimizer, Godaddy Managed WordPress Hosting and WP Engine
|
113 |
|
|
|
|
|
|
|
114 |
|
115 |
= Is it resource intensive, or will it use too much CPU on my shared hosting plan? =
|
116 |
|
@@ -199,6 +202,27 @@ If you would like to donate any amount to the plugin author (thank you in advanc
|
|
199 |
|
200 |
== Changelog ==
|
201 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
202 |
= 2.4.1 [2018.11.27] =
|
203 |
* better FVM default settings
|
204 |
|
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.4
|
6 |
Tested up to: 5.0
|
7 |
License: GPLv3 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
111 |
|
112 |
Please note, you must disable any features on your theme or cache plugins, which perform minification of css, html and js. Double minification not only slows the whole process, but also has the high potential of causing conflicts in javascript. The plugin will try to automatically purge several popular cache plugins, however if you have a cache on the server side (some hosting services have this) you may need to purge it manually, after you purge FVM. The automatic purge is active for the following plugins and hosting: W3 Total Cache, WP Supercache, WP Rocket, Wp Fastest Cache, Cachify, Comet Cache, Zen Cache, LiteSpeed Cache, Cache Enabler, SG Optimizer, Godaddy Managed WordPress Hosting and WP Engine
|
113 |
|
114 |
+
= Do you recommend a specific Cache Plugin? =
|
115 |
+
Yes! Currently FVM recommends the "Cache Enabler" plugin, for it's simplicity, compatibility with most systems and performance.
|
116 |
+
|
117 |
|
118 |
= Is it resource intensive, or will it use too much CPU on my shared hosting plan? =
|
119 |
|
202 |
|
203 |
== Changelog ==
|
204 |
|
205 |
+
= 2.4.4 [2018.12.03]
|
206 |
+
* added option to inline CSS in the footer, while still preserving the merged file in the header
|
207 |
+
* improvements for the google fonts merging option
|
208 |
+
* fixed double notification, when purging caches without a cache plugin
|
209 |
+
|
210 |
+
= 2.4.3 [2018.12.03] =
|
211 |
+
* added font-display, to ensure text remains visible during webfont load for inlined google fonts and font-awesome
|
212 |
+
* added automatic removal of "source mappings" from JS files during merging or minification
|
213 |
+
* added font awesome async and exclusion from PSI options, as well as merging and inlining when the url matches "font-awesome" (ie: cdnjs)
|
214 |
+
* added automatically inline of small CSS code (up to 20KB) for any FVM CSS files in the footer (requests reduction)
|
215 |
+
* added automatically inline of small CSS code (up to 20KB) for any FVM CSS files in the header, which are not of mediatype "all"
|
216 |
+
* improved the cache purge button (no more redirect from frontend to backend)
|
217 |
+
* updated PHP Minify and Path Converter from master
|
218 |
+
* bug fixes related to "Exclude JS files from PSI" option
|
219 |
+
|
220 |
+
= 2.4.2 [2018.11.29] =
|
221 |
+
* fixed a bug with the "Exclude JS files in the ignore list from PSI" option (it wasn't excluding properly)
|
222 |
+
* improved functionality with the "Exclude CSS files from PSI" option (now works with both inline and link stylesheets)
|
223 |
+
* added an option to automatically preload the CSS and JS files generated by FVM (beware that some server caches like Pantheon may push old css and js files even after purging caches on FVM)
|
224 |
+
* improved JavaScript minification
|
225 |
+
|
226 |
= 2.4.1 [2018.11.27] =
|
227 |
* better FVM default settings
|
228 |
|