Skip to main content

script/dom/animations/
animation.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use dom_struct::dom_struct;
6use js::context::JSContext;
7use js::rust::HandleObject;
8use script_bindings::codegen::GenericBindings::DocumentBinding::DocumentMethods;
9use script_bindings::inheritance::Castable;
10use script_bindings::reflector::reflect_dom_object_with_proto;
11use script_bindings::root::DomRoot;
12
13use crate::dom::animationeffect::AnimationEffect;
14use crate::dom::bindings::codegen::Bindings::AnimationBinding::AnimationMethods;
15use crate::dom::bindings::root::MutNullableDom;
16use crate::dom::eventtarget::EventTarget;
17use crate::dom::globalscope::GlobalScope;
18use crate::dom::types::AnimationTimeline;
19use crate::dom::window::Window;
20
21/// <https://drafts.csswg.org/web-animations-1/#animation>
22#[dom_struct]
23pub(crate) struct Animation {
24    event_target: EventTarget,
25
26    /// <https://drafts.csswg.org/web-animations-1/#timeline>
27    timeline: MutNullableDom<AnimationTimeline>,
28
29    /// <https://drafts.csswg.org/web-animations-1/#animation-associated-effect>
30    associated_effect: MutNullableDom<AnimationEffect>,
31}
32
33impl Animation {
34    pub(crate) fn new_inherited() -> Self {
35        Self {
36            event_target: EventTarget::new_inherited(),
37            timeline: Default::default(),
38            associated_effect: Default::default(),
39        }
40    }
41
42    fn new_with_proto(
43        cx: &mut JSContext,
44        global: &GlobalScope,
45        proto: Option<HandleObject>,
46    ) -> DomRoot<Self> {
47        reflect_dom_object_with_proto(cx, Box::new(Self::new_inherited()), global, proto)
48    }
49
50    pub(crate) fn new(cx: &mut JSContext, global: &GlobalScope) -> DomRoot<Self> {
51        Self::new_with_proto(cx, global, None)
52    }
53
54    /// <https://drafts.csswg.org/web-animations-1/#animation-set-the-timeline-of-an-animation>
55    fn set_the_timeline(&self, timeline: Option<&AnimationTimeline>) {
56        // FIXME: Implement this fully
57        self.timeline.set(timeline);
58    }
59
60    /// <https://drafts.csswg.org/web-animations-1/#animation-set-the-associated-effect-of-an-animation>
61    fn set_the_associated_effect(&self, effect: Option<&AnimationEffect>) {
62        // FIXME: Implement this fully
63        self.associated_effect.set(effect);
64    }
65}
66
67impl AnimationMethods<crate::DomTypeHolder> for Animation {
68    /// <https://drafts.csswg.org/web-animations-1/#dom-animation-animation>
69    fn Constructor(
70        cx: &mut JSContext,
71        window: &Window,
72        _object: Option<HandleObject>,
73        effect: Option<&AnimationEffect>,
74        timeline: Option<Option<&AnimationTimeline>>,
75    ) -> DomRoot<Self> {
76        // Step 1. Let animation be a new Animation object.
77        let animation = Animation::new(cx, window.upcast());
78
79        // Step 2. Run the procedure to set the timeline of an animation on animation passing timeline
80        // as the new timeline; or, if the timeline argument is missing, passing the default document
81        // timeline of the Document associated with the Window that is the current global object.
82        if let Some(timeline) = timeline.flatten() {
83            animation.set_the_timeline(Some(timeline));
84        } else {
85            let document = window.document_unrooted(cx.no_gc());
86            let timeline = document.Timeline();
87            animation.set_the_timeline(Some(timeline.upcast()));
88        }
89
90        // Step 3. Run the procedure to set the associated effect of an animation on animation passing
91        // source as the new effect.
92        animation.set_the_associated_effect(effect);
93
94        animation
95    }
96
97    /// <https://drafts.csswg.org/web-animations-1/#dom-animation-effect>
98    fn GetEffect(&self) -> Option<DomRoot<AnimationEffect>> {
99        self.associated_effect.get()
100    }
101
102    /// <https://drafts.csswg.org/web-animations-1/#dom-animation-effect>
103    fn SetEffect(&self, effect: Option<&AnimationEffect>) {
104        // > Setting this attribute updates the object’s associated effect using
105        // > the procedure to set the associated effect of an animation.
106        self.set_the_associated_effect(effect);
107    }
108
109    /// <https://drafts.csswg.org/web-animations-1/#dom-animation-animation-effect-timeline-timeline>
110    fn GetTimeline(&self) -> Option<DomRoot<AnimationTimeline>> {
111        self.timeline.get()
112    }
113
114    /// <https://drafts.csswg.org/web-animations-1/#dom-animation-animation-effect-timeline-timeline>
115    fn SetTimeline(&self, timeline: Option<&AnimationTimeline>) {
116        // > Setting this attribute updates the object’s timeline using the procedure
117        // > to set the timeline of an animation.
118        self.set_the_timeline(timeline);
119    }
120}