aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/compositing/constellation.rs10
-rw-r--r--components/compositing/pipeline.rs7
-rw-r--r--components/script/dom/browsercontext.rs10
-rw-r--r--components/script/dom/window.rs10
-rw-r--r--components/script/script_task.rs26
-rw-r--r--components/script_traits/lib.rs2
-rw-r--r--tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-2.htm.ini4
-rw-r--r--tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-3.htm.ini4
-rw-r--r--tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-4.htm.ini4
-rw-r--r--tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-5.htm.ini4
-rw-r--r--tests/wpt/metadata/XMLHttpRequest/open-url-multi-window.htm.ini4
11 files changed, 60 insertions, 25 deletions
diff --git a/components/compositing/constellation.rs b/components/compositing/constellation.rs
index 6b71bcc1c78..0a92cb8566c 100644
--- a/components/compositing/constellation.rs
+++ b/components/compositing/constellation.rs
@@ -393,11 +393,13 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
fn new_pipeline(&mut self,
id: PipelineId,
subpage_id: Option<SubpageId>,
+ parent_id: Option<PipelineId>,
script_pipeline: Option<Rc<Pipeline>>,
load_data: LoadData)
-> Rc<Pipeline> {
let pipe = Pipeline::create::<LTF, STF>(id,
subpage_id,
+ parent_id,
self.chan.clone(),
self.compositor_proxy.clone_compositor_proxy(),
self.devtools_chan.clone(),
@@ -570,7 +572,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
let new_id = self.get_next_pipeline_id();
let new_frame_id = self.get_next_frame_id();
- let pipeline = self.new_pipeline(new_id, subpage_id, None,
+ let pipeline = self.new_pipeline(new_id, subpage_id, None, None,
LoadData::new(Url::parse("about:failure").unwrap()));
self.browse(Some(pipeline_id),
@@ -597,7 +599,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
fn handle_init_load(&mut self, url: Url) {
let next_pipeline_id = self.get_next_pipeline_id();
let next_frame_id = self.get_next_frame_id();
- let pipeline = self.new_pipeline(next_pipeline_id, None, None, LoadData::new(url));
+ let pipeline = self.new_pipeline(next_pipeline_id, None, None, None, LoadData::new(url));
self.browse(None,
Rc::new(FrameTree::new(next_frame_id, pipeline.clone(), None)),
NavigationType::Load);
@@ -783,6 +785,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
let pipeline = self.new_pipeline(
new_frame_pipeline_id,
Some(new_subpage_id),
+ Some(containing_page_pipeline_id),
script_pipeline,
LoadData::new(url)
);
@@ -827,9 +830,10 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
let parent = source_frame.parent.clone();
let subpage_id = source_frame.pipeline.borrow().subpage_id;
+ let parent_id = source_frame.pipeline.borrow().parent_id;
let next_pipeline_id = self.get_next_pipeline_id();
let next_frame_id = self.get_next_frame_id();
- let pipeline = self.new_pipeline(next_pipeline_id, subpage_id, None, load_data);
+ let pipeline = self.new_pipeline(next_pipeline_id, subpage_id, parent_id, None, load_data);
self.browse(Some(source_id),
Rc::new(FrameTree::new(next_frame_id,
pipeline.clone(),
diff --git a/components/compositing/pipeline.rs b/components/compositing/pipeline.rs
index 9442b56099b..7d2c103b200 100644
--- a/components/compositing/pipeline.rs
+++ b/components/compositing/pipeline.rs
@@ -24,6 +24,7 @@ use std::sync::mpsc::{Receiver, channel};
pub struct Pipeline {
pub id: PipelineId,
pub subpage_id: Option<SubpageId>,
+ pub parent_id: Option<PipelineId>,
pub script_chan: ScriptControlChan,
pub layout_chan: LayoutControlChan,
pub paint_chan: PaintChan,
@@ -49,6 +50,7 @@ impl Pipeline {
/// If script_pipeline is not None, then subpage_id must also be not None.
pub fn create<LTF,STF>(id: PipelineId,
subpage_id: Option<SubpageId>,
+ parent_id: Option<PipelineId>,
constellation_chan: ConstellationChan,
compositor_proxy: Box<CompositorProxy+'static+Send>,
devtools_chan: Option<DevtoolsControlChan>,
@@ -130,6 +132,7 @@ impl Pipeline {
Pipeline::new(id,
subpage_id,
+ parent_id,
script_chan,
LayoutControlChan(pipeline_chan),
paint_chan,
@@ -140,6 +143,7 @@ impl Pipeline {
pub fn new(id: PipelineId,
subpage_id: Option<SubpageId>,
+ parent_id: Option<PipelineId>,
script_chan: ScriptControlChan,
layout_chan: LayoutControlChan,
paint_chan: PaintChan,
@@ -150,6 +154,7 @@ impl Pipeline {
Pipeline {
id: id,
subpage_id: subpage_id,
+ parent_id: parent_id,
script_chan: script_chan,
layout_chan: layout_chan,
paint_chan: paint_chan,
@@ -162,7 +167,7 @@ impl Pipeline {
pub fn load(&self) {
let ScriptControlChan(ref chan) = self.script_chan;
- chan.send(ConstellationControlMsg::Load(self.id, self.load_data.clone())).unwrap();
+ chan.send(ConstellationControlMsg::Load(self.id, self.parent_id, self.load_data.clone())).unwrap();
}
pub fn grant_paint_permission(&self) {
diff --git a/components/script/dom/browsercontext.rs b/components/script/dom/browsercontext.rs
index 3d486a3fe11..f7572d6d6a7 100644
--- a/components/script/dom/browsercontext.rs
+++ b/components/script/dom/browsercontext.rs
@@ -33,14 +33,16 @@ pub struct BrowserContext {
history: Vec<SessionHistoryEntry>,
active_index: uint,
window_proxy: *mut JSObject,
+ parent: Option<JS<Window>>,
}
impl BrowserContext {
- pub fn new(document: JSRef<Document>) -> BrowserContext {
+ pub fn new(document: JSRef<Document>, parent: Option<JSRef<Window>>) -> BrowserContext {
let mut context = BrowserContext {
history: vec!(SessionHistoryEntry::new(document)),
active_index: 0,
window_proxy: ptr::null_mut(),
+ parent: parent.map(|p| JS::from_rooted(p)),
};
context.create_window_proxy();
context
@@ -60,6 +62,12 @@ impl BrowserContext {
self.window_proxy
}
+ pub fn parent(&self) -> Option<Temporary<Window>> {
+ self.parent.map(|p| {
+ p.root().browser_context().as_ref().unwrap().active_window()
+ })
+ }
+
#[allow(unsafe_blocks)]
fn create_window_proxy(&mut self) {
let win = self.active_window().root();
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 5477f7a3d65..d1d76cfaa4e 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -272,9 +272,9 @@ impl<'a> WindowMethods for JSRef<'a, Window> {
self.Window()
}
+ // https://html.spec.whatwg.org/multipage/browsers.html#dom-parent
fn Parent(self) -> Temporary<Window> {
- //TODO - Once we support iframes correctly this needs to return the parent frame
- self.Window()
+ self.browser_context().as_ref().unwrap().parent().unwrap_or(self.Window())
}
fn Performance(self) -> Temporary<Performance> {
@@ -314,7 +314,7 @@ impl<'a> WindowMethods for JSRef<'a, Window> {
pub trait WindowHelpers {
fn flush_layout(self, goal: ReflowGoal, query: ReflowQueryType);
- fn init_browser_context(self, doc: JSRef<Document>);
+ fn init_browser_context(self, doc: JSRef<Document>, parent: Option<JSRef<Window>>);
fn load_url(self, href: DOMString);
fn handle_fire_timer(self, timer_id: TimerId);
fn IndexedGetter(self, _index: u32, _found: &mut bool) -> Option<Temporary<Window>>;
@@ -357,8 +357,8 @@ impl<'a> WindowHelpers for JSRef<'a, Window> {
self.page().flush_layout(goal, query);
}
- fn init_browser_context(self, doc: JSRef<Document>) {
- *self.browser_context.borrow_mut() = Some(BrowserContext::new(doc));
+ fn init_browser_context(self, doc: JSRef<Document>, parent: Option<JSRef<Window>>) {
+ *self.browser_context.borrow_mut() = Some(BrowserContext::new(doc, parent));
}
/// Commence a new URL load which will either replace this window or scroll to a fragment.
diff --git a/components/script/script_task.rs b/components/script/script_task.rs
index 2d64f53b396..287b6c61adf 100644
--- a/components/script/script_task.rs
+++ b/components/script/script_task.rs
@@ -581,8 +581,8 @@ impl ScriptTask {
match msg {
ConstellationControlMsg::AttachLayout(_) =>
panic!("should have handled AttachLayout already"),
- ConstellationControlMsg::Load(id, load_data) =>
- self.load(id, load_data),
+ ConstellationControlMsg::Load(id, parent_id, load_data) =>
+ self.load(id, parent_id, load_data),
ConstellationControlMsg::SendEvent(id, event) =>
self.handle_event(id, event),
ConstellationControlMsg::ReflowComplete(id, reflow_id) =>
@@ -757,12 +757,26 @@ impl ScriptTask {
/// The entry point to document loading. Defines bindings, sets up the window and document
/// objects, parses HTML and CSS, and kicks off initial layout.
- fn load(&self, pipeline_id: PipelineId, load_data: LoadData) {
+ fn load(&self, pipeline_id: PipelineId, parent_id: Option<PipelineId>, load_data: LoadData) {
let url = load_data.url.clone();
debug!("ScriptTask: loading {:?} on page {:?}", url, pipeline_id);
- let page = self.page.borrow_mut();
- let page = page.find(pipeline_id).expect("ScriptTask: received a load
+ let borrowed_page = self.page.borrow_mut();
+
+ let parent_window = parent_id.and_then(|pid| {
+ // In the case a parent id exists but the matching page
+ // cannot be found, this means the page exists in a different
+ // script task (due to origin) so it shouldn't be returned.
+ // TODO: window.parent will continue to return self in that
+ // case, which is wrong. We should be returning an object that
+ // denies access to most properties (per
+ // https://github.com/servo/servo/issues/3939#issuecomment-62287025).
+ borrowed_page.find(pid).and_then(|page| {
+ Some(*page.frame.borrow().as_ref().unwrap().window.root())
+ })
+ });
+
+ let page = borrowed_page.find(pipeline_id).expect("ScriptTask: received a load
message for a layout channel that is not associated with this script task. This
is a bug.");
@@ -841,7 +855,7 @@ impl ScriptTask {
if let Some(tm) = last_modified {
document.set_last_modified(dom_last_modified(&tm));
}
- window.r().init_browser_context(document.r());
+ window.r().init_browser_context(document.r(), parent_window);
{
diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs
index 8864b9caf43..9e6ab9140c0 100644
--- a/components/script_traits/lib.rs
+++ b/components/script_traits/lib.rs
@@ -56,7 +56,7 @@ pub struct NewLayoutInfo {
/// Messages sent from the constellation to the script task
pub enum ConstellationControlMsg {
/// Loads a new URL on the specified pipeline.
- Load(PipelineId, LoadData),
+ Load(PipelineId, Option<PipelineId>, LoadData),
/// Gives a channel and ID to a layout task, as well as the ID of that layout's parent
AttachLayout(NewLayoutInfo),
/// Window resized. Sends a DOM event eventually, but first we combine events.
diff --git a/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-2.htm.ini b/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-2.htm.ini
index ff922c6820a..862b46c6127 100644
--- a/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-2.htm.ini
+++ b/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-2.htm.ini
@@ -1,3 +1,5 @@
[open-url-multi-window-2.htm]
type: testharness
- expected: TIMEOUT
+ expected: OK
+ [XMLHttpRequest: open() resolving URLs (multi-Window; 2; evil)]
+ expected: FAIL
diff --git a/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-3.htm.ini b/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-3.htm.ini
index 9e3820745cb..97a29e015d1 100644
--- a/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-3.htm.ini
+++ b/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-3.htm.ini
@@ -1,3 +1,5 @@
[open-url-multi-window-3.htm]
type: testharness
- expected: TIMEOUT
+ expected: OK
+ [XMLHttpRequest: open() resolving URLs (multi-Window; 3; evil)]
+ expected: FAIL
diff --git a/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-4.htm.ini b/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-4.htm.ini
index 74d450582dd..222b2c97c7d 100644
--- a/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-4.htm.ini
+++ b/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-4.htm.ini
@@ -1,6 +1,6 @@
[open-url-multi-window-4.htm]
type: testharness
- expected: TIMEOUT
+ expected: OK
[XMLHttpRequest: open() resolving URLs (multi-Window; 4; evil)]
- expected: NOTRUN
+ expected: FAIL
diff --git a/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-5.htm.ini b/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-5.htm.ini
index 37a52227ee4..be714b4625f 100644
--- a/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-5.htm.ini
+++ b/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-5.htm.ini
@@ -1,6 +1,6 @@
[open-url-multi-window-5.htm]
type: testharness
- expected: TIMEOUT
+ expected: OK
[XMLHttpRequest: open() resolving URLs (multi-Window; 5)]
- expected: NOTRUN
+ expected: FAIL
diff --git a/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window.htm.ini b/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window.htm.ini
index ed241d0335a..0330785ec1b 100644
--- a/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window.htm.ini
+++ b/tests/wpt/metadata/XMLHttpRequest/open-url-multi-window.htm.ini
@@ -1,6 +1,6 @@
[open-url-multi-window.htm]
type: testharness
- expected: TIMEOUT
+ expected: OK
[XMLHttpRequest: open() resolving URLs (multi-Window; 1)]
- expected: NOTRUN
+ expected: FAIL