servo: Merge #16845 - Renamed BrowsingContext to WindowProxy in script (from asajeffrey:script-rename-browsing-contexts); r=jdm

<!-- Please describe your changes on the following line: -->

Renamed `script::dom::BrowsingContext` to `script::dom::WindowProxy`.

The browsing context is mostly maintained in the constellation, not in script. It would be nice to rename `constellation::Frame` to `constellation::BrowsingContext`, but that will be very confusing if there are two `BrowsingContext` types.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes do not require tests because renamings aren't externally visible

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

Source-Repo: https://github.com/servo/servo
Source-Revision: 34d0e59849a0a3e231e47fe10d66484340b8b80c

--HG--
rename : servo/components/script/dom/browsingcontext.rs => servo/components/script/dom/windowproxy.rs
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : b6982ad56bf64ced344baceb66c9728e6dad6e6d
This commit is contained in:
Alan Jeffrey 2017-05-13 07:09:29 -05:00
Родитель fd2887981d
Коммит cb93fc35dd
10 изменённых файлов: 150 добавлений и 157 удалений

Просмотреть файл

@ -34,8 +34,7 @@ DOMInterfaces = {
},
'WindowProxy' : {
'nativeType': 'BrowsingContext',
'path': 'dom::browsingcontext::BrowsingContext',
'path': 'dom::windowproxy::WindowProxy',
'register': False,
}

Просмотреть файл

@ -5638,7 +5638,7 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
'dom::bindings::weakref::DOM_WEAK_SLOT',
'dom::bindings::weakref::WeakBox',
'dom::bindings::weakref::WeakReferenceable',
'dom::browsingcontext::BrowsingContext',
'dom::windowproxy::WindowProxy',
'dom::globalscope::GlobalScope',
'mem::heap_size_of_raw_self_and_children',
'libc',

Просмотреть файл

@ -12,7 +12,7 @@ use dom::bindings::error::throw_invalid_this;
use dom::bindings::inheritance::TopTypeId;
use dom::bindings::str::DOMString;
use dom::bindings::trace::trace_object;
use dom::browsingcontext;
use dom::windowproxy;
use heapsize::HeapSizeOf;
use js;
use js::JS_CALLEE;
@ -58,7 +58,7 @@ impl GlobalStaticData {
/// Creates a new GlobalStaticData.
pub fn new() -> GlobalStaticData {
GlobalStaticData {
windowproxy_handler: browsingcontext::new_window_proxy_handler(),
windowproxy_handler: windowproxy::new_window_proxy_handler(),
}
}
}

Просмотреть файл

@ -9,9 +9,9 @@ use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, MutNullableJS, Root};
use dom::bindings::str::DOMString;
use dom::bindings::structuredclone::StructuredCloneData;
use dom::browsingcontext::BrowsingContext;
use dom::dissimilaroriginlocation::DissimilarOriginLocation;
use dom::globalscope::GlobalScope;
use dom::windowproxy::WindowProxy;
use dom_struct::dom_struct;
use ipc_channel::ipc;
use js::jsapi::{JSContext, HandleValue};
@ -28,7 +28,7 @@ use servo_url::ServoUrl;
/// directly, but some of its accessors (for example `window.parent`)
/// still need to function.
///
/// In `browsingcontext.rs`, we create a custom window proxy for these windows,
/// In `windowproxy.rs`, we create a custom window proxy for these windows,
/// that throws security exceptions for most accessors. This is not a replacement
/// for XOWs, but provides belt-and-braces security.
#[dom_struct]
@ -36,8 +36,8 @@ pub struct DissimilarOriginWindow {
/// The global for this window.
globalscope: GlobalScope,
/// The browsing context this window is part of.
browsing_context: JS<BrowsingContext>,
/// The window proxy for this window.
window_proxy: JS<WindowProxy>,
/// The location of this window, initialized lazily.
location: MutNullableJS<DissimilarOriginLocation>,
@ -45,7 +45,7 @@ pub struct DissimilarOriginWindow {
impl DissimilarOriginWindow {
#[allow(unsafe_code)]
pub fn new(global_to_clone_from: &GlobalScope, browsing_context: &BrowsingContext) -> Root<DissimilarOriginWindow> {
pub fn new(global_to_clone_from: &GlobalScope, window_proxy: &WindowProxy) -> Root<DissimilarOriginWindow> {
let cx = global_to_clone_from.get_cx();
// Any timer events fired on this window are ignored.
let (timer_event_chan, _) = ipc::channel().unwrap();
@ -59,7 +59,7 @@ impl DissimilarOriginWindow {
global_to_clone_from.resource_threads().clone(),
timer_event_chan,
global_to_clone_from.origin().clone()),
browsing_context: JS::from_ref(browsing_context),
window_proxy: JS::from_ref(window_proxy),
location: MutNullableJS::new(None),
};
unsafe { DissimilarOriginWindowBinding::Wrap(cx, win) }
@ -73,42 +73,42 @@ impl DissimilarOriginWindow {
impl DissimilarOriginWindowMethods for DissimilarOriginWindow {
// https://html.spec.whatwg.org/multipage/#dom-window
fn Window(&self) -> Root<BrowsingContext> {
Root::from_ref(&*self.browsing_context)
fn Window(&self) -> Root<WindowProxy> {
Root::from_ref(&*self.window_proxy)
}
// https://html.spec.whatwg.org/multipage/#dom-self
fn Self_(&self) -> Root<BrowsingContext> {
Root::from_ref(&*self.browsing_context)
fn Self_(&self) -> Root<WindowProxy> {
Root::from_ref(&*self.window_proxy)
}
// https://html.spec.whatwg.org/multipage/#dom-frames
fn Frames(&self) -> Root<BrowsingContext> {
Root::from_ref(&*self.browsing_context)
fn Frames(&self) -> Root<WindowProxy> {
Root::from_ref(&*self.window_proxy)
}
// https://html.spec.whatwg.org/multipage/#dom-parent
fn GetParent(&self) -> Option<Root<BrowsingContext>> {
fn GetParent(&self) -> Option<Root<WindowProxy>> {
// Steps 1-3.
if self.browsing_context.is_discarded() {
if self.window_proxy.is_browsing_context_discarded() {
return None;
}
// Step 4.
if let Some(parent) = self.browsing_context.parent() {
if let Some(parent) = self.window_proxy.parent() {
return Some(Root::from_ref(parent));
}
// Step 5.
Some(Root::from_ref(&*self.browsing_context))
Some(Root::from_ref(&*self.window_proxy))
}
// https://html.spec.whatwg.org/multipage/#dom-top
fn GetTop(&self) -> Option<Root<BrowsingContext>> {
fn GetTop(&self) -> Option<Root<WindowProxy>> {
// Steps 1-3.
if self.browsing_context.is_discarded() {
if self.window_proxy.is_browsing_context_discarded() {
return None;
}
// Steps 4-5.
Some(Root::from_ref(self.browsing_context.top()))
Some(Root::from_ref(self.window_proxy.top()))
}
// https://html.spec.whatwg.org/multipage/#dom-length
@ -184,7 +184,7 @@ impl DissimilarOriginWindowMethods for DissimilarOriginWindow {
impl DissimilarOriginWindow {
pub fn post_message(&self, origin: Option<ImmutableOrigin>, data: StructuredCloneData) {
let msg = ConstellationMsg::PostMessage(self.browsing_context.frame_id(), origin, data.move_to_arraybuffer());
let msg = ConstellationMsg::PostMessage(self.window_proxy.frame_id(), origin, data.move_to_arraybuffer());
let _ = self.upcast::<GlobalScope>().constellation_chan().send(msg);
}
}

Просмотреть файл

@ -34,7 +34,6 @@ use dom::bindings::reflector::{DomObject, reflect_dom_object};
use dom::bindings::str::{DOMString, USVString};
use dom::bindings::xmlname::{namespace_from_domstring, validate_and_extract, xml_name_type};
use dom::bindings::xmlname::XMLName::InvalidXMLName;
use dom::browsingcontext::BrowsingContext;
use dom::closeevent::CloseEvent;
use dom::comment::Comment;
use dom::customevent::CustomEvent;
@ -89,6 +88,7 @@ use dom::treewalker::TreeWalker;
use dom::uievent::UIEvent;
use dom::webglcontextevent::WebGLContextEvent;
use dom::window::{ReflowReason, Window};
use dom::windowproxy::WindowProxy;
use dom_struct::dom_struct;
use encoding::EncodingRef;
use encoding::all::UTF_8;
@ -401,9 +401,9 @@ impl Document {
/// https://html.spec.whatwg.org/multipage/#concept-document-bc
#[inline]
pub fn browsing_context(&self) -> Option<Root<BrowsingContext>> {
pub fn browsing_context(&self) -> Option<Root<WindowProxy>> {
if self.has_browsing_context {
self.window.maybe_browsing_context()
self.window.maybe_window_proxy()
} else {
None
}

Просмотреть файл

@ -23,7 +23,6 @@ use dom::bindings::js::{LayoutJS, MutNullableJS, Root};
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::DomObject;
use dom::bindings::str::DOMString;
use dom::browsingcontext::BrowsingContext;
use dom::customevent::CustomEvent;
use dom::document::Document;
use dom::domtokenlist::DOMTokenList;
@ -35,6 +34,7 @@ use dom::htmlelement::HTMLElement;
use dom::node::{Node, NodeDamage, UnbindContext, document_from_node, window_from_node};
use dom::virtualmethods::VirtualMethods;
use dom::window::{ReflowReason, Window};
use dom::windowproxy::WindowProxy;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use ipc_channel::ipc;
@ -540,8 +540,8 @@ impl HTMLIFrameElementMethods for HTMLIFrameElement {
}
// https://html.spec.whatwg.org/multipage/#dom-iframe-contentwindow
fn GetContentWindow(&self) -> Option<Root<BrowsingContext>> {
self.pipeline_id.get().and_then(|_| ScriptThread::find_browsing_context(self.frame_id))
fn GetContentWindow(&self) -> Option<Root<WindowProxy>> {
self.pipeline_id.get().and_then(|_| ScriptThread::find_window_proxy(self.frame_id))
}
// https://html.spec.whatwg.org/multipage/#dom-iframe-contentdocument
@ -769,7 +769,7 @@ impl VirtualMethods for HTMLIFrameElement {
// when the `PipelineExit` message arrives.
for exited_pipeline_id in exited_pipeline_ids {
if let Some(exited_document) = ScriptThread::find_document(exited_pipeline_id) {
exited_document.window().browsing_context().discard();
exited_document.window().window_proxy().discard_browsing_context();
for exited_iframe in exited_document.iter_iframes() {
exited_iframe.pipeline_id.set(None);
}

Просмотреть файл

@ -229,7 +229,6 @@ pub mod bluetoothremotegattdescriptor;
pub mod bluetoothremotegattserver;
pub mod bluetoothremotegattservice;
pub mod bluetoothuuid;
pub mod browsingcontext;
pub mod canvasgradient;
pub mod canvaspattern;
pub mod canvasrenderingcontext2d;
@ -465,6 +464,7 @@ pub mod webgltexture;
pub mod webgluniformlocation;
pub mod websocket;
pub mod window;
pub mod windowproxy;
pub mod worker;
pub mod workerglobalscope;
pub mod workerlocation;

Просмотреть файл

@ -30,7 +30,6 @@ use dom::bindings::structuredclone::StructuredCloneData;
use dom::bindings::trace::RootedTraceableBox;
use dom::bindings::utils::{GlobalStaticData, WindowProxyHandler};
use dom::bluetooth::BluetoothExtraPermissionData;
use dom::browsingcontext::BrowsingContext;
use dom::crypto::Crypto;
use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration, CSSStyleOwner};
use dom::document::{AnimationFrameCallback, Document};
@ -49,6 +48,7 @@ use dom::promise::Promise;
use dom::screen::Screen;
use dom::storage::Storage;
use dom::testrunner::TestRunner;
use dom::windowproxy::WindowProxy;
use dom_struct::dom_struct;
use euclid::{Point2D, Rect, Size2D};
use fetch;
@ -175,7 +175,7 @@ pub struct Window {
image_cache: Arc<ImageCache>,
#[ignore_heap_size_of = "channels are hard"]
image_cache_chan: Sender<ImageCacheMsg>,
browsing_context: MutNullableJS<BrowsingContext>,
window_proxy: MutNullableJS<WindowProxy>,
document: MutNullableJS<Document>,
history: MutNullableJS<History>,
performance: MutNullableJS<Performance>,
@ -280,7 +280,7 @@ impl Window {
pub fn clear_js_runtime_for_script_deallocation(&self) {
unsafe {
*self.js_runtime.borrow_for_script_deallocation() = None;
self.browsing_context.set(None);
self.window_proxy.set(None);
self.current_state.set(WindowState::Zombie);
self.ignore_further_async_events.borrow().store(true, Ordering::Relaxed);
}
@ -332,12 +332,12 @@ impl Window {
}
/// This can panic if it is called after the browsing context has been discarded
pub fn browsing_context(&self) -> Root<BrowsingContext> {
self.browsing_context.get().unwrap()
pub fn window_proxy(&self) -> Root<WindowProxy> {
self.window_proxy.get().unwrap()
}
pub fn maybe_browsing_context(&self) -> Option<Root<BrowsingContext>> {
self.browsing_context.get()
pub fn maybe_window_proxy(&self) -> Option<Root<WindowProxy>> {
self.window_proxy.get()
}
pub fn bluetooth_thread(&self) -> IpcSender<BluetoothRequest> {
@ -545,12 +545,12 @@ impl WindowMethods for Window {
// https://html.spec.whatwg.org/multipage/#dom-frameelement
fn GetFrameElement(&self) -> Option<Root<Element>> {
// Steps 1-3.
let context = match self.browsing_context.get() {
let window_proxy = match self.window_proxy.get() {
None => return None,
Some(context) => context,
Some(window_proxy) => window_proxy,
};
// Step 4-5.
let container = match context.frame_element() {
let container = match window_proxy.frame_element() {
None => return None,
Some(container) => container,
};
@ -624,50 +624,50 @@ impl WindowMethods for Window {
}
// https://html.spec.whatwg.org/multipage/#dom-window
fn Window(&self) -> Root<BrowsingContext> {
self.browsing_context()
fn Window(&self) -> Root<WindowProxy> {
self.window_proxy()
}
// https://html.spec.whatwg.org/multipage/#dom-self
fn Self_(&self) -> Root<BrowsingContext> {
self.browsing_context()
fn Self_(&self) -> Root<WindowProxy> {
self.window_proxy()
}
// https://html.spec.whatwg.org/multipage/#dom-frames
fn Frames(&self) -> Root<BrowsingContext> {
self.browsing_context()
fn Frames(&self) -> Root<WindowProxy> {
self.window_proxy()
}
// https://html.spec.whatwg.org/multipage/#dom-parent
fn GetParent(&self) -> Option<Root<BrowsingContext>> {
fn GetParent(&self) -> Option<Root<WindowProxy>> {
// Steps 1-3.
let context = match self.maybe_browsing_context() {
Some(context) => context,
let window_proxy = match self.maybe_window_proxy() {
Some(window_proxy) => window_proxy,
None => return None,
};
if context.is_discarded() {
if window_proxy.is_browsing_context_discarded() {
return None;
}
// Step 4.
if let Some(parent) = context.parent() {
if let Some(parent) = window_proxy.parent() {
return Some(Root::from_ref(parent));
}
// Step 5.
Some(context)
Some(window_proxy)
}
// https://html.spec.whatwg.org/multipage/#dom-top
fn GetTop(&self) -> Option<Root<BrowsingContext>> {
fn GetTop(&self) -> Option<Root<WindowProxy>> {
// Steps 1-3.
let context = match self.maybe_browsing_context() {
Some(context) => context,
let window_proxy = match self.maybe_window_proxy() {
Some(window_proxy) => window_proxy,
None => return None,
};
if context.is_discarded() {
if window_proxy.is_browsing_context_discarded() {
return None;
}
// Steps 4-5.
Some(Root::from_ref(context.top()))
Some(Root::from_ref(window_proxy.top()))
}
// https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/
@ -1036,7 +1036,7 @@ impl Window {
self.current_state.set(WindowState::Zombie);
*self.js_runtime.borrow_mut() = None;
self.browsing_context.set(None);
self.window_proxy.set(None);
self.ignore_further_async_events.borrow().store(true, Ordering::SeqCst);
}
@ -1491,9 +1491,9 @@ impl Window {
}
#[allow(unsafe_code)]
pub fn init_browsing_context(&self, browsing_context: &BrowsingContext) {
assert!(self.browsing_context.get().is_none());
self.browsing_context.set(Some(&browsing_context));
pub fn init_window_proxy(&self, window_proxy: &WindowProxy) {
assert!(self.window_proxy.get().is_none());
self.window_proxy.set(Some(&window_proxy));
}
#[allow(unsafe_code)]
@ -1625,8 +1625,8 @@ impl Window {
self.upcast::<GlobalScope>().suspend();
// Set the window proxy to be a cross-origin window.
if self.browsing_context().currently_active() == Some(self.global().pipeline_id()) {
self.browsing_context().unset_currently_active();
if self.window_proxy().currently_active() == Some(self.global().pipeline_id()) {
self.window_proxy().unset_currently_active();
}
// A hint to the JS runtime that now would be a good time to
@ -1641,7 +1641,7 @@ impl Window {
self.upcast::<GlobalScope>().resume();
// Set the window proxy to be this object.
self.browsing_context().set_currently_active(self);
self.window_proxy().set_currently_active(self);
// Push the document title to the compositor since we are
// activating this document due to a navigation.
@ -1790,7 +1790,7 @@ impl Window {
image_cache: image_cache.clone(),
navigator: Default::default(),
history: Default::default(),
browsing_context: Default::default(),
window_proxy: Default::default(),
document: Default::default(),
performance: Default::default(),
navigation_start: (current_time.sec * 1000 + current_time.nsec as i64 / 1000000) as u64,

Просмотреть файл

@ -38,8 +38,8 @@ use std::ptr;
// 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 BrowsingContext {
/// The WindowProxy object.
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.
@ -57,24 +57,24 @@ pub struct BrowsingContext {
/// the change, which could be expensive.
currently_active: Cell<Option<PipelineId>>,
/// Has this browsing context been discarded?
/// Has the browsing context been discarded?
discarded: Cell<bool>,
/// The containing iframe element, if this is a same-origin iframe
frame_element: Option<JS<Element>>,
/// The parent browsing context, if this is a nested browsing context
parent: Option<JS<BrowsingContext>>,
/// The parent browsing context's window proxy, if this is a nested browsing context
parent: Option<JS<WindowProxy>>,
}
impl BrowsingContext {
impl WindowProxy {
pub fn new_inherited(frame_id: FrameId,
currently_active: Option<PipelineId>,
frame_element: Option<&Element>,
parent: Option<&BrowsingContext>)
-> BrowsingContext
parent: Option<&WindowProxy>)
-> WindowProxy
{
BrowsingContext {
WindowProxy {
reflector: Reflector::new(),
frame_id: frame_id,
currently_active: Cell::new(currently_active),
@ -88,8 +88,8 @@ impl BrowsingContext {
pub fn new(window: &Window,
frame_id: FrameId,
frame_element: Option<&Element>,
parent: Option<&BrowsingContext>)
-> Root<BrowsingContext>
parent: Option<&WindowProxy>)
-> Root<WindowProxy>
{
unsafe {
let WindowProxyHandler(handler) = window.windowproxy_handler();
@ -102,32 +102,32 @@ impl BrowsingContext {
let _ac = JSAutoCompartment::new(cx, window_jsobject.get());
// Create a new window proxy.
rooted!(in(cx) let window_proxy = NewWindowProxy(cx, window_jsobject, handler));
assert!(!window_proxy.is_null());
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 browsing_context = box BrowsingContext::new_inherited(frame_id, current, frame_element, parent);
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(window_proxy.get(), 0, &PrivateValue((&*browsing_context).as_void_ptr()));
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, window_proxy.handle());
SetWindowProxy(cx, window_jsobject, js_proxy.handle());
// Set the reflector.
debug!("Initializing reflector of {:p} to {:p}.", browsing_context, window_proxy.get());
browsing_context.reflector.set_jsobject(window_proxy.get());
Root::from_ref(&*Box::into_raw(browsing_context))
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<&BrowsingContext>)
-> Root<BrowsingContext>
parent: Option<&WindowProxy>)
-> Root<WindowProxy>
{
unsafe {
let handler = CreateWrapperProxyHandler(&XORIGIN_PROXY_HANDLER);
@ -136,38 +136,38 @@ impl BrowsingContext {
let cx = global_to_clone_from.get_cx();
// Create a new browsing context.
let mut browsing_context = box BrowsingContext::new_inherited(frame_id, None, None, parent);
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, &*browsing_context);
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 window_proxy = NewWindowProxy(cx, window_jsobject, handler));
assert!(!window_proxy.is_null());
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(window_proxy.get(), 0, &PrivateValue((&*browsing_context).as_void_ptr()));
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, window_proxy.handle());
SetWindowProxy(cx, window_jsobject, js_proxy.handle());
// Set the reflector.
debug!("Initializing reflector of {:p} to {:p}.", browsing_context, window_proxy.get());
browsing_context.reflector.set_jsobject(window_proxy.get());
Root::from_ref(&*Box::into_raw(browsing_context))
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(&self) {
pub fn discard_browsing_context(&self) {
self.discarded.set(true);
}
pub fn is_discarded(&self) -> bool {
pub fn is_browsing_context_discarded(&self) -> bool {
self.discarded.get()
}
@ -179,11 +179,11 @@ impl BrowsingContext {
self.frame_element.r()
}
pub fn parent(&self) -> Option<&BrowsingContext> {
pub fn parent(&self) -> Option<&WindowProxy> {
self.parent.r()
}
pub fn top(&self) -> &BrowsingContext {
pub fn top(&self) -> &WindowProxy {
let mut result = self;
while let Some(parent) = result.parent() {
result = parent;
@ -192,24 +192,24 @@ impl BrowsingContext {
}
#[allow(unsafe_code)]
/// Change the Window that this browsing context's WindowProxy resolves to.
/// 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_proxy(&self, window: &GlobalScope, traps: &ProxyTraps) {
fn set_window(&self, window: &GlobalScope, traps: &ProxyTraps) {
unsafe {
debug!("Setting window proxy of {:p}.", self);
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_window_proxy = self.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_window_proxy.get(), 0, &PrivateValue(ptr::null_mut()));
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
@ -218,45 +218,39 @@ impl BrowsingContext {
// 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_window_proxy = NewWindowProxy(cx, window_jsobject, handler));
debug!("Transplanting window proxy from {:p} to {:p}.", old_window_proxy.get(), new_window_proxy.get());
rooted!(in(cx) let new_window_proxy = JS_TransplantObject(cx, old_window_proxy, new_window_proxy.handle()));
debug!("Transplanted window proxy is {:p}.", new_window_proxy.get());
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_window_proxy.get(), 0, &PrivateValue(self.as_void_ptr()));
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_window_proxy.handle());
SetWindowProxy(cx, window_jsobject, new_js_proxy.handle());
// Update the reflector.
debug!("Setting reflector of {:p} to {:p}.", self, new_window_proxy.get());
self.reflector.rootable().set(new_window_proxy.get());
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_proxy(&*globalscope, &PROXY_HANDLER);
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_proxy(&*window.upcast(), &XORIGIN_PROXY_HANDLER);
self.set_window(&*window.upcast(), &XORIGIN_PROXY_HANDLER);
self.currently_active.set(None);
}
pub fn currently_active(&self) -> Option<PipelineId> {
self.currently_active.get()
}
pub fn window_proxy(&self) -> *mut JSObject {
let window_proxy = self.reflector.get_jsobject();
assert!(!window_proxy.get().is_null());
window_proxy.get()
}
}
#[allow(unsafe_code)]
@ -581,19 +575,19 @@ 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 BrowsingContext;
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!("BrowsingContext 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) {
let this = GetProxyExtra(obj, 0).to_private() as *const BrowsingContext;
let this = GetProxyExtra(obj, 0).to_private() as *const WindowProxy;
if this.is_null() {
// GC during obj creation or after transplanting.
return;

Просмотреть файл

@ -40,7 +40,6 @@ use dom::bindings::str::DOMString;
use dom::bindings::structuredclone::StructuredCloneData;
use dom::bindings::trace::JSTraceable;
use dom::bindings::utils::WRAP_CALLBACKS;
use dom::browsingcontext::BrowsingContext;
use dom::document::{Document, DocumentSource, FocusType, HasBrowsingContext, IsHTMLDocument, TouchEventResult};
use dom::element::Element;
use dom::event::{Event, EventBubbles, EventCancelable};
@ -55,6 +54,7 @@ use dom::servoparser::{ParserContext, ServoParser};
use dom::transitionevent::TransitionEvent;
use dom::uievent::UIEvent;
use dom::window::{ReflowReason, Window};
use dom::windowproxy::WindowProxy;
use dom::worker::TrustedWorkerAddress;
use euclid::Rect;
use euclid::point::Point2D;
@ -400,9 +400,9 @@ impl<'a> Iterator for DocumentsIter<'a> {
pub struct ScriptThread {
/// The documents for pipelines managed by this thread
documents: DOMRefCell<Documents>,
/// The browsing contexts known by this thread
/// The window proxies known by this thread
/// TODO: this map grows, but never shrinks. Issue #15258.
browsing_contexts: DOMRefCell<HashMap<FrameId, JS<BrowsingContext>>>,
window_proxies: DOMRefCell<HashMap<FrameId, JS<WindowProxy>>>,
/// A list of data pertaining to loads that have not yet received a network response
incomplete_loads: DOMRefCell<Vec<InProgressLoad>>,
/// A map to store service worker registrations for a given origin
@ -656,10 +656,10 @@ impl ScriptThread {
}))
}
pub fn find_browsing_context(id: FrameId) -> Option<Root<BrowsingContext>> {
pub fn find_window_proxy(id: FrameId) -> Option<Root<WindowProxy>> {
SCRIPT_THREAD_ROOT.with(|root| root.get().and_then(|script_thread| {
let script_thread = unsafe { &*script_thread };
script_thread.browsing_contexts.borrow().get(&id)
script_thread.window_proxies.borrow().get(&id)
.map(|context| Root::from_ref(&**context))
}))
}
@ -692,7 +692,7 @@ impl ScriptThread {
ScriptThread {
documents: DOMRefCell::new(Documents::new()),
browsing_contexts: DOMRefCell::new(HashMap::new()),
window_proxies: DOMRefCell::new(HashMap::new()),
incomplete_loads: DOMRefCell::new(vec!()),
registration_map: DOMRefCell::new(HashMap::new()),
job_queue_map: Rc::new(JobQueue::new()),
@ -1559,7 +1559,7 @@ impl ScriptThread {
} else if let Some(document) = self.documents.borrow_mut().remove(id) {
let window = document.window();
if discard_bc == DiscardBrowsingContext::Yes {
window.browsing_context().discard();
window.window_proxy().discard_browsing_context();
}
window.clear_js_runtime();
window.layout_chan().clone()
@ -1682,59 +1682,59 @@ impl ScriptThread {
// Get the browsing context for a pipeline that may exist in another
// script thread. If the browsing context already exists in the
// `browsing_contexts` map, we return it, otherwise we recursively
// `window_proxies` map, we return it, otherwise we recursively
// get the browsing context for the parent if there is one,
// construct a new dissimilar-origin browsing context, add it
// to the `browsing_contexts` map, and return it.
fn remote_browsing_context(&self,
// to the `window_proxies` map, and return it.
fn remote_window_proxy(&self,
global_to_clone: &GlobalScope,
pipeline_id: PipelineId)
-> Option<Root<BrowsingContext>>
-> Option<Root<WindowProxy>>
{
let frame_id = match self.ask_constellation_for_frame_id(pipeline_id) {
Some(frame_id) => frame_id,
None => return None,
};
if let Some(browsing_context) = self.browsing_contexts.borrow().get(&frame_id) {
return Some(Root::from_ref(browsing_context));
if let Some(window_proxy) = self.window_proxies.borrow().get(&frame_id) {
return Some(Root::from_ref(window_proxy));
}
let parent = match self.ask_constellation_for_parent_info(pipeline_id) {
Some((parent_id, FrameType::IFrame)) => self.remote_browsing_context(global_to_clone, parent_id),
Some((parent_id, FrameType::IFrame)) => self.remote_window_proxy(global_to_clone, parent_id),
_ => None,
};
let browsing_context = BrowsingContext::new_dissimilar_origin(global_to_clone, frame_id, parent.r());
self.browsing_contexts.borrow_mut().insert(frame_id, JS::from_ref(&*browsing_context));
Some(browsing_context)
let window_proxy = WindowProxy::new_dissimilar_origin(global_to_clone, frame_id, parent.r());
self.window_proxies.borrow_mut().insert(frame_id, JS::from_ref(&*window_proxy));
Some(window_proxy)
}
// Get the browsing context for a pipeline that exists in this
// script thread. If the browsing context already exists in the
// `browsing_contexts` map, we return it, otherwise we recursively
// `window_proxies` map, we return it, otherwise we recursively
// get the browsing context for the parent if there is one,
// construct a new similar-origin browsing context, add it
// to the `browsing_contexts` map, and return it.
fn local_browsing_context(&self,
// to the `window_proxies` map, and return it.
fn local_window_proxy(&self,
window: &Window,
frame_id: FrameId,
parent_info: Option<(PipelineId, FrameType)>)
-> Root<BrowsingContext>
-> Root<WindowProxy>
{
if let Some(browsing_context) = self.browsing_contexts.borrow().get(&frame_id) {
browsing_context.set_currently_active(&*window);
return Root::from_ref(browsing_context);
if let Some(window_proxy) = self.window_proxies.borrow().get(&frame_id) {
window_proxy.set_currently_active(&*window);
return Root::from_ref(window_proxy);
}
let iframe = match parent_info {
Some((parent_id, FrameType::IFrame)) => self.documents.borrow().find_iframe(parent_id, frame_id),
_ => None,
};
let parent = match (parent_info, iframe.as_ref()) {
(_, Some(iframe)) => Some(window_from_node(&**iframe).browsing_context()),
(Some((parent_id, FrameType::IFrame)), _) => self.remote_browsing_context(window.upcast(), parent_id),
(_, Some(iframe)) => Some(window_from_node(&**iframe).window_proxy()),
(Some((parent_id, FrameType::IFrame)), _) => self.remote_window_proxy(window.upcast(), parent_id),
_ => None,
};
let browsing_context = BrowsingContext::new(&window, frame_id, iframe.r().map(Castable::upcast), parent.r());
self.browsing_contexts.borrow_mut().insert(frame_id, JS::from_ref(&*browsing_context));
browsing_context
let window_proxy = WindowProxy::new(&window, frame_id, iframe.r().map(Castable::upcast), parent.r());
self.window_proxies.borrow_mut().insert(frame_id, JS::from_ref(&*window_proxy));
window_proxy
}
/// The entry point to document loading. Defines bindings, sets up the window and document
@ -1790,8 +1790,8 @@ impl ScriptThread {
self.webvr_thread.clone());
// Initialize the browsing context for the window.
let browsing_context = self.local_browsing_context(&window, incomplete.frame_id, incomplete.parent_info);
window.init_browsing_context(&browsing_context);
let window_proxy = self.local_window_proxy(&window, incomplete.frame_id, incomplete.parent_info);
window.init_window_proxy(&window_proxy);
let last_modified = metadata.headers.as_ref().and_then(|headers| {
headers.get().map(|&LastModified(HttpDate(ref tm))| dom_last_modified(tm))