summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Andreev <narf@devilix.net>2013-10-28 13:16:18 +0100
committerAndrey Andreev <narf@devilix.net>2013-10-28 13:16:18 +0100
commit6a424902ba0dbd59de2dd6e69bbf9e73d10c083d (patch)
tree399598b6b9fbaa6384c01e3fa77d7d519c1b1dd1
parent8adac96fdc90cfc8c667d64b95ae29845808947b (diff)
An alternative to CI_Output::_minify_script_style() using more efficient regexp patterns
-rw-r--r--system/core/Output.php102
1 files changed, 97 insertions, 5 deletions
diff --git a/system/core/Output.php b/system/core/Output.php
index 719c43256..cae1347bc 100644
--- a/system/core/Output.php
+++ b/system/core/Output.php
@@ -740,13 +740,13 @@ class CI_Output {
preg_match_all('{<style.+</style>}msU', $output, $style_clean);
foreach ($style_clean[0] as $s)
{
- $output = str_replace($s, $this->_minify_script_style($s, TRUE), $output);
+ $output = str_replace($s, $this->_minify_js_css($s, 'css', TRUE), $output);
}
// Minify the javascript in <script> tags.
foreach ($javascript_clean[0] as $s)
{
- $javascript_mini[] = $this->_minify_script_style($s, TRUE);
+ $javascript_mini[] = $this->_minify_js_css($s, 'js', TRUE);
}
// Replace multiple spaces with a single space.
@@ -792,13 +792,14 @@ class CI_Output {
break;
case 'text/css':
+
+ return $this->_minify_js_css($output, 'css');
+
case 'text/javascript':
case 'application/javascript':
case 'application/x-javascript':
- $output = $this->_minify_script_style($output);
-
- break;
+ return $this->_minify_js_css($output, 'js');
default: break;
}
@@ -808,6 +809,97 @@ class CI_Output {
// --------------------------------------------------------------------
+ protected function _minify_js_css($output, $type, $tags = FALSE)
+ {
+ if ($tags === TRUE)
+ {
+ $tags = array('close' => strrchr($output, '<'));
+
+ $open_length = strpos($output, '>') + 1;
+ $tags['open'] = substr($output, 0, $open_length);
+
+ $output = substr($output, $open_length, -strlen($tags['close']));
+
+ // Strip spaces from the tags
+ $tags = preg_replace('#\s{2,}#', ' ', $tags);
+ }
+
+ $output = trim($output);
+
+ if ($type === 'js')
+ {
+ // Catch all string literals and comment blocks
+ if (preg_match_all('#((?:((?<!\\\)\'|")|/\*).*(?(2)(?<!\\\)\2|\*/))#msuUS', $output, $match, PREG_OFFSET_CAPTURE))
+ {
+ $js_literals = $js_code = array();
+ for ($match = $match[0], $c = count($match), $i = $pos = $offset = 0; $i < $c; $i++)
+ {
+ $js_code[$pos++] = substr($output, $offset, $match[$i][1] - $offset);
+ $offset = $match[$i][1] + strlen($match[$i][0]);
+
+ // Save only if we haven't matched a comment block
+ if ($match[$i][0][0] !== '/')
+ {
+ $js_literals[$pos++] = array_shift($match[$i]);
+ }
+ }
+ $js_code[$pos] = substr($output, $offset);
+
+ // $match might be quite large, so free it up together with other vars that we no longer need
+ unset($match, $offset, $pos);
+ }
+ else
+ {
+ $js_code = array($output);
+ $js_literals = array();
+ }
+
+ $varname = 'js_code';
+ }
+ else
+ {
+ $varname = 'output';
+ }
+
+ // Standartize new lines
+ $$varname = str_replace(array("\r\n", "\r"), "\n", $$varname);
+
+ if ($type === 'js')
+ {
+ $patterns = array(
+ '#\n?//[^\n]*#' => '', // Remove // line comments
+ '#\s*([!#%&()*+,\-./:;<=>?@\[\]^`{|}~])\s*#' => '$1', // Remove spaces following and preceeding JS-wise non-special & non-word characters
+ '#\s{2,}#' => ' ' // Reduce the remaining multiple whitespace characters to a single space
+ );
+ }
+ else
+ {
+ $patterns = array(
+ '#/\*.*(?=\*/)\*/#s' => '', // Remove /* block comments */
+ '#\n?//[^\n]*#' => '', // Remove // line comments
+ '#\s*([^\w.#%)\s*#U' => '$1', // Remove spaces following and preceeding non-word characters, excluding dots, hashes and the percent sign
+ '#\s{2,}#' => ' ' // Reduce the remaining multiple space characters to a single space
+ );
+ }
+
+ $$varname = preg_replace(array_keys($patterns), array_values($patterns), $$varname);
+
+ // Glue back JS quoted strings
+ if ($type === 'js')
+ {
+ $js_code += $js_literals;
+ ksort($js_code);
+ $output = implode($js_code);
+ unset($js_code, $js_literals, $varname, $patterns);
+ }
+
+ return is_array($tags)
+ ? $tags['open'].$output.$tags['close']
+ : $output;
+ }
+
+ // --------------------------------------------------------------------
+
/**
* Minify Style and Script
*