HTML_Compressor - Version 0.1.4

Version Notes

Bug fix

Download this release

Release Info

Developer Razorphyn
Extension HTML_Compressor
Version 0.1.4
Comparing to
See all releases


Code changes from version 0.1.3 to 0.1.4

app/code/local/Razorphyn/HTMLCompressor/Model/Observer.php CHANGED
@@ -12,8 +12,8 @@
12
  public function alterOutput($observer)
13
  {
14
  $lib_path = Mage::getBaseDir('lib').'/Razorphyn/HTMLCompressor/html_compressor.php';
15
-
16
- include_once($lib_path);
17
 
18
  //Retrieve html body
19
  $response = $observer->getResponse();
@@ -21,6 +21,7 @@
21
 
22
  //Compress HTML
23
  $html=html_compress($html);
 
24
 
25
  //Send Response
26
  $response->setBody($html);
12
  public function alterOutput($observer)
13
  {
14
  $lib_path = Mage::getBaseDir('lib').'/Razorphyn/HTMLCompressor/html_compressor.php';
15
+ //$lib_path = Mage::getBaseDir('lib').'/Razorphyn/HTMLCompressor/HTML.php';
16
+ require_once($lib_path);
17
 
18
  //Retrieve html body
19
  $response = $observer->getResponse();
21
 
22
  //Compress HTML
23
  $html=html_compress($html);
24
+ //$html=Minify_HTML::minify($html);
25
 
26
  //Send Response
27
  $response->setBody($html);
lib/Razorphyn/HTMLCompressor/HTML.php ADDED
@@ -0,0 +1,255 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class Minify_HTML
4
+ * @package Minify
5
+ */
6
+
7
+ /**
8
+ * Compress HTML
9
+ *
10
+ * This is a heavy regex-based removal of whitespace, unnecessary comments and
11
+ * tokens. IE conditional comments are preserved. There are also options to have
12
+ * STYLE and SCRIPT blocks compressed by callback functions.
13
+ *
14
+ * A test suite is available.
15
+ *
16
+ * @package Minify
17
+ * @author Stephen Clay <steve@mrclay.org>
18
+ */
19
+ class Minify_HTML {
20
+ /**
21
+ * @var boolean
22
+ */
23
+ protected $_jsCleanComments = true;
24
+
25
+ /**
26
+ * "Minify" an HTML page
27
+ *
28
+ * @param string $html
29
+ *
30
+ * @param array $options
31
+ *
32
+ * 'cssMinifier' : (optional) callback function to process content of STYLE
33
+ * elements.
34
+ *
35
+ * 'jsMinifier' : (optional) callback function to process content of SCRIPT
36
+ * elements. Note: the type attribute is ignored.
37
+ *
38
+ * 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If
39
+ * unset, minify will sniff for an XHTML doctype.
40
+ *
41
+ * @return string
42
+ */
43
+ public static function minify($html, $options = array()) {
44
+ $min = new self($html, $options);
45
+ return $min->process();
46
+ }
47
+
48
+
49
+ /**
50
+ * Create a minifier object
51
+ *
52
+ * @param string $html
53
+ *
54
+ * @param array $options
55
+ *
56
+ * 'cssMinifier' : (optional) callback function to process content of STYLE
57
+ * elements.
58
+ *
59
+ * 'jsMinifier' : (optional) callback function to process content of SCRIPT
60
+ * elements. Note: the type attribute is ignored.
61
+ *
62
+ * 'jsCleanComments' : (optional) whether to remove HTML comments beginning and end of script block
63
+ *
64
+ * 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If
65
+ * unset, minify will sniff for an XHTML doctype.
66
+ */
67
+ public function __construct($html, $options = array())
68
+ {
69
+ $this->_html = str_replace("\r\n", "\n", trim($html));
70
+ if (isset($options['xhtml'])) {
71
+ $this->_isXhtml = (bool)$options['xhtml'];
72
+ }
73
+ if (isset($options['cssMinifier'])) {
74
+ $this->_cssMinifier = $options['cssMinifier'];
75
+ }
76
+ if (isset($options['jsMinifier'])) {
77
+ $this->_jsMinifier = $options['jsMinifier'];
78
+ }
79
+ if (isset($options['jsCleanComments'])) {
80
+ $this->_jsCleanComments = (bool)$options['jsCleanComments'];
81
+ }
82
+ }
83
+
84
+
85
+ /**
86
+ * Minify the markeup given in the constructor
87
+ *
88
+ * @return string
89
+ */
90
+ public function process()
91
+ {
92
+ if ($this->_isXhtml === null) {
93
+ $this->_isXhtml = (false !== strpos($this->_html, '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML'));
94
+ }
95
+
96
+ $this->_replacementHash = 'MINIFYHTML' . md5($_SERVER['REQUEST_TIME']);
97
+ $this->_placeholders = array();
98
+
99
+ // replace SCRIPTs (and minify) with placeholders
100
+ $this->_html = preg_replace_callback(
101
+ '/(\\s*)<script(\\b[^>]*?>)([\\s\\S]*?)<\\/script>(\\s*)/i'
102
+ ,array($this, '_removeScriptCB')
103
+ ,$this->_html);
104
+
105
+ // replace STYLEs (and minify) with placeholders
106
+ $this->_html = preg_replace_callback(
107
+ '/\\s*<style(\\b[^>]*>)([\\s\\S]*?)<\\/style>\\s*/i'
108
+ ,array($this, '_removeStyleCB')
109
+ ,$this->_html);
110
+
111
+ // remove HTML comments (not containing IE conditional comments).
112
+ $this->_html = preg_replace_callback(
113
+ '/<!--([\\s\\S]*?)-->/'
114
+ ,array($this, '_commentCB')
115
+ ,$this->_html);
116
+
117
+ // replace PREs with placeholders
118
+ $this->_html = preg_replace_callback('/\\s*<pre(\\b[^>]*?>[\\s\\S]*?<\\/pre>)\\s*/i'
119
+ ,array($this, '_removePreCB')
120
+ ,$this->_html);
121
+
122
+ // replace TEXTAREAs with placeholders
123
+ $this->_html = preg_replace_callback(
124
+ '/\\s*<textarea(\\b[^>]*?>[\\s\\S]*?<\\/textarea>)\\s*/i'
125
+ ,array($this, '_removeTextareaCB')
126
+ ,$this->_html);
127
+
128
+ // trim each line.
129
+ // @todo take into account attribute values that span multiple lines.
130
+ $this->_html = preg_replace('/^\\s+|\\s+$/m', '', $this->_html);
131
+
132
+ // remove ws around block/undisplayed elements
133
+ $this->_html = preg_replace('/\\s+(<\\/?(?:area|base(?:font)?|blockquote|body'
134
+ .'|caption|center|col(?:group)?|dd|dir|div|dl|dt|fieldset|form'
135
+ .'|frame(?:set)?|h[1-6]|head|hr|html|legend|li|link|map|menu|meta'
136
+ .'|ol|opt(?:group|ion)|p|param|t(?:able|body|head|d|h||r|foot|itle)'
137
+ .'|ul)\\b[^>]*>)/i', '$1', $this->_html);
138
+
139
+ // remove ws outside of all elements
140
+ $this->_html = preg_replace(
141
+ '/>(\\s(?:\\s*))?([^<]+)(\\s(?:\s*))?</'
142
+ ,'>$1$2$3<'
143
+ ,$this->_html);
144
+
145
+ // use newlines before 1st attribute in open tags (to limit line lengths)
146
+ $this->_html = preg_replace('/(<[a-z\\-]+)\\s+([^>]+>)/i', "$1\n$2", $this->_html);
147
+
148
+ // fill placeholders
149
+ $this->_html = str_replace(
150
+ array_keys($this->_placeholders)
151
+ ,array_values($this->_placeholders)
152
+ ,$this->_html
153
+ );
154
+ // issue 229: multi-pass to catch scripts that didn't get replaced in textareas
155
+ $this->_html = str_replace(
156
+ array_keys($this->_placeholders)
157
+ ,array_values($this->_placeholders)
158
+ ,$this->_html
159
+ );
160
+ return $this->_html;
161
+ }
162
+
163
+ protected function _commentCB($m)
164
+ {
165
+ return (0 === strpos($m[1], '[') || false !== strpos($m[1], '<!['))
166
+ ? $m[0]
167
+ : '';
168
+ }
169
+
170
+ protected function _reservePlace($content)
171
+ {
172
+ $placeholder = '%' . $this->_replacementHash . count($this->_placeholders) . '%';
173
+ $this->_placeholders[$placeholder] = $content;
174
+ return $placeholder;
175
+ }
176
+
177
+ protected $_isXhtml = null;
178
+ protected $_replacementHash = null;
179
+ protected $_placeholders = array();
180
+ protected $_cssMinifier = null;
181
+ protected $_jsMinifier = null;
182
+
183
+ protected function _removePreCB($m)
184
+ {
185
+ return $this->_reservePlace("<pre{$m[1]}");
186
+ }
187
+
188
+ protected function _removeTextareaCB($m)
189
+ {
190
+ return $this->_reservePlace("<textarea{$m[1]}");
191
+ }
192
+
193
+ protected function _removeStyleCB($m)
194
+ {
195
+ $openStyle = "<style{$m[1]}";
196
+ $css = $m[2];
197
+ // remove HTML comments
198
+ $css = preg_replace('/(?:^\\s*<!--|-->\\s*$)/', '', $css);
199
+
200
+ // remove CDATA section markers
201
+ $css = $this->_removeCdata($css);
202
+
203
+ // minify
204
+ $minifier = $this->_cssMinifier
205
+ ? $this->_cssMinifier
206
+ : 'trim';
207
+ $css = call_user_func($minifier, $css);
208
+
209
+ return $this->_reservePlace($this->_needsCdata($css)
210
+ ? "{$openStyle}/*<![CDATA[*/{$css}/*]]>*/</style>"
211
+ : "{$openStyle}{$css}</style>"
212
+ );
213
+ }
214
+
215
+ protected function _removeScriptCB($m)
216
+ {
217
+ $openScript = "<script{$m[2]}";
218
+ $js = $m[3];
219
+
220
+ // whitespace surrounding? preserve at least one space
221
+ $ws1 = ($m[1] === '') ? '' : ' ';
222
+ $ws2 = ($m[4] === '') ? '' : ' ';
223
+
224
+ // remove HTML comments (and ending "//" if present)
225
+ if ($this->_jsCleanComments) {
226
+ $js = preg_replace('/(?:^\\s*<!--\\s*|\\s*(?:\\/\\/)?\\s*-->\\s*$)/', '', $js);
227
+ }
228
+
229
+ // remove CDATA section markers
230
+ $js = $this->_removeCdata($js);
231
+
232
+ // minify
233
+ $minifier = $this->_jsMinifier
234
+ ? $this->_jsMinifier
235
+ : 'trim';
236
+ $js = call_user_func($minifier, $js);
237
+
238
+ return $this->_reservePlace($this->_needsCdata($js)
239
+ ? "{$ws1}{$openScript}/*<![CDATA[*/{$js}/*]]>*/</script>{$ws2}"
240
+ : "{$ws1}{$openScript}{$js}</script>{$ws2}"
241
+ );
242
+ }
243
+
244
+ protected function _removeCdata($str)
245
+ {
246
+ return (false !== strpos($str, '<![CDATA['))
247
+ ? str_replace(array('<![CDATA[', ']]>'), '', $str)
248
+ : $str;
249
+ }
250
+
251
+ protected function _needsCdata($str)
252
+ {
253
+ return ($this->_isXhtml && preg_match('/(?:[<&]|\\-\\-|\\]\\]>)/', $str));
254
+ }
255
+ }
lib/Razorphyn/HTMLCompressor/html_compressor.php CHANGED
@@ -14,9 +14,9 @@
14
  global $idarray;
15
  $idarray=array();
16
 
17
- $search=array(
18
- '@<(\s)*pre[^>]*>(?:[^<]+|)</pre>@', //Find PRE Tag
19
- '@<(\s)*textarea(\b[^>]*?>[\\s\\S]*?</textarea>)\s*@', //Find TEXTAREA
20
  );
21
  $string=preg_replace_callback($search,
22
  function($m){
@@ -28,7 +28,6 @@
28
  $string
29
  );
30
 
31
-
32
  $search = array(
33
  '@( |\t|\f)+@', // Shorten multiple whitespace sequences
34
  '@^\s+|\s+$@', // Trim lines
@@ -37,13 +36,15 @@
37
  $replace = array(' ','',' ');
38
 
39
  $string = preg_replace($search, $replace, $string);
40
-
41
  $search=array(
42
  '@<!--\[if\s(?:[^<]+|<(?!!\[endif\]-->))*<!\[endif\]-->@', //Find IE Comments
43
- '@^(<)\s*?(script\b[^>]*?)(>)([\s\S]*?)(<)\s*(/\s*?script\s*)(>)$@', //Find SCRIPT Tag
44
- '@//<!\[CDATA\[(?:[^<]+|)//]]>@', //Find CDATA
45
- '@^(<)\s*?(style\b[^>]*?)(>)([\s\S]*?)(<)\s*(/\s*?style\s*)(>)$@' //Find STYLE Tag
 
46
  );
 
47
  $string=preg_replace_callback($search,
48
  function($m){
49
  $id='<!['.uniqid().']!>';
@@ -73,7 +74,7 @@
73
  for($i=0;$i<$c;$i++){
74
  $string = str_replace($idarray[$i][0], "\n".$idarray[$i][1]."\n", $string);
75
  }
76
-
77
  return $string;
78
  }
79
  ?>
14
  global $idarray;
15
  $idarray=array();
16
 
17
+ $search=array(
18
+ '@(<)\s*?(pre\b[^>]*?)(>)([\s\S]*?)(<)\s*(/\s*?pre\s*?)(>)@', //Find PRE Tag
19
+ '@(<)\s*?(textarea\b[^>]*?)(>)([\s\S]*?)(<)\s*?(/\s*?textarea\s*?)(>)@' //Find TEXTAREA
20
  );
21
  $string=preg_replace_callback($search,
22
  function($m){
28
  $string
29
  );
30
 
 
31
  $search = array(
32
  '@( |\t|\f)+@', // Shorten multiple whitespace sequences
33
  '@^\s+|\s+$@', // Trim lines
36
  $replace = array(' ','',' ');
37
 
38
  $string = preg_replace($search, $replace, $string);
39
+
40
  $search=array(
41
  '@<!--\[if\s(?:[^<]+|<(?!!\[endif\]-->))*<!\[endif\]-->@', //Find IE Comments
42
+ '@(<)\s*?(script\b[^>]*?)(>)([\s\S]*?)(<)\s*?(/\s*?script\s*?)(>)@', //Find SCRIPT Tag
43
+ '@(<)\s*?(style\b[^>]*?)(>)([\s\S]*?)(<)\s*?(/\s*?style\s*?)(>)@', //Find STYLE Tag
44
+ '@(//<!\[CDATA\[([\s\S]*?)//]]>)@', //Find commented CDATA
45
+ '@(<!\[CDATA\[([\s\S]*?)]]>)@' //Find CDATA
46
  );
47
+
48
  $string=preg_replace_callback($search,
49
  function($m){
50
  $id='<!['.uniqid().']!>';
74
  for($i=0;$i<$c;$i++){
75
  $string = str_replace($idarray[$i][0], "\n".$idarray[$i][1]."\n", $string);
76
  }
77
+
78
  return $string;
79
  }
80
  ?>
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>HTML_Compressor</name>
4
- <version>0.1.3</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.wtfpl.net/">WTFPL</license>
7
  <channel>community</channel>
@@ -24,11 +24,11 @@ Pre&#xD;
24
  CDATA&#xD;
25
  IE conditionals comments&#xD;
26
  </description>
27
- <notes>Enabled only for frontend</notes>
28
  <authors><author><name>Razorphyn</name><user>Razorphyn</user><email>est.grandi@gmail.com</email></author></authors>
29
- <date>2014-12-18</date>
30
- <time>19:16:07</time>
31
- <contents><target name="mageetc"><dir><dir name="modules"><file name="Razorphyn_HTMLCompressor.xml" hash="85359f1f2fa391942e0618e4edbbcbf4"/></dir></dir></target><target name="magelocal"><dir name="Razorphyn"><dir name="HTMLCompressor"><dir name="Model"><file name="Observer.php" hash="c8a7658d22159fcbeee8c75443cce021"/></dir><dir name="etc"><file name="config.xml" hash="dfeef644720af3338fcba106a0a5529b"/></dir></dir></dir></target><target name="magelib"><dir><dir name="Razorphyn"><dir name="HTMLCompressor"><file name="html_compressor.php" hash="ff87eacce1a396dc4e1fb6360add9d04"/></dir></dir></dir></target></contents>
32
  <compatible/>
33
  <dependencies><required><php><min>5.3.0</min><max>6.0.0</max></php></required></dependencies>
34
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>HTML_Compressor</name>
4
+ <version>0.1.4</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.wtfpl.net/">WTFPL</license>
7
  <channel>community</channel>
24
  CDATA&#xD;
25
  IE conditionals comments&#xD;
26
  </description>
27
+ <notes>Bug fix</notes>
28
  <authors><author><name>Razorphyn</name><user>Razorphyn</user><email>est.grandi@gmail.com</email></author></authors>
29
+ <date>2014-12-21</date>
30
+ <time>19:48:09</time>
31
+ <contents><target name="mageetc"><dir><dir name="modules"><file name="Razorphyn_HTMLCompressor.xml" hash="85359f1f2fa391942e0618e4edbbcbf4"/></dir></dir></target><target name="magelocal"><dir name="Razorphyn"><dir name="HTMLCompressor"><dir name="Model"><file name="Observer.php" hash="6700e05d80628ce18fe48ac68eb191e1"/></dir><dir name="etc"><file name="config.xml" hash="dfeef644720af3338fcba106a0a5529b"/></dir></dir></dir></target><target name="magelib"><dir><dir name="Razorphyn"><dir name="HTMLCompressor"><file name="HTML.php" hash="48560b34ff1996fab02daf46569bd3de"/><file name="html_compressor.php" hash="1337fc541424fda8f28a52d0b6ca3a83"/></dir></dir></dir></target></contents>
32
  <compatible/>
33
  <dependencies><required><php><min>5.3.0</min><max>6.0.0</max></php></required></dependencies>
34
  </package>