mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Implement window.parent for iframes.
This commit is contained in:
parent
7e3f504d94
commit
0873e5c8ca
11 changed files with 60 additions and 25 deletions
|
@ -393,11 +393,13 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||||
fn new_pipeline(&mut self,
|
fn new_pipeline(&mut self,
|
||||||
id: PipelineId,
|
id: PipelineId,
|
||||||
subpage_id: Option<SubpageId>,
|
subpage_id: Option<SubpageId>,
|
||||||
|
parent_id: Option<PipelineId>,
|
||||||
script_pipeline: Option<Rc<Pipeline>>,
|
script_pipeline: Option<Rc<Pipeline>>,
|
||||||
load_data: LoadData)
|
load_data: LoadData)
|
||||||
-> Rc<Pipeline> {
|
-> Rc<Pipeline> {
|
||||||
let pipe = Pipeline::create::<LTF, STF>(id,
|
let pipe = Pipeline::create::<LTF, STF>(id,
|
||||||
subpage_id,
|
subpage_id,
|
||||||
|
parent_id,
|
||||||
self.chan.clone(),
|
self.chan.clone(),
|
||||||
self.compositor_proxy.clone_compositor_proxy(),
|
self.compositor_proxy.clone_compositor_proxy(),
|
||||||
self.devtools_chan.clone(),
|
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_id = self.get_next_pipeline_id();
|
||||||
let new_frame_id = self.get_next_frame_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()));
|
LoadData::new(Url::parse("about:failure").unwrap()));
|
||||||
|
|
||||||
self.browse(Some(pipeline_id),
|
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) {
|
fn handle_init_load(&mut self, url: Url) {
|
||||||
let next_pipeline_id = self.get_next_pipeline_id();
|
let next_pipeline_id = self.get_next_pipeline_id();
|
||||||
let next_frame_id = self.get_next_frame_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,
|
self.browse(None,
|
||||||
Rc::new(FrameTree::new(next_frame_id, pipeline.clone(), None)),
|
Rc::new(FrameTree::new(next_frame_id, pipeline.clone(), None)),
|
||||||
NavigationType::Load);
|
NavigationType::Load);
|
||||||
|
@ -783,6 +785,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||||
let pipeline = self.new_pipeline(
|
let pipeline = self.new_pipeline(
|
||||||
new_frame_pipeline_id,
|
new_frame_pipeline_id,
|
||||||
Some(new_subpage_id),
|
Some(new_subpage_id),
|
||||||
|
Some(containing_page_pipeline_id),
|
||||||
script_pipeline,
|
script_pipeline,
|
||||||
LoadData::new(url)
|
LoadData::new(url)
|
||||||
);
|
);
|
||||||
|
@ -827,9 +830,10 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||||
|
|
||||||
let parent = source_frame.parent.clone();
|
let parent = source_frame.parent.clone();
|
||||||
let subpage_id = source_frame.pipeline.borrow().subpage_id;
|
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_pipeline_id = self.get_next_pipeline_id();
|
||||||
let next_frame_id = self.get_next_frame_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),
|
self.browse(Some(source_id),
|
||||||
Rc::new(FrameTree::new(next_frame_id,
|
Rc::new(FrameTree::new(next_frame_id,
|
||||||
pipeline.clone(),
|
pipeline.clone(),
|
||||||
|
|
|
@ -24,6 +24,7 @@ use std::sync::mpsc::{Receiver, channel};
|
||||||
pub struct Pipeline {
|
pub struct Pipeline {
|
||||||
pub id: PipelineId,
|
pub id: PipelineId,
|
||||||
pub subpage_id: Option<SubpageId>,
|
pub subpage_id: Option<SubpageId>,
|
||||||
|
pub parent_id: Option<PipelineId>,
|
||||||
pub script_chan: ScriptControlChan,
|
pub script_chan: ScriptControlChan,
|
||||||
pub layout_chan: LayoutControlChan,
|
pub layout_chan: LayoutControlChan,
|
||||||
pub paint_chan: PaintChan,
|
pub paint_chan: PaintChan,
|
||||||
|
@ -49,6 +50,7 @@ impl Pipeline {
|
||||||
/// If script_pipeline is not None, then subpage_id must also be not None.
|
/// If script_pipeline is not None, then subpage_id must also be not None.
|
||||||
pub fn create<LTF,STF>(id: PipelineId,
|
pub fn create<LTF,STF>(id: PipelineId,
|
||||||
subpage_id: Option<SubpageId>,
|
subpage_id: Option<SubpageId>,
|
||||||
|
parent_id: Option<PipelineId>,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
compositor_proxy: Box<CompositorProxy+'static+Send>,
|
compositor_proxy: Box<CompositorProxy+'static+Send>,
|
||||||
devtools_chan: Option<DevtoolsControlChan>,
|
devtools_chan: Option<DevtoolsControlChan>,
|
||||||
|
@ -130,6 +132,7 @@ impl Pipeline {
|
||||||
|
|
||||||
Pipeline::new(id,
|
Pipeline::new(id,
|
||||||
subpage_id,
|
subpage_id,
|
||||||
|
parent_id,
|
||||||
script_chan,
|
script_chan,
|
||||||
LayoutControlChan(pipeline_chan),
|
LayoutControlChan(pipeline_chan),
|
||||||
paint_chan,
|
paint_chan,
|
||||||
|
@ -140,6 +143,7 @@ impl Pipeline {
|
||||||
|
|
||||||
pub fn new(id: PipelineId,
|
pub fn new(id: PipelineId,
|
||||||
subpage_id: Option<SubpageId>,
|
subpage_id: Option<SubpageId>,
|
||||||
|
parent_id: Option<PipelineId>,
|
||||||
script_chan: ScriptControlChan,
|
script_chan: ScriptControlChan,
|
||||||
layout_chan: LayoutControlChan,
|
layout_chan: LayoutControlChan,
|
||||||
paint_chan: PaintChan,
|
paint_chan: PaintChan,
|
||||||
|
@ -150,6 +154,7 @@ impl Pipeline {
|
||||||
Pipeline {
|
Pipeline {
|
||||||
id: id,
|
id: id,
|
||||||
subpage_id: subpage_id,
|
subpage_id: subpage_id,
|
||||||
|
parent_id: parent_id,
|
||||||
script_chan: script_chan,
|
script_chan: script_chan,
|
||||||
layout_chan: layout_chan,
|
layout_chan: layout_chan,
|
||||||
paint_chan: paint_chan,
|
paint_chan: paint_chan,
|
||||||
|
@ -162,7 +167,7 @@ impl Pipeline {
|
||||||
|
|
||||||
pub fn load(&self) {
|
pub fn load(&self) {
|
||||||
let ScriptControlChan(ref chan) = self.script_chan;
|
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) {
|
pub fn grant_paint_permission(&self) {
|
||||||
|
|
|
@ -33,14 +33,16 @@ pub struct BrowserContext {
|
||||||
history: Vec<SessionHistoryEntry>,
|
history: Vec<SessionHistoryEntry>,
|
||||||
active_index: uint,
|
active_index: uint,
|
||||||
window_proxy: *mut JSObject,
|
window_proxy: *mut JSObject,
|
||||||
|
parent: Option<JS<Window>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BrowserContext {
|
impl BrowserContext {
|
||||||
pub fn new(document: JSRef<Document>) -> BrowserContext {
|
pub fn new(document: JSRef<Document>, parent: Option<JSRef<Window>>) -> BrowserContext {
|
||||||
let mut context = BrowserContext {
|
let mut context = BrowserContext {
|
||||||
history: vec!(SessionHistoryEntry::new(document)),
|
history: vec!(SessionHistoryEntry::new(document)),
|
||||||
active_index: 0,
|
active_index: 0,
|
||||||
window_proxy: ptr::null_mut(),
|
window_proxy: ptr::null_mut(),
|
||||||
|
parent: parent.map(|p| JS::from_rooted(p)),
|
||||||
};
|
};
|
||||||
context.create_window_proxy();
|
context.create_window_proxy();
|
||||||
context
|
context
|
||||||
|
@ -60,6 +62,12 @@ impl BrowserContext {
|
||||||
self.window_proxy
|
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)]
|
#[allow(unsafe_blocks)]
|
||||||
fn create_window_proxy(&mut self) {
|
fn create_window_proxy(&mut self) {
|
||||||
let win = self.active_window().root();
|
let win = self.active_window().root();
|
||||||
|
|
|
@ -272,9 +272,9 @@ impl<'a> WindowMethods for JSRef<'a, Window> {
|
||||||
self.Window()
|
self.Window()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/browsers.html#dom-parent
|
||||||
fn Parent(self) -> Temporary<Window> {
|
fn Parent(self) -> Temporary<Window> {
|
||||||
//TODO - Once we support iframes correctly this needs to return the parent frame
|
self.browser_context().as_ref().unwrap().parent().unwrap_or(self.Window())
|
||||||
self.Window()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Performance(self) -> Temporary<Performance> {
|
fn Performance(self) -> Temporary<Performance> {
|
||||||
|
@ -314,7 +314,7 @@ impl<'a> WindowMethods for JSRef<'a, Window> {
|
||||||
|
|
||||||
pub trait WindowHelpers {
|
pub trait WindowHelpers {
|
||||||
fn flush_layout(self, goal: ReflowGoal, query: ReflowQueryType);
|
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 load_url(self, href: DOMString);
|
||||||
fn handle_fire_timer(self, timer_id: TimerId);
|
fn handle_fire_timer(self, timer_id: TimerId);
|
||||||
fn IndexedGetter(self, _index: u32, _found: &mut bool) -> Option<Temporary<Window>>;
|
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);
|
self.page().flush_layout(goal, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_browser_context(self, doc: JSRef<Document>) {
|
fn init_browser_context(self, doc: JSRef<Document>, parent: Option<JSRef<Window>>) {
|
||||||
*self.browser_context.borrow_mut() = Some(BrowserContext::new(doc));
|
*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.
|
/// Commence a new URL load which will either replace this window or scroll to a fragment.
|
||||||
|
|
|
@ -581,8 +581,8 @@ impl ScriptTask {
|
||||||
match msg {
|
match msg {
|
||||||
ConstellationControlMsg::AttachLayout(_) =>
|
ConstellationControlMsg::AttachLayout(_) =>
|
||||||
panic!("should have handled AttachLayout already"),
|
panic!("should have handled AttachLayout already"),
|
||||||
ConstellationControlMsg::Load(id, load_data) =>
|
ConstellationControlMsg::Load(id, parent_id, load_data) =>
|
||||||
self.load(id, load_data),
|
self.load(id, parent_id, load_data),
|
||||||
ConstellationControlMsg::SendEvent(id, event) =>
|
ConstellationControlMsg::SendEvent(id, event) =>
|
||||||
self.handle_event(id, event),
|
self.handle_event(id, event),
|
||||||
ConstellationControlMsg::ReflowComplete(id, reflow_id) =>
|
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
|
/// The entry point to document loading. Defines bindings, sets up the window and document
|
||||||
/// objects, parses HTML and CSS, and kicks off initial layout.
|
/// 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();
|
let url = load_data.url.clone();
|
||||||
debug!("ScriptTask: loading {:?} on page {:?}", url, pipeline_id);
|
debug!("ScriptTask: loading {:?} on page {:?}", url, pipeline_id);
|
||||||
|
|
||||||
let page = self.page.borrow_mut();
|
let borrowed_page = self.page.borrow_mut();
|
||||||
let page = page.find(pipeline_id).expect("ScriptTask: received a load
|
|
||||||
|
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
|
message for a layout channel that is not associated with this script task. This
|
||||||
is a bug.");
|
is a bug.");
|
||||||
|
|
||||||
|
@ -841,7 +855,7 @@ impl ScriptTask {
|
||||||
if let Some(tm) = last_modified {
|
if let Some(tm) = last_modified {
|
||||||
document.set_last_modified(dom_last_modified(&tm));
|
document.set_last_modified(dom_last_modified(&tm));
|
||||||
}
|
}
|
||||||
window.r().init_browser_context(document.r());
|
window.r().init_browser_context(document.r(), parent_window);
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,7 +56,7 @@ pub struct NewLayoutInfo {
|
||||||
/// Messages sent from the constellation to the script task
|
/// Messages sent from the constellation to the script task
|
||||||
pub enum ConstellationControlMsg {
|
pub enum ConstellationControlMsg {
|
||||||
/// Loads a new URL on the specified pipeline.
|
/// 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
|
/// Gives a channel and ID to a layout task, as well as the ID of that layout's parent
|
||||||
AttachLayout(NewLayoutInfo),
|
AttachLayout(NewLayoutInfo),
|
||||||
/// Window resized. Sends a DOM event eventually, but first we combine events.
|
/// Window resized. Sends a DOM event eventually, but first we combine events.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
[open-url-multi-window-2.htm]
|
[open-url-multi-window-2.htm]
|
||||||
type: testharness
|
type: testharness
|
||||||
expected: TIMEOUT
|
expected: OK
|
||||||
|
[XMLHttpRequest: open() resolving URLs (multi-Window; 2; evil)]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
[open-url-multi-window-3.htm]
|
[open-url-multi-window-3.htm]
|
||||||
type: testharness
|
type: testharness
|
||||||
expected: TIMEOUT
|
expected: OK
|
||||||
|
[XMLHttpRequest: open() resolving URLs (multi-Window; 3; evil)]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[open-url-multi-window-4.htm]
|
[open-url-multi-window-4.htm]
|
||||||
type: testharness
|
type: testharness
|
||||||
expected: TIMEOUT
|
expected: OK
|
||||||
[XMLHttpRequest: open() resolving URLs (multi-Window; 4; evil)]
|
[XMLHttpRequest: open() resolving URLs (multi-Window; 4; evil)]
|
||||||
expected: NOTRUN
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[open-url-multi-window-5.htm]
|
[open-url-multi-window-5.htm]
|
||||||
type: testharness
|
type: testharness
|
||||||
expected: TIMEOUT
|
expected: OK
|
||||||
[XMLHttpRequest: open() resolving URLs (multi-Window; 5)]
|
[XMLHttpRequest: open() resolving URLs (multi-Window; 5)]
|
||||||
expected: NOTRUN
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[open-url-multi-window.htm]
|
[open-url-multi-window.htm]
|
||||||
type: testharness
|
type: testharness
|
||||||
expected: TIMEOUT
|
expected: OK
|
||||||
[XMLHttpRequest: open() resolving URLs (multi-Window; 1)]
|
[XMLHttpRequest: open() resolving URLs (multi-Window; 1)]
|
||||||
expected: NOTRUN
|
expected: FAIL
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue