summaryrefslogtreecommitdiffstats
path: root/content/browser/accessibility/browser_accessibility_win.cc
diff options
context:
space:
mode:
authordmazzoni <dmazzoni@chromium.org>2015-04-24 01:22:17 -0700
committerCommit bot <commit-bot@chromium.org>2015-04-24 08:22:27 +0000
commit9dbb3741802d2a5a3f6370fef9d712b077fa4b86 (patch)
treeac1147c3e471e87d7106fe4b80baee5c84e1bcf4 /content/browser/accessibility/browser_accessibility_win.cc
parent3396ad31e40ceef8d08cef11a91da9ee15ff6159 (diff)
downloadchromium_src-9dbb3741802d2a5a3f6370fef9d712b077fa4b86.zip
chromium_src-9dbb3741802d2a5a3f6370fef9d712b077fa4b86.tar.gz
chromium_src-9dbb3741802d2a5a3f6370fef9d712b077fa4b86.tar.bz2
Fix menu list and list box screen reader accessibility.
The most important change here is getting rid of code in renderer_accessibility.cc that recreated the subtree whenever AXSelectedChildrenChanged was fired. This is no longer necessary because Blink now fires the right events on each individual option in a menu list or list box. The rest of the changes just make sure the exact attributes and events match the spec and match what Firefox and Safari do when interacting with these elements, including adding some good tests for those. BUG=323462 Review URL: https://codereview.chromium.org/1057083002 Cr-Commit-Position: refs/heads/master@{#326755}
Diffstat (limited to 'content/browser/accessibility/browser_accessibility_win.cc')
-rw-r--r--content/browser/accessibility/browser_accessibility_win.cc52
1 files changed, 43 insertions, 9 deletions
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc
index b61f2f9..c6c7788 100644
--- a/content/browser/accessibility/browser_accessibility_win.cc
+++ b/content/browser/accessibility/browser_accessibility_win.cc
@@ -3179,9 +3179,9 @@ void BrowserAccessibilityWin::UpdateStep1ComputeWinAttributes() {
// WebKit stores the main accessible text in the "value" - swap it so
// that it's the "name".
if (name.empty() &&
- (GetRole() == ui::AX_ROLE_LIST_BOX_OPTION ||
- GetRole() == ui::AX_ROLE_STATIC_TEXT ||
- GetRole() == ui::AX_ROLE_LIST_MARKER)) {
+ (GetRole() == ui::AX_ROLE_STATIC_TEXT ||
+ GetRole() == ui::AX_ROLE_LIST_MARKER ||
+ IsListBoxOptionOrMenuListOption())) {
base::string16 tmp = value;
value = name;
name = tmp;
@@ -3298,10 +3298,22 @@ void BrowserAccessibilityWin::UpdateStep3FireEvents(bool is_subtree_creation) {
bool is_selected_now = (ia_state() & STATE_SYSTEM_SELECTED) != 0;
bool was_selected_before =
(old_win_attributes_->ia_state & STATE_SYSTEM_SELECTED) != 0;
- if (is_selected_now && !was_selected_before) {
- manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_SELECTIONADD, this);
- } else if (!is_selected_now && was_selected_before) {
- manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_SELECTIONREMOVE, this);
+ if (is_selected_now || was_selected_before) {
+ bool multiselect = false;
+ if (GetParent() && GetParent()->HasState(ui::AX_STATE_MULTISELECTABLE))
+ multiselect = true;
+
+ if (multiselect) {
+ // In a multi-select box, fire SELECTIONADD and SELECTIONREMOVE events.
+ if (is_selected_now && !was_selected_before) {
+ manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_SELECTIONADD, this);
+ } else if (!is_selected_now && was_selected_before) {
+ manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_SELECTIONREMOVE, this);
+ }
+ } else if (is_selected_now && !was_selected_before) {
+ // In a single-select box, only fire SELECTION events.
+ manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_SELECTION, this);
+ }
}
// Fire an event if this container object has scrolled.
@@ -3461,7 +3473,7 @@ base::string16 BrowserAccessibilityWin::GetValueText() {
}
base::string16 BrowserAccessibilityWin::TextForIAccessibleText() {
- if (IsEditableText())
+ if (IsEditableText() || GetRole() == ui::AX_ROLE_MENU_LIST_OPTION)
return value();
return (GetRole() == ui::AX_ROLE_STATIC_TEXT) ? name() : hypertext();
}
@@ -3587,6 +3599,26 @@ BrowserAccessibilityWin* BrowserAccessibilityWin::GetFromID(int32 id) {
return manager()->GetFromID(id)->ToBrowserAccessibilityWin();
}
+bool BrowserAccessibilityWin::IsListBoxOptionOrMenuListOption() {
+ if (!GetParent())
+ return false;
+
+ int32 role = GetRole();
+ int32 parent_role = GetParent()->GetRole();
+
+ if (role == ui::AX_ROLE_LIST_BOX_OPTION &&
+ parent_role == ui::AX_ROLE_LIST_BOX) {
+ return true;
+ }
+
+ if (role == ui::AX_ROLE_MENU_LIST_OPTION &&
+ parent_role == ui::AX_ROLE_MENU_LIST_POPUP) {
+ return true;
+ }
+
+ return false;
+}
+
void BrowserAccessibilityWin::InitRoleAndState() {
int32 ia_role = 0;
int32 ia_state = 0;
@@ -3909,10 +3941,12 @@ void BrowserAccessibilityWin::InitRoleAndState() {
ia2_role = IA2_ROLE_RADIO_MENU_ITEM;
break;
case ui::AX_ROLE_MENU_LIST_POPUP:
- ia_role = ROLE_SYSTEM_CLIENT;
+ ia_role = ROLE_SYSTEM_LIST;
+ ia2_state &= ~(IA2_STATE_EDITABLE);
break;
case ui::AX_ROLE_MENU_LIST_OPTION:
ia_role = ROLE_SYSTEM_LISTITEM;
+ ia2_state &= ~(IA2_STATE_EDITABLE);
if (ia_state & STATE_SYSTEM_SELECTABLE) {
ia_state |= STATE_SYSTEM_FOCUSABLE;
if (HasState(ui::AX_STATE_FOCUSED))