Fast Velocity Minify - Version 2.2.4

Version Description

Note: Kindly re-save all options and purge all caches (the plugin cache as well as your server /plugin cache).

=

Download this release

Release Info

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

Code changes from version 2.2.3 to 2.2.4

fvm.js CHANGED
@@ -87,8 +87,12 @@
87
 
88
 
89
  $.post(ajaxurl, data, function(response) {
 
 
 
 
90
 
91
- if(stamp == response.stamp) {
92
  if(response.js.length > 0) {
93
  $fastvelocity_min_jsprocessed.show();
94
 
@@ -99,7 +103,7 @@
99
  $li.find('pre').html(this.log);
100
  }
101
  } else {
102
- $fastvelocity_min_jsprocessed_ul.append('<li class="'+this.hash+'"><span class="filename">'+this.filename+'</span> <span class="actions"><a href="#" class="log button button-primary">View Log</a></span><pre>'+this.log+'</pre></li><div class="clear"></div>');
103
  }
104
  });
105
 
@@ -113,13 +117,13 @@
113
  $li.find('pre').html(this.log);
114
  }
115
  } else {
116
- $fastvelocity_min_cssprocessed_ul.append('<li class="'+this.hash+'"><span class="filename">'+this.filename+'</span> <span class="actions"><a href="#" class="log button button-primary">View Log</a></span><pre>'+this.log+'</pre></li><div class="clear"></div>');
117
  }
118
  });
119
  }
120
 
121
  // check for new files
122
- timeout = setTimeout(getFiles, 2500);
123
  }
124
  });
125
  }
87
 
88
 
