diff options
-rw-r--r-- | components/compositing/constellation.rs | 4 | ||||
-rw-r--r-- | components/script/script_task.rs | 54 | ||||
-rw-r--r-- | tests/wpt/mozilla/meta/MANIFEST.json | 6 | ||||
-rw-r--r-- | tests/wpt/mozilla/tests/mozilla/mozbrowser/iframe_goback.html | 37 |
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> |