LibWeb/CSS: Use ShorthandStyleValue to serialize shorthands

This wins us 65 new WPT subtest passes! It also shows up that we're
doing the wrong thing in ShorthandStyleValue in places, notably with
the grid properties. However, having one place to fix instead of two
will make it easier to correct them. :^)

In order to be fully correct, we should use the algorithm here:
https://drafts.csswg.org/cssom/#serialize-a-css-value

However, it's quite hand-wavy. What we do have in the meantime is
`ShorthandStyleValue::to_string()`, where we special-case the
serialization rules for shorthands with a generic fallback that's
equivalent to what the previous `get_property_value()` code was doing.
This commit is contained in:
Sam Atkins 2024-11-29 13:02:30 +00:00 committed by Andreas Kling
commit e4d55a6037
Notes: github-actions[bot] 2024-11-30 10:03:02 +00:00
13 changed files with 127 additions and 121 deletions

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2018-2024, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2023-2024, Sam Atkins <sam@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -11,6 +12,7 @@
#include <LibWeb/CSS/Parser/Parser.h>
#include <LibWeb/CSS/StyleComputer.h>
#include <LibWeb/CSS/StyleValues/ImageStyleValue.h>
#include <LibWeb/CSS/StyleValues/ShorthandStyleValue.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/DOM/Element.h>
#include <LibWeb/Infra/Strings.h>
@ -277,11 +279,12 @@ String CSSStyleDeclaration::get_property_value(StringView property_name) const
// 2. If property is a shorthand property, then follow these substeps:
if (property_is_shorthand(property_id.value())) {
// 1. Let list be a new empty array.
StringBuilder list;
Vector<ValueComparingNonnullRefPtr<CSSStyleValue const>> list;
Optional<Important> last_important_flag;
// 2. For each longhand property longhand that property maps to, in canonical order, follow these substeps:
for (auto longhand_property_id : longhands_for_shorthand(property_id.value())) {
Vector<PropertyID> longhand_ids = longhands_for_shorthand(property_id.value());
for (auto longhand_property_id : longhand_ids) {
// 1. If longhand is a case-sensitive match for a property name of a CSS declaration in the declarations, let declaration be that CSS declaration, or null otherwise.
auto declaration = property(longhand_property_id);
@ -290,9 +293,7 @@ String CSSStyleDeclaration::get_property_value(StringView property_name) const
return {};
// 3. Append the declaration to list.
if (!list.is_empty())
list.append(' ');
list.append(declaration->value->to_string());
list.append(declaration->value);
if (last_important_flag.has_value() && declaration->important != *last_important_flag)
return {};
@ -300,7 +301,8 @@ String CSSStyleDeclaration::get_property_value(StringView property_name) const
}
// 3. If important flags of all declarations in list are same, then return the serialization of list.
return list.to_string_without_validation();
// NOTE: Currently we implement property-specific shorthand serialization in ShorthandStyleValue::to_string().
return ShorthandStyleValue::create(property_id.value(), longhand_ids, list)->to_string();
// 4. Return the empty string.
// NOTE: This is handled by the loop.