Fast Velocity Minify - Version 3.3.0

Version Description

[2022.10.06] = * fixed minification error on html pre tags * fixed an error notice * bumped minimum requirements to PHP 7 and WP 5

Download this release

Release Info

Developer Alignak
Plugin Icon 128x128 Fast Velocity Minify
Version 3.3.0
Comparing to
See all releases

Code changes from version 3.2.9 to 3.3.0

Files changed (4) hide show
  1. fvm.php +8 -10
  2. inc/common.php +1 -1
  3. libs/raisermin/minify.php +28 -0
  4. readme.txt +8 -3
fvm.php CHANGED
@@ -6,7 +6,7 @@ Description: Improve your speed score on GTmetrix, Pingdom Tools and Google Page
6
  Author: Raul Peixoto
7
  Author URI: http://fastvelocity.com
8
  Text Domain: fast-velocity-minify
9
- Version: 3.2.9
10
  License: GPL2
11
 
12
  ------------------------------------------------------------------------
@@ -34,13 +34,14 @@ if(function_exists('wp_opcache_invalidate') && stripos(__FILE__, '/fvm.php') !==
34
  }
35
 
36
  # info, variables, paths
37
- $fvm_var_file = __FILE__; # /home/path/plugins/pluginname/wpr.php
 
 
 
 
38
  $fvm_var_basename = plugin_basename($fvm_var_file); # pluginname/wpr.php
39
- $fvm_var_dir_path = plugin_dir_path($fvm_var_file); # /home/path/plugins/pluginname/
40
  $fvm_var_url_path = plugins_url(dirname($fvm_var_basename)) . '/'; # https://example.com/wp-content/plugins/pluginname/
41
  $fvm_var_plugin_version = get_file_data($fvm_var_file, array('Version' => 'Version'), false)['Version'];
42
- $fvm_var_inc_dir = $fvm_var_dir_path . 'inc' . DIRECTORY_SEPARATOR; # /home/path/plugins/pluginname/inc/
43
- $fvm_var_inc_lib = $fvm_var_dir_path . 'libs' . DIRECTORY_SEPARATOR; # /home/path/plugins/pluginname/libs/
44
 
45
  # global functions for backend, frontend, ajax, etc
46
  require_once($fvm_var_inc_dir . 'common.php');
@@ -85,7 +86,7 @@ if(is_admin()) {
85
  add_action('avada_clear_dynamic_css_cache', 'fvm_purge_all');
86
  add_action('upgrader_process_complete', 'fvm_purge_all');
87
  add_action('update_option_theme_mods_' . get_option('stylesheet'), 'fvm_purge_all');
88
-
89
  }
90
 
91
 
@@ -104,10 +105,7 @@ if(!is_admin()) {
104
  add_action('init', 'fvm_process_cache_purge_request');
105
 
106
  # actions for frontend only
107
- add_action('template_redirect', 'fvm_start_buffer', PHP_INT_MAX);
108
-
109
- # actions for frontend only
110
- add_action('template_redirect', 'fvm_start_buffer', PHP_INT_MAX);
111
 
112
  }
113
 
6
  Author: Raul Peixoto
7
  Author URI: http://fastvelocity.com
8
  Text Domain: fast-velocity-minify
9
+ Version: 3.3.0
10
  License: GPL2
11
 
12
  ------------------------------------------------------------------------
34
  }
35
 
36
  # info, variables, paths
37
+ if (!defined('FVM_DIR')) { define('FVM_DIR', __DIR__ . '/'); } # /home/path/plugins/pluginname/
38
+ $fvm_var_dir_path = FVM_DIR; # /home/path/plugins/pluginname/
39
+ $fvm_var_file = FVM_DIR . 'fvm.php'; # /home/path/plugins/pluginname/wpr.php
40
+ $fvm_var_inc_dir = FVM_DIR . 'inc' . DIRECTORY_SEPARATOR; # /home/path/plugins/pluginname/inc/
41
+ $fvm_var_inc_lib = FVM_DIR . 'libs' . DIRECTORY_SEPARATOR; # /home/path/plugins/pluginname/libs/
42
  $fvm_var_basename = plugin_basename($fvm_var_file); # pluginname/wpr.php
 
43
  $fvm_var_url_path = plugins_url(dirname($fvm_var_basename)) . '/'; # https://example.com/wp-content/plugins/pluginname/
44
  $fvm_var_plugin_version = get_file_data($fvm_var_file, array('Version' => 'Version'), false)['Version'];
 
 
45
 
46
  # global functions for backend, frontend, ajax, etc
47
  require_once($fvm_var_inc_dir . 'common.php');
