-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Only restore dialog focus if focus is in the dialog #9178
Conversation
Fixes whatwg#8904 This patch prevents the behavior where closing a dialog focuses the previously focused element from before the dialog was opened only if focus is in the dialog when the dialog closes. Without this, focus can unexpectedly shift away from an element which is not going away, like a text input that the user is currently typing into for example.
source
Outdated
<li><p>If <var>subject</var>'s <span>node document</span>'s <span>focused area of the | ||
document</span>'s <span>DOM anchor</span> is a <span>shadow-including inclusive | ||
descendant</span> of <var>element</var>, then run the <span>focusing steps</span> for | ||
<var>element</var>; the viewport should not be scrolled by doing this step.</p></li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should run the focusing steps unconditionally for modal dialogs, since they make the whole page inert (so focus can never properly be outside of the dialog)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If focus can never be outside of the dialog, do you think it should be an assert?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is one case where focus can be outside the modal dialog, which is the one where the body is focused (which means no focused element). This can be asserted though, focus is on body or within the dialog. I'm not sure it would be super useful however.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But in the case the focus is on the body (e.g. no focused element) in the modal dialog case, I think we'd want to restore focus as well. It might mean that there was no element to focus within the dialog in the first place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah ok I'll just add a modal check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah we could unconditionally restore focus when the body element is focused...
The bug report definitely doesn't have the body element focused
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would slightly prefer a modal check, the body element could be focused in the non-modal case simply because the user tried to interact with something outside the dialog. In the modal case, that intent isn't really possible due to the backdrop and the inertness.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I just pushed a modal check, how does it look?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But in the case the focus is on the body (e.g. no focused element) in the modal dialog case, I think we'd want to restore focus as well. It might mean that there was no element to focus within the dialog in the first place.
In this case, the dialog element is focused - I changed this behavior somewhat recently but I don't fully remember what the context was, I can dig it up if you'd like.
However, what if you had multiple modal dialogs open?
If you open one modal dialog and then a second, should closing the first modal dialog attempt to restore focus?
I am OK either way; small atomic commits with separate tests and implementation bugs is reasonable, but so is keeping things together. I'd generally leave it up to @josepharhar. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Editorially LGTM, but given @nt1m's previous review I'd love his explicit signoff too (which should also serve for WebKit implementer interest).
This was implemented in WebKit in https://commits.webkit.org/263645@main |
@josepharhar could you get the tests merged? And maybe file a bug against Gecko? |
WPTs should be merged shortly. Here is a gecko bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1832869 |
@josepharhar I just noticed a small bug here on the spec, the "is modal" check will never be true, since we set is modal to false beforehand. We need to store whether the dialog was modal in a variable and use that. |
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):
The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment)
I opened a spec PR to fix this here: #9391 |
is_modal_ was being checked after the call to SetIsModal(false). This patch caches the value of is_modal_ so that the subsequent modal check actually works as intended. This was pointed out here: whatwg/html#9178 (comment) HTML spec PR: whatwg/html#9178 Change-Id: Ic1bd87f9843bce7016ff672dd73fcc616e41a85c
The value for is modal needs to be cached. This was pointed out here: #9178 (comment).
is_modal_ was being checked after the call to SetIsModal(false). This patch caches the value of is_modal_ so that the subsequent modal check actually works as intended. This was pointed out here: whatwg/html#9178 (comment) HTML spec PR: whatwg/html#9178 Change-Id: Ic1bd87f9843bce7016ff672dd73fcc616e41a85c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4596156 Reviewed-by: Di Zhang <[email protected]> Commit-Queue: Joey Arhar <[email protected]> Cr-Commit-Position: refs/heads/main@{#1159722}
is_modal_ was being checked after the call to SetIsModal(false). This patch caches the value of is_modal_ so that the subsequent modal check actually works as intended. This was pointed out here: whatwg/html#9178 (comment) HTML spec PR: whatwg/html#9178 Change-Id: Ic1bd87f9843bce7016ff672dd73fcc616e41a85c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4596156 Reviewed-by: Di Zhang <[email protected]> Commit-Queue: Joey Arhar <[email protected]> Cr-Commit-Position: refs/heads/main@{#1159722}
…tonly Automatic update from web-platform-tests Fix dialog modal check in Close() is_modal_ was being checked after the call to SetIsModal(false). This patch caches the value of is_modal_ so that the subsequent modal check actually works as intended. This was pointed out here: whatwg/html#9178 (comment) HTML spec PR: whatwg/html#9178 Change-Id: Ic1bd87f9843bce7016ff672dd73fcc616e41a85c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4596156 Reviewed-by: Di Zhang <[email protected]> Commit-Queue: Joey Arhar <[email protected]> Cr-Commit-Position: refs/heads/main@{#1159722} -- wpt-commits: 2f6058492b28367114a9195b97d1e58d8d96fae9 wpt-pr: 40404
…tonly Automatic update from web-platform-tests Fix dialog modal check in Close() is_modal_ was being checked after the call to SetIsModal(false). This patch caches the value of is_modal_ so that the subsequent modal check actually works as intended. This was pointed out here: whatwg/html#9178 (comment) HTML spec PR: whatwg/html#9178 Change-Id: Ic1bd87f9843bce7016ff672dd73fcc616e41a85c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4596156 Reviewed-by: Di Zhang <dizhanggchromium.org> Commit-Queue: Joey Arhar <jarharchromium.org> Cr-Commit-Position: refs/heads/main{#1159722} -- wpt-commits: 2f6058492b28367114a9195b97d1e58d8d96fae9 wpt-pr: 40404 UltraBlame original commit: fa9eb28958aefc0155015024205bdf4c6bb95e0a
…tonly Automatic update from web-platform-tests Fix dialog modal check in Close() is_modal_ was being checked after the call to SetIsModal(false). This patch caches the value of is_modal_ so that the subsequent modal check actually works as intended. This was pointed out here: whatwg/html#9178 (comment) HTML spec PR: whatwg/html#9178 Change-Id: Ic1bd87f9843bce7016ff672dd73fcc616e41a85c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4596156 Reviewed-by: Di Zhang <dizhanggchromium.org> Commit-Queue: Joey Arhar <jarharchromium.org> Cr-Commit-Position: refs/heads/main{#1159722} -- wpt-commits: 2f6058492b28367114a9195b97d1e58d8d96fae9 wpt-pr: 40404 UltraBlame original commit: fa9eb28958aefc0155015024205bdf4c6bb95e0a
…tonly Automatic update from web-platform-tests Fix dialog modal check in Close() is_modal_ was being checked after the call to SetIsModal(false). This patch caches the value of is_modal_ so that the subsequent modal check actually works as intended. This was pointed out here: whatwg/html#9178 (comment) HTML spec PR: whatwg/html#9178 Change-Id: Ic1bd87f9843bce7016ff672dd73fcc616e41a85c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4596156 Reviewed-by: Di Zhang <dizhanggchromium.org> Commit-Queue: Joey Arhar <jarharchromium.org> Cr-Commit-Position: refs/heads/main{#1159722} -- wpt-commits: 2f6058492b28367114a9195b97d1e58d8d96fae9 wpt-pr: 40404 UltraBlame original commit: fa9eb28958aefc0155015024205bdf4c6bb95e0a
…tonly Automatic update from web-platform-tests Fix dialog modal check in Close() is_modal_ was being checked after the call to SetIsModal(false). This patch caches the value of is_modal_ so that the subsequent modal check actually works as intended. This was pointed out here: whatwg/html#9178 (comment) HTML spec PR: whatwg/html#9178 Change-Id: Ic1bd87f9843bce7016ff672dd73fcc616e41a85c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4596156 Reviewed-by: Di Zhang <[email protected]> Commit-Queue: Joey Arhar <[email protected]> Cr-Commit-Position: refs/heads/main@{#1159722} -- wpt-commits: 2f6058492b28367114a9195b97d1e58d8d96fae9 wpt-pr: 40404
The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
rebase rebase Fix modal check in dialog closing algorithm The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
rebase rebase Fix modal check in dialog closing algorithm The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
rebase rebase Fix modal check in dialog closing algorithm The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
rebase rebase Fix modal check in dialog closing algorithm The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
rebase rebase Fix modal check in dialog closing algorithm The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
rebase rebase Fix modal check in dialog closing algorithm The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
rebase rebase Fix modal check in dialog closing algorithm The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
rebase rebase Fix modal check in dialog closing algorithm The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
rebase rebase Fix modal check in dialog closing algorithm The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
rebase rebase Fix modal check in dialog closing algorithm The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
rebase rebase Fix modal check in dialog closing algorithm The value for is modal needs to be cached. This was pointed out here: whatwg#9178 (comment).
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):
Fixes #8904
This patch prevents the behavior where closing a dialog focuses the previously focused element from before the dialog was opened only if focus is in the dialog when the dialog closes.
Without this, focus can unexpectedly shift away from an element which is not going away, like a text input that the user is currently typing into for example.
(See WHATWG Working Mode: Changes for more details.)
/interactive-elements.html ( diff )