Index: content/browser/accessibility/browser_accessibility_win.cc |
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc |
index e8a82f7e7f906cc102aa0fe473c0cdfe3a89aa47..05fc5da1d7fafb04b3ed12d7ae03d5f093e701c8 100644 |
--- a/content/browser/accessibility/browser_accessibility_win.cc |
+++ b/content/browser/accessibility/browser_accessibility_win.cc |
@@ -3191,9 +3191,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; |
@@ -3310,10 +3310,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. |
@@ -3473,7 +3485,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(); |
} |
@@ -3599,6 +3611,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; |
@@ -3921,10 +3953,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)) |