| OLD | NEW |
| 1 // Copyright (c) 2017 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2017 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_com_win.h" | 5 #include "content/browser/accessibility/browser_accessibility_com_win.h" |
| 6 | 6 |
| 7 #include <UIAutomationClient.h> | 7 #include <UIAutomationClient.h> |
| 8 #include <UIAutomationCoreApi.h> | 8 #include <UIAutomationCoreApi.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 | 560 |
| 561 STDMETHODIMP BrowserAccessibilityComWin::get_accState(VARIANT var_id, | 561 STDMETHODIMP BrowserAccessibilityComWin::get_accState(VARIANT var_id, |
| 562 VARIANT* state) { | 562 VARIANT* state) { |
| 563 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_STATE); | 563 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_STATE); |
| 564 if (!owner()) | 564 if (!owner()) |
| 565 return E_FAIL; | 565 return E_FAIL; |
| 566 | 566 |
| 567 return AXPlatformNodeWin::get_accState(var_id, state); | 567 return AXPlatformNodeWin::get_accState(var_id, state); |
| 568 } | 568 } |
| 569 | 569 |
| 570 bool BrowserAccessibilityComWin::IsRangeValueSupported() { | |
| 571 switch (MSAARole()) { | |
| 572 case ROLE_SYSTEM_PROGRESSBAR: | |
| 573 case ROLE_SYSTEM_SLIDER: | |
| 574 case ROLE_SYSTEM_SPINBUTTON: | |
| 575 case ROLE_SYSTEM_SCROLLBAR: | |
| 576 return true; | |
| 577 case ROLE_SYSTEM_SEPARATOR: | |
| 578 return owner()->HasState(ui::AX_STATE_FOCUSABLE); | |
| 579 default: | |
| 580 return false; | |
| 581 } | |
| 582 } | |
| 583 | |
| 584 STDMETHODIMP BrowserAccessibilityComWin::get_accValue(VARIANT var_id, | 570 STDMETHODIMP BrowserAccessibilityComWin::get_accValue(VARIANT var_id, |
| 585 BSTR* value) { | 571 BSTR* value) { |
| 586 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_VALUE); | 572 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_VALUE); |
| 587 if (!owner()) | 573 if (!owner()) |
| 588 return E_FAIL; | 574 return E_FAIL; |
| 589 | 575 |
| 590 return AXPlatformNodeWin::get_accValue(var_id, value); | 576 return AXPlatformNodeWin::get_accValue(var_id, value); |
| 591 } | 577 } |
| 592 | 578 |
| 593 STDMETHODIMP BrowserAccessibilityComWin::get_accHelpTopic(BSTR* help_file, | 579 STDMETHODIMP BrowserAccessibilityComWin::get_accHelpTopic(BSTR* help_file, |
| (...skipping 2610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3204 // Swap win_attributes_ to old_win_attributes_, allowing us to see | 3190 // Swap win_attributes_ to old_win_attributes_, allowing us to see |
| 3205 // exactly what changed and fire appropriate events. Note that | 3191 // exactly what changed and fire appropriate events. Note that |
| 3206 // old_win_attributes_ is cleared at the end of UpdateStep3FireEvents. | 3192 // old_win_attributes_ is cleared at the end of UpdateStep3FireEvents. |
| 3207 old_win_attributes_.swap(win_attributes_); | 3193 old_win_attributes_.swap(win_attributes_); |
| 3208 win_attributes_.reset(new WinAttributes()); | 3194 win_attributes_.reset(new WinAttributes()); |
| 3209 | 3195 |
| 3210 win_attributes_->ia_role = MSAARole(); | 3196 win_attributes_->ia_role = MSAARole(); |
| 3211 win_attributes_->ia_state = MSAAState(); | 3197 win_attributes_->ia_state = MSAAState(); |
| 3212 win_attributes_->role_name = base::UTF8ToUTF16(StringOverrideForMSAARole()); | 3198 win_attributes_->role_name = base::UTF8ToUTF16(StringOverrideForMSAARole()); |
| 3213 | 3199 |
| 3214 win_attributes_->ia2_role = IA2Role(); | 3200 win_attributes_->ia2_role = ComputeIA2Role(); |
| 3215 // If we didn't explicitly set the IAccessible2 role, make it the same | 3201 // If we didn't explicitly set the IAccessible2 role, make it the same |
| 3216 // as the MSAA role. | 3202 // as the MSAA role. |
| 3217 if (!win_attributes_->ia2_role) | 3203 if (!win_attributes_->ia2_role) |
| 3218 win_attributes_->ia2_role = win_attributes_->ia_role; | 3204 win_attributes_->ia2_role = win_attributes_->ia_role; |
| 3219 | 3205 |
| 3220 win_attributes_->ia2_state = IA2State(); | 3206 win_attributes_->ia2_state = ComputeIA2State(); |
| 3221 | 3207 win_attributes_->ia2_attributes = ComputeIA2Attributes(); |
| 3222 win_attributes_->ia2_attributes.clear(); | |
| 3223 | |
| 3224 // Expose some HTLM and ARIA attributes in the IAccessible2 attributes string. | |
| 3225 // "display", "tag", and "xml-roles" have somewhat unusual names for | |
| 3226 // historical reasons. Aside from that virtually every ARIA attribute | |
| 3227 // is exposed in a really straightforward way, i.e. "aria-foo" is exposed | |
| 3228 // as "foo". | |
| 3229 StringAttributeToIA2(ui::AX_ATTR_DISPLAY, "display"); | |
| 3230 StringAttributeToIA2(ui::AX_ATTR_HTML_TAG, "tag"); | |
| 3231 StringAttributeToIA2(ui::AX_ATTR_ROLE, "xml-roles"); | |
| 3232 | |
| 3233 StringAttributeToIA2(ui::AX_ATTR_AUTO_COMPLETE, "autocomplete"); | |
| 3234 StringAttributeToIA2(ui::AX_ATTR_ROLE_DESCRIPTION, "roledescription"); | |
| 3235 StringAttributeToIA2(ui::AX_ATTR_KEY_SHORTCUTS, "keyshortcuts"); | |
| 3236 | |
| 3237 IntAttributeToIA2(ui::AX_ATTR_HIERARCHICAL_LEVEL, "level"); | |
| 3238 IntAttributeToIA2(ui::AX_ATTR_SET_SIZE, "setsize"); | |
| 3239 IntAttributeToIA2(ui::AX_ATTR_POS_IN_SET, "posinset"); | |
| 3240 | |
| 3241 if (owner()->HasIntAttribute(ui::AX_ATTR_CHECKED_STATE)) | |
| 3242 win_attributes_->ia2_attributes.push_back(L"checkable:true"); | |
| 3243 | |
| 3244 // Expose live region attributes. | |
| 3245 StringAttributeToIA2(ui::AX_ATTR_LIVE_STATUS, "live"); | |
| 3246 StringAttributeToIA2(ui::AX_ATTR_LIVE_RELEVANT, "relevant"); | |
| 3247 BoolAttributeToIA2(ui::AX_ATTR_LIVE_ATOMIC, "atomic"); | |
| 3248 BoolAttributeToIA2(ui::AX_ATTR_LIVE_BUSY, "busy"); | |
| 3249 | |
| 3250 // Expose container live region attributes. | |
| 3251 StringAttributeToIA2(ui::AX_ATTR_CONTAINER_LIVE_STATUS, "container-live"); | |
| 3252 StringAttributeToIA2(ui::AX_ATTR_CONTAINER_LIVE_RELEVANT, | |
| 3253 "container-relevant"); | |
| 3254 BoolAttributeToIA2(ui::AX_ATTR_CONTAINER_LIVE_ATOMIC, "container-atomic"); | |
| 3255 BoolAttributeToIA2(ui::AX_ATTR_CONTAINER_LIVE_BUSY, "container-busy"); | |
| 3256 | |
| 3257 // Expose the non-standard explicit-name IA2 attribute. | |
| 3258 int name_from; | |
| 3259 if (owner()->GetIntAttribute(ui::AX_ATTR_NAME_FROM, &name_from) && | |
| 3260 name_from != ui::AX_NAME_FROM_CONTENTS) { | |
| 3261 win_attributes_->ia2_attributes.push_back(L"explicit-name:true"); | |
| 3262 } | |
| 3263 | |
| 3264 // Expose the aria-current attribute. | |
| 3265 int32_t aria_current_state; | |
| 3266 if (owner()->GetIntAttribute(ui::AX_ATTR_ARIA_CURRENT_STATE, | |
| 3267 &aria_current_state)) { | |
| 3268 switch (static_cast<ui::AXAriaCurrentState>(aria_current_state)) { | |
| 3269 case ui::AX_ARIA_CURRENT_STATE_NONE: | |
| 3270 break; | |
| 3271 case ui::AX_ARIA_CURRENT_STATE_FALSE: | |
| 3272 win_attributes_->ia2_attributes.push_back(L"current:false"); | |
| 3273 break; | |
| 3274 case ui::AX_ARIA_CURRENT_STATE_TRUE: | |
| 3275 win_attributes_->ia2_attributes.push_back(L"current:true"); | |
| 3276 break; | |
| 3277 case ui::AX_ARIA_CURRENT_STATE_PAGE: | |
| 3278 win_attributes_->ia2_attributes.push_back(L"current:page"); | |
| 3279 break; | |
| 3280 case ui::AX_ARIA_CURRENT_STATE_STEP: | |
| 3281 win_attributes_->ia2_attributes.push_back(L"current:step"); | |
| 3282 break; | |
| 3283 case ui::AX_ARIA_CURRENT_STATE_LOCATION: | |
| 3284 win_attributes_->ia2_attributes.push_back(L"current:location"); | |
| 3285 break; | |
| 3286 case ui::AX_ARIA_CURRENT_STATE_DATE: | |
| 3287 win_attributes_->ia2_attributes.push_back(L"current:date"); | |
| 3288 break; | |
| 3289 case ui::AX_ARIA_CURRENT_STATE_TIME: | |
| 3290 win_attributes_->ia2_attributes.push_back(L"current:time"); | |
| 3291 break; | |
| 3292 } | |
| 3293 } | |
| 3294 | |
| 3295 // Expose table cell index. | |
| 3296 if (ui::IsCellOrTableHeaderRole(owner()->GetRole())) { | |
| 3297 BrowserAccessibilityWin* win_parent = | |
| 3298 static_cast<BrowserAccessibilityWin*>(owner()->PlatformGetParent()); | |
| 3299 AXPlatformNodeBase* table = win_parent->GetCOM(); | |
| 3300 | |
| 3301 while (table && !ui::IsTableLikeRole(table->GetData().role)) | |
| 3302 table = FromNativeViewAccessible(table->GetParent()); | |
| 3303 | |
| 3304 if (table) { | |
| 3305 const std::vector<int32_t>& unique_cell_ids = | |
| 3306 table->GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS); | |
| 3307 for (size_t i = 0; i < unique_cell_ids.size(); ++i) { | |
| 3308 if (unique_cell_ids[i] == owner()->GetId()) { | |
| 3309 win_attributes_->ia2_attributes.push_back( | |
| 3310 base::string16(L"table-cell-index:") + base::IntToString16(i)); | |
| 3311 } | |
| 3312 } | |
| 3313 } | |
| 3314 } | |
| 3315 | |
| 3316 // Expose aria-colcount and aria-rowcount in a table, grid or treegrid. | |
| 3317 if (ui::IsTableLikeRole(owner()->GetRole())) { | |
| 3318 IntAttributeToIA2(ui::AX_ATTR_ARIA_COLUMN_COUNT, "colcount"); | |
| 3319 IntAttributeToIA2(ui::AX_ATTR_ARIA_ROW_COUNT, "rowcount"); | |
| 3320 } | |
| 3321 | |
| 3322 // Expose aria-colindex and aria-rowindex in a cell or row. | |
| 3323 if (ui::IsCellOrTableHeaderRole(owner()->GetRole()) || | |
| 3324 owner()->GetRole() == ui::AX_ROLE_ROW) { | |
| 3325 if (owner()->GetRole() != ui::AX_ROLE_ROW) | |
| 3326 IntAttributeToIA2(ui::AX_ATTR_ARIA_CELL_COLUMN_INDEX, "colindex"); | |
| 3327 IntAttributeToIA2(ui::AX_ATTR_ARIA_CELL_ROW_INDEX, "rowindex"); | |
| 3328 } | |
| 3329 | |
| 3330 // Expose row or column header sort direction. | |
| 3331 int32_t sort_direction; | |
| 3332 if ((MSAARole() == ROLE_SYSTEM_COLUMNHEADER || | |
| 3333 MSAARole() == ROLE_SYSTEM_ROWHEADER) && | |
| 3334 owner()->GetIntAttribute(ui::AX_ATTR_SORT_DIRECTION, &sort_direction)) { | |
| 3335 switch (static_cast<ui::AXSortDirection>(sort_direction)) { | |
| 3336 case ui::AX_SORT_DIRECTION_NONE: | |
| 3337 break; | |
| 3338 case ui::AX_SORT_DIRECTION_UNSORTED: | |
| 3339 win_attributes_->ia2_attributes.push_back(L"sort:none"); | |
| 3340 break; | |
| 3341 case ui::AX_SORT_DIRECTION_ASCENDING: | |
| 3342 win_attributes_->ia2_attributes.push_back(L"sort:ascending"); | |
| 3343 break; | |
| 3344 case ui::AX_SORT_DIRECTION_DESCENDING: | |
| 3345 win_attributes_->ia2_attributes.push_back(L"sort:descending"); | |
| 3346 break; | |
| 3347 case ui::AX_SORT_DIRECTION_OTHER: | |
| 3348 win_attributes_->ia2_attributes.push_back(L"sort:other"); | |
| 3349 break; | |
| 3350 } | |
| 3351 } | |
| 3352 | 3208 |
| 3353 win_attributes_->name = owner()->GetString16Attribute(ui::AX_ATTR_NAME); | 3209 win_attributes_->name = owner()->GetString16Attribute(ui::AX_ATTR_NAME); |
| 3210 |
| 3354 win_attributes_->description = | 3211 win_attributes_->description = |
| 3355 owner()->GetString16Attribute(ui::AX_ATTR_DESCRIPTION); | 3212 owner()->GetString16Attribute(ui::AX_ATTR_DESCRIPTION); |
| 3356 StringAttributeToIA2(ui::AX_ATTR_PLACEHOLDER, "placeholder"); | |
| 3357 | 3213 |
| 3358 base::string16 value = owner()->GetValue(); | 3214 base::string16 value = owner()->GetValue(); |
| 3359 | 3215 |
| 3360 // Expose slider value. | 3216 // Expose slider value. |
| 3361 if (IsRangeValueSupported()) { | 3217 if (IsRangeValueSupported()) { |
| 3362 value = GetRangeValueText(); | 3218 value = GetRangeValueText(); |
| 3363 SanitizeStringAttributeForIA2(value, &value); | 3219 } else if (owner()->IsDocument()) { |
| 3364 win_attributes_->ia2_attributes.push_back(L"valuetext:" + value); | |
| 3365 } else { | |
| 3366 // On Windows, the value of a document should be its url. | 3220 // On Windows, the value of a document should be its url. |
| 3367 if (owner()->IsDocument()) { | 3221 value = base::UTF8ToUTF16(Manager()->GetTreeData().url); |
| 3368 value = base::UTF8ToUTF16(Manager()->GetTreeData().url); | |
| 3369 } | |
| 3370 // If this doesn't have a value and is linked then set its value to the url | |
| 3371 // attribute. This allows screen readers to read an empty link's | |
| 3372 // destination. | |
| 3373 if (value.empty() && (MSAAState() & STATE_SYSTEM_LINKED)) | |
| 3374 value = owner()->GetString16Attribute(ui::AX_ATTR_URL); | |
| 3375 } | 3222 } |
| 3223 // If this doesn't have a value and is linked then set its value to the url |
| 3224 // attribute. This allows screen readers to read an empty link's |
| 3225 // destination. |
| 3226 if (value.empty() && (MSAAState() & STATE_SYSTEM_LINKED)) |
| 3227 value = owner()->GetString16Attribute(ui::AX_ATTR_URL); |
| 3376 | 3228 |
| 3377 win_attributes_->value = value; | 3229 win_attributes_->value = value; |
| 3378 | 3230 |
| 3379 ClearOwnRelations(); | 3231 ClearOwnRelations(); |
| 3380 AddBidirectionalRelations(IA2_RELATION_CONTROLLER_FOR, | 3232 AddBidirectionalRelations(IA2_RELATION_CONTROLLER_FOR, |
| 3381 IA2_RELATION_CONTROLLED_BY, | 3233 IA2_RELATION_CONTROLLED_BY, |
| 3382 ui::AX_ATTR_CONTROLS_IDS); | 3234 ui::AX_ATTR_CONTROLS_IDS); |
| 3383 AddBidirectionalRelations(IA2_RELATION_DESCRIBED_BY, | 3235 AddBidirectionalRelations(IA2_RELATION_DESCRIBED_BY, |
| 3384 IA2_RELATION_DESCRIPTION_FOR, | 3236 IA2_RELATION_DESCRIPTION_FOR, |
| 3385 ui::AX_ATTR_DESCRIBEDBY_IDS); | 3237 ui::AX_ATTR_DESCRIBEDBY_IDS); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3396 details_ids); | 3248 details_ids); |
| 3397 } | 3249 } |
| 3398 | 3250 |
| 3399 int member_of_id; | 3251 int member_of_id; |
| 3400 if (owner()->GetIntAttribute(ui::AX_ATTR_MEMBER_OF_ID, &member_of_id)) | 3252 if (owner()->GetIntAttribute(ui::AX_ATTR_MEMBER_OF_ID, &member_of_id)) |
| 3401 AddRelation(IA2_RELATION_MEMBER_OF, member_of_id); | 3253 AddRelation(IA2_RELATION_MEMBER_OF, member_of_id); |
| 3402 | 3254 |
| 3403 int error_message_id; | 3255 int error_message_id; |
| 3404 if (owner()->GetIntAttribute(ui::AX_ATTR_ERRORMESSAGE_ID, &error_message_id)) | 3256 if (owner()->GetIntAttribute(ui::AX_ATTR_ERRORMESSAGE_ID, &error_message_id)) |
| 3405 AddRelation(IA2_RELATION_ERROR_MESSAGE, error_message_id); | 3257 AddRelation(IA2_RELATION_ERROR_MESSAGE, error_message_id); |
| 3406 | |
| 3407 UpdateRequiredAttributes(); | |
| 3408 } | 3258 } |
| 3409 | 3259 |
| 3410 void BrowserAccessibilityComWin::UpdateStep2ComputeHypertext() { | 3260 void BrowserAccessibilityComWin::UpdateStep2ComputeHypertext() { |
| 3411 if (owner()->IsSimpleTextControl()) { | 3261 if (owner()->IsSimpleTextControl()) { |
| 3412 win_attributes_->hypertext = value(); | 3262 win_attributes_->hypertext = value(); |
| 3413 return; | 3263 return; |
| 3414 } | 3264 } |
| 3415 | 3265 |
| 3416 if (!owner()->PlatformChildCount()) { | 3266 if (!owner()->PlatformChildCount()) { |
| 3417 if (owner()->IsRichTextControl()) { | 3267 if (owner()->IsRichTextControl()) { |
| (...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3848 HandleSpecialTextOffset(&start_offset); | 3698 HandleSpecialTextOffset(&start_offset); |
| 3849 HandleSpecialTextOffset(&end_offset); | 3699 HandleSpecialTextOffset(&end_offset); |
| 3850 AXPlatformPositionInstance start_position = | 3700 AXPlatformPositionInstance start_position = |
| 3851 CreatePositionForSelectionAt(static_cast<int>(start_offset)); | 3701 CreatePositionForSelectionAt(static_cast<int>(start_offset)); |
| 3852 AXPlatformPositionInstance end_position = | 3702 AXPlatformPositionInstance end_position = |
| 3853 CreatePositionForSelectionAt(static_cast<int>(end_offset)); | 3703 CreatePositionForSelectionAt(static_cast<int>(end_offset)); |
| 3854 Manager()->SetSelection(AXPlatformRange(start_position->AsTextPosition(), | 3704 Manager()->SetSelection(AXPlatformRange(start_position->AsTextPosition(), |
| 3855 end_position->AsTextPosition())); | 3705 end_position->AsTextPosition())); |
| 3856 } | 3706 } |
| 3857 | 3707 |
| 3858 void BrowserAccessibilityComWin::StringAttributeToIA2( | |
| 3859 ui::AXStringAttribute attribute, | |
| 3860 const char* ia2_attr) { | |
| 3861 base::string16 value; | |
| 3862 if (owner()->GetString16Attribute(attribute, &value)) { | |
| 3863 SanitizeStringAttributeForIA2(value, &value); | |
| 3864 win_attributes_->ia2_attributes.push_back(base::ASCIIToUTF16(ia2_attr) + | |
| 3865 L":" + value); | |
| 3866 } | |
| 3867 } | |
| 3868 | |
| 3869 void BrowserAccessibilityComWin::BoolAttributeToIA2( | |
| 3870 ui::AXBoolAttribute attribute, | |
| 3871 const char* ia2_attr) { | |
| 3872 bool value; | |
| 3873 if (owner()->GetBoolAttribute(attribute, &value)) { | |
| 3874 win_attributes_->ia2_attributes.push_back( | |
| 3875 (base::ASCIIToUTF16(ia2_attr) + L":") + (value ? L"true" : L"false")); | |
| 3876 } | |
| 3877 } | |
| 3878 | |
| 3879 void BrowserAccessibilityComWin::IntAttributeToIA2(ui::AXIntAttribute attribute, | |
| 3880 const char* ia2_attr) { | |
| 3881 int value; | |
| 3882 if (owner()->GetIntAttribute(attribute, &value)) { | |
| 3883 win_attributes_->ia2_attributes.push_back( | |
| 3884 base::ASCIIToUTF16(ia2_attr) + L":" + base::IntToString16(value)); | |
| 3885 } | |
| 3886 } | |
| 3887 | |
| 3888 bool BrowserAccessibilityComWin::IsHyperlink() const { | 3708 bool BrowserAccessibilityComWin::IsHyperlink() const { |
| 3889 int32_t hyperlink_index = -1; | 3709 int32_t hyperlink_index = -1; |
| 3890 auto* parent = owner()->PlatformGetParent(); | 3710 auto* parent = owner()->PlatformGetParent(); |
| 3891 if (parent) { | 3711 if (parent) { |
| 3892 hyperlink_index = | 3712 hyperlink_index = |
| 3893 ToBrowserAccessibilityComWin(parent)->GetHyperlinkIndexFromChild(*this); | 3713 ToBrowserAccessibilityComWin(parent)->GetHyperlinkIndexFromChild(*this); |
| 3894 } | 3714 } |
| 3895 | 3715 |
| 3896 if (hyperlink_index >= 0) | 3716 if (hyperlink_index >= 0) |
| 3897 return true; | 3717 return true; |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4127 if (!hyperlink) | 3947 if (!hyperlink) |
| 4128 return; | 3948 return; |
| 4129 | 3949 |
| 4130 LONG n_selections = 0; | 3950 LONG n_selections = 0; |
| 4131 HRESULT hr = hyperlink->get_nSelections(&n_selections); | 3951 HRESULT hr = hyperlink->get_nSelections(&n_selections); |
| 4132 DCHECK(SUCCEEDED(hr)); | 3952 DCHECK(SUCCEEDED(hr)); |
| 4133 if (n_selections > 0) | 3953 if (n_selections > 0) |
| 4134 ++(*largest_offset); | 3954 ++(*largest_offset); |
| 4135 } | 3955 } |
| 4136 | 3956 |
| 4137 base::string16 BrowserAccessibilityComWin::GetRangeValueText() { | |
| 4138 float fval; | |
| 4139 base::string16 result = owner()->GetValue(); | |
| 4140 | |
| 4141 if (result.empty() && GetFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE, &fval)) { | |
| 4142 result = base::UTF8ToUTF16(base::DoubleToString(fval)); | |
| 4143 } | |
| 4144 return result; | |
| 4145 } | |
| 4146 | |
| 4147 bool BrowserAccessibilityComWin::IsSameHypertextCharacter( | 3957 bool BrowserAccessibilityComWin::IsSameHypertextCharacter( |
| 4148 size_t old_char_index, | 3958 size_t old_char_index, |
| 4149 size_t new_char_index) { | 3959 size_t new_char_index) { |
| 4150 CHECK(old_win_attributes_); | 3960 CHECK(old_win_attributes_); |
| 4151 | 3961 |
| 4152 // For anything other than the "embedded character", we just compare the | 3962 // For anything other than the "embedded character", we just compare the |
| 4153 // characters directly. | 3963 // characters directly. |
| 4154 base::char16 old_ch = old_win_attributes_->hypertext[old_char_index]; | 3964 base::char16 old_ch = old_win_attributes_->hypertext[old_char_index]; |
| 4155 base::char16 new_ch = win_attributes_->hypertext[new_char_index]; | 3965 base::char16 new_ch = win_attributes_->hypertext[new_char_index]; |
| 4156 if (old_ch != new_ch) | 3966 if (old_ch != new_ch) |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4498 } | 4308 } |
| 4499 if (relation->get_target_ids().empty()) { | 4309 if (relation->get_target_ids().empty()) { |
| 4500 iter = relations_.erase(iter); | 4310 iter = relations_.erase(iter); |
| 4501 relation->Release(); | 4311 relation->Release(); |
| 4502 } else { | 4312 } else { |
| 4503 ++iter; | 4313 ++iter; |
| 4504 } | 4314 } |
| 4505 } | 4315 } |
| 4506 } | 4316 } |
| 4507 | 4317 |
| 4508 void BrowserAccessibilityComWin::UpdateRequiredAttributes() { | |
| 4509 if (ui::IsCellOrTableHeaderRole(owner()->GetRole())) { | |
| 4510 // Expose colspan attribute. | |
| 4511 base::string16 colspan; | |
| 4512 if (owner()->GetHtmlAttribute("aria-colspan", &colspan)) { | |
| 4513 SanitizeStringAttributeForIA2(colspan, &colspan); | |
| 4514 win_attributes_->ia2_attributes.push_back(L"colspan:" + colspan); | |
| 4515 } | |
| 4516 // Expose rowspan attribute. | |
| 4517 base::string16 rowspan; | |
| 4518 if (owner()->GetHtmlAttribute("aria-rowspan", &rowspan)) { | |
| 4519 SanitizeStringAttributeForIA2(rowspan, &rowspan); | |
| 4520 win_attributes_->ia2_attributes.push_back(L"rowspan:" + rowspan); | |
| 4521 } | |
| 4522 } | |
| 4523 | |
| 4524 // Expose dropeffect attribute. | |
| 4525 base::string16 drop_effect; | |
| 4526 if (owner()->GetHtmlAttribute("aria-dropeffect", &drop_effect)) { | |
| 4527 SanitizeStringAttributeForIA2(drop_effect, &drop_effect); | |
| 4528 win_attributes_->ia2_attributes.push_back(L"dropeffect:" + drop_effect); | |
| 4529 } | |
| 4530 | |
| 4531 // Expose grabbed attribute. | |
| 4532 base::string16 grabbed; | |
| 4533 if (owner()->GetHtmlAttribute("aria-grabbed", &grabbed)) { | |
| 4534 SanitizeStringAttributeForIA2(grabbed, &grabbed); | |
| 4535 win_attributes_->ia2_attributes.push_back(L"grabbed:" + grabbed); | |
| 4536 } | |
| 4537 | |
| 4538 // Expose class attribute. | |
| 4539 base::string16 class_attr; | |
| 4540 if (owner()->GetHtmlAttribute("class", &class_attr)) { | |
| 4541 SanitizeStringAttributeForIA2(class_attr, &class_attr); | |
| 4542 win_attributes_->ia2_attributes.push_back(L"class:" + class_attr); | |
| 4543 } | |
| 4544 | |
| 4545 // Expose datetime attribute. | |
| 4546 base::string16 datetime; | |
| 4547 if (owner()->GetRole() == ui::AX_ROLE_TIME && | |
| 4548 owner()->GetHtmlAttribute("datetime", &datetime)) { | |
| 4549 SanitizeStringAttributeForIA2(datetime, &datetime); | |
| 4550 win_attributes_->ia2_attributes.push_back(L"datetime:" + datetime); | |
| 4551 } | |
| 4552 | |
| 4553 // Expose id attribute. | |
| 4554 base::string16 id; | |
| 4555 if (owner()->GetHtmlAttribute("id", &id)) { | |
| 4556 SanitizeStringAttributeForIA2(id, &id); | |
| 4557 win_attributes_->ia2_attributes.push_back(L"id:" + id); | |
| 4558 } | |
| 4559 | |
| 4560 // Expose src attribute. | |
| 4561 base::string16 src; | |
| 4562 if (owner()->GetRole() == ui::AX_ROLE_IMAGE && | |
| 4563 owner()->GetHtmlAttribute("src", &src)) { | |
| 4564 SanitizeStringAttributeForIA2(src, &src); | |
| 4565 win_attributes_->ia2_attributes.push_back(L"src:" + src); | |
| 4566 } | |
| 4567 | |
| 4568 // Expose input-text type attribute. | |
| 4569 base::string16 type; | |
| 4570 base::string16 html_tag = owner()->GetString16Attribute(ui::AX_ATTR_HTML_TAG); | |
| 4571 if (owner()->IsSimpleTextControl() && html_tag == L"input" && | |
| 4572 owner()->GetHtmlAttribute("type", &type)) { | |
| 4573 SanitizeStringAttributeForIA2(type, &type); | |
| 4574 win_attributes_->ia2_attributes.push_back(L"text-input-type:" + type); | |
| 4575 } | |
| 4576 } | |
| 4577 | |
| 4578 void BrowserAccessibilityComWin::FireNativeEvent(LONG win_event_type) const { | 4318 void BrowserAccessibilityComWin::FireNativeEvent(LONG win_event_type) const { |
| 4579 (new BrowserAccessibilityEventWin(BrowserAccessibilityEvent::FromTreeChange, | 4319 (new BrowserAccessibilityEventWin(BrowserAccessibilityEvent::FromTreeChange, |
| 4580 ui::AX_EVENT_NONE, win_event_type, owner())) | 4320 ui::AX_EVENT_NONE, win_event_type, owner())) |
| 4581 ->Fire(); | 4321 ->Fire(); |
| 4582 } | 4322 } |
| 4583 | 4323 |
| 4584 BrowserAccessibilityComWin* ToBrowserAccessibilityComWin( | 4324 BrowserAccessibilityComWin* ToBrowserAccessibilityComWin( |
| 4585 BrowserAccessibility* obj) { | 4325 BrowserAccessibility* obj) { |
| 4586 if (!obj || !obj->IsNative()) | 4326 if (!obj || !obj->IsNative()) |
| 4587 return nullptr; | 4327 return nullptr; |
| 4588 auto* result = static_cast<BrowserAccessibilityWin*>(obj)->GetCOM(); | 4328 auto* result = static_cast<BrowserAccessibilityWin*>(obj)->GetCOM(); |
| 4589 return result; | 4329 return result; |
| 4590 } | 4330 } |
| 4591 | 4331 |
| 4592 } // namespace content | 4332 } // namespace content |
| OLD | NEW |