use dom_struct::dom_struct;
use js::gc::HandleObject;
use num_traits::ToPrimitive;
use script_bindings::codegen::GenericBindings::DocumentTimelineBinding::DocumentTimelineOptions;
use script_bindings::root::DomRoot;
use script_bindings::script_runtime::CanGc;
use servo_base::cross_process_instant::CrossProcessInstant;
use servo_config::pref;
use time::Duration;
use crate::dom::bindings::codegen::Bindings::DocumentTimelineBinding::DocumentTimelineMethods;
use crate::dom::bindings::reflector::{reflect_dom_object, reflect_dom_object_with_proto};
use crate::dom::types::{AnimationTimeline, Window};
#[dom_struct]
pub(crate) struct DocumentTimeline {
animation_timeline: AnimationTimeline,
#[no_trace]
origin_offset: Duration,
}
impl DocumentTimeline {
pub(crate) fn new_with_duration(
window: &Window,
proto: Option<HandleObject>,
origin_time: Duration,
can_gc: CanGc,
) -> DomRoot<Self> {
let duration_since_time_origin =
CrossProcessInstant::now() - window.navigation_start() - origin_time;
reflect_dom_object_with_proto(
Box::new(Self {
animation_timeline: AnimationTimeline::new_inherited(duration_since_time_origin),
origin_offset: origin_time,
}),
window,
proto,
can_gc,
)
}
pub(crate) fn new(window: &Window, can_gc: CanGc) -> DomRoot<DocumentTimeline> {
let duration = if pref!(layout_animations_test_enabled) {
Duration::ZERO
} else {
CrossProcessInstant::now() - window.navigation_start()
};
reflect_dom_object(
Box::new(Self {
animation_timeline: AnimationTimeline::new_inherited(duration),
origin_offset: Duration::ZERO,
}),
window,
can_gc,
)
}
pub(crate) fn update(&self, window: &Window) {
let duration_since_time_origin =
CrossProcessInstant::now() - window.navigation_start() - self.origin_offset;
self.animation_timeline
.set_current_time(duration_since_time_origin);
}
pub(crate) fn advance_specific(&self, by: Duration) {
self.animation_timeline.advance_specific(by);
}
}
impl DocumentTimelineMethods<crate::DomTypeHolder> for DocumentTimeline {
fn Constructor(
window: &Window,
proto: Option<HandleObject>,
can_gc: CanGc,
options: &DocumentTimelineOptions,
) -> DomRoot<Self> {
Self::new_with_duration(
window,
proto,
Duration::seconds_f64(options.originTime.to_f64().unwrap_or_default() / 1000.),
can_gc,
)
}
}