mirror of
https://github.com/servo/servo.git
synced 2025-07-30 18:50:36 +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
|
@ -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();
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue