Permalink
Browse files

Update CSSmin, adds Minify_CSSmin wrapper, removes units for CSSmin

  • Loading branch information...
1 parent e778d4f commit 218f37fb44f9be2ea138cf9efb8b7f6dc84bad7f @mrclay committed Nov 14, 2013
Showing with 133 additions and 1,052 deletions.
  1. +6 −0 min/config.php
  2. +40 −23 min/lib/CSSmin.php
  3. +85 −0 min/lib/Minify/CSSmin.php
  4. +1 −1 min/quick-test.css
  5. +1 −1 min_extras/tools/minifyTextarea.php
  6. +0 −2 min_unit_tests/_test_files/yuic/background-position.css
  7. +0 −1 min_unit_tests/_test_files/yuic/background-position.css.min
  8. +0 −5 min_unit_tests/_test_files/yuic/border-none.css
  9. +0 −1 min_unit_tests/_test_files/yuic/border-none.css.min
  10. +0 −9 min_unit_tests/_test_files/yuic/box-model-hack.css
  11. +0 −1 min_unit_tests/_test_files/yuic/box-model-hack.css.min
  12. +0 −10 min_unit_tests/_test_files/yuic/bug2527974.css
  13. +0 −1 min_unit_tests/_test_files/yuic/bug2527974.css.min
  14. +0 −19 min_unit_tests/_test_files/yuic/bug2527991.css
  15. +0 −1 min_unit_tests/_test_files/yuic/bug2527991.css.min
  16. +0 −4 min_unit_tests/_test_files/yuic/bug2527998.css
  17. +0 −1 min_unit_tests/_test_files/yuic/bug2527998.css.min
  18. +0 −5 min_unit_tests/_test_files/yuic/bug2528034.css
  19. +0 −1 min_unit_tests/_test_files/yuic/bug2528034.css.min
  20. +0 −9 min_unit_tests/_test_files/yuic/charset-media.css
  21. +0 −1 min_unit_tests/_test_files/yuic/charset-media.css.min
  22. +0 −8 min_unit_tests/_test_files/yuic/color-simple.css
  23. +0 −1 min_unit_tests/_test_files/yuic/color-simple.css.min
  24. +0 −46 min_unit_tests/_test_files/yuic/color.css
  25. +0 −1 min_unit_tests/_test_files/yuic/color.css.min
  26. +0 −3 min_unit_tests/_test_files/yuic/comment.css
  27. +0 −1 min_unit_tests/_test_files/yuic/comment.css.min
  28. +0 −15 min_unit_tests/_test_files/yuic/concat-charset.css
  29. +0 −1 min_unit_tests/_test_files/yuic/concat-charset.css.min
  30. +0 −23 min_unit_tests/_test_files/yuic/dataurl-base64-doublequotes.css
  31. +0 −1 min_unit_tests/_test_files/yuic/dataurl-base64-doublequotes.css.min
  32. +0 −10 min_unit_tests/_test_files/yuic/dataurl-base64-eof.css
  33. +0 −1 min_unit_tests/_test_files/yuic/dataurl-base64-eof.css.min
  34. +0 −34 min_unit_tests/_test_files/yuic/dataurl-base64-linebreakindata.css
  35. +0 −1 min_unit_tests/_test_files/yuic/dataurl-base64-linebreakindata.css.min
  36. +0 −26 min_unit_tests/_test_files/yuic/dataurl-base64-noquotes.css
  37. +0 −1 min_unit_tests/_test_files/yuic/dataurl-base64-noquotes.css.min
  38. +0 −23 min_unit_tests/_test_files/yuic/dataurl-base64-singlequotes.css
  39. +0 −1 min_unit_tests/_test_files/yuic/dataurl-base64-singlequotes.css.min
  40. +0 −27 min_unit_tests/_test_files/yuic/dataurl-base64-twourls.css
  41. +0 −1 min_unit_tests/_test_files/yuic/dataurl-base64-twourls.css.min
  42. +0 −30 min_unit_tests/_test_files/yuic/dataurl-dbquote-font.css
  43. +0 −5 min_unit_tests/_test_files/yuic/dataurl-dbquote-font.css.min
  44. +0 −13 min_unit_tests/_test_files/yuic/dataurl-nonbase64-doublequotes.css
  45. +0 −1 min_unit_tests/_test_files/yuic/dataurl-nonbase64-doublequotes.css.min
  46. +0 −11 min_unit_tests/_test_files/yuic/dataurl-nonbase64-noquotes.css
  47. +0 −1 min_unit_tests/_test_files/yuic/dataurl-nonbase64-noquotes.css.min
  48. +0 −15 min_unit_tests/_test_files/yuic/dataurl-nonbase64-singlequotes.css
  49. +0 −2 min_unit_tests/_test_files/yuic/dataurl-nonbase64-singlequotes.css.min
  50. +0 −31 min_unit_tests/_test_files/yuic/dataurl-noquote-multiline-font.css
  51. +0 −3 min_unit_tests/_test_files/yuic/dataurl-noquote-multiline-font.css.min
  52. +0 −90 min_unit_tests/_test_files/yuic/dataurl-realdata-doublequotes.css
  53. +0 −1 min_unit_tests/_test_files/yuic/dataurl-realdata-doublequotes.css.min
  54. +0 −90 min_unit_tests/_test_files/yuic/dataurl-realdata-noquotes.css
  55. +0 −1 min_unit_tests/_test_files/yuic/dataurl-realdata-noquotes.css.min
  56. +0 −90 min_unit_tests/_test_files/yuic/dataurl-realdata-singlequotes.css
  57. +0 −1 min_unit_tests/_test_files/yuic/dataurl-realdata-singlequotes.css.min
  58. +0 −106 min_unit_tests/_test_files/yuic/dataurl-realdata-yuiapp.css
  59. +0 −1 min_unit_tests/_test_files/yuic/dataurl-realdata-yuiapp.css.min
  60. +0 −30 min_unit_tests/_test_files/yuic/dataurl-singlequote-font.css
  61. +0 −3 min_unit_tests/_test_files/yuic/dataurl-singlequote-font.css.min
  62. +0 −3 min_unit_tests/_test_files/yuic/decimals.css
  63. +0 −1 min_unit_tests/_test_files/yuic/decimals.css.min
  64. +0 −7 min_unit_tests/_test_files/yuic/dollar-header.css
  65. +0 −3 min_unit_tests/_test_files/yuic/dollar-header.css.min
  66. +0 −6 min_unit_tests/_test_files/yuic/font-face.css
  67. +0 −1 min_unit_tests/_test_files/yuic/font-face.css.min
  68. +0 −5 min_unit_tests/_test_files/yuic/ie5mac.css
  69. +0 −1 min_unit_tests/_test_files/yuic/ie5mac.css.min
  70. +0 −16 min_unit_tests/_test_files/yuic/media-empty-class.css
  71. +0 −1 min_unit_tests/_test_files/yuic/media-empty-class.css.min
  72. +0 −3 min_unit_tests/_test_files/yuic/media-multi.css
  73. +0 −1 min_unit_tests/_test_files/yuic/media-multi.css.min
  74. +0 −3 min_unit_tests/_test_files/yuic/media-test.css
  75. +0 −1 min_unit_tests/_test_files/yuic/media-test.css.min
  76. +0 −14 min_unit_tests/_test_files/yuic/opacity-filter.css
  77. +0 −1 min_unit_tests/_test_files/yuic/opacity-filter.css.min
  78. +0 −15 min_unit_tests/_test_files/yuic/preserve-case.css
  79. +0 −1 min_unit_tests/_test_files/yuic/preserve-case.css.min
  80. +0 −6 min_unit_tests/_test_files/yuic/preserve-new-line.css
  81. +0 −3 min_unit_tests/_test_files/yuic/preserve-new-line.css.min
  82. +0 −7 min_unit_tests/_test_files/yuic/preserve-strings.css
  83. +0 −1 min_unit_tests/_test_files/yuic/preserve-strings.css.min
  84. +0 −16 min_unit_tests/_test_files/yuic/pseudo-first.css
  85. +0 −1 min_unit_tests/_test_files/yuic/pseudo-first.css.min
  86. +0 −4 min_unit_tests/_test_files/yuic/pseudo.css
  87. +0 −1 min_unit_tests/_test_files/yuic/pseudo.css.min
  88. +0 −13 min_unit_tests/_test_files/yuic/special-comments.css
  89. +0 −9 min_unit_tests/_test_files/yuic/special-comments.css.min
  90. +0 −5 min_unit_tests/_test_files/yuic/star-underscore-hacks.css
  91. +0 −1 min_unit_tests/_test_files/yuic/star-underscore-hacks.css.min
  92. +0 −8 min_unit_tests/_test_files/yuic/string-in-comment.css
  93. +0 −1 min_unit_tests/_test_files/yuic/string-in-comment.css.min
  94. +0 −2 min_unit_tests/_test_files/yuic/webkit-transform.css
  95. +0 −1 min_unit_tests/_test_files/yuic/webkit-transform.css.min
  96. +0 −6 min_unit_tests/_test_files/yuic/zeros.css
  97. +0 −1 min_unit_tests/_test_files/yuic/zeros.css.min
  98. +0 −37 min_unit_tests/test_CSSmin.php
