Commit aaf10213 authored by Majid Valipour's avatar Majid Valipour Committed by Commit Bot

[web-animations] Make handling of keyframes more spec compliant

WebAnimations spec has two keyframe concepts:

A) keyframes [1]
B) computed keyframes [2]


A key difference is that in A property values remain unresolved while in
B these properties are resolved (e.g., shorthands expand to long hands
etc.)

KeyframeEffect.getKeyframes() is expected to return (A) but our current
implementation only keeps around (B).

This CL introduces the following changes to bring us closer to the
specified behavior:

 1. Introduce a new map <property, value> in StringKeyframe
   representing (A)
 2. CSS property pairs are added to this map as long as they parse
   correctly [3]
 3. Use the new map to produce the result of getKeyframes()


There is some additional special handling required for shorthand
properties because Blink CSS parser does not really produce any
shorthand values. As a shortcut this patch introduces a new type
of css value (`CSSKeyframeShorthandValue`) which represents a
shorthand by encapsulating all its relevant longhand property/value
pairs.

Note that we continue our old behavior for SVG and Presentation attrs
which will be switch over in follow up patch.

[1] https://drafts.csswg.org/web-animations/#keyframes-section
[2] https://drafts.csswg.org/web-animations/#calculating-computed-keyframes
[3] https://drafts.csswg.org/web-animations/#process-a-keyframes-argument step 8

TEST:
 - web-animations/interfaces/{Animatable, Keyframes} => PASS previously failing tests
 - Added two new test cases in above covering animated custom props
 - external/wpt/web-animations/interfaces/KeyframeEffect/getKeyframes.html => New test to cover serialization


