Fooman_Speedster - Version 1.0.2

Version Notes

reupload of 1.0.1

Download this release

Release Info

Developer Magento Core Team
Extension Fooman_Speedster
Version 1.0.2
Comparing to
See all releases


Code changes from version 1.0.1 to 1.0.2

app/code/community/Fooman/Speedster/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <Fooman_Speedster>
5
- <version>1.0.1</version>
6
  <depends>
7
  <Mage_Page />
8
  <Mage_Adminhtml />
2
  <config>
3
  <modules>
4
  <Fooman_Speedster>
5
+ <version>1.0.2</version>
6
  <depends>
7
  <Mage_Page />
8
  <Mage_Adminhtml />
lib/minify/HISTORY.txt CHANGED
@@ -1,5 +1,17 @@
1
  Minify Release History
2
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  Version 2.1.1
4
  * Bug fix release
5
  * Detection and workarounds for zlib.output_compression and non-PHP encoding modules
1
  Minify Release History
2
 
3
+ Version 2.1.2
4
+ * Javascript fixes
5
+ * Debug mode no longer confused by "*/*" in strings/RegExps (jQuery)
6
+ * quote characters inside RegExp literals no longer cause exception
7
+ * files ending in single-line comments no longer cause code loss
8
+ * CSS: data: URLs no longer mangled
9
+ * Optional error logging to Firefox's FirePHP extension
10
+ * Unit tests to check for common DOCUMENT_ROOT problems
11
+ * DOCUMENT_ROOT no longer overwritten on IIS servers
12
+ * Builder app doesn't fail on systems without gzdeflate()
13
+ * APC caching class included
14
+
15
  Version 2.1.1
16
  * Bug fix release
17
  * Detection and workarounds for zlib.output_compression and non-PHP encoding modules
lib/minify/README.txt CHANGED
@@ -7,6 +7,12 @@ GETs (serving content only when clients do not have a valid cache)
7
  and tell clients to cache the file for a period of time.
8
  More info: http://code.google.com/p/minify/
9
 
 
 
 
 
 
 
10
  INSTALLATION AND USAGE:
11
 
12
  1. Place the /min/ directory as a child of your DOCUMENT_ROOT
7
  and tell clients to cache the file for a period of time.
8
  More info: http://code.google.com/p/minify/
9
 
10
+
11
+ UPGRADING
12
+
13
+ See UPGRADING.txt for instructions.
14
+
15
+
16
  INSTALLATION AND USAGE:
17
 
18
  1. Place the /min/ directory as a child of your DOCUMENT_ROOT
lib/minify/lib/HTTP/ConditionalGet.php CHANGED
@@ -13,6 +13,7 @@
13
  * list($updateTime, $content) = getDbUpdateAndContent();
14
  * $cg = new HTTP_ConditionalGet(array(
15
  * 'lastModifiedTime' => $updateTime
 
16
  * ));
17
  * $cg->sendHeaders();
18
  * if ($cg->cacheIsValid) {
@@ -20,6 +21,12 @@
20
  * }
21
  * echo $content;
22
  * </code>
 
 
 
 
 
 
23
  *
24
  * E.g. Content from DB with no update time:
25
  * <code>
