mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-24 10:12:25 -05:00
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.
This commit is contained in:
parent
633ede5c6c
commit
11d3098f40
Notes:
sideshowbarker
2024-07-18 03:32:41 +09:00
Author: https://github.com/AtkinsSJ Commit: https://github.com/SerenityOS/serenity/commit/11d3098f40c Pull-request: https://github.com/SerenityOS/serenity/pull/10188
2 changed files with 104 additions and 0 deletions
|
@ -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) {
|
||||
|
|
|
@ -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@;
|
||||
|
|
Loading…
Add table
Reference in a new issue