summaryrefslogtreecommitdiff
path: root/Meta
diff options
context:
space:
mode:
authorSam Atkins <atkinssj@serenityos.org>2021-09-22 20:11:15 +0100
committerAndreas Kling <kling@serenityos.org>2021-09-23 17:47:40 +0200
commit11d3098f40cae7de7b7fe52780302f848a09c6af (patch)
tree1498b3d1143ec0d1b5307144056278201f9c5300 /Meta
parent633ede5c6c68ca21b1be2de57252446067b51a65 (diff)
downloadserenity-11d3098f40cae7de7b7fe52780302f848a09c6af.zip
LibWeb: Generate property_accepts_value() function :^)
Previously, we have not been validating the values for CSS declarations inside the Parser. This causes issues, since we should be discarding invalid style declarations, so that previous ones are used instead. For example, in this code: ```css .foo { width: 2em; width: orange; } ``` ... the `width: orange` declaration overwrites the `width: 2em` one, even though it is invalid. According to the spec, `width: orange` should be rejected at parse time, and discarded, leaving `width: 2em` as the resulting value. Many properties (mostly shorthands) are parsed specially, and so they are already rejected if they are invalid. But for simple properties, we currently accept any value. With `property_accepts_value()`, we can check if the value is valid in `parse_css_value()`, and reject it if it is not.
Diffstat (limited to 'Meta')
-rw-r--r--Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_cpp.cpp103
-rw-r--r--Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_h.cpp1
2 files changed, 104 insertions, 0 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 dcf0c96b74..6921131674 100644
--- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_cpp.cpp
+++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_cpp.cpp
@@ -252,6 +252,109 @@ bool property_has_quirk(PropertyID property_id, Quirk quirk)
}
}
+bool property_accepts_value(PropertyID property_id, StyleValue& style_value)
+{
+ if (style_value.is_builtin() || style_value.is_custom_property())
+ return true;
+
+ switch (property_id) {
+)~~~");
+
+ properties.for_each_member([&](auto& name, auto& value) {
+ VERIFY(value.is_object());
+ auto& object = value.as_object();
+ bool has_valid_types = object.has("valid-types");
+ auto has_valid_identifiers = object.has("valid-identifiers");
+ if (has_valid_types || has_valid_identifiers) {
+ auto property_generator = generator.fork();
+ property_generator.set("name:titlecase", title_casify(name));
+ property_generator.append(R"~~~(
+ case PropertyID::@name:titlecase@: {
+)~~~");
+
+ if (has_valid_types) {
+ auto valid_types_value = object.get("valid-types");
+ VERIFY(valid_types_value.is_array());
+ auto valid_types = valid_types_value.as_array();
+ if (!valid_types.is_empty()) {
+ for (auto& type : valid_types.values()) {
+ VERIFY(type.is_string());
+ auto type_name = type.as_string();
+ if (type_name == "color") {
+ property_generator.append(R"~~~(
+ if (style_value.is_color())
+ return true;
+)~~~");
+ } else if (type_name == "image") {
+ property_generator.append(R"~~~(
+ if (style_value.is_image())
+ return true;
+)~~~");
+ } else if (type_name == "length" || type_name == "percentage") {
+ // FIXME: Handle lengths and percentages separately
+ property_generator.append(R"~~~(
+ if (style_value.is_length() || style_value.is_calculated())
+ return true;
+)~~~");
+ } else if (type_name == "number" || type_name == "integer") {
+ // FIXME: Handle integers separately
+ property_generator.append(R"~~~(
+ if (style_value.is_numeric())
+ return true;
+)~~~");
+ } else if (type_name == "string") {
+ property_generator.append(R"~~~(
+ if (style_value.is_string())
+ return true;
+)~~~");
+ } else if (type_name == "url") {
+ // FIXME: Handle urls!
+ } else {
+ warnln("Unrecognized valid-type name: '{}'", type_name);
+ VERIFY_NOT_REACHED();
+ }
+ }
+ }
+ }
+
+ if (has_valid_identifiers) {
+ auto valid_identifiers_value = object.get("valid-identifiers");
+ VERIFY(valid_identifiers_value.is_array());
+ auto valid_identifiers = valid_identifiers_value.as_array();
+ if (!valid_identifiers.is_empty()) {
+ property_generator.append(R"~~~(
+ switch (style_value.to_identifier()) {
+)~~~");
+ for (auto& identifier : valid_identifiers.values()) {
+ VERIFY(identifier.is_string());
+ auto identifier_generator = generator.fork();
+ identifier_generator.set("identifier:titlecase", title_casify(identifier.as_string()));
+ identifier_generator.append(R"~~~(
+ case ValueID::@identifier:titlecase@:
+)~~~");
+ }
+ property_generator.append(R"~~~(
+ return true;
+ default:
+ break;
+ }
+)~~~");
+ }
+ }
+
+ generator.append(R"~~~(
+ return false;
+ }
+)~~~");
+ }
+ });
+
+ generator.append(R"~~~(
+ default:
+ return true;
+ }
+}
+
size_t property_maximum_value_count(PropertyID property_id)
{
switch (property_id) {
diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_h.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_h.cpp
index 3ce193e714..99958f4478 100644
--- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_h.cpp
+++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/Generate_CSS_PropertyID_h.cpp
@@ -106,6 +106,7 @@ bool is_inherited_property(PropertyID);
bool is_pseudo_property(PropertyID);
RefPtr<StyleValue> property_initial_value(PropertyID);
+bool property_accepts_value(PropertyID, StyleValue&);
size_t property_maximum_value_count(PropertyID);
constexpr PropertyID first_property_id = PropertyID::@first_property_id@;