summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/focus
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /testing/web-platform/tests/focus
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/focus')
-rw-r--r--testing/web-platform/tests/focus/activeelement-after-calling-window-focus.sub.html93
-rw-r--r--testing/web-platform/tests/focus/activeelement-after-focusing-different-site-iframe-contentwindow.html36
-rw-r--r--testing/web-platform/tests/focus/activeelement-after-focusing-different-site-iframe-then-immediately-focusing-back.html54
-rw-r--r--testing/web-platform/tests/focus/activeelement-after-focusing-different-site-iframe.html27
-rw-r--r--testing/web-platform/tests/focus/activeelement-after-focusing-same-site-iframe-contentwindow.html27
-rw-r--r--testing/web-platform/tests/focus/activeelement-after-focusing-same-site-iframe.html27
-rw-r--r--testing/web-platform/tests/focus/activeelement-after-immediately-focusing-different-site-iframe-contentwindow.html16
-rw-r--r--testing/web-platform/tests/focus/activeelement-after-immediately-focusing-different-site-iframe.html16
-rw-r--r--testing/web-platform/tests/focus/activeelement-after-immediately-focusing-same-site-iframe-contentwindow.html16
-rw-r--r--testing/web-platform/tests/focus/activeelement-after-immediately-focusing-same-site-iframe.html16
-rw-r--r--testing/web-platform/tests/focus/focus-already-focused-iframe-deep-different-site.html20
-rw-r--r--testing/web-platform/tests/focus/focus-already-focused-iframe-deep-same-site.html20
-rw-r--r--testing/web-platform/tests/focus/focus-already-focused-iframe-different-site.html20
-rw-r--r--testing/web-platform/tests/focus/focus-already-focused-iframe-same-site.html20
-rw-r--r--testing/web-platform/tests/focus/focus-event-after-focusing-iframes.html60
-rw-r--r--testing/web-platform/tests/focus/focus-event-after-iframe-gets-focus.html65
-rw-r--r--testing/web-platform/tests/focus/focus-restoration-in-different-site-iframes-window.html16
-rw-r--r--testing/web-platform/tests/focus/focus-restoration-in-different-site-iframes.html16
-rw-r--r--testing/web-platform/tests/focus/focus-restoration-in-same-site-iframes-window.html16
-rw-r--r--testing/web-platform/tests/focus/hasfocus-different-site.html16
-rw-r--r--testing/web-platform/tests/focus/hasfocus-same-site.html16
-rw-r--r--testing/web-platform/tests/focus/iframe-activeelement-after-focusing-out-iframes.html50
-rw-r--r--testing/web-platform/tests/focus/iframe-contentwindow-focus-with-different-site-intermediate-frame.html17
-rw-r--r--testing/web-platform/tests/focus/iframe-contentwindow-focus-with-same-as-top-intermediate-frame.html17
-rw-r--r--testing/web-platform/tests/focus/iframe-focus-with-different-site-intermediate-frame.html17
-rw-r--r--testing/web-platform/tests/focus/iframe-focus-with-same-as-top-intermediate-frame.html17
-rw-r--r--testing/web-platform/tests/focus/iframe-focuses-parent-different-site.html20
-rw-r--r--testing/web-platform/tests/focus/iframe-focuses-parent-same-site.html20
-rw-r--r--testing/web-platform/tests/focus/scroll-matches-focus.html47
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-calling-window-focus-inner.html38
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-calling-window-focus-middle.sub.html30
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-calling-window-focus-outer-different.sub.html35
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-calling-window-focus-outer-same.sub.html29
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-inner-contentwindow.html18
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-inner.html18
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-outer-contentwindow.sub.html29
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-outer.sub.html29
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-then-immediately-focusing-back-outer.sub.html39
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-focusing-same-site-iframe-inner-contentwindow.html18
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-focusing-same-site-iframe-inner.html18
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-focusing-same-site-iframe-outer-contentwindow.html29
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-focusing-same-site-iframe-outer.html29
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-different-site-iframe-inner-contentwindow.html20
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-different-site-iframe-inner.html18
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-different-site-iframe-outer-contentwindow.sub.html29
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-different-site-iframe-outer.sub.html29
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-same-site-iframe-inner-contentwindow.html20
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-same-site-iframe-inner.html18
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-same-site-iframe-outer-contentwindow.html29
-rw-r--r--testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-same-site-iframe-outer.html29
-rw-r--r--testing/web-platform/tests/focus/support/focus-already-focused-iframe-deep-different-site-outer.sub.html21
-rw-r--r--testing/web-platform/tests/focus/support/focus-already-focused-iframe-deep-same-site-outer.html21
-rw-r--r--testing/web-platform/tests/focus/support/focus-already-focused-iframe-different-site-outer.sub.html21
-rw-r--r--testing/web-platform/tests/focus/support/focus-already-focused-iframe-inner.html18
-rw-r--r--testing/web-platform/tests/focus/support/focus-already-focused-iframe-middle.html15
-rw-r--r--testing/web-platform/tests/focus/support/focus-already-focused-iframe-same-site-outer.html21
-rw-r--r--testing/web-platform/tests/focus/support/focus-event-after-different-site-iframe-gets-focus-outer.sub.html30
-rw-r--r--testing/web-platform/tests/focus/support/focus-event-after-focusing-different-site-iframes-outer.sub.html32
-rw-r--r--testing/web-platform/tests/focus/support/focus-event-after-focusing-iframes-inner.html27
-rw-r--r--testing/web-platform/tests/focus/support/focus-event-after-focusing-same-site-iframes-outer.html32
-rw-r--r--testing/web-platform/tests/focus/support/focus-event-after-iframe-gets-focus-inner.html31
-rw-r--r--testing/web-platform/tests/focus/support/focus-event-after-innermost-different-site-iframe-gets-focus-middle.sub.html27
-rw-r--r--testing/web-platform/tests/focus/support/focus-event-after-innermost-different-site-iframe-gets-focus-outer.sub.html30
-rw-r--r--testing/web-platform/tests/focus/support/focus-event-after-same-site-iframe-gets-focus-outer.html30
-rw-r--r--testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-inner-window.html31
-rw-r--r--testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-inner.html39
-rw-r--r--testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-other.html7
-rw-r--r--testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-outer-window.sub.html39
-rw-r--r--testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-outer.sub.html39
-rw-r--r--testing/web-platform/tests/focus/support/focus-restoration-in-same-site-iframes-inner-window.html31
-rw-r--r--testing/web-platform/tests/focus/support/focus-restoration-in-same-site-iframes-outer-window.html39
-rw-r--r--testing/web-platform/tests/focus/support/hasfocus-different-site-outer.sub.html50
-rw-r--r--testing/web-platform/tests/focus/support/hasfocus-inner.html41
-rw-r--r--testing/web-platform/tests/focus/support/hasfocus-other.html13
-rw-r--r--testing/web-platform/tests/focus/support/hasfocus-same-site-outer.html50
-rw-r--r--testing/web-platform/tests/focus/support/iframe-activeelement-after-focusing-out-different-site-iframes-outer.sub.html34
-rw-r--r--testing/web-platform/tests/focus/support/iframe-activeelement-after-focusing-out-iframes-inner.html38
-rw-r--r--testing/web-platform/tests/focus/support/iframe-activeelement-after-focusing-out-same-site-iframes-outer.html34
-rw-r--r--testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-different-site-intermediate-frame-inner.html13
-rw-r--r--testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-different-site-intermediate-frame-middle.sub.html37
-rw-r--r--testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-different-site-intermediate-frame-outer.sub.html22
-rw-r--r--testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-same-as-top-intermediate-frame-inner.html13
-rw-r--r--testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-same-as-top-intermediate-frame-middle.sub.html37
-rw-r--r--testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-same-as-top-intermediate-frame-outer.html22
-rw-r--r--testing/web-platform/tests/focus/support/iframe-focus-with-different-site-intermediate-frame-inner.html13
-rw-r--r--testing/web-platform/tests/focus/support/iframe-focus-with-different-site-intermediate-frame-middle.sub.html37
-rw-r--r--testing/web-platform/tests/focus/support/iframe-focus-with-different-site-intermediate-frame-outer.sub.html22
-rw-r--r--testing/web-platform/tests/focus/support/iframe-focus-with-same-as-top-intermediate-frame-inner.html13
-rw-r--r--testing/web-platform/tests/focus/support/iframe-focus-with-same-as-top-intermediate-frame-middle.sub.html37
-rw-r--r--testing/web-platform/tests/focus/support/iframe-focus-with-same-as-top-intermediate-frame-outer.html22
-rw-r--r--testing/web-platform/tests/focus/support/iframe-focuses-parent-different-site-inner.html17
-rw-r--r--testing/web-platform/tests/focus/support/iframe-focuses-parent-different-site-other.html14
-rw-r--r--testing/web-platform/tests/focus/support/iframe-focuses-parent-different-site-outer.sub.html39
-rw-r--r--testing/web-platform/tests/focus/support/iframe-focuses-parent-same-site-inner.html17
-rw-r--r--testing/web-platform/tests/focus/support/iframe-focuses-parent-same-site-other.html14
-rw-r--r--testing/web-platform/tests/focus/support/iframe-focuses-parent-same-site-outer.html39
96 files changed, 2638 insertions, 0 deletions
diff --git a/testing/web-platform/tests/focus/activeelement-after-calling-window-focus.sub.html b/testing/web-platform/tests/focus/activeelement-after-calling-window-focus.sub.html
new file mode 100644
index 0000000000..34579fb2a6
--- /dev/null
+++ b/testing/web-platform/tests/focus/activeelement-after-calling-window-focus.sub.html
@@ -0,0 +1,93 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>activeElement after calling window.focus()</title>
+<meta name="timeout" content="long">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+function waitForEvent(target, event, checkFn) {
+ return new Promise(resolve => {
+ target.addEventListener(event, e => {
+ if (checkFn && !checkFn(e)) {
+ return;
+ }
+ resolve();
+ }, { once: true });
+ });
+}
+
+function start(w) {
+ w.postMessage("start", "*");
+}
+
+function focusInnerInput(w) {
+ w.postMessage("focusinnerinput", "*");
+}
+
+function focusInnerFrame(w) {
+ w.postMessage("focusinner", "*");
+}
+
+function focusMiddleFrame(w) {
+ w.postMessage("focusmiddle", "*");
+}
+
+function focusOuterFrame(w) {
+ w.postMessage("focusouter", "*");
+}
+
+// This will send message to outer frame and also inner frame to ask them
+// send the log they collect back, the logs of outer and inner will be
+// concatenated.
+async function getLog(w) {
+ let log = "";
+ step_timeout(function() {
+ w.postMessage("getlog", "*");
+ }, 0);
+ await waitForEvent(window, "message", (e) => {
+ log = e.data;
+ return true;
+ });
+ return log;
+}
+
+async function runTest(t, url) {
+ let w = window.open(url);
+ t.add_cleanup(() => { w.close(); });
+ await waitForEvent(window, "message", e => e.data === "ready");
+ start(w);
+ // Calling input.focus() on inner iframe should move its document.activeElement to INPUT.
+ focusInnerInput(w);
+ assert_equals(await getLog(w), 'outerlog:windowblur,middlelog:innerlog:windowfocus,INPUT,');
+ // Calling window.focus() on inner iframe should NOT reset its document.activeElement to BODY
+ // because it's focused element is not an iframe.
+ focusInnerFrame(w);
+ assert_equals(await getLog(w), 'outerlog:windowblur,middlelog:innerlog:windowfocus,INPUT,INPUT,');
+ // Calling window.focus() on middle iframe should reset its document.activeElement to BODY.
+ focusMiddleFrame(w);
+ assert_equals(await getLog(w), 'outerlog:windowblur,middlelog:windowfocus,BODY,innerlog:windowfocus,INPUT,INPUT,windowblur,');
+ // Calling window.focus() on top-level frame should reset its document.activeElement to BODY.
+ focusOuterFrame(w);
+ assert_equals(await getLog(w), 'outerlog:windowblur,windowfocus,BODY,middlelog:windowfocus,BODY,windowblur,innerlog:windowfocus,INPUT,INPUT,windowblur,');
+}
+
+promise_test(async t => {
+ await runTest(t, "https://{{hosts[][www]}}:{{ports[https][0]}}/focus/support/activeelement-after-calling-window-focus-outer-same.sub.html");
+}, "Tests for all frames are in same origin");
+
+promise_test(async t => {
+ await runTest(t, "https://{{hosts[alt][www]}}:{{ports[https][0]}}/focus/support/activeelement-after-calling-window-focus-outer-same.sub.html");
+}, "Tests for middle frame and inner frame are in same origin and outer frame is in different origin");
+
+promise_test(async t => {
+ await runTest(t, "https://{{hosts[alt][www]}}:{{ports[https][0]}}/focus/support/activeelement-after-calling-window-focus-outer-different.sub.html");
+}, "Tests for outer frame and middle frame are in same origin and inner frame is in different origin");
+
+promise_test(async t => {
+ await runTest(t, "https://{{hosts[][www]}}:{{ports[https][0]}}/focus/support/activeelement-after-calling-window-focus-outer-different.sub.html");
+}, "Tests for outer frame and inner frame are in same origin and middle frame is in different origin");
+
+promise_test(async t => {
+ await runTest(t, "support/activeelement-after-calling-window-focus-outer-different.sub.html");
+}, "Tests for all frames are in different origin");
+</script>
diff --git a/testing/web-platform/tests/focus/activeelement-after-focusing-different-site-iframe-contentwindow.html b/testing/web-platform/tests/focus/activeelement-after-focusing-different-site-iframe-contentwindow.html
new file mode 100644
index 0000000000..b16280acbd
--- /dev/null
+++ b/testing/web-platform/tests/focus/activeelement-after-focusing-different-site-iframe-contentwindow.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>activeElement when focusing different-site iframe's contentWindow</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+window.onmessage = function(e) {
+ var actual = e.data;
+ test(function() {
+ // Handle trailing events separately to get make it easier to see
+ // if they are the only deviation from the expection.
+ var endedWith = false;
+ if (actual.endsWith(",willspineventloop,")) {
+ endedWith = true;
+ actual += "innerbodyfocus,";
+ }
+ assert_false(endedWith, "Should have gotten innerbodyfocus after willspineventloop");
+ }, "Check trailing events");
+ test(function() {
+ // This is a Fission oddity
+ var endedWith = false;
+ if (actual.endsWith(",willspineventloop,innerbodyfocus,")) {
+ endedWith = true;
+ actual += "innerbodyblur,innerbodyfocus,";
+ }
+ assert_true(endedWith, "Should have gotten innerbodyfocus after willspineventloop");
+ }, "Check more trailing events");
+ test(function() {
+ assert_equals(actual, "outeronload,activeElement:BODY,willfocusiframe,didfocusiframe,activeElement:IFRAME,willbluriframe,didbluriframe,activeElement:IFRAME,willspineventloop,innerbodyfocus,innerbodyblur,innerbodyfocus,", 'Check log');
+ }, "Check result");
+ w.close();
+ done();
+};
+var w = window.open("support/activeelement-after-focusing-different-site-iframe-outer-contentwindow.sub.html");
+</script>
diff --git a/testing/web-platform/tests/focus/activeelement-after-focusing-different-site-iframe-then-immediately-focusing-back.html b/testing/web-platform/tests/focus/activeelement-after-focusing-different-site-iframe-then-immediately-focusing-back.html
new file mode 100644
index 0000000000..b2385705bc
--- /dev/null
+++ b/testing/web-platform/tests/focus/activeelement-after-focusing-different-site-iframe-then-immediately-focusing-back.html
@@ -0,0 +1,54 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>activeElement when focusing different-site iframe then immediately focusing back</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+function waitForEvent(target, event, checkFn) {
+ return new Promise(resolve => {
+ target.addEventListener(event, e => {
+ if (checkFn && !checkFn(e)) {
+ return;
+ }
+ resolve();
+ }, { once: true });
+ });
+}
+
+// This will send message to outer frame and also inner frame to ask them
+// send the log they collect back, the logs of outer and inner will be
+// concatenated.
+async function getLog(w) {
+ let log = "";
+ step_timeout(function() {
+ w.postMessage("getlog", "*");
+ }, 0);
+ await waitForEvent(window, "message", (e) => {
+ log = e.data;
+ return true;
+ });
+ return log;
+}
+
+// This will send message to outer frame to ask it's activeElement.
+async function getActiveElement(w) {
+ let activeElement = "";
+ step_timeout(function() {
+ w.postMessage("getActiveElement", "*");
+ }, 0);
+ await waitForEvent(window, "message", (e) => {
+ activeElement = e.data;
+ return true;
+ });
+ return activeElement;
+}
+
+promise_test(async t => {
+ let w = window.open("support/activeelement-after-focusing-different-site-iframe-then-immediately-focusing-back-outer.sub.html");
+ t.add_cleanup(() => { w.close(); });
+ await waitForEvent(window, "message", e => e.data === "ready");
+ w.postMessage("focus", "*");
+ assert_equals(await getLog(w), 'outerlog:willfocusiframe,didfocusiframe,willfocusinput,inputfocus,didfocusinput,innerlog:windowfocus,windowblur,');
+ assert_equals(await getActiveElement(w), 'INPUT');
+}, "Check focus event and active element after focusing different site iframe then immediately focusing back");
+</script>
diff --git a/testing/web-platform/tests/focus/activeelement-after-focusing-different-site-iframe.html b/testing/web-platform/tests/focus/activeelement-after-focusing-different-site-iframe.html
new file mode 100644
index 0000000000..b974252555
--- /dev/null
+++ b/testing/web-platform/tests/focus/activeelement-after-focusing-different-site-iframe.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>activeElement when focusing different-site iframe</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+window.onmessage = function(e) {
+ var actual = e.data;
+ test(function() {
+ // Handle trailing events separately to get make it easier to see
+ // if they are the only deviation from the expection.
+ var endedWith = false;
+ if (actual.endsWith(",willspineventloop,")) {
+ endedWith = true;
+ actual += "innerbodyfocus,innerbodyblur,";
+ }
+ assert_false(endedWith, "Should have gotten innerbodyfocus,innerbodyblur after willspineventloop");
+ }, "Check trailing events");
+ test(function() {
+ assert_equals(actual, "outeronload,activeElement:BODY,willfocusiframe,didfocusiframe,activeElement:IFRAME,willbluriframe,didbluriframe,activeElement:BODY,willspineventloop,innerbodyfocus,innerbodyblur,", 'Check log');
+ }, "Check result");
+ w.close();
+ done();
+};
+var w = window.open("support/activeelement-after-focusing-different-site-iframe-outer.sub.html");
+</script>
diff --git a/testing/web-platform/tests/focus/activeelement-after-focusing-same-site-iframe-contentwindow.html b/testing/web-platform/tests/focus/activeelement-after-focusing-same-site-iframe-contentwindow.html
new file mode 100644
index 0000000000..b4a14e721f
--- /dev/null
+++ b/testing/web-platform/tests/focus/activeelement-after-focusing-same-site-iframe-contentwindow.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>activeElement when focusing same-site iframe's contentWindow</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+window.onmessage = function(e) {
+ var actual = e.data;
+ test(function() {
+ // Handle trailing events separately to get make it easier to see
+ // if they are the only deviation from the expection.
+ var endedWith = false;
+ if (actual.endsWith(",willspineventloop,")) {
+ endedWith = true;
+ actual += "innerbodyfocus,";
+ }
+ assert_false(endedWith, "Should have gotten innerbodyfocus after willspineventloop");
+ }, "Check trailing events");
+ test(function() {
+ assert_equals(actual, "outeronload,activeElement:BODY,willfocusiframe,didfocusiframe,activeElement:IFRAME,willbluriframe,didbluriframe,activeElement:IFRAME,willspineventloop,innerbodyfocus,", 'Check log');
+ }, "Check result");
+ w.close();
+ done();
+};
+var w = window.open("support/activeelement-after-focusing-same-site-iframe-outer-contentwindow.html");
+</script>
diff --git a/testing/web-platform/tests/focus/activeelement-after-focusing-same-site-iframe.html b/testing/web-platform/tests/focus/activeelement-after-focusing-same-site-iframe.html
new file mode 100644
index 0000000000..55918ebf07
--- /dev/null
+++ b/testing/web-platform/tests/focus/activeelement-after-focusing-same-site-iframe.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>activeElement when focusing same-site iframe</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+window.onmessage = function(e) {
+ var actual = e.data;
+ test(function() {
+ // Handle trailing events separately to get make it easier to see
+ // if they are the only deviation from the expection.
+ var endedWith = false;
+ if (actual.endsWith(",willspineventloop,")) {
+ endedWith = true;
+ actual += "innerbodyfocus,innerbodyblur,";
+ }
+ assert_false(endedWith, "Should have gotten innerbodyfocus,innerbodyblur after willspineventloop");
+ }, "Check trailing events");
+ test(function() {
+ assert_equals(actual, "outeronload,activeElement:BODY,willfocusiframe,didfocusiframe,activeElement:IFRAME,willbluriframe,didbluriframe,activeElement:BODY,willspineventloop,innerbodyfocus,innerbodyblur,", 'Check log');
+ }, "Check result");
+ w.close();
+ done();
+};
+var w = window.open("support/activeelement-after-focusing-same-site-iframe-outer.html");
+</script>
diff --git a/testing/web-platform/tests/focus/activeelement-after-immediately-focusing-different-site-iframe-contentwindow.html b/testing/web-platform/tests/focus/activeelement-after-immediately-focusing-different-site-iframe-contentwindow.html
new file mode 100644
index 0000000000..8c3a9d1195
--- /dev/null
+++ b/testing/web-platform/tests/focus/activeelement-after-immediately-focusing-different-site-iframe-contentwindow.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>activeElement when immediately focusing different-site iframe's contentWindow</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+window.onmessage = function(e) {
+ test(function() {
+ assert_equals(e.data, "outerparser,activeElement:BODY,willfocusiframe,didfocusiframe,activeElement:IFRAME,willbluriframe,didbluriframe,activeElement:IFRAME,willspineventloop,", 'Check log');
+ }, "Check result");
+ w.close();
+ done();
+};
+var w = window.open("support/activeelement-after-immediately-focusing-different-site-iframe-outer-contentwindow.sub.html");
+</script>
diff --git a/testing/web-platform/tests/focus/activeelement-after-immediately-focusing-different-site-iframe.html b/testing/web-platform/tests/focus/activeelement-after-immediately-focusing-different-site-iframe.html
new file mode 100644
index 0000000000..67bf733bc1
--- /dev/null
+++ b/testing/web-platform/tests/focus/activeelement-after-immediately-focusing-different-site-iframe.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>activeElement when immediately focusing different-site iframe</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+window.onmessage = function(e) {
+ test(function() {
+ assert_equals(e.data, "outerparser,activeElement:BODY,willfocusiframe,didfocusiframe,activeElement:IFRAME,willbluriframe,didbluriframe,activeElement:BODY,willspineventloop,", 'Check log');
+ }, "Check result");
+ w.close();
+ done();
+};
+var w = window.open("support/activeelement-after-immediately-focusing-different-site-iframe-outer.sub.html");
+</script>
diff --git a/testing/web-platform/tests/focus/activeelement-after-immediately-focusing-same-site-iframe-contentwindow.html b/testing/web-platform/tests/focus/activeelement-after-immediately-focusing-same-site-iframe-contentwindow.html
new file mode 100644
index 0000000000..2f6a8ac853
--- /dev/null
+++ b/testing/web-platform/tests/focus/activeelement-after-immediately-focusing-same-site-iframe-contentwindow.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>activeElement when immediately focusing same-site iframe's contentWindow</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+window.onmessage = function(e) {
+ test(function() {
+ assert_equals(e.data, "outerparse,activeElement:BODY,willfocusiframe,didfocusiframe,activeElement:IFRAME,willbluriframe,didbluriframe,activeElement:IFRAME,willspineventloop,", 'Check log');
+ }, "Check result");
+ w.close();
+ done();
+};
+var w = window.open("support/activeelement-after-immediately-focusing-same-site-iframe-outer-contentwindow.html");
+</script>
diff --git a/testing/web-platform/tests/focus/activeelement-after-immediately-focusing-same-site-iframe.html b/testing/web-platform/tests/focus/activeelement-after-immediately-focusing-same-site-iframe.html
new file mode 100644
index 0000000000..a035af072d
--- /dev/null
+++ b/testing/web-platform/tests/focus/activeelement-after-immediately-focusing-same-site-iframe.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>activeElement when immediately focusing same-site iframe</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+window.onmessage = function(e) {
+ test(function() {
+ assert_equals(e.data, "outerparse,activeElement:BODY,willfocusiframe,didfocusiframe,activeElement:IFRAME,willbluriframe,didbluriframe,activeElement:BODY,willspineventloop,", 'Check log');
+ }, "Check result");
+ w.close();
+ done();
+};
+var w = window.open("support/activeelement-after-immediately-focusing-same-site-iframe-outer.html");
+</script>
diff --git a/testing/web-platform/tests/focus/focus-already-focused-iframe-deep-different-site.html b/testing/web-platform/tests/focus/focus-already-focused-iframe-deep-different-site.html
new file mode 100644
index 0000000000..79226c5cd8
--- /dev/null
+++ b/testing/web-platform/tests/focus/focus-already-focused-iframe-deep-different-site.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Focus already focused iframe</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+var w = null;
+window.onload = function() {
+ window.onmessage = function(e) {
+ test(function() {
+ assert_equals(e.data, "PASS", 'Check result');
+ }, "Check result");
+ w.close();
+ w = null;
+ done();
+ };
+ w = window.open("support/focus-already-focused-iframe-deep-different-site-outer.sub.html");
+}
+</script>
diff --git a/testing/web-platform/tests/focus/focus-already-focused-iframe-deep-same-site.html b/testing/web-platform/tests/focus/focus-already-focused-iframe-deep-same-site.html
new file mode 100644
index 0000000000..fc08139205
--- /dev/null
+++ b/testing/web-platform/tests/focus/focus-already-focused-iframe-deep-same-site.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Focus already focused iframe</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+var w = null;
+window.onload = function() {
+ window.onmessage = function(e) {
+ test(function() {
+ assert_equals(e.data, "PASS", 'Check result');
+ }, "Check result");
+ w.close();
+ w = null;
+ done();
+ };
+ w = window.open("support/focus-already-focused-iframe-deep-same-site-outer.html");
+}
+</script>
diff --git a/testing/web-platform/tests/focus/focus-already-focused-iframe-different-site.html b/testing/web-platform/tests/focus/focus-already-focused-iframe-different-site.html
new file mode 100644
index 0000000000..9d7088cc39
--- /dev/null
+++ b/testing/web-platform/tests/focus/focus-already-focused-iframe-different-site.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Focus already focused iframe</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+var w = null;
+window.onload = function() {
+ window.onmessage = function(e) {
+ test(function() {
+ assert_equals(e.data, "PASS", 'Check result');
+ }, "Check result");
+ w.close();
+ w = null;
+ done();
+ };
+ w = window.open("support/focus-already-focused-iframe-different-site-outer.sub.html");
+}
+</script>
diff --git a/testing/web-platform/tests/focus/focus-already-focused-iframe-same-site.html b/testing/web-platform/tests/focus/focus-already-focused-iframe-same-site.html
new file mode 100644
index 0000000000..57ef5c7391
--- /dev/null
+++ b/testing/web-platform/tests/focus/focus-already-focused-iframe-same-site.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Focus already focused iframe</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+var w = null;
+window.onload = function() {
+ window.onmessage = function(e) {
+ test(function() {
+ assert_equals(e.data, "PASS", 'Check result');
+ }, "Check result");
+ w.close();
+ w = null;
+ done();
+ };
+ w = window.open("support/focus-already-focused-iframe-same-site-outer.html");
+}
+</script>
diff --git a/testing/web-platform/tests/focus/focus-event-after-focusing-iframes.html b/testing/web-platform/tests/focus/focus-event-after-focusing-iframes.html
new file mode 100644
index 0000000000..f2aa2233e5
--- /dev/null
+++ b/testing/web-platform/tests/focus/focus-event-after-focusing-iframes.html
@@ -0,0 +1,60 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test focus event after focusing iframe</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+function waitForEvent(target, event, checkFn) {
+ return new Promise(resolve => {
+ target.addEventListener(event, e => {
+ if (checkFn && !checkFn(e)) {
+ return;
+ }
+ resolve();
+ }, { once: true });
+ });
+}
+
+function start(w) {
+ w.postMessage("start", "*");
+}
+
+function focusIframe(w) {
+ w.postMessage("focus", "*");
+}
+
+// This will send message to outer frame and also inner frame to ask them
+// send the log they collect back, the logs of outer and inner will be
+// concatenated.
+async function getLog(w) {
+ let log = "";
+ step_timeout(function() {
+ w.postMessage("getlog", "*");
+ }, 0);
+ await waitForEvent(window, "message", (e) => {
+ log = e.data;
+ return true;
+ });
+ return log;
+}
+
+async function runTest(t, url) {
+ let w = window.open(url);
+ t.add_cleanup(() => { w.close(); });
+ await waitForEvent(window, "message", e => e.data === "ready");
+ start(w);
+ focusIframe(w);
+ assert_equals(await getLog(w), 'outerlog:willfocusiframe,windowblur,didfocusiframe,innerlog:windowfocus,');
+ focusIframe(w);
+ assert_equals(await getLog(w), 'outerlog:willfocusiframe,windowblur,didfocusiframe,willfocusiframe,didfocusiframe,innerlog:windowfocus,');
+}
+
+promise_test(async t => {
+ await runTest(t, "support/focus-event-after-focusing-different-site-iframes-outer.sub.html");
+}, "Check focus event after focusing different site iframe");
+
+promise_test(async t => {
+ await runTest(t, "support/focus-event-after-focusing-same-site-iframes-outer.html");
+}, "Check focus event after focusing same site iframe");
+
+</script>
diff --git a/testing/web-platform/tests/focus/focus-event-after-iframe-gets-focus.html b/testing/web-platform/tests/focus/focus-event-after-iframe-gets-focus.html
new file mode 100644
index 0000000000..bb2e895420
--- /dev/null
+++ b/testing/web-platform/tests/focus/focus-event-after-iframe-gets-focus.html
@@ -0,0 +1,65 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test focus event after iframe gets focus</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+function waitForEvent(target, event, checkFn) {
+ return new Promise(resolve => {
+ target.addEventListener(event, e => {
+ if (checkFn && !checkFn(e)) {
+ return;
+ }
+ resolve();
+ }, { once: true });
+ });
+}
+
+function start(w) {
+ w.postMessage("start", "*");
+}
+
+function focusIframe(w) {
+ w.postMessage("focus", "*");
+}
+
+// This will send message to outer frame and also inner frame to ask them
+// send the log they collect back, the logs of outer and inner will be
+// concatenated.
+async function getLog(w) {
+ let log = "";
+ step_timeout(function() {
+ w.postMessage("getlog", "*");
+ }, 0);
+ await waitForEvent(window, "message", (e) => {
+ log = e.data;
+ return true;
+ });
+ return log;
+}
+
+async function runTest(t, url, expectResult) {
+ let w = window.open(url);
+ t.add_cleanup(() => { w.close(); });
+ await waitForEvent(window, "message", e => e.data === "ready");
+ start(w);
+ focusIframe(w);
+ assert_equals(await getLog(w), expectResult);
+}
+
+promise_test(async t => {
+ await runTest(t, "support/focus-event-after-same-site-iframe-gets-focus-outer.html",
+ "outerlog:windowblur,innerlog:willfocuswindow,windowfocus,didfocuswindow,");
+}, "Check focus event after same site iframe gets focus");
+
+promise_test(async t => {
+ await runTest(t, "support/focus-event-after-different-site-iframe-gets-focus-outer.sub.html",
+ "outerlog:windowblur,innerlog:willfocuswindow,windowfocus,didfocuswindow,");
+}, "Check focus event after different site iframe gets focus");
+
+promise_test(async t => {
+ await runTest(t, "support/focus-event-after-innermost-different-site-iframe-gets-focus-outer.sub.html",
+ "outerlog:windowblur,middlelog:innerlog:willfocuswindow,windowfocus,didfocuswindow,");
+}, "Check focus event after innermost different site iframe gets focus");
+
+</script>
diff --git a/testing/web-platform/tests/focus/focus-restoration-in-different-site-iframes-window.html b/testing/web-platform/tests/focus/focus-restoration-in-different-site-iframes-window.html
new file mode 100644
index 0000000000..61e604b3c7
--- /dev/null
+++ b/testing/web-platform/tests/focus/focus-restoration-in-different-site-iframes-window.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test focus restoration</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+window.onmessage = function(e) {
+ test(function() {
+ assert_equals(e.data, "outerlog:log:willfocuswindow,windowfocus,didfocuswindow,windowblur,windowfocus,", 'Check log');
+ }, "Check result");
+ w.close();
+ done();
+};
+var w = window.open("support/focus-restoration-in-different-site-iframes-outer-window.sub.html");
+</script>
diff --git a/testing/web-platform/tests/focus/focus-restoration-in-different-site-iframes.html b/testing/web-platform/tests/focus/focus-restoration-in-different-site-iframes.html
new file mode 100644
index 0000000000..3861347fe6
--- /dev/null
+++ b/testing/web-platform/tests/focus/focus-restoration-in-different-site-iframes.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test focus restoration</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+window.onmessage = function(e) {
+ test(function() {
+ assert_equals(e.data, "outerlog:log:willfocusinput,bodyfocus,inputfocus,didfocusinput,inputblur,bodyblur,bodyfocus,inputfocus,", 'Check log');
+ }, "Check result");
+ w.close();
+ done();
+};
+var w = window.open("support/focus-restoration-in-different-site-iframes-outer.sub.html");
+</script>
diff --git a/testing/web-platform/tests/focus/focus-restoration-in-same-site-iframes-window.html b/testing/web-platform/tests/focus/focus-restoration-in-same-site-iframes-window.html
new file mode 100644
index 0000000000..46be5eb600
--- /dev/null
+++ b/testing/web-platform/tests/focus/focus-restoration-in-same-site-iframes-window.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test focus restoration</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+window.onmessage = function(e) {
+ test(function() {
+ assert_equals(e.data, "outerlog:log:willfocuswindow,windowfocus,didfocuswindow,windowblur,windowfocus,", 'Check log');
+ }, "Check result");
+ w.close();
+ done();
+};
+var w = window.open("support/focus-restoration-in-same-site-iframes-outer-window.html");
+</script>
diff --git a/testing/web-platform/tests/focus/hasfocus-different-site.html b/testing/web-platform/tests/focus/hasfocus-different-site.html
new file mode 100644
index 0000000000..4495778c81
--- /dev/null
+++ b/testing/web-platform/tests/focus/hasfocus-different-site.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>document.hasFocus() with focus in an iframe</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+window.onmessage = function(e) {
+ test(function() {
+ assert_equals(e.data, "PASS", 'Check result');
+ }, "Check result");
+ w.close();
+ done();
+};
+var w = window.open("support/hasfocus-different-site-outer.sub.html");
+</script>
diff --git a/testing/web-platform/tests/focus/hasfocus-same-site.html b/testing/web-platform/tests/focus/hasfocus-same-site.html
new file mode 100644
index 0000000000..71a2e0f4ed
--- /dev/null
+++ b/testing/web-platform/tests/focus/hasfocus-same-site.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>document.hasFocus() with focus in an iframe</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+window.onmessage = function(e) {
+ test(function() {
+ assert_equals(e.data, "PASS", 'Check result');
+ }, "Check result");
+ w.close();
+ done();
+};
+var w = window.open("support/hasfocus-same-site-outer.html");
+</script>
diff --git a/testing/web-platform/tests/focus/iframe-activeelement-after-focusing-out-iframes.html b/testing/web-platform/tests/focus/iframe-activeelement-after-focusing-out-iframes.html
new file mode 100644
index 0000000000..832b2675e2
--- /dev/null
+++ b/testing/web-platform/tests/focus/iframe-activeelement-after-focusing-out-iframes.html
@@ -0,0 +1,50 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>iframe activeElement after focusing out iframe</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+function waitForEvent(target, event, checkFn) {
+ return new Promise(resolve => {
+ target.addEventListener(event, e => {
+ if (checkFn && !checkFn(e)) {
+ return;
+ }
+ resolve();
+ }, { once: true });
+ });
+}
+
+function focusTopLevel(w) {
+ w.postMessage("focus", "*");
+}
+
+async function getLog(w) {
+ let log = "";
+ step_timeout(function() {
+ w.postMessage("getlog", "*");
+ }, 0);
+ await waitForEvent(window, "message", (e) => {
+ log = e.data;
+ return true;
+ });
+ return log;
+}
+
+async function runTest(t, url) {
+ let w = window.open(url);
+ t.add_cleanup(() => { w.close(); });
+ await waitForEvent(window, "message", e => e.data === "ready");
+ focusTopLevel(w);
+ assert_equals(await getLog(w), 'outerlog:willfocusinput,windowfocus,didfocusinput,innerlog:willfocusinput,windowfocus,didfocusinput,activeElement:INPUT,windowblur,activeElement:BODY,');
+}
+
+promise_test(async t => {
+ await runTest(t, "support/iframe-activeelement-after-focusing-out-different-site-iframes-outer.sub.html");
+}, "Check iframe activeElement after focusing out different site iframe");
+
+promise_test(async t => {
+ await runTest(t, "support/iframe-activeelement-after-focusing-out-same-site-iframes-outer.html");
+}, "Check iframe activeElement after focusing out same site iframe");
+
+</script>
diff --git a/testing/web-platform/tests/focus/iframe-contentwindow-focus-with-different-site-intermediate-frame.html b/testing/web-platform/tests/focus/iframe-contentwindow-focus-with-different-site-intermediate-frame.html
new file mode 100644
index 0000000000..2fdc8e843a
--- /dev/null
+++ b/testing/web-platform/tests/focus/iframe-contentwindow-focus-with-different-site-intermediate-frame.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>iframe.contentWindow.focus() with different-site intermediate frame</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+window.onmessage = function(e) {
+ var actual = e.data;
+ test(function() {
+ assert_equals(actual, "outeronload;outeractivelement:body;starttest;middleactivelement:body;callfocus;middleactivelement:iframe;innerfocus;middletimer;middleactivelement:iframe;outeractivelement:iframe;", 'Check log');
+ }, "Check result");
+ w.close();
+ done();
+};
+var w = window.open("support/iframe-contentwindow-focus-with-different-site-intermediate-frame-outer.sub.html");
+</script>
diff --git a/testing/web-platform/tests/focus/iframe-contentwindow-focus-with-same-as-top-intermediate-frame.html b/testing/web-platform/tests/focus/iframe-contentwindow-focus-with-same-as-top-intermediate-frame.html
new file mode 100644
index 0000000000..cb9239f44d
--- /dev/null
+++ b/testing/web-platform/tests/focus/iframe-contentwindow-focus-with-same-as-top-intermediate-frame.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>iframe.contentWindow.focus() with same-as-top intermediate frame</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+window.onmessage = function(e) {
+ var actual = e.data;
+ test(function() {
+ assert_equals(actual, "outeronload;outeractivelement:body;starttest;middleactivelement:body;callfocus;middleactivelement:iframe;innerfocus;middletimer;middleactivelement:iframe;outeractivelement:iframe;", 'Check log');
+ }, "Check result");
+ w.close();
+ done();
+};
+var w = window.open("support/iframe-contentwindow-focus-with-same-as-top-intermediate-frame-outer.html");
+</script>
diff --git a/testing/web-platform/tests/focus/iframe-focus-with-different-site-intermediate-frame.html b/testing/web-platform/tests/focus/iframe-focus-with-different-site-intermediate-frame.html
new file mode 100644
index 0000000000..fd3aab7057
--- /dev/null
+++ b/testing/web-platform/tests/focus/iframe-focus-with-different-site-intermediate-frame.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>iframe.focus() with different-site intermediate frame</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+window.onmessage = function(e) {
+ var actual = e.data;
+ test(function() {
+ assert_equals(actual, "outeronload;outeractivelement:body;starttest;middleactivelement:body;callfocus;middleactivelement:iframe;innerfocus;middletimer;middleactivelement:iframe;outeractivelement:iframe;", 'Check log');
+ }, "Check result");
+ w.close();
+ done();
+};
+var w = window.open("support/iframe-focus-with-different-site-intermediate-frame-outer.sub.html");
+</script>
diff --git a/testing/web-platform/tests/focus/iframe-focus-with-same-as-top-intermediate-frame.html b/testing/web-platform/tests/focus/iframe-focus-with-same-as-top-intermediate-frame.html
new file mode 100644
index 0000000000..b4763f9e2f
--- /dev/null
+++ b/testing/web-platform/tests/focus/iframe-focus-with-same-as-top-intermediate-frame.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>iframe.focus() with same-as-top intermediate frame</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+window.onmessage = function(e) {
+ var actual = e.data;
+ test(function() {
+ assert_equals(actual, "outeronload;outeractivelement:body;starttest;middleactivelement:body;callfocus;middleactivelement:iframe;innerfocus;middletimer;middleactivelement:iframe;outeractivelement:iframe;", 'Check log');
+ }, "Check result");
+ w.close();
+ done();
+};
+var w = window.open("support/iframe-focus-with-same-as-top-intermediate-frame-outer.html");
+</script>
diff --git a/testing/web-platform/tests/focus/iframe-focuses-parent-different-site.html b/testing/web-platform/tests/focus/iframe-focuses-parent-different-site.html
new file mode 100644
index 0000000000..8a0b5ecca0
--- /dev/null
+++ b/testing/web-platform/tests/focus/iframe-focuses-parent-different-site.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>iframe focuses parent</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+var w = null;
+window.onload = function() {
+ window.onmessage = function(e) {
+ test(function() {
+ assert_equals(e.data, "PASS", 'Check result');
+ }, "Check result");
+ w.close();
+ w = null;
+ done();
+ };
+ w = window.open("support/iframe-focuses-parent-different-site-outer.sub.html");
+}
+</script>
diff --git a/testing/web-platform/tests/focus/iframe-focuses-parent-same-site.html b/testing/web-platform/tests/focus/iframe-focuses-parent-same-site.html
new file mode 100644
index 0000000000..f130410e2a
--- /dev/null
+++ b/testing/web-platform/tests/focus/iframe-focuses-parent-same-site.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>iframe focuses parent</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+setup({explicit_done:true});
+var w = null;
+window.onload = function() {
+ window.onmessage = function(e) {
+ test(function() {
+ assert_equals(e.data, "PASS", 'Check result');
+ }, "Check result");
+ w.close();
+ w = null;
+ done();
+ };
+ w = window.open("support/iframe-focuses-parent-same-site-outer.html");
+}
+</script>
diff --git a/testing/web-platform/tests/focus/scroll-matches-focus.html b/testing/web-platform/tests/focus/scroll-matches-focus.html
new file mode 100644
index 0000000000..46a58fdf97
--- /dev/null
+++ b/testing/web-platform/tests/focus/scroll-matches-focus.html
@@ -0,0 +1,47 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>:focus applies before scrolling into view</title>
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1775451">
+<link href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link href="https://mozilla.com" title="Mozilla">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+body {
+ margin: 0;
+}
+.padding {
+ height: 200vh;
+ background-color: purple;
+}
+#focusable {
+ z-index: 0;
+ position: absolute;
+ top: 0;
+ left: 0;
+}
+#focusable:focus {
+ z-index: 1;
+ left: auto;
+ top: auto;
+}
+</style>
+<div class="padding"></div>
+<div id="focusable" tabindex=0>I am focusable</div>
+<div class="padding"></div>
+<script>
+onload = function() {
+ async_test(function(t) {
+ let focusable = document.getElementById("focusable");
+ assert_equals(getComputedStyle(focusable).zIndex, "0", "focusable style is correct");
+
+ window.addEventListener("scroll", t.step_func_done(function(e) {
+ assert_equals(document.activeElement, focusable, "activeElement should be set");
+ assert_true(focusable.matches(":focus"), ":focus should match by the time we scroll");
+ assert_equals(getComputedStyle(focusable).zIndex, "1", "focusable style is correct");
+ }), { once: true });
+
+ focusable.focus();
+ });
+};
+</script>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-calling-window-focus-inner.html b/testing/web-platform/tests/focus/support/activeelement-after-calling-window-focus-inner.html
new file mode 100644
index 0000000000..1fa14d4b8a
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-calling-window-focus-inner.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Focus test inner document</title>
+</head>
+<body>
+<h1>Inner</h1>
+<input>
+<script>
+let innerlog = "innerlog:";
+
+window.onmessage = function(e) {
+ if (e.data == "focusinnerinput") {
+ document.querySelector("input").focus();
+ innerlog += document.activeElement.tagName + ",";
+ } else if (e.data == "focusinner") {
+ window.focus();
+ innerlog += document.activeElement.tagName + ",";
+ } else if (e.data == "getlog") {
+ parent.postMessage(innerlog, "*");
+ }
+};
+
+window.onfocus = function() {
+ innerlog += "windowfocus,";
+};
+
+window.onblur = function() {
+ innerlog += "windowblur,";
+};
+
+window.onload = function() {
+ parent.postMessage("ready", "*");
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-calling-window-focus-middle.sub.html b/testing/web-platform/tests/focus/support/activeelement-after-calling-window-focus-middle.sub.html
new file mode 100644
index 0000000000..c5a0d60a71
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-calling-window-focus-middle.sub.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Focus test middle document</title>
+<h1>Middle</h1><br>
+<iframe src="https://{{hosts[][www]}}:{{ports[https][0]}}/focus/support/activeelement-after-calling-window-focus-inner.html"></iframe>
+<script>
+let middlelog = "middlelog:";
+
+let iframe = document.querySelector("iframe");
+window.onmessage = function(e) {
+ if (e.data == "ready") {
+ parent.postMessage(e.data, "*");
+ } else if (e.data == "focusinnerinput" || e.data == "focusinner" || e.data == "getlog") {
+ iframe.contentWindow.postMessage(e.data, "*");
+ } else if (e.data == "focusmiddle") {
+ window.focus();
+ middlelog += document.activeElement.tagName + ",";
+ } else {
+ parent.postMessage(middlelog + e.data, "*");
+ }
+};
+
+window.onfocus = function() {
+ middlelog += "windowfocus,";
+};
+
+window.onblur = function() {
+ middlelog += "windowblur,";
+};
+</script>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-calling-window-focus-outer-different.sub.html b/testing/web-platform/tests/focus/support/activeelement-after-calling-window-focus-outer-different.sub.html
new file mode 100644
index 0000000000..2cddcf233d
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-calling-window-focus-outer-different.sub.html
@@ -0,0 +1,35 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Focus test outer document</title>
+<iframe src="https://{{hosts[alt][www]}}:{{ports[https][0]}}/focus/support/activeelement-after-calling-window-focus-middle.sub.html"></iframe>
+<script>
+let outerlog = "outerlog:";
+
+let iframe = document.querySelector("iframe");
+window.onmessage = function(e) {
+ if (e.data == "ready") {
+ opener.postMessage(e.data, "*");
+ } else if (e.data == "start") {
+ window.onfocus = function() {
+ outerlog += "windowfocus,";
+ };
+ } else if (e.data == "focusinnerinput" || e.data == "focusinner" || e.data == "focusmiddle" || e.data == "getlog") {
+ iframe.contentWindow.postMessage(e.data, "*");
+ } else if (e.data == "focusouter") {
+ window.focus();
+ outerlog += document.activeElement.tagName + ",";
+ } else {
+ opener.postMessage(outerlog + e.data, "*");
+ }
+};
+
+window.onload = function() {
+ window.onfocus = function() {
+ outerlog += "windowfocus,";
+ };
+};
+
+window.onblur = function() {
+ outerlog += "windowblur,";
+};
+</script>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-calling-window-focus-outer-same.sub.html b/testing/web-platform/tests/focus/support/activeelement-after-calling-window-focus-outer-same.sub.html
new file mode 100644
index 0000000000..4833e94bc9
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-calling-window-focus-outer-same.sub.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Focus test outer document</title>
+<iframe src="https://{{hosts[][www]}}:{{ports[https][0]}}/focus/support/activeelement-after-calling-window-focus-middle.sub.html"></iframe>
+<script>
+let outerlog = "outerlog:";
+
+let iframe = document.querySelector("iframe");
+window.onmessage = function(e) {
+ if (e.data == "ready") {
+ opener.postMessage(e.data, "*");
+ } else if (e.data == "start") {
+ window.onfocus = function() {
+ outerlog += "windowfocus,";
+ };
+ } else if (e.data == "focusinnerinput" || e.data == "focusinner" || e.data == "focusmiddle" || e.data == "getlog") {
+ iframe.contentWindow.postMessage(e.data, "*");
+ } else if (e.data == "focusouter") {
+ window.focus();
+ outerlog += document.activeElement.tagName + ",";
+ } else {
+ opener.postMessage(outerlog + e.data, "*");
+ }
+};
+
+window.onblur = function() {
+ outerlog += "windowblur,";
+};
+</script>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-inner-contentwindow.html b/testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-inner-contentwindow.html
new file mode 100644
index 0000000000..bc78e6e053
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-inner-contentwindow.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Inner document</title>
+</head>
+<body>
+<h1>Inner</h1>
+<script>
+document.body.onfocus = function() {
+ parent.postMessage("innerbodyfocus,", "*");
+}
+document.body.onblur = function() {
+ parent.postMessage("innerbodyblur,", "*");
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-inner.html b/testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-inner.html
new file mode 100644
index 0000000000..bc78e6e053
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-inner.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Inner document</title>
+</head>
+<body>
+<h1>Inner</h1>
+<script>
+document.body.onfocus = function() {
+ parent.postMessage("innerbodyfocus,", "*");
+}
+document.body.onblur = function() {
+ parent.postMessage("innerbodyblur,", "*");
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-outer-contentwindow.sub.html b/testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-outer-contentwindow.sub.html
new file mode 100644
index 0000000000..fd66cbaa55
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-outer-contentwindow.sub.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>activeElement when focusing different-site iframe's contenWindow</title>
+<script>
+let log = "";
+function getLog() {
+ return log;
+}
+window.onmessage = function(e) {
+ log += e.data;
+};
+window.onload = function() {
+ log += "outeronload,";
+ log += "activeElement:" + document.activeElement.tagName + ",";
+ log += "willfocusiframe,";
+ document.getElementsByTagName("iframe")[0].contentWindow.focus();
+ log += "didfocusiframe,";
+ log += "activeElement:" + document.activeElement.tagName + ",";
+ log += "willbluriframe,";
+ document.getElementsByTagName("iframe")[0].contentWindow.blur();
+ log += "didbluriframe,";
+ log += "activeElement:" + document.activeElement.tagName + ",";
+ log += "willspineventloop,"
+ opener.step_timeout(function() {
+ opener.postMessage(getLog(), "*");
+ }, 1500);
+}
+</script>
+<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/activeelement-after-focusing-different-site-iframe-inner-contentwindow.html"></iframe>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-outer.sub.html b/testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-outer.sub.html
new file mode 100644
index 0000000000..bcbedb2f74
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-outer.sub.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>activeElement when focusing different-site iframe</title>
+<script>
+let log = "";
+function getLog() {
+ return log;
+}
+window.onmessage = function(e) {
+ log += e.data;
+};
+window.onload = function() {
+ log += "outeronload,";
+ log += "activeElement:" + document.activeElement.tagName + ",";
+ log += "willfocusiframe,";
+ document.getElementsByTagName("iframe")[0].focus();
+ log += "didfocusiframe,";
+ log += "activeElement:" + document.activeElement.tagName + ",";
+ log += "willbluriframe,";
+ document.getElementsByTagName("iframe")[0].blur();
+ log += "didbluriframe,";
+ log += "activeElement:" + document.activeElement.tagName + ",";
+ log += "willspineventloop,"
+ opener.step_timeout(function() {
+ opener.postMessage(getLog(), "*");
+ }, 1500);
+}
+</script>
+<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/activeelement-after-focusing-different-site-iframe-inner.html"></iframe>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-then-immediately-focusing-back-outer.sub.html b/testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-then-immediately-focusing-back-outer.sub.html
new file mode 100644
index 0000000000..6f38616380
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-focusing-different-site-iframe-then-immediately-focusing-back-outer.sub.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>activeElement when focusing different-site iframe then immediately focusing back outer</title>
+<input type="text">
+<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/focus-event-after-focusing-iframes-inner.html"></iframe>
+<script>
+let outerlog = "outerlog:";
+
+let iframe = document.querySelector("iframe");
+let input = document.querySelector("input");
+window.onmessage = function(e) {
+ if (e.data == "focus") {
+ outerlog += "willfocusiframe,";
+ iframe.focus();
+ outerlog += "didfocusiframe,";
+ outerlog += "willfocusinput,";
+ input.focus();
+ outerlog += "didfocusinput,";
+ } else if (e.data == "getlog") {
+ iframe.contentWindow.postMessage("getlog", "*");
+ } else if (e.data == "getActiveElement") {
+ opener.postMessage(document.activeElement.tagName, "*");
+ } else {
+ opener.postMessage(outerlog + e.data, "*");
+ }
+};
+
+window.onload = function() {
+ input.onfocus = function() {
+ outerlog += "inputfocus,";
+ };
+
+ input.onblur = function() {
+ outerlog += "inputblur,";
+ };
+
+ opener.postMessage("ready", "*");
+};
+</script>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-focusing-same-site-iframe-inner-contentwindow.html b/testing/web-platform/tests/focus/support/activeelement-after-focusing-same-site-iframe-inner-contentwindow.html
new file mode 100644
index 0000000000..bc78e6e053
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-focusing-same-site-iframe-inner-contentwindow.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Inner document</title>
+</head>
+<body>
+<h1>Inner</h1>
+<script>
+document.body.onfocus = function() {
+ parent.postMessage("innerbodyfocus,", "*");
+}
+document.body.onblur = function() {
+ parent.postMessage("innerbodyblur,", "*");
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-focusing-same-site-iframe-inner.html b/testing/web-platform/tests/focus/support/activeelement-after-focusing-same-site-iframe-inner.html
new file mode 100644
index 0000000000..bc78e6e053
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-focusing-same-site-iframe-inner.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Inner document</title>
+</head>
+<body>
+<h1>Inner</h1>
+<script>
+document.body.onfocus = function() {
+ parent.postMessage("innerbodyfocus,", "*");
+}
+document.body.onblur = function() {
+ parent.postMessage("innerbodyblur,", "*");
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-focusing-same-site-iframe-outer-contentwindow.html b/testing/web-platform/tests/focus/support/activeelement-after-focusing-same-site-iframe-outer-contentwindow.html
new file mode 100644
index 0000000000..63e2ac6019
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-focusing-same-site-iframe-outer-contentwindow.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>activeElement when focusing same-site iframe's contentWindow</title>
+<script>
+let log = "";
+function getLog() {
+ return log;
+}
+window.onmessage = function(e) {
+ log += e.data;
+};
+window.onload = function() {
+ log += "outeronload,";
+ log += "activeElement:" + document.activeElement.tagName + ",";
+ log += "willfocusiframe,";
+ document.getElementsByTagName("iframe")[0].contentWindow.focus();
+ log += "didfocusiframe,";
+ log += "activeElement:" + document.activeElement.tagName + ",";
+ log += "willbluriframe,";
+ document.getElementsByTagName("iframe")[0].contentWindow.blur();
+ log += "didbluriframe,";
+ log += "activeElement:" + document.activeElement.tagName + ",";
+ log += "willspineventloop,"
+ opener.step_timeout(function() {
+ opener.postMessage(getLog(), "*");
+ }, 1500);
+}
+</script>
+<iframe src="activeelement-after-focusing-same-site-iframe-inner-contentwindow.html"></iframe>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-focusing-same-site-iframe-outer.html b/testing/web-platform/tests/focus/support/activeelement-after-focusing-same-site-iframe-outer.html
new file mode 100644
index 0000000000..333b436ea1
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-focusing-same-site-iframe-outer.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>activeElement when focusing same-site iframe</title>
+<script>
+let log = "";
+function getLog() {
+ return log;
+}
+window.onmessage = function(e) {
+ log += e.data;
+};
+window.onload = function() {
+ log += "outeronload,";
+ log += "activeElement:" + document.activeElement.tagName + ",";
+ log += "willfocusiframe,";
+ document.getElementsByTagName("iframe")[0].focus();
+ log += "didfocusiframe,";
+ log += "activeElement:" + document.activeElement.tagName + ",";
+ log += "willbluriframe,";
+ document.getElementsByTagName("iframe")[0].blur();
+ log += "didbluriframe,";
+ log += "activeElement:" + document.activeElement.tagName + ",";
+ log += "willspineventloop,"
+ opener.step_timeout(function() {
+ opener.postMessage(getLog(), "*");
+ }, 1500);
+}
+</script>
+<iframe src="activeelement-after-focusing-same-site-iframe-inner.html"></iframe>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-different-site-iframe-inner-contentwindow.html b/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-different-site-iframe-inner-contentwindow.html
new file mode 100644
index 0000000000..7d47e7ecb9
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-different-site-iframe-inner-contentwindow.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Inner document</title>
+</head>
+<body>
+<h1>Inner</h1>
+<script>
+document.body.onfocus = function() {
+ // Commented out pending resolution of
+ // https://github.com/whatwg/html/issues/6209
+ // parent.postMessage("innerbodyfocus,", "*");
+}
+document.body.onblur = function() {
+ parent.postMessage("innerbodyblur,", "*");
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-different-site-iframe-inner.html b/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-different-site-iframe-inner.html
new file mode 100644
index 0000000000..bc78e6e053
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-different-site-iframe-inner.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Inner document</title>
+</head>
+<body>
+<h1>Inner</h1>
+<script>
+document.body.onfocus = function() {
+ parent.postMessage("innerbodyfocus,", "*");
+}
+document.body.onblur = function() {
+ parent.postMessage("innerbodyblur,", "*");
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-different-site-iframe-outer-contentwindow.sub.html b/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-different-site-iframe-outer-contentwindow.sub.html
new file mode 100644
index 0000000000..10240504fe
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-different-site-iframe-outer-contentwindow.sub.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>activeElement when immediately focusing different-site iframe's contentWindow</title>
+<script>
+let log = "";
+function getLog() {
+ return log;
+}
+window.onmessage = function(e) {
+ log += e.data;
+};
+</script>
+<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/activeelement-after-immediately-focusing-different-site-iframe-inner-contentwindow.html"></iframe>
+<script>
+log += "outerparser,";
+log += "activeElement:" + document.activeElement.tagName + ",";
+log += "willfocusiframe,";
+document.getElementsByTagName("iframe")[0].contentWindow.focus();
+log += "didfocusiframe,";
+log += "activeElement:" + document.activeElement.tagName + ",";
+log += "willbluriframe,";
+document.getElementsByTagName("iframe")[0].contentWindow.blur();
+log += "didbluriframe,";
+log += "activeElement:" + document.activeElement.tagName + ",";
+log += "willspineventloop,"
+opener.step_timeout(function() {
+ opener.postMessage(getLog(), "*");
+}, 1500);
+</script>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-different-site-iframe-outer.sub.html b/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-different-site-iframe-outer.sub.html
new file mode 100644
index 0000000000..3485f1b8e4
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-different-site-iframe-outer.sub.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>activeElement when immediately focusing different-site iframe</title>
+<script>
+let log = "";
+function getLog() {
+ return log;
+}
+window.onmessage = function(e) {
+ log += e.data;
+};
+</script>
+<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/activeelement-after-immediately-focusing-different-site-iframe-inner.html"></iframe>
+<script>
+log += "outerparser,";
+log += "activeElement:" + document.activeElement.tagName + ",";
+log += "willfocusiframe,";
+document.getElementsByTagName("iframe")[0].focus();
+log += "didfocusiframe,";
+log += "activeElement:" + document.activeElement.tagName + ",";
+log += "willbluriframe,";
+document.getElementsByTagName("iframe")[0].blur();
+log += "didbluriframe,";
+log += "activeElement:" + document.activeElement.tagName + ",";
+log += "willspineventloop,"
+opener.step_timeout(function() {
+ opener.postMessage(getLog(), "*");
+}, 1500);
+</script>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-same-site-iframe-inner-contentwindow.html b/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-same-site-iframe-inner-contentwindow.html
new file mode 100644
index 0000000000..7d47e7ecb9
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-same-site-iframe-inner-contentwindow.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Inner document</title>
+</head>
+<body>
+<h1>Inner</h1>
+<script>
+document.body.onfocus = function() {
+ // Commented out pending resolution of
+ // https://github.com/whatwg/html/issues/6209
+ // parent.postMessage("innerbodyfocus,", "*");
+}
+document.body.onblur = function() {
+ parent.postMessage("innerbodyblur,", "*");
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-same-site-iframe-inner.html b/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-same-site-iframe-inner.html
new file mode 100644
index 0000000000..bc78e6e053
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-same-site-iframe-inner.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Inner document</title>
+</head>
+<body>
+<h1>Inner</h1>
+<script>
+document.body.onfocus = function() {
+ parent.postMessage("innerbodyfocus,", "*");
+}
+document.body.onblur = function() {
+ parent.postMessage("innerbodyblur,", "*");
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-same-site-iframe-outer-contentwindow.html b/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-same-site-iframe-outer-contentwindow.html
new file mode 100644
index 0000000000..3849f6ea2c
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-same-site-iframe-outer-contentwindow.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>activeElement when focusing same-site iframe's contentWindow</title>
+<script>
+let log = "";
+function getLog() {
+ return log;
+}
+window.onmessage = function(e) {
+ log += e.data;
+};
+</script>
+<iframe src="activeelement-after-immediately-focusing-same-site-iframe-inner-contentwindow.html"></iframe>
+<script>
+log += "outerparse,";
+log += "activeElement:" + document.activeElement.tagName + ",";
+log += "willfocusiframe,";
+document.getElementsByTagName("iframe")[0].contentWindow.focus();
+log += "didfocusiframe,";
+log += "activeElement:" + document.activeElement.tagName + ",";
+log += "willbluriframe,";
+document.getElementsByTagName("iframe")[0].contentWindow.blur();
+log += "didbluriframe,";
+log += "activeElement:" + document.activeElement.tagName + ",";
+log += "willspineventloop,"
+opener.step_timeout(function() {
+ opener.postMessage(getLog(), "*");
+}, 1500);
+</script>
diff --git a/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-same-site-iframe-outer.html b/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-same-site-iframe-outer.html
new file mode 100644
index 0000000000..f22fa98076
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/activeelement-after-immediately-focusing-same-site-iframe-outer.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>activeElement when focusing same-site iframe</title>
+<script>
+let log = "";
+function getLog() {
+ return log;
+}
+window.onmessage = function(e) {
+ log += e.data;
+};
+</script>
+<iframe src="activeelement-after-immediately-focusing-same-site-iframe-inner.html"></iframe>
+<script>
+log += "outerparse,";
+log += "activeElement:" + document.activeElement.tagName + ",";
+log += "willfocusiframe,";
+document.getElementsByTagName("iframe")[0].focus();
+log += "didfocusiframe,";
+log += "activeElement:" + document.activeElement.tagName + ",";
+log += "willbluriframe,";
+document.getElementsByTagName("iframe")[0].blur();
+log += "didbluriframe,";
+log += "activeElement:" + document.activeElement.tagName + ",";
+log += "willspineventloop,"
+opener.step_timeout(function() {
+ opener.postMessage(getLog(), "*");
+}, 1500);
+</script>
diff --git a/testing/web-platform/tests/focus/support/focus-already-focused-iframe-deep-different-site-outer.sub.html b/testing/web-platform/tests/focus/support/focus-already-focused-iframe-deep-different-site-outer.sub.html
new file mode 100644
index 0000000000..aeafd9b5b3
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-already-focused-iframe-deep-different-site-outer.sub.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Focus already focused iframe</title>
+<script>
+let failed = false;
+window.onmessage = function(e) {
+ if (e.data == "focus") {
+ document.getElementsByTagName("iframe")[0].focus();
+ opener.step_timeout(function() {
+ if (failed) {
+ opener.postMessage("FAIL", "*");
+ } else {
+ opener.postMessage("PASS", "*");
+ }
+ }, 1500);
+ } else if (e.data == "FAIL") {
+ failed = true;
+ }
+}
+</script>
+<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/focus-already-focused-iframe-middle.html"></iframe>
diff --git a/testing/web-platform/tests/focus/support/focus-already-focused-iframe-deep-same-site-outer.html b/testing/web-platform/tests/focus/support/focus-already-focused-iframe-deep-same-site-outer.html
new file mode 100644
index 0000000000..69d47f44d7
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-already-focused-iframe-deep-same-site-outer.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Focus already focused iframe</title>
+<script>
+let failed = false;
+window.onmessage = function(e) {
+ if (e.data == "focus") {
+ document.getElementsByTagName("iframe")[0].focus();
+ opener.step_timeout(function() {
+ if (failed) {
+ opener.postMessage("FAIL", "*");
+ } else {
+ opener.postMessage("PASS", "*");
+ }
+ }, 1500);
+ } else if (e.data == "FAIL") {
+ failed = true;
+ }
+}
+</script>
+<iframe src="focus-already-focused-iframe-middle.html"></iframe>
diff --git a/testing/web-platform/tests/focus/support/focus-already-focused-iframe-different-site-outer.sub.html b/testing/web-platform/tests/focus/support/focus-already-focused-iframe-different-site-outer.sub.html
new file mode 100644
index 0000000000..54d16af68d
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-already-focused-iframe-different-site-outer.sub.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Focus already focused iframe</title>
+<script>
+let failed = false;
+window.onmessage = function(e) {
+ if (e.data == "focus") {
+ document.getElementsByTagName("iframe")[0].focus();
+ opener.step_timeout(function() {
+ if (failed) {
+ opener.postMessage("FAIL", "*");
+ } else {
+ opener.postMessage("PASS", "*");
+ }
+ }, 1500);
+ } else if (e.data == "FAIL") {
+ failed = true;
+ }
+}
+</script>
+<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/focus-already-focused-iframe-inner.html"></iframe>
diff --git a/testing/web-platform/tests/focus/support/focus-already-focused-iframe-inner.html b/testing/web-platform/tests/focus/support/focus-already-focused-iframe-inner.html
new file mode 100644
index 0000000000..6b3b4db843
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-already-focused-iframe-inner.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Focus already focused iframe</title>
+<script>
+let haveGottenFocus = false;
+function gotFocus() {
+ if (haveGottenFocus) {
+ parent.postMessage("FAIL", "*");
+ } else {
+ haveGottenFocus = true;
+ parent.postMessage("focus", "*");
+ }
+}
+window.onload = function() {
+ document.getElementsByTagName("input")[0].focus();
+}
+</script>
+<input onfocus="gotFocus();">
diff --git a/testing/web-platform/tests/focus/support/focus-already-focused-iframe-middle.html b/testing/web-platform/tests/focus/support/focus-already-focused-iframe-middle.html
new file mode 100644
index 0000000000..71d9b71c34
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-already-focused-iframe-middle.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Middle</title>
+<script>
+window.onmessage = function(e) {
+ parent.postMessage(e.data, "*");
+}
+</script>
+</head>
+<body>
+<iframe src="focus-already-focused-iframe-inner.html"></iframe>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/focus-already-focused-iframe-same-site-outer.html b/testing/web-platform/tests/focus/support/focus-already-focused-iframe-same-site-outer.html
new file mode 100644
index 0000000000..cc4efe8541
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-already-focused-iframe-same-site-outer.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Focus already focused iframe</title>
+<script>
+let failed = false;
+window.onmessage = function(e) {
+ if (e.data == "focus") {
+ document.getElementsByTagName("iframe")[0].focus();
+ opener.step_timeout(function() {
+ if (failed) {
+ opener.postMessage("FAIL", "*");
+ } else {
+ opener.postMessage("PASS", "*");
+ }
+ }, 1500);
+ } else if (e.data == "FAIL") {
+ failed = true;
+ }
+}
+</script>
+<iframe src="focus-already-focused-iframe-inner.html"></iframe>
diff --git a/testing/web-platform/tests/focus/support/focus-event-after-different-site-iframe-gets-focus-outer.sub.html b/testing/web-platform/tests/focus/support/focus-event-after-different-site-iframe-gets-focus-outer.sub.html
new file mode 100644
index 0000000000..da107ab8a2
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-event-after-different-site-iframe-gets-focus-outer.sub.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Focus event after different site iframe gets focus outer</title>
+<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/focus-event-after-iframe-gets-focus-inner.html"></iframe>
+<script>
+let outerlog = "outerlog:";
+
+let iframe = document.querySelector("iframe");
+window.onmessage = function(e) {
+ if (e.data == "start") {
+ window.onfocus = function() {
+ outerlog += "windowfocus,";
+ };
+ } else if (e.data == "focus") {
+ iframe.contentWindow.postMessage("focus", "*");
+ } else if (e.data == "getlog") {
+ iframe.contentWindow.postMessage("getlog", "*");
+ } else {
+ opener.postMessage(outerlog + e.data, "*");
+ }
+};
+
+window.onload = function() {
+ window.onblur = function() {
+ outerlog += "windowblur,";
+ };
+
+ opener.postMessage("ready", "*");
+};
+</script>
diff --git a/testing/web-platform/tests/focus/support/focus-event-after-focusing-different-site-iframes-outer.sub.html b/testing/web-platform/tests/focus/support/focus-event-after-focusing-different-site-iframes-outer.sub.html
new file mode 100644
index 0000000000..7c02a6b640
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-event-after-focusing-different-site-iframes-outer.sub.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Focus event after focusing different site iframes outer</title>
+<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/focus-event-after-focusing-iframes-inner.html"></iframe>
+<script>
+let outerlog = "outerlog:";
+
+let iframe = document.querySelector("iframe");
+window.onmessage = function(e) {
+ if (e.data == "start") {
+ window.onfocus = function() {
+ outerlog += "windowfocus,";
+ };
+ } else if (e.data == "focus") {
+ outerlog += "willfocusiframe,";
+ iframe.focus();
+ outerlog += "didfocusiframe,";
+ } else if (e.data == "getlog") {
+ iframe.contentWindow.postMessage("getlog", "*");
+ } else {
+ opener.postMessage(outerlog + e.data, "*");
+ }
+};
+
+window.onload = function() {
+ window.onblur = function() {
+ outerlog += "windowblur,";
+ };
+
+ opener.postMessage("ready", "*");
+};
+</script>
diff --git a/testing/web-platform/tests/focus/support/focus-event-after-focusing-iframes-inner.html b/testing/web-platform/tests/focus/support/focus-event-after-focusing-iframes-inner.html
new file mode 100644
index 0000000000..cb154160db
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-event-after-focusing-iframes-inner.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Focus event inner document</title>
+</head>
+<body>
+<h1>Inner</h1>
+<script>
+let innerlog = "innerlog:";
+
+window.onmessage = function(e) {
+ if (e.data == "getlog") {
+ parent.postMessage(innerlog, "*");
+ }
+};
+
+window.onfocus = function() {
+ innerlog += "windowfocus,";
+};
+
+window.onblur = function() {
+ innerlog += "windowblur,";
+};
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/focus-event-after-focusing-same-site-iframes-outer.html b/testing/web-platform/tests/focus/support/focus-event-after-focusing-same-site-iframes-outer.html
new file mode 100644
index 0000000000..9147b681c2
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-event-after-focusing-same-site-iframes-outer.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Focus event after focusing same site iframes outer</title>
+<iframe src="focus-event-after-focusing-iframes-inner.html"></iframe>
+<script>
+let outerlog = "outerlog:";
+
+let iframe = document.querySelector("iframe");
+window.onmessage = function(e) {
+ if (e.data == "start") {
+ window.onfocus = function() {
+ outerlog += "windowfocus,";
+ };
+ } else if (e.data == "focus") {
+ outerlog += "willfocusiframe,";
+ document.querySelector("iframe").focus();
+ outerlog += "didfocusiframe,";
+ } else if (e.data == "getlog") {
+ iframe.contentWindow.postMessage("getlog", "*");
+ } else {
+ opener.postMessage(outerlog + e.data, "*");
+ }
+};
+
+window.onload = function() {
+ window.onblur = function() {
+ outerlog += "windowblur,";
+ };
+
+ opener.postMessage("ready", "*");
+};
+</script>
diff --git a/testing/web-platform/tests/focus/support/focus-event-after-iframe-gets-focus-inner.html b/testing/web-platform/tests/focus/support/focus-event-after-iframe-gets-focus-inner.html
new file mode 100644
index 0000000000..bab32c0879
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-event-after-iframe-gets-focus-inner.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Focus event inner document</title>
+</head>
+<body>
+<h1>Inner</h1>
+<script>
+let innerlog = "innerlog:";
+
+window.onmessage = function(e) {
+ if (e.data == "focus") {
+ innerlog += "willfocuswindow,";
+ window.focus();
+ innerlog += "didfocuswindow,";
+ } else if (e.data == "getlog") {
+ parent.postMessage(innerlog, "*");
+ }
+};
+
+window.onfocus = function() {
+ innerlog += "windowfocus,";
+};
+
+window.onblur = function() {
+ innerlog += "windowblur,";
+};
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/focus-event-after-innermost-different-site-iframe-gets-focus-middle.sub.html b/testing/web-platform/tests/focus/support/focus-event-after-innermost-different-site-iframe-gets-focus-middle.sub.html
new file mode 100644
index 0000000000..ba2a9c7657
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-event-after-innermost-different-site-iframe-gets-focus-middle.sub.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Focus event after different site iframe gets focus middle</title>
+<h1>Middle</h1><br>
+<iframe src="https://{{hosts[][www]}}:{{ports[https][0]}}/focus/support/focus-event-after-iframe-gets-focus-inner.html"></iframe>
+<script>
+let middlelog = "middlelog:";
+
+let iframe = document.querySelector("iframe");
+window.onmessage = function(e) {
+ if (e.data == "focus") {
+ iframe.contentWindow.postMessage("focus", "*");
+ } else if (e.data == "getlog") {
+ iframe.contentWindow.postMessage("getlog", "*");
+ } else {
+ parent.postMessage(middlelog + e.data, "*");
+ }
+};
+
+window.onfocus = function() {
+ middlelog += "windowfocus,";
+};
+
+window.onblur = function() {
+ middlelog += "windowblur,";
+};
+</script>
diff --git a/testing/web-platform/tests/focus/support/focus-event-after-innermost-different-site-iframe-gets-focus-outer.sub.html b/testing/web-platform/tests/focus/support/focus-event-after-innermost-different-site-iframe-gets-focus-outer.sub.html
new file mode 100644
index 0000000000..fc0fb50e43
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-event-after-innermost-different-site-iframe-gets-focus-outer.sub.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Focus event after innermost different site iframe gets focus outer</title>
+<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/focus-event-after-innermost-different-site-iframe-gets-focus-middle.sub.html"></iframe>
+<script>
+let outerlog = "outerlog:";
+
+let iframe = document.querySelector("iframe");
+window.onmessage = function(e) {
+ if (e.data == "start") {
+ window.onfocus = function() {
+ outerlog += "windowfocus,";
+ };
+ } else if (e.data == "focus") {
+ iframe.contentWindow.postMessage("focus", "*");
+ } else if (e.data == "getlog") {
+ iframe.contentWindow.postMessage("getlog", "*");
+ } else {
+ opener.postMessage(outerlog + e.data, "*");
+ }
+};
+
+window.onload = function() {
+ window.onblur = function() {
+ outerlog += "windowblur,";
+ };
+
+ opener.postMessage("ready", "*");
+};
+</script>
diff --git a/testing/web-platform/tests/focus/support/focus-event-after-same-site-iframe-gets-focus-outer.html b/testing/web-platform/tests/focus/support/focus-event-after-same-site-iframe-gets-focus-outer.html
new file mode 100644
index 0000000000..c6799f0edb
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-event-after-same-site-iframe-gets-focus-outer.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Focus event after same site iframe gets focus outer</title>
+<iframe src="focus-event-after-iframe-gets-focus-inner.html"></iframe>
+<script>
+let outerlog = "outerlog:";
+
+let iframe = document.querySelector("iframe");
+window.onmessage = function(e) {
+ if (e.data == "start") {
+ window.onfocus = function() {
+ outerlog += "windowfocus,";
+ };
+ } else if (e.data == "focus") {
+ iframe.contentWindow.postMessage("focus", "*");
+ } else if (e.data == "getlog") {
+ iframe.contentWindow.postMessage("getlog", "*");
+ } else {
+ opener.postMessage(outerlog + e.data, "*");
+ }
+};
+
+window.onload = function() {
+ window.onblur = function() {
+ outerlog += "windowblur,";
+ };
+
+ opener.postMessage("ready", "*");
+};
+</script>
diff --git a/testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-inner-window.html b/testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-inner-window.html
new file mode 100644
index 0000000000..a5c75f496b
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-inner-window.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Inner document</title>
+</head>
+<body>
+<h1>Inner</h1>
+<script>
+window.onmessage = function(e) {
+ if (e.data == "getlog") {
+ parent.postMessage(log, "*");
+ }
+};
+
+let log = "log:";
+window.onfocus = function() {
+ log += "windowfocus,"
+}
+window.onblur = function() {
+ log += "windowblur,"
+}
+window.onload = function() {
+ log += "willfocuswindow,"
+ window.focus();
+ log += "didfocuswindow,"
+ parent.postMessage("start", "*");
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-inner.html b/testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-inner.html
new file mode 100644
index 0000000000..d076579017
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-inner.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Inner document</title>
+</head>
+<body>
+<h1>Inner</h1>
+<input type="text">
+<script>
+window.onmessage = function(e) {
+ if (e.data == "getlog") {
+ parent.postMessage(log, "*");
+ }
+};
+
+let log = "log:";
+let input = document.getElementsByTagName("input")[0];
+input.onfocus = function() {
+ log += "inputfocus,"
+}
+input.onblur = function() {
+ log += "inputblur,"
+}
+document.body.onfocus = function() {
+ log += "bodyfocus,"
+}
+document.body.onblur = function() {
+ log += "bodyblur,"
+}
+window.onload = function() {
+ log += "willfocusinput,"
+ input.focus();
+ log += "didfocusinput,"
+ parent.postMessage("start", "*");
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-other.html b/testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-other.html
new file mode 100644
index 0000000000..b302b90938
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-other.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script>
+window.onload = function() {
+ opener.postMessage("other", "*");
+}
+</script>
diff --git a/testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-outer-window.sub.html b/testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-outer-window.sub.html
new file mode 100644
index 0000000000..ac611323c4
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-outer-window.sub.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Focus restoration outer</title>
+<script>
+let other = null;
+let log = "outerlog:";
+function getLog() {
+ return log;
+}
+window.onmessage = function(e) {
+ if (e.data == "start") {
+ other = window.open("focus-restoration-in-different-site-iframes-other.html", "otherwindow", "resizable=yes");
+ } else if (e.data == "other") {
+ other.close();
+ opener.step_timeout(function() {
+ document.getElementsByTagName("iframe")[0].contentWindow.postMessage("getlog", "*");
+ }, 2000);
+ } else {
+ opener.step_timeout(function() {
+ opener.postMessage(getLog() + e.data, "*");
+ }, 1500);
+ }
+};
+window.onload = function() {
+ document.getElementsByTagName("iframe")[0].onfocus = function() {
+ log += "iframefocus,";
+ }
+ document.getElementsByTagName("iframe")[0].onblur = function() {
+ log += "iframeblur,";
+ }
+ document.body.onfocus = function() {
+ log += "bodyfocus,";
+ }
+ document.body.onblur = function() {
+ log += "bodyblur,";
+ }
+}
+</script>
+<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/focus-restoration-in-different-site-iframes-inner-window.html">
diff --git a/testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-outer.sub.html b/testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-outer.sub.html
new file mode 100644
index 0000000000..fa32c67173
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-restoration-in-different-site-iframes-outer.sub.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Focus restoration outer</title>
+<script>
+let other = null;
+let log = "outerlog:";
+function getLog() {
+ return log;
+}
+window.onmessage = function(e) {
+ if (e.data == "start") {
+ other = window.open("focus-restoration-in-different-site-iframes-other.html", "otherwindow", "resizable=yes");
+ } else if (e.data == "other") {
+ other.close();
+ opener.step_timeout(function() {
+ document.getElementsByTagName("iframe")[0].contentWindow.postMessage("getlog", "*");
+ }, 2000);
+ } else {
+ opener.step_timeout(function() {
+ opener.postMessage(getLog() + e.data, "*");
+ }, 1500);
+ }
+};
+window.onload = function() {
+ document.getElementsByTagName("iframe")[0].onfocus = function() {
+ log += "iframefocus,";
+ }
+ document.getElementsByTagName("iframe")[0].onblur = function() {
+ log += "iframeblur,";
+ }
+ document.body.onfocus = function() {
+ log += "bodyfocus,";
+ }
+ document.body.onblur = function() {
+ log += "bodyblur,";
+ }
+}
+</script>
+<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/focus-restoration-in-different-site-iframes-inner.html">
diff --git a/testing/web-platform/tests/focus/support/focus-restoration-in-same-site-iframes-inner-window.html b/testing/web-platform/tests/focus/support/focus-restoration-in-same-site-iframes-inner-window.html
new file mode 100644
index 0000000000..a5c75f496b
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-restoration-in-same-site-iframes-inner-window.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Inner document</title>
+</head>
+<body>
+<h1>Inner</h1>
+<script>
+window.onmessage = function(e) {
+ if (e.data == "getlog") {
+ parent.postMessage(log, "*");
+ }
+};
+
+let log = "log:";
+window.onfocus = function() {
+ log += "windowfocus,"
+}
+window.onblur = function() {
+ log += "windowblur,"
+}
+window.onload = function() {
+ log += "willfocuswindow,"
+ window.focus();
+ log += "didfocuswindow,"
+ parent.postMessage("start", "*");
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/focus-restoration-in-same-site-iframes-outer-window.html b/testing/web-platform/tests/focus/support/focus-restoration-in-same-site-iframes-outer-window.html
new file mode 100644
index 0000000000..4ccba143d3
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/focus-restoration-in-same-site-iframes-outer-window.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Focus restoration outer</title>
+<script>
+let other = null;
+let log = "outerlog:";
+function getLog() {
+ return log;
+}
+window.onmessage = function(e) {
+ if (e.data == "start") {
+ other = window.open("focus-restoration-in-different-site-iframes-other.html", "otherwindow", "resizable=yes");
+ } else if (e.data == "other") {
+ other.close();
+ opener.step_timeout(function() {
+ document.getElementsByTagName("iframe")[0].contentWindow.postMessage("getlog", "*");
+ }, 2000);
+ } else {
+ opener.step_timeout(function() {
+ opener.postMessage(getLog() + e.data, "*");
+ }, 1500);
+ }
+};
+window.onload = function() {
+ document.getElementsByTagName("iframe")[0].onfocus = function() {
+ log += "iframefocus,";
+ }
+ document.getElementsByTagName("iframe")[0].onblur = function() {
+ log += "iframeblur,";
+ }
+ document.body.onfocus = function() {
+ log += "bodyfocus,";
+ }
+ document.body.onblur = function() {
+ log += "bodyblur,";
+ }
+}
+</script>
+<iframe src="focus-restoration-in-same-site-iframes-inner-window.html">
diff --git a/testing/web-platform/tests/focus/support/hasfocus-different-site-outer.sub.html b/testing/web-platform/tests/focus/support/hasfocus-different-site-outer.sub.html
new file mode 100644
index 0000000000..bf91adb59e
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/hasfocus-different-site-outer.sub.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>hasFocus() outer</title>
+<script>
+var w = null;
+var hadInitialFocus = false;
+var hadLostFocus = false;
+window.onmessage = function(e) {
+ if (e.data == "restored") {
+ if (hadInitialFocus && hadLostFocus) {
+ let verdict = document.hasFocus() ? "PASS" : "FAIL: hasFocus false";
+ window.opener.postMessage(verdict, "*");
+ } else {
+ window.opener.postMessage("FAIL: should have failed already", "*");
+ }
+ } else if (e.data == "focused") {
+ w = window.open("hasfocus-other.html");
+ } else if (e.data == "noblur") {
+ window.opener.postMessage("FAIL: no inner blur", "*");
+ } else if (e.data == "opened") {
+ if (document.hasFocus()) {
+ w.close();
+ window.opener.postMessage("FAIL: focus not lost when other window opened", "*");
+ } else {
+ hadLostFocus = true;
+ window.frames[0].postMessage("hasfocus", "*");
+ }
+ } else if (e.data == "close") {
+ w.close();
+ } else if (e.data == "wrongfocus") {
+ w.close();
+ window.opener.postMessage("FAIL: hasFocus was true in iframe", "*");
+ }
+}
+window.onload = function() {
+ if (document.hasFocus()) {
+ hadInitialFocus = true;
+ window.frames[0].postMessage("focus", "*");
+ } else {
+ window.opener.postMessage("FAIL: did not have initial focus", "*");
+ }
+}
+</script>
+</head>
+<body>
+<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/hasfocus-inner.html"></iframe>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/hasfocus-inner.html b/testing/web-platform/tests/focus/support/hasfocus-inner.html
new file mode 100644
index 0000000000..40d42bbc25
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/hasfocus-inner.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>hasFocus inner</title>
+<script>
+var seenFocus = false;
+var seenBlur = false;
+window.onmessage = function(e) {
+ if (e.data == "focus") {
+ let input = document.getElementsByTagName("input")[0];
+ input.onblur = function() {
+ seenBlur = true;
+ }
+ input.onfocus = function() {
+ if (seenFocus) {
+ if (seenBlur) {
+ window.parent.postMessage("restored", "*");
+ } else {
+ window.parent.postMessage("noblur", "*");
+ }
+ } else {
+ seenFocus = true;
+ window.parent.postMessage("focused", "*");
+ }
+ }
+ input.focus();
+ } else if (e.data == "hasfocus") {
+ if (document.hasFocus()) {
+ window.parent.postMessage("wrongfocus", "*");
+ } else {
+ window.parent.postMessage("close", "*");
+ }
+ }
+}
+</script>
+</head>
+<body>
+<input>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/hasfocus-other.html b/testing/web-platform/tests/focus/support/hasfocus-other.html
new file mode 100644
index 0000000000..910b6d7970
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/hasfocus-other.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Outer</title>
+<script>
+window.onload = function() {
+ window.opener.postMessage("opened", "*")
+}
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/hasfocus-same-site-outer.html b/testing/web-platform/tests/focus/support/hasfocus-same-site-outer.html
new file mode 100644
index 0000000000..d6f93d87a0
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/hasfocus-same-site-outer.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>hasFocus() outer</title>
+<script>
+var w = null;
+var hadInitialFocus = false;
+var hadLostFocus = false;
+window.onmessage = function(e) {
+ if (e.data == "restored") {
+ if (hadInitialFocus && hadLostFocus) {
+ let verdict = document.hasFocus() ? "PASS" : "FAIL: hasFocus false";
+ window.opener.postMessage(verdict, "*");
+ } else {
+ window.opener.postMessage("FAIL: should have failed already", "*");
+ }
+ } else if (e.data == "focused") {
+ w = window.open("hasfocus-other.html");
+ } else if (e.data == "noblur") {
+ window.opener.postMessage("FAIL: no inner blur", "*");
+ } else if (e.data == "opened") {
+ if (document.hasFocus()) {
+ w.close();
+ window.opener.postMessage("FAIL: focus not lost when other window opened", "*");
+ } else {
+ hadLostFocus = true;
+ window.frames[0].postMessage("hasfocus", "*");
+ }
+ } else if (e.data == "close") {
+ w.close();
+ } else if (e.data == "wrongfocus") {
+ w.close();
+ window.opener.postMessage("FAIL: hasFocus was true in iframe", "*");
+ }
+}
+window.onload = function() {
+ if (document.hasFocus()) {
+ hadInitialFocus = true;
+ window.frames[0].postMessage("focus", "*");
+ } else {
+ window.opener.postMessage("FAIL: did not have initial focus", "*");
+ }
+}
+</script>
+</head>
+<body>
+<iframe src="hasfocus-inner.html"></iframe>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/iframe-activeelement-after-focusing-out-different-site-iframes-outer.sub.html b/testing/web-platform/tests/focus/support/iframe-activeelement-after-focusing-out-different-site-iframes-outer.sub.html
new file mode 100644
index 0000000000..3fcebfc8ba
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-activeelement-after-focusing-out-different-site-iframes-outer.sub.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>iframe active element after focusing out different site iframes outer</title>
+<input></input></br>
+<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/iframe-activeelement-after-focusing-out-iframes-inner.html"></iframe>
+<script>
+let outerlog = "outerlog:";
+
+let input = document.querySelector("input");
+let iframe = document.querySelector("iframe");
+window.onmessage = function(e) {
+ if (e.data == "ready") {
+ opener.postMessage("ready", "*");
+ } else if (e.data == "focus") {
+ outerlog += "willfocusinput,";
+ input.focus();
+ outerlog += "didfocusinput,";
+ } else if (e.data == "getlog") {
+ iframe.contentWindow.postMessage("getlog", "*");
+ } else {
+ opener.postMessage(outerlog + e.data, "*");
+ }
+};
+
+window.onload = function() {
+ window.onfocus = function() {
+ outerlog += "windowfocus,";
+ };
+
+ window.onblur = function() {
+ outerlog += "windowblur,";
+ };
+};
+</script>
diff --git a/testing/web-platform/tests/focus/support/iframe-activeelement-after-focusing-out-iframes-inner.html b/testing/web-platform/tests/focus/support/iframe-activeelement-after-focusing-out-iframes-inner.html
new file mode 100644
index 0000000000..a94af6b9fb
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-activeelement-after-focusing-out-iframes-inner.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>iframe active element inner document</title>
+</head>
+<body>
+<h1>Inner</h1><br>
+<input></input>
+<script>
+let innerlog = "innerlog:";
+
+window.onmessage = function(e) {
+ if (e.data == "getlog") {
+ parent.postMessage(innerlog, "*");
+ }
+};
+
+window.onfocus = function() {
+ innerlog += "windowfocus,";
+};
+
+window.onblur = function() {
+ innerlog += "windowblur,";
+ innerlog += "activeElement:" + document.activeElement.tagName + ",";
+};
+
+let input = document.querySelector("input");
+window.onload = function() {
+ innerlog += "willfocusinput,";
+ input.focus();
+ innerlog += "didfocusinput,";
+ innerlog += "activeElement:" + document.activeElement.tagName + ",";
+ parent.postMessage("ready", "*");
+};
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/iframe-activeelement-after-focusing-out-same-site-iframes-outer.html b/testing/web-platform/tests/focus/support/iframe-activeelement-after-focusing-out-same-site-iframes-outer.html
new file mode 100644
index 0000000000..98399deb7b
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-activeelement-after-focusing-out-same-site-iframes-outer.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>iframe active element after focusing out same site iframes outer</title>
+<input></input></br>
+<iframe src="iframe-activeelement-after-focusing-out-iframes-inner.html"></iframe>
+<script>
+let outerlog = "outerlog:";
+
+let input = document.querySelector("input");
+let iframe = document.querySelector("iframe");
+window.onmessage = function(e) {
+ if (e.data == "ready") {
+ opener.postMessage("ready", "*");
+ } else if (e.data == "focus") {
+ outerlog += "willfocusinput,";
+ input.focus();
+ outerlog += "didfocusinput,";
+ } else if (e.data == "getlog") {
+ iframe.contentWindow.postMessage("getlog", "*");
+ } else {
+ opener.postMessage(outerlog + e.data, "*");
+ }
+};
+
+window.onload = function() {
+ window.onfocus = function() {
+ outerlog += "windowfocus,";
+ };
+
+ window.onblur = function() {
+ outerlog += "windowblur,";
+ };
+};
+</script>
diff --git a/testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-different-site-intermediate-frame-inner.html b/testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-different-site-intermediate-frame-inner.html
new file mode 100644
index 0000000000..c4997f5bd4
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-different-site-intermediate-frame-inner.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>iframe.contentWindow.focus() with different-site intermediate frame inner</title>
+</head>
+<body>
+<script>
+document.body.onfocus = function() {
+ parent.postMessage("innerfocus;", "*");
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-different-site-intermediate-frame-middle.sub.html b/testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-different-site-intermediate-frame-middle.sub.html
new file mode 100644
index 0000000000..e3a5facf82
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-different-site-intermediate-frame-middle.sub.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>iframe.contentWindow.focus() with different-site intermediate frame middle</title>
+<iframe src="http://{{hosts[][www]}}:{{ports[http][0]}}/focus/support/iframe-contentwindow-focus-with-different-site-intermediate-frame-inner.html"></iframe>
+<script>
+let iframe = document.getElementsByTagName("iframe")[0];
+let log = "";
+function getLog() {
+ return log;
+}
+window.onmessage = function(e) {
+ log += e.data;
+ if (e.data == "starttest;") {
+ log += "middleactivelement:" + document.activeElement.localName + ";";
+ log += "callfocus;";
+ iframe.contentWindow.focus();
+ log += "middleactivelement:" + document.activeElement.localName + ";";
+ setTimeout(function() {
+ log += "middletimer;middleactivelement:" + document.activeElement.localName + ";";
+ parent.postMessage(getLog(), "*");
+ }, 1500);
+ }
+};
+/*
+ * TODO: Get browsers to agree on this one.
+ *
+ * Does not fire in Firefox without Fission
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=1675484
+ *
+ * Fires in Blink in the iframe.focus() case but not in
+ * the iframe.contentWindow.focus() case.
+ */
+// iframe.onfocus = function() {
+// log += "middlefocus;";
+// }
+
+</script>
diff --git a/testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-different-site-intermediate-frame-outer.sub.html b/testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-different-site-intermediate-frame-outer.sub.html
new file mode 100644
index 0000000000..9dbb6af9d9
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-different-site-intermediate-frame-outer.sub.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>iframe.contentWindow.focus() with different-site intermediate frame outer</title>
+<script>
+let log = "";
+function getLog() {
+ return log;
+}
+window.onmessage = function(e) {
+ log += e.data;
+};
+window.onload = function() {
+ log += "outeronload;";
+ log += "outeractivelement:" + document.activeElement.localName + ";";
+ document.getElementsByTagName("iframe")[0].contentWindow.postMessage("starttest;", "*");
+ setTimeout(function() {
+ log += "outeractivelement:" + document.activeElement.localName + ";";
+ opener.postMessage(getLog(), "*");
+ }, 3000);
+}
+</script>
+<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/iframe-contentwindow-focus-with-different-site-intermediate-frame-middle.sub.html"></iframe>
diff --git a/testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-same-as-top-intermediate-frame-inner.html b/testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-same-as-top-intermediate-frame-inner.html
new file mode 100644
index 0000000000..30be12aa81
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-same-as-top-intermediate-frame-inner.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>iframe.contentWindow.focus() with same-as-top intermediate frame inner</title>
+</head>
+<body>
+<script>
+document.body.onfocus = function() {
+ parent.postMessage("innerfocus;", "*");
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-same-as-top-intermediate-frame-middle.sub.html b/testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-same-as-top-intermediate-frame-middle.sub.html
new file mode 100644
index 0000000000..747e146746
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-same-as-top-intermediate-frame-middle.sub.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>iframe.contentWindow.focus() with same-as-top intermediate frame middle</title>
+<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/iframe-contentwindow-focus-with-same-as-top-intermediate-frame-inner.html"></iframe>
+<script>
+let iframe = document.getElementsByTagName("iframe")[0];
+let log = "";
+function getLog() {
+ return log;
+}
+window.onmessage = function(e) {
+ log += e.data;
+ if (e.data == "starttest;") {
+ log += "middleactivelement:" + document.activeElement.localName + ";";
+ log += "callfocus;";
+ iframe.contentWindow.focus();
+ log += "middleactivelement:" + document.activeElement.localName + ";";
+ parent.opener.step_timeout(function() {
+ log += "middletimer;middleactivelement:" + document.activeElement.localName + ";";
+ parent.postMessage(getLog(), "*");
+ }, 1500);
+ }
+};
+/*
+ * TODO: Get browsers to agree on this one.
+ *
+ * Does not fire in Firefox without Fission
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=1675484
+ *
+ * Fires in Blink in the iframe.focus() case but not in
+ * the iframe.contentWindow.focus() case.
+ */
+// iframe.onfocus = function() {
+// log += "middlefocus;";
+// }
+
+</script>
diff --git a/testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-same-as-top-intermediate-frame-outer.html b/testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-same-as-top-intermediate-frame-outer.html
new file mode 100644
index 0000000000..71cfe78c0d
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-contentwindow-focus-with-same-as-top-intermediate-frame-outer.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>iframe.contentWindow.focus() with same-as-top intermediate frame outer</title>
+<script>
+let log = "";
+function getLog() {
+ return log;
+}
+window.onmessage = function(e) {
+ log += e.data;
+};
+window.onload = function() {
+ log += "outeronload;";
+ log += "outeractivelement:" + document.activeElement.localName + ";";
+ document.getElementsByTagName("iframe")[0].contentWindow.postMessage("starttest;", "*");
+ opener.step_timeout(function() {
+ log += "outeractivelement:" + document.activeElement.localName + ";";
+ opener.postMessage(getLog(), "*");
+ }, 2000);
+}
+</script>
+<iframe src="iframe-contentwindow-focus-with-same-as-top-intermediate-frame-middle.sub.html"></iframe>
diff --git a/testing/web-platform/tests/focus/support/iframe-focus-with-different-site-intermediate-frame-inner.html b/testing/web-platform/tests/focus/support/iframe-focus-with-different-site-intermediate-frame-inner.html
new file mode 100644
index 0000000000..e2adcc06b2
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-focus-with-different-site-intermediate-frame-inner.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>iframe.focus() with different-site intermediate frame inner</title>
+</head>
+<body>
+<script>
+document.body.onfocus = function() {
+ parent.postMessage("innerfocus;", "*");
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/iframe-focus-with-different-site-intermediate-frame-middle.sub.html b/testing/web-platform/tests/focus/support/iframe-focus-with-different-site-intermediate-frame-middle.sub.html
new file mode 100644
index 0000000000..647f8928d6
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-focus-with-different-site-intermediate-frame-middle.sub.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>iframe.focus() with different-site intermediate frame middle</title>
+<iframe src="http://{{hosts[][www]}}:{{ports[http][0]}}/focus/support/iframe-focus-with-different-site-intermediate-frame-inner.html"></iframe>
+<script>
+let iframe = document.getElementsByTagName("iframe")[0];
+let log = "";
+function getLog() {
+ return log;
+}
+window.onmessage = function(e) {
+ log += e.data;
+ if (e.data == "starttest;") {
+ log += "middleactivelement:" + document.activeElement.localName + ";";
+ log += "callfocus;";
+ iframe.focus();
+ log += "middleactivelement:" + document.activeElement.localName + ";";
+ setTimeout(function() {
+ log += "middletimer;middleactivelement:" + document.activeElement.localName + ";";
+ parent.postMessage(getLog(), "*");
+ }, 1500);
+ }
+};
+/*
+ * TODO: Get browsers to agree on this one.
+ *
+ * Does not fire in Firefox without Fission
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=1675484
+ *
+ * Fires in Blink in the iframe.focus() case but not in
+ * the iframe.contentWindow.focus() case.
+ */
+// iframe.onfocus = function() {
+// log += "middlefocus;";
+// }
+
+</script>
diff --git a/testing/web-platform/tests/focus/support/iframe-focus-with-different-site-intermediate-frame-outer.sub.html b/testing/web-platform/tests/focus/support/iframe-focus-with-different-site-intermediate-frame-outer.sub.html
new file mode 100644
index 0000000000..5e80410206
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-focus-with-different-site-intermediate-frame-outer.sub.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>iframe.focus() with different-site intermediate frame outer</title>
+<script>
+let log = "";
+function getLog() {
+ return log;
+}
+window.onmessage = function(e) {
+ log += e.data;
+};
+window.onload = function() {
+ log += "outeronload;";
+ log += "outeractivelement:" + document.activeElement.localName + ";";
+ document.getElementsByTagName("iframe")[0].contentWindow.postMessage("starttest;", "*");
+ setTimeout(function() {
+ log += "outeractivelement:" + document.activeElement.localName + ";";
+ opener.postMessage(getLog(), "*");
+ }, 3000);
+}
+</script>
+<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/iframe-focus-with-different-site-intermediate-frame-middle.sub.html"></iframe>
diff --git a/testing/web-platform/tests/focus/support/iframe-focus-with-same-as-top-intermediate-frame-inner.html b/testing/web-platform/tests/focus/support/iframe-focus-with-same-as-top-intermediate-frame-inner.html
new file mode 100644
index 0000000000..c55c5b4499
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-focus-with-same-as-top-intermediate-frame-inner.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>iframe.focus() with same-as-top intermediate frame inner</title>
+</head>
+<body>
+<script>
+document.body.onfocus = function() {
+ parent.postMessage("innerfocus;", "*");
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/iframe-focus-with-same-as-top-intermediate-frame-middle.sub.html b/testing/web-platform/tests/focus/support/iframe-focus-with-same-as-top-intermediate-frame-middle.sub.html
new file mode 100644
index 0000000000..9fdbc3c358
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-focus-with-same-as-top-intermediate-frame-middle.sub.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>iframe.focus() with same-as-top intermediate frame middle</title>
+<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/iframe-focus-with-same-as-top-intermediate-frame-inner.html"></iframe>
+<script>
+let iframe = document.getElementsByTagName("iframe")[0];
+let log = "";
+function getLog() {
+ return log;
+}
+window.onmessage = function(e) {
+ log += e.data;
+ if (e.data == "starttest;") {
+ log += "middleactivelement:" + document.activeElement.localName + ";";
+ log += "callfocus;";
+ iframe.focus();
+ log += "middleactivelement:" + document.activeElement.localName + ";";
+ parent.opener.step_timeout(function() {
+ log += "middletimer;middleactivelement:" + document.activeElement.localName + ";";
+ parent.postMessage(getLog(), "*");
+ }, 1500);
+ }
+};
+/*
+ * TODO: Get browsers to agree on this one.
+ *
+ * Does not fire in Firefox without Fission
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=1675484
+ *
+ * Fires in Blink in the iframe.focus() case but not in
+ * the iframe.contentWindow.focus() case.
+ */
+// iframe.onfocus = function() {
+// log += "middlefocus;";
+// }
+
+</script>
diff --git a/testing/web-platform/tests/focus/support/iframe-focus-with-same-as-top-intermediate-frame-outer.html b/testing/web-platform/tests/focus/support/iframe-focus-with-same-as-top-intermediate-frame-outer.html
new file mode 100644
index 0000000000..3f6085a739
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-focus-with-same-as-top-intermediate-frame-outer.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>iframe.focus() with same-as-top intermediate frame outer</title>
+<script>
+let log = "";
+function getLog() {
+ return log;
+}
+window.onmessage = function(e) {
+ log += e.data;
+};
+window.onload = function() {
+ log += "outeronload;";
+ log += "outeractivelement:" + document.activeElement.localName + ";";
+ document.getElementsByTagName("iframe")[0].contentWindow.postMessage("starttest;", "*");
+ opener.step_timeout(function() {
+ log += "outeractivelement:" + document.activeElement.localName + ";";
+ opener.postMessage(getLog(), "*");
+ }, 2000);
+}
+</script>
+<iframe src="iframe-focus-with-same-as-top-intermediate-frame-middle.sub.html"></iframe>
diff --git a/testing/web-platform/tests/focus/support/iframe-focuses-parent-different-site-inner.html b/testing/web-platform/tests/focus/support/iframe-focuses-parent-different-site-inner.html
new file mode 100644
index 0000000000..8f2098e3fb
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-focuses-parent-different-site-inner.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>iframe focuses parent different site inner</title>
+</head>
+<body>
+<script>
+window.onmessage = function() {
+ parent.focus();
+ setTimeout(function() {
+ parent.postMessage("finished", "*");
+ }, 500);
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/iframe-focuses-parent-different-site-other.html b/testing/web-platform/tests/focus/support/iframe-focuses-parent-different-site-other.html
new file mode 100644
index 0000000000..6308c74924
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-focuses-parent-different-site-other.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>iframe focuses parent different site other</title>
+</head>
+<body>
+<script>
+window.onload = function() {
+ opener.postMessage("ready", "*");
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/iframe-focuses-parent-different-site-outer.sub.html b/testing/web-platform/tests/focus/support/iframe-focuses-parent-different-site-outer.sub.html
new file mode 100644
index 0000000000..4386c3964b
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-focuses-parent-different-site-outer.sub.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>iframe focuses parent different site outer</title>
+</head>
+<body>
+<iframe src="http://{{hosts[alt][www]}}:{{ports[http][0]}}/focus/support/iframe-focuses-parent-different-site-inner.html"></iframe>
+<script>
+var w = null;
+var focusDisallowed = false;
+var failed = false;
+window.onmessage = function(e) {
+ if (failed) {
+ return;
+ }
+ if (e.data == "ready") {
+ focusDisallowed = true;
+ document.getElementsByTagName("iframe")[0].contentWindow.postMessage("focus", "*");
+ return;
+ }
+ focusDisallowed = false;
+ if (w) {
+ w.close();
+ w = null;
+ }
+ opener.postMessage(failed ? "FAIL" : "PASS", "*");
+}
+window.onload = function() {
+ w = window.open("iframe-focuses-parent-different-site-other.html");
+}
+document.body.onfocus = function() {
+ if (focusDisallowed) {
+ failed = true;
+ }
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/iframe-focuses-parent-same-site-inner.html b/testing/web-platform/tests/focus/support/iframe-focuses-parent-same-site-inner.html
new file mode 100644
index 0000000000..222f73d075
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-focuses-parent-same-site-inner.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>iframe focuses parent same site inner</title>
+</head>
+<body>
+<script>
+window.onmessage = function() {
+ parent.focus();
+ setTimeout(function() {
+ parent.postMessage("finished", "*");
+ }, 500);
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/iframe-focuses-parent-same-site-other.html b/testing/web-platform/tests/focus/support/iframe-focuses-parent-same-site-other.html
new file mode 100644
index 0000000000..6d3f7dcc90
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-focuses-parent-same-site-other.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>iframe focuses parent same site other</title>
+</head>
+<body>
+<script>
+window.onload = function() {
+ opener.postMessage("ready", "*");
+}
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/focus/support/iframe-focuses-parent-same-site-outer.html b/testing/web-platform/tests/focus/support/iframe-focuses-parent-same-site-outer.html
new file mode 100644
index 0000000000..798500f080
--- /dev/null
+++ b/testing/web-platform/tests/focus/support/iframe-focuses-parent-same-site-outer.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>iframe focuses parent same site outer</title>
+</head>
+<body>
+<iframe src="iframe-focuses-parent-same-site-inner.html"></iframe>
+<script>
+var w = null;
+var focusDisallowed = false;
+var failed = false;
+window.onmessage = function(e) {
+ if (failed) {
+ return;
+ }
+ if (e.data == "ready") {
+ focusDisallowed = true;
+ document.getElementsByTagName("iframe")[0].contentWindow.postMessage("focus", "*");
+ return;
+ }
+ focusDisallowed = false;
+ if (w) {
+ w.close();
+ w = null;
+ }
+ opener.postMessage(failed ? "FAIL" : "PASS", "*");
+}
+window.onload = function() {
+ w = window.open("iframe-focuses-parent-same-site-other.html");
+}
+document.body.onfocus = function() {
+ if (focusDisallowed) {
+ failed = true;
+ }
+}
+</script>
+</body>
+</html>