script/dom/
useractivation.rs1use std::ops::Add;
6
7use base::cross_process_instant::CrossProcessInstant;
8use dom_struct::dom_struct;
9use script_bindings::codegen::GenericBindings::UserActivationBinding::UserActivationMethods;
10use time::Duration;
11
12use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
13use crate::dom::bindings::root::{Dom, DomRoot};
14use crate::dom::document::{
15 Document, SameOriginDescendantNavigablesIterator, SameoriginAncestorNavigablesIterator,
16};
17use crate::dom::globalscope::GlobalScope;
18use crate::script_runtime::CanGc;
19
20#[dom_struct]
22pub(crate) struct UserActivation {
23 reflector_: Reflector,
24}
25
26impl UserActivation {
27 fn new_inherited() -> UserActivation {
28 UserActivation {
29 reflector_: Reflector::new(),
30 }
31 }
32
33 pub(crate) fn new(global: &GlobalScope, can_gc: CanGc) -> DomRoot<UserActivation> {
34 reflect_dom_object(Box::new(UserActivation::new_inherited()), global, can_gc)
35 }
36
37 pub(crate) fn handle_user_activation_notification(document: &Document) {
39 debug_assert!(
42 document.is_fully_active(),
43 "Document should be fully active at this moment"
44 );
45
46 let owner_window = document.window();
49 rooted_vec!(let mut windows <- vec![Dom::from_ref(owner_window)].into_iter());
50
51 for document in SameoriginAncestorNavigablesIterator::new(DomRoot::from_ref(document)) {
55 windows.push(Dom::from_ref(document.window()));
56 }
57
58 for document in SameOriginDescendantNavigablesIterator::new(DomRoot::from_ref(document)) {
62 windows.push(Dom::from_ref(document.window()));
63 }
64
65 let current_timestamp = CrossProcessInstant::now();
68 for window in windows.iter() {
69 window.set_last_activation_timestamp(UserActivationTimestamp::TimeStamp(
72 current_timestamp,
73 ));
74
75 }
79 }
80}
81
82impl UserActivationMethods<crate::DomTypeHolder> for UserActivation {
83 fn HasBeenActive(&self) -> bool {
85 self.global().as_window().has_sticky_activation()
87 }
88
89 fn IsActive(&self) -> bool {
91 self.global().as_window().has_transient_activation()
93 }
94}
95
96#[derive(Clone, Copy, Default, PartialEq, PartialOrd, MallocSizeOf)]
101pub(crate) enum UserActivationTimestamp {
102 NegativeInfinity,
103 TimeStamp(CrossProcessInstant),
104 #[default]
105 PositiveInfinity,
106}
107
108impl Add<i64> for UserActivationTimestamp {
109 type Output = UserActivationTimestamp;
110
111 fn add(self, rhs: i64) -> Self::Output {
112 match self {
113 UserActivationTimestamp::TimeStamp(timestamp) => {
114 UserActivationTimestamp::TimeStamp(timestamp + Duration::milliseconds(rhs))
115 },
116 _ => self,
117 }
118 }
119}