Bug: 816956
Change-Id: Icc8e0bc4a0ee3019ad7d2c566aacb9d3aee0ffe3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1634393
Commit-Queue: Majid Valipour <majidvp@chromium.org>
Reviewed-by: default avatarStephen McGruer <smcgruer@chromium.org>
Reviewed-by: default avatarAnders Hartvoll Ruud <andruud@chromium.org>
Cr-Commit-Position: refs/heads/master@{#675665}
parent 665b8df8
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include "third_party/blink/renderer/core/animation/animation_input_helpers.h" #include "third_party/blink/renderer/core/animation/animation_input_helpers.h"
#include "third_party/blink/renderer/core/animation/css/css_animations.h" #include "third_party/blink/renderer/core/animation/css/css_animations.h"
#include "third_party/blink/renderer/core/css/css_custom_property_declaration.h" #include "third_party/blink/renderer/core/css/css_custom_property_declaration.h"
#include "third_party/blink/renderer/core/css/css_keyframe_shorthand_value.h"
#include "third_party/blink/renderer/core/css/parser/css_parser.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h" #include "third_party/blink/renderer/core/style_property_shorthand.h"
#include "third_party/blink/renderer/core/svg/svg_element.h" #include "third_party/blink/renderer/core/svg/svg_element.h"
...@@ -15,8 +17,39 @@ ...@@ -15,8 +17,39 @@
namespace blink { namespace blink {
namespace {
// Returns handle for the given CSSProperty.
// |value| is required only for custom properties.
PropertyHandle ToPropertyHandle(const CSSProperty& property,
const CSSValue* value) {
if (property.IDEquals(CSSPropertyID::kVariable)) {
return PropertyHandle(To<CSSCustomPropertyDeclaration>(*value).GetName());
} else {
return PropertyHandle(property, false);
}
}
const CSSValue* GetOrCreateCSSValueFrom(
const CSSProperty& property,
const MutableCSSPropertyValueSet& property_value_set) {
DCHECK_NE(property.PropertyID(), CSSPropertyID::kInvalid);
DCHECK_NE(property.PropertyID(), CSSPropertyID::kVariable);
if (!property.IsShorthand())
return property_value_set.GetPropertyCSSValue(property.PropertyID());
// For shorthands create a special wrapper value, |CSSKeyframeShorthandValue|,
// which can be used to correctly serialize it given longhands that are
// present in this set.
return MakeGarbageCollected<CSSKeyframeShorthandValue>(
property_value_set.ImmutableCopyIfNeeded());
}
} // namespace
StringKeyframe::StringKeyframe(const StringKeyframe& copy_from) StringKeyframe::StringKeyframe(const StringKeyframe& copy_from)
: Keyframe(copy_from.offset_, copy_from.composite_, copy_from.easing_), : Keyframe(copy_from.offset_, copy_from.composite_, copy_from.easing_),
input_properties_(copy_from.input_properties_),
css_property_map_(copy_from.css_property_map_->MutableCopy()), css_property_map_(copy_from.css_property_map_->MutableCopy()),
presentation_attribute_map_( presentation_attribute_map_(
copy_from.presentation_attribute_map_->MutableCopy()), copy_from.presentation_attribute_map_->MutableCopy()),
...@@ -29,30 +62,67 @@ MutableCSSPropertyValueSet::SetResult StringKeyframe::SetCSSPropertyValue( ...@@ -29,30 +62,67 @@ MutableCSSPropertyValueSet::SetResult StringKeyframe::SetCSSPropertyValue(
SecureContextMode secure_context_mode, SecureContextMode secure_context_mode,
StyleSheetContents* style_sheet_contents) { StyleSheetContents* style_sheet_contents) {
bool is_animation_tainted = true; bool is_animation_tainted = true;
return css_property_map_->SetProperty( MutableCSSPropertyValueSet::SetResult result = css_property_map_->SetProperty(
property_name, registry, value, false, secure_context_mode, property_name, registry, value, false, secure_context_mode,
style_sheet_contents, is_animation_tainted); style_sheet_contents, is_animation_tainted);
const CSSValue* parsed_value =
css_property_map_->GetPropertyCSSValue(property_name);
if (result.did_parse && parsed_value) {
// Per specification we only keep properties around which are parsable.
input_properties_.Set(PropertyHandle(property_name), *parsed_value);
}
return result;
} }
MutableCSSPropertyValueSet::SetResult StringKeyframe::SetCSSPropertyValue( MutableCSSPropertyValueSet::SetResult StringKeyframe::SetCSSPropertyValue(
CSSPropertyID property, CSSPropertyID property_id,
const String& value, const String& value,
SecureContextMode secure_context_mode, SecureContextMode secure_context_mode,
StyleSheetContents* style_sheet_contents) { StyleSheetContents* style_sheet_contents) {
DCHECK_NE(property, CSSPropertyID::kInvalid); DCHECK_NE(property_id, CSSPropertyID::kInvalid);
if (CSSAnimations::IsAnimationAffectingProperty(CSSProperty::Get(property))) { DCHECK_NE(property_id, CSSPropertyID::kVariable);
const CSSProperty& property = CSSProperty::Get(property_id);
if (CSSAnimations::IsAnimationAffectingProperty(property)) {
bool did_parse = true; bool did_parse = true;
bool did_change = false; bool did_change = false;
return MutableCSSPropertyValueSet::SetResult{did_parse, did_change}; return MutableCSSPropertyValueSet::SetResult{did_parse, did_change};
} }
return css_property_map_->SetProperty(
property, value, false, secure_context_mode, style_sheet_contents); // Use a temporary set for shorthands so that its longhands are stored
// separately and can later be used to construct a special shorthand value.
bool use_temporary_set = property.IsShorthand();
auto* property_value_set =
use_temporary_set ? MakeGarbageCollected<MutableCSSPropertyValueSet>(
css_property_map_->CssParserMode())
: css_property_map_.Get();
MutableCSSPropertyValueSet::SetResult result =
property_value_set->SetProperty(
property_id, value, false, secure_context_mode, style_sheet_contents);
const CSSValue* parsed_value =
GetOrCreateCSSValueFrom(property, *property_value_set);
if (result.did_parse && parsed_value) {
// Per specification we only keep properties around which are parsable.
input_properties_.Set(PropertyHandle(property), parsed_value);
}
if (use_temporary_set)
css_property_map_->MergeAndOverrideOnConflict(property_value_set);
return result;
} }
void StringKeyframe::SetCSSPropertyValue(const CSSProperty& property, void StringKeyframe::SetCSSPropertyValue(const CSSProperty& property,
const CSSValue& value) { const CSSValue& value) {
DCHECK_NE(property.PropertyID(), CSSPropertyID::kInvalid); DCHECK_NE(property.PropertyID(), CSSPropertyID::kInvalid);
DCHECK(!CSSAnimations::IsAnimationAffectingProperty(property)); DCHECK(!CSSAnimations::IsAnimationAffectingProperty(property));
input_properties_.Set(ToPropertyHandle(property, &value), value);
css_property_map_->SetProperty(property.PropertyID(), value, false); css_property_map_->SetProperty(property.PropertyID(), value, false);
} }
...@@ -85,13 +155,7 @@ PropertyHandleSet StringKeyframe::Properties() const { ...@@ -85,13 +155,7 @@ PropertyHandleSet StringKeyframe::Properties() const {
DCHECK(!property.IsShorthand()) DCHECK(!property.IsShorthand())
<< "Web Animations: Encountered unexpanded shorthand CSS property (" << "Web Animations: Encountered unexpanded shorthand CSS property ("
<< static_cast<int>(property.PropertyID()) << ")."; << static_cast<int>(property.PropertyID()) << ").";
if (property.IDEquals(CSSPropertyID::kVariable)) { properties.insert(ToPropertyHandle(property, &property_reference.Value()));
properties.insert(PropertyHandle(
To<CSSCustomPropertyDeclaration>(property_reference.Value())
.GetName()));
} else {
properties.insert(PropertyHandle(property, false));
}
} }
for (unsigned i = 0; i < presentation_attribute_map_->PropertyCount(); ++i) { for (unsigned i = 0; i < presentation_attribute_map_->PropertyCount(); ++i) {
...@@ -117,25 +181,41 @@ bool StringKeyframe::HasCssProperty() const { ...@@ -117,25 +181,41 @@ bool StringKeyframe::HasCssProperty() const {
void StringKeyframe::AddKeyframePropertiesToV8Object( void StringKeyframe::AddKeyframePropertiesToV8Object(
V8ObjectBuilder& object_builder) const { V8ObjectBuilder& object_builder) const {
Keyframe::AddKeyframePropertiesToV8Object(object_builder); Keyframe::AddKeyframePropertiesToV8Object(object_builder);
for (const auto& entry : input_properties_) {
const PropertyHandle& property_handle = entry.key;
const CSSValue* property_value = entry.value;
String property_name =
AnimationInputHelpers::PropertyHandleToKeyframeAttribute(
property_handle);
object_builder.Add(property_name, property_value->CssText());
}
// Legacy code path for SVG and Presentation attributes.
//
// TODO(816956): Move these to input_properties_ and remove this. Note that
// this code path is not well tested given that removing it didn't cause any
// test failures.
for (const PropertyHandle& property : Properties()) { for (const PropertyHandle& property : Properties()) {
if (property.IsCSSProperty())
continue;
String property_name = String property_name =
AnimationInputHelpers::PropertyHandleToKeyframeAttribute(property); AnimationInputHelpers::PropertyHandleToKeyframeAttribute(property);
String value; String property_value;
if (property.IsCSSProperty()) { if (property.IsPresentationAttribute()) {
value = CssPropertyValue(property).CssText();
} else if (property.IsPresentationAttribute()) {
const auto& attribute = property.PresentationAttribute(); const auto& attribute = property.PresentationAttribute();
value = PresentationAttributeValue(attribute).CssText(); property_value = PresentationAttributeValue(attribute).CssText();
} else { } else {
DCHECK(property.IsSVGAttribute()); DCHECK(property.IsSVGAttribute());
value = SvgPropertyValue(property.SvgAttribute()); property_value = SvgPropertyValue(property.SvgAttribute());
} }
object_builder.Add(property_name, property_value);
object_builder.Add(property_name, value);
} }
} }
void StringKeyframe::Trace(Visitor* visitor) { void StringKeyframe::Trace(Visitor* visitor) {
visitor->Trace(input_properties_);
visitor->Trace(css_property_map_); visitor->Trace(css_property_map_);
visitor->Trace(presentation_attribute_map_); visitor->Trace(presentation_attribute_map_);
Keyframe::Trace(visitor); Keyframe::Trace(visitor);
......
...@@ -165,6 +165,28 @@ class CORE_EXPORT StringKeyframe : public Keyframe { ...@@ -165,6 +165,28 @@ class CORE_EXPORT StringKeyframe : public Keyframe {
bool IsStringKeyframe() const override { return true; } bool IsStringKeyframe() const override { return true; }
// The unresolved property and their values. This is needed for correct
// implementation of KeyframeEffect.getKeyframes(). We use a single list for
// CSS, SVG properties. The only requirement for a property value to be
// in this list is that it parses correctly.
//
// See: https://drafts.csswg.org/web-animations/#keyframes-section
HeapHashMap<PropertyHandle, Member<const CSSValue>> input_properties_;
// The resolved properties are computed from unresolved ones applying these
// steps:
// 1. Resolve conflicts when multiple properties map to same underlying
// one (e.g., margin, margin-top)
// 2. Expand shorthands to longhands
// 3. Expand logical properties to physical ones
//
// See:
// https://drafts.csswg.org/web-animations/#calculating-computed-keyframes
//
// TODO(816956): AFAICT we don't do (1) at the moment rather we parse and feed
// values into the MutableCSSPropertyValueSet which keeps replacing values as
// they come in. I am not sure if it leads to the same conflict resolution
// that web-animation expects. This needs more investigation.
Member<MutableCSSPropertyValueSet> css_property_map_; Member<MutableCSSPropertyValueSet> css_property_map_;
Member<MutableCSSPropertyValueSet> presentation_attribute_map_; Member<MutableCSSPropertyValueSet> presentation_attribute_map_;
HashMap<const QualifiedName*, String> svg_attribute_map_; HashMap<const QualifiedName*, String> svg_attribute_map_;
......
...@@ -100,6 +100,8 @@ blink_core_sources("css") { ...@@ -100,6 +100,8 @@ blink_core_sources("css") {
"css_invalid_variable_value.h", "css_invalid_variable_value.h",
"css_keyframe_rule.cc", "css_keyframe_rule.cc",
"css_keyframe_rule.h", "css_keyframe_rule.h",
"css_keyframe_shorthand_value.cc",
"css_keyframe_shorthand_value.h",
"css_keyframes_rule.cc", "css_keyframes_rule.cc",
"css_keyframes_rule.h", "css_keyframes_rule.h",
"css_layout_function_value.cc", "css_layout_function_value.cc",
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/css/css_keyframe_shorthand_value.h"
namespace blink {
CSSKeyframeShorthandValue::CSSKeyframeShorthandValue(
ImmutableCSSPropertyValueSet* properties)
: CSSValue(kKeyframeShorthandClass), properties_(properties) {}
String CSSKeyframeShorthandValue::CustomCSSText() const {
// All property/value pairs belong to the same shorthand so we grab the id
// from the first one.
CSSPropertyID my_shorthand = properties_->PropertyAt(0).ShorthandID();
#if DCHECK_IS_ON()
for (unsigned i = 0; i < properties_->PropertyCount(); i++) {
DCHECK_EQ(my_shorthand, properties_->PropertyAt(i).ShorthandID())
<< "These are not the longhands you're looking for.";
}
#endif
return properties_->GetPropertyValue(my_shorthand);
}
void CSSKeyframeShorthandValue::TraceAfterDispatch(blink::Visitor* visitor) {
visitor->Trace(properties_);
CSSValue::TraceAfterDispatch(visitor);
}
} // namespace blink
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_KEYFRAME_SHORTHAND_VALUE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_KEYFRAME_SHORTHAND_VALUE_H_
#include "third_party/blink/renderer/core/css/css_value.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/core/css/style_property_serializer.h"
namespace blink {
// The special value is used to keep around individual longhand css
// property/values that resulted from parsing a shorthand value. This way we can
// reconstruct the shorthand back from them.
//
// Context:
//
// Web Animation specs requires that we keep around and return a parsed
// shorthand name/value pair if they are present in keyframes. However Blink css
// parser does not keep around shorthands and instead produces longhands.
// Instead of updating the css parser engine to preserve shorthands (which is a
// large undertaking) we are taking a shortcut here that allows us to use
// existing logic that enables serialization of a shorthand given its longhands
// i.e., `StylePropertySerializer`. To this end, this class is be used to wrap
// and store longhands produced by a single shorthand as part of animation
// keyframe logic.
//
// For more information see:
// - `StringKeyframe::SetCSSPropertyValue()`
// - https://drafts.csswg.org/web-animations/#process-a-keyframes-argument
class CSSKeyframeShorthandValue : public CSSValue {
public:
// Assumes that all property/value pairs that are present in the input set are
// longhands for the same shorthand property/value pair.
CSSKeyframeShorthandValue(ImmutableCSSPropertyValueSet*);
String CustomCSSText() const;
bool Equals(const CSSKeyframeShorthandValue& other) const {
return properties_ == other.properties_;
}
void TraceAfterDispatch(blink::Visitor*);
private:
Member<ImmutableCSSPropertyValueSet> properties_;
};
template <>
struct DowncastTraits<CSSKeyframeShorthandValue> {
static bool AllowFrom(const CSSValue& value) {
return value.IsShorthandWrapperValue();
}
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_KEYFRAME_SHORTHAND_VALUE_H_
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
#include "third_party/blink/renderer/core/css/css_inherited_value.h" #include "third_party/blink/renderer/core/css/css_inherited_value.h"
#include "third_party/blink/renderer/core/css/css_initial_value.h" #include "third_party/blink/renderer/core/css/css_initial_value.h"
#include "third_party/blink/renderer/core/css/css_invalid_variable_value.h" #include "third_party/blink/renderer/core/css/css_invalid_variable_value.h"
#include "third_party/blink/renderer/core/css/css_keyframe_shorthand_value.h"
#include "third_party/blink/renderer/core/css/css_layout_function_value.h" #include "third_party/blink/renderer/core/css/css_layout_function_value.h"
#include "third_party/blink/renderer/core/css/css_math_function_value.h" #include "third_party/blink/renderer/core/css/css_math_function_value.h"
#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
...@@ -224,6 +225,8 @@ bool CSSValue::operator==(const CSSValue& other) const { ...@@ -224,6 +225,8 @@ bool CSSValue::operator==(const CSSValue& other) const {
return CompareCSSValues<CSSRayValue>(*this, other); return CompareCSSValues<CSSRayValue>(*this, other);
case kIdentifierClass: case kIdentifierClass:
return CompareCSSValues<CSSIdentifierValue>(*this, other); return CompareCSSValues<CSSIdentifierValue>(*this, other);
case kKeyframeShorthandClass:
return CompareCSSValues<CSSKeyframeShorthandValue>(*this, other);
case kQuadClass: case kQuadClass:
return CompareCSSValues<CSSQuadValue>(*this, other); return CompareCSSValues<CSSQuadValue>(*this, other);
case kReflectClass: case kReflectClass:
...@@ -336,6 +339,8 @@ String CSSValue::CssText() const { ...@@ -336,6 +339,8 @@ String CSSValue::CssText() const {
return To<CSSRayValue>(this)->CustomCSSText(); return To<CSSRayValue>(this)->CustomCSSText();
case kIdentifierClass: case kIdentifierClass:
return To<CSSIdentifierValue>(this)->CustomCSSText(); return To<CSSIdentifierValue>(this)->CustomCSSText();
case kKeyframeShorthandClass:
return To<CSSKeyframeShorthandValue>(this)->CustomCSSText();
case kQuadClass: case kQuadClass:
return To<CSSQuadValue>(this)->CustomCSSText(); return To<CSSQuadValue>(this)->CustomCSSText();
case kReflectClass: case kReflectClass:
...@@ -480,6 +485,9 @@ void CSSValue::FinalizeGarbageCollectedObject() { ...@@ -480,6 +485,9 @@ void CSSValue::FinalizeGarbageCollectedObject() {
case kIdentifierClass: case kIdentifierClass:
To<CSSIdentifierValue>(this)->~CSSIdentifierValue(); To<CSSIdentifierValue>(this)->~CSSIdentifierValue();
return; return;
case kKeyframeShorthandClass:
To<CSSKeyframeShorthandValue>(this)->~CSSKeyframeShorthandValue();
return;
case kQuadClass: case kQuadClass:
To<CSSQuadValue>(this)->~CSSQuadValue(); To<CSSQuadValue>(this)->~CSSQuadValue();
return; return;
...@@ -640,6 +648,9 @@ void CSSValue::Trace(blink::Visitor* visitor) { ...@@ -640,6 +648,9 @@ void CSSValue::Trace(blink::Visitor* visitor) {
case kIdentifierClass: case kIdentifierClass:
To<CSSIdentifierValue>(this)->TraceAfterDispatch(visitor); To<CSSIdentifierValue>(this)->TraceAfterDispatch(visitor);
return; return;
case kKeyframeShorthandClass:
To<CSSKeyframeShorthandValue>(this)->TraceAfterDispatch(visitor);
return;
case kQuadClass: case kQuadClass:
To<CSSQuadValue>(this)->TraceAfterDispatch(visitor); To<CSSQuadValue>(this)->TraceAfterDispatch(visitor);
return; return;
......
...@@ -167,6 +167,9 @@ class CORE_EXPORT CSSValue : public GarbageCollectedFinalized<CSSValue> { ...@@ -167,6 +167,9 @@ class CORE_EXPORT CSSValue : public GarbageCollectedFinalized<CSSValue> {
return class_type_ == kInvalidVariableValueClass; return class_type_ == kInvalidVariableValueClass;
} }
bool IsAxisValue() const { return class_type_ == kAxisClass; } bool IsAxisValue() const { return class_type_ == kAxisClass; }
bool IsShorthandWrapperValue() const {
return class_type_ == kKeyframeShorthandClass;
}
bool HasFailedOrCanceledSubresources() const; bool HasFailedOrCanceledSubresources() const;
bool MayContainUrl() const; bool MayContainUrl() const;
...@@ -246,6 +249,8 @@ class CORE_EXPORT CSSValue : public GarbageCollectedFinalized<CSSValue> { ...@@ -246,6 +249,8 @@ class CORE_EXPORT CSSValue : public GarbageCollectedFinalized<CSSValue> {
kCSSContentDistributionClass, kCSSContentDistributionClass,
kKeyframeShorthandClass,
// List class types must appear after ValueListClass. // List class types must appear after ValueListClass.
kValueListClass, kValueListClass,
kFunctionClass, kFunctionClass,
......
This is a testharness.js-based test. This is a testharness.js-based test.
Found 135 tests; 126 PASS, 9 FAIL, 0 TIMEOUT, 0 NOTRUN. Found 137 tests; 134 PASS, 3 FAIL, 0 TIMEOUT, 0 NOTRUN.
PASS Element.animate() creates an Animation object PASS Element.animate() creates an Animation object
PASS Element.animate() creates an Animation object in the relevant realm of the target element PASS Element.animate() creates an Animation object in the relevant realm of the target element
PASS Element.animate() creates an Animation object with a KeyframeEffect PASS Element.animate() creates an Animation object with a KeyframeEffect
...@@ -8,18 +8,19 @@ PASS Element.animate() accepts empty keyframe lists (input: []) ...@@ -8,18 +8,19 @@ PASS Element.animate() accepts empty keyframe lists (input: [])
PASS Element.animate() accepts empty keyframe lists (input: null) PASS Element.animate() accepts empty keyframe lists (input: null)
PASS Element.animate() accepts empty keyframe lists (input: undefined) PASS Element.animate() accepts empty keyframe lists (input: undefined)
PASS Element.animate() accepts a one property two value property-indexed keyframes specification PASS Element.animate() accepts a one property two value property-indexed keyframes specification
FAIL Element.animate() accepts a one shorthand property two value property-indexed keyframes specification assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,margin,offset" but got "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" PASS Element.animate() accepts a one shorthand property two value property-indexed keyframes specification
FAIL Element.animate() accepts a two property (one shorthand and one of its longhand components) two value property-indexed keyframes specification assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,margin,marginTop,offset" but got "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" PASS Element.animate() accepts a two property (one shorthand and one of its longhand components) two value property-indexed keyframes specification
PASS Element.animate() accepts a two property two value property-indexed keyframes specification PASS Element.animate() accepts a two property two value property-indexed keyframes specification
PASS Element.animate() accepts a two property property-indexed keyframes specification with different numbers of values PASS Element.animate() accepts a two property property-indexed keyframes specification with different numbers of values
PASS Element.animate() accepts a property-indexed keyframes specification with an invalid value PASS Element.animate() accepts a property-indexed keyframes specification with an invalid value
PASS Element.animate() accepts a one property two value property-indexed keyframes specification that needs to stringify its values PASS Element.animate() accepts a one property two value property-indexed keyframes specification that needs to stringify its values
PASS Element.animate() accepts a property-indexed keyframes specification with a CSS variable reference PASS Element.animate() accepts a property-indexed keyframes specification with a CSS variable reference
FAIL Element.animate() accepts a property-indexed keyframes specification with a CSS variable reference in a shorthand property assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,margin,offset" but got "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" PASS Element.animate() accepts a property-indexed keyframes specification with a CSS variable reference in a shorthand property
PASS Element.animate() accepts a one property one value property-indexed keyframes specification PASS Element.animate() accepts a one property one value property-indexed keyframes specification
PASS Element.animate() accepts a one property one non-array value property-indexed keyframes specification PASS Element.animate() accepts a one property one non-array value property-indexed keyframes specification
PASS Element.animate() accepts a one property two value property-indexed keyframes specification where the first value is invalid PASS Element.animate() accepts a one property two value property-indexed keyframes specification where the first value is invalid
PASS Element.animate() accepts a one property two value property-indexed keyframes specification where the second value is invalid PASS Element.animate() accepts a one property two value property-indexed keyframes specification where the second value is invalid
PASS Element.animate() accepts a property-indexed keyframes specification with a CSS variable as the property
PASS Element.animate() accepts a property-indexed keyframe with a single offset PASS Element.animate() accepts a property-indexed keyframe with a single offset
PASS Element.animate() accepts a property-indexed keyframe with an array of offsets PASS Element.animate() accepts a property-indexed keyframe with an array of offsets
PASS Element.animate() accepts a property-indexed keyframe with an array of offsets that is too short PASS Element.animate() accepts a property-indexed keyframe with an array of offsets that is too short
...@@ -47,13 +48,14 @@ PASS Element.animate() accepts a property-indexed keyframe with a single-element ...@@ -47,13 +48,14 @@ PASS Element.animate() accepts a property-indexed keyframe with a single-element
PASS Element.animate() accepts a one property one keyframe sequence PASS Element.animate() accepts a one property one keyframe sequence
PASS Element.animate() accepts a one property two keyframe sequence PASS Element.animate() accepts a one property two keyframe sequence
PASS Element.animate() accepts a two property two keyframe sequence PASS Element.animate() accepts a two property two keyframe sequence
FAIL Element.animate() accepts a one shorthand property two keyframe sequence assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,margin,offset" but got "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" PASS Element.animate() accepts a one shorthand property two keyframe sequence
FAIL Element.animate() accepts a two property (a shorthand and one of its component longhands) two keyframe sequence assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,margin,marginTop,offset" but got "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" PASS Element.animate() accepts a two property (a shorthand and one of its component longhands) two keyframe sequence
PASS Element.animate() accepts a two property keyframe sequence where one property is missing from the first keyframe PASS Element.animate() accepts a two property keyframe sequence where one property is missing from the first keyframe
PASS Element.animate() accepts a two property keyframe sequence where one property is missing from the last keyframe PASS Element.animate() accepts a two property keyframe sequence where one property is missing from the last keyframe
PASS Element.animate() accepts a one property two keyframe sequence that needs to stringify its values PASS Element.animate() accepts a one property two keyframe sequence that needs to stringify its values
PASS Element.animate() accepts a keyframe sequence with a CSS variable reference PASS Element.animate() accepts a keyframe sequence with a CSS variable reference
FAIL Element.animate() accepts a keyframe sequence with a CSS variable reference in a shorthand property assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,margin,offset" but got "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" PASS Element.animate() accepts a keyframe sequence with a CSS variable reference in a shorthand property
PASS Element.animate() accepts a keyframe sequence with a CSS variable as its property
PASS Element.animate() accepts a keyframe sequence with duplicate values for a given interior offset PASS Element.animate() accepts a keyframe sequence with duplicate values for a given interior offset
PASS Element.animate() accepts a keyframe sequence with duplicate values for offsets 0 and 1 PASS Element.animate() accepts a keyframe sequence with duplicate values for offsets 0 and 1
PASS Element.animate() accepts a two property four keyframe sequence PASS Element.animate() accepts a two property four keyframe sequence
......
This is a testharness.js-based test. This is a testharness.js-based test.
Found 167 tests; 155 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN. Found 171 tests; 167 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN.
PASS A KeyframeEffect can be constructed with no frames PASS A KeyframeEffect can be constructed with no frames
PASS easing values are parsed correctly when passed to the KeyframeEffect constructor in KeyframeEffectOptions PASS easing values are parsed correctly when passed to the KeyframeEffect constructor in KeyframeEffectOptions
PASS Invalid easing values are correctly rejected when passed to the KeyframeEffect constructor in KeyframeEffectOptions PASS Invalid easing values are correctly rejected when passed to the KeyframeEffect constructor in KeyframeEffectOptions
...@@ -8,9 +8,9 @@ FAIL composite values are parsed correctly when passed to the KeyframeEffect con ...@@ -8,9 +8,9 @@ FAIL composite values are parsed correctly when passed to the KeyframeEffect con
PASS composite value is auto if the composite operation specified on the keyframe effect is being used PASS composite value is auto if the composite operation specified on the keyframe effect is being used
PASS A KeyframeEffect can be constructed with a one property two value property-indexed keyframes specification PASS A KeyframeEffect can be constructed with a one property two value property-indexed keyframes specification
PASS A KeyframeEffect constructed with a one property two value property-indexed keyframes specification roundtrips PASS A KeyframeEffect constructed with a one property two value property-indexed keyframes specification roundtrips
FAIL A KeyframeEffect can be constructed with a one shorthand property two value property-indexed keyframes specification assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,margin,offset" but got "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" PASS A KeyframeEffect can be constructed with a one shorthand property two value property-indexed keyframes specification
PASS A KeyframeEffect constructed with a one shorthand property two value property-indexed keyframes specification roundtrips PASS A KeyframeEffect constructed with a one shorthand property two value property-indexed keyframes specification roundtrips
FAIL A KeyframeEffect can be constructed with a two property (one shorthand and one of its longhand components) two value property-indexed keyframes specification assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,margin,marginTop,offset" but got "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" PASS A KeyframeEffect can be constructed with a two property (one shorthand and one of its longhand components) two value property-indexed keyframes specification
PASS A KeyframeEffect constructed with a two property (one shorthand and one of its longhand components) two value property-indexed keyframes specification roundtrips PASS A KeyframeEffect constructed with a two property (one shorthand and one of its longhand components) two value property-indexed keyframes specification roundtrips
PASS A KeyframeEffect can be constructed with a two property two value property-indexed keyframes specification PASS A KeyframeEffect can be constructed with a two property two value property-indexed keyframes specification
PASS A KeyframeEffect constructed with a two property two value property-indexed keyframes specification roundtrips PASS A KeyframeEffect constructed with a two property two value property-indexed keyframes specification roundtrips
...@@ -22,8 +22,8 @@ PASS A KeyframeEffect can be constructed with a one property two value property- ...@@ -22,8 +22,8 @@ PASS A KeyframeEffect can be constructed with a one property two value property-
PASS A KeyframeEffect constructed with a one property two value property-indexed keyframes specification that needs to stringify its values roundtrips PASS A KeyframeEffect constructed with a one property two value property-indexed keyframes specification that needs to stringify its values roundtrips
PASS A KeyframeEffect can be constructed with a property-indexed keyframes specification with a CSS variable reference PASS A KeyframeEffect can be constructed with a property-indexed keyframes specification with a CSS variable reference
PASS A KeyframeEffect constructed with a property-indexed keyframes specification with a CSS variable reference roundtrips PASS A KeyframeEffect constructed with a property-indexed keyframes specification with a CSS variable reference roundtrips
FAIL A KeyframeEffect can be constructed with a property-indexed keyframes specification with a CSS variable reference in a shorthand property assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,margin,offset" but got "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" PASS A KeyframeEffect can be constructed with a property-indexed keyframes specification with a CSS variable reference in a shorthand property
FAIL A KeyframeEffect constructed with a property-indexed keyframes specification with a CSS variable reference in a shorthand property roundtrips assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" but got "composite,computedOffset,easing,offset" PASS A KeyframeEffect constructed with a property-indexed keyframes specification with a CSS variable reference in a shorthand property roundtrips
PASS A KeyframeEffect can be constructed with a one property one value property-indexed keyframes specification PASS A KeyframeEffect can be constructed with a one property one value property-indexed keyframes specification
PASS A KeyframeEffect constructed with a one property one value property-indexed keyframes specification roundtrips PASS A KeyframeEffect constructed with a one property one value property-indexed keyframes specification roundtrips
PASS A KeyframeEffect can be constructed with a one property one non-array value property-indexed keyframes specification PASS A KeyframeEffect can be constructed with a one property one non-array value property-indexed keyframes specification
...@@ -32,6 +32,8 @@ PASS A KeyframeEffect can be constructed with a one property two value property- ...@@ -32,6 +32,8 @@ PASS A KeyframeEffect can be constructed with a one property two value property-
PASS A KeyframeEffect constructed with a one property two value property-indexed keyframes specification where the first value is invalid roundtrips PASS A KeyframeEffect constructed with a one property two value property-indexed keyframes specification where the first value is invalid roundtrips
PASS A KeyframeEffect can be constructed with a one property two value property-indexed keyframes specification where the second value is invalid PASS A KeyframeEffect can be constructed with a one property two value property-indexed keyframes specification where the second value is invalid
PASS A KeyframeEffect constructed with a one property two value property-indexed keyframes specification where the second value is invalid roundtrips PASS A KeyframeEffect constructed with a one property two value property-indexed keyframes specification where the second value is invalid roundtrips
PASS A KeyframeEffect can be constructed with a property-indexed keyframes specification with a CSS variable as the property
PASS A KeyframeEffect constructed with a property-indexed keyframes specification with a CSS variable as the property roundtrips
PASS A KeyframeEffect can be constructed with a property-indexed keyframe with a single offset PASS A KeyframeEffect can be constructed with a property-indexed keyframe with a single offset
PASS A KeyframeEffect constructed with a property-indexed keyframe with a single offset roundtrips PASS A KeyframeEffect constructed with a property-indexed keyframe with a single offset roundtrips
PASS A KeyframeEffect can be constructed with a property-indexed keyframe with an array of offsets PASS A KeyframeEffect can be constructed with a property-indexed keyframe with an array of offsets
...@@ -86,9 +88,9 @@ PASS A KeyframeEffect can be constructed with a one property two keyframe sequen ...@@ -86,9 +88,9 @@ PASS A KeyframeEffect can be constructed with a one property two keyframe sequen
PASS A KeyframeEffect constructed with a one property two keyframe sequence roundtrips PASS A KeyframeEffect constructed with a one property two keyframe sequence roundtrips
PASS A KeyframeEffect can be constructed with a two property two keyframe sequence PASS A KeyframeEffect can be constructed with a two property two keyframe sequence
PASS A KeyframeEffect constructed with a two property two keyframe sequence roundtrips PASS A KeyframeEffect constructed with a two property two keyframe sequence roundtrips
FAIL A KeyframeEffect can be constructed with a one shorthand property two keyframe sequence assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,margin,offset" but got "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" PASS A KeyframeEffect can be constructed with a one shorthand property two keyframe sequence
PASS A KeyframeEffect constructed with a one shorthand property two keyframe sequence roundtrips PASS A KeyframeEffect constructed with a one shorthand property two keyframe sequence roundtrips
FAIL A KeyframeEffect can be constructed with a two property (a shorthand and one of its component longhands) two keyframe sequence assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,margin,marginTop,offset" but got "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" PASS A KeyframeEffect can be constructed with a two property (a shorthand and one of its component longhands) two keyframe sequence
PASS A KeyframeEffect constructed with a two property (a shorthand and one of its component longhands) two keyframe sequence roundtrips PASS A KeyframeEffect constructed with a two property (a shorthand and one of its component longhands) two keyframe sequence roundtrips
PASS A KeyframeEffect can be constructed with a two property keyframe sequence where one property is missing from the first keyframe PASS A KeyframeEffect can be constructed with a two property keyframe sequence where one property is missing from the first keyframe
PASS A KeyframeEffect constructed with a two property keyframe sequence where one property is missing from the first keyframe roundtrips PASS A KeyframeEffect constructed with a two property keyframe sequence where one property is missing from the first keyframe roundtrips
...@@ -98,8 +100,10 @@ PASS A KeyframeEffect can be constructed with a one property two keyframe sequen ...@@ -98,8 +100,10 @@ PASS A KeyframeEffect can be constructed with a one property two keyframe sequen
PASS A KeyframeEffect constructed with a one property two keyframe sequence that needs to stringify its values roundtrips PASS A KeyframeEffect constructed with a one property two keyframe sequence that needs to stringify its values roundtrips
PASS A KeyframeEffect can be constructed with a keyframe sequence with a CSS variable reference PASS A KeyframeEffect can be constructed with a keyframe sequence with a CSS variable reference
PASS A KeyframeEffect constructed with a keyframe sequence with a CSS variable reference roundtrips PASS A KeyframeEffect constructed with a keyframe sequence with a CSS variable reference roundtrips
FAIL A KeyframeEffect can be constructed with a keyframe sequence with a CSS variable reference in a shorthand property assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,margin,offset" but got "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" PASS A KeyframeEffect can be constructed with a keyframe sequence with a CSS variable reference in a shorthand property
FAIL A KeyframeEffect constructed with a keyframe sequence with a CSS variable reference in a shorthand property roundtrips assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" but got "composite,computedOffset,easing,offset" PASS A KeyframeEffect constructed with a keyframe sequence with a CSS variable reference in a shorthand property roundtrips
PASS A KeyframeEffect can be constructed with a keyframe sequence with a CSS variable as its property
PASS A KeyframeEffect constructed with a keyframe sequence with a CSS variable as its property roundtrips
PASS A KeyframeEffect can be constructed with a keyframe sequence with duplicate values for a given interior offset PASS A KeyframeEffect can be constructed with a keyframe sequence with duplicate values for a given interior offset
PASS A KeyframeEffect constructed with a keyframe sequence with duplicate values for a given interior offset roundtrips PASS A KeyframeEffect constructed with a keyframe sequence with duplicate values for a given interior offset roundtrips
PASS A KeyframeEffect can be constructed with a keyframe sequence with duplicate values for offsets 0 and 1 PASS A KeyframeEffect can be constructed with a keyframe sequence with duplicate values for offsets 0 and 1
......
<!DOCTYPE html>
<meta charset=utf-8>
<title>KeyframeEffect getKeyframes()</title>
<link rel="help"
href="https://drafts.csswg.org/web-animations/#dom-keyframeeffect-getkeyframes">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../resources/keyframe-utils.js"></script>
<script src="../../resources/keyframe-tests.js"></script>
<body>
<div id="log"></div>
<div id="target"></div>
<script>
'use strict';
const target = document.getElementById('target');
for (const subtest of gKeyframeSerializationTests) {
test(t => {
const effect = new KeyframeEffect(target, subtest.input);
assert_frame_lists_equal(effect.getKeyframes(), subtest.output);
}, `getKeyframes() should serialize its css values with ${subtest.desc}`);
}
</script>
\ No newline at end of file
This is a testharness.js-based test. This is a testharness.js-based test.
Found 76 tests; 69 PASS, 7 FAIL, 0 TIMEOUT, 0 NOTRUN. Found 78 tests; 77 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
PASS Keyframes can be replaced with an empty keyframe PASS Keyframes can be replaced with an empty keyframe
PASS Keyframes can be replaced with a one property two value property-indexed keyframes specification PASS Keyframes can be replaced with a one property two value property-indexed keyframes specification
FAIL Keyframes can be replaced with a one shorthand property two value property-indexed keyframes specification assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,margin,offset" but got "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" PASS Keyframes can be replaced with a one shorthand property two value property-indexed keyframes specification
FAIL Keyframes can be replaced with a two property (one shorthand and one of its longhand components) two value property-indexed keyframes specification assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,margin,marginTop,offset" but got "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" PASS Keyframes can be replaced with a two property (one shorthand and one of its longhand components) two value property-indexed keyframes specification
PASS Keyframes can be replaced with a two property two value property-indexed keyframes specification PASS Keyframes can be replaced with a two property two value property-indexed keyframes specification
PASS Keyframes can be replaced with a two property property-indexed keyframes specification with different numbers of values PASS Keyframes can be replaced with a two property property-indexed keyframes specification with different numbers of values
PASS Keyframes can be replaced with a property-indexed keyframes specification with an invalid value PASS Keyframes can be replaced with a property-indexed keyframes specification with an invalid value
PASS Keyframes can be replaced with a one property two value property-indexed keyframes specification that needs to stringify its values PASS Keyframes can be replaced with a one property two value property-indexed keyframes specification that needs to stringify its values
PASS Keyframes can be replaced with a property-indexed keyframes specification with a CSS variable reference PASS Keyframes can be replaced with a property-indexed keyframes specification with a CSS variable reference
FAIL Keyframes can be replaced with a property-indexed keyframes specification with a CSS variable reference in a shorthand property assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,margin,offset" but got "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" PASS Keyframes can be replaced with a property-indexed keyframes specification with a CSS variable reference in a shorthand property
PASS Keyframes can be replaced with a one property one value property-indexed keyframes specification PASS Keyframes can be replaced with a one property one value property-indexed keyframes specification
PASS Keyframes can be replaced with a one property one non-array value property-indexed keyframes specification PASS Keyframes can be replaced with a one property one non-array value property-indexed keyframes specification
PASS Keyframes can be replaced with a one property two value property-indexed keyframes specification where the first value is invalid PASS Keyframes can be replaced with a one property two value property-indexed keyframes specification where the first value is invalid
PASS Keyframes can be replaced with a one property two value property-indexed keyframes specification where the second value is invalid PASS Keyframes can be replaced with a one property two value property-indexed keyframes specification where the second value is invalid
PASS Keyframes can be replaced with a property-indexed keyframes specification with a CSS variable as the property
PASS Keyframes can be replaced with a property-indexed keyframe with a single offset PASS Keyframes can be replaced with a property-indexed keyframe with a single offset
PASS Keyframes can be replaced with a property-indexed keyframe with an array of offsets PASS Keyframes can be replaced with a property-indexed keyframe with an array of offsets
PASS Keyframes can be replaced with a property-indexed keyframe with an array of offsets that is too short PASS Keyframes can be replaced with a property-indexed keyframe with an array of offsets that is too short
...@@ -41,13 +42,14 @@ PASS Keyframes can be replaced with a property-indexed keyframe with a single-el ...@@ -41,13 +42,14 @@ PASS Keyframes can be replaced with a property-indexed keyframe with a single-el
PASS Keyframes can be replaced with a one property one keyframe sequence PASS Keyframes can be replaced with a one property one keyframe sequence
PASS Keyframes can be replaced with a one property two keyframe sequence PASS Keyframes can be replaced with a one property two keyframe sequence
PASS Keyframes can be replaced with a two property two keyframe sequence PASS Keyframes can be replaced with a two property two keyframe sequence
FAIL Keyframes can be replaced with a one shorthand property two keyframe sequence assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,margin,offset" but got "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" PASS Keyframes can be replaced with a one shorthand property two keyframe sequence
FAIL Keyframes can be replaced with a two property (a shorthand and one of its component longhands) two keyframe sequence assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,margin,marginTop,offset" but got "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" PASS Keyframes can be replaced with a two property (a shorthand and one of its component longhands) two keyframe sequence
PASS Keyframes can be replaced with a two property keyframe sequence where one property is missing from the first keyframe PASS Keyframes can be replaced with a two property keyframe sequence where one property is missing from the first keyframe
PASS Keyframes can be replaced with a two property keyframe sequence where one property is missing from the last keyframe PASS Keyframes can be replaced with a two property keyframe sequence where one property is missing from the last keyframe
PASS Keyframes can be replaced with a one property two keyframe sequence that needs to stringify its values PASS Keyframes can be replaced with a one property two keyframe sequence that needs to stringify its values
PASS Keyframes can be replaced with a keyframe sequence with a CSS variable reference PASS Keyframes can be replaced with a keyframe sequence with a CSS variable reference
FAIL Keyframes can be replaced with a keyframe sequence with a CSS variable reference in a shorthand property assert_equals: properties on ComputedKeyframe #0 should match expected "composite,computedOffset,easing,margin,offset" but got "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" PASS Keyframes can be replaced with a keyframe sequence with a CSS variable reference in a shorthand property
PASS Keyframes can be replaced with a keyframe sequence with a CSS variable as its property
PASS Keyframes can be replaced with a keyframe sequence with duplicate values for a given interior offset PASS Keyframes can be replaced with a keyframe sequence with duplicate values for a given interior offset
PASS Keyframes can be replaced with a keyframe sequence with duplicate values for offsets 0 and 1 PASS Keyframes can be replaced with a keyframe sequence with duplicate values for offsets 0 and 1
PASS Keyframes can be replaced with a two property four keyframe sequence PASS Keyframes can be replaced with a two property four keyframe sequence
......
...@@ -159,6 +159,13 @@ const gKeyframesTests = [ ...@@ -159,6 +159,13 @@ const gKeyframesTests = [
output: [keyframe(computedOffset(0), { left: '10px' }), output: [keyframe(computedOffset(0), { left: '10px' }),
keyframe(computedOffset(1), {})] keyframe(computedOffset(1), {})]
}, },
{
desc: 'a property-indexed keyframes specification with a CSS variable as'
+ ' the property',
input: { '--custom': ['1', '2'] },
output: [keyframe(computedOffset(0), { '--custom': '1' }),
keyframe(computedOffset(1), { '--custom': '2' })]
},
// ----------- Property-indexed keyframes: offset handling ----------- // ----------- Property-indexed keyframes: offset handling -----------
...@@ -453,6 +460,13 @@ const gKeyframesTests = [ ...@@ -453,6 +460,13 @@ const gKeyframesTests = [
keyframe(computedOffset(1), keyframe(computedOffset(1),
{ margin: 'calc(var(--dist) + 100px)' })], { margin: 'calc(var(--dist) + 100px)' })],
}, },
{
desc: 'a keyframe sequence with a CSS variable as its property',
input: [{ '--custom': 'a' },
{ '--custom': 'b' }],
output: [keyframe(computedOffset(0), { '--custom': 'a' }),
keyframe(computedOffset(1), { '--custom': 'b' })]
},
// ----------- Keyframe sequence: offset handling ----------- // ----------- Keyframe sequence: offset handling -----------
...@@ -682,6 +696,18 @@ const gInvalidKeyframesTests = [ ...@@ -682,6 +696,18 @@ const gInvalidKeyframesTests = [
}, },
]; ];
const gKeyframeSerializationTests = [
{
desc: 'a on keyframe sequence which requires value serilaization of its'
+ ' values',
input: [{offset: 0, backgroundColor: 'rgb(1,2,3)' }],
output: [keyframe(offset(0), { backgroundColor: 'rgb(1, 2, 3)' })],
},
];
// ------------------------------ // ------------------------------
// KeyframeEffectOptions // KeyframeEffectOptions
// ------------------------------ // ------------------------------
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment