aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/compositing/constellation.rs4
-rw-r--r--components/script/script_task.rs54
-rw-r--r--tests/wpt/mozilla/meta/MANIFEST.json6
-rw-r--r--tests/wpt/mozilla/tests/mozilla/mozbrowser/iframe_goback.html37
4 files changed, 81 insertions, 20 deletions
diff --git a/components/compositing/constellation.rs b/components/compositing/constellation.rs
index c876e6e7a4d..131dfbd9e1d 100644
--- a/components/compositing/constellation.rs
+++ b/components/compositing/constellation.rs
@@ -834,6 +834,10 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
}
};
+ if let Some(pipeline_id) = old_pipeline_id {
+ self.pipeline(pipeline_id).freeze();
+ }
+
// Create the new pipeline, attached to the parent and push to pending frames
let window_size = old_pipeline_id.and_then(|old_pipeline_id| {
self.pipeline(old_pipeline_id).size
diff --git a/components/script/script_task.rs b/components/script/script_task.rs
index 04500ac5738..4af59aa1603 100644
--- a/components/script/script_task.rs
+++ b/components/script/script_task.rs
@@ -135,6 +135,8 @@ struct InProgressLoad {
layout_chan: LayoutChan,
/// The current viewport clipping rectangle applying to this pipeline, if any.
clip_rect: Option<Rect<f32>>,
+ /// Window is frozen (navigated away while loading for example).
+ is_frozen: bool,
/// The requested URL of the load.
url: Url,
}
@@ -152,6 +154,7 @@ impl InProgressLoad {
layout_chan: layout_chan,
window_size: window_size,
clip_rect: None,
+ is_frozen: false,
url: url,
}
}
@@ -1319,31 +1322,38 @@ impl ScriptTask {
/// Handles freeze message
fn handle_freeze_msg(&self, id: PipelineId) {
- // Workaround for a race condition when navigating before the initial page has
- // been constructed c.f. https://github.com/servo/servo/issues/7677
- if self.page.borrow().is_none() {
- return
- };
- let page = self.root_page();
- let page = page.find(id).expect("ScriptTask: received freeze msg for a
- pipeline ID not associated with this script task. This is a bug.");
- let window = page.window();
- window.freeze();
+ if let Some(root_page) = self.page.borrow().as_ref() {
+ if let Some(ref inner_page) = root_page.find(id) {
+ let window = inner_page.window();
+ window.freeze();
+ return;
+ }
+ }
+ let mut loads = self.incomplete_loads.borrow_mut();
+ if let Some(ref mut load) = loads.iter_mut().find(|load| load.pipeline_id == id) {
+ load.is_frozen = true;
+ return;
+ }
+ panic!("freeze sent to nonexistent pipeline");
}
/// Handles thaw message
fn handle_thaw_msg(&self, id: PipelineId) {
- // We should only get this message when moving in history, so all pages requested
- // should exist.
- let page = self.root_page().find(id).unwrap();
-
- let needed_reflow = page.set_reflow_status(false);
- if needed_reflow {
- self.rebuild_and_force_reflow(&*page, ReflowReason::CachedPageNeededReflow);
+ if let Some(ref inner_page) = self.root_page().find(id) {
+ let needed_reflow = inner_page.set_reflow_status(false);
+ if needed_reflow {
+ self.rebuild_and_force_reflow(&*inner_page, ReflowReason::CachedPageNeededReflow);
+ }
+ let window = inner_page.window();
+ window.thaw();
+ return;
}
-
- let window = page.window();
- window.thaw();
+ let mut loads = self.incomplete_loads.borrow_mut();
+ if let Some(ref mut load) = loads.iter_mut().find(|load| load.pipeline_id == id) {
+ load.is_frozen = false;
+ return;
+ }
+ panic!("thaw sent to nonexistent pipeline");
}
fn handle_focus_iframe_msg(&self,
@@ -1732,6 +1742,10 @@ impl ScriptTask {
}
}
+ if incomplete.is_frozen {
+ window.freeze();
+ }
+
page_remover.neuter();
document.get_current_parser().unwrap()
diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json
index 36de1f76640..64b128a17f9 100644
--- a/tests/wpt/mozilla/meta/MANIFEST.json
+++ b/tests/wpt/mozilla/meta/MANIFEST.json
@@ -5679,6 +5679,12 @@
"url": "/_mozilla/mozilla/load_event.html"
}
],
+ "mozilla/mozbrowser/iframe_goback.html": [
+ {
+ "path": "mozilla/mozbrowser/iframe_goback.html",
+ "url": "/_mozilla/mozilla/mozbrowser/iframe_goback.html"
+ }
+ ],
"mozilla/mozbrowser/mozbrowsericonchange_event.html": [
{
"path": "mozilla/mozbrowser/mozbrowsericonchange_event.html",
diff --git a/tests/wpt/mozilla/tests/mozilla/mozbrowser/iframe_goback.html b/tests/wpt/mozilla/tests/mozilla/mozbrowser/iframe_goback.html
new file mode 100644
index 00000000000..518bb3d5a47
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/mozbrowser/iframe_goback.html
@@ -0,0 +1,37 @@
+<head>
+<title>iframe.goBack()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+
+async_test(function(t) {
+
+ var url2 = "data:,a";
+ var url1 = `data:text/html,<script>setTimeout(() => location.assign("${url2}"), 0)</${"script"}>`;
+
+ var locations = []
+ var expected_locations = [url1, url2, url1];
+
+ var iframe = document.createElement("iframe");
+ iframe.mozbrowser = "true";
+ iframe.src = url1;
+
+ iframe.addEventListener("mozbrowserlocationchange", e => {
+ locations.push(e.detail);
+ if (e.detail == url2) {
+ iframe.goBack();
+ }
+ if (locations.length == expected_locations.length) {
+ assert_array_equals(locations, expected_locations);
+ t.done();
+ }
+ });
+
+ document.body.appendChild(iframe);
+
+});
+
+</script>
+</body>