Source of file SassPropertyNode.php
Size: 7,123 Bytes - Last Modified: 2021-12-23T10:32:55+00:00
/var/www/docs.ssmods.com/process/src/code/phpsass/tree/SassPropertyNode.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 | <?php /* SVN FILE: $Id: SassPropertyNode.php 118 2010-09-21 09:45:11Z chris.l.yates@gmail.com $ */ /** * SassPropertyNode class file. * @author Chris Yates <chris.l.yates@gmail.com> * @copyright Copyright (c) 2010 PBM Web Development * @license http://phamlp.googlecode.com/files/license.txt * @package PHamlP * @subpackage Sass.tree */ /** * SassPropertyNode class. * Represents a CSS property. * @package PHamlP * @subpackage Sass.tree */ class SassPropertyNode extends SassNode { const MATCH_PROPERTY_NEW = '/^([^\s=:"]+)\s*(?:(= )|:)([^\:].*?)?$/'; const MATCH_PROPERTY_OLD = '/^:([^\s=:]+)(?:\s*(=)\s*|\s+|$)(.*)/'; const MATCH_PSUEDO_SELECTOR = '/^:*\w[-\w]+\(?/i'; const MATCH_INTERPOLATION = '/^#\{(.*?)\}/i'; const MATCH_PROPRIETARY_SELECTOR = '/^:?-(moz|webkit|o|ms)-/'; const NAME = 1; const SCRIPT = 2; const VALUE = 3; const IS_SCRIPT = '= '; public static $psuedoSelectors = array( 'root', 'nth-child(', 'nth-last-child(', 'nth-of-type(', 'nth-last-of-type(', 'first-child', 'last-child', 'first-of-type', 'last-of-type', 'only-child', 'only-of-type', 'empty', 'link', 'visited', 'active', 'hover', 'focus', 'target', 'lang(', 'enabled', 'disabled', 'checked', ':first-line', ':first-letter', ':before', ':after', // CSS 2.1 'first-line', 'first-letter', 'before', 'after', // CSS 3 'not(', ); /** * @var string property name */ public $name; /** * @var string property value or expression to evaluate */ public $value; /** * SassPropertyNode constructor. * @param object source token * @param string property syntax * @return SassPropertyNode */ public function __construct($token, $syntax = 'new') { parent::__construct($token); $matches = self::match($token, $syntax); $this->name = @$matches[self::NAME]; if (!isset($matches[self::VALUE])) { $this->value = ''; } else { $this->value = $matches[self::VALUE]; if ($matches[self::SCRIPT] === self::IS_SCRIPT) { $this->addWarning('Setting CSS properties with "=" is deprecated; use "{name}: {value};"', array('{name}'=>$this->name, '{value}'=>$this->value) ); } } } /** * Parse this node. * If the node is a property namespace return all parsed child nodes. If not * return the parsed version of this node. * @param SassContext the context in which this node is parsed * @return array the parsed node */ public function parse($context) { $return = array(); if ($this->value !== "") { $node = clone $this; $node->name = ($this->inNamespace() ? "{$this->namespace}-" : '') . $this->interpolate($this->name, $context); $result = $this->evaluate($this->interpolate($this->value, $context), $context, SassScriptParser::CSS_PROPERTY); $node->value = $result && is_object($result) ? $result->toString() : $this->value; $return[] = $node; } if ($this->children) { $return = array_merge($return, $this->parseChildren($context)); } return $return; } /** * Render this node. * @return string the rendered node */ public function render() { return $this->renderer->renderProperty($this); } /** * Returns a value indicating if this node is in a namespace * @return boolean true if this node is in a property namespace, false if not */ public function inNamespace() { $parent = $this->parent; do { if ($parent instanceof SassPropertyNode) { return true; } $parent = $parent->parent; } while (is_object($parent)); return false; } /** * Returns the namespace for this node * @return string the namespace for this node */ public function getNamespace() { $namespace = array(); $parent = $this->parent; do { if ($parent instanceof SassPropertyNode) { $namespace[] = $parent->name; } $parent = $parent->parent; } while (is_object($parent)); return join('-', array_reverse($namespace)); } /** * Returns the name of this property. * If the property is in a namespace the namespace is prepended * @return string the name of this property */ public function getName() { return $this->name; } /** * Returns the parsed value of this property. * @return string the parsed value of this property */ public function getValue() { return $this->value; } /** * Returns a value indicating if the token represents this type of node. * @param object token * @param string the property syntax being used * @return boolean true if the token represents this type of node, false if not */ public static function isa($token) { if(!is_array($token)) { $syntax = 'old'; } else { $syntax = $token['syntax']; $token = $token['token']; } $matches = self::match($token, $syntax); if (!empty($matches)) { if (isset($matches[self::VALUE]) && self::isPseudoSelector($matches[self::VALUE])) { return false; } if ($token->level === 0) { # RL - if it's on the first level it's probably a false positive, not an error. # even if it is a genuine error, no need to kill the compiler about it. return false; // throw new SassPropertyNodeException('Properties can not be assigned at root level', $token); } else { return true; } } else { return false; } } /** * Returns the matches for this type of node. * @param array the line to match * @param string the property syntax being used * @return array matches */ public static function match($token, $syntax) { switch ($syntax) { case 'new': preg_match(self::MATCH_PROPERTY_NEW, $token->source, $matches); break; case 'old': preg_match(self::MATCH_PROPERTY_OLD, $token->source, $matches); break; default: if (preg_match(self::MATCH_PROPERTY_NEW, $token->source, $matches) == 0) { preg_match(self::MATCH_PROPERTY_OLD, $token->source, $matches); } break; } return $matches; } /** * Returns a value indicating if the string starts with a pseudo selector. * This is used to reject pseudo selectors as property values as, for example, * "a:hover" and "text-decoration:underline" look the same to the property * match regex. * It will also match interpolation to allow for constructs such as * content:#{$pos} * @see isa() * @param string the string to test * @return bool true if the string starts with a pseudo selector, false if not */ public static function isPseudoSelector($string) { preg_match(self::MATCH_PSUEDO_SELECTOR, $string, $matches); return (isset($matches[0]) && in_array($matches[0], self::$psuedoSelectors)) || preg_match(self::MATCH_INTERPOLATION, $string) || preg_match(self::MATCH_PROPRIETARY_SELECTOR, $string); } } |