public function getChildren(AssetFactory $factory, $content, $loadPath = null) { $children = array(); $includePaths = $this->includePaths; if (null !== $loadPath && !in_array($loadPath, $includePaths)) { array_unshift($includePaths, $loadPath); } if (empty($includePaths)) { return $children; } foreach (CssUtils::extractImports($content) as $reference) { if ('.css' === substr($reference, -4)) { continue; } // the reference may or may not have an extension or be a partial if (pathinfo($reference, PATHINFO_EXTENSION)) { $needles = array($reference, $this->partialize($reference)); } else { $needles = array($reference . '.scss', $this->partialize($reference) . '.scss'); } foreach ($includePaths as $includePath) { foreach ($needles as $needle) { if (file_exists($file = $includePath . '/' . $needle)) { $child = $factory->createAsset($file, array(), array('root' => $includePath)); $children[] = $child; $child->load(); $children = array_merge($children, $this->getChildren($factory, $child->getContent(), $includePath)); } } } } return $children; }
public function testFilterCommentless() { $content = 'A/*B*/C/*D*/E'; $filtered = ''; $result = CssUtils::filterCommentless($content, function ($part) use(&$filtered) { $filtered .= $part; return $part; }); $this->assertEquals('ACE', $filtered); $this->assertEquals($content, $result); }
public function rewrite() { $target = $this->target; return CssUtils::filterUrls($this->originalContent, function ($matches) use($target) { // root relative if (isset($matches['url'][0]) && '/' == $matches['url'][0]) { // ensure target is properly formatted $target = rtrim($target, '/'); // return the corrected content return str_replace($matches['url'], $target . $matches['url'], $matches[0]); } return $matches[0]; }); }
public function getChildren(AssetFactory $factory, $content, $loadPath = null) { $sc = new \scssc(); $sc->addImportPath($loadPath); foreach ($this->importPaths as $path) { $sc->addImportPath($path); } $children = array(); foreach (CssUtils::extractImports($content) as $match) { $file = $sc->findImport($match); if ($file) { $children[] = $child = $factory->createAsset($file, array(), array('root' => $loadPath)); $child->load(); $children = array_merge($children, $this->getChildren($factory, $child->getContent(), $loadPath)); } } return $children; }
public static function filterReferences($content, $callback) { return CssUtils::filterReferences($content, function ($matches) use($callback) { // The referenced path is a repository path // e.g. "/webmozart/puli/images/bg.png" $referencedPath = $matches['url']; // Ignore empty URLs if ('' === $referencedPath) { return $matches[0]; } // Ignore non-local paths if (!Path::isLocal($referencedPath)) { return $matches[0]; } // Ignore "data:" URLs if (0 === strpos($referencedPath, 'data:')) { return $matches[0]; } // If the referenced path is not absolute, resolve it relative to // the directory of the source file if (!Path::isAbsolute($referencedPath)) { $referencedPath = Path::makeAbsolute($referencedPath, $repoDir); } // The referenced asset must be known if (!array_key_exists($referencedPath, $pathMap)) { throw new AssetException(sprintf('The asset "%s" referenced in "%s" could not be found.', $matches['url'], $repoPath)); } // The target path of the referenced file must be set if (!$pathMap[$referencedPath]) { throw new AssetException(sprintf('The referenced path "%s" in "%s" cannot be resolved, because ' . 'the target path of "%s" is not set.', $matches['url'], $repoPath, $matches['url'])); } // The target path of the source file must be set if (!$targetPath) { throw new AssetException(sprintf('The referenced path "%s" in "%s" cannot be resolved, because ' . 'the target path of "%s" is not set.', $matches['url'], $repoPath, $repoPath)); } // Get the relative path from the source directory to the reference // e.g. "/css/style.css" + "/images/bg.png" = "../images/bg.png" $relativePath = Path::makeRelative($pathMap[$referencedPath], $targetDir); return str_replace($matches['url'], $relativePath, $matches[0]); }); }
public function getChildren(AssetFactory $factory, $content, $loadPath = null) { $loadPaths = $this->loadPaths; if ($loadPath) { array_unshift($loadPaths, $loadPath); } if (!$loadPaths) { return array(); } $children = array(); foreach (CssUtils::extractImports($content) as $reference) { if ('.css' === substr($reference, -4)) { // skip normal css imports // todo: skip imports with media queries continue; } // the reference may or may not have an extension or be a partial if (pathinfo($reference, PATHINFO_EXTENSION)) { $needles = array($reference, self::partialize($reference)); } else { $needles = array($reference . '.scss', $reference . '.sass', self::partialize($reference) . '.scss', self::partialize($reference) . '.sass'); } foreach ($loadPaths as $loadPath) { foreach ($needles as $needle) { if (file_exists($file = $loadPath . '/' . $needle)) { $coll = $factory->createAsset($file, array(), array('root' => $loadPath)); foreach ($coll as $leaf) { /** @var $leaf AssetInterface */ $leaf->ensureFilter($this); $children[] = $leaf; goto next_reference; } } } } next_reference: } return $children; }
/** * Filters an asset just before it's dumped. * * @param AssetInterface $asset An asset */ public function filterDump(AssetInterface $asset) { if (!$asset instanceof PuliAsset) { return; } $pathMap = array(); // Get a map of repository paths to target paths // e.g. "/webmozart/puli/images/bg.png" => "/images/bg.png" foreach ($this->am->getNames() as $name) { $this->extractTargetPaths($this->am->get($name), $pathMap); } // Remember the repository dir of the current resource $repoPath = $asset->getSourcePath(); $repoDir = Path::getDirectory($repoPath); // Get the target directory of the current resource // e.g. "css" $targetPath = $asset->getTargetPath(); $targetDir = Path::getDirectory($targetPath); // Convert to an absolute path so that we can create a proper // relative path later on // e.g. "/css" if (!Path::isAbsolute($targetDir)) { $targetDir = '/' . $targetDir; } $content = CssUtils::filterReferences($asset->getContent(), function ($matches) use($pathMap, $repoDir, $repoPath, $targetDir, $targetPath) { // The referenced path is a repository path // e.g. "/webmozart/puli/images/bg.png" $referencedPath = $matches['url']; // Ignore empty URLs if ('' === $referencedPath) { return $matches[0]; } // Ignore non-local paths if (!Path::isLocal($referencedPath)) { return $matches[0]; } // Ignore "data:" URLs if (0 === strpos($referencedPath, 'data:')) { return $matches[0]; } // If the referenced path is not absolute, resolve it relative to // the directory of the source file if (!Path::isAbsolute($referencedPath)) { $referencedPath = Path::makeAbsolute($referencedPath, $repoDir); } // The referenced asset must be known if (!array_key_exists($referencedPath, $pathMap)) { throw new AssetException(sprintf('The asset "%s" referenced in "%s" could not be found.', $referencedPath, $repoPath)); } // The target path of the referenced file must be set if (!$pathMap[$referencedPath]) { throw new AssetException(sprintf('The referenced path "%s" in "%s" cannot be resolved, because ' . 'the target path of "%s" is not set.', $matches['url'], $repoPath, $matches['url'])); } // The target path of the source file must be set if (!$targetPath) { throw new AssetException(sprintf('The referenced path "%s" in "%s" cannot be resolved, because ' . 'the target path of "%s" is not set.', $matches['url'], $repoPath, $repoPath)); } // Get the relative path from the source directory to the reference // e.g. "/css/style.css" + "/images/bg.png" = "../images/bg.png" $relativePath = Path::makeRelative($pathMap[$referencedPath], $targetDir); return str_replace($matches['url'], $relativePath, $matches[0]); }); $asset->setContent($content); }
/** * @see CssUtils::filterIEFilters() */ protected function filterIEFilters($content, $callback, $limit = -1, &$count = 0) { return CssUtils::filterIEFilters($content, $callback, $limit, $count); }
/** * Get advanced file info only for compiling collections * @return void */ public function fileAdvancedInfo() { $this->path = public_path() . '/' . app('config')->get('assets::public_dir') . '/' . $this->name; if (app('files')->exists($this->path)) { $this->fileName = basename($this->path); $this->extension = app('files')->extension($this->path); $this->modified = (int) @filemtime($this->path); $this->dirty = false; // Check for import statements $this->contents = $this->contents(); // Assets directory $assetDir = pathinfo($this->name, PATHINFO_DIRNAME); $item =& $this; // Prepare callback for imports $callback = function ($matches) use($assetDir, $item) { if (isset($matches[2]) and $import = $matches[2]) { $isRemote = (strpos($import, 'http://') === 0 or strpos($import, 'https://') === 0 or strpos($import, '//') === 0); if (!$isRemote) { $importPath = public_path() . '/' . app('config')->get('assets::public_path') . '/' . $assetDir . '/' . str_replace("\"", "", $import); $importModified = (int) @filemtime($importPath); // Check modified time if ($importModified > $item->modified) { $item->modified = $importModified; } // Get imported contents return app('files')->get($importPath); } elseif (isset($matches[0])) { return $matches[0]; } } }; // Test if ($this->type == 'css') { $this->contents = CssUtils::filterImports($this->contents, $callback); } // Update group modified time if ($this->modified > $this->collection->modified) { $this->collection->setModified($this->modified); } } }