aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/script_task.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/script_task.rs')
-rw-r--r--components/script/script_task.rs92
1 files changed, 52 insertions, 40 deletions
diff --git a/components/script/script_task.rs b/components/script/script_task.rs
index f46f2aa70ed..0f3f5c1b564 100644
--- a/components/script/script_task.rs
+++ b/components/script/script_task.rs
@@ -12,7 +12,7 @@ use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, Documen
use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
-use dom::bindings::codegen::InheritTypes::{ElementCast, EventTargetCast, NodeCast, EventCast};
+use dom::bindings::codegen::InheritTypes::{ElementCast, EventTargetCast, HTMLIFrameElementCast, NodeCast, EventCast};
use dom::bindings::conversions::FromJSValConvertible;
use dom::bindings::conversions::StringificationBehavior;
use dom::bindings::global::GlobalRef;
@@ -28,6 +28,7 @@ use dom::event::{Event, EventHelpers, EventBubbles, EventCancelable};
use dom::uievent::UIEvent;
use dom::eventtarget::{EventTarget, EventTargetHelpers};
use dom::htmlelement::HTMLElementTypeId;
+use dom::htmliframeelement::HTMLIFrameElement;
use dom::keyboardevent::KeyboardEvent;
use dom::mouseevent::MouseEvent;
use dom::node::{self, Node, NodeHelpers, NodeDamage, NodeTypeId};
@@ -53,7 +54,7 @@ use script_traits::ScriptTaskFactory;
use servo_msg::compositor_msg::ReadyState::{FinishedLoading, Loading, PerformingLayout};
use servo_msg::compositor_msg::{LayerId, ScriptListener};
use servo_msg::constellation_msg::{ConstellationChan};
-use servo_msg::constellation_msg::{LoadData, NavigationDirection, PipelineId};
+use servo_msg::constellation_msg::{LoadData, NavigationDirection, PipelineId, SubpageId};
use servo_msg::constellation_msg::{Failure, Msg, WindowSizeData, Key, KeyState};
use servo_msg::constellation_msg::{KeyModifiers, SUPER, SHIFT, CONTROL, ALT};
use servo_msg::constellation_msg::{PipelineExitType};
@@ -586,8 +587,8 @@ impl ScriptTask {
match msg {
ConstellationControlMsg::AttachLayout(_) =>
panic!("should have handled AttachLayout already"),
- ConstellationControlMsg::Load(id, parent_id, load_data) =>
- self.load(id, parent_id, load_data),
+ ConstellationControlMsg::Load(id, parent, load_data) =>
+ self.load(id, parent, load_data),
ConstellationControlMsg::SendEvent(id, event) =>
self.handle_event(id, event),
ConstellationControlMsg::ReflowComplete(id, reflow_id) =>
@@ -622,7 +623,7 @@ impl ScriptTask {
ScriptMsg::DOMMessage(..) =>
panic!("unexpected message"),
ScriptMsg::WorkerDispatchErrorEvent(addr, msg, file_name,line_num, col_num) =>
- Worker::handle_error_message(addr, msg, file_name, line_num, col_num),
+ Worker::handle_error_message(addr, msg, file_name, line_num, col_num),
ScriptMsg::RunnableMsg(runnable) =>
runnable.handler(),
ScriptMsg::RefcountCleanup(addr) =>
@@ -768,13 +769,14 @@ 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, parent_id: Option<PipelineId>, load_data: LoadData) {
+ fn load(&self, pipeline_id: PipelineId,
+ parent: Option<(PipelineId, SubpageId)>, load_data: LoadData) {
let url = load_data.url.clone();
debug!("ScriptTask: loading {:?} on page {:?}", url, pipeline_id);
let borrowed_page = self.page.borrow_mut();
- let parent_window = parent_id.and_then(|pid| {
+ let frame_element = parent.and_then(|(parent_id, subpage_id)| {
// 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.
@@ -782,10 +784,20 @@ impl ScriptTask {
// 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())
+ borrowed_page.find(parent_id).and_then(|page| {
+ let match_iframe = |&:&node: &JSRef<HTMLIFrameElement>| {
+ node.subpage_id().map_or(false, |id| id == subpage_id)
+ };
+
+ let doc = page.frame().as_ref().unwrap().document.root();
+ let doc: JSRef<Node> = NodeCast::from_ref(doc.r());
+
+ doc.traverse_preorder()
+ .filter_map(|node| HTMLIFrameElementCast::to_ref(node))
+ .find(match_iframe)
+ .map(|node| Temporary::from_rooted(ElementCast::from_ref(node)))
})
- });
+ }).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
@@ -866,7 +878,7 @@ impl ScriptTask {
if let Some(tm) = last_modified {
document.r().set_last_modified(dom_last_modified(&tm));
}
- window.r().init_browser_context(document.r(), parent_window.r());
+ window.r().init_browser_context(document.r(), frame_element.r());
{
@@ -968,7 +980,7 @@ impl ScriptTask {
fn handle_event(&self, pipeline_id: PipelineId, event: CompositorEvent) {
match event {
ResizeEvent(new_size) => {
- self.handle_resize_event(pipeline_id, new_size);
+ self.handle_resize_event(pipeline_id, new_size);
}
ReflowEvent(nodes) => {
@@ -996,13 +1008,13 @@ impl ScriptTask {
}
ClickEvent(_button, point) => {
- self.handle_click_event(pipeline_id, _button, point);
+ self.handle_click_event(pipeline_id, _button, point);
}
MouseDownEvent(..) => {}
MouseUpEvent(..) => {}
MouseMoveEvent(point) => {
- self.handle_mouse_move_event(pipeline_id, point);
+ self.handle_mouse_move_event(pipeline_id, point);
}
KeyEvent(key, state, modifiers) => {
@@ -1170,8 +1182,8 @@ impl ScriptTask {
debug!("node address is {:?}", node_address.0);
let temp_node =
- node::from_untrusted_node_address(
- self.js_runtime.ptr, node_address).root();
+ node::from_untrusted_node_address(
+ self.js_runtime.ptr, node_address).root();
let maybe_elem: Option<JSRef<Element>> = ElementCast::to_ref(temp_node.r());
let maybe_node = match maybe_elem {
@@ -1235,30 +1247,30 @@ impl ScriptTask {
}
if node_address.len() > 0 {
- let top_most_node =
- node::from_untrusted_node_address(self.js_runtime.ptr, node_address[0]).root();
-
- if let Some(ref frame) = *page.frame() {
- let window = frame.window.root();
-
- let x = point.x.to_i32().unwrap_or(0);
- let y = point.y.to_i32().unwrap_or(0);
-
- let mouse_event = MouseEvent::new(window.r(),
- "mousemove".to_owned(),
- true,
- true,
- Some(window.r()),
- 0i32,
- x, y, x, y,
- false, false, false, false,
- 0i16,
- None).root();
-
- let event: JSRef<Event> = EventCast::from_ref(mouse_event.r());
- let target: JSRef<EventTarget> = EventTargetCast::from_ref(top_most_node.r());
- event.fire(target);
- }
+ let top_most_node =
+ node::from_untrusted_node_address(self.js_runtime.ptr, node_address[0]).root();
+
+ if let Some(ref frame) = *page.frame() {
+ let window = frame.window.root();
+
+ let x = point.x.to_i32().unwrap_or(0);
+ let y = point.y.to_i32().unwrap_or(0);
+
+ let mouse_event = MouseEvent::new(window.r(),
+ "mousemove".to_owned(),
+ true,
+ true,
+ Some(window.r()),
+ 0i32,
+ x, y, x, y,
+ false, false, false, false,
+ 0i16,
+ None).root();
+
+ let event: JSRef<Event> = EventCast::from_ref(mouse_event.r());
+ let target: JSRef<EventTarget> = EventTargetCast::from_ref(top_most_node.r());
+ event.fire(target);
+ }
}
for node_address in node_address.iter() {