Skip to content

Commit

Permalink
Portals: focus() inside portal should change active element
Browse files Browse the repository at this point in the history
Allows a portal document's activeElement to update when focus is called.
Note that focus events won't be dispatched as the portal doesn't get
page focus, and the portal WebContents isn't set as the focused
WebContents (with the exception of orphaned portals). Updating the
activeElement also means an autofocused element inside a portal will
receive focus when the portal is activated.

More discussion here: WICG/portals#257

Change-Id: If67be1f424114653983b473a80c515337d49596a
Bug: 1059404
  • Loading branch information
a4sriniv authored and chromium-wpt-export-bot committed Feb 12, 2021
1 parent 3586ff7 commit acf4b17
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 3 deletions.
48 changes: 48 additions & 0 deletions portals/portals-focus.sub.html
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
Expand Down Expand Up @@ -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";
Expand Down
21 changes: 21 additions & 0 deletions portals/resources/focus-page-with-autofocus.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<body>
<button id="one">one</button>
<button id="two" autofocus>two</button>
<button id="three">three</button>
<script>
function messageHandler(e) {
if (e.data === 'check-active-element') {
let autofocusedButton = document.querySelector('#two');
e.source.postMessage(document.activeElement === autofocusedButton);
}
}

window.portalHost.onmessage = messageHandler;
window.onportalactivate = e => {
let portal = e.adoptPredecessor();
portal.onmessage = messageHandler;
document.body.appendChild(portal);
}
</script>
</body>
6 changes: 6 additions & 0 deletions portals/resources/focus-page-with-button.html
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 3 additions & 3 deletions portals/resources/focus-page-with-x-origin-iframe.sub.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<!DOCTYPE html>
<body>
<script>
function handleMessage(e) {
if (e.data == "focus") {
async function handleMessage(e) {
if (e.data == "focus" || e.data == "focus-update-active-element") {
let iframe = document.querySelector("iframe");
iframe.contentWindow.postMessage("focus", "*");
iframe.contentWindow.postMessage(e.data, "*");
}
}

Expand Down

0 comments on commit acf4b17

Please sign in to comment.