@@ -69,8 +76,8 @@ class HTTP_ConditionalGet {
69
  * @param array $spec options
70
  *
71
  * 'isPublic': (bool) if true, the Cache-Control header will contain
72
- * "public", allowing proxy caches to cache the content. Otherwise
73
- * "private" will be sent, allowing only browsers to cache. (default false)
74
  *
75
  * 'lastModifiedTime': (int) if given, both ETag AND Last-Modified headers
76
  * will be sent with content. This is recommended.
@@ -95,7 +102,8 @@ class HTTP_ConditionalGet {
95
  *
96
  * @return null
97
  */
98
- public function __construct($spec) {
 
99
  $scope = (isset($spec['isPublic']) && $spec['isPublic'])
100
  ? 'public'
101
  : 'private';
@@ -147,7 +155,8 @@ class HTTP_ConditionalGet {
147
  *
148
  * @return array
149
  */
150
- public function getHeaders() {
 
151
  return $this->_headers;
152
  }
153
 
@@ -162,7 +171,8 @@ class HTTP_ConditionalGet {
162
  *
163
  * @return int copy of input $bytes
164
  */
165
- public function setContentLength($bytes) {
 
166
  return $this->_headers['Content-Length'] = $bytes;
167
  }
168
 
@@ -177,7 +187,8 @@ class HTTP_ConditionalGet {
177
  *
178
  * @return null
179
  */
180
- public function sendHeaders() {
 
181
  $headers = $this->_headers;
182
  if (array_key_exists('_responseCode', $headers)) {
183
  header($headers['_responseCode']);
@@ -188,6 +199,36 @@ class HTTP_ConditionalGet {
188
  }
189
  }
190
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  /**
192
  * Get a GMT formatted date for use in HTTP headers
193
  *
@@ -199,7 +240,8 @@ class HTTP_ConditionalGet {
199
  *
200
  * @return string
201
  */
202
- public static function gmtDate($time) {
 
203
  return gmdate('D, d M Y H:i:s \G\M\T', $time);
204
  }
205
 
@@ -207,14 +249,16 @@ class HTTP_ConditionalGet {
207
  protected $_lmTime = null;
208
  protected $_etag = null;
209
 
210
- protected function _setEtag($hash, $scope) {
 
211
  $this->_etag = '"' . $hash
212
  . substr($scope, 0, 3)
213
  . '"';
214
  $this->_headers['ETag'] = $this->_etag;
215
  }
216
 
217
- protected function _setLastModified($time) {
 
218
  $this->_lmTime = (int)$time;
219
  $this->_headers['Last-Modified'] = self::gmtDate($time);
220
  }
@@ -237,7 +281,8 @@ class HTTP_ConditionalGet {
237
  return $isValid;
238
  }
239
 
240
- protected function resourceMatchedEtag() {
 
241
  if (!isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
242
  return false;
243
  }
@@ -253,7 +298,8 @@ class HTTP_ConditionalGet {
253
  return false;
254
  }
255
 
256
- protected function resourceNotModified() {
 
257
  if (!isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
258
  return false;
259
  }
13
  * list($updateTime, $content) = getDbUpdateAndContent();
14
  * $cg = new HTTP_ConditionalGet(array(
15
  * 'lastModifiedTime' => $updateTime
16
+ * ,'isPublic' => true
17
  * ));
18
  * $cg->sendHeaders();
19
  * if ($cg->cacheIsValid) {
21
  * }
22
  * echo $content;
23
  * </code>
24
+ *
25
+ * E.g. Shortcut for the above
26
+ * <code>
27
+ * HTTP_ConditionalGet::check($updateTime, true); // exits if client has cache
28
+ * echo $content;
29
+ * </code>
30
  *
31
  * E.g. Content from DB with no update time:
32
  * <code>
76
  * @param array $spec options
77
  *
78
  * 'isPublic': (bool) if true, the Cache-Control header will contain
79
+ * "public", allowing proxies to cache the content. Otherwise "private" will
80
+ * be sent, allowing only browser caching. (default false)
81
  *
82
  * 'lastModifiedTime': (int) if given, both ETag AND Last-Modified headers
83
  * will be sent with content. This is recommended.
102
  *
103
  * @return null
104
  */
105
+ public function __construct($spec)
106
+ {
107
  $scope = (isset($spec['isPublic']) && $spec['isPublic'])
108
  ? 'public'
109
  : 'private';
155
  *
156
  * @return array
157
  */
158
+ public function getHeaders()
159
+ {
160
  return $this->_headers;
161
  }
162
 
171
  *
172
  * @return int copy of input $bytes
173
  */
174
+ public function setContentLength($bytes)
175
+ {
176
  return $this->_headers['Content-Length'] = $bytes;
177
  }
178
 
187
  *
188
  * @return null
189
  */
190
+ public function sendHeaders()
191
+ {
192
  $headers = $this->_headers;
193
  if (array_key_exists('_responseCode', $headers)) {
194
  header($headers['_responseCode']);
199
  }
200
  }
201
 
202
+ /**
203
+ * Exit if the client's cache is valid for this resource
204
+ *
205
+ * This is a convenience method for common use of the class
206
+ *
207
+ * @param int $lastModifiedTime if given, both ETag AND Last-Modified headers
208
+ * will be sent with content. This is recommended.
209
+ *
210
+ * @param bool $isPublic (default false) if true, the Cache-Control header
211
+ * will contain "public", allowing proxies to cache the content. Otherwise
212
+ * "private" will be sent, allowing only browser caching.
213
+ *
214
+ * @param array $options (default empty) additional options for constructor
215
+ *
216
+ * @return null
217
+ */
218
+ public static function check($lastModifiedTime = null, $isPublic = false, $options = array())
219
+ {
220
+ if (null !== $lastModifiedTime) {
221
+ $options['lastModifiedTime'] = (int)$lastModifiedTime;
222
+ }
223
+ $options['isPublic'] = (bool)$isPublic;
224
+ $cg = new HTTP_ConditionalGet($options);
225
+ $cg->sendHeaders();
226
+ if ($cg->cacheIsValid) {
227
+ exit();
228
+ }
229
+ }
230
+
231
+
232
  /**
233
  * Get a GMT formatted date for use in HTTP headers
234
  *
240
  *
241
  * @return string
242
  */
243
+ public static function gmtDate($time)
244
+ {
245
  return gmdate('D, d M Y H:i:s \G\M\T', $time);
246
  }
247
 
249
  protected $_lmTime = null;
250
  protected $_etag = null;
251
 
252
+ protected function _setEtag($hash, $scope)
253
+ {
254
  $this->_etag = '"' . $hash
255
  . substr($scope, 0, 3)
256
  . '"';
257
  $this->_headers['ETag'] = $this->_etag;
258
  }
259
 
260
+ protected function _setLastModified($time)
261
+ {
262
  $this->_lmTime = (int)$time;
263
  $this->_headers['Last-Modified'] = self::gmtDate($time);
264
  }
281
  return $isValid;
282
  }
283
 
284
+ protected function resourceMatchedEtag()
285
+ {
286
  if (!isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
287
  return false;
288
  }
298
  return false;
299
  }
300
 
301
+ protected function resourceNotModified()
302
+ {
303
  if (!isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
304
  return false;
305
  }
lib/minify/lib/HTTP/Encoder.php CHANGED
@@ -19,6 +19,12 @@
19
  * </code>
20
  *
21
  * <code>
 
 
 
 
 
 
22
  * // Just sniff for the accepted encoding
23
  * $encoding = HTTP_Encoder::getAcceptedEncoding();
24
  * </code>
@@ -257,6 +263,29 @@ class HTTP_Encoder {
257
  $this->_headers['Vary'] = 'Accept-Encoding';
258
  $this->_content = $encoded;
259
  return true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  }
261
 
262
  protected $_content = '';
19
  * </code>
20
  *
21
  * <code>
22
+ * // Shortcut to encoding output
23
+ * header('Content-Type: text/css'); // needed if not HTML
24
+ * HTTP_Encoder::output($css);
25
+ * </code>
26
+ *
27
+ * <code>
28
  * // Just sniff for the accepted encoding
29
  * $encoding = HTTP_Encoder::getAcceptedEncoding();
30
  * </code>
263
  $this->_headers['Vary'] = 'Accept-Encoding';
264
  $this->_content = $encoded;
265
  return true;
266
+ }
267
+
268
+ /**
269
+ * Encode and send appropriate headers and content
270
+ *
271
+ * This is a convenience method for common use of the class
272
+ *
273
+ * @param string $content
274
+ *
275
+ * @param int $compressionLevel given to zlib functions. If not given, the
276
+ * class default will be used.
277
+ *
278
+ * @return bool success true if the content was actually compressed
279
+ */
280
+ public static function output($content, $compressionLevel = null)
281
+ {
282
+ if (null === $compressionLevel) {
283
+ $compressionLevel = self::$compressionLevel;
284
+ }
285
+ $he = new HTTP_Encoder(array('content' => $content));
286
+ $ret = $he->encode($compressionLevel);
287
+ $he->sendAll();
288
+ return $ret;
289
  }
290
 
291
  protected $_content = '';
lib/minify/lib/Minify.php CHANGED
@@ -48,6 +48,16 @@ class Minify {
48
  */
49
  public static $uploaderHoursBehind = 0;
50
 
 
 
 
 
 
 
 
 
 
 
51
  /**
52
  * Specify a cache object (with identical interface as Minify_Cache_File) or
53
  * a path to use with Minify_Cache_File.
@@ -103,6 +113,10 @@ class Minify {
103
  * 'rewriteCssUris' : If true, serve() will automatically set the 'currentDir'
104
  * minifier option to enable URI rewriting in CSS files (default true)
105
  *
 
 
 
 
106
  * 'debug' : set to true to minify all sources with the 'Lines' controller, which
107
  * eases the debugging of combined files. This also prevents 304 responses.
108
  * @see Minify_Lines::minify()
@@ -321,18 +335,22 @@ class Minify {
321
  *
322
  * @param array $sources array of filepaths and/or Minify_Source objects
323
  *
 
 
 
324
  * @return string
325
  */
326
- public static function combine($sources)
327
  {
328
  $cache = self::$_cache;
329
  self::$_cache = null;
330
- $out = self::serve('Files', array(
331
  'files' => (array)$sources
332
  ,'quiet' => true
333
  ,'encodeMethod' => ''
334
  ,'lastModifiedTime' => 0
335
- ));
 
336
  self::$_cache = $cache;
337
  return $out['content'];
338
  }
@@ -453,6 +471,10 @@ class Minify {
453
  $content = implode($implodeSeparator, $pieces);
454
  }
455
 
 
 
 
 
456
  // do any post-processing (esp. for editing build URIs)
457
  if (self::$_options['postprocessorRequire']) {
458
  require_once self::$_options['postprocessorRequire'];
@@ -476,6 +498,32 @@ class Minify {
476
  ,self::$_options['minifiers']
477
  ,self::$_options['minifierOptions']
478
  ,self::$_options['postprocessor']
 
479
  )));
480
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
481
  }
48
  */
49
  public static $uploaderHoursBehind = 0;
50
 
51
+ /**
52
+ * If this string is not empty AND the serve() option 'bubbleCssImports' is
53
+ * NOT set, then serve() will check CSS files for @import declarations that
54
+ * appear too late in the combined stylesheet. If found, serve() will prepend
55
+ * the output with this warning.
56
+ *
57
+ * @var string $importWarning
58
+ */
59
+ public static $importWarning = "/* See http://code.google.com/p/minify/wiki/CommonProblems#@imports_can_appear_in_invalid_locations_in_combined_CSS_files */\n";
60
+
61
  /**
62
  * Specify a cache object (with identical interface as Minify_Cache_File) or
63
  * a path to use with Minify_Cache_File.
113
  * 'rewriteCssUris' : If true, serve() will automatically set the 'currentDir'
114
  * minifier option to enable URI rewriting in CSS files (default true)
115
  *
116
+ * 'bubbleCssImports' : If true, all @import declarations in combined CSS
117
+ * files will be move to the top. Note this may alter effective CSS values
118
+ * due to a change in order. (default false)
119
+ *
120
  * 'debug' : set to true to minify all sources with the 'Lines' controller, which
121
  * eases the debugging of combined files. This also prevents 304 responses.
122
  * @see Minify_Lines::minify()
335
  *
336
  * @param array $sources array of filepaths and/or Minify_Source objects
337
  *
338
+ * @param array $options (optional) array of options for serve. By default
339
+ * these are already set: quiet = true, encodeMethod = '', lastModifiedTime = 0.
340
+ *
341
  * @return string
342
  */
343
+ public static function combine($sources, $options = array())
344
  {
345
  $cache = self::$_cache;
346
  self::$_cache = null;
347
+ $options = array_merge(array(
348
  'files' => (array)$sources
349
  ,'quiet' => true
350
  ,'encodeMethod' => ''
351
  ,'lastModifiedTime' => 0
352
+ ), $options);
353
+ $out = self::serve('Files', $options);
354
  self::$_cache = $cache;
355
  return $out['content'];
356
  }
471
  $content = implode($implodeSeparator, $pieces);
472
  }
473
 
474
+ if ($type === self::TYPE_CSS && false !== strpos($content, '@import')) {
475
+ $content = self::_handleCssImports($content);
476
+ }
477
+
478
  // do any post-processing (esp. for editing build URIs)
479
  if (self::$_options['postprocessorRequire']) {
480
  require_once self::$_options['postprocessorRequire'];
498
  ,self::$_options['minifiers']
499
  ,self::$_options['minifierOptions']
500
  ,self::$_options['postprocessor']
501
+ ,self::$_options['bubbleCssImports']
502
  )));
503
  }
504
+
505
+ /**
506
+ * Bubble CSS @imports to the top or prepend a warning if an
507
+ * @import is detected not at the top.
508
+ */
509
+ protected static function _handleCssImports($css) {
510
+ if (self::$_options['bubbleCssImports']) {
511
+ // bubble CSS imports
512
+ preg_match_all('/@import.*?;/', $css, $imports);
513
+ $css = implode('', $imports[0]) . preg_replace('/@import.*?;/', '', $css);
514
+ } else if ('' !== self::$importWarning) {
515
+ // remove comments so we don't mistake { in a comment as a block
516
+ $noCommentCss = preg_replace('@/\\*[\\s\\S]*?\\*/@', '', $css);
517
+ $lastImportPos = strrpos($noCommentCss, '@import');
518
+ $firstBlockPos = strpos($noCommentCss, '{');
519
+ if (false !== $lastImportPos
520
+ && false !== $firstBlockPos
521
+ && $firstBlockPos < $lastImportPos
522
+ ) {
523
+ // { appears before @import : prepend warning
524
+ $css = self::$importWarning . $css;
525
+ }
526
+ }
527
+ return $css;
528
+ }
529
  }
lib/minify/lib/Minify/CSS/Compressor.php CHANGED
@@ -147,7 +147,10 @@ class Minify_CSS_Compressor {
147
  \\s+
148
  /x'
149
  ,"$1\n", $css);
150
-
 
 
 
151
  return trim($css);
152
  }
153
 
147
  \\s+
148
  /x'
149
  ,"$1\n", $css);
150
+
151
+ // prevent triggering IE6 bug: http://www.crankygeek.com/ie6pebug/
152
+ $css = preg_replace('/:first-l(etter|ine)\\{/', ':first-l$1 {', $css);
153
+
154
  return trim($css);
155
  }
156
 
lib/minify/lib/Minify/CSS/UriRewriter.php CHANGED
@@ -19,6 +19,12 @@ class Minify_CSS_UriRewriter {
19
  */
20
  protected static $className = 'Minify_CSS_UriRewriter';
21
 
 
 
 
 
 
 
22
  /**
23
  * Rewrite file relative URIs as root relative in CSS files
24
  *
@@ -43,30 +49,35 @@ class Minify_CSS_UriRewriter {
43
  */
44
  public static function rewrite($css, $currentDir, $docRoot = null, $symlinks = array())
45
  {
46
- self::$_docRoot = $docRoot
47
- ? $docRoot
48
- : $_SERVER['DOCUMENT_ROOT'];
49
- self::$_docRoot = realpath(self::$_docRoot);
50
- self::$_currentDir = realpath($currentDir);
51
  self::$_symlinks = array();
52
-
53
- //echo "doc".self::$_docRoot."<br>";
54
- //echo "current".self::$_currentDir."<br>";exit;
55
 
56
  // normalize symlinks
57
- foreach ($symlinks as $link => $target) {//echo "link1: ".$link." <br>target: ".$target."<br>";
58
- $link = str_replace('//', realpath(self::$_docRoot), $link);//echo "link2: ".$link."<br>";
59
- $link = strtr($link, '/', DIRECTORY_SEPARATOR);//echo "link3: ".$link."<br>";
60
- self::$_symlinks[$link] = realpath($target);
 
 
61
  }
62
-
 
 
 
 
 
 
 
63
  $css = self::_trimUrls($css);
64
 
65
  // rewrite
66
  $css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/'
67
- ,array(self::$className, '_uriCB'), $css);
68
  $css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
69
- ,array(self::$className, '_uriCB'), $css);
70
 
71
  return $css;
72
  }
@@ -88,9 +99,9 @@ class Minify_CSS_UriRewriter {
88
 
89
  // append
90
  $css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/'
91
- ,array(self::$className, '_uriCB'), $css);
92
  $css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
93
- ,array(self::$className, '_uriCB'), $css);
94
 
95
  self::$_prependPath = null;
96
  return $css;
@@ -107,9 +118,9 @@ class Minify_CSS_UriRewriter {
107
  */
108
  private static $_docRoot = '';
109
 
110
- /**
111
- * @var array directory replacements to map symlink targets back to their
112
- * source (within the document root) E.g. '/var/www/symlink' => '/var/realpath'
113
  */
114
  private static $_symlinks = array();
115
 
@@ -118,27 +129,26 @@ class Minify_CSS_UriRewriter {
118
  */
119
  private static $_prependPath = null;
120
 
121
-
122
  private static function _trimUrls($css)
123
  {
124
  return preg_replace('/
125
  url\\( # url(
126
  \\s*
127
- ([^\\)]+?) # 1 = URI (really just a bunch of non right parenthesis)
128
  \\s*
129
  \\) # )
130
  /x', 'url($1)', $css);
131
  }
132
 
133
-
134
- private static function _uriCB($m)
135
  {
 
136
  $isImport = ($m[0][0] === '@');
 
137
  if ($isImport) {
138
  $quoteChar = $m[1];
139
  $uri = $m[2];
140
  } else {
141
- // is url()
142
  // $m[1] is either quoted or not
143
  $quoteChar = ($m[1][0] === "'" || $m[1][0] === '"')
144
  ? $m[1][0]
@@ -147,47 +157,116 @@ class Minify_CSS_UriRewriter {
147
  ? $m[1]
148
  : substr($m[1], 1, strlen($m[1]) - 2);
149
  }
150
- if ('/' !== $uri[0]) {
151
- if (strpos($uri, '//') > 0
152
- || 0 === strpos($uri, 'data:')
153
- ) {
154
- // probably starts with protocol, do not alter
155
- } else {
156
- // it's a file relative URI!
157
- // choose mode
158
- if (self::$_prependPath !== null) {
159
- // prepend path
160
- $uri = self::$_prependPath . $uri;
161
- } else {
162
- // rewrite path
163
- // prepend path with current dir separator (OS-independent)
164
- $path = strtr(self::$_currentDir, '/', DIRECTORY_SEPARATOR)
165
- . DIRECTORY_SEPARATOR . strtr($uri, '/', DIRECTORY_SEPARATOR);//echo "1".$path."<br>";
166
- // "unresolve" a symlink back to doc root
167
- foreach (self::$_symlinks as $link => $target) {
168
- if (0 === strpos($path, $target)) {
169
- // replace $target with $link
170
- $path = $link . substr($path, strlen($target));
171
- break;
172
- }
173
- }
174
- // strip doc root
175
- $path = substr($path, strlen(self::$_docRoot));//echo "2".$path."<br>";
176
- // fix to root-relative URI
177
- $uri = strtr($path, DIRECTORY_SEPARATOR, '/');//echo "3".$uri."<br>";
178
- // remove /./ and /../ where possible
179
- $uri = str_replace('/./', '/', $uri);//echo "4".$uri."<br>";
180
- // inspired by patch from Oleg Cherniy
181
- do {
182
- $uri = preg_replace('@/[^/]+/\\.\\./@', '/', $uri, -1, $changed);
183
- } while ($changed);
184
- }
185
- }
186
  }
187
- if ($isImport) {
188
- return "@import {$quoteChar}{$uri}{$quoteChar}";
189
- } else {
190
- return "url({$quoteChar}{$uri}{$quoteChar})";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  }
 
 
 
 
192
  }
193
  }
19
  */
20
  protected static $className = 'Minify_CSS_UriRewriter';
21
 
22
+ /**
23
+ * rewrite() and rewriteRelative() append debugging information here
24
+ * @var string
25
+ */
26
+ public static $debugText = '';
27
+
28
  /**
29
  * Rewrite file relative URIs as root relative in CSS files
30
  *
49
  */
50
  public static function rewrite($css, $currentDir, $docRoot = null, $symlinks = array())
51
  {
52
+ self::$_docRoot = self::_realpath(
53
+ $docRoot ? $docRoot : $_SERVER['DOCUMENT_ROOT']
54
+ );
55
+ self::$_currentDir = self::_realpath($currentDir);
 
56
  self::$_symlinks = array();
 
 
 
57
 
58
  // normalize symlinks
59
+ foreach ($symlinks as $link => $target) {
60
+ $link = ($link === '//')
61
+ ? self::$_docRoot
62
+ : str_replace('//', self::$_docRoot . '/', $link);
63
+ $link = strtr($link, '/', DIRECTORY_SEPARATOR);
64
+ self::$_symlinks[$link] = self::_realpath($target);
65
  }
66
+
67
+ self::$debugText .= "docRoot : " . self::$_docRoot . "\n"
68
+ . "currentDir : " . self::$_currentDir . "\n";
69
+ if (self::$_symlinks) {
70
+ self::$debugText .= "symlinks : " . var_export(self::$_symlinks, 1) . "\n";
71
+ }
72
+ self::$debugText .= "\n";
73
+
74
  $css = self::_trimUrls($css);
75
 
76
  // rewrite
77
  $css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/'
78
+ ,array(self::$className, '_processUriCB'), $css);
79
  $css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
80
+ ,array(self::$className, '_processUriCB'), $css);
81
 
82
  return $css;
83
  }
99
 
100
  // append
101
  $css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/'
102
+ ,array(self::$className, '_processUriCB'), $css);
103
  $css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
104
+ ,array(self::$className, '_processUriCB'), $css);
105
 
106
  self::$_prependPath = null;
107
  return $css;
118
  */
119
  private static $_docRoot = '';
120
 
121
+ /**
122
+ * @var array directory replacements to map symlink targets back to their
123
+ * source (within the document root) E.g. '/var/www/symlink' => '/var/realpath'
124
  */
125
  private static $_symlinks = array();
126
 
129
  */
130
  private static $_prependPath = null;
131
 
 
132
  private static function _trimUrls($css)
133
  {
134
  return preg_replace('/
135
  url\\( # url(
136
  \\s*
137
+ ([^\\)]+?) # 1 = URI (assuming does not contain ")")
138
  \\s*
139
  \\) # )
140
  /x', 'url($1)', $css);
141
  }
142
 
143
+ private static function _processUriCB($m)
 
144
  {
145
+ // $m matched either '/@import\\s+([\'"])(.*?)[\'"]/' or '/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
146
  $isImport = ($m[0][0] === '@');
147
+ // determine URI and the quote character (if any)
148
  if ($isImport) {
149
  $quoteChar = $m[1];
150
  $uri = $m[2];
151
  } else {
 
152
  // $m[1] is either quoted or not
153
  $quoteChar = ($m[1][0] === "'" || $m[1][0] === '"')
154
  ? $m[1][0]
157
  ? $m[1]
158
  : substr($m[1], 1, strlen($m[1]) - 2);
159
  }
160
+ // analyze URI
161
+ if ('/' !== $uri[0] // root-relative
162
+ && false === strpos($uri, '//') // protocol (non-data)
163
+ && 0 !== strpos($uri, 'data:') // data protocol
164
+ ) {
165
+ // URI is file-relative: rewrite depending on options
166
+ $uri = (self::$_prependPath !== null)
167
+ ? (self::$_prependPath . $uri)
168
+ : self::rewriteRelative($uri, self::$_currentDir, self::$_docRoot, self::$_symlinks);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  }
170
+ return $isImport
171
+ ? "@import {$quoteChar}{$uri}{$quoteChar}"
172
+ : "url({$quoteChar}{$uri}{$quoteChar})";
173
+ }
174
+
175
+ /**
176
+ * Rewrite a file relative URI as root relative
177
+ *
178
+ * <code>
179
+ * Minify_CSS_UriRewriter::rewriteRelative(
180
+ * '../img/hello.gif'
181
+ * , '/home/user/www/css' // path of CSS file
182
+ * , '/home/user/www' // doc root
183
+ * );
184
+ * // returns '/img/hello.gif'
185
+ *
186
+ * // example where static files are stored in a symlinked directory
187
+ * Minify_CSS_UriRewriter::rewriteRelative(
188
+ * 'hello.gif'
189
+ * , '/var/staticFiles/theme'
190
+ * , '/home/user/www'
191
+ * , array('/home/user/www/static' => '/var/staticFiles')
192
+ * );
193
+ * // returns '/static/theme/hello.gif'
194
+ * </code>
195
+ *
196
+ * @param string $uri file relative URI
197
+ *
198
+ * @param string $realCurrentDir realpath of the current file's directory.
199
+ *
200
+ * @param string $realDocRoot realpath of the site document root.
201
+ *
202
+ * @param array $symlinks (default = array()) If the file is stored in
203
+ * a symlink-ed directory, provide an array of link paths to
204
+ * real target paths, where the link paths "appear" to be within the document
205
+ * root. E.g.:
206
+ * <code>
207
+ * array('/home/foo/www/not/real/path' => '/real/target/path') // unix
208
+ * array('C:\\htdocs\\not\\real' => 'D:\\real\\target\\path') // Windows
209
+ * </code>
210
+ *
211
+ * @return string
212
+ */
213
+ public static function rewriteRelative($uri, $realCurrentDir, $realDocRoot, $symlinks = array())
214
+ {
215
+ // prepend path with current dir separator (OS-independent)
216
+ $path = strtr($realCurrentDir, '/', DIRECTORY_SEPARATOR)
217
+ . DIRECTORY_SEPARATOR . strtr($uri, '/', DIRECTORY_SEPARATOR);
218
+
219
+ self::$debugText .= "file-relative URI : {$uri}\n"
220
+ . "path prepended : {$path}\n";
221
+
222
+ // "unresolve" a symlink back to doc root
223
+ foreach ($symlinks as $link => $target) {
224
+ if (0 === strpos($path, $target)) {
225
+ // replace $target with $link
226
+ $path = $link . substr($path, strlen($target));
227
+
228
+ self::$debugText .= "symlink unresolved : {$path}\n";
229
+
230
+ break;
231
+ }
232
+ }
233
+ // strip doc root
234
+ $path = substr($path, strlen($realDocRoot));
235
+
236
+ self::$debugText .= "docroot stripped : {$path}\n";
237
+
238
+ // fix to root-relative URI
239
+ $uri = strtr($path, DIRECTORY_SEPARATOR, '/');
240
+ // remove /./ and /../ where possible
241
+ $uri = str_replace('/./', '/', $uri);
242
+ // inspired by patch from Oleg Cherniy
243
+ do {
244
+ $uri = preg_replace('@/[^/]+/\\.\\./@', '/', $uri, -1, $changed);
245
+ } while ($changed);
246
+
247
+ self::$debugText .= "traversals removed : {$uri}\n\n";
248
+
249
+ return $uri;
250
+ }
251
+
252
+
253
+
254
+ /**
255
+ * Get realpath with any trailing slash removed
256
+ *
257
+ * @param string $path
258
+ *
259
+ * @return mixed real path or false on realpath() failure
260
+ */
261
+ protected static function _realpath($path)
262
+ {
263
+ $path = realpath($path);
264
+ if (! $path) {
265
+ return false;
266
  }
267
+ $last = $path[strlen($path) - 1];
268
+ return ($last === '/' || $last === '\\')
269
+ ? substr($path, 0, strlen($path) - 1)
270
+ : $path;
271
  }
272
  }
