diff --git a/config/phpmd.xml b/config/phpmd.xml index cf1b3db1..f4a8eba0 100644 --- a/config/phpmd.xml +++ b/config/phpmd.xml @@ -9,8 +9,8 @@ - - + + diff --git a/config/phpstan-baseline.neon b/config/phpstan-baseline.neon index 976a1011..77fcb466 100644 --- a/config/phpstan-baseline.neon +++ b/config/phpstan-baseline.neon @@ -7,7 +7,7 @@ parameters: path: ../src/CssInliner.php - - message: '#^Parameter \#1 \$name of method Pelago\\Emogrifier\\Utilities\\DeclarationBlockParser\:\:normalizePropertyName\(\) expects non\-empty\-string, mixed given\.$#' + message: '#^Parameter \#1 \$name of static method Pelago\\Emogrifier\\Utilities\\DeclarationBlockParser\:\:normalizePropertyName\(\) expects non\-empty\-string, mixed given\.$#' identifier: argument.type count: 1 path: ../src/CssInliner.php diff --git a/src/CssInliner.php b/src/CssInliner.php index 8b9ac1db..ca39cc6e 100644 --- a/src/CssInliner.php +++ b/src/CssInliner.php @@ -435,12 +435,10 @@ private function getAllNodesWithStyleAttribute(): \DOMNodeList */ private function normalizeStyleAttributes(\DOMElement $node): void { - $declarationBlockParser = new DeclarationBlockParser(); - $pattern = '/-{0,2}+[_a-zA-Z][\\w\\-]*+(?=:)/S'; /** @param array $propertyNameMatches */ - $callback = static function (array $propertyNameMatches) use ($declarationBlockParser): string { - return $declarationBlockParser->normalizePropertyName($propertyNameMatches[0]); + $callback = static function (array $propertyNameMatches): string { + return DeclarationBlockParser::normalizePropertyName($propertyNameMatches[0]); }; if (\function_exists('Safe\\preg_replace_callback')) { $normalizedOriginalStyle = preg_replace_callback($pattern, $callback, $node->getAttribute('style')); @@ -453,7 +451,7 @@ private function normalizeStyleAttributes(\DOMElement $node): void // In order to not overwrite existing style attributes in the HTML, we have to save the original HTML styles. $nodePath = $node->getNodePath(); if (\is_string($nodePath) && ($nodePath !== '') && !isset($this->styleAttributesForNodes[$nodePath])) { - $this->styleAttributesForNodes[$nodePath] = $declarationBlockParser->parse($normalizedOriginalStyle); + $this->styleAttributesForNodes[$nodePath] = DeclarationBlockParser::parse($normalizedOriginalStyle); $this->visitedNodes[$nodePath] = $node; } @@ -759,8 +757,7 @@ private function getCssSelectorPrecedence(string $selector): int private function copyInlinableCssToStyleAttribute(\DOMElement $node, array $cssRule): void { $declarationsBlock = $cssRule['declarationsBlock']; - $declarationBlockParser = new DeclarationBlockParser(); - $newStyleDeclarations = $declarationBlockParser->parse($declarationsBlock); + $newStyleDeclarations = DeclarationBlockParser::parse($declarationsBlock); if ($newStyleDeclarations === []) { return; } @@ -768,7 +765,7 @@ private function copyInlinableCssToStyleAttribute(\DOMElement $node, array $cssR // if it has a style attribute, get it, process it, and append (overwrite) new stuff if ($node->hasAttribute('style')) { // break it up into an associative array - $oldStyleDeclarations = $declarationBlockParser->parse($node->getAttribute('style')); + $oldStyleDeclarations = DeclarationBlockParser::parse($node->getAttribute('style')); } else { $oldStyleDeclarations = []; } @@ -816,14 +813,13 @@ private function generateStyleStringFromDeclarationsArrays(array $oldStyles, arr $combinedStyles = \array_merge($oldStyles, $newStyles); - $declarationBlockParser = new DeclarationBlockParser(); $style = ''; foreach ($combinedStyles as $attributeName => $attributeValue) { $trimmedAttributeName = \trim($attributeName); if ($trimmedAttributeName === '') { throw new \UnexpectedValueException('An empty property name was encountered.', 1727046078); } - $propertyName = $declarationBlockParser->normalizePropertyName($trimmedAttributeName); + $propertyName = DeclarationBlockParser::normalizePropertyName($trimmedAttributeName); $propertyValue = \trim($attributeValue); $style .= $propertyName . ': ' . $propertyValue . '; '; } @@ -847,10 +843,9 @@ private function attributeValueIsImportant(string $attributeValue): bool */ private function fillStyleAttributesWithMergedStyles(): void { - $declarationBlockParser = new DeclarationBlockParser(); foreach ($this->styleAttributesForNodes as $nodePath => $styleAttributesForNode) { $node = $this->visitedNodes[$nodePath]; - $currentStyleAttributes = $declarationBlockParser->parse($node->getAttribute('style')); + $currentStyleAttributes = DeclarationBlockParser::parse($node->getAttribute('style')); $node->setAttribute( 'style', $this->generateStyleStringFromDeclarationsArrays( @@ -887,7 +882,7 @@ private function removeImportantAnnotationFromAllInlineStyles(): void private function removeImportantAnnotationFromNodeInlineStyle(\DOMElement $node): void { $style = $node->getAttribute('style'); - $inlineStyleDeclarations = (new DeclarationBlockParser())->parse((bool) $style ? $style : ''); + $inlineStyleDeclarations = DeclarationBlockParser::parse((bool) $style ? $style : ''); /** @var array $regularStyleDeclarations */ $regularStyleDeclarations = []; /** @var array $importantStyleDeclarations */ diff --git a/src/HtmlProcessor/CssToAttributeConverter.php b/src/HtmlProcessor/CssToAttributeConverter.php index 9c0da2fa..496d5ae6 100644 --- a/src/HtmlProcessor/CssToAttributeConverter.php +++ b/src/HtmlProcessor/CssToAttributeConverter.php @@ -62,9 +62,8 @@ final class CssToAttributeConverter extends AbstractHtmlProcessor */ public function convertCssToVisualAttributes(): self { - $declarationBlockParser = new DeclarationBlockParser(); foreach ($this->getAllNodesWithStyleAttribute() as $node) { - $inlineStyleDeclarations = $declarationBlockParser->parse($node->getAttribute('style')); + $inlineStyleDeclarations = DeclarationBlockParser::parse($node->getAttribute('style')); $this->mapCssToHtmlAttributes($inlineStyleDeclarations, $node); } diff --git a/src/HtmlProcessor/CssVariableEvaluator.php b/src/HtmlProcessor/CssVariableEvaluator.php index 9d9c2d51..ca0259ac 100644 --- a/src/HtmlProcessor/CssVariableEvaluator.php +++ b/src/HtmlProcessor/CssVariableEvaluator.php @@ -45,7 +45,7 @@ public function evaluateVariables(): self // Avoid parsing declarations if none use or define a variable if (preg_match('/(?parse($style); + $declarations = DeclarationBlockParser::parse($style); $variableDefinitions = $this->getVariableDefinitionsFromDeclarations($declarations) + $currentAncestorDefinitions; $this->currentVariableDefinitions = $variableDefinitions; diff --git a/src/Utilities/DeclarationBlockParser.php b/src/Utilities/DeclarationBlockParser.php index 92ab254b..ada49458 100644 --- a/src/Utilities/DeclarationBlockParser.php +++ b/src/Utilities/DeclarationBlockParser.php @@ -41,7 +41,7 @@ public static function clearCache(): void * * @return non-empty-string */ - public function normalizePropertyName(string $name): string + public static function normalizePropertyName(string $name): string { if (\substr($name, 0, 2) === '--') { return $name; @@ -77,7 +77,7 @@ public function normalizePropertyName(string $name): string * * @throws \UnexpectedValueException if an empty property name is encountered (which cannot happen) */ - public function parse(string $declarationBlock): array + public static function parse(string $declarationBlock): array { $trimmedDeclarationBlock = \trim($declarationBlock, "; \n\r\t\v\x00"); if ($trimmedDeclarationBlock === '') { @@ -103,7 +103,7 @@ public function parse(string $declarationBlock): array $propertyName = $matches[1]; $propertyValue = $matches[2]; - $properties[$this->normalizePropertyName($propertyName)] = $propertyValue; + $properties[self::normalizePropertyName($propertyName)] = $propertyValue; } self::$cache[$trimmedDeclarationBlock] = $properties; diff --git a/tests/Unit/CssInlinerTest.php b/tests/Unit/CssInlinerTest.php index 2c811176..644d1083 100644 --- a/tests/Unit/CssInlinerTest.php +++ b/tests/Unit/CssInlinerTest.php @@ -3922,8 +3922,7 @@ public function copyUninlinableCssToStyleNodeHasNoSideEffects(): void */ public function inlineCssClearsDeclarationBlockParserCache(): void { - $subject = new DeclarationBlockParser(); - $subject->parse('color: green;'); + DeclarationBlockParser::parse('color: green;'); $cacheProperty = new \ReflectionProperty(DeclarationBlockParser::class, 'cache'); if (\PHP_VERSION_ID < 80100) { diff --git a/tests/Unit/Utilities/DeclarationBlockParserTest.php b/tests/Unit/Utilities/DeclarationBlockParserTest.php index 03551189..061f57ca 100644 --- a/tests/Unit/Utilities/DeclarationBlockParserTest.php +++ b/tests/Unit/Utilities/DeclarationBlockParserTest.php @@ -63,9 +63,7 @@ public function providePropertyNameAndExpectedNormalization(): array */ public function normalizesPropertyName(string $name, string $expectedNormalization): void { - $subject = new DeclarationBlockParser(); - - $result = $subject->normalizePropertyName($name); + $result = DeclarationBlockParser::normalizePropertyName($name); self::assertSame($expectedNormalization, $result); } @@ -264,9 +262,7 @@ public function provideDeclarationBlockAsStringAndArray(): array */ public function parses(string $declarationBlockAsString, array $declarationBlockAsArray): void { - $subject = new DeclarationBlockParser(); - - $result = $subject->parse($declarationBlockAsString); + $result = DeclarationBlockParser::parse($declarationBlockAsString); self::assertSame($declarationBlockAsArray, $result); } @@ -276,9 +272,7 @@ public function parses(string $declarationBlockAsString, array $declarationBlock */ public function overridesEarlierDeclarationWithLaterOne(): void { - $subject = new DeclarationBlockParser(); - - $result = $subject->parse('color: red; color: green;'); + $result = DeclarationBlockParser::parse('color: red; color: green;'); self::assertSame(['color' => 'green'], $result); } @@ -291,11 +285,10 @@ public function overridesEarlierDeclarationWithLaterOne(): void */ public function providesConsistentResults(): void { - $subject = new DeclarationBlockParser(); $declarationBlock = 'color: green;'; - $firstResult = $subject->parse($declarationBlock); - $secondResult = $subject->parse($declarationBlock); + $firstResult = DeclarationBlockParser::parse($declarationBlock); + $secondResult = DeclarationBlockParser::parse($declarationBlock); self::assertSame($firstResult, $secondResult); } @@ -305,8 +298,7 @@ public function providesConsistentResults(): void */ public function clearCacheEmptiesStaticCache(): void { - $subject = new DeclarationBlockParser(); - $subject->parse('color: green;'); + DeclarationBlockParser::parse('color: green;'); DeclarationBlockParser::clearCache();