-
Notifications
You must be signed in to change notification settings - Fork 170
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
132 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,29 @@ | ||
<?php namespace October\Rain\Assetic\Filter; | ||
|
||
use October\Rain\Assetic\Filter\HashableInterface; | ||
use October\Rain\Assetic\Asset\AssetInterface; | ||
use October\Rain\Assetic\Asset\FileAsset; | ||
use October\Rain\Assetic\Asset\HttpAsset; | ||
use October\Rain\Assetic\Factory\AssetFactory; | ||
use October\Rain\Assetic\Util\CssUtils; | ||
|
||
/** | ||
* CssImportFilter inlines imported stylesheets. | ||
* CssImportFilter converts imported stylesheets to inline. | ||
* | ||
* @author Kris Wallsmith <[email protected]> | ||
*/ | ||
class CssImportFilter extends BaseCssFilter implements DependencyExtractorInterface | ||
class CssImportFilter extends BaseCssFilter implements HashableInterface, DependencyExtractorInterface | ||
{ | ||
/** | ||
* @var mixed importFilter | ||
*/ | ||
protected $importFilter; | ||
|
||
/** | ||
* @var string lastHash | ||
*/ | ||
protected $lastHash; | ||
|
||
/** | ||
* __construct | ||
* | ||
|
@@ -37,29 +44,29 @@ public function filterLoad(AssetInterface $asset) | |
$sourcePath = $asset->getSourcePath(); | ||
|
||
$callback = function ($matches) use ($importFilter, $sourceRoot, $sourcePath) { | ||
if (!$matches['url'] || null === $sourceRoot) { | ||
if (!$matches['url'] || $sourceRoot === null) { | ||
return $matches[0]; | ||
} | ||
|
||
$importRoot = $sourceRoot; | ||
|
||
if (false !== strpos($matches['url'], '://')) { | ||
// absolute | ||
// Absolute | ||
if (strpos($matches['url'], '://') !== false) { | ||
list($importScheme, $tmp) = explode('://', $matches['url'], 2); | ||
list($importHost, $importPath) = explode('/', $tmp, 2); | ||
$importRoot = $importScheme.'://'.$importHost; | ||
} | ||
elseif (0 === strpos($matches['url'], '//')) { | ||
// protocol-relative | ||
// Protocol-relative | ||
elseif (strpos($matches['url'], '//') === 0) { | ||
list($importHost, $importPath) = explode('/', substr($matches['url'], 2), 2); | ||
$importRoot = '//'.$importHost; | ||
} | ||
elseif ('/' == $matches['url'][0]) { | ||
// root-relative | ||
// Root-relative | ||
elseif ($matches['url'][0] == '/') { | ||
$importPath = substr($matches['url'], 1); | ||
} | ||
elseif (null !== $sourcePath) { | ||
// document-relative | ||
// Document-relative | ||
elseif ($sourcePath !== null) { | ||
$importPath = $matches['url']; | ||
if ('.' != $sourceDir = dirname($sourcePath)) { | ||
$importPath = $sourceDir.'/'.$importPath; | ||
|
@@ -70,15 +77,15 @@ public function filterLoad(AssetInterface $asset) | |
} | ||
|
||
$importSource = $importRoot.'/'.$importPath; | ||
if (false !== strpos($importSource, '://') || 0 === strpos($importSource, '//')) { | ||
$import = new HttpAsset($importSource, array($importFilter), true); | ||
if (strpos($importSource, '://') !== false || strpos($importSource, '//') === 0) { | ||
$import = new HttpAsset($importSource, [$importFilter], true); | ||
} | ||
elseif ('css' != pathinfo($importPath, PATHINFO_EXTENSION) || !file_exists($importSource)) { | ||
// ignore non-css and non-existant imports | ||
// Ignore non-css and non-existent imports | ||
elseif (pathinfo($importPath, PATHINFO_EXTENSION) != 'css' || !file_exists($importSource)) { | ||
return $matches[0]; | ||
} | ||
else { | ||
$import = new FileAsset($importSource, array($importFilter), $importRoot, $importPath); | ||
$import = new FileAsset($importSource, [$importFilter], $importRoot, $importPath); | ||
} | ||
|
||
$import->setTargetPath($sourcePath); | ||
|
@@ -92,7 +99,7 @@ public function filterLoad(AssetInterface $asset) | |
do { | ||
$content = $this->filterImports($content, $callback); | ||
$hash = md5($content); | ||
} while ($lastHash != $hash && $lastHash = $hash); | ||
} while ($lastHash != $hash && ($lastHash = $hash)); | ||
|
||
$asset->setContent($content); | ||
} | ||
|
@@ -105,11 +112,84 @@ public function filterDump(AssetInterface $asset) | |
} | ||
|
||
/** | ||
* getChildren | ||
* hashAsset | ||
*/ | ||
public function hashAsset($asset, $localPath) | ||
{ | ||
$factory = new AssetFactory($localPath); | ||
$children = $this->getAllChildren($factory, file_get_contents($asset), dirname($asset)); | ||
|
||
$allFiles = []; | ||
foreach ($children as $child) { | ||
$allFiles[] = $child; | ||
} | ||
|
||
$modified = []; | ||
foreach ($allFiles as $file) { | ||
$modified[] = $file->getLastModified(); | ||
} | ||
|
||
return md5(implode('|', $modified)); | ||
} | ||
|
||
/** | ||
* setHash | ||
*/ | ||
public function setHash($hash) | ||
{ | ||
$this->lastHash = $hash; | ||
} | ||
|
||
/** | ||
* hash generated for the object | ||
* @return string | ||
*/ | ||
public function hash() | ||
{ | ||
return $this->lastHash ?: serialize($this); | ||
} | ||
|
||
/** | ||
* getAllChildren loads all children recursively | ||
*/ | ||
public function getAllChildren(AssetFactory $factory, $content, $loadPath = null) | ||
{ | ||
$children = (new static)->getChildren($factory, $content, $loadPath); | ||
|
||
foreach ($children as $child) { | ||
$childContent = file_get_contents($child->getSourceRoot().'/'.$child->getSourcePath()); | ||
$children = array_merge($children, (new static)->getChildren($factory, $childContent, $loadPath.'/'.dirname($child->getSourcePath()))); | ||
} | ||
|
||
return $children; | ||
} | ||
|
||
/** | ||
* getChildren only returns one level of children | ||
*/ | ||
public function getChildren(AssetFactory $factory, $content, $loadPath = null) | ||
{ | ||
// todo | ||
return []; | ||
if (!$loadPath) { | ||
return []; | ||
} | ||
|
||
$children = []; | ||
foreach (CssUtils::extractImports($content) as $reference) { | ||
// Strict check, only allow .css imports | ||
if (substr($reference, -4) !== '.css') { | ||
continue; | ||
} | ||
|
||
if (file_exists($file = $loadPath.'/'.$reference)) { | ||
$coll = $factory->createAsset($file, [], ['root' => $loadPath]); | ||
foreach ($coll as $leaf) { | ||
$leaf->ensureFilter($this); | ||
$children[] = $leaf; | ||
break; | ||
} | ||
} | ||
} | ||
|
||
return $children; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters