aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGregory Terzian <gterzian@users.noreply.github.com>2018-05-20 23:49:15 +0800
committerGregory Terzian <gterzian@users.noreply.github.com>2018-05-22 18:11:45 +0800
commit57c0d82944969f7ee645c9208f41fb24e8561d43 (patch)
tree9f0e61c53b8ce41180add6e63c1d564b944613c6
parenta297e8f2881d0d1927160d2ebc0e4b26d71f2534 (diff)
downloadservo-57c0d82944969f7ee645c9208f41fb24e8561d43.tar.gz
servo-57c0d82944969f7ee645c9208f41fb24e8561d43.zip
prevent overwriting of salvageable state in later prompt/unload steps
-rw-r--r--components/script/dom/document.rs16
-rw-r--r--tests/wpt/metadata/MANIFEST.json28
-rw-r--r--tests/wpt/web-platform-tests/html/browsers/browsing-the-web/unloading-documents/prompt/004-1.html28
-rw-r--r--tests/wpt/web-platform-tests/html/browsers/browsing-the-web/unloading-documents/prompt/004-2.html5
-rw-r--r--tests/wpt/web-platform-tests/html/browsers/browsing-the-web/unloading-documents/prompt/004.html29
5 files changed, 101 insertions, 5 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 3b6b92246f1..16adcd7edbd 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -1654,7 +1654,9 @@ impl Document {
);
// TODO: Step 6, decrease the event loop's termination nesting level by 1.
// Step 7
- self.salvageable.set(!has_listeners);
+ if has_listeners {
+ self.salvageable.set(false);
+ }
let mut can_unload = true;
// TODO: Step 8 send a message to embedder to prompt user.
// Step 9
@@ -1662,9 +1664,11 @@ impl Document {
for iframe in self.iter_iframes() {
// TODO: handle the case of cross origin iframes.
let document = document_from_node(&*iframe);
- if !document.prompt_to_unload(true) {
- self.salvageable.set(document.salvageable());
- can_unload = false;
+ can_unload = document.prompt_to_unload(true);
+ if !document.salvageable() {
+ self.salvageable.set(false);
+ }
+ if !can_unload {
break;
}
}
@@ -1715,7 +1719,9 @@ impl Document {
);
self.fired_unload.set(true);
// Step 9
- self.salvageable.set(!has_listeners);
+ if has_listeners {
+ self.salvageable.set(false);
+ }
}
// TODO: Step 8, decrease the event loop's termination nesting level by 1.
diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json
index 1e38218000f..1cfd355612e 100644
--- a/tests/wpt/metadata/MANIFEST.json
+++ b/tests/wpt/metadata/MANIFEST.json
@@ -277161,6 +277161,16 @@
{}
]
],
+ "html/browsers/browsing-the-web/unloading-documents/prompt/004-1.html": [
+ [
+ {}
+ ]
+ ],
+ "html/browsers/browsing-the-web/unloading-documents/prompt/004-2.html": [
+ [
+ {}
+ ]
+ ],
"html/browsers/browsing-the-web/unloading-documents/prompt/manual-001.html": [
[
{}
@@ -333024,6 +333034,12 @@
{}
]
],
+ "html/browsers/browsing-the-web/unloading-documents/prompt/004.html": [
+ [
+ "/html/browsers/browsing-the-web/unloading-documents/prompt/004.html",
+ {}
+ ]
+ ],
"html/browsers/browsing-the-web/unloading-documents/unload/001.html": [
[
"/html/browsers/browsing-the-web/unloading-documents/unload/001.html",
@@ -564777,6 +564793,18 @@
"c37ad1ea3a1c8e389f6066c95c7b2745648e9e7e",
"testharness"
],
+ "html/browsers/browsing-the-web/unloading-documents/prompt/004-1.html": [
+ "3530a94754361d436b6c20496bea07eb0bec4893",
+ "support"
+ ],
+ "html/browsers/browsing-the-web/unloading-documents/prompt/004-2.html": [
+ "01dc2c7f9c673781291a5afbdb40ca0f0919e797",
+ "support"
+ ],
+ "html/browsers/browsing-the-web/unloading-documents/prompt/004.html": [
+ "4c8485a929926005115dd0f8e2d2a2d8e1673c6f",
+ "testharness"
+ ],
"html/browsers/browsing-the-web/unloading-documents/prompt/manual-001.html": [
"895580cf70904918397da755527c5dda3f227b8a",
"support"
diff --git a/tests/wpt/web-platform-tests/html/browsers/browsing-the-web/unloading-documents/prompt/004-1.html b/tests/wpt/web-platform-tests/html/browsers/browsing-the-web/unloading-documents/prompt/004-1.html
new file mode 100644
index 00000000000..a3ca82f520a
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/browsers/browsing-the-web/unloading-documents/prompt/004-1.html
@@ -0,0 +1,28 @@
+<!doctype html>
+004-1
+<script>
+var handleBeforeUnload = function() {
+ parent.beforeunload_fired = true;
+ removeListener();
+ setTimeout(function() {
+ parent.timeout_fired = true;
+ }, 1000);
+}
+
+var removeListener = function() {
+ assert_true(window.removeEventListener('beforeunload', handleBeforeUnload, false));
+}
+
+window.addEventListener('beforeunload', handleBeforeUnload, false);
+
+onload = function() {
+ if (!parent.loaded) {
+ parent.loaded = true;
+ location="004-2.html?" + Math.random();
+ }
+}
+</script>
+// child frame with no onbeforeunload listener. Should leave the parent as unsalvageable.
+// Adding the iframe prevents potential implementation bugs where the the recursive steps of #prompt-to-unload-a-document
+// would overwrite the salvageable state of the parent.
+<iframe></iframe>
diff --git a/tests/wpt/web-platform-tests/html/browsers/browsing-the-web/unloading-documents/prompt/004-2.html b/tests/wpt/web-platform-tests/html/browsers/browsing-the-web/unloading-documents/prompt/004-2.html
new file mode 100644
index 00000000000..1a605b1b3d5
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/browsers/browsing-the-web/unloading-documents/prompt/004-2.html
@@ -0,0 +1,5 @@
+<!doctype html>
+004-2
+<script>
+onload = function() {setTimeout(parent.t.step_func(function() {parent.start_test(); history.go(-1)}), 100)}
+</script>
diff --git a/tests/wpt/web-platform-tests/html/browsers/browsing-the-web/unloading-documents/prompt/004.html b/tests/wpt/web-platform-tests/html/browsers/browsing-the-web/unloading-documents/prompt/004.html
new file mode 100644
index 00000000000..7076a4dd18e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/browsers/browsing-the-web/unloading-documents/prompt/004.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>salvagable state of document after setting beforeunload listener</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+var t = async_test();
+
+var loaded = false;
+var beforeunload_fired = false;
+var timeout_fired = false;
+
+function start_test() {
+ step_timeout(
+ t.step_func(function() {
+ assert_true(beforeunload_fired);
+ assert_false(timeout_fired);
+ t.done()
+ }), 1000);
+}
+
+onload = function() {
+ var iframe = document.getElementsByTagName("iframe")[0]
+ onload = null;
+ iframe.src="004-1.html?" + Math.random();
+};
+
+</script>
+<iframe></iframe>