public function __construct() { $this->selector = CssSelectorParser::instance(); // Imported rules $this->ws = $this->selector->ws; $this->ident = $this->selector->ident; $this->string = $this->selector->string; $this->num = $this->selector->num; $this->dimension = $this->selector->dimension; $this->positive = $this->selector->positive; $escape = '\\\\[0-9a-fA-F]{1,6}|\\\\[^0-9a-fA-F\\r\\n]+'; $nonascii = '[^\\0-\\177]'; $this->hash = new Concatenate(new Sequence('#', "([a-zA-Z0-9_-]+|{$escape}|{$nonascii})+")); $this->numeric = new Concatenate(new Sequence($this->num, new OptionalChoice('%', $this->ident))); $this->comment = new Ignore(new RegexParser('/\\*.*?\\*/\\s*', 'ms')); $this->values = new Many($this->comment, $this->string, $this->hash, $this->ident, $this->numeric, ',', new WhitespaceParser(1)); $this->function = new Concatenate(new Sequence($this->ident, '(', $this->positive, $this->values, ')')); $this->values->prepend($this->function); $this->declaration = new Closure(new Sequence($this->ident, $this->ws, ':', $this->ws, $this->values, $this->ws, new OptionalChoice('!important')), function ($data) { return new CssDeclaration($data[0], implode(' ', $data[2]), $data[3] !== null); }); $this->ruleset = new Closure(new Sequence($this->selector, $this->positive, $this->ws, '{', $this->ws, new RepSep($this->declaration, ';\\s*'), '}', $this->ws), function ($data) { return new CssRuleSet($data[0], $data[2]); }); $this->root = new Closure(new Many($this->ruleset, $this->comment), function ($data) { return new Css($data); }); }
public function testDoesNotConsumeBlocks() { $input = new Input('h1 {}'); $result = $this->parser->parse($input)->data; $this->assertEquals('Element(h1)', $result->__toString()); $this->assertEquals(' {}', $input->get()); }
public function matches($selector) { if (!is_string($selector)) { throw new \InvalidArgumentException("{$selector} must be a string"); } // When dealing with selectors describing objects commas should denote a match of any of these things. foreach (explode(',', $selector) as $part) { $part = trim($part); $selector = CssSelectorParser::instance()->parseString($part); $object = $selector->define(); $object->isRoot = true; if ($this->matchesObject($object)) { return true; } } return false; }
/** * @param string|CssObject|Selector $selector * @return CssObject * * @throws \LogicException */ public static function buildObject($selector) { if ($selector instanceof CssObject) { return $selector; } if (is_string($selector)) { if (!isset(self::$objectCache[$selector])) { // When dealing with selectors describing objects commas should denote a match of any of these things. // An object that must match all of its children should do this. $choices = []; foreach (explode(',', $selector) as $part) { $part = trim($part); $choices[] = CssSelectorParser::instance()->parseString($part); } self::$objectCache[$selector] = new AllSelector($choices); } $selector = self::$objectCache[$selector]; } if ($selector instanceof Selector) { return $selector->define(); } throw new \LogicException('I dont know how to build an object from ' . get_class($selector)); }