protected static function parseArgs($input, $allowSpaceDelim = false) { $args = csscrush_util::splitDelimList($input, $allowSpaceDelim ? '\\s*[,\\s]\\s*' : ',', true, true); return array_map('trim', $args->list); }
protected static function rewriteImportRelativeUrls($import) { $stream = $import->content; // We're comparing file system position so we'll $hostDir = csscrush_util::normalizeSystemPath($import->hostDir, true); $importDir = csscrush_util::normalizeSystemPath(dirname($import->path), true); csscrush::$storage->tmp->relativeUrlPrefix = ''; $url_prefix = ''; if ($importDir === $hostDir) { // Do nothing if files are in the same directory return $stream; } elseif (strpos($importDir, $hostDir) === false) { // Import directory is higher than the host directory // Split the directory paths into arrays so we can compare segment by segment $host_segs = preg_split('!/+!', $hostDir, null, PREG_SPLIT_NO_EMPTY); $import_segs = preg_split('!/+!', $importDir, null, PREG_SPLIT_NO_EMPTY); // Shift the segments until they are on different branches while (@($host_segs[0] == $import_segs[0])) { array_shift($host_segs); array_shift($import_segs); // csscrush::log( array( $host_segs, $import_segs ) ); } // Count the remaining $host_segs to get the offset $level_diff = count($host_segs); $url_prefix = str_repeat('../', $level_diff) . implode('/', $import_segs); } else { // Import directory is lower than host directory // easy, url_prefix is the difference $url_prefix = substr($importDir, strlen($hostDir) + 1); } if (empty($url_prefix)) { return $stream; } // Add the directory seperator ending (if needed) if ($url_prefix[strlen($url_prefix) - 1] !== '/') { $url_prefix .= '/'; } csscrush::log('relative_url_prefix: ' . $url_prefix); // Search for all relative url and data-uri references in the content // and prepend $relative_url_prefix // Make $url_prefix accessible in callback scope csscrush::$storage->tmp->relativeUrlPrefix = $url_prefix; $url_function_patt = '! ([^a-z-]) # the preceeding character (data-uri|url) # the function name \\(\\s*([^\\)]+)\\s*\\) # the url !xi'; $stream = preg_replace_callback($url_function_patt, array('self', 'cb_rewriteImportRelativeUrl'), $stream); return $stream; }
protected static function cb_extractVariables($match) { $regex = self::$regex; $block = $match[2]; // Strip comment markers $block = preg_replace($regex->token->comment, '', $block); // Need to split safely as there are semi-colons in data-uris $variables_match = csscrush_util::splitDelimList($block, ';', true); // Loop through the pairs, restore parens foreach ($variables_match->list as $var) { $colon = strpos($var, ':'); if ($colon === -1) { continue; } $name = trim(substr($var, 0, $colon)); $value = trim(substr($var, $colon + 1)); self::$storage->variables[trim($name)] = $value; } return ''; }
public function __construct($selector_string = null, $declarations_string) { $regex = csscrush::$regex; // Parse the selectors chunk if (!empty($selector_string)) { $selectors_match = csscrush_util::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; } // Apply any custom functions $declarations_string = csscrush_function::parseAndExecuteValue($declarations_string); // Parse the declarations chunk // Need to split safely as there are semi-colons in data-uris $declarations_match = csscrush_util::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; } // The property name $prop = trim(substr($declaration, 0, $colonPos)); // Test for escape tilde if ($skip = strpos($prop, '~') === 0) { $prop = substr($prop, 1); } // Store the property name $this->addProperty($prop); // 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; } // 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; } // Create an index of all functions in the current declaration if (preg_match_all($regex->function->match, $value, $functions) > 0) { // csscrush::log( $functions ); $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, 'skip' => $skip); $this->declarations[] = $_declaration; } }