/** * minify css and return css link * if minify is disabled: return direct css links * * @return string with html tag * @param array $stylesheets with css files */ public function minifycss($stylesheets) { if (Zend_Registry::get('config')->cache->enable == 1 && Zend_Registry::get('config')->cache->minifycss == 1) { // check file $target = Zend_Registry::get('config')->pub->path . 'stylesheets/' . Zend_Registry::get('config')->cache->minifiedcssfile; $targeturl = 'stylesheets/' . Zend_Registry::get('config')->cache->minifiedcssfile; if (file_exists($target)) { return "<link rel=\"stylesheet\" media=\"screen, handheld, projection, tv\" href=\"" . $targeturl . "\" />\n"; } // load and minify files $all = ""; foreach ($stylesheets as $css) { $csscontent = file_get_contents(Zend_Registry::get('config')->pub->path . $css); $csscontent = CssMin::minify($csscontent); $all .= $csscontent; } file_put_contents($target, $all); return "<link rel=\"stylesheet\" media=\"screen, handheld, projection, tv\" href=\"" . $targeturl . "\" />\n"; } else { $ret = ""; foreach ($stylesheets as $css) { $ret = $ret . "<link rel=\"stylesheet\" media=\"screen, handheld, projection, tv\" href=\"" . $css . "\" />\n"; } return $ret; } }
/** * */ public function load($resource, $type = null) { $publishPath = $this->pathHelper->joinPaths($this->assetDirectory, $resource); $tmpPath = $this->pathHelper->joinPaths(sys_get_temp_dir(), $resource); $fs = $this->getFilesystem(); if ($this->debugMode) { $fs->dumpFile($tmpPath, "/* --- composition: {$resource} ---*/"); } $tmpFile = fopen($tmpPath, "a"); foreach ($this->compositions[$resource] as $asset) { $path = $this->locator->locate($asset); switch ($type) { case 'css': if (preg_match('/\\.min\\.css/', $asset)) { $content = file_get_contents($path); } else { $content = \CssMin::minify(file_get_contents($path)); } break; default: $content = file_get_contents($path); } if ($this->debugMode) { fwrite($tmpFile, "\n\n/* --- asset: {$asset} ({$path}) ---*/\n\n" . $content); } } fclose($tmpFile); if ($this->publishMode && $resource !== null) { $fs->copy($tmpPath, $publishPath); } return $tmpPath; }
/** * Implements {@link aCssParserPlugin::parse()}. * * @param integer $index Current index * @param string $char Current char * @param string $previousChar Previous char * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing */ public function parse($index, $char, $previousChar, $state) { if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 7)) === "@import") { $this->parser->pushState("T_AT_IMPORT"); $this->parser->clearBuffer(); return $index + 7; } elseif (($char === ";" || $char === "\n") && $state === "T_AT_IMPORT") { $this->buffer = $this->parser->getAndClearBuffer(";"); $pos = false; foreach (array(")", "\"", "'") as $needle) { if (($pos = strrpos($this->buffer, $needle)) !== false) { break; } } $import = substr($this->buffer, 0, $pos + 1); if (stripos($import, "url(") === 0) { $import = substr($import, 4, -1); } $import = trim($import, " \t\n\r\v'\""); $mediaTypes = array_filter(array_map("trim", explode(",", trim(substr($this->buffer, $pos + 1), " \t\n\r\v{")))); if ($pos) { $this->parser->appendToken(new CssAtImportToken($import, $mediaTypes)); } else { CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Invalid @import at-rule syntax", $this->parser->buffer)); } $this->parser->popState(); } else { return false; } return true; }
public function __invoke($file, $minify = null) { if (!is_file($this->getOptions()->getPublicDir() . $file)) { throw new \InvalidArgumentException('File "' . $this->getOptions()->getPublicDir() . $file . '" not found.'); } $less = new \lessc(); $info = pathinfo($file); $newFile = $this->getOptions()->getDestinationDir() . $info['filename'] . '.' . filemtime($this->getOptions()->getPublicDir() . $file) . '.css'; $_file = $this->getOptions()->getPublicDir() . $newFile; if (!is_file($_file)) { $globPattern = $this->getOptions()->getPublicDir() . $this->getOptions()->getDestinationDir() . $info['filename'] . '.*.css'; foreach (Glob::glob($globPattern, Glob::GLOB_BRACE) as $match) { if (preg_match("/^" . $info['filename'] . "\\.[0-9]{10}\\.css\$/", basename($match))) { unlink($match); } } $compiledFile = new \SplFileObject($_file, 'w'); $result = $less->compileFile($this->getOptions()->getPublicDir() . $file); if (is_null($minify) && $this->getOptions()->getMinify() || $minify === true) { $result = \CssMin::minify($result); } $compiledFile->fwrite($result); } return $newFile; }
function prepare($source, $min = true) { if ($min) { $source = \CssMin::minify($source); } return trim($source); }
/** * */ public function load($resource, $type = null) { $publishPath = $this->pathHelper->joinPaths($this->assetDirectory, $resource); $tmpPath = $this->pathHelper->joinPaths(sys_get_temp_dir(), $resource); $path = $this->locator->locate($resource); $fs = $this->getFilesystem(); $fs->dumpFile($tmpPath, null); switch ($type) { case 'css': // minify only if it isnt already minified if (preg_match('/\\.min\\.css/', $resource)) { $content = file_get_contents($path); } else { $content = \CssMin::minify(file_get_contents($path)); } break; default: $content = file_get_contents($path); } file_put_contents($tmpPath, $content); if ($this->publishMode && $resource !== null) { $fs->copy($tmpPath, $publishPath); } return $tmpPath; }
/** * Apply CssMin to $content. * * @param string $filename target filename * @param string $content Content to filter. * @throws Exception * @return string */ public function output($filename, $content) { App::import('Vendor', 'cssmin', array('file' => $this->_settings['path'])); if (!class_exists('CssMin')) { throw new Exception(sprintf('Cannot not load filter class "%s".', 'CssMin')); } return CssMin::minify($content); }
/** * Constructer. * * Creates instances of {@link aCssMinifierFilter filters} and {@link aCssMinifierPlugin plugins}. * * @param string $source CSS source [optional] * @param array $filters Filter configuration [optional] * @param array $plugins Plugin configuration [optional] * @return void */ public function __construct($source = null, array $filters = null, array $plugins = null) { $filters = array_merge(array("ImportImports" => false, "RemoveComments" => true, "RemoveEmptyRulesets" => true, "RemoveEmptyAtBlocks" => true, "ConvertLevel3Properties" => false, "ConvertLevel3AtKeyframes" => false, "Variables" => true, "RemoveLastDelarationSemiColon" => true), is_array($filters) ? $filters : array()); $plugins = array_merge(array("Variables" => true, "ConvertFontWeight" => false, "ConvertHslColors" => false, "ConvertRgbColors" => false, "ConvertNamedColors" => false, "CompressColorValues" => false, "CompressUnitValues" => false, "CompressExpressionValues" => false), is_array($plugins) ? $plugins : array()); // Filters foreach ($filters as $name => $config) { if ($config !== false) { $class = "Css" . $name . "MinifierFilter"; $config = is_array($config) ? $config : array(); if (class_exists($class)) { $this->filters[] = new $class($this, $config); } else { CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The filter <code>" . $name . "</code> with the class name <code>" . $class . "</code> was not found")); } } } // Plugins foreach ($plugins as $name => $config) { if ($config !== false) { $class = "Css" . $name . "MinifierPlugin"; $config = is_array($config) ? $config : array(); if (class_exists($class)) { $this->plugins[] = new $class($this, $config); } else { CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The plugin <code>" . $name . "</code> with the class name <code>" . $class . "</code> was not found")); } } } // -- if (!is_null($source)) { $this->minify($source); } }
public static function minifyCss($cssList, $concat = false) { $websiteHelper = Zend_Controller_Action_HelperBroker::getExistingHelper('website'); $cacheHelper = Zend_Controller_Action_HelperBroker::getExistingHelper('cache'); if (null === ($hashStack = $cacheHelper->load(strtolower(__CLASS__), ''))) { $hashStack = array(); } $container = $cssList->getContainer(); foreach ($container->getArrayCopy() as $css) { if (preg_match('/^https?:\\/\\//', $css->href) != false && strpos($css->href, $websiteHelper->getUrl()) !== 0) { continue; } $path = str_replace($websiteHelper->getUrl(), '', $css->href); if (!is_file($websiteHelper->getPath() . $path) || !file_exists($websiteHelper->getPath() . $path)) { continue; } $hash = sha1_file($websiteHelper->getPath() . $path); $name = Tools_Filesystem_Tools::basename($path); if (!$hash) { continue; } if (!isset($hashStack[$path]) || $hashStack[$path]['hash'] !== $hash) { $compressor = new CssMin(); $cssContent = Tools_Filesystem_Tools::getFile($path); $cssContent = preg_replace('/url\\([\'"]?([^)\'"]*)[\'"]?\\)/', 'url("../' . dirname($path) . DIRECTORY_SEPARATOR . '${1}")', $cssContent); $hashStack[$path] = array('hash' => $hash, 'content' => $compressor->run($cssContent)); Tools_Filesystem_Tools::saveFile($websiteHelper->getPath() . $websiteHelper->getTmp() . $hash . '.css', $hashStack[$path]['content']); unset($cssContent); } if (!$concat) { $css->href = $websiteHelper->getUrl() . $websiteHelper->getTmp() . $hash . '.css?' . $name; } else { $concatCss = isset($concatCss) ? $concatCss . PHP_EOL . "/* {$path} */" . PHP_EOL . $hashStack[$path]['content'] : "/* {$path} */" . PHP_EOL . $hashStack[$path]['content']; } } if (isset($concatCss) && !empty($concatCss)) { $cname = sha1($concatCss) . '.concat.min.css'; $concatPath = $websiteHelper->getPath() . $websiteHelper->getTmp() . $cname; if (!file_exists($concatPath) || sha1_file($concatPath) !== sha1($concatCss)) { Tools_Filesystem_Tools::saveFile($concatPath, $concatCss); } $cssList->setStylesheet($websiteHelper->getUrl() . $websiteHelper->getTmp() . $cname); } $cacheHelper->save(strtolower(__CLASS__), $hashStack, '', array(), Helpers_Action_Cache::CACHE_LONG); return $cssList; }
/** */ public function apply($in, $params = []) { require_php_lib('cssmin'); if (!class_exists('\\CssMin')) { throw new Exception('Assets: class \\CssMin not found'); return $in; } return \CssMin::minify($in); }
/** * New resource file update handler. * * @param string $resource Resource full path * @param string $extension Resource extension * @param string $content Compiled output resource content */ public function renderer($resource, &$extension, &$content) { // If CSS resource has been updated if ($extension === 'css') { // Read updated CSS resource file and compile it $content = \CssMin::minify($content); } elseif ($extension === 'js') { $content = \JShrink\Minifier::minify($content); } }
/** * Implements {@link aCssParserPlugin::parse()}. * * @param integer $index Current index * @param string $char Current char * @param string $previousChar Previous char * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing */ public function parse($index, $char, $previousChar, $state) { // Start of Ruleset and selectors if ($char === "," && ($state === "T_DOCUMENT" || $state === "T_AT_MEDIA" || $state === "T_RULESET::SELECTORS")) { if ($state !== "T_RULESET::SELECTORS") { $this->parser->pushState("T_RULESET::SELECTORS"); } $this->selectors[] = $this->parser->getAndClearBuffer(",{"); } elseif ($char === "{" && ($state === "T_DOCUMENT" || $state === "T_AT_MEDIA" || $state === "T_RULESET::SELECTORS")) { if ($this->parser->getBuffer() !== "") { $this->selectors[] = $this->parser->getAndClearBuffer(",{"); if ($state == "T_RULESET::SELECTORS") { $this->parser->popState(); } $this->parser->pushState("T_RULESET"); $this->parser->appendToken(new CssRulesetStartToken($this->selectors)); $this->selectors = array(); } } elseif ($char === ":" && $state === "T_RULESET") { $this->parser->pushState("T_RULESET_DECLARATION"); $this->buffer = $this->parser->getAndClearBuffer(":;", true); } elseif ($char === ":" && $state === "T_RULESET_DECLARATION") { // Ignore Internet Explorer filter declarations if ($this->buffer === "filter") { return false; } CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_")); } elseif (($char === ";" || $char === "}") && $state === "T_RULESET_DECLARATION") { $value = $this->parser->getAndClearBuffer(";}"); if (strtolower(substr($value, -10, 10)) === "!important") { $value = trim(substr($value, 0, -10)); $isImportant = true; } else { $isImportant = false; } $this->parser->popState(); $this->parser->appendToken(new CssRulesetDeclarationToken($this->buffer, $value, $this->parser->getMediaTypes(), $isImportant)); // Declaration ends with a right curly brace; so we have to end the ruleset if ($char === "}") { $this->parser->appendToken(new CssRulesetEndToken()); $this->parser->popState(); } $this->buffer = ""; } elseif ($char === "}" && $state === "T_RULESET") { $this->parser->popState(); $this->parser->clearBuffer(); $this->parser->appendToken(new CssRulesetEndToken()); $this->buffer = ""; $this->selectors = array(); } else { return false; } return true; }
public function init($cssData) { $this->parsedCSS = CssMin::parse($cssData, $plugins); $this->countSelectors(); if ($this->selCount > $this->conf['css.']['scriptmergerBless.']['threshold'] && isset($this->conf['css.']['scriptmergerBless.']['activate']) && $this->conf['css.']['scriptmergerBless.']['activate'] == 1) { $this->split(); } else { $this->cssFiles[] = $cssData; } return array_reverse($this->cssFiles); }
/** * Implements {@link aCssMinifierFilter::filter()}. * * @param array $tokens Array of objects of type aCssToken * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array */ public function apply(array &$tokens) { $variables = array(); $defaultMediaTypes = array("all"); $mediaTypes = array(); $remove = array(); for ($i = 0, $l = count($tokens); $i < $l; $i++) { // @variables at-rule block found if (get_class($tokens[$i]) === "CssAtVariablesStartToken") { $remove[] = $i; $mediaTypes = count($tokens[$i]->MediaTypes) == 0 ? $defaultMediaTypes : $tokens[$i]->MediaTypes; foreach ($mediaTypes as $mediaType) { if (!isset($variables[$mediaType])) { $variables[$mediaType] = array(); } } // Read the variable declaration tokens for ($i = $i; $i < $l; $i++) { // Found a variable declaration => read the variable values if (get_class($tokens[$i]) === "CssAtVariablesDeclarationToken") { foreach ($mediaTypes as $mediaType) { $variables[$mediaType][$tokens[$i]->Property] = $tokens[$i]->Value; } $remove[] = $i; } elseif (get_class($tokens[$i]) === "CssAtVariablesEndToken") { $remove[] = $i; break; } } } } // Variables in @variables at-rule blocks foreach ($variables as $mediaType => $null) { foreach ($variables[$mediaType] as $variable => $value) { // If a var() statement in a variable value found... if (stripos($value, "var") !== false && preg_match_all("/var\\((.+)\\)/iSU", $value, $m)) { // ... then replace the var() statement with the variable values. for ($i = 0, $l = count($m[0]); $i < $l; $i++) { $variables[$mediaType][$variable] = str_replace($m[0][$i], isset($variables[$mediaType][$m[1][$i]]) ? $variables[$mediaType][$m[1][$i]] : "", $variables[$mediaType][$variable]); } } } } // Remove the complete @variables at-rule block foreach ($remove as $i) { $tokens[$i] = null; } if (!($plugin = $this->minifier->getPlugin("CssVariablesMinifierPlugin"))) { CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The plugin <code>CssVariablesMinifierPlugin</code> was not found but is required for <code>" . __CLASS__ . "</code>")); } else { $plugin->setVariables($variables); } return count($remove); }
public function filterDump(AssetInterface $asset) { $filters = $this->filters; $plugins = $this->plugins; if (isset($filters['ImportImports']) && true === $filters['ImportImports']) { if ($dir = $asset->getSourceDirectory()) { $filters['ImportImports'] = array('BasePath' => $dir); } else { unset($filters['ImportImports']); } } $asset->setContent(\CssMin::minify($asset->getContent(), $filters, $plugins)); }
/** * Get a file's content, minified. * @param string $path The file path. * @return string The file's content, minified. */ public function executeGetMinified($path) { $manager = $this->managers()->getManagerOf('file'); if (!$manager->exists($path)) { throw new \RuntimeException('"' . $path . '" : no such file or directory', 404); } $out = $manager->read($path); if ($manager->extension($manager->filename($path)) != 'min' && false) { $ext = $manager->extension($path); switch ($ext) { case 'js': $out = \JSMinPlus::minify($out); break; case 'css': $minifier = new \CssMin(); $out = $minifier->minify($out); break; default: throw new \RuntimeException('Cannot minify "' . $path . '" : unsupported file type', 406); } } $this->responseContent->setChannel(1, $out); }
public function packer($file, $type) { if (!file_exists($file)) { return; } $fileDst = preg_replace('/\\.(js|css)$/', '.min.\\1', $file); if ($type == "js") { $minContent = JSMin::minify(file_get_contents($file)); } else { $minContent = CssMin::minify(file_get_contents($file)); } echo "[01;41m " . $file . " [0m -> [32;40m" . $fileDst . "[0m\n"; file_put_contents($fileDst, $minContent); echo shell_exec("git add " . $fileDst); }
public function filterDump(AssetInterface $asset) { $filters = $this->filters; $plugins = $this->plugins; if (isset($filters['ImportImports']) && true === $filters['ImportImports']) { $root = $asset->getSourceRoot(); $path = $asset->getSourcePath(); if ($root && $path) { $filters['ImportImports'] = array('BasePath' => dirname($root . '/' . $path)); } else { unset($filters['ImportImports']); } } $asset->setContent(\CssMin::minify($asset->getContent(), $filters, $plugins)); }
protected function createComponentCss() { $cssLoader = new \WebLoader\CssLoader(null, null, true); $cssLoader->sourcePath = __DIR__ . "/css"; $cssLoader->tempUri = $this->tempUri; $cssLoader->tempPath = $this->tempPath; foreach ($this->css as $css) { $cssLoader->addFile($css); } $cssLoader->filter(); $cssLoader->filters[] = function ($code) { return \CssMin::minify($code); }; return $cssLoader; }
/** * Implements {@link aCssParserPlugin::parse()}. * * @param integer $index Current index * @param string $char Current char * @param string $previousChar Previous char * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing */ public function parse($index, $char, $previousChar, $state) { // Start of @page at-rule block if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 5)) === "@page") { $this->parser->pushState("T_AT_PAGE::SELECTOR"); $this->parser->clearBuffer(); return $index + 5; } elseif ($char === "{" && $state === "T_AT_PAGE::SELECTOR") { $selector = $this->parser->getAndClearBuffer("{"); $this->parser->setState("T_AT_PAGE"); $this->parser->clearBuffer(); $this->parser->appendToken(new CssAtPageStartToken($selector)); } elseif ($char === ":" && $state === "T_AT_PAGE") { $this->parser->pushState("T_AT_PAGE_DECLARATION"); $this->buffer = $this->parser->getAndClearBuffer(":", true); } elseif ($char === ":" && $state === "T_AT_PAGE_DECLARATION") { // Ignore Internet Explorer filter declarations if ($this->buffer === "filter") { return false; } CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated @page declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_")); } elseif (($char === ";" || $char === "}") && $state == "T_AT_PAGE_DECLARATION") { $value = $this->parser->getAndClearBuffer(";}"); if (strtolower(substr($value, -10, 10)) == "!important") { $value = trim(substr($value, 0, -10)); $isImportant = true; } else { $isImportant = false; } $this->parser->popState(); $this->parser->appendToken(new CssAtPageDeclarationToken($this->buffer, $value, $isImportant)); // -- if ($char === "}") { $this->parser->popState(); $this->parser->appendToken(new CssAtPageEndToken()); } $this->buffer = ""; } elseif ($char === "}" && $state === "T_AT_PAGE") { $this->parser->popState(); $this->parser->clearBuffer(); $this->parser->appendToken(new CssAtPageEndToken()); } else { return false; } return true; }
public function filterDump(AssetInterface $asset) { $filters = $this->filters; $plugins = $this->plugins; if (isset($filters['ImportImports']) && true === $filters['ImportImports']) { // find the base path $sourceUrl = $asset->getSourceUrl(); if (self::isAbsoluteUrl($sourceUrl) || self::isAbsolutePath($sourceUrl)) { $filters['ImportImports'] = array('BasePath' => dirname($sourceUrl)); } elseif ($this->baseDir) { $filters['ImportImports'] = array('BasePath' => $this->baseDir); if ('.' != ($dir = dirname($sourceUrl))) { $filters['ImportImports']['BasePath'] .= '/' . $dir; } } } $asset->setContent(\CssMin::minify($asset->getContent(), $filters, $plugins)); }
/** * Constructer. * * Create instances of the used {@link aCssParserPlugin plugins}. * * @param string $source CSS source [optional] * @param array $plugins Plugin configuration [optional] * @return void */ public function __construct($source = null, array $plugins = null) { $plugins = array_merge(array("Comment" => true, "String" => true, "Url" => true, "Expression" => true, "Ruleset" => true, "AtCharset" => true, "AtFontFace" => true, "AtImport" => true, "AtKeyframes" => true, "AtMedia" => true, "AtPage" => true, "AtVariables" => true), is_array($plugins) ? $plugins : array()); // Create plugin instances foreach ($plugins as $name => $config) { if ($config !== false) { $class = "Css" . $name . "ParserPlugin"; $config = is_array($config) ? $config : array(); if (class_exists($class)) { $this->plugins[] = new $class($this, $config); } else { CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The plugin <code>" . $name . "</code> with the class name <code>" . $class . "</code> was not found")); } } } if (!is_null($source)) { $this->parse($source); } }
public function renderCss($critical = false, $type = null, $isMobile = false) { if ($critical) { $this->renderCssCritical($type, $isMobile); } else { $config = $this->getPresenter()->context->parameters['scriptLoader']['css' . ($isMobile ? '_mobile' : '')]; if (!$this->getPresenter()->context->parameters['scriptLoader']['enable']) { if (!is_null($config['default'])) { foreach ($config['default'] as $css) { echo '<link rel="stylesheet" media="screen,projection,tv" href="/' . $css . '">'; } } } else { $cache = new Cache($this->getPresenter()->storage, 'scriptLoader'); if (is_null($cache->load('css' . ($isMobile ? '_mobile' : '')))) { //zminimalizuju $cssFile = ''; $cssFiles = array(); if (!is_null($config['default'])) { foreach ($config['default'] as $css) { $cssFile .= \CssMin::minify(file_get_contents($this->getPresenter()->context->parameters['wwwDir'] . '/' . $css)); $cssFiles[] = $this->getPresenter()->context->parameters['wwwDir'] . '/' . $css; } } $cache->save('css' . ($isMobile ? '_mobile' : ''), true, array(Cache::FILES => $cssFiles)); file_put_contents($this->getPresenter()->context->parameters['wwwDir'] . '/css/css.css', $cssFile); } echo '<script> var cb = function() { var l = document.createElement(\'link\'); l.rel = \'stylesheet\'; l.href = \'/css/css.css\'; var h = document.getElementsByTagName(\'head\')[0]; h.parentNode.insertBefore(l, h); }; var raf = requestAnimationFrame || mozRequestAnimationFrame || webkitRequestAnimationFrame || msRequestAnimationFrame; if (raf) raf(cb); else window.addEventListener(\'load\', cb); </script>'; //echo '<link rel="stylesheet" media="screen,projection,tv" href="/css/css.css">'; } } }
/** * Implements {@link aCssParserPlugin::parse()}. * * @param integer $index Current index * @param string $char Current char * @param string $previousChar Previous char * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing */ public function parse($index, $char, $previousChar, $state) { // Start of @variables at-rule block if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 10)) === "@variables") { $this->parser->pushState("T_AT_VARIABLES::PREPARE"); $this->parser->clearBuffer(); return $index + 10; } elseif ($char === "{" && $state === "T_AT_VARIABLES::PREPARE") { $this->parser->setState("T_AT_VARIABLES"); $mediaTypes = array_filter(array_map("trim", explode(",", $this->parser->getAndClearBuffer("{")))); $this->parser->appendToken(new CssAtVariablesStartToken($mediaTypes)); } // Start of @variables declaration if ($char === ":" && $state === "T_AT_VARIABLES") { $this->buffer = $this->parser->getAndClearBuffer(":"); $this->parser->pushState("T_AT_VARIABLES_DECLARATION"); } elseif ($char === ":" && $state === "T_AT_VARIABLES_DECLARATION") { // Ignore Internet Explorer filter declarations if ($this->buffer === "filter") { return false; } CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated @variables declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_")); } elseif (($char === ";" || $char === "}") && $state === "T_AT_VARIABLES_DECLARATION") { $value = $this->parser->getAndClearBuffer(";}"); if (strtolower(substr($value, -10, 10)) === "!important") { $value = trim(substr($value, 0, -10)); $isImportant = true; } else { $isImportant = false; } $this->parser->popState(); $this->parser->appendToken(new CssAtVariablesDeclarationToken($this->buffer, $value, $isImportant)); $this->buffer = ""; } elseif ($char === "}" && $state === "T_AT_VARIABLES") { $this->parser->popState(); $this->parser->clearBuffer(); $this->parser->appendToken(new CssAtVariablesEndToken()); } else { return false; } return true; }
public function compileLessFile( $less_file = '', $css_file = '', $css_min_file = '' ){ global $wp_filesystem; if( empty( $less_file ) ) $less_file = dirname( __FILE__ ) . '/assets/css/style.less'; if( empty( $css_file ) ) $css_file = dirname( __FILE__ ) . '/assets/css/style.css'; if( empty( $css_min_file ) ) $css_min_file = dirname( __FILE__ ) . '/assets/css/style.min.css'; // Write less file if ( is_writable( $css_file ) && is_writable( $css_min_file ) ) { if ( ! class_exists( 'lessc' ) ){ include( dirname( __FILE__ ) . '/lib/lessc.inc.php' ); } if ( ! class_exists( 'cssmin' ) ){ include( dirname( __FILE__ ) . '/lib/cssmin.inc.php' ); } try { $less = new lessc; $compiled_css = $less->compileFile( $less_file ); if ( $compiled_css != '' ){ $wp_filesystem->put_contents( $css_file, $compiled_css ); $compiled_css_min = CssMin::minify( $compiled_css ); if ( $compiled_css_min != '' ) $wp_filesystem->put_contents( $css_min_file, $compiled_css_min ); } } catch ( exception $ex ) { //echo ( __( 'Could not compile .less:', 'sass' ) . ' ' . $ex->getMessage() ); } } }
protected function minify($scripts, $ext, $output) { $path = $this->rootDir(); $outfile = "{$path}/{$output}"; if (file_exists($outfile)) { if ($this->ttl == -1) { // never recompile return true; } $fileage = time() - filemtime($outfile); if ($fileage < $this->ttl) { return true; } } $str = $this->join_files($scripts); switch ($ext) { case "css": switch ($this->cssmin) { case "cssmin": $packed = \CssMin::minify($str); break; default: $packed = $str; } break; case "js": switch ($this->jsmin) { case "packer": $packer = new \JavaScriptPacker($str, "Normal", true, false); $packed = $packer->pack(); break; case "jshrink": $packed = \JShrink\Minifier::minify($str); break; default: $packed = $str; } break; } $this->fileClient->put($outfile, $packed); }
/** * Implements {@link aCssParserPlugin::parse()}. * * @param integer $index Current index * @param string $char Current char * @param string $previousChar Previous char * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing */ public function parse($index, $char, $previousChar, $state) { // Start of string if (($char === "\"" || $char === "'") && $state !== "T_STRING") { $this->delimiterChar = $char; $this->parser->pushState("T_STRING"); $this->parser->setExclusive(__CLASS__); } elseif ($char === "\n" && $previousChar === "\\" && $state === "T_STRING") { $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -2)); } elseif ($char === "\n" && $previousChar !== "\\" && $state === "T_STRING") { $line = $this->parser->getBuffer(); $this->parser->popState(); $this->parser->unsetExclusive(); $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -1) . $this->delimiterChar); // Replace the LF with the current string char CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated string literal", $line . "_")); $this->delimiterChar = null; } elseif ($char === $this->delimiterChar && $state === "T_STRING") { // If the Previous char is a escape char count the amount of the previous escape chars. If the amount of // escape chars is uneven do not end the string if ($previousChar == "\\") { $source = $this->parser->getSource(); $c = 1; $i = $index - 2; while (substr($source, $i, 1) === "\\") { $c++; $i--; } if ($c % 2) { return false; } } $this->parser->popState(); $this->parser->unsetExclusive(); $this->delimiterChar = null; } else { return false; } return true; }
/** * Implements {@link aCssParserPlugin::parse()}. * * @param integer $index Current index * @param string $char Current char * @param string $previousChar Previous char * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing */ public function parse($index, $char, $previousChar, $state) { // Start of string if ($char === "(" && strtolower(substr($this->parser->getSource(), $index - 3, 4)) === "url(" && $state !== "T_URL") { $this->parser->pushState("T_URL"); $this->parser->setExclusive(__CLASS__); } elseif ($char === "\n" && $previousChar === "\\" && $state === "T_URL") { $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -2)); } elseif ($char === "\n" && $previousChar !== "\\" && $state === "T_URL") { $line = $this->parser->getBuffer(); $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -1) . ")"); // Replace the LF with the url string delimiter $this->parser->popState(); $this->parser->unsetExclusive(); CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated string literal", $line . "_")); } elseif ($char === ")" && $state === "T_URL") { $this->parser->popState(); $this->parser->unsetExclusive(); } else { return false; } return true; }
public function minify($format, $content, $compression_option = "remote") { if ($format == "js") { if ($compression_option == "remote") { return $this->getMinified($this->urlJS, $content); // remote compression } else { require "vendor/JShrink/Minifier.php"; return \JShrink\Minifier::minify($content); // local compression } } if ($format == "css") { if ($compression_option == "remote") { return $this->getMinified($this->urlCSS, $content); // remote compression } else { require "vendor/cssmin/cssmin-v3.0.1-minified.php"; return CssMin::minify($content); // local compression } } }
/** * Implements {@link aCssMinifierPlugin::minify()}. * * @param aCssToken $token Token to process * @return boolean Return TRUE to break the processing of this token; FALSE to continue */ public function apply(aCssToken &$token) { if (stripos($token->Value, "var") !== false && preg_match_all($this->reMatch, $token->Value, $m)) { $mediaTypes = $token->MediaTypes; if (!in_array("all", $mediaTypes)) { $mediaTypes[] = "all"; } for ($i = 0, $l = count($m[0]); $i < $l; $i++) { $variable = trim($m[1][$i]); foreach ($mediaTypes as $mediaType) { if (isset($this->variables[$mediaType], $this->variables[$mediaType][$variable])) { // Variable value found => set the declaration value to the variable value and return $token->Value = str_replace($m[0][$i], $this->variables[$mediaType][$variable], $token->Value); continue 2; } } // If no value was found trigger an error and replace the token with a CssNullToken CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": No value found for variable <code>" . $variable . "</code> in media types <code>" . implode(", ", $mediaTypes) . "</code>", (string) $token)); $token = new CssNullToken(); return true; } } return false; }