script/dom/bindings/
settings_stack.rs1use std::cell::RefCell;
6
7use js::jsapi::{GetScriptedCallerGlobal, JSTracer};
8use js::rust::Runtime;
9use script_bindings::settings_stack::*;
10
11use crate::dom::bindings::root::DomRoot;
13use crate::dom::bindings::trace::JSTraceable;
14use crate::dom::globalscope::GlobalScope;
15
16thread_local!(pub(super) static STACK: RefCell<Vec<StackEntry<crate::DomTypeHolder>>> = const {
17 RefCell::new(Vec::new())
18});
19
20pub(crate) unsafe fn trace(tracer: *mut JSTracer) {
22 STACK.with(|stack| {
23 unsafe { stack.borrow().trace(tracer) };
24 })
25}
26
27pub(crate) fn is_execution_stack_empty() -> bool {
28 STACK.with(|stack| stack.borrow().is_empty())
29}
30
31pub(crate) type AutoEntryScript = GenericAutoEntryScript<crate::DomTypeHolder>;
32
33pub(crate) fn entry_global() -> DomRoot<GlobalScope> {
37 STACK
38 .with(|stack| {
39 stack
40 .borrow()
41 .iter()
42 .rev()
43 .find(|entry| entry.kind == StackEntryKind::Entry)
44 .map(|entry| DomRoot::from_ref(&*entry.global))
45 })
46 .unwrap()
47}
48
49pub type AutoIncumbentScript = GenericAutoIncumbentScript<crate::DomTypeHolder>;
50
51pub(crate) fn incumbent_global() -> Option<DomRoot<GlobalScope>> {
55 unsafe {
62 let Some(cx) = Runtime::get() else {
63 return None;
66 };
67 let global = GetScriptedCallerGlobal(cx.as_ptr());
68 if !global.is_null() {
69 return Some(GlobalScope::from_object(global));
70 }
71 }
72
73 STACK.with(|stack| {
75 stack
76 .borrow()
77 .last()
78 .map(|entry| DomRoot::from_ref(&*entry.global))
79 })
80}