mirror of
https://github.com/zebrajr/ladybird.git
synced 2025-12-06 00:19:53 +01:00
LibWeb: Define <opacity-value> as a ValueType
Since `<opacity-value>` is used across multiple properties it makes sense to have it defined as a value.
This commit is contained in:
parent
01c5b6f74f
commit
0e82ab2966
|
|
@ -398,6 +398,7 @@ private:
|
|||
RefPtr<StyleValue const> parse_contain_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<StyleValue const> parse_container_type_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<StringStyleValue const> parse_opentype_tag_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<StyleValue const> parse_opacity_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<FontSourceStyleValue const> parse_font_source_value(TokenStream<ComponentValue>&);
|
||||
|
||||
RefPtr<StyleValue const> parse_anchor(TokenStream<ComponentValue>&);
|
||||
|
|
@ -460,7 +461,6 @@ private:
|
|||
RefPtr<StyleValue const> parse_list_style_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<StyleValue const> parse_mask_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<StyleValue const> parse_math_depth_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<StyleValue const> parse_opacity_value(PropertyID property_id, TokenStream<ComponentValue>&);
|
||||
RefPtr<StyleValue const> parse_overflow_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<StyleValue const> parse_paint_order_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<StyleValue const> parse_place_content_value(TokenStream<ComponentValue>&);
|
||||
|
|
|
|||
|
|
@ -172,6 +172,8 @@ Optional<Parser::PropertyAndValue> Parser::parse_css_value_for_properties(Readon
|
|||
return parsed.release_value();
|
||||
if (auto parsed = parse_for_type(ValueType::Ratio); parsed.has_value())
|
||||
return parsed.release_value();
|
||||
if (auto parsed = parse_for_type(ValueType::Opacity); parsed.has_value())
|
||||
return parsed.release_value();
|
||||
if (auto parsed = parse_for_type(ValueType::OpentypeTag); parsed.has_value())
|
||||
return parsed.release_value();
|
||||
if (auto parsed = parse_for_type(ValueType::Rect); parsed.has_value())
|
||||
|
|
@ -721,14 +723,6 @@ Parser::ParseErrorOr<NonnullRefPtr<StyleValue const>> Parser::parse_css_value(Pr
|
|||
if (auto parsed_value = parse_comma_separated_value_list(tokens, [this, property_id](auto& tokens) { return parse_single_background_size_value(property_id, tokens); }))
|
||||
return parsed_value.release_nonnull();
|
||||
return ParseError::SyntaxError;
|
||||
case PropertyID::Opacity:
|
||||
case PropertyID::FillOpacity:
|
||||
case PropertyID::FloodOpacity:
|
||||
case PropertyID::StopOpacity:
|
||||
case PropertyID::StrokeOpacity:
|
||||
if (auto parsed_value = parse_opacity_value(property_id, tokens); parsed_value && !tokens.has_next_token())
|
||||
return parsed_value.release_nonnull();
|
||||
return ParseError::SyntaxError;
|
||||
// FIXME: This can be removed once we have generic logic for parsing "positional-value-list-shorthand"s
|
||||
case PropertyID::Overflow:
|
||||
if (auto parsed_value = parse_overflow_value(tokens); parsed_value && !tokens.has_next_token())
|
||||
|
|
@ -4061,19 +4055,6 @@ RefPtr<StyleValue const> Parser::parse_math_depth_value(TokenStream<ComponentVal
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<StyleValue const> Parser::parse_opacity_value(PropertyID property_id, TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
auto value = parse_css_value_for_property(property_id, tokens);
|
||||
if (!value)
|
||||
return nullptr;
|
||||
|
||||
// Percentages map to the range [0,1] for opacity values
|
||||
if (value->is_percentage())
|
||||
value = NumberStyleValue::create(value->as_percentage().percentage().as_fraction());
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
RefPtr<StyleValue const> Parser::parse_overflow_value(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
auto transaction = tokens.begin_transaction();
|
||||
|
|
|
|||
|
|
@ -4458,6 +4458,21 @@ RefPtr<CalculationNode const> Parser::parse_a_calculation(Vector<ComponentValue>
|
|||
return simplify_a_calculation_tree(*calculation_tree, context, CalculationResolutionContext {});
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-color-4/#typedef-opacity-opacity-value
|
||||
RefPtr<StyleValue const> Parser::parse_opacity_value(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
auto value = parse_number_percentage_value(tokens);
|
||||
|
||||
if (!value)
|
||||
return nullptr;
|
||||
|
||||
// Percentages map to the range [0,1] for opacity values
|
||||
if (value->is_percentage())
|
||||
return NumberStyleValue::create(value->as_percentage().percentage().as_fraction());
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-fonts/#typedef-opentype-tag
|
||||
RefPtr<StringStyleValue const> Parser::parse_opentype_tag_value(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
|
|
@ -4869,6 +4884,8 @@ RefPtr<StyleValue const> Parser::parse_value(ValueType value_type, TokenStream<C
|
|||
return parse_length_value(tokens);
|
||||
case ValueType::Number:
|
||||
return parse_number_value(tokens);
|
||||
case ValueType::Opacity:
|
||||
return parse_opacity_value(tokens);
|
||||
case ValueType::OpentypeTag:
|
||||
return parse_opentype_tag_value(tokens);
|
||||
case ValueType::Paint:
|
||||
|
|
|
|||
|
|
@ -1717,8 +1717,7 @@
|
|||
"inherited": true,
|
||||
"initial": "1",
|
||||
"valid-types": [
|
||||
"number [-∞,∞]",
|
||||
"percentage [-∞,∞]"
|
||||
"opacity"
|
||||
]
|
||||
},
|
||||
"fill-rule": {
|
||||
|
|
@ -1834,8 +1833,7 @@
|
|||
"inherited": false,
|
||||
"initial": "1",
|
||||
"valid-types": [
|
||||
"number [-∞,∞]",
|
||||
"percentage [-∞,∞]"
|
||||
"opacity"
|
||||
]
|
||||
},
|
||||
"font": {
|
||||
|
|
@ -2950,10 +2948,8 @@
|
|||
"inherited": false,
|
||||
"initial": "1",
|
||||
"valid-types": [
|
||||
"number [-∞,∞]",
|
||||
"percentage [-∞,∞]"
|
||||
],
|
||||
"__comment": "We don't have a percentages-resolve-to here because even though we're supposed to map percentages to [0,1], calc(10%) should resolve to 10% not 0.1."
|
||||
"opacity"
|
||||
]
|
||||
},
|
||||
"order": {
|
||||
"animation-type": "by-computed-value",
|
||||
|
|
@ -3479,10 +3475,8 @@
|
|||
"inherited": false,
|
||||
"initial": "1",
|
||||
"valid-types": [
|
||||
"number [-∞,∞]",
|
||||
"percentage [-∞,∞]"
|
||||
],
|
||||
"__comment": "We don't have a percentages-resolve-to here for the same reason as for opacity."
|
||||
"opacity"
|
||||
]
|
||||
},
|
||||
"stroke": {
|
||||
"affects-layout": false,
|
||||
|
|
@ -3545,10 +3539,8 @@
|
|||
"inherited": true,
|
||||
"initial": "1",
|
||||
"valid-types": [
|
||||
"number [-∞,∞]",
|
||||
"percentage [-∞,∞]"
|
||||
],
|
||||
"__comment": "We don't have a percentages-resolve-to here for the same reason as for opacity."
|
||||
"opacity"
|
||||
]
|
||||
},
|
||||
"stroke-width": {
|
||||
"affects-layout": false,
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ Optional<ValueType> value_type_from_string(StringView string)
|
|||
return ValueType::Length;
|
||||
if (string.equals_ignoring_ascii_case("number"sv))
|
||||
return ValueType::Number;
|
||||
if (string.equals_ignoring_ascii_case("opacity"sv))
|
||||
return ValueType::Opacity;
|
||||
if (string.equals_ignoring_ascii_case("opentype-tag"sv))
|
||||
return ValueType::OpentypeTag;
|
||||
if (string.equals_ignoring_ascii_case("paint"sv))
|
||||
|
|
@ -109,6 +111,8 @@ StringView value_type_to_string(ValueType value_type)
|
|||
return "Length"sv;
|
||||
case Web::CSS::ValueType::Number:
|
||||
return "Number"sv;
|
||||
case Web::CSS::ValueType::Opacity:
|
||||
return "Opacity"sv;
|
||||
case Web::CSS::ValueType::OpentypeTag:
|
||||
return "OpenTypeTag"sv;
|
||||
case Web::CSS::ValueType::Paint:
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ enum class ValueType : u8 {
|
|||
Integer,
|
||||
Length,
|
||||
Number,
|
||||
Opacity,
|
||||
OpentypeTag,
|
||||
Paint,
|
||||
Percentage,
|
||||
|
|
|
|||
|
|
@ -234,6 +234,7 @@ enum class PropertyID : @property_id_underlying_type@ {
|
|||
generator.set("first_inherited_longhand_property_id", title_casify(inherited_longhand_property_ids.first()));
|
||||
generator.set("last_inherited_longhand_property_id", title_casify(inherited_longhand_property_ids.last()));
|
||||
|
||||
// FIXME: property_accepts_{number,percentage}() has a different range from accepted_type_ranges() despite the names sounding similar.
|
||||
generator.append(R"~~~(
|
||||
};
|
||||
|
||||
|
|
@ -923,44 +924,42 @@ AcceptedTypeRangeMap property_accepted_type_ranges(PropertyID property_id)
|
|||
|
||||
StringBuilder ranges_builder;
|
||||
|
||||
// Opacity values are unique in that the range which calculated and interpolated values should be clamped
|
||||
// to [0,1] is different from the range of allowed values [-∞,∞]. To handle this we set the allowed range
|
||||
// in Properties.json to [-∞,∞] but overwrite it to [0,1] here.
|
||||
// FIXME: This is confusing as property_accepts_{number,percentage}() has a different range from this
|
||||
// despite the names sounding similar.
|
||||
if (first_is_one_of(name, "opacity"sv, "fill-opacity"sv, "flood-opacity"sv, "stop-opacity"sv, "stroke-opacity"sv)) {
|
||||
ranges_builder.append("{ ValueType::Number, { 0, 1 } }, { ValueType::Percentage, { 0, 100 } }"sv);
|
||||
} else {
|
||||
for (auto& type : valid_types.values()) {
|
||||
VERIFY(type.is_string());
|
||||
for (auto& type : valid_types.values()) {
|
||||
VERIFY(type.is_string());
|
||||
|
||||
Vector<String> type_parts = MUST(type.as_string().split(' '));
|
||||
|
||||
if (type_parts.size() < 2)
|
||||
continue;
|
||||
|
||||
auto type_name = type_parts.first();
|
||||
|
||||
if (type_name == "custom-ident")
|
||||
continue;
|
||||
|
||||
// Drop the brackets on the range e.g. "[-∞,∞]" -> "-∞,∞"
|
||||
auto type_range = MUST(type_parts.get(1)->substring_from_byte_offset(1, type_parts.get(1)->byte_count() - 2));
|
||||
|
||||
auto limits = MUST(type_range.split(','));
|
||||
|
||||
if (limits.size() != 2)
|
||||
VERIFY_NOT_REACHED();
|
||||
|
||||
// FIXME: Use min and max values for i32 instead of float where applicable (e.g. for "integer")
|
||||
auto min = limits.get(0) == "-∞" ? "AK::NumericLimits<float>::lowest()"_string : *limits.get(0);
|
||||
auto max = limits.get(1) == "∞" ? "AK::NumericLimits<float>::max()"_string : *limits.get(1);
|
||||
|
||||
if (!ranges_builder.is_empty())
|
||||
ranges_builder.appendff(", ");
|
||||
|
||||
ranges_builder.appendff("{{ ValueType::{}, {{ {}, {} }} }}", title_casify(type_name), min, max);
|
||||
// Opacity values should have their calculated and interpolated values clamped to [0,1] which is
|
||||
// different from the range of allowed values [-∞,∞].
|
||||
if (type.as_string() == "opacity"sv) {
|
||||
ranges_builder.append("{ ValueType::Number, { 0, 1 } }, { ValueType::Percentage, { 0, 100 } }"sv);
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector<String> type_parts = MUST(type.as_string().split(' '));
|
||||
|
||||
if (type_parts.size() < 2)
|
||||
continue;
|
||||
|
||||
auto type_name = type_parts.first();
|
||||
|
||||
if (type_name == "custom-ident")
|
||||
continue;
|
||||
|
||||
// Drop the brackets on the range e.g. "[-∞,∞]" -> "-∞,∞"
|
||||
auto type_range = MUST(type_parts.get(1)->substring_from_byte_offset(1, type_parts.get(1)->byte_count() - 2));
|
||||
|
||||
auto limits = MUST(type_range.split(','));
|
||||
|
||||
if (limits.size() != 2)
|
||||
VERIFY_NOT_REACHED();
|
||||
|
||||
// FIXME: Use min and max values for i32 instead of float where applicable (e.g. for "integer")
|
||||
auto min = limits.get(0) == "-∞" ? "AK::NumericLimits<float>::lowest()"_string : *limits.get(0);
|
||||
auto max = limits.get(1) == "∞" ? "AK::NumericLimits<float>::max()"_string : *limits.get(1);
|
||||
|
||||
if (!ranges_builder.is_empty())
|
||||
ranges_builder.appendff(", ");
|
||||
|
||||
ranges_builder.appendff("{{ ValueType::{}, {{ {}, {} }} }}", title_casify(type_name), min, max);
|
||||
}
|
||||
|
||||
property_generator.set("ranges", ranges_builder.to_string_without_validation());
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user