LibWeb: Add range-checking to property_accepts_value()

For `number` and `integer` types, you can add a range afterwards to add
a range check, using similar syntax to that used in the CSS specs. For
example:

```json
"font-weight": {
  ...
  "valid-types": [
    "number [1,1000]"
  ],
  ...
}
```

This limits any numbers to the range `1 <= n <= 1000`.
This commit is contained in:
Sam Atkins 2021-09-23 12:45:08 +01:00 committed by Andreas Kling
parent e262596ee1
commit b927972da7
Notes: sideshowbarker 2024-07-19 01:59:31 +09:00
4 changed files with 31 additions and 3 deletions

View file

@ -279,7 +279,9 @@ bool property_accepts_value(PropertyID property_id, StyleValue& style_value)
if (!valid_types.is_empty()) {
for (auto& type : valid_types.values()) {
VERIFY(type.is_string());
auto type_name = type.as_string();
auto type_parts = type.as_string().split_view(' ');
auto type_name = type_parts.first();
auto type_args = type_parts.size() > 1 ? type_parts[1] : ""sv;
if (type_name == "color") {
property_generator.append(R"~~~(
if (style_value.is_color())
@ -298,8 +300,25 @@ bool property_accepts_value(PropertyID property_id, StyleValue& style_value)
)~~~");
} else if (type_name == "number" || type_name == "integer") {
// FIXME: Handle integers separately
StringView min_value;
StringView max_value;
if (!type_args.is_empty()) {
VERIFY(type_args.starts_with('[') && type_args.ends_with(']'));
auto comma_index = type_args.find(',').value();
min_value = type_args.substring_view(1, comma_index - 1);
max_value = type_args.substring_view(comma_index + 1, type_args.length() - comma_index - 2);
}
property_generator.append(R"~~~(
if (style_value.is_numeric())
if (style_value.is_numeric())~~~");
if (!min_value.is_empty()) {
property_generator.set("minvalue", min_value);
property_generator.append(" && (style_value.as_number() >= (float)@minvalue@)");
}
if (!max_value.is_empty()) {
property_generator.set("maxvalue", max_value);
property_generator.append(" && (style_value.as_number() <= (float)@maxvalue@)");
}
property_generator.append(R"~~~()
return true;
)~~~");
} else if (type_name == "string") {

View file

@ -668,7 +668,7 @@
"inherited": true,
"initial": "normal",
"valid-types": [
"integer"
"number [1,1000]"
],
"valid-identifiers": [
"bold",

View file

@ -98,6 +98,12 @@ bool StyleValue::is_color() const
return false;
}
float StyleValue::as_number() const
{
VERIFY(is_numeric());
return static_cast<NumericStyleValue const&>(*this).value();
}
String IdentifierStyleValue::to_string() const
{
return CSS::string_from_value_id(m_id);

View file

@ -290,8 +290,11 @@ public:
return is_builtin() || is_custom_property() || is_calculated();
}
float as_number() const;
virtual String to_string() const = 0;
virtual Length to_length() const { return {}; }
virtual Color to_color(Layout::NodeWithStyle const&) const { return {}; }
CSS::ValueID to_identifier() const;