Skip to content
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

Let web developers signal their "DPAD mechanics" #1049

Closed
hugoholgersson opened this issue Sep 6, 2019 · 5 comments
Closed

Let web developers signal their "DPAD mechanics" #1049

hugoholgersson opened this issue Sep 6, 2019 · 5 comments
Labels

Comments

@hugoholgersson
Copy link

Background

When users browse the web on their TV, the remote's directional pad, "the DPAD" (usually 4 arrow keys), is often the only input device available.

Most web apps have custom JS to move focus upon DPAD (or, more generically, arrow key) input. However, Chromium's built-in "focus moving logic", Spatial Navigation, has become better the last few years so app authors might now choose to offload their JS' "focus movement"-logic to the browser.

General problem

A browser cannot know if a web app has either:

  1. Built-in JS logic for directional focus movements (YouTube TV and others).
  2. No built-in JS logic that moves focus (probably not a TV app).
  3. No built-in JS logic that moves focus but works well with Spatial Navigation.

Accessibility problem

Some screen readers, such as TalkBack on Android TV, walk web pages sequentially, even if the app has its own DPAD-logic in JavaScript.

When TalkBack reads a TV web app with built-in DPAD support, TalkBack moves focus sequentially (think Tab/Shift+Tab) even though the web app has its own DPAD-logic. => The web app's UX degrades from 2D to 1D directional navigation only because the user enabled her screen reader!

Suggestion

An attribute, for now let's call it dpad, that gives the browser (and screen readers) a hint about how the author expects focus movement/highlighting to happen:

Example:

(1) <body dpad="js">       <!-- This app moves and highlights focus in its own ways. -->
(2) <body dpad="default">  <!-- The browser (or a screen reader) _may_ move and highlight focus. -->
(3) <body dpad="browser">  <!-- The app _requests_ Spatial Navigation to move and highlight focus. -->

Here the attribute indicates how navigation is supposed to work within the document.
Most TV apps use one strategy for the entire app so the primary (or only?) use case would be to put the attribute on the document <body>.

In all cases, a screen reader may still emphasize activeElement the way TalkBack does with its green rectangle above the web content. A rectangle on top of the content, rendered outside the browser, is fine because it will not conflict with the web page's :focus CSS.

Follow-up

<body dpad=".."> is the primary use case but, as a follow-up, <div dpad=".."> could be a hook for web developers (or custom element developers) to control focus management within widgets (DOM sub trees).

Possible implementation

When activeElement is within a dpad="js" / "browser" sub tree, the browser could expose a one-node accessibility tree that only consists of activeElement. This would force screen readers to only speak about activeElement, keep it from navigating elsewhere and, instead, let the DPAD/arrow key events through to the web page.

@jnurthen
Copy link
Member

Can you explain how this is different to role=application?

Note - we really try not to encourage use of role=application as it makes it much more difficult to use many of the ways that screen reader users use to navigate pages.
From what I understand of this request it sounds like you want a more locked down version of role application. My personal opinion is that I think this would be resisted by users due to the massive potential for misuse.

@hugoholgersson
Copy link
Author

Thanks. I didn't know of role=application. I guess TV apps like YouTube TV should use this role?

Can you explain how this is different to role=application?

Yeah. What I request is a way for authors to not only hint "we're handling focus movements on our own" (role=application) but also 1) hint how focus movements are handled so 2) for dpad="browser", actually trigger the browser to go into Spatial Navigation mode. 1) and 2) are implementation details the screen reader doesn't need to know about.

From what I understand of this request it sounds like you want a more locked down version of role application.

role=application sounds like a good thing. I don't want to change it. I think my suggestion, since it's not only describing the content but also potentially triggers Spatial Navigation, makes more sense in another spec. A screen reader doesn't need to know how focus movements are implemented by the app.

Note - we really try not to encourage use of role=application as it makes it much more difficult to use many of the ways that screen reader users use to navigate pages.

Understood. role=application means the author must take full responsibility for focus movements.

Imagine dpad becomes standardized elsewhere... If role is not already set, then I guess dpad should give role an implicit value:

dpad= role=
js application
default unchanged
browser application

