/** * Converts the ruleset to CSS. Applies the output filters to the output. * * @param ILess_Node_Ruleset $ruleset * @param array $variables * @return string The generated CSS code */ protected function toCSS(ILess_Node_Ruleset $ruleset, array $variables) { // the cache key consists of: // 1) parsed rules // 2) assigned variables via the API // 3) environment options $cacheKey = $this->generateCacheKey(serialize($this->rules) . serialize($variables) . serialize(array($this->env->compress, $this->env->sourceMap, $this->env->sourceMapOptions, $this->env->relativeUrls, $this->env->precision, $this->env->debug, $this->env->dumpLineNumbers, $this->env->canShortenColors, $this->env->ieCompat, $this->env->strictMath, $this->env->strictUnits))); $rebuild = true; if ($this->cache->has($cacheKey)) { $rebuild = false; list($css, $importedFiles) = $this->cache->get($cacheKey); // we need to check if the file has been modified foreach ($importedFiles as $importedFileArray) { list($lastModifiedBefore, $path, $currentFileInfo) = $importedFileArray; $lastModified = $this->importer->getLastModified($path, $currentFileInfo); if ($lastModifiedBefore != $lastModified) { $rebuild = true; // no need to continue, we will rebuild the CSS break; } } } if ($rebuild) { $css = parent::toCSS($ruleset, $variables); // what have been imported? $importedFiles = array(); foreach ($this->importer->getImportedFiles() as $importedFile) { // we need to save original path, last modified timestamp and currentFileInfo object // see ILess_Importer::setImportedFile() $importedFiles[] = array($importedFile[0]->getLastModified(), $importedFile[1], $importedFile[2]); } $this->cache->set($cacheKey, array($css, $importedFiles)); } return $this->filter($css); }
/** * Does the import * * @param ILess_ImportedFile $file The imported file * @param string $path The original path * @param ILess_FileInfo $currentFileInfo Current file info * @param array $importOptions Import options * @param boolean $fromCache Is the imported file coming from cache? * @return array */ protected function doImport(ILess_ImportedFile $file, $path, ILess_FileInfo $currentFileInfo, array $importOptions = array(), $fromCache = false) { $newEnv = ILess_Environment::createCopy($this->env, $this->env->frames); $newFileInfo = clone $currentFileInfo; if ($this->env->relativeUrls) { // Pass on an updated rootPath if path of imported file is relative and file // is in a (sub|sup) directory // // Examples: // - If path of imported file is 'module/nav/nav.less' and rootPath is 'less/', // then rootPath should become 'less/module/nav/' // - If path of imported file is '../mixins.less' and rootPath is 'less/', // then rootPath should become 'less/../' if (!ILess_Util::isPathAbsolute($path) && ($lastSlash = strrpos($path, '/')) !== false) { $relativeSubDirectory = substr($path, 0, $lastSlash + 1); $newFileInfo->rootPath = $newFileInfo->rootPath . $relativeSubDirectory; } } // we need to clone here, to prevent modification of node current info object $newEnv->currentFileInfo = $newFileInfo; $newEnv->processImports = false; if ($currentFileInfo->reference || isset($importOptions['reference']) && $importOptions['reference']) { $newEnv->currentFileInfo->reference = true; } $key = $file->getPath(); $error = $root = null; $alreadyImported = false; // check for already imported file if (isset($this->importedFiles[$key])) { $alreadyImported = true; } elseif (!$file->getRuleset()) { $parser = new ILess_Parser_Core($newEnv, $this); try { // we do not parse the root but load the file as is if (isset($importOptions['inline']) && $importOptions['inline']) { $root = $file->getContent(); } else { $root = $parser->parseFile($file, true); $root->root = false; $root->firstRoot = false; } $file->setRuleset($root); // we need to catch parse exceptions } catch (ILess_Exception_Parser $e) { // rethrow throw $e; } catch (Exception $error) { // FIXME: what other exceptions are allowed here? $file->setError($error); } $this->setImportedFile($key, $file, $path, $currentFileInfo); } else { $this->setImportedFile($key, $file, $path, $currentFileInfo); } if ($fromCache) { $ruleset = $this->importedFiles[$key][0]->getRuleset(); if ($ruleset instanceof ILess_Node) { // FIXME: this is a workaround for reference and import one issues // when taken cache $this->updateReferenceInCurrentFileInfo($ruleset, $newEnv->currentFileInfo->reference); } } return array($alreadyImported, $this->importedFiles[$key][0]); }
public function testParseMedia($string) { $this->setStringToBeParsed($string); return parent::parseMedia(); }