This is a heavy regex-based removal of whitespace, unnecessary
comments and tokens, and some CSS value minimization, where practical.
Many steps have been taken to avoid breaking comment-based hacks,
including the ie5/mac filter (and its inversion), but expect tricky
hacks involving comment tokens in 'content' value strings to break
minimization badly. A test suite is available.
Note: This replaces a lot of spaces with line breaks. It's rumored
(https://github.com/yui/yuicompressor/blob/master/README.md#global-options)
that some source control tools and old browsers don't like very long lines.
Compressed files with shorter lines are also easier to diff. If this is
unacceptable please use CSSmin instead.
/** * Minify a CSS string * * @param string $css * * @param array $options (currently ignored) * * @return string */ public static function process($css, $options = array()) { static $instance; if (!$instance) { $instance = new Minify_CSS_Compressor($options); } return $instance->_process($css); }
protected function _process($css) { $css = parent::_process($css); $css = preg_replace('`\\s*`', '', $css); $css = preg_replace('`;}`', '}', $css); return $css; }
/** * Minify a CSS string * * @param string $css * * @param array $options available options: * * 'preserveComments': (default true) multi-line comments that begin * with "/*!" will be preserved with newlines before and after to * enhance readability. * * 'removeCharsets': (default true) remove all @charset at-rules * * 'prependRelativePath': (default null) if given, this string will be * prepended to all relative URIs in import/url declarations * * 'currentDir': (default null) if given, this is assumed to be the * directory of the current CSS file. Using this, minify will rewrite * all relative URIs in import/url declarations to correctly point to * the desired files. For this to work, the files *must* exist and be * visible by the PHP process. * * 'symlinks': (default = array()) If the CSS file is stored in * a symlink-ed directory, provide an array of link paths to * target paths, where the link paths are within the document root. Because * paths need to be normalized for this to work, use "//" to substitute * the doc root in the link paths (the array keys). E.g.: * <code> * array('//symlink' => '/real/target/path') // unix * array('//static' => 'D:\\staticStorage') // Windows * </code> * * 'docRoot': (default = $_SERVER['DOCUMENT_ROOT']) * see Minify_CSS_UriRewriter::rewrite * * @return string */ public static function minify($css, $options = array()) { $options = array_merge(array('compress' => true, 'removeCharsets' => true, 'preserveComments' => true, 'currentDir' => null, 'docRoot' => $_SERVER['DOCUMENT_ROOT'], 'prependRelativePath' => null, 'symlinks' => array()), $options); if ($options['removeCharsets']) { $css = preg_replace('/@charset[^;]+;\\s*/', '', $css); } if ($options['compress']) { if (!$options['preserveComments']) { require_once 'Compressor.php'; $css = Minify_CSS_Compressor::process($css, $options); } else { require_once 'CommentPreserver.php'; require_once 'Compressor.php'; $css = Minify_CommentPreserver::process($css, array('Minify_CSS_Compressor', 'process'), array($options)); } } if (!$options['currentDir'] && !$options['prependRelativePath']) { return $css; } require_once 'UriRewriter.php'; if ($options['currentDir']) { return Minify_CSS_UriRewriter::rewrite($css, $options['currentDir'], $options['docRoot'], $options['symlinks']); } else { return Minify_CSS_UriRewriter::prepend($css, $options['prependRelativePath']); } }
/** * Minify a CSS string * * @param string $css * * @param array $options available options: * * 'preserveComments': (default true) multi-line comments that begin * with "/*!" will be preserved with newlines before and after to * enhance readability. * * 'prependRelativePath': (default null) if given, this string will be * prepended to all relative URIs in import/url declarations * * 'currentDir': (default null) if given, this is assumed to be the * directory of the current CSS file. Using this, minify will rewrite * all relative URIs in import/url declarations to correctly point to * the desired files. For this to work, the files *must* exist and be * visible by the PHP process. * * 'symlinks': (default = array()) If the CSS file is stored in * a symlink-ed directory, provide an array of link paths to * target paths, where the link paths are within the document root. Because * paths need to be normalized for this to work, use "//" to substitute * the doc root in the link paths (the array keys). E.g.: * <code> * array('//symlink' => '/real/target/path') // unix * array('//static' => 'D:\\staticStorage') // Windows * </code> * * @return string */ static public function minify($css, $options = array()) { require_once 'Minify/CSS/Compressor.php'; if (isset($options['preserveComments']) && !$options['preserveComments']) { $css = Minify_CSS_Compressor::process($css, $options); } else { require_once 'Minify/CommentPreserver.php'; $css = Minify_CommentPreserver::process( $css ,array('Minify_CSS_Compressor', 'process') ,array($options) ); } if (! isset($options['currentDir']) && ! isset($options['prependRelativePath'])) { return $css; } require_once 'Minify/CSS/UriRewriter.php'; if (isset($options['currentDir'])) { return Minify_CSS_UriRewriter::rewrite( $css ,$options['currentDir'] ,isset($options['docRoot']) ? $options['docRoot'] : $_SERVER['DOCUMENT_ROOT'] ,isset($options['symlinks']) ? $options['symlinks'] : array() ); } else { return Minify_CSS_UriRewriter::prepend( $css ,$options['prependRelativePath'] ); } }
protected function _commentCB($m) { if ($m[1][0] === '!') { return '/*' . $m[1] . '*/'; } return parent::_commentCB($m); }
public function doProcessFile($file, $replace = false) { $optimizedContent = Minify_CSS_Compressor::process(file_get_contents($file)); if ($replace) { return parent::replaceFile($file, $optimizedContent); } else { return $optimizedContent; } }
private function buildApiCss() { // copy file $this->getFilesystem()->copy(sfConfig::get('sf_web_dir') . '/css/api_sources/button.css', sfConfig::get('sf_web_dir') . '/css/v1/button.css', array('override' => true)); // replace wildcards $this->getFilesystem()->replaceTokens(sfConfig::get('sf_web_dir') . '/css/v1/button.css', '##', '##', array('YIID_WIDGET_HOST' => sfConfig::get('app_settings_widgets_host'), 'YIID_BUTTON_HOST' => sfConfig::get('app_settings_button_url'))); $lCssMin = Minify_CSS_Compressor::process(file_get_contents(sfConfig::get('sf_web_dir') . '/css/v1/button.css')); $lCssMinFile = fopen(sfConfig::get('sf_web_dir') . '/css/v1/button.css', 'w+'); $lDone = fwrite($lCssMinFile, $lCssMin); fclose($lCssMinFile); }
/** * Minify a CSS string * * @param string $css * * @param array $options available options: * * 'preserveComments': (default true) multi-line comments that begin * with "/*!" will be preserved with newlines before and after to * enhance readability. * * 'removeCharsets': (default true) remove all @charset at-rules * * 'prependRelativePath': (default null) if given, this string will be * prepended to all relative URIs in import/url declarations * * 'currentDir': (default null) if given, this is assumed to be the * directory of the current CSS file. Using this, minify will rewrite * all relative URIs in import/url declarations to correctly point to * the desired files. For this to work, the files *must* exist and be * visible by the PHP process. * * 'symlinks': (default = array()) If the CSS file is stored in * a symlink-ed directory, provide an array of link paths to * target paths, where the link paths are within the document root. Because * paths need to be normalized for this to work, use "//" to substitute * the doc root in the link paths (the array keys). E.g.: * <code> * array('//symlink' => '/real/target/path') // unix * array('//static' => 'D:\\staticStorage') // Windows * </code> * * 'docRoot': (default = $_SERVER['DOCUMENT_ROOT']) * see Minify_CSS_UriRewriter::rewrite * * @return string */ public static function minify($css, $options = array()) { $options = array_merge(array('removeCharsets' => true, 'preserveComments' => true), $options); if ($options['removeCharsets']) { $css = preg_replace('/@charset[^;]+;\\s*/', '', $css); } if (!$options['preserveComments']) { $css = Minify_CSS_Compressor::process($css, $options); } else { $css = Minify_CommentPreserver::process($css, array('Minify_CSS_Compressor', 'process'), array($options)); } return $css; }
/** * Minify a CSS string * * @param string $css * * @param array $options available options: * * 'preserveComments': (default true) multi-line comments that begin * with "/*!" will be preserved with newlines before and after to * enhance readability. * * 'prependRelativePath': (default null) if given, this string will be * prepended to all relative URIs in import/url declarations * * 'currentDir': (default null) if given, this is assumed to be the * directory of the current CSS file. Using this, minify will rewrite * all relative URIs in import/url declarations to correctly point to * the desired files. For this to work, the files *must* exist and be * visible by the PHP process. * * 'symlinks': (default = array()) If the CSS file is stored in * a symlink-ed directory, provide an array of link paths to * target paths, where the link paths are within the document root. Because * paths need to be normalized for this to work, use "//" to substitute * the doc root in the link paths (the array keys). E.g.: * <code> * array('//symlink' => '/real/target/path') // unix * array('//static' => 'D:\\staticStorage') // Windows * </code> * * @return string */ public static function minify($css, $options = array()) { require_once W3TC_LIB_MINIFY_DIR . '/Minify/CSS/Compressor.php'; if (isset($options['preserveComments']) && $options['preserveComments']) { require_once W3TC_LIB_MINIFY_DIR . '/Minify/CommentPreserver.php'; $css = Minify_CommentPreserver::process($css, array('Minify_CSS_Compressor', 'process'), array($options)); } else { $css = Minify_CSS_Compressor::process($css, $options); } require_once W3TC_LIB_MINIFY_DIR . '/Minify/CSS/UriRewriter.php'; $css = Minify_CSS_UriRewriter::rewrite($css, $options); return $css; }
public function min() { $this->_options = array_merge(array('remove_charsets' => true, 'preserve_comments' => true, 'current_dir' => null, 'doc_root' => $_SERVER['DOCUMENT_ROOT'], 'prepend_relative_path' => null, 'symlinks' => array()), $this->_options); if ($this->_options['remove_charsets']) { $this->_css = preg_replace('/@charset[^;]+;\\s*/', '', $this->_css); } if (!$this->_options['preserve_comments']) { $this->_css = Minify_CSS_Compressor::process($this->_css, $this->_options); } else { $this->_css = Minify_CSS_Comment_Preserver::process($this->_css, array('Minify_CSS_Compressor', 'process'), array($this->_options)); } if (!$this->_options['current_dir'] && !$this->_options['prepend_relative_path']) { return $this->_css; } if ($this->_options['current_dir']) { return Minify_CSS_Uri_Rewriter::rewrite($this->_css, $this->_options['current_dir'], $this->_options['doc_root'], $this->_options['symlinks']); } else { return Minify_CSS_Uri_Rewriter::prepend($this->_css, $this->_options['prepend_relative_path']); } }
/** * Execute preprocessor * * This will take all CSS files from the source dir, minify each one and * then combine them into one file. * * @param array $options Options for execution * @return void */ public function execute($options = array()) { $cssFiles = FileOps::rglob("*.css", 0, $this->getSourceDir()); if (empty($cssFiles)) { return false; } FileOps::ensurePathExists($this->getDestinationDir()); // Just get the basename of the main style sheet, this will be written // to the destination dir $mainStylesheet = basename($options['main_stylesheet']); $mainStylesheet = $this->getDestinationDir() . DIRECTORY_SEPARATOR . $mainStylesheet; $buffer = array(); foreach ($cssFiles as $file) { $content = file_get_contents($file); $newContent = \Minify_CSS_Compressor::process($content); $buffer[] = $newContent; } if ($buffer) { file_put_contents($mainStylesheet, implode("\n", $buffer)); } }
/** * doExecute * * @return int */ protected function doExecute() { $path = $this->getArgument(0); $package = $this->getOption('p'); $folder = $this->console->get('asset.folder', 'asset'); if ($package = PackageHelper::getPackage($package)) { $path = $package->getDir() . '/Resources/asset/' . $path; } else { $path = WINDWALKER_PUBLIC . '/' . trim($folder, '/') . '/' . $path; } if (is_file($path)) { $files = array(new \SplFileInfo($path)); } elseif (is_dir($path)) { $files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, \FilesystemIterator::FOLLOW_SYMLINKS)); } else { throw new \InvalidArgumentException('No path'); } /** @var \SplFileInfo $file */ foreach ($files as $file) { $ext = File::getExtension($file->getPathname()); if (StringHelper::endsWith($file->getBasename(), '.min.' . $ext)) { continue; } if ($ext == 'css') { $this->out('[<comment>Compressing</comment>] ' . $file); $data = \Minify_CSS_Compressor::process(file_get_contents($file)); $data = str_replace("\n", ' ', $data); } elseif ($ext == 'js') { $this->out('[<comment>Compressing</comment>] ' . $file); $data = \JSMinPlus::minify(file_get_contents($file)); $data = str_replace("\n", ';', $data); } else { continue; } $newName = $file->getPath() . '/' . File::stripExtension($file->getBasename()) . '.min.' . $ext; file_put_contents($newName, $data); $this->out('[<info>Compressed</info>] ' . $newName); } }
/** * @see sfCombineMinifierInterface */ public static function minify($content, array $options = array()) { return Minify_CSS_Compressor::process($content, $options); }
/** * Minify CSS * * @param string $s CSS string to minify * @return string minified CSS string. */ function _minifyCss($s) { require_once BX_DIRECTORY_PATH_PLUGINS . 'minify/lib/Minify/CSS/Compressor.php'; return Minify_CSS_Compressor::process($s); }
public function getStyles() { if (defined('HTTP_CATALOG')) { return $this->styles; } global $registry; $combinedStyles = array(); $result = array(); $oc_root = dirname(DIR_APPLICATION); $cache = NULL; $cachefile = NULL; $recache = false; $filename = NULL; $megaHashes = array(); if (!defined('DS')) { define('DS', DIRECTORY_SEPARATOR); } //load NitroCache require_once $oc_root . DS . 'system' . DS . 'nitro' . DS . 'config.php'; require_once $oc_root . DS . 'system' . DS . 'nitro' . DS . 'core' . DS . 'core.php'; $nitroSettings = getNitroPersistence(); if (empty($nitroSettings['Nitro']['Enabled']) || $nitroSettings['Nitro']['Enabled'] != 'yes' || empty($nitroSettings['Nitro']['Mini']['Enabled']) || empty($nitroSettings['Nitro']['Mini']['CSS']) || $nitroSettings['Nitro']['Mini']['Enabled'] != 'yes' || $nitroSettings['Nitro']['Mini']['CSS'] != 'yes' || function_exists('areWeInIgnoredUrl') && areWeInIgnoredUrl()) { return $this->styles; } if (!file_exists($oc_root . DS . 'assets')) { mkdir($oc_root . DS . 'assets'); } if (!file_exists($oc_root . DS . 'assets' . DS . 'style')) { mkdir($oc_root . DS . 'assets' . DS . 'style'); } $cssExclude = array(); $excludedCSS = array(); $includedCSS = 0; if (!empty($nitroSettings['Nitro']['Mini']['CSSExclude'])) { $cssExclude = explode("\n", $nitroSettings['Nitro']['Mini']['CSSExclude']); foreach ($cssExclude as $k => $stylename) { $cssExclude[$k] = trim($stylename, "\n\r "); } } //extract local fylesystem path foreach ($this->styles as $hash => $style) { $url_info = parse_url($style['href']); if (!empty($url_info['path'])) { $f = trim($url_info['path'], '/'); if (file_exists($oc_root . DS . $f)) { $this->styles[$hash]['href'] = $f; } else { if (empty($nitroSettings['Nitro']['Mini']['CSSExclude'])) { $nitroSettings['Nitro']['Mini']['CSSExclude'] = ''; } $cssExclude[] = basename($style['href']); } } else { if (empty($nitroSettings['Nitro']['Mini']['CSSExclude'])) { $nitroSettings['Nitro']['Mini']['CSSExclude'] = ''; } $cssExclude[] = basename($style['href']); } } if (!empty($nitroSettings['Nitro']['Mini']['CSSCombine']) && $nitroSettings['Nitro']['Mini']['CSSCombine'] == 'yes') { $cachefile = $oc_root . DS . 'assets' . DS . 'style' . DS . getSSLCachePrefix() . 'styles-combined.cache'; if (!file_exists($cachefile)) { touch($cachefile); file_put_contents($cachefile, json_encode(array())); } $cache = json_decode(file_get_contents($cachefile), true); //build combination hash foreach ($this->styles as $hash => $style) { if (!in_array(basename($style['href']), $cssExclude)) { if (empty($megaHashes[$style['rel'] . $style['media']])) { $megaHashes[$style['rel'] . $style['media']] = ''; } $megaHashes[$style['rel'] . $style['media']] .= $hash; $includedCSS++; } else { $excludedCSS[$hash] = $style; } } foreach ($megaHashes as $k => $megaHash) { $megaHashes[$k] = md5($megaHash); } // Check the cache if we should recache foreach ($this->styles as $hash => $style) { if (empty($style)) { continue; } if (!in_array(basename($style['href']), $cssExclude)) { $filename = $oc_root . DS . trim(str_replace('/', DS, $style['href']), DS); //convert relative url to absolute filesystem specific path (all of this, because of Windows) $comboKey = $megaHashes[$style['rel'] . $style['media']]; if (empty($cache[$comboKey]) || !is_array($cache[$comboKey])) { $cache[$comboKey] = array(); } if (array_key_exists($filename, $cache[$comboKey])) { if ($cache[$comboKey][$filename] != filemtime($filename)) { $recache = true; break; } } else { $recache = true; break; } } } //end of check if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == '1')) { $webshopUrl = $registry->get('config')->get('config_ssl'); } else { $webshopUrl = $registry->get('config')->get('config_url'); } $webshopUrl = rtrim(preg_replace('~^https?\\:~i', '', $webshopUrl), '/'); include_once $oc_root . DS . 'system' . DS . 'nitro' . DS . 'lib' . DS . 'minifier' . DS . 'CSSMin.php'; foreach ($this->styles as $hash => $style) { if (empty($style)) { continue; } if (!in_array(basename($style['href']), $cssExclude)) { $target = '/assets/style/' . getSSLCachePrefix() . 'nitro-combined-' . $megaHashes[$style['rel'] . $style['media']] . '.css'; $targetAbsolutePath = $oc_root . DS . trim(str_replace('/', DS, $target), DS); $filename = $oc_root . DS . trim(str_replace('/', DS, $style['href']), DS); $comboHash = $megaHashes[$style['rel'] . $style['media']]; if (empty($combinedStyles[$style['rel'] . $style['media']])) { $combinedStyles[$style['rel'] . $style['media']] = array('rel' => $style['rel'], 'media' => $style['media'], 'content' => '', 'megaHash' => $comboHash); } if ($recache || !file_exists($targetAbsolutePath)) { if (empty($counters[$style['rel'] . $style['media']])) { $counters[$style['rel'] . $style['media']] = 0; } $urlToCurrentDir = $webshopUrl . dirname('/' . trim($style['href'], '/')); /* replace relative urls with absolute ones */ $tmpContent = preg_replace('/(url\\()(?![\'\\"]?https?\\:\\/\\/)([\'\\"]?)\\/?/', '$1$2' . $urlToCurrentDir . '/', file_get_contents($filename)); //minify $tmpContent = Minify_CSS_Compressor::process($tmpContent); $combinedStyles[$style['rel'] . $style['media']]['content'] .= $tmpContent; unset($tmpContent); $cache[$comboHash][$filename] = filemtime($filename); } } } file_put_contents($cachefile, json_encode($cache)); foreach ($combinedStyles as $key => $value) { $target = '/assets/style/' . getSSLCachePrefix() . 'nitro-combined-' . $megaHashes[$key] . '.css'; $targetAbsolutePath = $oc_root . DS . trim(str_replace('/', DS, $target), DS); if ($recache || !file_exists($targetAbsolutePath)) { file_put_contents($targetAbsolutePath, $value['content']); } $result[$megaHashes[$key]] = array('rel' => $value['rel'], 'media' => $value['media'], 'href' => trim($target, '/')); } if ($includedCSS > 0) { return array_merge($excludedCSS, $result); } else { return $excludedCSS; } } else { $cachefile = $oc_root . DS . 'assets' . DS . 'style' . DS . getSSLCachePrefix() . 'styles.cache'; if (!file_exists($cachefile)) { touch($cachefile); file_put_contents($cachefile, json_encode(array())); } $cache = json_decode(file_get_contents($cachefile), true); if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == '1')) { $webshopUrl = $registry->get('config')->get('config_ssl'); } else { $webshopUrl = $registry->get('config')->get('config_url'); } $webshopUrl = rtrim(preg_replace('~^https?\\:~i', '', $webshopUrl), '/'); include_once $oc_root . DS . 'system' . DS . 'nitro' . DS . 'lib' . DS . 'minifier' . DS . 'CSSMin.php'; foreach ($this->styles as $hash => $style) { if (empty($style)) { continue; } $recache = false; if (!in_array(trim(basename($style['href']), "\r\n"), $cssExclude)) { $filename = $oc_root . DS . trim(str_replace('/', DS, $style['href']), DS); $basefilename = basename($style['href'], '.css'); $target = '/assets/style/' . getSSLCachePrefix() . 'nitro-mini-' . $basefilename . '.css'; $targetAbsolutePath = $oc_root . DS . trim(str_replace('/', DS, $target), DS); if (array_key_exists($filename, $cache)) { if ($cache[$filename] != filemtime($filename)) { $recache = true; } } else { $recache = true; } if ($recache || !file_exists($targetAbsolutePath)) { $urlToCurrentDir = $webshopUrl . dirname('/' . trim($style['href'], '/')); /* replace relative urls with absolute ones */ $tmpContent = preg_replace('/(url\\()(?![\'\\"]?https?\\:\\/\\/)([\'\\"]?)\\/?/', '$1$2' . $urlToCurrentDir . '/', file_get_contents($filename)); //minify $tmpContent = Minify_CSS_Compressor::process($tmpContent); file_put_contents($targetAbsolutePath, $tmpContent); unset($tmpContent); $cache[$filename] = filemtime($filename); } $this->styles[$hash]['href'] = trim($target, '/'); } } file_put_contents($cachefile, json_encode($cache)); return $this->styles; } }
/** * Process asset content * * @param string $content * @return string */ public static function process($content) { // Include the processor include_once Kohana::find_file('vendor', 'minify_css_compressor/Compressor'); return Minify_CSS_Compressor::process($content); }
/** * Minify the given $content according to the file type indicated in $filename * * @param string $filename * @param string $content * @return string */ protected function minifyFile($filename, $content) { // if we have a javascript file and jsmin is enabled, minify the content $isJS = stripos($filename, '.js'); require_once 'thirdparty/jsmin/jsmin.php'; require_once BASE_PATH . '/minify/code/thirdparty/Compressor.php'; require_once BASE_PATH . '/minify/code/thirdparty/UriRewriter.php'; increase_time_limit_to(); if ($isJS) { $content = JSMin::minify($content) . ";\n"; } else { $content = Minify_CSS_UriRewriter::rewrite($content, Director::baseFolder() . "/" . dirname($filename), Director::baseFolder()); $content = Minify_CSS_Compressor::process($content) . "\n"; } return $content; }
public function filterDump(AssetInterface $asset) { $asset->setContent(\Minify_CSS_Compressor::process($asset->getContent())); }
private function process($content, $type, $compress, $file = null) { switch ($type) { case 'css': if (!empty($file)) { $content = preg_replace('#url\\((?!\\s*[\'"]?(data\\:image|/|http([s]*)\\:\\/\\/))\\s*([\'"])?#i', "url(\$3{$this->getPath($file)}", $content); } $content = trim($compress ? Minify_CSS_Compressor::process($content) : $content); break; case 'js': $content = trim($compress ? JSMin::minify($content) : $content, ';') . ';'; break; } return $content; }
/** * Minify a CSS string * * @param string $css * * @param array $options (currently ignored) * * @return string */ public static function process($css, $options = array()) { $obj = new Minify_CSS_Compressor($options); return $obj->_process($css); }
/** * merges and minifies the styles * @param array $styles * @param string $theme * @return string HTML */ public static function styles($styles, $theme = NULL) { if ($theme === NULL) { $theme = self::$theme; } $ret = ''; if (Kohana::$environment == Kohana::DEVELOPMENT or Core::config('config.minify') == FALSE) { foreach ($styles as $file => $type) { $file = self::public_path($file, $theme); $ret .= HTML::style($file, array('media' => $type)); } } else { $files = array(); foreach ($styles as $file => $type) { //not external file we need the public link if (!Valid::url($file)) { $files[] = $file; } else { $ret .= HTML::style($file, array('media' => $type)); } } //name for the minify js file $css_minified_name = URL::title('minified-' . str_replace('css', '', implode('-', $files))) . '.css'; //check if file exists. $file_name = self::theme_folder($theme) . '/css/' . $css_minified_name; //only generate if file doesnt exists or older than 1 week if (!file_exists($file_name) or time() > strtotime('+1 week', filemtime($file_name))) { $min = ''; require_once Kohana::find_file('vendor', 'minify/css', 'php'); //getting the content from files foreach ($files as $file) { if (($version = strpos($file, '?')) > 0) { $file = substr($file, 0, $version); } if (file_exists(self::theme_folder($theme) . '/' . $file)) { $min .= file_get_contents(self::theme_folder($theme) . '/' . $file); } } File::write($file_name, Minify_CSS_Compressor::process($min)); } $ret .= HTML::style(self::public_path('css/' . $css_minified_name, $theme), array('media' => 'screen')); } return $ret; }
public static function optimizecss($tpl) { $outputpath = JPATH_ROOT . '/' . $tpl->getParam('t3-assets', 't3-assets') . '/css'; $outputurl = JURI::root(true) . '/' . $tpl->getParam('t3-assets', 't3-assets') . '/css'; if (!JFile::exists($outputpath)){ JFolder::create($outputpath); @chmod($outputpath, 0755); } if (!is_writeable($outputpath)) { return false; } $doc = JFactory::getDocument(); //======================= Group css ================= // $cssgroups = array(); $stylesheets = array(); $ielimit = 4095; $selcounts = 0; $regex = '/\{.+?\}|,/s'; //selector counter $csspath = ''; foreach ($doc->_styleSheets as $url => $stylesheet) { $url = self::fixUrl($url); if ($stylesheet['mime'] == 'text/css' && ($csspath = self::cssPath($url))) { $stylesheet['path'] = $csspath; $stylesheet['data'] = JFile::read($csspath); $selcount = preg_match_all($regex, $stylesheet['data'], $matched); if(!$selcount) { $selcount = 1; //just for sure } //if we found an @import rule or reach IE limit css selector count, break into the new group if (preg_match('#@import\s+.+#', $stylesheet['data']) || $selcounts + $selcount >= $ielimit) { if(count($stylesheets)){ $cssgroup = array(); $groupname = array(); foreach ( $stylesheets as $gurl => $gsheet ) { $cssgroup[$gurl] = $gsheet; $groupname[] = $gurl; } $cssgroup['groupname'] = implode('', $groupname); $cssgroups[] = $cssgroup; } $stylesheets = array($url => $stylesheet); // empty - begin a new group $selcounts = $selcount; } else { $stylesheets[$url] = $stylesheet; $selcounts += $selcount; } } else { // first get all the stylsheets up to this point, and get them into // the items array if(count($stylesheets)){ $cssgroup = array(); $groupname = array(); foreach ( $stylesheets as $gurl => $gsheet ) { $cssgroup[$gurl] = $gsheet; $groupname[] = $gurl; } $cssgroup['groupname'] = implode('', $groupname); $cssgroups[] = $cssgroup; } //mark ignore current stylesheet $cssgroup = array($url => $stylesheet, 'ignore' => true); $cssgroups[] = $cssgroup; $stylesheets = array(); // empty - begin a new group } } if(count($stylesheets)){ $cssgroup = array(); $groupname = array(); foreach ( $stylesheets as $gurl => $gsheet ) { $cssgroup[$gurl] = $gsheet; $groupname[] = $gurl; } $cssgroup['groupname'] = implode('', $groupname); $cssgroups[] = $cssgroup; } //======================= Group css ================= // $output = array(); foreach ($cssgroups as $cssgroup) { if(isset($cssgroup['ignore'])){ unset($cssgroup['ignore']); foreach ($cssgroup as $furl => $fsheet) { $output[$furl] = $fsheet; } } else { $groupname = 'css-' . substr(md5($cssgroup['groupname']), 0, 5) . '.css'; $groupfile = $outputpath . '/' . $groupname; $grouptime = JFile::exists($groupfile) ? @filemtime($groupfile) : -1; $rebuild = $grouptime < 0; //filemtime == -1 => rebuild unset($cssgroup['groupname']); foreach ($cssgroup as $furl => $fsheet) { if(!$rebuild && @filemtime($fsheet['path']) > $grouptime){ $rebuild = true; } } if($rebuild){ $cssdata = array(); foreach ($cssgroup as $furl => $fsheet) { $cssdata[] = "\n\n/*==============================="; $cssdata[] = $furl; $cssdata[] = "================================================================================*/"; $cssmin = Minify_CSS_Compressor::process($fsheet['data']); $cssmin = T3Path::updateUrl($cssmin, T3Path::relativePath($outputurl, dirname($furl))); $cssdata[] = $cssmin; } $cssdata = implode("\n", $cssdata); JFile::write($groupfile, $cssdata); @chmod($groupfile, 0644); } $output[$outputurl . '/' . $groupname] = array( 'mime' => 'text/css', 'media' => null, 'attribs' => array() ); } } //apply the change make change $doc->_styleSheets = $output; }
/** * HideMyWP::global_css_filter() * Generate new style from main file * @return */ function global_css_filter() { global $wp_query; $new_style_path = trim($this->opt('new_style_name'), ' /'); //$this->h->ends_with($_SERVER["REQUEST_URI"], 'main.css') || <- For multisite if (isset($wp_query->query_vars['style_wrapper']) && $wp_query->query_vars['style_wrapper'] && $this->is_permalink()) { if (is_multisite() && isset($wp_query->query_vars['template_wrapper'])) { $css_file = str_replace(get_stylesheet(), $wp_query->query_vars['template_wrapper'], get_stylesheet_directory()) . '/style.css'; } else { $css_file = get_stylesheet_directory() . '/style.css'; } status_header(200); //$expires = 60*60*24; // 1 day $expires = 60 * 60 * 24 * 3; //3 day header("Pragma: public"); header("Cache-Control: maxage=" . $expires); header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $expires) . ' GMT'); header('Content-type: text/css; charset=UTF-8'); $css = file_get_contents($css_file); if ($this->opt('minify_new_style')) { if ($this->opt('minify_new_style') == 'quick') { $to_remove = array('%\\n\\r%', '!/\\*.*?\\*/!s', '/\\n\\s*\\n/', "%(\\s){1,}%"); $css = preg_replace($to_remove, ' ', $css); } elseif ($this->opt('minify_new_style') == 'safe') { require_once 'lib/class.CSS-minify.php'; $css = Minify_CSS_Compressor::process($css, array()); } } if ($this->opt('clean_new_style')) { if (strpos($css, 'alignright') === false) { //Disable it if it uses import or so on if (is_multisite()) { $opts = get_blog_option(BLOG_ID_CURRENT_SITE, self::slug); $opts['clean_new_style'] = ''; update_blog_option(BLOG_ID_CURRENT_SITE, self::slug, $opts); } else { $opts = get_option(self::slug); $opts['clean_new_style'] = ''; update_option(self::slug, $opts); } } else { $old = array('wp-caption', 'alignright', 'alignleft', 'alignnone', 'aligncenter'); $new = array('x-caption', 'x-right', 'x-left', 'x-none', 'x-center'); $css = str_replace($old, $new, $css); } //We replace HTML, too } // if (is_child_theme()) // $css = str_replace('/thematic/', '/parent/', $css); echo $css; // if(extension_loaded('zlib')) // ob_end_flush(); exit; } }
public function getcontent() { // restore IE hacks $this->content = $this->restore_iehacks($this->content); // restore comments $this->content = $this->restore_comments($this->content); // restore noscript if (strpos($this->content, '%%NOSCRIPT%%') !== false) { $this->content = preg_replace_callback('#%%NOSCRIPT%%(.*?)%%NOSCRIPT%%#is', create_function('$matches', 'return stripslashes(base64_decode($matches[1]));'), $this->content); } // restore noptimize $this->content = $this->restore_noptimize($this->content); //Restore the full content if (!empty($this->restofcontent)) { $this->content .= $this->restofcontent; $this->restofcontent = ''; } // Inject the new stylesheets $replaceTag = array("<title", "before"); $replaceTag = apply_filters('autoptimize_filter_css_replacetag', $replaceTag); if ($this->inline == true) { foreach ($this->csscode as $media => $code) { $this->inject_in_html('<style type="text/css" media="' . $media . '">' . $code . '</style>', $replaceTag); } } else { if ($this->defer == true) { $deferredCssBlock = "<script>function lCss(url,media) {var d=document;var l=d.createElement('link');l.rel='stylesheet';l.type='text/css';l.href=url;l.media=media; d.getElementsByTagName('head')[0].appendChild(l);}function deferredCSS() {"; $noScriptCssBlock = "<noscript>"; $defer_inline_code = $this->defer_inline; $defer_inline_code = apply_filters('autoptimize_filter_css_defer_inline', $defer_inline_code); if (!empty($defer_inline_code)) { $iCssHash = md5($defer_inline_code); $iCssCache = new autoptimizeCache($iCssHash, 'css'); if ($iCssCache->check()) { // we have the optimized inline CSS in cache $defer_inline_code = $iCssCache->retrieve(); } else { if (class_exists('Minify_CSS_Compressor')) { $tmp_code = trim(Minify_CSS_Compressor::process($this->defer_inline)); } else { if (class_exists('CSSmin')) { $cssmin = new CSSmin(); $tmp_code = trim($cssmin->run($defer_inline_code)); } } if (!empty($tmp_code)) { $defer_inline_code = $tmp_code; $iCssCache->cache($defer_inline_code, "text/css"); unset($tmp_code); } } $code_out = '<style type="text/css" media="all">' . $defer_inline_code . '</style>'; $this->inject_in_html($code_out, $replaceTag); } } foreach ($this->url as $media => $url) { $url = $this->url_replace_cdn($url); //Add the stylesheet either deferred (import at bottom) or normal links in head if ($this->defer == true) { $deferredCssBlock .= "lCss('" . $url . "','" . $media . "');"; $noScriptCssBlock .= '<link type="text/css" media="' . $media . '" href="' . $url . '" rel="stylesheet" />'; } else { $this->inject_in_html('<link type="text/css" media="' . $media . '" href="' . $url . '" rel="stylesheet" />', $replaceTag); } } if ($this->defer == true) { $deferredCssBlock .= "}if(window.addEventListener){window.addEventListener('DOMContentLoaded',deferredCSS,false);}else{window.onload = deferredCSS;}</script>"; $noScriptCssBlock .= "</noscript>"; $this->inject_in_html($noScriptCssBlock, array('<title>', 'before')); $this->inject_in_html($deferredCssBlock, array('</body>', 'before')); } } //Return the modified stylesheet return $this->content; }
protected function _Consolidate($Files, $Suffix, $Prefix = '') { $Token = $Prefix . md5(serialize($Files)) . $Suffix; $CacheFile = PATH_CACHE . "/Consolidate/{$Token}"; if (in_array($Token, $this->ChunkedFiles)) { return $Token; } if (!file_exists($CacheFile)) { $ConsolidateFile = ''; $PathRootParts = split(DS, PATH_ROOT); $WebRootParts = split(DS, $this->WebRoot); $Base = join(DS, array_slice($PathRootParts, 0, -count($WebRootParts))); foreach ($Files as $File) { $ConsolidateFile .= "/*\n"; $ConsolidateFile .= "* Consolidate '{$File['fullhref']}'\n"; $ConsolidateFile .= "*/\n\n"; $OriginalFile = PATH_ROOT . DS . $File['href']; $FileStr = file_get_contents($OriginalFile); if ($FileStr && strtolower($Suffix) == '.css') { $FileStr = Minify_CSS_UriRewriter::rewrite($FileStr, dirname($Base . DS . $this->WebRoot . DS . $File['href']), $Base); $FileStr = Minify_CSS_Compressor::process($FileStr); } $ConsolidateFile .= trim($FileStr); if ($FileStr && strtolower($Suffix) == '.js') { if (substr($ConsolidateFile, -1) != ';') { $ConsolidateFile .= ";"; } } $ConsolidateFile .= "\n\n"; } if (!file_exists(dirname($CacheFile))) { mkdir(dirname($CacheFile), 0777, TRUE); } file_put_contents($CacheFile, $ConsolidateFile); } if (!in_array($Token, $this->ChunkedFiles)) { $this->ChunkedFiles[] = $Token; } return $Token; }
/** * Minify text * * @access public * @param string Text to minify * @param string Type to minify (css/html). Default is css * @return string Minified text */ public function minify($text, $type = 'css') { $type = strtolower($type); /* What to do? */ if ($type == 'css') { require_once IPS_PUBLIC_PATH . 'min/lib/Minify/CSS/Compressor.php'; /*noLibHook*/ $text = Minify_CSS_Compressor::process($text); } else { if ($type == 'html') { require_once IPS_PUBLIC_PATH . 'min/lib/Minify/HTML.php'; /*noLibHook*/ $text = Minify_HTML::minify($text, array('xhtml' => 1)); } } return $text; }
function sp_combine_plugin_css_files() { global $sp_plugin_styles, $spDevice; if (!is_a($sp_plugin_styles, 'WP_Styles')) { $sp_plugin_styles = new WP_Styles(); } # save copy of styles in case of failure writing $saved_styles = clone $sp_plugin_styles; # check for standard theme or mobile if ($spDevice == 'mobile') { $option = 'sp_css_concat_mobile'; } else { if ($spDevice == 'tablet') { $option = 'sp_css_concat_tablet'; } else { $option = 'sp_css_concat'; } } $css_concat = sp_get_option($option); if (!is_array($css_concat)) { $css_concat = array(); } $css_files_modify = array(); $css_files = array(); if (is_array($sp_plugin_styles->queue)) { # is there anything in the queue? $sp_plugin_styles->all_deps($sp_plugin_styles->queue); # preparing the queue taking dependencies into account foreach ($css_concat as $css => $value) { # going through all the already found css files, checking that they are still required if (!in_array(substr($css, 4), $sp_plugin_styles->to_do) && substr($css, 0, 4) == 'css-') { # if the css is not queued, rewrite the file $css_media = $value['type']; $css_files_modify[$css_media] = true; unset($css_concat[$css]); } } foreach ($sp_plugin_styles->to_do as $css) { $css_src = $sp_plugin_styles->registered[$css]->src; $css_media = $sp_plugin_styles->registered[$css]->args; # is the css is hosted localy AND is a css file? if ((!(strpos($css_src, get_bloginfo('url')) === false) || substr($css_src, 0, 1) === '/' || substr($css_src, 0, 1) === '.') && (substr($css_src, strrpos($css_src, '.'), 4) == '.css' || substr($css_src, strrpos($css_src, '.'), 4) == '.php')) { if (!is_array($css_files) || !array_key_exists($css_media, $css_files)) { $css_files[$css_media] = array(); } if (strpos($css_src, get_bloginfo('url')) === false) { $css_relative_url = substr($css_src, 1); } else { $css_relative_url = substr($css_src, strlen(get_bloginfo('url')) + 1); } if (strpos($css_relative_url, '?')) { $css_relative_url = substr($css_relative_url, 0, strpos($css_relative_url, '?')); } # removing parameters $css_m_time = null; @($css_m_time = filemtime($css_relative_url)); # getting the mofified time of the css file. extracting the file's dir if ($css_m_time) { # only add the file if it's accessible # check for php theme file indicating main theme file and save whole url vs just relative if (substr($css_src, strrpos($css_src, '.'), 4) == '.php') { array_push($css_files[$css_media], $css_src); } else { array_push($css_files[$css_media], $css_relative_url); } if (!file_exists(SP_COMBINED_CACHE_DIR . SP_COMBINED_CSS_BASE_NAME . $css_media . '.css') || isset($css_concat['css-' . $css]) && ($css_m_time != $css_concat['css-' . $css]['modified'] || $css_concat['css-' . $css]['type'] != $css_media) || !isset($css_concat['css-' . $css])) { # css file is first identified $css_files_modify[$css_media] = true; # the combined file containing this media type css should be changed if (isset($css_concat['css-' . $css]) && $css_concat['css-' . $css]['type'] != $css_media) { # if the media type changed - rewrite both css files $tmp = $css_concat['css-' . $css]['type']; $css_files_modify[$tmp] = true; } if (!is_array($css_concat['css-' . $css])) { $css_concat['css-' . $css] = array(); } $css_concat['css-' . $css]['modified'] = $css_m_time; # write the new modified date $css_concat['css-' . $css]['type'] = $css_media; } $sp_plugin_styles->remove($css); # removes the css file from the queue } } } } foreach ($css_files_modify as $key => $value) { $combined_file = fopen(SP_COMBINED_CACHE_DIR . SP_COMBINED_CSS_BASE_NAME . $key . '.css', 'w'); if ($combined_file) { $css_content = ''; if (is_array($css_files[$key])) { foreach ($css_files[$key] as $css_src) { $css_content .= "\n" . sp_get_css_content($css_src) . "\n"; } } if (!isset($css_concat['ver'][$key])) { $css_concat['ver'][$key] = 0; } $css_concat['ver'][$key]++; # compress the css before writing it out require 'sp-api-class-css-compressor.php'; $css_content = Minify_CSS_Compressor::process($css_content); fwrite($combined_file, $css_content); fclose($combined_file); } else { # couldnt open file for writing so revert back to enqueueing all the styles if (!empty($saved_styles)) { foreach ($saved_styles->queue as $handle) { wp_enqueue_style($handle, $saved_styles->registered[$handle]->src); } } return; # enqueued through wp now so bail } } foreach ($css_files as $key => $value) { # enqueue the combined css files wp_enqueue_style(SP_COMBINED_CSS_BASE_NAME . $key, SP_COMBINED_CACHE_URL . SP_COMBINED_CSS_BASE_NAME . $key . '.css', array(), $css_concat['ver'][$key]); } sp_update_option($option, $css_concat); }
/** * Minify a CSS text * * @param string $css CSS text * @param array $options Optional options * @return string Minified CSS text */ public function minify($css, array $options = array()) { return \Minify_CSS_Compressor::process($css, $options); }
public static function OutputCombined($tag, $modstamp = 0) { if (substr($tag, 0, 3) == 'css') { self::ProcessCSS(); } else { self::ProcessJS(); } if (self::$memcached) { $ret = self::$memcached->get($tag . '-' . $modstamp); if ($ret) { echo $ret; return; } ob_start(); } if (isset(self::$combined[$tag])) { foreach (self::$combined[$tag] as $_f) { if ($_f->flags & self::NO_MINIFY || (self::$features & self::FEAT_MINIFY) == 0) { readfile(WEB_ROOT . DIRECTORY_SEPARATOR . $_f->link); } else { if ($_f->type == self::TYPE_JS) { try { echo JSMin::minify(file_get_contents(WEB_ROOT . DIRECTORY_SEPARATOR . $_f->link)); } catch (Exception $ex) { error_log((string) $ex); } } elseif ($_f->type == self::TYPE_CSS) { try { echo Minify_CSS_Compressor::process(file_get_contents(WEB_ROOT . DIRECTORY_SEPARATOR . $_f->link)); } catch (Exception $ex) { error_log((string) $ex); } } } } } if (self::$memcached) { self::$memcached->set($tag . '-' . $modstamp, ob_get_contents()); ob_end_flush(); } }
/** * @param $contents * @return string */ private function minifyCSS($contents) { if (!$contents) { return ""; } return Minify_CSS_Compressor::process($contents); }