Skip to content

Commit

Permalink
[SpatNav]: Make {cursor: pointer} trees focus candidates
Browse files Browse the repository at this point in the history
Background:
Some web apps use one "catch all"-click handler, often put
on <body> or a container <div>, to react on clicks within
certain areas of the page. These web pages expect clicks
(or touches) and are not designed with key[board] users in
mind (they lack tabindex).

These pages' clickables, for example <div>s that look like
buttons, are often styled with {cursor: pointer}.

Problem:
These web pages are inaccessible for keyboard-only users.

Solution:
Enable SpatNav on these web apps by adding {cursor: pointer}
sub trees' tip to the list of navigation candidates.

Spec discussion:
w3c/csswg-drafts#3395

Note:
snav-imagemap-area-not-focusable.html found a bug in
Chrome's UA CSS. We used to style *all* <area>s as
clickables, with {cursor: pointer}, even those without a
href-attribute. I fixed this in crrev.com/c/1653009.

(cherry picked from commit 308a300)

Bug: 961927
Change-Id: I7baa2ba6f5f36ebc23b072d677edc66acfb2a70b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1632231
Commit-Queue: Hugo Holgersson <hholgersson@fb.com>
Reviewed-by: David Bokan <bokan@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#669193}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1662868
Cr-Commit-Position: refs/branch-heads/3809@{#375}
Cr-Branched-From: d82dec1-refs/heads/master@{#665002}
  • Loading branch information
hugoholgersson authored and bokand committed Jun 17, 2019
1 parent b7e89d8 commit b2f29c7
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
15 changes: 15 additions & 0 deletions third_party/blink/renderer/core/dom/element.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3519,11 +3519,26 @@ bool Element::SupportsSpatialNavigationFocus() const {
// events).
if (!IsSpatialNavigationEnabled(GetDocument().GetFrame()))
return false;

if (!GetLayoutObject())
return false;

if (HasEventListeners(event_type_names::kClick) ||
HasEventListeners(event_type_names::kKeydown) ||
HasEventListeners(event_type_names::kKeypress) ||
HasEventListeners(event_type_names::kKeyup))
return true;

// Some web apps use click-handlers to react on clicks within rects that are
// styled with {cursor: pointer}. Such rects *look* clickable so they probably
// are. Here we make Hand-trees' tip, the first (biggest) node with {cursor:
// pointer}, navigable because users shouldn't need to navigate through every
// sub element that inherit this CSS.
if (GetComputedStyle()->Cursor() == ECursor::kPointer &&
ParentComputedStyle()->Cursor() != ECursor::kPointer) {
return true;
}

if (!IsSVGElement())
return false;
return (HasEventListeners(event_type_names::kFocus) ||
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!doctype html>
<style>
#popup {width: 300px; height: 150px; background: LightBlue;}
.button {font-family: sans-serif; font-weight: bold; width: 80px; height: 40px; background: SeaGreen; color: white; cursor: pointer;}
.balancer {display: flex; justify-content: space-evenly; align-items: center;}
</style>

<div class="balancer" id="popup">
<div class="button balancer" id="ok"><div id="dontgohere1">OK</div></div>
<div class="button balancer" id="cancel"><div id="dontgohere2">Cancel</div></div>
</div>

<div id="log"><div>

<p>A typical popup dialog that listens for clicks on its two custom buttons.</p>

<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="resources/snav-testharness.js"></script>
<script>
var resultMap = [
["Down", "ok"],
["Right", "cancel"],
["Left", "ok"],
];
snav.assertFocusMoves(resultMap);
</script>

<p><em>Manual test instruction: Ensure that all buttons can be focused.</em></p>

0 comments on commit b2f29c7

Please sign in to comment.