diff --git a/lib/Sabberworm/CSS/CSSList/CSSList.php b/lib/Sabberworm/CSS/CSSList/CSSList.php index 9cd970fe..debf9122 100644 --- a/lib/Sabberworm/CSS/CSSList/CSSList.php +++ b/lib/Sabberworm/CSS/CSSList/CSSList.php @@ -6,6 +6,7 @@ use Sabberworm\CSS\Parsing\ParserState; use Sabberworm\CSS\Parsing\SourceException; use Sabberworm\CSS\Parsing\UnexpectedTokenException; +use Sabberworm\CSS\Parsing\UnexpectedEOFException; use Sabberworm\CSS\Property\AtRule; use Sabberworm\CSS\Property\Charset; use Sabberworm\CSS\Property\CSSNamespace; @@ -111,14 +112,14 @@ private static function parseAtRule(ParserState $oParserState) { $oParserState->consumeWhiteSpace(); $sMediaQuery = null; if (!$oParserState->comes(';')) { - $sMediaQuery = $oParserState->consumeUntil(';'); + $sMediaQuery = trim($oParserState->consumeUntil(array(';', ParserState::EOF))); } - $oParserState->consume(';'); + $oParserState->consumeUntil(array(';', ParserState::EOF), true, true); return new Import($oLocation, $sMediaQuery, $iIdentifierLineNum); } else if ($sIdentifier === 'charset') { $sCharset = CSSString::parse($oParserState); $oParserState->consumeWhiteSpace(); - $oParserState->consume(';'); + $oParserState->consumeUntil(array(';', ParserState::EOF), true, true); return new Charset($sCharset, $iIdentifierLineNum); } else if (self::identifierIs($sIdentifier, 'keyframes')) { $oResult = new KeyFrame($iIdentifierLineNum); @@ -136,7 +137,7 @@ private static function parseAtRule(ParserState $oParserState) { $sPrefix = $mUrl; $mUrl = Value::parsePrimitiveValue($oParserState); } - $oParserState->consume(';'); + $oParserState->consumeUntil(array(';', ParserState::EOF), true, true); if ($sPrefix !== null && !is_string($sPrefix)) { throw new UnexpectedTokenException('Wrong namespace prefix', $sPrefix, 'custom', $iIdentifierLineNum); } diff --git a/lib/Sabberworm/CSS/Parsing/ParserState.php b/lib/Sabberworm/CSS/Parsing/ParserState.php index b57b7e90..ad79820a 100644 --- a/lib/Sabberworm/CSS/Parsing/ParserState.php +++ b/lib/Sabberworm/CSS/Parsing/ParserState.php @@ -3,9 +3,12 @@ use Sabberworm\CSS\Comment\Comment; use Sabberworm\CSS\Parsing\UnexpectedTokenException; +use Sabberworm\CSS\Parsing\UnexpectedEOFException; use Sabberworm\CSS\Settings; class ParserState { + const EOF = null; + private $oParserSettings; private $sText; @@ -118,8 +121,7 @@ public function consumeWhiteSpace() { if($this->oParserSettings->bLenientParsing) { try { $oComment = $this->consumeComment(); - } catch(UnexpectedTokenException $e) { - // When we can’t find the end of a comment, we assume the document is finished. + } catch(UnexpectedEOFException $e) { $this->iCurrentPosition = $this->iLength; return; } @@ -160,7 +162,7 @@ public function consume($mValue = 1) { return $mValue; } else { if ($this->iCurrentPosition + $mValue > $this->iLength) { - throw new UnexpectedTokenException($mValue, $this->peek(5), 'count', $this->iLineNo); + throw new UnexpectedEOFException($mValue, $this->peek(5), 'count', $this->iLineNo); } $sResult = $this->substr($this->iCurrentPosition, $mValue); $iLineCount = substr_count($sResult, "\n"); @@ -214,7 +216,8 @@ public function consumeUntil($aEnd, $bIncludeEnd = false, $consumeEnd = false, a $out = ''; $start = $this->iCurrentPosition; - while (($char = $this->consume(1)) !== '') { + while (!$this->isEnd()) { + $char = $this->consume(1); if (in_array($char, $aEnd)) { if ($bIncludeEnd) { $out .= $char; @@ -229,8 +232,12 @@ public function consumeUntil($aEnd, $bIncludeEnd = false, $consumeEnd = false, a } } + if (in_array(self::EOF, $aEnd)) { + return $out; + } + $this->iCurrentPosition = $start; - throw new UnexpectedTokenException('One of ("'.implode('","', $aEnd).'")', $this->peek(5), 'search', $this->iLineNo); + throw new UnexpectedEOFException('One of ("'.implode('","', $aEnd).'")', $this->peek(5), 'search', $this->iLineNo); } private function inputLeft() { @@ -309,4 +316,4 @@ private function strpos($sString, $sNeedle, $iOffset) { return strpos($sString, $sNeedle, $iOffset); } } -} \ No newline at end of file +} diff --git a/lib/Sabberworm/CSS/Parsing/UnexpectedEOFException.php b/lib/Sabberworm/CSS/Parsing/UnexpectedEOFException.php new file mode 100644 index 00000000..e3d89489 --- /dev/null +++ b/lib/Sabberworm/CSS/Parsing/UnexpectedEOFException.php @@ -0,0 +1,9 @@ +assertSame($sExpected, $oDoc->render()); } + + function testLonelyImport() { + $oDoc = $this->parsedStructureForFile('lonely-import'); + $sExpected = "@import url(\"example.css\") only screen and (max-width: 600px);"; + $this->assertSame($sExpected, $oDoc->render()); + } } diff --git a/tests/files/lonely-import.css b/tests/files/lonely-import.css new file mode 100644 index 00000000..87767bba --- /dev/null +++ b/tests/files/lonely-import.css @@ -0,0 +1 @@ +@import "example.css" only screen and (max-width: 600px) \ No newline at end of file