From 369b314c57bb7fd7d32949fe5f47c307468913eb Mon Sep 17 00:00:00 2001 From: Andrew Podner Date: Mon, 17 Dec 2012 22:32:02 -0500 Subject: Issue #2078: refinement of the minify function for CSS and scripts. --- system/core/Output.php | 215 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 142 insertions(+), 73 deletions(-) diff --git a/system/core/Output.php b/system/core/Output.php index 0ba0a5743..1fafa848b 100644 --- a/system/core/Output.php +++ b/system/core/Output.php @@ -705,103 +705,172 @@ class CI_Output { * @return string Minified output */ public function minify($output, $type = 'text/html') - { - switch ($type) - { - case 'text/html': + { + switch ($type) + { + case 'text/html': - $size_before = strlen($output); + $size_before = strlen($output); - if ($size_before === 0) - { - return ''; - } + if ($size_before === 0) + { + return ''; + } - // Find all the
,,}msU', $output, $textareas_clean);
-				preg_match_all('{}msU', $output, $javascript_clean);
+                // Find all the 
,,}msU', $output, $textareas_clean);
+                preg_match_all('{}msU', $output, $javascript_clean);
 
-				// Minify the CSS in all the }msU', $output, $style_clean);
-				foreach ($style_clean[0] as $s)
-				{
-					$output = str_replace($s, $this->minify($s, 'text/css'), $output);
-				}
+                // Minify the CSS in all the }msU', $output, $style_clean);
+                foreach ($style_clean[0] as $s)
+                {
+                    $output = str_replace($s, $this->_minify_script_style($s, $type), $output);
+                }
 
-				// Minify the javascript in }msU', $output, $javascript_messed);
-					$output = str_replace($javascript_messed[0], $javascript_mini, $output);
-				}
+                if (isset($javascript_mini))
+                {
+                    preg_match_all('{}msU', $output, $javascript_messed);
+                    $output = str_replace($javascript_messed[0], $javascript_mini, $output);
+                }
 
-				$size_removed = $size_before - strlen($output);
-				$savings_percent = round(($size_removed / $size_before * 100));
+                $size_removed = $size_before - strlen($output);
+                $savings_percent = round(($size_removed / $size_before * 100));
 
-				log_message('debug', 'Minifier shaved '.($size_removed / 1000).'KB ('.$savings_percent.'%) off final HTML output.');
+                log_message('debug', 'Minifier shaved '.($size_removed / 1000).'KB ('.$savings_percent.'%) off final HTML output.');
 
-			break;
+            break;
 
-			case 'text/css':
-			case 'text/javascript':
+            case 'text/css':
+            case 'text/javascript':
 
-				//Remove CSS comments
-				$output = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $output);
+                $output = $this->_minify_scripts_css($output, $type);
 
-				// Remove spaces around curly brackets, colons,
-				// semi-colons, parenthesis, commas
-				$output = preg_replace('!\s*(:|;|,|}|{|\(|\))\s*!', '$1', $output);
+            break;
 
-				// Remove spaces
-			        $output =  preg_replace('/  /s', ' ', $output);
+            default: break;
+        }
 
-			        // Remove breaklines and tabs
-			        $output =  preg_replace('/[\r\n\t]/', '', $output);
+        return $output;
+    }
 
-			break;
 
-			default: break;
-		}
+    // --------------------------------------------------------------------
 
-		return $output;
-	}
+	/**
+	 * Minify Style and Script
+	 *
+	 * Reduce excessive size of CSS/JavaScript content.  To remove spaces this
+     * script walks the string as an array and determines if the pointer is inside
+     * a string created by single quotes or double quotes.  spaces inside those
+     * strings are not stripped.  Opening and closing tags are severed from
+     * the string initially and saved without stripping whitespace to preserve
+     * the tags and any associated properties if tags are present
+	 *
+	 * @param	string	$output	Output to minify
+     * @param   string  $type Output content MIME type
+	 * @return	string	Minified output
+	 */
+    protected function _minify_script_style($output, $type = 'text/html')
+    {
+        // We only need this if there are tags in the file
+        if ($type == 'text/html')
+        {
+            // Remove opening tag and save for later
+            $pos = strpos($output, '>');
+            $open_tag = substr($output, 0, $pos);
+            $output = substr_replace($output, '', 0, $pos);
+
+            // Remove closing tag and save it for later
+            $end_pos = strlen($output);
+            $pos = strpos($output, ' $value)
+        {
+            if ($in_string === FALSE and $in_dstring === FALSE)
+            {
+                if ($value == ' ')
+                {
+                    unset($array_output[$key]);
+                }
+            }
+
+            if ($value == "'")
+            {
+                $in_string = !$in_string;
+            }
+
+            if ($value == '"')
+            {
+                $in_dstring = !$in_dstring;
+            }
+        }
+
+        $output =  implode($array_output);
+
+        // Remove breaklines and tabs
+        $output =  preg_replace('/[\r\n\t]/', '', $output);
+
+        // Put the opening and closing tags back if applicable
+        if (isset($open_tag))
+        {
+            $output = $open_tag . $output . $closing_tag;
+        }
+
+        return $output;
+    }
 
 }
 
-- 
cgit v1.2.3-24-g4f1b