PluginProbe
Autoptimize / trunk
Autoptimize vtrunk
3.1.16 2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 All 108 releases
← All changes | classes/external/php/yui-php-cssmin-bundled/Minifier.php +46 -3 2.4.0 → trunk View file →
@@ -28,13 +28,15 @@
28 28 const COMMENT_TOKEN = '_CSSMIN_CMT_%d_';
29 29 const COMMENT_TOKEN_START = '_CSSMIN_CMT_';
30 30 const RULE_BODY_TOKEN = '_CSSMIN_RBT_%d_';
31 31 const PRESERVED_TOKEN = '_CSSMIN_PTK_%d_';
32 + const UNQUOTED_FONT_TOKEN = '_CSSMIN_UFT_%d_';
32 33
33 34 // Token lists
34 35 private $comments = array();
35 36 private $ruleBodies = array();
36 37 private $preservedTokens = array();
38 + private $unquotedFontTokens = array();
37 39
38 40 // Output options
39 41 private $keepImportantComments = true;
40 42 private $keepSourceMapComment = false;
@@ -61,8 +63,9 @@
61 63 private $shortenTwoZeroesRegex;
62 64 private $shortenThreeZeroesRegex;
63 65 private $shortenFourZeroesRegex;
64 66 private $unitsGroupRegex = '(?:ch|cm|em|ex|gd|in|mm|px|pt|pc|q|rem|vh|vmax|vmin|vw|%)';
67 + private $unquotedFontsRegex = '/(font-family:|font:)([^\'"]+?)[^};]*/Si';
65 68
66 69 /**
67 70 * @param bool|int $raisePhpLimits If true, PHP settings will be raised if needed
68 71 */
@@ -286,8 +289,19 @@
286 289 $this->ruleBodies[$tokenId] = $body;
287 290 return $tokenId;
288 291 }
289 292
293 + private function registerUnquotedFontToken($body)
294 + {
295 + if (empty($body)) {
296 + return '';
297 + }
298 +
299 + $tokenId = sprintf(self::UNQUOTED_FONT_TOKEN, count($this->unquotedFontTokens));
300 + $this->unquotedFontTokens[$tokenId] = $body;
301 + return $tokenId;
302 + }
303 +
290 304 /**
291 305 * Parses & minifies the given input CSS string
292 306 * @param string $css
293 307 * @return string
@@ -514,8 +528,13 @@
514 528 $searchOffset = $substrOffset = 0;
515 529
516 530 while (($blockStartPos = strpos($css, '{', $searchOffset)) !== false) {
517 531 $blockEndPos = strpos($css, '}', $blockStartPos);
532 + // When ending curly brace is missing, let's
533 + // behave like there was one at the end of the block...
534 + if ( false === $blockEndPos ) {
535 + $blockEndPos = strlen($css) - 1;
536 + }
518 537 $nextBlockStartPos = strpos($css, '{', $blockStartPos + 1);
519 538 $ret .= substr($css, $substrOffset, $blockStartPos - $substrOffset);
520 539
521 540 if ($nextBlockStartPos !== false && $nextBlockStartPos < $blockEndPos) {
@@ -585,10 +604,13 @@
585 604
586 605 // Shorten colors from rgb(51,102,153) to #336699, rgb(100%,0%,0%) to #ff0000 (sRGB color space)
587 606 // Shorten colors from hsl(0, 100%, 50%) to #ff0000 (sRGB color space)
588 607 // This makes it more likely that it'll get further compressed in the next step.
608 + // Only the plain three-component form is converted (comma- or space-separated).
609 + // Colors with an alpha channel, i.e. rgb(0, 0, 0, .5) and rgb(0 0 0 / 50%), are
610 + // left alone just like rgba()/hsla(): a 6-digit hex cannot carry the alpha.
589 611 $body = preg_replace_callback(
590 - '/(rgb|hsl)\(([0-9,.% -]+)\)(.|$)/Si',
612 + '/(rgb|hsl)\(\s*(-?[0-9.]+%?)\s*[, ]\s*(-?[0-9.]+%?)\s*[, ]\s*(-?[0-9.]+%?)\s*\)(.|$)/Si',
591 613 array($this, 'shortenHslAndRgbToHexCallback'),
592 614 $body
593 615 );
594 616
@@ -599,8 +621,16 @@
599 621 array($this, 'shortenHexColorsCallback'),
600 622 $body
601 623 );
602 624
625 + // Tokenize unquoted font names in order to hide them from
626 + // color name replacements.
627 + $body = preg_replace_callback(
628 + $this->unquotedFontsRegex,
629 + array($this, 'preserveUnquotedFontTokens'),
630 + $body
631 + );
632 +
603 633 // Shorten long named colors with a shorter HEX counterpart: white -> #fff.
604 634 // Run at least 2 times to cover most cases
605 635 $body = preg_replace_callback(
606 636 array($this->namedToHexColorsRegex, $this->namedToHexColorsRegex),
@@ -607,8 +637,11 @@
607 637 array($this, 'shortenNamedColorsCallback'),
608 638 $body
609 639 );
610 640
641 + // Restore unquoted font tokens now after colors have been changed.
642 + $body = $this->restoreUnquotedFontTokens($body);
643 +
611 644 // Replace positive sign from numbers before the leading space is removed.
612 645 // +1.2em to 1.2em, +.8px to .8px, +2% to 2%
613 646 $body = preg_replace('/([ :,(])\+(\.?\d+)/S', '$1$2', $body);
614 647
@@ -694,8 +727,18 @@
694 727
695 728 return $body;
696 729 }
697 730
731 + private function preserveUnquotedFontTokens($matches)
732 + {
733 + return $this->registerUnquotedFontToken($matches[0]);
734 + }
735 +
736 + private function restoreUnquotedFontTokens($body)
737 + {
738 + return strtr($body, $this->unquotedFontTokens);
739 + }
740 +
698 741 /**
699 742 * Compresses At-rules and selectors.
700 743 * @param string $css the whole stylesheet with rule bodies tokenized.
701 744 * @return string
@@ -830,10 +873,10 @@
830 873 */
831 874 private function shortenHslAndRgbToHexCallback($matches)
832 875 {
833 876 $type = $matches[1];
834 - $values = explode(',', $matches[2]);
835 - $terminator = $matches[3];
877 + $values = array($matches[2], $matches[3], $matches[4]);
878 + $terminator = $matches[5];
836 879
837 880 if ($type === 'hsl') {
838 881 $values = Utils::hslToRgb($values);
839 882 }