diff --git a/src/CSSList/CSSBlockList.php b/src/CSSList/CSSBlockList.php index 8c58fbf9..4db38bfa 100644 --- a/src/CSSList/CSSBlockList.php +++ b/src/CSSList/CSSBlockList.php @@ -140,4 +140,27 @@ protected function allSelectors(array &$aResult, $sSpecificitySearch = null) } } } + + /** + * @param CSSList|Rule|RuleSet|Value $oElement + * @param array $aResult + * + * @return void + */ + protected function allFunctions($oElement, array &$aResult) + { + if ($oElement instanceof CSSBlockList) { + foreach ($oElement->getContents() as $oContent) { + $this->allFunctions($oContent, $aResult); + } + } elseif ($oElement instanceof RuleSet) { + foreach ($oElement->getRules() as $oRule) { + $this->allFunctions($oRule, $aResult); + } + } elseif ($oElement instanceof Rule) { + $this->allFunctions($oElement->getValue(), $aResult); + } elseif ($oElement instanceof CSSFunction) { + $aResult[] = $oElement; + } + } } diff --git a/src/CSSList/Document.php b/src/CSSList/Document.php index 822f3995..1ae31d01 100644 --- a/src/CSSList/Document.php +++ b/src/CSSList/Document.php @@ -109,6 +109,26 @@ public function getSelectorsBySpecificity($sSpecificitySearch = null) return $aResult; } + /** + * Returns all `CSSFunction` objects recursively found in the tree, no matter how deeply nested the rule sets are. + * + * @param CSSList|RuleSet|string $mElement + * the `CSSList` or `RuleSet` to start the search from (defaults to the whole document). + * If a string is given, it is used as rule name filter. + * + * @return array + */ + public function getAllFunctions($mElement = null) + { + if ($mElement === null) { + $mElement = $this; + } + /** @var array $aResult */ + $aResult = []; + $this->allFunctions($mElement, $aResult); + return $aResult; + } + /** * Expands all shorthand properties to their long value. * diff --git a/src/Value/Size.php b/src/Value/Size.php index 8fd92f13..18466f05 100644 --- a/src/Value/Size.php +++ b/src/Value/Size.php @@ -23,6 +23,7 @@ class Size extends PrimitiveValue 'vh', 'dvh', 'svh', 'lvh', 'vw', 'vmin', 'vmax', 'rem', 'svw', 'lvw', 'dvw', + 'x', 'dppx', 'dpi', 'dpcm', ]; /** diff --git a/tests/ParserTest.php b/tests/ParserTest.php index 965376d0..8f1422a7 100644 --- a/tests/ParserTest.php +++ b/tests/ParserTest.php @@ -1325,4 +1325,19 @@ public function escapedSpecialCaseTokens(): void self::assertTrue(\is_a($urlRule->getValue(), '\\Sabberworm\\CSS\\Value\\URL')); self::assertTrue(\is_a($calcRule->getValue(), '\\Sabberworm\\CSS\\Value\\CalcFunction')); } + + /** + * @test + */ + public function imagesetInFile(): void + { + $oDoc = self::parsedStructureForFile('image-set', Settings::create()->withMultibyteSupport(true)); + $sExpected = sprintf( + '%s%s%s', + '.home_banner {background-image: image-set(url("https://www.example.us/images/home-banner.webp") 1x,', + 'url("https://www.example.us/images/home-banner@2x.webp") 2x,', + 'url("https://www.example.us/images/home-banner@3x.webp") 3x);}' + ); + self::assertSame($sExpected, $oDoc->render()); + } } diff --git a/tests/fixtures/image-set.css b/tests/fixtures/image-set.css new file mode 100644 index 00000000..17e3d606 --- /dev/null +++ b/tests/fixtures/image-set.css @@ -0,0 +1 @@ +.home_banner{background-image: image-set(url(https://www.example.us/images/home-banner.webp) 1x,url(https://www.example.us/images/home-banner@2x.webp) 2x,url(https://www.example.us/images/home-banner@3x.webp) 3x);} \ No newline at end of file