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_with_cx, reflect_dom_object_with_proto};
11use script_bindings::root::DomRoot;
12use servo_base::cross_process_instant::CrossProcessInstant;
13use servo_config::pref;
14use time::Duration;
15
16use crate::dom::bindings::codegen::Bindings::DocumentTimelineBinding::DocumentTimelineMethods;
17use crate::dom::types::{AnimationTimeline, Window};
18
19#[dom_struct]
21pub(crate) struct DocumentTimeline {
22 animation_timeline: AnimationTimeline,
23 #[no_trace]
31 origin_offset: Duration,
32}
33
34impl DocumentTimeline {
35 fn new_with_duration(
36 cx: &mut JSContext,
37 window: &Window,
38 proto: Option<HandleObject>,
39 origin_time: Duration,
40 ) -> DomRoot<Self> {
41 let duration_since_time_origin =
42 CrossProcessInstant::now() - window.navigation_start() - origin_time;
43 reflect_dom_object_with_proto(
44 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 )
52 }
53
54 pub(crate) fn new(cx: &mut JSContext, window: &Window) -> DomRoot<DocumentTimeline> {
55 let duration = if pref!(layout_animations_test_enabled) {
56 Duration::ZERO
57 } else {
58 CrossProcessInstant::now() - window.navigation_start()
59 };
60 reflect_dom_object_with_cx(
61 Box::new(Self {
62 animation_timeline: AnimationTimeline::new_inherited(duration),
63 origin_offset: Duration::ZERO,
64 }),
65 window,
66 cx,
67 )
68 }
69
70 pub(crate) fn update(&self, window: &Window) {
72 let duration_since_time_origin =
73 CrossProcessInstant::now() - window.navigation_start() - self.origin_offset;
74 self.animation_timeline
75 .set_current_time(duration_since_time_origin);
76 }
77
78 pub(crate) fn advance_specific(&self, by: Duration) {
81 self.animation_timeline.advance_specific(by);
82 }
83}
84
85impl DocumentTimelineMethods<crate::DomTypeHolder> for DocumentTimeline {
86 fn Constructor(
87 cx: &mut JSContext,
88 window: &Window,
89 proto: Option<HandleObject>,
90 options: &DocumentTimelineOptions,
91 ) -> DomRoot<Self> {
92 Self::new_with_duration(
93 cx,
94 window,
95 proto,
96 Duration::seconds_f64(options.originTime.to_f64().unwrap_or_default() / 1000.),
97 )
98 }
99}