From 52fbaf7e17bf19d52675cdf044fd2db60080fbb4 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Wed, 14 May 2014 12:37:35 +0200 Subject: [PATCH 1/7] Pass a non-Option SubpageId to Pipeline::with_script. The ScriptTask is only reused for subpages, so there's no reason to pass an Option. --- src/components/main/constellation.rs | 2 +- src/components/main/pipeline.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/main/constellation.rs b/src/components/main/constellation.rs index fcd93ee238c..e2c63f16630 100644 --- a/src/components/main/constellation.rs +++ b/src/components/main/constellation.rs @@ -573,7 +573,7 @@ impl Constellation { debug!("Constellation: loading same-origin iframe at {:?}", url); // Reuse the script task if same-origin url's Pipeline::with_script(next_pipeline_id, - Some(subpage_id), + subpage_id, self.chan.clone(), self.compositor_chan.clone(), self.image_cache_task.clone(), diff --git a/src/components/main/pipeline.rs b/src/components/main/pipeline.rs index 2b17085e6a2..d4a117fe08b 100644 --- a/src/components/main/pipeline.rs +++ b/src/components/main/pipeline.rs @@ -45,7 +45,7 @@ impl Pipeline { /// Starts a render task, layout task, and script task. Returns the channels wrapped in a /// struct. pub fn with_script(id: PipelineId, - subpage_id: Option, + subpage_id: SubpageId, constellation_chan: ConstellationChan, compositor_chan: CompositorChan, image_cache_task: ImageCacheTask, @@ -61,7 +61,7 @@ impl Pipeline { let failure = Failure { pipeline_id: id, - subpage_id: subpage_id, + subpage_id: Some(subpage_id), }; RenderTask::create(id, @@ -95,7 +95,7 @@ impl Pipeline { chan.send(AttachLayoutMsg(new_layout_info)); Pipeline::new(id, - subpage_id, + Some(subpage_id), script_pipeline.script_chan.clone(), layout_chan, render_chan, From 69172a1ae5d7187c4fe18e3a0d6d8732753a3d56 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Wed, 14 May 2014 12:44:59 +0200 Subject: [PATCH 2/7] Rename the pipeline ID fields in NewLayoutInfo. This will make the distinction clearer with the subpage ID field to be added. --- src/components/main/pipeline.rs | 4 ++-- src/components/script/script_task.rs | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/main/pipeline.rs b/src/components/main/pipeline.rs index d4a117fe08b..f32214ae181 100644 --- a/src/components/main/pipeline.rs +++ b/src/components/main/pipeline.rs @@ -86,8 +86,8 @@ impl Pipeline { layout_shutdown_chan); let new_layout_info = NewLayoutInfo { - old_id: script_pipeline.id.clone(), - new_id: id, + old_pipeline_id: script_pipeline.id.clone(), + new_pipeline_id: id, layout_chan: layout_chan.clone(), }; diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs index a750903e45d..6c2d8032a21 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -91,8 +91,8 @@ pub enum ScriptMsg { } pub struct NewLayoutInfo { - pub old_id: PipelineId, - pub new_id: PipelineId, + pub old_pipeline_id: PipelineId, + pub new_pipeline_id: PipelineId, pub layout_chan: LayoutChan, } @@ -782,18 +782,18 @@ impl ScriptTask { fn handle_new_layout(&self, new_layout_info: NewLayoutInfo) { debug!("Script: new layout: {:?}", new_layout_info); let NewLayoutInfo { - old_id, - new_id, + old_pipeline_id, + new_pipeline_id, layout_chan } = new_layout_info; let mut page = self.page.borrow_mut(); - let parent_page = page.find(old_id).expect("ScriptTask: received a layout + let parent_page = page.find(old_pipeline_id).expect("ScriptTask: received a layout whose parent has a PipelineId which does not correspond to a pipeline in the script task's page tree. This is a bug."); let new_page = { let window_size = parent_page.window_size.deref().get(); - Page::new(new_id, layout_chan, window_size, + Page::new(new_pipeline_id, layout_chan, window_size, parent_page.resource_task.deref().clone(), self.constellation_chan.clone(), self.js_context.borrow().get_ref().clone()) From b77869bd9ab404d17941e17280db0b0a7184ee68 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Wed, 14 May 2014 12:50:26 +0200 Subject: [PATCH 3/7] Add a subpage_id field to NewLayoutInfo. --- src/components/main/pipeline.rs | 1 + src/components/script/script_task.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/components/main/pipeline.rs b/src/components/main/pipeline.rs index f32214ae181..02da6479e5f 100644 --- a/src/components/main/pipeline.rs +++ b/src/components/main/pipeline.rs @@ -88,6 +88,7 @@ impl Pipeline { let new_layout_info = NewLayoutInfo { old_pipeline_id: script_pipeline.id.clone(), new_pipeline_id: id, + subpage_id: subpage_id, layout_chan: layout_chan.clone(), }; diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs index 6c2d8032a21..470a39822de 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -93,6 +93,7 @@ pub enum ScriptMsg { pub struct NewLayoutInfo { pub old_pipeline_id: PipelineId, pub new_pipeline_id: PipelineId, + pub subpage_id: SubpageId, pub layout_chan: LayoutChan, } @@ -784,6 +785,7 @@ impl ScriptTask { let NewLayoutInfo { old_pipeline_id, new_pipeline_id, + subpage_id, layout_chan } = new_layout_info; From 8f63c9e1c8ee776b72b0a906a137b7155773ec50 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Wed, 14 May 2014 17:23:18 +0200 Subject: [PATCH 4/7] Store the subpage id in the Page. --- src/components/script/script_task.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs index 470a39822de..82f4ab0bb5f 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -121,6 +121,9 @@ pub struct Page { /// Pipeline id associated with this page. pub id: PipelineId, + /// Subpage id associated with this page, if any. + pub subpage_id: Option, + /// Unique id for last reflow request; used for confirming completion reply. pub last_reflow_id: Traceable>, @@ -191,7 +194,8 @@ impl IterablePage for Rc { } impl Page { - fn new(id: PipelineId, layout_chan: LayoutChan, + fn new(id: PipelineId, subpage_id: Option, + layout_chan: LayoutChan, window_size: Size2D, resource_task: ResourceTask, constellation_chan: ConstellationChan, js_context: Rc) -> Page { @@ -201,6 +205,7 @@ impl Page { }; Page { id: id, + subpage_id: subpage_id, frame: Traceable::new(RefCell::new(None)), layout_chan: Untraceable::new(layout_chan), layout_join_port: Untraceable::new(RefCell::new(None)), @@ -607,7 +612,7 @@ impl ScriptTask { window_size: Size2D) -> Rc { let (js_runtime, js_context) = ScriptTask::new_rt_and_cx(); - let page = Page::new(id, layout_chan, window_size, + let page = Page::new(id, None, layout_chan, window_size, resource_task.clone(), constellation_chan.clone(), js_context.clone()); @@ -795,7 +800,7 @@ impl ScriptTask { task's page tree. This is a bug."); let new_page = { let window_size = parent_page.window_size.deref().get(); - Page::new(new_pipeline_id, layout_chan, window_size, + Page::new(new_pipeline_id, Some(subpage_id), layout_chan, window_size, parent_page.resource_task.deref().clone(), self.constellation_chan.clone(), self.js_context.borrow().get_ref().clone()) From 85285113e436eb1bfb8695dc23fc26878ecbf721 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Wed, 14 May 2014 17:39:13 +0200 Subject: [PATCH 5/7] Instate a pre-wrap hook that outerizes its argument, to satisfy an undocumented JSAPI requirement. --- src/components/script/dom/bindings/utils.rs | 19 +++++++++++++++++++ src/components/script/script_task.rs | 7 ++++--- src/support/spidermonkey/rust-mozjs | 2 +- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index f5b0f08849e..507f024c5d6 100644 --- a/src/components/script/dom/bindings/utils.rs +++ b/src/components/script/dom/bindings/utils.rs @@ -610,6 +610,25 @@ pub extern fn wrap_for_same_compartment(cx: *JSContext, obj: *JSObject) -> *JSOb } } +pub extern fn pre_wrap(cx: *mut JSContext, _scope: *mut JSObject, + obj: *mut JSObject, flags: c_uint) -> *mut JSObject { + unsafe { + let clasp = JS_GetClass(obj as *_); + let clasp = clasp as *js::Class; + match (*clasp).ext.outerObject { + Some(outerize) => { + debug!("found an outerize hook"); + let obj = JSHandleObject { unnamed: &(obj as *_) }; + outerize(cx as *_, obj) as *mut _ + } + None => { + debug!("no outerize hook found"); + obj + } + } + } +} + pub extern fn outerize_global(_cx: *JSContext, obj: JSHandleObject) -> *JSObject { unsafe { debug!("outerizing"); diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs index 82f4ab0bb5f..02c19c52dd3 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -11,7 +11,8 @@ use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, ElementCas use dom::bindings::js::{JS, JSRef, RootCollection, Temporary, OptionalSettable}; use dom::bindings::js::OptionalRootable; use dom::bindings::trace::{Traceable, Untraceable}; -use dom::bindings::utils::{Reflectable, GlobalStaticData, wrap_for_same_compartment}; +use dom::bindings::utils::{Reflectable, GlobalStaticData}; +use dom::bindings::utils::{wrap_for_same_compartment, pre_wrap}; use dom::document::{Document, HTMLDocument, DocumentMethods, DocumentHelpers}; use dom::element::{Element, AttributeHandlers}; use dom::event::{Event_, ResizeEvent, ReflowEvent, ClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent}; @@ -647,11 +648,11 @@ impl ScriptTask { let callback = JS_SetWrapObjectCallbacks((*js_runtime).ptr, ptr::null(), wrap_for_same_compartment, - ptr::null()); + None); JS_SetWrapObjectCallbacks((*js_runtime).ptr, callback, wrap_for_same_compartment, - ptr::null()); + Some(pre_wrap)); } let js_context = js_runtime.cx(); diff --git a/src/support/spidermonkey/rust-mozjs b/src/support/spidermonkey/rust-mozjs index 07acb44df9b..07f19496bd7 160000 --- a/src/support/spidermonkey/rust-mozjs +++ b/src/support/spidermonkey/rust-mozjs @@ -1 +1 @@ -Subproject commit 07acb44df9b3f638743931f392c0ebe7040a7bab +Subproject commit 07f19496bd7703b502812a6b4228f08dec59ec0b From 765cea73d94f5b2a17272a895e0d99cf239e5b81 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Wed, 14 May 2014 17:58:40 +0200 Subject: [PATCH 6/7] Implement iframe.contentWindow. --- src/components/script/dom/htmliframeelement.rs | 14 +++++++++++++- src/components/script/script_task.rs | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/components/script/dom/htmliframeelement.rs b/src/components/script/dom/htmliframeelement.rs index f92fddabdaa..766d7a711f9 100644 --- a/src/components/script/dom/htmliframeelement.rs +++ b/src/components/script/dom/htmliframeelement.rs @@ -14,6 +14,7 @@ use dom::htmlelement::HTMLElement; use dom::node::{Node, ElementNodeTypeId, window_from_node}; use dom::virtualmethods::VirtualMethods; use dom::window::Window; +use script_task::IterablePage; use servo_msg::constellation_msg::{PipelineId, SubpageId}; use servo_msg::constellation_msg::{IFrameSandboxed, IFrameUnsandboxed}; use servo_msg::constellation_msg::{ConstellationChan, LoadIframeUrlMsg}; @@ -184,7 +185,18 @@ impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> { } fn GetContentWindow(&self) -> Option> { - None + self.size.and_then(|size| { + let window = window_from_node(self).root(); + let children = &*window.deref().page.children.deref().borrow(); + let child = children.iter().find(|child| { + child.subpage_id.unwrap() == size.subpage_id + }); + child.and_then(|page| { + page.frame.deref().borrow().as_ref().map(|frame| { + Temporary::new(frame.window.clone()) + }) + }) + }) } fn Align(&self) -> DOMString { diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs index 02c19c52dd3..0ce993d5e19 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -173,7 +173,7 @@ pub struct PageIterator { stack: Vec>, } -trait IterablePage { +pub trait IterablePage { fn iter(&self) -> PageIterator; fn find(&self, id: PipelineId) -> Option>; } From 81821052040eab42e9b3ca72aeccbb17cd002197 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Thu, 15 May 2014 20:58:51 +0200 Subject: [PATCH 7/7] Use JS_ObjectToOuterObject in wrap callbacks. --- src/components/script/dom/bindings/utils.rs | 31 +++------------------ src/support/spidermonkey/rust-mozjs | 2 +- 2 files changed, 5 insertions(+), 28 deletions(-) diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index 507f024c5d6..7c742efcbb2 100644 --- a/src/components/script/dom/bindings/utils.rs +++ b/src/components/script/dom/bindings/utils.rs @@ -37,6 +37,7 @@ use js::jsapi::{JSContext, JSObject, JSBool, jsid, JSClass, JSNative}; use js::jsapi::{JSFunctionSpec, JSPropertySpec}; use js::jsapi::{JS_NewGlobalObject, JS_InitStandardClasses}; use js::jsapi::{JSString}; +use js::jsfriendapi::JS_ObjectToOuterObject; use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType; use js::jsval::JSVal; use js::jsval::{PrivateValue, ObjectValue, NullValue, ObjectOrNullValue}; @@ -594,38 +595,14 @@ pub fn CreateDOMGlobal(cx: *JSContext, class: *JSClass) -> *JSObject { pub extern fn wrap_for_same_compartment(cx: *JSContext, obj: *JSObject) -> *JSObject { unsafe { - let clasp = JS_GetClass(obj); - let clasp = clasp as *js::Class; - match (*clasp).ext.outerObject { - Some(outerize) => { - debug!("found an outerize hook"); - let obj = JSHandleObject { unnamed: &obj }; - outerize(cx, obj) - } - None => { - debug!("no outerize hook found"); - obj - } - } + JS_ObjectToOuterObject(cx as *mut _, obj as *mut _) as *_ } } pub extern fn pre_wrap(cx: *mut JSContext, _scope: *mut JSObject, - obj: *mut JSObject, flags: c_uint) -> *mut JSObject { + obj: *mut JSObject, _flags: c_uint) -> *mut JSObject { unsafe { - let clasp = JS_GetClass(obj as *_); - let clasp = clasp as *js::Class; - match (*clasp).ext.outerObject { - Some(outerize) => { - debug!("found an outerize hook"); - let obj = JSHandleObject { unnamed: &(obj as *_) }; - outerize(cx as *_, obj) as *mut _ - } - None => { - debug!("no outerize hook found"); - obj - } - } + JS_ObjectToOuterObject(cx, obj) } } diff --git a/src/support/spidermonkey/rust-mozjs b/src/support/spidermonkey/rust-mozjs index 07f19496bd7..ff296137c65 160000 --- a/src/support/spidermonkey/rust-mozjs +++ b/src/support/spidermonkey/rust-mozjs @@ -1 +1 @@ -Subproject commit 07f19496bd7703b502812a6b4228f08dec59ec0b +Subproject commit ff296137c652248138eb7f5a377d8daac52ed233