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 2961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2972 ui::AX_ATTR_UNIQUE_CELL_IDS); | 2972 ui::AX_ATTR_UNIQUE_CELL_IDS); |
2973 for (size_t i = 0; i < unique_cell_ids.size(); ++i) { | 2973 for (size_t i = 0; i < unique_cell_ids.size(); ++i) { |
2974 if (unique_cell_ids[i] == GetId()) { | 2974 if (unique_cell_ids[i] == GetId()) { |
2975 ia2_attributes_.push_back( | 2975 ia2_attributes_.push_back( |
2976 base::string16(L"table-cell-index:") + base::IntToString16(i)); | 2976 base::string16(L"table-cell-index:") + base::IntToString16(i)); |
2977 } | 2977 } |
2978 } | 2978 } |
2979 } | 2979 } |
2980 } | 2980 } |
2981 | 2981 |
2982 // Expose invalid state for form controls and elements with aria-invalid. | |
2983 int invalidState; | |
dmazzoni
2014/12/19 17:30:33
nit: invalid_state (c++ files in Chromium are like
| |
2984 if (GetIntAttribute(ui::AX_ATTR_INVALID_STATE, &invalidState)) { | |
2985 // TODO(nektar): Handle the possibility of having multiple aria-invalid | |
2986 // attributes defined, e.g., "invalid:spelling,grammar". | |
2987 switch (invalidState) { | |
2988 case ui::AX_INVALID_STATE_NONE: | |
2989 break; | |
2990 case ui::AX_INVALID_STATE_FALSE: | |
2991 ia2_attributes_.push_back(L"invalid:false"); | |
2992 break; | |
2993 case ui::AX_INVALID_STATE_TRUE: | |
2994 ia2_attributes_.push_back(L"invalid:true"); | |
2995 break; | |
2996 case ui::AX_INVALID_STATE_SPELLING: | |
2997 ia2_attributes_.push_back(L"invalid:spelling"); | |
2998 break; | |
2999 case ui::AX_INVALID_STATE_GRAMMAR: | |
3000 ia2_attributes_.push_back(L"invalid:grammar"); | |
3001 break; | |
3002 case ui::AX_INVALID_STATE_OTHER: | |
3003 { | |
3004 base::string16 ariaInvalidValue; | |
3005 if (GetString16Attribute(ui::AX_ATTR_ARIA_INVALID_VALUE, | |
dmazzoni
2014/12/19 17:30:33
nit: you need braces for both the "if" and "else"
| |
3006 &ariaInvalidValue)) | |
3007 ia2_attributes_.push_back(L"invalid:" + ariaInvalidValue); | |
dmazzoni
2014/12/19 17:30:33
nit: indent 2 less
| |
3008 else | |
3009 // Set the attribute to L"true", since we cannot be more specific. | |
3010 ia2_attributes_.push_back(L"invalid:true"); | |
dmazzoni
2014/12/19 17:30:33
nit: indent 2 less
| |
3011 } | |
3012 break; | |
3013 default: | |
3014 NOTREACHED(); | |
3015 } | |
3016 } | |
3017 | |
2982 // The calculation of the accessible name of an element has been | 3018 // The calculation of the accessible name of an element has been |
2983 // standardized in the HTML to Platform Accessibility APIs Implementation | 3019 // standardized in the HTML to Platform Accessibility APIs Implementation |
2984 // Guide (http://www.w3.org/TR/html-aapi/). In order to return the | 3020 // Guide (http://www.w3.org/TR/html-aapi/). In order to return the |
2985 // appropriate accessible name on Windows, we need to apply some logic | 3021 // appropriate accessible name on Windows, we need to apply some logic |
2986 // to the fields we get from WebKit. | 3022 // to the fields we get from WebKit. |
2987 // | 3023 // |
2988 // TODO(dmazzoni): move most of this logic into WebKit. | 3024 // TODO(dmazzoni): move most of this logic into WebKit. |
2989 // | 3025 // |
2990 // WebKit gives us: | 3026 // WebKit gives us: |
2991 // | 3027 // |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3278 LONG* offset) { | 3314 LONG* offset) { |
3279 if (*offset == IA2_TEXT_OFFSET_LENGTH) | 3315 if (*offset == IA2_TEXT_OFFSET_LENGTH) |
3280 *offset = static_cast<LONG>(text.size()); | 3316 *offset = static_cast<LONG>(text.size()); |
3281 else if (*offset == IA2_TEXT_OFFSET_CARET) | 3317 else if (*offset == IA2_TEXT_OFFSET_CARET) |
3282 get_caretOffset(offset); | 3318 get_caretOffset(offset); |
3283 } | 3319 } |
3284 | 3320 |
3285 ui::TextBoundaryType BrowserAccessibilityWin::IA2TextBoundaryToTextBoundary( | 3321 ui::TextBoundaryType BrowserAccessibilityWin::IA2TextBoundaryToTextBoundary( |
3286 IA2TextBoundaryType ia2_boundary) { | 3322 IA2TextBoundaryType ia2_boundary) { |
3287 switch(ia2_boundary) { | 3323 switch(ia2_boundary) { |
3288 case IA2_TEXT_BOUNDARY_CHAR: return ui::CHAR_BOUNDARY; | 3324 case IA2_TEXT_BOUNDARY_CHAR: |
3289 case IA2_TEXT_BOUNDARY_WORD: return ui::WORD_BOUNDARY; | 3325 return ui::CHAR_BOUNDARY; |
3290 case IA2_TEXT_BOUNDARY_LINE: return ui::LINE_BOUNDARY; | 3326 case IA2_TEXT_BOUNDARY_WORD: |
3291 case IA2_TEXT_BOUNDARY_SENTENCE: return ui::SENTENCE_BOUNDARY; | 3327 return ui::WORD_BOUNDARY; |
3292 case IA2_TEXT_BOUNDARY_PARAGRAPH: return ui::PARAGRAPH_BOUNDARY; | 3328 case IA2_TEXT_BOUNDARY_LINE: |
3293 case IA2_TEXT_BOUNDARY_ALL: return ui::ALL_BOUNDARY; | 3329 return ui::LINE_BOUNDARY; |
3330 case IA2_TEXT_BOUNDARY_SENTENCE: | |
3331 return ui::SENTENCE_BOUNDARY; | |
3332 case IA2_TEXT_BOUNDARY_PARAGRAPH: | |
3333 return ui::PARAGRAPH_BOUNDARY; | |
3334 case IA2_TEXT_BOUNDARY_ALL: | |
3335 return ui::ALL_BOUNDARY; | |
3294 default: | 3336 default: |
3295 NOTREACHED(); | 3337 NOTREACHED(); |
3296 return ui::CHAR_BOUNDARY; | |
3297 } | 3338 } |
3339 return ui::CHAR_BOUNDARY; | |
3298 } | 3340 } |
3299 | 3341 |
3300 LONG BrowserAccessibilityWin::FindBoundary( | 3342 LONG BrowserAccessibilityWin::FindBoundary( |
3301 const base::string16& text, | 3343 const base::string16& text, |
3302 IA2TextBoundaryType ia2_boundary, | 3344 IA2TextBoundaryType ia2_boundary, |
3303 LONG start_offset, | 3345 LONG start_offset, |
3304 ui::TextBoundaryDirection direction) { | 3346 ui::TextBoundaryDirection direction) { |
3305 HandleSpecialTextOffset(text, &start_offset); | 3347 HandleSpecialTextOffset(text, &start_offset); |
3306 ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary); | 3348 ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary); |
3307 const std::vector<int32>& line_breaks = GetIntListAttribute( | 3349 const std::vector<int32>& line_breaks = GetIntListAttribute( |
(...skipping 20 matching lines...) Expand all Loading... | |
3328 if (HasState(ui::AX_STATE_EXPANDED)) | 3370 if (HasState(ui::AX_STATE_EXPANDED)) |
3329 ia_state_ |= STATE_SYSTEM_EXPANDED; | 3371 ia_state_ |= STATE_SYSTEM_EXPANDED; |
3330 if (HasState(ui::AX_STATE_FOCUSABLE)) | 3372 if (HasState(ui::AX_STATE_FOCUSABLE)) |
3331 ia_state_ |= STATE_SYSTEM_FOCUSABLE; | 3373 ia_state_ |= STATE_SYSTEM_FOCUSABLE; |
3332 if (HasState(ui::AX_STATE_HASPOPUP)) | 3374 if (HasState(ui::AX_STATE_HASPOPUP)) |
3333 ia_state_ |= STATE_SYSTEM_HASPOPUP; | 3375 ia_state_ |= STATE_SYSTEM_HASPOPUP; |
3334 if (HasState(ui::AX_STATE_HOVERED)) | 3376 if (HasState(ui::AX_STATE_HOVERED)) |
3335 ia_state_ |= STATE_SYSTEM_HOTTRACKED; | 3377 ia_state_ |= STATE_SYSTEM_HOTTRACKED; |
3336 if (HasState(ui::AX_STATE_INDETERMINATE)) | 3378 if (HasState(ui::AX_STATE_INDETERMINATE)) |
3337 ia_state_ |= STATE_SYSTEM_INDETERMINATE; | 3379 ia_state_ |= STATE_SYSTEM_INDETERMINATE; |
3380 if (HasIntAttribute(ui::AX_ATTR_INVALID_STATE) && | |
3381 GetIntAttribute(ui::AX_ATTR_INVALID_STATE) != ui::AX_INVALID_STATE_FALSE) | |
3382 ia2_state_ |= IA2_STATE_INVALID_ENTRY; | |
dmazzoni
2014/12/19 17:30:34
nit: indent 2 less
| |
3338 if (HasState(ui::AX_STATE_INVISIBLE)) | 3383 if (HasState(ui::AX_STATE_INVISIBLE)) |
3339 ia_state_ |= STATE_SYSTEM_INVISIBLE; | 3384 ia_state_ |= STATE_SYSTEM_INVISIBLE; |
3340 if (HasState(ui::AX_STATE_LINKED)) | 3385 if (HasState(ui::AX_STATE_LINKED)) |
3341 ia_state_ |= STATE_SYSTEM_LINKED; | 3386 ia_state_ |= STATE_SYSTEM_LINKED; |
3342 if (HasState(ui::AX_STATE_MULTISELECTABLE)) { | 3387 if (HasState(ui::AX_STATE_MULTISELECTABLE)) { |
3343 ia_state_ |= STATE_SYSTEM_EXTSELECTABLE; | 3388 ia_state_ |= STATE_SYSTEM_EXTSELECTABLE; |
3344 ia_state_ |= STATE_SYSTEM_MULTISELECTABLE; | 3389 ia_state_ |= STATE_SYSTEM_MULTISELECTABLE; |
3345 } | 3390 } |
3346 // TODO(ctguil): Support STATE_SYSTEM_EXTSELECTABLE/accSelect. | 3391 // TODO(ctguil): Support STATE_SYSTEM_EXTSELECTABLE/accSelect. |
3347 if (HasState(ui::AX_STATE_OFFSCREEN)) | 3392 if (HasState(ui::AX_STATE_OFFSCREEN)) |
(...skipping 18 matching lines...) Expand all Loading... | |
3366 ia2_state_ |= IA2_STATE_HORIZONTAL; | 3411 ia2_state_ |= IA2_STATE_HORIZONTAL; |
3367 if (HasState(ui::AX_STATE_VISITED)) | 3412 if (HasState(ui::AX_STATE_VISITED)) |
3368 ia_state_ |= STATE_SYSTEM_TRAVERSED; | 3413 ia_state_ |= STATE_SYSTEM_TRAVERSED; |
3369 | 3414 |
3370 // WebKit marks everything as readonly unless it's editable text, so if it's | 3415 // WebKit marks everything as readonly unless it's editable text, so if it's |
3371 // not readonly, mark it as editable now. The final computation of the | 3416 // not readonly, mark it as editable now. The final computation of the |
3372 // READONLY state for MSAA is below, after the switch. | 3417 // READONLY state for MSAA is below, after the switch. |
3373 if (!HasState(ui::AX_STATE_READ_ONLY)) | 3418 if (!HasState(ui::AX_STATE_READ_ONLY)) |
3374 ia2_state_ |= IA2_STATE_EDITABLE; | 3419 ia2_state_ |= IA2_STATE_EDITABLE; |
3375 | 3420 |
3376 base::string16 invalid; | |
3377 if (GetHtmlAttribute("aria-invalid", &invalid)) | |
3378 ia2_state_ |= IA2_STATE_INVALID_ENTRY; | |
3379 | |
3380 if (GetBoolAttribute(ui::AX_ATTR_BUTTON_MIXED)) | 3421 if (GetBoolAttribute(ui::AX_ATTR_BUTTON_MIXED)) |
3381 ia_state_ |= STATE_SYSTEM_MIXED; | 3422 ia_state_ |= STATE_SYSTEM_MIXED; |
3382 | 3423 |
3383 if (GetBoolAttribute(ui::AX_ATTR_CAN_SET_VALUE)) | 3424 if (GetBoolAttribute(ui::AX_ATTR_CAN_SET_VALUE)) |
3384 ia2_state_ |= IA2_STATE_EDITABLE; | 3425 ia2_state_ |= IA2_STATE_EDITABLE; |
3385 | 3426 |
3386 if (!GetStringAttribute(ui::AX_ATTR_AUTO_COMPLETE).empty()) | 3427 if (!GetStringAttribute(ui::AX_ATTR_AUTO_COMPLETE).empty()) |
3387 ia2_state_ |= IA2_STATE_SUPPORTS_AUTOCOMPLETION; | 3428 ia2_state_ |= IA2_STATE_SUPPORTS_AUTOCOMPLETION; |
3388 | 3429 |
3389 base::string16 html_tag = GetString16Attribute( | 3430 base::string16 html_tag = GetString16Attribute( |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3831 // The role should always be set. | 3872 // The role should always be set. |
3832 DCHECK(!role_name_.empty() || ia_role_); | 3873 DCHECK(!role_name_.empty() || ia_role_); |
3833 | 3874 |
3834 // If we didn't explicitly set the IAccessible2 role, make it the same | 3875 // If we didn't explicitly set the IAccessible2 role, make it the same |
3835 // as the MSAA role. | 3876 // as the MSAA role. |
3836 if (!ia2_role_) | 3877 if (!ia2_role_) |
3837 ia2_role_ = ia_role_; | 3878 ia2_role_ = ia_role_; |
3838 } | 3879 } |
3839 | 3880 |
3840 } // namespace content | 3881 } // namespace content |
OLD | NEW |