aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/constellation/constellation.rs27
-rw-r--r--components/constellation/pipeline.rs6
-rw-r--r--tests/wpt/mozilla/tests/mozilla/mozbrowser/iframe_visibility.html23
3 files changed, 45 insertions, 11 deletions
diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs
index ba5a4353d12..a57bc38dfd6 100644
--- a/components/constellation/constellation.rs
+++ b/components/constellation/constellation.rs
@@ -548,6 +548,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
fn new_pipeline(&mut self,
pipeline_id: PipelineId,
parent_info: Option<(PipelineId, FrameType)>,
+ old_pipeline_id: Option<PipelineId>,
initial_window_size: Option<TypedSize2D<f32, PagePx>>,
script_channel: Option<IpcSender<ConstellationControlMsg>>,
load_data: LoadData,
@@ -560,7 +561,9 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
self.public_resource_threads.clone()
};
- let parent_visibility = if let Some((parent_pipeline_id, _)) = parent_info {
+ let prev_visibility = if let Some(id) = old_pipeline_id {
+ self.pipelines.get(&id).map(|pipeline| pipeline.visible)
+ } else if let Some((parent_pipeline_id, _)) = parent_info {
self.pipelines.get(&parent_pipeline_id).map(|pipeline| pipeline.visible)
} else {
None
@@ -586,7 +589,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
load_data: load_data,
device_pixel_ratio: self.window_size.device_pixel_ratio,
pipeline_namespace_id: self.next_pipeline_namespace_id(),
- parent_visibility: parent_visibility,
+ prev_visibility: prev_visibility,
webrender_api_sender: self.webrender_api_sender.clone(),
is_private: is_private,
});
@@ -1146,7 +1149,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
let new_pipeline_id = PipelineId::new();
let load_data = LoadData::new(failure_url, None, None);
- self.new_pipeline(new_pipeline_id, parent_info, window_size, None, load_data, false);
+ self.new_pipeline(new_pipeline_id, parent_info, Some(pipeline_id), window_size, None, load_data, false);
self.push_pending_frame(new_pipeline_id, Some(pipeline_id));
@@ -1171,7 +1174,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
let window_size = self.window_size.visible_viewport;
let root_pipeline_id = PipelineId::new();
debug_assert!(PipelineId::fake_root_pipeline_id() == root_pipeline_id);
- self.new_pipeline(root_pipeline_id, None, Some(window_size), None,
+ self.new_pipeline(root_pipeline_id, None, None, Some(window_size), None,
LoadData::new(url.clone(), None, None), false);
self.handle_load_start_msg(root_pipeline_id);
self.push_pending_frame(root_pipeline_id, None);
@@ -1290,6 +1293,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
// Create the new pipeline, attached to the parent and push to pending frames
self.new_pipeline(load_info.new_pipeline_id,
Some((load_info.parent_pipeline_id, load_info.frame_type)),
+ load_info.old_pipeline_id,
window_size,
script_chan,
load_data,
@@ -1424,7 +1428,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
// Create the new pipeline
let window_size = self.pipelines.get(&source_id).and_then(|source| source.size);
let new_pipeline_id = PipelineId::new();
- self.new_pipeline(new_pipeline_id, None, window_size, None, load_data, false);
+ self.new_pipeline(new_pipeline_id, None, None, window_size, None, load_data, false);
self.push_pending_frame(new_pipeline_id, Some(source_id));
// Send message to ScriptThread that will suspend all timers
@@ -1668,9 +1672,16 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
fn handle_set_visible_msg(&mut self, pipeline_id: PipelineId, visible: bool) {
- let frame_id = self.pipelines.get(&pipeline_id).and_then(|pipeline| pipeline.frame);
- let child_pipeline_ids: Vec<PipelineId> = self.current_frame_tree_iter(frame_id)
- .map(|frame| frame.current.pipeline_id)
+ let frame_id = match self.pipelines.get(&pipeline_id).and_then(|pipeline| pipeline.frame) {
+ Some(id) => id,
+ None => return warn!("No frame associated with pipeline {:?}", pipeline_id),
+ };
+
+ let child_pipeline_ids: Vec<PipelineId> = self.full_frame_tree_iter(frame_id)
+ .flat_map(|frame| frame.next.iter()
+ .chain(frame.prev.iter())
+ .chain(once(&frame.current)))
+ .map(|state| state.pipeline_id)
.collect();
for id in child_pipeline_ids {
if let Some(pipeline) = self.pipelines.get_mut(&id) {
diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs
index 7ed977b89ad..300aada7430 100644
--- a/components/constellation/pipeline.rs
+++ b/components/constellation/pipeline.rs
@@ -121,8 +121,8 @@ pub struct InitialPipelineState {
pub load_data: LoadData,
/// The ID of the pipeline namespace for this script thread.
pub pipeline_namespace_id: PipelineNamespaceId,
- /// Pipeline visibility is inherited from parent
- pub parent_visibility: Option<bool>,
+ /// Pipeline visibility to be inherited
+ pub prev_visibility: Option<bool>,
/// Optional webrender api (if enabled).
pub webrender_api_sender: Option<webrender_traits::RenderApiSender>,
/// Whether this pipeline is considered private.
@@ -263,7 +263,7 @@ impl Pipeline {
state.is_private,
state.load_data.url,
state.window_size,
- state.parent_visibility.unwrap_or(true));
+ state.prev_visibility.unwrap_or(true));
pipeline.notify_visibility();
diff --git a/tests/wpt/mozilla/tests/mozilla/mozbrowser/iframe_visibility.html b/tests/wpt/mozilla/tests/mozilla/mozbrowser/iframe_visibility.html
index 4681f5db25a..8987998993c 100644
--- a/tests/wpt/mozilla/tests/mozilla/mozbrowser/iframe_visibility.html
+++ b/tests/wpt/mozilla/tests/mozilla/mozbrowser/iframe_visibility.html
@@ -88,5 +88,28 @@
});
document.body.appendChild(iframe);
}, 'Minimum setTimeout of 1s when pipeline is invisible');
+
+ async_test(function(t) {
+ var iframe = document.createElement("iframe");
+ var destination = "helper.html";
+ iframe.src = "http://web-platform.test:8000/common/blank.html";
+ iframe.mozbrowser = true;
+ iframe.onload = t.step_func(function() {
+ iframe.addEventListener("mozbrowservisibilitychange", t.step_func(function() {
+ iframe.src = destination;
+ }));
+ if (iframe.src !== destination) {
+ iframe.setVisible(false);
+ } else {
+ var startTime = Date.now();
+ iframe.contentWindow.setTimeout(t.step_func(function() {
+ assert_true(Date.now() - startTime >= 1000);
+ t.done();
+ }), 1);
+ }
+ });
+ document.body.appendChild(iframe);
+ }, 'Minimum setTimeout of 1s persists after new page is loaded');
+
</script>
</body>