forked from SerenityOS/serenity
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
LibWeb: Add the Animation IDL object
- Loading branch information
1 parent
0df06ce
commit 1ca46af
Showing
6 changed files
with
270 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
/* | ||
* Copyright (c) 2023, Matthew Olsson <[email protected]>. | ||
* | ||
* SPDX-License-Identifier: BSD-2-Clause | ||
*/ | ||
|
||
#include <LibWeb/Animations/Animation.h> | ||
#include <LibWeb/Animations/AnimationEffect.h> | ||
#include <LibWeb/Animations/DocumentTimeline.h> | ||
#include <LibWeb/Bindings/Intrinsics.h> | ||
#include <LibWeb/DOM/Document.h> | ||
#include <LibWeb/HTML/Window.h> | ||
#include <LibWeb/WebIDL/ExceptionOr.h> | ||
#include <LibWeb/WebIDL/Promise.h> | ||
|
||
namespace Web::Animations { | ||
|
||
// https://www.w3.org/TR/web-animations-1/#dom-animation-animation | ||
JS::NonnullGCPtr<Animation> Animation::create(JS::Realm& realm, JS::GCPtr<AnimationEffect> effect, JS::GCPtr<AnimationTimeline> timeline) | ||
{ | ||
// 1. Let animation be a new Animation object. | ||
auto animation = realm.heap().allocate<Animation>(realm, realm); | ||
|
||
// 2. Run the procedure to set the timeline of an animation on animation passing timeline as the new timeline or, if | ||
// a timeline argument is missing, passing the default document timeline of the Document associated with the | ||
// Window that is the current global object. | ||
if (!timeline) { | ||
auto& window = verify_cast<HTML::Window>(HTML::current_global_object()); | ||
timeline = window.associated_document().timeline(); | ||
} | ||
animation->set_timeline(timeline); | ||
|
||
// 3. Run the procedure to set the associated effect of an animation on animation passing source as the new effect. | ||
animation->set_effect(effect); | ||
|
||
return animation; | ||
} | ||
|
||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Animation>> Animation::construct_impl(JS::Realm& realm, JS::GCPtr<AnimationEffect> effect, JS::GCPtr<AnimationTimeline> timeline) | ||
{ | ||
return create(realm, effect, timeline); | ||
} | ||
|
||
// https://www.w3.org/TR/web-animations-1/#animation-set-the-associated-effect-of-an-animation | ||
void Animation::set_effect(JS::GCPtr<AnimationEffect> new_effect) | ||
{ | ||
// FIXME: Implement | ||
(void)new_effect; | ||
} | ||
|
||
// https://www.w3.org/TR/web-animations-1/#animation-set-the-timeline-of-an-animation | ||
void Animation::set_timeline(JS::GCPtr<AnimationTimeline> new_timeline) | ||
{ | ||
// FIXME: Implement | ||
(void)new_timeline; | ||
} | ||
|
||
// https://www.w3.org/TR/web-animations-1/#dom-animation-starttime | ||
// https://www.w3.org/TR/web-animations-1/#set-the-start-time | ||
void Animation::set_start_time(Optional<double> const& new_start_time) | ||
{ | ||
// FIXME: Implement | ||
(void)new_start_time; | ||
} | ||
|
||
// https://www.w3.org/TR/web-animations-1/#animation-current-time | ||
Optional<double> Animation::current_time() const | ||
{ | ||
// FIXME: Implement | ||
return {}; | ||
} | ||
|
||
// https://www.w3.org/TR/web-animations-1/#animation-set-the-current-time | ||
WebIDL::ExceptionOr<void> Animation::set_current_time(Optional<double> const& seek_time) | ||
{ | ||
// FIXME: Implement | ||
(void)seek_time; | ||
return {}; | ||
} | ||
|
||
// https://www.w3.org/TR/web-animations-1/#dom-animation-playbackrate | ||
// https://www.w3.org/TR/web-animations-1/#set-the-playback-rate | ||
WebIDL::ExceptionOr<void> Animation::set_playback_rate(double new_playback_rate) | ||
{ | ||
// FIXME: Implement | ||
(void)new_playback_rate; | ||
return {}; | ||
} | ||
|
||
// https://www.w3.org/TR/web-animations-1/#animation-play-state | ||
Bindings::AnimationPlayState Animation::play_state() const | ||
{ | ||
// FIXME: Implement | ||
return Bindings::AnimationPlayState::Idle; | ||
} | ||
|
||
JS::NonnullGCPtr<WebIDL::Promise> Animation::current_ready_promise() const | ||
{ | ||
if (!m_current_ready_promise) { | ||
// The current ready promise is initially a resolved Promise created using the procedure to create a new | ||
// resolved Promise with the animation itself as its value and created in the relevant Realm of the animation. | ||
m_current_ready_promise = WebIDL::create_resolved_promise(realm(), this); | ||
} | ||
|
||
return *m_current_ready_promise; | ||
} | ||
|
||
JS::NonnullGCPtr<WebIDL::Promise> Animation::current_finished_promise() const | ||
{ | ||
if (!m_current_finished_promise) { | ||
// The current finished promise is initially a pending Promise object. | ||
m_current_finished_promise = WebIDL::create_promise(realm()); | ||
} | ||
|
||
return *m_current_finished_promise; | ||
} | ||
|
||
Animation::Animation(JS::Realm& realm) | ||
: DOM::EventTarget(realm) | ||
{ | ||
} | ||
|
||
void Animation::initialize(JS::Realm& realm) | ||
{ | ||
Base::initialize(realm); | ||
set_prototype(&Bindings::ensure_web_prototype<Bindings::AnimationPrototype>(realm, "Animation")); | ||
} | ||
|
||
void Animation::visit_edges(Cell::Visitor& visitor) | ||
{ | ||
Base::visit_edges(visitor); | ||
visitor.visit(m_effect); | ||
visitor.visit(m_timeline); | ||
visitor.visit(m_current_ready_promise); | ||
visitor.visit(m_current_finished_promise); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/* | ||
* Copyright (c) 2023, Matthew Olsson <[email protected]>. | ||
* | ||
* SPDX-License-Identifier: BSD-2-Clause | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <LibJS/Runtime/PromiseCapability.h> | ||
#include <LibWeb/Bindings/AnimationPrototype.h> | ||
#include <LibWeb/DOM/EventTarget.h> | ||
|
||
namespace Web::Animations { | ||
|
||
// https://www.w3.org/TR/web-animations-1/#the-animation-interface | ||
class Animation : public DOM::EventTarget { | ||
WEB_PLATFORM_OBJECT(Animation, DOM::EventTarget); | ||
|
||
public: | ||
static JS::NonnullGCPtr<Animation> create(JS::Realm&, JS::GCPtr<AnimationEffect>, JS::GCPtr<AnimationTimeline>); | ||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<Animation>> construct_impl(JS::Realm&, JS::GCPtr<AnimationEffect>, JS::GCPtr<AnimationTimeline>); | ||
|
||
FlyString const& id() const { return m_id; } | ||
void set_id(FlyString value) { m_id = move(value); } | ||
|
||
JS::GCPtr<AnimationEffect> effect() const { return m_effect; } | ||
void set_effect(JS::GCPtr<AnimationEffect>); | ||
|
||
JS::GCPtr<AnimationTimeline> timeline() const { return m_timeline; } | ||
void set_timeline(JS::GCPtr<AnimationTimeline>); | ||
|
||
Optional<double> const& start_time() const { return m_start_time; } | ||
void set_start_time(Optional<double> const&); | ||
|
||
Optional<double> current_time() const; | ||
WebIDL::ExceptionOr<void> set_current_time(Optional<double> const&); | ||
|
||
double playback_rate() const { return m_playback_rate; } | ||
WebIDL::ExceptionOr<void> set_playback_rate(double value); | ||
|
||
Bindings::AnimationPlayState play_state() const; | ||
|
||
Bindings::AnimationReplaceState replace_state() const { return m_replace_state; } | ||
|
||
// https://www.w3.org/TR/web-animations-1/#dom-animation-ready | ||
JS::NonnullGCPtr<JS::Object> ready() const { return *current_ready_promise()->promise(); } | ||
|
||
// https://www.w3.org/TR/web-animations-1/#dom-animation-finished | ||
JS::NonnullGCPtr<JS::Object> finished() const { return *current_finished_promise()->promise(); } | ||
|
||
protected: | ||
Animation(JS::Realm&); | ||
|
||
virtual void initialize(JS::Realm&) override; | ||
virtual void visit_edges(Cell::Visitor&) override; | ||
|
||
private: | ||
JS::NonnullGCPtr<WebIDL::Promise> current_ready_promise() const; | ||
JS::NonnullGCPtr<WebIDL::Promise> current_finished_promise() const; | ||
|
||
// https://www.w3.org/TR/web-animations-1/#dom-animation-id | ||
FlyString m_id; | ||
|
||
// https://www.w3.org/TR/web-animations-1/#dom-animation-effect | ||
JS::GCPtr<AnimationEffect> m_effect; | ||
|
||
// https://www.w3.org/TR/web-animations-1/#dom-animation-timeline | ||
JS::GCPtr<AnimationTimeline> m_timeline; | ||
|
||
// https://www.w3.org/TR/web-animations-1/#animation-start-time | ||
Optional<double> m_start_time {}; | ||
|
||
// https://www.w3.org/TR/web-animations-1/#playback-rate | ||
double m_playback_rate { 1.0 }; | ||
|
||
// https://www.w3.org/TR/web-animations-1/#dom-animation-replacestate | ||
Bindings::AnimationReplaceState m_replace_state { Bindings::AnimationReplaceState::Active }; | ||
|
||
// Note: The following promises are initialized lazily to avoid constructing them outside of an execution context | ||
// https://www.w3.org/TR/web-animations-1/#current-ready-promise | ||
mutable JS::GCPtr<WebIDL::Promise> m_current_ready_promise; | ||
|
||
// https://www.w3.org/TR/web-animations-1/#current-finished-promise | ||
mutable JS::GCPtr<WebIDL::Promise> m_current_finished_promise; | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#import <Animations/AnimationEffect.idl> | ||
#import <Animations/AnimationTimeline.idl> | ||
|
||
// https://www.w3.org/TR/web-animations-1/#the-animation-interface | ||
[Exposed=Window] | ||
interface Animation : EventTarget { | ||
constructor(optional AnimationEffect? effect = null, | ||
optional AnimationTimeline? timeline); | ||
attribute DOMString id; | ||
attribute AnimationEffect? effect; | ||
attribute AnimationTimeline? timeline; | ||
attribute double? startTime; | ||
attribute double? currentTime; | ||
attribute double playbackRate; | ||
readonly attribute AnimationPlayState playState; | ||
readonly attribute AnimationReplaceState replaceState; | ||
// FIXME: | ||
// readonly attribute boolean pending; | ||
readonly attribute Promise<Animation> ready; | ||
readonly attribute Promise<Animation> finished; | ||
|
||
// FIXME: | ||
// attribute EventHandler onfinish; | ||
// attribute EventHandler oncancel; | ||
// attribute EventHandler onremove; | ||
|
||
// undefined cancel(); | ||
// undefined finish(); | ||
// undefined play(); | ||
// undefined pause(); | ||
// undefined updatePlaybackRate(double playbackRate); | ||
// undefined reverse(); | ||
// undefined persist(); | ||
// [CEReactions] | ||
// undefined commitStyles(); | ||
}; | ||
|
||
// https://www.w3.org/TR/web-animations-1/#the-animationplaystate-enumeration | ||
enum AnimationPlayState { "idle", "running", "paused", "finished" }; | ||
|
||
// https://www.w3.org/TR/web-animations-1/#the-animationreplacestate-enumeration | ||
enum AnimationReplaceState { "active", "removed", "persisted" }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters