Commit 2cb648f2 authored by David Tseng's avatar David Tseng Committed by Commit Bot

Consider a few more aria roles as leaf nodes

Radio buttons, switches, and check boxes should always be visited during all types of navigation.

The one corner case here is if there are clickable descendants for the node;
this can occur only if an author creates a complex subtree for the node.

R=dmazzoni@chromium.org

Test: browser_tests --gtest_filter=ChromeVox*.AriaRadios
Change-Id: I6306404f8a303164f4af4a9e3f4b5bde3a261502
Fixed: 1136253
AX-Relnotes: makes ChromeVox output aria radio buttons that don't receive focus.
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2468076
Commit-Queue: David Tseng <dtseng@chromium.org>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#817049}
parent 41cd75bc
...@@ -3217,3 +3217,41 @@ TEST_F('ChromeVoxBackgroundTest', 'FocusOnWebAreaIgnoresEvents', function() { ...@@ -3217,3 +3217,41 @@ TEST_F('ChromeVoxBackgroundTest', 'FocusOnWebAreaIgnoresEvents', function() {
assertEquals(undefined, nextSpeech); assertEquals(undefined, nextSpeech);
}); });
}); });
TEST_F('ChromeVoxBackgroundTest', 'AriaLeaves', function() {
const mockFeedback = this.createMockFeedback();
const site = `
<div role="radio"><p>PM</p></div>
<div role="switch"><p>Agree</p></div>
<div role="checkbox"><p>Agree</p></div>
<script>
const p = document.getElementsByTagName('p')[0];
p.addEventListener('click', () => {});
</script>
`;
this.runWithLoadedTree(site, function(root) {
mockFeedback.expectSpeech('PM, radio button unselected')
.call(doCmd('nextObject'))
.expectSpeech('PM')
.call(
() => assertEquals(
RoleType.STATIC_TEXT,
ChromeVoxState.instance.currentRange.start.node.role))
.call(doCmd('nextObject'))
.expectSpeech('Agree, switch off')
.call(
() => assertEquals(
RoleType.SWITCH,
ChromeVoxState.instance.currentRange.start.node.role))
.call(doCmd('nextObject'))
.expectSpeech('Agree', 'Check box')
.call(
() => assertEquals(
RoleType.CHECK_BOX,
ChromeVoxState.instance.currentRange.start.node.role))
.replay();
});
});
...@@ -2186,7 +2186,7 @@ Output.ROLE_INFO_ = { ...@@ -2186,7 +2186,7 @@ Output.ROLE_INFO_ = {
application: {msgId: 'role_application', inherits: 'abstractContainer'}, application: {msgId: 'role_application', inherits: 'abstractContainer'},
audio: {msgId: 'tag_audio', inherits: 'abstractContainer'}, audio: {msgId: 'tag_audio', inherits: 'abstractContainer'},
banner: {msgId: 'role_banner', inherits: 'abstractContainer'}, banner: {msgId: 'role_banner', inherits: 'abstractContainer'},
button: {msgId: 'role_button', earconId: 'BUTTON', inherits: 'button'}, button: {msgId: 'role_button', earconId: 'BUTTON'},
buttonDropDown: {msgId: 'role_button', earconId: 'BUTTON'}, buttonDropDown: {msgId: 'role_button', earconId: 'BUTTON'},
checkBox: {msgId: 'role_checkbox'}, checkBox: {msgId: 'role_checkbox'},
columnHeader: {msgId: 'role_columnheader', inherits: 'cell'}, columnHeader: {msgId: 'role_columnheader', inherits: 'cell'},
......
...@@ -26,7 +26,9 @@ const State = chrome.automation.StateType; ...@@ -26,7 +26,9 @@ const State = chrome.automation.StateType;
*/ */
const isActionableOrHasActionableDescendant = function(node) { const isActionableOrHasActionableDescendant = function(node) {
// DefaultActionVerb does not have value 'none' even though it gets set. // DefaultActionVerb does not have value 'none' even though it gets set.
if (node.defaultActionVerb != 'none') { // Static text nodes are never actionable for the purposes of navigation even
// if they have default action verb set.
if (node.role != Role.STATIC_TEXT && node.defaultActionVerb != 'none') {
return true; return true;
} }
...@@ -179,8 +181,10 @@ AutomationPredicate = class { ...@@ -179,8 +181,10 @@ AutomationPredicate = class {
*/ */
static touchLeaf(node) { static touchLeaf(node) {
return !!(!node.firstChild && node.name) || node.role == Role.BUTTON || return !!(!node.firstChild && node.name) || node.role == Role.BUTTON ||
node.role == Role.POP_UP_BUTTON || node.role == Role.PORTAL || node.role == Role.CHECK_BOX || node.role == Role.POP_UP_BUTTON ||
node.role == Role.SLIDER || node.role == Role.TEXT_FIELD || node.role == Role.PORTAL || node.role == Role.RADIO_BUTTON ||
node.role == Role.SLIDER || node.role == Role.SWITCH ||
node.role == Role.TEXT_FIELD ||
(node.role == Role.MENU_ITEM && !hasActionableDescendant(node)); (node.role == Role.MENU_ITEM && !hasActionableDescendant(node));
} }
...@@ -350,7 +354,9 @@ AutomationPredicate = class { ...@@ -350,7 +354,9 @@ AutomationPredicate = class {
// Always try to dive into subtrees with actionable descendants for some // Always try to dive into subtrees with actionable descendants for some
// roles even if these roles are not naturally containers. // roles even if these roles are not naturally containers.
if (node.role == Role.BUTTON && hasActionableDescendant(node)) { if ((node.role == Role.BUTTON || node.role == Role.CHECK_BOX ||
node.role == Role.RADIO_BUTTON || node.role == Role.SWITCH) &&
hasActionableDescendant(node)) {
return true; return true;
} }
......
...@@ -2,8 +2,8 @@ rootWebArea ...@@ -2,8 +2,8 @@ rootWebArea
++genericContainer ignored ++genericContainer ignored
++++genericContainer ignored ++++genericContainer ignored
++++++link name='link with no href but onclick' defaultActionVerb=jump ++++++link name='link with no href but onclick' defaultActionVerb=jump
++++++++staticText name='link with no href but onclick' defaultActionVerb=click-ancestor ++++++++staticText name='link with no href but onclick' defaultActionVerb=clickAncestor
++++++++++inlineTextBox name='link with no href but onclick' ++++++++++inlineTextBox name='link with no href but onclick'
++++++link name='link with no href and click handler added via script' defaultActionVerb=jump ++++++link name='link with no href and click handler added via script' defaultActionVerb=jump
++++++++staticText name='link with no href and click handler added via script' defaultActionVerb=click-ancestor ++++++++staticText name='link with no href and click handler added via script' defaultActionVerb=clickAncestor
++++++++++inlineTextBox name='link with no href and click handler added via script' ++++++++++inlineTextBox name='link with no href and click handler added via script'
\ No newline at end of file
ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
++ROLE_SYSTEM_LINK name='link with no href but onclick' LINKED default_action='jump' action_name='jump' ++ROLE_SYSTEM_LINK name='link with no href but onclick' LINKED default_action='jump' action_name='jump'
++++ROLE_SYSTEM_STATICTEXT name='link with no href but onclick' default_action='click ancestor' action_name='click-ancestor' ++++ROLE_SYSTEM_STATICTEXT name='link with no href but onclick' default_action='click ancestor' action_name='clickAncestor'
++ROLE_SYSTEM_LINK name='link with no href and click handler added via script' LINKED default_action='jump' action_name='jump' ++ROLE_SYSTEM_LINK name='link with no href and click handler added via script' LINKED default_action='jump' action_name='jump'
++++ROLE_SYSTEM_STATICTEXT name='link with no href and click handler added via script' default_action='click ancestor' action_name='click-ancestor' ++++ROLE_SYSTEM_STATICTEXT name='link with no href and click handler added via script' default_action='click ancestor' action_name='clickAncestor'
\ No newline at end of file
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
++++[static] name='Heading' ++++[static] name='Heading'
++[push button] name='Button' actions=(press) ++[push button] name='Button' actions=(press)
++[link] name='Link' actions=(jump) ++[link] name='Link' actions=(jump)
++++[static] name='Link' actions=(click-ancestor) ++++[static] name='Link' actions=(clickAncestor)
++[entry] selectable-text actions=(activate) ++[entry] selectable-text actions=(activate)
++[entry] selectable-text actions=(activate) ++[entry] selectable-text actions=(activate)
++[entry] selectable-text actions=(activate) ++[entry] selectable-text actions=(activate)
...@@ -21,10 +21,10 @@ ...@@ -21,10 +21,10 @@
++++[menu] ++++[menu]
++++++[menu item] name='Pop-up button' selectable selected actions=(select) ++++++[menu item] name='Pop-up button' selectable selected actions=(select)
++[section] actions=(click) ++[section] actions=(click)
++++[static] name='Div with click handler' actions=(click-ancestor) ++++[static] name='Div with click handler' actions=(clickAncestor)
++[panel] actions=(click) ++[panel] actions=(click)
++++[paragraph] actions=(click-ancestor) ++++[paragraph] actions=(clickAncestor)
++++++[static] name='Paragraph with click handler on parent' actions=(click-ancestor) ++++++[static] name='Paragraph with click handler on parent' actions=(clickAncestor)
++[menu] ++[menu]
++++[menu item] name='Menu item 1' actions=(select) ++++[menu item] name='Menu item 1' actions=(select)
++++[check menu item] name='Menu item 2' checked actions=(uncheck) checkable:true ++++[check menu item] name='Menu item 2' checked actions=(uncheck) checkable:true
...@@ -33,4 +33,4 @@ ...@@ -33,4 +33,4 @@
++[push button] name='ARIA button with tab index' actions=(press) ++[push button] name='ARIA button with tab index' actions=(press)
++[push button] name='ARIA button with negative tab index' actions=(press) ++[push button] name='ARIA button with negative tab index' actions=(press)
++[section] ++[section]
++++[push button] name='ARIA button that is an active descendant' actions=(press) ++++[push button] name='ARIA button that is an active descendant' actions=(press)
\ No newline at end of file
...@@ -11,7 +11,7 @@ rootWebArea name='Action verbs' ...@@ -11,7 +11,7 @@ rootWebArea name='Action verbs'
++++++++staticText name='Button' ++++++++staticText name='Button'
++++++++++inlineTextBox name='Button' ++++++++++inlineTextBox name='Button'
++++++link name='Link' defaultActionVerb=jump ++++++link name='Link' defaultActionVerb=jump
++++++++staticText name='Link' defaultActionVerb=click-ancestor ++++++++staticText name='Link' defaultActionVerb=clickAncestor
++++++++++inlineTextBox name='Link' ++++++++++inlineTextBox name='Link'
++++++textField defaultActionVerb=activate ++++++textField defaultActionVerb=activate
++++++++genericContainer ++++++++genericContainer
...@@ -32,11 +32,11 @@ rootWebArea name='Action verbs' ...@@ -32,11 +32,11 @@ rootWebArea name='Action verbs'
++++++++menuListPopup invisible ++++++++menuListPopup invisible
++++++++++menuListOption name='Pop-up button' defaultActionVerb=select selected=true ++++++++++menuListOption name='Pop-up button' defaultActionVerb=select selected=true
++++++genericContainer defaultActionVerb=click ++++++genericContainer defaultActionVerb=click
++++++++staticText name='Div with click handler' defaultActionVerb=click-ancestor ++++++++staticText name='Div with click handler' defaultActionVerb=clickAncestor
++++++++++inlineTextBox name='Div with click handler' ++++++++++inlineTextBox name='Div with click handler'
++++++group defaultActionVerb=click ++++++group defaultActionVerb=click
++++++++paragraph defaultActionVerb=click-ancestor ++++++++paragraph defaultActionVerb=clickAncestor
++++++++++staticText name='Paragraph with click handler on parent' defaultActionVerb=click-ancestor ++++++++++staticText name='Paragraph with click handler on parent' defaultActionVerb=clickAncestor
++++++++++++inlineTextBox name='Paragraph with click handler on parent' ++++++++++++inlineTextBox name='Paragraph with click handler on parent'
++++++menu ++++++menu
++++++++menuItem name='Menu item 1' defaultActionVerb=select ++++++++menuItem name='Menu item 1' defaultActionVerb=select
...@@ -54,4 +54,4 @@ rootWebArea name='Action verbs' ...@@ -54,4 +54,4 @@ rootWebArea name='Action verbs'
++++++genericContainer activedescendantId=button ++++++genericContainer activedescendantId=button
++++++++button name='ARIA button that is an active descendant' defaultActionVerb=press ++++++++button name='ARIA button that is an active descendant' defaultActionVerb=press
++++++++++staticText name='ARIA button that is an active descendant' ++++++++++staticText name='ARIA button that is an active descendant'
++++++++++++inlineTextBox name='ARIA button that is an active descendant' ++++++++++++inlineTextBox name='ARIA button that is an active descendant'
\ No newline at end of file
...@@ -5,7 +5,7 @@ ROLE_SYSTEM_DOCUMENT name='Action verbs' READONLY FOCUSABLE ...@@ -5,7 +5,7 @@ ROLE_SYSTEM_DOCUMENT name='Action verbs' READONLY FOCUSABLE
++++ROLE_SYSTEM_STATICTEXT name='Heading' ++++ROLE_SYSTEM_STATICTEXT name='Heading'
++ROLE_SYSTEM_PUSHBUTTON name='Button' FOCUSABLE default_action='press' action_name='press' ++ROLE_SYSTEM_PUSHBUTTON name='Button' FOCUSABLE default_action='press' action_name='press'
++ROLE_SYSTEM_LINK name='Link' FOCUSABLE default_action='jump' action_name='jump' ++ROLE_SYSTEM_LINK name='Link' FOCUSABLE default_action='jump' action_name='jump'
++++ROLE_SYSTEM_STATICTEXT name='Link' default_action='click ancestor' action_name='click-ancestor' ++++ROLE_SYSTEM_STATICTEXT name='Link' default_action='click ancestor' action_name='clickAncestor'
++ROLE_SYSTEM_TEXT FOCUSABLE default_action='activate' action_name='activate' ++ROLE_SYSTEM_TEXT FOCUSABLE default_action='activate' action_name='activate'
++ROLE_SYSTEM_TEXT FOCUSABLE default_action='activate' action_name='activate' ++ROLE_SYSTEM_TEXT FOCUSABLE default_action='activate' action_name='activate'
++ROLE_SYSTEM_TEXT FOCUSABLE IA2_STATE_MULTI_LINE default_action='activate' action_name='activate' ++ROLE_SYSTEM_TEXT FOCUSABLE IA2_STATE_MULTI_LINE default_action='activate' action_name='activate'
...@@ -19,10 +19,10 @@ ROLE_SYSTEM_DOCUMENT name='Action verbs' READONLY FOCUSABLE ...@@ -19,10 +19,10 @@ ROLE_SYSTEM_DOCUMENT name='Action verbs' READONLY FOCUSABLE
++++++ROLE_SYSTEM_STATICTEXT name='Summary' ++++++ROLE_SYSTEM_STATICTEXT name='Summary'
++ROLE_SYSTEM_COMBOBOX value='Pop-up button' COLLAPSED FOCUSABLE HASPOPUP haspopup:menu default_action='open' action_name='open' ++ROLE_SYSTEM_COMBOBOX value='Pop-up button' COLLAPSED FOCUSABLE HASPOPUP haspopup:menu default_action='open' action_name='open'
++IA2_ROLE_SECTION default_action='click' action_name='click' ++IA2_ROLE_SECTION default_action='click' action_name='click'
++++ROLE_SYSTEM_STATICTEXT name='Div with click handler' default_action='click ancestor' action_name='click-ancestor' ++++ROLE_SYSTEM_STATICTEXT name='Div with click handler' default_action='click ancestor' action_name='clickAncestor'
++ROLE_SYSTEM_GROUPING default_action='click' action_name='click' ++ROLE_SYSTEM_GROUPING default_action='click' action_name='click'
++++IA2_ROLE_PARAGRAPH default_action='click ancestor' action_name='click-ancestor' ++++IA2_ROLE_PARAGRAPH default_action='click ancestor' action_name='clickAncestor'
++++++ROLE_SYSTEM_STATICTEXT name='Paragraph with click handler on parent' default_action='click ancestor' action_name='click-ancestor' ++++++ROLE_SYSTEM_STATICTEXT name='Paragraph with click handler on parent' default_action='click ancestor' action_name='clickAncestor'
++ROLE_SYSTEM_MENUPOPUP ++ROLE_SYSTEM_MENUPOPUP
++++ROLE_SYSTEM_MENUITEM name='Menu item 1' default_action='select' action_name='select' ++++ROLE_SYSTEM_MENUITEM name='Menu item 1' default_action='select' action_name='select'
++++IA2_ROLE_CHECK_MENU_ITEM name='Menu item 2' CHECKED IA2_STATE_CHECKABLE checkable:true default_action='uncheck' action_name='uncheck' ++++IA2_ROLE_CHECK_MENU_ITEM name='Menu item 2' CHECKED IA2_STATE_CHECKABLE checkable:true default_action='uncheck' action_name='uncheck'
...@@ -31,4 +31,4 @@ ROLE_SYSTEM_DOCUMENT name='Action verbs' READONLY FOCUSABLE ...@@ -31,4 +31,4 @@ ROLE_SYSTEM_DOCUMENT name='Action verbs' READONLY FOCUSABLE
++ROLE_SYSTEM_PUSHBUTTON name='ARIA button with tab index' FOCUSABLE default_action='press' action_name='press' ++ROLE_SYSTEM_PUSHBUTTON name='ARIA button with tab index' FOCUSABLE default_action='press' action_name='press'
++ROLE_SYSTEM_PUSHBUTTON name='ARIA button with negative tab index' FOCUSABLE default_action='press' action_name='press' ++ROLE_SYSTEM_PUSHBUTTON name='ARIA button with negative tab index' FOCUSABLE default_action='press' action_name='press'
++IA2_ROLE_SECTION ++IA2_ROLE_SECTION
++++ROLE_SYSTEM_PUSHBUTTON name='ARIA button that is an active descendant' FOCUSABLE default_action='press' action_name='press' ++++ROLE_SYSTEM_PUSHBUTTON name='ARIA button that is an active descendant' FOCUSABLE default_action='press' action_name='press'
\ No newline at end of file
...@@ -688,7 +688,7 @@ const char* ToString(ax::mojom::DefaultActionVerb default_action_verb) { ...@@ -688,7 +688,7 @@ const char* ToString(ax::mojom::DefaultActionVerb default_action_verb) {
case ax::mojom::DefaultActionVerb::kClickAncestor: case ax::mojom::DefaultActionVerb::kClickAncestor:
// Some screen readers, such as Jaws, expect the following spelling of // Some screen readers, such as Jaws, expect the following spelling of
// this verb. // this verb.
return "click-ancestor"; return "clickAncestor";
case ax::mojom::DefaultActionVerb::kJump: case ax::mojom::DefaultActionVerb::kJump:
return "jump"; return "jump";
case ax::mojom::DefaultActionVerb::kOpen: case ax::mojom::DefaultActionVerb::kOpen:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment