mirror of
https://github.com/servo/servo.git
synced 2025-08-04 05:00:08 +01:00
Removed root browsing context from constellation.
This commit is contained in:
parent
ad47d33511
commit
2fd925bac9
5 changed files with 181 additions and 153 deletions
|
@ -96,6 +96,11 @@ impl BrowsingContext {
|
||||||
self.instant = entry.instant;
|
self.instant = entry.instant;
|
||||||
self.load_data = entry.load_data;
|
self.load_data = entry.load_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Is this a top-level browsing context?
|
||||||
|
pub fn is_top_level(&self) -> bool {
|
||||||
|
self.id == self.top_level_id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An entry in a browsing context's session history.
|
/// An entry in a browsing context's session history.
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
//! example tabs in a browser UI), and nested ones (typically caused
|
//! example tabs in a browser UI), and nested ones (typically caused
|
||||||
//! by `iframe` elements). Browsing contexts have a hierarchy
|
//! by `iframe` elements). Browsing contexts have a hierarchy
|
||||||
//! (typically caused by `iframe`s containing `iframe`s), giving rise
|
//! (typically caused by `iframe`s containing `iframe`s), giving rise
|
||||||
//! to a tree with a root top-level browsing context. The logical
|
//! to a forest whose roots are top-level browsing context. The logical
|
||||||
//! relationship between these types is:
|
//! relationship between these types is:
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
|
@ -38,6 +38,7 @@
|
||||||
//! | | ------prev*--------> | | <---pipeline*-- | |
|
//! | | ------prev*--------> | | <---pipeline*-- | |
|
||||||
//! | | ------next*--------> | | +---------+
|
//! | | ------next*--------> | | +---------+
|
||||||
//! | | | |
|
//! | | | |
|
||||||
|
//! | | <-top_level--------- | |
|
||||||
//! | | <-browsing_context-- | |
|
//! | | <-browsing_context-- | |
|
||||||
//! +------------+ +------------+
|
//! +------------+ +------------+
|
||||||
//! ```
|
//! ```
|
||||||
|
@ -259,9 +260,6 @@ pub struct Constellation<Message, LTF, STF> {
|
||||||
/// we store a `SessionHistoryChange` object for the navigation in progress.
|
/// we store a `SessionHistoryChange` object for the navigation in progress.
|
||||||
pending_changes: Vec<SessionHistoryChange>,
|
pending_changes: Vec<SessionHistoryChange>,
|
||||||
|
|
||||||
/// The root browsing context.
|
|
||||||
root_browsing_context_id: TopLevelBrowsingContextId,
|
|
||||||
|
|
||||||
/// The currently focused pipeline for key events.
|
/// The currently focused pipeline for key events.
|
||||||
focus_pipeline_id: Option<PipelineId>,
|
focus_pipeline_id: Option<PipelineId>,
|
||||||
|
|
||||||
|
@ -355,7 +353,7 @@ impl WebDriverData {
|
||||||
/// This enum gives the possible states of preparing such an image.
|
/// This enum gives the possible states of preparing such an image.
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
enum ReadyToSave {
|
enum ReadyToSave {
|
||||||
NoRootBrowsingContext,
|
NoTopLevelBrowsingContext,
|
||||||
PendingChanges,
|
PendingChanges,
|
||||||
WebFontNotLoaded,
|
WebFontNotLoaded,
|
||||||
DocumentLoading,
|
DocumentLoading,
|
||||||
|
@ -540,7 +538,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
pending_changes: vec!(),
|
pending_changes: vec!(),
|
||||||
// We initialize the namespace at 1, since we reserved namespace 0 for the constellation
|
// We initialize the namespace at 1, since we reserved namespace 0 for the constellation
|
||||||
next_pipeline_namespace_id: PipelineNamespaceId(1),
|
next_pipeline_namespace_id: PipelineNamespaceId(1),
|
||||||
root_browsing_context_id: TopLevelBrowsingContextId::new(),
|
|
||||||
focus_pipeline_id: None,
|
focus_pipeline_id: None,
|
||||||
time_profiler_chan: state.time_profiler_chan,
|
time_profiler_chan: state.time_profiler_chan,
|
||||||
mem_profiler_chan: state.mem_profiler_chan,
|
mem_profiler_chan: state.mem_profiler_chan,
|
||||||
|
@ -848,13 +845,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
|
|
||||||
let request = match request {
|
let request = match request {
|
||||||
Ok(request) => request,
|
Ok(request) => request,
|
||||||
Err(err) => {
|
Err(err) => return error!("Deserialization failed ({}).", err),
|
||||||
// Treat deserialization error the same as receiving a panic message
|
|
||||||
debug!("Deserialization failed ({:?}).", err);
|
|
||||||
let reason = format!("Deserialization failed ({})", err);
|
|
||||||
let root_browsing_context_id = self.root_browsing_context_id;
|
|
||||||
return self.handle_panic(root_browsing_context_id, reason, None);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match request {
|
match request {
|
||||||
|
@ -912,7 +903,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
self.handle_get_browsing_context(pipeline_id, resp_chan);
|
self.handle_get_browsing_context(pipeline_id, resp_chan);
|
||||||
}
|
}
|
||||||
FromCompositorMsg::GetPipeline(browsing_context_id, resp_chan) => {
|
FromCompositorMsg::GetPipeline(browsing_context_id, resp_chan) => {
|
||||||
debug!("constellation got get root pipeline message");
|
debug!("constellation got get pipeline message");
|
||||||
self.handle_get_pipeline(browsing_context_id, resp_chan);
|
self.handle_get_pipeline(browsing_context_id, resp_chan);
|
||||||
}
|
}
|
||||||
FromCompositorMsg::GetFocusTopLevelBrowsingContext(resp_chan) => {
|
FromCompositorMsg::GetFocusTopLevelBrowsingContext(resp_chan) => {
|
||||||
|
@ -1054,11 +1045,9 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
debug!("constellation got postMessage message");
|
debug!("constellation got postMessage message");
|
||||||
self.handle_post_message_msg(browsing_context_id, origin, data);
|
self.handle_post_message_msg(browsing_context_id, origin, data);
|
||||||
}
|
}
|
||||||
FromScriptMsg::MozBrowserEvent(parent_pipeline_id, pipeline_id, event) => {
|
FromScriptMsg::MozBrowserEvent(pipeline_id, top_level_browsing_context_id, event) => {
|
||||||
debug!("constellation got mozbrowser event message");
|
debug!("constellation got mozbrowser event message");
|
||||||
self.handle_mozbrowser_event_msg(parent_pipeline_id,
|
self.handle_mozbrowser_event_msg(pipeline_id, top_level_browsing_context_id, event);
|
||||||
pipeline_id,
|
|
||||||
event);
|
|
||||||
}
|
}
|
||||||
FromScriptMsg::Focus(pipeline_id) => {
|
FromScriptMsg::Focus(pipeline_id) => {
|
||||||
debug!("constellation got focus message");
|
debug!("constellation got focus message");
|
||||||
|
@ -1259,10 +1248,15 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
|
|
||||||
self.mem_profiler_chan.send(mem::ProfilerMsg::Exit);
|
self.mem_profiler_chan.send(mem::ProfilerMsg::Exit);
|
||||||
|
|
||||||
// TODO: exit before the root browsing context is initialized?
|
// Close the top-level browsing contexts
|
||||||
debug!("Removing root browsing context.");
|
let browsing_context_ids: Vec<BrowsingContextId> = self.browsing_contexts.values()
|
||||||
let root_browsing_context_id = BrowsingContextId::from(self.root_browsing_context_id);
|
.filter(|browsing_context| browsing_context.is_top_level())
|
||||||
self.close_browsing_context(root_browsing_context_id, ExitPipelineMode::Normal);
|
.map(|browsing_context| browsing_context.id)
|
||||||
|
.collect();
|
||||||
|
for browsing_context_id in browsing_context_ids {
|
||||||
|
debug!("Removing top-level browsing context {}.", browsing_context_id);
|
||||||
|
self.close_browsing_context(browsing_context_id, ExitPipelineMode::Normal);
|
||||||
|
}
|
||||||
|
|
||||||
// Close any pending changes and pipelines
|
// Close any pending changes and pipelines
|
||||||
while let Some(pending) = self.pending_changes.pop() {
|
while let Some(pending) = self.pending_changes.pop() {
|
||||||
|
@ -1362,15 +1356,14 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
|
|
||||||
fn handle_send_error(&mut self, pipeline_id: PipelineId, err: IpcError) {
|
fn handle_send_error(&mut self, pipeline_id: PipelineId, err: IpcError) {
|
||||||
// Treat send error the same as receiving a panic message
|
// Treat send error the same as receiving a panic message
|
||||||
debug!("Pipeline {:?} send error ({}).", pipeline_id, err);
|
error!("Pipeline {} send error ({}).", pipeline_id, err);
|
||||||
let top_level_browsing_context_id = self.pipelines.get(&pipeline_id)
|
let top_level_browsing_context_id = self.pipelines.get(&pipeline_id)
|
||||||
.map(|pipeline| pipeline.browsing_context_id)
|
.map(|pipeline| pipeline.top_level_browsing_context_id);
|
||||||
.and_then(|browsing_context_id| self.browsing_contexts.get(&browsing_context_id))
|
if let Some(top_level_browsing_context_id) = top_level_browsing_context_id {
|
||||||
.map(|browsing_context| browsing_context.top_level_id)
|
|
||||||
.unwrap_or(self.root_browsing_context_id);
|
|
||||||
let reason = format!("Send failed ({})", err);
|
let reason = format!("Send failed ({})", err);
|
||||||
self.handle_panic(top_level_browsing_context_id, reason, None);
|
self.handle_panic(top_level_browsing_context_id, reason, None);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_panic(&mut self,
|
fn handle_panic(&mut self,
|
||||||
top_level_browsing_context_id: TopLevelBrowsingContextId,
|
top_level_browsing_context_id: TopLevelBrowsingContextId,
|
||||||
|
@ -1424,6 +1417,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
let sandbox = IFrameSandboxState::IFrameSandboxed;
|
let sandbox = IFrameSandboxState::IFrameSandboxed;
|
||||||
self.new_pipeline(new_pipeline_id, browsing_context_id, top_level_browsing_context_id, parent_info,
|
self.new_pipeline(new_pipeline_id, browsing_context_id, top_level_browsing_context_id, parent_info,
|
||||||
window_size, load_data.clone(), sandbox, false);
|
window_size, load_data.clone(), sandbox, false);
|
||||||
|
self.handle_load_start_msg(new_pipeline_id);
|
||||||
self.pending_changes.push(SessionHistoryChange {
|
self.pending_changes.push(SessionHistoryChange {
|
||||||
top_level_browsing_context_id: top_level_browsing_context_id,
|
top_level_browsing_context_id: top_level_browsing_context_id,
|
||||||
browsing_context_id: browsing_context_id,
|
browsing_context_id: browsing_context_id,
|
||||||
|
@ -1439,12 +1433,11 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
entry: LogEntry)
|
entry: LogEntry)
|
||||||
{
|
{
|
||||||
debug!("Received log entry {:?}.", entry);
|
debug!("Received log entry {:?}.", entry);
|
||||||
let top_level_browsing_context_id = top_level_browsing_context_id.unwrap_or(self.root_browsing_context_id);
|
match (entry, top_level_browsing_context_id) {
|
||||||
match entry {
|
(LogEntry::Panic(reason, backtrace), Some(top_level_browsing_context_id)) => {
|
||||||
LogEntry::Panic(reason, backtrace) => {
|
|
||||||
self.handle_panic(top_level_browsing_context_id, reason, Some(backtrace));
|
self.handle_panic(top_level_browsing_context_id, reason, Some(backtrace));
|
||||||
},
|
},
|
||||||
LogEntry::Error(reason) | LogEntry::Warn(reason) => {
|
(LogEntry::Panic(reason, _), _) | (LogEntry::Error(reason), _) | (LogEntry::Warn(reason), _) => {
|
||||||
// VecDeque::truncate is unstable
|
// VecDeque::truncate is unstable
|
||||||
if WARNINGS_BUFFER_SIZE <= self.handled_warnings.len() {
|
if WARNINGS_BUFFER_SIZE <= self.handled_warnings.len() {
|
||||||
self.handled_warnings.pop_front();
|
self.handled_warnings.pop_front();
|
||||||
|
@ -1468,24 +1461,25 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
|
|
||||||
fn handle_init_load(&mut self, url: ServoUrl) {
|
fn handle_init_load(&mut self, url: ServoUrl) {
|
||||||
let window_size = self.window_size.initial_viewport;
|
let window_size = self.window_size.initial_viewport;
|
||||||
let root_pipeline_id = PipelineId::new();
|
let pipeline_id = PipelineId::new();
|
||||||
let root_browsing_context_id = self.root_browsing_context_id;
|
let top_level_browsing_context_id = TopLevelBrowsingContextId::new();
|
||||||
self.focus_pipeline_id = Some(root_pipeline_id);
|
let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id);
|
||||||
let load_data = LoadData::new(url.clone(), None, None, None);
|
let load_data = LoadData::new(url.clone(), None, None, None);
|
||||||
let sandbox = IFrameSandboxState::IFrameUnsandboxed;
|
let sandbox = IFrameSandboxState::IFrameUnsandboxed;
|
||||||
self.new_pipeline(root_pipeline_id,
|
self.focus_pipeline_id = Some(pipeline_id);
|
||||||
BrowsingContextId::from(root_browsing_context_id),
|
self.new_pipeline(pipeline_id,
|
||||||
root_browsing_context_id,
|
browsing_context_id,
|
||||||
|
top_level_browsing_context_id,
|
||||||
None,
|
None,
|
||||||
Some(window_size),
|
Some(window_size),
|
||||||
load_data.clone(),
|
load_data.clone(),
|
||||||
sandbox,
|
sandbox,
|
||||||
false);
|
false);
|
||||||
self.handle_load_start_msg(root_pipeline_id);
|
self.handle_load_start_msg(pipeline_id);
|
||||||
self.pending_changes.push(SessionHistoryChange {
|
self.pending_changes.push(SessionHistoryChange {
|
||||||
top_level_browsing_context_id: root_browsing_context_id,
|
top_level_browsing_context_id: top_level_browsing_context_id,
|
||||||
browsing_context_id: BrowsingContextId::from(root_browsing_context_id),
|
browsing_context_id: browsing_context_id,
|
||||||
new_pipeline_id: root_pipeline_id,
|
new_pipeline_id: pipeline_id,
|
||||||
load_data: load_data,
|
load_data: load_data,
|
||||||
replace_instant: None,
|
replace_instant: None,
|
||||||
});
|
});
|
||||||
|
@ -1507,7 +1501,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
let (browsing_context_id, parent_id) = match self.pipelines.get(&pipeline_id) {
|
let (browsing_context_id, parent_id) = match self.pipelines.get(&pipeline_id) {
|
||||||
Some(pipeline) => match pipeline.parent_info {
|
Some(pipeline) => match pipeline.parent_info {
|
||||||
Some((parent_id, _)) => (pipeline.browsing_context_id, parent_id),
|
Some((parent_id, _)) => (pipeline.browsing_context_id, parent_id),
|
||||||
None => return warn!("Pipeline {} has no parent.", pipeline_id),
|
None => return debug!("Pipeline {} has no parent.", pipeline_id),
|
||||||
},
|
},
|
||||||
None => return warn!("Pipeline {} loaded after closure.", pipeline_id),
|
None => return warn!("Pipeline {} loaded after closure.", pipeline_id),
|
||||||
};
|
};
|
||||||
|
@ -1578,6 +1572,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create the new pipeline, attached to the parent and push to pending changes
|
// Create the new pipeline, attached to the parent and push to pending changes
|
||||||
|
self.handle_load_start_msg(load_info.info.new_pipeline_id);
|
||||||
self.pending_changes.push(SessionHistoryChange {
|
self.pending_changes.push(SessionHistoryChange {
|
||||||
top_level_browsing_context_id: load_info.info.top_level_browsing_context_id,
|
top_level_browsing_context_id: load_info.info.top_level_browsing_context_id,
|
||||||
browsing_context_id: load_info.info.browsing_context_id,
|
browsing_context_id: load_info.info.browsing_context_id,
|
||||||
|
@ -1643,6 +1638,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
assert!(!self.pipelines.contains_key(&new_pipeline_id));
|
assert!(!self.pipelines.contains_key(&new_pipeline_id));
|
||||||
self.pipelines.insert(new_pipeline_id, pipeline);
|
self.pipelines.insert(new_pipeline_id, pipeline);
|
||||||
|
|
||||||
|
self.handle_load_start_msg(new_pipeline_id);
|
||||||
self.pending_changes.push(SessionHistoryChange {
|
self.pending_changes.push(SessionHistoryChange {
|
||||||
top_level_browsing_context_id: top_level_browsing_context_id,
|
top_level_browsing_context_id: top_level_browsing_context_id,
|
||||||
browsing_context_id: browsing_context_id,
|
browsing_context_id: browsing_context_id,
|
||||||
|
@ -1689,8 +1685,15 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
pipeline_id: PipelineId,
|
pipeline_id: PipelineId,
|
||||||
message: String,
|
message: String,
|
||||||
sender: IpcSender<bool>) {
|
sender: IpcSender<bool>) {
|
||||||
let pipeline_isnt_root = self.pipelines.get(&pipeline_id).and_then(|pipeline| pipeline.parent_info).is_some();
|
let top_level_browsing_context_id = self.pipelines.get(&pipeline_id)
|
||||||
let mozbrowser_modal_prompt = pipeline_isnt_root && PREFS.is_mozbrowser_enabled();
|
.map(|pipeline| pipeline.top_level_browsing_context_id);
|
||||||
|
let browser_pipeline_id = top_level_browsing_context_id
|
||||||
|
.map(BrowsingContextId::from)
|
||||||
|
.and_then(|browsing_context_id| self.browsing_contexts.get(&browsing_context_id))
|
||||||
|
.and_then(|browsing_context| self.pipelines.get(&browsing_context.pipeline_id))
|
||||||
|
.and_then(|pipeline| pipeline.parent_info)
|
||||||
|
.map(|(browser_pipeline_id, _)| browser_pipeline_id);
|
||||||
|
let mozbrowser_modal_prompt = PREFS.is_mozbrowser_enabled() && browser_pipeline_id.is_some();
|
||||||
|
|
||||||
if mozbrowser_modal_prompt {
|
if mozbrowser_modal_prompt {
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowsershowmodalprompt
|
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowsershowmodalprompt
|
||||||
|
@ -1698,19 +1701,11 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
let title = String::from("Alert");
|
let title = String::from("Alert");
|
||||||
let return_value = String::from("");
|
let return_value = String::from("");
|
||||||
let event = MozBrowserEvent::ShowModalPrompt(prompt_type, title, message, return_value);
|
let event = MozBrowserEvent::ShowModalPrompt(prompt_type, title, message, return_value);
|
||||||
let root_browsing_context_id = BrowsingContextId::from(self.root_browsing_context_id);
|
match browser_pipeline_id.and_then(|id| self.pipelines.get(&id)) {
|
||||||
let top_level_browsing_context_id = self.pipelines.get(&pipeline_id)
|
None => warn!("Alert sent after browser pipeline closure."),
|
||||||
.and_then(|pipeline| self.browsing_contexts.get(&pipeline.browsing_context_id))
|
|
||||||
.map(|browsing_context| browsing_context.top_level_id);
|
|
||||||
|
|
||||||
match self.browsing_contexts.get(&root_browsing_context_id) {
|
|
||||||
None => warn!("Alert sent after root browsing context closure."),
|
|
||||||
Some(root_browsing_context) => match self.pipelines.get(&root_browsing_context.pipeline_id) {
|
|
||||||
None => warn!("Alert sent after root pipeline closure."),
|
|
||||||
Some(pipeline) => pipeline.trigger_mozbrowser_event(top_level_browsing_context_id, event),
|
Some(pipeline) => pipeline.trigger_mozbrowser_event(top_level_browsing_context_id, event),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let result = sender.send(!mozbrowser_modal_prompt);
|
let result = sender.send(!mozbrowser_modal_prompt);
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
|
@ -1740,14 +1735,13 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
let (browsing_context_id, parent_info) = match self.pipelines.get(&source_id) {
|
let (browsing_context_id, parent_info) = match self.pipelines.get(&source_id) {
|
||||||
Some(pipeline) => (pipeline.browsing_context_id, pipeline.parent_info),
|
Some(pipeline) => (pipeline.browsing_context_id, pipeline.parent_info),
|
||||||
None => {
|
None => {
|
||||||
warn!("Pipeline {:?} loaded after closure.", source_id);
|
warn!("Pipeline {} loaded after closure.", source_id);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match parent_info {
|
match parent_info {
|
||||||
Some((parent_pipeline_id, _)) => {
|
Some((parent_pipeline_id, _)) => {
|
||||||
self.handle_load_start_msg(source_id);
|
// Find the script thread for the pipeline containing the 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,
|
let msg = ConstellationControlMsg::Navigate(parent_pipeline_id,
|
||||||
browsing_context_id,
|
browsing_context_id,
|
||||||
|
@ -1763,14 +1757,12 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
self.handle_send_error(parent_pipeline_id, e);
|
self.handle_send_error(parent_pipeline_id, e);
|
||||||
}
|
}
|
||||||
Some(source_id)
|
None
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let root_browsing_context_id = self.root_browsing_context_id;
|
|
||||||
|
|
||||||
// Make sure no pending page would be overridden.
|
// Make sure no pending page would be overridden.
|
||||||
for change in &self.pending_changes {
|
for change in &self.pending_changes {
|
||||||
if change.browsing_context_id == BrowsingContextId::from(root_browsing_context_id) {
|
if change.browsing_context_id == browsing_context_id {
|
||||||
// id that sent load msg is being changed already; abort
|
// id that sent load msg is being changed already; abort
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -1784,30 +1776,31 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.handle_load_start_msg(source_id);
|
|
||||||
// Being here means either there are no pending changes, or none of the pending
|
// Being here means either there are no pending changes, or none of the pending
|
||||||
// changes would be overridden by changing the subframe associated with source_id.
|
// changes would be overridden by changing the subframe associated with source_id.
|
||||||
|
|
||||||
// Create the new pipeline
|
// Create the new pipeline
|
||||||
let window_size = self.browsing_contexts.get(&BrowsingContextId::from(root_browsing_context_id))
|
let (top_level_id, window_size, timestamp) = match self.browsing_contexts.get(&browsing_context_id) {
|
||||||
.and_then(|browsing_context| browsing_context.size);
|
Some(context) => (context.top_level_id, context.size, context.instant),
|
||||||
|
None => {
|
||||||
|
warn!("Browsing context {} loaded after closure.", browsing_context_id);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
let new_pipeline_id = PipelineId::new();
|
let new_pipeline_id = PipelineId::new();
|
||||||
let sandbox = IFrameSandboxState::IFrameUnsandboxed;
|
let sandbox = IFrameSandboxState::IFrameUnsandboxed;
|
||||||
let replace_instant = if replace {
|
let replace_instant = if replace { Some(timestamp) } else { None };
|
||||||
self.browsing_contexts.get(&browsing_context_id).map(|browsing_context| browsing_context.instant)
|
self.handle_load_start_msg(new_pipeline_id);
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
self.pending_changes.push(SessionHistoryChange {
|
self.pending_changes.push(SessionHistoryChange {
|
||||||
top_level_browsing_context_id: root_browsing_context_id,
|
top_level_browsing_context_id: top_level_id,
|
||||||
browsing_context_id: BrowsingContextId::from(root_browsing_context_id),
|
browsing_context_id: browsing_context_id,
|
||||||
new_pipeline_id: new_pipeline_id,
|
new_pipeline_id: new_pipeline_id,
|
||||||
load_data: load_data.clone(),
|
load_data: load_data.clone(),
|
||||||
replace_instant: replace_instant,
|
replace_instant: replace_instant,
|
||||||
});
|
});
|
||||||
self.new_pipeline(new_pipeline_id,
|
self.new_pipeline(new_pipeline_id,
|
||||||
BrowsingContextId::from(root_browsing_context_id),
|
browsing_context_id,
|
||||||
root_browsing_context_id,
|
top_level_id,
|
||||||
None,
|
None,
|
||||||
window_size,
|
window_size,
|
||||||
load_data,
|
load_data,
|
||||||
|
@ -1885,15 +1878,9 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_key_msg(&mut self, ch: Option<char>, key: Key, state: KeyState, mods: KeyModifiers) {
|
fn handle_key_msg(&mut self, ch: Option<char>, key: Key, state: KeyState, mods: KeyModifiers) {
|
||||||
// Send to the explicitly focused pipeline (if it exists), or the root
|
// Send to the explicitly focused pipeline. If it doesn't exist, fall back to sending to
|
||||||
// browsing context's current pipeline. If neither exist, fall back to sending to
|
// the compositor.
|
||||||
// the compositor below.
|
match self.focus_pipeline_id {
|
||||||
let root_browsing_context_id = BrowsingContextId::from(self.root_browsing_context_id);
|
|
||||||
let root_pipeline_id = self.browsing_contexts.get(&root_browsing_context_id)
|
|
||||||
.map(|root_browsing_context| root_browsing_context.pipeline_id);
|
|
||||||
let pipeline_id = self.focus_pipeline_id.or(root_pipeline_id);
|
|
||||||
|
|
||||||
match pipeline_id {
|
|
||||||
Some(pipeline_id) => {
|
Some(pipeline_id) => {
|
||||||
let event = CompositorEvent::KeyEvent(ch, key, state, mods);
|
let event = CompositorEvent::KeyEvent(ch, key, state, mods);
|
||||||
let msg = ConstellationControlMsg::SendEvent(pipeline_id, event);
|
let msg = ConstellationControlMsg::SendEvent(pipeline_id, event);
|
||||||
|
@ -1958,8 +1945,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_mozbrowser_event_msg(&mut self,
|
fn handle_mozbrowser_event_msg(&mut self,
|
||||||
parent_pipeline_id: PipelineId,
|
|
||||||
pipeline_id: PipelineId,
|
pipeline_id: PipelineId,
|
||||||
|
top_level_browsing_context_id: TopLevelBrowsingContextId,
|
||||||
event: MozBrowserEvent) {
|
event: MozBrowserEvent) {
|
||||||
assert!(PREFS.is_mozbrowser_enabled());
|
assert!(PREFS.is_mozbrowser_enabled());
|
||||||
|
|
||||||
|
@ -1967,12 +1954,9 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
// 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.
|
||||||
let top_level_browsing_context_id = self.pipelines.get(&pipeline_id)
|
match self.pipelines.get(&pipeline_id) {
|
||||||
.and_then(|pipeline| self.browsing_contexts.get(&pipeline.browsing_context_id))
|
Some(pipeline) => pipeline.trigger_mozbrowser_event(Some(top_level_browsing_context_id), event),
|
||||||
.map(|browsing_context| browsing_context.top_level_id);
|
None => warn!("Pipeline {:?} handling mozbrowser event after closure.", pipeline_id),
|
||||||
match self.pipelines.get(&parent_pipeline_id) {
|
|
||||||
Some(pipeline) => pipeline.trigger_mozbrowser_event(top_level_browsing_context_id, event),
|
|
||||||
None => warn!("Pipeline {:?} handling mozbrowser event after closure.", parent_pipeline_id),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2195,6 +2179,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
};
|
};
|
||||||
self.new_pipeline(new_pipeline_id, browsing_context_id, top_level_id, parent_info,
|
self.new_pipeline(new_pipeline_id, browsing_context_id, top_level_id, parent_info,
|
||||||
window_size, load_data.clone(), sandbox, is_private);
|
window_size, load_data.clone(), sandbox, is_private);
|
||||||
|
self.handle_load_start_msg(new_pipeline_id);
|
||||||
self.pending_changes.push(SessionHistoryChange {
|
self.pending_changes.push(SessionHistoryChange {
|
||||||
top_level_browsing_context_id: top_level_id,
|
top_level_browsing_context_id: top_level_id,
|
||||||
browsing_context_id: browsing_context_id,
|
browsing_context_id: browsing_context_id,
|
||||||
|
@ -2269,11 +2254,11 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
self.notify_history_changed(top_level_id);
|
self.notify_history_changed(top_level_id);
|
||||||
|
|
||||||
// Set paint permissions correctly for the compositor layers.
|
// Set paint permissions correctly for the compositor layers.
|
||||||
self.send_frame_tree();
|
self.send_frame_tree(top_level_id);
|
||||||
|
|
||||||
// Update the owning iframe to point to the new pipeline id.
|
// Update the owning iframe to point to the new pipeline id.
|
||||||
// This makes things like contentDocument work correctly.
|
// This makes things like contentDocument work correctly.
|
||||||
if let Some((parent_pipeline_id, _)) = parent_info {
|
if let Some((parent_pipeline_id, frame_type)) = parent_info {
|
||||||
let msg = ConstellationControlMsg::UpdatePipelineId(parent_pipeline_id,
|
let msg = ConstellationControlMsg::UpdatePipelineId(parent_pipeline_id,
|
||||||
browsing_context_id, pipeline_id, UpdatePipelineIdReason::Traversal);
|
browsing_context_id, pipeline_id, UpdatePipelineIdReason::Traversal);
|
||||||
let result = match self.pipelines.get(&parent_pipeline_id) {
|
let result = match self.pipelines.get(&parent_pipeline_id) {
|
||||||
|
@ -2284,9 +2269,11 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
self.handle_send_error(parent_pipeline_id, e);
|
self.handle_send_error(parent_pipeline_id, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is an iframe, send a mozbrowser location change event.
|
// If this is a mozbrowser iframe, send a mozbrowser location change event.
|
||||||
// This is the result of a back/forward traversal.
|
// This is the result of a back/forward traversal.
|
||||||
self.trigger_mozbrowserlocationchange(pipeline_id);
|
if frame_type == FrameType::MozBrowserIFrame {
|
||||||
|
self.trigger_mozbrowserlocationchange(top_level_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2373,7 +2360,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
self.focus_pipeline_id = Some(change.new_pipeline_id);
|
self.focus_pipeline_id = Some(change.new_pipeline_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (evicted_id, new_context, navigated, location_changed) = if let Some(instant) = change.replace_instant {
|
let (evicted_id, new_context, navigated) = if let Some(instant) = change.replace_instant {
|
||||||
debug!("Replacing pipeline in existing browsing context with timestamp {:?}.", instant);
|
debug!("Replacing pipeline in existing browsing context with timestamp {:?}.", instant);
|
||||||
let entry = SessionHistoryEntry {
|
let entry = SessionHistoryEntry {
|
||||||
browsing_context_id: change.browsing_context_id,
|
browsing_context_id: change.browsing_context_id,
|
||||||
|
@ -2382,7 +2369,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
instant: instant,
|
instant: instant,
|
||||||
};
|
};
|
||||||
self.traverse_to_entry(entry);
|
self.traverse_to_entry(entry);
|
||||||
(None, false, None, false)
|
(None, false, None)
|
||||||
} else if let Some(browsing_context) = self.browsing_contexts.get_mut(&change.browsing_context_id) {
|
} else if let Some(browsing_context) = self.browsing_contexts.get_mut(&change.browsing_context_id) {
|
||||||
debug!("Adding pipeline to existing browsing context.");
|
debug!("Adding pipeline to existing browsing context.");
|
||||||
let old_pipeline_id = browsing_context.pipeline_id;
|
let old_pipeline_id = browsing_context.pipeline_id;
|
||||||
|
@ -2391,10 +2378,10 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
.checked_sub(PREFS.get("session-history.max-length").as_u64().unwrap_or(20) as usize)
|
.checked_sub(PREFS.get("session-history.max-length").as_u64().unwrap_or(20) as usize)
|
||||||
.and_then(|index| browsing_context.prev.get_mut(index))
|
.and_then(|index| browsing_context.prev.get_mut(index))
|
||||||
.and_then(|entry| entry.pipeline_id.take());
|
.and_then(|entry| entry.pipeline_id.take());
|
||||||
(evicted_id, false, Some(old_pipeline_id), true)
|
(evicted_id, false, Some(old_pipeline_id))
|
||||||
} else {
|
} else {
|
||||||
debug!("Adding pipeline to new browsing context.");
|
debug!("Adding pipeline to new browsing context.");
|
||||||
(None, true, None, true)
|
(None, true, None)
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(evicted_id) = evicted_id {
|
if let Some(evicted_id) = evicted_id {
|
||||||
|
@ -2419,12 +2406,13 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
self.notify_history_changed(change.top_level_browsing_context_id);
|
self.notify_history_changed(change.top_level_browsing_context_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if location_changed {
|
// If the navigation is for a top-level browsing context, inform mozbrowser
|
||||||
self.trigger_mozbrowserlocationchange(change.new_pipeline_id);
|
if change.browsing_context_id == change.top_level_browsing_context_id {
|
||||||
|
self.trigger_mozbrowserlocationchange(change.top_level_browsing_context_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build frame tree
|
// Build frame tree
|
||||||
self.send_frame_tree();
|
self.send_frame_tree(change.top_level_browsing_context_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_activate_document_msg(&mut self, pipeline_id: PipelineId) {
|
fn handle_activate_document_msg(&mut self, pipeline_id: PipelineId) {
|
||||||
|
@ -2484,17 +2472,20 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
/// to check if the output image is "stable" and can be written as a screenshot
|
/// to check if the output image is "stable" and can be written as a screenshot
|
||||||
/// for reftests.
|
/// for reftests.
|
||||||
/// Since this function is only used in reftests, we do not harden it against panic.
|
/// Since this function is only used in reftests, we do not harden it against panic.
|
||||||
fn handle_is_ready_to_save_image(&mut self,
|
fn handle_is_ready_to_save_image(&mut self, pipeline_states: HashMap<PipelineId, Epoch>) -> ReadyToSave {
|
||||||
pipeline_states: HashMap<PipelineId, Epoch>) -> ReadyToSave {
|
|
||||||
// Note that this function can panic, due to ipc-channel creation failure.
|
// Note that this function can panic, due to ipc-channel creation failure.
|
||||||
// avoiding this panic would require a mechanism for dealing
|
// avoiding this panic would require a mechanism for dealing
|
||||||
// with low-resource scenarios.
|
// with low-resource scenarios.
|
||||||
//
|
//
|
||||||
// If there is no root browsing context yet, the initial page has
|
// If there is no focus browsing context yet, the initial page has
|
||||||
// not loaded, so there is nothing to save yet.
|
// not loaded, so there is nothing to save yet.
|
||||||
if !self.browsing_contexts.contains_key(&BrowsingContextId::from(self.root_browsing_context_id)) {
|
let top_level_browsing_context_id = self.focus_pipeline_id
|
||||||
return ReadyToSave::NoRootBrowsingContext;
|
.and_then(|pipeline_id| self.pipelines.get(&pipeline_id))
|
||||||
}
|
.map(|pipeline| pipeline.top_level_browsing_context_id);
|
||||||
|
let top_level_browsing_context_id = match top_level_browsing_context_id {
|
||||||
|
Some(id) => id,
|
||||||
|
None => return ReadyToSave::NoTopLevelBrowsingContext,
|
||||||
|
};
|
||||||
|
|
||||||
// If there are pending loads, wait for those to complete.
|
// If there are pending loads, wait for those to complete.
|
||||||
if !self.pending_changes.is_empty() {
|
if !self.pending_changes.is_empty() {
|
||||||
|
@ -2509,13 +2500,13 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
// matches what the compositor has painted. If all these conditions
|
// matches what the compositor has painted. If all these conditions
|
||||||
// are met, then the output image should not change and a reftest
|
// are met, then the output image should not change and a reftest
|
||||||
// screenshot can safely be written.
|
// screenshot can safely be written.
|
||||||
for browsing_context in self.fully_active_browsing_contexts_iter(self.root_browsing_context_id) {
|
for browsing_context in self.fully_active_browsing_contexts_iter(top_level_browsing_context_id) {
|
||||||
let pipeline_id = browsing_context.pipeline_id;
|
let pipeline_id = browsing_context.pipeline_id;
|
||||||
debug!("Checking readiness of browsing context {}, pipeline {}.", browsing_context.id, pipeline_id);
|
debug!("Checking readiness of browsing context {}, pipeline {}.", browsing_context.id, pipeline_id);
|
||||||
|
|
||||||
let pipeline = match self.pipelines.get(&pipeline_id) {
|
let pipeline = match self.pipelines.get(&pipeline_id) {
|
||||||
None => {
|
None => {
|
||||||
warn!("Pipeline {:?} screenshot while closing.", pipeline_id);
|
warn!("Pipeline {} screenshot while closing.", pipeline_id);
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
Some(pipeline) => pipeline,
|
Some(pipeline) => pipeline,
|
||||||
|
@ -2855,13 +2846,30 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the current frame tree to compositor
|
// Send the current frame tree to compositor
|
||||||
fn send_frame_tree(&mut self) {
|
fn send_frame_tree(&mut self, top_level_browsing_context_id: TopLevelBrowsingContextId) {
|
||||||
|
// This might be a mozbrowser iframe, so we need to climb the parent hierarchy,
|
||||||
|
// even though it's a top-level browsing context.
|
||||||
|
let mut browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id);
|
||||||
|
let mut pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
|
||||||
|
Some(browsing_context) => browsing_context.pipeline_id,
|
||||||
|
None => return warn!("Sending frame tree for discarded browsing context {}.", browsing_context_id),
|
||||||
|
};
|
||||||
|
|
||||||
|
while let Some(pipeline) = self.pipelines.get(&pipeline_id) {
|
||||||
|
match pipeline.parent_info {
|
||||||
|
Some((parent_id, _)) => {
|
||||||
|
browsing_context_id = pipeline.browsing_context_id;
|
||||||
|
pipeline_id = parent_id;
|
||||||
|
},
|
||||||
|
None => break,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Note that this function can panic, due to ipc-channel creation failure.
|
// Note that this function can panic, due to ipc-channel creation failure.
|
||||||
// avoiding this panic would require a mechanism for dealing
|
// avoiding this panic would require a mechanism for dealing
|
||||||
// with low-resource scenarios.
|
// with low-resource scenarios.
|
||||||
let root_browsing_context_id = BrowsingContextId::from(self.root_browsing_context_id);
|
debug!("Sending frame tree for browsing context {}.", browsing_context_id);
|
||||||
debug!("Sending frame tree for browsing context {}.", root_browsing_context_id);
|
if let Some(frame_tree) = self.browsing_context_to_sendable(browsing_context_id) {
|
||||||
if let Some(frame_tree) = self.browsing_context_to_sendable(root_browsing_context_id) {
|
|
||||||
let (chan, port) = ipc::channel().expect("Failed to create IPC channel!");
|
let (chan, port) = ipc::channel().expect("Failed to create IPC channel!");
|
||||||
self.compositor_proxy.send(ToCompositorMsg::SetFrameTree(frame_tree,
|
self.compositor_proxy.send(ToCompositorMsg::SetFrameTree(frame_tree,
|
||||||
chan));
|
chan));
|
||||||
|
@ -2874,29 +2882,32 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserlocationchange
|
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserlocationchange
|
||||||
// Note that this is a no-op if the pipeline is not a mozbrowser iframe
|
// Note that this is a no-op if the pipeline is not a mozbrowser iframe
|
||||||
fn trigger_mozbrowserlocationchange(&self, pipeline_id: PipelineId) {
|
fn trigger_mozbrowserlocationchange(&self,
|
||||||
match self.pipelines.get(&pipeline_id) {
|
top_level_browsing_context_id: TopLevelBrowsingContextId)
|
||||||
Some(pipeline) => if let Some((parent_id, FrameType::MozBrowserIFrame)) = pipeline.parent_info {
|
{
|
||||||
match self.pipelines.get(&parent_id) {
|
let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id);
|
||||||
Some(parent) => {
|
let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
|
||||||
let top_level_browsing_context_id = self.browsing_contexts.get(&pipeline.browsing_context_id)
|
Some(browsing_context) => browsing_context.pipeline_id,
|
||||||
.map(|browsing_context| browsing_context.top_level_id)
|
None => return warn!("mozbrowser location change on closed browsing context {}.", browsing_context_id),
|
||||||
.unwrap_or(self.root_browsing_context_id);
|
};
|
||||||
let url = pipeline.url.to_string();
|
let (url, parent_info) = match self.pipelines.get(&pipeline_id) {
|
||||||
|
Some(pipeline) => (pipeline.url.clone(), pipeline.parent_info),
|
||||||
|
None => return warn!("mozbrowser location change on closed pipeline {}.", pipeline_id),
|
||||||
|
};
|
||||||
|
let parent_id = match parent_info {
|
||||||
|
Some((parent_id, FrameType::MozBrowserIFrame)) => parent_id,
|
||||||
|
_ => return debug!("mozbrowser location change on a regular iframe {}", browsing_context_id),
|
||||||
|
};
|
||||||
let can_go_forward = !self.joint_session_future_is_empty(top_level_browsing_context_id);
|
let can_go_forward = !self.joint_session_future_is_empty(top_level_browsing_context_id);
|
||||||
let can_go_back = !self.joint_session_past_is_empty(top_level_browsing_context_id);
|
let can_go_back = !self.joint_session_past_is_empty(top_level_browsing_context_id);
|
||||||
let event = MozBrowserEvent::LocationChange(url, can_go_back, can_go_forward);
|
let event = MozBrowserEvent::LocationChange(url.to_string(), can_go_back, can_go_forward);
|
||||||
parent.trigger_mozbrowser_event(Some(top_level_browsing_context_id), event);
|
match self.pipelines.get(&parent_id) {
|
||||||
},
|
Some(parent) => parent.trigger_mozbrowser_event(Some(top_level_browsing_context_id), event),
|
||||||
None => warn!("triggered mozbrowser location change on closed parent {}", parent_id),
|
None => return warn!("mozbrowser location change on closed parent {}", parent_id),
|
||||||
}
|
};
|
||||||
},
|
|
||||||
None => warn!("triggered mozbrowser location change on closed pipeline {}", pipeline_id),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowsererror
|
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowsererror
|
||||||
// Note that this does not require the pipeline to be an immediate child of the root
|
|
||||||
fn trigger_mozbrowsererror(&mut self,
|
fn trigger_mozbrowsererror(&mut self,
|
||||||
top_level_browsing_context_id: TopLevelBrowsingContextId,
|
top_level_browsing_context_id: TopLevelBrowsingContextId,
|
||||||
reason: String,
|
reason: String,
|
||||||
|
@ -2923,19 +2934,20 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
|
|
||||||
let event = MozBrowserEvent::Error(MozBrowserErrorType::Fatal, reason, report);
|
let event = MozBrowserEvent::Error(MozBrowserErrorType::Fatal, reason, report);
|
||||||
let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id);
|
let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id);
|
||||||
|
let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
|
||||||
match self.browsing_contexts.get(&browsing_context_id) {
|
Some(browsing_context) => browsing_context.pipeline_id,
|
||||||
None => warn!("Mozbrowser error after top-level browsing context closed."),
|
None => return warn!("Mozbrowser error after top-level browsing context closed."),
|
||||||
Some(browsing_context) => match self.pipelines.get(&browsing_context.pipeline_id) {
|
};
|
||||||
None => warn!("Mozbrowser error after top-level pipeline closed."),
|
let parent_id = match self.pipelines.get(&pipeline_id) {
|
||||||
Some(pipeline) => match pipeline.parent_info {
|
Some(pipeline) => match pipeline.parent_info {
|
||||||
None => pipeline.trigger_mozbrowser_event(None, event),
|
Some((parent_id, FrameType::MozBrowserIFrame)) => parent_id,
|
||||||
Some((parent_id, _)) => match self.pipelines.get(&parent_id) {
|
_ => return pipeline.trigger_mozbrowser_event(None, event),
|
||||||
None => warn!("Mozbrowser error after root pipeline closed."),
|
},
|
||||||
|
None => return warn!("Mozbrowser error on a closed pipeline {}", pipeline_id),
|
||||||
|
};
|
||||||
|
match self.pipelines.get(&parent_id) {
|
||||||
|
None => warn!("Mozbrowser error after parent pipeline {} closed.", parent_id),
|
||||||
Some(parent) => parent.trigger_mozbrowser_event(Some(top_level_browsing_context_id), event),
|
Some(parent) => parent.trigger_mozbrowser_event(Some(top_level_browsing_context_id), event),
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -318,6 +318,18 @@ impl From<TopLevelBrowsingContextId> for BrowsingContextId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq<TopLevelBrowsingContextId> for BrowsingContextId {
|
||||||
|
fn eq(&self, rhs: &TopLevelBrowsingContextId) -> bool {
|
||||||
|
self.eq(&rhs.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq<BrowsingContextId> for TopLevelBrowsingContextId {
|
||||||
|
fn eq(&self, rhs: &BrowsingContextId) -> bool {
|
||||||
|
self.0.eq(rhs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We provide ids just for unit testing.
|
// We provide ids just for unit testing.
|
||||||
pub const TEST_NAMESPACE: PipelineNamespaceId = PipelineNamespaceId(1234);
|
pub const TEST_NAMESPACE: PipelineNamespaceId = PipelineNamespaceId(1234);
|
||||||
pub const TEST_PIPELINE_INDEX: PipelineIndex = PipelineIndex(5678);
|
pub const TEST_PIPELINE_INDEX: PipelineIndex = PipelineIndex(5678);
|
||||||
|
|
|
@ -1521,11 +1521,11 @@ impl Document {
|
||||||
pub fn trigger_mozbrowser_event(&self, event: MozBrowserEvent) {
|
pub fn trigger_mozbrowser_event(&self, event: MozBrowserEvent) {
|
||||||
if PREFS.is_mozbrowser_enabled() {
|
if PREFS.is_mozbrowser_enabled() {
|
||||||
if let Some((parent_pipeline_id, _)) = self.window.parent_info() {
|
if let Some((parent_pipeline_id, _)) = self.window.parent_info() {
|
||||||
let global_scope = self.window.upcast::<GlobalScope>();
|
let top_level_browsing_context_id = self.window.window_proxy().top_level_browsing_context_id();
|
||||||
let event = ConstellationMsg::MozBrowserEvent(parent_pipeline_id,
|
let event = ConstellationMsg::MozBrowserEvent(parent_pipeline_id,
|
||||||
global_scope.pipeline_id(),
|
top_level_browsing_context_id,
|
||||||
event);
|
event);
|
||||||
global_scope.constellation_chan().send(event).unwrap();
|
self.window.upcast::<GlobalScope>().constellation_chan().send(event).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,9 +104,8 @@ pub enum ScriptMsg {
|
||||||
LoadUrl(PipelineId, LoadData, bool),
|
LoadUrl(PipelineId, LoadData, bool),
|
||||||
/// Post a message to the currently active window of a given browsing context.
|
/// Post a message to the currently active window of a given browsing context.
|
||||||
PostMessage(BrowsingContextId, Option<ImmutableOrigin>, Vec<u8>),
|
PostMessage(BrowsingContextId, Option<ImmutableOrigin>, Vec<u8>),
|
||||||
/// Dispatch a mozbrowser event to the parent of this pipeline.
|
/// Dispatch a mozbrowser event to the parent of a mozbrowser iframe.
|
||||||
/// The first PipelineId is for the parent, the second is for the originating pipeline.
|
MozBrowserEvent(PipelineId, TopLevelBrowsingContextId, MozBrowserEvent),
|
||||||
MozBrowserEvent(PipelineId, PipelineId, MozBrowserEvent),
|
|
||||||
/// HTMLIFrameElement Forward or Back traversal.
|
/// HTMLIFrameElement Forward or Back traversal.
|
||||||
TraverseHistory(TopLevelBrowsingContextId, TraversalDirection),
|
TraverseHistory(TopLevelBrowsingContextId, TraversalDirection),
|
||||||
/// Gets the length of the joint session history from the constellation.
|
/// Gets the length of the joint session history from the constellation.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue