Permalink
Browse files

Basic functionality: Supports linked files, not inlined ones

  • Loading branch information...
1 parent 8ce2431 commit f32af839a839cac3f4b213f344d77fa5fb7ca99d @canton7 committed May 31, 2012
Showing with 61 additions and 11 deletions.
  1. +12 −9 classes/casset.php
  2. +49 −2 classes/casset/cssurirewriterrelative.php
View
@@ -901,6 +901,7 @@ public static function render_css($group = false, $options = array(), $attr_dep
{
if ($inline)
{
+ // TODO: Add destination_filepath
$content = static::load_file($file['file'], 'css');
if ($options['gen_tags'])
$ret .= html_tag('style', $attr, PHP_EOL.$content.PHP_EOL).PHP_EOL;
@@ -1070,7 +1071,7 @@ protected static function files_to_render($type, $group)
* @param type $filename
* @return type
*/
- protected static function load_file($filename, $type, $file_group = false)
+ protected static function load_file($filename, $type, $file_group = false, $destination_filename = null)
{
$content = file_get_contents($filename);
if (static::$post_load_callback != null)
@@ -1080,7 +1081,7 @@ protected static function load_file($filename, $type, $file_group = false)
$content = $func($content, $filename, $type, $file_group);
}
if ($type == 'css')
- $content = static::css_rewrite_uris($content, $filename);
+ $content = static::css_rewrite_uris($content, $filename, $destination_filename);
return $content;
}
@@ -1089,15 +1090,16 @@ protected static function load_file($filename, $type, $file_group = false)
*
* @param string $content the contents of the file to rewrite
* @param string $filename the original location of the file
+ * @param string $destination_filename the name of the file where the css will be written to
* @return string The re-written content
*/
- protected static function css_rewrite_uris($content, $filename) {
+ protected static function css_rewrite_uris($content, $filename, $destination_filename) {
switch (static::$css_uri_rewriter) {
case 'absolute':
$rewritten = Casset_Cssurirewriter::rewrite($content, dirname($filename));
break;
case 'relative':
- $rewritten = Casset_Cssurirewriterrelative::rewrite($content);
+ $rewritten = Casset_Cssurirewriterrelative::rewrite_css($content, dirname($filename), dirname($destination_filename));
break;
case 'none':
$rewritten = $content;
@@ -1141,8 +1143,9 @@ protected static function combine($type, $file_group, $minify, $inline)
return $a['file'];
}, $file_group)).($minify ? 'min' : '').$last_mod).'.'.$type;
- $filepath = DOCROOT.static::$cache_path.'/'.$filename;
- $needs_update = (!file_exists($filepath));
+ $rel_filepath = static::$cache_path.'/'.$filename;
+ $abs_filepath = DOCROOT.$rel_filepath;
+ $needs_update = (!file_exists($abs_filepath));
if ($needs_update)
{
@@ -1152,10 +1155,10 @@ protected static function combine($type, $file_group, $minify, $inline)
if (static::$show_files_inline)
$content .= PHP_EOL.'/* '.$file['file'].' */'.PHP_EOL.PHP_EOL;
if ($file['minified'] || !$minify)
- $content .= static::load_file($file['file'], $type, $file_group).PHP_EOL;
+ $content .= static::load_file($file['file'], $type, $file_group, $rel_filepath).PHP_EOL;
else
{
- $file_content = static::load_file($file['file'], $type, $file_group);
+ $file_content = static::load_file($file['file'], $type, $file_group, $rel_filepath);
if ($file_content === false)
throw new Casset_Exception("Couldn't not open file {$file['file']}");
if ($type == 'js')
@@ -1168,7 +1171,7 @@ protected static function combine($type, $file_group, $minify, $inline)
}
}
}
- file_put_contents($filepath, $content, LOCK_EX);
+ file_put_contents($abs_filepath, $content, LOCK_EX);
$mtime = time();
}
@@ -13,8 +13,55 @@
namespace Casset;
class Casset_Cssurirewriterrelative {
- public static function rewrite($content) {
- return $content;
+ const PATTERN = '/(url|@import)\s*\(\s*([\'"]?)([^\/\'"][^)\2]+)\2\s*\)/';
+
+ public static function rewrite_css($css, $before_dir, $after_dir) {
+ // Normalise slashes
+ $before_dir = str_replace('\\', '/', $before_dir);
+ $after_dir = str_replace('\\', '/', $after_dir);
+
+ // Make sure before_dir and after_dir have trailing slashes
+ $before_dir = rtrim($before_dir, '/') . '/';
+ $after_dir = rtrim($after_dir, '/') . '/';
+
+ // Trim off common leading prefix
+ $i = 0;
+ for (; $i<strlen($after_dir); $i++) {
+ if ($after_dir[$i] != $before_dir[$i])
+ break;
+ }
+ // If we quit on the first loop, $i holds first index of mismatch, otherwise last index of match
+ $i = max($i-1, 0);
+ $after_dir = substr($after_dir, $i);
+ $before_dir = substr($before_dir, $i);
+
+ // Move back out of the dir that the file ends up in
+ // then back into the dir the file was in before
+ $rel = str_repeat('../', substr_count($after_dir, '/')) . $before_dir;
+
+ // return $css;
+
+ $css = preg_replace_callback(static::PATTERN, function($m) use ($rel) {
+ list($match, $type, $quote, $url) = $m;
+ if (strpos($url, 'data:') === 0 || strpos($url, '://') !== false)
+ return $match;
+ // PHP anonymous function binding fail
+ $rel_url = Casset_Cssurirewriterrelative::tidy_url("$rel$url");
+ return "$type($quote$rel_url$quote)";
+ }, $css);
+
+ return $css;
+ }
+
+ public static function tidy_url($url) {
+ // Get rid of /./ and something/../
+ $url = preg_replace('#(/|^)\./#', '\1', $url);
+
+ do {
+ $url = preg_replace('#(/|^)[^/\.]+/\.\./#', '\1', $url, -1, $changed);
+ } while ($changed);
+
+ return $url;
}
}

0 comments on commit f32af83

Please sign in to comment.