mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 14:17:36 +00:00
LibWeb: Set KeyframeEffect's pseudo-element if applicable
This commit is contained in:
parent
921f6c1e78
commit
2ee022dead
3 changed files with 40 additions and 13 deletions
|
@ -630,7 +630,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<KeyframeEffect>> KeyframeEffect::construct_
|
||||||
// When assigning this property, the error-handling defined for the pseudoElement setter on the interface is
|
// When assigning this property, the error-handling defined for the pseudoElement setter on the interface is
|
||||||
// applied. If the setter requires an exception to be thrown, this procedure must throw the same exception and
|
// applied. If the setter requires an exception to be thrown, this procedure must throw the same exception and
|
||||||
// abort all further steps.
|
// abort all further steps.
|
||||||
effect->set_pseudo_element(options.get<KeyframeEffectOptions>().pseudo_element);
|
TRY(effect->set_pseudo_element(options.get<KeyframeEffectOptions>().pseudo_element));
|
||||||
}
|
}
|
||||||
// Otherwise,
|
// Otherwise,
|
||||||
else {
|
else {
|
||||||
|
@ -730,16 +730,14 @@ void KeyframeEffect::set_target(DOM::Element* target)
|
||||||
m_target_element->associate_with_effect(*this);
|
m_target_element->associate_with_effect(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyframeEffect::set_pseudo_element(Optional<String> pseudo_element)
|
WebIDL::ExceptionOr<void> KeyframeEffect::set_pseudo_element(Optional<String> pseudo_element)
|
||||||
{
|
{
|
||||||
|
auto& realm = this->realm();
|
||||||
|
|
||||||
// On setting, sets the target pseudo-selector of the animation effect to the provided value after applying the
|
// On setting, sets the target pseudo-selector of the animation effect to the provided value after applying the
|
||||||
// following exceptions:
|
// following exceptions:
|
||||||
|
|
||||||
// FIXME:
|
// FIXME:
|
||||||
// - If the provided value is not null and is an invalid <pseudo-element-selector>, the user agent must throw a
|
|
||||||
// DOMException with error name SyntaxError and leave the target pseudo-selector of this animation effect
|
|
||||||
// unchanged.
|
|
||||||
|
|
||||||
// - If one of the legacy Selectors Level 2 single-colon selectors (':before', ':after', ':first-letter', or
|
// - If one of the legacy Selectors Level 2 single-colon selectors (':before', ':after', ':first-letter', or
|
||||||
// ':first-line') is specified, the target pseudo-selector must be set to the equivalent two-colon selector
|
// ':first-line') is specified, the target pseudo-selector must be set to the equivalent two-colon selector
|
||||||
// (e.g. '::before').
|
// (e.g. '::before').
|
||||||
|
@ -747,12 +745,33 @@ void KeyframeEffect::set_pseudo_element(Optional<String> pseudo_element)
|
||||||
auto value = pseudo_element.value();
|
auto value = pseudo_element.value();
|
||||||
|
|
||||||
if (value == ":before" || value == ":after" || value == ":first-letter" || value == ":first-line") {
|
if (value == ":before" || value == ":after" || value == ":first-letter" || value == ":first-line") {
|
||||||
m_target_pseudo_selector = MUST(String::formatted(":{}", value));
|
m_target_pseudo_selector = CSS::Selector::PseudoElement::from_string(MUST(value.substring_from_byte_offset(1)));
|
||||||
return;
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_target_pseudo_selector = pseudo_element;
|
// - If the provided value is not null and is an invalid <pseudo-element-selector>, the user agent must throw a
|
||||||
|
// DOMException with error name SyntaxError and leave the target pseudo-selector of this animation effect
|
||||||
|
// unchanged.
|
||||||
|
if (pseudo_element.has_value()) {
|
||||||
|
auto pseudo_element_without_colons = MUST(pseudo_element->replace("::"sv, ""sv, ReplaceMode::FirstOnly));
|
||||||
|
if (auto value = CSS::Selector::PseudoElement::from_string(pseudo_element_without_colons); value.has_value()) {
|
||||||
|
m_target_pseudo_selector = value;
|
||||||
|
} else {
|
||||||
|
return WebIDL::SyntaxError::create(realm, MUST(String::formatted("Invalid pseudo-element selector: \"{}\"", pseudo_element.value())));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_target_pseudo_selector = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<CSS::Selector::PseudoElement::Type> KeyframeEffect::pseudo_element_type() const
|
||||||
|
{
|
||||||
|
if (!m_target_pseudo_selector.has_value())
|
||||||
|
return {};
|
||||||
|
return m_target_pseudo_selector->type();
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/web-animations-1/#dom-keyframeeffect-getkeyframes
|
// https://www.w3.org/TR/web-animations-1/#dom-keyframeeffect-getkeyframes
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <LibWeb/Bindings/KeyframeEffectPrototype.h>
|
#include <LibWeb/Bindings/KeyframeEffectPrototype.h>
|
||||||
#include <LibWeb/Bindings/PlatformObject.h>
|
#include <LibWeb/Bindings/PlatformObject.h>
|
||||||
#include <LibWeb/CSS/PropertyID.h>
|
#include <LibWeb/CSS/PropertyID.h>
|
||||||
|
#include <LibWeb/CSS/Selector.h>
|
||||||
#include <LibWeb/CSS/StyleValue.h>
|
#include <LibWeb/CSS/StyleValue.h>
|
||||||
|
|
||||||
namespace Web::Animations {
|
namespace Web::Animations {
|
||||||
|
@ -84,8 +85,12 @@ public:
|
||||||
DOM::Element* target() const override { return m_target_element; }
|
DOM::Element* target() const override { return m_target_element; }
|
||||||
void set_target(DOM::Element* target);
|
void set_target(DOM::Element* target);
|
||||||
|
|
||||||
Optional<String> pseudo_element() const { return m_target_pseudo_selector; }
|
// JS bindings
|
||||||
void set_pseudo_element(Optional<String>);
|
Optional<StringView> pseudo_element() const { return m_target_pseudo_selector->name(); }
|
||||||
|
WebIDL::ExceptionOr<void> set_pseudo_element(Optional<String>);
|
||||||
|
|
||||||
|
Optional<CSS::Selector::PseudoElement::Type> pseudo_element_type() const;
|
||||||
|
void set_pseudo_element(Optional<CSS::Selector::PseudoElement> pseudo_element) { m_target_pseudo_selector = pseudo_element; }
|
||||||
|
|
||||||
Bindings::CompositeOperation composite() const { return m_composite; }
|
Bindings::CompositeOperation composite() const { return m_composite; }
|
||||||
void set_composite(Bindings::CompositeOperation value) { m_composite = value; }
|
void set_composite(Bindings::CompositeOperation value) { m_composite = value; }
|
||||||
|
@ -109,7 +114,7 @@ private:
|
||||||
JS::GCPtr<DOM::Element> m_target_element {};
|
JS::GCPtr<DOM::Element> m_target_element {};
|
||||||
|
|
||||||
// https://www.w3.org/TR/web-animations-1/#dom-keyframeeffect-pseudoelement
|
// https://www.w3.org/TR/web-animations-1/#dom-keyframeeffect-pseudoelement
|
||||||
Optional<String> m_target_pseudo_selector {};
|
Optional<CSS::Selector::PseudoElement> m_target_pseudo_selector {};
|
||||||
|
|
||||||
// https://www.w3.org/TR/web-animations-1/#dom-keyframeeffect-composite
|
// https://www.w3.org/TR/web-animations-1/#dom-keyframeeffect-composite
|
||||||
Bindings::CompositeOperation m_composite { Bindings::CompositeOperation::Replace };
|
Bindings::CompositeOperation m_composite { Bindings::CompositeOperation::Replace };
|
||||||
|
|
|
@ -1074,6 +1074,8 @@ ErrorOr<void> StyleComputer::compute_cascaded_values(StyleProperties& style, DOM
|
||||||
effect->set_timing_function(move(timing_function));
|
effect->set_timing_function(move(timing_function));
|
||||||
effect->set_fill_mode(Animations::css_fill_mode_to_bindings_fill_mode(fill_mode));
|
effect->set_fill_mode(Animations::css_fill_mode_to_bindings_fill_mode(fill_mode));
|
||||||
effect->set_playback_direction(Animations::css_animation_direction_to_bindings_playback_direction(direction));
|
effect->set_playback_direction(Animations::css_animation_direction_to_bindings_playback_direction(direction));
|
||||||
|
if (pseudo_element.has_value())
|
||||||
|
effect->set_pseudo_element(Selector::PseudoElement { pseudo_element.value() });
|
||||||
|
|
||||||
auto animation = CSSAnimation::create(realm);
|
auto animation = CSSAnimation::create(realm);
|
||||||
animation->set_id(animation_name.release_value());
|
animation->set_id(animation_name.release_value());
|
||||||
|
@ -1099,7 +1101,8 @@ ErrorOr<void> StyleComputer::compute_cascaded_values(StyleProperties& style, DOM
|
||||||
|
|
||||||
if (auto effect = animation->effect(); effect && effect->is_keyframe_effect()) {
|
if (auto effect = animation->effect(); effect && effect->is_keyframe_effect()) {
|
||||||
auto& keyframe_effect = *static_cast<Animations::KeyframeEffect*>(effect.ptr());
|
auto& keyframe_effect = *static_cast<Animations::KeyframeEffect*>(effect.ptr());
|
||||||
TRY(collect_animation_into(keyframe_effect, style));
|
if (keyframe_effect.pseudo_element_type() == pseudo_element)
|
||||||
|
TRY(collect_animation_into(keyframe_effect, style));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue