From 29c1d8470e4f2090d6ef2ab9497fc88e81667f3b Mon Sep 17 00:00:00 2001 From: raxbg Date: Mon, 24 Sep 2018 11:20:33 +0300 Subject: [PATCH 1/3] Add support for unicode-range --- lib/Sabberworm/CSS/Parser.php | 10 ++++++++++ tests/Sabberworm/CSS/ParserTest.php | 6 ++++++ tests/files/unicode-range.css | 3 +++ 3 files changed, 19 insertions(+) create mode 100644 tests/files/unicode-range.css diff --git a/lib/Sabberworm/CSS/Parser.php b/lib/Sabberworm/CSS/Parser.php index adc0d390..f539f346 100644 --- a/lib/Sabberworm/CSS/Parser.php +++ b/lib/Sabberworm/CSS/Parser.php @@ -454,6 +454,8 @@ private function parsePrimitiveValue() { $oValue = $this->parseMicrosoftFilter(); } else if ($this->comes("[")) { $oValue = $this->parseLineNameValue(); + } else if ($this->comes("U+")) { + $oValue = $this->parseUnicodeRangeValue(); } else { $oValue = $this->parseIdentifier(true, false); } @@ -505,6 +507,14 @@ private function parseLineNameValue() { return new LineName($aNames, $this->iLineNo); } + private function parseUnicodeRangeValue() { + $sRange = ""; + do { + $sRange .= $this->consume(1); + } while (!$this->comes(',') && !$this->comes(';') && !$this->comes('}')); + return $sRange; + } + private function parseColorValue() { $aColor = array(); if ($this->comes('#')) { diff --git a/tests/Sabberworm/CSS/ParserTest.php b/tests/Sabberworm/CSS/ParserTest.php index ea8bbdf5..2ab28f27 100644 --- a/tests/Sabberworm/CSS/ParserTest.php +++ b/tests/Sabberworm/CSS/ParserTest.php @@ -126,6 +126,12 @@ function testUnicodeParsing() { } } + function testUnicodeRangeParsing() { + $oDoc = $this->parsedStructureForFile('unicode-range'); + $sExpected = "@font-face {unicode-range: U+0100-024F,U+0259,U+1E??-2EFF,U+202F;}"; + $this->assertSame($sExpected, $oDoc->render()); + } + function testSpecificity() { $oDoc = $this->parsedStructureForFile('specificity'); $oDeclarationBlock = $oDoc->getAllDeclarationBlocks(); diff --git a/tests/files/unicode-range.css b/tests/files/unicode-range.css new file mode 100644 index 00000000..d5e152a0 --- /dev/null +++ b/tests/files/unicode-range.css @@ -0,0 +1,3 @@ +@font-face { + unicode-range: U+0100-024F, U+0259, U+1E??-2EFF, U+202F; +} From 37f0bad6a99616afb587639c0c8925d78ebae3b5 Mon Sep 17 00:00:00 2001 From: raxbg Date: Mon, 24 Sep 2018 11:42:12 +0300 Subject: [PATCH 2/3] Tighter loop constraints when parsing unicode-range --- lib/Sabberworm/CSS/Parser.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/Sabberworm/CSS/Parser.php b/lib/Sabberworm/CSS/Parser.php index f539f346..00709d92 100644 --- a/lib/Sabberworm/CSS/Parser.php +++ b/lib/Sabberworm/CSS/Parser.php @@ -508,11 +508,14 @@ private function parseLineNameValue() { } private function parseUnicodeRangeValue() { + $iCodepointMaxLenth = 6; // Code points outside BMP can use up to six digits $sRange = ""; + $this->consume("U+"); do { + if ($this->comes('-')) $iCodepointMaxLenth = 13; // Max length is 2 six digit code points + the dash(-) between them $sRange .= $this->consume(1); - } while (!$this->comes(',') && !$this->comes(';') && !$this->comes('}')); - return $sRange; + } while (strlen($sRange) < $iCodepointMaxLenth && preg_match("/[A-Fa-f0-9\?-]/", $this->peek())); + return "U+{$sRange}"; } private function parseColorValue() { From 9966dbe1013b187a4238309d91ce5e1b47bd6f51 Mon Sep 17 00:00:00 2001 From: raxbg Date: Mon, 19 Nov 2018 15:31:09 +0200 Subject: [PATCH 3/3] Reimplement the unicode-range support after the parser logic refactor --- lib/Sabberworm/CSS/Value/Value.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/Sabberworm/CSS/Value/Value.php b/lib/Sabberworm/CSS/Value/Value.php index 5c550498..ed478877 100644 --- a/lib/Sabberworm/CSS/Value/Value.php +++ b/lib/Sabberworm/CSS/Value/Value.php @@ -88,6 +88,8 @@ public static function parsePrimitiveValue(ParserState $oParserState) { $oValue = self::parseMicrosoftFilter($oParserState); } else if ($oParserState->comes("[")) { $oValue = LineName::parse($oParserState); + } else if ($oParserState->comes("U+")) { + $oValue = self::parseUnicodeRangeValue($oParserState); } else { $oValue = self::parseIdentifierOrFunction($oParserState); } @@ -100,6 +102,17 @@ private static function parseMicrosoftFilter(ParserState $oParserState) { $aArguments = Value::parseValue($oParserState, array(',', '=')); return new CSSFunction($sFunction, $aArguments, ',', $oParserState->currentLine()); } + + private static function parseUnicodeRangeValue(ParserState $oParserState) { + $iCodepointMaxLenth = 6; // Code points outside BMP can use up to six digits + $sRange = ""; + $oParserState->consume("U+"); + do { + if ($oParserState->comes('-')) $iCodepointMaxLenth = 13; // Max length is 2 six digit code points + the dash(-) between them + $sRange .= $oParserState->consume(1); + } while (strlen($sRange) < $iCodepointMaxLenth && preg_match("/[A-Fa-f0-9\?-]/", $oParserState->peek())); + return "U+{$sRange}"; + } /** * @return int