diff --git a/portals/portals-focus.sub.html b/portals/portals-focus.sub.html index 3e3045adf90aabd..54b4312be0ada5c 100644 --- a/portals/portals-focus.sub.html +++ b/portals/portals-focus.sub.html @@ -29,6 +29,19 @@ } }, "test that an element inside a portal cannot steal focus"); + promise_test(async () => { + let portal = await createPortal(document, new URL("resources/focus-page-with-button.html", location.href)); + try { + let activeElementUpdated = new Promise(r => { + portal.onmessage = e => r(e.data.activeElementUpdated) + }); + portal.postMessage('focus-update-active-element'); + assert_true(await activeElementUpdated); + } finally { + document.body.removeChild(portal); + } + }, "test that activeElement inside a portal is updated after focus() is called"); + promise_test(async t => { let portal = await createPortal(document, new URL("resources/focus-page-with-x-origin-iframe.sub.html", location.href)); try { @@ -42,6 +55,19 @@ } }, "test that an element inside a portal's x-origin subframe cannot steal focus"); + promise_test(async () => { + let portal = await createPortal(document, new URL("resources/focus-page-with-x-origin-iframe.sub.html", location.href)); + try { + portal.postMessage("focus-update-active-element"); + let {activeElementUpdated} = await new Promise(r => { + portal.onmessage = e => r(e.data); + }); + assert_true(activeElementUpdated); + } finally { + document.body.removeChild(portal); + } + }, "test that a portal's x-origin subframe becomes active element on focus"); + promise_test(async t => { let win = await openBlankPortalHost(); let doc = win.document; @@ -87,6 +113,28 @@ } }, "test that a x-origin iframe inside an adopted portal cannot steal focus"); + promise_test(async () => { + let win = await openBlankPortalHost(); + let doc = win.document; + try { + let portal = await createPortal(doc, new URL("resources/focus-page-with-autofocus.html", location.href)); + portal.postMessage('check-active-element'); + let result = await new Promise(r => { + portal.onmessage = e => r(e.data); + }); + assert_true(result, "autofocused element is active element"); + + await portal.activate(); + win.portalHost.postMessage('check-active-element'); + result = await new Promise(r => { + win.portalHost.onmessage = e => r(e.data) + }); + assert_true(result, "autofocused element is still active element"); + } finally { + win.close(); + } + }, "test that autofocus inside a portal works"); + const TAB = "\ue004"; // https://w3c.github.io/webdriver/#keyboard-actions const SPACE = " " const RETURN = "\r"; diff --git a/portals/resources/focus-page-with-autofocus.html b/portals/resources/focus-page-with-autofocus.html new file mode 100644 index 000000000000000..8c56e73782a814f --- /dev/null +++ b/portals/resources/focus-page-with-autofocus.html @@ -0,0 +1,21 @@ + +
+ + + + + diff --git a/portals/resources/focus-page-with-button.html b/portals/resources/focus-page-with-button.html index 067221965100181..81ed5465ab10cec 100644 --- a/portals/resources/focus-page-with-button.html +++ b/portals/resources/focus-page-with-button.html @@ -7,6 +7,12 @@ button.onfocus = () => e.source.postMessage({focused: true}, {targetOrigin: "*"}); button.focus(); } + + if (e.data == "focus-update-active-element") { + let button = document.querySelector("button"); + button.focus(); + e.source.postMessage({activeElementUpdated: document.activeElement === button}, {targetOrigin: "*"}); + } } if (window.portalHost) diff --git a/portals/resources/focus-page-with-x-origin-iframe.sub.html b/portals/resources/focus-page-with-x-origin-iframe.sub.html index 9807898a3543eca..df7974e75bb9460 100644 --- a/portals/resources/focus-page-with-x-origin-iframe.sub.html +++ b/portals/resources/focus-page-with-x-origin-iframe.sub.html @@ -1,10 +1,10 @@