aboutsummaryrefslogtreecommitdiffstats
path: root/components/constellation
diff options
context:
space:
mode:
authormandreyel <mandreyel@protonmail.com>2018-08-19 21:15:04 +0200
committermandreyel <mandreyel@protonmail.com>2018-09-12 17:04:18 +0200
commitb051df76ef3f5d9764c37607105b8a31956aaec0 (patch)
tree49ac831a9152eb856e5a3d297be1ed1f1fa95456 /components/constellation
parent235187235431e1d9bacdcc4fcc2f8b4d85fd4f77 (diff)
downloadservo-b051df76ef3f5d9764c37607105b8a31956aaec0.tar.gz
servo-b051df76ef3f5d9764c37607105b8a31956aaec0.zip
Move Pipeline::{parent_info,visible,is_private} to BrowsingContext
Diffstat (limited to 'components/constellation')
-rw-r--r--components/constellation/browsingcontext.rs51
-rw-r--r--components/constellation/constellation.rs662
-rw-r--r--components/constellation/pipeline.rs62
-rw-r--r--components/constellation/session_history.rs5
4 files changed, 454 insertions, 326 deletions
diff --git a/components/constellation/browsingcontext.rs b/components/constellation/browsingcontext.rs
index 329a3ef20a0..c4415ff169c 100644
--- a/components/constellation/browsingcontext.rs
+++ b/components/constellation/browsingcontext.rs
@@ -8,13 +8,31 @@ use pipeline::Pipeline;
use std::collections::{HashMap, HashSet};
use style_traits::CSSPixel;
+/// Because a browsing context is only constructed once the document that's
+/// going to be in it becomes active (i.e. not when a pipeline is spawned), some
+/// values needed in browsing context are not easily available at the point of
+/// constructing it. Thus, every time a pipeline is created for a browsing
+/// context which doesn't exist yet, these values needed for the new browsing
+/// context are stored here so that they may be available later.
+pub struct NewBrowsingContextInfo {
+ /// The parent pipeline that contains this browsing context. `None` if this
+ /// is a top level browsing context.
+ pub parent_pipeline_id: Option<PipelineId>,
+
+ /// Whether this browsing context is in private browsing mode.
+ pub is_private: bool,
+
+ /// Whether this browsing context should be treated as visible for the
+ /// purposes of scheduling and resource management.
+ pub is_visible: bool,
+}
+
/// The constellation's view of a browsing context.
-/// Each browsing context has a session history, caused by
-/// navigation and traversing the history. Each browsing context has its
-/// current entry, plus past and future entries. The past is sorted
-/// chronologically, the future is sorted reverse chronologically:
-/// in particular prev.pop() is the latest past entry, and
-/// next.pop() is the earliest future entry.
+/// Each browsing context has a session history, caused by navigation and
+/// traversing the history. Each browsing context has its current entry, plus
+/// past and future entries. The past is sorted chronologically, the future is
+/// sorted reverse chronologically: in particular prev.pop() is the latest
+/// past entry, and next.pop() is the earliest future entry.
pub struct BrowsingContext {
/// The browsing context id.
pub id: BrowsingContextId,
@@ -25,9 +43,22 @@ pub struct BrowsingContext {
/// The size of the frame.
pub size: Option<TypedSize2D<f32, CSSPixel>>,
+ /// Whether this browsing context is in private browsing mode.
+ pub is_private: bool,
+
+ /// Whether this browsing context should be treated as visible for the
+ /// purposes of scheduling and resource management.
+ pub is_visible: bool,
+
/// The pipeline for the current session history entry.
pub pipeline_id: PipelineId,
+ /// The parent pipeline that contains this browsing context. `None` if this
+ /// is a top level browsing context.
+ pub parent_pipeline_id: Option<PipelineId>,
+
+ /// All the pipelines that have been presented or will be presented in
+ /// this browsing context.
pub pipelines: HashSet<PipelineId>,
}
@@ -38,6 +69,9 @@ impl BrowsingContext {
id: BrowsingContextId,
top_level_id: TopLevelBrowsingContextId,
pipeline_id: PipelineId,
+ parent_pipeline_id: Option<PipelineId>,
+ is_private: bool,
+ is_visible: bool,
) -> BrowsingContext {
let mut pipelines = HashSet::new();
pipelines.insert(pipeline_id);
@@ -45,8 +79,11 @@ impl BrowsingContext {
id: id,
top_level_id: top_level_id,
size: None,
+ is_private: is_private,
+ is_visible: is_visible,
pipeline_id: pipeline_id,
- pipelines,
+ parent_pipeline_id: parent_pipeline_id,
+ pipelines: pipelines,
}
}
diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs
index a08768c06dc..15a57c3f45e 100644
--- a/components/constellation/constellation.rs
+++ b/components/constellation/constellation.rs
@@ -92,6 +92,7 @@
use backtrace::Backtrace;
use bluetooth_traits::BluetoothRequest;
use browsingcontext::{AllBrowsingContextsIterator, BrowsingContext, FullyActiveBrowsingContextsIterator};
+use browsingcontext::NewBrowsingContextInfo;
use canvas::canvas_paint_thread::CanvasPaintThread;
use canvas::webgl_thread::WebGLThreads;
use canvas_traits::canvas::CanvasId;
@@ -606,9 +607,8 @@ where
pipelines: HashMap::new(),
browsing_contexts: HashMap::new(),
pending_changes: vec![],
- // We initialize the namespace at 2,
- // since we reserved namespace 0 for the embedder,
- // and 0 for the constellation
+ // We initialize the namespace at 2, since we reserved
+ // namespace 0 for the embedder, and 0 for the constellation
next_pipeline_namespace_id: PipelineNamespaceId(2),
focus_pipeline_id: None,
time_profiler_chan: state.time_profiler_chan,
@@ -687,7 +687,7 @@ where
pipeline_id: PipelineId,
browsing_context_id: BrowsingContextId,
top_level_browsing_context_id: TopLevelBrowsingContextId,
- parent_info: Option<PipelineId>,
+ parent_pipeline_id: Option<PipelineId>,
opener: Option<BrowsingContextId>,
initial_window_size: Option<TypedSize2D<f32, CSSPixel>>,
// TODO: we have to provide ownership of the LoadData
@@ -697,6 +697,7 @@ where
load_data: LoadData,
sandbox: IFrameSandboxState,
is_private: bool,
+ is_visible: bool,
) {
if self.shutting_down {
return;
@@ -725,7 +726,7 @@ where
},
}
} else if let Some(parent) =
- parent_info.and_then(|pipeline_id| self.pipelines.get(&pipeline_id))
+ parent_pipeline_id.and_then(|pipeline_id| self.pipelines.get(&pipeline_id))
{
(Some(parent.event_loop.clone()), None)
} else if let Some(creator) = load_data
@@ -745,22 +746,11 @@ where
self.public_resource_threads.clone()
};
- let parent_visibility = parent_info
- .and_then(|parent_pipeline_id| self.pipelines.get(&parent_pipeline_id))
- .map(|pipeline| pipeline.visible);
-
- let prev_visibility = self
- .browsing_contexts
- .get(&browsing_context_id)
- .and_then(|browsing_context| self.pipelines.get(&browsing_context.pipeline_id))
- .map(|pipeline| pipeline.visible)
- .or(parent_visibility);
-
let result = Pipeline::spawn::<Message, LTF, STF>(InitialPipelineState {
id: pipeline_id,
browsing_context_id,
top_level_browsing_context_id,
- parent_info,
+ parent_pipeline_id,
opener,
script_to_constellation_chan: ScriptToConstellationChan {
sender: self.script_sender.clone(),
@@ -781,10 +771,9 @@ where
load_data,
device_pixel_ratio: self.window_size.device_pixel_ratio,
pipeline_namespace_id: self.next_pipeline_namespace_id(),
- prev_visibility,
+ prev_visibility: is_visible,
webrender_api_sender: self.webrender_api_sender.clone(),
webrender_document: self.webrender_document,
- is_private,
webgl_chan: self
.webgl_threads
.as_ref()
@@ -851,26 +840,31 @@ where
browsing_context_id: BrowsingContextId,
top_level_id: TopLevelBrowsingContextId,
pipeline_id: PipelineId,
+ parent_pipeline_id: Option<PipelineId>,
+ is_private: bool,
+ is_visible: bool,
) {
debug!("Creating new browsing context {}", browsing_context_id);
- let browsing_context = BrowsingContext::new(browsing_context_id, top_level_id, pipeline_id);
- self.browsing_contexts
- .insert(browsing_context_id, browsing_context);
+ let browsing_context = BrowsingContext::new(
+ browsing_context_id,
+ top_level_id,
+ pipeline_id,
+ parent_pipeline_id,
+ is_private,
+ is_visible,
+ );
+ self.browsing_contexts.insert(browsing_context_id, browsing_context);
- // If a child browsing_context, add it to the parent pipeline.
- let parent_info = self
- .pipelines
- .get(&pipeline_id)
- .and_then(|pipeline| pipeline.parent_info);
- if let Some(parent_id) = parent_info {
- if let Some(parent) = self.pipelines.get_mut(&parent_id) {
+ // If this context is a nested container, attach it to parent pipeline.
+ if let Some(parent_pipeline_id) = parent_pipeline_id {
+ if let Some(parent) = self.pipelines.get_mut(&parent_pipeline_id) {
parent.add_child(browsing_context_id);
}
}
}
fn add_pending_change(&mut self, change: SessionHistoryChange) {
- self.handle_load_start_msg(change.top_level_browsing_context_id, change.new_pipeline_id);
+ self.handle_load_start_msg(change.top_level_browsing_context_id, change.browsing_context_id);
self.pending_changes.push(change);
}
@@ -1199,11 +1193,11 @@ where
}
}
},
- FromScriptMsg::SetVisible(visible) => {
- self.handle_set_visible_msg(source_pipeline_id, visible);
+ FromScriptMsg::SetVisible(is_visible) => {
+ self.handle_set_visible_msg(source_pipeline_id, is_visible);
},
- FromScriptMsg::VisibilityChangeComplete(visible) => {
- self.handle_visibility_change_complete(source_pipeline_id, visible);
+ FromScriptMsg::VisibilityChangeComplete(is_visible) => {
+ self.handle_visibility_change_complete(source_pipeline_id, is_visible);
},
FromScriptMsg::RemoveIFrame(browsing_context_id, sender) => {
let removed_pipeline_ids = self.handle_remove_iframe_msg(browsing_context_id);
@@ -1244,13 +1238,19 @@ where
warn!("Sending reply to get browsing context failed ({:?}).", e);
}
},
+ // TODO(mandreyel): maybe change semantics of this message to
+ // reflect moving parent_info into BrowsingContext, i.e. message
+ // could be: GetParentInfo(BrowsingContextId, Sender)
FromScriptMsg::GetParentInfo(pipeline_id, sender) => {
- let result = self
- .pipelines
+ let browsing_context = self.pipelines
.get(&pipeline_id)
- .and_then(|pipeline| pipeline.parent_info);
- if let Err(e) = sender.send(result) {
- warn!("Sending reply to get parent info failed ({:?}).", e);
+ .and_then(|pipeline| self.browsing_contexts.get(&pipeline.browsing_context_id));
+ if let Some(browsing_context) = browsing_context {
+ if let Err(e) = sender.send(browsing_context.parent_pipeline_id) {
+ warn!("Sending reply to get parent info failed ({:?}).", e);
+ }
+ } else {
+ warn!("GetParentInfo for pipeline {} with no browsing context.", pipeline_id)
}
},
FromScriptMsg::GetTopForBrowsingContext(browsing_context_id, sender) => {
@@ -1544,19 +1544,19 @@ where
EmbedderMsg::Panic(reason, backtrace),
));
- let (window_size, pipeline_id) = {
+ let (window_size, pipeline_id, is_visible) = {
let browsing_context = self.browsing_contexts.get(&browsing_context_id);
- let window_size = browsing_context.and_then(|browsing_context| browsing_context.size);
- let pipeline_id = browsing_context.map(|browsing_context| browsing_context.pipeline_id);
- (window_size, pipeline_id)
+ let window_size = browsing_context.and_then(|ctx| ctx.size);
+ let pipeline_id = browsing_context.map(|ctx| ctx.pipeline_id);
+ let is_visible = browsing_context.map(|ctx| ctx.is_visible);
+ (window_size, pipeline_id, is_visible)
};
- let (pipeline_url, parent_info, opener) = {
+ let (pipeline_url, opener) = {
let pipeline = pipeline_id.and_then(|id| self.pipelines.get(&id));
let pipeline_url = pipeline.map(|pipeline| pipeline.url.clone());
- let parent_info = pipeline.and_then(|pipeline| pipeline.parent_info);
let opener = pipeline.and_then(|pipeline| pipeline.opener);
- (pipeline_url, parent_info, opener)
+ (pipeline_url, opener)
};
self.close_browsing_context_children(
@@ -1578,22 +1578,25 @@ where
let new_pipeline_id = PipelineId::new();
let load_data = LoadData::new(failure_url, None, None, None);
let sandbox = IFrameSandboxState::IFrameSandboxed;
+ let is_private = false;
self.new_pipeline(
new_pipeline_id,
browsing_context_id,
top_level_browsing_context_id,
- parent_info,
+ None,
opener,
window_size,
load_data.clone(),
sandbox,
- false,
+ is_private,
+ is_visible.unwrap_or(true),
);
self.add_pending_change(SessionHistoryChange {
top_level_browsing_context_id: top_level_browsing_context_id,
browsing_context_id: browsing_context_id,
new_pipeline_id: new_pipeline_id,
replace: None,
+ new_browsing_context_info: None,
});
}
@@ -1663,6 +1666,9 @@ where
let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id);
let load_data = LoadData::new(url.clone(), None, None, None);
let sandbox = IFrameSandboxState::IFrameUnsandboxed;
+ let is_private = false;
+ let is_visible = true;
+
if self.focus_pipeline_id.is_none() {
self.focus_pipeline_id = Some(pipeline_id);
}
@@ -1677,13 +1683,19 @@ where
Some(window_size),
load_data.clone(),
sandbox,
- false,
+ is_private,
+ is_visible,
);
self.add_pending_change(SessionHistoryChange {
top_level_browsing_context_id: top_level_browsing_context_id,
browsing_context_id: browsing_context_id,
new_pipeline_id: pipeline_id,
replace: None,
+ new_browsing_context_info: Some(NewBrowsingContextInfo {
+ parent_pipeline_id: None,
+ is_private: is_private,
+ is_visible: is_visible,
+ }),
});
}
@@ -1710,29 +1722,38 @@ where
}
fn handle_subframe_loaded(&mut self, pipeline_id: PipelineId) {
- let (browsing_context_id, parent_id) = match self.pipelines.get(&pipeline_id) {
- Some(pipeline) => match pipeline.parent_info {
- Some(parent_id) => (pipeline.browsing_context_id, parent_id),
- None => return debug!("Pipeline {} has no parent.", pipeline_id),
- },
- None => return warn!("Pipeline {} loaded after closure.", pipeline_id),
+ let browsing_context_id = match self.pipelines.get(&pipeline_id) {
+ Some(pipeline) => pipeline.browsing_context_id,
+ None => return warn!("Subframe {} loaded after closure.", pipeline_id),
+ };
+ let parent_pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
+ Some(browsing_context) => browsing_context.parent_pipeline_id,
+ None => return warn!(
+ "Subframe {} loaded in closed browsing context {}.",
+ pipeline_id,
+ browsing_context_id,
+ ),
+ };
+ let parent_pipeline_id = match parent_pipeline_id {
+ Some(parent_pipeline_id) => parent_pipeline_id,
+ None => return warn!("Subframe {} has no parent.", pipeline_id),
};
let msg = ConstellationControlMsg::DispatchIFrameLoadEvent {
target: browsing_context_id,
- parent: parent_id,
+ parent: parent_pipeline_id,
child: pipeline_id,
};
- let result = match self.pipelines.get(&parent_id) {
+ let result = match self.pipelines.get(&parent_pipeline_id) {
Some(parent) => parent.event_loop.send(msg),
None => {
return warn!(
"Parent {} browsing context loaded after closure.",
- parent_id
+ parent_pipeline_id
)
},
};
if let Err(e) = result {
- self.handle_send_error(parent_id, e);
+ self.handle_send_error(parent_pipeline_id, e);
}
}
@@ -1752,27 +1773,24 @@ where
listener.initiate_fetch(Some(cancel_chan));
}
- // The script thread associated with pipeline_id has loaded a URL in an iframe via script. This
- // will result in a new pipeline being spawned and a child being added to
- // the parent pipeline. This message is never the result of a
- // page navigation.
+ // The script thread associated with pipeline_id has loaded a URL in an
+ // iframe via script. This will result in a new pipeline being spawned and
+ // a child being added to the parent browsing context. This message is never
+ // the result of a page navigation.
fn handle_script_loaded_url_in_iframe_msg(&mut self, load_info: IFrameLoadInfoWithData) {
- let (load_data, window_size, is_private) = {
- let old_pipeline = load_info
- .old_pipeline_id
- .and_then(|old_pipeline_id| self.pipelines.get(&old_pipeline_id));
-
- let source_pipeline = match self.pipelines.get(&load_info.info.parent_pipeline_id) {
- Some(source_pipeline) => source_pipeline,
- None => {
- return warn!(
- "Script loaded url in closed iframe {}.",
- load_info.info.parent_pipeline_id
- )
- },
- };
+ let IFrameLoadInfo {
+ parent_pipeline_id,
+ browsing_context_id,
+ top_level_browsing_context_id,
+ new_pipeline_id,
+ is_private,
+ replace,
+ } = load_info.info;
+ let (load_data, is_private) = {
// If no url is specified, reload.
+ let old_pipeline = load_info.old_pipeline_id
+ .and_then(|id| self.pipelines.get(&id));
let load_data = load_info.load_data.unwrap_or_else(|| {
let url = match old_pipeline {
Some(old_pipeline) => old_pipeline.url.clone(),
@@ -1780,44 +1798,71 @@ where
};
// TODO - loaddata here should have referrer info (not None, None)
- LoadData::new(url, Some(source_pipeline.id), None, None)
+ LoadData::new(url, Some(parent_pipeline_id), None, None)
});
- let is_private = load_info.info.is_private || source_pipeline.is_private;
-
- let window_size = self
- .browsing_contexts
- .get(&load_info.info.browsing_context_id)
- .and_then(|browsing_context| browsing_context.size);
+ let is_parent_private = {
+ let parent_browsing_context_id =
+ match self.pipelines.get(&parent_pipeline_id) {
+ Some(pipeline) => pipeline.browsing_context_id,
+ None => return warn!(
+ "Script loaded url in iframe {} in closed parent pipeline {}.",
+ browsing_context_id,
+ parent_pipeline_id,
+ ),
+ };
+ let is_parent_private =
+ match self.browsing_contexts.get(&parent_browsing_context_id) {
+ Some(ctx) => ctx.is_private,
+ None => return warn!(
+ "Script loaded url in iframe {} in closed parent browsing context {}.",
+ browsing_context_id,
+ parent_browsing_context_id,
+ ),
+ };
+ is_parent_private
+ };
+ let is_private = is_private || is_parent_private;
- (load_data, window_size, is_private)
+ (load_data, is_private)
};
- let replace = if load_info.info.replace {
- self.browsing_contexts
- .get(&load_info.info.browsing_context_id)
- .map(|browsing_context| NeedsToReload::No(browsing_context.pipeline_id))
- } else {
- None
+ let (replace, window_size, is_visible) = {
+ let browsing_context = match self.browsing_contexts.get(&browsing_context_id) {
+ Some(ctx) => ctx,
+ None => return warn!(
+ "Script loaded url in iframe with closed browsing context {}.",
+ browsing_context_id,
+ ),
+ };
+ let replace = if replace {
+ Some(NeedsToReload::No(browsing_context.pipeline_id))
+ } else {
+ None
+ };
+ (replace, browsing_context.size, browsing_context.is_visible)
};
// Create the new pipeline, attached to the parent and push to pending changes
self.new_pipeline(
- load_info.info.new_pipeline_id,
- load_info.info.browsing_context_id,
- load_info.info.top_level_browsing_context_id,
- Some(load_info.info.parent_pipeline_id),
+ new_pipeline_id,
+ browsing_context_id,
+ top_level_browsing_context_id,
+ Some(parent_pipeline_id),
None,
window_size,
load_data.clone(),
load_info.sandbox,
is_private,
+ is_visible,
);
self.add_pending_change(SessionHistoryChange {
- top_level_browsing_context_id: load_info.info.top_level_browsing_context_id,
- browsing_context_id: load_info.info.browsing_context_id,
- new_pipeline_id: load_info.info.new_pipeline_id,
- replace,
+ top_level_browsing_context_id: top_level_browsing_context_id,
+ browsing_context_id: browsing_context_id,
+ new_pipeline_id: new_pipeline_id,
+ replace: replace,
+ // Browsing context for iframe already exists.
+ new_browsing_context_info: None,
});
}
@@ -1840,38 +1885,51 @@ where
// TODO: Referrer?
let load_data = LoadData::new(url.clone(), Some(parent_pipeline_id), None, None);
- let pipeline = {
- let parent_pipeline = match self.pipelines.get(&parent_pipeline_id) {
- Some(parent_pipeline) => parent_pipeline,
- None => return warn!("Script loaded url in closed iframe {}.", parent_pipeline_id),
- };
-
- let script_sender = parent_pipeline.event_loop.clone();
-
- Pipeline::new(
+ let (pipeline, is_private, is_visible) = {
+ let (script_sender, parent_browsing_context_id) =
+ match self.pipelines.get(&parent_pipeline_id) {
+ Some(pipeline) => (pipeline.event_loop.clone(), pipeline.browsing_context_id),
+ None => return warn!("Script loaded url in closed iframe {}.", parent_pipeline_id),
+ };
+ let (is_parent_private, is_parent_visible) =
+ match self.browsing_contexts.get(&parent_browsing_context_id) {
+ Some(ctx) => (ctx.is_private, ctx.is_visible),
+ None => return warn!(
+ "New iframe {} loaded in closed parent browsing context {}.",
+ browsing_context_id,
+ parent_browsing_context_id,
+ ),
+ };
+ let is_private = is_private || is_parent_private;
+ let pipeline = Pipeline::new(
new_pipeline_id,
browsing_context_id,
top_level_browsing_context_id,
- Some(parent_pipeline_id),
None,
script_sender,
layout_sender,
self.compositor_proxy.clone(),
- is_private || parent_pipeline.is_private,
url,
- parent_pipeline.visible,
+ is_parent_visible,
load_data,
- )
+ );
+
+ (pipeline, is_private, is_parent_visible)
};
assert!(!self.pipelines.contains_key(&new_pipeline_id));
self.pipelines.insert(new_pipeline_id, pipeline);
-
self.add_pending_change(SessionHistoryChange {
top_level_browsing_context_id: top_level_browsing_context_id,
browsing_context_id: browsing_context_id,
new_pipeline_id: new_pipeline_id,
replace: None,
+ // Browsing context for iframe doesn't exist yet.
+ new_browsing_context_info: Some(NewBrowsingContextInfo {
+ parent_pipeline_id: Some(parent_pipeline_id),
+ is_private: is_private,
+ is_visible: is_visible,
+ }),
});
}
@@ -1890,24 +1948,38 @@ where
// TODO: Referrer?
let load_data = LoadData::new(url.clone(), None, None, None);
- let pipeline = {
- let (opener_pipeline, opener_id) = match self.pipelines.get(&opener_pipeline_id) {
- Some(opener_pipeline) => (opener_pipeline, opener_pipeline.browsing_context_id),
- None => return warn!("Auxiliary loaded url in closed pipeline {}.", opener_pipeline_id),
- };
- let script_sender = opener_pipeline.event_loop.clone();
- Pipeline::new(new_pipeline_id,
- new_browsing_context_id,
- new_top_level_browsing_context_id,
- None,
- Some(opener_id),
- script_sender,
- layout_sender,
- self.compositor_proxy.clone(),
- opener_pipeline.is_private,
- url,
- opener_pipeline.visible,
- load_data)
+ let (pipeline, is_private, is_visible) = {
+ let (script_sender, opener_browsing_context_id) =
+ match self.pipelines.get(&opener_pipeline_id) {
+ Some(pipeline) => (pipeline.event_loop.clone(), pipeline.browsing_context_id),
+ None => return warn!(
+ "Auxiliary loaded url in closed iframe {}.",
+ opener_pipeline_id
+ ),
+ };
+ let (is_opener_private, is_opener_visible) =
+ match self.browsing_contexts.get(&opener_browsing_context_id) {
+ Some(ctx) => (ctx.is_private, ctx.is_visible),
+ None => return warn!(
+ "New auxiliary {} loaded in closed opener browsing context {}.",
+ new_browsing_context_id,
+ opener_browsing_context_id,
+ ),
+ };
+ let pipeline = Pipeline::new(
+ new_pipeline_id,
+ new_browsing_context_id,
+ new_top_level_browsing_context_id,
+ Some(opener_browsing_context_id),
+ script_sender,
+ layout_sender,
+ self.compositor_proxy.clone(),
+ url,
+ is_opener_visible,
+ load_data
+ );
+
+ (pipeline, is_opener_private, is_opener_visible)
};
assert!(!self.pipelines.contains_key(&new_pipeline_id));
@@ -1918,6 +1990,12 @@ where
browsing_context_id: new_browsing_context_id,
new_pipeline_id: new_pipeline_id,
replace: None,
+ new_browsing_context_info: Some(NewBrowsingContextInfo {
+ // Auxiliary browsing contexts are always top-level.
+ parent_pipeline_id: None,
+ is_private: is_private,
+ is_visible: is_visible,
+ }),
});
}
@@ -2004,14 +2082,36 @@ where
// 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.
- let (browsing_context_id, parent_info, opener) = match self.pipelines.get(&source_id) {
- Some(pipeline) => (pipeline.browsing_context_id, pipeline.parent_info, pipeline.opener),
+ let (browsing_context_id, opener) = match self.pipelines.get(&source_id) {
+ Some(pipeline) => (pipeline.browsing_context_id, pipeline.opener),
None => {
warn!("Pipeline {} loaded after closure.", source_id);
return None;
},
};
- match parent_info {
+ let (window_size, pipeline_id, parent_pipeline_id, is_visible) =
+ match self.browsing_contexts.get(&browsing_context_id) {
+ Some(ctx) => (
+ ctx.size,
+ ctx.pipeline_id,
+ ctx.parent_pipeline_id,
+ ctx.is_visible,
+ ),
+ None => {
+ // This should technically never happen (since `load_url` is
+ // only called on existing browsing contexts), but we prefer to
+ // avoid `expect`s or `unwrap`s in `Constellation` to ward
+ // against future changes that might break things.
+ warn!(
+ "Pipeline {} loaded url in closed browsing context {}.",
+ source_id,
+ browsing_context_id,
+ );
+ return None;
+ },
+ };
+
+ match parent_pipeline_id {
Some(parent_pipeline_id) => {
// Find the script thread for the pipeline containing the iframe
// and issue an iframe load through there.
@@ -2057,17 +2157,6 @@ where
// changes would be overridden by changing the subframe associated with source_id.
// Create the new pipeline
- let (top_level_id, window_size, pipeline_id) =
- match self.browsing_contexts.get(&browsing_context_id) {
- Some(context) => (context.top_level_id, context.size, context.pipeline_id),
- None => {
- warn!(
- "Browsing context {} loaded after closure.",
- browsing_context_id
- );
- return None;
- },
- };
let replace = if replace {
Some(NeedsToReload::No(pipeline_id))
@@ -2077,22 +2166,28 @@ where
let new_pipeline_id = PipelineId::new();
let sandbox = IFrameSandboxState::IFrameUnsandboxed;
+ // TODO(mandreyel): why is this false? Should we not inherit the
+ // privacy of the (existing) browsing context?
+ let is_private = false;
self.new_pipeline(
new_pipeline_id,
browsing_context_id,
- top_level_id,
+ top_level_browsing_context_id,
None,
opener,
window_size,
load_data.clone(),
sandbox,
- false,
+ is_private,
+ is_visible,
);
self.add_pending_change(SessionHistoryChange {
- top_level_browsing_context_id: top_level_id,
+ top_level_browsing_context_id: top_level_browsing_context_id,
browsing_context_id: browsing_context_id,
new_pipeline_id: new_pipeline_id,
replace,
+ // `load_url` is always invoked on an existing browsing context.
+ new_browsing_context_info: None,
});
Some(new_pipeline_id)
},
@@ -2119,14 +2214,9 @@ where
fn handle_load_start_msg(
&mut self,
top_level_browsing_context_id: TopLevelBrowsingContextId,
- pipeline_id: PipelineId,
+ browsing_context_id: BrowsingContextId,
) {
- if self
- .pipelines
- .get(&pipeline_id)
- .and_then(|p| p.parent_info)
- .is_none()
- {
+ if browsing_context_id == top_level_browsing_context_id {
// Notify embedder top level document started loading.
self.embedder_proxy
.send((Some(top_level_browsing_context_id), EmbedderMsg::LoadStart));
@@ -2175,8 +2265,9 @@ where
EmbedderMsg::LoadComplete,
));
}
+ } else {
+ self.handle_subframe_loaded(pipeline_id);
}
- self.handle_subframe_loaded(pipeline_id);
}
fn handle_navigated_to_fragment(
@@ -2366,73 +2457,71 @@ where
// TODO: Save the sandbox state so it can be restored here.
let sandbox = IFrameSandboxState::IFrameUnsandboxed;
+ let (top_level_id,
+ old_pipeline_id,
+ parent_pipeline_id,
+ window_size,
+ is_private,
+ is_visible
+ ) = match self.browsing_contexts.get(&browsing_context_id) {
+ Some(ctx) => (
+ ctx.top_level_id,
+ ctx.pipeline_id,
+ ctx.parent_pipeline_id,
+ ctx.size,
+ ctx.is_private,
+ ctx.is_visible,
+ ),
+ None => return warn!("No browsing context to traverse!"),
+ };
+ let opener = match self.pipelines.get(&old_pipeline_id) {
+ Some(pipeline) => pipeline.opener,
+ None => None,
+ };
let new_pipeline_id = PipelineId::new();
- let (top_level_id, parent_info, opener, window_size, is_private) =
- match self.browsing_contexts.get(&browsing_context_id) {
- Some(browsing_context) => {
- match self.pipelines.get(&browsing_context.pipeline_id) {
- Some(pipeline) => (
- browsing_context.top_level_id,
- pipeline.parent_info,
- pipeline.opener,
- browsing_context.size,
- pipeline.is_private,
- ),
- None => (
- browsing_context.top_level_id,
- None,
- None,
- browsing_context.size,
- false,
- ),
- }
- },
- None => return warn!("No browsing context to traverse!"),
- };
self.new_pipeline(
new_pipeline_id,
browsing_context_id,
top_level_id,
- parent_info,
+ parent_pipeline_id,
opener,
window_size,
load_data.clone(),
sandbox,
is_private,
+ is_visible,
);
self.add_pending_change(SessionHistoryChange {
top_level_browsing_context_id: top_level_id,
browsing_context_id: browsing_context_id,
new_pipeline_id: new_pipeline_id,
replace: Some(NeedsToReload::Yes(pipeline_id, load_data.clone())),
+ // Browsing context must exist at this point.
+ new_browsing_context_info: None,
});
return;
},
};
- let old_pipeline_id = match self.browsing_contexts.get_mut(&browsing_context_id) {
- Some(browsing_context) => {
- let old_pipeline_id = browsing_context.pipeline_id;
- browsing_context.update_current_entry(new_pipeline_id);
- old_pipeline_id
- },
- None => {
- return warn!(
- "Browsing context {} was closed during traversal",
- browsing_context_id
- );
- },
- };
-
- let parent_info = self
- .pipelines
- .get(&old_pipeline_id)
- .and_then(|pipeline| pipeline.parent_info);
+ let (old_pipeline_id, parent_pipeline_id) =
+ match self.browsing_contexts.get_mut(&browsing_context_id) {
+ Some(browsing_context) => {
+ let old_pipeline_id = browsing_context.pipeline_id;
+ browsing_context.update_current_entry(new_pipeline_id);
+ (old_pipeline_id, browsing_context.parent_pipeline_id)
+ },
+ None => {
+ return warn!(
+ "Browsing context {} was closed during traversal",
+ browsing_context_id
+ );
+ },
+ };
self.update_activity(old_pipeline_id);
self.update_activity(new_pipeline_id);
- if let Some(parent_pipeline_id) = parent_info {
+ if let Some(parent_pipeline_id) = parent_pipeline_id {
let msg = ConstellationControlMsg::UpdatePipelineId(
parent_pipeline_id,
browsing_context_id,
@@ -2613,7 +2702,7 @@ where
let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
None => {
return warn!(
- "postMessage to closed browsing_context {}.",
+ "PostMessage to closed browsing_context {}.",
browsing_context_id
)
},
@@ -2664,12 +2753,23 @@ where
}
}
+ fn handle_focus_msg(&mut self, pipeline_id: PipelineId) {
+ self.focus_pipeline_id = Some(pipeline_id);
+
+ // Focus parent iframes recursively
+ self.focus_parent_pipeline(pipeline_id);
+ }
+
fn focus_parent_pipeline(&mut self, pipeline_id: PipelineId) {
- let (browsing_context_id, parent_info) = match self.pipelines.get(&pipeline_id) {
- Some(pipeline) => (pipeline.browsing_context_id, pipeline.parent_info),
+ let browsing_context_id = match self.pipelines.get(&pipeline_id) {
+ Some(pipeline) => pipeline.browsing_context_id,
None => return warn!("Pipeline {:?} focus parent after closure.", pipeline_id),
};
- let parent_pipeline_id = match parent_info {
+ let parent_pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
+ Some(ctx) => ctx.parent_pipeline_id,
+ None => return warn!("Browsing context {:?} focus parent after closure.", browsing_context_id),
+ };
+ let parent_pipeline_id = match parent_pipeline_id {
Some(info) => info,
None => return debug!("Pipeline {:?} focus has no parent.", pipeline_id),
};
@@ -2687,13 +2787,6 @@ where
self.focus_parent_pipeline(parent_pipeline_id);
}
- fn handle_focus_msg(&mut self, pipeline_id: PipelineId) {
- self.focus_pipeline_id = Some(pipeline_id);
-
- // Focus parent iframes recursively
- self.focus_parent_pipeline(pipeline_id);
- }
-
fn handle_remove_iframe_msg(
&mut self,
browsing_context_id: BrowsingContextId,
@@ -2706,7 +2799,7 @@ where
result
}
- fn handle_set_visible_msg(&mut self, pipeline_id: PipelineId, visible: bool) {
+ fn handle_set_visible_msg(&mut self, pipeline_id: PipelineId, is_visible: bool) {
let browsing_context_id = match self.pipelines.get(&pipeline_id) {
Some(pipeline) => pipeline.browsing_context_id,
None => {
@@ -2717,24 +2810,38 @@ where
},
};
- let child_pipeline_ids: Vec<PipelineId> = self
+ // TODO(mandreyel): can we make a mutable version of
+ // AllBrowsingContextsIterator to directly modify a browsing context
+ // without the need for this indirection?
+ let nested_ctx_ids: Vec<BrowsingContextId> = self
.all_descendant_browsing_contexts_iter(browsing_context_id)
- .flat_map(|browsing_context| browsing_context.pipelines.iter().cloned())
+ .filter(|ctx| ctx.is_visible != is_visible)
+ .map(|ctx| ctx.id)
.collect();
- for id in child_pipeline_ids {
- if let Some(pipeline) = self.pipelines.get_mut(&id) {
- pipeline.change_visibility(visible);
+ for ctx_id in nested_ctx_ids {
+ if let Some(browsing_context) = self.browsing_contexts.get_mut(&ctx_id) {
+ browsing_context.is_visible = is_visible;
+ for pipeline_id in browsing_context.pipelines.iter() {
+ if let Some(pipeline) = self.pipelines.get_mut(&pipeline_id) {
+ pipeline.notify_visibility(is_visible);
+ }
+ }
}
}
}
fn handle_visibility_change_complete(&mut self, pipeline_id: PipelineId, visibility: bool) {
- let (browsing_context_id, parent_pipeline_info) = match self.pipelines.get(&pipeline_id) {
+ let browsing_context_id = match self.pipelines.get(&pipeline_id) {
+ Some(pipeline) => pipeline.browsing_context_id,
None => return warn!("Visibity change for closed pipeline {:?}.", pipeline_id),
- Some(pipeline) => (pipeline.browsing_context_id, pipeline.parent_info),
};
- if let Some(parent_pipeline_id) = parent_pipeline_info {
+ let parent_pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
+ Some(ctx) => ctx.parent_pipeline_id,
+ None => return warn!("Visibility change for closed browsing context {:?}.", pipeline_id),
+ };
+
+ if let Some(parent_pipeline_id) = parent_pipeline_id {
let visibility_msg = ConstellationControlMsg::NotifyVisibilityChange(
parent_pipeline_id,
browsing_context_id,
@@ -2797,18 +2904,8 @@ where
},
WebDriverCommandMsg::Refresh(top_level_browsing_context_id, reply) => {
let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id);
- let load_data = match self.browsing_contexts.get(&browsing_context_id) {
- Some(browsing_context) => {
- match self.pipelines.get(&browsing_context.pipeline_id) {
- Some(pipeline) => pipeline.load_data.clone(),
- None => {
- return warn!(
- "Pipeline {} refresh after closure.",
- browsing_context.pipeline_id
- )
- },
- }
- },
+ let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
+ Some(browsing_context) => browsing_context.pipeline_id,
None => {
return warn!(
"Browsing context {} Refresh after closure.",
@@ -2816,6 +2913,10 @@ where
)
},
};
+ let load_data = match self.pipelines.get(&pipeline_id) {
+ Some(pipeline) => pipeline.load_data.clone(),
+ None => return warn!("Pipeline {} refresh after closure.", pipeline_id),
+ };
self.load_url_for_webdriver(top_level_browsing_context_id, load_data, reply, true);
},
WebDriverCommandMsg::ScriptCommand(browsing_context_id, cmd) => {
@@ -2867,10 +2968,11 @@ where
}
fn notify_history_changed(&self, top_level_browsing_context_id: TopLevelBrowsingContextId) {
- // Send a flat projection of the history.
- // The final vector is a concatenation of the LoadData of the past entries,
- // the current entry and the future entries.
- // LoadData of inner frames are ignored and replaced with the LoadData of the parent.
+ // Send a flat projection of the history to embedder.
+ // The final vector is a concatenation of the LoadData of the past
+ // entries, the current entry and the future entries.
+ // LoadData of inner frames are ignored and replaced with the LoadData
+ // of the parent.
let session_history = match self
.joint_session_histories
@@ -3044,10 +3146,22 @@ where
match old_pipeline_id {
None => {
+ let new_context_info = match change.new_browsing_context_info {
+ Some(info) => info,
+ None => {
+ return warn!(
+ "No NewBrowsingContextInfo for browsing context {}",
+ change.browsing_context_id,
+ )
+ },
+ };
self.new_browsing_context(
change.browsing_context_id,
change.top_level_browsing_context_id,
change.new_pipeline_id,
+ new_context_info.parent_pipeline_id,
+ new_context_info.is_private,
+ new_context_info.is_visible,
);
self.update_activity(change.new_pipeline_id);
self.notify_history_changed(change.top_level_browsing_context_id);
@@ -3221,21 +3335,6 @@ where
fn handle_activate_document_msg(&mut self, pipeline_id: PipelineId) {
debug!("Document ready to activate {}", pipeline_id);
- // Notify the parent (if there is one).
- if let Some(pipeline) = self.pipelines.get(&pipeline_id) {
- if let Some(parent_pipeline_id) = pipeline.parent_info {
- if let Some(parent_pipeline) = self.pipelines.get(&parent_pipeline_id) {
- let msg = ConstellationControlMsg::UpdatePipelineId(
- parent_pipeline_id,
- pipeline.browsing_context_id,
- pipeline_id,
- UpdatePipelineIdReason::Navigation,
- );
- let _ = parent_pipeline.event_loop.send(msg);
- }
- }
- }
-
// Find the pending change whose new pipeline id is pipeline_id.
let pending_index = self
.pending_changes
@@ -3246,6 +3345,31 @@ where
// the active document of its frame.
if let Some(pending_index) = pending_index {
let change = self.pending_changes.swap_remove(pending_index);
+ // Notify the parent (if there is one).
+ let parent_pipeline_id = match change.new_browsing_context_info {
+ // This will be a new browsing context.
+ Some(ref info) => info.parent_pipeline_id,
+ // This is an existing browsing context.
+ None => match self.browsing_contexts.get(&change.browsing_context_id) {
+ Some(ctx) => ctx.parent_pipeline_id,
+ None => return warn!(
+ "Activated document {} after browsing context {} closure.",
+ change.new_pipeline_id,
+ change.browsing_context_id,
+ ),
+ },
+ };
+ if let Some(parent_pipeline_id) = parent_pipeline_id {
+ if let Some(parent_pipeline) = self.pipelines.get(&parent_pipeline_id) {
+ let msg = ConstellationControlMsg::UpdatePipelineId(
+ parent_pipeline_id,
+ change.browsing_context_id,
+ pipeline_id,
+ UpdatePipelineIdReason::Navigation,
+ );
+ let _ = parent_pipeline.event_loop.send(msg);
+ }
+ }
self.change_session_history(change);
}
}
@@ -3420,8 +3544,8 @@ where
self.browsing_contexts.get(&ancestor.browsing_context_id)
{
if browsing_context.pipeline_id == ancestor_id {
- if let Some(parent_id) = ancestor.parent_info {
- ancestor_id = parent_id;
+ if let Some(parent_pipeline_id) = browsing_context.parent_pipeline_id {
+ ancestor_id = parent_pipeline_id;
continue;
} else {
return DocumentActivity::FullyActive;
@@ -3470,11 +3594,7 @@ where
) {
if let Some(browsing_context) = self.browsing_contexts.get_mut(&browsing_context_id) {
browsing_context.size = Some(new_size.initial_viewport);
- }
-
- if let Some(browsing_context) = self.browsing_contexts.get(&browsing_context_id) {
- // Send Resize (or ResizeInactive) messages to each
- // pipeline in the frame tree.
+ // Send Resize (or ResizeInactive) messages to each pipeline in the frame tree.
let pipeline_id = browsing_context.pipeline_id;
let pipeline = match self.pipelines.get(&pipeline_id) {
None => return warn!("Pipeline {:?} resized after closing.", pipeline_id),
@@ -3485,18 +3605,17 @@ where
new_size,
size_type,
));
- let pipelines = browsing_context
- .pipelines
+ let pipeline_ids = browsing_context.pipelines
.iter()
- .filter(|pipeline_id| **pipeline_id != pipeline.id)
- .filter_map(|pipeline_id| self.pipelines.get(&pipeline_id));
- for pipeline in pipelines {
- let _ = pipeline
- .event_loop
- .send(ConstellationControlMsg::ResizeInactive(
- pipeline.id,
- new_size,
- ));
+ .filter(|pipeline_id| **pipeline_id != pipeline.id);
+ for id in pipeline_ids {
+ if let Some(pipeline) = self.pipelines.get(&id) {
+ let _ = pipeline.event_loop
+ .send(ConstellationControlMsg::ResizeInactive(
+ pipeline.id,
+ new_size,
+ ));
+ }
}
}
@@ -3535,8 +3654,8 @@ where
);
let browsing_context = match self.browsing_contexts.remove(&browsing_context_id) {
+ Some(ctx) => ctx,
None => return warn!("Closing browsing context {:?} twice.", browsing_context_id),
- Some(browsing_context) => browsing_context,
};
{
@@ -3544,12 +3663,7 @@ where
session_history.remove_entries_for_browsing_context(browsing_context_id);
}
- let parent_info = self
- .pipelines
- .get(&browsing_context.pipeline_id)
- .and_then(|pipeline| pipeline.parent_info);
-
- if let Some(parent_pipeline_id) = parent_info {
+ if let Some(parent_pipeline_id) = browsing_context.parent_pipeline_id {
match self.pipelines.get_mut(&parent_pipeline_id) {
None => {
return warn!(
diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs
index 62899328ca1..ab9f463c235 100644
--- a/components/constellation/pipeline.rs
+++ b/components/constellation/pipeline.rs
@@ -58,10 +58,6 @@ pub struct Pipeline {
/// The ID of the top-level browsing context that contains this Pipeline.
pub top_level_browsing_context_id: TopLevelBrowsingContextId,
- /// The parent pipeline of this one. `None` if this is a root pipeline.
- /// TODO: move this field to `BrowsingContext`.
- pub parent_info: Option<PipelineId>,
-
pub opener: Option<BrowsingContextId>,
/// The event loop handling this pipeline.
@@ -85,14 +81,6 @@ pub struct Pipeline {
/// The child browsing contexts of this pipeline (these are iframes in the document).
pub children: Vec<BrowsingContextId>,
- /// Whether this pipeline is in private browsing mode.
- /// TODO: move this field to `BrowsingContext`.
- pub is_private: bool,
-
- /// Whether this pipeline should be treated as visible for the purposes of scheduling and
- /// resource management.
- pub visible: bool,
-
/// The Load Data used to create this pipeline.
pub load_data: LoadData,
@@ -119,7 +107,7 @@ pub struct InitialPipelineState {
/// The ID of the parent pipeline and frame type, if any.
/// If `None`, this is the root.
- pub parent_info: Option<PipelineId>,
+ pub parent_pipeline_id: Option<PipelineId>,
pub opener: Option<BrowsingContextId>,
@@ -171,8 +159,11 @@ pub struct InitialPipelineState {
/// The ID of the pipeline namespace for this script thread.
pub pipeline_namespace_id: PipelineNamespaceId,
- /// Pipeline visibility to be inherited
- pub prev_visibility: Option<bool>,
+ /// Whether the browsing context in which pipeline is embedded is visible
+ /// for the purposes of scheduling and resource management. This field is
+ /// only used to notify script and compositor threads after spawning
+ /// a pipeline.
+ pub prev_visibility: bool,
/// Webrender api.
pub webrender_api_sender: webrender_api::RenderApiSender,
@@ -180,9 +171,6 @@ pub struct InitialPipelineState {
/// The ID of the document processed by this script thread.
pub webrender_document: webrender_api::DocumentId,
- /// Whether this pipeline is considered private.
- pub is_private: bool,
-
/// A channel to the WebGL thread.
pub webgl_chan: Option<WebGLPipeline>,
@@ -216,7 +204,7 @@ impl Pipeline {
let script_chan = match state.event_loop {
Some(script_chan) => {
let new_layout_info = NewLayoutInfo {
- parent_info: state.parent_info,
+ parent_info: state.parent_pipeline_id,
new_pipeline_id: state.id,
browsing_context_id: state.browsing_context_id,
top_level_browsing_context_id: state.top_level_browsing_context_id,
@@ -270,7 +258,7 @@ impl Pipeline {
id: state.id,
browsing_context_id: state.browsing_context_id,
top_level_browsing_context_id: state.top_level_browsing_context_id,
- parent_info: state.parent_info,
+ parent_pipeline_id: state.parent_pipeline_id,
opener: state.opener,
script_to_constellation_chan: state.script_to_constellation_chan.clone(),
scheduler_chan: state.scheduler_chan,
@@ -317,14 +305,12 @@ impl Pipeline {
state.id,
state.browsing_context_id,
state.top_level_browsing_context_id,
- state.parent_info,
state.opener,
script_chan,
pipeline_chan,
state.compositor_proxy,
- state.is_private,
url,
- state.prev_visibility.unwrap_or(true),
+ state.prev_visibility,
state.load_data,
))
}
@@ -335,21 +321,18 @@ impl Pipeline {
id: PipelineId,
browsing_context_id: BrowsingContextId,
top_level_browsing_context_id: TopLevelBrowsingContextId,
- parent_info: Option<PipelineId>,
opener: Option<BrowsingContextId>,
event_loop: Rc<EventLoop>,
layout_chan: IpcSender<LayoutControlMsg>,
compositor_proxy: CompositorProxy,
- is_private: bool,
url: ServoUrl,
- visible: bool,
+ is_visible: bool,
load_data: LoadData,
) -> Pipeline {
let pipeline = Pipeline {
id: id,
browsing_context_id: browsing_context_id,
top_level_browsing_context_id: top_level_browsing_context_id,
- parent_info: parent_info,
opener: opener,
event_loop: event_loop,
layout_chan: layout_chan,
@@ -357,14 +340,12 @@ impl Pipeline {
url: url,
children: vec![],
running_animations: false,
- visible: visible,
- is_private: is_private,
load_data: load_data,
history_state_id: None,
history_states: HashSet::new(),
};
- pipeline.notify_visibility();
+ pipeline.notify_visibility(is_visible);
pipeline
}
@@ -448,25 +429,16 @@ impl Pipeline {
}
/// Notify the script thread that this pipeline is visible.
- fn notify_visibility(&self) {
+ pub fn notify_visibility(&self, is_visible: bool) {
let script_msg =
- ConstellationControlMsg::ChangeFrameVisibilityStatus(self.id, self.visible);
- let compositor_msg = CompositorMsg::PipelineVisibilityChanged(self.id, self.visible);
+ ConstellationControlMsg::ChangeFrameVisibilityStatus(self.id, is_visible);
+ let compositor_msg = CompositorMsg::PipelineVisibilityChanged(self.id, is_visible);
let err = self.event_loop.send(script_msg);
if let Err(e) = err {
warn!("Sending visibility change failed ({}).", e);
}
self.compositor_proxy.send(compositor_msg);
}
-
- /// Change the visibility of this pipeline.
- pub fn change_visibility(&mut self, visible: bool) {
- if visible == self.visible {
- return;
- }
- self.visible = visible;
- self.notify_visibility();
- }
}
/// Creating a new pipeline may require creating a new event loop.
@@ -477,7 +449,7 @@ pub struct UnprivilegedPipelineContent {
id: PipelineId,
top_level_browsing_context_id: TopLevelBrowsingContextId,
browsing_context_id: BrowsingContextId,
- parent_info: Option<PipelineId>,
+ parent_pipeline_id: Option<PipelineId>,
opener: Option<BrowsingContextId>,
script_to_constellation_chan: ScriptToConstellationChan,
layout_to_constellation_chan: IpcSender<LayoutMsg>,
@@ -526,7 +498,7 @@ impl UnprivilegedPipelineContent {
id: self.id,
browsing_context_id: self.browsing_context_id,
top_level_browsing_context_id: self.top_level_browsing_context_id,
- parent_info: self.parent_info,
+ parent_info: self.parent_pipeline_id,
opener: self.opener,
control_chan: self.script_chan.clone(),
control_port: self.script_port,
@@ -553,7 +525,7 @@ impl UnprivilegedPipelineContent {
self.id,
self.top_level_browsing_context_id,
self.load_data.url,
- self.parent_info.is_some(),
+ self.parent_pipeline_id.is_some(),
layout_pair,
self.pipeline_port,
self.layout_to_constellation_chan,
diff --git a/components/constellation/session_history.rs b/components/constellation/session_history.rs
index aa550fac0fb..8faa09e7555 100644
--- a/components/constellation/session_history.rs
+++ b/components/constellation/session_history.rs
@@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+use browsingcontext::NewBrowsingContextInfo;
use msg::constellation_msg::{BrowsingContextId, HistoryStateId, PipelineId, TopLevelBrowsingContextId};
use script_traits::LoadData;
use servo_url::ServoUrl;
@@ -113,6 +114,10 @@ pub struct SessionHistoryChange {
/// The old pipeline that the new pipeline should replace.
pub replace: Option<NeedsToReload>,
+
+ /// Holds data for not-yet constructed browsing contexts that are not
+ /// easily available when they need to be constructed.
+ pub new_browsing_context_info: Option<NewBrowsingContextInfo>,
}
/// Represents a pipeline or discarded pipeline in a history entry.