diff options
author | Josh Matthews <josh@joshmatthews.net> | 2025-05-24 23:21:05 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-25 03:21:05 +0000 |
commit | 3a04f4195eb650f092c44d5a05fee178b9e84fbe (patch) | |
tree | be0a28b7a0f7d0d678d1516a3e52db5de144d844 /components/script/dom | |
parent | 0d44ca8ddcea5399807abf0e3aef7b097133f679 (diff) | |
download | servo-3a04f4195eb650f092c44d5a05fee178b9e84fbe.tar.gz servo-3a04f4195eb650f092c44d5a05fee178b9e84fbe.zip |
script: Return global objects for DOM objects in the relevant realm (#37120)
DomObject::global is a tricky API because it's used pervasively but has
subtle requirements that are not documented and not yet enforced by the
type system (#36116). The method returns the relevant global object for
a given DOM object, but that operation is only meaningful if there is an
active realm. We usually, but not always, have an active realm.
This change avoids a footgun by following the principle of least
surprise. Rather than making every single caller of `something.global()`
both prove that there is an active realm and think about which realm
they want active, we implement the obvious behaviour: always activate
the realm of the callee before obtaining the relevant global.
Testing: Existing WPT coverage is sufficient; this method is called all
over the codebase.
Fixes: #37070 #27037
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/bindings/reflector.rs | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/components/script/dom/bindings/reflector.rs b/components/script/dom/bindings/reflector.rs index 0a5afbce487..c888686974e 100644 --- a/components/script/dom/bindings/reflector.rs +++ b/components/script/dom/bindings/reflector.rs @@ -11,7 +11,7 @@ use crate::DomTypes; use crate::dom::bindings::conversions::DerivedFrom; use crate::dom::bindings::root::DomRoot; use crate::dom::globalscope::GlobalScope; -use crate::realms::InRealm; +use crate::realms::{InRealm, enter_realm}; use crate::script_runtime::CanGc; /// Create the reflector for a new DOM object and yield ownership to the @@ -42,7 +42,16 @@ where } pub(crate) trait DomGlobal { + /// Returns the [relevant global] in whatever realm is currently active. + /// + /// [relevant global]: https://html.spec.whatwg.org/multipage/#concept-relevant-global fn global_(&self, realm: InRealm) -> DomRoot<GlobalScope>; + + /// Returns the [relevant global] in the same realm as the callee object. + /// If you know the callee's realm is already the current realm, it is + /// more efficient to call [DomGlobal::global_] instead. + /// + /// [relevant global]: https://html.spec.whatwg.org/multipage/#concept-relevant-global fn global(&self) -> DomRoot<GlobalScope>; } @@ -51,7 +60,8 @@ impl<T: DomGlobalGeneric<crate::DomTypeHolder>> DomGlobal for T { <Self as DomGlobalGeneric<crate::DomTypeHolder>>::global_(self, realm) } fn global(&self) -> DomRoot<GlobalScope> { - <Self as DomGlobalGeneric<crate::DomTypeHolder>>::global(self) + let realm = enter_realm(self); + <Self as DomGlobalGeneric<crate::DomTypeHolder>>::global_(self, InRealm::entered(&realm)) } } |