script/dom/animations/
documenttimeline.rs1use dom_struct::dom_struct;
6use js::context::JSContext;
7use js::gc::HandleObject;
8use num_traits::ToPrimitive;
9use script_bindings::codegen::GenericBindings::DocumentTimelineBinding::DocumentTimelineOptions;
10use script_bindings::reflector::{reflect_dom_object, reflect_dom_object_with_proto_and_cx};
11use script_bindings::root::DomRoot;
12use script_bindings::script_runtime::CanGc;
13use servo_base::cross_process_instant::CrossProcessInstant;
14use servo_config::pref;
15use time::Duration;
16
17use crate::dom::bindings::codegen::Bindings::DocumentTimelineBinding::DocumentTimelineMethods;
18use crate::dom::types::{AnimationTimeline, Window};
19
20#[dom_struct]
22pub(crate) struct DocumentTimeline {
23 animation_timeline: AnimationTimeline,
24 #[no_trace]
32 origin_offset: Duration,
33}
34
35impl DocumentTimeline {
36 fn new_with_duration(
37 cx: &mut JSContext,
38 window: &Window,
39 proto: Option<HandleObject>,
40 origin_time: Duration,
41 ) -> DomRoot<Self> {
42 let duration_since_time_origin =
43 CrossProcessInstant::now() - window.navigation_start() - origin_time;
44 reflect_dom_object_with_proto_and_cx(
45 Box::new(Self {
46 animation_timeline: AnimationTimeline::new_inherited(duration_since_time_origin),
47 origin_offset: origin_time,
48 }),
49 window,
50 proto,
51 cx,
52 )
53 }
54
55 pub(crate) fn new(window: &Window, can_gc: CanGc) -> DomRoot<DocumentTimeline> {
56 let duration = if pref!(layout_animations_test_enabled) {
57 Duration::ZERO
58 } else {
59 CrossProcessInstant::now() - window.navigation_start()
60 };
61 reflect_dom_object(
62 Box::new(Self {
63 animation_timeline: AnimationTimeline::new_inherited(duration),
64 origin_offset: Duration::ZERO,
65 }),
66 window,
67 can_gc,
68 )
69 }
70
71 pub(crate) fn update(&self, window: &Window) {
73 let duration_since_time_origin =
74 CrossProcessInstant::now() - window.navigation_start() - self.origin_offset;
75 self.animation_timeline
76 .set_current_time(duration_since_time_origin);
77 }
78
79 pub(crate) fn advance_specific(&self, by: Duration) {
82 self.animation_timeline.advance_specific(by);
83 }
84}
85
86impl DocumentTimelineMethods<crate::DomTypeHolder> for DocumentTimeline {
87 fn Constructor(
88 cx: &mut JSContext,
89 window: &Window,
90 proto: Option<HandleObject>,
91 options: &DocumentTimelineOptions,
92 ) -> DomRoot<Self> {
93 Self::new_with_duration(
94 cx,
95 window,
96 proto,
97 Duration::seconds_f64(options.originTime.to_f64().unwrap_or_default() / 1000.),
98 )
99 }
100}