mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 20:15:17 +00:00
LibWeb/CSS: Remove use of Dimension in calc() parsing
Rather than partly-converting number, dimension, and ident tokens at the start of parsing a calculation, and then later finishing it off, we can just do the whole step in convert_to_calculation_node(). This is a little less code, but mainly means we are left with only a single use of the Dimension type in the codebase, so that can be removed soon.
This commit is contained in:
parent
5cda2ac961
commit
ba43dfe49a
Notes:
github-actions[bot]
2025-01-08 14:29:57 +00:00
Author: https://github.com/AtkinsSJ Commit: https://github.com/LadybirdBrowser/ladybird/commit/ba43dfe49a5 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3167
2 changed files with 51 additions and 52 deletions
|
@ -9175,39 +9175,6 @@ OwnPtr<CalculationNode> Parser::convert_to_calculation_node(CalcParsing::Node co
|
|||
return NegateCalculationNode::create(child_as_node.release_nonnull());
|
||||
return nullptr;
|
||||
},
|
||||
[](Number const& number) -> OwnPtr<CalculationNode> {
|
||||
return NumericCalculationNode::create(number);
|
||||
},
|
||||
[this](Dimension const& dimension) -> OwnPtr<CalculationNode> {
|
||||
if (dimension.is_angle())
|
||||
return NumericCalculationNode::create(dimension.angle());
|
||||
if (dimension.is_frequency())
|
||||
return NumericCalculationNode::create(dimension.frequency());
|
||||
if (dimension.is_length())
|
||||
return NumericCalculationNode::create(dimension.length());
|
||||
if (dimension.is_percentage()) {
|
||||
// FIXME: Figure this out in non-property contexts
|
||||
auto percentage_resolved_type = property_resolves_percentages_relative_to(m_context.current_property_id());
|
||||
return NumericCalculationNode::create(dimension.percentage(), percentage_resolved_type);
|
||||
}
|
||||
if (dimension.is_resolution())
|
||||
return NumericCalculationNode::create(dimension.resolution());
|
||||
if (dimension.is_time())
|
||||
return NumericCalculationNode::create(dimension.time());
|
||||
if (dimension.is_flex()) {
|
||||
// https://www.w3.org/TR/css3-grid-layout/#fr-unit
|
||||
// NOTE: <flex> values are not <length>s (nor are they compatible with <length>s, like some <percentage> values),
|
||||
// so they cannot be represented in or combined with other unit types in calc() expressions.
|
||||
// FIXME: Flex is allowed in calc(), so figure out what this spec text means and how to implement it.
|
||||
dbgln_if(CSS_PARSER_DEBUG, "Rejecting <flex> in calc()");
|
||||
return nullptr;
|
||||
}
|
||||
dbgln_if(CSS_PARSER_DEBUG, "Unrecognized dimension type in calc() expression: {}", dimension.to_string());
|
||||
return nullptr;
|
||||
},
|
||||
[](CalculationNode::ConstantType const& constant_type) -> OwnPtr<CalculationNode> {
|
||||
return ConstantCalculationNode::create(constant_type);
|
||||
},
|
||||
[this](NonnullRawPtr<ComponentValue const> const& component_value) -> OwnPtr<CalculationNode> {
|
||||
// NOTE: This is the "process the leaf nodes" part of step 5 of https://drafts.csswg.org/css-values-4/#parse-a-calculation
|
||||
// We divert a little from the spec: Rather than modify an existing tree of values, we construct a new one from that source tree.
|
||||
|
@ -9233,6 +9200,56 @@ OwnPtr<CalculationNode> Parser::convert_to_calculation_node(CalcParsing::Node co
|
|||
return leaf_calculation.release_nonnull();
|
||||
}
|
||||
|
||||
// AD-HOC: We also need to convert tokens into their numeric types.
|
||||
|
||||
if (component_value->is(Token::Type::Ident)) {
|
||||
auto maybe_constant = CalculationNode::constant_type_from_string(component_value->token().ident());
|
||||
if (!maybe_constant.has_value())
|
||||
return nullptr;
|
||||
return ConstantCalculationNode::create(*maybe_constant);
|
||||
}
|
||||
|
||||
if (component_value->is(Token::Type::Number))
|
||||
return NumericCalculationNode::create(component_value->token().number());
|
||||
|
||||
if (component_value->is(Token::Type::Dimension)) {
|
||||
auto numeric_value = component_value->token().dimension_value();
|
||||
auto unit_string = component_value->token().dimension_unit();
|
||||
|
||||
if (auto length_type = Length::unit_from_name(unit_string); length_type.has_value())
|
||||
return NumericCalculationNode::create(Length { numeric_value, length_type.release_value() });
|
||||
|
||||
if (auto angle_type = Angle::unit_from_name(unit_string); angle_type.has_value())
|
||||
return NumericCalculationNode::create(Angle { numeric_value, angle_type.release_value() });
|
||||
|
||||
if (auto flex_type = Flex::unit_from_name(unit_string); flex_type.has_value()) {
|
||||
// https://www.w3.org/TR/css3-grid-layout/#fr-unit
|
||||
// NOTE: <flex> values are not <length>s (nor are they compatible with <length>s, like some <percentage> values),
|
||||
// so they cannot be represented in or combined with other unit types in calc() expressions.
|
||||
// FIXME: Flex is allowed in calc(), so figure out what this spec text means and how to implement it.
|
||||
dbgln_if(CSS_PARSER_DEBUG, "Rejecting <flex> in calc()");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (auto frequency_type = Frequency::unit_from_name(unit_string); frequency_type.has_value())
|
||||
return NumericCalculationNode::create(Frequency { numeric_value, frequency_type.release_value() });
|
||||
|
||||
if (auto resolution_type = Resolution::unit_from_name(unit_string); resolution_type.has_value())
|
||||
return NumericCalculationNode::create(Resolution { numeric_value, resolution_type.release_value() });
|
||||
|
||||
if (auto time_type = Time::unit_from_name(unit_string); time_type.has_value())
|
||||
return NumericCalculationNode::create(Time { numeric_value, time_type.release_value() });
|
||||
|
||||
dbgln_if(CSS_PARSER_DEBUG, "Unrecognized dimension type in calc() expression: {}", component_value->to_string());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (component_value->is(Token::Type::Percentage)) {
|
||||
// FIXME: Figure this out in non-property contexts
|
||||
auto percentage_resolved_type = property_resolves_percentages_relative_to(m_context.current_property_id());
|
||||
return NumericCalculationNode::create(Percentage { component_value->token().percentage() }, percentage_resolved_type);
|
||||
}
|
||||
|
||||
// NOTE: If we get here, then we have a ComponentValue that didn't get replaced with something else,
|
||||
// so the calc() is invalid.
|
||||
dbgln_if(CSS_PARSER_DEBUG, "Leftover ComponentValue in calc tree! That probably means the syntax is invalid, but maybe we just didn't implement `{}` yet.", component_value->to_debug_string());
|
||||
|
@ -9265,24 +9282,6 @@ OwnPtr<CalculationNode> Parser::parse_a_calculation(Vector<ComponentValue> const
|
|||
}
|
||||
}
|
||||
|
||||
if (value.is(Token::Type::Ident)) {
|
||||
auto maybe_constant = CalculationNode::constant_type_from_string(value.token().ident());
|
||||
if (maybe_constant.has_value()) {
|
||||
values.append(maybe_constant.value());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (value.is(Token::Type::Number)) {
|
||||
values.append(value.token().number());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (auto dimension = parse_dimension(value); dimension.has_value()) {
|
||||
values.append(dimension.release_value());
|
||||
continue;
|
||||
}
|
||||
|
||||
values.append(NonnullRawPtr { value });
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ struct ProductNode;
|
|||
struct SumNode;
|
||||
struct InvertNode;
|
||||
struct NegateNode;
|
||||
using Node = Variant<Operator, Number, Dimension, CalculationNode::ConstantType, NonnullOwnPtr<ProductNode>, NonnullOwnPtr<SumNode>, NonnullOwnPtr<InvertNode>, NonnullOwnPtr<NegateNode>, NonnullRawPtr<ComponentValue const>>;
|
||||
using Node = Variant<Operator, NonnullOwnPtr<ProductNode>, NonnullOwnPtr<SumNode>, NonnullOwnPtr<InvertNode>, NonnullOwnPtr<NegateNode>, NonnullRawPtr<ComponentValue const>>;
|
||||
struct ProductNode {
|
||||
Vector<Node> children;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue