Skip to content

Commit

Permalink
Treat mixed value on switch role as false
Browse files Browse the repository at this point in the history
Currently, mixed (indeterminate) values are exposed as true or mixed on
the switch role. According to https://w3c.github.io/aria/#switch, they
should be exposed as false.

Bug: 1372131
Change-Id: I08ec7f764305812b9867b1083649577589052d8f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4632270
Reviewed-by: Aaron Leventhal <aleventhal@chromium.org>
Commit-Queue: Aaron Leventhal <aleventhal@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1167552}
  • Loading branch information
tranjocelyn authored and Chromium LUCI CQ committed Jul 7, 2023
1 parent c4953a7 commit eca9732
Show file tree
Hide file tree
Showing 8 changed files with 23 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ WebView focusable focused scrollable actions:[CLEAR_FOCUS, AX_FOCUS] bundle:[chr
++ToggleButton text:"Switch1" stateDescription:"Off" checkable clickable actions:[CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="switch", roleDescription="switch"]
++ToggleButton text:"Switch2" stateDescription:"Off" checkable clickable actions:[CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="switch", roleDescription="switch"]
++ToggleButton text:"Switch3" stateDescription:"On" checkable checked clickable actions:[CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="switch", roleDescription="switch"]
++ToggleButton text:"Switch4" stateDescription:"On" checkable checked clickable actions:[CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="switch", roleDescription="switch"]
++ToggleButton text:"Switch4" stateDescription:"Off" checkable clickable actions:[CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="switch", roleDescription="switch"]
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ android.webkit.WebView focusable focused scrollable
++android.widget.ToggleButton role_description='switch' checkable clickable name='Switch1' state_description='Off'
++android.widget.ToggleButton role_description='switch' checkable clickable name='Switch2' state_description='Off'
++android.widget.ToggleButton role_description='switch' checkable checked clickable name='Switch3' state_description='On'
++android.widget.ToggleButton role_description='switch' checkable checked clickable name='Switch4' state_description='On'
++android.widget.ToggleButton role_description='switch' checkable clickable name='Switch4' state_description='Off'
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
++[toggle button] name='Switch1' checkable:true xml-roles:switch
++[toggle button] name='Switch2' checkable:true xml-roles:switch
++[toggle button] name='Switch3' checked checkable:true xml-roles:switch
++[toggle button] name='Switch4' checked checkable:true xml-roles:switch
++[toggle button] name='Switch4' checkable:true xml-roles:switch
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ rootWebArea
++++++switch name='Switch3' checkedState=true
++++++++staticText name='Switch3'
++++++++++inlineTextBox name='Switch3'
++++++switch name='Switch4' checkedState=true
++++++switch name='Switch4' checkedState=false
++++++++staticText name='Switch4'
++++++++++inlineTextBox name='Switch4'
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ AXWebArea AXRoleDescription='HTML content'
++AXCheckBox AXSubrole=AXSwitch AXRoleDescription='switch' AXTitle='Switch1' AXValue=0
++AXCheckBox AXSubrole=AXSwitch AXRoleDescription='switch' AXTitle='Switch2' AXValue=0
++AXCheckBox AXSubrole=AXSwitch AXRoleDescription='switch' AXTitle='Switch3' AXValue=1
++AXCheckBox AXSubrole=AXSwitch AXRoleDescription='switch' AXTitle='Switch4' AXValue=1
++AXCheckBox AXSubrole=AXSwitch AXRoleDescription='switch' AXTitle='Switch4' AXValue=0
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ia2_hypertext='<obj0><obj1><obj2><obj3>'
++IA2_ROLE_TOGGLE_BUTTON name='Switch1' IA2_STATE_CHECKABLE xml-roles:switch checkable:true ia2_hypertext='Switch1'
++IA2_ROLE_TOGGLE_BUTTON name='Switch2' IA2_STATE_CHECKABLE xml-roles:switch checkable:true ia2_hypertext='Switch2'
++IA2_ROLE_TOGGLE_BUTTON name='Switch3' PRESSED CHECKED IA2_STATE_CHECKABLE xml-roles:switch checkable:true ia2_hypertext='Switch3'
++IA2_ROLE_TOGGLE_BUTTON name='Switch4' PRESSED CHECKED IA2_STATE_CHECKABLE xml-roles:switch checkable:true ia2_hypertext='Switch4'
++IA2_ROLE_TOGGLE_BUTTON name='Switch4' IA2_STATE_CHECKABLE xml-roles:switch checkable:true ia2_hypertext='Switch4'
25 changes: 15 additions & 10 deletions third_party/blink/renderer/modules/accessibility/ax_object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2718,9 +2718,10 @@ ax::mojom::blink::CheckedState AXObject::CheckedState() const {
const AtomicString& checked_attribute = GetAOMPropertyOrARIAAttribute(prop);
if (checked_attribute) {
if (EqualIgnoringASCIICase(checked_attribute, "mixed")) {
// Only checkable role that doesn't support mixed is the switch.
if (role != ax::mojom::blink::Role::kSwitch)
return ax::mojom::blink::CheckedState::kMixed;
// Mixed value is invalid for switch role. Treat as false.
return role == ax::mojom::blink::Role::kSwitch
? ax::mojom::blink::CheckedState::kFalse
: ax::mojom::blink::CheckedState::kMixed;
}

// Anything other than "false" should be treated as "true".
Expand All @@ -2735,13 +2736,17 @@ ax::mojom::blink::CheckedState AXObject::CheckedState() const {
if (!node)
return ax::mojom::blink::CheckedState::kNone;

// Expose native checkbox mixed state as accessibility mixed state. However,
// do not expose native radio mixed state as accessibility mixed state.
// This would confuse the JAWS screen reader, which reports a mixed radio as
// both checked and partially checked, but a native mixed native radio
// button simply means no radio buttons have been checked in the group yet.
if (IsNativeCheckboxInMixedState(node))
return ax::mojom::blink::CheckedState::kMixed;
// Expose native checkbox mixed state as accessibility mixed state (unless
// the role is switch). However, do not expose native radio mixed state as
// accessibility mixed state. This would confuse the JAWS screen reader,
// which reports a mixed radio as both checked and partially checked, but a
// native mixed native radio button simply means no radio buttons have been
// checked in the group yet.
if (IsNativeCheckboxInMixedState(node)) {
return role == ax::mojom::blink::Role::kSwitch
? ax::mojom::blink::CheckedState::kFalse
: ax::mojom::blink::CheckedState::kMixed;
}

auto* html_input_element = DynamicTo<HTMLInputElement>(node);
if (html_input_element && html_input_element->ShouldAppearChecked()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<div id="element2" role="menuitemcheckbox" aria-checked="mixed"></div>
<div id="element3" role="radio" aria-checked="mixed"></div>
<div id="element4" role="menuitemradio" aria-checked="mixed"></div>
<!-- Switch specifically does not support mixed -->
<!-- Switch specifically does not support mixed. It's treated as false. -->
<div id="element5" role="switch" aria-checked="mixed"></div>

<input id="element6" type="checkbox" aria-checked="mixed" checked />
Expand Down Expand Up @@ -39,7 +39,7 @@
"mixed",
"mixed",
"mixed",
"true",
"false",
"mixed",
"mixed",
"mixed",
Expand Down

0 comments on commit eca9732

Please sign in to comment.