From 5efa864eb8171e52eee5f766093ec6b1892a8876 Mon Sep 17 00:00:00 2001 From: Adithya Srinivasan Date: Fri, 12 Feb 2021 20:25:10 +0000 Subject: [PATCH] Portals: focus() inside portal should change active element 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: https://github.com/WICG/portals/issues/257 Change-Id: If67be1f424114653983b473a80c515337d49596a Bug: 1059404 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2566072 Commit-Queue: Adithya Srinivasan Reviewed-by: Lucas Gadani Reviewed-by: Jeremy Roman Reviewed-by: Alex Moshchuk Reviewed-by: David Trainor Cr-Commit-Position: refs/heads/master@{#853647} GitOrigin-RevId: 11c3d6ba0f0c5e26aec2c764f9f95d037c23fc10 --- blink/renderer/core/dom/document.cc | 3 -- .../wpt/portals/portals-focus.sub.html | 48 +++++++++++++++++++ .../resources/focus-page-with-autofocus.html | 21 ++++++++ .../resources/focus-page-with-button.html | 6 +++ .../focus-page-with-x-origin-iframe.sub.html | 6 +-- 5 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 blink/web_tests/external/wpt/portals/resources/focus-page-with-autofocus.html diff --git a/blink/renderer/core/dom/document.cc b/blink/renderer/core/dom/document.cc index 9bab2956543e..c47ed215cd83 100644 --- a/blink/renderer/core/dom/document.cc +++ b/blink/renderer/core/dom/document.cc @@ -8195,9 +8195,6 @@ bool Document::IsSlotAssignmentOrLegacyDistributionDirty() const { } bool Document::IsFocusAllowed() const { - if (GetFrame() && GetFrame()->GetPage()->InsidePortal()) - return false; - if (!GetFrame() || GetFrame()->IsMainFrame() || LocalFrame::HasTransientUserActivation(GetFrame())) { // 'autofocus' runs Element::focus asynchronously at which point the diff --git a/blink/web_tests/external/wpt/portals/portals-focus.sub.html b/blink/web_tests/external/wpt/portals/portals-focus.sub.html index 3e3045adf90a..54b4312be0ad 100644 --- a/blink/web_tests/external/wpt/portals/portals-focus.sub.html +++ b/blink/web_tests/external/wpt/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/blink/web_tests/external/wpt/portals/resources/focus-page-with-autofocus.html b/blink/web_tests/external/wpt/portals/resources/focus-page-with-autofocus.html new file mode 100644 index 000000000000..8c56e73782a8 --- /dev/null +++ b/blink/web_tests/external/wpt/portals/resources/focus-page-with-autofocus.html @@ -0,0 +1,21 @@ + + + + + + + diff --git a/blink/web_tests/external/wpt/portals/resources/focus-page-with-button.html b/blink/web_tests/external/wpt/portals/resources/focus-page-with-button.html index 067221965100..81ed5465ab10 100644 --- a/blink/web_tests/external/wpt/portals/resources/focus-page-with-button.html +++ b/blink/web_tests/external/wpt/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/blink/web_tests/external/wpt/portals/resources/focus-page-with-x-origin-iframe.sub.html b/blink/web_tests/external/wpt/portals/resources/focus-page-with-x-origin-iframe.sub.html index 9807898a3543..df7974e75bb9 100644 --- a/blink/web_tests/external/wpt/portals/resources/focus-page-with-x-origin-iframe.sub.html +++ b/blink/web_tests/external/wpt/portals/resources/focus-page-with-x-origin-iframe.sub.html @@ -1,10 +1,10 @@