Lookup frames by frame_id, not pipeline_id.

This commit is contained in:
Alan Jeffrey 2016-10-07 15:52:49 -05:00
parent 23d030e7a7
commit cda9099396
7 changed files with 112 additions and 89 deletions

View file

@ -1208,8 +1208,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
} }
fn handle_subframe_loaded(&mut self, pipeline_id: PipelineId) { fn handle_subframe_loaded(&mut self, pipeline_id: PipelineId) {
let parent_info = match self.pipelines.get(&pipeline_id) { let (frame_id, parent_info) = match self.pipelines.get(&pipeline_id) {
Some(pipeline) => pipeline.parent_info, Some(pipeline) => (pipeline.frame_id, pipeline.parent_info),
None => return warn!("Pipeline {:?} loaded after closure.", pipeline_id), None => return warn!("Pipeline {:?} loaded after closure.", pipeline_id),
}; };
let subframe_parent_id = match parent_info { let subframe_parent_id = match parent_info {
@ -1217,7 +1217,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
None => return warn!("Pipeline {:?} has no parent.", pipeline_id), None => return warn!("Pipeline {:?} has no parent.", pipeline_id),
}; };
let msg = ConstellationControlMsg::DispatchFrameLoadEvent { let msg = ConstellationControlMsg::DispatchFrameLoadEvent {
target: pipeline_id, target: frame_id,
parent: subframe_parent_id, parent: subframe_parent_id,
}; };
let result = match self.pipelines.get(&subframe_parent_id) { let result = match self.pipelines.get(&subframe_parent_id) {
@ -1392,13 +1392,19 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
// requested change so it can update its internal state. // requested change so it can update its internal state.
// //
// If replace is true, the current entry is replaced instead of a new entry being added. // If replace is true, the current entry is replaced instead of a new entry being added.
let parent_info = self.pipelines.get(&source_id).and_then(|source| source.parent_info); let (frame_id, parent_info) = match self.pipelines.get(&source_id) {
Some(pipeline) => (pipeline.frame_id, pipeline.parent_info),
None => {
warn!("Pipeline {:?} loaded after closure.", source_id);
return None;
}
};
match parent_info { match parent_info {
Some((parent_pipeline_id, _)) => { Some((parent_pipeline_id, _)) => {
self.handle_load_start_msg(source_id); self.handle_load_start_msg(source_id);
// Message the constellation to find the script thread for this iframe // Message the constellation to find the script thread for this iframe
// and issue an iframe load through there. // and issue an iframe load through there.
let msg = ConstellationControlMsg::Navigate(parent_pipeline_id, source_id, load_data, replace); let msg = ConstellationControlMsg::Navigate(parent_pipeline_id, frame_id, load_data, replace);
let result = match self.pipelines.get(&parent_pipeline_id) { let result = match self.pipelines.get(&parent_pipeline_id) {
Some(parent_pipeline) => parent_pipeline.script_chan.send(msg), Some(parent_pipeline) => parent_pipeline.script_chan.send(msg),
None => { None => {
@ -1590,12 +1596,16 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
event: MozBrowserEvent) { event: MozBrowserEvent) {
assert!(PREFS.is_mozbrowser_enabled()); assert!(PREFS.is_mozbrowser_enabled());
let frame_id = pipeline_id
.and_then(|pipeline_id| self.pipelines.get(&pipeline_id))
.map(|pipeline| pipeline.frame_id);
// Find the script channel for the given parent pipeline, // Find the script channel for the given parent pipeline,
// and pass the event to that script thread. // and pass the event to that script thread.
// If the pipeline lookup fails, it is because we have torn down the pipeline, // If the pipeline lookup fails, it is because we have torn down the pipeline,
// so it is reasonable to silently ignore the event. // so it is reasonable to silently ignore the event.
match self.pipelines.get(&parent_pipeline_id) { match self.pipelines.get(&parent_pipeline_id) {
Some(pipeline) => pipeline.trigger_mozbrowser_event(pipeline_id, event), Some(pipeline) => pipeline.trigger_mozbrowser_event(frame_id, event),
None => warn!("Pipeline {:?} handling mozbrowser event after closure.", parent_pipeline_id), None => warn!("Pipeline {:?} handling mozbrowser event after closure.", parent_pipeline_id),
} }
} }
@ -1626,8 +1636,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
} }
fn focus_parent_pipeline(&mut self, pipeline_id: PipelineId) { fn focus_parent_pipeline(&mut self, pipeline_id: PipelineId) {
let parent_info = match self.pipelines.get(&pipeline_id) { let (frame_id, parent_info) = match self.pipelines.get(&pipeline_id) {
Some(pipeline) => pipeline.parent_info, Some(pipeline) => (pipeline.frame_id, pipeline.parent_info),
None => return warn!("Pipeline {:?} focus parent after closure.", pipeline_id), None => return warn!("Pipeline {:?} focus parent after closure.", pipeline_id),
}; };
let (parent_pipeline_id, _) = match parent_info { let (parent_pipeline_id, _) = match parent_info {
@ -1637,7 +1647,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
// Send a message to the parent of the provided pipeline (if it exists) // Send a message to the parent of the provided pipeline (if it exists)
// telling it to mark the iframe element as focused. // telling it to mark the iframe element as focused.
let msg = ConstellationControlMsg::FocusIFrame(parent_pipeline_id, pipeline_id); let msg = ConstellationControlMsg::FocusIFrame(parent_pipeline_id, frame_id);
let result = match self.pipelines.get(&parent_pipeline_id) { let result = match self.pipelines.get(&parent_pipeline_id) {
Some(pipeline) => pipeline.script_chan.send(msg), Some(pipeline) => pipeline.script_chan.send(msg),
None => return warn!("Pipeline {:?} focus after closure.", parent_pipeline_id), None => return warn!("Pipeline {:?} focus after closure.", parent_pipeline_id),
@ -1691,10 +1701,13 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
} }
fn handle_visibility_change_complete(&mut self, pipeline_id: PipelineId, visibility: bool) { fn handle_visibility_change_complete(&mut self, pipeline_id: PipelineId, visibility: bool) {
let parent_pipeline_info = self.pipelines.get(&pipeline_id).and_then(|source| source.parent_info); let (frame_id, parent_pipeline_info) = match self.pipelines.get(&pipeline_id) {
None => return warn!("Visibity change for closed pipeline {:?}.", pipeline_id),
Some(pipeline) => (pipeline.frame_id, pipeline.parent_info),
};
if let Some((parent_pipeline_id, _)) = parent_pipeline_info { if let Some((parent_pipeline_id, _)) = parent_pipeline_info {
let visibility_msg = ConstellationControlMsg::NotifyVisibilityChange(parent_pipeline_id, let visibility_msg = ConstellationControlMsg::NotifyVisibilityChange(parent_pipeline_id,
pipeline_id, frame_id,
visibility); visibility);
let result = match self.pipelines.get(&parent_pipeline_id) { let result = match self.pipelines.get(&parent_pipeline_id) {
None => return warn!("Parent pipeline {:?} closed", parent_pipeline_id), None => return warn!("Parent pipeline {:?} closed", parent_pipeline_id),
@ -1856,7 +1869,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
// This makes things like contentDocument work correctly. // This makes things like contentDocument work correctly.
if let Some((parent_pipeline_id, _)) = pipeline_info { if let Some((parent_pipeline_id, _)) = pipeline_info {
let msg = ConstellationControlMsg::UpdatePipelineId(parent_pipeline_id, let msg = ConstellationControlMsg::UpdatePipelineId(parent_pipeline_id,
prev_pipeline_id, frame_id,
next_pipeline_id); next_pipeline_id);
let result = match self.pipelines.get(&parent_pipeline_id) { let result = match self.pipelines.get(&parent_pipeline_id) {
None => return warn!("Pipeline {:?} child traversed after closure.", parent_pipeline_id), None => return warn!("Pipeline {:?} child traversed after closure.", parent_pipeline_id),
@ -1875,8 +1888,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
fn get_top_level_frame_for_pipeline(&self, pipeline_id: Option<PipelineId>) -> FrameId { fn get_top_level_frame_for_pipeline(&self, pipeline_id: Option<PipelineId>) -> FrameId {
if PREFS.is_mozbrowser_enabled() { if PREFS.is_mozbrowser_enabled() {
pipeline_id.and_then(|id| self.get_mozbrowser_ancestor_info(id)) pipeline_id.and_then(|id| self.get_mozbrowser_ancestor_info(id))
.and_then(|pipeline_info| self.pipelines.get(&pipeline_info.1)) .map(|(_, mozbrowser_iframe_id)| mozbrowser_iframe_id)
.map(|pipeline| pipeline.frame_id)
.unwrap_or(self.root_frame_id) .unwrap_or(self.root_frame_id)
} else { } else {
// If mozbrowser is not enabled, the root frame is the only top-level frame // If mozbrowser is not enabled, the root frame is the only top-level frame
@ -1964,7 +1976,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
let _ = parent_pipeline.script_chan let _ = parent_pipeline.script_chan
.send(ConstellationControlMsg::FramedContentChanged( .send(ConstellationControlMsg::FramedContentChanged(
parent_info.0, parent_info.0,
pipeline_id)); child_pipeline.frame_id));
} }
} }
} }
@ -2350,12 +2362,12 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
/// For a given pipeline, determine the mozbrowser iframe that transitively contains /// For a given pipeline, determine the mozbrowser iframe that transitively contains
/// it. There could be arbitrary levels of nested iframes in between them. /// it. There could be arbitrary levels of nested iframes in between them.
fn get_mozbrowser_ancestor_info(&self, original_pipeline_id: PipelineId) -> Option<(PipelineId, PipelineId)> { fn get_mozbrowser_ancestor_info(&self, original_pipeline_id: PipelineId) -> Option<(PipelineId, FrameId)> {
let mut pipeline_id = original_pipeline_id; let mut pipeline_id = original_pipeline_id;
loop { loop {
match self.pipelines.get(&pipeline_id) { match self.pipelines.get(&pipeline_id) {
Some(pipeline) => match pipeline.parent_info { Some(pipeline) => match pipeline.parent_info {
Some((parent_id, FrameType::MozBrowserIFrame)) => return Some((parent_id, pipeline_id)), Some((parent_id, FrameType::MozBrowserIFrame)) => return Some((parent_id, pipeline.frame_id)),
Some((parent_id, _)) => pipeline_id = parent_id, Some((parent_id, _)) => pipeline_id = parent_id,
None => return None, None => return None,
}, },
@ -2380,12 +2392,10 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
// If this is a mozbrowser iframe, then send the event with new url // If this is a mozbrowser iframe, then send the event with new url
if let Some((ancestor_id, mozbrowser_iframe_id)) = self.get_mozbrowser_ancestor_info(pipeline_id) { if let Some((ancestor_id, mozbrowser_iframe_id)) = self.get_mozbrowser_ancestor_info(pipeline_id) {
if let Some(ancestor) = self.pipelines.get(&ancestor_id) { if let Some(ancestor) = self.pipelines.get(&ancestor_id) {
if let Some(pipeline) = self.pipelines.get(&mozbrowser_iframe_id) { let can_go_forward = !self.joint_session_future(mozbrowser_iframe_id).is_empty();
let can_go_forward = !self.joint_session_future(pipeline.frame_id).is_empty(); let can_go_back = !self.joint_session_past(mozbrowser_iframe_id).is_empty();
let can_go_back = !self.joint_session_past(pipeline.frame_id).is_empty(); let event = MozBrowserEvent::LocationChange(url, can_go_back, can_go_forward);
let event = MozBrowserEvent::LocationChange(url, can_go_back, can_go_forward); ancestor.trigger_mozbrowser_event(Some(mozbrowser_iframe_id), event);
ancestor.trigger_mozbrowser_event(Some(mozbrowser_iframe_id), event);
}
} }
} }
} }

View file

@ -152,6 +152,7 @@ impl Pipeline {
let new_layout_info = NewLayoutInfo { let new_layout_info = NewLayoutInfo {
parent_pipeline_id: parent_pipeline_id, parent_pipeline_id: parent_pipeline_id,
new_pipeline_id: state.id, new_pipeline_id: state.id,
frame_id: state.frame_id,
frame_type: frame_type, frame_type: frame_type,
load_data: state.load_data.clone(), load_data: state.load_data.clone(),
pipeline_port: pipeline_port, pipeline_port: pipeline_port,
@ -203,6 +204,7 @@ impl Pipeline {
let unprivileged_pipeline_content = UnprivilegedPipelineContent { let unprivileged_pipeline_content = UnprivilegedPipelineContent {
id: state.id, id: state.id,
frame_id: state.frame_id,
parent_info: state.parent_info, parent_info: state.parent_info,
constellation_chan: state.constellation_chan, constellation_chan: state.constellation_chan,
scheduler_chan: state.scheduler_chan, scheduler_chan: state.scheduler_chan,
@ -348,7 +350,7 @@ impl Pipeline {
} }
pub fn trigger_mozbrowser_event(&self, pub fn trigger_mozbrowser_event(&self,
child_id: Option<PipelineId>, child_id: Option<FrameId>,
event: MozBrowserEvent) { event: MozBrowserEvent) {
assert!(PREFS.is_mozbrowser_enabled()); assert!(PREFS.is_mozbrowser_enabled());
@ -380,6 +382,7 @@ impl Pipeline {
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub struct UnprivilegedPipelineContent { pub struct UnprivilegedPipelineContent {
id: PipelineId, id: PipelineId,
frame_id: FrameId,
parent_info: Option<(PipelineId, FrameType)>, parent_info: Option<(PipelineId, FrameType)>,
constellation_chan: IpcSender<ScriptMsg>, constellation_chan: IpcSender<ScriptMsg>,
layout_to_constellation_chan: IpcSender<LayoutMsg>, layout_to_constellation_chan: IpcSender<LayoutMsg>,
@ -414,6 +417,7 @@ impl UnprivilegedPipelineContent {
{ {
let layout_pair = STF::create(InitialScriptState { let layout_pair = STF::create(InitialScriptState {
id: self.id, id: self.id,
frame_id: self.frame_id,
parent_info: self.parent_info, parent_info: self.parent_info,
control_chan: self.script_chan.clone(), control_chan: self.script_chan.clone(),
control_port: self.script_port, control_port: self.script_port,

View file

@ -95,8 +95,8 @@ use ipc_channel::ipc::{self, IpcSender};
use js::jsapi::{JSContext, JSObject, JSRuntime}; use js::jsapi::{JSContext, JSObject, JSRuntime};
use js::jsapi::JS_GetRuntime; use js::jsapi::JS_GetRuntime;
use msg::constellation_msg::{ALT, CONTROL, SHIFT, SUPER}; use msg::constellation_msg::{ALT, CONTROL, SHIFT, SUPER};
use msg::constellation_msg::{FrameId, ReferrerPolicy};
use msg::constellation_msg::{Key, KeyModifiers, KeyState}; use msg::constellation_msg::{Key, KeyModifiers, KeyState};
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
use net_traits::{FetchResponseMsg, IpcSend}; use net_traits::{FetchResponseMsg, IpcSend};
use net_traits::CookieSource::NonHTTP; use net_traits::CookieSource::NonHTTP;
use net_traits::CoreResourceMsg::{GetCookiesForUrl, SetCookiesForUrl}; use net_traits::CoreResourceMsg::{GetCookiesForUrl, SetCookiesForUrl};
@ -1629,11 +1629,11 @@ impl Document {
} }
/// Find an iframe element in the document. /// Find an iframe element in the document.
pub fn find_iframe(&self, pipeline: PipelineId) -> Option<Root<HTMLIFrameElement>> { pub fn find_iframe(&self, frame_id: FrameId) -> Option<Root<HTMLIFrameElement>> {
self.upcast::<Node>() self.upcast::<Node>()
.traverse_preorder() .traverse_preorder()
.filter_map(Root::downcast::<HTMLIFrameElement>) .filter_map(Root::downcast::<HTMLIFrameElement>)
.find(|node| node.pipeline_id() == Some(pipeline)) .find(|node| node.frame_id() == frame_id)
} }
pub fn get_dom_loading(&self) -> u64 { pub fn get_dom_loading(&self) -> u64 {

View file

@ -206,6 +206,11 @@ impl HTMLIFrameElement {
self.pipeline_id.get() self.pipeline_id.get()
} }
#[inline]
pub fn frame_id(&self) -> FrameId {
self.frame_id
}
pub fn change_visibility_status(&self, visibility: bool) { pub fn change_visibility_status(&self, visibility: bool) {
if self.visibility.get() != visibility { if self.visibility.get() != visibility {
self.visibility.set(visibility); self.visibility.set(visibility);
@ -226,11 +231,7 @@ impl HTMLIFrameElement {
} }
/// https://html.spec.whatwg.org/multipage/#iframe-load-event-steps steps 1-4 /// https://html.spec.whatwg.org/multipage/#iframe-load-event-steps steps 1-4
pub fn iframe_load_event_steps(&self, loaded_pipeline: PipelineId) { pub fn iframe_load_event_steps(&self) {
// TODO(#9592): assert that the load blocker is present at all times when we
// can guarantee that it's created for the case of iframe.reload().
assert_eq!(loaded_pipeline, self.pipeline_id().unwrap());
// TODO A cross-origin child document would not be easily accessible // TODO A cross-origin child document would not be easily accessible
// from this script thread. It's unclear how to implement // from this script thread. It's unclear how to implement
// steps 2, 3, and 5 efficiently in this case. // steps 2, 3, and 5 efficiently in this case.

View file

@ -71,8 +71,9 @@ use js::jsval::UndefinedValue;
use js::rust::Runtime; use js::rust::Runtime;
use layout_wrapper::ServoLayoutNode; use layout_wrapper::ServoLayoutNode;
use mem::heap_size_of_self_and_children; use mem::heap_size_of_self_and_children;
use msg::constellation_msg::{FrameType, PipelineId, PipelineNamespace, ReferrerPolicy}; use msg::constellation_msg::{FrameId, FrameType, PipelineId, PipelineNamespace, ReferrerPolicy};
use net_traits::{CoreResourceMsg, IpcSend, Metadata, ResourceThreads}; use net_traits::{AsyncResponseTarget, CoreResourceMsg, LoadConsumer, LoadContext, Metadata, ResourceThreads};
use net_traits::{IpcSend, LoadData as NetLoadData};
use net_traits::bluetooth_thread::BluetoothMethodMsg; use net_traits::bluetooth_thread::BluetoothMethodMsg;
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCacheThread}; use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCacheThread};
use net_traits::request::{CredentialsMode, Destination, RequestInit}; use net_traits::request::{CredentialsMode, Destination, RequestInit};
@ -135,6 +136,8 @@ pub unsafe fn trace_thread(tr: *mut JSTracer) {
struct InProgressLoad { struct InProgressLoad {
/// The pipeline which requested this load. /// The pipeline which requested this load.
pipeline_id: PipelineId, pipeline_id: PipelineId,
/// The frame being loaded into.
frame_id: FrameId,
/// The parent pipeline and frame type associated with this load, if any. /// The parent pipeline and frame type associated with this load, if any.
parent_info: Option<(PipelineId, FrameType)>, parent_info: Option<(PipelineId, FrameType)>,
/// The current window size associated with this pipeline. /// The current window size associated with this pipeline.
@ -154,12 +157,14 @@ struct InProgressLoad {
impl InProgressLoad { impl InProgressLoad {
/// Create a new InProgressLoad object. /// Create a new InProgressLoad object.
fn new(id: PipelineId, fn new(id: PipelineId,
frame_id: FrameId,
parent_info: Option<(PipelineId, FrameType)>, parent_info: Option<(PipelineId, FrameType)>,
layout_chan: Sender<message::Msg>, layout_chan: Sender<message::Msg>,
window_size: Option<WindowSizeData>, window_size: Option<WindowSizeData>,
url: Url) -> InProgressLoad { url: Url) -> InProgressLoad {
InProgressLoad { InProgressLoad {
pipeline_id: id, pipeline_id: id,
frame_id: frame_id,
parent_info: parent_info, parent_info: parent_info,
layout_chan: layout_chan, layout_chan: layout_chan,
window_size: window_size, window_size: window_size,
@ -452,15 +457,15 @@ impl ScriptThreadFactory for ScriptThread {
let (sender, receiver) = channel(); let (sender, receiver) = channel();
let layout_chan = sender.clone(); let layout_chan = sender.clone();
let pipeline_id = state.id;
thread::spawn_named(format!("ScriptThread {:?}", state.id), thread::spawn_named(format!("ScriptThread {:?}", state.id),
move || { move || {
thread_state::initialize(thread_state::SCRIPT); thread_state::initialize(thread_state::SCRIPT);
PipelineId::install(pipeline_id); PipelineId::install(state.id);
PipelineNamespace::install(state.pipeline_namespace_id); PipelineNamespace::install(state.pipeline_namespace_id);
let roots = RootCollection::new(); let roots = RootCollection::new();
let _stack_roots_tls = StackRootTLS::new(&roots); let _stack_roots_tls = StackRootTLS::new(&roots);
let id = state.id; let id = state.id;
let frame_id = state.frame_id;
let parent_info = state.parent_info; let parent_info = state.parent_info;
let mem_profiler_chan = state.mem_profiler_chan.clone(); let mem_profiler_chan = state.mem_profiler_chan.clone();
let window_size = state.window_size; let window_size = state.window_size;
@ -474,7 +479,7 @@ impl ScriptThreadFactory for ScriptThread {
let mut failsafe = ScriptMemoryFailsafe::new(&script_thread); let mut failsafe = ScriptMemoryFailsafe::new(&script_thread);
let new_load = InProgressLoad::new(id, parent_info, layout_chan, window_size, let new_load = InProgressLoad::new(id, frame_id, parent_info, layout_chan, window_size,
load_data.url.clone()); load_data.url.clone());
script_thread.start_page_load(new_load, load_data); script_thread.start_page_load(new_load, load_data);
@ -888,8 +893,8 @@ impl ScriptThread {
fn handle_msg_from_constellation(&self, msg: ConstellationControlMsg) { fn handle_msg_from_constellation(&self, msg: ConstellationControlMsg) {
match msg { match msg {
ConstellationControlMsg::Navigate(parent_pipeline_id, pipeline_id, load_data, replace) => ConstellationControlMsg::Navigate(parent_pipeline_id, frame_id, load_data, replace) =>
self.handle_navigate(parent_pipeline_id, Some(pipeline_id), load_data, replace), self.handle_navigate(parent_pipeline_id, Some(frame_id), load_data, replace),
ConstellationControlMsg::SendEvent(id, event) => ConstellationControlMsg::SendEvent(id, event) =>
self.handle_event(id, event), self.handle_event(id, event),
ConstellationControlMsg::ResizeInactive(id, new_size) => ConstellationControlMsg::ResizeInactive(id, new_size) =>
@ -902,22 +907,22 @@ impl ScriptThread {
self.handle_thaw_msg(pipeline_id), self.handle_thaw_msg(pipeline_id),
ConstellationControlMsg::ChangeFrameVisibilityStatus(pipeline_id, visible) => ConstellationControlMsg::ChangeFrameVisibilityStatus(pipeline_id, visible) =>
self.handle_visibility_change_msg(pipeline_id, visible), self.handle_visibility_change_msg(pipeline_id, visible),
ConstellationControlMsg::NotifyVisibilityChange(parent_pipeline_id, pipeline_id, visible) => ConstellationControlMsg::NotifyVisibilityChange(parent_pipeline_id, frame_id, visible) =>
self.handle_visibility_change_complete_msg(parent_pipeline_id, pipeline_id, visible), self.handle_visibility_change_complete_msg(parent_pipeline_id, frame_id, visible),
ConstellationControlMsg::MozBrowserEvent(parent_pipeline_id, ConstellationControlMsg::MozBrowserEvent(parent_pipeline_id,
pipeline_id, frame_id,
event) => event) =>
self.handle_mozbrowser_event_msg(parent_pipeline_id, self.handle_mozbrowser_event_msg(parent_pipeline_id,
pipeline_id, frame_id,
event), event),
ConstellationControlMsg::UpdatePipelineId(parent_pipeline_id, ConstellationControlMsg::UpdatePipelineId(parent_pipeline_id,
old_pipeline_id, frame_id,
new_pipeline_id) => new_pipeline_id) =>
self.handle_update_pipeline_id(parent_pipeline_id, self.handle_update_pipeline_id(parent_pipeline_id,
old_pipeline_id, frame_id,
new_pipeline_id), new_pipeline_id),
ConstellationControlMsg::FocusIFrame(parent_pipeline_id, pipeline_id) => ConstellationControlMsg::FocusIFrame(parent_pipeline_id, frame_id) =>
self.handle_focus_iframe_msg(parent_pipeline_id, pipeline_id), self.handle_focus_iframe_msg(parent_pipeline_id, frame_id),
ConstellationControlMsg::WebDriverScriptCommand(pipeline_id, msg) => ConstellationControlMsg::WebDriverScriptCommand(pipeline_id, msg) =>
self.handle_webdriver_msg(pipeline_id, msg), self.handle_webdriver_msg(pipeline_id, msg),
ConstellationControlMsg::TickAllAnimations(pipeline_id) => ConstellationControlMsg::TickAllAnimations(pipeline_id) =>
@ -927,10 +932,10 @@ impl ScriptThread {
ConstellationControlMsg::WebFontLoaded(pipeline_id) => ConstellationControlMsg::WebFontLoaded(pipeline_id) =>
self.handle_web_font_loaded(pipeline_id), self.handle_web_font_loaded(pipeline_id),
ConstellationControlMsg::DispatchFrameLoadEvent { ConstellationControlMsg::DispatchFrameLoadEvent {
target: pipeline_id, parent: parent_pipeline_id } => target: frame_id, parent: parent_pipeline_id } =>
self.handle_frame_load_event(parent_pipeline_id, pipeline_id), self.handle_frame_load_event(parent_pipeline_id, frame_id),
ConstellationControlMsg::FramedContentChanged(parent_pipeline_id, pipeline_id) => ConstellationControlMsg::FramedContentChanged(parent_pipeline_id, frame_id) =>
self.handle_framed_content_changed(parent_pipeline_id, pipeline_id), self.handle_framed_content_changed(parent_pipeline_id, frame_id),
ConstellationControlMsg::ReportCSSError(pipeline_id, filename, line, column, msg) => ConstellationControlMsg::ReportCSSError(pipeline_id, filename, line, column, msg) =>
self.handle_css_error_reporting(pipeline_id, filename, line, column, msg), self.handle_css_error_reporting(pipeline_id, filename, line, column, msg),
ConstellationControlMsg::Reload(pipeline_id) => ConstellationControlMsg::Reload(pipeline_id) =>
@ -1139,6 +1144,7 @@ impl ScriptThread {
let NewLayoutInfo { let NewLayoutInfo {
parent_pipeline_id, parent_pipeline_id,
new_pipeline_id, new_pipeline_id,
frame_id,
frame_type, frame_type,
load_data, load_data,
pipeline_port, pipeline_port,
@ -1175,7 +1181,7 @@ impl ScriptThread {
.unwrap(); .unwrap();
// Kick off the fetch for the new resource. // Kick off the fetch for the new resource.
let new_load = InProgressLoad::new(new_pipeline_id, Some((parent_pipeline_id, frame_type)), let new_load = InProgressLoad::new(new_pipeline_id, frame_id, Some((parent_pipeline_id, frame_type)),
layout_chan, parent_window.window_size(), layout_chan, parent_window.window_size(),
load_data.url.clone()); load_data.url.clone());
self.start_page_load(new_load, load_data); self.start_page_load(new_load, load_data);
@ -1259,7 +1265,7 @@ impl ScriptThread {
} }
/// Updates iframe element after a change in visibility /// Updates iframe element after a change in visibility
fn handle_visibility_change_complete_msg(&self, parent_pipeline_id: PipelineId, id: PipelineId, visible: bool) { fn handle_visibility_change_complete_msg(&self, parent_pipeline_id: PipelineId, id: FrameId, visible: bool) {
if let Some(root_context) = self.browsing_context.get() { if let Some(root_context) = self.browsing_context.get() {
if let Some(ref inner_context) = root_context.find(parent_pipeline_id) { if let Some(ref inner_context) = root_context.find(parent_pipeline_id) {
if let Some(iframe) = inner_context.active_document().find_iframe(id) { if let Some(iframe) = inner_context.active_document().find_iframe(id) {
@ -1328,12 +1334,12 @@ impl ScriptThread {
fn handle_focus_iframe_msg(&self, fn handle_focus_iframe_msg(&self,
parent_pipeline_id: PipelineId, parent_pipeline_id: PipelineId,
pipeline_id: PipelineId) { frame_id: FrameId) {
let borrowed_context = self.root_browsing_context(); let borrowed_context = self.root_browsing_context();
let context = borrowed_context.find(parent_pipeline_id).unwrap(); let context = borrowed_context.find(parent_pipeline_id).unwrap();
let doc = context.active_document(); let doc = context.active_document();
let frame_element = doc.find_iframe(pipeline_id); let frame_element = doc.find_iframe(frame_id);
if let Some(ref frame_element) = frame_element { if let Some(ref frame_element) = frame_element {
doc.begin_focus_transaction(); doc.begin_focus_transaction();
@ -1344,11 +1350,11 @@ impl ScriptThread {
fn handle_framed_content_changed(&self, fn handle_framed_content_changed(&self,
parent_pipeline_id: PipelineId, parent_pipeline_id: PipelineId,
pipeline_id: PipelineId) { frame_id: FrameId) {
let root_context = self.root_browsing_context(); let root_context = self.root_browsing_context();
let context = root_context.find(parent_pipeline_id).unwrap(); let context = root_context.find(parent_pipeline_id).unwrap();
let doc = context.active_document(); let doc = context.active_document();
let frame_element = doc.find_iframe(pipeline_id); let frame_element = doc.find_iframe(frame_id);
if let Some(ref frame_element) = frame_element { if let Some(ref frame_element) = frame_element {
frame_element.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); frame_element.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
let window = context.active_window(); let window = context.active_window();
@ -1362,14 +1368,14 @@ impl ScriptThread {
/// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserloadstart /// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserloadstart
fn handle_mozbrowser_event_msg(&self, fn handle_mozbrowser_event_msg(&self,
parent_pipeline_id: PipelineId, parent_pipeline_id: PipelineId,
pipeline_id: Option<PipelineId>, frame_id: Option<FrameId>,
event: MozBrowserEvent) { event: MozBrowserEvent) {
match self.root_browsing_context().find(parent_pipeline_id) { match self.root_browsing_context().find(parent_pipeline_id) {
None => warn!("Mozbrowser event after pipeline {:?} closed.", parent_pipeline_id), None => warn!("Mozbrowser event after pipeline {:?} closed.", parent_pipeline_id),
Some(context) => match pipeline_id { Some(context) => match frame_id {
None => context.active_window().dispatch_mozbrowser_event(event), None => context.active_window().dispatch_mozbrowser_event(event),
Some(pipeline_id) => match context.active_document().find_iframe(pipeline_id) { Some(frame_id) => match context.active_document().find_iframe(frame_id) {
None => warn!("Mozbrowser event after iframe {:?}/{:?} closed.", parent_pipeline_id, pipeline_id), None => warn!("Mozbrowser event after iframe {:?}/{:?} closed.", parent_pipeline_id, frame_id),
Some(frame_element) => frame_element.dispatch_mozbrowser_event(event), Some(frame_element) => frame_element.dispatch_mozbrowser_event(event),
}, },
}, },
@ -1378,13 +1384,13 @@ impl ScriptThread {
fn handle_update_pipeline_id(&self, fn handle_update_pipeline_id(&self,
parent_pipeline_id: PipelineId, parent_pipeline_id: PipelineId,
old_pipeline_id: PipelineId, frame_id: FrameId,
new_pipeline_id: PipelineId) { new_pipeline_id: PipelineId) {
let borrowed_context = self.root_browsing_context(); let borrowed_context = self.root_browsing_context();
let frame_element = borrowed_context.find(parent_pipeline_id).and_then(|context| { let frame_element = borrowed_context.find(parent_pipeline_id).and_then(|context| {
let doc = context.active_document(); let doc = context.active_document();
doc.find_iframe(old_pipeline_id) doc.find_iframe(frame_id)
}); });
frame_element.unwrap().update_pipeline_id(new_pipeline_id); frame_element.unwrap().update_pipeline_id(new_pipeline_id);
@ -1567,13 +1573,13 @@ impl ScriptThread {
} }
/// Notify the containing document of a child frame that has completed loading. /// Notify the containing document of a child frame that has completed loading.
fn handle_frame_load_event(&self, parent_pipeline_id: PipelineId, id: PipelineId) { fn handle_frame_load_event(&self, parent_pipeline_id: PipelineId, id: FrameId) {
let document = match self.root_browsing_context().find(parent_pipeline_id) { let document = match self.root_browsing_context().find(parent_pipeline_id) {
Some(browsing_context) => browsing_context.active_document(), Some(browsing_context) => browsing_context.active_document(),
None => return warn!("Message sent to closed pipeline {}.", parent_pipeline_id), None => return warn!("Message sent to closed pipeline {}.", parent_pipeline_id),
}; };
if let Some(iframe) = document.find_iframe(id) { if let Some(iframe) = document.find_iframe(id) {
iframe.iframe_load_event_steps(id); iframe.iframe_load_event_steps();
} }
} }
@ -1609,7 +1615,7 @@ impl ScriptThread {
root_context.and_then(|root_context| { root_context.and_then(|root_context| {
root_context.find(parent_id).and_then(|context| { root_context.find(parent_id).and_then(|context| {
let doc = context.active_document(); let doc = context.active_document();
doc.find_iframe(incomplete.pipeline_id) doc.find_iframe(incomplete.frame_id)
}) })
}) })
}); });
@ -2033,7 +2039,7 @@ impl ScriptThread {
/// The entry point for content to notify that a new load has been requested /// The entry point for content to notify that a new load has been requested
/// for the given pipeline (specifically the "navigate" algorithm). /// for the given pipeline (specifically the "navigate" algorithm).
fn handle_navigate(&self, parent_pipeline_id: PipelineId, fn handle_navigate(&self, parent_pipeline_id: PipelineId,
pipeline_id: Option<PipelineId>, frame_id: Option<FrameId>,
load_data: LoadData, load_data: LoadData,
replace: bool) { replace: bool) {
// Step 7. // Step 7.
@ -2053,12 +2059,12 @@ impl ScriptThread {
} }
} }
match pipeline_id { match frame_id {
Some(pipeline_id) => { Some(frame_id) => {
let root_context = self.root_browsing_context(); let root_context = self.root_browsing_context();
let iframe = root_context.find(parent_pipeline_id).and_then(|context| { let iframe = root_context.find(parent_pipeline_id).and_then(|context| {
let doc = context.active_document(); let doc = context.active_document();
doc.find_iframe(pipeline_id) doc.find_iframe(frame_id)
}); });
if let Some(iframe) = iframe.r() { if let Some(iframe) = iframe.r() {
iframe.navigate_or_reload_child_browsing_context(Some(load_data), replace); iframe.navigate_or_reload_child_browsing_context(Some(load_data), replace);

View file

@ -166,7 +166,9 @@ pub struct NewLayoutInfo {
pub parent_pipeline_id: PipelineId, pub parent_pipeline_id: PipelineId,
/// Id of the newly-created pipeline. /// Id of the newly-created pipeline.
pub new_pipeline_id: PipelineId, pub new_pipeline_id: PipelineId,
/// Type of the new frame associated with this pipeline. /// Id of the frame associated with this pipeline.
pub frame_id: FrameId,
/// Type of the frame associated with this pipeline.
pub frame_type: FrameType, pub frame_type: FrameType,
/// Network request data which will be initiated by the script thread. /// Network request data which will be initiated by the script thread.
pub load_data: LoadData, pub load_data: LoadData,
@ -206,22 +208,20 @@ pub enum ConstellationControlMsg {
/// Notifies script thread whether frame is visible /// Notifies script thread whether frame is visible
ChangeFrameVisibilityStatus(PipelineId, bool), ChangeFrameVisibilityStatus(PipelineId, bool),
/// Notifies script thread that frame visibility change is complete /// Notifies script thread that frame visibility change is complete
/// First PipelineId is for the parent, second PipelineId is for the actual pipeline. /// PipelineId is for the parent, FrameId is for the actual frame.
NotifyVisibilityChange(PipelineId, PipelineId, bool), NotifyVisibilityChange(PipelineId, FrameId, bool),
/// Notifies script thread that a url should be loaded in this iframe. /// Notifies script thread that a url should be loaded in this iframe.
/// First PipelineId is for the parent, second PipelineId is for the actual pipeline. /// PipelineId is for the parent, FrameId is for the actual frame.
Navigate(PipelineId, PipelineId, LoadData, bool), Navigate(PipelineId, FrameId, LoadData, bool),
/// Requests the script thread forward a mozbrowser event to an iframe it owns, /// Requests the script thread forward a mozbrowser event to an iframe it owns,
/// or to the window if no child pipeline id is provided. /// or to the window if no child frame id is provided.
/// First PipelineId is for the parent, second PipelineId is for the actual pipeline. MozBrowserEvent(PipelineId, Option<FrameId>, MozBrowserEvent),
MozBrowserEvent(PipelineId, Option<PipelineId>, MozBrowserEvent),
/// Updates the current pipeline ID of a given iframe. /// Updates the current pipeline ID of a given iframe.
/// First PipelineId is for the parent, second is the old PipelineId for the frame, /// First PipelineId is for the parent, second is the new PipelineId for the frame.
/// third is the new PipelineId for the frame. UpdatePipelineId(PipelineId, FrameId, PipelineId),
UpdatePipelineId(PipelineId, PipelineId, PipelineId),
/// Set an iframe to be focused. Used when an element in an iframe gains focus. /// Set an iframe to be focused. Used when an element in an iframe gains focus.
/// First PipelineId is for the parent, second PipelineId is for the actual pipeline. /// PipelineId is for the parent, FrameId is for the actual frame.
FocusIFrame(PipelineId, PipelineId), FocusIFrame(PipelineId, FrameId),
/// Passes a webdriver command to the script thread for execution /// Passes a webdriver command to the script thread for execution
WebDriverScriptCommand(PipelineId, WebDriverScriptCommand), WebDriverScriptCommand(PipelineId, WebDriverScriptCommand),
/// Notifies script thread that all animations are done /// Notifies script thread that all animations are done
@ -233,14 +233,14 @@ pub enum ConstellationControlMsg {
WebFontLoaded(PipelineId), WebFontLoaded(PipelineId),
/// Cause a `load` event to be dispatched at the appropriate frame element. /// Cause a `load` event to be dispatched at the appropriate frame element.
DispatchFrameLoadEvent { DispatchFrameLoadEvent {
/// The pipeline that has been marked as loaded. /// The frame that has been marked as loaded.
target: PipelineId, target: FrameId,
/// The pipeline that contains a frame loading the target pipeline. /// The pipeline that contains a frame loading the target pipeline.
parent: PipelineId, parent: PipelineId,
}, },
/// Notifies a parent frame that one of its child frames is now active. /// Notifies a parent pipeline that one of its child frames is now active.
/// First PipelineId is for the parent, second PipelineId is for the actual pipeline. /// PipelineId is for the parent, FrameId is the child frame.
FramedContentChanged(PipelineId, PipelineId), FramedContentChanged(PipelineId, FrameId),
/// Report an error from a CSS parser for the given pipeline /// Report an error from a CSS parser for the given pipeline
ReportCSSError(PipelineId, String, usize, usize, String), ReportCSSError(PipelineId, String, usize, usize, String),
/// Reload the given page. /// Reload the given page.
@ -428,6 +428,8 @@ pub struct InitialScriptState {
/// The subpage ID of this pipeline to create in its pipeline parent. /// The subpage ID of this pipeline to create in its pipeline parent.
/// If `None`, this is the root. /// If `None`, this is the root.
pub parent_info: Option<(PipelineId, FrameType)>, pub parent_info: Option<(PipelineId, FrameType)>,
/// The ID of the frame this script is part of.
pub frame_id: FrameId,
/// A channel with which messages can be sent to us (the script thread). /// A channel with which messages can be sent to us (the script thread).
pub control_chan: IpcSender<ConstellationControlMsg>, pub control_chan: IpcSender<ConstellationControlMsg>,
/// A port on which messages sent by the constellation to script can be received. /// A port on which messages sent by the constellation to script can be received.

View file

@ -85,7 +85,7 @@ pub enum ScriptMsg {
LoadUrl(PipelineId, LoadData, bool), LoadUrl(PipelineId, LoadData, bool),
/// Dispatch a mozbrowser event to a given iframe, /// Dispatch a mozbrowser event to a given iframe,
/// or to the window if no subpage id is provided. /// or to the window if no subpage id is provided.
/// First PipelineId is for the parent, second PipelineId is for the actual pipeline. /// First PipelineId is for the parent, second PipelineId is in the frame.
MozBrowserEvent(PipelineId, Option<PipelineId>, MozBrowserEvent), MozBrowserEvent(PipelineId, Option<PipelineId>, MozBrowserEvent),
/// HTMLIFrameElement Forward or Back traversal. /// HTMLIFrameElement Forward or Back traversal.
TraverseHistory(Option<PipelineId>, TraversalDirection), TraverseHistory(Option<PipelineId>, TraversalDirection),