Skip to content

Commit

Permalink
Only restore dialog focus if focus is in dialog
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=256717
rdar://109572320

Reviewed by NOBODY (OOPS!).

Implement whatwg/html#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):
  • Loading branch information
nt1m committed Jun 5, 2023
1 parent 62bb3c7 commit 75b1800
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -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 <button id="b2">button 2</button> but got Element node <button id="b1">button 1</button>
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 <div id="host">

</div> but got Element node <button id="b2">button 2</button>
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 <button id="b2">button 2</button> but got Element node <button id="host2button">button</button>

14 changes: 9 additions & 5 deletions Source/WebCore/html/HTMLDialogElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ void HTMLDialogElement::close(const String& result)

setBooleanAttribute(openAttr, false);

if (isModal())
bool isClosingModal = isModal();

if (isClosingModal)
removeFromTopLayer();

setIsModal(false);
Expand All @@ -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));
Expand All @@ -142,7 +146,7 @@ void HTMLDialogElement::queueCancelTask()
void HTMLDialogElement::runFocusingSteps()
{
RefPtr<Element> control;
if (m_isModal && hasAttributeWithoutSynchronization(HTMLNames::autofocusAttr))
if (hasAttributeWithoutSynchronization(HTMLNames::autofocusAttr))
control = this;
if (!control)
control = findFocusDelegate();
Expand Down

0 comments on commit 75b1800

Please sign in to comment.