diff options
-rw-r--r-- | components/compositing/constellation.rs | 10 | ||||
-rw-r--r-- | components/compositing/pipeline.rs | 7 | ||||
-rw-r--r-- | components/script/dom/browsercontext.rs | 10 | ||||
-rw-r--r-- | components/script/dom/window.rs | 10 | ||||
-rw-r--r-- | components/script/script_task.rs | 26 | ||||
-rw-r--r-- | components/script_traits/lib.rs | 2 | ||||
-rw-r--r-- | tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-2.htm.ini | 4 | ||||
-rw-r--r-- | tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-3.htm.ini | 4 | ||||
-rw-r--r-- | tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-4.htm.ini | 4 | ||||
-rw-r--r-- | tests/wpt/metadata/XMLHttpRequest/open-url-multi-window-5.htm.ini | 4 | ||||
-rw-r--r-- | tests/wpt/metadata/XMLHttpRequest/open-url-multi-window.htm.ini | 4 |
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 |