lib/minify/lib/Minify/Controller/Base.php CHANGED
@@ -48,6 +48,7 @@ abstract class Minify_Controller_Base {
48
  ,'contentTypeCharset' => 'UTF-8'
49
  ,'maxAge' => 1800 // 30 minutes
50
  ,'rewriteCssUris' => true
 
51
  ,'quiet' => false // serve() will send headers and output
52
  ,'debug' => false
53
 
48
  ,'contentTypeCharset' => 'UTF-8'
49
  ,'maxAge' => 1800 // 30 minutes
50
  ,'rewriteCssUris' => true
51
+ ,'bubbleCssImports' => false
52
  ,'quiet' => false // serve() will send headers and output
53
  ,'debug' => false
54
 
lib/minify/lib/Minify/HTML.php CHANGED
@@ -18,13 +18,6 @@
18
  */
19
  class Minify_HTML {
20
 
21
- /**
22
- * Defines which class to call as part of callbacks, change this
23
- * if you extend Minify_HTML
24
- * @var string
25
- */
26
- protected static $className = 'Minify_HTML';
27
-
28
  /**
29
  * "Minify" an HTML page
30
  *
@@ -44,122 +37,152 @@ class Minify_HTML {
44
  * @return string
45
  */
46
  public static function minify($html, $options = array()) {
47
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  if (isset($options['cssMinifier'])) {
49
- self::$_cssMinifier = $options['cssMinifier'];
50
  }
51
  if (isset($options['jsMinifier'])) {
52
- self::$_jsMinifier = $options['jsMinifier'];
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  }
54
 
55
- $html = str_replace("\r\n", "\n", trim($html));
56
-
57
- self::$_isXhtml = (
58
- isset($options['xhtml'])
59
- ? (bool)$options['xhtml']
60
- : (false !== strpos($html, '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML'))
61
- );
62
-
63
- self::$_replacementHash = 'MINIFYHTML' . md5(time());
64
- self::$_placeholders = array();
65
 
66
  // replace SCRIPTs (and minify) with placeholders
67
- $html = preg_replace_callback(
68
  '/(\\s*)(<script\\b[^>]*?>)([\\s\\S]*?)<\\/script>(\\s*)/i'
69
- ,array(self::$className, '_removeScriptCB')
70
- ,$html);
71
 
72
  // replace STYLEs (and minify) with placeholders
73
- $html = preg_replace_callback(
74
  '/\\s*(<style\\b[^>]*?>)([\\s\\S]*?)<\\/style>\\s*/i'
75
- ,array(self::$className, '_removeStyleCB')
76
- ,$html);
77
 
78
  // remove HTML comments (not containing IE conditional comments).
79
- $html = preg_replace_callback(
80
  '/<!--([\\s\\S]*?)-->/'
81
- ,array(self::$className, '_commentCB')
82
- ,$html);
83
 
84
  // replace PREs with placeholders
85
- $html = preg_replace_callback('/\\s*(<pre\\b[^>]*?>[\\s\\S]*?<\\/pre>)\\s*/i'
86
- ,array(self::$className, '_removePreCB')
87
- , $html);
88
 
89
  // replace TEXTAREAs with placeholders
90
- $html = preg_replace_callback(
91
  '/\\s*(<textarea\\b[^>]*?>[\\s\\S]*?<\\/textarea>)\\s*/i'
92
- ,array(self::$className, '_removeTaCB')
93
- , $html);
94
 
95
  // trim each line.
96
  // @todo take into account attribute values that span multiple lines.
97
- $html = preg_replace('/^\\s+|\\s+$/m', '', $html);
98
 
99
  // remove ws around block/undisplayed elements
100
- $html = preg_replace('/\\s+(<\\/?(?:area|base(?:font)?|blockquote|body'
101
  .'|caption|center|cite|col(?:group)?|dd|dir|div|dl|dt|fieldset|form'
102
  .'|frame(?:set)?|h[1-6]|head|hr|html|legend|li|link|map|menu|meta'
103
  .'|ol|opt(?:group|ion)|p|param|t(?:able|body|head|d|h||r|foot|itle)'
104
- .'|ul)\\b[^>]*>)/i', '$1', $html);
105
 
106
  // remove ws outside of all elements
107
- $html = preg_replace_callback(
108
  '/>([^<]+)</'
109
- ,array(self::$className, '_outsideTagCB')
110
- ,$html);
111
 
112
  // use newlines before 1st attribute in open tags (to limit line lengths)
113
- $html = preg_replace('/(<[a-z\\-]+)\\s+([^>]+>)/i', "$1\n$2", $html);
114
 
115
  // fill placeholders
116
- $html = str_replace(
117
- array_keys(self::$_placeholders)
118
- ,array_values(self::$_placeholders)
119
- ,$html
120
  );
121
- self::$_placeholders = array();
122
-
123
- self::$_cssMinifier = self::$_jsMinifier = null;
124
- return $html;
125
  }
126
 
127
- protected static function _commentCB($m)
128
  {
129
  return (0 === strpos($m[1], '[') || false !== strpos($m[1], '<!['))
130
  ? $m[0]
131
  : '';
132
  }
133
 
134
- protected static function _reservePlace($content)
135
  {
136
- $placeholder = '%' . self::$_replacementHash . count(self::$_placeholders) . '%';
137
- self::$_placeholders[$placeholder] = $content;
138
  return $placeholder;
139
  }
140
 
141
- protected static $_isXhtml = false;
142
- protected static $_replacementHash = null;
143
- protected static $_placeholders = array();
144
- protected static $_cssMinifier = null;
145
- protected static $_jsMinifier = null;
146
 
147
- protected static function _outsideTagCB($m)
148
  {
149
  return '>' . preg_replace('/^\\s+|\\s+$/', ' ', $m[1]) . '<';
150
  }
151
 
152
- protected static function _removePreCB($m)
153
  {
154
- return self::_reservePlace($m[1]);
155
  }
156
 
157
- protected static function _removeTaCB($m)
158
  {
159
- return self::_reservePlace($m[1]);
160
  }
161
 
162
- protected static function _removeStyleCB($m)
163
  {
164
  $openStyle = $m[1];
165
  $css = $m[2];
@@ -167,21 +190,21 @@ class Minify_HTML {
167
  $css = preg_replace('/(?:^\\s*<!--|-->\\s*$)/', '', $css);
168
 
169
  // remove CDATA section markers
170
- $css = self::_removeCdata($css);
171
 
172
  // minify
173
- $minifier = self::$_cssMinifier
174
- ? self::$_cssMinifier
175
  : 'trim';
176
  $css = call_user_func($minifier, $css);
177
 
178
- return self::_reservePlace(self::_needsCdata($css)
179
  ? "{$openStyle}/*<![CDATA[*/{$css}/*]]>*/</style>"
180
  : "{$openStyle}{$css}</style>"
181
  );
182
  }
183
 
184
- protected static function _removeScriptCB($m)
185
  {
186
  $openScript = $m[2];
187
  $js = $m[3];
@@ -194,29 +217,29 @@ class Minify_HTML {
194
  $js = preg_replace('/(?:^\\s*<!--\\s*|\\s*(?:\\/\\/)?\\s*-->\\s*$)/', '', $js);
195
 
196
  // remove CDATA section markers
197
- $js = self::_removeCdata($js);
198
 
199
  // minify
200
- $minifier = self::$_jsMinifier
201
- ? self::$_jsMinifier
202
  : 'trim';
203
  $js = call_user_func($minifier, $js);
204
 
205
- return self::_reservePlace(self::_needsCdata($js)
206
  ? "{$ws1}{$openScript}/*<![CDATA[*/{$js}/*]]>*/</script>{$ws2}"
207
  : "{$ws1}{$openScript}{$js}</script>{$ws2}"
208
  );
209
  }
210
 
211
- protected static function _removeCdata($str)
212
  {
213
  return (false !== strpos($str, '<![CDATA['))
214
  ? str_replace(array('<![CDATA[', ']]>'), '', $str)
215
  : $str;
216
  }
217
 
218
- protected static function _needsCdata($str)
219
  {
220
- return (self::$_isXhtml && preg_match('/(?:[<&]|\\-\\-|\\]\\]>)/', $str));
221
  }
222
  }
18
  */
19
  class Minify_HTML {
20
 
 
 
 
 
 
 
 
21
  /**
22
  * "Minify" an HTML page
23
  *
37
  * @return string
38
  */
39
  public static function minify($html, $options = array()) {
40
+ $min = new Minify_HTML($html, $options);
41
+ return $min->process();
42
+ }
43
+
44
+
45
+ /**
46
+ * Create a minifier object
47
+ *
48
+ * @param string $html
49
+ *
50
+ * @param array $options
51
+ *
52
+ * 'cssMinifier' : (optional) callback function to process content of STYLE
53
+ * elements.
54
+ *
55
+ * 'jsMinifier' : (optional) callback function to process content of SCRIPT
56
+ * elements. Note: the type attribute is ignored.
57
+ *
58
+ * 'xhtml' : (optional boolean) should content be treated as XHTML1.0? If
59
+ * unset, minify will sniff for an XHTML doctype.
60
+ *
61
+ * @return null
62
+ */
63
+ public function __construct($html, $options = array())
64
+ {
65
+ $this->_html = str_replace("\r\n", "\n", trim($html));
66
+ if (isset($options['xhtml'])) {
67
+ $this->_isXhtml = (bool)$options['xhtml'];
68
+ }
69
  if (isset($options['cssMinifier'])) {
70
+ $this->_cssMinifier = $options['cssMinifier'];
71
  }
72
  if (isset($options['jsMinifier'])) {
73
+ $this->_jsMinifier = $options['jsMinifier'];
74
+ }
75
+ }
76
+
77
+
78
+ /**
79
+ * Minify the markeup given in the constructor
80
+ *
81
+ * @return string
82
+ */
83
+ public function process()
84
+ {
85
+ if ($this->_isXhtml === null) {
86
+ $this->_isXhtml = (false !== strpos($this->_html, '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML'));
87
  }
88
 
89
+ $this->_replacementHash = 'MINIFYHTML' . md5($_SERVER['REQUEST_TIME']);
90
+ $this->_placeholders = array();
 
 
 
 
 
 
 
 
91
 
92
  // replace SCRIPTs (and minify) with placeholders
93
+ $this->_html = preg_replace_callback(
94
  '/(\\s*)(<script\\b[^>]*?>)([\\s\\S]*?)<\\/script>(\\s*)/i'
95
+ ,array($this, '_removeScriptCB')
96
+ ,$this->_html);
97
 
98
  // replace STYLEs (and minify) with placeholders
99
+ $this->_html = preg_replace_callback(
100
  '/\\s*(<style\\b[^>]*?>)([\\s\\S]*?)<\\/style>\\s*/i'
101
+ ,array($this, '_removeStyleCB')
102
+ ,$this->_html);
103
 
104
  // remove HTML comments (not containing IE conditional comments).
105
+ $this->_html = preg_replace_callback(
106
  '/<!--([\\s\\S]*?)-->/'
107
+ ,array($this, '_commentCB')
108
+ ,$this->_html);
109
 
110
  // replace PREs with placeholders
111
+ $this->_html = preg_replace_callback('/\\s*(<pre\\b[^>]*?>[\\s\\S]*?<\\/pre>)\\s*/i'
112
+ ,array($this, '_removePreCB')
113
+ ,$this->_html);
114
 
115
  // replace TEXTAREAs with placeholders
116
+ $this->_html = preg_replace_callback(
117
  '/\\s*(<textarea\\b[^>]*?>[\\s\\S]*?<\\/textarea>)\\s*/i'
118
+ ,array($this, '_removeTextareaCB')
119
+ ,$this->_html);
120
 
121
  // trim each line.
122
  // @todo take into account attribute values that span multiple lines.
123
+ $this->_html = preg_replace('/^\\s+|\\s+$/m', '', $this->_html);
124
 
125
  // remove ws around block/undisplayed elements
126
+ $this->_html = preg_replace('/\\s+(<\\/?(?:area|base(?:font)?|blockquote|body'
127
  .'|caption|center|cite|col(?:group)?|dd|dir|div|dl|dt|fieldset|form'
128
  .'|frame(?:set)?|h[1-6]|head|hr|html|legend|li|link|map|menu|meta'
129
  .'|ol|opt(?:group|ion)|p|param|t(?:able|body|head|d|h||r|foot|itle)'
130
+ .'|ul)\\b[^>]*>)/i', '$1', $this->_html);
131
 
132
  // remove ws outside of all elements
133
+ $this->_html = preg_replace_callback(
134
  '/>([^<]+)</'
135
+ ,array($this, '_outsideTagCB')
136
+ ,$this->_html);
137
 
138
  // use newlines before 1st attribute in open tags (to limit line lengths)
139
+ $this->_html = preg_replace('/(<[a-z\\-]+)\\s+([^>]+>)/i', "$1\n$2", $this->_html);
140
 
141
  // fill placeholders
142
+ $this->_html = str_replace(
143
+ array_keys($this->_placeholders)
144
+ ,array_values($this->_placeholders)
145
+ ,$this->_html
146
  );
147
+ return $this->_html;
 
 
 
148
  }
149
 
150
+ protected function _commentCB($m)
151
  {
152
  return (0 === strpos($m[1], '[') || false !== strpos($m[1], '<!['))
153
  ? $m[0]
154
  : '';
155
  }
156
 
157
+ protected function _reservePlace($content)
158
  {
159
+ $placeholder = '%' . $this->_replacementHash . count($this->_placeholders) . '%';
160
+ $this->_placeholders[$placeholder] = $content;
161
  return $placeholder;
162
  }
163
 
164
+ protected $_isXhtml = null;
165
+ protected $_replacementHash = null;
166
+ protected $_placeholders = array();
167
+ protected $_cssMinifier = null;
168
+ protected $_jsMinifier = null;
169
 
170
+ protected function _outsideTagCB($m)
171
  {
172
  return '>' . preg_replace('/^\\s+|\\s+$/', ' ', $m[1]) . '<';
173
  }
174
 
175
+ protected function _removePreCB($m)
176
  {
177
+ return $this->_reservePlace($m[1]);
178
  }
179
 
180
+ protected function _removeTextareaCB($m)
181
  {
182
+ return $this->_reservePlace($m[1]);
183
  }
184
 
185
+ protected function _removeStyleCB($m)
186
  {
187
  $openStyle = $m[1];
188
  $css = $m[2];
190
  $css = preg_replace('/(?:^\\s*<!--|-->\\s*$)/', '', $css);
191
 
192
  // remove CDATA section markers
193
+ $css = $this->_removeCdata($css);
194
 
195
  // minify
196
+ $minifier = $this->_cssMinifier
197
+ ? $this->_cssMinifier
198
  : 'trim';
199
  $css = call_user_func($minifier, $css);
200
 
201
+ return $this->_reservePlace($this->_needsCdata($css)
202
  ? "{$openStyle}/*<![CDATA[*/{$css}/*]]>*/</style>"
203
  : "{$openStyle}{$css}</style>"
204
  );
205
  }
206
 
207
+ protected function _removeScriptCB($m)
208
  {
209
  $openScript = $m[2];
210
  $js = $m[3];
217
  $js = preg_replace('/(?:^\\s*<!--\\s*|\\s*(?:\\/\\/)?\\s*-->\\s*$)/', '', $js);
218
 
219
  // remove CDATA section markers
220
+ $js = $this->_removeCdata($js);
221
 
222
  // minify
223
+ $minifier = $this->_jsMinifier
224
+ ? $this->_jsMinifier
225
  : 'trim';
226
  $js = call_user_func($minifier, $js);
227
 
228
+ return $this->_reservePlace($this->_needsCdata($js)
229
  ? "{$ws1}{$openScript}/*<![CDATA[*/{$js}/*]]>*/</script>{$ws2}"
230
  : "{$ws1}{$openScript}{$js}</script>{$ws2}"
231
  );
232
  }
233
 
234
+ protected function _removeCdata($str)
235
  {
236
  return (false !== strpos($str, '<![CDATA['))
237
  ? str_replace(array('<![CDATA[', ']]>'), '', $str)
238
  : $str;
239
  }
240
 
241
+ protected function _needsCdata($str)
242
  {
243
+ return ($this->_isXhtml && preg_match('/(?:[<&]|\\-\\-|\\]\\]>)/', $str));
244
  }
245
  }
lib/minify/lib/Minify/Lines.php CHANGED
@@ -18,13 +18,19 @@ class Minify_Lines {
18
  *
19
  * This uses a very basic parser easily fooled by comment tokens inside
20
  * strings or regexes, but, otherwise, generally clean code will not be
21
- * mangled.
22
- *
23
  * @param string $content
24
  *
25
  * @param array $options available options:
26
  *
27
  * 'id': (optional) string to identify file. E.g. file name/path
 
 
 
 
 
 
28
  *
29
  * @return string
30
  */
@@ -49,7 +55,24 @@ class Minify_Lines {
49
  $newLines[] = self::_addNote($line, $i, $inComment, $padTo);
50
  $inComment = self::_eolInComment($line, $inComment);
51
  }
52
- return implode("\n", $newLines) . "\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  }
54
 
55
  /**
18
  *
19
  * This uses a very basic parser easily fooled by comment tokens inside
20
  * strings or regexes, but, otherwise, generally clean code will not be
21
+ * mangled. URI rewriting can also be performed.
22
+ *
23
  * @param string $content
24
  *
25
  * @param array $options available options:
26
  *
27
  * 'id': (optional) string to identify file. E.g. file name/path
28
+ *
29
+ * 'currentDir': (default null) if given, this is assumed to be the
30
+ * directory of the current CSS file. Using this, minify will rewrite
31
+ * all relative URIs in import/url declarations to correctly point to
32
+ * the desired files, and prepend a comment with debugging information about
33
+ * this process.
34
  *
35
  * @return string
36
  */
55
  $newLines[] = self::_addNote($line, $i, $inComment, $padTo);
56
  $inComment = self::_eolInComment($line, $inComment);
57
  }
58
+ $content = implode("\n", $newLines) . "\n";
59
+
60
+ // check for desired URI rewriting
61
+ if (isset($options['currentDir'])) {
62
+ require_once 'Minify/CSS/UriRewriter.php';
63
+ Minify_CSS_UriRewriter::$debugText = '';
64
+ $content = Minify_CSS_UriRewriter::rewrite(
65
+ $content
66
+ ,$options['currentDir']
67
+ ,isset($options['docRoot']) ? $options['docRoot'] : $_SERVER['DOCUMENT_ROOT']
68
+ ,isset($options['symlinks']) ? $options['symlinks'] : array()
69
+ );
70
+ $content = "/* Minify_CSS_UriRewriter::\$debugText\n\n"
71
+ . Minify_CSS_UriRewriter::$debugText . "*/\n"
72
+ . $content;
73
+ }
74
+
75
+ return $content;
76
  }
77
 
78
  /**
lib/minify/lib/MyMin.php DELETED
@@ -1,289 +0,0 @@
1
- <?php
2
- /**
3
- * MyMin - JSMin like alternative parser for JavaScript
4
- *
5
- * This class is a jsmin alternative, based on same parser logic but modified
6
- * to mantain performances and to parse correctly JavaScript conditional comments too.
7
- *
8
- * SERVER SIDE
9
- * PHP 5 or greater is required.
10
- * This code is compatible with every error_reporting level (E_ALL | E_STRICT)
11
- * The best practice to use this code is caching results without run-time
12
- * evaluation (your server should be stressed too much with big files)
13
- *
14
- * Permission is hereby granted to use this version of the library under the
15
- * same terms as jsmin.php, which has the following license:
16
- *
17
- * --
18
- * Copyright (c) 2002 Douglas Crockford (www.crockford.com)
19
- *
20
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
21
- * this software and associated documentation files (the "Software"), to deal in
22
- * the Software without restriction, including without limitation the rights to
23
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
24
- * of the Software, and to permit persons to whom the Software is furnished to do
25
- * so, subject to the following conditions:
26
- *
27
- * The above copyright notice and this permission notice shall be included in all
28
- * copies or substantial portions of the Software.
29
- *
30
- * The Software shall be used for Good, not Evil.
31
- *
32
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38
- * SOFTWARE.
39
- * --
40
- *
41
- * @class MyMin
42
- * @author Andrea Giammarchi <http://www.3site.eu>
43
- * @copyright 2002 Douglas Crockford <douglas@crockford.com> (jsmin.c)
44
- * @copyright 2007 Ryan Grove <ryan@wonko.com> (PHP port)
45
- * @copyright 2007 Andrea Giammarchi (improvements + MyMinCompressor + MyMinCSS)
46
- * @license http://opensource.org/licenses/mit-license.php MIT License
47
- * @version 1.0.1 (2007-10-05) - updated 2008-02-17
48
- */
49
-
50
- // -- Class MyMin --------------------------------------------------------------
51
- class MyMin {
52
-
53
- const /* char */ LF = "\n",
54
- SPACE = ' ',
55
- EOS = "\x00";
56
-
57
- protected /* boolean */ $cc_on;
58
-
59
- protected /* char */ $a,
60
- $ahead,
61
- $b;
62
-
63
- protected /* int */ $index = 0,
64
- $length;
65
-
66
- protected /* string */ $input,
67
- $output = "";
68
-
69
- // -- Public Static Methods ----------------------------------------------------
70
- static public final function /* string */ parse(/* string */ $input, /* boolean */ $cc_on = true){
71
- return "".(new MyMin($input, $cc_on));
72
- }
73
-
74
- // -- Public Instance Methods --------------------------------------------------
75
- public final function /* object */ __construct(/* string */ $input, /* boolean */ $cc_on = true){
76
- $this->input = preg_replace("/(\r\n|\n\r|\r|\n)+/", self::LF, trim($input));
77
- $this->length = strlen($this->input);
78
- $this->cc_on = $cc_on;
79
- $this->b = $this->ahead = self::SPACE;
80
- $this->a = self::LF;
81
- $this->action(3);
82
- while($this->a !== self::EOS){
83
- switch($this->a){
84
- case self::SPACE:
85
- $this->action($this->isAlNum($this->b) ? 1 : 2);
86
- break;
87
- case self::LF:
88
- switch($this->b){
89
- case '{':
90
- case '[':
91
- case '(':
92
- case '+':
93
- case '-':
94
- $this->action(1);
95
- break;
96
- case self::SPACE:
97
- $this->action(3);
98
- break;
99
- default:
100
- $this->action($this->isAlNum($this->b) ? 1 : 2);
101
- break;
102
- }
103
- break;
104
- default:
105
- switch($this->b){
106
- case self::SPACE:
107
- $this->action($this->isAlNum($this->a) ? 1 : 3);
108
- break;
109
- case self::LF:
110
- switch($this->a){
111
- case '}':
112
- case ']':
113
- case ')':
114
- case '+':
115
- case '-':
116
- case '"':
117
- case '\'':
118
- $this->action(1);
119
- break;
120
- default:
121
- $this->action($this->isAlNum($this->a) ? 1 : 3);
122
- break;
123
- }
124
- break;
125
- default:
126
- $this->action(1);
127
- break;
128
- }
129
- break;
130
- }
131
- }
132
- }
133
-
134
- public final function /* string */ __toString(/* void */){
135
- return str_replace("\n\n", "\n", ltrim($this->output));
136
- }
137
-
138
- // -- Protected Instance Methods -----------------------------------------------
139
- protected function /* void */ action(/* int */ $i){
140
- switch($i){
141
- case 1:
142
- $this->output .= $this->a;
143
- case 2:
144
- $this->a = $this->b;
145
- if($this->a === '\'' || $this->a === '"'){
146
- while(true){
147
- $this->output .= $this->a;
148
- if(!$this->nextCharNoSlash($this->b, "Unterminated string literal."))
149
- break;
150
- }
151
- }
152
- case 3:
153
- $this->b = $this->next();
154
- if($this->b === '/'){
155
- switch($this->a){
156
- case self::LF:
157
- case self::SPACE:
158
- if(!$this->spaceBeforeRegExp($this->output))
159
- break;
160
-
161
- case '{':
162
- case ';':
163
-
164
- case '(':
165
- case ',':
166
- case '=':
167
- case ':':
168
- case '[':
169
- case '!':
170
- case '&':
171
- case '|':
172
- case '?':
173
- $this->output .= $this->a.$this->b;
174
- while($this->nextCharNoSlash('/', "Unterminated regular expression literal."))
175
- $this->output .= $this->a;
176
- $this->b = $this->next();
177
- break;
178
- }
179
- }
180
- break;
181
- }
182
- }
183
-
184
- protected function /* void */ appendComment(/* int */ $pos, /* string */ $open, /* string */ $close) {
185
- $this->output .= $this->a.$open.(new MyMin(substr($this->input, $this->index, $pos - $this->index), $this->cc_on)).$close;
186
- $this->index = $pos;
187
- $this->a = self::LF;
188
- }
189
-
190
- protected function /* void */ conditionalComment(/* char */ $find) {
191
- $single = $find === self::LF;
192
- $pos = strpos($this->input, $find, $this->index);
193
- if($pos === false){
194
- if($single)
195
- $pos = $this->length;
196
- else
197
- throw new MyMinException("Unterminated comment.");
198
- }
199
- $this->appendComment($pos, $single ? "//" : "/*", $find);
200
- }
201
-
202
- protected function /* char */ get(/* void */) {
203
- $c = $this->ahead;
204
- $this->ahead = self::EOS;
205
- if($c === self::EOS && $this->index < $this->length)
206
- $c = $this->input{$this->index++};
207
- return ($c === self::EOS || $c === self::LF || $c >= self::SPACE) ? $c : self::SPACE;
208
- }
209
-
210
- protected function /* boolean */ isAlNum(/* char */ $c) {
211
- return $c > 126 || $c === '\\' || preg_match('/^(\w|\$)$/', $c);
212
- }
213
-
214
- protected function /* char */ next(/* void */) {
215
- $c = $this->get();
216
- $loop = true;
217
- if($c === '/'){
218
- switch($this->ahead = $this->get()){
219
- case '/':
220
- if($this->cc_on && $this->input{$this->index} === '@')
221
- $this->conditionalComment(self::LF);
222
- while($loop){
223
- $c = $this->get();
224
- if($c <= self::LF)
225
- $loop = false;
226
- }
227
- break;
228
- case '*':
229
- $this->get();
230
- if($this->cc_on && $this->input{$this->index} === '@')
231
- $this->conditionalComment("*/");
232
- while($loop){
233
- switch($this->get()){
234
- case '*':
235
- if(($this->ahead = $this->get()) === '/'){
236
- $this->get();
237
- $c = self::SPACE;
238
- $loop = false;
239
- }
240
- break;
241
- case self::EOS:
242
- throw new MyMinException("Unterminated comment.");
243
- }
244
- }
245
- break;
246
- }
247
- }
248
- return $c;
249
- }
250
-
251
- protected function /* boolean */ nextCharNoSlash(/* char */ $c, /* string */ $message) {
252
- $loop = true;
253
- $this->a = $this->get();
254
- if($this->a === $c)
255
- $loop = false;
256
- else{
257
- if($this->a === '\\'){
258
- $this->output .= $this->a;
259
- $this->a = $this->get();
260
- }
261
- if($this->a <= self::LF)
262
- throw new MyMinException($message);
263
- }
264
- return $loop;
265
- }
266
-
267
- protected function /* boolean */ spaceBeforeRegExp(/* string */ $output){
268
- for(
269
- $i = 0,
270
- $length = strlen($output),
271
- $reserved = array("case", "else", "in", "return", "typeof"),
272
- $result = false,
273
- $tmp = "";
274
- $i < 5 && !$result;
275
- $i++
276
- ){
277
- if($length === strlen($reserved[$i]))
278
- $result = $reserved[$i] === $output;
279
- else if($length > strlen($reserved[$i])){
280
- $tmp = substr($output, $length - strlen($reserved[$i]) - 1);
281
- $result = substr($tmp, 1) === $reserved[$i] && !$this->isAlNum($tmp{0});
282
- }
283
- };
284
- return $length < 2 ? true : $result;
285
- }
286
- }
287
-
288
- // -- MyMin Exceptions ---------------------------------------------------------
289
- class MyMinException extends Exception {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
package.xml CHANGED
@@ -1,23 +1,23 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Fooman_Speedster</name>
4
- <version>1.0.1</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.opensource.org/licenses/osl-3.0.php">OSL v3.0 / BSD see files</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Speed up your store by combining, compressing and caching JS and CSS.</summary>
10
- <description>&lt;p&gt;FOOMAN Speedster 1.0.1&lt;/p&gt;
11
 
12
  &lt;p&gt;Speed up your store by combining, compressing and caching JS and CSS.&lt;/p&gt;
13
 
14
  &lt;p&gt;Please read the installation instructions and latest changes &lt;a href="http://www.magentocommerce.com/extension/457/fooman-speedster"&gt;here.&lt;/a&gt;
15
  &lt;/p&gt;</description>
16
- <notes>updated to newer minify build 309</notes>
17
  <authors><author><name>Kristof Ringleff</name><user>auto-converted</user><email>kristof@fooman.co.nz</email></author></authors>
18
- <date>2009-03-21</date>
19
- <time>21:29:16</time>
20
- <contents><target name="mage"><dir name="app"><dir name="etc"><dir name="modules"><file name="Fooman_Speedster.xml" hash="94d303cd2552119381411068d2e7809b"/></dir></dir></dir><dir name="js"><dir name="prototype"><file name="validation-4min.js" hash="6772623b37ef0a68e845e27004d7e1cb"/></dir></dir><dir name="lib"><dir name="minify"><file name=".htaccess" hash="4d6b8833e4ccae2d2393dfeba369b894"/></dir></dir><dir name="var"><dir name="minifycache"><file name="cache.txt" hash="f0d69d04e957df748496700370c146d7"/></dir></dir></target><target name="magecommunity"><dir name="Fooman"><dir name="Speedster"><dir name="Block"><dir name="Adminhtml"><dir name="Page"><file name="Head.php" hash="d850197d05af7b972eda1ef6bf3da2ed"/></dir></dir><dir name="Page"><dir name="Html"><file name="Head.php" hash="d3cb5b9869689fd5535511ebbab9efee"/></dir></dir></dir><dir name="etc"><file name="config.xml" hash="ad386f588fbd35fc75252ee55e4d5478"/></dir></dir></dir></target><target name="magelib"><dir name="minify"><dir name="lib"><dir name="HTTP"><file name="ConditionalGet.php" hash="66fdaeffbf7d4fb2fa9733b751b1881e"/><file name="Encoder.php" hash="cbadcc9dd18dfa0fad233c010b85427e"/></dir><dir name="Minify"><dir name="Cache"><file name="APC.php" hash="2766ccf5e1e4d6e38d3ec128dbc4bc6f"/><file name="File.php" hash="dd7545011e50c153a11dd100db35315a"/><file name="Memcache.php" hash="fa208d979196d0479e3aacec853502c8"/></dir><dir name="Controller"><file name="Base.php" hash="1bc3c5b3d855d27d6b4b0a7df081ad73"/><file name="Files.php" hash="f579a28cea39da5c595057e72fc65967"/><file name="Groups.php" hash="79bb7cbd0b598dc35a93b99adfdbfab6"/><file name="MinApp.php" hash="42803a069db0f5892012991af5ec5334"/><file name="Page.php" hash="113e99f1206cfb3c3a64aedef65554d1"/><file name="Version1.php" hash="4369c8793be1d5cf061a99651b16da26"/></dir><dir name="CSS"><file name="Compressor.php" hash="d6910fa97966f193e13332c92f80e203"/><file name="UriRewriter.php" hash="a61a9c74dcbd8fdf7774cd2a767393bc"/></dir><file name="Build.php" hash="6e329c2acc80b72cfde52be6918940bb"/><file name="BuildSpeedster.php" hash="29409f498535de615ea68679939afc27"/><file name="CommentPreserver.php" hash="86bab05265083b57935503bdd735ce74"/><file name="CSS.php" hash="cdeb49c0f35a6cef166c6cfee7f1dd95"/><file name="HTML.php" hash="0c7f8537dd1cae03db0db281b269fc2a"/><file name="ImportProcessor.php" hash="3d1726a5df7eb2edba8cd6da2cb75eec"/><file name="Javascript.php" hash="1baa1a43818fcecb89c2a08b40a544da"/><file name="Lines.php" hash="68d454e2156c281a138c7901541e4d55"/><file name="Logger.php" hash="b2844a8c35e028b9ee725be05adbcf7e"/><file name="Packer.php" hash="41878d87ec3b3e3bbd1538291edeb7cf"/><file name="Source.php" hash="a8d9fa9f0ab2ba9e9b37209148375924"/><file name="YUICompressor.php" hash="13840856d6340e70e7289035827b8b7d"/></dir><dir name="Solar"><file name="Dir.php" hash="6c88f363f6830ac4dc3917eac3c9d78c"/></dir><file name="FirePHP.php" hash="f619b5a77fee4b21e4397e98d858fbf4"/><file name="JSMin.php" hash="e9fe7911a2787240d3ed6dd2da9bc95b"/><file name="Minify.php" hash="20da0e607a7466b6498943188616e1df"/><file name="MyMin.php" hash="b752af08d4c877234f28cd24e9fa69b1"/></dir><file name="HISTORY.txt" hash="ec89f1a4c4cd8d9fb42fc3d6b690feee"/><file name="LICENSE.txt" hash="911d374696c0a5e9e6e848e7f20d0ee1"/><file name="m.php" hash="49b12c34094a3ba1090f7b42719706e7"/><file name="README.txt" hash="4a98dae0654ab37acb46b64c821c9b9c"/></dir></target></contents>
21
  <compatible/>
22
  <dependencies/>
23
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Fooman_Speedster</name>
4
+ <version>1.0.2</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.opensource.org/licenses/osl-3.0.php">OSL v3.0 / BSD see files</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Speed up your store by combining, compressing and caching JS and CSS.</summary>
10
+ <description>&lt;p&gt;FOOMAN Speedster 1.0.2&lt;/p&gt;
11
 
12
  &lt;p&gt;Speed up your store by combining, compressing and caching JS and CSS.&lt;/p&gt;
13
 
14
  &lt;p&gt;Please read the installation instructions and latest changes &lt;a href="http://www.magentocommerce.com/extension/457/fooman-speedster"&gt;here.&lt;/a&gt;
15
  &lt;/p&gt;</description>
16
+ <notes>reupload of 1.0.1</notes>
17
  <authors><author><name>Kristof Ringleff</name><user>auto-converted</user><email>kristof@fooman.co.nz</email></author></authors>
18
+ <date>2009-03-22</date>
19
+ <time>10:29:47</time>
20
+ <contents><target name="mage"><dir name="app"><dir name="etc"><dir name="modules"><file name="Fooman_Speedster.xml" hash="94d303cd2552119381411068d2e7809b"/></dir></dir></dir><dir name="js"><dir name="prototype"><file name="validation-4min.js" hash="6772623b37ef0a68e845e27004d7e1cb"/></dir></dir><dir name="lib"><dir name="minify"><file name=".htaccess" hash="4d6b8833e4ccae2d2393dfeba369b894"/></dir></dir><dir name="var"><dir name="minifycache"><file name="cache.txt" hash="5709c1d6a6f85fb7b7ea2eef23086b46"/></dir></dir></target><target name="magecommunity"><dir name="Fooman"><dir name="Speedster"><dir name="Block"><dir name="Adminhtml"><dir name="Page"><file name="Head.php" hash="d850197d05af7b972eda1ef6bf3da2ed"/></dir></dir><dir name="Page"><dir name="Html"><file name="Head.php" hash="d3cb5b9869689fd5535511ebbab9efee"/></dir></dir></dir><dir name="etc"><file name="config.xml" hash="a64a32de72467805e9d2e45afcb44bdb"/></dir></dir></dir></target><target name="magelib"><dir name="minify"><dir name="lib"><dir name="HTTP"><file name="ConditionalGet.php" hash="2617a41438dff20749abb9be1793b10f"/><file name="Encoder.php" hash="a2f4ae355c06fb6a98d6b4bd82c34e76"/></dir><dir name="Minify"><dir name="Cache"><file name="APC.php" hash="2766ccf5e1e4d6e38d3ec128dbc4bc6f"/><file name="File.php" hash="dd7545011e50c153a11dd100db35315a"/><file name="Memcache.php" hash="fa208d979196d0479e3aacec853502c8"/></dir><dir name="Controller"><file name="Base.php" hash="070ed4d5f471a88f2f45cf2e93ba720a"/><file name="Files.php" hash="f579a28cea39da5c595057e72fc65967"/><file name="Groups.php" hash="79bb7cbd0b598dc35a93b99adfdbfab6"/><file name="MinApp.php" hash="42803a069db0f5892012991af5ec5334"/><file name="Page.php" hash="113e99f1206cfb3c3a64aedef65554d1"/><file name="Version1.php" hash="4369c8793be1d5cf061a99651b16da26"/></dir><dir name="CSS"><file name="Compressor.php" hash="3a3a65aa92f74958f50d9d43f8827f8a"/><file name="UriRewriter.php" hash="da8f5cdad4726e0370bbe5f351ec9d98"/></dir><file name="Build.php" hash="6e329c2acc80b72cfde52be6918940bb"/><file name="BuildSpeedster.php" hash="29409f498535de615ea68679939afc27"/><file name="CommentPreserver.php" hash="86bab05265083b57935503bdd735ce74"/><file name="CSS.php" hash="cdeb49c0f35a6cef166c6cfee7f1dd95"/><file name="HTML.php" hash="e774a70491041048fef690d4b162e0ce"/><file name="ImportProcessor.php" hash="3d1726a5df7eb2edba8cd6da2cb75eec"/><file name="Javascript.php" hash="1baa1a43818fcecb89c2a08b40a544da"/><file name="Lines.php" hash="80b2932320c98d1e84aa7f48fceb35e8"/><file name="Logger.php" hash="b2844a8c35e028b9ee725be05adbcf7e"/><file name="Packer.php" hash="41878d87ec3b3e3bbd1538291edeb7cf"/><file name="Source.php" hash="a8d9fa9f0ab2ba9e9b37209148375924"/><file name="YUICompressor.php" hash="13840856d6340e70e7289035827b8b7d"/></dir><dir name="Solar"><file name="Dir.php" hash="6c88f363f6830ac4dc3917eac3c9d78c"/></dir><file name="FirePHP.php" hash="f619b5a77fee4b21e4397e98d858fbf4"/><file name="JSMin.php" hash="e9fe7911a2787240d3ed6dd2da9bc95b"/><file name="Minify.php" hash="9ee5b8bb23e3d856faec4358aa887e33"/></dir><file name="HISTORY.txt" hash="70c3e25e9331dc17e5d538bfc3dd8fe1"/><file name="LICENSE.txt" hash="911d374696c0a5e9e6e848e7f20d0ee1"/><file name="m.php" hash="49b12c34094a3ba1090f7b42719706e7"/><file name="README.txt" hash="6e961a626ae6814c72fab53bcad4a4a7"/></dir></target></contents>
21
  <compatible/>
22
  <dependencies/>
23
  </package>
var/minifycache/cache.txt CHANGED
@@ -1 +1,5 @@
 
 
 
1
  this file can be deleted
 
1
+ FOOMAN Speedster
2
+ folder to cache minified output
3
+
4
  this file can be deleted
5
+