From 75b1800762aee51af1a51115e116d4e6628879e7 Mon Sep 17 00:00:00 2001 From: Tim Nguyen Date: Mon, 5 Jun 2023 14:20:02 -0700 Subject: [PATCH] Only restore dialog focus if focus is in dialog https://bugs.webkit.org/show_bug.cgi?id=256717 rdar://109572320 Reviewed by NOBODY (OOPS!). Implement https://github.com/whatwg/html/pull/9178/ to avoid unexpected focus shifting when focus is already outside of the dialog. * LayoutTests/imported/w3c/web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-focus-previous-outside-expected.txt: * Source/WebCore/html/HTMLDialogElement.cpp: (WebCore::HTMLDialogElement::close): (WebCore::HTMLDialogElement::runFocusingSteps): --- .../dialog-focus-previous-outside-expected.txt | 8 +++----- Source/WebCore/html/HTMLDialogElement.cpp | 14 +++++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/LayoutTests/imported/w3c/web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-focus-previous-outside-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-focus-previous-outside-expected.txt index 4b86cbbc1924e..650685113cfdd 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-focus-previous-outside-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/interactive-elements/the-dialog-element/dialog-focus-previous-outside-expected.txt @@ -1,9 +1,7 @@ button 1 button 2 -FAIL Focus should not be restored if the currently focused element is not inside the dialog. assert_equals: expected Element node but got Element node -FAIL Focus restore should not occur when the focused element is in a shadowroot outside of the dialog. assert_equals: document.activeElement should point at the shadow host. expected Element node
- -
but got Element node +PASS Focus should not be restored if the currently focused element is not inside the dialog. +PASS Focus restore should not occur when the focused element is in a shadowroot outside of the dialog. PASS Focus restore should occur when the focused element is in a shadowroot inside the dialog. -PASS Focus restore should occur when the focused element is slotted into a dialog. +FAIL Focus restore should occur when the focused element is slotted into a dialog. assert_equals: expected Element node but got Element node diff --git a/Source/WebCore/html/HTMLDialogElement.cpp b/Source/WebCore/html/HTMLDialogElement.cpp index 930041b904bb3..0c3a38c98dad8 100644 --- a/Source/WebCore/html/HTMLDialogElement.cpp +++ b/Source/WebCore/html/HTMLDialogElement.cpp @@ -111,7 +111,9 @@ void HTMLDialogElement::close(const String& result) setBooleanAttribute(openAttr, false); - if (isModal()) + bool isClosingModal = isModal(); + + if (isClosingModal) removeFromTopLayer(); setIsModal(false); @@ -120,9 +122,11 @@ void HTMLDialogElement::close(const String& result) m_returnValue = result; if (RefPtr element = std::exchange(m_previouslyFocusedElement, nullptr).get()) { - FocusOptions options; - options.preventScroll = true; - element->focus(options); + if (containsIncludingShadowDOM(document().focusedElement()) || isClosingModal) { + FocusOptions options; + options.preventScroll = true; + element->focus(options); + } } queueTaskToDispatchEvent(TaskSource::UserInteraction, Event::create(eventNames().closeEvent, Event::CanBubble::No, Event::IsCancelable::No)); @@ -142,7 +146,7 @@ void HTMLDialogElement::queueCancelTask() void HTMLDialogElement::runFocusingSteps() { RefPtr control; - if (m_isModal && hasAttributeWithoutSynchronization(HTMLNames::autofocusAttr)) + if (hasAttributeWithoutSynchronization(HTMLNames::autofocusAttr)) control = this; if (!control) control = findFocusDelegate();