1
0
mirror of https://github.com/mrclay/minify.git synced 2025-08-10 16:14:18 +02:00

CSS/Linearizer.php : URI rewriting + initial unit test

This commit is contained in:
Steve Clay
2008-08-28 03:16:33 +00:00
parent 41e937f143
commit 1cbcefa634
9 changed files with 134 additions and 14 deletions

View File

@@ -192,7 +192,7 @@ class Minify_CSS {
if ($rewrite) {
$css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/'
,array('Minify_CSS', '_urlCB'), $css);
$css = preg_replace_callback('/url\\(([^\\)]+)\\)/'
$css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
,array('Minify_CSS', '_urlCB'), $css);
}
self::$_tempPrepend = self::$_tempCurrentDir = '';

View File

@@ -30,19 +30,27 @@ class Minify_CSS_Linearizer {
private function _getStyles($file)
{
if (false === ($css = file_get_contents($file))) {
if (false === ($css = @file_get_contents($file))) {
return '';
}
self::$filesIncluded[] = $file;
$this->_currentDir = dirname($file);
// TODO: rewrite relative URIs (non-imports)
$css = preg_replace_callback(
'/
(?<!@import\\s)
url\\(\\s*([^\\)\\s]+)\\s*\\)
/x'
,array($this, '_urlCB')
,$css
);
// replace @imports with contents of files
$css = preg_replace_callback(
'/
@import\\s+
(?:url\\(\\s*)?(([\'"])?
(?:url\\(\\s*)?[\'"]?
(.*?) # 1 = URI
[\'"]?(?:\\s*\\))?
([a-zA-Z,\\s]*)? # 2 = media list
@@ -63,11 +71,10 @@ class Minify_CSS_Linearizer {
? ':'
: '';
if (strpos('://', $url) > 0) {
if (strpos($url, '://') > 0) {
// protocol, leave import in place
return $m[0];
}
if ('/' === $url[0]) {
// protocol-relative or root path
$url = ltrim($url, '/');
@@ -81,8 +88,36 @@ class Minify_CSS_Linearizer {
$obj = new Minify_CSS_Linearizer(dirname($file));
$css = $obj->_getStyles($file);
if ('' === $css) {
return $m[0];
}
return "@media {$mediaList} {\n{$css}\n}\n{$endToken}";
return "/* Minify_CSS_Linearizer : could not open '{$file}' */";
}
return preg_match('@(?:^$|\\ball\\b)@', $mediaList)
? "{$css}\n{$endToken}"
: "@media {$mediaList} {\n{$css}\n}\n{$endToken}";
}
private function _urlCB($m)
{
// $m[1] is either quoted or not
$quote = ($m[1][0] === "'" || $m[1][0] === '"')
? $m[1][0]
: '';
$url = ($quote === '')
? $m[1]
: substr($m[1], 1, strlen($m[1]) - 2);
if ('/' !== $url[0]) {
if (strpos($url, '//') > 0) {
// probably starts with protocol, do not alter
} else {
// prepend path with current dir separator (OS-independent)
$path = $this->_currentDir
. DIRECTORY_SEPARATOR . strtr($url, '/', DIRECTORY_SEPARATOR);
// strip doc root
$path = substr($path, strlen($_SERVER['DOCUMENT_ROOT']));
// fix to absolute URL
$url = strtr($path, DIRECTORY_SEPARATOR, '/');
$url = str_replace('/./', '/', $url);
}
}
return "url({$quote}{$url}{$quote})";
}
}

View File

@@ -22,10 +22,10 @@ h1 + p {
margin-top: 0;
}
@media all and (min-width: 640px) {
#media-queries-1 { background-color: #0f0; }
}
@media screen and (max-width: 2000px) {
#media-queries-2 { background-color: #0f0; }
@media all and (min-width: 640px) {
#media-queries-1 { background-color: #0f0; }
}
@media screen and (max-width: 2000px) {
#media-queries-2 { background-color: #0f0; }
}

View File

@@ -0,0 +1,2 @@
adjacent2 foo { background: red url(/red.gif); }
adjacent2 bar { background: url('../green.gif') }

View File

@@ -0,0 +1,3 @@
@import url( adjacent.css ) all;
tv foo { background: red url(/red.gif); }
tv bar { background: url('../green.gif') }

View File

@@ -0,0 +1,4 @@
@import url(../css/styles.css);
@import url(http://example.com/hello.css);
adjacent foo { background: red url(/red.gif); }
adjacent bar { background: url('../green.gif') }

View File

@@ -0,0 +1,4 @@
@import url( adjacent.css ) screen;
@import "1/tv.css" tv, projection;
input foo { background: red url(/red.gif); }
input bar { background: url('../green.gif') }

View File

@@ -0,0 +1,48 @@
@media screen {
/* some CSS to try to exercise things in general */
/* Minify_CSS_Linearizer : could not open 'M:/home/mrclayor/public_html\_3rd_party\minify\web\test\_test_files\cssLinearizer\..\css\more.css' */
body, td, th {
font-family: Verdana , "Bitstream Vera Sans" , sans-serif ;
font-size : 12px;
}
.nav {
margin-left: 20%;
}
#main-nav {
background-color: red;
border: 1px solid #00ff77;
}
div#content
h1 + p {
padding-top: 0;
margin-top: 0;
}
@media all and (min-width: 640px) {
#media-queries-1 { background-color: #0f0; }
}
@media screen and (max-width: 2000px) {
#media-queries-2 { background-color: #0f0; }
}
@import url(http://example.com/hello.css);
adjacent foo { background: red url(/red.gif); }
adjacent bar { background: url('/_3rd_party/minify/web/test/_test_files/cssLinearizer/../green.gif') }
}
@media tv,projection {
adjacent2 foo { background: red url(/red.gif); }
adjacent2 bar { background: url('/_3rd_party/minify/web/test/_test_files/cssLinearizer/1/../green.gif') }
tv foo { background: red url(/red.gif); }
tv bar { background: url('/_3rd_party/minify/web/test/_test_files/cssLinearizer/1/../green.gif') }
}
input foo { background: red url(/red.gif); }
input bar { background: url('/_3rd_party/minify/web/test/_test_files/cssLinearizer/../green.gif') }

View File

@@ -0,0 +1,24 @@
<?php
require_once '_inc.php';
require_once 'Minify/CSS/Linearizer.php';
function test_Minify_CSS_Linearizer()
{
global $thisDir;
$expected = file_get_contents($thisDir . '/_test_files/cssLinearizer/output.css');
$actual = Minify_CSS_Linearizer::linearize($thisDir . '/_test_files/cssLinearizer/input.css');
$passed = assertTrue($expected === $actual, 'Minify_CSS_Linearizer');
if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) {
echo "\n---Output: " .strlen($actual). " bytes\n\n{$actual}\n\n";
if (!$passed) {
echo "---Expected: " .strlen($expected). " bytes\n\n{$expected}\n\n\n";
}
}
}
test_Minify_CSS_Linearizer();