/sally/core/lib/Scaffold/libraries/Scaffold/CSS.php
PHP | 371 lines | 194 code | 45 blank | 132 comment | 14 complexity | 12266e3e7ae5536478259624695387dc MD5 | raw file
Possible License(s): BSD-3-Clause
- <?php
- /**
- * CSS Utilities
- *
- * Has methods for interacting with the CSS string
- * and makes it very easy to find properties and values within the css
- *
- * @package CSScaffold
- * @author Anthony Short
- * @license BSD License
- */
- class Scaffold_CSS
- {
- /**
- * Server path to this CSS file
- *
- * @var string
- */
- public $path;
- /**
- * The name of this CSS file
- *
- * @var string
- */
- public $file;
- /**
- * The string of CSS code
- *
- * @var string
- */
- public $string;
- /**
- * Constructor
- *
- * @param $file
- * @return void
- */
- public function __construct($file)
- {
- $this->path = dirname($file);
- $this->file = $file;
- $this->string = $this->remove_inline_comments(file_get_contents($file));
- }
- /**
- * Returns the CSS string when treated as a string
- *
- * @return string
- */
- public function __toString()
- {
- return $this->string;
- }
- /**
- * Compresses down the CSS file. Not a complete compression,
- * but enough to minimize parsing time.
- *
- * @return string $css
- */
- public function compress($css)
- {
- # Remove comments
- $this->string = $this->remove_comments($this->string);
- # Remove extra white space
- $this->string = preg_replace('/\s+/', ' ', $css);
- # Remove line breaks
- $this->string = preg_replace('/\n|\r/', '', $css);
- }
- /**
- * Removes inline comments
- *
- * @return return type
- */
- public function remove_inline_comments($css)
- {
- return preg_replace('#(\s|$)//.*$#Umsi', '', $css);
- }
- /**
- * Removes css comments
- *
- * @return string $css
- */
- public function remove_comments($css)
- {
- $css = $this->convert_entities('encode', $css);
- $css = trim(preg_replace('#/\*[^*]*\*+([^/*][^*]*\*+)*/#', '', $css));
- $css = $this->convert_entities('decode', $css);
- $css = $this->remove_inline_comments($css);
- return $css;
- }
- /**
- * Finds CSS 'functions'. These are things like url(), embed() etc.
- *
- * @author Anthony Short
- * @param $name
- * @param $capture_group
- * @return array
- */
- public function find_functions($name, $capture_group = "")
- {
- $regex =
- "/
- {$name}
- (
- \s*\(\s*
- ( (?: (?1) | [^()]+ )* )
- \s*\)\s*
- )
- /sx";
- if(preg_match_all($regex, $this->string, $match))
- {
- return ($capture_group == "") ? $match : $match[$capture_group];
- }
- else
- {
- return array();
- }
- }
- /**
- * Finds @groups within the css and returns
- * an array with the values, and groups.
- *
- * @author Anthony Short
- * @param $group string
- * @param $css string
- */
- public function find_at_group($group, $remove = true)
- {
- $found = array();
- $regex =
- "/
- # Group name
- @{$group}
- # Flag
- (?:
- \(( [^)]*? )\)
- )?
- [^{]*?
- (
- ([0-9a-zA-Z\_\-\@*&]*?)\s*
- \{
- ( (?: [^{}]+ | (?2) )*)
- \}
- )
- /ixs";
- if(preg_match_all($regex, $this->string, $matches))
- {
- $found['groups'] = $matches[0];
- $found['flag'] = $matches[1];
- $found['content'] = $matches[4];
- foreach($matches[4] as $key => $value)
- {
- // Remove comments to prevent breaking it
- $value = $this->remove_comments($value);
- foreach(explode(";", substr($value, 0, -1)) as $value)
- {
- // Encode any colons inside quotations
- if( preg_match_all('/[\'"](.*?\:.*?)[\'"]/',$value,$m) )
- {
- $value = str_replace($m[0][0],str_replace(':','#COLON#',$m[0][0]),$value);
- }
- $value = explode(":", $value);
- // Make sure it's set
- if(isset($value[1]))
- {
- $found['values'][trim($value[0])] = str_replace('#COLON#', ':', Scaffold::unquote($value[1]));
- }
- }
- }
- // Remove the found @ groups
- if($remove === true)
- {
- $this->string = str_replace($found['groups'], array(), $this->string);
- }
- return $found;
- }
- return false;
- }
- /**
- * Finds selectors which contain a particular property
- *
- * @author Anthony Short
- * @param $css
- * @param $property string
- * @param $value string
- */
- public function find_selectors_with_property($property, $value = ".*?")
- {
- if(preg_match_all("/([^{}]*)\s*\{\s*[^}]*(".$property."\s*\:\s*(".$value.")\s*\;).*?\s*\}/sx", $this->string, $match))
- {
- return $match;
- }
- else
- {
- return array();
- }
- }
- /**
- * Finds all properties with a particular value
- *
- * @author Anthony Short
- * @param $property
- * @param $value
- * @param $css
- * @return array
- */
- public function find_properties_with_value($property, $value = ".*?")
- {
- # Make the property name regex-friendly
- $property = Scaffold_Utils::preg_quote($property);
- $regex = "/ ({$property}) \s*\:\s* ({$value}) /sx";
- if(preg_match_all($regex, $this->string, $match))
- {
- return $match;
- }
- else
- {
- return array();
- }
- }
- /**
- * Finds a selector and returns it as string
- *
- * @author Anthony Short
- * @param $selector string
- * @param $css string
- */
- public function find_selectors($selector, $recursive = "")
- {
- if($recursive != "")
- {
- $recursive = "|(?{$recursive})";
- }
- $regex =
- "/
- # This is the selector we're looking for
- ({$selector})
- # Return all inner selectors and properties
- (
- ([0-9a-zA-Z\_\-\*&]*?)\s*
- \{
- (?P<properties>(?:[^{}]+{$recursive})*)
- \}
- )
- /xs";
- if(preg_match_all($regex, $this->string, $match))
- {
- return $match;
- }
- else
- {
- return array();
- }
- }
- /**
- * Finds all properties within a css string
- *
- * @author Anthony Short
- * @param $property string
- * @param $css string
- */
- public function find_property($property)
- {
- if(preg_match_all('/('.Scaffold_Utils::preg_quote($property).')\s*\:\s*(.*?)\s*\;/sx', $this->string, $matches))
- {
- return (array)$matches;
- }
- else
- {
- return array();
- }
- }
- /**
- * Check if a selector exists
- *
- * @param $name
- * @return boolean
- */
- public function selector_exists($name)
- {
- return preg_match('/'.preg_quote($name).'\s*?({|,)/', $this->string);
- }
- /**
- * Removes all instances of a particular property from the css string
- *
- * @author Anthony Short
- * @param $property string
- * @param $value string
- * @param $css string
- */
- public function remove_properties($property, $value)
- {
- return preg_replace('/'.$property.'\s*\:\s*'.$value.'\s*\;/', '', $this->string);
- }
- /**
- * Encodes or decodes parts of the css that break the xml
- *
- * @author Anthony Short
- * @param $css
- * @return string
- */
- public function convert_entities($action = 'encode', $css = false)
- {
- if($css === false)
- $css =& $this->string;
- $css_replacements = array(
- '"' => '#SCAFFOLD-QUOTE#',
- '>' => '#SCAFFOLD-GREATER#',
- '&' => '#SCAFFOLD-PARENT#',
- 'data:image/PNG;' => '#SCAFFOLD-IMGDATA-PNG#',
- 'data:image/JPG;' => "#SCAFFOLD-IMGDATA-JPG#",
- 'data:image/png;' => '#SCAFFOLD-IMGDATA-PNG#',
- 'data:image/jpg;' => "#SCAFFOLD-IMGDATA-JPG#",
- 'http://' => "#SCAFFOLD-HTTP#",
- );
- switch ($action)
- {
- case 'decode':
- $this->string = str_replace(array_values($css_replacements),array_keys($css_replacements), $this->string);
- break;
- case 'encode':
- $this->string = str_replace(array_keys($css_replacements),array_values($css_replacements), $this->string);
- break;
- }
- return $css;
- }
- }