Skip to content

Commit 75f7b13

Browse files
committed
Match selectors with comments or quoted strings
1 parent 425c78e commit 75f7b13

File tree

4 files changed

+23
-12
lines changed

4 files changed

+23
-12
lines changed

lib/Sabberworm/CSS/Property/Selector.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class Selector {
3838
/ix';
3939

4040
const SELECTOR_VALIDATION_RX = '/
41-
^((?:[a-zA-Z0-9\x{00A0}-\x{FFFF}_\^\$\|\*\=\"\'\~\[\]\(\)\-\s\.:#\+\>]*(?:\\\\.)?)*|\s*?[\+-]?\d+\%\s*)$
41+
^((?:[a-zA-Z0-9\x{00A0}-\x{FFFF}_\^\$\|\*\=\"\'\~\[\]\(\)\-\s\.:#\+\>]*(?:\\\\.)?(?:\'.*?\')?(?:\".*?\")?)*|\s*?[\+-]?\d+\%\s*)$
4242
/ux';
4343

4444
private $sSelector;
@@ -50,7 +50,7 @@ public static function isValid($sSelector) {
5050

5151
public function __construct($sSelector, $bCalculateSpecificity = false) {
5252
if (!Selector::isValid($sSelector)) {
53-
throw new UnexpectedTokenException("Selector did not match '{self::SELECTOR_VALIDATION_RX}'.", $sSelector, "custom");
53+
throw new UnexpectedTokenException("Selector did not match '" . self::SELECTOR_VALIDATION_RX . "'.", $sSelector, "custom");
5454
}
5555
$this->setSelector($sSelector);
5656
if ($bCalculateSpecificity) {

lib/Sabberworm/CSS/RuleSet/DeclarationBlock.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,19 @@ public static function parse(ParserState $oParserState) {
3030
$aComments = array();
3131
$oResult = new DeclarationBlock($oParserState->currentLine());
3232
try {
33-
$oResult->setSelector($oParserState->consume(1) . $oParserState->consumeUntil(array('{', '}'), false, false, $aComments));
33+
$aSelectorParts = array();
34+
$sStringWrapperChar = false;
35+
do {
36+
$aSelectorParts[] = $oParserState->consume(1) . $oParserState->consumeUntil(array('{', '}', '\'', '"'), false, false, $aComments);
37+
if ( in_array($oParserState->peek(), array('\'', '"')) && substr(end($aSelectorParts), -1) != "\\" ) {
38+
if ( $sStringWrapperChar === false ) {
39+
$sStringWrapperChar = $oParserState->peek();
40+
} else if ($sStringWrapperChar == $oParserState->peek()) {
41+
$sStringWrapperChar = false;
42+
}
43+
}
44+
} while (!in_array($oParserState->peek(), array('{', '}')) || $sStringWrapperChar !== false);
45+
$oResult->setSelector(implode('', $aSelectorParts));
3446
if ($oParserState->comes('{')) {
3547
$oParserState->consume(1);
3648
}

tests/Sabberworm/CSS/ParserTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,14 @@ function testSelectorEscapesInFile() {
465465
$this->assertSame($sExpected, $oDoc->render());
466466
}
467467

468+
function testSelectorIgnoresInFile() {
469+
$oDoc = $this->parsedStructureForFile('selector-ignores', Settings::create()->withMultibyteSupport(true));
470+
$sExpected = '.some[selectors-may=\'contain-a-{\'] {}
471+
.this-selector .valid {width: 100px;}
472+
@media only screen and (min-width: 200px) {.test {prop: val;}}';
473+
$this->assertSame($sExpected, $oDoc->render());
474+
}
475+
468476
/**
469477
* @expectedException Sabberworm\CSS\Parsing\UnexpectedTokenException
470478
*/

tests/files/-tobedone.css

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)