mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-23 00:19:18 +00:00
LibWeb: Maintain easing keywords as KeywordStyleValue
until use-time
This excludes `step-end` and `step-start` which are expected to be converted to the equivalent function at parse time. We are expected to serialize these as the explicit keywords - previously we would parse as `EasingStyleValue` and serialize equivalent functions as the keywords. This caused issues as we would incorrectly serialize even explicit functions as the keyword. This also allows us to move the magic easing functions to `EasingFunction` rather than `EasingStyleValue` which is a bit tidier
This commit is contained in:
parent
755a576013
commit
03be70087d
Notes:
github-actions[bot]
2025-10-20 10:29:02 +00:00
Author: https://github.com/Calme1709
Commit: 03be70087d
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6459
Reviewed-by: https://github.com/AtkinsSJ ✅
15 changed files with 210 additions and 125 deletions
|
@ -13,7 +13,9 @@
|
|||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/CSS/ComputedProperties.h>
|
||||
#include <LibWeb/CSS/Parser/Parser.h>
|
||||
#include <LibWeb/CSS/StyleComputer.h>
|
||||
#include <LibWeb/CSS/StyleInvalidation.h>
|
||||
#include <LibWeb/CSS/StyleValues/KeywordStyleValue.h>
|
||||
#include <LibWeb/DOM/Element.h>
|
||||
#include <LibWeb/Layout/Node.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
|
@ -606,9 +608,11 @@ Optional<double> AnimationEffect::transformed_progress() const
|
|||
Optional<CSS::EasingFunction> AnimationEffect::parse_easing_string(StringView value)
|
||||
{
|
||||
if (auto style_value = parse_css_value(CSS::Parser::ParsingParams(), value, CSS::PropertyID::AnimationTimingFunction)) {
|
||||
if (style_value->is_easing())
|
||||
if (style_value->is_unresolved() || style_value->is_value_list() || style_value->is_css_wide_keyword())
|
||||
return {};
|
||||
|
||||
// FIXME: We should absolutize style_value to resolve relative lengths within calcs
|
||||
return CSS::EasingFunction::from_style_value(*style_value);
|
||||
return CSS::EasingFunction::from_style_value(style_value.release_nonnull());
|
||||
}
|
||||
|
||||
return {};
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/CSS/EasingFunction.h>
|
||||
#include <LibWeb/CSS/Enums.h>
|
||||
#include <LibWeb/CSS/StyleValues/EasingStyleValue.h>
|
||||
|
||||
namespace Web::Animations {
|
||||
|
||||
|
@ -194,7 +193,7 @@ protected:
|
|||
GC::Ptr<Animation> m_associated_animation {};
|
||||
|
||||
// https://www.w3.org/TR/web-animations-1/#time-transformations
|
||||
CSS::EasingFunction m_timing_function { CSS::EasingFunction::from_style_value(CSS::EasingStyleValue::create(CSS::EasingStyleValue::Linear::identity())) };
|
||||
CSS::EasingFunction m_timing_function { CSS::EasingFunction::linear() };
|
||||
|
||||
// Used for calculating transitions in StyleComputer
|
||||
Phase m_previous_phase { Phase::Idle };
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <AK/BinarySearch.h>
|
||||
#include <LibWeb/CSS/StyleValues/EasingStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/IntegerStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/KeywordStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/NumberStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
|
||||
|
||||
|
@ -268,6 +269,41 @@ static Vector<LinearEasingFunction::ControlPoint> canonicalize_linear_easing_fun
|
|||
return canonicalized_control_points;
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-easing-2/#linear-easing-function
|
||||
EasingFunction EasingFunction::linear()
|
||||
{
|
||||
// Equivalent to linear(0, 1)
|
||||
return LinearEasingFunction { { { 0, 0 }, { 1, 1 } }, "linear"_string };
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-easing-2/#valdef-cubic-bezier-easing-function-ease-in
|
||||
EasingFunction EasingFunction::ease_in()
|
||||
{
|
||||
// Equivalent to cubic-bezier(0.42, 0, 1, 1).
|
||||
return CubicBezierEasingFunction { 0.42, 0, 1, 1, "ease-in"_string };
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-easing-2/#valdef-cubic-bezier-easing-function-ease-out
|
||||
EasingFunction EasingFunction::ease_out()
|
||||
{
|
||||
// Equivalent to cubic-bezier(0, 0, 0.58, 1).
|
||||
return CubicBezierEasingFunction { 0, 0, 0.58, 1, "ease-out"_string };
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-easing-2/#valdef-cubic-bezier-easing-function-ease-in-out
|
||||
EasingFunction EasingFunction::ease_in_out()
|
||||
{
|
||||
// Equivalent to cubic-bezier(0.42, 0, 0.58, 1).
|
||||
return CubicBezierEasingFunction { 0.42, 0, 0.58, 1, "ease-in-out"_string };
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-easing-2/#valdef-cubic-bezier-easing-function-ease
|
||||
EasingFunction EasingFunction::ease()
|
||||
{
|
||||
// Equivalent to cubic-bezier(0.25, 0.1, 0.25, 1).
|
||||
return CubicBezierEasingFunction { 0.25, 0.1, 0.25, 1, "ease"_string };
|
||||
}
|
||||
|
||||
EasingFunction EasingFunction::from_style_value(StyleValue const& style_value)
|
||||
{
|
||||
auto const resolve_number = [](StyleValue const& style_value) {
|
||||
|
@ -335,6 +371,22 @@ EasingFunction EasingFunction::from_style_value(StyleValue const& style_value)
|
|||
});
|
||||
}
|
||||
|
||||
switch (style_value.to_keyword()) {
|
||||
case Keyword::Linear:
|
||||
return EasingFunction::linear();
|
||||
case Keyword::EaseIn:
|
||||
return EasingFunction::ease_in();
|
||||
case Keyword::EaseOut:
|
||||
return EasingFunction::ease_out();
|
||||
case Keyword::EaseInOut:
|
||||
return EasingFunction::ease_in_out();
|
||||
case Keyword::Ease:
|
||||
return EasingFunction::ease();
|
||||
default: {
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,13 @@ struct StepsEasingFunction {
|
|||
|
||||
struct EasingFunction : public Variant<LinearEasingFunction, CubicBezierEasingFunction, StepsEasingFunction> {
|
||||
using Variant::Variant;
|
||||
|
||||
static EasingFunction linear();
|
||||
static EasingFunction ease_in();
|
||||
static EasingFunction ease_out();
|
||||
static EasingFunction ease_in_out();
|
||||
static EasingFunction ease();
|
||||
|
||||
static EasingFunction from_style_value(StyleValue const&);
|
||||
|
||||
double evaluate_at(double input_progress, bool before_flag) const;
|
||||
|
|
|
@ -281,6 +281,13 @@
|
|||
"inline",
|
||||
"run-in"
|
||||
],
|
||||
"easing-keyword": [
|
||||
"linear",
|
||||
"ease",
|
||||
"ease-in",
|
||||
"ease-out",
|
||||
"ease-in-out"
|
||||
],
|
||||
"empty-cells": [
|
||||
"show",
|
||||
"hide"
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include <LibWeb/CSS/StyleValues/CursorStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/CustomIdentStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/DisplayStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/EasingStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/EdgeStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/FilterValueListStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/FitContentStyleValue.h>
|
||||
|
@ -825,7 +824,7 @@ Parser::ParseErrorOr<NonnullRefPtr<StyleValue const>> Parser::parse_css_value(Pr
|
|||
return parsed_value.release_nonnull();
|
||||
return ParseError::SyntaxError;
|
||||
case PropertyID::TransitionTimingFunction:
|
||||
if (auto parsed_value = parse_comma_separated_value_list(tokens, [this](auto& tokens) { return parse_easing_value(tokens); }))
|
||||
if (auto parsed_value = parse_simple_comma_separated_value_list(property_id, tokens); parsed_value && !tokens.has_next_token())
|
||||
return parsed_value.release_nonnull();
|
||||
return ParseError::SyntaxError;
|
||||
case PropertyID::Translate:
|
||||
|
@ -5117,7 +5116,7 @@ RefPtr<StyleValue const> Parser::parse_transition_value(TokenStream<ComponentVal
|
|||
continue;
|
||||
}
|
||||
|
||||
if (auto easing = parse_easing_value(tokens)) {
|
||||
if (auto easing = parse_css_value_for_property(PropertyID::TransitionTimingFunction, tokens)) {
|
||||
if (transition.easing) {
|
||||
ErrorReporter::the().report(InvalidPropertyError {
|
||||
.property_name = "transition"_fly_string,
|
||||
|
@ -5127,7 +5126,7 @@ RefPtr<StyleValue const> Parser::parse_transition_value(TokenStream<ComponentVal
|
|||
return {};
|
||||
}
|
||||
|
||||
transition.easing = easing->as_easing();
|
||||
transition.easing = easing;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -5183,7 +5182,7 @@ RefPtr<StyleValue const> Parser::parse_transition_value(TokenStream<ComponentVal
|
|||
transition.property_name = KeywordStyleValue::create(Keyword::All);
|
||||
|
||||
if (!transition.easing)
|
||||
transition.easing = EasingStyleValue::create(EasingStyleValue::CubicBezier::ease());
|
||||
transition.easing = KeywordStyleValue::create(Keyword::Ease);
|
||||
|
||||
transitions.append(move(transition));
|
||||
|
||||
|
|
|
@ -2865,20 +2865,10 @@ RefPtr<StyleValue const> Parser::parse_easing_value(TokenStream<ComponentValue>&
|
|||
if (part.is(Token::Type::Ident)) {
|
||||
auto name = part.token().ident();
|
||||
auto maybe_simple_easing = [&] -> RefPtr<EasingStyleValue const> {
|
||||
if (name.equals_ignoring_ascii_case("linear"sv))
|
||||
return EasingStyleValue::create(EasingStyleValue::Linear::identity());
|
||||
if (name.equals_ignoring_ascii_case("ease"sv))
|
||||
return EasingStyleValue::create(EasingStyleValue::CubicBezier::ease());
|
||||
if (name.equals_ignoring_ascii_case("ease-in"sv))
|
||||
return EasingStyleValue::create(EasingStyleValue::CubicBezier::ease_in());
|
||||
if (name.equals_ignoring_ascii_case("ease-out"sv))
|
||||
return EasingStyleValue::create(EasingStyleValue::CubicBezier::ease_out());
|
||||
if (name.equals_ignoring_ascii_case("ease-in-out"sv))
|
||||
return EasingStyleValue::create(EasingStyleValue::CubicBezier::ease_in_out());
|
||||
if (name.equals_ignoring_ascii_case("step-start"sv))
|
||||
return EasingStyleValue::create(EasingStyleValue::Steps::step_start());
|
||||
return EasingStyleValue::create(EasingStyleValue::Steps { IntegerStyleValue::create(1), StepPosition::Start });
|
||||
if (name.equals_ignoring_ascii_case("step-end"sv))
|
||||
return EasingStyleValue::create(EasingStyleValue::Steps::step_end());
|
||||
return EasingStyleValue::create(EasingStyleValue::Steps { IntegerStyleValue::create(1), StepPosition::End });
|
||||
return {};
|
||||
}();
|
||||
|
||||
|
|
|
@ -345,7 +345,8 @@
|
|||
"__comment": "FIXME: animation properties should be coordinating-lists",
|
||||
"multiplicity": "single",
|
||||
"valid-types": [
|
||||
"easing-function"
|
||||
"easing-function",
|
||||
"easing-keyword"
|
||||
]
|
||||
},
|
||||
"appearance": {
|
||||
|
@ -3900,7 +3901,8 @@
|
|||
"initial": "ease",
|
||||
"multiplicity": "coordinating-list",
|
||||
"valid-types": [
|
||||
"easing-function"
|
||||
"easing-function",
|
||||
"easing-keyword"
|
||||
]
|
||||
},
|
||||
"translate": {
|
||||
|
|
|
@ -718,7 +718,7 @@ void StyleComputer::for_each_property_expanding_shorthands(PropertyID property_i
|
|||
set_longhand_property(CSS::PropertyID::TransitionProperty, KeywordStyleValue::create(Keyword::All));
|
||||
set_longhand_property(CSS::PropertyID::TransitionDuration, TimeStyleValue::create(CSS::Time::make_seconds(0)));
|
||||
set_longhand_property(CSS::PropertyID::TransitionDelay, TimeStyleValue::create(CSS::Time::make_seconds(0)));
|
||||
set_longhand_property(CSS::PropertyID::TransitionTimingFunction, EasingStyleValue::create(EasingStyleValue::CubicBezier::ease()));
|
||||
set_longhand_property(CSS::PropertyID::TransitionTimingFunction, KeywordStyleValue::create(Keyword::Ease));
|
||||
set_longhand_property(CSS::PropertyID::TransitionBehavior, KeywordStyleValue::create(Keyword::Normal));
|
||||
} else if (value.is_transition()) {
|
||||
auto const& transitions = value.as_transition().transitions();
|
||||
|
@ -1277,9 +1277,9 @@ static void apply_animation_properties(DOM::Document& document, CascadedProperti
|
|||
play_state = *play_state_value;
|
||||
}
|
||||
|
||||
EasingFunction timing_function = EasingFunction::from_style_value(EasingStyleValue::create(EasingStyleValue::CubicBezier::ease()));
|
||||
if (auto timing_property = cascaded_properties.property(PropertyID::AnimationTimingFunction); timing_property && timing_property->is_easing())
|
||||
timing_function = EasingFunction::from_style_value(timing_property->as_easing());
|
||||
EasingFunction timing_function = EasingFunction::ease();
|
||||
if (auto timing_property = cascaded_properties.property(PropertyID::AnimationTimingFunction); timing_property && (timing_property->is_easing() || (timing_property->is_keyword() && !timing_property->is_css_wide_keyword())))
|
||||
timing_function = EasingFunction::from_style_value(timing_property.release_nonnull());
|
||||
|
||||
Bindings::CompositeOperation composite_operation { Bindings::CompositeOperation::Replace };
|
||||
if (auto composite_property = cascaded_properties.property(PropertyID::AnimationComposition); composite_property) {
|
||||
|
@ -1421,7 +1421,7 @@ static void compute_transitioned_properties(ComputedProperties const& style, DOM
|
|||
[] { return TimeStyleValue::create(Time::make_seconds(0.0)); });
|
||||
auto timing_functions = normalize_transition_length_list(
|
||||
PropertyID::TransitionTimingFunction,
|
||||
[] { return EasingStyleValue::create(EasingStyleValue::CubicBezier::ease()); });
|
||||
[] { return KeywordStyleValue::create(Keyword::Ease); });
|
||||
auto transition_behaviors = normalize_transition_length_list(
|
||||
PropertyID::TransitionBehavior,
|
||||
[] { return KeywordStyleValue::create(Keyword::None); });
|
||||
|
|
|
@ -16,58 +16,9 @@
|
|||
|
||||
namespace Web::CSS {
|
||||
|
||||
// https://drafts.csswg.org/css-easing-1/#valdef-easing-function-linear
|
||||
EasingStyleValue::Linear EasingStyleValue::Linear::identity()
|
||||
{
|
||||
static Linear linear { { { NumberStyleValue::create(0), {} }, { NumberStyleValue::create(1), {} } } };
|
||||
return linear;
|
||||
}
|
||||
|
||||
// NOTE: Magic cubic bezier values from https://www.w3.org/TR/css-easing-1/#valdef-cubic-bezier-easing-function-ease
|
||||
|
||||
EasingStyleValue::CubicBezier EasingStyleValue::CubicBezier::ease()
|
||||
{
|
||||
static CubicBezier bezier { NumberStyleValue::create(0.25), NumberStyleValue::create(0.1), NumberStyleValue::create(0.25), NumberStyleValue::create(1.0) };
|
||||
return bezier;
|
||||
}
|
||||
|
||||
EasingStyleValue::CubicBezier EasingStyleValue::CubicBezier::ease_in()
|
||||
{
|
||||
static CubicBezier bezier { NumberStyleValue::create(0.42), NumberStyleValue::create(0.0), NumberStyleValue::create(1.0), NumberStyleValue::create(1.0) };
|
||||
return bezier;
|
||||
}
|
||||
|
||||
EasingStyleValue::CubicBezier EasingStyleValue::CubicBezier::ease_out()
|
||||
{
|
||||
static CubicBezier bezier { NumberStyleValue::create(0.0), NumberStyleValue::create(0.0), NumberStyleValue::create(0.58), NumberStyleValue::create(1.0) };
|
||||
return bezier;
|
||||
}
|
||||
|
||||
EasingStyleValue::CubicBezier EasingStyleValue::CubicBezier::ease_in_out()
|
||||
{
|
||||
static CubicBezier bezier { NumberStyleValue::create(0.42), NumberStyleValue::create(0.0), NumberStyleValue::create(0.58), NumberStyleValue::create(1.0) };
|
||||
return bezier;
|
||||
}
|
||||
|
||||
EasingStyleValue::Steps EasingStyleValue::Steps::step_start()
|
||||
{
|
||||
static Steps steps { IntegerStyleValue::create(1), StepPosition::Start };
|
||||
return steps;
|
||||
}
|
||||
|
||||
EasingStyleValue::Steps EasingStyleValue::Steps::step_end()
|
||||
{
|
||||
static Steps steps { IntegerStyleValue::create(1), StepPosition::End };
|
||||
return steps;
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-easing/#linear-easing-function-serializing
|
||||
String EasingStyleValue::Linear::to_string(SerializationMode mode) const
|
||||
{
|
||||
// The linear keyword is serialized as itself.
|
||||
if (*this == identity())
|
||||
return "linear"_string;
|
||||
|
||||
// To serialize a linear() function:
|
||||
// 1. Let s be the string "linear(".
|
||||
StringBuilder builder;
|
||||
|
@ -106,44 +57,23 @@ String EasingStyleValue::Linear::to_string(SerializationMode mode) const
|
|||
// https://drafts.csswg.org/css-easing/#bezier-serialization
|
||||
String EasingStyleValue::CubicBezier::to_string(SerializationMode mode) const
|
||||
{
|
||||
StringBuilder builder;
|
||||
if (*this == CubicBezier::ease()) {
|
||||
builder.append("ease"sv);
|
||||
} else if (*this == CubicBezier::ease_in()) {
|
||||
builder.append("ease-in"sv);
|
||||
} else if (*this == CubicBezier::ease_out()) {
|
||||
builder.append("ease-out"sv);
|
||||
} else if (*this == CubicBezier::ease_in_out()) {
|
||||
builder.append("ease-in-out"sv);
|
||||
} else {
|
||||
builder.appendff("cubic-bezier({}, {}, {}, {})", x1->to_string(mode), y1->to_string(mode), x2->to_string(mode), y2->to_string(mode));
|
||||
}
|
||||
return MUST(builder.to_string());
|
||||
return MUST(String::formatted("cubic-bezier({}, {}, {}, {})", x1->to_string(mode), y1->to_string(mode), x2->to_string(mode), y2->to_string(mode)));
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-easing/#steps-serialization
|
||||
String EasingStyleValue::Steps::to_string(SerializationMode mode) const
|
||||
{
|
||||
StringBuilder builder;
|
||||
// Unlike the other easing function keywords, step-start and step-end do not serialize as themselves.
|
||||
// Instead, they serialize as "steps(1, start)" and "steps(1)", respectively.
|
||||
if (*this == Steps::step_start()) {
|
||||
builder.append("steps(1, start)"sv);
|
||||
} else if (*this == Steps::step_end()) {
|
||||
builder.append("steps(1)"sv);
|
||||
} else {
|
||||
auto position = [&] -> Optional<StringView> {
|
||||
if (first_is_one_of(this->position, StepPosition::JumpEnd, StepPosition::End))
|
||||
return {};
|
||||
return CSS::to_string(this->position);
|
||||
}();
|
||||
|
||||
if (position.has_value()) {
|
||||
builder.appendff("steps({}, {})", number_of_intervals->to_string(mode), position.value());
|
||||
} else {
|
||||
builder.appendff("steps({})", number_of_intervals->to_string(mode));
|
||||
return MUST(String::formatted("steps({}, {})", number_of_intervals->to_string(mode), position.value()));
|
||||
}
|
||||
}
|
||||
return MUST(builder.to_string());
|
||||
|
||||
return MUST(String::formatted("steps({})", number_of_intervals->to_string(mode)));
|
||||
}
|
||||
|
||||
String EasingStyleValue::Function::to_string(SerializationMode mode) const
|
||||
|
|
|
@ -19,8 +19,6 @@ namespace Web::CSS {
|
|||
class EasingStyleValue final : public StyleValueWithDefaultOperators<EasingStyleValue> {
|
||||
public:
|
||||
struct Linear {
|
||||
static Linear identity();
|
||||
|
||||
struct Stop {
|
||||
ValueComparingNonnullRefPtr<StyleValue const> output;
|
||||
ValueComparingRefPtr<StyleValue const> input;
|
||||
|
@ -36,11 +34,6 @@ public:
|
|||
};
|
||||
|
||||
struct CubicBezier {
|
||||
static CubicBezier ease();
|
||||
static CubicBezier ease_in();
|
||||
static CubicBezier ease_out();
|
||||
static CubicBezier ease_in_out();
|
||||
|
||||
ValueComparingNonnullRefPtr<StyleValue const> x1;
|
||||
ValueComparingNonnullRefPtr<StyleValue const> y1;
|
||||
ValueComparingNonnullRefPtr<StyleValue const> x2;
|
||||
|
@ -63,9 +56,6 @@ public:
|
|||
};
|
||||
|
||||
struct Steps {
|
||||
static Steps step_start();
|
||||
static Steps step_end();
|
||||
|
||||
ValueComparingNonnullRefPtr<StyleValue const> number_of_intervals;
|
||||
StepPosition position;
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include <LibWeb/CSS/CalculatedOr.h>
|
||||
#include <LibWeb/CSS/StyleValues/CustomIdentStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/EasingStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/StyleValue.h>
|
||||
#include <LibWeb/CSS/Time.h>
|
||||
|
||||
|
@ -20,7 +19,7 @@ public:
|
|||
ValueComparingRefPtr<StyleValue const> property_name;
|
||||
TimeOrCalculated duration { CSS::Time::make_seconds(0.0) };
|
||||
TimeOrCalculated delay { CSS::Time::make_seconds(0.0) };
|
||||
ValueComparingRefPtr<EasingStyleValue const> easing;
|
||||
ValueComparingRefPtr<StyleValue const> easing;
|
||||
TransitionBehavior transition_behavior { TransitionBehavior::Normal };
|
||||
|
||||
bool operator==(Transition const&) const = default;
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
Specified: #linear { animation-timing-function: linear; transition-timing-function: linear(0, 1); }
|
||||
Keyword computed: linear
|
||||
Function computed: linear(0, 1)
|
||||
|
||||
Specified: #ease-in { animation-timing-function: ease-in; transition-timing-function: cubic-bezier(0.42, 0, 1, 1); }
|
||||
Keyword computed: ease-in
|
||||
Function computed: cubic-bezier(0.42, 0, 1, 1)
|
||||
|
||||
Specified: #ease-out { animation-timing-function: ease-out; transition-timing-function: cubic-bezier(0, 0, 0.58, 1); }
|
||||
Keyword computed: ease-out
|
||||
Function computed: cubic-bezier(0, 0, 0.58, 1)
|
||||
|
||||
Specified: #ease-in-out { animation-timing-function: ease-in-out; transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1); }
|
||||
Keyword computed: ease-in-out
|
||||
Function computed: cubic-bezier(0.42, 0, 0.58, 1)
|
||||
|
||||
Specified: #ease { animation-timing-function: ease; transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1); }
|
||||
Keyword computed: ease
|
||||
Function computed: cubic-bezier(0.25, 0.1, 0.25, 1)
|
||||
|
||||
Specified: #step-start { animation-timing-function: steps(1, start); transition-timing-function: steps(1, start); }
|
||||
Keyword computed: steps(1, start)
|
||||
Function computed: steps(1, start)
|
||||
|
||||
Specified: #step-end { animation-timing-function: steps(1); transition-timing-function: steps(1); }
|
||||
Keyword computed: steps(1)
|
||||
Function computed: steps(1)
|
||||
|
|
@ -2,11 +2,11 @@ Harness status: OK
|
|||
|
||||
Found 35 tests
|
||||
|
||||
19 Pass
|
||||
16 Fail
|
||||
20 Pass
|
||||
15 Fail
|
||||
Pass e.style['animation-timing-function'] = "linear(0 0%, 1 100%)" should set the property value
|
||||
Pass e.style['animation-timing-function'] = "linear( 0 0%, 1 100% )" should set the property value
|
||||
Fail e.style['animation-timing-function'] = "linear(0, 1)" should set the property value
|
||||
Pass e.style['animation-timing-function'] = "linear(0, 1)" should set the property value
|
||||
Pass e.style['animation-timing-function'] = "linear(-10, -5, 0, 5, 10)" should set the property value
|
||||
Pass e.style['animation-timing-function'] = "linear(-10 -10%, -5 -5%, 0, 5, 10)" should set the property value
|
||||
Pass e.style['animation-timing-function'] = "linear(0 calc(0%), 0 calc(100%))" should set the property value
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<style>
|
||||
#linear {
|
||||
animation-timing-function: linear;
|
||||
transition-timing-function: linear(0, 1);
|
||||
}
|
||||
|
||||
#ease-in {
|
||||
animation-timing-function: ease-in;
|
||||
transition-timing-function: cubic-bezier(0.42, 0, 1, 1);
|
||||
}
|
||||
|
||||
#ease-out {
|
||||
animation-timing-function: ease-out;
|
||||
transition-timing-function: cubic-bezier(0, 0, 0.58, 1);
|
||||
}
|
||||
|
||||
#ease-in-out {
|
||||
animation-timing-function: ease-in-out;
|
||||
transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1);
|
||||
}
|
||||
|
||||
#ease {
|
||||
animation-timing-function: ease;
|
||||
transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
|
||||
}
|
||||
|
||||
#step-start {
|
||||
animation-timing-function: step-start;
|
||||
transition-timing-function: steps(1, start);
|
||||
}
|
||||
|
||||
#step-end {
|
||||
animation-timing-function: step-end;
|
||||
transition-timing-function: steps(1, end);
|
||||
}
|
||||
</style>
|
||||
<div id="linear"></div>
|
||||
<div id="ease-in"></div>
|
||||
<div id="ease-out"></div>
|
||||
<div id="ease-in-out"></div>
|
||||
<div id="ease"></div>
|
||||
<div id="step-start"></div>
|
||||
<div id="step-end"></div>
|
||||
<script src="../include.js"></script>
|
||||
<script>
|
||||
test(() => {
|
||||
const keywords = [
|
||||
"linear",
|
||||
"ease-in",
|
||||
"ease-out",
|
||||
"ease-in-out",
|
||||
"ease",
|
||||
"step-start",
|
||||
"step-end",
|
||||
];
|
||||
|
||||
for (let i = 0; i < keywords.length; i++) {
|
||||
println(`Specified: ${document.styleSheets[0].cssRules[i].cssText}`);
|
||||
println(
|
||||
`Keyword computed: ${
|
||||
getComputedStyle(document.getElementById(keywords[i]))
|
||||
.animationTimingFunction
|
||||
}`
|
||||
);
|
||||
println(
|
||||
`Function computed: ${
|
||||
getComputedStyle(document.getElementById(keywords[i]))
|
||||
.transitionTimingFunction
|
||||
}\n`
|
||||
);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue