From 4a5e284b5811bf62af89bbef558688875d36bd06 Mon Sep 17 00:00:00 2001 From: JakeQZ Date: Wed, 9 Apr 2025 13:44:00 +0100 Subject: [PATCH 1/6] [TASK] Deconflate getAllValues() parameters This is the backport of #1231, #1240 and #1241. cf. #1230 --- CHANGELOG.md | 1 + src/CSSElement.php | 17 ++++++++++++ src/CSSList/CSSBlockList.php | 3 ++- src/CSSList/CSSList.php | 3 ++- src/CSSList/Document.php | 3 ++- src/Rule/Rule.php | 4 +-- src/RuleSet/RuleSet.php | 3 ++- src/Value/Value.php | 4 +-- tests/Unit/CSSList/CSSListTest.php | 25 ++++++++++++++++++ .../Unit/CSSList/Fixtures/ConcreteCSSList.php | 21 +++++++++++++++ tests/Unit/Rule/RuleTest.php | 11 ++++++++ .../Unit/RuleSet/Fixtures/ConcreteRuleSet.php | 19 ++++++++++++++ tests/Unit/RuleSet/RuleSetTest.php | 25 ++++++++++++++++++ tests/Unit/Value/Fixtures/ConcreteValue.php | 19 ++++++++++++++ tests/Unit/Value/ValueTest.php | 26 +++++++++++++++++++ 15 files changed, 176 insertions(+), 8 deletions(-) create mode 100644 src/CSSElement.php create mode 100644 tests/Unit/CSSList/CSSListTest.php create mode 100644 tests/Unit/CSSList/Fixtures/ConcreteCSSList.php create mode 100644 tests/Unit/RuleSet/Fixtures/ConcreteRuleSet.php create mode 100644 tests/Unit/RuleSet/RuleSetTest.php create mode 100644 tests/Unit/Value/Fixtures/ConcreteValue.php create mode 100644 tests/Unit/Value/ValueTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 891adc8af..4efe3c22d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](https://semver.org/). ### Added +- Add Interface `CSSElement` (#1231) - Methods `getLineNumber` and `getColumnNumber` which return a nullable `int` for the following classes: `Comment`, `CSSList`, `SourceException`, `Charset`, `CSSNamespace`, `Import`, diff --git a/src/CSSElement.php b/src/CSSElement.php new file mode 100644 index 000000000..944aabe2c --- /dev/null +++ b/src/CSSElement.php @@ -0,0 +1,17 @@ + $aResult * @param string|null $sSearchString * @param bool $bSearchInFunctionArguments diff --git a/src/CSSList/CSSList.php b/src/CSSList/CSSList.php index 2156aa111..18d926e15 100644 --- a/src/CSSList/CSSList.php +++ b/src/CSSList/CSSList.php @@ -4,6 +4,7 @@ use Sabberworm\CSS\Comment\Comment; use Sabberworm\CSS\Comment\Commentable; +use Sabberworm\CSS\CSSElement; use Sabberworm\CSS\OutputFormat; use Sabberworm\CSS\Parsing\ParserState; use Sabberworm\CSS\Parsing\SourceException; @@ -31,7 +32,7 @@ * * It can also contain `Import` and `Charset` objects stemming from at-rules. */ -abstract class CSSList implements Commentable, Positionable, Renderable +abstract class CSSList implements Commentable, CSSElement, Positionable { use Position; diff --git a/src/CSSList/Document.php b/src/CSSList/Document.php index f74c89645..ca06b1abd 100644 --- a/src/CSSList/Document.php +++ b/src/CSSList/Document.php @@ -2,6 +2,7 @@ namespace Sabberworm\CSS\CSSList; +use Sabberworm\CSS\CSSElement; use Sabberworm\CSS\OutputFormat; use Sabberworm\CSS\Parsing\ParserState; use Sabberworm\CSS\Parsing\SourceException; @@ -80,7 +81,7 @@ public function getAllRuleSets() /** * Returns all `Value` objects found recursively in `Rule`s in the tree. * - * @param CSSList|RuleSet|string $mElement + * @param CSSElement|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. * @param bool $bSearchInFunctionArguments whether to also return Value objects used as Function arguments. diff --git a/src/Rule/Rule.php b/src/Rule/Rule.php index e358d93f4..a34018a84 100644 --- a/src/Rule/Rule.php +++ b/src/Rule/Rule.php @@ -4,13 +4,13 @@ use Sabberworm\CSS\Comment\Comment; use Sabberworm\CSS\Comment\Commentable; +use Sabberworm\CSS\CSSElement; use Sabberworm\CSS\OutputFormat; use Sabberworm\CSS\Parsing\ParserState; use Sabberworm\CSS\Parsing\UnexpectedEOFException; use Sabberworm\CSS\Parsing\UnexpectedTokenException; use Sabberworm\CSS\Position\Position; use Sabberworm\CSS\Position\Positionable; -use Sabberworm\CSS\Renderable; use Sabberworm\CSS\Value\RuleValueList; use Sabberworm\CSS\Value\Value; @@ -19,7 +19,7 @@ * * In CSS, `Rule`s are expressed as follows: “key: value[0][0] value[0][1], value[1][0] value[1][1];” */ -class Rule implements Commentable, Positionable, Renderable +class Rule implements Commentable, CSSElement, Positionable { use Position; diff --git a/src/RuleSet/RuleSet.php b/src/RuleSet/RuleSet.php index 85b94f263..12b8157ac 100644 --- a/src/RuleSet/RuleSet.php +++ b/src/RuleSet/RuleSet.php @@ -4,6 +4,7 @@ use Sabberworm\CSS\Comment\Comment; use Sabberworm\CSS\Comment\Commentable; +use Sabberworm\CSS\CSSElement; use Sabberworm\CSS\OutputFormat; use Sabberworm\CSS\Parsing\ParserState; use Sabberworm\CSS\Parsing\UnexpectedEOFException; @@ -22,7 +23,7 @@ * If you want to manipulate a `RuleSet`, use the methods `addRule(Rule $rule)`, `getRules()` and `removeRule($rule)` * (which accepts either a `Rule` or a rule name; optionally suffixed by a dash to remove all related rules). */ -abstract class RuleSet implements Commentable, Positionable, Renderable +abstract class RuleSet implements CSSElement, Commentable, Positionable { use Position; diff --git a/src/Value/Value.php b/src/Value/Value.php index beb74464a..3025566f0 100644 --- a/src/Value/Value.php +++ b/src/Value/Value.php @@ -2,19 +2,19 @@ namespace Sabberworm\CSS\Value; +use Sabberworm\CSS\CSSElement; use Sabberworm\CSS\Parsing\ParserState; use Sabberworm\CSS\Parsing\SourceException; use Sabberworm\CSS\Parsing\UnexpectedEOFException; use Sabberworm\CSS\Parsing\UnexpectedTokenException; use Sabberworm\CSS\Position\Position; use Sabberworm\CSS\Position\Positionable; -use Sabberworm\CSS\Renderable; /** * Abstract base class for specific classes of CSS values: `Size`, `Color`, `CSSString` and `URL`, and another * abstract subclass `ValueList`. */ -abstract class Value implements Positionable, Renderable +abstract class Value implements CSSElement, Positionable { use Position; diff --git a/tests/Unit/CSSList/CSSListTest.php b/tests/Unit/CSSList/CSSListTest.php new file mode 100644 index 000000000..6ed4e24c9 --- /dev/null +++ b/tests/Unit/CSSList/CSSListTest.php @@ -0,0 +1,25 @@ +}> */ diff --git a/tests/Unit/RuleSet/Fixtures/ConcreteRuleSet.php b/tests/Unit/RuleSet/Fixtures/ConcreteRuleSet.php new file mode 100644 index 000000000..9c79c09dc --- /dev/null +++ b/tests/Unit/RuleSet/Fixtures/ConcreteRuleSet.php @@ -0,0 +1,19 @@ + Date: Sat, 12 Apr 2025 00:30:01 +0100 Subject: [PATCH 2/6] Remove PHP language features incompatible with 5.6 --- tests/Unit/CSSList/CSSListTest.php | 4 +++- tests/Unit/CSSList/Fixtures/ConcreteCSSList.php | 12 ++++++++++-- tests/Unit/Rule/RuleTest.php | 4 +++- tests/Unit/RuleSet/Fixtures/ConcreteRuleSet.php | 4 +++- tests/Unit/RuleSet/RuleSetTest.php | 4 +++- tests/Unit/Value/Fixtures/ConcreteValue.php | 4 +++- tests/Unit/Value/ValueTest.php | 4 +++- 7 files changed, 28 insertions(+), 8 deletions(-) diff --git a/tests/Unit/CSSList/CSSListTest.php b/tests/Unit/CSSList/CSSListTest.php index 6ed4e24c9..d7fa79cba 100644 --- a/tests/Unit/CSSList/CSSListTest.php +++ b/tests/Unit/CSSList/CSSListTest.php @@ -15,8 +15,10 @@ final class CSSListTest extends TestCase { /** * @test + * + * @return void */ - public function implementsCSSElement(): void + public function implementsCSSElement() { $subject = new ConcreteCSSList(); diff --git a/tests/Unit/CSSList/Fixtures/ConcreteCSSList.php b/tests/Unit/CSSList/Fixtures/ConcreteCSSList.php index 250f2a1b0..ec00ce6f6 100644 --- a/tests/Unit/CSSList/Fixtures/ConcreteCSSList.php +++ b/tests/Unit/CSSList/Fixtures/ConcreteCSSList.php @@ -9,12 +9,20 @@ final class ConcreteCSSList extends CSSList { - public function isRootList(): bool + /** + * @return never + */ + public function isRootList() { throw new \BadMethodCallException('Not implemented', 1740395831); } - public function render(OutputFormat $outputFormat): string + /** + * @param OutputFormat|null $outputFormat + * + * @return never + */ + public function render($outputFormat) { throw new \BadMethodCallException('Not implemented', 1740395836); } diff --git a/tests/Unit/Rule/RuleTest.php b/tests/Unit/Rule/RuleTest.php index d154e6630..8a2f0e6d4 100644 --- a/tests/Unit/Rule/RuleTest.php +++ b/tests/Unit/Rule/RuleTest.php @@ -18,8 +18,10 @@ final class RuleTest extends TestCase { /** * @test + * + * @return void */ - public function implementsCSSElement(): void + public function implementsCSSElement() { $subject = new Rule('beverage-container'); diff --git a/tests/Unit/RuleSet/Fixtures/ConcreteRuleSet.php b/tests/Unit/RuleSet/Fixtures/ConcreteRuleSet.php index 9c79c09dc..0aa966699 100644 --- a/tests/Unit/RuleSet/Fixtures/ConcreteRuleSet.php +++ b/tests/Unit/RuleSet/Fixtures/ConcreteRuleSet.php @@ -10,9 +10,11 @@ final class ConcreteRuleSet extends RuleSet { /** + * @param OutputFormat|null $outputFormat + * * @return never */ - public function render(OutputFormat $outputFormat): string + public function render($outputFormat) { throw new \BadMethodCallException('Nothing to see here :/', 1744067015); } diff --git a/tests/Unit/RuleSet/RuleSetTest.php b/tests/Unit/RuleSet/RuleSetTest.php index 7211a77c9..d5231e1fb 100644 --- a/tests/Unit/RuleSet/RuleSetTest.php +++ b/tests/Unit/RuleSet/RuleSetTest.php @@ -15,8 +15,10 @@ final class RuleSetTest extends TestCase { /** * @test + * + * @return void */ - public function implementsCSSElement(): void + public function implementsCSSElement() { $subject = new ConcreteRuleSet(); diff --git a/tests/Unit/Value/Fixtures/ConcreteValue.php b/tests/Unit/Value/Fixtures/ConcreteValue.php index b6e924805..fe27ac108 100644 --- a/tests/Unit/Value/Fixtures/ConcreteValue.php +++ b/tests/Unit/Value/Fixtures/ConcreteValue.php @@ -10,9 +10,11 @@ final class ConcreteValue extends Value { /** + * @param OutputFormat|null $outputFormat + * * @return never */ - public function render(OutputFormat $outputFormat): string + public function render($outputFormat) { throw new \BadMethodCallException('Nothing to see here :/', 1744067951); } diff --git a/tests/Unit/Value/ValueTest.php b/tests/Unit/Value/ValueTest.php index 27777295d..d9ce5a4f3 100644 --- a/tests/Unit/Value/ValueTest.php +++ b/tests/Unit/Value/ValueTest.php @@ -16,8 +16,10 @@ final class ValueTest extends TestCase { /** * @test + * + * @return void */ - public function implementsCSSElement(): void + public function implementsCSSElement() { $subject = new ConcreteValue(); From 4036801feac55e25517610ab634888f37d894eff Mon Sep 17 00:00:00 2001 From: Jake Hotson Date: Sat, 12 Apr 2025 00:50:14 +0100 Subject: [PATCH 3/6] Add `ConcreteValue::__toString()` --- tests/Unit/Value/Fixtures/ConcreteValue.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/Unit/Value/Fixtures/ConcreteValue.php b/tests/Unit/Value/Fixtures/ConcreteValue.php index fe27ac108..e47e2da5e 100644 --- a/tests/Unit/Value/Fixtures/ConcreteValue.php +++ b/tests/Unit/Value/Fixtures/ConcreteValue.php @@ -18,4 +18,12 @@ public function render($outputFormat) { throw new \BadMethodCallException('Nothing to see here :/', 1744067951); } + + /** + * @return string + */ + public function __toString() + { + return $this->render(new OutputFormat()); + } } From 1ff84efca6c56bf431b5f49987cf7a0361001826 Mon Sep 17 00:00:00 2001 From: JakeQZ Date: Thu, 10 Apr 2025 09:04:19 +0100 Subject: [PATCH 4/6] Apply #1240 --- src/CSSList/CSSBlockList.php | 26 +++ src/CSSList/Document.php | 29 --- tests/Unit/CSSList/CSSBlockListTest.php | 212 ++++++++++++++++++ .../CSSList/Fixtures/ConcreteCSSBlockList.php | 21 ++ 4 files changed, 259 insertions(+), 29 deletions(-) create mode 100644 tests/Unit/CSSList/CSSBlockListTest.php create mode 100644 tests/Unit/CSSList/Fixtures/ConcreteCSSBlockList.php diff --git a/src/CSSList/CSSBlockList.php b/src/CSSList/CSSBlockList.php index 16bf66f9d..c437bf832 100644 --- a/src/CSSList/CSSBlockList.php +++ b/src/CSSList/CSSBlockList.php @@ -59,6 +59,32 @@ protected function allRuleSets(array &$aResult) } } + /** + * Returns all `Value` objects found recursively in `Rule`s in the tree. + * + * @param CSSElement|string $element + * 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. + * @param bool $searchInFunctionArguments whether to also return Value objects used as Function arguments. + * + * @return array + * + * @see RuleSet->getRules() + */ + public function getAllValues($element = null, bool $searchInFunctionArguments = false): array + { + $searchString = null; + if ($element === null) { + $element = $this; + } elseif (\is_string($element)) { + $searchString = $element; + $element = $this; + } + $result = []; + $this->allValues($element, $result, $searchString, $searchInFunctionArguments); + return $result; + } + /** * @param CSSElement|string $oElement * @param array $aResult diff --git a/src/CSSList/Document.php b/src/CSSList/Document.php index ca06b1abd..ed4b09b38 100644 --- a/src/CSSList/Document.php +++ b/src/CSSList/Document.php @@ -2,14 +2,12 @@ namespace Sabberworm\CSS\CSSList; -use Sabberworm\CSS\CSSElement; use Sabberworm\CSS\OutputFormat; use Sabberworm\CSS\Parsing\ParserState; use Sabberworm\CSS\Parsing\SourceException; use Sabberworm\CSS\Property\Selector; use Sabberworm\CSS\RuleSet\DeclarationBlock; use Sabberworm\CSS\RuleSet\RuleSet; -use Sabberworm\CSS\Value\Value; /** * This class represents the root of a parsed CSS file. It contains all top-level CSS contents: mostly declaration @@ -78,33 +76,6 @@ public function getAllRuleSets() return $aResult; } - /** - * Returns all `Value` objects found recursively in `Rule`s in the tree. - * - * @param CSSElement|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. - * @param bool $bSearchInFunctionArguments whether to also return Value objects used as Function arguments. - * - * @return array - * - * @see RuleSet->getRules() - */ - public function getAllValues($mElement = null, $bSearchInFunctionArguments = false) - { - $sSearchString = null; - if ($mElement === null) { - $mElement = $this; - } elseif (is_string($mElement)) { - $sSearchString = $mElement; - $mElement = $this; - } - /** @var array $aResult */ - $aResult = []; - $this->allValues($mElement, $aResult, $sSearchString, $bSearchInFunctionArguments); - return $aResult; - } - /** * Returns all `Selector` objects with the requested specificity found recursively in the tree. * diff --git a/tests/Unit/CSSList/CSSBlockListTest.php b/tests/Unit/CSSList/CSSBlockListTest.php new file mode 100644 index 000000000..2eef1b570 --- /dev/null +++ b/tests/Unit/CSSList/CSSBlockListTest.php @@ -0,0 +1,212 @@ +getAllValues()); + } + + /** + * @test + */ + public function getAllValuesReturnsOneValueDirectlySetAsContent(): void + { + $subject = new ConcreteCSSBlockList(); + + $value = new CSSString('Superfont'); + + $declarationBlock = new DeclarationBlock(); + $rule = new Rule('font-family'); + $rule->setValue($value); + $declarationBlock->addRule($rule); + $subject->setContents([$declarationBlock]); + + $result = $subject->getAllValues(); + + self::assertSame([$value], $result); + } + + /** + * @test + */ + public function getAllValuesReturnsMultipleValuesDirectlySetAsContentInOneDeclarationBlock(): void + { + $subject = new ConcreteCSSBlockList(); + + $value1 = new CSSString('Superfont'); + $value2 = new CSSString('aquamarine'); + + $declarationBlock = new DeclarationBlock(); + $rule1 = new Rule('font-family'); + $rule1->setValue($value1); + $declarationBlock->addRule($rule1); + $rule2 = new Rule('color'); + $rule2->setValue($value2); + $declarationBlock->addRule($rule2); + $subject->setContents([$declarationBlock]); + + $result = $subject->getAllValues(); + + self::assertSame([$value1, $value2], $result); + } + + /** + * @test + */ + public function getAllValuesReturnsMultipleValuesDirectlySetAsContentInMultipleDeclarationBlocks(): void + { + $subject = new ConcreteCSSBlockList(); + + $value1 = new CSSString('Superfont'); + $value2 = new CSSString('aquamarine'); + + $declarationBlock1 = new DeclarationBlock(); + $rule1 = new Rule('font-family'); + $rule1->setValue($value1); + $declarationBlock1->addRule($rule1); + $declarationBlock2 = new DeclarationBlock(); + $rule2 = new Rule('color'); + $rule2->setValue($value2); + $declarationBlock2->addRule($rule2); + $subject->setContents([$declarationBlock1, $declarationBlock2]); + + $result = $subject->getAllValues(); + + self::assertSame([$value1, $value2], $result); + } + + /** + * @test + */ + public function getAllValuesReturnsValuesWithinAtRuleBlockList(): void + { + $subject = new ConcreteCSSBlockList(); + + $value = new CSSString('Superfont'); + + $declarationBlock = new DeclarationBlock(); + $rule = new Rule('font-family'); + $rule->setValue($value); + $declarationBlock->addRule($rule); + $atRuleBlockList = new AtRuleBlockList('media'); + $atRuleBlockList->setContents([$declarationBlock]); + $subject->setContents([$atRuleBlockList]); + + $result = $subject->getAllValues(); + + self::assertSame([$value], $result); + } + + /** + * @test + */ + public function getAllValuesWithElementProvidedReturnsOnlyValuesWithinThatElement(): void + { + $subject = new ConcreteCSSBlockList(); + + $value1 = new CSSString('Superfont'); + $value2 = new CSSString('aquamarine'); + + $declarationBlock1 = new DeclarationBlock(); + $rule1 = new Rule('font-family'); + $rule1->setValue($value1); + $declarationBlock1->addRule($rule1); + $declarationBlock2 = new DeclarationBlock(); + $rule2 = new Rule('color'); + $rule2->setValue($value2); + $declarationBlock2->addRule($rule2); + $subject->setContents([$declarationBlock1, $declarationBlock2]); + + $result = $subject->getAllValues($declarationBlock1); + + self::assertSame([$value1], $result); + } + + /** + * @test + */ + public function getAllValuesWithSearchStringProvidedReturnsOnlyValuesFromMatchingRules(): void + { + $subject = new ConcreteCSSBlockList(); + + $value1 = new CSSString('Superfont'); + $value2 = new CSSString('aquamarine'); + + $declarationBlock = new DeclarationBlock(); + $rule1 = new Rule('font-family'); + $rule1->setValue($value1); + $declarationBlock->addRule($rule1); + $rule2 = new Rule('color'); + $rule2->setValue($value2); + $declarationBlock->addRule($rule2); + $subject->setContents([$declarationBlock]); + + $result = $subject->getAllValues('font-'); + + self::assertSame([$value1], $result); + } + + /** + * @test + */ + public function getAllValuesByDefaultDoesNotReturnValuesInFunctionArguments(): void + { + $subject = new ConcreteCSSBlockList(); + + $value1 = new Size(10, 'px'); + $value2 = new Size(2, '%'); + + $declarationBlock = new DeclarationBlock(); + $rule = new Rule('margin'); + $rule->setValue(new CSSFunction('max', [$value1, $value2])); + $declarationBlock->addRule($rule); + $subject->setContents([$declarationBlock]); + + $result = $subject->getAllValues(); + + self::assertSame([], $result); + } + + /** + * @test + */ + public function getAllValuesWithSearchInFunctionArgumentsReturnsValuesInFunctionArguments(): void + { + $subject = new ConcreteCSSBlockList(); + + $value1 = new Size(10, 'px'); + $value2 = new Size(2, '%'); + + $declarationBlock = new DeclarationBlock(); + $rule = new Rule('margin'); + $rule->setValue(new CSSFunction('max', [$value1, $value2])); + $declarationBlock->addRule($rule); + $subject->setContents([$declarationBlock]); + + $result = $subject->getAllValues(null, true); + + self::assertSame([$value1, $value2], $result); + } +} diff --git a/tests/Unit/CSSList/Fixtures/ConcreteCSSBlockList.php b/tests/Unit/CSSList/Fixtures/ConcreteCSSBlockList.php new file mode 100644 index 000000000..956c7036a --- /dev/null +++ b/tests/Unit/CSSList/Fixtures/ConcreteCSSBlockList.php @@ -0,0 +1,21 @@ + Date: Sat, 12 Apr 2025 01:21:32 +0100 Subject: [PATCH 5/6] Remove use of PHP language features incompatible with 5.6 --- src/CSSList/CSSBlockList.php | 2 +- tests/Unit/CSSList/CSSBlockListTest.php | 36 ++++++++++++++----- .../CSSList/Fixtures/ConcreteCSSBlockList.php | 12 +++++-- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/CSSList/CSSBlockList.php b/src/CSSList/CSSBlockList.php index c437bf832..11d6c28fb 100644 --- a/src/CSSList/CSSBlockList.php +++ b/src/CSSList/CSSBlockList.php @@ -71,7 +71,7 @@ protected function allRuleSets(array &$aResult) * * @see RuleSet->getRules() */ - public function getAllValues($element = null, bool $searchInFunctionArguments = false): array + public function getAllValues($element = null, $searchInFunctionArguments = false) { $searchString = null; if ($element === null) { diff --git a/tests/Unit/CSSList/CSSBlockListTest.php b/tests/Unit/CSSList/CSSBlockListTest.php index 2eef1b570..97663eae4 100644 --- a/tests/Unit/CSSList/CSSBlockListTest.php +++ b/tests/Unit/CSSList/CSSBlockListTest.php @@ -20,8 +20,10 @@ final class CSSBlockListTest extends TestCase { /** * @test + * + * @return void */ - public function getAllValuesWhenNoContentSetReturnsEmptyArray(): void + public function getAllValuesWhenNoContentSetReturnsEmptyArray() { $subject = new ConcreteCSSBlockList(); @@ -30,8 +32,10 @@ public function getAllValuesWhenNoContentSetReturnsEmptyArray(): void /** * @test + * + * @return void */ - public function getAllValuesReturnsOneValueDirectlySetAsContent(): void + public function getAllValuesReturnsOneValueDirectlySetAsContent() { $subject = new ConcreteCSSBlockList(); @@ -50,8 +54,10 @@ public function getAllValuesReturnsOneValueDirectlySetAsContent(): void /** * @test + * + * @return void */ - public function getAllValuesReturnsMultipleValuesDirectlySetAsContentInOneDeclarationBlock(): void + public function getAllValuesReturnsMultipleValuesDirectlySetAsContentInOneDeclarationBlock() { $subject = new ConcreteCSSBlockList(); @@ -74,8 +80,10 @@ public function getAllValuesReturnsMultipleValuesDirectlySetAsContentInOneDeclar /** * @test + * + * @return void */ - public function getAllValuesReturnsMultipleValuesDirectlySetAsContentInMultipleDeclarationBlocks(): void + public function getAllValuesReturnsMultipleValuesDirectlySetAsContentInMultipleDeclarationBlocks() { $subject = new ConcreteCSSBlockList(); @@ -99,8 +107,10 @@ public function getAllValuesReturnsMultipleValuesDirectlySetAsContentInMultipleD /** * @test + * + * @return void */ - public function getAllValuesReturnsValuesWithinAtRuleBlockList(): void + public function getAllValuesReturnsValuesWithinAtRuleBlockList() { $subject = new ConcreteCSSBlockList(); @@ -121,8 +131,10 @@ public function getAllValuesReturnsValuesWithinAtRuleBlockList(): void /** * @test + * + * @return void */ - public function getAllValuesWithElementProvidedReturnsOnlyValuesWithinThatElement(): void + public function getAllValuesWithElementProvidedReturnsOnlyValuesWithinThatElement() { $subject = new ConcreteCSSBlockList(); @@ -146,8 +158,10 @@ public function getAllValuesWithElementProvidedReturnsOnlyValuesWithinThatElemen /** * @test + * + * @return void */ - public function getAllValuesWithSearchStringProvidedReturnsOnlyValuesFromMatchingRules(): void + public function getAllValuesWithSearchStringProvidedReturnsOnlyValuesFromMatchingRules() { $subject = new ConcreteCSSBlockList(); @@ -170,8 +184,10 @@ public function getAllValuesWithSearchStringProvidedReturnsOnlyValuesFromMatchin /** * @test + * + * @return void */ - public function getAllValuesByDefaultDoesNotReturnValuesInFunctionArguments(): void + public function getAllValuesByDefaultDoesNotReturnValuesInFunctionArguments() { $subject = new ConcreteCSSBlockList(); @@ -191,8 +207,10 @@ public function getAllValuesByDefaultDoesNotReturnValuesInFunctionArguments(): v /** * @test + * + * @return void */ - public function getAllValuesWithSearchInFunctionArgumentsReturnsValuesInFunctionArguments(): void + public function getAllValuesWithSearchInFunctionArgumentsReturnsValuesInFunctionArguments() { $subject = new ConcreteCSSBlockList(); diff --git a/tests/Unit/CSSList/Fixtures/ConcreteCSSBlockList.php b/tests/Unit/CSSList/Fixtures/ConcreteCSSBlockList.php index 956c7036a..574fef2d9 100644 --- a/tests/Unit/CSSList/Fixtures/ConcreteCSSBlockList.php +++ b/tests/Unit/CSSList/Fixtures/ConcreteCSSBlockList.php @@ -9,12 +9,20 @@ final class ConcreteCSSBlockList extends CSSBlockList { - public function isRootList(): bool + /** + * @return never + */ + public function isRootList() { throw new \BadMethodCallException('Not implemented', 1740395831); } - public function render(OutputFormat $outputFormat): string + /** + * @param OutputFormat|null $outputFormat + * + * @return never + */ + public function render($outputFormat) { throw new \BadMethodCallException('Not implemented', 1740395836); } From 8d192a6e68b7dafe8075eef3c74ea7d319d03346 Mon Sep 17 00:00:00 2001 From: JakeQZ Date: Fri, 11 Apr 2025 21:05:22 +0100 Subject: [PATCH 6/6] Apply #1241 --- CHANGELOG.md | 8 ++++ src/CSSList/CSSBlockList.php | 32 +++++++++++++--- tests/Unit/CSSList/CSSBlockListTest.php | 49 +++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4efe3c22d..b08c38a28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,12 +17,20 @@ This project adheres to [Semantic Versioning](https://semver.org/). ### Changed +- Parameters for `getAllValues()` are deconflated, so it now takes three (all + optional), allowing `$element` and `$ruleSearchPattern` to be specified + separately (#1241) - Implement `Positionable` in the following CSS item classes: `Comment`, `CSSList`, `SourceException`, `Charset`, `CSSNamespace`, `Import`, `Rule`, `DeclarationBlock`, `RuleSet`, `CSSFunction`, `Value` (#1225) ### Deprecated +- Passing a string as the first argument to `getAllValues()` is deprecated; + the search pattern should now be passed as the second argument (#1241) +- Passing a Boolean as the second argument to `getAllValues()` is deprecated; + the flag for searching in function arguments should now be passed as the third + argument (#1241) - `getLineNo()` is deprecated in these classes (use `getLineNumber()` instead): `Comment`, `CSSList`, `SourceException`, `Charset`, `CSSNamespace`, `Import`, `Rule`, `DeclarationBlock`, `RuleSet`, `CSSFunction`, `Value` (#1225, #1233) diff --git a/src/CSSList/CSSBlockList.php b/src/CSSList/CSSBlockList.php index 11d6c28fb..aa0c67fcd 100644 --- a/src/CSSList/CSSBlockList.php +++ b/src/CSSList/CSSBlockList.php @@ -62,24 +62,44 @@ protected function allRuleSets(array &$aResult) /** * Returns all `Value` objects found recursively in `Rule`s in the tree. * - * @param CSSElement|string $element - * 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. + * @param CSSElement|string|null $element + * This is the `CSSList` or `RuleSet` to start the search from (defaults to the whole document). + * If a string is given, it is used as a rule name filter. + * Passing a string for this parameter is deprecated in version 8.9.0, and will not work from v9.0; + * use the following parameter to pass a rule name filter instead. + * @param string|bool|null $ruleSearchPatternOrSearchInFunctionArguments + * This allows filtering rules by property name + * (e.g. if "color" is passed, only `Value`s from `color` properties will be returned, + * or if "font-" is provided, `Value`s from all font rules, like `font-size`, and including `font` itself, + * will be returned). + * If a Boolean is provided, it is treated as the `$searchInFunctionArguments` argument. + * Passing a Boolean for this parameter is deprecated in version 8.9.0, and will not work from v9.0; + * use the `$searchInFunctionArguments` parameter instead. * @param bool $searchInFunctionArguments whether to also return Value objects used as Function arguments. * * @return array * * @see RuleSet->getRules() */ - public function getAllValues($element = null, $searchInFunctionArguments = false) - { - $searchString = null; + public function getAllValues( + $element = null, + $ruleSearchPatternOrSearchInFunctionArguments = null, + $searchInFunctionArguments = false + ) { + if (\is_bool($ruleSearchPatternOrSearchInFunctionArguments)) { + $searchInFunctionArguments = $ruleSearchPatternOrSearchInFunctionArguments; + $searchString = null; + } else { + $searchString = $ruleSearchPatternOrSearchInFunctionArguments; + } + if ($element === null) { $element = $this; } elseif (\is_string($element)) { $searchString = $element; $element = $this; } + $result = []; $this->allValues($element, $result, $searchString, $searchInFunctionArguments); return $result; diff --git a/tests/Unit/CSSList/CSSBlockListTest.php b/tests/Unit/CSSList/CSSBlockListTest.php index 97663eae4..85a2e9e75 100644 --- a/tests/Unit/CSSList/CSSBlockListTest.php +++ b/tests/Unit/CSSList/CSSBlockListTest.php @@ -182,6 +182,32 @@ public function getAllValuesWithSearchStringProvidedReturnsOnlyValuesFromMatchin self::assertSame([$value1], $result); } + /** + * @test + * + * @return void + */ + public function getAllValuesWithSearchStringProvidedInNewMethodSignatureReturnsOnlyValuesFromMatchingRules() + { + $subject = new ConcreteCSSBlockList(); + + $value1 = new CSSString('Superfont'); + $value2 = new CSSString('aquamarine'); + + $declarationBlock = new DeclarationBlock(); + $rule1 = new Rule('font-family'); + $rule1->setValue($value1); + $declarationBlock->addRule($rule1); + $rule2 = new Rule('color'); + $rule2->setValue($value2); + $declarationBlock->addRule($rule2); + $subject->setContents([$declarationBlock]); + + $result = $subject->getAllValues(null, 'font-'); + + self::assertSame([$value1], $result); + } + /** * @test * @@ -227,4 +253,27 @@ public function getAllValuesWithSearchInFunctionArgumentsReturnsValuesInFunction self::assertSame([$value1, $value2], $result); } + + /** + * @test + * + * @return void + */ + public function getAllValuesWithSearchInFunctionArgumentsInNewMethodSignatureReturnsValuesInFunctionArguments() + { + $subject = new ConcreteCSSBlockList(); + + $value1 = new Size(10, 'px'); + $value2 = new Size(2, '%'); + + $declarationBlock = new DeclarationBlock(); + $rule = new Rule('margin'); + $rule->setValue(new CSSFunction('max', [$value1, $value2])); + $declarationBlock->addRule($rule); + $subject->setContents([$declarationBlock]); + + $result = $subject->getAllValues(null, null, true); + + self::assertSame([$value1, $value2], $result); + } }