Skip to content

Commit 519dd61

Browse files
committed
Allow lenient parsing (on by default)
Closes MyIntervals#51 as fixed
1 parent 569dbf7 commit 519dd61

File tree

4 files changed

+68
-8
lines changed

4 files changed

+68
-8
lines changed

lib/Sabberworm/CSS/Parser.php

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,23 @@ private function parseRuleSet($oRuleSet) {
249249
$this->consumeWhiteSpace();
250250
}
251251
while (!$this->comes('}')) {
252-
$oRuleSet->addRule($this->parseRule());
252+
$oRule = null;
253+
if($this->oParserSettings->bLenientParsing) {
254+
try {
255+
$oRule = $this->parseRule();
256+
} catch (UnexpectedTokenException $e) {
257+
$this->consumeUntil(array("\n", ";"), true);
258+
$this->consumeWhiteSpace();
259+
while ($this->comes(';')) {
260+
$this->consume(';');
261+
}
262+
}
263+
} else {
264+
$oRule = $this->parseRule();
265+
}
266+
if($oRule) {
267+
$oRuleSet->addRule($oRule);
268+
}
253269
$this->consumeWhiteSpace();
254270
}
255271
$this->consume('}');
@@ -506,10 +522,20 @@ private function isEnd() {
506522
return $this->iCurrentPosition >= $this->iLength;
507523
}
508524

509-
private function consumeUntil($sEnd) {
510-
$iEndPos = mb_strpos($this->sText, $sEnd, $this->iCurrentPosition, $this->sCharset);
511-
if ($iEndPos === false) {
512-
throw new UnexpectedTokenException($sEnd, $this->peek(5), 'search');
525+
private function consumeUntil($aEnd, $bIncludeEnd = false) {
526+
$aEnd = is_array($aEnd) ? $aEnd : array($aEnd);
527+
$iEndPos = null;
528+
foreach ($aEnd as $sEnd) {
529+
$iCurrentEndPos = mb_strpos($this->sText, $sEnd, $this->iCurrentPosition, $this->sCharset);
530+
if($iCurrentEndPos === false) {
531+
continue;
532+
}
533+
if($iEndPos === null || $iCurrentEndPos < $iEndPos) {
534+
$iEndPos = $iCurrentEndPos + ($bIncludeEnd ? $this->strlen($sEnd) : 0);
535+
}
536+
}
537+
if ($iEndPos === null) {
538+
throw new UnexpectedTokenException($aEnd, $this->peek(5), 'search');
513539
}
514540
return $this->consume($iEndPos - $this->iCurrentPosition);
515541
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Sabberworm\CSS\RuleSet;
4+
5+
use Sabberworm\CSS\Parser;
6+
use Sabberworm\CSS\Settings;
7+
8+
class LenientParsingTest extends \PHPUnit_Framework_TestCase {
9+
10+
/**
11+
* @expectedException Sabberworm\CSS\Parsing\UnexpectedTokenException
12+
*/
13+
public function testFaultToleranceOff() {
14+
$sFile = dirname(__FILE__) . '/../../../files' . DIRECTORY_SEPARATOR . "fault-tolerance.css";
15+
$oParser = new Parser(file_get_contents($sFile), Settings::create()->beStrict());
16+
$oParser->parse();
17+
}
18+
19+
public function testFaultToleranceOn() {
20+
$sFile = dirname(__FILE__) . '/../../../files' . DIRECTORY_SEPARATOR . "fault-tolerance.css";
21+
$oParser = new Parser(file_get_contents($sFile), Settings::create()->withLenientParsing(true));
22+
$oResult = $oParser->parse();
23+
$this->assertSame('.test1 {}'."\n".'.test2 {hello: 2;}'."\n", $oResult->__toString());
24+
}
25+
26+
}

tests/files/atrules.css

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
@charset "utf-8";
22

33
@font-face {
4-
font-family: "CrassRoots";
5-
src: url("../media/cr.ttf")
4+
font-family: "CrassRoots";
5+
src: url("../media/cr.ttf")
66
}
77

88
html, body {
9-
font-size: 1.6em
9+
font-size: 1.6em
1010
}
1111

1212
@keyframes mymove {

tests/files/fault-tolerance.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.test1 {
2+
//gaga: hello;
3+
}
4+
5+
.test2 {
6+
*hello: 1;
7+
hello: 2;
8+
}

0 commit comments

Comments
 (0)