Update composer dependencies

This commit is contained in:
Kijin Sung 2020-04-08 00:10:06 +09:00
parent 255352df62
commit 61d2e8c141
419 changed files with 37794 additions and 5489 deletions

View file

@ -217,6 +217,8 @@ class CSS extends Minify
// grab referenced file & minify it (which may include importing
// yet other @import statements recursively)
$minifier = new static($importPath);
$minifier->setMaxImportSize($this->maxImportSize);
$minifier->setImportExtensions($this->importExtensions);
$importContent = $minifier->execute($source, $parents);
// check if this is only valid for certain media
@ -305,10 +307,11 @@ class CSS extends Minify
*/
$this->extractStrings();
$this->stripComments();
$this->extractCalcs();
$css = $this->replace($css);
$css = $this->stripWhitespace($css);
$css = $this->shortenHex($css);
$css = $this->shortenColors($css);
$css = $this->shortenZeroes($css);
$css = $this->shortenFontWeights($css);
$css = $this->stripEmptyTags($css);
@ -479,12 +482,16 @@ class CSS extends Minify
*
* @return string
*/
protected function shortenHex($content)
protected function shortenColors($content)
{
$content = preg_replace('/(?<=[: ])#([0-9a-z])\\1([0-9a-z])\\2([0-9a-z])\\3(?=[; }])/i', '#$1$2$3', $content);
$content = preg_replace('/(?<=[: ])#([0-9a-z])\\1([0-9a-z])\\2([0-9a-z])\\3(?:([0-9a-z])\\4)?(?=[; }])/i', '#$1$2$3$4', $content);
// remove alpha channel if it's pointless...
$content = preg_replace('/(?<=[: ])#([0-9a-z]{6})ff?(?=[; }])/i', '#$1', $content);
$content = preg_replace('/(?<=[: ])#([0-9a-z]{3})f?(?=[; }])/i', '#$1', $content);
// we can shorten some even more by replacing them with their color name
$colors = array(
// we can shorten some even more by replacing them with their color name
'#F0FFFF' => 'azure',
'#F5F5DC' => 'beige',
'#A52A2A' => 'brown',
@ -512,10 +519,13 @@ class CSS extends Minify
'#FF6347' => 'tomato',
'#EE82EE' => 'violet',
'#F5DEB3' => 'wheat',
// or the other way around
'WHITE' => '#fff',
'BLACK' => '#000',
);
return preg_replace_callback(
'/(?<=[: ])('.implode(array_keys($colors), '|').')(?=[; }])/i',
'/(?<=[: ])('.implode('|', array_keys($colors)).')(?=[; }])/i',
function ($match) use ($colors) {
return $colors[strtoupper($match[0])];
},
@ -557,11 +567,7 @@ class CSS extends Minify
// `5px - 0px` is valid, but `5px - 0` is not
// `10px * 0` is valid (equates to 0), and so is `10 * 0px`, but
// `10 * 0` is invalid
// best to just leave `calc()`s alone, even if they could be optimized
// (which is a whole other undertaking, where units & order of
// operations all need to be considered...)
$calcs = $this->findCalcs($content);
$content = str_replace($calcs, array_keys($calcs), $content);
// we've extracted calcs earlier, so we don't need to worry about this
// reusable bits of code throughout these regexes:
// before & after are used to make sure we don't match lose unintended
@ -598,9 +604,6 @@ class CSS extends Minify
$content = preg_replace('/flex:([0-9]+\s[0-9]+\s)0([;\}])/', 'flex:${1}0%${2}', $content);
$content = preg_replace('/flex-basis:0([;\}])/', 'flex-basis:0%${1}', $content);
// restore `calc()` expressions
$content = str_replace(array_keys($calcs), $calcs, $content);
return $content;
}
@ -624,6 +627,17 @@ class CSS extends Minify
*/
protected function stripComments()
{
// PHP only supports $this inside anonymous functions since 5.4
$minifier = $this;
$callback = function ($match) use ($minifier) {
$count = count($minifier->extracted);
$placeholder = '/*'.$count.'*/';
$minifier->extracted[$placeholder] = $match[0];
return $placeholder;
};
$this->registerPattern('/\n?\/\*(!|.*?@license|.*?@preserve).*?\*\/\n?/s', $callback);
$this->registerPattern('/\/\*.*?\*\//s', '');
}
@ -646,8 +660,8 @@ class CSS extends Minify
// remove whitespace around meta characters
// inspired by stackoverflow.com/questions/15195750/minify-compress-css-with-regex
$content = preg_replace('/\s*([\*$~^|]?+=|[{};,>~]|!important\b)\s*/', '$1', $content);
$content = preg_replace('/([\[(:])\s+/', '$1', $content);
$content = preg_replace('/\s+([\]\)])/', '$1', $content);
$content = preg_replace('/([\[(:>\+])\s+/', '$1', $content);
$content = preg_replace('/\s+([\]\)>\+])/', '$1', $content);
$content = preg_replace('/\s+(:)(?![^\}]*\{)/', '$1', $content);
// whitespace around + and - can only be stripped inside some pseudo-
@ -664,18 +678,13 @@ class CSS extends Minify
}
/**
* Find all `calc()` occurrences.
*
* @param string $content The CSS content to find `calc()`s in.
*
* @return string[]
* Replace all `calc()` occurrences.
*/
protected function findCalcs($content)
protected function extractCalcs()
{
$results = array();
preg_match_all('/calc(\(.+?)(?=$|;|calc\()/', $content, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
// PHP only supports $this inside anonymous functions since 5.4
$minifier = $this;
$callback = function ($match) use ($minifier) {
$length = strlen($match[1]);
$expr = '';
$opened = 0;
@ -689,11 +698,18 @@ class CSS extends Minify
break;
}
}
$rest = str_replace($expr, '', $match[1]);
$expr = trim(substr($expr, 1, -1));
$results['calc('.count($results).')'] = 'calc'.$expr;
}
$count = count($minifier->extracted);
$placeholder = 'calc('.$count.')';
$minifier->extracted[$placeholder] = 'calc('.$expr.')';
return $results;
return $placeholder.$rest;
};
$this->registerPattern('/calc(\(.+?)(?=$|;|}|calc\()/', $callback);
$this->registerPattern('/calc(\(.+?)(?=$|;|}|calc\()/m', $callback);
}
/**

View file

@ -195,11 +195,21 @@ class JS extends Minify
*/
protected function stripComments()
{
// PHP only supports $this inside anonymous functions since 5.4
$minifier = $this;
$callback = function ($match) use ($minifier) {
$count = count($minifier->extracted);
$placeholder = '/*'.$count.'*/';
$minifier->extracted[$placeholder] = $match[0];
return $placeholder;
};
// multi-line comments
$this->registerPattern('/\n?\/\*(!|.*?@license|.*?@preserve).*?\*\/\n?/s', $callback);
$this->registerPattern('/\/\*.*?\*\//s', '');
// single-line comments
$this->registerPattern('/\/\/.*$/m', '');
// multi-line comments
$this->registerPattern('/\/\*.*?\*\//s', '');
}
/**
@ -238,7 +248,7 @@ class JS extends Minify
// closing the regex)
// then also ignore bare `/` inside `[]`, where they don't need to be
// escaped: anything inside `[]` can be ignored safely
$pattern = '\\/(?:[^\\[\\/\\\\\n\r]+|(?:\\\\.)+|(?:\\[(?:[^\\]\\\\\n\r]+|(?:\\\\.)+)+\\])+)++\\/[gimuy]*';
$pattern = '\\/(?!\*)(?:[^\\[\\/\\\\\n\r]++|(?:\\\\.)++|(?:\\[(?:[^\\]\\\\\n\r]++|(?:\\\\.)++)++\\])++)++\\/[gimuy]*';
// a regular expression can only be followed by a few operators or some
// of the RegExp methods (a `\` followed by a variable or value is
@ -335,7 +345,9 @@ class JS extends Minify
array(
'/('.implode('|', $operatorsBefore).')\s+/',
'/\s+('.implode('|', $operatorsAfter).')/',
), '\\1', $content
),
'\\1',
$content
);
// make sure + and - can't be mistaken for, or joined into ++ and --
@ -343,7 +355,9 @@ class JS extends Minify
array(
'/(?<![\+\-])\s*([\+\-])(?![\+\-])/',
'/(?<![\+\-])([\+\-])\s*(?![\+\-])/',
), '\\1', $content
),
'\\1',
$content
);
// collapse whitespace around reserved words into single space

View file

@ -99,6 +99,44 @@ abstract class Minify
return $this;
}
/**
* Add a file to be minified.
*
* @param string|string[] $data
*
* @return static
*
* @throws IOException
*/
public function addFile($data /* $data = null, ... */)
{
// bogus "usage" of parameter $data: scrutinizer warns this variable is
// not used (we're using func_get_args instead to support overloading),
// but it still needs to be defined because it makes no sense to have
// this function without argument :)
$args = array($data) + func_get_args();
// this method can be overloaded
foreach ($args as $path) {
if (is_array($path)) {
call_user_func_array(array($this, 'addFile'), $path);
continue;
}
// redefine var
$path = (string) $path;
// check if we can read the file
if (!$this->canImportFile($path)) {
throw new IOException('The file "'.$path.'" could not be opened for reading. Check if PHP has enough permissions.');
}
$this->add($path);
}
return $this;
}
/**
* Minify the data & (optionally) saves it to a file.
*
@ -241,7 +279,7 @@ abstract class Minify
// we can safely ignore patterns for positions we've unset earlier,
// because we know these won't show up anymore
if (!isset($positions[$i])) {
if (array_key_exists($i, $positions) == false) {
continue;
}

View file

@ -31,16 +31,17 @@ class Converter implements ConverterInterface
/**
* @param string $from The original base path (directory, not file!)
* @param string $to The new base path (directory, not file!)
* @param string $root Root directory (defaults to `getcwd`)
*/
public function __construct($from, $to)
public function __construct($from, $to, $root = '')
{
$shared = $this->shared($from, $to);
if ($shared === '') {
// when both paths have nothing in common, one of them is probably
// absolute while the other is relative
$cwd = getcwd();
$from = strpos($from, $cwd) === 0 ? $from : $cwd.'/'.$from;
$to = strpos($to, $cwd) === 0 ? $to : $cwd.'/'.$to;
$root = $root ?: getcwd();
$from = strpos($from, $root) === 0 ? $from : preg_replace('/\/+/', '/', $root.'/'.$from);
$to = strpos($to, $root) === 0 ? $to : preg_replace('/\/+/', '/', $root.'/'.$to);
// or traveling the tree via `..`
// attempt to resolve path, or assume it's fine if it doesn't exist
@ -70,6 +71,14 @@ class Converter implements ConverterInterface
// deal with different operating systems' directory structure
$path = rtrim(str_replace(DIRECTORY_SEPARATOR, '/', $path), '/');
// remove leading current directory.
if (substr($path, 0, 2) === './') {
$path = substr($path, 2);
}
// remove references to current directory in the path.
$path = str_replace('/./', '/', $path);
/*
* Example:
* /home/forkcms/frontend/cache/compiled_templates/../../core/layout/css/../images/img.gif
@ -155,7 +164,7 @@ class Converter implements ConverterInterface
$to = mb_substr($this->to, mb_strlen($shared));
// add .. for every directory that needs to be traversed to new path
$to = str_repeat('../', mb_substr_count($to, '/'));
$to = str_repeat('../', count(array_filter(explode('/', $to))));
return $to.ltrim($path, '/');
}