View
@@ -106,6 +106,12 @@
/**
+ * To use CSSmin (Túbal Martín's port of the YUI CSS compressor), uncomment the following line:
+ */
+//$min_serveOptions['minifiers']['text/css'] = array('Minify_CSSmin', 'minify');
+
+
+/**
* To use Google's Closure Compiler API to minify Javascript (falling back to JSMin
* on failure), uncomment the following line:
*/
View
@@ -1,11 +1,11 @@
<?php
/*!
- * cssmin.php rev ebaf67b 12/06/2013
+ * cssmin.php 2.4.8-2
* Author: Tubal Martin - http://tubalmartin.me/
* Repo: https://github.com/tubalmartin/YUI-CSS-compressor-PHP-port
*
- * This is a PHP port of the CSS minification tool distributed with YUICompressor,
+ * This is a PHP port of the CSS minification tool distributed with YUICompressor,
* itself a port of the cssmin utility by Isaac Schlueter - http://foohack.com/
* Permission is hereby granted to use the PHP version under the same
* conditions as the YUICompressor.
@@ -92,7 +92,7 @@ public function run($css = '', $linebreak_pos = FALSE)
// preserve strings so their content doesn't get accidentally minified
$css = preg_replace_callback('/(?:"(?:[^\\\\"]|\\\\.|\\\\)*")|'."(?:'(?:[^\\\\']|\\\\.|\\\\)*')/S", array($this, 'replace_string'), $css);
- // Let's divide css code in chunks of 25.000 chars aprox.
+ // Let's divide css code in chunks of 5.000 chars aprox.
// Reason: PHP's PCRE functions like preg_replace have a "backtrack limit"
// of 100.000 chars by default (php < 5.3.7) so if we're dealing with really
// long strings and a (sub)pattern matches a number of chars greater than
@@ -101,7 +101,7 @@ public function run($css = '', $linebreak_pos = FALSE)
$charset = '';
$charset_regexp = '/(@charset)( [^;]+;)/i';
$css_chunks = array();
- $css_chunk_length = 25000; // aprox size, not exact
+ $css_chunk_length = 5000; // aprox size, not exact
$start_index = 0;
$i = $css_chunk_length; // save initial iterations
$l = strlen($css);
@@ -113,7 +113,7 @@ public function run($css = '', $linebreak_pos = FALSE)
} else {
// chunk css code securely
while ($i < $l) {
- $i += 50; // save iterations. 500 checks for a closing curly brace }
+ $i += 50; // save iterations
if ($l - $start_index <= $css_chunk_length || $i >= $l) {
$css_chunks[] = $this->str_slice($css, $start_index);
break;
@@ -264,6 +264,9 @@ private function minify($css, $linebreak_pos)
// Normalize all whitespace strings to single spaces. Easier to work with that way.
$css = preg_replace('/\s+/', ' ', $css);
+ // Fix IE7 issue on matrix filters which browser accept whitespaces between Matrix parameters
+ $css = preg_replace_callback('/\s*filter\:\s*progid:DXImageTransform\.Microsoft\.Matrix\(([^\)]+)\)/', array($this, 'preserve_old_IE_specific_matrix_definition'), $css);
+
// Shorten & preserve calculations calc(...) since spaces are important
$css = preg_replace_callback('/calc(\(((?:[^\(\)]+|(?1))*)\))/i', array($this, 'replace_calc'), $css);
@@ -289,7 +292,7 @@ private function minify($css, $linebreak_pos)
// But, be careful not to turn "p :link {...}" into "p:link{...}"
// Swap out any pseudo-class colons with the token, and then swap back.
$css = preg_replace_callback('/(?:^|\})(?:(?:[^\{\:])+\:)+(?:[^\{]*\{)/', array($this, 'replace_colon'), $css);
-
+
// Remove spaces before the things that should not have spaces before them.
$css = preg_replace('/\s+([\!\{\}\;\:\>\+\(\)\]\~\=,])/', '$1', $css);
@@ -317,7 +320,7 @@ private function minify($css, $linebreak_pos)
// lower case some common function that can be values
// NOTE: rgb() isn't useful as we replace with #hex later, as well as and() is already done for us
$css = preg_replace_callback('/([:,\( ]\s*)(attr|color-stop|from|rgba|to|url|(?:-(?:atsc|khtml|moz|ms|o|wap|webkit)-)?(?:calc|max|min|(?:repeating-)?(?:linear|radial)-gradient)|-webkit-gradient)/iS', array($this, 'lowercase_common_functions_values'), $css);
-
+
// Put the space back in some cases, to support stuff like
// @media screen and (-webkit-min-device-pixel-ratio:0){
$css = preg_replace('/\band\(/i', 'and (', $css);
@@ -336,6 +339,9 @@ private function minify($css, $linebreak_pos)
// Replace 0 length units 0(px,em,%) with 0.
$css = preg_replace('/(^|[^0-9])(?:0?\.)?0(?:em|ex|ch|rem|vw|vh|vm|vmin|cm|mm|in|px|pt|pc|%|deg|g?rad|m?s|k?hz)/iS', '${1}0', $css);
+ // 0% step in a keyframe? restore the % unit
+ $css = preg_replace_callback('/(@[a-z\-]*?keyframes[^\{]*?\{)(.*?\}\s*\})/iS', array($this, 'replace_keyframe_zero'), $css);
+
// Replace 0 0; or 0 0 0; or 0 0 0 0; with 0.
$css = preg_replace('/\:0(?: 0){1,3}(;|\}| \!)/', ':0$1', $css);
@@ -373,6 +379,16 @@ private function minify($css, $linebreak_pos)
// Add "/" back to fix Opera -o-device-pixel-ratio query
$css = preg_replace('/'. self::QUERY_FRACTION .'/', '/', $css);
+ // Replace multiple semi-colons in a row by a single one
+ // See SF bug #1980989
+ $css = preg_replace('/;;+/', ';', $css);
+
+ // Restore new lines for /*! important comments
+ $css = preg_replace('/'. self::NL .'/', "\n", $css);
+
+ // Lowercase all uppercase properties
+ $css = preg_replace_callback('/(\{|\;)([A-Z\-]+)(\:)/', array($this, 'lowercase_properties'), $css);
+
// Some source control tools don't like it when files containing lines longer
// than, say 8000 characters, are checked in. The linebreak option is used in
// that case to split long lines after a specific column.
@@ -388,18 +404,8 @@ private function minify($css, $linebreak_pos)
}
}
- // Replace multiple semi-colons in a row by a single one
- // See SF bug #1980989
- $css = preg_replace('/;;+/', ';', $css);
-
- // Restore new lines for /*! important comments
- $css = preg_replace('/'. self::NL .'/', "\n", $css);
-
- // Lowercase all uppercase properties
- $css = preg_replace_callback('/(\{|\;)([A-Z\-]+)(\:)/', array($this, 'lowercase_properties'), $css);
-
- // restore preserved comments and strings
- for ($i = 0, $max = count($this->preserved_tokens); $i < $max; $i++) {
+ // restore preserved comments and strings in reverse order
+ for ($i = count($this->preserved_tokens) - 1; $i >= 0; $i--) {
$css = preg_replace('/' . self::TOKEN . $i . '___/', $this->preserved_tokens[$i], $css, 1);
}
@@ -582,6 +588,17 @@ private function replace_calc($matches)
return 'calc('. self::TOKEN . (count($this->preserved_tokens) - 1) . '___' . ')';
}
+ private function preserve_old_IE_specific_matrix_definition($matches)
+ {
+ $this->preserved_tokens[] = $matches[1];
+ return 'filter:progid:DXImageTransform.Microsoft.Matrix(' . self::TOKEN . (count($this->preserved_tokens) - 1) . '___' . ')';
+ }
+
+ private function replace_keyframe_zero($matches)
+ {
+ return $matches[1] . preg_replace('/0\s*,/', '0%,', preg_replace('/\s*0\s*\{/', '0%{', $matches[2]));
+ }
+
private function rgb_to_hex($matches)
{
// Support for percentage values rgb(100%, 0%, 45%);
@@ -638,22 +655,22 @@ private function lowercase_pseudo_first($matches)
return ':first-'. strtolower($matches[1]) .' '. $matches[2];
}
- private function lowercase_directives($matches)
+ private function lowercase_directives($matches)
{
return '@'. strtolower($matches[1]);
}
- private function lowercase_pseudo_elements($matches)
+ private function lowercase_pseudo_elements($matches)
{
return ':'. strtolower($matches[1]);
}
- private function lowercase_common_functions($matches)
+ private function lowercase_common_functions($matches)
{
return ':'. strtolower($matches[1]) .'(';
}
- private function lowercase_common_functions_values($matches)
+ private function lowercase_common_functions_values($matches)
{
return $matches[1] . strtolower($matches[2]);
}
View
@@ -0,0 +1,85 @@
+<?php
+/**
+ * Class Minify_CSSmin
+ * @package Minify
+ */
+
+/**
+ * Wrapper for CSSmin
+ *
+ * This class uses CSSmin and Minify_CSS_UriRewriter to minify CSS and rewrite relative URIs.
+ *
+ * @package Minify
+ * @author Stephen Clay <steve@mrclay.org>
+ */
+class Minify_CSSmin {
+
+ /**
+ * Minify a CSS string
+ *
+ * @param string $css
+ *
+ * @param array $options available options:
+ *
+ * 'removeCharsets': (default true) remove all @charset at-rules
+ *
+ * 'prependRelativePath': (default null) if given, this string will be
+ * prepended to all relative URIs in import/url declarations
+ *
+ * 'currentDir': (default null) if given, this is assumed to be the
+ * directory of the current CSS file. Using this, minify will rewrite
+ * all relative URIs in import/url declarations to correctly point to
+ * the desired files. For this to work, the files *must* exist and be
+ * visible by the PHP process.
+ *
+ * 'symlinks': (default = array()) If the CSS file is stored in
+ * a symlink-ed directory, provide an array of link paths to
+ * target paths, where the link paths are within the document root. Because
+ * paths need to be normalized for this to work, use "//" to substitute
+ * the doc root in the link paths (the array keys). E.g.:
+ * <code>
+ * array('//symlink' => '/real/target/path') // unix
+ * array('//static' => 'D:\\staticStorage') // Windows
+ * </code>
+ *
+ * 'docRoot': (default = $_SERVER['DOCUMENT_ROOT'])
+ * see Minify_CSS_UriRewriter::rewrite
+ *
+ * @return string
+ */
+ public static function minify($css, $options = array())
+ {
+ $options = array_merge(array(
+ 'compress' => true,
+ 'removeCharsets' => true,
+ 'currentDir' => null,
+ 'docRoot' => $_SERVER['DOCUMENT_ROOT'],
+ 'prependRelativePath' => null,
+ 'symlinks' => array(),
+ ), $options);
+
+ if ($options['removeCharsets']) {
+ $css = preg_replace('/@charset[^;]+;\\s*/', '', $css);
+ }
+ if ($options['compress']) {
+ $obj = new CSSmin();
+ $css = $obj->run($css);
+ }
+ if (! $options['currentDir'] && ! $options['prependRelativePath']) {
+ return $css;
+ }
+ if ($options['currentDir']) {
+ return Minify_CSS_UriRewriter::rewrite(
+ $css
+ ,$options['currentDir']
+ ,$options['docRoot']
+ ,$options['symlinks']
+ );
+ } else {
+ return Minify_CSS_UriRewriter::prepend(
+ $css
+ ,$options['prependRelativePath']
+ );
+ }
+ }
+}
View
@@ -3,7 +3,7 @@
* http://example.org/min/f=min/quick-test.css
*/
-@import url( /more.css );
+@import url( more.css );
body, td, th {
font-family: Verdana , "Bitstream Vera Sans" , Arial Narrow, sans-serif ;
@@ -43,7 +43,7 @@ function getPost($key) {
exit();
}
-$classes = array('Minify_HTML', 'Minify_CSS', 'JSMin', 'JSMinPlus');
+$classes = array('Minify_HTML', 'JSMin', 'Minify_CSS', 'Minify_CSSmin', 'JSMinPlus');
if (isset($_POST['method']) && in_array($_POST['method'], $classes)) {
@@ -1,2 +0,0 @@
-a {background-position: 0 0 0 0;}
-b {BACKGROUND-POSITION: 0 0;}
@@ -1 +0,0 @@
-a{background-position:0 0}b{background-position:0 0}
@@ -1,5 +0,0 @@
-a {
- border: none;
-}
-b {BACKGROUND:none}
-s {border-top: none;}
@@ -1 +0,0 @@
-a{border:0}b{background:0}s{border-top:0}
@@ -1,9 +0,0 @@
-#elem {
- width: 100px;
- voice-family: "\"}\"";
- voice-family:inherit;
- width: 200px;
-}
-html>body #elem {
- width: 200px;
-}
@@ -1 +0,0 @@
-#elem{width:100px;voice-family:"\"}\"";voice-family:inherit;width:200px}html>body #elem{width:200px}
@@ -1,10 +0,0 @@
-/* this file contains no css, it exists purely to put the revision number into the
- combined css before uploading it to SiteManager. The exclaimation at the start
- of the comment informs yuicompressor not to strip the comment out */
-
-/*! $LastChangedRevision: 81 $ $LastChangedDate: 2009-05-27 17:41:02 +0100 (Wed, 27 May 2009) $ */
-
-body {
- yo: cats;
-}
-ul[id$=foo] label:hover {yo: yo;}
@@ -1 +0,0 @@
-/*! $LastChangedRevision: 81 $ $LastChangedDate: 2009-05-27 17:41:02 +0100 (Wed, 27 May 2009) $ */body{yo:cats}ul[id$=foo] label:hover{yo:yo}
@@ -1,19 +0,0 @@
-@media screen and/*!YUI-Compresser */(-webkit-min-device-pixel-ratio:0) {
- a{
- b: 1;
- }
-}
-
-
-@media screen and/*! */ /*! */(-webkit-min-device-pixel-ratio:0) {
- a{
- b: 1;
- }
-}
-
-
-@media -webkit-min-device-pixel-ratio:0 {
- a{
- b: 1;
- }
-}
@@ -1 +0,0 @@
-@media screen and/*!YUI-Compresser */(-webkit-min-device-pixel-ratio:0){a{b:1}}@media screen and/*! *//*! */(-webkit-min-device-pixel-ratio:0){a{b:1}}@media -webkit-min-device-pixel-ratio:0{a{b:1}}
@@ -1,4 +0,0 @@
-/*! special */
-body {
-
-}
@@ -1 +0,0 @@
-/*! special */
@@ -1,5 +0,0 @@
-a[href$="/test/"] span:first-child { b:1; }
-a[href$="/test/"] span:first-child { }
-
-
-
@@ -1 +0,0 @@
-a[href$="/test/"] span:first-child{b:1}
@@ -1,9 +0,0 @@
-/* re: 2495387 */
-@charset 'utf-8';
-@media all {
-body {
-}
-body {
-background-color: gold;
-}
-}
@@ -1 +0,0 @@
-@charset 'utf-8';@media all{body{background-color:gold}}
@@ -1,8 +0,0 @@
-.foo, #AABBCC {
- background-color:#aabbcc;
- border-color:#Ee66aA #ABCDEF #FeAb2C;
- filter:chroma(color = #FFFFFF );
- filter:chroma(color="#AABBCC");
- filter:chroma(color='#BBDDEE');
- color:#112233
-}
@@ -1 +0,0 @@
-.foo,#AABBCC{background-color:#abc;border-color:#e6a #abcdef #feab2c;filter:chroma(color = #FFFFFF);filter:chroma(color="#AABBCC");filter:chroma(color='#BBDDEE');color:#123}
Oops, something went wrong.

0 comments on commit 218f37f

Please sign in to comment.