86
  add_action('avada_clear_dynamic_css_cache', 'fvm_purge_all');
87
  add_action('upgrader_process_complete', 'fvm_purge_all');
88
  add_action('update_option_theme_mods_' . get_option('stylesheet'), 'fvm_purge_all');
89
+
90
  }
91
 
92
 
105
  add_action('init', 'fvm_process_cache_purge_request');
106
 
107
  # actions for frontend only
108
+ add_action('template_redirect', 'fvm_start_buffer', 999999);
 
 
 
109
 
110
  }
111
 
inc/common.php CHANGED
@@ -2168,7 +2168,7 @@ function fvm_maybe_download($url) {
2168
  function fvm_add_header_function($html) {
2169
 
2170
  # based on wp rocket delay js feature
2171
- $fvmf.= <<<'EOF'
2172
  <script data-cfasync="false">if(navigator.userAgent.match(/MSIE|Internet Explorer/i)||navigator.userAgent.match(/Trident\/7\..*?rv:11/i)){var href=document.location.href;if(!href.match(/[?&]iebrowser/)){if(href.indexOf("?")==-1){if(href.indexOf("#")==-1){document.location.href=href+"?iebrowser=1"}else{document.location.href=href.replace("#","?iebrowser=1#")}}else{if(href.indexOf("#")==-1){document.location.href=href+"&iebrowser=1"}else{document.location.href=href.replace("#","&iebrowser=1#")}}}}</script>
2173
  <script data-cfasync="false">class FVMLoader{constructor(e){this.triggerEvents=e,this.eventOptions={passive:!0},this.userEventListener=this.triggerListener.bind(this),this.delayedScripts={normal:[],async:[],defer:[]},this.allJQueries=[]}_addUserInteractionListener(e){this.triggerEvents.forEach(t=>window.addEventListener(t,e.userEventListener,e.eventOptions))}_removeUserInteractionListener(e){this.triggerEvents.forEach(t=>window.removeEventListener(t,e.userEventListener,e.eventOptions))}triggerListener(){this._removeUserInteractionListener(this),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",this._loadEverythingNow.bind(this)):this._loadEverythingNow()}async _loadEverythingNow(){this._runAllDelayedCSS(),this._delayEventListeners(),this._delayJQueryReady(this),this._handleDocumentWrite(),this._registerAllDelayedScripts(),await this._loadScriptsFromList(this.delayedScripts.normal),await this._loadScriptsFromList(this.delayedScripts.defer),await this._loadScriptsFromList(this.delayedScripts.async),await this._triggerDOMContentLoaded(),await this._triggerWindowLoad(),window.dispatchEvent(new Event("wpr-allScriptsLoaded"))}_registerAllDelayedScripts(){document.querySelectorAll("script[type=fvmdelay]").forEach(e=>{e.hasAttribute("src")?e.hasAttribute("async")&&!1!==e.async?this.delayedScripts.async.push(e):e.hasAttribute("defer")&&!1!==e.defer||"module"===e.getAttribute("data-type")?this.delayedScripts.defer.push(e):this.delayedScripts.normal.push(e):this.delayedScripts.normal.push(e)})}_runAllDelayedCSS(){document.querySelectorAll("link[rel=fvmdelay]").forEach(e=>{e.setAttribute("rel","stylesheet")})}async _transformScript(e){return await this._requestAnimFrame(),new Promise(t=>{const n=document.createElement("script");let r;[...e.attributes].forEach(e=>{let t=e.nodeName;"type"!==t&&("data-type"===t&&(t="type",r=e.nodeValue),n.setAttribute(t,e.nodeValue))}),e.hasAttribute("src")?(n.addEventListener("load",t),n.addEventListener("error",t)):(n.text=e.text,t()),e.parentNode.replaceChild(n,e)})}async _loadScriptsFromList(e){const t=e.shift();return t?(await this._transformScript(t),this._loadScriptsFromList(e)):Promise.resolve()}_delayEventListeners(){let e={};function t(t,n){!function(t){function n(n){return e[t].eventsToRewrite.indexOf(n)>=0?"wpr-"+n:n}e[t]||(e[t]={originalFunctions:{add:t.addEventListener,remove:t.removeEventListener},eventsToRewrite:[]},t.addEventListener=function(){arguments[0]=n(arguments[0]),e[t].originalFunctions.add.apply(t,arguments)},t.removeEventListener=function(){arguments[0]=n(arguments[0]),e[t].originalFunctions.remove.apply(t,arguments)})}(t),e[t].eventsToRewrite.push(n)}function n(e,t){let n=e[t];Object.defineProperty(e,t,{get:()=>n||function(){},set(r){e["wpr"+t]=n=r}})}t(document,"DOMContentLoaded"),t(window,"DOMContentLoaded"),t(window,"load"),t(window,"pageshow"),t(document,"readystatechange"),n(document,"onreadystatechange"),n(window,"onload"),n(window,"onpageshow")}_delayJQueryReady(e){let t=window.jQuery;Object.defineProperty(window,"jQuery",{get:()=>t,set(n){if(n&&n.fn&&!e.allJQueries.includes(n)){n.fn.ready=n.fn.init.prototype.ready=function(t){e.domReadyFired?t.bind(document)(n):document.addEventListener("DOMContentLoaded2",()=>t.bind(document)(n))};const t=n.fn.on;n.fn.on=n.fn.init.prototype.on=function(){if(this[0]===window){function e(e){return e.split(" ").map(e=>"load"===e||0===e.indexOf("load.")?"wpr-jquery-load":e).join(" ")}"string"==typeof arguments[0]||arguments[0]instanceof String?arguments[0]=e(arguments[0]):"object"==typeof arguments[0]&&Object.keys(arguments[0]).forEach(t=>{delete Object.assign(arguments[0],{[e(t)]:arguments[0][t]})[t]})}return t.apply(this,arguments),this},e.allJQueries.push(n)}t=n}})}async _triggerDOMContentLoaded(){this.domReadyFired=!0,await this._requestAnimFrame(),document.dispatchEvent(new Event("DOMContentLoaded2")),await this._requestAnimFrame(),window.dispatchEvent(new Event("DOMContentLoaded2")),await this._requestAnimFrame(),document.dispatchEvent(new Event("wpr-readystatechange")),await this._requestAnimFrame(),document.wpronreadystatechange&&document.wpronreadystatechange()}async _triggerWindowLoad(){await this._requestAnimFrame(),window.dispatchEvent(new Event("wpr-load")),await this._requestAnimFrame(),window.wpronload&&window.wpronload(),await this._requestAnimFrame(),this.allJQueries.forEach(e=>e(window).trigger("wpr-jquery-load")),window.dispatchEvent(new Event("wpr-pageshow")),await this._requestAnimFrame(),window.wpronpageshow&&window.wpronpageshow()}_handleDocumentWrite(){const e=new Map;document.write=document.writeln=function(t){const n=document.currentScript,r=document.createRange(),i=n.parentElement;let a=e.get(n);void 0===a&&(a=n.nextSibling,e.set(n,a));const s=document.createDocumentFragment();r.setStart(s,0),s.appendChild(r.createContextualFragment(t)),i.insertBefore(s,a)}}async _requestAnimFrame(){return new Promise(e=>requestAnimationFrame(e))}static run(){const e=new FVMLoader(["keydown","mousemove","touchmove","touchstart","touchend","wheel"]);e._addUserInteractionListener(e)}}FVMLoader.run();</script>
2174
  EOF;
2168
  function fvm_add_header_function($html) {
2169
 
2170
  # based on wp rocket delay js feature
2171
+ $fvmf = <<<'EOF'
2172
  <script data-cfasync="false">if(navigator.userAgent.match(/MSIE|Internet Explorer/i)||navigator.userAgent.match(/Trident\/7\..*?rv:11/i)){var href=document.location.href;if(!href.match(/[?&]iebrowser/)){if(href.indexOf("?")==-1){if(href.indexOf("#")==-1){document.location.href=href+"?iebrowser=1"}else{document.location.href=href.replace("#","?iebrowser=1#")}}else{if(href.indexOf("#")==-1){document.location.href=href+"&iebrowser=1"}else{document.location.href=href.replace("#","&iebrowser=1#")}}}}</script>
2173
  <script data-cfasync="false">class FVMLoader{constructor(e){this.triggerEvents=e,this.eventOptions={passive:!0},this.userEventListener=this.triggerListener.bind(this),this.delayedScripts={normal:[],async:[],defer:[]},this.allJQueries=[]}_addUserInteractionListener(e){this.triggerEvents.forEach(t=>window.addEventListener(t,e.userEventListener,e.eventOptions))}_removeUserInteractionListener(e){this.triggerEvents.forEach(t=>window.removeEventListener(t,e.userEventListener,e.eventOptions))}triggerListener(){this._removeUserInteractionListener(this),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",this._loadEverythingNow.bind(this)):this._loadEverythingNow()}async _loadEverythingNow(){this._runAllDelayedCSS(),this._delayEventListeners(),this._delayJQueryReady(this),this._handleDocumentWrite(),this._registerAllDelayedScripts(),await this._loadScriptsFromList(this.delayedScripts.normal),await this._loadScriptsFromList(this.delayedScripts.defer),await this._loadScriptsFromList(this.delayedScripts.async),await this._triggerDOMContentLoaded(),await this._triggerWindowLoad(),window.dispatchEvent(new Event("wpr-allScriptsLoaded"))}_registerAllDelayedScripts(){document.querySelectorAll("script[type=fvmdelay]").forEach(e=>{e.hasAttribute("src")?e.hasAttribute("async")&&!1!==e.async?this.delayedScripts.async.push(e):e.hasAttribute("defer")&&!1!==e.defer||"module"===e.getAttribute("data-type")?this.delayedScripts.defer.push(e):this.delayedScripts.normal.push(e):this.delayedScripts.normal.push(e)})}_runAllDelayedCSS(){document.querySelectorAll("link[rel=fvmdelay]").forEach(e=>{e.setAttribute("rel","stylesheet")})}async _transformScript(e){return await this._requestAnimFrame(),new Promise(t=>{const n=document.createElement("script");let r;[...e.attributes].forEach(e=>{let t=e.nodeName;"type"!==t&&("data-type"===t&&(t="type",r=e.nodeValue),n.setAttribute(t,e.nodeValue))}),e.hasAttribute("src")?(n.addEventListener("load",t),n.addEventListener("error",t)):(n.text=e.text,t()),e.parentNode.replaceChild(n,e)})}async _loadScriptsFromList(e){const t=e.shift();return t?(await this._transformScript(t),this._loadScriptsFromList(e)):Promise.resolve()}_delayEventListeners(){let e={};function t(t,n){!function(t){function n(n){return e[t].eventsToRewrite.indexOf(n)>=0?"wpr-"+n:n}e[t]||(e[t]={originalFunctions:{add:t.addEventListener,remove:t.removeEventListener},eventsToRewrite:[]},t.addEventListener=function(){arguments[0]=n(arguments[0]),e[t].originalFunctions.add.apply(t,arguments)},t.removeEventListener=function(){arguments[0]=n(arguments[0]),e[t].originalFunctions.remove.apply(t,arguments)})}(t),e[t].eventsToRewrite.push(n)}function n(e,t){let n=e[t];Object.defineProperty(e,t,{get:()=>n||function(){},set(r){e["wpr"+t]=n=r}})}t(document,"DOMContentLoaded"),t(window,"DOMContentLoaded"),t(window,"load"),t(window,"pageshow"),t(document,"readystatechange"),n(document,"onreadystatechange"),n(window,"onload"),n(window,"onpageshow")}_delayJQueryReady(e){let t=window.jQuery;Object.defineProperty(window,"jQuery",{get:()=>t,set(n){if(n&&n.fn&&!e.allJQueries.includes(n)){n.fn.ready=n.fn.init.prototype.ready=function(t){e.domReadyFired?t.bind(document)(n):document.addEventListener("DOMContentLoaded2",()=>t.bind(document)(n))};const t=n.fn.on;n.fn.on=n.fn.init.prototype.on=function(){if(this[0]===window){function e(e){return e.split(" ").map(e=>"load"===e||0===e.indexOf("load.")?"wpr-jquery-load":e).join(" ")}"string"==typeof arguments[0]||arguments[0]instanceof String?arguments[0]=e(arguments[0]):"object"==typeof arguments[0]&&Object.keys(arguments[0]).forEach(t=>{delete Object.assign(arguments[0],{[e(t)]:arguments[0][t]})[t]})}return t.apply(this,arguments),this},e.allJQueries.push(n)}t=n}})}async _triggerDOMContentLoaded(){this.domReadyFired=!0,await this._requestAnimFrame(),document.dispatchEvent(new Event("DOMContentLoaded2")),await this._requestAnimFrame(),window.dispatchEvent(new Event("DOMContentLoaded2")),await this._requestAnimFrame(),document.dispatchEvent(new Event("wpr-readystatechange")),await this._requestAnimFrame(),document.wpronreadystatechange&&document.wpronreadystatechange()}async _triggerWindowLoad(){await this._requestAnimFrame(),window.dispatchEvent(new Event("wpr-load")),await this._requestAnimFrame(),window.wpronload&&window.wpronload(),await this._requestAnimFrame(),this.allJQueries.forEach(e=>e(window).trigger("wpr-jquery-load")),window.dispatchEvent(new Event("wpr-pageshow")),await this._requestAnimFrame(),window.wpronpageshow&&window.wpronpageshow()}_handleDocumentWrite(){const e=new Map;document.write=document.writeln=function(t){const n=document.currentScript,r=document.createRange(),i=n.parentElement;let a=e.get(n);void 0===a&&(a=n.nextSibling,e.set(n,a));const s=document.createDocumentFragment();r.setStart(s,0),s.appendChild(r.createContextualFragment(t)),i.insertBefore(s,a)}}async _requestAnimFrame(){return new Promise(e=>requestAnimationFrame(e))}static run(){const e=new FVMLoader(["keydown","mousemove","touchmove","touchstart","touchend","wheel"]);e._addUserInteractionListener(e)}}FVMLoader.run();</script>
2174
  EOF;
libs/raisermin/minify.php CHANGED
@@ -15,6 +15,20 @@ if (!defined('ABSPATH')){ exit(); }
15
 
16
  # minify js, whitespace only
17
  function fvm_raisermin_js($code){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  # remove // comments
20
  $code = preg_replace('/(^|\s)\/\/(.*)\n/m', '', $code);
@@ -46,6 +60,20 @@ function fvm_raisermin_js($code){
46
  $code = preg_replace('/(\,)(\h+)/ui', '$1 ', $code);
47
  $code = preg_replace('/(\h+)(\,)/ui', ' $2', $code);
48
  $code = preg_replace('/([if])(\h+)(\()/ui', '$1$3', $code);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
  # trim whitespace on beginning/end
51
  return trim($code);
15
 
16
  # minify js, whitespace only
17
  function fvm_raisermin_js($code){
18
+
19
+ # tags to preserve
20
+ $restore = array();
21
+
22
+ # encode pre tags
23
+ $pattern = "/<pre\s?(.*)>(.*)<\/pre>/ium";
24
+ $matches = array();
25
+ if(preg_match_all($pattern, $code, $matches)) {
26
+ foreach($matches[0] as $tag) {
27
+ $enc = base64_encode($tag);
28
+ $restore[$enc] = $tag;
29
+ $code = str_replace($tag, $enc, $code);
30
+ }
31
+ }
32
 
33
  # remove // comments
34
  $code = preg_replace('/(^|\s)\/\/(.*)\n/m', '', $code);
60
  $code = preg_replace('/(\,)(\h+)/ui', '$1 ', $code);
61
  $code = preg_replace('/(\h+)(\,)/ui', ' $2', $code);
62
  $code = preg_replace('/([if])(\h+)(\()/ui', '$1$3', $code);
63
+
64
+ # restore pre tags
65
+ if(is_array($restore) && count($restore) > 0) {
66
+ foreach($restore as $enc=>$tag) {
67
+ $code = str_replace($enc, $tag, $code);
68
+ }
69
+ }
70
+
71
+ # restore pre tags
72
+ if(is_array($restore) && count($restore) > 0) {
73
+ foreach($restore as $enc=>$tag) {
74
+ $code = str_replace($enc, $tag, $code);
75
+ }
76
+ }
77
 
78
  # trim whitespace on beginning/end
79
  return trim($code);
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
  === Fast Velocity Minify ===
2
  Contributors: Alignak
3
  Tags: PHP Minify, Lighthouse, GTmetrix, Pingdom, Pagespeed, Merging, Minification, Optimization, Speed, Performance, FVM
4
- Requires at least: 4.9
5
- Requires PHP: 5.6
6
- Stable tag: 3.2.9
7
  Tested up to: 6.0.2
8
  Text Domain: fast-velocity-minify
9
  License: GPLv3 or later
@@ -49,6 +49,11 @@ You need a public directory to store and serve minified cache files. If you need
49
 
50
  == Changelog ==
51
 
 
 
 
 
 
52
  = 3.2.9 [2022.08.30] =
53
  * legacy code removal and other bugfixes
54
 
1
  === Fast Velocity Minify ===
2
  Contributors: Alignak
3
  Tags: PHP Minify, Lighthouse, GTmetrix, Pingdom, Pagespeed, Merging, Minification, Optimization, Speed, Performance, FVM
4
+ Requires at least: 5.0
5
+ Requires PHP: 7.0
6
+ Stable tag: 3.3.0
7
  Tested up to: 6.0.2
8
  Text Domain: fast-velocity-minify
9
  License: GPLv3 or later
49
 
50
  == Changelog ==
51
 
52
+ = 3.3.0 [2022.10.06] =
53
+ * fixed minification error on html pre tags
54
+ * fixed an error notice
55
+ * bumped minimum requirements to PHP 7 and WP 5
56
+
57
  = 3.2.9 [2022.08.30] =
58
  * legacy code removal and other bugfixes
59