mirror of
https://github.com/mrclay/minify.git
synced 2025-08-11 16:44:44 +02:00
Refactoring CSS/Linearizer.php to Minify/ImportProcessor.php
This commit is contained in:
@@ -1,43 +1,47 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Class Minify_CSS_Linearizer
|
* Class Minify_ImportProcessor
|
||||||
* @package Minify
|
* @package Minify
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Linearize a CSS file
|
* Linearize a CSS/JS file by including content specified by CSS import
|
||||||
|
* declarations. In CSS files, relative URIs are fixed.
|
||||||
*
|
*
|
||||||
* @package Minify
|
* @package Minify
|
||||||
* @author Stephen Clay <steve@mrclay.org>
|
* @author Stephen Clay <steve@mrclay.org>
|
||||||
*/
|
*/
|
||||||
class Minify_CSS_Linearizer {
|
class Minify_ImportProcessor {
|
||||||
|
|
||||||
public static $filesIncluded = array();
|
public static $filesIncluded = array();
|
||||||
|
|
||||||
public static function linearize($file)
|
public static function linearize($file)
|
||||||
{
|
{
|
||||||
self::$filesIncluded = array();
|
self::$filesIncluded = array();
|
||||||
$obj = new Minify_CSS_Linearizer(dirname($file));
|
self::$_isCss = (strtolower(substr($file, -4)) === '.css');
|
||||||
return $obj->_getStyles($file);
|
$obj = new Minify_ImportProcessor(dirname($file));
|
||||||
|
return $obj->_getContent($file);
|
||||||
}
|
}
|
||||||
|
|
||||||
// allows callback funcs to know the current directory
|
// allows callback funcs to know the current directory
|
||||||
private $_currentDir = null;
|
private $_currentDir = null;
|
||||||
|
|
||||||
// allows _importCB to write the fetched content back to the obj
|
// allows _importCB to write the fetched content back to the obj
|
||||||
private $_importedCss = '';
|
private $_importedContent = '';
|
||||||
|
|
||||||
|
private static $_isCss = null;
|
||||||
|
|
||||||
private function __construct($currentDir)
|
private function __construct($currentDir)
|
||||||
{
|
{
|
||||||
$this->_currentDir = $currentDir;
|
$this->_currentDir = $currentDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function _getStyles($file)
|
private function _getContent($file)
|
||||||
{
|
{
|
||||||
$file = realpath($file);
|
$file = realpath($file);
|
||||||
if (! $file
|
if (! $file
|
||||||
|| in_array($file, self::$filesIncluded)
|
|| in_array($file, self::$filesIncluded)
|
||||||
|| false === ($css = @file_get_contents($file))
|
|| false === ($content = @file_get_contents($file))
|
||||||
) {
|
) {
|
||||||
// file missing, already included, or failed read
|
// file missing, already included, or failed read
|
||||||
return '';
|
return '';
|
||||||
@@ -46,19 +50,14 @@ class Minify_CSS_Linearizer {
|
|||||||
$this->_currentDir = dirname($file);
|
$this->_currentDir = dirname($file);
|
||||||
|
|
||||||
// remove UTF-8 BOM if present
|
// remove UTF-8 BOM if present
|
||||||
if (pack("CCC",0xef,0xbb,0xbf) === substr($css, 0, 3)) {
|
if (pack("CCC",0xef,0xbb,0xbf) === substr($content, 0, 3)) {
|
||||||
$css = substr($css, 3);
|
$content = substr($content, 3);
|
||||||
}
|
}
|
||||||
// ensure uniform EOLs
|
// ensure uniform EOLs
|
||||||
$css = str_replace("\r\n", "\n", $css);
|
$content = str_replace("\r\n", "\n", $content);
|
||||||
|
|
||||||
// make copy w/ comments removed
|
// process @imports
|
||||||
$copy = preg_replace('@/\\*.*?\\*/@', '', $css);
|
$content = preg_replace_callback(
|
||||||
|
|
||||||
// process remaining @imports (we work on copy because we don't want to
|
|
||||||
// pull in @imports that have been commented out). the replacement
|
|
||||||
// result is unimportant; we'd use "preg_match_callback" if it existed.
|
|
||||||
preg_replace_callback(
|
|
||||||
'/
|
'/
|
||||||
@import\\s+
|
@import\\s+
|
||||||
(?:url\\(\\s*)? # maybe url(
|
(?:url\\(\\s*)? # maybe url(
|
||||||
@@ -70,34 +69,19 @@ class Minify_CSS_Linearizer {
|
|||||||
; # end token
|
; # end token
|
||||||
/x'
|
/x'
|
||||||
,array($this, '_importCB')
|
,array($this, '_importCB')
|
||||||
,$copy
|
,$content
|
||||||
);
|
|
||||||
|
|
||||||
unset($copy); // copy served its purpose
|
|
||||||
|
|
||||||
// on original, strip all imports (we don't know which were successful
|
|
||||||
// and they aren't allowed to appear below the top anyway).
|
|
||||||
$css = preg_replace(
|
|
||||||
'/
|
|
||||||
@import\\s+
|
|
||||||
(?:url\\(\\s*)?[\'"]?
|
|
||||||
.*?
|
|
||||||
[\'"]?(?:\\s*\\))?
|
|
||||||
[a-zA-Z,\\s]*
|
|
||||||
;
|
|
||||||
/x'
|
|
||||||
,''
|
|
||||||
,$css
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (self::$_isCss) {
|
||||||
// rewrite remaining relative URIs
|
// rewrite remaining relative URIs
|
||||||
$css = preg_replace_callback(
|
$content = preg_replace_callback(
|
||||||
'/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
|
'/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
|
||||||
,array($this, '_urlCB')
|
,array($this, '_urlCB')
|
||||||
,$css
|
,$content
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->_importedCss . $css;
|
return $this->_importedContent . $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function _importCB($m)
|
private function _importCB($m)
|
||||||
@@ -106,8 +90,10 @@ class Minify_CSS_Linearizer {
|
|||||||
$mediaList = preg_replace('/\\s+/', '', $m[2]);
|
$mediaList = preg_replace('/\\s+/', '', $m[2]);
|
||||||
|
|
||||||
if (strpos($url, '://') > 0) {
|
if (strpos($url, '://') > 0) {
|
||||||
// protocol, external content will not be fetched
|
// protocol, leave in place for CSS, comment for JS
|
||||||
return '';
|
return self::$_isCss
|
||||||
|
? $m[0]
|
||||||
|
: "/* Minify_ImportProcessor will not include remote content */";
|
||||||
}
|
}
|
||||||
if ('/' === $url[0]) {
|
if ('/' === $url[0]) {
|
||||||
// protocol-relative or root path
|
// protocol-relative or root path
|
||||||
@@ -119,16 +105,17 @@ class Minify_CSS_Linearizer {
|
|||||||
$file = $this->_currentDir . DIRECTORY_SEPARATOR
|
$file = $this->_currentDir . DIRECTORY_SEPARATOR
|
||||||
. strtr($url, '/', DIRECTORY_SEPARATOR);
|
. strtr($url, '/', DIRECTORY_SEPARATOR);
|
||||||
}
|
}
|
||||||
$obj = new Minify_CSS_Linearizer(dirname($file));
|
$obj = new Minify_ImportProcessor(dirname($file));
|
||||||
$css = $obj->_getStyles($file);
|
$content = $obj->_getContent($file);
|
||||||
if ('' === $css) {
|
if ('' === $content) {
|
||||||
// failed
|
// failed. leave in place for CSS, comment for JS
|
||||||
return '';
|
return self::$_isCss
|
||||||
|
? $m[0]
|
||||||
|
: "/* Minify_ImportProcessor could not fetch '{$file}' */";;
|
||||||
}
|
}
|
||||||
$this->_importedCss .= preg_match('@(?:^$|\\ball\\b)@', $mediaList)
|
return (!self::$_isCss || preg_match('@(?:^$|\\ball\\b)@', $mediaList))
|
||||||
? $css
|
? $content
|
||||||
: "@media {$mediaList} {\n{$css}\n}\n";
|
: "@media {$mediaList} {\n{$content}\n}\n";
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function _urlCB($m)
|
private function _urlCB($m)
|
@@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
return; // being refactored
|
||||||
|
|
||||||
require_once '_inc.php';
|
require_once '_inc.php';
|
||||||
|
|
||||||
require_once 'Minify/CSS/Linearizer.php';
|
require_once 'Minify/CSS/Linearizer.php';
|
||||||
|
Reference in New Issue
Block a user