-
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
Improve autofocus and delegatesFocus interaction #6990
Conversation
Now, when focusing a shadow host with delegates focus set, we try to focus the first focusable area with the autofocus attribute set, instead of just the first focusable area. Closes #833.
Looks good! I've filed the bug for Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1728864 |
Ping @mfreed7 for review and maybe tests if he's up for writing them :) |
I'll start working on the Firefox implementation for this shortly, and I can write the tests along the way. |
|
||
<ol> | ||
<li><p>Set <var>potential autofocus delegates</var> to the list of all <span>click | ||
focusable</span> <span data-x="focusable area">focusable areas</span> whose <span>DOM |
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.
Shadow host with delegateFocus = true
is not a focusable area right, so we won't try to delegating the focus to the inner shadow DOM for hosts that have autofocus
+ delegatesFocus = true
?
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.
Hmm, you are right. And that is consistent with the existing behavior where you can't delegateFocus to a delegatesFocus shadow root. And you cannot delegatesFocus to an area element's shapes, either, I guess. Because we strictly look for focusable areas when assembling possible focus delegates / possible autofocus delegates.
But that feels a bit weird. Maybe we should fix that, both for the existing case and for this new case? WDYT?
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.
Right now, we look for focusable area
in the flat tree, so we are able to delegate the focus to an inner shadow DOM with delegatesFocus.
So something like this https://jsfiddle.net/8t297ekp/ works. Do I misunderstand something?
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 am not sure; I think I might be confused too. In your example, innerHost
is not a focusable area, right? Only the <input>
is. So it doesn't matter where innerHost
is delegatesFocus or not, right? When you try to focus host
, It just finds the <input>
as a flat tree child and focuses that instead, I think...
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.
That sounds right. How about an example like this https://jsfiddle.net/41e0zhqn/1/?
I think we'd want the innerInput
to be focus, however with the current PR, it won't because nothing will be added to the possible autofocus delegates
, so we go through possible focus delegates
, thus the outerInput
is 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.
Yes, I agree. I can imagine roughly the following paths to solving this:
-
Make potential autofocus delegates only care about the
autofocus
attribute, and not care about focusable area-ness. -
Make potential autofocus delegates include delegatesHost shadow hosts via a one-off addition. I.e. set it to what it currently is plus any descendant delegatesFocus shadow hosts.
-
Make potential autofocus delegates computation smarter, by having it look at all descendants, call "get the focusable area", and if the result is non-null store it in potential autofocus delegates.
-
Try to use the flat tree somehow instead of the DOM tree? That was my original approach but @rniwa pointed out in Improve autofocus and delegatesFocus interaction #6990 (comment) that it didn't work that well. I wonder if there's something smarter we can do that lets us stay more symmetric with the non-autofocus case, but I can't think of what that would be.
I think (3) is probably best. WDYT?
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.
So I think rniwa's concern was if we have a DOM like this
<div #host> (delegatesFocus = true)
#shadowRoot
<div #innertHost>
#shadowRoot
<input autofocus #innerInput>
<input autofocus #outerInput>
We'd want #outerInput
to be focused, so we don't want to use a flat tree?
(3) also sounds the best to me, however, I think we still need to make sure the above example works?
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 think I pushed a version of (3) and I believe it works for that case as well. PTAL!
<ol> | ||
<li><p>If <var>descendant</var> does not have an <code | ||
data-x="attr-fe-autofocus">autofocus</code> content attribute, then | ||
<span>continue</span>.</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.
Hmm....So we don't consider inner elements if the ancestor doesn't have autofocus
. For a case like this
<div #host> (delegatesFocus = true)
<input #outerInput>
#shadowRoot
<div #innertHost>
#shadowRoot
<input autofocus #innerInput>
outerInput
is going to be focused, is this expected...?
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 that is the desired behavior, although it'd be good to have @rniwa confirm. The way I think about it is that at a per-shadow-tree level, by default you focus the first focusable area, but you can put autofocus
on something specific to override it. Since there's no autofocus in the first level (i.e. in the shadow-including children of #host
), we focus #outerInput
.
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.
Sorry for the long delay reviewing this. After reading and re-reading, I think the last comment (and the current state of the spec text) feels right. The delegatesfocus
attribute applies to each shadow host individually, and does not "cascade" into contained shadow roots. I like the recursive use of "get the focusable area". So LGTM.
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.
Got it, I agree, that makes sense to me.
<ol> | ||
<li><p>If <var>descendant</var> does not have an <code | ||
data-x="attr-fe-autofocus">autofocus</code> content attribute, then | ||
<span>continue</span>.</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.
Sorry for the long delay reviewing this. After reading and re-reading, I think the last comment (and the current state of the spec text) feels right. The delegatesfocus
attribute applies to each shadow host individually, and does not "cascade" into contained shadow roots. I like the recursive use of "get the focusable area". So LGTM.
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.
Looks good editorially, apart from one sentence that should be addressed before landing. But approving to make that easier.
source
Outdated
<li><p>Return the first <span>focusable area</span> in <span>tree order</span> of their <span | ||
data-x="DOM anchor">DOM anchors</span> in <var>possible focus delegates</var>, or null if |
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.
"of who their" and "are in"?
Great, this is ready to land except for tests then. @sefeng211 any progress on those? |
I just finished the patch for Firefox (which includes the tests). It's under review, hopefully, it'll be landed soon. |
Spec: whatwg/html#6990 Differential Revision: https://phabricator.services.mozilla.com/D128301 bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1728864 gecko-commit: d3034ec3376b62837afd4ee95acb18373d0143df gecko-reviewers: smaug
…ates focus r=smaug Spec: whatwg/html#6990 Differential Revision: https://phabricator.services.mozilla.com/D128301
Spec: whatwg/html#6990 Differential Revision: https://phabricator.services.mozilla.com/D128301 bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1728864 gecko-commit: d3034ec3376b62837afd4ee95acb18373d0143df gecko-reviewers: smaug
…ates focus r=smaug Spec: whatwg/html#6990 Differential Revision: https://phabricator.services.mozilla.com/D128301
Spec: whatwg/html#6990 Differential Revision: https://phabricator.services.mozilla.com/D128301 bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1728864 gecko-commit: d3034ec3376b62837afd4ee95acb18373d0143df gecko-reviewers: smaug
Now, when focusing a shadow host with delegates focus set, we try to focus the first focusable area with the autofocus attribute set, instead of just the first focusable area.
Closes #833. Note that this implements (2) from #833 (comment) , not (1).
(See WHATWG Working Mode: Changes for more details.)
/infrastructure.html ( diff )
/interaction.html ( diff )