OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/accessibility/browser_accessibility_win.h" | 5 #include "content/browser/accessibility/browser_accessibility_win.h" |
6 | 6 |
7 #include <UIAutomationClient.h> | 7 #include <UIAutomationClient.h> |
8 #include <UIAutomationCoreApi.h> | 8 #include <UIAutomationCoreApi.h> |
9 | 9 |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
(...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
896 STDMETHODIMP BrowserAccessibilityWin::get_groupPosition( | 896 STDMETHODIMP BrowserAccessibilityWin::get_groupPosition( |
897 LONG* group_level, | 897 LONG* group_level, |
898 LONG* similar_items_in_group, | 898 LONG* similar_items_in_group, |
899 LONG* position_in_group) { | 899 LONG* position_in_group) { |
900 if (!instance_active()) | 900 if (!instance_active()) |
901 return E_FAIL; | 901 return E_FAIL; |
902 | 902 |
903 if (!group_level || !similar_items_in_group || !position_in_group) | 903 if (!group_level || !similar_items_in_group || !position_in_group) |
904 return E_INVALIDARG; | 904 return E_INVALIDARG; |
905 | 905 |
906 if (GetRole() == ui::AX_ROLE_LIST_BOX_OPTION && | 906 if (IsListBoxOptionOrMenuListOption()) { |
907 GetParent() && | |
908 GetParent()->GetRole() == ui::AX_ROLE_LIST_BOX) { | |
909 *group_level = 0; | 907 *group_level = 0; |
910 *similar_items_in_group = GetParent()->PlatformChildCount(); | 908 *similar_items_in_group = GetParent()->PlatformChildCount(); |
911 *position_in_group = GetIndexInParent() + 1; | 909 *position_in_group = GetIndexInParent() + 1; |
912 return S_OK; | 910 return S_OK; |
913 } | 911 } |
914 | 912 |
915 return E_NOTIMPL; | 913 return E_NOTIMPL; |
916 } | 914 } |
917 | 915 |
918 // | 916 // |
(...skipping 2070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2989 StringAttributeToIA2(ui::AX_ATTR_DISPLAY, "display"); | 2987 StringAttributeToIA2(ui::AX_ATTR_DISPLAY, "display"); |
2990 StringAttributeToIA2(ui::AX_ATTR_DROPEFFECT, "dropeffect"); | 2988 StringAttributeToIA2(ui::AX_ATTR_DROPEFFECT, "dropeffect"); |
2991 StringAttributeToIA2(ui::AX_ATTR_TEXT_INPUT_TYPE, "text-input-type"); | 2989 StringAttributeToIA2(ui::AX_ATTR_TEXT_INPUT_TYPE, "text-input-type"); |
2992 StringAttributeToIA2(ui::AX_ATTR_HTML_TAG, "tag"); | 2990 StringAttributeToIA2(ui::AX_ATTR_HTML_TAG, "tag"); |
2993 StringAttributeToIA2(ui::AX_ATTR_ROLE, "xml-roles"); | 2991 StringAttributeToIA2(ui::AX_ATTR_ROLE, "xml-roles"); |
2994 | 2992 |
2995 // Expose "level" attribute for headings, trees, etc. | 2993 // Expose "level" attribute for headings, trees, etc. |
2996 IntAttributeToIA2(ui::AX_ATTR_HIERARCHICAL_LEVEL, "level"); | 2994 IntAttributeToIA2(ui::AX_ATTR_HIERARCHICAL_LEVEL, "level"); |
2997 | 2995 |
2998 // Expose the set size and position in set for listbox options. | 2996 // Expose the set size and position in set for listbox options. |
2999 if (GetRole() == ui::AX_ROLE_LIST_BOX_OPTION && | 2997 if (IsListBoxOptionOrMenuListOption()) { |
3000 GetParent() && | |
3001 GetParent()->GetRole() == ui::AX_ROLE_LIST_BOX) { | |
3002 win_attributes_->ia2_attributes.push_back( | 2998 win_attributes_->ia2_attributes.push_back( |
3003 L"setsize:" + base::IntToString16(GetParent()->PlatformChildCount())); | 2999 L"setsize:" + base::IntToString16(GetParent()->PlatformChildCount())); |
3004 win_attributes_->ia2_attributes.push_back( | 3000 win_attributes_->ia2_attributes.push_back( |
3005 L"setsize:" + base::IntToString16(GetIndexInParent() + 1)); | 3001 L"posinset:" + base::IntToString16(GetIndexInParent() + 1)); |
3002 win_attributes_->ia2_attributes.push_back( | |
3003 L"tag:option"); | |
3006 } | 3004 } |
3007 | 3005 |
3008 if (ia_role() == ROLE_SYSTEM_CHECKBUTTON || | 3006 if (ia_role() == ROLE_SYSTEM_CHECKBUTTON || |
3009 ia_role() == ROLE_SYSTEM_RADIOBUTTON || | 3007 ia_role() == ROLE_SYSTEM_RADIOBUTTON || |
3010 ia2_role() == IA2_ROLE_CHECK_MENU_ITEM || | 3008 ia2_role() == IA2_ROLE_CHECK_MENU_ITEM || |
3011 ia2_role() == IA2_ROLE_RADIO_MENU_ITEM || | 3009 ia2_role() == IA2_ROLE_RADIO_MENU_ITEM || |
3012 ia2_role() == IA2_ROLE_TOGGLE_BUTTON) { | 3010 ia2_role() == IA2_ROLE_TOGGLE_BUTTON) { |
3013 win_attributes_->ia2_attributes.push_back(L"checkable:true"); | 3011 win_attributes_->ia2_attributes.push_back(L"checkable:true"); |
3014 } | 3012 } |
3015 | 3013 |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3177 // On Windows, the value of a document should be its url. | 3175 // On Windows, the value of a document should be its url. |
3178 if (GetRole() == ui::AX_ROLE_ROOT_WEB_AREA || | 3176 if (GetRole() == ui::AX_ROLE_ROOT_WEB_AREA || |
3179 GetRole() == ui::AX_ROLE_WEB_AREA) { | 3177 GetRole() == ui::AX_ROLE_WEB_AREA) { |
3180 value = GetString16Attribute(ui::AX_ATTR_DOC_URL); | 3178 value = GetString16Attribute(ui::AX_ATTR_DOC_URL); |
3181 } | 3179 } |
3182 | 3180 |
3183 // For certain roles (listbox option, static text, and list marker) | 3181 // For certain roles (listbox option, static text, and list marker) |
3184 // WebKit stores the main accessible text in the "value" - swap it so | 3182 // WebKit stores the main accessible text in the "value" - swap it so |
3185 // that it's the "name". | 3183 // that it's the "name". |
3186 if (name.empty() && | 3184 if (name.empty() && |
3187 (GetRole() == ui::AX_ROLE_LIST_BOX_OPTION || | 3185 (GetRole() == ui::AX_ROLE_STATIC_TEXT || |
3188 GetRole() == ui::AX_ROLE_STATIC_TEXT || | 3186 GetRole() == ui::AX_ROLE_LIST_MARKER || |
3189 GetRole() == ui::AX_ROLE_LIST_MARKER)) { | 3187 IsListBoxOptionOrMenuListOption())) { |
3190 base::string16 tmp = value; | 3188 base::string16 tmp = value; |
3191 value = name; | 3189 value = name; |
3192 name = tmp; | 3190 name = tmp; |
3193 } | 3191 } |
3194 | 3192 |
3195 // If this doesn't have a value and is linked then set its value to the url | 3193 // If this doesn't have a value and is linked then set its value to the url |
3196 // attribute. This allows screen readers to read an empty link's destination. | 3194 // attribute. This allows screen readers to read an empty link's destination. |
3197 if (value.empty() && (ia_state() & STATE_SYSTEM_LINKED)) | 3195 if (value.empty() && (ia_state() & STATE_SYSTEM_LINKED)) |
3198 value = GetString16Attribute(ui::AX_ATTR_URL); | 3196 value = GetString16Attribute(ui::AX_ATTR_URL); |
3199 | 3197 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3296 (ia_state() & STATE_SYSTEM_SELECTABLE) && | 3294 (ia_state() & STATE_SYSTEM_SELECTABLE) && |
3297 (ia_state() & STATE_SYSTEM_FOCUSED) && | 3295 (ia_state() & STATE_SYSTEM_FOCUSED) && |
3298 !(old_win_attributes_->ia_state & STATE_SYSTEM_FOCUSED)) { | 3296 !(old_win_attributes_->ia_state & STATE_SYSTEM_FOCUSED)) { |
3299 manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_FOCUS, this); | 3297 manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_FOCUS, this); |
3300 } | 3298 } |
3301 | 3299 |
3302 // Handle selection being added or removed. | 3300 // Handle selection being added or removed. |
3303 bool is_selected_now = (ia_state() & STATE_SYSTEM_SELECTED) != 0; | 3301 bool is_selected_now = (ia_state() & STATE_SYSTEM_SELECTED) != 0; |
3304 bool was_selected_before = | 3302 bool was_selected_before = |
3305 (old_win_attributes_->ia_state & STATE_SYSTEM_SELECTED) != 0; | 3303 (old_win_attributes_->ia_state & STATE_SYSTEM_SELECTED) != 0; |
3306 if (is_selected_now && !was_selected_before) { | 3304 if (is_selected_now || was_selected_before) { |
3307 manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_SELECTIONADD, this); | 3305 bool multiselect = false; |
3308 } else if (!is_selected_now && was_selected_before) { | 3306 if (GetParent() && GetParent()->HasState(ui::AX_STATE_MULTISELECTABLE)) |
3309 manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_SELECTIONREMOVE, this); | 3307 multiselect = true; |
3308 | |
3309 if (multiselect) { | |
je_julie(Not used)
2015/04/06 10:31:48
Do we need this variable? it doesn't seem to be us
| |
3310 // In a multi-select box, fire SELECTIONADD and SELECTIONREMOVE events. | |
3311 if (is_selected_now && !was_selected_before) { | |
3312 manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_SELECTIONADD, this); | |
3313 } else if (!is_selected_now && was_selected_before) { | |
3314 manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_SELECTIONREMOVE, this); | |
3315 } | |
3316 } else if (is_selected_now && !was_selected_before) { | |
3317 // In a single-select box, only fire SELECTION events. | |
3318 manager->MaybeCallNotifyWinEvent(EVENT_OBJECT_SELECTION, this); | |
3319 } | |
3310 } | 3320 } |
3311 | 3321 |
3312 // Fire an event if this container object has scrolled. | 3322 // Fire an event if this container object has scrolled. |
3313 int sx = 0; | 3323 int sx = 0; |
3314 int sy = 0; | 3324 int sy = 0; |
3315 if (GetIntAttribute(ui::AX_ATTR_SCROLL_X, &sx) && | 3325 if (GetIntAttribute(ui::AX_ATTR_SCROLL_X, &sx) && |
3316 GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &sy)) { | 3326 GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &sy)) { |
3317 if (sx != previous_scroll_x_ || sy != previous_scroll_y_) | 3327 if (sx != previous_scroll_x_ || sy != previous_scroll_y_) |
3318 manager->MaybeCallNotifyWinEvent(EVENT_SYSTEM_SCROLLINGEND, this); | 3328 manager->MaybeCallNotifyWinEvent(EVENT_SYSTEM_SCROLLINGEND, this); |
3319 previous_scroll_x_ = sx; | 3329 previous_scroll_x_ = sx; |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3459 base::string16 value = this->value(); | 3469 base::string16 value = this->value(); |
3460 | 3470 |
3461 if (value.empty() && | 3471 if (value.empty() && |
3462 GetFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE, &fval)) { | 3472 GetFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE, &fval)) { |
3463 value = base::UTF8ToUTF16(base::DoubleToString(fval)); | 3473 value = base::UTF8ToUTF16(base::DoubleToString(fval)); |
3464 } | 3474 } |
3465 return value; | 3475 return value; |
3466 } | 3476 } |
3467 | 3477 |
3468 base::string16 BrowserAccessibilityWin::TextForIAccessibleText() { | 3478 base::string16 BrowserAccessibilityWin::TextForIAccessibleText() { |
3469 if (IsEditableText()) | 3479 if (IsEditableText() || GetRole() == ui::AX_ROLE_MENU_LIST_OPTION) |
3470 return value(); | 3480 return value(); |
3471 return (GetRole() == ui::AX_ROLE_STATIC_TEXT) ? name() : hypertext(); | 3481 return (GetRole() == ui::AX_ROLE_STATIC_TEXT) ? name() : hypertext(); |
3472 } | 3482 } |
3473 | 3483 |
3474 bool BrowserAccessibilityWin::IsSameHypertextCharacter(size_t old_char_index, | 3484 bool BrowserAccessibilityWin::IsSameHypertextCharacter(size_t old_char_index, |
3475 size_t new_char_index) { | 3485 size_t new_char_index) { |
3476 CHECK(old_win_attributes_); | 3486 CHECK(old_win_attributes_); |
3477 | 3487 |
3478 // For anything other than the "embedded character", we just compare the | 3488 // For anything other than the "embedded character", we just compare the |
3479 // characters directly. | 3489 // characters directly. |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3585 const std::vector<int32>& line_breaks = GetIntListAttribute( | 3595 const std::vector<int32>& line_breaks = GetIntListAttribute( |
3586 ui::AX_ATTR_LINE_BREAKS); | 3596 ui::AX_ATTR_LINE_BREAKS); |
3587 return ui::FindAccessibleTextBoundary( | 3597 return ui::FindAccessibleTextBoundary( |
3588 text, line_breaks, boundary, start_offset, direction); | 3598 text, line_breaks, boundary, start_offset, direction); |
3589 } | 3599 } |
3590 | 3600 |
3591 BrowserAccessibilityWin* BrowserAccessibilityWin::GetFromID(int32 id) { | 3601 BrowserAccessibilityWin* BrowserAccessibilityWin::GetFromID(int32 id) { |
3592 return manager()->GetFromID(id)->ToBrowserAccessibilityWin(); | 3602 return manager()->GetFromID(id)->ToBrowserAccessibilityWin(); |
3593 } | 3603 } |
3594 | 3604 |
3605 bool BrowserAccessibilityWin::IsListBoxOptionOrMenuListOption() { | |
3606 if (!GetParent()) | |
3607 return false; | |
3608 | |
3609 int32 role = GetRole(); | |
3610 int32 parent_role = GetParent()->GetRole(); | |
3611 | |
3612 if (role == ui::AX_ROLE_LIST_BOX_OPTION && | |
3613 parent_role == ui::AX_ROLE_LIST_BOX) { | |
3614 return true; | |
3615 } | |
3616 | |
3617 if (role == ui::AX_ROLE_MENU_LIST_OPTION && | |
3618 parent_role == ui::AX_ROLE_MENU_LIST_POPUP) { | |
3619 return true; | |
3620 } | |
3621 | |
3622 return false; | |
3623 } | |
3624 | |
3595 void BrowserAccessibilityWin::InitRoleAndState() { | 3625 void BrowserAccessibilityWin::InitRoleAndState() { |
3596 int32 ia_role = 0; | 3626 int32 ia_role = 0; |
3597 int32 ia_state = 0; | 3627 int32 ia_state = 0; |
3598 base::string16 role_name; | 3628 base::string16 role_name; |
3599 int32 ia2_role = 0; | 3629 int32 ia2_role = 0; |
3600 int32 ia2_state = IA2_STATE_OPAQUE; | 3630 int32 ia2_state = IA2_STATE_OPAQUE; |
3601 | 3631 |
3602 if (HasState(ui::AX_STATE_BUSY)) | 3632 if (HasState(ui::AX_STATE_BUSY)) |
3603 ia_state |= STATE_SYSTEM_BUSY; | 3633 ia_state |= STATE_SYSTEM_BUSY; |
3604 if (HasState(ui::AX_STATE_CHECKED)) | 3634 if (HasState(ui::AX_STATE_CHECKED)) |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3907 case ui::AX_ROLE_MENU_ITEM_CHECK_BOX: | 3937 case ui::AX_ROLE_MENU_ITEM_CHECK_BOX: |
3908 ia_role = ROLE_SYSTEM_MENUITEM; | 3938 ia_role = ROLE_SYSTEM_MENUITEM; |
3909 ia2_role = IA2_ROLE_CHECK_MENU_ITEM; | 3939 ia2_role = IA2_ROLE_CHECK_MENU_ITEM; |
3910 ia2_state |= IA2_STATE_CHECKABLE; | 3940 ia2_state |= IA2_STATE_CHECKABLE; |
3911 break; | 3941 break; |
3912 case ui::AX_ROLE_MENU_ITEM_RADIO: | 3942 case ui::AX_ROLE_MENU_ITEM_RADIO: |
3913 ia_role = ROLE_SYSTEM_MENUITEM; | 3943 ia_role = ROLE_SYSTEM_MENUITEM; |
3914 ia2_role = IA2_ROLE_RADIO_MENU_ITEM; | 3944 ia2_role = IA2_ROLE_RADIO_MENU_ITEM; |
3915 break; | 3945 break; |
3916 case ui::AX_ROLE_MENU_LIST_POPUP: | 3946 case ui::AX_ROLE_MENU_LIST_POPUP: |
3917 ia_role = ROLE_SYSTEM_CLIENT; | 3947 ia_role = ROLE_SYSTEM_LIST; |
3948 ia2_state &= ~(IA2_STATE_EDITABLE); | |
3918 break; | 3949 break; |
3919 case ui::AX_ROLE_MENU_LIST_OPTION: | 3950 case ui::AX_ROLE_MENU_LIST_OPTION: |
3920 ia_role = ROLE_SYSTEM_LISTITEM; | 3951 ia_role = ROLE_SYSTEM_LISTITEM; |
3952 ia2_state &= ~(IA2_STATE_EDITABLE); | |
3921 if (ia_state & STATE_SYSTEM_SELECTABLE) { | 3953 if (ia_state & STATE_SYSTEM_SELECTABLE) { |
3922 ia_state |= STATE_SYSTEM_FOCUSABLE; | 3954 ia_state |= STATE_SYSTEM_FOCUSABLE; |
3923 if (HasState(ui::AX_STATE_FOCUSED)) | 3955 if (HasState(ui::AX_STATE_FOCUSED)) |
3924 ia_state |= STATE_SYSTEM_FOCUSED; | 3956 ia_state |= STATE_SYSTEM_FOCUSED; |
3925 } | 3957 } |
3926 break; | 3958 break; |
3927 case ui::AX_ROLE_METER: | 3959 case ui::AX_ROLE_METER: |
3928 role_name = html_tag; | 3960 role_name = html_tag; |
3929 ia_role = ROLE_SYSTEM_PROGRESSBAR; | 3961 ia_role = ROLE_SYSTEM_PROGRESSBAR; |
3930 break; | 3962 break; |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4137 ia2_role = ia_role; | 4169 ia2_role = ia_role; |
4138 | 4170 |
4139 win_attributes_->ia_role = ia_role; | 4171 win_attributes_->ia_role = ia_role; |
4140 win_attributes_->ia_state = ia_state; | 4172 win_attributes_->ia_state = ia_state; |
4141 win_attributes_->role_name = role_name; | 4173 win_attributes_->role_name = role_name; |
4142 win_attributes_->ia2_role = ia2_role; | 4174 win_attributes_->ia2_role = ia2_role; |
4143 win_attributes_->ia2_state = ia2_state; | 4175 win_attributes_->ia2_state = ia2_state; |
4144 } | 4176 } |
4145 | 4177 |
4146 } // namespace content | 4178 } // namespace content |
OLD | NEW |