89
  $.post(ajaxurl, data, function(response) {
90
+
91
+ if(response.cachesize.length > 0) {
92
+ $("#fvm_cache_size").html(response.cachesize);
93
+ }
94
 
95
+ if(stamp == response.stamp) {
96
  if(response.js.length > 0) {
97
  $fastvelocity_min_jsprocessed.show();
98
 
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
 
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
  }
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.2.3
9
  License: GPL2
10
 
11
  ------------------------------------------------------------------------
@@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26
 
27
 
28
  # check for minimum requirements and prevent activation or disable if not fully compatible
29
- function fvm_compat_checker() {
30
  global $wp_version;
31
 
32
  # defaults
@@ -71,7 +71,6 @@ $tmpdir = $cachepath['tmpdir'];
71
  $cachedir = $cachepath['cachedir'];
72
  $cachedirurl = $cachepath['cachedirurl'];
73
 
74
- # get the current wordpress installation url and path
75
  $wp_home = site_url(); # get the current wordpress installation url
76
  $wp_domain = trim(str_ireplace(array('http://', 'https://'), '', trim($wp_home, '/')));
77
  $wp_home_path = ABSPATH;
@@ -124,7 +123,6 @@ $fvm_remove_css = get_option('fastvelocity_min_fvm_removecss');
124
  $critical_path_css = get_option('fastvelocity_min_critical_path_css');
125
  $fvm_cdn_url = get_option('fastvelocity_min_fvm_cdn_url');
126
 
127
-
128
  # default options
129
  $used_css_files = array();
130
 
@@ -205,7 +203,8 @@ function fastvelocity_min_files_callback() {
205
  global $cachedir;
206
 
207
  # default
208
- $return = array('js' => array(), 'css' => array(), 'stamp' => $_POST['stamp']);
 
209
 
210
  # inspect directory with opendir, since glob might not be available in some systems
211
  if ($handle = opendir($cachedir.'/')) {
@@ -219,11 +218,12 @@ function fastvelocity_min_files_callback() {
219
  $filename = basename($file);
220
  if ($ext == 'css' && file_exists($mincss)) { $filename = basename($mincss); }
221
  if ($ext == 'js' && file_exists($minjs)) { $filename = basename($minjs); }
 
222
 
223
- # get location, hash, modified date
224
  $info = explode('-', $filename);
225
  $hash = $info['1'];
226
- array_push($return[$ext], array('hash' => $hash, 'filename' => $filename, 'log' => $log));
227
  }
228
  }
229
  closedir($handle);
@@ -281,6 +281,8 @@ function fastvelocity_min_register_settings() {
281
  register_setting('fvm-group-pro', 'fastvelocity_min_ignorelist');
282
  register_setting('fvm-group-pro', 'fastvelocity_min_blacklist');
283
  register_setting('fvm-group-pro', 'fastvelocity_min_merge_allowed_urls');
 
 
284
  }
285
 
286
 
@@ -342,7 +344,7 @@ echo fastvelocity_purge_others(); # purge third party caches
342
  <div class="inside" id="fastvelocity_min_topbtns">
343
  <ul class="processed">
344
  <li id="purgeall-row">
345
- <span class="filename">Purge processed CSS and JS files (<?php echo fastvelocity_get_cachestats(); ?>)</span>
346
  <span class="actions">
347
  <form method="post" id="fastvelocity_min_clearall" action="<?php echo admin_url('options-general.php?page=fastvelocity-min&tab=status'); ?>">
348
  <input type="hidden" name="purgeall" value="1" />
@@ -593,7 +595,7 @@ Skip deferring completely on the login page <span class="note-info">[ If selecte
593
 
594
  <div style="height: 20px;"></div>
595
  <h2 class="title">CDN Options</h2>
596
- <p class="fvm-bold-green">Use this to map your static assets to your cdn url.</p>
597
 
598
  <table class="form-table fvm-settings">
599
  <tbody>
@@ -602,7 +604,7 @@ Skip deferring completely on the login page <span class="note-info">[ If selecte
602
  <td><fieldset>
603
  <label for="fastvelocity_min_fvm_cdn_url">
604
  <p><input type="text" name="fastvelocity_min_fvm_cdn_url" id="fastvelocity_min_fvm_cdn_url" value="<?php echo get_option('fastvelocity_min_fvm_cdn_url', ''); ?>" size="80" /></p>
605
- <p class="description">[ This will rewrite the generated CSS and JS urls to use your cdn domain name, ie: cdn.example.com ]</p></label>
606
  </fieldset></td>
607
  </tr>
608
  </tbody></table>
@@ -675,7 +677,7 @@ Skip deferring completely on the login page <span class="note-info">[ If selecte
675
  <p>
676
  <textarea name="fastvelocity_min_critical_path_css" rows="10" cols="50" id="fastvelocity_min_critical_path_css" class="large-text code" placeholder="your css code here"><?php echo get_option('fastvelocity_min_critical_path_css'); ?></textarea>
677
  </p>
678
- <p class="description">[ Use this if you're familiar with <a target="_blank" href="https://github.com/giakki/uncss">UnCSS</a> or have the critical path css. ]</p>
679
  </fieldset>
680
  </td>
681
  </tr>
@@ -686,8 +688,8 @@ Skip deferring completely on the login page <span class="note-info">[ If selecte
686
  <td><fieldset>
687
  <label for="fastvelocity_min_fvm_removecss">
688
  <input name="fastvelocity_min_fvm_removecss" type="checkbox" id="fastvelocity_min_fvm_removecss" value="1" <?php echo checked(1 == get_option('fastvelocity_min_fvm_removecss'), true, false); ?>>
689
- Dequeue all CSS files <span class="note-info">[ Use this if you have your own uncss stylesheet or want to test how the critical path css looks ]</span></label>
690
- </td>
691
  </tr>
692
  </tbody></table>
693
 
@@ -703,7 +705,7 @@ Dequeue all CSS files <span class="note-info">[ Use this if you have your own un
703
  <td><fieldset>
704
  <label for="fastvelocity_min_loadcss">
705
  <input name="fastvelocity_min_loadcss" type="checkbox" id="fastvelocity_min_loadcss" value="1" <?php echo checked(1 == get_option('fastvelocity_min_loadcss'), true, false); ?>>
706
- Async CSS with LoadCSS<span class="note-info">[ Only works if "Inline all header /footer CSS files" is disabled ]</span></label>
707
  </fieldset>
708
  </td>
709
  </tr>
@@ -762,6 +764,32 @@ Async CSS with LoadCSS<span class="note-info">[ Only works if "Inline all header
762
  </tbody></table>
763
 
764
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
765
  <p class="submit"><input type="submit" name="fastvelocity_min_save_options" id="fastvelocity_min_save_options" class="button button-primary" value="Save Changes"></p>
766
  </form>
767
 
@@ -1302,7 +1330,7 @@ if(!$skip_cssorder) {
1302
  }
1303
  }
1304
 
1305
- # critical path + default visibility styles
1306
  if(!empty($critical_path_css) && $critical_path_css != false) {
1307
  echo '<style id="critical-path-global" type="text/css" media="all">'.$critical_path_css.'</style>'."\n";
1308
  }
@@ -1388,9 +1416,16 @@ for($i=0,$l=count($header);$i<$l;$i++) {
1388
 
1389
  # save to some sort of global and show it on the footer
1390
  $mt = $header[$i]['media'];
 
 
 
 
 
 
1391
  echo <<<EOF
1392
  <script type="text/javascript">var ldfvm$i=document.createElement("link");ldfvm$i.rel="stylesheet",ldfvm$i.type="text/css",ldfvm$i.media="bogus",ldfvm$i.href="$file_url",ldfvm$i.onload=function(){ldfvm$i.media="$mt"},document.getElementsByTagName("head")[0].appendChild(ldfvm$i);</script>
1393
  EOF;
 
1394
 
1395
  }
1396
  } else {
@@ -1445,14 +1480,6 @@ if($fvm_remove_css != false) {
1445
  # add defaults to ignore list
1446
  $ignore = fastvelocity_default_ignore($ignore);
1447
 
1448
- # header styles that moved to footer
1449
- if(isset($GLOBALS["fvm-css"]) && is_array($GLOBALS["fvm-css"])) {
1450
- foreach ($GLOBALS["fvm-css"] as $st) {
1451
- if(!empty($st)) { echo $st; }
1452
- }
1453
- }
1454
-
1455
-
1456
  # google fonts to the top
1457
  foreach( $styles->to_do as $handle ) :
1458
  # dequeue and get a list of google fonts, or requeue external
@@ -1668,6 +1695,25 @@ $wp_styles->done = $done;
1668
 
1669
 
1670
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1671
 
1672
  ###########################################
1673
  # add preconnect and preload headers
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.2.4
9
  License: GPL2
10
 
11
  ------------------------------------------------------------------------
26
 
27
 
28
  # check for minimum requirements and prevent activation or disable if not fully compatible
29
+ function fvm_compat_checker() {
30
  global $wp_version;
31
 
32
  # defaults
71
  $cachedir = $cachepath['cachedir'];
72
  $cachedirurl = $cachepath['cachedirurl'];
73
 
 
74
  $wp_home = site_url(); # get the current wordpress installation url
75
  $wp_domain = trim(str_ireplace(array('http://', 'https://'), '', trim($wp_home, '/')));
76
  $wp_home_path = ABSPATH;
123
  $critical_path_css = get_option('fastvelocity_min_critical_path_css');
124
  $fvm_cdn_url = get_option('fastvelocity_min_fvm_cdn_url');
125
 
 
126
  # default options
127
  $used_css_files = array();
128
 
203
  global $cachedir;
204
 
205
  # default
206
+ $size = fastvelocity_get_cachestats();
207
+ $return = array('js' => array(), 'css' => array(), 'stamp' => $_POST['stamp'], 'cachesize'=> $size);
208
 
209
  # inspect directory with opendir, since glob might not be available in some systems
210
  if ($handle = opendir($cachedir.'/')) {
218
  $filename = basename($file);
219
  if ($ext == 'css' && file_exists($mincss)) { $filename = basename($mincss); }
220
  if ($ext == 'js' && file_exists($minjs)) { $filename = basename($minjs); }
221
+ $fsize = fastvelocity_format_filesize(filesize($file));
222
 
223
+ # get location, hash, log
224
  $info = explode('-', $filename);
225
  $hash = $info['1'];
226
+ array_push($return[$ext], array('hash' => $hash, 'filename' => $filename, 'log' => $log, 'fsize' => $fsize));
227
  }
228
  }
229
  closedir($handle);
281
  register_setting('fvm-group-pro', 'fastvelocity_min_ignorelist');
282
  register_setting('fvm-group-pro', 'fastvelocity_min_blacklist');
283
  register_setting('fvm-group-pro', 'fastvelocity_min_merge_allowed_urls');
284
+ register_setting('fvm-group-pro', 'fastvelocity_min_change_cache_path');
285
+ register_setting('fvm-group-pro', 'fastvelocity_min_change_cache_base_url');
286
  }
287
 
288
 
344
  <div class="inside" id="fastvelocity_min_topbtns">
345
  <ul class="processed">
346
  <li id="purgeall-row">
347
+ <span class="filename">Purge FVM cache directory (<span id="fvm_cache_size"><?php echo fastvelocity_get_cachestats(); ?></span>)</span>
348
  <span class="actions">
349
  <form method="post" id="fastvelocity_min_clearall" action="<?php echo admin_url('options-general.php?page=fastvelocity-min&tab=status'); ?>">
350
  <input type="hidden" name="purgeall" value="1" />
595
 
596
  <div style="height: 20px;"></div>
597
  <h2 class="title">CDN Options</h2>
598
+ <p class="fvm-bold-green">If the "Enable defer of JS for Pagespeed Insights" option is enabled, JS and CSS files will not be loaded from the CDN.<br />However, the static assets used inside the CSS and JS files will load from the CDN directly.</p>
599
 
600
  <table class="form-table fvm-settings">
601
  <tbody>
604
  <td><fieldset>
605
  <label for="fastvelocity_min_fvm_cdn_url">
606
  <p><input type="text" name="fastvelocity_min_fvm_cdn_url" id="fastvelocity_min_fvm_cdn_url" value="<?php echo get_option('fastvelocity_min_fvm_cdn_url', ''); ?>" size="80" /></p>
607
+ <p class="description">[ Load the generated CSS and JS urls (only) from your cdn domain name, ie: cdn.example.com ]</p></label>
608
  </fieldset></td>
609
  </tr>
610
  </tbody></table>
677
  <p>
678
  <textarea name="fastvelocity_min_critical_path_css" rows="10" cols="50" id="fastvelocity_min_critical_path_css" class="large-text code" placeholder="your css code here"><?php echo get_option('fastvelocity_min_critical_path_css'); ?></textarea>
679
  </p>
680
+ <p class="description">[ Use this if you're familiar with <a target="_blank" href="https://github.com/giakki/uncss">UnCSS</a> or have the correct critical path css. ]</p>
681
  </fieldset>
682
  </td>
683
  </tr>
688
  <td><fieldset>
689
  <label for="fastvelocity_min_fvm_removecss">
690
  <input name="fastvelocity_min_fvm_removecss" type="checkbox" id="fastvelocity_min_fvm_removecss" value="1" <?php echo checked(1 == get_option('fastvelocity_min_fvm_removecss'), true, false); ?>>
691
+ Dequeue all CSS files <span class="note-info">[ Use this if you have your uncss code, your own css file or want to test how the critical path css looks like ]</span></label>
692
+ </td>
693
  </tr>
694
  </tbody></table>
695
 
705
  <td><fieldset>
706
  <label for="fastvelocity_min_loadcss">
707
  <input name="fastvelocity_min_loadcss" type="checkbox" id="fastvelocity_min_loadcss" value="1" <?php echo checked(1 == get_option('fastvelocity_min_loadcss'), true, false); ?>>
708
+ Async CSS with LoadCSS<span class="note-info">[ Only works if "Inline all header / footer CSS files" is disabled ]</span></label>
709
  </fieldset>
710
  </td>
711
  </tr>
764
  </tbody></table>
765
 
766
 
767
+ <div style="height: 20px;"></div>
768
+ <h2 class="title">Cache Location</h2>
769
+ <p class="fvm-bold-green">Make sure you choose a publicly available directory and that there are writting permissions on that directory.</p>
770
+ <table class="form-table fvm-settings">
771
+ <tbody>
772
+ <tr>
773
+ <th scope="row"><span class="fvm-label-special">Cache Path</span></th>
774
+ <td><fieldset>
775
+ <label for="fastvelocity_min_change_cache_path">
776
+ <p><input type="text" name="fastvelocity_min_change_cache_path" id="fastvelocity_min_change_cache_path" value="<?php echo get_option('fastvelocity_min_change_cache_path', ''); ?>" size="80" /></p>
777
+ <p class="description">[ Default cache path is: <?php echo rtrim(wp_upload_dir()['basedir'], '/'); ?> ]</p>
778
+ </label>
779
+ </fieldset></td>
780
+ </tr>
781
+ <tr>
782
+ <th scope="row"><span class="fvm-label-special">Cache Base URL</span></th>
783
+ <td><fieldset>
784
+ <label for="fastvelocity_min_change_cache_base_url">
785
+ <p><input type="text" name="fastvelocity_min_change_cache_base_url" id="fastvelocity_min_change_cache_base_url" value="<?php echo get_option('fastvelocity_min_change_cache_base_url', ''); ?>" size="80" /></p>
786
+ <p class="description">[ Default cache base url is: <?php echo trim(fvm_get_protocol(wp_upload_dir()['baseurl']), '/'); ?> ]</p>
787
+ </label>
788
+ </fieldset></td>
789
+ </tr>
790
+ </tbody></table>
791
+
792
+
793
  <p class="submit"><input type="submit" name="fastvelocity_min_save_options" id="fastvelocity_min_save_options" class="button button-primary" value="Save Changes"></p>
794
  </form>
795
 
1330
  }
1331
  }
1332
 
1333
+ # critical path
1334
  if(!empty($critical_path_css) && $critical_path_css != false) {
1335
  echo '<style id="critical-path-global" type="text/css" media="all">'.$critical_path_css.'</style>'."\n";
1336
  }
1416
 
1417
  # save to some sort of global and show it on the footer
1418
  $mt = $header[$i]['media'];
1419
+ echo '<link rel="preload" href="'.$file_url.'" as="style" media="'.$mt.'" onload="this.onload=null;this.rel=\'stylesheet\'">';
1420
+ echo '<noscript><link rel="stylesheet" type="text/css" media="'.$mt.'" href="'.$file_url.'"></noscript>';
1421
+ echo '<!--[if IE]><link rel="stylesheet" type="text/css" media="'.$mt.'" href="'.$file_url.'"><![endif]-->';
1422
+
1423
+ /*
1424
+ # alternative way
1425
  echo <<<EOF
1426
  <script type="text/javascript">var ldfvm$i=document.createElement("link");ldfvm$i.rel="stylesheet",ldfvm$i.type="text/css",ldfvm$i.media="bogus",ldfvm$i.href="$file_url",ldfvm$i.onload=function(){ldfvm$i.media="$mt"},document.getElementsByTagName("head")[0].appendChild(ldfvm$i);</script>
1427
  EOF;
1428
+ */
1429
 
1430
  }
1431
  } else {
1480
  # add defaults to ignore list
1481
  $ignore = fastvelocity_default_ignore($ignore);
1482
 
 
 
 
 
 
 
 
 
1483
  # google fonts to the top
1484
  foreach( $styles->to_do as $handle ) :
1485
  # dequeue and get a list of google fonts, or requeue external
1695
 
1696
 
1697
 
1698
+ ###########################################
1699
+ # defer CSS globally from the header (order matters)
1700
+ ###########################################
1701
+ function fvm_add_loadcss() {
1702
+ global $force_inline_css, $loadcss, $fvm_remove_css;
1703
+ if($force_inline_css == true && $loadcss != false && $fvm_remove_css != true) {
1704
+
1705
+ # echo LoadCSS scripts
1706
+ echo '<script>
1707
+ /*! loadCSS rel=preload polyfill. [c]2017 Filament Group, Inc. MIT License */
1708
+ !function(t){"use strict";t.loadCSS||(t.loadCSS=function(){});var e=loadCSS.relpreload={};if(e.support=function(){var e;try{e=t.document.createElement("link").relList.supports("preload")}catch(t){e=!1}return function(){return e}}(),e.bindMediaToggle=function(t){function e(){t.media=a}var a=t.media||"all";t.addEventListener?t.addEventListener("load",e):t.attachEvent&&t.attachEvent("onload",e),setTimeout(function(){t.rel="stylesheet",t.media="only x"}),setTimeout(e,3e3)},e.poly=function(){if(!e.support())for(var a=t.document.getElementsByTagName("link"),n=0;n<a.length;n++){var o=a[n];"preload"!==o.rel||"style"!==o.getAttribute("as")||o.getAttribute("data-loadcss")||(o.setAttribute("data-loadcss",!0),e.bindMediaToggle(o))}},!e.support()){e.poly();var a=t.setInterval(e.poly,500);t.addEventListener?t.addEventListener("load",function(){e.poly(),t.clearInterval(a)}):t.attachEvent&&t.attachEvent("onload",function(){e.poly(),t.clearInterval(a)})}"undefined"!=typeof exports?exports.loadCSS=loadCSS:t.loadCSS=loadCSS}("undefined"!=typeof global?global:this);
1709
+ </script>';
1710
+ }
1711
+ }
1712
+
1713
+ if (!is_admin()) { add_action('wp_head', 'fvm_add_loadcss', PHP_INT_MAX); }
1714
+
1715
+
1716
+
1717
 
1718
  ###########################################
1719
  # add preconnect and preload headers
inc/functions.php CHANGED
@@ -3,7 +3,7 @@
3
  # handle better utf-8 and unicode encoding
4
  if(function_exists('mb_internal_encoding')) { mb_internal_encoding('UTF-8'); }
5
 
6
- # Consider fallback to PHP Minify [2017.07.01] from https://github.com/matthiasmullie/minify (must be defined on the outer scope)
7
  $path = $plugindir . 'libs/matthiasmullie';
8
  require_once $path . '/minify/src/Minify.php';
9
  require_once $path . '/minify/src/CSS.php';
@@ -22,24 +22,27 @@ require_once ($plugindir . 'libs/mrclay/HTML.php');
22
  # get cache directories and urls
23
  function fvm_cachepath() {
24
 
 
 
 
 
 
 
 
 
 
 
25
  # create
26
- $upload = wp_upload_dir();
27
  $cachebase = rtrim($upload['basedir'], '/').'/fvm';
28
- $cachedir = rtrim($upload['basedir'], '/').'/fvm/cache';
29
- $tmpdir = rtrim($upload['basedir'], '/').'/fvm/temp';
30
- $cachedirurl = rtrim($upload['baseurl'], '/').'/fvm/cache';
31
- if(!is_dir($cachebase)) { mkdir($cachebase); }
32
- if(!is_dir($cachedir)) { mkdir($cachedir); }
33
- if(!is_dir($tmpdir)) { mkdir($tmpdir); }
34
- $return = array('cachebase'=>$cachebase,'tmpdir'=>$tmpdir, 'cachedir'=>$cachedir, 'cachedirurl'=>$cachedirurl);
35
-
36
- # save or update
37
- $save = get_option('fvm-cachepath', array());
38
- if($save != $return) {
39
- update_option('fvm-cachepath', $return);
40
- }
41
 
42
- return $return;
 
43
  }
44
 
45
 
@@ -606,7 +609,10 @@ function fvm_get_protocol($url) {
606
 
607
  # cdn support
608
  $fvm_cdn_url = get_option('fastvelocity_min_fvm_cdn_url');
609
- if(!empty($fvm_cdn_url)) {
 
 
 
610
  $fvm_cdn_url = trim(trim(str_ireplace(array('http://', 'https://'), '', trim($fvm_cdn_url, '/'))), '/');
611
  $url = str_ireplace($wp_domain, $fvm_cdn_url, $url);
612
  }
@@ -638,6 +644,8 @@ foreach( $transient_keys as $t ) { delete_transient( $t ); } # delete
638
  # purge all caches
639
  function fvm_purge_all() {
640
 
 
 
641
  # get cache directories and urls
642
  $cachepath = fvm_cachepath();
643
  $tmpdir = $cachepath['tmpdir'];
3
  # handle better utf-8 and unicode encoding
4
  if(function_exists('mb_internal_encoding')) { mb_internal_encoding('UTF-8'); }
5
 
6
+ # Consider fallback to PHP Minify [2017.12.17] from https://github.com/matthiasmullie/minify (must be defined on the outer scope)
7
  $path = $plugindir . 'libs/matthiasmullie';
8
  require_once $path . '/minify/src/Minify.php';
9
  require_once $path . '/minify/src/CSS.php';
22
  # get cache directories and urls
23
  function fvm_cachepath() {
24
 
25
+ # custom directory
26
+ $fvm_change_cache_path = get_option('fastvelocity_min_change_cache_path');
27
+ $fvm_change_cache_base = get_option('fastvelocity_min_change_cache_base_url');
28
+ if(!empty(trim($fvm_change_cache_path)) && $fvm_change_cache_path !== false && !empty(trim($fvm_change_cache_base)) && $fvm_change_cache_base !== false) {
29
+ $upload['basedir'] = trim($fvm_change_cache_path);
30
+ $upload['baseurl'] = trim($fvm_change_cache_base);
31
+ } else {
32
+ $upload = wp_upload_dir(); # default
33
+ }
34
+
35
  # create
 
36
  $cachebase = rtrim($upload['basedir'], '/').'/fvm';
37
+ $cachedir = rtrim($upload['basedir'], '/').'/fvm/out';
38
+ $tmpdir = rtrim($upload['basedir'], '/').'/fvm/tmp';
39
+ $cachedirurl = rtrim($upload['baseurl'], '/').'/fvm/out';
40
+ if(!is_dir($cachebase)) { mkdir($cachebase, 0755, true); }
41
+ if(!is_dir($cachedir)) { mkdir($cachedir, 0755, true); }
42
+ if(!is_dir($tmpdir)) { mkdir($tmpdir, 0755, true); }
 
 
 
 
 
 
 
43
 
44
+ # return
45
+ return array('cachebase'=>$cachebase,'tmpdir'=>$tmpdir, 'cachedir'=>$cachedir, 'cachedirurl'=>$cachedirurl);
46
  }
47
 
48
 
609
 
610
  # cdn support
611
  $fvm_cdn_url = get_option('fastvelocity_min_fvm_cdn_url');
612
+ $defer_for_pagespeed = get_option('fastvelocity_min_defer_for_pagespeed');
613
+
614
+ # excluded from cdn because of https://www.chromestatus.com/feature/5718547946799104 (we use document.write to preserve render blocking)
615
+ if(!empty($fvm_cdn_url) && $defer_for_pagespeed != true) {
616
  $fvm_cdn_url = trim(trim(str_ireplace(array('http://', 'https://'), '', trim($fvm_cdn_url, '/'))), '/');
617
  $url = str_ireplace($wp_domain, $fvm_cdn_url, $url);
618
  }
644
  # purge all caches
645
  function fvm_purge_all() {
646
 
647
+
648
+
649
  # get cache directories and urls
650
  $cachepath = fvm_cachepath();
651
  $tmpdir = $cachepath['tmpdir'];
libs/matthiasmullie/minify/data/js/operators_after.txt CHANGED
@@ -18,7 +18,6 @@
18
  &
19
  |
20
  ^
21
- ~
22
  <<
23
  >>
24
  >>>
18
  &
19
  |
20
  ^
 
21
  <<
22
  >>
23
  >>>
libs/matthiasmullie/minify/src/CSS.php CHANGED
@@ -1,4 +1,13 @@
1
  <?php
 
 
 
 
 
 
 
 
 
2
 
3
  namespace MatthiasMullie\Minify;
4
 
@@ -7,10 +16,11 @@ use MatthiasMullie\PathConverter\ConverterInterface;
7
  use MatthiasMullie\PathConverter\Converter;
8
 
9
  /**
10
- * CSS minifier.
11
  *
12
  * Please report bugs on https://github.com/matthiasmullie/minify/issues
13
  *
 
14
  * @author Matthias Mullie <minify@mullie.eu>
15
  * @author Tijs Verkoyen <minify@verkoyen.eu>
16
  * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
@@ -19,12 +29,12 @@ use MatthiasMullie\PathConverter\Converter;
19
  class CSS extends Minify
20
  {
21
  /**
22
- * @var int
23
  */
24
  protected $maxImportSize = 5;
25
 
26
  /**
27
- * @var string[]
28
  */
29
  protected $importExtensions = array(
30
  'gif' => 'data:image/gif',
@@ -76,14 +86,14 @@ class CSS extends Minify
76
  */
77
  protected function moveImportsToTop($content)
78
  {
79
- if (preg_match_all('/@import[^;]+;/', $content, $matches)) {
80
  // remove from content
81
  foreach ($matches[0] as $import) {
82
  $content = str_replace($import, '', $content);
83
  }
84
 
85
  // add to top
86
- $content = implode('', $matches[0]).$content;
87
  }
88
 
89
  return $content;
@@ -437,12 +447,14 @@ class CSS extends Minify
437
  * Urls with `)` (as could happen with data: uris) should also be
438
  * quoted to avoid being confused for the url() closing parentheses.
439
  * And urls with a # have also been reported to cause issues.
 
440
  *
441
  * @see https://developer.mozilla.org/nl/docs/Web/CSS/url#The_url()_functional_notation
442
  * @see https://hg.mozilla.org/mozilla-central/rev/14abca4e7378
 
443
  */
444
  $url = trim($url);
445
- if (preg_match('/[\s\)#\x{7f}-\x{9f}]/u', $url)) {
446
  $url = $match['quotes'] . $url . $match['quotes'];
447
  }
448
 
@@ -541,6 +553,16 @@ class CSS extends Minify
541
  */
542
  protected function shortenZeroes($content)
543
  {
 
 
 
 
 
 
 
 
 
 
544
  // reusable bits of code throughout these regexes:
545
  // before & after are used to make sure we don't match lose unintended
546
  // 0-like values (e.g. in #000, or in http://url/1.0)
@@ -569,35 +591,20 @@ class CSS extends Minify
569
  // strip negative zeroes (-0 -> 0) & truncate zeroes (00 -> 0)
570
  $content = preg_replace('/'.$before.'-?0+'.$units.'?'.$after.'/', '0\\1', $content);
571
 
572
- // remove zeroes where they make no sense in calc: e.g. calc(100px - 0)
573
- // the 0 doesn't have any effect, and this isn't even valid without unit
574
- // strip all `+ 0` or `- 0` occurrences: calc(10% + 0) -> calc(10%)
575
- // looped because there may be multiple 0s inside 1 group of parentheses
576
- do {
577
- $previous = $content;
578
- $content = preg_replace('/\(([^\(\)]+) [\+\-] 0( [^\(\)]+)?\)/', '(\\1\\2)', $content);
579
- } while ($content !== $previous);
580
- // strip all `0 +` occurrences: calc(0 + 10%) -> calc(10%)
581
- $content = preg_replace('/\(0 \+ ([^\(\)]+)\)/', '(\\1)', $content);
582
- // strip all `0 -` occurrences: calc(0 - 10%) -> calc(-10%)
583
- $content = preg_replace('/\(0 \- ([^\(\)]+)\)/', '(-\\1)', $content);
584
- // I'm not going to attempt to optimize away `x * 0` instances:
585
- // it's dumb enough code already that it likely won't occur, and it's
586
- // too complex to do right (order of operations would have to be
587
- // respected etc)
588
- // what I cared about most here was fixing incorrectly truncated units
589
-
590
  // IE doesn't seem to understand a unitless flex-basis value, so let's
591
  // add it in again (make it `%`, which is only 1 char: 0%, 0px, 0
592
  // anything, it's all just the same)
593
  $content = preg_replace('/flex:([^ ]+ [^ ]+ )0([;\}])/', 'flex:${1}0%${2}', $content);
594
  $content = preg_replace('/flex-basis:0([;\}])/', 'flex-basis:0%${1}', $content);
595
 
 
 
 
596
  return $content;
597
  }
598
 
599
  /**
600
- * Strip comments from source code.
601
  *
602
  * @param string $content
603
  *
@@ -605,7 +612,10 @@ class CSS extends Minify
605
  */
606
  protected function stripEmptyTags($content)
607
  {
608
- return preg_replace('/(^|\}|;)[^\{\};]+\{\s*\}/', '\\1', $content);
 
 
 
609
  }
610
 
611
  /**
@@ -639,10 +649,12 @@ class CSS extends Minify
639
  $content = preg_replace('/\s+([\]\)])/', '$1', $content);
640
  $content = preg_replace('/\s+(:)(?![^\}]*\{)/', '$1', $content);
641
 
642
- // whitespace around + and - can only be stripped in selectors, like
643
- // :nth-child(3+2n), not in things like calc(3px + 2px) or shorthands
644
- // like 3px -2px
645
- $content = preg_replace('/\s*([+-])\s*(?=[^}]*{)/', '$1', $content);
 
 
646
 
647
  // remove semicolon/whitespace followed by closing bracket
648
  $content = str_replace(';}', '}', $content);
@@ -650,6 +662,39 @@ class CSS extends Minify
650
  return trim($content);
651
  }
652
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
653
  /**
654
  * Check if file is small enough to be imported.
655
  *
1
  <?php
2
+ /**
3
+ * CSS Minifier
4
+ *
5
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
6
+ *
7
+ * @author Matthias Mullie <minify@mullie.eu>
8
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
9
+ * @license MIT License
10
+ */
11
 
12
  namespace MatthiasMullie\Minify;
13
 
16
  use MatthiasMullie\PathConverter\Converter;
17
 
18
  /**
19
+ * CSS minifier
20
  *
21
  * Please report bugs on https://github.com/matthiasmullie/minify/issues
22
  *
23
+ * @package Minify
24
  * @author Matthias Mullie <minify@mullie.eu>
25
  * @author Tijs Verkoyen <minify@verkoyen.eu>
26
  * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
29
  class CSS extends Minify
30
  {
31
  /**
32
+ * @var int maximum inport size in kB
33
  */
34
  protected $maxImportSize = 5;
35
 
36
  /**
37
+ * @var string[] valid import extensions
38
  */
39
  protected $importExtensions = array(
40
  'gif' => 'data:image/gif',
86
  */
87
  protected function moveImportsToTop($content)
88
  {
89
+ if (preg_match_all('/(;?)(@import (?<url>url\()?(?P<quotes>["\']?).+?(?P=quotes)(?(url)\)))/', $content, $matches)) {
90
  // remove from content
91
  foreach ($matches[0] as $import) {
92
  $content = str_replace($import, '', $content);
93
  }
94
 
95
  // add to top
96
+ $content = implode(';', $matches[2]).';'.trim($content, ';');
97
  }
98
 
99
  return $content;
447
  * Urls with `)` (as could happen with data: uris) should also be
448
  * quoted to avoid being confused for the url() closing parentheses.
449
  * And urls with a # have also been reported to cause issues.
450
+ * Urls with quotes inside should also remain escaped.
451
  *
452
  * @see https://developer.mozilla.org/nl/docs/Web/CSS/url#The_url()_functional_notation
453
  * @see https://hg.mozilla.org/mozilla-central/rev/14abca4e7378
454
+ * @see https://github.com/matthiasmullie/minify/issues/193
455
  */
456
  $url = trim($url);
457
+ if (preg_match('/[\s\)\'"#\x{7f}-\x{9f}]/u', $url)) {
458
  $url = $match['quotes'] . $url . $match['quotes'];
459
  }
460
 
553
  */
554
  protected function shortenZeroes($content)
555
  {
556
+ // we don't want to strip units in `calc()` expressions:
557
+ // `5px - 0px` is valid, but `5px - 0` is not
558
+ // `10px * 0` is valid (equates to 0), and so is `10 * 0px`, but
559
+ // `10 * 0` is invalid
560
+ // best to just leave `calc()`s alone, even if they could be optimized
561
+ // (which is a whole other undertaking, where units & order of
562
+ // operations all need to be considered...)
563
+ $calcs = $this->findCalcs($content);
564
+ $content = str_replace($calcs, array_keys($calcs), $content);
565
+
566
  // reusable bits of code throughout these regexes:
567
  // before & after are used to make sure we don't match lose unintended
568
  // 0-like values (e.g. in #000, or in http://url/1.0)
591
  // strip negative zeroes (-0 -> 0) & truncate zeroes (00 -> 0)
592
  $content = preg_replace('/'.$before.'-?0+'.$units.'?'.$after.'/', '0\\1', $content);
593
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
594
  // IE doesn't seem to understand a unitless flex-basis value, so let's
595
  // add it in again (make it `%`, which is only 1 char: 0%, 0px, 0
596
  // anything, it's all just the same)
597
  $content = preg_replace('/flex:([^ ]+ [^ ]+ )0([;\}])/', 'flex:${1}0%${2}', $content);
598
  $content = preg_replace('/flex-basis:0([;\}])/', 'flex-basis:0%${1}', $content);
599
 
600
+ // restore `calc()` expressions
601
+ $content = str_replace(array_keys($calcs), $calcs, $content);
602
+
603
  return $content;
604
  }
605
 
606
  /**
607
+ * Strip empty tags from source code.
608
  *
609
  * @param string $content
610
  *
612
  */
613
  protected function stripEmptyTags($content)
614
  {
615
+ $content = preg_replace('/(?<=^)[^\{\};]+\{\s*\}/', '', $content);
616
+ $content = preg_replace('/(?<=(\}|;))[^\{\};]+\{\s*\}/', '', $content);
617
+
618
+ return $content;
619
  }
620
 
621
  /**
649
  $content = preg_replace('/\s+([\]\)])/', '$1', $content);
650
  $content = preg_replace('/\s+(:)(?![^\}]*\{)/', '$1', $content);
651
 
652
+ // whitespace around + and - can only be stripped inside some pseudo-
653
+ // classes, like `:nth-child(3+2n)`
654
+ // not in things like `calc(3px + 2px)`, shorthands like `3px -2px`, or
655
+ // selectors like `div.weird- p`
656
+ $pseudos = array('nth-child', 'nth-last-child', 'nth-last-of-type', 'nth-of-type');
657
+ $content = preg_replace('/:('.implode('|', $pseudos).')\(\s*([+-]?)\s*(.+?)\s*([+-]?)\s*(.*?)\s*\)/', ':$1($2$3$4$5)', $content);
658
 
659
  // remove semicolon/whitespace followed by closing bracket
660
  $content = str_replace(';}', '}', $content);
662
  return trim($content);
663
  }
664
 
665
+ /**
666
+ * Find all `calc()` occurrences.
667
+ *
668
+ * @param string $content The CSS content to find `calc()`s in.
669
+ *
670
+ * @return string[]
671
+ */
672
+ protected function findCalcs($content)
673
+ {
674
+ $results = array();
675
+ preg_match_all('/calc(\(.+?)(?=$|;|calc\()/', $content, $matches, PREG_SET_ORDER);
676
+
677
+ foreach ($matches as $match) {
678
+ $length = strlen($match[1]);
679
+ $expr = '';
680
+ $opened = 0;
681
+
682
+ for ($i = 0; $i < $length; $i++) {
683
+ $char = $match[1][$i];
684
+ $expr .= $char;
685
+ if ($char === '(') {
686
+ $opened++;
687
+ } elseif ($char === ')' && --$opened === 0) {
688
+ break;
689
+ }
690
+ }
691
+
692
+ $results['calc('.count($results).')'] = 'calc'.$expr;
693
+ }
694
+
695
+ return $results;
696
+ }
697
+
698
  /**
699
  * Check if file is small enough to be imported.
700
  *
libs/matthiasmullie/minify/src/Exception.php CHANGED
@@ -1,10 +1,18 @@
1
  <?php
2
-
 
 
 
 
 
 
3
  namespace MatthiasMullie\Minify;
4
 
5
  /**
 
6
  * @deprecated Use Exceptions\BasicException instead
7
  *
 
8
  * @author Matthias Mullie <minify@mullie.eu>
9
  */
10
  abstract class Exception extends \Exception
1
  <?php
2
+ /**
3
+ * Base Exception
4
+ *
5
+ * @deprecated Use Exceptions\BasicException instead
6
+ *
7
+ * @author Matthias Mullie <minify@mullie.eu>
8
+ */
9
  namespace MatthiasMullie\Minify;
10
 
11
  /**
12
+ * Base Exception Class
13
  * @deprecated Use Exceptions\BasicException instead
14
  *
15
+ * @package Minify
16
  * @author Matthias Mullie <minify@mullie.eu>
17
  */
18
  abstract class Exception extends \Exception
libs/matthiasmullie/minify/src/Exceptions/BasicException.php CHANGED
@@ -1,10 +1,21 @@
1
  <?php
2
-
 
 
 
 
 
 
 
 
3
  namespace MatthiasMullie\Minify\Exceptions;
4
 
5
  use MatthiasMullie\Minify\Exception;
6
 
7
  /**
 
 
 
8
  * @author Matthias Mullie <minify@mullie.eu>
9
  */
10
  abstract class BasicException extends Exception
1
  <?php
2
+ /**
3
+ * Basic exception
4
+ *
5
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
6
+ *
7
+ * @author Matthias Mullie <minify@mullie.eu>
8
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
9
+ * @license MIT License
10
+ */
11
  namespace MatthiasMullie\Minify\Exceptions;
12
 
13
  use MatthiasMullie\Minify\Exception;
14
 
15
  /**
16
+ * Basic Exception Class
17
+ *
18
+ * @package Minify\Exception
19
  * @author Matthias Mullie <minify@mullie.eu>
20
  */
21
  abstract class BasicException extends Exception
libs/matthiasmullie/minify/src/Exceptions/FileImportException.php CHANGED
@@ -1,8 +1,19 @@
1
  <?php
2
-
 
 
 
 
 
 
 
 
3
  namespace MatthiasMullie\Minify\Exceptions;
4
 
5
  /**
 
 
 
6
  * @author Matthias Mullie <minify@mullie.eu>
7
  */
8
  class FileImportException extends BasicException
1
  <?php
2
+ /**
3
+ * File Import Exception
4
+ *
5
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
6
+ *
7
+ * @author Matthias Mullie <minify@mullie.eu>
8
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
9
+ * @license MIT License
10
+ */
11
  namespace MatthiasMullie\Minify\Exceptions;
12
 
13
  /**
14
+ * File Import Exception Class
15
+ *
16
+ * @package Minify\Exception
17
  * @author Matthias Mullie <minify@mullie.eu>
18
  */
19
  class FileImportException extends BasicException
libs/matthiasmullie/minify/src/Exceptions/IOException.php CHANGED
@@ -1,8 +1,19 @@
1
  <?php
2
-
 
 
 
 
 
 
 
 
3
  namespace MatthiasMullie\Minify\Exceptions;
4
 
5
  /**
 
 
 
6
  * @author Matthias Mullie <minify@mullie.eu>
7
  */
8
  class IOException extends BasicException
1
  <?php
2
+ /**
3
+ * IO Exception
4
+ *
5
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
6
+ *
7
+ * @author Matthias Mullie <minify@mullie.eu>
8
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
9
+ * @license MIT License
10
+ */
11
  namespace MatthiasMullie\Minify\Exceptions;
12
 
13
  /**
14
+ * IO Exception Class
15
+ *
16
+ * @package Minify\Exception
17
  * @author Matthias Mullie <minify@mullie.eu>
18
  */
19
  class IOException extends BasicException
libs/matthiasmullie/minify/src/JS.php CHANGED
@@ -1,12 +1,21 @@
1
  <?php
2
-
 
 
 
 
 
 
 
 
3
  namespace MatthiasMullie\Minify;
4
 
5
  /**
6
- * JavaScript minifier.
7
  *
8
  * Please report bugs on https://github.com/matthiasmullie/minify/issues
9
  *
 
10
  * @author Matthias Mullie <minify@mullie.eu>
11
  * @author Tijs Verkoyen <minify@verkoyen.eu>
12
  * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
@@ -80,8 +89,7 @@ class JS extends Minify
80
  * them. Some end of lines are not the end of a statement, like with these
81
  * operators.
82
  *
83
- * Note: Most operators are fine, we've only removed !, ++ and --.
84
- * There can't be a newline separating ! and whatever it is negating.
85
  * ++ & -- have to be joined with the value they're in-/decrementing.
86
  *
87
  * Will be loaded from /data/js/operators_before.txt
@@ -97,7 +105,8 @@ class JS extends Minify
97
  * them. Some end of lines are not the end of a statement, like when
98
  * continued by one of these operators on the newline.
99
  *
100
- * Note: Most operators are fine, we've only removed ), ], ++ and --.
 
101
  * ++ & -- have to be joined with the value they're in-/decrementing.
102
  * ) & ] are "special" in that they have lots or usecases. () for example
103
  * is used for function calls, for grouping, in if () and for (), ...
@@ -139,19 +148,6 @@ class JS extends Minify
139
  {
140
  $content = '';
141
 
142
- // loop files
143
- foreach ($this->data as $source => $js) {
144
- /*
145
- * Combine js: separating the scripts by a ;
146
- * I'm also adding a newline: it will be eaten when whitespace is
147
- * stripped, but we need to make sure we're not just appending
148
- * a new script right after a previous script that ended with a
149
- * singe-line comment on the last line (in which case it would also
150
- * be seen as part of that comment)
151
- */
152
- $content .= $js."\n;";
153
- }
154
-
155
  /*
156
  * Let's first take out strings, comments and regular expressions.
157
  * All of these can contain JS code-like characters, and we should make
@@ -166,11 +162,24 @@ class JS extends Minify
166
  $this->extractStrings('\'"`');
167
  $this->stripComments();
168
  $this->extractRegex();
169
- $content = $this->replace($content);
170
 
171
- $content = $this->propertyNotation($content);
172
- $content = $this->shortenBools($content);
173
- $content = $this->stripWhitespace($content);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
 
175
  /*
176
  * Earlier, we extracted strings & regular expressions and replaced them
@@ -216,20 +225,45 @@ class JS extends Minify
216
  $minifier = $this;
217
  $callback = function ($match) use ($minifier) {
218
  $count = count($minifier->extracted);
219
- $placeholder = '/'.$count.'/';
220
  $minifier->extracted[$placeholder] = $match[0];
221
 
222
  return $placeholder;
223
  };
224
 
225
- $pattern = '\/.*?(?<!\\\\)(\\\\\\\\)*\/[gimy]*(?![0-9a-zA-Z\/])';
 
 
 
 
 
226
 
227
  // a regular expression can only be followed by a few operators or some
228
  // of the RegExp methods (a `\` followed by a variable or value is
229
  // likely part of a division, not a regex)
230
- $after = '[\.,;\)\}]';
231
- $methods = '\.(exec|test|match|search|replace|split)\(';
232
- $this->registerPattern('/'.$pattern.'(?=\s*('.$after.'|'.$methods.'))/', $callback);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
 
234
  // 1 more edge case: a regex can be followed by a lot more operators or
235
  // keywords if there's a newline (ASI) in between, where the operator
@@ -237,7 +271,8 @@ class JS extends Minify
237
  // (https://github.com/matthiasmullie/minify/issues/56)
238
  $operators = $this->getOperatorsForRegex($this->operatorsBefore, '/');
239
  $operators += $this->getOperatorsForRegex($this->keywordsReserved, '/');
240
- $this->registerPattern('/'.$pattern.'\s*\n(?=\s*('.implode('|', $operators).'))/', $callback);
 
241
  }
242
 
243
  /**
@@ -309,6 +344,12 @@ class JS extends Minify
309
  $content = preg_replace('/('.implode('|', $operatorsDiffBefore).')[^\S\n]+/', '\\1', $content);
310
  $content = preg_replace('/[^\S\n]+('.implode('|', $operatorsDiffAfter).')/', '\\1', $content);
311
 
 
 
 
 
 
 
312
  /*
313
  * Get rid of double semicolons, except where they can be used like:
314
  * "for(v=1,_=b;;)", "for(v=1;;v++)" or "for(;;ja||(ja=true))".
@@ -326,12 +367,19 @@ class JS extends Minify
326
  * semicolon), like: `for(i=1;i<3;i++);`, of `for(i in list);`
327
  * Here, nothing happens during the loop; it's just used to keep
328
  * increasing `i`. With that ; omitted, the next line would be expected
329
- * to be the for-loop's body...
330
  * I'm going to double that semicolon (if any) so after the next line,
331
  * which strips semicolons here & there, we're still left with this one.
332
  */
333
  $content = preg_replace('/(for\([^;\{]*;[^;\{]*;[^;\{]*\));(\}|$)/s', '\\1;;\\2', $content);
334
  $content = preg_replace('/(for\([^;\{]+\s+in\s+[^;\{]+\));(\}|$)/s', '\\1;;\\2', $content);
 
 
 
 
 
 
 
335
 
336
  /*
337
  * We also can't strip empty else-statements. Even though they're
1
  <?php
2
+ /**
3
+ * JavaScript minifier
4
+ *
5
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
6
+ *
7
+ * @author Matthias Mullie <minify@mullie.eu>
8
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
9
+ * @license MIT License
10
+ */
11
  namespace MatthiasMullie\Minify;
12
 
13
  /**
14
+ * JavaScript Minifier Class
15
  *
16
  * Please report bugs on https://github.com/matthiasmullie/minify/issues
17
  *
18
+ * @package Minify
19
  * @author Matthias Mullie <minify@mullie.eu>
20
  * @author Tijs Verkoyen <minify@verkoyen.eu>
21
  * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
89
  * them. Some end of lines are not the end of a statement, like with these
90
  * operators.
91
  *
92
+ * Note: Most operators are fine, we've only removed ++ and --.
 
93
  * ++ & -- have to be joined with the value they're in-/decrementing.
94
  *
95
  * Will be loaded from /data/js/operators_before.txt
105
  * them. Some end of lines are not the end of a statement, like when
106
  * continued by one of these operators on the newline.
107
  *
108
+ * Note: Most operators are fine, we've only removed ), ], ++, --, ! and ~.
109
+ * There can't be a newline separating ! or ~ and whatever it is negating.
110
  * ++ & -- have to be joined with the value they're in-/decrementing.
111
  * ) & ] are "special" in that they have lots or usecases. () for example
112
  * is used for function calls, for grouping, in if () and for (), ...
148
  {
149
  $content = '';
150
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  /*
152
  * Let's first take out strings, comments and regular expressions.
153
  * All of these can contain JS code-like characters, and we should make
162
  $this->extractStrings('\'"`');
163
  $this->stripComments();
164
  $this->extractRegex();
 
165
 
166
+ // loop files
167
+ foreach ($this->data as $source => $js) {
168
+ // take out strings, comments & regex (for which we've registered
169
+ // the regexes just a few lines earlier)
170
+ $js = $this->replace($js);
171
+
172
+ $js = $this->propertyNotation($js);
173
+ $js = $this->shortenBools($js);
174
+ $js = $this->stripWhitespace($js);
175
+
176
+ // combine js: separating the scripts by a ;
177
+ $content .= $js.";";
178
+ }
179
+
180
+ // clean up leftover `;`s from the combination of multiple scripts
181
+ $content = ltrim($content, ';');
182
+ $content = substr($content, 0, -1);
183
 
184
  /*
185
  * Earlier, we extracted strings & regular expressions and replaced them
225
  $minifier = $this;
226
  $callback = function ($match) use ($minifier) {
227
  $count = count($minifier->extracted);
228
+ $placeholder = '"'.$count.'"';
229
  $minifier->extracted[$placeholder] = $match[0];
230
 
231
  return $placeholder;
232
  };
233
 
234
+ // match all chars except `/` and `\`
235
+ // `\` is allowed though, along with whatever char follows (which is the
236
+ // one being escaped)
237
+ // this should allow all chars, except for an unescaped `/` (= the one
238
+ // closing the regex)
239
+ $pattern = '\\/([^\\/\\\\]*+|(\\\\.)*+)+\\/[gimy]*';
240
 
241
  // a regular expression can only be followed by a few operators or some
242
  // of the RegExp methods (a `\` followed by a variable or value is
243
  // likely part of a division, not a regex)
244
+ $keywords = array('do', 'in', 'new', 'else', 'throw', 'yield', 'delete', 'return', 'typeof');
245
+ $before = '([=:,;\}\(\{\[&\|!\)]|^|'.implode('|', $keywords).')\s*';
246
+ $propertiesAndMethods = array(
247
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#Properties_2
248
+ 'constructor',
249
+ 'flags',
250
+ 'global',
251
+ 'ignoreCase',
252
+ 'multiline',
253
+ 'source',
254
+ 'sticky',
255
+ 'unicode',
256
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#Methods_2
257
+ 'compile(',
258
+ 'exec(',
259
+ 'test(',
260
+ 'toSource(',
261
+ 'toString(',
262
+ );
263
+ $delimiters = array_fill(0, count($propertiesAndMethods), '/');
264
+ $propertiesAndMethods = array_map('preg_quote', $propertiesAndMethods, $delimiters);
265
+ $after = '(?=\s*[\.,;\)\}&\|+]|\/\/|$|\.('.implode('|', $propertiesAndMethods).'))';
266
+ $this->registerPattern('/'.$before.'\K'.$pattern.$after.'/', $callback);
267
 
268
  // 1 more edge case: a regex can be followed by a lot more operators or
269
  // keywords if there's a newline (ASI) in between, where the operator
271
  // (https://github.com/matthiasmullie/minify/issues/56)
272
  $operators = $this->getOperatorsForRegex($this->operatorsBefore, '/');
273
  $operators += $this->getOperatorsForRegex($this->keywordsReserved, '/');
274
+ $after = '(?=\s*\n\s*('.implode('|', $operators).'))';
275
+ $this->registerPattern('/'.$pattern.$after.'/', $callback);
276
  }
277
 
278
  /**
344
  $content = preg_replace('/('.implode('|', $operatorsDiffBefore).')[^\S\n]+/', '\\1', $content);
345
  $content = preg_replace('/[^\S\n]+('.implode('|', $operatorsDiffAfter).')/', '\\1', $content);
346
 
347
+ /*
348
+ * Whitespace after `return` can be omitted in a few occasions
349
+ * (such as when followed by a string or regex)
350
+ */
351
+ $content = preg_replace('/\breturn\s+(["\'\/\+\-])/', 'return$1', $content);
352
+
353
  /*
354
  * Get rid of double semicolons, except where they can be used like:
355
  * "for(v=1,_=b;;)", "for(v=1;;v++)" or "for(;;ja||(ja=true))".
367
  * semicolon), like: `for(i=1;i<3;i++);`, of `for(i in list);`
368
  * Here, nothing happens during the loop; it's just used to keep
369
  * increasing `i`. With that ; omitted, the next line would be expected
370
+ * to be the for-loop's body... Same goes for while loops.
371
  * I'm going to double that semicolon (if any) so after the next line,
372
  * which strips semicolons here & there, we're still left with this one.
373
  */
374
  $content = preg_replace('/(for\([^;\{]*;[^;\{]*;[^;\{]*\));(\}|$)/s', '\\1;;\\2', $content);
375
  $content = preg_replace('/(for\([^;\{]+\s+in\s+[^;\{]+\));(\}|$)/s', '\\1;;\\2', $content);
376
+ /*
377
+ * Below will also keep `;` after a `do{}while();` along with `while();`
378
+ * While these could be stripped after do-while, detecting this
379
+ * distinction is cumbersome, so I'll play it safe and make sure `;`
380
+ * after any kind of `while` is kept.
381
+ */
382
+ $content = preg_replace('/(while\([^;\{]+\));(\}|$)/s', '\\1;;\\2', $content);
383
 
384
  /*
385
  * We also can't strip empty else-statements. Even though they're
libs/matthiasmullie/minify/src/Minify.php CHANGED
@@ -1,5 +1,13 @@
1
  <?php
2
-
 
 
 
 
 
 
 
 
3
  namespace MatthiasMullie\Minify;
4
 
5
  use MatthiasMullie\Minify\Exceptions\IOException;
@@ -10,6 +18,7 @@ use Psr\Cache\CacheItemInterface;
10
  *
11
  * Please report bugs on https://github.com/matthiasmullie/minify/issues
12
  *
 
13
  * @author Matthias Mullie <minify@mullie.eu>
14
  * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
15
  * @license MIT License
@@ -324,12 +333,13 @@ abstract class Minify
324
  * via restoreStrings().
325
  *
326
  * @param string[optional] $chars
 
327
  */
328
- protected function extractStrings($chars = '\'"')
329
  {
330
  // PHP only supports $this inside anonymous functions since 5.4
331
  $minifier = $this;
332
- $callback = function ($match) use ($minifier) {
333
  // check the second index here, because the first always contains a quote
334
  if ($match[2] === '') {
335
  /*
@@ -342,7 +352,7 @@ abstract class Minify
342
  }
343
 
344
  $count = count($minifier->extracted);
345
- $placeholder = $match[1].$count.$match[1];
346
  $minifier->extracted[$placeholder] = $match[1].$match[2].$match[1];
347
 
348
  return $placeholder;
1
  <?php
2
+ /**
3
+ * Abstract minifier class
4
+ *
5
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
6
+ *
7
+ * @author Matthias Mullie <minify@mullie.eu>
8
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
9
+ * @license MIT License
10
+ */
11
  namespace MatthiasMullie\Minify;
12
 
13
  use MatthiasMullie\Minify\Exceptions\IOException;
18
  *
19
  * Please report bugs on https://github.com/matthiasmullie/minify/issues
20
  *
21
+ * @package Minify
22
  * @author Matthias Mullie <minify@mullie.eu>
23
  * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
24
  * @license MIT License
333
  * via restoreStrings().
334
  *
335
  * @param string[optional] $chars
336
+ * @param string[optional] $placeholderPrefix
337
  */
338
+ protected function extractStrings($chars = '\'"', $placeholderPrefix = '')
339
  {
340
  // PHP only supports $this inside anonymous functions since 5.4
341
  $minifier = $this;
342
+ $callback = function ($match) use ($minifier, $placeholderPrefix) {
343
  // check the second index here, because the first always contains a quote
344
  if ($match[2] === '') {
345
  /*
352
  }
353
 
354
  $count = count($minifier->extracted);
355
+ $placeholder = $match[1].$placeholderPrefix.$count.$match[1];
356
  $minifier->extracted[$placeholder] = $match[1].$match[2].$match[1];
357
 
358
  return $placeholder;
readme.txt CHANGED
@@ -2,7 +2,7 @@
2
  Contributors: Alignak
3
  Tags: merge, combine, concatenate, PHP Minify, YUI Compressor, CSS, javascript, JS, minification, minify, optimization, optimize, stylesheet, aggregate, cache, CSS, html, minimize, pagespeed, performance, speed, GTmetrix, pingdom
4
  Requires at least: 4.5
5
- Stable tag: 2.2.3
6
  Tested up to: 4.9.1
7
  License: GPLv3 or later
8
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
@@ -268,13 +268,20 @@ If you would like to donate any amount to the plugin author (thank you in advanc
268
 
269
  == Upgrade Notice ==
270
 
271
- = 2.1.6 =
272
- Note: Kindly purge the plugin cache as well as your server /plugin cache after updating.
273
 
274
 
275
  == Changelog ==
276
 
277
- = 2.2.3 [2017.12.17] =
 
 
 
 
 
 
 
278
  * added robots.txt and ajax requests to the exclusion list
279
  * added some cdn fixes
280
  * added a new Pro tab
2
  Contributors: Alignak
3
  Tags: merge, combine, concatenate, PHP Minify, YUI Compressor, CSS, javascript, JS, minification, minify, optimization, optimize, stylesheet, aggregate, cache, CSS, html, minimize, pagespeed, performance, speed, GTmetrix, pingdom
4
  Requires at least: 4.5
5
+ Stable tag: 2.2.4
6
  Tested up to: 4.9.1
7
  License: GPLv3 or later
8
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
268
 
269
  == Upgrade Notice ==
270
 
271
+ = 2.2.4 =
272
+ Note: Kindly re-save all options and purge all caches (the plugin cache as well as your server /plugin cache).
273
 
274
 
275
  == Changelog ==
276
 
277
+ = 2.2.4 [2017.12.17] =
278
+ * added custom cache directory and url support
279
+ * cleaned up some old unused code
280
+ * updated to the latest PHP Minify version
281
+ * added better descriptions and labels for some options
282
+ * added auto exclusion for js and css files when defer for pagespeed is enabled
283
+
284
+ = 2.2.3 [2017.12.16] =
285
  * added robots.txt and ajax requests to the exclusion list
286
  * added some cdn fixes
287
  * added a new Pro tab