aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/bindings/trace.rs5
-rw-r--r--components/script/dom/dedicatedworkerglobalscope.rs6
-rw-r--r--components/script/dom/document.rs18
-rw-r--r--components/script/dom/htmliframeelement.rs92
-rw-r--r--components/script/dom/node.rs2
-rw-r--r--components/script/dom/windowproxy.rs25
-rw-r--r--components/script/script_thread.rs78
7 files changed, 164 insertions, 62 deletions
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index 3b96d954dcb..dca1b0e2ea5 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -58,7 +58,7 @@ use js::glue::{CallObjectTracer, CallValueTracer};
use js::jsapi::{GCTraceKindToAscii, Heap, JSObject, JSTracer, TraceKind};
use js::jsval::JSVal;
use js::rust::Runtime;
-use msg::constellation_msg::{BrowsingContextId, FrameType, PipelineId};
+use msg::constellation_msg::{BrowsingContextId, FrameType, PipelineId, TopLevelBrowsingContextId};
use net_traits::{Metadata, NetworkError, ReferrerPolicy, ResourceThreads};
use net_traits::filemanager_thread::RelativePos;
use net_traits::image::base::{Image, ImageMetadata};
@@ -336,7 +336,8 @@ unsafe_no_jsmanaged_fields!(TrustedPromise);
unsafe_no_jsmanaged_fields!(PropertyDeclarationBlock);
// These three are interdependent, if you plan to put jsmanaged data
// in one of these make sure it is propagated properly to containing structs
-unsafe_no_jsmanaged_fields!(DocumentActivity, BrowsingContextId, FrameType, WindowSizeData, WindowSizeType, PipelineId);
+unsafe_no_jsmanaged_fields!(DocumentActivity, WindowSizeData, WindowSizeType);
+unsafe_no_jsmanaged_fields!(BrowsingContextId, FrameType, PipelineId, TopLevelBrowsingContextId);
unsafe_no_jsmanaged_fields!(TimerEventId, TimerSource);
unsafe_no_jsmanaged_fields!(TimelineMarkerType);
unsafe_no_jsmanaged_fields!(WorkerId);
diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs
index 6b73df12dfc..f4de73747c4 100644
--- a/components/script/dom/dedicatedworkerglobalscope.rs
+++ b/components/script/dom/dedicatedworkerglobalscope.rs
@@ -27,7 +27,7 @@ use js::jsapi::{HandleValue, JS_SetInterruptCallback};
use js::jsapi::{JSAutoCompartment, JSContext};
use js::jsval::UndefinedValue;
use js::rust::Runtime;
-use msg::constellation_msg::BrowsingContextId;
+use msg::constellation_msg::TopLevelBrowsingContextId;
use net_traits::{IpcSend, load_whole_resource};
use net_traits::request::{CredentialsMode, Destination, RequestInit, Type as RequestType};
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, StackRootTLS, get_reports, new_rt_and_cx};
@@ -159,13 +159,13 @@ impl DedicatedWorkerGlobalScope {
closing: Arc<AtomicBool>) {
let serialized_worker_url = worker_url.to_string();
let name = format!("WebWorker for {}", serialized_worker_url);
- let top_level_browsing_context_id = BrowsingContextId::installed();
+ let top_level_browsing_context_id = TopLevelBrowsingContextId::installed();
thread::Builder::new().name(name).spawn(move || {
thread_state::initialize(thread_state::SCRIPT | thread_state::IN_WORKER);
if let Some(top_level_browsing_context_id) = top_level_browsing_context_id {
- BrowsingContextId::install(top_level_browsing_context_id);
+ TopLevelBrowsingContextId::install(top_level_browsing_context_id);
}
let roots = RootCollection::new();
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 3bca1dcee9e..378dee975fa 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -100,7 +100,7 @@ use ipc_channel::ipc::{self, IpcSender};
use js::jsapi::{JSContext, JSObject, JSRuntime};
use js::jsapi::JS_GetRuntime;
use msg::constellation_msg::{ALT, CONTROL, SHIFT, SUPER};
-use msg::constellation_msg::{BrowsingContextId, Key, KeyModifiers, KeyState};
+use msg::constellation_msg::{BrowsingContextId, Key, KeyModifiers, KeyState, TopLevelBrowsingContextId};
use net_traits::{FetchResponseMsg, IpcSend, ReferrerPolicy};
use net_traits::CookieSource::NonHTTP;
use net_traits::CoreResourceMsg::{GetCookiesForUrl, SetCookiesForUrl};
@@ -1899,7 +1899,21 @@ impl Document {
/// Find an iframe element in the document.
pub fn find_iframe(&self, browsing_context_id: BrowsingContextId) -> Option<Root<HTMLIFrameElement>> {
self.iter_iframes()
- .find(|node| node.browsing_context_id() == browsing_context_id)
+ .find(|node| node.browsing_context_id() == Some(browsing_context_id))
+ }
+
+ /// Find a mozbrowser iframe element in the document.
+ pub fn find_mozbrowser_iframe(&self,
+ top_level_browsing_context_id: TopLevelBrowsingContextId)
+ -> Option<Root<HTMLIFrameElement>>
+ {
+ match self.find_iframe(BrowsingContextId::from(top_level_browsing_context_id)) {
+ None => None,
+ Some(iframe) => {
+ assert!(iframe.Mozbrowser());
+ Some(iframe)
+ },
+ }
}
pub fn get_dom_loading(&self) -> u64 {
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs
index 8334b4cb421..00755213c75 100644
--- a/components/script/dom/htmliframeelement.rs
+++ b/components/script/dom/htmliframeelement.rs
@@ -40,7 +40,7 @@ use html5ever::{LocalName, Prefix};
use ipc_channel::ipc;
use js::jsapi::{JSAutoCompartment, JSContext, MutableHandleValue};
use js::jsval::{NullValue, UndefinedValue};
-use msg::constellation_msg::{FrameType, BrowsingContextId, PipelineId, TraversalDirection};
+use msg::constellation_msg::{FrameType, BrowsingContextId, PipelineId, TopLevelBrowsingContextId, TraversalDirection};
use net_traits::response::HttpsState;
use script_layout_interface::message::ReflowQueryType;
use script_thread::{ScriptThread, Runnable};
@@ -84,7 +84,8 @@ enum ProcessingMode {
#[dom_struct]
pub struct HTMLIFrameElement {
htmlelement: HTMLElement,
- browsing_context_id: BrowsingContextId,
+ top_level_browsing_context_id: Cell<Option<TopLevelBrowsingContextId>>,
+ browsing_context_id: Cell<Option<BrowsingContextId>>,
pipeline_id: Cell<Option<PipelineId>>,
pending_pipeline_id: Cell<Option<PipelineId>>,
sandbox: MutNullableJS<DOMTokenList>,
@@ -112,13 +113,6 @@ impl HTMLIFrameElement {
}).unwrap_or_else(|| ServoUrl::parse("about:blank").unwrap())
}
- pub fn generate_new_pipeline_id(&self) -> (Option<PipelineId>, PipelineId) {
- let old_pipeline_id = self.pipeline_id.get();
- let new_pipeline_id = PipelineId::new();
- debug!("Frame {} created pipeline {}.", self.browsing_context_id, new_pipeline_id);
- (old_pipeline_id, new_pipeline_id)
- }
-
pub fn navigate_or_reload_child_browsing_context(&self,
load_data: Option<LoadData>,
nav_type: NavigationType,
@@ -129,6 +123,16 @@ impl HTMLIFrameElement {
IFrameUnsandboxed
};
+ let browsing_context_id = match self.browsing_context_id() {
+ None => return warn!("Navigating unattached iframe."),
+ Some(id) => id,
+ };
+
+ let top_level_browsing_context_id = match self.top_level_browsing_context_id() {
+ None => return warn!("Navigating unattached iframe."),
+ Some(id) => id,
+ };
+
let document = document_from_node(self);
let mut load_blocker = self.load_blocker.borrow_mut();
@@ -144,7 +148,8 @@ impl HTMLIFrameElement {
}
let window = window_from_node(self);
- let (old_pipeline_id, new_pipeline_id) = self.generate_new_pipeline_id();
+ let old_pipeline_id = self.pipeline_id();
+ let new_pipeline_id = PipelineId::new();
self.pending_pipeline_id.set(Some(new_pipeline_id));
let private_iframe = self.privatebrowsing();
let frame_type = if self.Mozbrowser() { FrameType::MozBrowserIFrame } else { FrameType::IFrame };
@@ -152,7 +157,8 @@ impl HTMLIFrameElement {
let global_scope = window.upcast::<GlobalScope>();
let load_info = IFrameLoadInfo {
parent_pipeline_id: global_scope.pipeline_id(),
- browsing_context_id: self.browsing_context_id,
+ browsing_context_id: browsing_context_id,
+ top_level_browsing_context_id: top_level_browsing_context_id,
new_pipeline_id: new_pipeline_id,
is_private: private_iframe,
frame_type: frame_type,
@@ -171,7 +177,8 @@ impl HTMLIFrameElement {
let new_layout_info = NewLayoutInfo {
parent_info: Some((global_scope.pipeline_id(), frame_type)),
new_pipeline_id: new_pipeline_id,
- browsing_context_id: self.browsing_context_id,
+ browsing_context_id: browsing_context_id,
+ top_level_browsing_context_id: top_level_browsing_context_id,
load_data: load_data.unwrap(),
pipeline_port: pipeline_receiver,
content_process_shutdown_chan: None,
@@ -246,11 +253,29 @@ impl HTMLIFrameElement {
// Synchronously create a new context and navigate it to about:blank.
let url = ServoUrl::parse("about:blank").unwrap();
let document = document_from_node(self);
- let pipeline_id = Some(window_from_node(self).upcast::<GlobalScope>().pipeline_id());
+ let window = window_from_node(self);
+ let pipeline_id = Some(window.upcast::<GlobalScope>().pipeline_id());
let load_data = LoadData::new(url, pipeline_id, document.get_referrer_policy(), Some(document.url().clone()));
+ let (browsing_context_id, top_level_browsing_context_id) = if self.Mozbrowser() {
+ let top_level_browsing_context_id = TopLevelBrowsingContextId::new();
+ (BrowsingContextId::from(top_level_browsing_context_id), top_level_browsing_context_id)
+ } else {
+ (BrowsingContextId::new(), window.window_proxy().top_level_browsing_context_id())
+ };
+ self.pipeline_id.set(None);
+ self.pending_pipeline_id.set(None);
+ self.top_level_browsing_context_id.set(Some(top_level_browsing_context_id));
+ self.browsing_context_id.set(Some(browsing_context_id));
self.navigate_or_reload_child_browsing_context(Some(load_data), NavigationType::InitialAboutBlank, false);
}
+ fn destroy_nested_browsing_context(&self) {
+ self.pipeline_id.set(None);
+ self.pending_pipeline_id.set(None);
+ self.top_level_browsing_context_id.set(None);
+ self.browsing_context_id.set(None);
+ }
+
pub fn update_pipeline_id(&self, new_pipeline_id: PipelineId, reason: UpdatePipelineIdReason) {
if self.pending_pipeline_id.get() != Some(new_pipeline_id) && reason == UpdatePipelineIdReason::Navigation {
return;
@@ -277,7 +302,8 @@ impl HTMLIFrameElement {
document: &Document) -> HTMLIFrameElement {
HTMLIFrameElement {
htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
- browsing_context_id: BrowsingContextId::new(),
+ browsing_context_id: Cell::new(None),
+ top_level_browsing_context_id: Cell::new(None),
pipeline_id: Cell::new(None),
pending_pipeline_id: Cell::new(None),
sandbox: Default::default(),
@@ -302,8 +328,13 @@ impl HTMLIFrameElement {
}
#[inline]
- pub fn browsing_context_id(&self) -> BrowsingContextId {
- self.browsing_context_id
+ pub fn browsing_context_id(&self) -> Option<BrowsingContextId> {
+ self.browsing_context_id.get()
+ }
+
+ #[inline]
+ pub fn top_level_browsing_context_id(&self) -> Option<TopLevelBrowsingContextId> {
+ self.top_level_browsing_context_id.get()
}
pub fn change_visibility_status(&self, visibility: bool) {
@@ -364,7 +395,7 @@ impl HTMLIFrameElement {
pub trait HTMLIFrameElementLayoutMethods {
fn pipeline_id(&self) -> Option<PipelineId>;
- fn browsing_context_id(&self) -> BrowsingContextId;
+ fn browsing_context_id(&self) -> Option<BrowsingContextId>;
fn get_width(&self) -> LengthOrPercentageOrAuto;
fn get_height(&self) -> LengthOrPercentageOrAuto;
}
@@ -380,9 +411,9 @@ impl HTMLIFrameElementLayoutMethods for LayoutJS<HTMLIFrameElement> {
#[inline]
#[allow(unsafe_code)]
- fn browsing_context_id(&self) -> BrowsingContextId {
+ fn browsing_context_id(&self) -> Option<BrowsingContextId> {
unsafe {
- (*self.unsafe_get()).browsing_context_id
+ (*self.unsafe_get()).browsing_context_id.get()
}
}
@@ -541,7 +572,8 @@ impl HTMLIFrameElementMethods for HTMLIFrameElement {
// https://html.spec.whatwg.org/multipage/#dom-iframe-contentwindow
fn GetContentWindow(&self) -> Option<Root<WindowProxy>> {
- self.pipeline_id.get().and_then(|_| ScriptThread::find_window_proxy(self.browsing_context_id))
+ self.browsing_context_id.get()
+ .and_then(|browsing_context_id| ScriptThread::find_window_proxy(browsing_context_id))
}
// https://html.spec.whatwg.org/multipage/#dom-iframe-contentdocument
@@ -711,7 +743,7 @@ impl VirtualMethods for HTMLIFrameElement {
// is in a document tree and has a browsing context, which is what causes
// the child browsing context to be created.
if self.upcast::<Node>().is_in_doc_with_browsing_context() {
- debug!("iframe {} src set while in browsing context.", self.browsing_context_id);
+ debug!("iframe src set while in browsing context.");
self.process_the_iframe_attributes(ProcessingMode::NotFirstTime);
}
},
@@ -740,7 +772,7 @@ impl VirtualMethods for HTMLIFrameElement {
// to the newly-created browsing context, and then process the
// iframe attributes for the "first time"."
if self.upcast::<Node>().is_in_doc_with_browsing_context() {
- debug!("iframe {} bound to browsing context.", self.browsing_context_id);
+ debug!("iframe bound to browsing context.");
debug_assert!(tree_in_doc, "is_in_doc_with_bc, but not tree_in_doc");
self.create_nested_browsing_context();
self.process_the_iframe_attributes(ProcessingMode::FirstTime);
@@ -754,13 +786,18 @@ impl VirtualMethods for HTMLIFrameElement {
LoadBlocker::terminate(&mut blocker);
// https://html.spec.whatwg.org/multipage/#a-browsing-context-is-discarded
- debug!("Unbinding frame {}.", self.browsing_context_id);
let window = window_from_node(self);
let (sender, receiver) = ipc::channel().unwrap();
// Ask the constellation to remove the iframe, and tell us the
// pipeline ids of the closed pipelines.
- let msg = ConstellationMsg::RemoveIFrame(self.browsing_context_id, sender);
+ let browsing_context_id = match self.browsing_context_id() {
+ None => return warn!("Unbinding already unbound iframe."),
+ Some(id) => id,
+ };
+ debug!("Unbinding frame {}.", browsing_context_id);
+
+ let msg = ConstellationMsg::RemoveIFrame(browsing_context_id, sender);
window.upcast::<GlobalScope>().constellation_chan().send(msg).unwrap();
let exited_pipeline_ids = receiver.recv().unwrap();
@@ -769,9 +806,11 @@ 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) {
+ debug!("Discarding browsing context for pipeline {}", exited_pipeline_id);
exited_document.window().window_proxy().discard_browsing_context();
for exited_iframe in exited_document.iter_iframes() {
- exited_iframe.pipeline_id.set(None);
+ debug!("Discarding nested browsing context");
+ exited_iframe.destroy_nested_browsing_context();
}
}
}
@@ -781,8 +820,7 @@ impl VirtualMethods for HTMLIFrameElement {
// the load doesn't think that it's a navigation, but instead
// a new iframe. Without this, the constellation gets very
// confused.
- self.pipeline_id.set(None);
- self.pending_pipeline_id.set(None);
+ self.destroy_nested_browsing_context();
}
}
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index ff3e5d64787..cc817587eda 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -1136,7 +1136,7 @@ impl LayoutNodeHelpers for LayoutJS<Node> {
fn iframe_browsing_context_id(&self) -> BrowsingContextId {
let iframe_element = self.downcast::<HTMLIFrameElement>()
.expect("not an iframe element!");
- iframe_element.browsing_context_id()
+ iframe_element.browsing_context_id().unwrap()
}
fn iframe_pipeline_id(&self) -> PipelineId {
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<PipelineId>,
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<WindowProxy>
@@ -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<WindowProxy>
{
@@ -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()
}
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index eeab44c4c71..d66baaeda81 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -73,7 +73,7 @@ use js::jsval::UndefinedValue;
use js::rust::Runtime;
use mem::heap_size_of_self_and_children;
use microtask::{MicrotaskQueue, Microtask};
-use msg::constellation_msg::{BrowsingContextId, FrameType, PipelineId, PipelineNamespace};
+use msg::constellation_msg::{BrowsingContextId, FrameType, PipelineId, PipelineNamespace, TopLevelBrowsingContextId};
use net_traits::{CoreResourceMsg, FetchMetadata, FetchResponseListener};
use net_traits::{IpcSend, Metadata, ReferrerPolicy, ResourceThreads};
use net_traits::image_cache::{ImageCache, PendingImageResponse};
@@ -143,8 +143,10 @@ pub unsafe fn trace_thread(tr: *mut JSTracer) {
struct InProgressLoad {
/// The pipeline which requested this load.
pipeline_id: PipelineId,
- /// The frame being loaded into.
+ /// The browsing context being loaded into.
browsing_context_id: BrowsingContextId,
+ /// The top level ancestor browsing context.
+ top_level_browsing_context_id: TopLevelBrowsingContextId,
/// The parent pipeline and frame type associated with this load, if any.
parent_info: Option<(PipelineId, FrameType)>,
/// The current window size associated with this pipeline.
@@ -165,6 +167,7 @@ impl InProgressLoad {
/// Create a new InProgressLoad object.
fn new(id: PipelineId,
browsing_context_id: BrowsingContextId,
+ top_level_browsing_context_id: TopLevelBrowsingContextId,
parent_info: Option<(PipelineId, FrameType)>,
layout_chan: Sender<message::Msg>,
window_size: Option<WindowSizeData>,
@@ -173,6 +176,7 @@ impl InProgressLoad {
InProgressLoad {
pipeline_id: id,
browsing_context_id: browsing_context_id,
+ top_level_browsing_context_id: top_level_browsing_context_id,
parent_info: parent_info,
layout_chan: layout_chan,
window_size: window_size,
@@ -548,11 +552,12 @@ impl ScriptThreadFactory for ScriptThread {
thread::Builder::new().name(format!("ScriptThread {:?}", state.id)).spawn(move || {
thread_state::initialize(thread_state::SCRIPT);
PipelineNamespace::install(state.pipeline_namespace_id);
- BrowsingContextId::install(state.top_level_browsing_context_id);
+ TopLevelBrowsingContextId::install(state.top_level_browsing_context_id);
let roots = RootCollection::new();
let _stack_roots_tls = StackRootTLS::new(&roots);
let id = state.id;
let browsing_context_id = state.browsing_context_id;
+ let top_level_browsing_context_id = state.top_level_browsing_context_id;
let parent_info = state.parent_info;
let mem_profiler_chan = state.mem_profiler_chan.clone();
let window_size = state.window_size;
@@ -567,7 +572,7 @@ impl ScriptThreadFactory for ScriptThread {
let mut failsafe = ScriptMemoryFailsafe::new(&script_thread);
let origin = MutableOrigin::new(load_data.url.origin());
- let new_load = InProgressLoad::new(id, browsing_context_id, parent_info,
+ let new_load = InProgressLoad::new(id, browsing_context_id, top_level_browsing_context_id, parent_info,
layout_chan, window_size, load_data.url.clone(), origin);
script_thread.start_page_load(new_load, load_data);
@@ -1117,10 +1122,10 @@ impl ScriptThread {
ConstellationControlMsg::PostMessage(pipeline_id, origin, data) =>
self.handle_post_message_msg(pipeline_id, origin, data),
ConstellationControlMsg::MozBrowserEvent(parent_pipeline_id,
- browsing_context_id,
+ top_level_browsing_context_id,
event) =>
self.handle_mozbrowser_event_msg(parent_pipeline_id,
- browsing_context_id,
+ top_level_browsing_context_id,
event),
ConstellationControlMsg::UpdatePipelineId(parent_pipeline_id,
browsing_context_id,
@@ -1344,6 +1349,7 @@ impl ScriptThread {
parent_info,
new_pipeline_id,
browsing_context_id,
+ top_level_browsing_context_id,
load_data,
window_size,
pipeline_port,
@@ -1379,9 +1385,14 @@ impl ScriptThread {
};
// Kick off the fetch for the new resource.
- let new_load = InProgressLoad::new(new_pipeline_id, browsing_context_id, parent_info,
- layout_chan, window_size,
- load_data.url.clone(), origin);
+ let new_load = InProgressLoad::new(new_pipeline_id,
+ browsing_context_id,
+ top_level_browsing_context_id,
+ parent_info,
+ layout_chan,
+ window_size,
+ load_data.url.clone(),
+ origin);
if load_data.url.as_str() == "about:blank" {
self.start_page_load_about_blank(new_load);
} else {
@@ -1495,17 +1506,18 @@ impl ScriptThread {
/// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserloadstart
fn handle_mozbrowser_event_msg(&self,
parent_pipeline_id: PipelineId,
- browsing_context_id: Option<BrowsingContextId>,
+ top_level_browsing_context_id: Option<TopLevelBrowsingContextId>,
event: MozBrowserEvent) {
let doc = match { self.documents.borrow().find_document(parent_pipeline_id) } {
None => return warn!("Mozbrowser event after pipeline {} closed.", parent_pipeline_id),
Some(doc) => doc,
};
- match browsing_context_id {
+ match top_level_browsing_context_id {
None => doc.window().dispatch_mozbrowser_event(event),
- Some(browsing_context_id) => match doc.find_iframe(browsing_context_id) {
- None => warn!("Mozbrowser event after iframe {}/{} closed.", parent_pipeline_id, browsing_context_id),
+ Some(top_level_browsing_context_id) => match doc.find_mozbrowser_iframe(top_level_browsing_context_id) {
+ None => warn!("Mozbrowser event after iframe {}/{} closed.",
+ parent_pipeline_id, top_level_browsing_context_id),
Some(frame_element) => frame_element.dispatch_mozbrowser_event(event),
},
}
@@ -1779,9 +1791,10 @@ impl ScriptThread {
// construct a new dissimilar-origin browsing context, add it
// to the `window_proxies` map, and return it.
fn remote_window_proxy(&self,
- global_to_clone: &GlobalScope,
- pipeline_id: PipelineId)
- -> Option<Root<WindowProxy>>
+ global_to_clone: &GlobalScope,
+ top_level_browsing_context_id: TopLevelBrowsingContextId,
+ pipeline_id: PipelineId)
+ -> Option<Root<WindowProxy>>
{
let browsing_context_id = match self.ask_constellation_for_browsing_context_id(pipeline_id) {
Some(browsing_context_id) => browsing_context_id,
@@ -1791,10 +1804,15 @@ impl ScriptThread {
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_window_proxy(global_to_clone, parent_id),
+ Some((parent_id, FrameType::IFrame)) => self.remote_window_proxy(global_to_clone,
+ top_level_browsing_context_id,
+ parent_id),
_ => None,
};
- let window_proxy = WindowProxy::new_dissimilar_origin(global_to_clone, browsing_context_id, parent.r());
+ let window_proxy = WindowProxy::new_dissimilar_origin(global_to_clone,
+ browsing_context_id,
+ top_level_browsing_context_id,
+ parent.r());
self.window_proxies.borrow_mut().insert(browsing_context_id, JS::from_ref(&*window_proxy));
Some(window_proxy)
}
@@ -1806,10 +1824,11 @@ impl ScriptThread {
// construct a new similar-origin browsing context, add it
// to the `window_proxies` map, and return it.
fn local_window_proxy(&self,
- window: &Window,
- browsing_context_id: BrowsingContextId,
- parent_info: Option<(PipelineId, FrameType)>)
- -> Root<WindowProxy>
+ window: &Window,
+ browsing_context_id: BrowsingContextId,
+ top_level_browsing_context_id: TopLevelBrowsingContextId,
+ parent_info: Option<(PipelineId, FrameType)>)
+ -> Root<WindowProxy>
{
if let Some(window_proxy) = self.window_proxies.borrow().get(&browsing_context_id) {
window_proxy.set_currently_active(&*window);
@@ -1821,10 +1840,16 @@ impl ScriptThread {
};
let parent = match (parent_info, iframe.as_ref()) {
(_, Some(iframe)) => Some(window_from_node(&**iframe).window_proxy()),
- (Some((parent_id, FrameType::IFrame)), _) => self.remote_window_proxy(window.upcast(), parent_id),
+ (Some((parent_id, FrameType::IFrame)), _) => self.remote_window_proxy(window.upcast(),
+ top_level_browsing_context_id,
+ parent_id),
_ => None,
};
- let window_proxy = WindowProxy::new(&window, browsing_context_id, iframe.r().map(Castable::upcast), parent.r());
+ let window_proxy = WindowProxy::new(&window,
+ browsing_context_id,
+ top_level_browsing_context_id,
+ iframe.r().map(Castable::upcast),
+ parent.r());
self.window_proxies.borrow_mut().insert(browsing_context_id, JS::from_ref(&*window_proxy));
window_proxy
}
@@ -1882,7 +1907,10 @@ impl ScriptThread {
self.webvr_thread.clone());
// Initialize the browsing context for the window.
- let window_proxy = self.local_window_proxy(&window, incomplete.browsing_context_id, incomplete.parent_info);
+ let window_proxy = self.local_window_proxy(&window,
+ incomplete.browsing_context_id,
+ incomplete.top_level_browsing_context_id,
+ incomplete.parent_info);
window.init_window_proxy(&window_proxy);
let last_modified = metadata.headers.as_ref().and_then(|headers| {