public function filterLoad(AssetInterface $asset)
 {
     $options = array();
     if (null !== $this->debug) {
         $options['debug'] = (bool) $this->debug;
     }
     if (null !== $this->boilerplate) {
         $options['boilerplate'] = (bool) $this->boilerplate;
     }
     if (null !== $this->versioning) {
         $options['versioning'] = (bool) $this->versioning;
     }
     if (!empty($this->plugins)) {
         $options['enable'] = $this->plugins;
     }
     // remember the previous document root
     $snapshot = \CssCrush::$config->docRoot;
     // process the asset
     \CssCrush::$config->docRoot = $asset->getSourceRoot();
     $output = (string) \CssCrush::string($asset->getContent(), $options);
     $asset->setContent($output);
     // cleanup
     \CssCrush::$config->docRoot = $snapshot;
 }
/**
 *
 * CSS Crush
 * Extensible CSS preprocessor
 * 
 * @version    1.4.1
 * @license    http://www.opensource.org/licenses/mit-license.php (MIT)
 * @copyright  Copyright 2010-2012 Pete Boere
 * 
 * 
 * <?php
 *
 * // Basic usage
 * require_once 'CssCrush.php';
 * $global_css = CssCrush::file( '/css/global.css' );
 *
 * ?>
 *
 * <link rel="stylesheet" href="<?php echo $global_css; ?>" />
 *
 */
require_once 'lib/Util.php';
require_once 'lib/Core.php';
CssCrush::init(dirname(__FILE__));
require_once 'lib/Rule.php';
require_once 'lib/Function.php';
CssCrush_Function::init();
require_once 'lib/Importer.php';
require_once 'lib/Color.php';
require_once 'lib/Hook.php';
Example #3
0
 public static function hostfile($hostfile)
 {
     $config = CssCrush::$config;
     $regex = CssCrush::$regex;
     // Keep track of all import file info for later logging
     $mtimes = array();
     $filenames = array();
     // Get the hostfile contents and obfuscate commented imports
     $str = self::obfuscateComments(file_get_contents($hostfile->path));
     // This may be set non-zero if an absoulte URL is encountered
     $searchOffset = 0;
     // Recurses until the nesting heirarchy is flattened and all files are combined
     while (preg_match($regex->import, $str, $match, PREG_OFFSET_CAPTURE, $searchOffset)) {
         $fullMatch = $match[0][0];
         // Full match
         $matchStart = $match[0][1];
         // Full match offset
         $matchEnd = $matchStart + strlen($fullMatch);
         $url = trim($match[1][0]);
         // The url
         $mediaContext = trim($match[2][0]);
         // The media context if specified
         $preStatement = substr($str, 0, $matchStart);
         $postStatement = substr($str, $matchEnd);
         // Pass over absolute urls
         // Move the search pointer forward
         if (preg_match('!^https?://!', $url)) {
             $searchOffset = $matchEnd;
             continue;
         }
         $import = new stdClass();
         $import->name = $url;
         $import->mediaContext = $mediaContext;
         $import->path = "{$hostfile->dir}/{$import->name}";
         $import->content = @file_get_contents($import->path);
         // Failed to open import, just continue with the import line removed
         if (!$import->content) {
             CssCrush::log("Import file '{$import->name}' not found");
             $str = $preStatement . $postStatement;
             continue;
         } else {
             $import->content = self::obfuscateComments($import->content);
             if ($import->mediaContext) {
                 $import->content = "@media {$import->mediaContext} {" . $import->content . '}';
             }
             $import->dir = dirname($import->name);
             // Store import file info
             $mtimes[] = filemtime($import->path);
             $filenames[] = $import->name;
             // Store the replacements we might find
             $replacements = array();
             // Match all @import statements in the import content
             // Alter all the url strings to be paths relative to the hostfile
             $matchCount = preg_match_all($regex->import, $import->content, $matchAll, PREG_OFFSET_CAPTURE);
             for ($index = 0; $index < $matchCount; $index++) {
                 $fullMatch = $matchAll[0][$index][0];
                 $urlMatch = $matchAll[1][$index][0];
                 $search = $urlMatch;
                 $replace = "{$import->dir}/{$urlMatch}";
                 // Try to resolve absolute paths
                 // On failure strip the @import statement
                 if (strpos($urlMatch, '/') === 0) {
                     $replace = self::resolveAbsolutePath($urlMatch);
                     if (!$replace) {
                         $search = $fullMatch;
                         $replace = '';
                     }
                 }
                 $replacements[$fullMatch] = str_replace($search, $replace, $fullMatch);
             }
             // If we've stored any altered @import strings then we need to apply them
             if (count($replacements)) {
                 $import->content = str_replace(array_keys($replacements), array_values($replacements), $import->content);
             }
             // CssCrush::log( $replacements );
             $str = $preStatement . $import->content . $postStatement;
         }
     }
     // End while
     self::save(array('imports' => $filenames, 'datem_sum' => array_sum($mtimes) + $hostfile->mtime, 'options' => CssCrush::$options));
     return $str;
 }
