From 278ca0051cc0e5ad0e3131a0625c86e1b01bed97 Mon Sep 17 00:00:00 2001 From: snap01 <43982555+snap01@users.noreply.github.com> Date: Mon, 2 Sep 2024 18:05:45 +0100 Subject: [PATCH] Support for supports and layers in @import statements --- src/CSS.php | 38 ++++++++++++++++++++ tests/CSS/CSSTest.php | 34 ++++++++++++++++++ tests/CSS/sample/combine_imports/import2.css | 3 ++ tests/CSS/sample/combine_imports/index10.css | 2 ++ tests/CSS/sample/combine_imports/index11.css | 2 ++ tests/CSS/sample/combine_imports/index12.css | 2 ++ tests/CSS/sample/combine_imports/index7.css | 2 ++ tests/CSS/sample/combine_imports/index8.css | 3 ++ tests/CSS/sample/combine_imports/index9.css | 1 + tests/JS/JSTest.php | 2 ++ 10 files changed, 89 insertions(+) create mode 100644 tests/CSS/sample/combine_imports/import2.css create mode 100644 tests/CSS/sample/combine_imports/index10.css create mode 100644 tests/CSS/sample/combine_imports/index11.css create mode 100644 tests/CSS/sample/combine_imports/index12.css create mode 100644 tests/CSS/sample/combine_imports/index7.css create mode 100644 tests/CSS/sample/combine_imports/index8.css create mode 100644 tests/CSS/sample/combine_imports/index9.css diff --git a/src/CSS.php b/src/CSS.php index 4f56320c..9d636b87 100644 --- a/src/CSS.php +++ b/src/CSS.php @@ -33,6 +33,8 @@ class CSS extends Minify */ protected $maxImportSize = 5; + protected $maxSupportsNesting = 5; + /** * @var string[] valid import extensions */ @@ -146,6 +148,18 @@ protected function combineImports($source, $content, $parents) # (optional) trailing whitespace \s* + # layer + (?Player(\((?P[^\)]+)\))?)? + + # (optional) trailing whitespace + \s* + + # supports + (?Psupports'.str_repeat('\([^)(]*(?:', $this->maxSupportsNesting).'\([^)(]*\)'.str_repeat('[^)(]*)*\)', $this->maxSupportsNesting).')? + + # (optional) trailing whitespace + \s* + # (optional) media statement(s) (?P[^;]*) @@ -178,6 +192,18 @@ protected function combineImports($source, $content, $parents) # (optional) trailing whitespace \s* + # layer + (?Player(\((?P[^\)]+)\))?)? + + # (optional) trailing whitespace + \s* + + # supports + (?Psupports'.str_repeat('\([^)(]*(?:', $this->maxSupportsNesting).'\([^)(]*\)'.str_repeat('[^)(]*)*\)', $this->maxSupportsNesting).')? + + # (optional) trailing whitespace + \s* + # (optional) media statement(s) (?P[^;]*) @@ -225,6 +251,18 @@ protected function combineImports($source, $content, $parents) $minifier->setImportExtensions($this->importExtensions); $importContent = $minifier->execute($source, $parents); + // check if this is only valid for certain layers (named or unnamed) + if (!empty($match['layerName'])) { + $importContent = '@layer ' . $match['layerName'] . '{' . $importContent . '}'; + } elseif (!empty($match['layer'])) { + $importContent = '@layer{' . $importContent . '}'; + } + + // check if this is only valid for certain layers (named or unnamed) + if (!empty($match['supports'])) { + $importContent = '@' . $match['supports'] . '{' . $importContent . '}'; + } + // check if this is only valid for certain media if (!empty($match['media'])) { $importContent = '@media ' . $match['media'] . '{' . $importContent . '}'; diff --git a/tests/CSS/CSSTest.php b/tests/CSS/CSSTest.php index 0046c4ed..6fe398aa 100644 --- a/tests/CSS/CSSTest.php +++ b/tests/CSS/CSSTest.php @@ -3,6 +3,7 @@ namespace MatthiasMullie\Minify\Tests\CSS; use MatthiasMullie\Minify\Tests\CompatTestCase; +use PHPUnit\Framework\Attributes\DataProvider; /** * CSS minifier test case. @@ -21,6 +22,7 @@ protected function getMinifier() * * @dataProvider dataProvider */ + #[dataProvider('dataProvider')] public function testMinify($input, $expected) { $minifier = $this->getMinifier(); @@ -34,6 +36,7 @@ public function testMinify($input, $expected) * * @dataProvider dataProviderPaths */ + #[dataProvider('dataProviderPaths')] public function testConvertRelativePath($source, $target, $expected) { $minifier = $this->getMinifier(); @@ -877,6 +880,37 @@ public static function dataProvider() 'a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:none}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}', ); + // https://github.com/matthiasmullie/minify/issues/428 + $tests[] = array( + __DIR__ . '/sample/combine_imports/index7.css', + '@layer;@layer{body{color:red}}' + ); + + $tests[] = array( + __DIR__ . '/sample/combine_imports/index8.css', + '@layer testLayer1,testLayer2;@layer testLayer1{body{color:blue}}@layer testLayer2{body{color:red}}' + ); + + $tests[] = array( + __DIR__ . '/sample/combine_imports/index9.css', + '@supports(((display:grid) and (selector(h2>p))) or (not (display:flex))){body{color:red}}' + ); + + $tests[] = array( + __DIR__ . '/sample/combine_imports/index10.css', + '@layer;@supports(((display:grid) and (selector(h2>p))) or (not (display:flex))){@layer{body{color:red}}}' + ); + + $tests[] = array( + __DIR__ . '/sample/combine_imports/index11.css', + '@layer testLayer1;@supports(((display:grid) and (selector(h2>p))) or (not (display:flex))){@layer testLayer1{body{color:red}}}' + ); + + $tests[] = array( + __DIR__ . '/sample/combine_imports/index12.css', + '@layer testLayer1;@media screen and (orientation:landscape){@supports(((display:grid) and (selector(h2>p))) or (not (display:flex))){@layer testLayer1{body{color:red}}}}' + ); + return $tests; } diff --git a/tests/CSS/sample/combine_imports/import2.css b/tests/CSS/sample/combine_imports/import2.css new file mode 100644 index 00000000..13b96b36 --- /dev/null +++ b/tests/CSS/sample/combine_imports/import2.css @@ -0,0 +1,3 @@ +body { + color: blue; +} diff --git a/tests/CSS/sample/combine_imports/index10.css b/tests/CSS/sample/combine_imports/index10.css new file mode 100644 index 00000000..4c0c0b63 --- /dev/null +++ b/tests/CSS/sample/combine_imports/index10.css @@ -0,0 +1,2 @@ +@layer; +@import url('import.css') layer supports(((display: grid) and (selector(h2 > p))) or (not (display: flex))); \ No newline at end of file diff --git a/tests/CSS/sample/combine_imports/index11.css b/tests/CSS/sample/combine_imports/index11.css new file mode 100644 index 00000000..224a0472 --- /dev/null +++ b/tests/CSS/sample/combine_imports/index11.css @@ -0,0 +1,2 @@ +@layer testLayer1; +@import url('import.css') layer(testLayer1) supports(((display: grid) and (selector(h2 > p))) or (not (display: flex))); \ No newline at end of file diff --git a/tests/CSS/sample/combine_imports/index12.css b/tests/CSS/sample/combine_imports/index12.css new file mode 100644 index 00000000..08dd63a6 --- /dev/null +++ b/tests/CSS/sample/combine_imports/index12.css @@ -0,0 +1,2 @@ +@layer testLayer1; +@import url('import.css') layer(testLayer1) supports(((display: grid) and (selector(h2 > p))) or (not (display: flex))) screen and (orientation: landscape); \ No newline at end of file diff --git a/tests/CSS/sample/combine_imports/index7.css b/tests/CSS/sample/combine_imports/index7.css new file mode 100644 index 00000000..359bfd9f --- /dev/null +++ b/tests/CSS/sample/combine_imports/index7.css @@ -0,0 +1,2 @@ +@layer; +@import url('import.css') layer; \ No newline at end of file diff --git a/tests/CSS/sample/combine_imports/index8.css b/tests/CSS/sample/combine_imports/index8.css new file mode 100644 index 00000000..0e199ddc --- /dev/null +++ b/tests/CSS/sample/combine_imports/index8.css @@ -0,0 +1,3 @@ +@layer testLayer1, testLayer2; +@import url('import2.css') layer(testLayer1); +@import url('import.css') layer(testLayer2); \ No newline at end of file diff --git a/tests/CSS/sample/combine_imports/index9.css b/tests/CSS/sample/combine_imports/index9.css new file mode 100644 index 00000000..f746833c --- /dev/null +++ b/tests/CSS/sample/combine_imports/index9.css @@ -0,0 +1 @@ +@import url('import.css') supports(((display: grid) and (selector(h2 > p))) or (not (display: flex))); \ No newline at end of file diff --git a/tests/JS/JSTest.php b/tests/JS/JSTest.php index 7e0e1566..22dafa14 100644 --- a/tests/JS/JSTest.php +++ b/tests/JS/JSTest.php @@ -3,6 +3,7 @@ namespace MatthiasMullie\Minify\Tests\JS; use MatthiasMullie\Minify\Tests\CompatTestCase; +use PHPUnit\Framework\Attributes\DataProvider; /** * JS minifier test case. @@ -45,6 +46,7 @@ public function testAddFile() * * @dataProvider dataProvider */ + #[dataProvider('dataProvider')] public function testMinify($input, $expected) { $minifier = $this->getMinifier();