Fix html_attr dropping style declarations whose value is zero

InlineStyle::getValue() skipped a declaration when empty($value) was true,
which also matches 0, 0.0 and '0'. Those are ordinary CSS values (opacity: 0,
z-index: 0, margin: 0, flex-grow: 0), so they were silently dropped, and a
style map containing only such declarations omitted the attribute entirely.

The sibling SeparatedTokenList::getValue() already uses an explicit
null/false test, so class token lists keep a 0 while style declarations did
not. The numeric-key branch of InlineStyle itself never consulted empty(),
so {style: ['opacity: 0']} printed while {style: {opacity: 0}} did not.
This commit is contained in:
Dylan Pulver
2026-09-03 20:24:11 +03:00
parent cb80d7ac89
commit c072ff85b3
3 changed files with 25 additions and 1 deletions
+1
View File
@@ -1,5 +1,6 @@
# 3.29.0 (2026-XX-XX)
* Fix `html_attr` dropping `style` declarations whose value is `0`, `0.0` or `'0'`
* Fix the `default` filter fallback emitting an undefined variable warning when it uses the null-safe operator
* Fix the `matches` operator silently treating PCRE execution errors as non-matches
* Add the `HtmlExtension::htmlAttrValue()` method to resolve a single HTML attribute value the way the `html_attr` function renders it
+3 -1
View File
@@ -55,7 +55,9 @@ final class InlineStyle implements MergeableInterface, AttributeValueInterface
{
$style = '';
foreach ($this->value as $name => $value) {
if (empty($value) || true === $value) {
// `0`, `0.0` and `'0'` are valid CSS values, so only the values that carry
// no declaration at all are skipped here
if (null === $value || false === $value || true === $value || '' === $value || [] === $value) {
continue;
}
if (is_numeric($name)) {
+21
View File
@@ -157,6 +157,27 @@ class HtmlAttrTest extends TestCase
],
];
yield 'zero style declaration values are printed' => [
'style="opacity: 0; z-index: 0; margin: 0;"',
[
['style' => ['opacity' => 0, 'z-index' => '0', 'margin' => 0.0]],
],
];
yield 'null, false and empty string style declaration values are omitted' => [
'style="color: red;"',
[
['style' => ['a' => null, 'b' => false, 'c' => '', 'd' => true, 'color' => 'red']],
],
];
yield 'style attribute is omitted when every declaration is omitted' => [
'',
[
['style' => ['a' => null, 'b' => false, 'c' => '']],
],
];
yield 'merging style attributes overrides by key' => [
'style="color: blue; font-size: 14px;"',
[