mirror of
https://github.com/moodle/moodle.git
synced 2025-03-21 08:00:37 +01:00
MDL-65744 lib: Update minify minify lib
This commit is contained in:
parent
f7e108438f
commit
0918e156a0
18
lib/minify/matthiasmullie-minify/LICENSE
Executable file
18
lib/minify/matthiasmullie-minify/LICENSE
Executable file
@ -0,0 +1,18 @@
|
||||
Copyright (c) 2012 Matthias Mullie
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@ -1,4 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* CSS Minifier
|
||||
*
|
||||
* Please report bugs on https://github.com/matthiasmullie/minify/issues
|
||||
*
|
||||
* @author Matthias Mullie <minify@mullie.eu>
|
||||
* @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
namespace MatthiasMullie\Minify;
|
||||
|
||||
@ -7,10 +16,11 @@ use MatthiasMullie\PathConverter\ConverterInterface;
|
||||
use MatthiasMullie\PathConverter\Converter;
|
||||
|
||||
/**
|
||||
* CSS minifier.
|
||||
* CSS minifier
|
||||
*
|
||||
* Please report bugs on https://github.com/matthiasmullie/minify/issues
|
||||
*
|
||||
* @package Minify
|
||||
* @author Matthias Mullie <minify@mullie.eu>
|
||||
* @author Tijs Verkoyen <minify@verkoyen.eu>
|
||||
* @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
|
||||
@ -19,12 +29,12 @@ use MatthiasMullie\PathConverter\Converter;
|
||||
class CSS extends Minify
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
* @var int maximum inport size in kB
|
||||
*/
|
||||
protected $maxImportSize = 5;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* @var string[] valid import extensions
|
||||
*/
|
||||
protected $importExtensions = array(
|
||||
'gif' => 'data:image/gif',
|
||||
@ -76,14 +86,14 @@ class CSS extends Minify
|
||||
*/
|
||||
protected function moveImportsToTop($content)
|
||||
{
|
||||
if (preg_match_all('/@import[^;]+;/', $content, $matches)) {
|
||||
if (preg_match_all('/(;?)(@import (?<url>url\()?(?P<quotes>["\']?).+?(?P=quotes)(?(url)\)));?/', $content, $matches)) {
|
||||
// remove from content
|
||||
foreach ($matches[0] as $import) {
|
||||
$content = str_replace($import, '', $content);
|
||||
}
|
||||
|
||||
// add to top
|
||||
$content = implode('', $matches[0]).$content;
|
||||
$content = implode(';', $matches[2]).';'.trim($content, ';');
|
||||
}
|
||||
|
||||
return $content;
|
||||
@ -207,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
|
||||
@ -295,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);
|
||||
@ -469,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',
|
||||
@ -502,6 +519,9 @@ class CSS extends Minify
|
||||
'#FF6347' => 'tomato',
|
||||
'#EE82EE' => 'violet',
|
||||
'#F5DEB3' => 'wheat',
|
||||
// or the other way around
|
||||
'WHITE' => '#fff',
|
||||
'BLACK' => '#000',
|
||||
);
|
||||
|
||||
return preg_replace_callback(
|
||||
@ -543,6 +563,12 @@ class CSS extends Minify
|
||||
*/
|
||||
protected function shortenZeroes($content)
|
||||
{
|
||||
// we don't want to strip units in `calc()` expressions:
|
||||
// `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
|
||||
// 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
|
||||
// 0-like values (e.g. in #000, or in http://url/1.0)
|
||||
@ -571,28 +597,11 @@ class CSS extends Minify
|
||||
// strip negative zeroes (-0 -> 0) & truncate zeroes (00 -> 0)
|
||||
$content = preg_replace('/'.$before.'-?0+'.$units.'?'.$after.'/', '0\\1', $content);
|
||||
|
||||
// remove zeroes where they make no sense in calc: e.g. calc(100px - 0)
|
||||
// the 0 doesn't have any effect, and this isn't even valid without unit
|
||||
// strip all `+ 0` or `- 0` occurrences: calc(10% + 0) -> calc(10%)
|
||||
// looped because there may be multiple 0s inside 1 group of parentheses
|
||||
do {
|
||||
$previous = $content;
|
||||
$content = preg_replace('/\(([^\(\)]+) [\+\-] 0( [^\(\)]+)?\)/', '(\\1\\2)', $content);
|
||||
} while ($content !== $previous);
|
||||
// strip all `0 +` occurrences: calc(0 + 10%) -> calc(10%)
|
||||
$content = preg_replace('/\(0 \+ ([^\(\)]+)\)/', '(\\1)', $content);
|
||||
// strip all `0 -` occurrences: calc(0 - 10%) -> calc(-10%)
|
||||
$content = preg_replace('/\(0 \- ([^\(\)]+)\)/', '(-\\1)', $content);
|
||||
// I'm not going to attempt to optimize away `x * 0` instances:
|
||||
// it's dumb enough code already that it likely won't occur, and it's
|
||||
// too complex to do right (order of operations would have to be
|
||||
// respected etc)
|
||||
// what I cared about most here was fixing incorrectly truncated units
|
||||
|
||||
// IE doesn't seem to understand a unitless flex-basis value, so let's
|
||||
// add it in again (make it `%`, which is only 1 char: 0%, 0px, 0
|
||||
// anything, it's all just the same)
|
||||
$content = preg_replace('/flex:([^ ]+ [^ ]+ )0([;\}])/', 'flex:${1}0%${2}', $content);
|
||||
// IE doesn't seem to understand a unitless flex-basis value (correct -
|
||||
// it goes against the spec), so let's add it in again (make it `%`,
|
||||
// which is only 1 char: 0%, 0px, 0 anything, it's all just the same)
|
||||
// @see https://developer.mozilla.org/nl/docs/Web/CSS/flex
|
||||
$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);
|
||||
|
||||
return $content;
|
||||
@ -607,7 +616,10 @@ class CSS extends Minify
|
||||
*/
|
||||
protected function stripEmptyTags($content)
|
||||
{
|
||||
return preg_replace('/(^|\}|;)[^\{\};]+\{\s*\}/', '\\1', $content);
|
||||
$content = preg_replace('/(?<=^)[^\{\};]+\{\s*\}/', '', $content);
|
||||
$content = preg_replace('/(?<=(\}|;))[^\{\};]+\{\s*\}/', '', $content);
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -615,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', '');
|
||||
}
|
||||
|
||||
@ -637,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-
|
||||
@ -654,6 +677,40 @@ class CSS extends Minify
|
||||
return trim($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all `calc()` occurrences.
|
||||
*/
|
||||
protected function extractCalcs()
|
||||
{
|
||||
// PHP only supports $this inside anonymous functions since 5.4
|
||||
$minifier = $this;
|
||||
$callback = function ($match) use ($minifier) {
|
||||
$length = strlen($match[1]);
|
||||
$expr = '';
|
||||
$opened = 0;
|
||||
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$char = $match[1][$i];
|
||||
$expr .= $char;
|
||||
if ($char === '(') {
|
||||
$opened++;
|
||||
} elseif ($char === ')' && --$opened === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$rest = str_replace($expr, '', $match[1]);
|
||||
$expr = trim(substr($expr, 1, -1));
|
||||
|
||||
$count = count($minifier->extracted);
|
||||
$placeholder = 'calc('.$count.')';
|
||||
$minifier->extracted[$placeholder] = 'calc('.$expr.')';
|
||||
|
||||
return $placeholder.$rest;
|
||||
};
|
||||
|
||||
$this->registerPattern('/calc(\(.+?)(?=$|;|calc\()/', $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if file is small enough to be imported.
|
||||
*
|
||||
|
@ -1,10 +1,18 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Base Exception
|
||||
*
|
||||
* @deprecated Use Exceptions\BasicException instead
|
||||
*
|
||||
* @author Matthias Mullie <minify@mullie.eu>
|
||||
*/
|
||||
namespace MatthiasMullie\Minify;
|
||||
|
||||
/**
|
||||
* Base Exception Class
|
||||
* @deprecated Use Exceptions\BasicException instead
|
||||
*
|
||||
* @package Minify
|
||||
* @author Matthias Mullie <minify@mullie.eu>
|
||||
*/
|
||||
abstract class Exception extends \Exception
|
||||
|
@ -1,10 +1,21 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Basic exception
|
||||
*
|
||||
* Please report bugs on https://github.com/matthiasmullie/minify/issues
|
||||
*
|
||||
* @author Matthias Mullie <minify@mullie.eu>
|
||||
* @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
|
||||
* @license MIT License
|
||||
*/
|
||||
namespace MatthiasMullie\Minify\Exceptions;
|
||||
|
||||
use MatthiasMullie\Minify\Exception;
|
||||
|
||||
/**
|
||||
* Basic Exception Class
|
||||
*
|
||||
* @package Minify\Exception
|
||||
* @author Matthias Mullie <minify@mullie.eu>
|
||||
*/
|
||||
abstract class BasicException extends Exception
|
||||
|
@ -1,8 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* File Import Exception
|
||||
*
|
||||
* Please report bugs on https://github.com/matthiasmullie/minify/issues
|
||||
*
|
||||
* @author Matthias Mullie <minify@mullie.eu>
|
||||
* @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
|
||||
* @license MIT License
|
||||
*/
|
||||
namespace MatthiasMullie\Minify\Exceptions;
|
||||
|
||||
/**
|
||||
* File Import Exception Class
|
||||
*
|
||||
* @package Minify\Exception
|
||||
* @author Matthias Mullie <minify@mullie.eu>
|
||||
*/
|
||||
class FileImportException extends BasicException
|
||||
|
@ -1,8 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* IO Exception
|
||||
*
|
||||
* Please report bugs on https://github.com/matthiasmullie/minify/issues
|
||||
*
|
||||
* @author Matthias Mullie <minify@mullie.eu>
|
||||
* @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
|
||||
* @license MIT License
|
||||
*/
|
||||
namespace MatthiasMullie\Minify\Exceptions;
|
||||
|
||||
/**
|
||||
* IO Exception Class
|
||||
*
|
||||
* @package Minify\Exception
|
||||
* @author Matthias Mullie <minify@mullie.eu>
|
||||
*/
|
||||
class IOException extends BasicException
|
||||
|
@ -1,13 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace MatthiasMullie\Minify;
|
||||
|
||||
/**
|
||||
* JavaScript minifier.
|
||||
* JavaScript minifier
|
||||
*
|
||||
* Please report bugs on https://github.com/matthiasmullie/minify/issues
|
||||
*
|
||||
* @author Matthias Mullie <minify@mullie.eu>
|
||||
* @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
|
||||
* @license MIT License
|
||||
*/
|
||||
namespace MatthiasMullie\Minify;
|
||||
|
||||
/**
|
||||
* JavaScript Minifier Class
|
||||
*
|
||||
* Please report bugs on https://github.com/matthiasmullie/minify/issues
|
||||
*
|
||||
* @package Minify
|
||||
* @author Matthias Mullie <minify@mullie.eu>
|
||||
* @author Tijs Verkoyen <minify@verkoyen.eu>
|
||||
* @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
|
||||
* @license MIT License
|
||||
@ -110,11 +119,6 @@ class JS extends Minify
|
||||
*/
|
||||
protected $operatorsAfter = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $nestedExtracted = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -144,19 +148,6 @@ class JS extends Minify
|
||||
{
|
||||
$content = '';
|
||||
|
||||
// loop files
|
||||
foreach ($this->data as $source => $js) {
|
||||
/*
|
||||
* Combine js: separating the scripts by a ;
|
||||
* I'm also adding a newline: it will be eaten when whitespace is
|
||||
* stripped, but we need to make sure we're not just appending
|
||||
* a new script right after a previous script that ended with a
|
||||
* singe-line comment on the last line (in which case it would also
|
||||
* be seen as part of that comment)
|
||||
*/
|
||||
$content .= $js."\n;";
|
||||
}
|
||||
|
||||
/*
|
||||
* Let's first take out strings, comments and regular expressions.
|
||||
* All of these can contain JS code-like characters, and we should make
|
||||
@ -171,11 +162,24 @@ class JS extends Minify
|
||||
$this->extractStrings('\'"`');
|
||||
$this->stripComments();
|
||||
$this->extractRegex();
|
||||
$content = $this->replace($content);
|
||||
|
||||
$content = $this->propertyNotation($content);
|
||||
$content = $this->shortenBools($content);
|
||||
$content = $this->stripWhitespace($content);
|
||||
// loop files
|
||||
foreach ($this->data as $source => $js) {
|
||||
// take out strings, comments & regex (for which we've registered
|
||||
// the regexes just a few lines earlier)
|
||||
$js = $this->replace($js);
|
||||
|
||||
$js = $this->propertyNotation($js);
|
||||
$js = $this->shortenBools($js);
|
||||
$js = $this->stripWhitespace($js);
|
||||
|
||||
// combine js: separating the scripts by a ;
|
||||
$content .= $js.";";
|
||||
}
|
||||
|
||||
// clean up leftover `;`s from the combination of multiple scripts
|
||||
$content = ltrim($content, ';');
|
||||
$content = (string) substr($content, 0, -1);
|
||||
|
||||
/*
|
||||
* Earlier, we extracted strings & regular expressions and replaced them
|
||||
@ -191,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', '');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -222,38 +236,26 @@ class JS extends Minify
|
||||
$callback = function ($match) use ($minifier) {
|
||||
$count = count($minifier->extracted);
|
||||
$placeholder = '"'.$count.'"';
|
||||
$minifier->extracted[$placeholder] = $match['regex'];
|
||||
$minifier->extracted[$placeholder] = $match[0];
|
||||
|
||||
// because we're also trying to find regular expressions that follow
|
||||
// if/when/for statements, we should also make sure that the content
|
||||
// within these statements is also minified...
|
||||
// e.g. `if("some string"/* or comment */)` should become
|
||||
// `if("some string")`
|
||||
if (isset($match['before'])) {
|
||||
$other = new static();
|
||||
$other->extractStrings('\'"`', "$count-");
|
||||
$other->stripComments();
|
||||
$match['before'] = $other->replace($match['before']);
|
||||
$this->nestedExtracted += $other->extracted;
|
||||
}
|
||||
|
||||
return (isset($match['before']) ? $match['before'] : '').
|
||||
$placeholder.
|
||||
(isset($match['after']) ? $match['after'] : '');
|
||||
return $placeholder;
|
||||
};
|
||||
|
||||
$pattern = '(?P<regex>\/.+?((?<!\\\\)\\\\\\\\)*\/[gimy]*)(?![0-9a-zA-Z\/])';
|
||||
// match all chars except `/` and `\`
|
||||
// `\` is allowed though, along with whatever char follows (which is the
|
||||
// one being escaped)
|
||||
// this should allow all chars, except for an unescaped `/` (= the one
|
||||
// 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]*';
|
||||
|
||||
// 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
|
||||
// likely part of a division, not a regex)
|
||||
$keywords = array('do', 'in', 'new', 'else', 'throw', 'yield', 'delete', 'return', 'typeof');
|
||||
$before = '(?P<before>[=:,;\}\(\{&\|!]|^|'.implode('|', $keywords).')';
|
||||
$before = '([=:,;\+\-\*\/\}\(\{\[&\|!]|^|'.implode('|', $keywords).')\s*';
|
||||
$propertiesAndMethods = array(
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#Properties
|
||||
'prototype',
|
||||
'length',
|
||||
'lastIndex',
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#Properties_2
|
||||
'constructor',
|
||||
'flags',
|
||||
@ -267,29 +269,28 @@ class JS extends Minify
|
||||
'compile(',
|
||||
'exec(',
|
||||
'test(',
|
||||
'match',
|
||||
'replace(',
|
||||
'search(',
|
||||
'split(',
|
||||
'toSource(',
|
||||
'toString(',
|
||||
);
|
||||
$delimiters = array_fill(0, count($propertiesAndMethods), '/');
|
||||
$propertiesAndMethods = array_map('preg_quote', $propertiesAndMethods, $delimiters);
|
||||
$after = '(?P<after>[\.,;\)\}&\|+]|$|\.('.implode('|', $propertiesAndMethods).'))';
|
||||
$this->registerPattern('/'.$before.'\s*'.$pattern.'\s*'.$after.'/', $callback);
|
||||
$after = '(?=\s*([\.,;\)\}&\|+]|\/\/|$|\.('.implode('|', $propertiesAndMethods).')))';
|
||||
$this->registerPattern('/'.$before.'\K'.$pattern.$after.'/', $callback);
|
||||
|
||||
// we didn't check for regular expressions after `)`, because that is
|
||||
// more often than not not a character where a regex can follow (e.g.
|
||||
// (1+2)/3/4 -> /3/ could be considered a regex, but it's not)
|
||||
// however, after single-line if/while/for, there could very well be a
|
||||
// regex after `)` (e.g. if(true)/regex/)
|
||||
// there is one problem, though: it's (near) impossible to check for
|
||||
// when the if/while/for statement is closed (same amount of closing
|
||||
// brackets as there were opened), so I'll ignore single-line statements
|
||||
// with nested brackets followed by a regex for now...
|
||||
$before = '(?P<before>\b(if|while|for)\s*\((?P<code>[^\(]+?)\))';
|
||||
$this->registerPattern('/'.$before.'\s*'.$pattern.'\s*'.$after.'/', $callback);
|
||||
// regular expressions following a `)` are rather annoying to detect...
|
||||
// quite often, `/` after `)` is a division operator & if it happens to
|
||||
// be followed by another one (or a comment), it is likely to be
|
||||
// confused for a regular expression
|
||||
// however, it's perfectly possible for a regex to follow a `)`: after
|
||||
// a single-line `if()`, `while()`, ... statement, for example
|
||||
// since, when they occur like that, they're always the start of a
|
||||
// statement, there's only a limited amount of ways they can be useful:
|
||||
// by calling the regex methods directly
|
||||
// if a regex following `)` is not followed by `.<property or method>`,
|
||||
// it's quite likely not a regex
|
||||
$before = '\)\s*';
|
||||
$after = '(?=\s*\.('.implode('|', $propertiesAndMethods).'))';
|
||||
$this->registerPattern('/'.$before.'\K'.$pattern.$after.'/', $callback);
|
||||
|
||||
// 1 more edge case: a regex can be followed by a lot more operators or
|
||||
// keywords if there's a newline (ASI) in between, where the operator
|
||||
@ -297,25 +298,8 @@ class JS extends Minify
|
||||
// (https://github.com/matthiasmullie/minify/issues/56)
|
||||
$operators = $this->getOperatorsForRegex($this->operatorsBefore, '/');
|
||||
$operators += $this->getOperatorsForRegex($this->keywordsReserved, '/');
|
||||
$after = '(?P<after>\n\s*('.implode('|', $operators).'))';
|
||||
$this->registerPattern('/'.$pattern.'\s*'.$after.'/', $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* In addition to the regular restore routine, we also need to restore a few
|
||||
* more things that have been extracted as part of the regex extraction...
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function restoreExtractedData($content)
|
||||
{
|
||||
// restore regular extracted stuff
|
||||
$content = parent::restoreExtractedData($content);
|
||||
|
||||
// restore nested stuff from within regex extraction
|
||||
$content = strtr($content, $this->nestedExtracted);
|
||||
|
||||
return $content;
|
||||
$after = '(?=\s*\n\s*('.implode('|', $operators).'))';
|
||||
$this->registerPattern('/'.$pattern.$after.'/', $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -361,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 --
|
||||
@ -369,7 +355,9 @@ class JS extends Minify
|
||||
array(
|
||||
'/(?<![\+\-])\s*([\+\-])(?![\+\-])/',
|
||||
'/(?<![\+\-])([\+\-])\s*(?![\+\-])/',
|
||||
), '\\1', $content
|
||||
),
|
||||
'\\1',
|
||||
$content
|
||||
);
|
||||
|
||||
// collapse whitespace around reserved words into single space
|
||||
@ -387,6 +375,16 @@ class JS extends Minify
|
||||
$content = preg_replace('/('.implode('|', $operatorsDiffBefore).')[^\S\n]+/', '\\1', $content);
|
||||
$content = preg_replace('/[^\S\n]+('.implode('|', $operatorsDiffAfter).')/', '\\1', $content);
|
||||
|
||||
/*
|
||||
* Whitespace after `return` can be omitted in a few occasions
|
||||
* (such as when followed by a string or regex)
|
||||
* Same for whitespace in between `)` and `{`, or between `{` and some
|
||||
* keywords.
|
||||
*/
|
||||
$content = preg_replace('/\breturn\s+(["\'\/\+\-])/', 'return$1', $content);
|
||||
$content = preg_replace('/\)\s+\{/', '){', $content);
|
||||
$content = preg_replace('/}\n(else|catch|finally)\b/', '}$1', $content);
|
||||
|
||||
/*
|
||||
* Get rid of double semicolons, except where they can be used like:
|
||||
* "for(v=1,_=b;;)", "for(v=1;;v++)" or "for(;;ja||(ja=true))".
|
||||
@ -404,12 +402,19 @@ class JS extends Minify
|
||||
* semicolon), like: `for(i=1;i<3;i++);`, of `for(i in list);`
|
||||
* Here, nothing happens during the loop; it's just used to keep
|
||||
* increasing `i`. With that ; omitted, the next line would be expected
|
||||
* to be the for-loop's body...
|
||||
* to be the for-loop's body... Same goes for while loops.
|
||||
* I'm going to double that semicolon (if any) so after the next line,
|
||||
* which strips semicolons here & there, we're still left with this one.
|
||||
*/
|
||||
$content = preg_replace('/(for\([^;\{]*;[^;\{]*;[^;\{]*\));(\}|$)/s', '\\1;;\\2', $content);
|
||||
$content = preg_replace('/(for\([^;\{]+\s+in\s+[^;\{]+\));(\}|$)/s', '\\1;;\\2', $content);
|
||||
/*
|
||||
* Below will also keep `;` after a `do{}while();` along with `while();`
|
||||
* While these could be stripped after do-while, detecting this
|
||||
* distinction is cumbersome, so I'll play it safe and make sure `;`
|
||||
* after any kind of `while` is kept.
|
||||
*/
|
||||
$content = preg_replace('/(while\([^;\{]+\));(\}|$)/s', '\\1;;\\2', $content);
|
||||
|
||||
/*
|
||||
* We also can't strip empty else-statements. Even though they're
|
||||
|
@ -1,5 +1,13 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Abstract minifier class
|
||||
*
|
||||
* Please report bugs on https://github.com/matthiasmullie/minify/issues
|
||||
*
|
||||
* @author Matthias Mullie <minify@mullie.eu>
|
||||
* @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
|
||||
* @license MIT License
|
||||
*/
|
||||
namespace MatthiasMullie\Minify;
|
||||
|
||||
use MatthiasMullie\Minify\Exceptions\IOException;
|
||||
@ -10,6 +18,7 @@ use Psr\Cache\CacheItemInterface;
|
||||
*
|
||||
* Please report bugs on https://github.com/matthiasmullie/minify/issues
|
||||
*
|
||||
* @package Minify
|
||||
* @author Matthias Mullie <minify@mullie.eu>
|
||||
* @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
|
||||
* @license MIT License
|
||||
@ -230,6 +239,12 @@ abstract class Minify
|
||||
foreach ($this->patterns as $i => $pattern) {
|
||||
list($pattern, $replacement) = $pattern;
|
||||
|
||||
// we can safely ignore patterns for positions we've unset earlier,
|
||||
// because we know these won't show up anymore
|
||||
if (array_key_exists($i, $positions) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// no need to re-run matches that are still in the part of the
|
||||
// content that hasn't been processed
|
||||
if ($positions[$i] >= 0) {
|
||||
@ -237,19 +252,18 @@ abstract class Minify
|
||||
}
|
||||
|
||||
$match = null;
|
||||
if (preg_match($pattern, $content, $match)) {
|
||||
if (preg_match($pattern, $content, $match, PREG_OFFSET_CAPTURE)) {
|
||||
$matches[$i] = $match;
|
||||
|
||||
// we'll store the match position as well; that way, we
|
||||
// don't have to redo all preg_matches after changing only
|
||||
// the first (we'll still know where those others are)
|
||||
$positions[$i] = strpos($content, $match[0]);
|
||||
$positions[$i] = $match[0][1];
|
||||
} else {
|
||||
// if the pattern couldn't be matched, there's no point in
|
||||
// executing it again in later runs on this same content;
|
||||
// ignore this one until we reach end of content
|
||||
unset($matches[$i]);
|
||||
$positions[$i] = strlen($content);
|
||||
unset($matches[$i], $positions[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -264,7 +278,7 @@ abstract class Minify
|
||||
// other found was not inside what the first found)
|
||||
$discardLength = min($positions);
|
||||
$firstPattern = array_search($discardLength, $positions);
|
||||
$match = $matches[$firstPattern][0];
|
||||
$match = $matches[$firstPattern][0][0];
|
||||
|
||||
// execute the pattern that matches earliest in the content string
|
||||
list($pattern, $replacement) = $this->patterns[$firstPattern];
|
||||
@ -272,7 +286,7 @@ abstract class Minify
|
||||
|
||||
// figure out which part of the string was unmatched; that's the
|
||||
// part we'll execute the patterns on again next
|
||||
$content = substr($content, $discardLength);
|
||||
$content = (string) substr($content, $discardLength);
|
||||
$unmatched = (string) substr($content, strpos($content, $match) + strlen($match));
|
||||
|
||||
// move the replaced part to $processed and prepare $content to
|
||||
@ -396,6 +410,16 @@ abstract class Minify
|
||||
*/
|
||||
protected function canImportFile($path)
|
||||
{
|
||||
$parsed = parse_url($path);
|
||||
if (
|
||||
// file is elsewhere
|
||||
isset($parsed['host']) ||
|
||||
// file responds to queries (may change, or need to bypass cache)
|
||||
isset($parsed['query'])
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return strlen($path) < PHP_MAXPATHLEN && @is_file($path) && is_readable($path);
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@
|
||||
<location>minify/matthiasmullie-minify</location>
|
||||
<name>MatthiasMullie\Minify</name>
|
||||
<license>MIT</license>
|
||||
<version>1.3.51</version>
|
||||
<version>1.3.61</version>
|
||||
<licenseversion></licenseversion>
|
||||
</library>
|
||||
<library>
|
||||
|
Loading…
x
Reference in New Issue
Block a user