summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Atkins <atkinssj@serenityos.org>2021-09-17 16:53:43 +0100
committerAndreas Kling <kling@serenityos.org>2021-09-17 23:06:45 +0200
commit6ea9edf84be5fbfaf242a6e06e353f9e92ca07ad (patch)
tree62fc63ba8f40028cf7e7cf1b31a884fdae92d035
parentbb1cc99750acc5254ee8d42d81897cc096d0c5e7 (diff)
downloadserenity-6ea9edf84be5fbfaf242a6e06e353f9e92ca07ad.zip
LibWeb: Generate shorthand initial values after their longhands
When parsing shorthand values, we'd like to use `property_initial_value()` to get their longhand property values, instead of hard-coding them as we currently do. That involves recursively calling that function while the `initial_values` map is being initialized, which causes problems because the shorthands appear alphabetically before their longhand components, so the longhands aren't initialized yet! The solution here is to perform 2 passes when generating the code, outputting properties without "longhands" first, and the rest after. This could potentially cause issues when shorthands have multiple levels, in particular `border` -> `border-color` -> `border-left-color`. But, we do not currently define a default value for `border`, and `border-color` takes only a single value, so it's fine for now. :^)
-rw-r--r--Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_cpp.cpp35
1 files changed, 29 insertions, 6 deletions
diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_cpp.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_cpp.cpp
index 3af8e6abfc..6421aba9b5 100644
--- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_cpp.cpp
+++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_cpp.cpp
@@ -164,11 +164,14 @@ RefPtr<StyleValue> property_initial_value(PropertyID property_id)
ParsingContext parsing_context;
)~~~");
- properties.for_each_member([&](auto& name, auto& value) {
- VERIFY(value.is_object());
-
- if (value.as_object().has("initial")) {
- auto& initial_value = value.as_object().get("initial");
+ // NOTE: Parsing a shorthand property requires that its longhands are already available here.
+ // So, we do this in two passes: First longhands, then shorthands.
+ // Probably we should build a dependency graph and then handle them in order, but this
+ // works for now! :^)
+
+ auto output_initial_value_code = [&](auto& name, auto& object) {
+ if (object.has("initial")) {
+ auto& initial_value = object.get("initial");
VERIFY(initial_value.is_string());
auto initial_value_string = initial_value.as_string();
@@ -180,11 +183,31 @@ RefPtr<StyleValue> property_initial_value(PropertyID property_id)
initial_values.set(PropertyID::@name:titlecase@, parsed_value.release_nonnull());
)~~~");
}
+ };
+
+ properties.for_each_member([&](auto& name, auto& value) {
+ VERIFY(value.is_object());
+ if (value.as_object().has("longhands"))
+ return;
+ output_initial_value_code(name, value.as_object());
+ });
+
+ properties.for_each_member([&](auto& name, auto& value) {
+ VERIFY(value.is_object());
+ if (!value.as_object().has("longhands"))
+ return;
+ output_initial_value_code(name, value.as_object());
});
generator.append(R"~~~(
}
- return initial_values.get(property_id).value_or(nullptr);
+
+ auto maybe_value = initial_values.get(property_id);
+ if (!maybe_value.has_value()) {
+ dbgln("No initial value found for '{}' property!", string_from_property_id(property_id));
+ return nullptr;
+ }
+ return maybe_value.value();
}
bool property_has_quirk(PropertyID property_id, Quirk quirk)