Does that make sense? (There's no new, locked down, role here so the risk of misuse is the same.)

@pkra
Copy link
Member

pkra commented Sep 11, 2019

A screen reader doesn't need to know how focus movements are implemented by the app.

I think that's not the case.

The following may be too far apart from what @hugoholgersson has in mind but let me write it down and if it turns out to be off-topic, I'll hide the comment.

I'm quite interested in the topic of "something less extensive than role=application". That is, ways to provide AT with more information about the content structure and preferred navigation as intended by an author while keeping AT's ability to override where needed.

An existing example are table walkers provided by most screenreaders. They allow two dimensional navigation as opposed to the linear reading modes and positional information, purely from HTML markup (in particular, no JS).

An example of a role that I think could become or lead to another example would be role=tree. That is, AT could provide treewalkers much like it provides table walkers (e.g., depth-first, breadth first).

I like role=tree because it is already an example of slowly reducing authoring complexity: setting active-descendant vs moving tabindex, creating aria-setsize, aria-posinset, aria-level vs browsers calculating those automatically. In the light of this history, it does not seem too far fetched to work across the stack to ensure AT can provide basic tree navigation while allowing authors to nevertheless do fancier (optional) navigation via JS (e.g., cyclical navigation on a tree level can be very helpful in SVG content).

@hugoholgersson
Copy link
Author

A screen reader doesn't need to know how focus movements are implemented by the app.

I think that's not the case.

Thanks for the feedback but let's try to keep this discussion about role=application. For role=application, isn't it enough for the screen reader to passively receive events about where focus went (it does not need the logic behind why focus moved the way it did)?

I'm quite interested in ... ways to provide AT with more information about the content structure and preferred navigation as intended by an author.
An existing example are table walkers provided by most screen readers. They allow two dimensional navigation as opposed to the linear reading modes and positional information, purely from HTML markup (in particular, no JS).

Chrome's Spatial Navigation can walk tables, and many other structures, just fine (but it can only jump between focusables!). Chrome's Spatial Navigation is really just heuristics for finding the closest, focusable element up/down/left/right of current focus. Sure, SpatNav's output could probably be valuable to screen readers in a broader context but not when it comes to dpad=browser (⇒ role=application)? dpad=browser, as I imagine it, would let Spatial Navigation walk the widget (offloading the screen reader) so the screen reader would only have to listen for focus changes and describe each focus move (just after it happened). Does that make sense?

@pkra
Copy link
Member

pkra commented Sep 27, 2019

We discussed this issue on the ARIA WG call on Sept 26.

It's not clear to the WG how this issue relates to ARIA. The problem appears to be primarily about how Assisitive Technology focus management interacts with the CSS spatial navigation spec.

We would suggest to perhaps start a discussion on the spatial navigation end so as to identify issues that relate to accessibility in general and ARIA (or related) specs in particular. In fact, there already has been some discussion around (the trouble of) focus managment, cf. w3c/csswg-drafts#3379 which seems like a good place to continue fleshing out this problem.

@pkra pkra removed their assignment Sep 27, 2019
@pkra pkra added the question label Sep 27, 2019
hugoholgersson added a commit to hugoholgersson/talkback that referenced this issue Oct 18, 2019
Background:
Within <xxx role=application>...</xxx>, screen readers
should not consume DPAD (arrow key) events. Web apps or
widgets with role=application have, per the WAI-ARIA
spec's contract, their own JavaScript logic for moving
focus [1].

[1] w3c/aria#1049, where we
discussed this.

Problem:
TalkBack does not handle role=application so such web apps
loose their 4-way (up/down/left/right) navigation.
TalkBack only moves foward/backward which breaks authors'
pre-defined TV UX.

Solution:
Whenever accessibility focus (the green rect) goes to a
WebView with <body role=application> or anywhere within
a role=application widget, we don't consume the DPAD
events; we let them through.

Testing done:
From TalkBack's test app, open dpad_a11y.html
which has <body role=application>.
Notice:
 I. Once the WebView gets accessibilty focus,
    TalkBack won't consume DPAD key events.
 II. The key events reach the web page's key
     handlers in JavaScript.
 III: TalkBack describes HTML elements once
      they get focused.

Change-Id: I6110ec8adec1e827ee523559e08dc3f79c5ca515
Signed-off-by: Hugo Holgersson <[email protected]>
hugoholgersson added a commit to hugoholgersson/talkback that referenced this issue Oct 18, 2019
Background:
Within <xxx role=application>...</xxx>, screen readers
should not consume DPAD (arrow key) events. Web apps or
widgets with role=application have, per the WAI-ARIA
spec's contract, their own JavaScript logic for moving
focus [1].

[1] w3c/aria#1049, where we
discussed this.

Problem:
TalkBack does not handle role=application so such web apps
loose their 4-way (up/down/left/right) navigation.
TalkBack only moves foward/backward which breaks authors'
pre-defined TV UX.

Solution:
Whenever accessibility focus (the green rect) goes to a
WebView with <body role=application> or anywhere within
a role=application widget, we don't consume the DPAD
events; we let them through.

Testing done:
From TalkBack's test app, open dpad_a11y.html
which has <body role=application>.
Notice:
 I. Once the WebView gets accessibilty focus,
    TalkBack won't consume DPAD key events.
 II. The key events reach the web page's key
     handlers in JavaScript.
 III: TalkBack describes HTML elements once
      they get focused.
hugoholgersson added a commit to hugoholgersson/talkback that referenced this issue Oct 18, 2019
Background:
Within <xxx role=application>...</xxx>, screen readers
should not consume DPAD (arrow key) events. Web apps or
widgets with role=application have, per the WAI-ARIA
spec's contract, their own JavaScript logic for moving
focus [1].

[1] w3c/aria#1049, where we
discussed this.

Problem:
TalkBack does not handle role=application so such web apps
loose their 4-way (up/down/left/right) navigation.
TalkBack only moves foward/backward which breaks authors'
pre-defined TV UX.

Solution:
Whenever accessibility focus (the green rect) goes to a
WebView with <body role=application> or anywhere within
a role=application widget, we don't consume the DPAD
events; we let them through.

Testing done:
From TalkBack's test app, open dpad_a11y.html
which has <body role=application>.
Notice:
 I. Once the WebView gets accessibilty focus,
    TalkBack won't consume DPAD key events.
 II. The key events reach the web page's key
     handlers in JavaScript.
 III: TalkBack describes HTML elements once
      they get focused.
hugoholgersson added a commit to hugoholgersson/talkback that referenced this issue Oct 18, 2019
Background:
Within <xxx role=application>...</xxx>, screen readers
should not consume DPAD (arrow key) events. Web apps or
widgets with role=application have, per the WAI-ARIA
spec's contract, their own JavaScript logic for moving
focus [1].

[1] w3c/aria#1049, where we discussed this.

Problem:
TalkBack does not handle role=application so such web apps
loose their 4-way (up/down/left/right) navigation.
TalkBack only moves foward/backward which breaks authors'
pre-defined TV UX.

Solution:
Whenever accessibility focus (the green rect) goes to a
WebView with <body role=application> or anywhere within
a role=application widget, we don't consume the DPAD
events; we let them through.

Testing done:
From TalkBack's test app, open dpad_a11y.html
which has <body role=application>.
Notice:
 I. Once the WebView gets accessibilty focus,
    TalkBack won't consume DPAD key events.
 II. The key events reach the web page's key
     handlers in JavaScript.
 III: TalkBack describes HTML elements once
      they get focused.
hugoholgersson added a commit to hugoholgersson/talkback that referenced this issue Oct 21, 2019
Background:
Within <xxx role=application>...</xxx>, screen readers
should not consume DPAD (arrow key) events. Web apps
or widgets with role=application have, per the WAI-ARIA
spec's contract, their own JavaScript logic for moving
focus [1].

[1] w3c/aria#1049, where we discussed this.

Problem:
TalkBack does not handle role=application so such web
apps loose their 4-way (up/down/left/right) navigation.
TalkBack only moves foward/backward which breaks
authors' pre-defined TV UX.

Solution:
Whenever accessibility focus (the green rect) goes to
a WebView with <body role=application> or anywhere
within a role=application widget, we don't consume the
DPAD events; we let them through.

Testing done:
From TalkBack's test app, open dpad_a11y.html which
has <body role=application>.

Notice:
 I. Once the WebView gets accessibilty focus,
    TalkBack won't consume DPAD key events.
 II. The key events reach the web page's key
     handlers in JavaScript.
 III: TalkBack describes HTML elements once
      they get focused.
hugoholgersson added a commit to hugoholgersson/talkback that referenced this issue Nov 25, 2019
Background:
Within <xxx role=application>...</xxx>, screen readers
should not consume DPAD (arrow key) events. Web apps
or widgets with role=application have, per the WAI-ARIA
spec's contract, their own JavaScript logic for moving
focus [1].

[1] w3c/aria#1049, where we discussed this.

Problem:
TalkBack does not handle role=application so such web
apps lose their 4-way (up/down/left/right) navigation.
TalkBack only moves foward/backward which breaks
authors' pre-defined TV UX.

Solution:
Whenever accessibility focus (the green rect) goes to
a WebView with <body role=application> or anywhere
within a role=application widget, we don't consume the
DPAD events; we let them through.

Testing done:
From TalkBack's test app, open dpad_a11y.html which
has <body role=application>.

Notice:
 I. Once the WebView gets accessibilty focus,
    TalkBack won't consume DPAD key events.
 II. The key events reach the web page's key
     handlers in JavaScript.
 III: TalkBack describes HTML elements once
      they get focused.
hugoholgersson added a commit to hugoholgersson/talkback that referenced this issue Feb 3, 2020
Background:
Within <xxx role=application>...</xxx>, screen readers
should not consume DPAD (arrow key) events. Web apps
or widgets with role=application have, per the WAI-ARIA
spec's contract, their own JavaScript logic for moving
focus [1].

[1] w3c/aria#1049, where we discussed this.

Problem:
TalkBack does not handle role=application so such web
apps lose their 4-way (up/down/left/right) navigation.
TalkBack only moves forward/backward which breaks
authors' pre-defined TV UX.

Solution:
Whenever accessibility focus (the green rect) goes to
some web content with <body role=application> or anywhere
within a role=application widget, we don't consume the
DPAD events; we let them through.

Testing done:
From TalkBack's test app, open dpad_a11y.html which
has <body role=application>.

$ cd testapp
$ export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
$ export ANDROID_HOME=~/AndroidSDK
$ ./gradlew --debug assemble
$ adb install -r app/build/outputs/apk/app-debug.apk
$ adb shell am start -n com.android.talkbacktests/.MainActivity

Notice:
 I. Once the WebView gets accessibilty focus,
    TalkBack won't consume DPAD key events.
 II. The key events reach the web page's key
     handlers in JavaScript.
 III: TalkBack describes HTML elements once
      they get focused.
Signed-off-by: Hugo Holgersson <[email protected]>
hugoholgersson added a commit to hugoholgersson/talkback that referenced this issue Dec 3, 2021
After: The green rect follows web focus.
Before: TalkBack tries to read the TV apps as a
textual documents.

Background:
Within <xxx role=application>...</xxx>, screen readers
should not consume DPAD (arrow key) events. Web apps or
widgets with role=application have, per the WAI-ARIA
spec's contract, their own JavaScript logic for moving
focus.

I learned this through:
w3c/aria#1049

Problem:
TalkBack completely neglects role=application.

Solution:
Whenever accessibility focus (the green rect) goes to a
WebView with <body role=application> or anywhere within
such a document, don't consume the DPAD events; let them
through.

Testing done:
Open a simple TV web app that has <body role=application>.
Notice:
 Once the web view gets accessibilty focus, TalkBack
 won't eat (consume) DPAD key events and the the key
 events reach the web page's key handler in JavaScript.

Signed-off-by: Hugo Holgersson <[email protected]>
hugoholgersson added a commit to hugoholgersson/talkback that referenced this issue Dec 3, 2021
After: The green rect follows web focus.
Before: TalkBack tries to read the TV apps as text documents.

Background:
Within <xxx role=application>...</xxx>, screen readers
should not consume DPAD (arrow key) events. Web apps
or widgets with role=application have, per the WAI-ARIA
spec's contract, their own JavaScript logic for moving
focus [1].

[1] w3c/aria#1049, where we discussed this.

Problem:
TalkBack does not handle role=application so such web
apps lose their 4-way (up/down/left/right) navigation.
TalkBack only moves forward/backward which breaks
authors' pre-defined TV UX.

Solution:
Whenever accessibility focus (the green rect) goes to
some web content with <body role=application> or anywhere
within a role=application widget, we don't consume the
DPAD events; we let them through.

Testing done:
Open a simple TV web app that has <body role=application>.
Notice:
 Once the web view gets accessibilty focus, TalkBack
 won't eat (consume) DPAD key events and the the key
 events reach the web page's key handler in JavaScript.
PatrykMis pushed a commit to talkback-foss-team/talkback-foss that referenced this issue Dec 6, 2021
After: The green rect follows web focus.
Before: TalkBack tries to read the TV apps as text documents.

Background:
Within <xxx role=application>...</xxx>, screen readers
should not consume DPAD (arrow key) events. Web apps
or widgets with role=application have, per the WAI-ARIA
spec's contract, their own JavaScript logic for moving
focus [1].

[1] w3c/aria#1049, where we discussed this.

Problem:
TalkBack does not handle role=application so such web
apps lose their 4-way (up/down/left/right) navigation.
TalkBack only moves forward/backward which breaks
authors' pre-defined TV UX.

Solution:
Whenever accessibility focus (the green rect) goes to
some web content with <body role=application> or anywhere
within a role=application widget, we don't consume the
DPAD events; we let them through.

Testing done:
Open a simple TV web app that has <body role=application>.
Notice:
 Once the web view gets accessibilty focus, TalkBack
 won't eat (consume) DPAD key events and the the key
 events reach the web page's key handler in JavaScript.
hugoholgersson added a commit to hugoholgersson/talkback that referenced this issue Dec 8, 2021
After: The green rect follows web focus.
Before: TalkBack tries to read TV apps as text documents.

Background:
Within <xxx role=application>...</xxx>, screen readers
should not consume DPAD (arrow key) events. Web apps
or widgets with role=application have, per the WAI-ARIA
spec's contract, their own JavaScript logic for moving
focus [1].

[1] w3c/aria#1049, where we discussed this.

Problem:
TalkBack does not handle role=application so such web
apps lose their 4-way (up/down/left/right) navigation.
TalkBack only moves forward/backward which breaks
authors' pre-defined TV UX.

Solution:
Whenever accessibility focus (the green rect) goes to
some web content with <body role=application> or anywhere
within a role=application widget, we don't consume the
DPAD events; we let them through.

Testing done:
Open a simple TV web app, hosted in an Android WebView,
that has <body role=application>.
Notice:
 Once the web view gets accessibilty focus, TalkBack
 won't eat (consume) DPAD key events and the the key
 events reach the web page's key handler in JavaScript.
PatrykMis pushed a commit to talkback-foss-team/talkback-foss that referenced this issue Jan 10, 2022
After: The green rect follows web focus.
Before: TalkBack tries to read the TV apps as text documents.

Background:
Within <xxx role=application>...</xxx>, screen readers
should not consume DPAD (arrow key) events. Web apps
or widgets with role=application have, per the WAI-ARIA
spec's contract, their own JavaScript logic for moving
focus [1].

[1] w3c/aria#1049, where we discussed this.

Problem:
TalkBack does not handle role=application so such web
apps lose their 4-way (up/down/left/right) navigation.
TalkBack only moves forward/backward which breaks
authors' pre-defined TV UX.

Solution:
Whenever accessibility focus (the green rect) goes to
some web content with <body role=application> or anywhere
within a role=application widget, we don't consume the
DPAD events; we let them through.

Testing done:
Open a simple TV web app that has <body role=application>.
Notice:
 Once the web view gets accessibilty focus, TalkBack
 won't eat (consume) DPAD key events and the the key
 events reach the web page's key handler in JavaScript.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants