From 27cdd49d71f69022eb921d1b9301acd2e36de66e Mon Sep 17 00:00:00 2001 From: Florian Rivoal Date: Tue, 20 Mar 2018 16:04:35 +0900 Subject: [PATCH] Remove the spatial-navigation property Whether spatnav should get invoked from arrow keys or something else is for the UA to decide, and we don't need (at least in this level) to provide control over it. This also lets us get rid of the monkey-patch on UI-Events. Closes #35 Also closes #22, #24, and #26 (as invalid / out of scope) by deleting the section these issues applied to. --- index.bs | 327 ++++++++++++++++++++++--------------------------------- 1 file changed, 133 insertions(+), 194 deletions(-) diff --git a/index.bs b/index.bs index 880e62e1..9de01c23 100644 --- a/index.bs +++ b/index.bs @@ -23,6 +23,7 @@ spec: html; urlPrefix: https://html.spec.whatwg.org/multipage/; text: focusable area text: currently focused area of a top-level browsing context text: sequential focus navigation order + text: sequential focus navigation starting point text: sequential navigation search algorithm text: control group urlPrefix: dom.html @@ -74,17 +75,16 @@ depending on their position allowing it to address problems encountered with sequential navigation.
- An image about enabling spatnav + When elements are layed out in a grid pattern, spatial navigation makes it much easier to predict and control where focus should move to.
Application using a grid-like layout.
While arrow keys are naturally suited to control spatial navigation, -pressing them (on devices that have such keys) -has generally triggered other behavior, -such as scrolling. -This specification introduces CSS properties and JavaScript APIs -enabling authors to turn on spatial navigation using arrow keys -and to control its behavior. +no previous specification describes how that should work, +or how it may be controled. +This specification introduces a processing model for spatial navigation, +as well as APIs +enabling authors to control and override how spatial navigation works. Some aspects of this specification, such as the JavaScript Events, also extends how sequential navigation work, @@ -119,8 +119,10 @@ Overview This section is not normative. -When spatial navigation is active, -pressing an arrow key will either +Using a UA-defined mechanism +(typically arrow keys, possibly in combination with modifier keys like Shift or Control), +the user may ask the User Agent to navigate in a particular direction. +This will either move the focus from its current location to a new focusable item in the direction requested, or scroll if there is no appropriate item. @@ -155,7 +157,8 @@ scrolled, or reached the root. Additionally, when the user has focused a scroll container which contains focusable elements, -the user may move the focus to the nested elements by pressing Enter. +the user may ask the User Agent to move the focus to the nested elements +(for instance by pressing Enter). The User Agent will then follow a similar logic: first, search for visible and focusable items within the currently focused scroll container, @@ -185,9 +188,11 @@ element of the author's choosing. See [[#events-nav-type]] for details about the various events.
- In this example, a series of elements are arranged in the spatial navigation focus container. - This example allows the arrow keys to move focus among elements within a scrollable spatial navigation focus container - using the 'spatial-navigation' property. + In this example, shows how a series of focusable elements + arranged in a scrollable element + would be navigated when using spatial navigation. + For the sake of keeping the description simple, + this example assumes a UA where spatial navigation is triggered using arrow keys.
An image about enabling spatnav using active value @@ -218,7 +223,6 @@ See [[#events-nav-type]] for details about the various events. height: 700px; overflow-x: hidden; overflow-y: auto; - spatial-navigation: active; } .box { @@ -245,53 +249,6 @@ See [[#events-nav-type]] for details about the various events.

Controlling spatial navigation through declarative means

-

-Activating Spatial Navigation: the 'spatial-navigation' property

- -Spatial navigation is said to be available -when there is a mechanism available to the user to invoke spatial navigation. - -Spatial navigation is said to be active on an element -when the user can invoke spatial navigation -by pressing the arrow keys without modifier keys -when that element is focused. - -The 'spatial-navigation' property enables the author to declare -that their document, or part of their document, -has been authored with spatial navigation in mind, -and the User Agent can make spatial navigation active -to avoid risk of interfering with other behavior. - -
-Name: spatial-navigation
-Value: auto | active
-Initial: auto
-Inherited: yes
-
- - -
-
auto -
The User Agent defines - whether spatial navigation is available, - and if so, which UI mechanisms may trigger the spatial navigation steps - (e.g. certain key combinations, gestures, buttons in the UI, voice commands…). - - On devices which do not have any pointing input device, - and especially on devices such as TVs which also lack a Tab key to control - sequential focus navigation, - User Agents should make spatial navigation active. - -
active -
The User Agent must make spatial navigation active - on the element. - - Additionally, User Agents which make spatial navigation available - by other mechanisms - when the value of 'spatial-navigation' is ''spatial-navigation/auto'' - must continue to do so. -
-

Establishing focus navigation containers: the 'spatnav-container' property

@@ -804,159 +761,122 @@ and aims for as much detail as necessary to fully define the behavior. This includes integration with sequential navigation. -Note: Much of section is monkey patches on other specs, -and should in the long term be integrated back into them. -This is all specified here for now in order to explore and incubate -this topic. - Issue(19): The following currently does not account for the proposed overscroll-behavior specification. Issue(21): The following does not take shadow dom into account. -

-Handling key presses

+

+Triggering Spatial Navigation

-
+When the user triggers spatial navigation in a given direction, +the User Agent must run the spatial navigation steps in that direction. -Issue(22): This should be an extension of [[!UI-EVENTS]]'s processing model -but [[UI-EVENTS]] does not have a fully defined processing model. -It does define the events, but does not define the algorithm which -is supposed to dispatch them and respond to cancellation and so on. -Therefore, this is being written as (a rough sketch of) what that -model should be. -Once this is sufficiently detailed and tested, this should be turned into -a pull request against [[UI-EVENTS]]. +This specification does not define what UI mechanism User Agents should offer to users to trigger spatial navigation. +This intentionaly left for User Agents to decide. -There is a navigation starting point, initially unset. -The user agent may set it when the user indicates that it should be moved. +
Note: + It is expected that User Agents on devices with limited input capabilities, + such as TVs operated with a remote control, + or devices operated with a game controller, + will use spatial navigation as their primary or exclusive navigation mechanism. +
-Note: The user agent could set it to the position of the user's click if the user clicks on the document contents. - -Issue(23): The focusing steps should probably reset the navigation starting point - -When the user presses a key on the keyboard, -the following steps are run to react to key presses. - -1. Let eventTarget be the DOM anchor of the currently focused area of a top-level browsing context. -2. If eventTarget is the Document of the top-level browsing context - set eventTarget to the body element if it is not null or - to the document element otherwise. -3. If the navigation starting point is not null - and it is a descendant of eventTarget - then let startingPoint be the navigation starting point, - else let startingPoint be eventTarget. -4. Fire an event named keydown at eventTarget - using {{KeyboardEvent}} with its arguments initialized as per [[UI-EVENTS#event-type-keydown]] - and let actOnKeyPress be the result. -5. If actOnKeyPress is false, return -6. If the element is an editing host or a descendent of one, - or a <{textarea}> element, - or an <{input}> element comprising a text control - then… - - Issue(24): …invoke beforeinput events, execcommand, IMEs, input events, and numerous details…
- However, a key point here is that if the caret is at the beginning (resp. end) of the content, - and the user presses an arrow key to go up or left (resp. down or right), - and there's no IME or similar thing consuming that key, - then we should jump to point 11.1 -7. Else if the key is .... and the modifiers are ..., then .... -8. Else if the key is enter - * If the eventTarget has an activation behavior, - 1. Fire an event named click at eventTarget - using {{MouseEvent}} with its arguments initialized as per [[UI-EVENTS#click]] - and let actOnClick be the result. - 2. If actOnClick is false, return - 3. Initiate the activation behavior (See [[UI-EVENTS#event-flow-activation]]) then return. - - * Else, if spatial navigation is active on eventTarget - and eventTarget is a scroll container, - run the navigation steps on eventTarget in direction inside, - then return -9. Issue(24): … more of the same, handling all sorts of keys in various situations … -10. Else, if the {{KeyboardEvent/key}} is "Tab" - and all of {{KeyboardEvent/ctrlKey}}, {{KeyboardEvent/altKey}} and {{KeyboardEvent/metaKey}} are false, - run the navigation steps on eventTarget from startingPoint - in the forward direction if {{KeyboardEvent/shiftKey}} is false - or in the backward direction if it is true, - then return -11. Else, if the {{KeyboardEvent/key}} is one of ArrowUp, ArrowDown, ArrowLeft, or ArrowRight: - 1. Let dir be: - * up if the {{KeyboardEvent/key}} is ArrowUp - * down if the {{KeyboardEvent/key}} is ArrowDown - * left if the {{KeyboardEvent/key}} is ArrowLeft - * right if the {{KeyboardEvent/key}} is ArrowRight - - 2. If eventTarget is a (form) control that reacts to arrow keys, - do that then return - - Issue: define a nice hook so that elements can be specified to react to arrow keys - 3. Else, if eventTarget is a scroll container that can be manually scrolled in dir - directionally scroll the element eventTarget in the direction dir - then return. - - Note: Due to [[CSS-OVERFLOW-3#overflow-propagation]], the body element and the document element of the top-level browsing context - are typically not scroll containers; - the viewport is. - Therefore, in the simple case - where there is no unusual setting of the 'overflow' property on these elements, - and where no element in particular was focused and - eventTarget was set to the body element or the document element of the top-level browsing context in steps 1 & 2, - the condition of this step is not matched, - and we fallback to the next step. - 4. Else, if spatial navigation is active on eventTarget - run the navigation steps on eventTarget in direction dir from startingPoint, - then return - 5. Else, let ancestor be the nearest ancestor of startingPoint that is a scroll container that can be scrolled manually, - including in an ancestor browsing contexts, - or null if no such element can be found. - - If ancestor is null, - return, - otherwise directionally scroll the element ancestor in the direction dir - then return. - - Issue(26): This is how Chrome and Safari do it. - Firefox only looks at the first ancestor of startingPoint, - and if that cannot be manually scrolled, - it stops there rather than looking further up the ancestry chain. +Although it is possible for User Agents +to implement the processing model and APIs defined by the specification +without giving any direct means to the user to trigger spatial navigation themself, +this specification recommends not to do so: +User Agents should offer a means for users to trigger spatial navigation directly, +without having to use the APIs. + +Regardless of the actual mechanism chosen to trigger spatial navigation, +the following requiremnts apply: +* If the mechanism the user must use to trigger spatial navigation + would normally fire a {{UIEvent}}, + then that event must be fired prior to running the spatial navigation steps + and these steps must not be run if that event's canceled flag + gets set. + +
+ Gaming devices may trigger spatial navigation based on pressing the D-pad. + This would result in firing a keydown event + with the key set to one of + ArrowDown, + ArrowLeft, + ArrowRight, + or ArrowUp, + followed if not canceled by running the spatial navigation steps, + including firing the relevant {{NavigationEvent}}s. + + A User Agent on a desktop computer that triggers spatial navigation + using the arrow keys of the keyboard + would follow the same sequence. +
+* If the mechanism the user must use to trigger spatial navigation + would in some contexts trigger other actions, + the User Agent should in these contexts + give priority to these other actions + and execute them instead of spatial navigation. + It must not trigger both. + +
+ In a User Agent that triggers spatial navigation + using the arrow keys without modifier keys, + and uses these same arrow keys to move + the text insertion caret when an editable element is focused, + the arrow keys should by default to moving the caret. + Spatial navigation would only be triggered by the arrow keys + when the focused element is not editable, + or when it is editable but the caret cannot move any further in the requested direction. +
+ + An exception is made for scrolling: + since spatial navigation itself handles scrolling + (in addition to moving the focus) + User Agents should not offer the same mechanism to trigger both spatial navigation + and a scrolling behavior separate from spatial navigation. + UAs may however, offer a way for the user to switch between different modes, + or offer both based on different UI mechanism. + +
+ A User Agent may have a setting to let the user choose + between using the arrow keys without modifier keys + for spatial navigation or for scrolling. + Another one may offer scrolling on arrow keys without modifiers, + and spatial navigation on arrow keys when pressed together + with the Shift key, + or on the W A S D keys. + Offering only spatial navigation or only scrolling + as responses to pressing arrow keys would also be possibilities. +
-
-
-To run the navigation steps in direction on eventTarget from startingPoint, do the following: - -* If direction is forward or backward, - run step 1 through 9 of the HTML steps for sequential navigation, - with one change: - between step 5 and 6, add the following: - - > 5.5. if candidate is not null, - > Fire an event named navbeforefocus at eventTarget using {{NavigationEvent}} - > with its {{NavigationEvent/dir}} set to direction and {{NavigationEvent/relatedTarget}} set to candidate - > and return if the result is false - > - > Issue(27): This is a monkeypatch on [[HTML]]. - > Eventually this should be upstreamed: - > modify the steps as described here, - > and give them a name (“the sequential navigation steps”?) so that they can be invoked. +There can be a spatial navigation starting point. It is initially unset. +The user agent may set it when the user indicates that it should be moved. - Then, return. +Note: For example, the user agent could set it to the position of the user's click if the user clicks on the document contents. -* Else if direction is inside, - run the navigate inside steps on eventTarget, +If the UA sets both a spatial navigation starting point and a sequential focus navigation starting point, +they must not be set differently. -* Else (assert: direction is one of up, down, left, or right), - run the spatial navigation steps in direction from startingPoint. - -
+Issue(23): The focusing steps should probably reset the spatial navigation starting point
-To run the spatial navigation steps in direction from startingPoint, do the following: +To run the spatial navigation steps in direction, do the following: + +1. Let startingPoint be the DOM anchor of the currently focused area of a top-level browsing context. +2. If startingPoint is the Document of the top-level browsing context + set startingPoint to the body element if it is not null + or to the document element otherwise. +3. If the spatial navigation starting point is not null + and it is a descendant of startingPoint + then set startingPoint to the spatial navigation starting point +4. If the direction is inside, + then run the navigate inside steps on startingPoint. 1. Let eventTarget be startingPoint if startingPoint is an element, or let eventTarget be the element which contains startingPoint if startingPoint is a position. @@ -1037,6 +957,25 @@ To run the navigate inside steps on eventTarget, do the fo
+For consistency between sequential focus navigation and the model defined above, +the following is also defined: + +
+To run the sequential navigation steps +run step 1 through 9 of the HTML steps for sequential navigation, +with one change: +between step 5 and 6, add the following: + +> 5.5. if candidate is not null, +> Fire an event named navbeforefocus at eventTarget using {{NavigationEvent}} +> with its {{NavigationEvent/dir}} set to direction and {{NavigationEvent/relatedTarget}} set to candidate +> and return if the result is false +> + +Issue(27): This is a monkeypatch on [[HTML]]. +Eventually this should be upstreamed. +
+

Focus Navigation Heuristics