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 2962 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2973 ui::AX_ATTR_UNIQUE_CELL_IDS); | 2973 ui::AX_ATTR_UNIQUE_CELL_IDS); |
2974 for (size_t i = 0; i < unique_cell_ids.size(); ++i) { | 2974 for (size_t i = 0; i < unique_cell_ids.size(); ++i) { |
2975 if (unique_cell_ids[i] == GetId()) { | 2975 if (unique_cell_ids[i] == GetId()) { |
2976 ia2_attributes_.push_back( | 2976 ia2_attributes_.push_back( |
2977 base::string16(L"table-cell-index:") + base::IntToString16(i)); | 2977 base::string16(L"table-cell-index:") + base::IntToString16(i)); |
2978 } | 2978 } |
2979 } | 2979 } |
2980 } | 2980 } |
2981 } | 2981 } |
2982 | 2982 |
| 2983 // Expose invalid state for form controls and elements with aria-invalid. |
| 2984 int invalid_state; |
| 2985 if (GetIntAttribute(ui::AX_ATTR_INVALID_STATE, &invalid_state)) { |
| 2986 // TODO(nektar): Handle the possibility of having multiple aria-invalid |
| 2987 // attributes defined, e.g., "invalid:spelling,grammar". |
| 2988 switch (invalid_state) { |
| 2989 case ui::AX_INVALID_STATE_NONE: |
| 2990 break; |
| 2991 case ui::AX_INVALID_STATE_FALSE: |
| 2992 ia2_attributes_.push_back(L"invalid:false"); |
| 2993 break; |
| 2994 case ui::AX_INVALID_STATE_TRUE: |
| 2995 ia2_attributes_.push_back(L"invalid:true"); |
| 2996 break; |
| 2997 case ui::AX_INVALID_STATE_SPELLING: |
| 2998 ia2_attributes_.push_back(L"invalid:spelling"); |
| 2999 break; |
| 3000 case ui::AX_INVALID_STATE_GRAMMAR: |
| 3001 ia2_attributes_.push_back(L"invalid:grammar"); |
| 3002 break; |
| 3003 case ui::AX_INVALID_STATE_OTHER: |
| 3004 { |
| 3005 base::string16 aria_invalid_value; |
| 3006 if (GetString16Attribute(ui::AX_ATTR_ARIA_INVALID_VALUE, |
| 3007 &aria_invalid_value)) { |
| 3008 ia2_attributes_.push_back(L"invalid:" + aria_invalid_value); |
| 3009 } else { |
| 3010 // Set the attribute to L"true", since we cannot be more specific. |
| 3011 ia2_attributes_.push_back(L"invalid:true"); |
| 3012 } |
| 3013 } |
| 3014 break; |
| 3015 default: |
| 3016 NOTREACHED(); |
| 3017 } |
| 3018 } |
| 3019 |
2983 // The calculation of the accessible name of an element has been | 3020 // The calculation of the accessible name of an element has been |
2984 // standardized in the HTML to Platform Accessibility APIs Implementation | 3021 // standardized in the HTML to Platform Accessibility APIs Implementation |
2985 // Guide (http://www.w3.org/TR/html-aapi/). In order to return the | 3022 // Guide (http://www.w3.org/TR/html-aapi/). In order to return the |
2986 // appropriate accessible name on Windows, we need to apply some logic | 3023 // appropriate accessible name on Windows, we need to apply some logic |
2987 // to the fields we get from WebKit. | 3024 // to the fields we get from WebKit. |
2988 // | 3025 // |
2989 // TODO(dmazzoni): move most of this logic into WebKit. | 3026 // TODO(dmazzoni): move most of this logic into WebKit. |
2990 // | 3027 // |
2991 // WebKit gives us: | 3028 // WebKit gives us: |
2992 // | 3029 // |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3287 LONG* offset) { | 3324 LONG* offset) { |
3288 if (*offset == IA2_TEXT_OFFSET_LENGTH) | 3325 if (*offset == IA2_TEXT_OFFSET_LENGTH) |
3289 *offset = static_cast<LONG>(text.size()); | 3326 *offset = static_cast<LONG>(text.size()); |
3290 else if (*offset == IA2_TEXT_OFFSET_CARET) | 3327 else if (*offset == IA2_TEXT_OFFSET_CARET) |
3291 get_caretOffset(offset); | 3328 get_caretOffset(offset); |
3292 } | 3329 } |
3293 | 3330 |
3294 ui::TextBoundaryType BrowserAccessibilityWin::IA2TextBoundaryToTextBoundary( | 3331 ui::TextBoundaryType BrowserAccessibilityWin::IA2TextBoundaryToTextBoundary( |
3295 IA2TextBoundaryType ia2_boundary) { | 3332 IA2TextBoundaryType ia2_boundary) { |
3296 switch(ia2_boundary) { | 3333 switch(ia2_boundary) { |
3297 case IA2_TEXT_BOUNDARY_CHAR: return ui::CHAR_BOUNDARY; | 3334 case IA2_TEXT_BOUNDARY_CHAR: |
3298 case IA2_TEXT_BOUNDARY_WORD: return ui::WORD_BOUNDARY; | 3335 return ui::CHAR_BOUNDARY; |
3299 case IA2_TEXT_BOUNDARY_LINE: return ui::LINE_BOUNDARY; | 3336 case IA2_TEXT_BOUNDARY_WORD: |
3300 case IA2_TEXT_BOUNDARY_SENTENCE: return ui::SENTENCE_BOUNDARY; | 3337 return ui::WORD_BOUNDARY; |
3301 case IA2_TEXT_BOUNDARY_PARAGRAPH: return ui::PARAGRAPH_BOUNDARY; | 3338 case IA2_TEXT_BOUNDARY_LINE: |
3302 case IA2_TEXT_BOUNDARY_ALL: return ui::ALL_BOUNDARY; | 3339 return ui::LINE_BOUNDARY; |
| 3340 case IA2_TEXT_BOUNDARY_SENTENCE: |
| 3341 return ui::SENTENCE_BOUNDARY; |
| 3342 case IA2_TEXT_BOUNDARY_PARAGRAPH: |
| 3343 return ui::PARAGRAPH_BOUNDARY; |
| 3344 case IA2_TEXT_BOUNDARY_ALL: |
| 3345 return ui::ALL_BOUNDARY; |
3303 default: | 3346 default: |
3304 NOTREACHED(); | 3347 NOTREACHED(); |
3305 return ui::CHAR_BOUNDARY; | |
3306 } | 3348 } |
| 3349 return ui::CHAR_BOUNDARY; |
3307 } | 3350 } |
3308 | 3351 |
3309 LONG BrowserAccessibilityWin::FindBoundary( | 3352 LONG BrowserAccessibilityWin::FindBoundary( |
3310 const base::string16& text, | 3353 const base::string16& text, |
3311 IA2TextBoundaryType ia2_boundary, | 3354 IA2TextBoundaryType ia2_boundary, |
3312 LONG start_offset, | 3355 LONG start_offset, |
3313 ui::TextBoundaryDirection direction) { | 3356 ui::TextBoundaryDirection direction) { |
3314 HandleSpecialTextOffset(text, &start_offset); | 3357 HandleSpecialTextOffset(text, &start_offset); |
3315 ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary); | 3358 ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary); |
3316 const std::vector<int32>& line_breaks = GetIntListAttribute( | 3359 const std::vector<int32>& line_breaks = GetIntListAttribute( |
(...skipping 20 matching lines...) Expand all Loading... |
3337 if (HasState(ui::AX_STATE_EXPANDED)) | 3380 if (HasState(ui::AX_STATE_EXPANDED)) |
3338 ia_state_ |= STATE_SYSTEM_EXPANDED; | 3381 ia_state_ |= STATE_SYSTEM_EXPANDED; |
3339 if (HasState(ui::AX_STATE_FOCUSABLE)) | 3382 if (HasState(ui::AX_STATE_FOCUSABLE)) |
3340 ia_state_ |= STATE_SYSTEM_FOCUSABLE; | 3383 ia_state_ |= STATE_SYSTEM_FOCUSABLE; |
3341 if (HasState(ui::AX_STATE_HASPOPUP)) | 3384 if (HasState(ui::AX_STATE_HASPOPUP)) |
3342 ia_state_ |= STATE_SYSTEM_HASPOPUP; | 3385 ia_state_ |= STATE_SYSTEM_HASPOPUP; |
3343 if (HasState(ui::AX_STATE_HOVERED)) | 3386 if (HasState(ui::AX_STATE_HOVERED)) |
3344 ia_state_ |= STATE_SYSTEM_HOTTRACKED; | 3387 ia_state_ |= STATE_SYSTEM_HOTTRACKED; |
3345 if (HasState(ui::AX_STATE_INDETERMINATE)) | 3388 if (HasState(ui::AX_STATE_INDETERMINATE)) |
3346 ia_state_ |= STATE_SYSTEM_INDETERMINATE; | 3389 ia_state_ |= STATE_SYSTEM_INDETERMINATE; |
| 3390 if (HasIntAttribute(ui::AX_ATTR_INVALID_STATE) && |
| 3391 GetIntAttribute(ui::AX_ATTR_INVALID_STATE) != ui::AX_INVALID_STATE_FALSE) |
| 3392 ia2_state_ |= IA2_STATE_INVALID_ENTRY; |
3347 if (HasState(ui::AX_STATE_INVISIBLE)) | 3393 if (HasState(ui::AX_STATE_INVISIBLE)) |
3348 ia_state_ |= STATE_SYSTEM_INVISIBLE; | 3394 ia_state_ |= STATE_SYSTEM_INVISIBLE; |
3349 if (HasState(ui::AX_STATE_LINKED)) | 3395 if (HasState(ui::AX_STATE_LINKED)) |
3350 ia_state_ |= STATE_SYSTEM_LINKED; | 3396 ia_state_ |= STATE_SYSTEM_LINKED; |
3351 if (HasState(ui::AX_STATE_MULTISELECTABLE)) { | 3397 if (HasState(ui::AX_STATE_MULTISELECTABLE)) { |
3352 ia_state_ |= STATE_SYSTEM_EXTSELECTABLE; | 3398 ia_state_ |= STATE_SYSTEM_EXTSELECTABLE; |
3353 ia_state_ |= STATE_SYSTEM_MULTISELECTABLE; | 3399 ia_state_ |= STATE_SYSTEM_MULTISELECTABLE; |
3354 } | 3400 } |
3355 // TODO(ctguil): Support STATE_SYSTEM_EXTSELECTABLE/accSelect. | 3401 // TODO(ctguil): Support STATE_SYSTEM_EXTSELECTABLE/accSelect. |
3356 if (HasState(ui::AX_STATE_OFFSCREEN)) | 3402 if (HasState(ui::AX_STATE_OFFSCREEN)) |
(...skipping 18 matching lines...) Expand all Loading... |
3375 ia2_state_ |= IA2_STATE_HORIZONTAL; | 3421 ia2_state_ |= IA2_STATE_HORIZONTAL; |
3376 if (HasState(ui::AX_STATE_VISITED)) | 3422 if (HasState(ui::AX_STATE_VISITED)) |
3377 ia_state_ |= STATE_SYSTEM_TRAVERSED; | 3423 ia_state_ |= STATE_SYSTEM_TRAVERSED; |
3378 | 3424 |
3379 // WebKit marks everything as readonly unless it's editable text, so if it's | 3425 // WebKit marks everything as readonly unless it's editable text, so if it's |
3380 // not readonly, mark it as editable now. The final computation of the | 3426 // not readonly, mark it as editable now. The final computation of the |
3381 // READONLY state for MSAA is below, after the switch. | 3427 // READONLY state for MSAA is below, after the switch. |
3382 if (!HasState(ui::AX_STATE_READ_ONLY)) | 3428 if (!HasState(ui::AX_STATE_READ_ONLY)) |
3383 ia2_state_ |= IA2_STATE_EDITABLE; | 3429 ia2_state_ |= IA2_STATE_EDITABLE; |
3384 | 3430 |
3385 base::string16 invalid; | |
3386 if (GetHtmlAttribute("aria-invalid", &invalid)) | |
3387 ia2_state_ |= IA2_STATE_INVALID_ENTRY; | |
3388 | |
3389 if (GetBoolAttribute(ui::AX_ATTR_BUTTON_MIXED)) | 3431 if (GetBoolAttribute(ui::AX_ATTR_BUTTON_MIXED)) |
3390 ia_state_ |= STATE_SYSTEM_MIXED; | 3432 ia_state_ |= STATE_SYSTEM_MIXED; |
3391 | 3433 |
3392 if (GetBoolAttribute(ui::AX_ATTR_CAN_SET_VALUE)) | 3434 if (GetBoolAttribute(ui::AX_ATTR_CAN_SET_VALUE)) |
3393 ia2_state_ |= IA2_STATE_EDITABLE; | 3435 ia2_state_ |= IA2_STATE_EDITABLE; |
3394 | 3436 |
3395 if (!GetStringAttribute(ui::AX_ATTR_AUTO_COMPLETE).empty()) | 3437 if (!GetStringAttribute(ui::AX_ATTR_AUTO_COMPLETE).empty()) |
3396 ia2_state_ |= IA2_STATE_SUPPORTS_AUTOCOMPLETION; | 3438 ia2_state_ |= IA2_STATE_SUPPORTS_AUTOCOMPLETION; |
3397 | 3439 |
3398 base::string16 html_tag = GetString16Attribute( | 3440 base::string16 html_tag = GetString16Attribute( |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3851 // The role should always be set. | 3893 // The role should always be set. |
3852 DCHECK(!role_name_.empty() || ia_role_); | 3894 DCHECK(!role_name_.empty() || ia_role_); |
3853 | 3895 |
3854 // If we didn't explicitly set the IAccessible2 role, make it the same | 3896 // If we didn't explicitly set the IAccessible2 role, make it the same |
3855 // as the MSAA role. | 3897 // as the MSAA role. |
3856 if (!ia2_role_) | 3898 if (!ia2_role_) |
3857 ia2_role_ = ia_role_; | 3899 ia2_role_ = ia_role_; |
3858 } | 3900 } |
3859 | 3901 |
3860 } // namespace content | 3902 } // namespace content |
OLD | NEW |