1*04fd306cSNickeau<?php 2*04fd306cSNickeau/** 3*04fd306cSNickeau * An element (token) generated by the scan 4*04fd306cSNickeau * 5*04fd306cSNickeau * @license http://www.opensource.org/licenses/mit-license.php The MIT License 6*04fd306cSNickeau * @copyright Copyright 2010-2014 PhpCss Team 7*04fd306cSNickeau */ 8*04fd306cSNickeau 9*04fd306cSNickeaunamespace PhpCss\Scanner { 10*04fd306cSNickeau 11*04fd306cSNickeau use BadMethodCallException; 12*04fd306cSNickeau use InvalidArgumentException; 13*04fd306cSNickeau 14*04fd306cSNickeau /** 15*04fd306cSNickeau * An element (token) generated by the scan 16*04fd306cSNickeau * 17*04fd306cSNickeau * @property-read integer $type 18*04fd306cSNickeau * @property-read string $content 19*04fd306cSNickeau * @property-read integer $length 20*04fd306cSNickeau * @property-read integer $position 21*04fd306cSNickeau */ 22*04fd306cSNickeau class Token { 23*04fd306cSNickeau 24*04fd306cSNickeau // special any token (a joker) 25*04fd306cSNickeau public const ANY = 255; 26*04fd306cSNickeau 27*04fd306cSNickeau //whitespace 28*04fd306cSNickeau public const WHITESPACE = 1; 29*04fd306cSNickeau public const NUMBER = 2; 30*04fd306cSNickeau public const IDENTIFIER = 3; 31*04fd306cSNickeau 32*04fd306cSNickeau //simple selectors 33*04fd306cSNickeau public const CLASS_SELECTOR = 11; 34*04fd306cSNickeau public const ID_SELECTOR = 12; 35*04fd306cSNickeau public const PSEUDO_CLASS = 13; 36*04fd306cSNickeau public const PSEUDO_CLASS_POSITION = 14; 37*04fd306cSNickeau public const PSEUDO_ELEMENT = 15; 38*04fd306cSNickeau 39*04fd306cSNickeau // attribute selectors - [...] 40*04fd306cSNickeau public const ATTRIBUTE_SELECTOR_START = 20; 41*04fd306cSNickeau public const ATTRIBUTE_SELECTOR_END = 21; 42*04fd306cSNickeau public const ATTRIBUTE_OPERATOR = 22; 43*04fd306cSNickeau 44*04fd306cSNickeau // parentheses - (...) 45*04fd306cSNickeau public const PARENTHESES_START = 31; 46*04fd306cSNickeau public const PARENTHESES_END = 32; 47*04fd306cSNickeau 48*04fd306cSNickeau //selector separator 49*04fd306cSNickeau public const COMBINATOR = 41; 50*04fd306cSNickeau public const SEPARATOR = 42; 51*04fd306cSNickeau 52*04fd306cSNickeau //single quoted strings 53*04fd306cSNickeau public const SINGLEQUOTE_STRING_START = 100; 54*04fd306cSNickeau public const SINGLEQUOTE_STRING_END = 101; 55*04fd306cSNickeau // double quoted strings 56*04fd306cSNickeau public const DOUBLEQUOTE_STRING_START = 102; 57*04fd306cSNickeau public const DOUBLEQUOTE_STRING_END = 103; 58*04fd306cSNickeau // string general 59*04fd306cSNickeau public const STRING_CHARACTERS = 110; 60*04fd306cSNickeau public const STRING_ESCAPED_CHARACTER = 111; 61*04fd306cSNickeau 62*04fd306cSNickeau private static $_names = [ 63*04fd306cSNickeau self::ANY => 'ANY', 64*04fd306cSNickeau self::WHITESPACE => 'WHITESPACE', 65*04fd306cSNickeau self::NUMBER => 'NUMBER', 66*04fd306cSNickeau self::IDENTIFIER => 'IDENTIFIER', 67*04fd306cSNickeau self::CLASS_SELECTOR => 'SIMPLESELECTOR_CLASS', 68*04fd306cSNickeau self::ID_SELECTOR => 'SIMPLE_SELECTOR_ID', 69*04fd306cSNickeau self::PSEUDO_CLASS => 'PSEUDOCLASS', 70*04fd306cSNickeau self::PSEUDO_CLASS_POSITION => 'PSEUDOCLASS_POSITION', 71*04fd306cSNickeau self::PSEUDO_ELEMENT => 'PSEUDOELEMENT', 72*04fd306cSNickeau self::ATTRIBUTE_SELECTOR_START => 'SIMPLESELECTOR_ATTRIBUTE_START', 73*04fd306cSNickeau self::ATTRIBUTE_SELECTOR_END => 'SIMPLESELECTOR_ATTRIBUTE_END', 74*04fd306cSNickeau self::ATTRIBUTE_OPERATOR => 'SIMPLESELECTOR_ATTRIBUTE_OPERATOR', 75*04fd306cSNickeau self::PARENTHESES_START => 'PARENTHESES_START', 76*04fd306cSNickeau self::PARENTHESES_END => 'PARENTHESES_END', 77*04fd306cSNickeau self::COMBINATOR => 'SELECTOR_COMBINATOR', 78*04fd306cSNickeau self::SEPARATOR => 'SELECTOR_SEPARATOR', 79*04fd306cSNickeau self::SINGLEQUOTE_STRING_START => 'STRING_SINGLE_QUOTE_START', 80*04fd306cSNickeau self::SINGLEQUOTE_STRING_END => 'STRING_SINGLE_QUOTE_END', 81*04fd306cSNickeau self::DOUBLEQUOTE_STRING_START => 'STRING_DOUBLE_QUOTE_START', 82*04fd306cSNickeau self::DOUBLEQUOTE_STRING_END => 'STRING_DOUBLE_QUOTE_END', 83*04fd306cSNickeau self::STRING_CHARACTERS => 'STRING_CHARACTERS', 84*04fd306cSNickeau self::STRING_ESCAPED_CHARACTER => 'STRING_ESCAPED_CHARACTER', 85*04fd306cSNickeau ]; 86*04fd306cSNickeau 87*04fd306cSNickeau /** 88*04fd306cSNickeau * Token type 89*04fd306cSNickeau * @var integer 90*04fd306cSNickeau */ 91*04fd306cSNickeau private $_type; 92*04fd306cSNickeau /** 93*04fd306cSNickeau * Token string content 94*04fd306cSNickeau * @var string 95*04fd306cSNickeau */ 96*04fd306cSNickeau private $_content; 97*04fd306cSNickeau /** 98*04fd306cSNickeau * Token string content length 99*04fd306cSNickeau * @var integer 100*04fd306cSNickeau */ 101*04fd306cSNickeau private $_length; 102*04fd306cSNickeau /** 103*04fd306cSNickeau * Byte position the token was found at 104*04fd306cSNickeau * @var integer 105*04fd306cSNickeau */ 106*04fd306cSNickeau private $_position; 107*04fd306cSNickeau 108*04fd306cSNickeau /** 109*04fd306cSNickeau * Construct and initialize token 110*04fd306cSNickeau * 111*04fd306cSNickeau * @param integer $type 112*04fd306cSNickeau * @param string $content 113*04fd306cSNickeau * @param integer $position 114*04fd306cSNickeau */ 115*04fd306cSNickeau public function __construct(int $type = 0, string $content = '', int $position = -1) { 116*04fd306cSNickeau $this->_type = $type; 117*04fd306cSNickeau $this->_content = $content; 118*04fd306cSNickeau $this->_length = strlen($content); 119*04fd306cSNickeau $this->_position = $position; 120*04fd306cSNickeau } 121*04fd306cSNickeau 122*04fd306cSNickeau /** 123*04fd306cSNickeau * Get token attribute 124*04fd306cSNickeau * 125*04fd306cSNickeau * @param string $name 126*04fd306cSNickeau * @return int|string 127*04fd306cSNickeau * @throws InvalidArgumentException 128*04fd306cSNickeau */ 129*04fd306cSNickeau public function __get(string $name) { 130*04fd306cSNickeau switch ($name) { 131*04fd306cSNickeau case 'type' : 132*04fd306cSNickeau return $this->_type; 133*04fd306cSNickeau case 'content' : 134*04fd306cSNickeau return $this->_content; 135*04fd306cSNickeau case 'length' : 136*04fd306cSNickeau return $this->_length; 137*04fd306cSNickeau case 'position' : 138*04fd306cSNickeau return $this->_position; 139*04fd306cSNickeau } 140*04fd306cSNickeau throw new InvalidArgumentException(); 141*04fd306cSNickeau } 142*04fd306cSNickeau 143*04fd306cSNickeau /** 144*04fd306cSNickeau * Has token property 145*04fd306cSNickeau * 146*04fd306cSNickeau * @param string $name 147*04fd306cSNickeau * @return bool 148*04fd306cSNickeau */ 149*04fd306cSNickeau public function __isset(string $name): bool { 150*04fd306cSNickeau switch ($name) { 151*04fd306cSNickeau case 'type' : 152*04fd306cSNickeau case 'content' : 153*04fd306cSNickeau case 'length' : 154*04fd306cSNickeau case 'position' : 155*04fd306cSNickeau return TRUE; 156*04fd306cSNickeau } 157*04fd306cSNickeau return FALSE; 158*04fd306cSNickeau } 159*04fd306cSNickeau 160*04fd306cSNickeau /** 161*04fd306cSNickeau * Do not allow to set attributes 162*04fd306cSNickeau * 163*04fd306cSNickeau * @param string $name 164*04fd306cSNickeau * @param mixed $value 165*04fd306cSNickeau * @return void 166*04fd306cSNickeau * @throws BadMethodCallException 167*04fd306cSNickeau */ 168*04fd306cSNickeau public function __set(string $name, $value): void { 169*04fd306cSNickeau throw new BadMethodCallException(); 170*04fd306cSNickeau } 171*04fd306cSNickeau 172*04fd306cSNickeau /** 173*04fd306cSNickeau * Convert token object to string 174*04fd306cSNickeau * @return string 175*04fd306cSNickeau */ 176*04fd306cSNickeau public function __toString() { 177*04fd306cSNickeau return 'TOKEN::'.self::typeToString($this->type). 178*04fd306cSNickeau ' @'.$this->position.' '.$this->quoteContent($this->content); 179*04fd306cSNickeau } 180*04fd306cSNickeau 181*04fd306cSNickeau /** 182*04fd306cSNickeau * Return string representation of token type 183*04fd306cSNickeau * 184*04fd306cSNickeau * @param integer $type 185*04fd306cSNickeau * @return string 186*04fd306cSNickeau */ 187*04fd306cSNickeau public static function typeToString(int $type): string { 188*04fd306cSNickeau return self::$_names[$type]; 189*04fd306cSNickeau } 190*04fd306cSNickeau 191*04fd306cSNickeau /** 192*04fd306cSNickeau * Escape content for double quoted, single line string representation 193*04fd306cSNickeau * 194*04fd306cSNickeau * @param string $content 195*04fd306cSNickeau * @return string 196*04fd306cSNickeau */ 197*04fd306cSNickeau protected function quoteContent(string $content): string { 198*04fd306cSNickeau return "'".str_replace( 199*04fd306cSNickeau ['\\', "\r", "\n", "'"], 200*04fd306cSNickeau ['\\\\', '\\r', '\\n', "\\'"], 201*04fd306cSNickeau $content 202*04fd306cSNickeau )."'"; 203*04fd306cSNickeau } 204*04fd306cSNickeau } 205*04fd306cSNickeau} 206