From 43ca26068935e014b1a41a6a02f45d05436577b4 Mon Sep 17 00:00:00 2001 From: Alan Jeffrey Date: Fri, 12 May 2017 15:02:35 -0500 Subject: Renamed BrowsingContext to WindowProxy in script. --- components/script/dom/windowproxy.rs | 596 +++++++++++++++++++++++++++++++++++ 1 file changed, 596 insertions(+) create mode 100644 components/script/dom/windowproxy.rs (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs new file mode 100644 index 00000000000..3290afa1f2c --- /dev/null +++ b/components/script/dom/windowproxy.rs @@ -0,0 +1,596 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use dom::bindings::conversions::{ToJSValConvertible, root_from_handleobject}; +use dom::bindings::error::{Error, throw_dom_exception}; +use dom::bindings::inheritance::Castable; +use dom::bindings::js::{JS, Root, RootedReference}; +use dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor}; +use dom::bindings::reflector::{DomObject, Reflector}; +use dom::bindings::trace::JSTraceable; +use dom::bindings::utils::{WindowProxyHandler, get_array_index_from_id, AsVoidPtr}; +use dom::dissimilaroriginwindow::DissimilarOriginWindow; +use dom::element::Element; +use dom::globalscope::GlobalScope; +use dom::window::Window; +use dom_struct::dom_struct; +use js::JSCLASS_IS_GLOBAL; +use js::glue::{CreateWrapperProxyHandler, ProxyTraps, NewWindowProxy}; +use js::glue::{GetProxyPrivate, SetProxyExtra, GetProxyExtra}; +use js::jsapi::{Handle, HandleId, HandleObject, HandleValue}; +use js::jsapi::{JSAutoCompartment, JSContext, JSErrNum, JSFreeOp, JSObject}; +use js::jsapi::{JSPROP_READONLY, JSTracer, JS_DefinePropertyById}; +use js::jsapi::{JS_ForwardGetPropertyTo, JS_ForwardSetPropertyTo}; +use js::jsapi::{JS_GetOwnPropertyDescriptorById, JS_HasPropertyById, JS_HasOwnPropertyById}; +use js::jsapi::{JS_IsExceptionPending, JS_TransplantObject, SetWindowProxy}; +use js::jsapi::{MutableHandle, MutableHandleObject, MutableHandleValue}; +use js::jsapi::{ObjectOpResult, PropertyDescriptor}; +use js::jsval::{UndefinedValue, PrivateValue}; +use js::rust::get_object_class; +use msg::constellation_msg::FrameId; +use msg::constellation_msg::PipelineId; +use std::cell::Cell; +use std::ptr; + +#[dom_struct] +// 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. +pub struct WindowProxy { + /// The JS WindowProxy object. + /// Unlike other reflectors, we mutate this field because + /// we have to brain-transplant the reflector when the WindowProxy + /// changes Window. + reflector: Reflector, + + /// The frame id of the browsing context. + /// In the case that this is a nested browsing context, this is the frame id + /// of the container. + frame_id: FrameId, + + /// The pipeline id of the currently active document. + /// May be None, when the currently active document is in another script thread. + /// We do not try to keep the pipeline id for documents in other threads, + /// as this would require the constellation notifying many script threads about + /// the change, which could be expensive. + currently_active: Cell>, + + /// Has the browsing context been discarded? + discarded: Cell, + + /// The containing iframe element, if this is a same-origin iframe + frame_element: Option>, + + /// The parent browsing context's window proxy, if this is a nested browsing context + parent: Option>, +} + +impl WindowProxy { + pub fn new_inherited(frame_id: FrameId, + currently_active: Option, + frame_element: Option<&Element>, + parent: Option<&WindowProxy>) + -> WindowProxy + { + WindowProxy { + reflector: Reflector::new(), + frame_id: frame_id, + currently_active: Cell::new(currently_active), + discarded: Cell::new(false), + frame_element: frame_element.map(JS::from_ref), + parent: parent.map(JS::from_ref), + } + } + + #[allow(unsafe_code)] + pub fn new(window: &Window, + frame_id: FrameId, + frame_element: Option<&Element>, + parent: Option<&WindowProxy>) + -> Root + { + unsafe { + let WindowProxyHandler(handler) = window.windowproxy_handler(); + assert!(!handler.is_null()); + + let cx = window.get_cx(); + let window_jsobject = window.reflector().get_jsobject(); + assert!(!window_jsobject.get().is_null()); + assert!(((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL) != 0); + let _ac = JSAutoCompartment::new(cx, window_jsobject.get()); + + // Create a new window proxy. + rooted!(in(cx) let js_proxy = NewWindowProxy(cx, window_jsobject, handler)); + assert!(!js_proxy.is_null()); + + // Create a new browsing context. + let current = Some(window.global().pipeline_id()); + let mut window_proxy = box WindowProxy::new_inherited(frame_id, current, frame_element, parent); + + // The window proxy owns the browsing context. + // When we finalize the window proxy, it drops the browsing context it owns. + SetProxyExtra(js_proxy.get(), 0, &PrivateValue((&*window_proxy).as_void_ptr())); + + // Notify the JS engine about the new window proxy binding. + SetWindowProxy(cx, window_jsobject, js_proxy.handle()); + + // Set the reflector. + debug!("Initializing reflector of {:p} to {:p}.", window_proxy, js_proxy.get()); + window_proxy.reflector.set_jsobject(js_proxy.get()); + Root::from_ref(&*Box::into_raw(window_proxy)) + } + } + + #[allow(unsafe_code)] + pub fn new_dissimilar_origin(global_to_clone_from: &GlobalScope, + frame_id: FrameId, + parent: Option<&WindowProxy>) + -> Root + { + unsafe { + let handler = CreateWrapperProxyHandler(&XORIGIN_PROXY_HANDLER); + assert!(!handler.is_null()); + + let cx = global_to_clone_from.get_cx(); + + // Create a new browsing context. + let mut window_proxy = box WindowProxy::new_inherited(frame_id, None, None, parent); + + // Create a new dissimilar-origin window. + let window = DissimilarOriginWindow::new(global_to_clone_from, &*window_proxy); + let window_jsobject = window.reflector().get_jsobject(); + assert!(!window_jsobject.get().is_null()); + assert!(((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL) != 0); + let _ac = JSAutoCompartment::new(cx, window_jsobject.get()); + + // Create a new window proxy. + rooted!(in(cx) let js_proxy = NewWindowProxy(cx, window_jsobject, handler)); + assert!(!js_proxy.is_null()); + + // The window proxy owns the browsing context. + // When we finalize the window proxy, it drops the browsing context it owns. + SetProxyExtra(js_proxy.get(), 0, &PrivateValue((&*window_proxy).as_void_ptr())); + + // Notify the JS engine about the new window proxy binding. + SetWindowProxy(cx, window_jsobject, js_proxy.handle()); + + // Set the reflector. + debug!("Initializing reflector of {:p} to {:p}.", window_proxy, js_proxy.get()); + window_proxy.reflector.set_jsobject(js_proxy.get()); + Root::from_ref(&*Box::into_raw(window_proxy)) + } + } + + pub fn discard_browsing_context(&self) { + self.discarded.set(true); + } + + pub fn is_browsing_context_discarded(&self) -> bool { + self.discarded.get() + } + + pub fn frame_id(&self) -> FrameId { + self.frame_id + } + + pub fn frame_element(&self) -> Option<&Element> { + self.frame_element.r() + } + + pub fn parent(&self) -> Option<&WindowProxy> { + self.parent.r() + } + + pub fn top(&self) -> &WindowProxy { + let mut result = self; + while let Some(parent) = result.parent() { + result = parent; + } + result + } + + #[allow(unsafe_code)] + /// Change the Window that this WindowProxy resolves to. + // TODO: support setting the window proxy to a dummy value, + // to handle the case when the active document is in another script thread. + fn set_window(&self, window: &GlobalScope, traps: &ProxyTraps) { + unsafe { + debug!("Setting window of {:p}.", self); + let handler = CreateWrapperProxyHandler(traps); + assert!(!handler.is_null()); + + let cx = window.get_cx(); + let window_jsobject = window.reflector().get_jsobject(); + let old_js_proxy = self.reflector.get_jsobject(); + assert!(!window_jsobject.get().is_null()); + assert!(((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL) != 0); + let _ac = JSAutoCompartment::new(cx, window_jsobject.get()); + + // The old window proxy no longer owns this browsing context. + SetProxyExtra(old_js_proxy.get(), 0, &PrivateValue(ptr::null_mut())); + + // Brain transpant the window proxy. + // We need to do this, because the Window and WindowProxy + // objects need to be in the same compartment. + // JS_TransplantObject does this by copying the contents + // of the old window proxy to the new window proxy, then + // making the old window proxy a cross-compartment wrapper + // pointing to the new window proxy. + rooted!(in(cx) let new_js_proxy = NewWindowProxy(cx, window_jsobject, handler)); + debug!("Transplanting proxy from {:p} to {:p}.", old_js_proxy.get(), new_js_proxy.get()); + 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()); + + // Transfer ownership of this browsing context from the old window proxy to the new one. + SetProxyExtra(new_js_proxy.get(), 0, &PrivateValue(self.as_void_ptr())); + + // Notify the JS engine about the new window proxy binding. + SetWindowProxy(cx, window_jsobject, new_js_proxy.handle()); + + // Update the reflector. + debug!("Setting reflector of {:p} to {:p}.", self, new_js_proxy.get()); + self.reflector.rootable().set(new_js_proxy.get()); + } + } + + pub fn set_currently_active(&self, window: &Window) { + let globalscope = window.upcast(); + self.set_window(&*globalscope, &PROXY_HANDLER); + self.currently_active.set(Some(globalscope.pipeline_id())); + } + + pub fn unset_currently_active(&self) { + let globalscope = self.global(); + let window = DissimilarOriginWindow::new(&*globalscope, self); + self.set_window(&*window.upcast(), &XORIGIN_PROXY_HANDLER); + self.currently_active.set(None); + } + + pub fn currently_active(&self) -> Option { + self.currently_active.get() + } +} + +#[allow(unsafe_code)] +unsafe fn GetSubframeWindow(cx: *mut JSContext, + proxy: HandleObject, + id: HandleId) + -> Option> { + let index = get_array_index_from_id(cx, id); + if let Some(index) = index { + rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object()); + let win = root_from_handleobject::(target.handle()).unwrap(); + let mut found = false; + return win.IndexedGetter(index, &mut found); + } + + None +} + +#[allow(unsafe_code)] +unsafe extern "C" fn getOwnPropertyDescriptor(cx: *mut JSContext, + proxy: HandleObject, + id: HandleId, + mut desc: MutableHandle) + -> bool { + let window = GetSubframeWindow(cx, proxy, id); + if let Some(window) = window { + rooted!(in(cx) let mut val = UndefinedValue()); + window.to_jsval(cx, val.handle_mut()); + desc.value = val.get(); + fill_property_descriptor(desc, proxy.get(), JSPROP_READONLY); + return true; + } + + rooted!(in(cx) let target = GetProxyPrivate(proxy.get()).to_object()); + if !JS_GetOwnPropertyDescriptorById(cx, target.handle(), id, desc) { + return false; + } + + assert!(desc.obj.is_null() || desc.obj == target.get()); + if desc.obj == target.get() { + // FIXME(#11868) Should assign to desc.obj, desc.get() is a copy. + desc.get().obj = proxy.get(); + } + + true +} + +#[allow(unsafe_code)] +unsafe extern "C" fn defineProperty(cx: *mut JSContext, + proxy: HandleObject, + id: HandleId, + desc: Handle, + res: *mut ObjectOpResult) + -> bool { + if get_array_index_from_id(cx, id).is_some() { + // Spec says to Reject whether this is a supported index or not, + // since we have no indexed setter or indexed creator. That means + // throwing in strict mode (FIXME: Bug 828137), doing nothing in + // non-strict mode. + (*res).code_ = JSErrNum::JSMSG_CANT_DEFINE_WINDOW_ELEMENT as ::libc::uintptr_t; + return true; + } + + rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object()); + JS_DefinePropertyById(cx, target.handle(), id, desc, res) +} + +#[allow(unsafe_code)] +unsafe extern "C" fn has(cx: *mut JSContext, + proxy: HandleObject, + id: HandleId, + bp: *mut bool) + -> bool { + let window = GetSubframeWindow(cx, proxy, id); + if window.is_some() { + *bp = true; + return true; + } + + rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object()); + let mut found = false; + if !JS_HasPropertyById(cx, target.handle(), id, &mut found) { + return false; + } + + *bp = found; + true +} + +#[allow(unsafe_code)] +unsafe extern "C" fn get(cx: *mut JSContext, + proxy: HandleObject, + receiver: HandleValue, + id: HandleId, + vp: MutableHandleValue) + -> bool { + let window = GetSubframeWindow(cx, proxy, id); + if let Some(window) = window { + window.to_jsval(cx, vp); + return true; + } + + rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object()); + JS_ForwardGetPropertyTo(cx, target.handle(), id, receiver, vp) +} + +#[allow(unsafe_code)] +unsafe extern "C" fn set(cx: *mut JSContext, + proxy: HandleObject, + id: HandleId, + v: HandleValue, + receiver: HandleValue, + res: *mut ObjectOpResult) + -> bool { + if get_array_index_from_id(cx, id).is_some() { + // Reject (which means throw if and only if strict) the set. + (*res).code_ = JSErrNum::JSMSG_READ_ONLY as ::libc::uintptr_t; + return true; + } + + rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object()); + JS_ForwardSetPropertyTo(cx, + target.handle(), + id, + v, + receiver, + res) +} + +#[allow(unsafe_code)] +unsafe extern "C" fn get_prototype_if_ordinary(_: *mut JSContext, + _: HandleObject, + is_ordinary: *mut bool, + _: MutableHandleObject) + -> bool { + // Window's [[GetPrototypeOf]] trap isn't the ordinary definition: + // + // https://html.spec.whatwg.org/multipage/#windowproxy-getprototypeof + // + // We nonetheless can implement it with a static [[Prototype]], because + // wrapper-class handlers (particularly, XOW in FilteringWrapper.cpp) supply + // all non-ordinary behavior. + // + // But from a spec point of view, it's the exact same object in both cases -- + // only the observer's changed. So this getPrototypeIfOrdinary trap on the + // non-wrapper object *must* report non-ordinary, even if static [[Prototype]] + // usually means ordinary. + *is_ordinary = false; + return true; +} + +static PROXY_HANDLER: ProxyTraps = ProxyTraps { + enter: None, + getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor), + defineProperty: Some(defineProperty), + ownPropertyKeys: None, + delete_: None, + enumerate: None, + getPrototypeIfOrdinary: Some(get_prototype_if_ordinary), + preventExtensions: None, + isExtensible: None, + has: Some(has), + get: Some(get), + set: Some(set), + call: None, + construct: None, + getPropertyDescriptor: Some(get_property_descriptor), + hasOwn: None, + getOwnEnumerablePropertyKeys: None, + nativeCall: None, + hasInstance: None, + objectClassIs: None, + className: None, + fun_toString: None, + boxedValue_unbox: None, + defaultValue: None, + trace: Some(trace), + finalize: Some(finalize), + objectMoved: None, + isCallable: None, + isConstructor: None, +}; + +#[allow(unsafe_code)] +pub fn new_window_proxy_handler() -> WindowProxyHandler { + unsafe { + WindowProxyHandler(CreateWrapperProxyHandler(&PROXY_HANDLER)) + } +} + +// The proxy traps for cross-origin windows. +// These traps often throw security errors, and only pass on calls to methods +// defined in the DissimilarOriginWindow IDL. + +#[allow(unsafe_code)] +unsafe fn throw_security_error(cx: *mut JSContext) -> bool { + if !JS_IsExceptionPending(cx) { + let global = GlobalScope::from_context(cx); + throw_dom_exception(cx, &*global, Error::Security); + } + false +} + +#[allow(unsafe_code)] +unsafe extern "C" fn has_xorigin(cx: *mut JSContext, + proxy: HandleObject, + id: HandleId, + bp: *mut bool) + -> bool +{ + rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object()); + let mut found = false; + JS_HasOwnPropertyById(cx, target.handle(), id, &mut found); + if found { + *bp = true; + true + } else { + throw_security_error(cx) + } +} + +#[allow(unsafe_code)] +unsafe extern "C" fn get_xorigin(cx: *mut JSContext, + proxy: HandleObject, + receiver: HandleValue, + id: HandleId, + vp: MutableHandleValue) + -> bool +{ + let mut found = false; + has_xorigin(cx, proxy, id, &mut found); + found && get(cx, proxy, receiver, id, vp) +} + +#[allow(unsafe_code)] +unsafe extern "C" fn set_xorigin(cx: *mut JSContext, + _: HandleObject, + _: HandleId, + _: HandleValue, + _: HandleValue, + _: *mut ObjectOpResult) + -> bool +{ + throw_security_error(cx) +} + +#[allow(unsafe_code)] +unsafe extern "C" fn delete_xorigin(cx: *mut JSContext, + _: HandleObject, + _: HandleId, + _: *mut ObjectOpResult) + -> bool +{ + throw_security_error(cx) +} + +#[allow(unsafe_code)] +unsafe extern "C" fn getOwnPropertyDescriptor_xorigin(cx: *mut JSContext, + proxy: HandleObject, + id: HandleId, + desc: MutableHandle) + -> bool +{ + let mut found = false; + has_xorigin(cx, proxy, id, &mut found); + found && getOwnPropertyDescriptor(cx, proxy, id, desc) +} + +#[allow(unsafe_code)] +unsafe extern "C" fn defineProperty_xorigin(cx: *mut JSContext, + _: HandleObject, + _: HandleId, + _: Handle, + _: *mut ObjectOpResult) + -> bool +{ + throw_security_error(cx) +} + +#[allow(unsafe_code)] +unsafe extern "C" fn preventExtensions_xorigin(cx: *mut JSContext, + _: HandleObject, + _: *mut ObjectOpResult) + -> bool +{ + throw_security_error(cx) +} + +static XORIGIN_PROXY_HANDLER: ProxyTraps = ProxyTraps { + enter: None, + getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor_xorigin), + defineProperty: Some(defineProperty_xorigin), + ownPropertyKeys: None, + delete_: Some(delete_xorigin), + enumerate: None, + getPrototypeIfOrdinary: None, + preventExtensions: Some(preventExtensions_xorigin), + isExtensible: None, + has: Some(has_xorigin), + get: Some(get_xorigin), + set: Some(set_xorigin), + call: None, + construct: None, + getPropertyDescriptor: Some(getOwnPropertyDescriptor_xorigin), + hasOwn: Some(has_xorigin), + getOwnEnumerablePropertyKeys: None, + nativeCall: None, + hasInstance: None, + objectClassIs: None, + className: None, + fun_toString: None, + boxedValue_unbox: None, + defaultValue: None, + trace: Some(trace), + finalize: Some(finalize), + objectMoved: None, + isCallable: None, + isConstructor: None, +}; + +// How WindowProxy objects are garbage collected. + +#[allow(unsafe_code)] +unsafe extern fn finalize(_fop: *mut JSFreeOp, obj: *mut JSObject) { + let this = GetProxyExtra(obj, 0).to_private() as *mut WindowProxy; + if this.is_null() { + // GC during obj creation or after transplanting. + return; + } + let jsobject = (*this).reflector.get_jsobject().get(); + debug!("WindowProxy finalize: {:p}, with reflector {:p} from {:p}.", this, jsobject, obj); + let _ = Box::from_raw(this); +} + +#[allow(unsafe_code)] +unsafe extern fn trace(trc: *mut JSTracer, obj: *mut JSObject) { + let this = GetProxyExtra(obj, 0).to_private() as *const WindowProxy; + if this.is_null() { + // GC during obj creation or after transplanting. + return; + } + (*this).trace(trc); +} -- cgit v1.2.3 From 607e011b050f22e10a69fc7d57d7e2dc473d979e Mon Sep 17 00:00:00 2001 From: Alan Jeffrey Date: Fri, 12 May 2017 16:15:15 -0500 Subject: Renamed constellation::Frame to constellation::BrowsingContext. --- components/script/dom/windowproxy.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 3290afa1f2c..e022e69a810 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -28,7 +28,7 @@ use js::jsapi::{MutableHandle, MutableHandleObject, MutableHandleValue}; use js::jsapi::{ObjectOpResult, PropertyDescriptor}; use js::jsval::{UndefinedValue, PrivateValue}; use js::rust::get_object_class; -use msg::constellation_msg::FrameId; +use msg::constellation_msg::BrowsingContextId; use msg::constellation_msg::PipelineId; use std::cell::Cell; use std::ptr; @@ -45,10 +45,10 @@ pub struct WindowProxy { /// changes Window. reflector: Reflector, - /// The frame id of the browsing context. - /// In the case that this is a nested browsing context, this is the frame id + /// The id of the browsing context. + /// In the case that this is a nested browsing context, this is the id /// of the container. - frame_id: FrameId, + browsing_context_id: BrowsingContextId, /// The pipeline id of the currently active document. /// May be None, when the currently active document is in another script thread. @@ -68,7 +68,7 @@ pub struct WindowProxy { } impl WindowProxy { - pub fn new_inherited(frame_id: FrameId, + pub fn new_inherited(browsing_context_id: BrowsingContextId, currently_active: Option, frame_element: Option<&Element>, parent: Option<&WindowProxy>) @@ -76,7 +76,7 @@ impl WindowProxy { { WindowProxy { reflector: Reflector::new(), - frame_id: frame_id, + browsing_context_id: browsing_context_id, currently_active: Cell::new(currently_active), discarded: Cell::new(false), frame_element: frame_element.map(JS::from_ref), @@ -86,7 +86,7 @@ impl WindowProxy { #[allow(unsafe_code)] pub fn new(window: &Window, - frame_id: FrameId, + browsing_context_id: BrowsingContextId, frame_element: Option<&Element>, parent: Option<&WindowProxy>) -> Root @@ -107,7 +107,7 @@ impl WindowProxy { // Create a new browsing context. let current = Some(window.global().pipeline_id()); - let mut window_proxy = box WindowProxy::new_inherited(frame_id, current, frame_element, parent); + let mut window_proxy = box WindowProxy::new_inherited(browsing_context_id, current, frame_element, parent); // The window proxy owns the browsing context. // When we finalize the window proxy, it drops the browsing context it owns. @@ -125,7 +125,7 @@ impl WindowProxy { #[allow(unsafe_code)] pub fn new_dissimilar_origin(global_to_clone_from: &GlobalScope, - frame_id: FrameId, + browsing_context_id: BrowsingContextId, parent: Option<&WindowProxy>) -> Root { @@ -136,7 +136,7 @@ impl WindowProxy { let cx = global_to_clone_from.get_cx(); // Create a new browsing context. - let mut window_proxy = box WindowProxy::new_inherited(frame_id, None, None, parent); + let mut window_proxy = box WindowProxy::new_inherited(browsing_context_id, None, None, parent); // Create a new dissimilar-origin window. let window = DissimilarOriginWindow::new(global_to_clone_from, &*window_proxy); @@ -171,8 +171,8 @@ impl WindowProxy { self.discarded.get() } - pub fn frame_id(&self) -> FrameId { - self.frame_id + pub fn browsing_context_id(&self) -> BrowsingContextId { + self.browsing_context_id } pub fn frame_element(&self) -> Option<&Element> { -- cgit v1.2.3 From 42577365b7924d0af64033d852447ff61579da3a Mon Sep 17 00:00:00 2001 From: Alan Jeffrey Date: Mon, 15 May 2017 16:09:49 -0500 Subject: Added a TopLevelBrowsingContextId type. --- components/script/dom/windowproxy.rs | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index e022e69a810..2578bb3b46c 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -30,6 +30,7 @@ use js::jsval::{UndefinedValue, PrivateValue}; use js::rust::get_object_class; use msg::constellation_msg::BrowsingContextId; use msg::constellation_msg::PipelineId; +use msg::constellation_msg::TopLevelBrowsingContextId; use std::cell::Cell; use std::ptr; @@ -50,6 +51,10 @@ pub struct WindowProxy { /// of the container. browsing_context_id: BrowsingContextId, + /// The frame id of the top-level ancestor browsing context. + /// In the case that this is a top-level window, this is our id. + top_level_browsing_context_id: TopLevelBrowsingContextId, + /// The pipeline id of the currently active document. /// May be None, when the currently active document is in another script thread. /// We do not try to keep the pipeline id for documents in other threads, @@ -69,6 +74,7 @@ pub struct WindowProxy { impl WindowProxy { pub fn new_inherited(browsing_context_id: BrowsingContextId, + top_level_browsing_context_id: TopLevelBrowsingContextId, currently_active: Option, frame_element: Option<&Element>, parent: Option<&WindowProxy>) @@ -77,6 +83,7 @@ impl WindowProxy { WindowProxy { reflector: Reflector::new(), browsing_context_id: browsing_context_id, + top_level_browsing_context_id: top_level_browsing_context_id, currently_active: Cell::new(currently_active), discarded: Cell::new(false), frame_element: frame_element.map(JS::from_ref), @@ -87,6 +94,7 @@ impl WindowProxy { #[allow(unsafe_code)] pub fn new(window: &Window, browsing_context_id: BrowsingContextId, + top_level_browsing_context_id: TopLevelBrowsingContextId, frame_element: Option<&Element>, parent: Option<&WindowProxy>) -> Root @@ -107,7 +115,11 @@ impl WindowProxy { // Create a new browsing context. let current = Some(window.global().pipeline_id()); - let mut window_proxy = box WindowProxy::new_inherited(browsing_context_id, current, frame_element, parent); + let mut window_proxy = box WindowProxy::new_inherited(browsing_context_id, + top_level_browsing_context_id, + current, + frame_element, + parent); // The window proxy owns the browsing context. // When we finalize the window proxy, it drops the browsing context it owns. @@ -126,6 +138,7 @@ impl WindowProxy { #[allow(unsafe_code)] pub fn new_dissimilar_origin(global_to_clone_from: &GlobalScope, browsing_context_id: BrowsingContextId, + top_level_browsing_context_id: TopLevelBrowsingContextId, parent: Option<&WindowProxy>) -> Root { @@ -136,7 +149,11 @@ impl WindowProxy { let cx = global_to_clone_from.get_cx(); // Create a new browsing context. - let mut window_proxy = box WindowProxy::new_inherited(browsing_context_id, None, None, parent); + let mut window_proxy = box WindowProxy::new_inherited(browsing_context_id, + top_level_browsing_context_id, + None, + None, + parent); // Create a new dissimilar-origin window. let window = DissimilarOriginWindow::new(global_to_clone_from, &*window_proxy); @@ -175,6 +192,10 @@ impl WindowProxy { self.browsing_context_id } + pub fn top_level_browsing_context_id(&self) -> TopLevelBrowsingContextId { + self.top_level_browsing_context_id + } + pub fn frame_element(&self) -> Option<&Element> { self.frame_element.r() } -- cgit v1.2.3 From 0e3c54c1911ba2c3bf305ee04f04fcd9bf2fc2fe Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Mon, 25 Sep 2017 23:30:24 +0200 Subject: Rename dom::bindings::js to dom::bindings::root --- components/script/dom/windowproxy.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 2578bb3b46c..e76435818d9 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -5,9 +5,9 @@ use dom::bindings::conversions::{ToJSValConvertible, root_from_handleobject}; use dom::bindings::error::{Error, throw_dom_exception}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, Root, RootedReference}; use dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor}; use dom::bindings::reflector::{DomObject, Reflector}; +use dom::bindings::root::{JS, Root, RootedReference}; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::{WindowProxyHandler, get_array_index_from_id, AsVoidPtr}; use dom::dissimilaroriginwindow::DissimilarOriginWindow; -- cgit v1.2.3 From 7be32fb2371a14ba61b008a37e79761f66c073c7 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Mon, 25 Sep 2017 23:56:32 +0200 Subject: Rename JS to Dom --- components/script/dom/windowproxy.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index e76435818d9..3c8a340d0f7 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -7,7 +7,7 @@ use dom::bindings::error::{Error, throw_dom_exception}; use dom::bindings::inheritance::Castable; use dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor}; use dom::bindings::reflector::{DomObject, Reflector}; -use dom::bindings::root::{JS, Root, RootedReference}; +use dom::bindings::root::{Dom, Root, RootedReference}; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::{WindowProxyHandler, get_array_index_from_id, AsVoidPtr}; use dom::dissimilaroriginwindow::DissimilarOriginWindow; @@ -66,10 +66,10 @@ pub struct WindowProxy { discarded: Cell, /// The containing iframe element, if this is a same-origin iframe - frame_element: Option>, + frame_element: Option>, /// The parent browsing context's window proxy, if this is a nested browsing context - parent: Option>, + parent: Option>, } impl WindowProxy { @@ -86,8 +86,8 @@ impl WindowProxy { top_level_browsing_context_id: top_level_browsing_context_id, currently_active: Cell::new(currently_active), discarded: Cell::new(false), - frame_element: frame_element.map(JS::from_ref), - parent: parent.map(JS::from_ref), + frame_element: frame_element.map(Dom::from_ref), + parent: parent.map(Dom::from_ref), } } -- cgit v1.2.3 From f87c2a8d7616112ca924e30292db2d244cf87eec Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Tue, 26 Sep 2017 01:53:40 +0200 Subject: Rename Root to DomRoot In a later PR, DomRoot will become a type alias of Root>, where Root will be able to handle all the things that need to be rooted that have a stable traceable address that doesn't move for the whole lifetime of the root. Stay tuned. --- components/script/dom/windowproxy.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 3c8a340d0f7..3d5faba1ad3 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -7,7 +7,7 @@ use dom::bindings::error::{Error, throw_dom_exception}; use dom::bindings::inheritance::Castable; use dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor}; use dom::bindings::reflector::{DomObject, Reflector}; -use dom::bindings::root::{Dom, Root, RootedReference}; +use dom::bindings::root::{Dom, DomRoot, RootedReference}; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::{WindowProxyHandler, get_array_index_from_id, AsVoidPtr}; use dom::dissimilaroriginwindow::DissimilarOriginWindow; @@ -97,7 +97,7 @@ impl WindowProxy { top_level_browsing_context_id: TopLevelBrowsingContextId, frame_element: Option<&Element>, parent: Option<&WindowProxy>) - -> Root + -> DomRoot { unsafe { let WindowProxyHandler(handler) = window.windowproxy_handler(); @@ -131,7 +131,7 @@ impl WindowProxy { // Set the reflector. debug!("Initializing reflector of {:p} to {:p}.", window_proxy, js_proxy.get()); window_proxy.reflector.set_jsobject(js_proxy.get()); - Root::from_ref(&*Box::into_raw(window_proxy)) + DomRoot::from_ref(&*Box::into_raw(window_proxy)) } } @@ -140,7 +140,7 @@ impl WindowProxy { browsing_context_id: BrowsingContextId, top_level_browsing_context_id: TopLevelBrowsingContextId, parent: Option<&WindowProxy>) - -> Root + -> DomRoot { unsafe { let handler = CreateWrapperProxyHandler(&XORIGIN_PROXY_HANDLER); @@ -176,7 +176,7 @@ impl WindowProxy { // Set the reflector. debug!("Initializing reflector of {:p} to {:p}.", window_proxy, js_proxy.get()); window_proxy.reflector.set_jsobject(js_proxy.get()); - Root::from_ref(&*Box::into_raw(window_proxy)) + DomRoot::from_ref(&*Box::into_raw(window_proxy)) } } @@ -278,7 +278,7 @@ impl WindowProxy { unsafe fn GetSubframeWindow(cx: *mut JSContext, proxy: HandleObject, id: HandleId) - -> Option> { + -> Option> { let index = get_array_index_from_id(cx, id); if let Some(index) = index { rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object()); -- cgit v1.2.3 From aa15dc269f41503d81ad44cd7e85d69e6f4aeac7 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 16 Oct 2017 14:35:30 +0200 Subject: Remove use of unstable box syntax. http://www.robohornet.org gives a score of 101.36 on master, and 102.68 with this PR. The latter is slightly better, but probably within noise level. So it looks like this PR does not affect DOM performance. This is expected since `Box::new` is defined as: ```rust impl Box { #[inline(always)] pub fn new(x: T) -> Box { box x } } ``` With inlining, it should compile to the same as box syntax. --- components/script/dom/windowproxy.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 3d5faba1ad3..663b6fd7030 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -115,11 +115,13 @@ impl WindowProxy { // Create a new browsing context. let current = Some(window.global().pipeline_id()); - let mut window_proxy = box WindowProxy::new_inherited(browsing_context_id, - top_level_browsing_context_id, - current, - frame_element, - parent); + let mut window_proxy = Box::new(WindowProxy::new_inherited( + browsing_context_id, + top_level_browsing_context_id, + current, + frame_element, + parent + )); // The window proxy owns the browsing context. // When we finalize the window proxy, it drops the browsing context it owns. @@ -149,11 +151,13 @@ impl WindowProxy { let cx = global_to_clone_from.get_cx(); // Create a new browsing context. - let mut window_proxy = box WindowProxy::new_inherited(browsing_context_id, - top_level_browsing_context_id, - None, - None, - parent); + let mut window_proxy = Box::new(WindowProxy::new_inherited( + browsing_context_id, + top_level_browsing_context_id, + None, + None, + parent + )); // Create a new dissimilar-origin window. let window = DissimilarOriginWindow::new(global_to_clone_from, &*window_proxy); -- cgit v1.2.3 From 2a1723062373418f2dd8b9805d7750f6f286d1c7 Mon Sep 17 00:00:00 2001 From: CYBAI Date: Fri, 26 Jan 2018 02:23:39 +0800 Subject: Use specific negative assertion for DOM Window Proxy --- components/script/dom/windowproxy.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 663b6fd7030..1ab615c9824 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -106,7 +106,7 @@ impl WindowProxy { let cx = window.get_cx(); let window_jsobject = window.reflector().get_jsobject(); assert!(!window_jsobject.get().is_null()); - assert!(((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL) != 0); + assert_ne!(((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL), 0); let _ac = JSAutoCompartment::new(cx, window_jsobject.get()); // Create a new window proxy. @@ -163,7 +163,7 @@ impl WindowProxy { let window = DissimilarOriginWindow::new(global_to_clone_from, &*window_proxy); let window_jsobject = window.reflector().get_jsobject(); assert!(!window_jsobject.get().is_null()); - assert!(((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL) != 0); + assert_ne!(((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL), 0); let _ac = JSAutoCompartment::new(cx, window_jsobject.get()); // Create a new window proxy. @@ -230,7 +230,7 @@ impl WindowProxy { let window_jsobject = window.reflector().get_jsobject(); let old_js_proxy = self.reflector.get_jsobject(); assert!(!window_jsobject.get().is_null()); - assert!(((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL) != 0); + assert_ne!(((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL), 0); let _ac = JSAutoCompartment::new(cx, window_jsobject.get()); // The old window proxy no longer owns this browsing context. -- cgit v1.2.3 From b9f7aa468610b7091eb7e3cdc34a085f7931302d Mon Sep 17 00:00:00 2001 From: paavininanda Date: Tue, 13 Feb 2018 14:51:20 +0530 Subject: Adding Name and SetName functions for window --- components/script/dom/windowproxy.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 1ab615c9824..55f13618361 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -2,12 +2,14 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use dom::bindings::cell::DomRefCell; use dom::bindings::conversions::{ToJSValConvertible, root_from_handleobject}; use dom::bindings::error::{Error, throw_dom_exception}; use dom::bindings::inheritance::Castable; use dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor}; use dom::bindings::reflector::{DomObject, Reflector}; use dom::bindings::root::{Dom, DomRoot, RootedReference}; +use dom::bindings::str::DOMString; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::{WindowProxyHandler, get_array_index_from_id, AsVoidPtr}; use dom::dissimilaroriginwindow::DissimilarOriginWindow; @@ -55,6 +57,8 @@ pub struct WindowProxy { /// In the case that this is a top-level window, this is our id. top_level_browsing_context_id: TopLevelBrowsingContextId, + /// The name of the browsing context + name: DomRefCell, /// The pipeline id of the currently active document. /// May be None, when the currently active document is in another script thread. /// We do not try to keep the pipeline id for documents in other threads, @@ -80,10 +84,12 @@ impl WindowProxy { parent: Option<&WindowProxy>) -> WindowProxy { + let name = frame_element.map_or(DOMString::new(), |e| e.get_string_attribute(&local_name!("name"))); WindowProxy { reflector: Reflector::new(), browsing_context_id: browsing_context_id, top_level_browsing_context_id: top_level_browsing_context_id, + name: DomRefCell::new(name), currently_active: Cell::new(currently_active), discarded: Cell::new(false), frame_element: frame_element.map(Dom::from_ref), @@ -276,6 +282,14 @@ impl WindowProxy { pub fn currently_active(&self) -> Option { self.currently_active.get() } + + pub fn get_name(&self) -> DOMString { + self.name.borrow().clone() + } + + pub fn set_name(&self, name: DOMString) { + *self.name.borrow_mut() = name; + } } #[allow(unsafe_code)] -- cgit v1.2.3 From 356c57e628255ed338b32246ce5e7de75da621f0 Mon Sep 17 00:00:00 2001 From: Marcin Mielniczuk Date: Wed, 28 Mar 2018 21:28:30 +0200 Subject: Adapt Servo for mozjs 0.6 and the changes introduced in servo/rust-mozjs#393 --- components/script/dom/windowproxy.rs | 121 +++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 56 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 55f13618361..e1df10646d6 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -18,18 +18,25 @@ use dom::globalscope::GlobalScope; use dom::window::Window; use dom_struct::dom_struct; use js::JSCLASS_IS_GLOBAL; -use js::glue::{CreateWrapperProxyHandler, ProxyTraps, NewWindowProxy}; +use js::glue::{CreateWrapperProxyHandler, ProxyTraps}; use js::glue::{GetProxyPrivate, SetProxyExtra, GetProxyExtra}; -use js::jsapi::{Handle, HandleId, HandleObject, HandleValue}; use js::jsapi::{JSAutoCompartment, JSContext, JSErrNum, JSFreeOp, JSObject}; use js::jsapi::{JSPROP_READONLY, JSTracer, JS_DefinePropertyById}; use js::jsapi::{JS_ForwardGetPropertyTo, JS_ForwardSetPropertyTo}; -use js::jsapi::{JS_GetOwnPropertyDescriptorById, JS_HasPropertyById, JS_HasOwnPropertyById}; -use js::jsapi::{JS_IsExceptionPending, JS_TransplantObject, SetWindowProxy}; -use js::jsapi::{MutableHandle, MutableHandleObject, MutableHandleValue}; +use js::jsapi::{JS_HasPropertyById, JS_HasOwnPropertyById}; +use js::jsapi::{JS_IsExceptionPending, JS_GetOwnPropertyDescriptorById}; use js::jsapi::{ObjectOpResult, PropertyDescriptor}; +use js::jsapi::Handle as RawHandle; +use js::jsapi::HandleId as RawHandleId; +use js::jsapi::HandleObject as RawHandleObject; +use js::jsapi::HandleValue as RawHandleValue; +use js::jsapi::MutableHandle as RawMutableHandle; +use js::jsapi::MutableHandleObject as RawMutableHandleObject; +use js::jsapi::MutableHandleValue as RawMutableHandleValue; use js::jsval::{UndefinedValue, PrivateValue}; +use js::rust::{Handle, MutableHandle}; use js::rust::get_object_class; +use js::rust::wrappers::{NewWindowProxy, SetWindowProxy, JS_TransplantObject}; use msg::constellation_msg::BrowsingContextId; use msg::constellation_msg::PipelineId; use msg::constellation_msg::TopLevelBrowsingContextId; @@ -292,14 +299,16 @@ impl WindowProxy { } } +// This is only called from extern functions, +// there's no use using the lifetimed handles here. #[allow(unsafe_code)] unsafe fn GetSubframeWindow(cx: *mut JSContext, - proxy: HandleObject, - id: HandleId) + proxy: RawHandleObject, + id: RawHandleId) -> Option> { - let index = get_array_index_from_id(cx, id); + let index = get_array_index_from_id(cx, Handle::from_raw(id)); if let Some(index) = index { - rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object()); + rooted!(in(cx) let target = GetProxyPrivate(*proxy).to_object()); let win = root_from_handleobject::(target.handle()).unwrap(); let mut found = false; return win.IndexedGetter(index, &mut found); @@ -310,21 +319,21 @@ unsafe fn GetSubframeWindow(cx: *mut JSContext, #[allow(unsafe_code)] unsafe extern "C" fn getOwnPropertyDescriptor(cx: *mut JSContext, - proxy: HandleObject, - id: HandleId, - mut desc: MutableHandle) + proxy: RawHandleObject, + id: RawHandleId, + mut desc: RawMutableHandle) -> bool { let window = GetSubframeWindow(cx, proxy, id); if let Some(window) = window { rooted!(in(cx) let mut val = UndefinedValue()); window.to_jsval(cx, val.handle_mut()); desc.value = val.get(); - fill_property_descriptor(desc, proxy.get(), JSPROP_READONLY); + fill_property_descriptor(MutableHandle::from_raw(desc), proxy.get(), JSPROP_READONLY); return true; } rooted!(in(cx) let target = GetProxyPrivate(proxy.get()).to_object()); - if !JS_GetOwnPropertyDescriptorById(cx, target.handle(), id, desc) { + if !JS_GetOwnPropertyDescriptorById(cx, target.handle().into(), id, desc) { return false; } @@ -339,12 +348,12 @@ unsafe extern "C" fn getOwnPropertyDescriptor(cx: *mut JSContext, #[allow(unsafe_code)] unsafe extern "C" fn defineProperty(cx: *mut JSContext, - proxy: HandleObject, - id: HandleId, - desc: Handle, + proxy: RawHandleObject, + id: RawHandleId, + desc: RawHandle, res: *mut ObjectOpResult) -> bool { - if get_array_index_from_id(cx, id).is_some() { + if get_array_index_from_id(cx, Handle::from_raw(id)).is_some() { // Spec says to Reject whether this is a supported index or not, // since we have no indexed setter or indexed creator. That means // throwing in strict mode (FIXME: Bug 828137), doing nothing in @@ -354,13 +363,13 @@ unsafe extern "C" fn defineProperty(cx: *mut JSContext, } rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object()); - JS_DefinePropertyById(cx, target.handle(), id, desc, res) + JS_DefinePropertyById(cx, target.handle().into(), id, desc, res) } #[allow(unsafe_code)] unsafe extern "C" fn has(cx: *mut JSContext, - proxy: HandleObject, - id: HandleId, + proxy: RawHandleObject, + id: RawHandleId, bp: *mut bool) -> bool { let window = GetSubframeWindow(cx, proxy, id); @@ -371,7 +380,7 @@ unsafe extern "C" fn has(cx: *mut JSContext, rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object()); let mut found = false; - if !JS_HasPropertyById(cx, target.handle(), id, &mut found) { + if !JS_HasPropertyById(cx, target.handle().into(), id, &mut found) { return false; } @@ -381,30 +390,30 @@ unsafe extern "C" fn has(cx: *mut JSContext, #[allow(unsafe_code)] unsafe extern "C" fn get(cx: *mut JSContext, - proxy: HandleObject, - receiver: HandleValue, - id: HandleId, - vp: MutableHandleValue) + proxy: RawHandleObject, + receiver: RawHandleValue, + id: RawHandleId, + vp: RawMutableHandleValue) -> bool { let window = GetSubframeWindow(cx, proxy, id); if let Some(window) = window { - window.to_jsval(cx, vp); + window.to_jsval(cx, MutableHandle::from_raw(vp)); return true; } rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object()); - JS_ForwardGetPropertyTo(cx, target.handle(), id, receiver, vp) + JS_ForwardGetPropertyTo(cx, target.handle().into(), id, receiver, vp) } #[allow(unsafe_code)] unsafe extern "C" fn set(cx: *mut JSContext, - proxy: HandleObject, - id: HandleId, - v: HandleValue, - receiver: HandleValue, + proxy: RawHandleObject, + id: RawHandleId, + v: RawHandleValue, + receiver: RawHandleValue, res: *mut ObjectOpResult) -> bool { - if get_array_index_from_id(cx, id).is_some() { + if get_array_index_from_id(cx, Handle::from_raw(id)).is_some() { // Reject (which means throw if and only if strict) the set. (*res).code_ = JSErrNum::JSMSG_READ_ONLY as ::libc::uintptr_t; return true; @@ -412,7 +421,7 @@ unsafe extern "C" fn set(cx: *mut JSContext, rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object()); JS_ForwardSetPropertyTo(cx, - target.handle(), + target.handle().into(), id, v, receiver, @@ -421,9 +430,9 @@ unsafe extern "C" fn set(cx: *mut JSContext, #[allow(unsafe_code)] unsafe extern "C" fn get_prototype_if_ordinary(_: *mut JSContext, - _: HandleObject, + _: RawHandleObject, is_ordinary: *mut bool, - _: MutableHandleObject) + _: RawMutableHandleObject) -> bool { // Window's [[GetPrototypeOf]] trap isn't the ordinary definition: // @@ -495,14 +504,14 @@ unsafe fn throw_security_error(cx: *mut JSContext) -> bool { #[allow(unsafe_code)] unsafe extern "C" fn has_xorigin(cx: *mut JSContext, - proxy: HandleObject, - id: HandleId, + proxy: RawHandleObject, + id: RawHandleId, bp: *mut bool) -> bool { rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object()); let mut found = false; - JS_HasOwnPropertyById(cx, target.handle(), id, &mut found); + JS_HasOwnPropertyById(cx, target.handle().into(), id, &mut found); if found { *bp = true; true @@ -513,10 +522,10 @@ unsafe extern "C" fn has_xorigin(cx: *mut JSContext, #[allow(unsafe_code)] unsafe extern "C" fn get_xorigin(cx: *mut JSContext, - proxy: HandleObject, - receiver: HandleValue, - id: HandleId, - vp: MutableHandleValue) + proxy: RawHandleObject, + receiver: RawHandleValue, + id: RawHandleId, + vp: RawMutableHandleValue) -> bool { let mut found = false; @@ -526,10 +535,10 @@ unsafe extern "C" fn get_xorigin(cx: *mut JSContext, #[allow(unsafe_code)] unsafe extern "C" fn set_xorigin(cx: *mut JSContext, - _: HandleObject, - _: HandleId, - _: HandleValue, - _: HandleValue, + _: RawHandleObject, + _: RawHandleId, + _: RawHandleValue, + _: RawHandleValue, _: *mut ObjectOpResult) -> bool { @@ -538,8 +547,8 @@ unsafe extern "C" fn set_xorigin(cx: *mut JSContext, #[allow(unsafe_code)] unsafe extern "C" fn delete_xorigin(cx: *mut JSContext, - _: HandleObject, - _: HandleId, + _: RawHandleObject, + _: RawHandleId, _: *mut ObjectOpResult) -> bool { @@ -548,9 +557,9 @@ unsafe extern "C" fn delete_xorigin(cx: *mut JSContext, #[allow(unsafe_code)] unsafe extern "C" fn getOwnPropertyDescriptor_xorigin(cx: *mut JSContext, - proxy: HandleObject, - id: HandleId, - desc: MutableHandle) + proxy: RawHandleObject, + id: RawHandleId, + desc: RawMutableHandle) -> bool { let mut found = false; @@ -560,9 +569,9 @@ unsafe extern "C" fn getOwnPropertyDescriptor_xorigin(cx: *mut JSContext, #[allow(unsafe_code)] unsafe extern "C" fn defineProperty_xorigin(cx: *mut JSContext, - _: HandleObject, - _: HandleId, - _: Handle, + _: RawHandleObject, + _: RawHandleId, + _: RawHandle, _: *mut ObjectOpResult) -> bool { @@ -571,7 +580,7 @@ unsafe extern "C" fn defineProperty_xorigin(cx: *mut JSContext, #[allow(unsafe_code)] unsafe extern "C" fn preventExtensions_xorigin(cx: *mut JSContext, - _: HandleObject, + _: RawHandleObject, _: *mut ObjectOpResult) -> bool { -- cgit v1.2.3 From 080600003ce1704164a816e7fbf6b1c05f46376e Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Tue, 10 Apr 2018 11:52:48 -0700 Subject: Return window proxy properly for indexed window getter --- components/script/dom/windowproxy.rs | 49 ++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 10 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index e1df10646d6..e93c51acc01 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -17,6 +17,7 @@ use dom::element::Element; use dom::globalscope::GlobalScope; use dom::window::Window; use dom_struct::dom_struct; +use ipc_channel::ipc; use js::JSCLASS_IS_GLOBAL; use js::glue::{CreateWrapperProxyHandler, ProxyTraps}; use js::glue::{GetProxyPrivate, SetProxyExtra, GetProxyExtra}; @@ -40,6 +41,8 @@ use js::rust::wrappers::{NewWindowProxy, SetWindowProxy, JS_TransplantObject}; use msg::constellation_msg::BrowsingContextId; use msg::constellation_msg::PipelineId; use msg::constellation_msg::TopLevelBrowsingContextId; +use script_thread::ScriptThread; +use script_traits::ScriptMsg; use std::cell::Cell; use std::ptr; @@ -301,17 +304,43 @@ impl WindowProxy { // This is only called from extern functions, // there's no use using the lifetimed handles here. +// https://html.spec.whatwg.org/multipage/#accessing-other-browsing-contexts #[allow(unsafe_code)] -unsafe fn GetSubframeWindow(cx: *mut JSContext, - proxy: RawHandleObject, - id: RawHandleId) - -> Option> { +unsafe fn GetSubframeWindowProxy( + cx: *mut JSContext, + proxy: RawHandleObject, + id: RawHandleId +) -> Option> { let index = get_array_index_from_id(cx, Handle::from_raw(id)); if let Some(index) = index { rooted!(in(cx) let target = GetProxyPrivate(*proxy).to_object()); - let win = root_from_handleobject::(target.handle()).unwrap(); - let mut found = false; - return win.IndexedGetter(index, &mut found); + if let Ok(win) = root_from_handleobject::(target.handle()) { + let browsing_context_id = win.window_proxy().browsing_context_id(); + let (result_sender, result_receiver) = ipc::channel().unwrap(); + + let _ = win.upcast::().script_to_constellation_chan().send( + ScriptMsg::GetChildBrowsingContextId( + browsing_context_id, + index as usize, + result_sender + ) + ); + return result_receiver.recv().ok() + .and_then(|maybe_bcid| maybe_bcid) + .and_then(ScriptThread::find_window_proxy); + } else if let Ok(win) = root_from_handleobject::(target.handle()) { + let browsing_context_id = win.window_proxy().browsing_context_id(); + let (result_sender, result_receiver) = ipc::channel().unwrap(); + + let _ = win.global().script_to_constellation_chan().send(ScriptMsg::GetChildBrowsingContextId( + browsing_context_id, + index as usize, + result_sender + )); + return result_receiver.recv().ok() + .and_then(|maybe_bcid| maybe_bcid) + .and_then(ScriptThread::find_window_proxy); + } } None @@ -323,7 +352,7 @@ unsafe extern "C" fn getOwnPropertyDescriptor(cx: *mut JSContext, id: RawHandleId, mut desc: RawMutableHandle) -> bool { - let window = GetSubframeWindow(cx, proxy, id); + let window = GetSubframeWindowProxy(cx, proxy, id); if let Some(window) = window { rooted!(in(cx) let mut val = UndefinedValue()); window.to_jsval(cx, val.handle_mut()); @@ -372,7 +401,7 @@ unsafe extern "C" fn has(cx: *mut JSContext, id: RawHandleId, bp: *mut bool) -> bool { - let window = GetSubframeWindow(cx, proxy, id); + let window = GetSubframeWindowProxy(cx, proxy, id); if window.is_some() { *bp = true; return true; @@ -395,7 +424,7 @@ unsafe extern "C" fn get(cx: *mut JSContext, id: RawHandleId, vp: RawMutableHandleValue) -> bool { - let window = GetSubframeWindow(cx, proxy, id); + let window = GetSubframeWindowProxy(cx, proxy, id); if let Some(window) = window { window.to_jsval(cx, MutableHandle::from_raw(vp)); return true; -- cgit v1.2.3 From 249e8a575f258cbc57ab9655b7cbaf2eca21e3ad Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Sun, 29 Apr 2018 00:32:15 -0700 Subject: Set the proper attributes for the WindowProxy property descriptor --- components/script/dom/windowproxy.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index e93c51acc01..bfd75f879dc 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -22,7 +22,7 @@ use js::JSCLASS_IS_GLOBAL; use js::glue::{CreateWrapperProxyHandler, ProxyTraps}; use js::glue::{GetProxyPrivate, SetProxyExtra, GetProxyExtra}; use js::jsapi::{JSAutoCompartment, JSContext, JSErrNum, JSFreeOp, JSObject}; -use js::jsapi::{JSPROP_READONLY, JSTracer, JS_DefinePropertyById}; +use js::jsapi::{JSPROP_ENUMERATE, JSPROP_READONLY, JSTracer, JS_DefinePropertyById}; use js::jsapi::{JS_ForwardGetPropertyTo, JS_ForwardSetPropertyTo}; use js::jsapi::{JS_HasPropertyById, JS_HasOwnPropertyById}; use js::jsapi::{JS_IsExceptionPending, JS_GetOwnPropertyDescriptorById}; @@ -310,7 +310,7 @@ unsafe fn GetSubframeWindowProxy( cx: *mut JSContext, proxy: RawHandleObject, id: RawHandleId -) -> Option> { +) -> Option<(DomRoot, u32)> { let index = get_array_index_from_id(cx, Handle::from_raw(id)); if let Some(index) = index { rooted!(in(cx) let target = GetProxyPrivate(*proxy).to_object()); @@ -327,7 +327,8 @@ unsafe fn GetSubframeWindowProxy( ); return result_receiver.recv().ok() .and_then(|maybe_bcid| maybe_bcid) - .and_then(ScriptThread::find_window_proxy); + .and_then(ScriptThread::find_window_proxy) + .map(|proxy| (proxy, JSPROP_ENUMERATE | JSPROP_READONLY)); } else if let Ok(win) = root_from_handleobject::(target.handle()) { let browsing_context_id = win.window_proxy().browsing_context_id(); let (result_sender, result_receiver) = ipc::channel().unwrap(); @@ -339,7 +340,8 @@ unsafe fn GetSubframeWindowProxy( )); return result_receiver.recv().ok() .and_then(|maybe_bcid| maybe_bcid) - .and_then(ScriptThread::find_window_proxy); + .and_then(ScriptThread::find_window_proxy) + .map(|proxy| (proxy, JSPROP_READONLY)); } } @@ -353,11 +355,11 @@ unsafe extern "C" fn getOwnPropertyDescriptor(cx: *mut JSContext, mut desc: RawMutableHandle) -> bool { let window = GetSubframeWindowProxy(cx, proxy, id); - if let Some(window) = window { + if let Some((window, attrs)) = window { rooted!(in(cx) let mut val = UndefinedValue()); window.to_jsval(cx, val.handle_mut()); desc.value = val.get(); - fill_property_descriptor(MutableHandle::from_raw(desc), proxy.get(), JSPROP_READONLY); + fill_property_descriptor(MutableHandle::from_raw(desc), proxy.get(), attrs); return true; } @@ -425,7 +427,7 @@ unsafe extern "C" fn get(cx: *mut JSContext, vp: RawMutableHandleValue) -> bool { let window = GetSubframeWindowProxy(cx, proxy, id); - if let Some(window) = window { + if let Some((window, _attrs)) = window { window.to_jsval(cx, MutableHandle::from_raw(vp)); return true; } -- cgit v1.2.3 From f408b798c4666eddeb8b52d8965d7d4a6942e066 Mon Sep 17 00:00:00 2001 From: Gregory Terzian Date: Sun, 22 Apr 2018 12:58:30 +0800 Subject: implement window.open, create auxiliary browsing context --- components/script/dom/windowproxy.rs | 143 ++++++++++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 1 deletion(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index bfd75f879dc..10c925cb28d 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -13,10 +13,12 @@ use dom::bindings::str::DOMString; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::{WindowProxyHandler, get_array_index_from_id, AsVoidPtr}; use dom::dissimilaroriginwindow::DissimilarOriginWindow; +use dom::document::Document; use dom::element::Element; use dom::globalscope::GlobalScope; use dom::window::Window; use dom_struct::dom_struct; +use embedder_traits::EmbedderMsg; use ipc_channel::ipc; use js::JSCLASS_IS_GLOBAL; use js::glue::{CreateWrapperProxyHandler, ProxyTraps}; @@ -42,7 +44,9 @@ use msg::constellation_msg::BrowsingContextId; use msg::constellation_msg::PipelineId; use msg::constellation_msg::TopLevelBrowsingContextId; use script_thread::ScriptThread; -use script_traits::ScriptMsg; +use script_traits::{AuxiliaryBrowsingContextLoadInfo, LoadData, NewLayoutInfo, ScriptMsg}; +use servo_config::prefs::PREFS; +use servo_url::ServoUrl; use std::cell::Cell; use std::ptr; @@ -200,6 +204,138 @@ impl WindowProxy { } } + // https://html.spec.whatwg.org/multipage/#auxiliary-browsing-context + fn create_auxiliary_browsing_context(&self, name: DOMString, _noopener: bool) -> Option> { + let (chan, port) = ipc::channel().unwrap(); + let window = self.currently_active.get() + .and_then(|id| ScriptThread::find_document(id)) + .and_then(|doc| Some(DomRoot::from_ref(doc.window()))) + .unwrap(); + let msg = EmbedderMsg::AllowOpeningBrowser(chan); + window.send_to_embedder(msg); + if port.recv().unwrap() { + let new_top_level_browsing_context_id = TopLevelBrowsingContextId::new(); + let new_browsing_context_id = BrowsingContextId::from(new_top_level_browsing_context_id); + let new_pipeline_id = PipelineId::new(); + let load_info = AuxiliaryBrowsingContextLoadInfo { + opener_pipeline_id: self.currently_active.get().unwrap(), + new_browsing_context_id: new_browsing_context_id, + new_top_level_browsing_context_id: new_top_level_browsing_context_id, + new_pipeline_id: new_pipeline_id, + }; + let document = self.currently_active.get() + .and_then(|id| ScriptThread::find_document(id)) + .unwrap(); + let blank_url = ServoUrl::parse("about:blank").ok().unwrap(); + let load_data = LoadData::new(blank_url, + None, + document.get_referrer_policy(), + Some(document.url().clone())); + let (pipeline_sender, pipeline_receiver) = ipc::channel().unwrap(); + let new_layout_info = NewLayoutInfo { + parent_info: None, + new_pipeline_id: new_pipeline_id, + browsing_context_id: new_browsing_context_id, + top_level_browsing_context_id: new_top_level_browsing_context_id, + load_data: load_data, + pipeline_port: pipeline_receiver, + content_process_shutdown_chan: None, + window_size: None, + layout_threads: PREFS.get("layout.threads").as_u64().expect("count") as usize, + }; + let constellation_msg = ScriptMsg::ScriptNewAuxiliary(load_info, pipeline_sender); + window.send_to_constellation(constellation_msg); + ScriptThread::process_attach_layout(new_layout_info, document.origin().clone()); + let msg = EmbedderMsg::BrowserCreated(new_top_level_browsing_context_id); + window.send_to_embedder(msg); + let auxiliary = ScriptThread::find_document(new_pipeline_id).and_then(|doc| doc.browsing_context()); + if let Some(proxy) = auxiliary { + if name.to_lowercase() != "_blank" { + proxy.set_name(name); + } + return Some(proxy) + } + } + None + } + + // https://html.spec.whatwg.org/multipage/#window-open-steps + pub fn open(&self, + url: DOMString, + target: DOMString, + features: DOMString) + -> Option> { + // Step 3. + let non_empty_target = match target.as_ref() { + "" => DOMString::from("_blank"), + _ => target + }; + // TODO Step 4, properly tokenize features. + // Step 5 + let noopener = features.contains("noopener"); + // Step 6, 7 + let (chosen, new) = match self.choose_browsing_context(non_empty_target, noopener) { + (Some(chosen), new) => (chosen, new), + (None, _) => return None + }; + // TODO Step 8, set up browsing context features. + let target_document = match chosen.document() { + Some(target_document) => target_document, + None => return None + }; + let target_window = target_document.window(); + // Step 9, and 10.2, will have happened elsewhere, + // since we've created a new browsing context and loaded it with about:blank. + if !url.is_empty() { + let existing_document = self.currently_active.get() + .and_then(|id| ScriptThread::find_document(id)).unwrap(); + // Step 10.1 + let url = match existing_document.url().join(&url) { + Ok(url) => url, + Err(_) => return None, // TODO: throw a "SyntaxError" DOMException. + }; + // Step 10.3 + target_window.load_url(url, new, false, target_document.get_referrer_policy()); + } + if noopener { + // Step 11 (Dis-owning has been done in create_auxiliary_browsing_context). + return None + } + // Step 12. + return target_document.browsing_context() + } + + // https://html.spec.whatwg.org/multipage/#the-rules-for-choosing-a-browsing-context-given-a-browsing-context-name + pub fn choose_browsing_context(&self, name: DOMString, noopener: bool) -> (Option>, bool) { + match name.to_lowercase().as_ref() { + "" | "_self" => { + // Step 3. + (Some(DomRoot::from_ref(self)), false) + }, + "_parent" => { + // Step 4 + (Some(DomRoot::from_ref(self.parent().unwrap())), false) + }, + "_top" => { + // Step 5 + (Some(DomRoot::from_ref(self.top())), false) + }, + "_blank" => { + (self.create_auxiliary_browsing_context(name, noopener), true) + }, + _ => { + // Step 6. + // TODO: expand the search to all 'familiar' bc, + // including auxiliaries familiar by way of their opener. + // See https://html.spec.whatwg.org/multipage/#familiar-with + match ScriptThread::find_window_proxy_by_name(&name) { + Some(proxy) => (Some(proxy), false), + None => (self.create_auxiliary_browsing_context(name, noopener), true) + } + } + } + } + pub fn discard_browsing_context(&self) { self.discarded.set(true); } @@ -220,6 +356,11 @@ impl WindowProxy { self.frame_element.r() } + pub fn document(&self) -> Option> { + self.currently_active.get() + .and_then(|id| ScriptThread::find_document(id)) + } + pub fn parent(&self) -> Option<&WindowProxy> { self.parent.r() } -- cgit v1.2.3 From 21bf5a3a4b6398cd7c20449ba9110499feca7d6b Mon Sep 17 00:00:00 2001 From: Gregory Terzian Date: Sat, 2 Jun 2018 20:56:00 +0800 Subject: implement opener, disowning --- components/script/dom/windowproxy.rs | 85 ++++++++++++++++++++++++++++++++---- 1 file changed, 77 insertions(+), 8 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 10c925cb28d..093ea29b3d7 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -36,7 +36,7 @@ use js::jsapi::HandleValue as RawHandleValue; use js::jsapi::MutableHandle as RawMutableHandle; use js::jsapi::MutableHandleObject as RawMutableHandleObject; use js::jsapi::MutableHandleValue as RawMutableHandleValue; -use js::jsval::{UndefinedValue, PrivateValue}; +use js::jsval::{JSVal, NullValue, UndefinedValue, PrivateValue}; use js::rust::{Handle, MutableHandle}; use js::rust::get_object_class; use js::rust::wrappers::{NewWindowProxy, SetWindowProxy, JS_TransplantObject}; @@ -67,6 +67,9 @@ pub struct WindowProxy { /// of the container. browsing_context_id: BrowsingContextId, + // https://html.spec.whatwg.org/multipage/#opener-browsing-context + opener: Option, + /// The frame id of the top-level ancestor browsing context. /// In the case that this is a top-level window, this is our id. top_level_browsing_context_id: TopLevelBrowsingContextId, @@ -83,6 +86,9 @@ pub struct WindowProxy { /// Has the browsing context been discarded? discarded: Cell, + /// Has the browsing context been disowned? + disowned: Cell, + /// The containing iframe element, if this is a same-origin iframe frame_element: Option>, @@ -95,7 +101,8 @@ impl WindowProxy { top_level_browsing_context_id: TopLevelBrowsingContextId, currently_active: Option, frame_element: Option<&Element>, - parent: Option<&WindowProxy>) + parent: Option<&WindowProxy>, + opener: Option) -> WindowProxy { let name = frame_element.map_or(DOMString::new(), |e| e.get_string_attribute(&local_name!("name"))); @@ -106,8 +113,10 @@ impl WindowProxy { name: DomRefCell::new(name), currently_active: Cell::new(currently_active), discarded: Cell::new(false), + disowned: Cell::new(false), frame_element: frame_element.map(Dom::from_ref), parent: parent.map(Dom::from_ref), + opener, } } @@ -116,7 +125,8 @@ impl WindowProxy { browsing_context_id: BrowsingContextId, top_level_browsing_context_id: TopLevelBrowsingContextId, frame_element: Option<&Element>, - parent: Option<&WindowProxy>) + parent: Option<&WindowProxy>, + opener: Option) -> DomRoot { unsafe { @@ -140,7 +150,8 @@ impl WindowProxy { top_level_browsing_context_id, current, frame_element, - parent + parent, + opener, )); // The window proxy owns the browsing context. @@ -161,7 +172,8 @@ impl WindowProxy { pub fn new_dissimilar_origin(global_to_clone_from: &GlobalScope, browsing_context_id: BrowsingContextId, top_level_browsing_context_id: TopLevelBrowsingContextId, - parent: Option<&WindowProxy>) + parent: Option<&WindowProxy>, + opener: Option) -> DomRoot { unsafe { @@ -176,7 +188,8 @@ impl WindowProxy { top_level_browsing_context_id, None, None, - parent + parent, + opener )); // Create a new dissimilar-origin window. @@ -205,7 +218,7 @@ impl WindowProxy { } // https://html.spec.whatwg.org/multipage/#auxiliary-browsing-context - fn create_auxiliary_browsing_context(&self, name: DOMString, _noopener: bool) -> Option> { + fn create_auxiliary_browsing_context(&self, name: DOMString, noopener: bool) -> Option> { let (chan, port) = ipc::channel().unwrap(); let window = self.currently_active.get() .and_then(|id| ScriptThread::find_document(id)) @@ -237,6 +250,7 @@ impl WindowProxy { new_pipeline_id: new_pipeline_id, browsing_context_id: new_browsing_context_id, top_level_browsing_context_id: new_top_level_browsing_context_id, + opener: Some(self.browsing_context_id), load_data: load_data, pipeline_port: pipeline_receiver, content_process_shutdown_chan: None, @@ -248,17 +262,64 @@ impl WindowProxy { ScriptThread::process_attach_layout(new_layout_info, document.origin().clone()); let msg = EmbedderMsg::BrowserCreated(new_top_level_browsing_context_id); window.send_to_embedder(msg); + // TODO: if noopener is false, copy the sessionStorage storage area of the creator origin. + // See step 14 of https://html.spec.whatwg.org/multipage/#creating-a-new-browsing-context let auxiliary = ScriptThread::find_document(new_pipeline_id).and_then(|doc| doc.browsing_context()); if let Some(proxy) = auxiliary { if name.to_lowercase() != "_blank" { proxy.set_name(name); } + if noopener { + proxy.disown(); + } return Some(proxy) } } None } + // https://html.spec.whatwg.org/multipage/#disowned-its-opener + pub fn disown(&self) { + self.disowned.set(true); + } + + #[allow(unsafe_code)] + // https://html.spec.whatwg.org/multipage/#dom-opener + pub unsafe fn opener(&self, cx: *mut JSContext) -> JSVal { + if self.disowned.get() { + return NullValue() + } + let opener_id = match self.opener { + Some(opener_browsing_context_id) => opener_browsing_context_id, + None => return NullValue() + }; + let opener_proxy = match ScriptThread::find_window_proxy(opener_id) { + Some(window_proxy) => window_proxy, + None => { + let sender_pipeline_id = self.currently_active().unwrap(); + match ScriptThread::get_top_level_for_browsing_context(sender_pipeline_id, opener_id) { + Some(opener_top_id) => { + let global_to_clone_from = GlobalScope::from_context(cx); + WindowProxy::new_dissimilar_origin( + &*global_to_clone_from, + opener_id, + opener_top_id, + None, + None + ) + }, + None => return NullValue() + } + } + }; + if opener_proxy.is_browsing_context_discarded() { + return NullValue() + } + rooted!(in(cx) let mut val = UndefinedValue()); + opener_proxy.to_jsval(cx, val.handle_mut()); + return val.get() + } + // https://html.spec.whatwg.org/multipage/#window-open-steps pub fn open(&self, url: DOMString, @@ -314,7 +375,11 @@ impl WindowProxy { }, "_parent" => { // Step 4 - (Some(DomRoot::from_ref(self.parent().unwrap())), false) + if let Some(parent) = self.parent() { + return (Some(DomRoot::from_ref(parent)), false) + } + (None, false) + }, "_top" => { // Step 5 @@ -336,6 +401,10 @@ impl WindowProxy { } } + pub fn is_auxiliary(&self) -> bool { + self.opener.is_some() + } + pub fn discard_browsing_context(&self) { self.discarded.set(true); } -- cgit v1.2.3 From 74c1e00d8163f255bb4141ff3549bbdedd7ea766 Mon Sep 17 00:00:00 2001 From: Alan Jeffrey Date: Fri, 1 Jun 2018 17:24:25 -0500 Subject: Upgraded to SM 60 --- components/script/dom/windowproxy.rs | 50 ++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 16 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 093ea29b3d7..f7d677b37fc 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -22,7 +22,7 @@ use embedder_traits::EmbedderMsg; use ipc_channel::ipc; use js::JSCLASS_IS_GLOBAL; use js::glue::{CreateWrapperProxyHandler, ProxyTraps}; -use js::glue::{GetProxyPrivate, SetProxyExtra, GetProxyExtra}; +use js::glue::{GetProxyPrivate, SetProxyReservedSlot, GetProxyReservedSlot}; use js::jsapi::{JSAutoCompartment, JSContext, JSErrNum, JSFreeOp, JSObject}; use js::jsapi::{JSPROP_ENUMERATE, JSPROP_READONLY, JSTracer, JS_DefinePropertyById}; use js::jsapi::{JS_ForwardGetPropertyTo, JS_ForwardSetPropertyTo}; @@ -156,7 +156,7 @@ impl WindowProxy { // The window proxy owns the browsing context. // When we finalize the window proxy, it drops the browsing context it owns. - SetProxyExtra(js_proxy.get(), 0, &PrivateValue((&*window_proxy).as_void_ptr())); + SetProxyReservedSlot(js_proxy.get(), 0, &PrivateValue((&*window_proxy).as_void_ptr())); // Notify the JS engine about the new window proxy binding. SetWindowProxy(cx, window_jsobject, js_proxy.handle()); @@ -205,7 +205,7 @@ impl WindowProxy { // The window proxy owns the browsing context. // When we finalize the window proxy, it drops the browsing context it owns. - SetProxyExtra(js_proxy.get(), 0, &PrivateValue((&*window_proxy).as_void_ptr())); + SetProxyReservedSlot(js_proxy.get(), 0, &PrivateValue((&*window_proxy).as_void_ptr())); // Notify the JS engine about the new window proxy binding. SetWindowProxy(cx, window_jsobject, js_proxy.handle()); @@ -460,7 +460,7 @@ impl WindowProxy { let _ac = JSAutoCompartment::new(cx, window_jsobject.get()); // The old window proxy no longer owns this browsing context. - SetProxyExtra(old_js_proxy.get(), 0, &PrivateValue(ptr::null_mut())); + SetProxyReservedSlot(old_js_proxy.get(), 0, &PrivateValue(ptr::null_mut())); // Brain transpant the window proxy. // We need to do this, because the Window and WindowProxy @@ -475,7 +475,7 @@ impl WindowProxy { debug!("Transplanted proxy is {:p}.", new_js_proxy.get()); // Transfer ownership of this browsing context from the old window proxy to the new one. - SetProxyExtra(new_js_proxy.get(), 0, &PrivateValue(self.as_void_ptr())); + SetProxyReservedSlot(new_js_proxy.get(), 0, &PrivateValue(self.as_void_ptr())); // Notify the JS engine about the new window proxy binding. SetWindowProxy(cx, window_jsobject, new_js_proxy.handle()); @@ -523,7 +523,9 @@ unsafe fn GetSubframeWindowProxy( ) -> Option<(DomRoot, u32)> { let index = get_array_index_from_id(cx, Handle::from_raw(id)); if let Some(index) = index { - rooted!(in(cx) let target = GetProxyPrivate(*proxy).to_object()); + let mut slot = UndefinedValue(); + GetProxyPrivate(*proxy, &mut slot); + rooted!(in(cx) let target = slot.to_object()); if let Ok(win) = root_from_handleobject::(target.handle()) { let browsing_context_id = win.window_proxy().browsing_context_id(); let (result_sender, result_receiver) = ipc::channel().unwrap(); @@ -538,7 +540,7 @@ unsafe fn GetSubframeWindowProxy( return result_receiver.recv().ok() .and_then(|maybe_bcid| maybe_bcid) .and_then(ScriptThread::find_window_proxy) - .map(|proxy| (proxy, JSPROP_ENUMERATE | JSPROP_READONLY)); + .map(|proxy| (proxy, (JSPROP_ENUMERATE | JSPROP_READONLY) as u32)); } else if let Ok(win) = root_from_handleobject::(target.handle()) { let browsing_context_id = win.window_proxy().browsing_context_id(); let (result_sender, result_receiver) = ipc::channel().unwrap(); @@ -551,7 +553,7 @@ unsafe fn GetSubframeWindowProxy( return result_receiver.recv().ok() .and_then(|maybe_bcid| maybe_bcid) .and_then(ScriptThread::find_window_proxy) - .map(|proxy| (proxy, JSPROP_READONLY)); + .map(|proxy| (proxy, JSPROP_READONLY as u32)); } } @@ -573,7 +575,9 @@ unsafe extern "C" fn getOwnPropertyDescriptor(cx: *mut JSContext, return true; } - rooted!(in(cx) let target = GetProxyPrivate(proxy.get()).to_object()); + let mut slot = UndefinedValue(); + GetProxyPrivate(proxy.get(), &mut slot); + rooted!(in(cx) let target = slot.to_object()); if !JS_GetOwnPropertyDescriptorById(cx, target.handle().into(), id, desc) { return false; } @@ -603,7 +607,9 @@ unsafe extern "C" fn defineProperty(cx: *mut JSContext, return true; } - rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object()); + let mut slot = UndefinedValue(); + GetProxyPrivate(*proxy.ptr, &mut slot); + rooted!(in(cx) let target = slot.to_object()); JS_DefinePropertyById(cx, target.handle().into(), id, desc, res) } @@ -619,7 +625,9 @@ unsafe extern "C" fn has(cx: *mut JSContext, return true; } - rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object()); + let mut slot = UndefinedValue(); + GetProxyPrivate(*proxy.ptr, &mut slot); + rooted!(in(cx) let target = slot.to_object()); let mut found = false; if !JS_HasPropertyById(cx, target.handle().into(), id, &mut found) { return false; @@ -642,7 +650,9 @@ unsafe extern "C" fn get(cx: *mut JSContext, return true; } - rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object()); + let mut slot = UndefinedValue(); + GetProxyPrivate(*proxy.ptr, &mut slot); + rooted!(in(cx) let target = slot.to_object()); JS_ForwardGetPropertyTo(cx, target.handle().into(), id, receiver, vp) } @@ -660,7 +670,9 @@ unsafe extern "C" fn set(cx: *mut JSContext, return true; } - rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object()); + let mut slot = UndefinedValue(); + GetProxyPrivate(*proxy.ptr, &mut slot); + rooted!(in(cx) let target = slot.to_object()); JS_ForwardSetPropertyTo(cx, target.handle().into(), id, @@ -750,7 +762,9 @@ unsafe extern "C" fn has_xorigin(cx: *mut JSContext, bp: *mut bool) -> bool { - rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object()); + let mut slot = UndefinedValue(); + GetProxyPrivate(*proxy.ptr, &mut slot); + rooted!(in(cx) let target = slot.to_object()); let mut found = false; JS_HasOwnPropertyById(cx, target.handle().into(), id, &mut found); if found { @@ -864,7 +878,9 @@ static XORIGIN_PROXY_HANDLER: ProxyTraps = ProxyTraps { #[allow(unsafe_code)] unsafe extern fn finalize(_fop: *mut JSFreeOp, obj: *mut JSObject) { - let this = GetProxyExtra(obj, 0).to_private() as *mut WindowProxy; + let mut slot = UndefinedValue(); + GetProxyReservedSlot(obj, 0, &mut slot); + let this = slot.to_private() as *mut WindowProxy; if this.is_null() { // GC during obj creation or after transplanting. return; @@ -876,7 +892,9 @@ unsafe extern fn finalize(_fop: *mut JSFreeOp, obj: *mut JSObject) { #[allow(unsafe_code)] unsafe extern fn trace(trc: *mut JSTracer, obj: *mut JSObject) { - let this = GetProxyExtra(obj, 0).to_private() as *const WindowProxy; + let mut slot = UndefinedValue(); + GetProxyReservedSlot(obj, 0, &mut slot); + let this = slot.to_private() as *const WindowProxy; if this.is_null() { // GC during obj creation or after transplanting. return; -- cgit v1.2.3 From c37a345dc9f4dda6ea29c42f96f6c7201c42cbac Mon Sep 17 00:00:00 2001 From: chansuke Date: Tue, 18 Sep 2018 23:24:15 +0900 Subject: Format script component --- components/script/dom/windowproxy.rs | 425 ++++++++++++++++++++--------------- 1 file changed, 245 insertions(+), 180 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index f7d677b37fc..d1b5c185565 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -97,15 +97,17 @@ pub struct WindowProxy { } impl WindowProxy { - pub fn new_inherited(browsing_context_id: BrowsingContextId, - top_level_browsing_context_id: TopLevelBrowsingContextId, - currently_active: Option, - frame_element: Option<&Element>, - parent: Option<&WindowProxy>, - opener: Option) - -> WindowProxy - { - let name = frame_element.map_or(DOMString::new(), |e| e.get_string_attribute(&local_name!("name"))); + pub fn new_inherited( + browsing_context_id: BrowsingContextId, + top_level_browsing_context_id: TopLevelBrowsingContextId, + currently_active: Option, + frame_element: Option<&Element>, + parent: Option<&WindowProxy>, + opener: Option, + ) -> WindowProxy { + let name = frame_element.map_or(DOMString::new(), |e| { + e.get_string_attribute(&local_name!("name")) + }); WindowProxy { reflector: Reflector::new(), browsing_context_id: browsing_context_id, @@ -121,14 +123,14 @@ impl WindowProxy { } #[allow(unsafe_code)] - pub fn new(window: &Window, - browsing_context_id: BrowsingContextId, - top_level_browsing_context_id: TopLevelBrowsingContextId, - frame_element: Option<&Element>, - parent: Option<&WindowProxy>, - opener: Option) - -> DomRoot - { + pub fn new( + window: &Window, + browsing_context_id: BrowsingContextId, + top_level_browsing_context_id: TopLevelBrowsingContextId, + frame_element: Option<&Element>, + parent: Option<&WindowProxy>, + opener: Option, + ) -> DomRoot { unsafe { let WindowProxyHandler(handler) = window.windowproxy_handler(); assert!(!handler.is_null()); @@ -136,7 +138,10 @@ impl WindowProxy { let cx = window.get_cx(); let window_jsobject = window.reflector().get_jsobject(); assert!(!window_jsobject.get().is_null()); - assert_ne!(((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL), 0); + assert_ne!( + ((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL), + 0 + ); let _ac = JSAutoCompartment::new(cx, window_jsobject.get()); // Create a new window proxy. @@ -156,26 +161,34 @@ impl WindowProxy { // The window proxy owns the browsing context. // When we finalize the window proxy, it drops the browsing context it owns. - SetProxyReservedSlot(js_proxy.get(), 0, &PrivateValue((&*window_proxy).as_void_ptr())); + SetProxyReservedSlot( + js_proxy.get(), + 0, + &PrivateValue((&*window_proxy).as_void_ptr()), + ); // Notify the JS engine about the new window proxy binding. SetWindowProxy(cx, window_jsobject, js_proxy.handle()); // Set the reflector. - debug!("Initializing reflector of {:p} to {:p}.", window_proxy, js_proxy.get()); + debug!( + "Initializing reflector of {:p} to {:p}.", + window_proxy, + js_proxy.get() + ); window_proxy.reflector.set_jsobject(js_proxy.get()); DomRoot::from_ref(&*Box::into_raw(window_proxy)) } } #[allow(unsafe_code)] - pub fn new_dissimilar_origin(global_to_clone_from: &GlobalScope, - browsing_context_id: BrowsingContextId, - top_level_browsing_context_id: TopLevelBrowsingContextId, - parent: Option<&WindowProxy>, - opener: Option) - -> DomRoot - { + pub fn new_dissimilar_origin( + global_to_clone_from: &GlobalScope, + browsing_context_id: BrowsingContextId, + top_level_browsing_context_id: TopLevelBrowsingContextId, + parent: Option<&WindowProxy>, + opener: Option, + ) -> DomRoot { unsafe { let handler = CreateWrapperProxyHandler(&XORIGIN_PROXY_HANDLER); assert!(!handler.is_null()); @@ -189,14 +202,17 @@ impl WindowProxy { None, None, parent, - opener + opener, )); // Create a new dissimilar-origin window. let window = DissimilarOriginWindow::new(global_to_clone_from, &*window_proxy); let window_jsobject = window.reflector().get_jsobject(); assert!(!window_jsobject.get().is_null()); - assert_ne!(((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL), 0); + assert_ne!( + ((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL), + 0 + ); let _ac = JSAutoCompartment::new(cx, window_jsobject.get()); // Create a new window proxy. @@ -205,30 +221,45 @@ impl WindowProxy { // The window proxy owns the browsing context. // When we finalize the window proxy, it drops the browsing context it owns. - SetProxyReservedSlot(js_proxy.get(), 0, &PrivateValue((&*window_proxy).as_void_ptr())); + SetProxyReservedSlot( + js_proxy.get(), + 0, + &PrivateValue((&*window_proxy).as_void_ptr()), + ); // Notify the JS engine about the new window proxy binding. SetWindowProxy(cx, window_jsobject, js_proxy.handle()); // Set the reflector. - debug!("Initializing reflector of {:p} to {:p}.", window_proxy, js_proxy.get()); + debug!( + "Initializing reflector of {:p} to {:p}.", + window_proxy, + js_proxy.get() + ); window_proxy.reflector.set_jsobject(js_proxy.get()); DomRoot::from_ref(&*Box::into_raw(window_proxy)) } } // https://html.spec.whatwg.org/multipage/#auxiliary-browsing-context - fn create_auxiliary_browsing_context(&self, name: DOMString, noopener: bool) -> Option> { + fn create_auxiliary_browsing_context( + &self, + name: DOMString, + noopener: bool, + ) -> Option> { let (chan, port) = ipc::channel().unwrap(); - let window = self.currently_active.get() - .and_then(|id| ScriptThread::find_document(id)) - .and_then(|doc| Some(DomRoot::from_ref(doc.window()))) - .unwrap(); + let window = self + .currently_active + .get() + .and_then(|id| ScriptThread::find_document(id)) + .and_then(|doc| Some(DomRoot::from_ref(doc.window()))) + .unwrap(); let msg = EmbedderMsg::AllowOpeningBrowser(chan); window.send_to_embedder(msg); if port.recv().unwrap() { let new_top_level_browsing_context_id = TopLevelBrowsingContextId::new(); - let new_browsing_context_id = BrowsingContextId::from(new_top_level_browsing_context_id); + let new_browsing_context_id = + BrowsingContextId::from(new_top_level_browsing_context_id); let new_pipeline_id = PipelineId::new(); let load_info = AuxiliaryBrowsingContextLoadInfo { opener_pipeline_id: self.currently_active.get().unwrap(), @@ -236,14 +267,18 @@ impl WindowProxy { new_top_level_browsing_context_id: new_top_level_browsing_context_id, new_pipeline_id: new_pipeline_id, }; - let document = self.currently_active.get() + let document = self + .currently_active + .get() .and_then(|id| ScriptThread::find_document(id)) .unwrap(); let blank_url = ServoUrl::parse("about:blank").ok().unwrap(); - let load_data = LoadData::new(blank_url, - None, - document.get_referrer_policy(), - Some(document.url().clone())); + let load_data = LoadData::new( + blank_url, + None, + document.get_referrer_policy(), + Some(document.url().clone()), + ); let (pipeline_sender, pipeline_receiver) = ipc::channel().unwrap(); let new_layout_info = NewLayoutInfo { parent_info: None, @@ -264,7 +299,8 @@ impl WindowProxy { window.send_to_embedder(msg); // TODO: if noopener is false, copy the sessionStorage storage area of the creator origin. // See step 14 of https://html.spec.whatwg.org/multipage/#creating-a-new-browsing-context - let auxiliary = ScriptThread::find_document(new_pipeline_id).and_then(|doc| doc.browsing_context()); + let auxiliary = + ScriptThread::find_document(new_pipeline_id).and_then(|doc| doc.browsing_context()); if let Some(proxy) = auxiliary { if name.to_lowercase() != "_blank" { proxy.set_name(name); @@ -272,7 +308,7 @@ impl WindowProxy { if noopener { proxy.disown(); } - return Some(proxy) + return Some(proxy); } } None @@ -287,17 +323,20 @@ impl WindowProxy { // https://html.spec.whatwg.org/multipage/#dom-opener pub unsafe fn opener(&self, cx: *mut JSContext) -> JSVal { if self.disowned.get() { - return NullValue() + return NullValue(); } let opener_id = match self.opener { Some(opener_browsing_context_id) => opener_browsing_context_id, - None => return NullValue() + None => return NullValue(), }; let opener_proxy = match ScriptThread::find_window_proxy(opener_id) { Some(window_proxy) => window_proxy, None => { let sender_pipeline_id = self.currently_active().unwrap(); - match ScriptThread::get_top_level_for_browsing_context(sender_pipeline_id, opener_id) { + match ScriptThread::get_top_level_for_browsing_context( + sender_pipeline_id, + opener_id, + ) { Some(opener_top_id) => { let global_to_clone_from = GlobalScope::from_context(cx); WindowProxy::new_dissimilar_origin( @@ -305,31 +344,32 @@ impl WindowProxy { opener_id, opener_top_id, None, - None + None, ) }, - None => return NullValue() + None => return NullValue(), } - } + }, }; if opener_proxy.is_browsing_context_discarded() { - return NullValue() + return NullValue(); } rooted!(in(cx) let mut val = UndefinedValue()); opener_proxy.to_jsval(cx, val.handle_mut()); - return val.get() + return val.get(); } // https://html.spec.whatwg.org/multipage/#window-open-steps - pub fn open(&self, - url: DOMString, - target: DOMString, - features: DOMString) - -> Option> { + pub fn open( + &self, + url: DOMString, + target: DOMString, + features: DOMString, + ) -> Option> { // Step 3. let non_empty_target = match target.as_ref() { "" => DOMString::from("_blank"), - _ => target + _ => target, }; // TODO Step 4, properly tokenize features. // Step 5 @@ -337,19 +377,22 @@ impl WindowProxy { // Step 6, 7 let (chosen, new) = match self.choose_browsing_context(non_empty_target, noopener) { (Some(chosen), new) => (chosen, new), - (None, _) => return None + (None, _) => return None, }; // TODO Step 8, set up browsing context features. let target_document = match chosen.document() { Some(target_document) => target_document, - None => return None + None => return None, }; let target_window = target_document.window(); // Step 9, and 10.2, will have happened elsewhere, // since we've created a new browsing context and loaded it with about:blank. if !url.is_empty() { - let existing_document = self.currently_active.get() - .and_then(|id| ScriptThread::find_document(id)).unwrap(); + let existing_document = self + .currently_active + .get() + .and_then(|id| ScriptThread::find_document(id)) + .unwrap(); // Step 10.1 let url = match existing_document.url().join(&url) { Ok(url) => url, @@ -360,14 +403,18 @@ impl WindowProxy { } if noopener { // Step 11 (Dis-owning has been done in create_auxiliary_browsing_context). - return None + return None; } // Step 12. - return target_document.browsing_context() + return target_document.browsing_context(); } // https://html.spec.whatwg.org/multipage/#the-rules-for-choosing-a-browsing-context-given-a-browsing-context-name - pub fn choose_browsing_context(&self, name: DOMString, noopener: bool) -> (Option>, bool) { + pub fn choose_browsing_context( + &self, + name: DOMString, + noopener: bool, + ) -> (Option>, bool) { match name.to_lowercase().as_ref() { "" | "_self" => { // Step 3. @@ -376,18 +423,15 @@ impl WindowProxy { "_parent" => { // Step 4 if let Some(parent) = self.parent() { - return (Some(DomRoot::from_ref(parent)), false) + return (Some(DomRoot::from_ref(parent)), false); } (None, false) - }, "_top" => { // Step 5 (Some(DomRoot::from_ref(self.top())), false) }, - "_blank" => { - (self.create_auxiliary_browsing_context(name, noopener), true) - }, + "_blank" => (self.create_auxiliary_browsing_context(name, noopener), true), _ => { // Step 6. // TODO: expand the search to all 'familiar' bc, @@ -395,9 +439,9 @@ impl WindowProxy { // See https://html.spec.whatwg.org/multipage/#familiar-with match ScriptThread::find_window_proxy_by_name(&name) { Some(proxy) => (Some(proxy), false), - None => (self.create_auxiliary_browsing_context(name, noopener), true) + None => (self.create_auxiliary_browsing_context(name, noopener), true), } - } + }, } } @@ -426,7 +470,8 @@ impl WindowProxy { } pub fn document(&self) -> Option> { - self.currently_active.get() + self.currently_active + .get() .and_then(|id| ScriptThread::find_document(id)) } @@ -456,7 +501,10 @@ impl WindowProxy { let window_jsobject = window.reflector().get_jsobject(); let old_js_proxy = self.reflector.get_jsobject(); assert!(!window_jsobject.get().is_null()); - assert_ne!(((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL), 0); + assert_ne!( + ((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL), + 0 + ); let _ac = JSAutoCompartment::new(cx, window_jsobject.get()); // The old window proxy no longer owns this browsing context. @@ -470,7 +518,11 @@ impl WindowProxy { // making the old window proxy a cross-compartment wrapper // pointing to the new window proxy. rooted!(in(cx) let new_js_proxy = NewWindowProxy(cx, window_jsobject, handler)); - debug!("Transplanting proxy from {:p} to {:p}.", old_js_proxy.get(), new_js_proxy.get()); + debug!( + "Transplanting proxy from {:p} to {:p}.", + old_js_proxy.get(), + new_js_proxy.get() + ); 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()); @@ -481,7 +533,11 @@ impl WindowProxy { SetWindowProxy(cx, window_jsobject, new_js_proxy.handle()); // Update the reflector. - debug!("Setting reflector of {:p} to {:p}.", self, new_js_proxy.get()); + debug!( + "Setting reflector of {:p} to {:p}.", + self, + new_js_proxy.get() + ); self.reflector.rootable().set(new_js_proxy.get()); } } @@ -519,7 +575,7 @@ impl WindowProxy { unsafe fn GetSubframeWindowProxy( cx: *mut JSContext, proxy: RawHandleObject, - id: RawHandleId + id: RawHandleId, ) -> Option<(DomRoot, u32)> { let index = get_array_index_from_id(cx, Handle::from_raw(id)); if let Some(index) = index { @@ -530,14 +586,17 @@ unsafe fn GetSubframeWindowProxy( let browsing_context_id = win.window_proxy().browsing_context_id(); let (result_sender, result_receiver) = ipc::channel().unwrap(); - let _ = win.upcast::().script_to_constellation_chan().send( - ScriptMsg::GetChildBrowsingContextId( + let _ = win + .upcast::() + .script_to_constellation_chan() + .send(ScriptMsg::GetChildBrowsingContextId( browsing_context_id, index as usize, - result_sender - ) - ); - return result_receiver.recv().ok() + result_sender, + )); + return result_receiver + .recv() + .ok() .and_then(|maybe_bcid| maybe_bcid) .and_then(ScriptThread::find_window_proxy) .map(|proxy| (proxy, (JSPROP_ENUMERATE | JSPROP_READONLY) as u32)); @@ -545,12 +604,16 @@ unsafe fn GetSubframeWindowProxy( let browsing_context_id = win.window_proxy().browsing_context_id(); let (result_sender, result_receiver) = ipc::channel().unwrap(); - let _ = win.global().script_to_constellation_chan().send(ScriptMsg::GetChildBrowsingContextId( - browsing_context_id, - index as usize, - result_sender - )); - return result_receiver.recv().ok() + let _ = win.global().script_to_constellation_chan().send( + ScriptMsg::GetChildBrowsingContextId( + browsing_context_id, + index as usize, + result_sender, + ), + ); + return result_receiver + .recv() + .ok() .and_then(|maybe_bcid| maybe_bcid) .and_then(ScriptThread::find_window_proxy) .map(|proxy| (proxy, JSPROP_READONLY as u32)); @@ -561,11 +624,12 @@ unsafe fn GetSubframeWindowProxy( } #[allow(unsafe_code)] -unsafe extern "C" fn getOwnPropertyDescriptor(cx: *mut JSContext, - proxy: RawHandleObject, - id: RawHandleId, - mut desc: RawMutableHandle) - -> bool { +unsafe extern "C" fn getOwnPropertyDescriptor( + cx: *mut JSContext, + proxy: RawHandleObject, + id: RawHandleId, + mut desc: RawMutableHandle, +) -> bool { let window = GetSubframeWindowProxy(cx, proxy, id); if let Some((window, attrs)) = window { rooted!(in(cx) let mut val = UndefinedValue()); @@ -592,12 +656,13 @@ unsafe extern "C" fn getOwnPropertyDescriptor(cx: *mut JSContext, } #[allow(unsafe_code)] -unsafe extern "C" fn defineProperty(cx: *mut JSContext, - proxy: RawHandleObject, - id: RawHandleId, - desc: RawHandle, - res: *mut ObjectOpResult) - -> bool { +unsafe extern "C" fn defineProperty( + cx: *mut JSContext, + proxy: RawHandleObject, + id: RawHandleId, + desc: RawHandle, + res: *mut ObjectOpResult, +) -> bool { if get_array_index_from_id(cx, Handle::from_raw(id)).is_some() { // Spec says to Reject whether this is a supported index or not, // since we have no indexed setter or indexed creator. That means @@ -614,11 +679,12 @@ unsafe extern "C" fn defineProperty(cx: *mut JSContext, } #[allow(unsafe_code)] -unsafe extern "C" fn has(cx: *mut JSContext, - proxy: RawHandleObject, - id: RawHandleId, - bp: *mut bool) - -> bool { +unsafe extern "C" fn has( + cx: *mut JSContext, + proxy: RawHandleObject, + id: RawHandleId, + bp: *mut bool, +) -> bool { let window = GetSubframeWindowProxy(cx, proxy, id); if window.is_some() { *bp = true; @@ -638,12 +704,13 @@ unsafe extern "C" fn has(cx: *mut JSContext, } #[allow(unsafe_code)] -unsafe extern "C" fn get(cx: *mut JSContext, - proxy: RawHandleObject, - receiver: RawHandleValue, - id: RawHandleId, - vp: RawMutableHandleValue) - -> bool { +unsafe extern "C" fn get( + cx: *mut JSContext, + proxy: RawHandleObject, + receiver: RawHandleValue, + id: RawHandleId, + vp: RawMutableHandleValue, +) -> bool { let window = GetSubframeWindowProxy(cx, proxy, id); if let Some((window, _attrs)) = window { window.to_jsval(cx, MutableHandle::from_raw(vp)); @@ -657,13 +724,14 @@ unsafe extern "C" fn get(cx: *mut JSContext, } #[allow(unsafe_code)] -unsafe extern "C" fn set(cx: *mut JSContext, - proxy: RawHandleObject, - id: RawHandleId, - v: RawHandleValue, - receiver: RawHandleValue, - res: *mut ObjectOpResult) - -> bool { +unsafe extern "C" fn set( + cx: *mut JSContext, + proxy: RawHandleObject, + id: RawHandleId, + v: RawHandleValue, + receiver: RawHandleValue, + res: *mut ObjectOpResult, +) -> bool { if get_array_index_from_id(cx, Handle::from_raw(id)).is_some() { // Reject (which means throw if and only if strict) the set. (*res).code_ = JSErrNum::JSMSG_READ_ONLY as ::libc::uintptr_t; @@ -673,20 +741,16 @@ unsafe extern "C" fn set(cx: *mut JSContext, let mut slot = UndefinedValue(); GetProxyPrivate(*proxy.ptr, &mut slot); rooted!(in(cx) let target = slot.to_object()); - JS_ForwardSetPropertyTo(cx, - target.handle().into(), - id, - v, - receiver, - res) + JS_ForwardSetPropertyTo(cx, target.handle().into(), id, v, receiver, res) } #[allow(unsafe_code)] -unsafe extern "C" fn get_prototype_if_ordinary(_: *mut JSContext, - _: RawHandleObject, - is_ordinary: *mut bool, - _: RawMutableHandleObject) - -> bool { +unsafe extern "C" fn get_prototype_if_ordinary( + _: *mut JSContext, + _: RawHandleObject, + is_ordinary: *mut bool, + _: RawMutableHandleObject, +) -> bool { // Window's [[GetPrototypeOf]] trap isn't the ordinary definition: // // https://html.spec.whatwg.org/multipage/#windowproxy-getprototypeof @@ -737,9 +801,7 @@ static PROXY_HANDLER: ProxyTraps = ProxyTraps { #[allow(unsafe_code)] pub fn new_window_proxy_handler() -> WindowProxyHandler { - unsafe { - WindowProxyHandler(CreateWrapperProxyHandler(&PROXY_HANDLER)) - } + unsafe { WindowProxyHandler(CreateWrapperProxyHandler(&PROXY_HANDLER)) } } // The proxy traps for cross-origin windows. @@ -756,12 +818,12 @@ unsafe fn throw_security_error(cx: *mut JSContext) -> bool { } #[allow(unsafe_code)] -unsafe extern "C" fn has_xorigin(cx: *mut JSContext, - proxy: RawHandleObject, - id: RawHandleId, - bp: *mut bool) - -> bool -{ +unsafe extern "C" fn has_xorigin( + cx: *mut JSContext, + proxy: RawHandleObject, + id: RawHandleId, + bp: *mut bool, +) -> bool { let mut slot = UndefinedValue(); GetProxyPrivate(*proxy.ptr, &mut slot); rooted!(in(cx) let target = slot.to_object()); @@ -776,69 +838,69 @@ unsafe extern "C" fn has_xorigin(cx: *mut JSContext, } #[allow(unsafe_code)] -unsafe extern "C" fn get_xorigin(cx: *mut JSContext, - proxy: RawHandleObject, - receiver: RawHandleValue, - id: RawHandleId, - vp: RawMutableHandleValue) - -> bool -{ +unsafe extern "C" fn get_xorigin( + cx: *mut JSContext, + proxy: RawHandleObject, + receiver: RawHandleValue, + id: RawHandleId, + vp: RawMutableHandleValue, +) -> bool { let mut found = false; has_xorigin(cx, proxy, id, &mut found); found && get(cx, proxy, receiver, id, vp) } #[allow(unsafe_code)] -unsafe extern "C" fn set_xorigin(cx: *mut JSContext, - _: RawHandleObject, - _: RawHandleId, - _: RawHandleValue, - _: RawHandleValue, - _: *mut ObjectOpResult) - -> bool -{ +unsafe extern "C" fn set_xorigin( + cx: *mut JSContext, + _: RawHandleObject, + _: RawHandleId, + _: RawHandleValue, + _: RawHandleValue, + _: *mut ObjectOpResult, +) -> bool { throw_security_error(cx) } #[allow(unsafe_code)] -unsafe extern "C" fn delete_xorigin(cx: *mut JSContext, - _: RawHandleObject, - _: RawHandleId, - _: *mut ObjectOpResult) - -> bool -{ +unsafe extern "C" fn delete_xorigin( + cx: *mut JSContext, + _: RawHandleObject, + _: RawHandleId, + _: *mut ObjectOpResult, +) -> bool { throw_security_error(cx) } #[allow(unsafe_code)] -unsafe extern "C" fn getOwnPropertyDescriptor_xorigin(cx: *mut JSContext, - proxy: RawHandleObject, - id: RawHandleId, - desc: RawMutableHandle) - -> bool -{ +unsafe extern "C" fn getOwnPropertyDescriptor_xorigin( + cx: *mut JSContext, + proxy: RawHandleObject, + id: RawHandleId, + desc: RawMutableHandle, +) -> bool { let mut found = false; has_xorigin(cx, proxy, id, &mut found); found && getOwnPropertyDescriptor(cx, proxy, id, desc) } #[allow(unsafe_code)] -unsafe extern "C" fn defineProperty_xorigin(cx: *mut JSContext, - _: RawHandleObject, - _: RawHandleId, - _: RawHandle, - _: *mut ObjectOpResult) - -> bool -{ +unsafe extern "C" fn defineProperty_xorigin( + cx: *mut JSContext, + _: RawHandleObject, + _: RawHandleId, + _: RawHandle, + _: *mut ObjectOpResult, +) -> bool { throw_security_error(cx) } #[allow(unsafe_code)] -unsafe extern "C" fn preventExtensions_xorigin(cx: *mut JSContext, - _: RawHandleObject, - _: *mut ObjectOpResult) - -> bool -{ +unsafe extern "C" fn preventExtensions_xorigin( + cx: *mut JSContext, + _: RawHandleObject, + _: *mut ObjectOpResult, +) -> bool { throw_security_error(cx) } @@ -877,7 +939,7 @@ static XORIGIN_PROXY_HANDLER: ProxyTraps = ProxyTraps { // How WindowProxy objects are garbage collected. #[allow(unsafe_code)] -unsafe extern fn finalize(_fop: *mut JSFreeOp, obj: *mut JSObject) { +unsafe extern "C" fn finalize(_fop: *mut JSFreeOp, obj: *mut JSObject) { let mut slot = UndefinedValue(); GetProxyReservedSlot(obj, 0, &mut slot); let this = slot.to_private() as *mut WindowProxy; @@ -886,12 +948,15 @@ unsafe extern fn finalize(_fop: *mut JSFreeOp, obj: *mut JSObject) { return; } let jsobject = (*this).reflector.get_jsobject().get(); - debug!("WindowProxy finalize: {:p}, with reflector {:p} from {:p}.", this, jsobject, obj); + debug!( + "WindowProxy finalize: {:p}, with reflector {:p} from {:p}.", + this, jsobject, obj + ); let _ = Box::from_raw(this); } #[allow(unsafe_code)] -unsafe extern fn trace(trc: *mut JSTracer, obj: *mut JSObject) { +unsafe extern "C" fn trace(trc: *mut JSTracer, obj: *mut JSObject) { let mut slot = UndefinedValue(); GetProxyReservedSlot(obj, 0, &mut slot); let this = slot.to_private() as *const WindowProxy; -- cgit v1.2.3 From 45f7199eee82c66637ec68287eafa40a651001c4 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 1 Nov 2018 23:45:06 +0100 Subject: `cargo fix --edition` --- components/script/dom/windowproxy.rs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index d1b5c185565..0cbcf7c2df5 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -2,21 +2,21 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use dom::bindings::cell::DomRefCell; -use dom::bindings::conversions::{ToJSValConvertible, root_from_handleobject}; -use dom::bindings::error::{Error, throw_dom_exception}; -use dom::bindings::inheritance::Castable; -use dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor}; -use dom::bindings::reflector::{DomObject, Reflector}; -use dom::bindings::root::{Dom, DomRoot, RootedReference}; -use dom::bindings::str::DOMString; -use dom::bindings::trace::JSTraceable; -use dom::bindings::utils::{WindowProxyHandler, get_array_index_from_id, AsVoidPtr}; -use dom::dissimilaroriginwindow::DissimilarOriginWindow; -use dom::document::Document; -use dom::element::Element; -use dom::globalscope::GlobalScope; -use dom::window::Window; +use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::conversions::{ToJSValConvertible, root_from_handleobject}; +use crate::dom::bindings::error::{Error, throw_dom_exception}; +use crate::dom::bindings::inheritance::Castable; +use crate::dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor}; +use crate::dom::bindings::reflector::{DomObject, Reflector}; +use crate::dom::bindings::root::{Dom, DomRoot, RootedReference}; +use crate::dom::bindings::str::DOMString; +use crate::dom::bindings::trace::JSTraceable; +use crate::dom::bindings::utils::{WindowProxyHandler, get_array_index_from_id, AsVoidPtr}; +use crate::dom::dissimilaroriginwindow::DissimilarOriginWindow; +use crate::dom::document::Document; +use crate::dom::element::Element; +use crate::dom::globalscope::GlobalScope; +use crate::dom::window::Window; use dom_struct::dom_struct; use embedder_traits::EmbedderMsg; use ipc_channel::ipc; @@ -43,7 +43,7 @@ use js::rust::wrappers::{NewWindowProxy, SetWindowProxy, JS_TransplantObject}; use msg::constellation_msg::BrowsingContextId; use msg::constellation_msg::PipelineId; use msg::constellation_msg::TopLevelBrowsingContextId; -use script_thread::ScriptThread; +use crate::script_thread::ScriptThread; use script_traits::{AuxiliaryBrowsingContextLoadInfo, LoadData, NewLayoutInfo, ScriptMsg}; use servo_config::prefs::PREFS; use servo_url::ServoUrl; -- cgit v1.2.3 From 76e59a46d3aff701b2e8dfbaf047f6d5c3edcced Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 1 Nov 2018 17:23:56 +0100 Subject: Sort `use` statements --- components/script/dom/windowproxy.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 0cbcf7c2df5..bc0fe4a9e09 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -17,6 +17,7 @@ use crate::dom::document::Document; use crate::dom::element::Element; use crate::dom::globalscope::GlobalScope; use crate::dom::window::Window; +use crate::script_thread::ScriptThread; use dom_struct::dom_struct; use embedder_traits::EmbedderMsg; use ipc_channel::ipc; @@ -43,7 +44,6 @@ use js::rust::wrappers::{NewWindowProxy, SetWindowProxy, JS_TransplantObject}; use msg::constellation_msg::BrowsingContextId; use msg::constellation_msg::PipelineId; use msg::constellation_msg::TopLevelBrowsingContextId; -use crate::script_thread::ScriptThread; use script_traits::{AuxiliaryBrowsingContextLoadInfo, LoadData, NewLayoutInfo, ScriptMsg}; use servo_config::prefs::PREFS; use servo_url::ServoUrl; -- cgit v1.2.3 From 9e92eb205a2a12fe0be883e42cb7f82deebc9031 Mon Sep 17 00:00:00 2001 From: Pyfisch Date: Tue, 6 Nov 2018 20:38:02 +0100 Subject: Reorder imports --- components/script/dom/windowproxy.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index bc0fe4a9e09..4de2eed66f4 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -3,15 +3,15 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::cell::DomRefCell; -use crate::dom::bindings::conversions::{ToJSValConvertible, root_from_handleobject}; -use crate::dom::bindings::error::{Error, throw_dom_exception}; +use crate::dom::bindings::conversions::{root_from_handleobject, ToJSValConvertible}; +use crate::dom::bindings::error::{throw_dom_exception, Error}; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor}; use crate::dom::bindings::reflector::{DomObject, Reflector}; use crate::dom::bindings::root::{Dom, DomRoot, RootedReference}; use crate::dom::bindings::str::DOMString; use crate::dom::bindings::trace::JSTraceable; -use crate::dom::bindings::utils::{WindowProxyHandler, get_array_index_from_id, AsVoidPtr}; +use crate::dom::bindings::utils::{get_array_index_from_id, AsVoidPtr, WindowProxyHandler}; use crate::dom::dissimilaroriginwindow::DissimilarOriginWindow; use crate::dom::document::Document; use crate::dom::element::Element; @@ -21,15 +21,8 @@ use crate::script_thread::ScriptThread; use dom_struct::dom_struct; use embedder_traits::EmbedderMsg; use ipc_channel::ipc; -use js::JSCLASS_IS_GLOBAL; use js::glue::{CreateWrapperProxyHandler, ProxyTraps}; -use js::glue::{GetProxyPrivate, SetProxyReservedSlot, GetProxyReservedSlot}; -use js::jsapi::{JSAutoCompartment, JSContext, JSErrNum, JSFreeOp, JSObject}; -use js::jsapi::{JSPROP_ENUMERATE, JSPROP_READONLY, JSTracer, JS_DefinePropertyById}; -use js::jsapi::{JS_ForwardGetPropertyTo, JS_ForwardSetPropertyTo}; -use js::jsapi::{JS_HasPropertyById, JS_HasOwnPropertyById}; -use js::jsapi::{JS_IsExceptionPending, JS_GetOwnPropertyDescriptorById}; -use js::jsapi::{ObjectOpResult, PropertyDescriptor}; +use js::glue::{GetProxyPrivate, GetProxyReservedSlot, SetProxyReservedSlot}; use js::jsapi::Handle as RawHandle; use js::jsapi::HandleId as RawHandleId; use js::jsapi::HandleObject as RawHandleObject; @@ -37,10 +30,17 @@ use js::jsapi::HandleValue as RawHandleValue; use js::jsapi::MutableHandle as RawMutableHandle; use js::jsapi::MutableHandleObject as RawMutableHandleObject; use js::jsapi::MutableHandleValue as RawMutableHandleValue; -use js::jsval::{JSVal, NullValue, UndefinedValue, PrivateValue}; -use js::rust::{Handle, MutableHandle}; +use js::jsapi::{JSAutoCompartment, JSContext, JSErrNum, JSFreeOp, JSObject}; +use js::jsapi::{JSTracer, JS_DefinePropertyById, JSPROP_ENUMERATE, JSPROP_READONLY}; +use js::jsapi::{JS_ForwardGetPropertyTo, JS_ForwardSetPropertyTo}; +use js::jsapi::{JS_GetOwnPropertyDescriptorById, JS_IsExceptionPending}; +use js::jsapi::{JS_HasOwnPropertyById, JS_HasPropertyById}; +use js::jsapi::{ObjectOpResult, PropertyDescriptor}; +use js::jsval::{JSVal, NullValue, PrivateValue, UndefinedValue}; use js::rust::get_object_class; -use js::rust::wrappers::{NewWindowProxy, SetWindowProxy, JS_TransplantObject}; +use js::rust::wrappers::{JS_TransplantObject, NewWindowProxy, SetWindowProxy}; +use js::rust::{Handle, MutableHandle}; +use js::JSCLASS_IS_GLOBAL; use msg::constellation_msg::BrowsingContextId; use msg::constellation_msg::PipelineId; use msg::constellation_msg::TopLevelBrowsingContextId; -- cgit v1.2.3 From a1a14459c141afc6ac6771b8a6c9ca374537edf2 Mon Sep 17 00:00:00 2001 From: Jan Andre Ikenmeyer Date: Mon, 19 Nov 2018 14:47:12 +0100 Subject: Update MPL license to https (part 3) --- components/script/dom/windowproxy.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 4de2eed66f4..80850e804b5 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -1,6 +1,6 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::conversions::{root_from_handleobject, ToJSValConvertible}; -- cgit v1.2.3 From 231a37be24ee62cef69d69e0d1919b7b7f80cfed Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Sun, 9 Dec 2018 14:16:14 -0500 Subject: Initial window sizes are mandatory. --- components/script/dom/windowproxy.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 80850e804b5..65362ee0d17 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -289,7 +289,7 @@ impl WindowProxy { load_data: load_data, pipeline_port: pipeline_receiver, content_process_shutdown_chan: None, - window_size: None, + window_size: window.window_size(), layout_threads: PREFS.get("layout.threads").as_u64().expect("count") as usize, }; let constellation_msg = ScriptMsg::ScriptNewAuxiliary(load_info, pipeline_sender); -- cgit v1.2.3 From eb82e781a36c055dab4c1cc3772f7a555abd31a6 Mon Sep 17 00:00:00 2001 From: Gregory Terzian Date: Wed, 12 Dec 2018 21:16:07 +0800 Subject: implement windowproxy "delay-load-event-mode", and partially document "completely-loaded" --- components/script/dom/windowproxy.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 65362ee0d17..42b53fc5ead 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -94,6 +94,9 @@ pub struct WindowProxy { /// The parent browsing context's window proxy, if this is a nested browsing context parent: Option>, + + /// https://html.spec.whatwg.org/multipage/#delaying-load-events-mode + delaying_load_events_mode: Cell, } impl WindowProxy { @@ -118,6 +121,7 @@ impl WindowProxy { disowned: Cell::new(false), frame_element: frame_element.map(Dom::from_ref), parent: parent.map(Dom::from_ref), + delaying_load_events_mode: Cell::new(false), opener, } } @@ -314,6 +318,26 @@ impl WindowProxy { None } + /// https://html.spec.whatwg.org/multipage/#delaying-load-events-mode + pub fn is_delaying_load_events_mode(&self) -> bool { + self.delaying_load_events_mode.get() + } + + /// https://html.spec.whatwg.org/multipage/#delaying-load-events-mode + pub fn start_delaying_load_events_mode(&self) { + self.delaying_load_events_mode.set(true); + } + + /// https://html.spec.whatwg.org/multipage/#delaying-load-events-mode + pub fn stop_delaying_load_events_mode(&self) { + self.delaying_load_events_mode.set(false); + if let Some(document) = self.document() { + if !document.loader().events_inhibited() { + ScriptThread::mark_document_with_no_blocked_loads(&document); + } + } + } + // https://html.spec.whatwg.org/multipage/#disowned-its-opener pub fn disown(&self) { self.disowned.set(true); -- cgit v1.2.3 From 006e71c7dec624935d3d4faf9ea5f783e2a24a67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 17 Dec 2018 23:46:42 +0100 Subject: style: Make Servo use a single thread-pool for layout-related tasks per-process. Instead of per-document. This also allows to reuse this thread-pool if needed for other stuff, like parallel CSS parsing (#22478), and to share more code with Gecko, which is always nice. --- components/script/dom/windowproxy.rs | 2 -- 1 file changed, 2 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 65362ee0d17..8b0af9a147e 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -45,7 +45,6 @@ use msg::constellation_msg::BrowsingContextId; use msg::constellation_msg::PipelineId; use msg::constellation_msg::TopLevelBrowsingContextId; use script_traits::{AuxiliaryBrowsingContextLoadInfo, LoadData, NewLayoutInfo, ScriptMsg}; -use servo_config::prefs::PREFS; use servo_url::ServoUrl; use std::cell::Cell; use std::ptr; @@ -290,7 +289,6 @@ impl WindowProxy { pipeline_port: pipeline_receiver, content_process_shutdown_chan: None, window_size: window.window_size(), - layout_threads: PREFS.get("layout.threads").as_u64().expect("count") as usize, }; let constellation_msg = ScriptMsg::ScriptNewAuxiliary(load_info, pipeline_sender); window.send_to_constellation(constellation_msg); -- cgit v1.2.3 From 5fe5e5d6debef5adf234b650ee1b758e683a5230 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Sun, 10 Mar 2019 13:20:07 +0100 Subject: Remove most RootedReference uses We can replace all uses of RootedReference for Option by Option::deref calls. --- components/script/dom/windowproxy.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index c3d995be936..d7c1f9da73d 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -8,7 +8,7 @@ use crate::dom::bindings::error::{throw_dom_exception, Error}; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor}; use crate::dom::bindings::reflector::{DomObject, Reflector}; -use crate::dom::bindings::root::{Dom, DomRoot, RootedReference}; +use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::str::DOMString; use crate::dom::bindings::trace::JSTraceable; use crate::dom::bindings::utils::{get_array_index_from_id, AsVoidPtr, WindowProxyHandler}; @@ -488,7 +488,7 @@ impl WindowProxy { } pub fn frame_element(&self) -> Option<&Element> { - self.frame_element.r() + self.frame_element.deref() } pub fn document(&self) -> Option> { @@ -498,7 +498,7 @@ impl WindowProxy { } pub fn parent(&self) -> Option<&WindowProxy> { - self.parent.r() + self.parent.deref() } pub fn top(&self) -> &WindowProxy { -- cgit v1.2.3 From f261799e64feb2a9d75af63abd217938d7c3995d Mon Sep 17 00:00:00 2001 From: Boyan Ding Date: Sun, 10 Mar 2019 23:25:38 +0800 Subject: Add a tokenizer for features in window.open() --- components/script/dom/windowproxy.rs | 116 ++++++++++++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 10 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index c3d995be936..c78dc7811e0 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -20,6 +20,7 @@ use crate::dom::window::Window; use crate::script_thread::ScriptThread; use dom_struct::dom_struct; use embedder_traits::EmbedderMsg; +use indexmap::map::IndexMap; use ipc_channel::ipc; use js::glue::{CreateWrapperProxyHandler, ProxyTraps}; use js::glue::{GetProxyPrivate, GetProxyReservedSlot, SetProxyReservedSlot}; @@ -48,6 +49,7 @@ use script_traits::{AuxiliaryBrowsingContextLoadInfo, LoadData, NewLayoutInfo, S use servo_url::ServoUrl; use std::cell::Cell; use std::ptr; +use style::attr::parse_integer; #[dom_struct] // NOTE: the browsing context for a window is managed in two places: @@ -388,26 +390,32 @@ impl WindowProxy { target: DOMString, features: DOMString, ) -> Option> { - // Step 3. + // Step 4. let non_empty_target = match target.as_ref() { "" => DOMString::from("_blank"), _ => target, }; - // TODO Step 4, properly tokenize features. // Step 5 - let noopener = features.contains("noopener"); - // Step 6, 7 + let tokenized_features = tokenize_open_features(features); + // Step 7-9 + let noreferrer = parse_open_feature_boolean(&tokenized_features, "noreferrer"); + let noopener = if noreferrer { + true + } else { + parse_open_feature_boolean(&tokenized_features, "noopener") + }; + // Step 10, 11 let (chosen, new) = match self.choose_browsing_context(non_empty_target, noopener) { (Some(chosen), new) => (chosen, new), (None, _) => return None, }; - // TODO Step 8, set up browsing context features. + // TODO Step 12, set up browsing context features. let target_document = match chosen.document() { Some(target_document) => target_document, None => return None, }; let target_window = target_document.window(); - // Step 9, and 10.2, will have happened elsewhere, + // Step 13, and 14.4, will have happened elsewhere, // since we've created a new browsing context and loaded it with about:blank. if !url.is_empty() { let existing_document = self @@ -415,19 +423,20 @@ impl WindowProxy { .get() .and_then(|id| ScriptThread::find_document(id)) .unwrap(); - // Step 10.1 + // Step 14.1 let url = match existing_document.url().join(&url) { Ok(url) => url, Err(_) => return None, // TODO: throw a "SyntaxError" DOMException. }; - // Step 10.3 + // TODO Step 14.3, handle noreferrer flag + // Step 14.5 target_window.load_url(url, new, false, target_document.get_referrer_policy()); } if noopener { - // Step 11 (Dis-owning has been done in create_auxiliary_browsing_context). + // Step 15 (Dis-owning has been done in create_auxiliary_browsing_context). return None; } - // Step 12. + // Step 17. return target_document.browsing_context(); } @@ -590,6 +599,93 @@ impl WindowProxy { } } +// https://html.spec.whatwg.org/multipage/#concept-window-open-features-tokenize +fn tokenize_open_features(features: DOMString) -> IndexMap { + let is_feature_sep = |c: char| c.is_ascii_whitespace() || ['=', ','].contains(&c); + // Step 1 + let mut tokenized_features = IndexMap::new(); + // Step 2 + let mut iter = features.chars(); + let mut cur = iter.next(); + + // Step 3 + while cur != None { + // Step 3.1 & 3.2 + let mut name = String::new(); + let mut value = String::new(); + // Step 3.3 + while let Some(cur_char) = cur { + if !is_feature_sep(cur_char) { + break; + } + cur = iter.next(); + } + // Step 3.4 + while let Some(cur_char) = cur { + if is_feature_sep(cur_char) { + break; + } + name.push(cur_char.to_ascii_lowercase()); + cur = iter.next(); + } + // Step 3.5 + let normalized_name = String::from(match name.as_ref() { + "screenx" => "left", + "screeny" => "top", + "innerwidth" => "width", + "innerheight" => "height", + _ => name.as_ref(), + }); + // Step 3.6 + while let Some(cur_char) = cur { + if cur_char == '=' || cur_char == ',' || !is_feature_sep(cur_char) { + break; + } + cur = iter.next(); + } + // Step 3.7 + if cur.is_some() && is_feature_sep(cur.unwrap()) { + // Step 3.7.1 + while let Some(cur_char) = cur { + if !is_feature_sep(cur_char) || cur_char == ',' { + break; + } + cur = iter.next(); + } + // Step 3.7.2 + while let Some(cur_char) = cur { + if is_feature_sep(cur_char) { + break; + } + value.push(cur_char.to_ascii_lowercase()); + cur = iter.next(); + } + } + // Step 3.8 + if !name.is_empty() { + tokenized_features.insert(normalized_name, value); + } + } + // Step 4 + tokenized_features +} + +// https://html.spec.whatwg.org/multipage/#concept-window-open-features-parse-boolean +fn parse_open_feature_boolean(tokenized_features: &IndexMap, name: &str) -> bool { + if let Some(value) = tokenized_features.get(name) { + // Step 1 & 2 + if value == "" || value == "yes" { + return true; + } + // Step 3 & 4 + if let Ok(int) = parse_integer(value.chars()) { + return int != 0; + } + } + // Step 5 + return false; +} + // This is only called from extern functions, // there's no use using the lifetimed handles here. // https://html.spec.whatwg.org/multipage/#accessing-other-browsing-contexts -- cgit v1.2.3 From 2440e0f98ade12cf595fe7c791a1065b29b53d74 Mon Sep 17 00:00:00 2001 From: Russell Cousineau Date: Sun, 24 Mar 2019 23:04:17 -0700 Subject: set referrer in window.load_url - this conforms to follow-hyperlinks spec step 13 - this conforms to window-open spec step 14.3 - replace uses of `referrer_url` with `referrer` - in Request class, change "no-referrer" to "" - set websocket fetch referrer to "no-referrer" --- components/script/dom/windowproxy.rs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 8a78b661a76..12e726f1752 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -45,6 +45,7 @@ use js::JSCLASS_IS_GLOBAL; use msg::constellation_msg::BrowsingContextId; use msg::constellation_msg::PipelineId; use msg::constellation_msg::TopLevelBrowsingContextId; +use net_traits::request::Referrer; use script_traits::{AuxiliaryBrowsingContextLoadInfo, LoadData, NewLayoutInfo, ScriptMsg}; use servo_url::ServoUrl; use std::cell::Cell; @@ -281,8 +282,8 @@ impl WindowProxy { let load_data = LoadData::new( blank_url, None, + Some(Referrer::ReferrerUrl(document.url().clone())), document.get_referrer_policy(), - Some(document.url().clone()), ); let (pipeline_sender, pipeline_receiver) = ipc::channel().unwrap(); let new_layout_info = NewLayoutInfo { @@ -428,9 +429,20 @@ impl WindowProxy { Ok(url) => url, Err(_) => return None, // TODO: throw a "SyntaxError" DOMException. }; - // TODO Step 14.3, handle noreferrer flag + // Step 14.3 + let referrer = if noreferrer { + Referrer::NoReferrer + } else { + Referrer::Client + }; // Step 14.5 - target_window.load_url(url, new, false, target_document.get_referrer_policy()); + target_window.load_url( + url, + new, + false, + referrer, + target_document.get_referrer_policy(), + ); } if noopener { // Step 15 (Dis-owning has been done in create_auxiliary_browsing_context). -- cgit v1.2.3 From 4328713f71d5bc389ecd47e78bfe9b8087b8c104 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Mon, 6 May 2019 11:38:34 -0400 Subject: Update to SpiderMonkey 66. --- components/script/dom/windowproxy.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 12e726f1752..7b53656e918 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -31,7 +31,7 @@ use js::jsapi::HandleValue as RawHandleValue; use js::jsapi::MutableHandle as RawMutableHandle; use js::jsapi::MutableHandleObject as RawMutableHandleObject; use js::jsapi::MutableHandleValue as RawMutableHandleValue; -use js::jsapi::{JSAutoCompartment, JSContext, JSErrNum, JSFreeOp, JSObject}; +use js::jsapi::{JSAutoRealm, JSContext, JSErrNum, JSFreeOp, JSObject}; use js::jsapi::{JSTracer, JS_DefinePropertyById, JSPROP_ENUMERATE, JSPROP_READONLY}; use js::jsapi::{JS_ForwardGetPropertyTo, JS_ForwardSetPropertyTo}; use js::jsapi::{JS_GetOwnPropertyDescriptorById, JS_IsExceptionPending}; @@ -148,7 +148,7 @@ impl WindowProxy { ((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL), 0 ); - let _ac = JSAutoCompartment::new(cx, window_jsobject.get()); + let _ac = JSAutoRealm::new(cx, window_jsobject.get()); // Create a new window proxy. rooted!(in(cx) let js_proxy = NewWindowProxy(cx, window_jsobject, handler)); @@ -219,7 +219,7 @@ impl WindowProxy { ((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL), 0 ); - let _ac = JSAutoCompartment::new(cx, window_jsobject.get()); + let _ac = JSAutoRealm::new(cx, window_jsobject.get()); // Create a new window proxy. rooted!(in(cx) let js_proxy = NewWindowProxy(cx, window_jsobject, handler)); @@ -548,7 +548,7 @@ impl WindowProxy { ((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL), 0 ); - let _ac = JSAutoCompartment::new(cx, window_jsobject.get()); + let _ac = JSAutoRealm::new(cx, window_jsobject.get()); // The old window proxy no longer owns this browsing context. SetProxyReservedSlot(old_js_proxy.get(), 0, &PrivateValue(ptr::null_mut())); -- cgit v1.2.3 From 63714c90fb5bbad86f28fc188120b2ecfd3337ab Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Sun, 2 Jun 2019 23:38:12 -0400 Subject: Upgrade to Spidermonkey 67. --- components/script/dom/windowproxy.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 7b53656e918..69a73a1547e 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -6,7 +6,7 @@ use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::conversions::{root_from_handleobject, ToJSValConvertible}; use crate::dom::bindings::error::{throw_dom_exception, Error}; use crate::dom::bindings::inheritance::Castable; -use crate::dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor}; +use crate::dom::bindings::proxyhandler::fill_property_descriptor; use crate::dom::bindings::reflector::{DomObject, Reflector}; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::str::DOMString; @@ -712,7 +712,7 @@ unsafe fn GetSubframeWindowProxy( let mut slot = UndefinedValue(); GetProxyPrivate(*proxy, &mut slot); rooted!(in(cx) let target = slot.to_object()); - if let Ok(win) = root_from_handleobject::(target.handle()) { + if let Ok(win) = root_from_handleobject::(target.handle(), cx) { let browsing_context_id = win.window_proxy().browsing_context_id(); let (result_sender, result_receiver) = ipc::channel().unwrap(); @@ -730,7 +730,9 @@ unsafe fn GetSubframeWindowProxy( .and_then(|maybe_bcid| maybe_bcid) .and_then(ScriptThread::find_window_proxy) .map(|proxy| (proxy, (JSPROP_ENUMERATE | JSPROP_READONLY) as u32)); - } else if let Ok(win) = root_from_handleobject::(target.handle()) { + } else if let Ok(win) = + root_from_handleobject::(target.handle(), cx) + { let browsing_context_id = win.window_proxy().browsing_context_id(); let (result_sender, result_receiver) = ipc::channel().unwrap(); @@ -912,7 +914,6 @@ static PROXY_HANDLER: ProxyTraps = ProxyTraps { set: Some(set), call: None, construct: None, - getPropertyDescriptor: Some(get_property_descriptor), hasOwn: None, getOwnEnumerablePropertyKeys: None, nativeCall: None, @@ -1049,7 +1050,6 @@ static XORIGIN_PROXY_HANDLER: ProxyTraps = ProxyTraps { set: Some(set_xorigin), call: None, construct: None, - getPropertyDescriptor: Some(getOwnPropertyDescriptor_xorigin), hasOwn: Some(has_xorigin), getOwnEnumerablePropertyKeys: None, nativeCall: None, -- cgit v1.2.3 From adb402487e7f8bf2cd0a1db360b16592f5c654ed Mon Sep 17 00:00:00 2001 From: Kamil Niski Date: Sat, 4 May 2019 11:27:21 +0200 Subject: Create a helper API for entering a DOM object's compartment Revert some unnecessary changes Fix fmt errors --- components/script/dom/windowproxy.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 69a73a1547e..3a124b70876 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use crate::compartments::enter_realm; use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::conversions::{root_from_handleobject, ToJSValConvertible}; use crate::dom::bindings::error::{throw_dom_exception, Error}; @@ -548,7 +549,7 @@ impl WindowProxy { ((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL), 0 ); - let _ac = JSAutoRealm::new(cx, window_jsobject.get()); + let _ac = enter_realm(&*window); // The old window proxy no longer owns this browsing context. SetProxyReservedSlot(old_js_proxy.get(), 0, &PrivateValue(ptr::null_mut())); -- cgit v1.2.3 From 571beec179fe9fd5fff2c12b3c5dfa0a5d93df01 Mon Sep 17 00:00:00 2001 From: Gregory Terzian Date: Sun, 12 May 2019 17:37:19 +0800 Subject: clean-up navigation security: check target and source origin before executing JS url implement replacement-enabled flag as a HistoryEntryReplacement enum add source origin string on loaddata add LoadOrigin iframe: remove optional load-data auxiliaries: add load-data into info constellation: remove url from Pipeline::new check load origin: link to whatwg issue switch loadorigin toplevel to constellation --- components/script/dom/windowproxy.rs | 41 ++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 13 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 7b53656e918..6e042a16f4b 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -46,7 +46,10 @@ use msg::constellation_msg::BrowsingContextId; use msg::constellation_msg::PipelineId; use msg::constellation_msg::TopLevelBrowsingContextId; use net_traits::request::Referrer; -use script_traits::{AuxiliaryBrowsingContextLoadInfo, LoadData, NewLayoutInfo, ScriptMsg}; +use script_traits::{ + AuxiliaryBrowsingContextLoadInfo, HistoryEntryReplacement, LoadData, LoadOrigin, +}; +use script_traits::{NewLayoutInfo, ScriptMsg}; use servo_url::ServoUrl; use std::cell::Cell; use std::ptr; @@ -267,24 +270,28 @@ impl WindowProxy { let new_browsing_context_id = BrowsingContextId::from(new_top_level_browsing_context_id); let new_pipeline_id = PipelineId::new(); - let load_info = AuxiliaryBrowsingContextLoadInfo { - opener_pipeline_id: self.currently_active.get().unwrap(), - new_browsing_context_id: new_browsing_context_id, - new_top_level_browsing_context_id: new_top_level_browsing_context_id, - new_pipeline_id: new_pipeline_id, - }; let document = self .currently_active .get() .and_then(|id| ScriptThread::find_document(id)) - .unwrap(); + .expect("A WindowProxy creating an auxiliary to have an active document"); + let blank_url = ServoUrl::parse("about:blank").ok().unwrap(); let load_data = LoadData::new( + LoadOrigin::Script(document.origin().immutable().clone()), blank_url, None, Some(Referrer::ReferrerUrl(document.url().clone())), document.get_referrer_policy(), ); + let load_info = AuxiliaryBrowsingContextLoadInfo { + load_data: load_data.clone(), + opener_pipeline_id: self.currently_active.get().unwrap(), + new_browsing_context_id: new_browsing_context_id, + new_top_level_browsing_context_id: new_top_level_browsing_context_id, + new_pipeline_id: new_pipeline_id, + }; + let (pipeline_sender, pipeline_receiver) = ipc::channel().unwrap(); let new_layout_info = NewLayoutInfo { parent_info: None, @@ -436,13 +443,21 @@ impl WindowProxy { Referrer::Client }; // Step 14.5 - target_window.load_url( + let referrer_policy = target_document.get_referrer_policy(); + let pipeline_id = target_window.upcast::().pipeline_id(); + let load_data = LoadData::new( + LoadOrigin::Script(existing_document.origin().immutable().clone()), url, - new, - false, - referrer, - target_document.get_referrer_policy(), + Some(pipeline_id), + Some(referrer), + referrer_policy, ); + let replacement_flag = if new { + HistoryEntryReplacement::Enabled + } else { + HistoryEntryReplacement::Disabled + }; + target_window.load_url(replacement_flag, false, load_data); } if noopener { // Step 15 (Dis-owning has been done in create_auxiliary_browsing_context). -- cgit v1.2.3 From 88cacfb0098e20be70c27bfde6b74cd3290f1fe4 Mon Sep 17 00:00:00 2001 From: marmeladema Date: Mon, 22 Jul 2019 22:14:11 +0100 Subject: Modify *::get_cx methods to return a safe JSContext instead of a raw one --- components/script/dom/windowproxy.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index d527a73c86f..0c7a00978bc 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -152,10 +152,10 @@ impl WindowProxy { ((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL), 0 ); - let _ac = JSAutoRealm::new(cx, window_jsobject.get()); + let _ac = JSAutoRealm::new(*cx, window_jsobject.get()); // Create a new window proxy. - rooted!(in(cx) let js_proxy = NewWindowProxy(cx, window_jsobject, handler)); + rooted!(in(*cx) let js_proxy = NewWindowProxy(*cx, window_jsobject, handler)); assert!(!js_proxy.is_null()); // Create a new browsing context. @@ -178,7 +178,7 @@ impl WindowProxy { ); // Notify the JS engine about the new window proxy binding. - SetWindowProxy(cx, window_jsobject, js_proxy.handle()); + SetWindowProxy(*cx, window_jsobject, js_proxy.handle()); // Set the reflector. debug!( @@ -223,10 +223,10 @@ impl WindowProxy { ((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL), 0 ); - let _ac = JSAutoRealm::new(cx, window_jsobject.get()); + let _ac = JSAutoRealm::new(*cx, window_jsobject.get()); // Create a new window proxy. - rooted!(in(cx) let js_proxy = NewWindowProxy(cx, window_jsobject, handler)); + rooted!(in(*cx) let js_proxy = NewWindowProxy(*cx, window_jsobject, handler)); assert!(!js_proxy.is_null()); // The window proxy owns the browsing context. @@ -238,7 +238,7 @@ impl WindowProxy { ); // Notify the JS engine about the new window proxy binding. - SetWindowProxy(cx, window_jsobject, js_proxy.handle()); + SetWindowProxy(*cx, window_jsobject, js_proxy.handle()); // Set the reflector. debug!( @@ -576,20 +576,20 @@ impl WindowProxy { // of the old window proxy to the new window proxy, then // making the old window proxy a cross-compartment wrapper // pointing to the new window proxy. - rooted!(in(cx) let new_js_proxy = NewWindowProxy(cx, window_jsobject, handler)); + rooted!(in(*cx) let new_js_proxy = NewWindowProxy(*cx, window_jsobject, handler)); debug!( "Transplanting proxy from {:p} to {:p}.", old_js_proxy.get(), new_js_proxy.get() ); - rooted!(in(cx) let new_js_proxy = JS_TransplantObject(cx, old_js_proxy, new_js_proxy.handle())); + 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()); // 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())); // Notify the JS engine about the new window proxy binding. - SetWindowProxy(cx, window_jsobject, new_js_proxy.handle()); + SetWindowProxy(*cx, window_jsobject, new_js_proxy.handle()); // Update the reflector. debug!( -- cgit v1.2.3 From c38c964f1b1d2614f50863be0b896e1700b5fea8 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 31 Jul 2019 13:34:01 +0200 Subject: Upgrade to rustc 1.38.0-nightly (dddb7fca0 2019-07-30) --- components/script/dom/windowproxy.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 0c7a00978bc..dbdd09eabb9 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -525,7 +525,7 @@ impl WindowProxy { } pub fn frame_element(&self) -> Option<&Element> { - self.frame_element.deref() + self.frame_element.as_deref() } pub fn document(&self) -> Option> { @@ -535,7 +535,7 @@ impl WindowProxy { } pub fn parent(&self) -> Option<&WindowProxy> { - self.parent.deref() + self.parent.as_deref() } pub fn top(&self) -> &WindowProxy { -- cgit v1.2.3 From 0703a1ad6d736796d467f5a028e5ab3c6d876268 Mon Sep 17 00:00:00 2001 From: marmeladema Date: Sat, 27 Jul 2019 19:36:21 +0100 Subject: Use safe JSContext as first argument for throw_dom_exception --- components/script/dom/windowproxy.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index dbdd09eabb9..99336ec7f66 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -18,6 +18,7 @@ use crate::dom::document::Document; use crate::dom::element::Element; use crate::dom::globalscope::GlobalScope; use crate::dom::window::Window; +use crate::script_runtime::JSContext as SafeJSContext; use crate::script_thread::ScriptThread; use dom_struct::dom_struct; use embedder_traits::EmbedderMsg; @@ -959,7 +960,7 @@ pub fn new_window_proxy_handler() -> WindowProxyHandler { unsafe fn throw_security_error(cx: *mut JSContext) -> bool { if !JS_IsExceptionPending(cx) { let global = GlobalScope::from_context(cx); - throw_dom_exception(cx, &*global, Error::Security); + throw_dom_exception(SafeJSContext::from_ptr(cx), &*global, Error::Security); } false } -- cgit v1.2.3 From 9acf3f6d4d8630e1b824a7cd652827ba1159e081 Mon Sep 17 00:00:00 2001 From: Gregory Terzian Date: Wed, 14 Aug 2019 20:38:47 +0200 Subject: windowproxy: prevent unnecessary calls to set_window --- components/script/dom/windowproxy.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 0c7a00978bc..d468e234590 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -602,12 +602,23 @@ impl WindowProxy { } pub fn set_currently_active(&self, window: &Window) { - let globalscope = window.upcast(); + let globalscope = window.upcast::(); + let dest_pipeline_id = globalscope.pipeline_id(); + if let Some(pipeline_id) = self.currently_active() { + if pipeline_id == dest_pipeline_id { + return debug!( + "Attempt to set the currently active window to the currently active window." + ); + } + } self.set_window(&*globalscope, &PROXY_HANDLER); self.currently_active.set(Some(globalscope.pipeline_id())); } pub fn unset_currently_active(&self) { + if self.currently_active().is_none() { + return debug!("Attempt to unset the currently active window on a windowproxy that does not have one."); + } let globalscope = self.global(); let window = DissimilarOriginWindow::new(&*globalscope, self); self.set_window(&*window.upcast(), &XORIGIN_PROXY_HANDLER); -- cgit v1.2.3 From 8482d2e781fc948d0d33b0366005264c4f99ccdd Mon Sep 17 00:00:00 2001 From: Gregory Terzian Date: Fri, 9 Aug 2019 15:52:49 +0800 Subject: restructure content process shutdown ack with threaded sender, without layout --- components/script/dom/windowproxy.rs | 1 - 1 file changed, 1 deletion(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 79b93792ce5..d64975a78b9 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -303,7 +303,6 @@ impl WindowProxy { opener: Some(self.browsing_context_id), load_data: load_data, pipeline_port: pipeline_receiver, - content_process_shutdown_chan: None, window_size: window.window_size(), }; let constellation_msg = ScriptMsg::ScriptNewAuxiliary(load_info, pipeline_sender); -- cgit v1.2.3 From ec6b478775056c7cc31509c2a50856b041fb3bf8 Mon Sep 17 00:00:00 2001 From: Bastien Orivel Date: Sat, 24 Aug 2019 16:27:46 +0200 Subject: Update Window::open and document::open parameters to match the spec Fixes #24012 --- components/script/dom/windowproxy.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index d64975a78b9..3ff326c683a 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -10,7 +10,7 @@ use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::proxyhandler::fill_property_descriptor; use crate::dom::bindings::reflector::{DomObject, Reflector}; use crate::dom::bindings::root::{Dom, DomRoot}; -use crate::dom::bindings::str::DOMString; +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}; use crate::dom::dissimilaroriginwindow::DissimilarOriginWindow; @@ -395,7 +395,7 @@ impl WindowProxy { // https://html.spec.whatwg.org/multipage/#window-open-steps pub fn open( &self, - url: DOMString, + url: USVString, target: DOMString, features: DOMString, ) -> Option> { -- cgit v1.2.3 From 45ec250b0a989643865880734ff898de4b15bd7d Mon Sep 17 00:00:00 2001 From: Gregory Terzian Date: Thu, 5 Sep 2019 16:12:52 +0800 Subject: improve spec compliance of discarding BCs do not handle compositor input events when BC is being discarded prevent firing of timers for discarded BCs return null for opener is BC has been discarded bundle discard BC steps into window method return null in window.opener, if BC has already been discarded move the window closed check pre-event to script-thread --- components/script/dom/windowproxy.rs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 3ff326c683a..7fea1728c12 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -96,6 +96,9 @@ pub struct WindowProxy { /// Has the browsing context been disowned? disowned: Cell, + /// https://html.spec.whatwg.org/multipage/#is-closing + is_closing: Cell, + /// The containing iframe element, if this is a same-origin iframe frame_element: Option>, @@ -126,6 +129,7 @@ impl WindowProxy { currently_active: Cell::new(currently_active), discarded: Cell::new(false), disowned: Cell::new(false), + is_closing: Cell::new(false), frame_element: frame_element.map(Dom::from_ref), parent: parent.map(Dom::from_ref), delaying_load_events_mode: Cell::new(false), @@ -352,9 +356,20 @@ impl WindowProxy { self.disowned.set(true); } + /// https://html.spec.whatwg.org/multipage/#dom-window-close + /// Step 3.1, set BCs `is_closing` to true. + pub fn close(&self) { + self.is_closing.set(true); + } + + /// https://html.spec.whatwg.org/multipage/#is-closing + pub fn is_closing(&self) -> bool { + self.is_closing.get() + } + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-opener - pub unsafe fn opener(&self, cx: *mut JSContext) -> JSVal { + pub fn opener(&self, cx: *mut JSContext) -> JSVal { if self.disowned.get() { return NullValue(); } @@ -371,7 +386,7 @@ impl WindowProxy { opener_id, ) { Some(opener_top_id) => { - let global_to_clone_from = GlobalScope::from_context(cx); + let global_to_clone_from = unsafe { GlobalScope::from_context(cx) }; WindowProxy::new_dissimilar_origin( &*global_to_clone_from, opener_id, @@ -388,7 +403,7 @@ impl WindowProxy { return NullValue(); } rooted!(in(cx) let mut val = UndefinedValue()); - opener_proxy.to_jsval(cx, val.handle_mut()); + unsafe { opener_proxy.to_jsval(cx, val.handle_mut()) }; return val.get(); } -- cgit v1.2.3 From 111ede9c77a41ab353f12683a62cd4b4dabb65da Mon Sep 17 00:00:00 2001 From: Patrick Shaughnessy Date: Mon, 6 Jan 2020 14:20:51 -0500 Subject: Make property descriptors hold named/indexed property values --- components/script/dom/windowproxy.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 7fea1728c12..6aa0b9244cf 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -822,8 +822,7 @@ unsafe extern "C" fn getOwnPropertyDescriptor( assert!(desc.obj.is_null() || desc.obj == target.get()); if desc.obj == target.get() { - // FIXME(#11868) Should assign to desc.obj, desc.get() is a copy. - desc.get().obj = proxy.get(); + desc.obj = proxy.get(); } true -- cgit v1.2.3 From f7db4b7f8011239f01c3ba2e5e402c866fbe68fb Mon Sep 17 00:00:00 2001 From: Kunal Mohan Date: Sat, 18 Jan 2020 01:29:26 +0530 Subject: Modify `script` to prevent further violations of snake_case --- components/script/dom/windowproxy.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 6aa0b9244cf..21e40f79989 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -743,7 +743,7 @@ fn parse_open_feature_boolean(tokenized_features: &IndexMap, nam // This is only called from extern functions, // there's no use using the lifetimed handles here. // https://html.spec.whatwg.org/multipage/#accessing-other-browsing-contexts -#[allow(unsafe_code)] +#[allow(unsafe_code, non_snake_case)] unsafe fn GetSubframeWindowProxy( cx: *mut JSContext, proxy: RawHandleObject, @@ -797,7 +797,7 @@ unsafe fn GetSubframeWindowProxy( None } -#[allow(unsafe_code)] +#[allow(unsafe_code, non_snake_case)] unsafe extern "C" fn getOwnPropertyDescriptor( cx: *mut JSContext, proxy: RawHandleObject, @@ -828,7 +828,7 @@ unsafe extern "C" fn getOwnPropertyDescriptor( true } -#[allow(unsafe_code)] +#[allow(unsafe_code, non_snake_case)] unsafe extern "C" fn defineProperty( cx: *mut JSContext, proxy: RawHandleObject, @@ -1044,7 +1044,7 @@ unsafe extern "C" fn delete_xorigin( throw_security_error(cx) } -#[allow(unsafe_code)] +#[allow(unsafe_code, non_snake_case)] unsafe extern "C" fn getOwnPropertyDescriptor_xorigin( cx: *mut JSContext, proxy: RawHandleObject, @@ -1056,7 +1056,7 @@ unsafe extern "C" fn getOwnPropertyDescriptor_xorigin( found && getOwnPropertyDescriptor(cx, proxy, id, desc) } -#[allow(unsafe_code)] +#[allow(unsafe_code, non_snake_case)] unsafe extern "C" fn defineProperty_xorigin( cx: *mut JSContext, _: RawHandleObject, @@ -1067,7 +1067,7 @@ unsafe extern "C" fn defineProperty_xorigin( throw_security_error(cx) } -#[allow(unsafe_code)] +#[allow(unsafe_code, non_snake_case)] unsafe extern "C" fn preventExtensions_xorigin( cx: *mut JSContext, _: RawHandleObject, -- cgit v1.2.3 From 5a3e1b8e6903c825e50597a218532d417f1dfef9 Mon Sep 17 00:00:00 2001 From: Kunal Mohan Date: Fri, 24 Jan 2020 13:29:09 +0530 Subject: rename compartment to realm --- components/script/dom/windowproxy.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 21e40f79989..24afc54a133 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -2,7 +2,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use crate::compartments::enter_realm; use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::conversions::{root_from_handleobject, ToJSValConvertible}; use crate::dom::bindings::error::{throw_dom_exception, Error}; @@ -18,6 +17,7 @@ use crate::dom::document::Document; use crate::dom::element::Element; use crate::dom::globalscope::GlobalScope; use crate::dom::window::Window; +use crate::realms::enter_realm; use crate::script_runtime::JSContext as SafeJSContext; use crate::script_thread::ScriptThread; use dom_struct::dom_struct; @@ -586,10 +586,10 @@ impl WindowProxy { // Brain transpant the window proxy. // We need to do this, because the Window and WindowProxy - // objects need to be in the same compartment. + // objects need to be in the same realm. // JS_TransplantObject does this by copying the contents // of the old window proxy to the new window proxy, then - // making the old window proxy a cross-compartment wrapper + // making the old window proxy a cross-realm wrapper // pointing to the new window proxy. rooted!(in(*cx) let new_js_proxy = NewWindowProxy(*cx, window_jsobject, handler)); debug!( -- cgit v1.2.3 From f29e22f131291ed1bcd581cb9be6807c66c1534e Mon Sep 17 00:00:00 2001 From: Patrick Shaughnessy Date: Tue, 21 Jan 2020 11:06:31 -0500 Subject: Names should now be consistently atoms --- components/script/dom/windowproxy.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 24afc54a133..c910e956e7e 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -81,7 +81,8 @@ pub struct WindowProxy { /// In the case that this is a top-level window, this is our id. top_level_browsing_context_id: TopLevelBrowsingContextId, - /// The name of the browsing context + /// The name of the browsing context (sometimes, but not always, + /// equal to the name of a container element) name: DomRefCell, /// The pipeline id of the currently active document. /// May be None, when the currently active document is in another script thread. -- cgit v1.2.3 From 403ffcf1eb5c659626f70dec72f76aaf7782986d Mon Sep 17 00:00:00 2001 From: CYBAI Date: Fri, 24 Jan 2020 12:43:49 +0900 Subject: Always pass InRealm to GlobalScope::from_context to avoid getting null global --- components/script/dom/windowproxy.rs | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index c910e956e7e..8abbbb480d6 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -17,7 +17,7 @@ use crate::dom::document::Document; use crate::dom::element::Element; use crate::dom::globalscope::GlobalScope; use crate::dom::window::Window; -use crate::realms::enter_realm; +use crate::realms::{enter_realm, AlreadyInRealm, InRealm}; use crate::script_runtime::JSContext as SafeJSContext; use crate::script_thread::ScriptThread; use dom_struct::dom_struct; @@ -370,7 +370,7 @@ impl WindowProxy { #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-opener - pub fn opener(&self, cx: *mut JSContext) -> JSVal { + pub fn opener(&self, cx: *mut JSContext, in_realm_proof: InRealm) -> JSVal { if self.disowned.get() { return NullValue(); } @@ -387,7 +387,8 @@ impl WindowProxy { opener_id, ) { Some(opener_top_id) => { - let global_to_clone_from = unsafe { GlobalScope::from_context(cx) }; + let global_to_clone_from = + unsafe { GlobalScope::from_context(cx, in_realm_proof) }; WindowProxy::new_dissimilar_origin( &*global_to_clone_from, opener_id, @@ -982,10 +983,11 @@ pub fn new_window_proxy_handler() -> WindowProxyHandler { // defined in the DissimilarOriginWindow IDL. #[allow(unsafe_code)] -unsafe fn throw_security_error(cx: *mut JSContext) -> bool { +unsafe fn throw_security_error(cx: *mut JSContext, realm: InRealm) -> bool { if !JS_IsExceptionPending(cx) { - let global = GlobalScope::from_context(cx); - throw_dom_exception(SafeJSContext::from_ptr(cx), &*global, Error::Security); + let safe_context = SafeJSContext::from_ptr(cx); + let global = GlobalScope::from_context(cx, realm); + throw_dom_exception(safe_context, &*global, Error::Security); } false } @@ -1006,7 +1008,8 @@ unsafe extern "C" fn has_xorigin( *bp = true; true } else { - throw_security_error(cx) + let in_realm_proof = AlreadyInRealm::assert_for_cx(SafeJSContext::from_ptr(cx)); + throw_security_error(cx, InRealm::Already(&in_realm_proof)) } } @@ -1032,7 +1035,8 @@ unsafe extern "C" fn set_xorigin( _: RawHandleValue, _: *mut ObjectOpResult, ) -> bool { - throw_security_error(cx) + let in_realm_proof = AlreadyInRealm::assert_for_cx(SafeJSContext::from_ptr(cx)); + throw_security_error(cx, InRealm::Already(&in_realm_proof)) } #[allow(unsafe_code)] @@ -1042,7 +1046,8 @@ unsafe extern "C" fn delete_xorigin( _: RawHandleId, _: *mut ObjectOpResult, ) -> bool { - throw_security_error(cx) + let in_realm_proof = AlreadyInRealm::assert_for_cx(SafeJSContext::from_ptr(cx)); + throw_security_error(cx, InRealm::Already(&in_realm_proof)) } #[allow(unsafe_code, non_snake_case)] @@ -1065,7 +1070,8 @@ unsafe extern "C" fn defineProperty_xorigin( _: RawHandle, _: *mut ObjectOpResult, ) -> bool { - throw_security_error(cx) + let in_realm_proof = AlreadyInRealm::assert_for_cx(SafeJSContext::from_ptr(cx)); + throw_security_error(cx, InRealm::Already(&in_realm_proof)) } #[allow(unsafe_code, non_snake_case)] @@ -1074,7 +1080,8 @@ unsafe extern "C" fn preventExtensions_xorigin( _: RawHandleObject, _: *mut ObjectOpResult, ) -> bool { - throw_security_error(cx) + let in_realm_proof = AlreadyInRealm::assert_for_cx(SafeJSContext::from_ptr(cx)); + throw_security_error(cx, InRealm::Already(&in_realm_proof)) } static XORIGIN_PROXY_HANDLER: ProxyTraps = ProxyTraps { -- cgit v1.2.3 From 14846d0567583d58510565c2223f81883f152262 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Mon, 17 Feb 2020 10:17:47 +0100 Subject: Introduce a new type MaybeUnreflectedDom (fixes #25701) --- components/script/dom/windowproxy.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index c910e956e7e..49927d8c1e3 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -166,7 +166,7 @@ impl WindowProxy { // Create a new browsing context. let current = Some(window.global().pipeline_id()); - let mut window_proxy = Box::new(WindowProxy::new_inherited( + let window_proxy = Box::new(WindowProxy::new_inherited( browsing_context_id, top_level_browsing_context_id, current, @@ -212,7 +212,7 @@ impl WindowProxy { let cx = global_to_clone_from.get_cx(); // Create a new browsing context. - let mut window_proxy = Box::new(WindowProxy::new_inherited( + let window_proxy = Box::new(WindowProxy::new_inherited( browsing_context_id, top_level_browsing_context_id, None, -- cgit v1.2.3 From 86a5cf75aa4b67ded34eaecc0b3eda3d78e47b24 Mon Sep 17 00:00:00 2001 From: Utsav Oza Date: Mon, 4 May 2020 19:02:38 +0530 Subject: Update window.open() to return fallible result --- components/script/dom/windowproxy.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 4155d3626a2..14f9f80e20a 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -4,7 +4,7 @@ use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::conversions::{root_from_handleobject, ToJSValConvertible}; -use crate::dom::bindings::error::{throw_dom_exception, Error}; +use crate::dom::bindings::error::{throw_dom_exception, Error, Fallible}; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::proxyhandler::fill_property_descriptor; use crate::dom::bindings::reflector::{DomObject, Reflector}; @@ -415,7 +415,7 @@ impl WindowProxy { url: USVString, target: DOMString, features: DOMString, - ) -> Option> { + ) -> Fallible>> { // Step 4. let non_empty_target = match target.as_ref() { "" => DOMString::from("_blank"), @@ -433,12 +433,12 @@ impl WindowProxy { // Step 10, 11 let (chosen, new) = match self.choose_browsing_context(non_empty_target, noopener) { (Some(chosen), new) => (chosen, new), - (None, _) => return None, + (None, _) => return Ok(None), }; // TODO Step 12, set up browsing context features. let target_document = match chosen.document() { Some(target_document) => target_document, - None => return None, + None => return Ok(None), }; let target_window = target_document.window(); // Step 13, and 14.4, will have happened elsewhere, @@ -452,7 +452,7 @@ impl WindowProxy { // Step 14.1 let url = match existing_document.url().join(&url) { Ok(url) => url, - Err(_) => return None, // TODO: throw a "SyntaxError" DOMException. + Err(_) => return Err(Error::Syntax), }; // Step 14.3 let referrer = if noreferrer { @@ -479,10 +479,10 @@ impl WindowProxy { } if noopener { // Step 15 (Dis-owning has been done in create_auxiliary_browsing_context). - return None; + return Ok(None); } // Step 17. - return target_document.browsing_context(); + return Ok(target_document.browsing_context()); } // https://html.spec.whatwg.org/multipage/#the-rules-for-choosing-a-browsing-context-given-a-browsing-context-name -- cgit v1.2.3 From ab672577e888c44b4875c9990abfb99ae08fd646 Mon Sep 17 00:00:00 2001 From: Utsav Oza Date: Wed, 13 May 2020 00:30:58 +0530 Subject: Add creator URL, creator base URL and creator origin in browsing context --- components/script/dom/windowproxy.rs | 100 ++++++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 14f9f80e20a..23e4641c4f9 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -52,7 +52,7 @@ use script_traits::{ AuxiliaryBrowsingContextLoadInfo, HistoryEntryReplacement, LoadData, LoadOrigin, }; use script_traits::{NewLayoutInfo, ScriptMsg}; -use servo_url::ServoUrl; +use servo_url::{ImmutableOrigin, ServoUrl}; use std::cell::Cell; use std::ptr; use style::attr::parse_integer; @@ -108,6 +108,15 @@ pub struct WindowProxy { /// https://html.spec.whatwg.org/multipage/#delaying-load-events-mode delaying_load_events_mode: Cell, + + /// The creator browsing context's base url. + creator_base_url: Option, + + /// The creator browsing context's url. + creator_url: Option, + + /// The creator browsing context's origin. + creator_origin: Option, } impl WindowProxy { @@ -118,6 +127,7 @@ impl WindowProxy { frame_element: Option<&Element>, parent: Option<&WindowProxy>, opener: Option, + creator: CreatorBrowsingContextInfo, ) -> WindowProxy { let name = frame_element.map_or(DOMString::new(), |e| { e.get_string_attribute(&local_name!("name")) @@ -135,6 +145,9 @@ impl WindowProxy { parent: parent.map(Dom::from_ref), delaying_load_events_mode: Cell::new(false), opener, + creator_base_url: creator.base_url, + creator_url: creator.url, + creator_origin: creator.origin, } } @@ -146,6 +159,7 @@ impl WindowProxy { frame_element: Option<&Element>, parent: Option<&WindowProxy>, opener: Option, + creator: CreatorBrowsingContextInfo, ) -> DomRoot { unsafe { let WindowProxyHandler(handler) = window.windowproxy_handler(); @@ -173,6 +187,7 @@ impl WindowProxy { frame_element, parent, opener, + creator, )); // The window proxy owns the browsing context. @@ -204,6 +219,7 @@ impl WindowProxy { top_level_browsing_context_id: TopLevelBrowsingContextId, parent: Option<&WindowProxy>, opener: Option, + creator: CreatorBrowsingContextInfo, ) -> DomRoot { unsafe { let handler = CreateWrapperProxyHandler(&XORIGIN_PROXY_HANDLER); @@ -219,6 +235,7 @@ impl WindowProxy { None, parent, opener, + creator, )); // Create a new dissimilar-origin window. @@ -368,6 +385,33 @@ impl WindowProxy { self.is_closing.get() } + /// https://html.spec.whatwg.org/multipage/browsers.html#creator-base-url + pub fn creator_base_url(&self) -> Option { + self.creator_base_url.clone() + } + + pub fn has_creator_base_url(&self) -> bool { + self.creator_base_url.is_some() + } + + /// https://html.spec.whatwg.org/multipage/browsers.html#creator-url + pub fn creator_url(&self) -> Option { + self.creator_url.clone() + } + + pub fn has_creator_url(&self) -> bool { + self.creator_base_url.is_some() + } + + /// https://html.spec.whatwg.org/multipage/browsers.html#creator-origin + pub fn creator_origin(&self) -> Option { + self.creator_origin.clone() + } + + pub fn has_creator_origin(&self) -> bool { + self.creator_origin.is_some() + } + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-opener pub fn opener(&self, cx: *mut JSContext, in_realm_proof: InRealm) -> JSVal { @@ -378,6 +422,7 @@ impl WindowProxy { Some(opener_browsing_context_id) => opener_browsing_context_id, None => return NullValue(), }; + let parent_browsing_context = self.parent.as_deref(); let opener_proxy = match ScriptThread::find_window_proxy(opener_id) { Some(window_proxy) => window_proxy, None => { @@ -389,12 +434,15 @@ impl WindowProxy { Some(opener_top_id) => { let global_to_clone_from = unsafe { GlobalScope::from_context(cx, in_realm_proof) }; + let creator = + CreatorBrowsingContextInfo::from(parent_browsing_context, None); WindowProxy::new_dissimilar_origin( &*global_to_clone_from, opener_id, opener_top_id, None, None, + creator, ) }, None => return NullValue(), @@ -655,6 +703,56 @@ impl WindowProxy { } } +/// A browsing context can have a creator browsing context, the browsing context that +/// was responsible for its creation. If a browsing context has a parent browsing context, +/// then that is its creator browsing context. Otherwise, if the browsing context has an +/// opener browsing context, then that is its creator browsing context. Otherwise, the +/// browsing context has no creator browsing context. +/// +/// If a browsing context A has a creator browsing context, then the Document that was the +/// active document of that creator browsing context at the time A was created is the creator +/// Document. +/// +/// See: https://html.spec.whatwg.org/multipage/browsers.html#creating-browsing-contexts +#[derive(Debug, Deserialize, Serialize)] +pub struct CreatorBrowsingContextInfo { + /// Creator document URL. + url: Option, + + /// Creator document base URL. + base_url: Option, + + /// Creator document origin. + origin: Option, +} + +impl CreatorBrowsingContextInfo { + pub fn from( + parent: Option<&WindowProxy>, + opener: Option<&WindowProxy>, + ) -> CreatorBrowsingContextInfo { + let creator = if parent.is_some() { + parent.unwrap().document() + } else if opener.is_some() { + opener.unwrap().document() + } else { + None + }; + + let base_url = creator.as_deref().map(|document| document.base_url()); + let url = creator.as_deref().map(|document| document.url()); + let origin = creator + .as_deref() + .map(|document| document.origin().immutable().clone()); + + CreatorBrowsingContextInfo { + base_url, + url, + origin, + } + } +} + // https://html.spec.whatwg.org/multipage/#concept-window-open-features-tokenize fn tokenize_open_features(features: DOMString) -> IndexMap { let is_feature_sep = |c: char| c.is_ascii_whitespace() || ['=', ','].contains(&c); -- cgit v1.2.3 From 55a3eb6bf42c013a034168448ed915adae9009b7 Mon Sep 17 00:00:00 2001 From: Utsav Oza Date: Wed, 13 May 2020 00:51:02 +0530 Subject: Run mach test-tidy --- components/script/dom/windowproxy.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 23e4641c4f9..ba2797f6183 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -385,7 +385,7 @@ impl WindowProxy { self.is_closing.get() } - /// https://html.spec.whatwg.org/multipage/browsers.html#creator-base-url + /// https://html.spec.whatwg.org/multipage/#creator-base-url pub fn creator_base_url(&self) -> Option { self.creator_base_url.clone() } @@ -394,7 +394,7 @@ impl WindowProxy { self.creator_base_url.is_some() } - /// https://html.spec.whatwg.org/multipage/browsers.html#creator-url + /// https://html.spec.whatwg.org/multipage/#creator-url pub fn creator_url(&self) -> Option { self.creator_url.clone() } @@ -403,7 +403,7 @@ impl WindowProxy { self.creator_base_url.is_some() } - /// https://html.spec.whatwg.org/multipage/browsers.html#creator-origin + /// https://html.spec.whatwg.org/multipage/#creator-origin pub fn creator_origin(&self) -> Option { self.creator_origin.clone() } @@ -713,7 +713,7 @@ impl WindowProxy { /// active document of that creator browsing context at the time A was created is the creator /// Document. /// -/// See: https://html.spec.whatwg.org/multipage/browsers.html#creating-browsing-contexts +/// See: https://html.spec.whatwg.org/multipage/#creating-browsing-contexts #[derive(Debug, Deserialize, Serialize)] pub struct CreatorBrowsingContextInfo { /// Creator document URL. -- cgit v1.2.3 From 4c637e0601351c052d64c69ec4f806f05a832a80 Mon Sep 17 00:00:00 2001 From: Utsav Oza Date: Thu, 14 May 2020 19:55:37 +0530 Subject: Update wpt-tests metadata --- components/script/dom/windowproxy.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index ba2797f6183..9aac99dc447 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -731,12 +731,10 @@ impl CreatorBrowsingContextInfo { parent: Option<&WindowProxy>, opener: Option<&WindowProxy>, ) -> CreatorBrowsingContextInfo { - let creator = if parent.is_some() { - parent.unwrap().document() - } else if opener.is_some() { - opener.unwrap().document() - } else { - None + let creator = match (parent, opener) { + (Some(parent), _) => parent.document(), + (None, Some(opener)) => opener.document(), + (None, None) => None, }; let base_url = creator.as_deref().map(|document| document.base_url()); -- cgit v1.2.3 From fa18cf620f1c271bee8808026ab40ffbaa11aee6 Mon Sep 17 00:00:00 2001 From: Matthias Deiml Date: Mon, 15 Jun 2020 18:44:59 +0200 Subject: Make url for "client" referrer mandatory --- components/script/dom/windowproxy.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 9aac99dc447..8be356e5ea2 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -305,7 +305,7 @@ impl WindowProxy { LoadOrigin::Script(document.origin().immutable().clone()), blank_url, None, - Some(Referrer::ReferrerUrl(document.url().clone())), + document.global().get_referrer(), document.get_referrer_policy(), ); let load_info = AuxiliaryBrowsingContextLoadInfo { @@ -506,7 +506,7 @@ impl WindowProxy { let referrer = if noreferrer { Referrer::NoReferrer } else { - Referrer::Client + target_window.upcast::().get_referrer() }; // Step 14.5 let referrer_policy = target_document.get_referrer_policy(); @@ -515,7 +515,7 @@ impl WindowProxy { LoadOrigin::Script(existing_document.origin().immutable().clone()), url, Some(pipeline_id), - Some(referrer), + referrer, referrer_policy, ); let replacement_flag = if new { -- cgit v1.2.3 From 0e1479cc847333c81a37d11f0f65f0304972ba3c Mon Sep 17 00:00:00 2001 From: Jonathan Kingston Date: Tue, 24 Nov 2020 02:06:08 +0000 Subject: Add creation url and Secure Contexts --- components/script/dom/windowproxy.rs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 8be356e5ea2..e37e561af06 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -307,6 +307,7 @@ impl WindowProxy { None, document.global().get_referrer(), document.get_referrer_policy(), + None, // Doesn't inherit secure context ); let load_info = AuxiliaryBrowsingContextLoadInfo { load_data: load_data.clone(), @@ -511,12 +512,14 @@ impl WindowProxy { // Step 14.5 let referrer_policy = target_document.get_referrer_policy(); let pipeline_id = target_window.upcast::().pipeline_id(); + let secure = target_window.upcast::().is_secure_context(); let load_data = LoadData::new( LoadOrigin::Script(existing_document.origin().immutable().clone()), url, Some(pipeline_id), referrer, referrer_policy, + Some(secure), ); let replacement_flag = if new { HistoryEntryReplacement::Enabled -- cgit v1.2.3 From d597264d1b2260cd5c8d56116b3eec857c365d58 Mon Sep 17 00:00:00 2001 From: yvt Date: Wed, 7 Jul 2021 22:21:26 +0900 Subject: doc(script): we don't do cross-compartment brain transplantation anymore --- components/script/dom/windowproxy.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'components/script/dom/windowproxy.rs') diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index e37e561af06..0f92e4b3367 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -637,13 +637,11 @@ impl WindowProxy { // The old window proxy no longer owns this browsing context. SetProxyReservedSlot(old_js_proxy.get(), 0, &PrivateValue(ptr::null_mut())); - // Brain transpant the window proxy. - // We need to do this, because the Window and WindowProxy - // objects need to be in the same realm. - // JS_TransplantObject does this by copying the contents - // of the old window proxy to the new window proxy, then - // making the old window proxy a cross-realm wrapper - // pointing to the new window proxy. + // Brain transpant the window proxy. Brain transplantation is + // usually done to move a window proxy between compartments, but + // that's not what we are doing here. We need to do this just + // because we want to replace the wrapper's `ProxyTraps`, but we + // don't want to update its identity. rooted!(in(*cx) let new_js_proxy = NewWindowProxy(*cx, window_jsobject, handler)); debug!( "Transplanting proxy from {:p} to {:p}.", -- cgit v1.2.3