Renamed BrowsingContext to WindowProxy in script.

This commit is contained in:
Alan Jeffrey 2017-05-12 15:02:35 -05:00
parent eeb1ee9723
commit 43ca260689
10 changed files with 150 additions and 157 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -38,8 +38,8 @@ use std::ptr;
// here, in script, but also in the constellation. The constellation // here, in script, but also in the constellation. The constellation
// manages the session history, which in script is accessed through // manages the session history, which in script is accessed through
// History objects, messaging the constellation. // History objects, messaging the constellation.
pub struct BrowsingContext { pub struct WindowProxy {
/// The WindowProxy object. /// The JS WindowProxy object.
/// Unlike other reflectors, we mutate this field because /// Unlike other reflectors, we mutate this field because
/// we have to brain-transplant the reflector when the WindowProxy /// we have to brain-transplant the reflector when the WindowProxy
/// changes Window. /// changes Window.
@ -57,24 +57,24 @@ pub struct BrowsingContext {
/// the change, which could be expensive. /// the change, which could be expensive.
currently_active: Cell<Option<PipelineId>>, currently_active: Cell<Option<PipelineId>>,
/// Has this browsing context been discarded? /// Has the browsing context been discarded?
discarded: Cell<bool>, discarded: Cell<bool>,
/// The containing iframe element, if this is a same-origin iframe /// The containing iframe element, if this is a same-origin iframe
frame_element: Option<JS<Element>>, frame_element: Option<JS<Element>>,
/// The parent browsing context, if this is a nested browsing context /// The parent browsing context's window proxy, if this is a nested browsing context
parent: Option<JS<BrowsingContext>>, parent: Option<JS<WindowProxy>>,
} }
impl BrowsingContext { impl WindowProxy {
pub fn new_inherited(frame_id: FrameId, pub fn new_inherited(frame_id: FrameId,
currently_active: Option<PipelineId>, currently_active: Option<PipelineId>,
frame_element: Option<&Element>, frame_element: Option<&Element>,
parent: Option<&BrowsingContext>) parent: Option<&WindowProxy>)
-> BrowsingContext -> WindowProxy
{ {
BrowsingContext { WindowProxy {
reflector: Reflector::new(), reflector: Reflector::new(),
frame_id: frame_id, frame_id: frame_id,
currently_active: Cell::new(currently_active), currently_active: Cell::new(currently_active),
@ -88,8 +88,8 @@ impl BrowsingContext {
pub fn new(window: &Window, pub fn new(window: &Window,
frame_id: FrameId, frame_id: FrameId,
frame_element: Option<&Element>, frame_element: Option<&Element>,
parent: Option<&BrowsingContext>) parent: Option<&WindowProxy>)
-> Root<BrowsingContext> -> Root<WindowProxy>
{ {
unsafe { unsafe {
let WindowProxyHandler(handler) = window.windowproxy_handler(); let WindowProxyHandler(handler) = window.windowproxy_handler();
@ -102,32 +102,32 @@ impl BrowsingContext {
let _ac = JSAutoCompartment::new(cx, window_jsobject.get()); let _ac = JSAutoCompartment::new(cx, window_jsobject.get());
// Create a new window proxy. // Create a new window proxy.
rooted!(in(cx) let window_proxy = NewWindowProxy(cx, window_jsobject, handler)); rooted!(in(cx) let js_proxy = NewWindowProxy(cx, window_jsobject, handler));
assert!(!window_proxy.is_null()); assert!(!js_proxy.is_null());
// Create a new browsing context. // Create a new browsing context.
let current = Some(window.global().pipeline_id()); 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. // The window proxy owns the browsing context.
// When we finalize the window proxy, it drops the browsing context it owns. // 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. // 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. // Set the reflector.
debug!("Initializing reflector of {:p} to {:p}.", browsing_context, window_proxy.get()); debug!("Initializing reflector of {:p} to {:p}.", window_proxy, js_proxy.get());
browsing_context.reflector.set_jsobject(window_proxy.get()); window_proxy.reflector.set_jsobject(js_proxy.get());
Root::from_ref(&*Box::into_raw(browsing_context)) Root::from_ref(&*Box::into_raw(window_proxy))
} }
} }
#[allow(unsafe_code)] #[allow(unsafe_code)]
pub fn new_dissimilar_origin(global_to_clone_from: &GlobalScope, pub fn new_dissimilar_origin(global_to_clone_from: &GlobalScope,
frame_id: FrameId, frame_id: FrameId,
parent: Option<&BrowsingContext>) parent: Option<&WindowProxy>)
-> Root<BrowsingContext> -> Root<WindowProxy>
{ {
unsafe { unsafe {
let handler = CreateWrapperProxyHandler(&XORIGIN_PROXY_HANDLER); let handler = CreateWrapperProxyHandler(&XORIGIN_PROXY_HANDLER);
@ -136,38 +136,38 @@ impl BrowsingContext {
let cx = global_to_clone_from.get_cx(); let cx = global_to_clone_from.get_cx();
// Create a new browsing context. // 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. // 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(); let window_jsobject = window.reflector().get_jsobject();
assert!(!window_jsobject.get().is_null()); assert!(!window_jsobject.get().is_null());
assert!(((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL) != 0); assert!(((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL) != 0);
let _ac = JSAutoCompartment::new(cx, window_jsobject.get()); let _ac = JSAutoCompartment::new(cx, window_jsobject.get());
// Create a new window proxy. // Create a new window proxy.
rooted!(in(cx) let window_proxy = NewWindowProxy(cx, window_jsobject, handler)); rooted!(in(cx) let js_proxy = NewWindowProxy(cx, window_jsobject, handler));
assert!(!window_proxy.is_null()); assert!(!js_proxy.is_null());
// The window proxy owns the browsing context. // The window proxy owns the browsing context.
// When we finalize the window proxy, it drops the browsing context it owns. // 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. // 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. // Set the reflector.
debug!("Initializing reflector of {:p} to {:p}.", browsing_context, window_proxy.get()); debug!("Initializing reflector of {:p} to {:p}.", window_proxy, js_proxy.get());
browsing_context.reflector.set_jsobject(window_proxy.get()); window_proxy.reflector.set_jsobject(js_proxy.get());
Root::from_ref(&*Box::into_raw(browsing_context)) Root::from_ref(&*Box::into_raw(window_proxy))
} }
} }
pub fn discard(&self) { pub fn discard_browsing_context(&self) {
self.discarded.set(true); self.discarded.set(true);
} }
pub fn is_discarded(&self) -> bool { pub fn is_browsing_context_discarded(&self) -> bool {
self.discarded.get() self.discarded.get()
} }
@ -179,11 +179,11 @@ impl BrowsingContext {
self.frame_element.r() self.frame_element.r()
} }
pub fn parent(&self) -> Option<&BrowsingContext> { pub fn parent(&self) -> Option<&WindowProxy> {
self.parent.r() self.parent.r()
} }
pub fn top(&self) -> &BrowsingContext { pub fn top(&self) -> &WindowProxy {
let mut result = self; let mut result = self;
while let Some(parent) = result.parent() { while let Some(parent) = result.parent() {
result = parent; result = parent;
@ -192,24 +192,24 @@ impl BrowsingContext {
} }
#[allow(unsafe_code)] #[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, // TODO: support setting the window proxy to a dummy value,
// to handle the case when the active document is in another script thread. // 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 { unsafe {
debug!("Setting window proxy of {:p}.", self); debug!("Setting window of {:p}.", self);
let handler = CreateWrapperProxyHandler(traps); let handler = CreateWrapperProxyHandler(traps);
assert!(!handler.is_null()); assert!(!handler.is_null());
let cx = window.get_cx(); let cx = window.get_cx();
let window_jsobject = window.reflector().get_jsobject(); 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!(!window_jsobject.get().is_null());
assert!(((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL) != 0); assert!(((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL) != 0);
let _ac = JSAutoCompartment::new(cx, window_jsobject.get()); let _ac = JSAutoCompartment::new(cx, window_jsobject.get());
// The old window proxy no longer owns this browsing context. // 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. // Brain transpant the window proxy.
// We need to do this, because the Window and WindowProxy // 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 // 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-compartment wrapper
// pointing to the new window proxy. // pointing to the new window proxy.
rooted!(in(cx) let new_window_proxy = NewWindowProxy(cx, window_jsobject, handler)); rooted!(in(cx) let new_js_proxy = NewWindowProxy(cx, window_jsobject, handler));
debug!("Transplanting window proxy from {:p} to {:p}.", old_window_proxy.get(), new_window_proxy.get()); debug!("Transplanting proxy from {:p} to {:p}.", old_js_proxy.get(), new_js_proxy.get());
rooted!(in(cx) let new_window_proxy = JS_TransplantObject(cx, old_window_proxy, new_window_proxy.handle())); rooted!(in(cx) let new_js_proxy = JS_TransplantObject(cx, old_js_proxy, new_js_proxy.handle()));
debug!("Transplanted window proxy is {:p}.", new_window_proxy.get()); debug!("Transplanted proxy is {:p}.", new_js_proxy.get());
// Transfer ownership of this browsing context from the old window proxy to the new one. // 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. // 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. // Update the reflector.
debug!("Setting reflector of {:p} to {:p}.", self, new_window_proxy.get()); debug!("Setting reflector of {:p} to {:p}.", self, new_js_proxy.get());
self.reflector.rootable().set(new_window_proxy.get()); self.reflector.rootable().set(new_js_proxy.get());
} }
} }
pub fn set_currently_active(&self, window: &Window) { pub fn set_currently_active(&self, window: &Window) {
let globalscope = window.upcast(); 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())); self.currently_active.set(Some(globalscope.pipeline_id()));
} }
pub fn unset_currently_active(&self) { pub fn unset_currently_active(&self) {
let globalscope = self.global(); let globalscope = self.global();
let window = DissimilarOriginWindow::new(&*globalscope, self); 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); self.currently_active.set(None);
} }
pub fn currently_active(&self) -> Option<PipelineId> { pub fn currently_active(&self) -> Option<PipelineId> {
self.currently_active.get() 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)] #[allow(unsafe_code)]
@ -581,19 +575,19 @@ static XORIGIN_PROXY_HANDLER: ProxyTraps = ProxyTraps {
#[allow(unsafe_code)] #[allow(unsafe_code)]
unsafe extern fn finalize(_fop: *mut JSFreeOp, obj: *mut JSObject) { 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() { if this.is_null() {
// GC during obj creation or after transplanting. // GC during obj creation or after transplanting.
return; return;
} }
let jsobject = (*this).reflector.get_jsobject().get(); 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); let _ = Box::from_raw(this);
} }
#[allow(unsafe_code)] #[allow(unsafe_code)]
unsafe extern fn trace(trc: *mut JSTracer, obj: *mut JSObject) { 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() { if this.is_null() {
// GC during obj creation or after transplanting. // GC during obj creation or after transplanting.
return; return;

View file

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