summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/bailout-exception-vs-return-origin.sub.window.js
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/bailout-exception-vs-return-origin.sub.window.js')
-rw-r--r--testing/web-platform/tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/bailout-exception-vs-return-origin.sub.window.js117
1 files changed, 117 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/bailout-exception-vs-return-origin.sub.window.js b/testing/web-platform/tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/bailout-exception-vs-return-origin.sub.window.js
new file mode 100644
index 0000000000..b20c3e3f31
--- /dev/null
+++ b/testing/web-platform/tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/bailout-exception-vs-return-origin.sub.window.js
@@ -0,0 +1,117 @@
+document.domain = "{{host}}";
+
+// In many cases in this test, we want to delay execution of a piece of code so
+// that the entry settings object would be the top-level page. A microtask is
+// perfect for this purpose as it is executed in the "clean up after running
+// script" algorithm, which is generally called right after the callback.
+function setEntryToTopLevel(cb) {
+ Promise.resolve().then(cb);
+}
+
+async_test(t => {
+ const iframe = document.body.appendChild(document.createElement("iframe"));
+ t.add_cleanup(() => { iframe.remove(); });
+ iframe.onload = t.step_func_done(() => {
+ // Since this is called as an event handler on an element of this window,
+ // the entry settings object is that of this browsing context.
+ assert_throws_dom(
+ "InvalidStateError",
+ iframe.contentWindow.DOMException,
+ () => {
+ iframe.contentDocument.open();
+ },
+ "opening an XML document should throw an InvalidStateError"
+ );
+ });
+ const frameURL = new URL("resources/bailout-order-xml-with-domain-frame.sub.xhtml", document.URL);
+ frameURL.port = "{{ports[http][1]}}";
+ iframe.src = frameURL.href;
+}, "document.open should throw an InvalidStateError with XML document even if it is cross-origin");
+
+async_test(t => {
+ const iframe = document.body.appendChild(document.createElement("iframe"));
+ t.add_cleanup(() => { iframe.remove(); });
+ window.onCustomElementReady = t.step_func(() => {
+ window.onCustomElementReady = t.unreached_func("onCustomElementReady called again");
+ // Here, the entry settings object is still the iframe's, as the function
+ // is called from a custom element constructor in the iframe document.
+ // Delay execution in such a way that makes the entry settings object the
+ // top-level page's, but without delaying too much that the
+ // throw-on-dynamic-markup-insertion counter gets decremented (which is
+ // what this test tries to pit against the cross-origin document check).
+ //
+ // "Clean up after running script" is executed through the "construct" Web
+ // IDL algorithm in "create an element", called by "create an element for a
+ // token" in the parser.
+ setEntryToTopLevel(t.step_func_done(() => {
+ assert_throws_dom(
+ "InvalidStateError",
+ iframe.contentWindow.DOMException,
+ () => {
+ iframe.contentDocument.open();
+ },
+ "opening a document when the throw-on-dynamic-markup-insertion counter is incremented should throw an InvalidStateError"
+ );
+ }));
+ });
+ const frameURL = new URL("resources/bailout-order-custom-element-with-domain-frame.sub.html", document.URL);
+ frameURL.port = "{{ports[http][1]}}";
+ iframe.src = frameURL.href;
+}, "document.open should throw an InvalidStateError when the throw-on-dynamic-markup-insertion counter is incremented even if the document is cross-origin");
+
+async_test(t => {
+ const iframe = document.body.appendChild(document.createElement("iframe"));
+ t.add_cleanup(() => { iframe.remove(); });
+ self.testSynchronousScript = t.step_func(() => {
+ // Here, the entry settings object is still the iframe's, as the function
+ // is synchronously called from a <script> element in the iframe's
+ // document.
+ //
+ // "Clean up after running script" is executed when the </script> tag is
+ // seen by the HTML parser.
+ setEntryToTopLevel(t.step_func_done(() => {
+ assert_throws_dom(
+ "SecurityError",
+ iframe.contentWindow.DOMException,
+ () => {
+ iframe.contentDocument.open();
+ },
+ "opening a same origin-domain (but not same origin) document should throw a SecurityError"
+ );
+ }));
+ });
+ const frameURL = new URL("resources/bailout-order-synchronous-script-with-domain-frame.sub.html", document.URL);
+ frameURL.port = "{{ports[http][1]}}";
+ iframe.src = frameURL.href;
+}, "document.open should throw a SecurityError with cross-origin document even when there is an active parser executing script");
+
+for (const ev of ["beforeunload", "pagehide", "unload"]) {
+ async_test(t => {
+ const iframe = document.body.appendChild(document.createElement("iframe"));
+ t.add_cleanup(() => { iframe.remove(); });
+ iframe.addEventListener("load", t.step_func(() => {
+ iframe.contentWindow.addEventListener(ev, t.step_func(() => {
+ // Here, the entry settings object should be the top-level page's, as
+ // the callback context of this event listener is the incumbent
+ // settings object, which is the this page. However, due to a Chrome
+ // bug (https://crbug.com/606900), the entry settings object may be
+ // mis-set to the iframe's.
+ //
+ // "Clean up after running script" is called in the task that
+ // navigates.
+ setEntryToTopLevel(t.step_func_done(() => {
+ assert_throws_dom(
+ "SecurityError",
+ iframe.contentWindow.DOMException,
+ () => {
+ iframe.contentDocument.open();
+ },
+ "opening a same origin-domain (but not same origin) document should throw a SecurityError"
+ );
+ }));
+ }));
+ iframe.src = "about:blank";
+ }), { once: true });
+ iframe.src = "http://{{host}}:{{ports[http][1]}}/common/domain-setter.sub.html";
+ }, `document.open should throw a SecurityError with cross-origin document even when the ignore-opens-during-unload counter is greater than 0 (during ${ev} event)`);
+}