Example #4
0
 public function __construct($selector_string = null, $declarations_string)
 {
     $regex = CssCrush::$regex;
     // Parse the selectors chunk
     if (!empty($selector_string)) {
         $selector_adjustments = array('!:hocus([^a-z0-9_-])!' => ':any(:hover,:focus)$1', '!:pocus([^a-z0-9_-])!' => ':any(:hover,:focus,:active)$1', '!::(after|before|first-letter|first-line)!' => ':$1');
         $selector_string = preg_replace(array_keys($selector_adjustments), array_values($selector_adjustments), $selector_string);
         $selectors_match = CssCrush::splitDelimList($selector_string, ',');
         $this->parens += $selectors_match->matches;
         // Remove and store comments that sit above the first selector
         // remove all comments between the other selectors
         preg_match_all($regex->token->comment, $selectors_match->list[0], $m);
         $this->comments = $m[0];
         foreach ($selectors_match->list as &$selector) {
             $selector = preg_replace($regex->token->comment, '', $selector);
             $selector = trim($selector);
         }
         $this->selectors = $selectors_match->list;
     }
     // Parse the declarations chunk
     $declarations_match = CssCrush::splitDelimList($declarations_string, ';');
     $this->parens += $declarations_match->matches;
     // Parse declarations in to property/value pairs
     foreach ($declarations_match->list as $declaration) {
         // Strip comments around the property
         $declaration = preg_replace($regex->token->comment, '', $declaration);
         // Store the property
         $colonPos = strpos($declaration, ':');
         if ($colonPos === false) {
             // If there is no colon it's malformed
             continue;
         } else {
             $prop = trim(substr($declaration, 0, $colonPos));
             // Store the property name
             $this->addProperty($prop);
         }
         // Extract the value part of the declaration
         $value = substr($declaration, $colonPos + 1);
         $value = $value !== false ? trim($value) : $value;
         if ($value === false or $value === '') {
             // We'll ignore declarations with empty values
             continue;
         }
         // If are parenthesised expressions in the value
         // Search for any custom functions so we can apply them
         if (count($declarations_match->matches)) {
             CssCrush::$storage->tmpParens = $declarations_match->matches;
             $value = preg_replace_callback($regex->function->custom, array('CssCrush_Function', 'css_fn'), $value);
         }
         // Store the property family
         // Store the vendor id, if one is present
         if (preg_match($regex->vendorPrefix, $prop, $vendor)) {
             $family = $vendor[2];
             $vendor = $vendor[1];
         } else {
             $vendor = null;
             $family = $prop;
         }
         // Create an index of all functions in the current declaration
         if (preg_match_all($regex->function->match, $value, $functions) > 0) {
             $out = array();
             foreach ($functions[2] as $index => $fn_name) {
                 $out[] = $fn_name;
             }
             $functions = array_unique($out);
         } else {
             $functions = array();
         }
         // Store the declaration
         $_declaration = (object) array('property' => $prop, 'family' => $family, 'vendor' => $vendor, 'functions' => $functions, 'value' => $value);
         $this->declarations[] = $_declaration;
     }
 }
Example #5
0
<?php

################################################################################################
# Comment out/in as required
// IE 6 shims
CssCrush::addRuleMacro('csscrush_minheight');
// IE 6/7 shims
CssCrush::addRuleMacro('csscrush_clip');
CssCrush::addRuleMacro('csscrush_display_inlineblock');
// IE filter
CssCrush::addRuleMacro('csscrush_filter');
// RGBA fallback
CssCrush::addRuleMacro('csscrush_rgba');
// HSL for all browsers
CssCrush::addRuleMacro('csscrush_hsl');
################################################################################################
/**
 * Simulate inline-block in IE < 8
 * 
 * Before: 
 *     display: inline-block;
 * 
 * After:
 *     display: inline-block;
 *     *display: inline;
 *     *zoom: 1;
 */
function csscrush_display_inlineblock(CssCrush_Rule $rule)
{
    if ($rule->propertyCount('display') < 1) {
        return;
Example #6
0
 protected static function parseArgs($input, $argCount = null)
 {
     $args = CssCrush::splitDelimList($input, ',', true, true);
     return array_map('trim', $args->list);
 }
Example #7
0
 protected static function compile($stream)
 {
     $regex = self::$regex;
     // Reset properties for current process
     self::$tokenUID = 0;
     self::$storage = new stdClass();
     self::$storage->tokens = (object) array('strings' => array(), 'comments' => array(), 'rules' => array(), 'parens' => array());
     self::$storage->variables = array();
     // Load in aliases and macros
     if (!self::$assetsLoaded) {
         self::loadAssets();
         self::$assetsLoaded = true;
     }
     // Set the custom function regular expression
     $css_functions = CssCrush_Function::getFunctions();
     $regex->function->custom = str_replace('<functions>', implode('|', $css_functions), $regex->function->custom);
     // Extract comments
     $stream = preg_replace_callback($regex->comment, array('self', 'cb_extractComments'), $stream);
     // Extract strings
     $stream = preg_replace_callback($regex->string, array('self', 'cb_extractStrings'), $stream);
     // Parse variables
     $stream = preg_replace_callback($regex->variables, array('self', 'cb_extractVariables'), $stream);
     // Calculate the variable stack
     self::calculateVariables();
     self::log(self::$storage->variables);
     // Place the variables
     $stream = self::placeVariables($stream);
     // Normalize whitespace
     $stream = self::normalize($stream);
     // Adjust the stream so we can extract the rules cleanly
     $map = array('@' => "\n@", '}' => "}\n", '{' => "{\n", ';' => ";\n");
     $stream = "\n" . str_replace(array_keys($map), array_values($map), $stream);
     // Extract rules
     $stream = preg_replace_callback($regex->rule, array('self', 'cb_extractRules'), $stream);
     // Alias at-rules (if there are any)
     $stream = self::aliasAtRules($stream);
     // print it all back
     $stream = self::display($stream);
     // self::log( self::$storage->tokens->rules );
     // self::log( self::$storage->tokens );
     self::log(self::$config->data);
     // Release memory
     self::$storage = null;
     return $stream;
 }