mirror of
https://github.com/servo/servo.git
synced 2025-07-22 14:53:49 +01:00
revert: Introduce Untransplantable
trait to indicate transplantability at the type level
(8f7b0cff87f0eab921e13e6990d76e12935e8675)
This commit is contained in:
parent
4c7f198ee2
commit
1f74d4c75b
8 changed files with 47 additions and 382 deletions
|
@ -8,7 +8,7 @@ use crate::dom::bindings::error::{throw_dom_exception, Error, Fallible};
|
|||
use crate::dom::bindings::inheritance::Castable;
|
||||
use crate::dom::bindings::proxyhandler::set_property_descriptor;
|
||||
use crate::dom::bindings::reflector::{DomObject, Reflector};
|
||||
use crate::dom::bindings::root::{DomRoot, TransplantableDomOnceCell};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::bindings::str::{DOMString, USVString};
|
||||
use crate::dom::bindings::trace::JSTraceable;
|
||||
use crate::dom::bindings::utils::{get_array_index_from_id, AsVoidPtr, WindowProxyHandler};
|
||||
|
@ -58,18 +58,10 @@ use std::ptr;
|
|||
use style::attr::parse_integer;
|
||||
|
||||
#[dom_struct]
|
||||
// `dom_object(transplantable)` removes `!Untransplantable` impl.
|
||||
#[dom_object(transplantable)]
|
||||
// NOTE: the browsing context for a window is managed in two places:
|
||||
// here, in script, but also in the constellation. The constellation
|
||||
// manages the session history, which in script is accessed through
|
||||
// History objects, messaging the constellation.
|
||||
//
|
||||
// `WindowProxy` being transplantable means all references to `WindowProxy` must
|
||||
// be maintained through cross-realm compatible reference wrappers such as
|
||||
// `*TransplantableDom*`. In addition, all DOM references contained within
|
||||
// must be wrapped by `*TransplantableDom*` as well because their realms vary
|
||||
// from `WindowProxy`'s point of view.
|
||||
pub struct WindowProxy {
|
||||
/// The JS WindowProxy object.
|
||||
/// Unlike other reflectors, we mutate this field because
|
||||
|
@ -109,10 +101,10 @@ pub struct WindowProxy {
|
|||
is_closing: Cell<bool>,
|
||||
|
||||
/// The containing iframe element, if this is a same-origin iframe
|
||||
frame_element: TransplantableDomOnceCell<Element>,
|
||||
frame_element: Option<Dom<Element>>,
|
||||
|
||||
/// The parent browsing context's window proxy, if this is a nested browsing context
|
||||
parent: TransplantableDomOnceCell<WindowProxy>,
|
||||
parent: Option<Dom<WindowProxy>>,
|
||||
|
||||
/// https://html.spec.whatwg.org/multipage/#delaying-load-events-mode
|
||||
delaying_load_events_mode: Cell<bool>,
|
||||
|
@ -128,12 +120,12 @@ pub struct WindowProxy {
|
|||
}
|
||||
|
||||
impl WindowProxy {
|
||||
#[allow(unsafe_code)]
|
||||
pub fn new_inherited(
|
||||
browsing_context_id: BrowsingContextId,
|
||||
top_level_browsing_context_id: TopLevelBrowsingContextId,
|
||||
currently_active: Option<PipelineId>,
|
||||
frame_element: Option<&Element>,
|
||||
parent: Option<&WindowProxy>,
|
||||
opener: Option<BrowsingContextId>,
|
||||
creator: CreatorBrowsingContextInfo,
|
||||
) -> WindowProxy {
|
||||
|
@ -149,9 +141,8 @@ impl WindowProxy {
|
|||
discarded: Cell::new(false),
|
||||
disowned: Cell::new(false),
|
||||
is_closing: Cell::new(false),
|
||||
// Safety: These fields are not set until they are pinned
|
||||
frame_element: unsafe { TransplantableDomOnceCell::new() },
|
||||
parent: unsafe { TransplantableDomOnceCell::new() },
|
||||
frame_element: frame_element.map(Dom::from_ref),
|
||||
parent: parent.map(Dom::from_ref),
|
||||
delaying_load_events_mode: Cell::new(false),
|
||||
opener,
|
||||
creator_base_url: creator.base_url,
|
||||
|
@ -194,6 +185,7 @@ impl WindowProxy {
|
|||
top_level_browsing_context_id,
|
||||
current,
|
||||
frame_element,
|
||||
parent,
|
||||
opener,
|
||||
creator,
|
||||
));
|
||||
|
@ -216,17 +208,6 @@ impl WindowProxy {
|
|||
js_proxy.get()
|
||||
);
|
||||
window_proxy.reflector.set_jsobject(js_proxy.get());
|
||||
|
||||
// Set the remaining fields after pinning.
|
||||
window_proxy
|
||||
.frame_element
|
||||
.set(frame_element, &window_proxy.global())
|
||||
.unwrap();
|
||||
window_proxy
|
||||
.parent
|
||||
.set(parent, &window_proxy.global())
|
||||
.unwrap();
|
||||
|
||||
DomRoot::from_ref(&*Box::into_raw(window_proxy))
|
||||
}
|
||||
}
|
||||
|
@ -252,6 +233,7 @@ impl WindowProxy {
|
|||
top_level_browsing_context_id,
|
||||
None,
|
||||
None,
|
||||
parent,
|
||||
opener,
|
||||
creator,
|
||||
));
|
||||
|
@ -288,13 +270,6 @@ impl WindowProxy {
|
|||
js_proxy.get()
|
||||
);
|
||||
window_proxy.reflector.set_jsobject(js_proxy.get());
|
||||
|
||||
// Set the remaining field after pinning.
|
||||
window_proxy
|
||||
.parent
|
||||
.set(parent, &window_proxy.global())
|
||||
.unwrap();
|
||||
|
||||
DomRoot::from_ref(&*Box::into_raw(window_proxy))
|
||||
}
|
||||
}
|
||||
|
@ -448,7 +423,7 @@ impl WindowProxy {
|
|||
Some(opener_browsing_context_id) => opener_browsing_context_id,
|
||||
None => return NullValue(),
|
||||
};
|
||||
let parent_browsing_context = self.parent.as_ref();
|
||||
let parent_browsing_context = self.parent.as_deref();
|
||||
let opener_proxy = match ScriptThread::find_window_proxy(opener_id) {
|
||||
Some(window_proxy) => window_proxy,
|
||||
None => {
|
||||
|
@ -618,7 +593,7 @@ impl WindowProxy {
|
|||
}
|
||||
|
||||
pub fn frame_element(&self) -> Option<&Element> {
|
||||
self.frame_element.as_ref()
|
||||
self.frame_element.as_deref()
|
||||
}
|
||||
|
||||
pub fn document(&self) -> Option<DomRoot<Document>> {
|
||||
|
@ -628,7 +603,7 @@ impl WindowProxy {
|
|||
}
|
||||
|
||||
pub fn parent(&self) -> Option<&WindowProxy> {
|
||||
self.parent.as_ref()
|
||||
self.parent.as_deref()
|
||||
}
|
||||
|
||||
pub fn top(&self) -> &WindowProxy {
|
||||
|
@ -649,11 +624,6 @@ impl WindowProxy {
|
|||
let handler = CreateWrapperProxyHandler(traps);
|
||||
assert!(!handler.is_null());
|
||||
|
||||
// FIXME: Disable compacting GC during this operation so that
|
||||
// yet-to-be-rewrapped child pointers won't be traced with
|
||||
// an incorrect compartment. We need something like
|
||||
// `js::AutoDisableCompactingGC`.
|
||||
|
||||
let cx = window.get_cx();
|
||||
let window_jsobject = window.reflector().get_jsobject();
|
||||
let old_js_proxy = self.reflector.get_jsobject();
|
||||
|
@ -681,10 +651,6 @@ impl WindowProxy {
|
|||
rooted!(in(*cx) let new_js_proxy = JS_TransplantObject(*cx, old_js_proxy, new_js_proxy.handle()));
|
||||
debug!("Transplanted proxy is {:p}.", new_js_proxy.get());
|
||||
|
||||
// Re-wrap reflectors for the new realm.
|
||||
self.frame_element.rewrap(window);
|
||||
self.parent.rewrap(window);
|
||||
|
||||
// Transfer ownership of this browsing context from the old window proxy to the new one.
|
||||
SetProxyReservedSlot(new_js_proxy.get(), 0, &PrivateValue(self.as_void_ptr()));
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue