diff --git a/Tests/LibWeb/Text/expected/css/PropertyOwningCSSStyleDeclaration-serialized-custom-properties.txt b/Tests/LibWeb/Text/expected/css/PropertyOwningCSSStyleDeclaration-serialized-custom-properties.txt new file mode 100644 index 0000000000..7e8b5b60fc --- /dev/null +++ b/Tests/LibWeb/Text/expected/css/PropertyOwningCSSStyleDeclaration-serialized-custom-properties.txt @@ -0,0 +1 @@ +test { --color: red; color: rgb(255, 0, 0); } diff --git a/Tests/LibWeb/Text/input/css/PropertyOwningCSSStyleDeclaration-serialized-custom-properties.html b/Tests/LibWeb/Text/input/css/PropertyOwningCSSStyleDeclaration-serialized-custom-properties.html new file mode 100644 index 0000000000..c84538eca3 --- /dev/null +++ b/Tests/LibWeb/Text/input/css/PropertyOwningCSSStyleDeclaration-serialized-custom-properties.html @@ -0,0 +1,15 @@ + + diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp index dd37e2e9c9..ce5266992f 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp @@ -287,6 +287,60 @@ DeprecatedString PropertyOwningCSSStyleDeclaration::serialized() const // 2. Let already serialized be an empty array. HashTable already_serialized; + // NOTE: The spec treats custom properties the same as any other property, and expects the above loop to handle them. + // However, our implementation separates them from regular properties, so we need to handle them separately here. + // FIXME: Is the relative order of custom properties and regular properties supposed to be preserved? + for (auto& declaration : m_custom_properties) { + // 1. Let property be declaration’s property name. + auto const& property = declaration.key; + + // 2. If property is in already serialized, continue with the steps labeled declaration loop. + // NOTE: It is never in already serialized, as there are no shorthands for custom properties. + + // 3. If property maps to one or more shorthand properties, let shorthands be an array of those shorthand properties, in preferred order. + // NOTE: There are no shorthands for custom properties. + + // 4. Shorthand loop: For each shorthand in shorthands, follow these substeps: ... + // NOTE: There are no shorthands for custom properties. + + // 5. Let value be the result of invoking serialize a CSS value of declaration. + auto value = declaration.value.value->to_string().release_value_but_fixme_should_propagate_errors().to_deprecated_string(); + + // 6. Let serialized declaration be the result of invoking serialize a CSS declaration with property name property, value value, + // and the important flag set if declaration has its important flag set. + // NOTE: We have to inline this here as the actual implementation does not accept custom properties. + DeprecatedString serialized_declaration = [&] { + // https://www.w3.org/TR/cssom/#serialize-a-css-declaration + StringBuilder builder; + + // 1. Let s be the empty string. + // 2. Append property to s. + builder.append(property); + + // 3. Append ": " (U+003A U+0020) to s. + builder.append(": "sv); + + // 4. Append value to s. + builder.append(value); + + // 5. If the important flag is set, append " !important" (U+0020 U+0021 U+0069 U+006D U+0070 U+006F U+0072 U+0074 U+0061 U+006E U+0074) to s. + if (declaration.value.important == Important::Yes) + builder.append(" !important"sv); + + // 6. Append ";" (U+003B) to s. + builder.append(';'); + + // 7. Return s. + return builder.to_deprecated_string(); + }(); + + // 7. Append serialized declaration to list. + list.append(move(serialized_declaration)); + + // 8. Append property to already serialized. + // NOTE: We don't need to do this, as we don't have shorthands for custom properties. + } + // 3. Declaration loop: For each CSS declaration declaration in declaration block’s declarations, follow these substeps: for (auto& declaration : m_properties) { // 1. Let property be declaration’s property name.