[focusgroup] Add the focusgroup attribute #11723
[focusgroup] Add the focusgroup attribute #11723janewman wants to merge 127 commits intowhatwg:mainfrom
Conversation
|
Opening up for review, but please keep in mind this is an early draft. |
|
@annevk, during TPAC you expressed interest in taking a look at this draft spec change - I would really appreciate any feedback you had as I work to move this towards something we think accurately captures the behavior and fits in with the existing logic. |
|
It is unclear to me what happens if the page has keydown, or keyup event listener and calls preventDefault() when arrow key is used. Which event listener has some affect and which doesn't? |
…ng section, improve segment definition with example, and simplify key conflict element handling
I've added a new section that should answer all of these questions, please let me know what you thank and if it still isn't clear. |
…talled event See whatwg#12145 (comment) for context.
This change allows select elements with the multiple attribute to be rendered as a drop-down box when the author explicitly sets the size attribute to 1. The related issue should be resolved by suggesting that mobile browsers and desktop browsers both follow these rules in order to improve cross-platform compatibility. Fixes whatwg#8189.
This aligns `ancestorOrigins` exposure with referrer policy when using the `iframe referrerpolicy` attribute, so an embedder can prevent revealing its own origin to embedded documents. If an `<iframe>` uses `referrerpolicy="no-referrer"` or `same-origin` (and the parent and child are cross-origin), the parent’s origin and any same-origin ancestors are replaced with opaque origins (until reaching an ancestor that is cross-origin). Other policies continue to expose full origins. This approach keeps existing behavior by default (for web compat) while addressing privacy concerns with an opt-out. The algorithm reuses the parent's existing list of ancestor origins, avoiding synchronous cross-process lookups and ensuring a stable snapshot even if ancestors mutate their `referrerpolicy` attributes later. Fixes whatwg#1918. Closes whatwg#2480.
Instead of having a "scripting flag" and then "fixing" scripts in createContextualFragment(), change "scripting flag" to an enum for clarity.
See https://github.com/whatwg/spec-factory for details.
Currently per spec, #update-the-navigation-api-entries-for-a-same-document-navigation will be called in different order to the #wait-for-all navigation handler list depending on if the navigation is intercepted or not. This is not ideal, but even more so, in case of a "traverse" navigation, the callback passed to the #wait-for-all and the might be called before the call to #update-the-navigation-api-entries-for-a-same-document-navigation has happened. This means that we'll run the finish steps with the wrong session history entry. Since all same document navigations, intercepted or otherwise, eventually call #update-the-navigation-api-entries-for-a-same-document-navigation we can ensure that we never run the navigation handlers with bad state. This patch also reverts the patch that introduced always having a method tracker, since that was intended to solve this issue but failed doing so. Fixes whatwg#12222, fixes whatwg#12165. Reverts whatwg#11814.
* Markup: For some `data-x="attr-input-{max,min}"`, change `attr` to `concept`
* Punctuation: Insert a couple periods
* Punctuation: Change colon to period
…attribute Specify support for the loading attribute for the video element and audio element using similar conventions to img and iframe, where the attribute already has precedent. Loading has possible values of eager and lazy. When a media element's loading attribute value is lazy, loading of any video or poster image data, as well as autoplay playback, will defer until layout is known and the video is in the viewport. Fixes whatwg#10376 Fixes whatwg#6636
Key changes: - Rename 'no-memory' token to 'nomemory' (unhyphenated, matching explainer) - Add 'nowrap' modifier token for explicitly disabling wrapping - Add default modifiers per behavior token (toolbar→inline, tablist→inline wrap, menu→block wrap, menubar→inline wrap) - Add default modifiers column to behavior tokens table - Add text explaining how default modifiers work and interact with explicit modifiers - Update ARIA Role Inference to document <button> child role inference eligibility (buttons are the most common composite widget item) - Add note that aria-orientation is not inferred from inline/block - Add note about reading-flow CSS property interaction with both sequential and directional navigation - Update directional navigation algorithm to reference effective modifiers (including defaults) - Update wrap check in navigation algorithm to account for nowrap and default modifiers - Replace toolbar example with proper tablist example showing default modifiers, focusgroupstart, child role inference, and tab panel association - Add menubar/menu nested focusgroup example demonstrating independent nested focusgroups with default axis/wrap behavior Co-authored-by: Copilot <[email protected]>
- Reword key conflict element definition to emphasize native/built-in arrow key behavior (UA-determined), not author-scripted handlers - Add note with author guidance for scripted key conflicts: use focusgroup='none', limit axis, or activation/escape pattern - Fix scrolling conflict scenario to reference key conflict escape behavior and clarify that only focusable scrollable regions (UA-determined) are affected Co-authored-by: Copilot <[email protected]>
# Conflicts: # source
|
@smaug----, @annevk, I would love to get your thoughts on the latest iteration, friendly ping for review, I appreciate your time. |
When an element enters the document's top layer (e.g., a popover shown via showPopover(), a modal dialog, or a fullscreen element), exclude it and its shadow-including descendants from any ancestor focusgroup scope. Changes: - focusgroup scope: exclude top-layer elements and their shadow-including descendants (qualified so the owner's own focusgroup is unaffected) - focusgroup segment: top-layer subtrees create segment boundaries - entry element algorithm: last-focused-item is ineligible while its subtree is in the top layer - clearing conditions: exception preserves last-focused-item when scope exit is solely due to top-layer membership - new "Top layer interaction" section with normative prose and examples Co-authored-by: Copilot <[email protected]>
Align the top-layer segment boundary clause with the focusgroup="none" clause by requiring the top-layer element to be sequentially focusable. This matches the Chromium implementation, which only creates segment boundaries for excluded subtrees containing focusable content. Co-authored-by: Copilot <[email protected]>
annevk
left a comment
There was a problem hiding this comment.
I'm also missing the WebDriver integration piece.
|
|
||
| [<span>CEReactions</span>, <span data-x="xattr-Reflect">Reflect</span>] attribute boolean <dfn attribute for="HTMLOrSVGElement" data-x="dom-fe-autofocus">autofocus</dfn>; | ||
| [<span>CEReactions</span>, <span data-x="xattr-ReflectSetter">ReflectSetter</span>] attribute long <span data-x="dom-tabindex">tabIndex</span>; | ||
| [<span>CEReactions</span>, <span data-x="xattr-Reflect">Reflect</span>] attribute DOMString <dfn attribute for="HTMLOrSVGElement" data-x="dom-focusgroup">focusgroup</dfn>; |
There was a problem hiding this comment.
This is something I considered, but felt that the behavior-first ordering and modifier pattern felt like it might not fit into the patterns that other attributes that use DOMTokenList have today.
This is not a strong opinion, so if you feel that DOMTokenList is a much better fit for this use case, I'd be OK with changing this.
- Rename IDL properties: focusgroup → focusGroup, focusgroupStart → focusGroupStart - Rename concept terms: 'focusgroup item/owner/scope/segment' → 'focus group ...' - Revert wrong punctuation change (. not ;) in focusable area conditions - Replace 'store' with 'set' per spec conventions - Remove duplicate note about memory/focusgroupstart - Add cross-reference for 'set of space-separated tokens' - Add terminal punctuation on list items - Fix 'effective modifiers' cross-reference - Fix 'focus group owner of' data-x slug in algorithms - Move last focused item dfn to concepts section - Move domintro entries after their attribute dfns - Move focusGroupStart domintro to focusgroupstart section Co-authored-by: Copilot <[email protected]>
- Fix radiogroup/listbox default modifiers (wrap, block) - Add token case-sensitivity statement (ASCII case-insensitive) - Fix entry element top-layer check with owner-descendant qualifier - Disambiguate tabindex-ordered scope conjunction - Add clearing condition for focusgroup attribute removal - Fix tree order → shadow-including tree order - Add empty items guard in directional navigation - Fix toplayer parenthetical and Tab reachability explanation - Add AT browse mode note and aria-orientation example - Add missing 'then' in If-conditionals - Change ul to ul class=brief for key conflict list - Fix redundant key conflict element re-definition - Tighten focus group owner definition - Fix scope definition wording precision Co-authored-by: Copilot <[email protected]>
On macOS, Safari does not include button elements in the tab order by default without Full Keyboard Access enabled. Adding explicit tabindex="0" ensures the examples work cross-platform and matches the approach taken in the WPT tests. Co-authored-by: Copilot <[email protected]>
I'm still looking into what we can do here. Regarding having WebDriver toggle the MacOS keyboard setting, I've reached out to James Craig who I've worked with in aria and WPT regarding our options here, waiting to hear a response. In the meantime, I've adjusted all WPTs to accommodate, with all buttons having a tabindex of 0 manually set. |
#11641
This adds the
focusgroupattributes needed to allow for declarative focus navigation using the directional navigation (arrow keys, d-pad).This specs the behavior detailed in the explainer on OpenUI.
/dom.html ( diff )
/index.html ( diff )
/infrastructure.html ( diff )
/interaction.html ( diff )