mirror of
https://github.com/zebrajr/ladybird.git
synced 2025-12-06 00:19:53 +01:00
LibWeb: Clamp calculated steps() interval count using normal system
Previously we were doing this ad-hoc later in the process but we now have the `calc` clamping system which can simplify things. This reveals some false-positives in that we don't handle relative lengths within these `calc`s but these are fixed in the next commit
This commit is contained in:
parent
06a57a280d
commit
ad41f053b8
|
|
@ -320,7 +320,7 @@ EasingFunction EasingFunction::from_style_value(StyleValue const& style_value)
|
|||
return CubicBezierEasingFunction { resolved_x1, resolved_y1, resolved_x2, resolved_y2, cubic_bezier.to_string(SerializationMode::Normal) };
|
||||
},
|
||||
[](EasingStyleValue::Steps const& steps) -> EasingFunction {
|
||||
auto resolved_interval_count = max(steps.number_of_intervals.resolved({}).value_or(1), steps.position == StepPosition::JumpNone ? 2 : 1);
|
||||
auto resolved_interval_count = steps.number_of_intervals.resolved({}).value_or(1);
|
||||
|
||||
return StepsEasingFunction { resolved_interval_count, steps.position, steps.to_string(SerializationMode::ResolvedValue) };
|
||||
});
|
||||
|
|
|
|||
|
|
@ -568,6 +568,8 @@ private:
|
|||
AngularColorStopList,
|
||||
CubicBezierFunctionXCoordinate,
|
||||
ShadowBlurRadius,
|
||||
StepsIntervalsJumpNone,
|
||||
StepsIntervalsNormal,
|
||||
TranslateZArgument
|
||||
};
|
||||
// FIXME: Use PropertyNameAndID instead of PropertyID as the context, for registered custom properties.
|
||||
|
|
|
|||
|
|
@ -2991,13 +2991,7 @@ RefPtr<StyleValue const> Parser::parse_easing_value(TokenStream<ComponentValue>&
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
EasingStyleValue::Steps steps;
|
||||
|
||||
auto const& intervals_argument = comma_separated_arguments[0][0];
|
||||
auto intervals_token = TokenStream<ComponentValue>::of_single_token(intervals_argument);
|
||||
auto intervals = parse_integer(intervals_token);
|
||||
if (!intervals.has_value())
|
||||
return nullptr;
|
||||
StepPosition position = StepPosition::End;
|
||||
|
||||
if (comma_separated_arguments.size() == 2) {
|
||||
if (comma_separated_arguments[1].size() != 1)
|
||||
|
|
@ -3018,15 +3012,23 @@ RefPtr<StyleValue const> Parser::parse_easing_value(TokenStream<ComponentValue>&
|
|||
if (!step_position.has_value())
|
||||
return nullptr;
|
||||
|
||||
steps.position = step_position.value();
|
||||
position = step_position.value();
|
||||
}
|
||||
|
||||
auto const& intervals_argument = comma_separated_arguments[0][0];
|
||||
auto intervals_token = TokenStream<ComponentValue>::of_single_token(intervals_argument);
|
||||
m_value_context.append(position == StepPosition::JumpNone ? SpecialContext::StepsIntervalsJumpNone : SpecialContext::StepsIntervalsNormal);
|
||||
auto intervals = parse_integer(intervals_token);
|
||||
m_value_context.take_last();
|
||||
if (!intervals.has_value())
|
||||
return nullptr;
|
||||
|
||||
// Perform extra validation
|
||||
// https://drafts.csswg.org/css-easing/#step-easing-functions
|
||||
// If the <step-position> is jump-none, the <integer> must be at least 2, or the function is invalid.
|
||||
// Otherwise, the <integer> must be at least 1, or the function is invalid.
|
||||
if (!intervals->is_calculated()) {
|
||||
if (steps.position == StepPosition::JumpNone) {
|
||||
if (position == StepPosition::JumpNone) {
|
||||
if (intervals->value() <= 1)
|
||||
return nullptr;
|
||||
} else if (intervals->value() <= 0) {
|
||||
|
|
@ -3034,9 +3036,8 @@ RefPtr<StyleValue const> Parser::parse_easing_value(TokenStream<ComponentValue>&
|
|||
}
|
||||
}
|
||||
|
||||
steps.number_of_intervals = *intervals;
|
||||
transaction.commit();
|
||||
return EasingStyleValue::create(steps);
|
||||
return EasingStyleValue::create(EasingStyleValue::Steps { *intervals, position });
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
|
@ -4142,6 +4143,10 @@ RefPtr<CalculatedStyleValue const> Parser::parse_calculated_value(ComponentValue
|
|||
case SpecialContext::CubicBezierFunctionXCoordinate:
|
||||
// Coordinates on the X axis must be between 0 and 1
|
||||
return CalculationContext { .accepted_type_ranges = { { ValueType::Number, { 0, 1 } } } };
|
||||
case SpecialContext::StepsIntervalsJumpNone:
|
||||
return CalculationContext { .resolve_numbers_as_integers = true, .accepted_type_ranges = { { ValueType::Integer, { 2, NumericLimits<float>::max() } } } };
|
||||
case SpecialContext::StepsIntervalsNormal:
|
||||
return CalculationContext { .resolve_numbers_as_integers = true, .accepted_type_ranges = { { ValueType::Integer, { 1, NumericLimits<float>::max() } } } };
|
||||
case SpecialContext::ShadowBlurRadius:
|
||||
return CalculationContext { .accepted_type_ranges = { { ValueType::Length, { 0, NumericLimits<float>::max() } } } };
|
||||
case SpecialContext::TranslateZArgument:
|
||||
|
|
|
|||
|
|
@ -137,15 +137,10 @@ String EasingStyleValue::Steps::to_string(SerializationMode mode) const
|
|||
return {};
|
||||
return CSS::to_string(this->position);
|
||||
}();
|
||||
auto intervals = number_of_intervals;
|
||||
if (mode == SerializationMode::ResolvedValue) {
|
||||
auto resolved_value = number_of_intervals.resolved({}).value_or(1);
|
||||
intervals = max(resolved_value, this->position == StepPosition::JumpNone ? 2 : 1);
|
||||
}
|
||||
if (position.has_value()) {
|
||||
builder.appendff("steps({}, {})", intervals.to_string(mode), position.value());
|
||||
builder.appendff("steps({}, {})", number_of_intervals.to_string(mode), position.value());
|
||||
} else {
|
||||
builder.appendff("steps({})", intervals.to_string(mode));
|
||||
builder.appendff("steps({})", number_of_intervals.to_string(mode));
|
||||
}
|
||||
}
|
||||
return MUST(builder.to_string());
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ Harness status: OK
|
|||
|
||||
Found 22 tests
|
||||
|
||||
20 Pass
|
||||
2 Fail
|
||||
18 Pass
|
||||
4 Fail
|
||||
Pass Property transition-timing-function value 'linear'
|
||||
Pass Property transition-timing-function value 'ease'
|
||||
Pass Property transition-timing-function value 'ease-in'
|
||||
|
|
@ -23,6 +23,6 @@ Pass Property transition-timing-function value 'steps(2, jump-both)'
|
|||
Pass Property transition-timing-function value 'steps(2, jump-none)'
|
||||
Fail Property transition-timing-function value 'steps(calc(2 * sibling-index()), jump-none)'
|
||||
Fail Property transition-timing-function value 'steps(sibling-index(), jump-none)'
|
||||
Pass Property transition-timing-function value 'steps(calc(2 * sign(1em - 1000px)), jump-none)'
|
||||
Pass Property transition-timing-function value 'steps(calc(2 * sign(1em - 1000px)), start)'
|
||||
Fail Property transition-timing-function value 'steps(calc(2 * sign(1em - 1000px)), jump-none)'
|
||||
Fail Property transition-timing-function value 'steps(calc(2 * sign(1em - 1000px)), start)'
|
||||
Pass Property transition-timing-function value 'linear, ease, linear'
|
||||
Loading…
Reference in New Issue
Block a user