| 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 <algorithm> | 10 #include <algorithm> |
| 11 | 11 |
| 12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 13 #include "base/strings/string_split.h" | 13 #include "base/strings/string_split.h" |
| 14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
| 15 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
| 16 #include "base/win/enum_variant.h" | 16 #include "base/win/enum_variant.h" |
| 17 #include "base/win/scoped_comptr.h" | 17 #include "base/win/scoped_comptr.h" |
| 18 #include "base/win/windows_version.h" | 18 #include "base/win/windows_version.h" |
| 19 #include "content/browser/accessibility/browser_accessibility_manager_win.h" | 19 #include "content/browser/accessibility/browser_accessibility_manager_win.h" |
| 20 #include "content/browser/accessibility/browser_accessibility_state_impl.h" | 20 #include "content/browser/accessibility/browser_accessibility_state_impl.h" |
| 21 #include "content/common/accessibility_messages.h" | 21 #include "content/common/accessibility_messages.h" |
| 22 #include "content/public/common/content_client.h" | 22 #include "content/public/common/content_client.h" |
| 23 #include "third_party/skia/include/core/SkColor.h" |
| 23 #include "ui/accessibility/ax_text_utils.h" | 24 #include "ui/accessibility/ax_text_utils.h" |
| 24 #include "ui/base/win/accessibility_ids_win.h" | 25 #include "ui/base/win/accessibility_ids_win.h" |
| 25 #include "ui/base/win/accessibility_misc_utils.h" | 26 #include "ui/base/win/accessibility_misc_utils.h" |
| 26 #include "ui/base/win/atl_module.h" | 27 #include "ui/base/win/atl_module.h" |
| 27 | 28 |
| 28 namespace content { | 29 namespace content { |
| 29 | 30 |
| 30 // These nonstandard GUIDs are taken directly from the Mozilla sources | 31 // These nonstandard GUIDs are taken directly from the Mozilla sources |
| 31 // (accessible/src/msaa/nsAccessNodeWrap.cpp); some documentation is here: | 32 // (accessible/src/msaa/nsAccessNodeWrap.cpp); some documentation is here: |
| 32 // http://developer.mozilla.org/en/Accessibility/AT-APIs/ImplementationFeatures/
MSAA | 33 // http://developer.mozilla.org/en/Accessibility/AT-APIs/ImplementationFeatures/
MSAA |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 | 109 |
| 109 STDMETHODIMP BrowserAccessibilityRelation::get_nTargets(long* n_targets) { | 110 STDMETHODIMP BrowserAccessibilityRelation::get_nTargets(long* n_targets) { |
| 110 if (!n_targets) | 111 if (!n_targets) |
| 111 return E_INVALIDARG; | 112 return E_INVALIDARG; |
| 112 | 113 |
| 113 if (!owner_->instance_active()) | 114 if (!owner_->instance_active()) |
| 114 return E_FAIL; | 115 return E_FAIL; |
| 115 | 116 |
| 116 *n_targets = static_cast<long>(target_ids_.size()); | 117 *n_targets = static_cast<long>(target_ids_.size()); |
| 117 | 118 |
| 118 BrowserAccessibilityManager* manager = owner_->manager(); | |
| 119 for (long i = *n_targets - 1; i >= 0; --i) { | 119 for (long i = *n_targets - 1; i >= 0; --i) { |
| 120 BrowserAccessibility* result = manager->GetFromID(target_ids_[i]); | 120 BrowserAccessibilityWin* result = owner_->GetFromID(target_ids_[i]); |
| 121 if (!result || !result->instance_active()) { | 121 if (!result || !result->instance_active()) { |
| 122 *n_targets = 0; | 122 *n_targets = 0; |
| 123 break; | 123 break; |
| 124 } | 124 } |
| 125 } | 125 } |
| 126 return S_OK; | 126 return S_OK; |
| 127 } | 127 } |
| 128 | 128 |
| 129 STDMETHODIMP BrowserAccessibilityRelation::get_target(long target_index, | 129 STDMETHODIMP BrowserAccessibilityRelation::get_target(long target_index, |
| 130 IUnknown** target) { | 130 IUnknown** target) { |
| 131 if (!target) | 131 if (!target) |
| 132 return E_INVALIDARG; | 132 return E_INVALIDARG; |
| 133 | 133 |
| 134 if (!owner_->instance_active()) | 134 if (!owner_->instance_active()) |
| 135 return E_FAIL; | 135 return E_FAIL; |
| 136 | 136 |
| 137 if (target_index < 0 || | 137 if (target_index < 0 || |
| 138 target_index >= static_cast<long>(target_ids_.size())) { | 138 target_index >= static_cast<long>(target_ids_.size())) { |
| 139 return E_INVALIDARG; | 139 return E_INVALIDARG; |
| 140 } | 140 } |
| 141 | 141 |
| 142 BrowserAccessibilityManager* manager = owner_->manager(); | 142 BrowserAccessibility* result = owner_->GetFromID(target_ids_[target_index]); |
| 143 BrowserAccessibility* result = | |
| 144 manager->GetFromID(target_ids_[target_index]); | |
| 145 if (!result || !result->instance_active()) | 143 if (!result || !result->instance_active()) |
| 146 return E_FAIL; | 144 return E_FAIL; |
| 147 | 145 |
| 148 *target = static_cast<IAccessible*>( | 146 *target = static_cast<IAccessible*>( |
| 149 ToBrowserAccessibilityWin(result)->NewReference()); | 147 ToBrowserAccessibilityWin(result)->NewReference()); |
| 150 return S_OK; | 148 return S_OK; |
| 151 } | 149 } |
| 152 | 150 |
| 153 STDMETHODIMP BrowserAccessibilityRelation::get_targets(long max_targets, | 151 STDMETHODIMP BrowserAccessibilityRelation::get_targets(long max_targets, |
| 154 IUnknown** targets, | 152 IUnknown** targets, |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 target->ia_role() == ROLE_SYSTEM_SCROLLBAR || | 567 target->ia_role() == ROLE_SYSTEM_SCROLLBAR || |
| 570 target->ia_role() == ROLE_SYSTEM_SLIDER) { | 568 target->ia_role() == ROLE_SYSTEM_SLIDER) { |
| 571 base::string16 value_text = target->GetValueText(); | 569 base::string16 value_text = target->GetValueText(); |
| 572 *value = SysAllocString(value_text.c_str()); | 570 *value = SysAllocString(value_text.c_str()); |
| 573 DCHECK(*value); | 571 DCHECK(*value); |
| 574 return S_OK; | 572 return S_OK; |
| 575 } | 573 } |
| 576 | 574 |
| 577 // Expose color well value. | 575 // Expose color well value. |
| 578 if (target->ia2_role() == IA2_ROLE_COLOR_CHOOSER) { | 576 if (target->ia2_role() == IA2_ROLE_COLOR_CHOOSER) { |
| 579 int color = target->GetIntAttribute(ui::AX_ATTR_COLOR_VALUE); | 577 unsigned int color = static_cast<unsigned int>( |
| 580 int red = (color >> 16) & 0xFF; | 578 target->GetIntAttribute(ui::AX_ATTR_COLOR_VALUE)); |
| 581 int green = (color >> 8) & 0xFF; | 579 unsigned int red = SkColorGetR(color); |
| 582 int blue = color & 0xFF; | 580 unsigned int green = SkColorGetG(color); |
| 581 unsigned int blue = SkColorGetB(color); |
| 583 base::string16 value_text; | 582 base::string16 value_text; |
| 584 value_text = base::IntToString16((red * 100) / 255) + L"% red " + | 583 value_text = base::UintToString16(red * 100 / 255) + L"% red " + |
| 585 base::IntToString16((green * 100) / 255) + L"% green " + | 584 base::UintToString16(green * 100 / 255) + L"% green " + |
| 586 base::IntToString16((blue * 100) / 255) + L"% blue"; | 585 base::UintToString16(blue * 100 / 255) + L"% blue"; |
| 587 *value = SysAllocString(value_text.c_str()); | 586 *value = SysAllocString(value_text.c_str()); |
| 588 DCHECK(*value); | 587 DCHECK(*value); |
| 589 return S_OK; | 588 return S_OK; |
| 590 } | 589 } |
| 591 | 590 |
| 592 *value = SysAllocString(target->value().c_str()); | 591 *value = SysAllocString(target->value().c_str()); |
| 593 DCHECK(*value); | 592 DCHECK(*value); |
| 594 return S_OK; | 593 return S_OK; |
| 595 } | 594 } |
| 596 | 595 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 680 | 679 |
| 681 if (!role) | 680 if (!role) |
| 682 return E_INVALIDARG; | 681 return E_INVALIDARG; |
| 683 | 682 |
| 684 *role = ia2_role(); | 683 *role = ia2_role(); |
| 685 | 684 |
| 686 return S_OK; | 685 return S_OK; |
| 687 } | 686 } |
| 688 | 687 |
| 689 STDMETHODIMP BrowserAccessibilityWin::get_attributes(BSTR* attributes) { | 688 STDMETHODIMP BrowserAccessibilityWin::get_attributes(BSTR* attributes) { |
| 689 if (!attributes) |
| 690 return E_INVALIDARG; |
| 691 *attributes = nullptr; |
| 692 |
| 690 if (!instance_active()) | 693 if (!instance_active()) |
| 691 return E_FAIL; | 694 return E_FAIL; |
| 692 | 695 |
| 693 if (!attributes) | |
| 694 return E_INVALIDARG; | |
| 695 | |
| 696 // The iaccessible2 attributes are a set of key-value pairs | |
| 697 // separated by semicolons, with a colon between the key and the value. | |
| 698 base::string16 str; | 696 base::string16 str; |
| 699 const std::vector<base::string16>& attributes_list = ia2_attributes(); | 697 for (const base::string16& attribute : ia2_attributes()) |
| 700 for (unsigned int i = 0; i < attributes_list.size(); ++i) { | 698 str += attribute + L';'; |
| 701 str += attributes_list[i] + L';'; | |
| 702 } | |
| 703 | 699 |
| 704 if (str.empty()) | 700 if (str.empty()) |
| 705 return S_FALSE; | 701 return S_FALSE; |
| 706 | 702 |
| 707 *attributes = SysAllocString(str.c_str()); | 703 *attributes = SysAllocString(str.c_str()); |
| 708 DCHECK(*attributes); | 704 DCHECK(*attributes); |
| 709 return S_OK; | 705 return S_OK; |
| 710 } | 706 } |
| 711 | 707 |
| 712 STDMETHODIMP BrowserAccessibilityWin::get_states(AccessibleStates* states) { | 708 STDMETHODIMP BrowserAccessibilityWin::get_states(AccessibleStates* states) { |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 840 manager()->ScrollToMakeVisible( | 836 manager()->ScrollToMakeVisible( |
| 841 *this, gfx::Rect(r.right(), r.y(), 0, r.height())); | 837 *this, gfx::Rect(r.right(), r.y(), 0, r.height())); |
| 842 break; | 838 break; |
| 843 case IA2_SCROLL_TYPE_ANYWHERE: | 839 case IA2_SCROLL_TYPE_ANYWHERE: |
| 844 default: | 840 default: |
| 845 manager()->ScrollToMakeVisible(*this, r); | 841 manager()->ScrollToMakeVisible(*this, r); |
| 846 break; | 842 break; |
| 847 } | 843 } |
| 848 | 844 |
| 849 manager()->ToBrowserAccessibilityManagerWin()->TrackScrollingObject(this); | 845 manager()->ToBrowserAccessibilityManagerWin()->TrackScrollingObject(this); |
| 850 | |
| 851 return S_OK; | 846 return S_OK; |
| 852 } | 847 } |
| 853 | 848 |
| 854 STDMETHODIMP BrowserAccessibilityWin::scrollToPoint( | 849 STDMETHODIMP BrowserAccessibilityWin::scrollToPoint( |
| 855 IA2CoordinateType coordinate_type, | 850 IA2CoordinateType coordinate_type, |
| 856 LONG x, | 851 LONG x, |
| 857 LONG y) { | 852 LONG y) { |
| 858 if (!instance_active()) | 853 if (!instance_active()) |
| 859 return E_FAIL; | 854 return E_FAIL; |
| 860 | 855 |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1174 return S_FALSE; | 1169 return S_FALSE; |
| 1175 } | 1170 } |
| 1176 | 1171 |
| 1177 if (column < 0 || column >= columns) | 1172 if (column < 0 || column >= columns) |
| 1178 return E_INVALIDARG; | 1173 return E_INVALIDARG; |
| 1179 | 1174 |
| 1180 const std::vector<int32_t>& cell_ids = | 1175 const std::vector<int32_t>& cell_ids = |
| 1181 GetIntListAttribute(ui::AX_ATTR_CELL_IDS); | 1176 GetIntListAttribute(ui::AX_ATTR_CELL_IDS); |
| 1182 for (int i = 0; i < rows; ++i) { | 1177 for (int i = 0; i < rows; ++i) { |
| 1183 int cell_id = cell_ids[i * columns + column]; | 1178 int cell_id = cell_ids[i * columns + column]; |
| 1184 BrowserAccessibilityWin* cell = static_cast<BrowserAccessibilityWin*>( | 1179 BrowserAccessibilityWin* cell = GetFromID(cell_id); |
| 1185 manager()->GetFromID(cell_id)); | |
| 1186 if (cell && cell->GetRole() == ui::AX_ROLE_COLUMN_HEADER) { | 1180 if (cell && cell->GetRole() == ui::AX_ROLE_COLUMN_HEADER) { |
| 1187 base::string16 cell_name = cell->GetString16Attribute( | 1181 base::string16 cell_name = cell->GetString16Attribute( |
| 1188 ui::AX_ATTR_NAME); | 1182 ui::AX_ATTR_NAME); |
| 1189 if (cell_name.size() > 0) { | 1183 if (cell_name.size() > 0) { |
| 1190 *description = SysAllocString(cell_name.c_str()); | 1184 *description = SysAllocString(cell_name.c_str()); |
| 1191 return S_OK; | 1185 return S_OK; |
| 1192 } | 1186 } |
| 1193 | 1187 |
| 1194 if (cell->description().size() > 0) { | 1188 if (cell->description().size() > 0) { |
| 1195 *description = SysAllocString(cell->description().c_str()); | 1189 *description = SysAllocString(cell->description().c_str()); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1220 rows <= 0) { | 1214 rows <= 0) { |
| 1221 return S_FALSE; | 1215 return S_FALSE; |
| 1222 } | 1216 } |
| 1223 | 1217 |
| 1224 if (row < 0 || row >= rows || column < 0 || column >= columns) | 1218 if (row < 0 || row >= rows || column < 0 || column >= columns) |
| 1225 return E_INVALIDARG; | 1219 return E_INVALIDARG; |
| 1226 | 1220 |
| 1227 const std::vector<int32_t>& cell_ids = | 1221 const std::vector<int32_t>& cell_ids = |
| 1228 GetIntListAttribute(ui::AX_ATTR_CELL_IDS); | 1222 GetIntListAttribute(ui::AX_ATTR_CELL_IDS); |
| 1229 int cell_id = cell_ids[row * columns + column]; | 1223 int cell_id = cell_ids[row * columns + column]; |
| 1230 BrowserAccessibilityWin* cell = static_cast<BrowserAccessibilityWin*>( | 1224 BrowserAccessibilityWin* cell = GetFromID(cell_id); |
| 1231 manager()->GetFromID(cell_id)); | |
| 1232 int colspan; | 1225 int colspan; |
| 1233 if (cell && | 1226 if (cell && |
| 1234 cell->GetIntAttribute( | 1227 cell->GetIntAttribute( |
| 1235 ui::AX_ATTR_TABLE_CELL_COLUMN_SPAN, &colspan) && | 1228 ui::AX_ATTR_TABLE_CELL_COLUMN_SPAN, &colspan) && |
| 1236 colspan >= 1) { | 1229 colspan >= 1) { |
| 1237 *n_columns_spanned = colspan; | 1230 *n_columns_spanned = colspan; |
| 1238 return S_OK; | 1231 return S_OK; |
| 1239 } | 1232 } |
| 1240 | 1233 |
| 1241 return S_FALSE; | 1234 return S_FALSE; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1258 | 1251 |
| 1259 const std::vector<int32_t>& unique_cell_ids = | 1252 const std::vector<int32_t>& unique_cell_ids = |
| 1260 GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS); | 1253 GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS); |
| 1261 int cell_id_count = static_cast<int>(unique_cell_ids.size()); | 1254 int cell_id_count = static_cast<int>(unique_cell_ids.size()); |
| 1262 if (cell_index < 0) | 1255 if (cell_index < 0) |
| 1263 return E_INVALIDARG; | 1256 return E_INVALIDARG; |
| 1264 if (cell_index >= cell_id_count) | 1257 if (cell_index >= cell_id_count) |
| 1265 return S_FALSE; | 1258 return S_FALSE; |
| 1266 | 1259 |
| 1267 int cell_id = unique_cell_ids[cell_index]; | 1260 int cell_id = unique_cell_ids[cell_index]; |
| 1268 BrowserAccessibilityWin* cell = | 1261 BrowserAccessibilityWin* cell = GetFromID(cell_id); |
| 1269 ToBrowserAccessibilityWin(manager()->GetFromID(cell_id)); | |
| 1270 int col_index; | 1262 int col_index; |
| 1271 if (cell && | 1263 if (cell && |
| 1272 cell->GetIntAttribute( | 1264 cell->GetIntAttribute( |
| 1273 ui::AX_ATTR_TABLE_CELL_COLUMN_INDEX, &col_index)) { | 1265 ui::AX_ATTR_TABLE_CELL_COLUMN_INDEX, &col_index)) { |
| 1274 *column_index = col_index; | 1266 *column_index = col_index; |
| 1275 return S_OK; | 1267 return S_OK; |
| 1276 } | 1268 } |
| 1277 | 1269 |
| 1278 return S_FALSE; | 1270 return S_FALSE; |
| 1279 } | 1271 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1363 return S_FALSE; | 1355 return S_FALSE; |
| 1364 } | 1356 } |
| 1365 | 1357 |
| 1366 if (row < 0 || row >= rows) | 1358 if (row < 0 || row >= rows) |
| 1367 return E_INVALIDARG; | 1359 return E_INVALIDARG; |
| 1368 | 1360 |
| 1369 const std::vector<int32_t>& cell_ids = | 1361 const std::vector<int32_t>& cell_ids = |
| 1370 GetIntListAttribute(ui::AX_ATTR_CELL_IDS); | 1362 GetIntListAttribute(ui::AX_ATTR_CELL_IDS); |
| 1371 for (int i = 0; i < columns; ++i) { | 1363 for (int i = 0; i < columns; ++i) { |
| 1372 int cell_id = cell_ids[row * columns + i]; | 1364 int cell_id = cell_ids[row * columns + i]; |
| 1373 BrowserAccessibilityWin* cell = | 1365 BrowserAccessibilityWin* cell = GetFromID(cell_id); |
| 1374 ToBrowserAccessibilityWin(manager()->GetFromID(cell_id)); | |
| 1375 if (cell && cell->GetRole() == ui::AX_ROLE_ROW_HEADER) { | 1366 if (cell && cell->GetRole() == ui::AX_ROLE_ROW_HEADER) { |
| 1376 base::string16 cell_name = cell->GetString16Attribute( | 1367 base::string16 cell_name = cell->GetString16Attribute( |
| 1377 ui::AX_ATTR_NAME); | 1368 ui::AX_ATTR_NAME); |
| 1378 if (cell_name.size() > 0) { | 1369 if (cell_name.size() > 0) { |
| 1379 *description = SysAllocString(cell_name.c_str()); | 1370 *description = SysAllocString(cell_name.c_str()); |
| 1380 return S_OK; | 1371 return S_OK; |
| 1381 } | 1372 } |
| 1382 | 1373 |
| 1383 if (cell->description().size() > 0) { | 1374 if (cell->description().size() > 0) { |
| 1384 *description = SysAllocString(cell->description().c_str()); | 1375 *description = SysAllocString(cell->description().c_str()); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1408 rows <= 0) { | 1399 rows <= 0) { |
| 1409 return S_FALSE; | 1400 return S_FALSE; |
| 1410 } | 1401 } |
| 1411 | 1402 |
| 1412 if (row < 0 || row >= rows || column < 0 || column >= columns) | 1403 if (row < 0 || row >= rows || column < 0 || column >= columns) |
| 1413 return E_INVALIDARG; | 1404 return E_INVALIDARG; |
| 1414 | 1405 |
| 1415 const std::vector<int32_t>& cell_ids = | 1406 const std::vector<int32_t>& cell_ids = |
| 1416 GetIntListAttribute(ui::AX_ATTR_CELL_IDS); | 1407 GetIntListAttribute(ui::AX_ATTR_CELL_IDS); |
| 1417 int cell_id = cell_ids[row * columns + column]; | 1408 int cell_id = cell_ids[row * columns + column]; |
| 1418 BrowserAccessibilityWin* cell = | 1409 BrowserAccessibilityWin* cell = GetFromID(cell_id); |
| 1419 ToBrowserAccessibilityWin(manager()->GetFromID(cell_id)); | |
| 1420 int rowspan; | 1410 int rowspan; |
| 1421 if (cell && | 1411 if (cell && |
| 1422 cell->GetIntAttribute( | 1412 cell->GetIntAttribute( |
| 1423 ui::AX_ATTR_TABLE_CELL_ROW_SPAN, &rowspan) && | 1413 ui::AX_ATTR_TABLE_CELL_ROW_SPAN, &rowspan) && |
| 1424 rowspan >= 1) { | 1414 rowspan >= 1) { |
| 1425 *n_rows_spanned = rowspan; | 1415 *n_rows_spanned = rowspan; |
| 1426 return S_OK; | 1416 return S_OK; |
| 1427 } | 1417 } |
| 1428 | 1418 |
| 1429 return S_FALSE; | 1419 return S_FALSE; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1446 | 1436 |
| 1447 const std::vector<int32_t>& unique_cell_ids = | 1437 const std::vector<int32_t>& unique_cell_ids = |
| 1448 GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS); | 1438 GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS); |
| 1449 int cell_id_count = static_cast<int>(unique_cell_ids.size()); | 1439 int cell_id_count = static_cast<int>(unique_cell_ids.size()); |
| 1450 if (cell_index < 0) | 1440 if (cell_index < 0) |
| 1451 return E_INVALIDARG; | 1441 return E_INVALIDARG; |
| 1452 if (cell_index >= cell_id_count) | 1442 if (cell_index >= cell_id_count) |
| 1453 return S_FALSE; | 1443 return S_FALSE; |
| 1454 | 1444 |
| 1455 int cell_id = unique_cell_ids[cell_index]; | 1445 int cell_id = unique_cell_ids[cell_index]; |
| 1456 BrowserAccessibilityWin* cell = | 1446 BrowserAccessibilityWin* cell = GetFromID(cell_id); |
| 1457 ToBrowserAccessibilityWin(manager()->GetFromID(cell_id)); | |
| 1458 int cell_row_index; | 1447 int cell_row_index; |
| 1459 if (cell && | 1448 if (cell && |
| 1460 cell->GetIntAttribute( | 1449 cell->GetIntAttribute( |
| 1461 ui::AX_ATTR_TABLE_CELL_ROW_INDEX, &cell_row_index)) { | 1450 ui::AX_ATTR_TABLE_CELL_ROW_INDEX, &cell_row_index)) { |
| 1462 *row_index = cell_row_index; | 1451 *row_index = cell_row_index; |
| 1463 return S_OK; | 1452 return S_OK; |
| 1464 } | 1453 } |
| 1465 | 1454 |
| 1466 return S_FALSE; | 1455 return S_FALSE; |
| 1467 } | 1456 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1575 | 1564 |
| 1576 const std::vector<int32_t>& unique_cell_ids = | 1565 const std::vector<int32_t>& unique_cell_ids = |
| 1577 GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS); | 1566 GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS); |
| 1578 int cell_id_count = static_cast<int>(unique_cell_ids.size()); | 1567 int cell_id_count = static_cast<int>(unique_cell_ids.size()); |
| 1579 if (index < 0) | 1568 if (index < 0) |
| 1580 return E_INVALIDARG; | 1569 return E_INVALIDARG; |
| 1581 if (index >= cell_id_count) | 1570 if (index >= cell_id_count) |
| 1582 return S_FALSE; | 1571 return S_FALSE; |
| 1583 | 1572 |
| 1584 int cell_id = unique_cell_ids[index]; | 1573 int cell_id = unique_cell_ids[index]; |
| 1585 BrowserAccessibilityWin* cell = | 1574 BrowserAccessibilityWin* cell = GetFromID(cell_id); |
| 1586 ToBrowserAccessibilityWin(manager()->GetFromID(cell_id)); | |
| 1587 int rowspan; | 1575 int rowspan; |
| 1588 int colspan; | 1576 int colspan; |
| 1589 if (cell && | 1577 if (cell && |
| 1590 cell->GetIntAttribute( | 1578 cell->GetIntAttribute( |
| 1591 ui::AX_ATTR_TABLE_CELL_ROW_SPAN, &rowspan) && | 1579 ui::AX_ATTR_TABLE_CELL_ROW_SPAN, &rowspan) && |
| 1592 cell->GetIntAttribute( | 1580 cell->GetIntAttribute( |
| 1593 ui::AX_ATTR_TABLE_CELL_COLUMN_SPAN, &colspan) && | 1581 ui::AX_ATTR_TABLE_CELL_COLUMN_SPAN, &colspan) && |
| 1594 rowspan >= 1 && | 1582 rowspan >= 1 && |
| 1595 colspan >= 1) { | 1583 colspan >= 1) { |
| 1596 *row_extents = rowspan; | 1584 *row_extents = rowspan; |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1734 return S_FALSE; | 1722 return S_FALSE; |
| 1735 } | 1723 } |
| 1736 if (columns <= 0 || rows <= 0 || column < 0 || column >= columns) | 1724 if (columns <= 0 || rows <= 0 || column < 0 || column >= columns) |
| 1737 return S_FALSE; | 1725 return S_FALSE; |
| 1738 | 1726 |
| 1739 const std::vector<int32_t>& cell_ids = | 1727 const std::vector<int32_t>& cell_ids = |
| 1740 table->GetIntListAttribute(ui::AX_ATTR_CELL_IDS); | 1728 table->GetIntListAttribute(ui::AX_ATTR_CELL_IDS); |
| 1741 | 1729 |
| 1742 for (int i = 0; i < rows; ++i) { | 1730 for (int i = 0; i < rows; ++i) { |
| 1743 int cell_id = cell_ids[i * columns + column]; | 1731 int cell_id = cell_ids[i * columns + column]; |
| 1744 BrowserAccessibilityWin* cell = | 1732 BrowserAccessibilityWin* cell = GetFromID(cell_id); |
| 1745 ToBrowserAccessibilityWin(manager()->GetFromID(cell_id)); | |
| 1746 if (cell && cell->GetRole() == ui::AX_ROLE_COLUMN_HEADER) | 1733 if (cell && cell->GetRole() == ui::AX_ROLE_COLUMN_HEADER) |
| 1747 (*n_column_header_cells)++; | 1734 (*n_column_header_cells)++; |
| 1748 } | 1735 } |
| 1749 | 1736 |
| 1750 *cell_accessibles = static_cast<IUnknown**>(CoTaskMemAlloc( | 1737 *cell_accessibles = static_cast<IUnknown**>(CoTaskMemAlloc( |
| 1751 (*n_column_header_cells) * sizeof(cell_accessibles[0]))); | 1738 (*n_column_header_cells) * sizeof(cell_accessibles[0]))); |
| 1752 int index = 0; | 1739 int index = 0; |
| 1753 for (int i = 0; i < rows; ++i) { | 1740 for (int i = 0; i < rows; ++i) { |
| 1754 int cell_id = cell_ids[i * columns + column]; | 1741 int cell_id = cell_ids[i * columns + column]; |
| 1755 BrowserAccessibility* cell = manager()->GetFromID(cell_id); | 1742 BrowserAccessibility* cell = manager()->GetFromID(cell_id); |
| (...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2342 return E_INVALIDARG; | 2329 return E_INVALIDARG; |
| 2343 | 2330 |
| 2344 const base::string16& text_str = GetText(); | 2331 const base::string16& text_str = GetText(); |
| 2345 HandleSpecialTextOffset(text_str, &start_offset); | 2332 HandleSpecialTextOffset(text_str, &start_offset); |
| 2346 HandleSpecialTextOffset(text_str, &end_offset); | 2333 HandleSpecialTextOffset(text_str, &end_offset); |
| 2347 | 2334 |
| 2348 manager()->SetTextSelection(*this, start_offset, end_offset); | 2335 manager()->SetTextSelection(*this, start_offset, end_offset); |
| 2349 return S_OK; | 2336 return S_OK; |
| 2350 } | 2337 } |
| 2351 | 2338 |
| 2352 // | |
| 2353 // IAccessibleText methods not implemented. | |
| 2354 // | |
| 2355 | |
| 2356 STDMETHODIMP BrowserAccessibilityWin::get_attributes(LONG offset, | 2339 STDMETHODIMP BrowserAccessibilityWin::get_attributes(LONG offset, |
| 2357 LONG* start_offset, | 2340 LONG* start_offset, |
| 2358 LONG* end_offset, | 2341 LONG* end_offset, |
| 2359 BSTR* text_attributes) { | 2342 BSTR* text_attributes) { |
| 2360 return E_NOTIMPL; | 2343 if (!start_offset || !end_offset || !text_attributes) |
| 2344 return E_INVALIDARG; |
| 2345 |
| 2346 *start_offset = *end_offset = 0; |
| 2347 *text_attributes = nullptr; |
| 2348 if (!instance_active()) |
| 2349 return E_FAIL; |
| 2350 |
| 2351 const base::string16& text = GetText(); |
| 2352 HandleSpecialTextOffset(text, &offset); |
| 2353 if (offset < 0 || offset > static_cast<LONG>(text.size())) |
| 2354 return E_INVALIDARG; |
| 2355 |
| 2356 ComputeStylesIfNeeded(); |
| 2357 *start_offset = FindStartOfStyle(offset, ui::BACKWARDS_DIRECTION); |
| 2358 *end_offset = FindStartOfStyle(offset, ui::FORWARDS_DIRECTION); |
| 2359 |
| 2360 base::string16 attributes_str; |
| 2361 const std::vector<base::string16>& attributes = |
| 2362 offset_to_text_attributes().find(*start_offset)->second; |
| 2363 for (const base::string16& attribute : attributes) { |
| 2364 attributes_str += attribute + L';'; |
| 2365 } |
| 2366 |
| 2367 if (attributes.empty()) |
| 2368 return S_FALSE; |
| 2369 |
| 2370 *text_attributes = SysAllocString(attributes_str.c_str()); |
| 2371 DCHECK(*text_attributes); |
| 2372 return S_OK; |
| 2361 } | 2373 } |
| 2362 | 2374 |
| 2363 // | 2375 // |
| 2364 // IAccessibleHypertext methods. | 2376 // IAccessibleHypertext methods. |
| 2365 // | 2377 // |
| 2366 | 2378 |
| 2367 STDMETHODIMP BrowserAccessibilityWin::get_nHyperlinks(long* hyperlink_count) { | 2379 STDMETHODIMP BrowserAccessibilityWin::get_nHyperlinks(long* hyperlink_count) { |
| 2368 if (!instance_active()) | 2380 if (!instance_active()) |
| 2369 return E_FAIL; | 2381 return E_FAIL; |
| 2370 | 2382 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2381 if (!instance_active()) | 2393 if (!instance_active()) |
| 2382 return E_FAIL; | 2394 return E_FAIL; |
| 2383 | 2395 |
| 2384 if (!hyperlink || | 2396 if (!hyperlink || |
| 2385 index < 0 || | 2397 index < 0 || |
| 2386 index >= static_cast<long>(hyperlinks().size())) { | 2398 index >= static_cast<long>(hyperlinks().size())) { |
| 2387 return E_INVALIDARG; | 2399 return E_INVALIDARG; |
| 2388 } | 2400 } |
| 2389 | 2401 |
| 2390 int32_t id = hyperlinks()[index]; | 2402 int32_t id = hyperlinks()[index]; |
| 2391 BrowserAccessibilityWin* child = | 2403 BrowserAccessibilityWin* link = GetFromID(id); |
| 2392 ToBrowserAccessibilityWin(manager()->GetFromID(id)); | 2404 if (!link) |
| 2393 if (child) { | 2405 return E_FAIL; |
| 2394 *hyperlink = static_cast<IAccessibleHyperlink*>(child->NewReference()); | |
| 2395 return S_OK; | |
| 2396 } | |
| 2397 | 2406 |
| 2398 return E_FAIL; | 2407 *hyperlink = static_cast<IAccessibleHyperlink*>(link->NewReference()); |
| 2408 return S_OK; |
| 2399 } | 2409 } |
| 2400 | 2410 |
| 2401 STDMETHODIMP BrowserAccessibilityWin::get_hyperlinkIndex( | 2411 STDMETHODIMP BrowserAccessibilityWin::get_hyperlinkIndex( |
| 2402 long char_index, | 2412 long char_index, |
| 2403 long* hyperlink_index) { | 2413 long* hyperlink_index) { |
| 2404 if (!instance_active()) | 2414 if (!instance_active()) |
| 2405 return E_FAIL; | 2415 return E_FAIL; |
| 2406 | 2416 |
| 2407 if (!hyperlink_index) | 2417 if (!hyperlink_index) |
| 2408 return E_INVALIDARG; | 2418 return E_INVALIDARG; |
| (...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2966 STDMETHODIMP BrowserAccessibilityWin::get_innerHTML(BSTR* innerHTML) { | 2976 STDMETHODIMP BrowserAccessibilityWin::get_innerHTML(BSTR* innerHTML) { |
| 2967 return E_NOTIMPL; | 2977 return E_NOTIMPL; |
| 2968 } | 2978 } |
| 2969 | 2979 |
| 2970 STDMETHODIMP | 2980 STDMETHODIMP |
| 2971 BrowserAccessibilityWin::get_localInterface(void** local_interface) { | 2981 BrowserAccessibilityWin::get_localInterface(void** local_interface) { |
| 2972 return E_NOTIMPL; | 2982 return E_NOTIMPL; |
| 2973 } | 2983 } |
| 2974 | 2984 |
| 2975 STDMETHODIMP BrowserAccessibilityWin::get_language(BSTR* language) { | 2985 STDMETHODIMP BrowserAccessibilityWin::get_language(BSTR* language) { |
| 2976 return E_NOTIMPL; | 2986 if (!language) |
| 2987 return E_INVALIDARG; |
| 2988 *language = nullptr; |
| 2989 |
| 2990 if (!instance_active()) |
| 2991 return E_FAIL; |
| 2992 |
| 2993 base::string16 lang = GetInheritedString16Attribute(ui::AX_ATTR_LANGUAGE); |
| 2994 if (lang.empty()) |
| 2995 lang = L"en-US"; |
| 2996 |
| 2997 *language = SysAllocString(lang.c_str()); |
| 2998 DCHECK(*language); |
| 2999 return S_OK; |
| 2977 } | 3000 } |
| 2978 | 3001 |
| 2979 // | 3002 // |
| 2980 // ISimpleDOMText methods. | 3003 // ISimpleDOMText methods. |
| 2981 // | 3004 // |
| 2982 | 3005 |
| 2983 STDMETHODIMP BrowserAccessibilityWin::get_domText(BSTR* dom_text) { | 3006 STDMETHODIMP BrowserAccessibilityWin::get_domText(BSTR* dom_text) { |
| 2984 if (!instance_active()) | 3007 if (!instance_active()) |
| 2985 return E_FAIL; | 3008 return E_FAIL; |
| 2986 | 3009 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3045 } | 3068 } |
| 3046 | 3069 |
| 3047 manager()->ScrollToMakeVisible(*this, GetLocalBoundsForRange( | 3070 manager()->ScrollToMakeVisible(*this, GetLocalBoundsForRange( |
| 3048 start_index, end_index - start_index)); | 3071 start_index, end_index - start_index)); |
| 3049 manager()->ToBrowserAccessibilityManagerWin()->TrackScrollingObject(this); | 3072 manager()->ToBrowserAccessibilityManagerWin()->TrackScrollingObject(this); |
| 3050 | 3073 |
| 3051 return S_OK; | 3074 return S_OK; |
| 3052 } | 3075 } |
| 3053 | 3076 |
| 3054 STDMETHODIMP BrowserAccessibilityWin::get_fontFamily(BSTR* font_family) { | 3077 STDMETHODIMP BrowserAccessibilityWin::get_fontFamily(BSTR* font_family) { |
| 3055 return E_NOTIMPL; | 3078 if (!font_family) |
| 3079 return E_INVALIDARG; |
| 3080 *font_family = nullptr; |
| 3081 |
| 3082 if (!instance_active()) |
| 3083 return E_FAIL; |
| 3084 |
| 3085 base::string16 family = |
| 3086 GetInheritedString16Attribute(ui::AX_ATTR_FONT_FAMILY); |
| 3087 if (family.empty()) |
| 3088 return S_FALSE; |
| 3089 |
| 3090 *font_family = SysAllocString(family.c_str()); |
| 3091 DCHECK(*font_family); |
| 3092 return S_OK; |
| 3056 } | 3093 } |
| 3057 | 3094 |
| 3058 // | 3095 // |
| 3059 // IServiceProvider methods. | 3096 // IServiceProvider methods. |
| 3060 // | 3097 // |
| 3061 | 3098 |
| 3062 STDMETHODIMP BrowserAccessibilityWin::QueryService(REFGUID guid_service, | 3099 STDMETHODIMP BrowserAccessibilityWin::QueryService(REFGUID guid_service, |
| 3063 REFIID riid, | 3100 REFIID riid, |
| 3064 void** object) { | 3101 void** object) { |
| 3065 if (!instance_active()) | 3102 if (!instance_active()) |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3226 if (!ax_object || !ax_object->IsHyperlink()) { | 3263 if (!ax_object || !ax_object->IsHyperlink()) { |
| 3227 *object = nullptr; | 3264 *object = nullptr; |
| 3228 return E_NOINTERFACE; | 3265 return E_NOINTERFACE; |
| 3229 } | 3266 } |
| 3230 } | 3267 } |
| 3231 | 3268 |
| 3232 return CComObjectRootBase::InternalQueryInterface( | 3269 return CComObjectRootBase::InternalQueryInterface( |
| 3233 this_ptr, entries, iid, object); | 3270 this_ptr, entries, iid, object); |
| 3234 } | 3271 } |
| 3235 | 3272 |
| 3273 void BrowserAccessibilityWin::ComputeStylesIfNeeded() { |
| 3274 if (!offset_to_text_attributes().empty()) |
| 3275 return; |
| 3276 |
| 3277 std::map<int, std::vector<base::string16>> attributes_map; |
| 3278 if (PlatformIsLeaf()) { |
| 3279 attributes_map[0] = ComputeTextAttributes(); |
| 3280 win_attributes_->offset_to_text_attributes.swap(attributes_map); |
| 3281 return; |
| 3282 } |
| 3283 |
| 3284 int start_offset = 0; |
| 3285 for (size_t i = 0; i < PlatformChildCount(); ++i) { |
| 3286 const auto child = ToBrowserAccessibilityWin(PlatformGetChild(i)); |
| 3287 DCHECK(child); |
| 3288 std::vector<base::string16> attributes(child->ComputeTextAttributes()); |
| 3289 |
| 3290 if (attributes_map.empty()) { |
| 3291 attributes_map[start_offset] = attributes; |
| 3292 } else { |
| 3293 // Only add the attributes for this child if we are at the start of a new |
| 3294 // style span. |
| 3295 std::vector<base::string16> previous_attributes = |
| 3296 attributes_map.rbegin()->second; |
| 3297 if (!std::equal(attributes.begin(), attributes.end(), |
| 3298 previous_attributes.begin())) { |
| 3299 attributes_map[start_offset] = attributes; |
| 3300 } |
| 3301 } |
| 3302 |
| 3303 if (child->IsTextOnlyObject()) |
| 3304 start_offset += child->GetText().length(); |
| 3305 else |
| 3306 start_offset += 1; |
| 3307 } |
| 3308 |
| 3309 win_attributes_->offset_to_text_attributes.swap(attributes_map); |
| 3310 } |
| 3311 |
| 3236 base::string16 BrowserAccessibilityWin::GetText() const { | 3312 base::string16 BrowserAccessibilityWin::GetText() const { |
| 3237 if (PlatformIsChildOfLeaf()) | 3313 if (PlatformIsChildOfLeaf()) |
| 3238 return BrowserAccessibility::GetText(); | 3314 return BrowserAccessibility::GetText(); |
| 3239 return win_attributes_->hypertext; | 3315 return win_attributes_->hypertext; |
| 3240 } | 3316 } |
| 3241 | 3317 |
| 3242 // | 3318 // |
| 3243 // Private methods. | 3319 // Private methods. |
| 3244 // | 3320 // |
| 3245 | 3321 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3310 table->GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS); | 3386 table->GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS); |
| 3311 for (size_t i = 0; i < unique_cell_ids.size(); ++i) { | 3387 for (size_t i = 0; i < unique_cell_ids.size(); ++i) { |
| 3312 if (unique_cell_ids[i] == GetId()) { | 3388 if (unique_cell_ids[i] == GetId()) { |
| 3313 win_attributes_->ia2_attributes.push_back( | 3389 win_attributes_->ia2_attributes.push_back( |
| 3314 base::string16(L"table-cell-index:") + base::IntToString16(i)); | 3390 base::string16(L"table-cell-index:") + base::IntToString16(i)); |
| 3315 } | 3391 } |
| 3316 } | 3392 } |
| 3317 } | 3393 } |
| 3318 } | 3394 } |
| 3319 | 3395 |
| 3320 // Expose invalid state for form controls and elements with aria-invalid. | |
| 3321 int invalid_state; | |
| 3322 if (GetIntAttribute(ui::AX_ATTR_INVALID_STATE, &invalid_state)) { | |
| 3323 // TODO(nektar): Handle the possibility of having multiple aria-invalid | |
| 3324 // attributes defined, e.g., "invalid:spelling,grammar". | |
| 3325 switch (invalid_state) { | |
| 3326 case ui::AX_INVALID_STATE_FALSE: | |
| 3327 win_attributes_->ia2_attributes.push_back(L"invalid:false"); | |
| 3328 break; | |
| 3329 case ui::AX_INVALID_STATE_TRUE: | |
| 3330 win_attributes_->ia2_attributes.push_back(L"invalid:true"); | |
| 3331 break; | |
| 3332 case ui::AX_INVALID_STATE_SPELLING: | |
| 3333 win_attributes_->ia2_attributes.push_back(L"invalid:spelling"); | |
| 3334 break; | |
| 3335 case ui::AX_INVALID_STATE_GRAMMAR: | |
| 3336 win_attributes_->ia2_attributes.push_back(L"invalid:grammar"); | |
| 3337 break; | |
| 3338 case ui::AX_INVALID_STATE_OTHER: | |
| 3339 { | |
| 3340 base::string16 aria_invalid_value; | |
| 3341 if (GetString16Attribute(ui::AX_ATTR_ARIA_INVALID_VALUE, | |
| 3342 &aria_invalid_value)) { | |
| 3343 SanitizeStringAttributeForIA2(aria_invalid_value, | |
| 3344 &aria_invalid_value); | |
| 3345 win_attributes_->ia2_attributes.push_back( | |
| 3346 L"invalid:" + aria_invalid_value); | |
| 3347 } else { | |
| 3348 // Set the attribute to L"true", since we cannot be more specific. | |
| 3349 win_attributes_->ia2_attributes.push_back(L"invalid:true"); | |
| 3350 } | |
| 3351 } | |
| 3352 break; | |
| 3353 default: | |
| 3354 NOTREACHED(); | |
| 3355 } | |
| 3356 } | |
| 3357 | |
| 3358 // Expose row or column header sort direction. | 3396 // Expose row or column header sort direction. |
| 3359 int32_t sort_direction; | 3397 int32_t sort_direction; |
| 3360 if ((ia_role() == ROLE_SYSTEM_COLUMNHEADER || | 3398 if ((ia_role() == ROLE_SYSTEM_COLUMNHEADER || |
| 3361 ia_role() == ROLE_SYSTEM_ROWHEADER) && | 3399 ia_role() == ROLE_SYSTEM_ROWHEADER) && |
| 3362 GetIntAttribute(ui::AX_ATTR_SORT_DIRECTION, &sort_direction)) { | 3400 GetIntAttribute(ui::AX_ATTR_SORT_DIRECTION, &sort_direction)) { |
| 3363 switch (sort_direction) { | 3401 switch (sort_direction) { |
| 3364 case ui::AX_SORT_DIRECTION_UNSORTED: | 3402 case ui::AX_SORT_DIRECTION_UNSORTED: |
| 3365 win_attributes_->ia2_attributes.push_back(L"sort:none"); | 3403 win_attributes_->ia2_attributes.push_back(L"sort:none"); |
| 3366 break; | 3404 break; |
| 3367 case ui::AX_SORT_DIRECTION_ASCENDING: | 3405 case ui::AX_SORT_DIRECTION_ASCENDING: |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3427 | 3465 |
| 3428 return; | 3466 return; |
| 3429 } | 3467 } |
| 3430 | 3468 |
| 3431 // Construct the hypertext for this node, which contains the concatenation | 3469 // Construct the hypertext for this node, which contains the concatenation |
| 3432 // of all of the static text and widespace of this node's children and an | 3470 // of all of the static text and widespace of this node's children and an |
| 3433 // embedded object character for all the other children. Build up a map from | 3471 // embedded object character for all the other children. Build up a map from |
| 3434 // the character index of each embedded object character to the id of the | 3472 // the character index of each embedded object character to the id of the |
| 3435 // child object it points to. | 3473 // child object it points to. |
| 3436 for (unsigned int i = 0; i < PlatformChildCount(); ++i) { | 3474 for (unsigned int i = 0; i < PlatformChildCount(); ++i) { |
| 3437 BrowserAccessibilityWin* child = | 3475 const auto child = ToBrowserAccessibilityWin(PlatformGetChild(i)); |
| 3438 ToBrowserAccessibilityWin(PlatformGetChild(i)); | |
| 3439 DCHECK(child); | 3476 DCHECK(child); |
| 3440 // Similar to Firefox, we don't expose text-only objects in IA2 hypertext. | 3477 // Similar to Firefox, we don't expose text-only objects in IA2 hypertext. |
| 3441 if (child->IsTextOnlyObject()) { | 3478 if (child->IsTextOnlyObject()) { |
| 3442 win_attributes_->hypertext += child->name(); | 3479 win_attributes_->hypertext += child->name(); |
| 3443 } else { | 3480 } else { |
| 3444 int32_t char_offset = static_cast<int32_t>(GetText().size()); | 3481 int32_t char_offset = static_cast<int32_t>(GetText().size()); |
| 3445 int32_t child_id = child->GetId(); | 3482 int32_t child_id = child->GetId(); |
| 3446 int32_t index = hyperlinks().size(); | 3483 int32_t index = hyperlinks().size(); |
| 3447 win_attributes_->hyperlink_offset_to_index[char_offset] = index; | 3484 win_attributes_->hyperlink_offset_to_index[char_offset] = index; |
| 3448 win_attributes_->hyperlinks.push_back(child_id); | 3485 win_attributes_->hyperlinks.push_back(child_id); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3566 | 3603 |
| 3567 bool BrowserAccessibilityWin::IsNative() const { | 3604 bool BrowserAccessibilityWin::IsNative() const { |
| 3568 return true; | 3605 return true; |
| 3569 } | 3606 } |
| 3570 | 3607 |
| 3571 void BrowserAccessibilityWin::OnLocationChanged() { | 3608 void BrowserAccessibilityWin::OnLocationChanged() { |
| 3572 manager()->ToBrowserAccessibilityManagerWin()->MaybeCallNotifyWinEvent( | 3609 manager()->ToBrowserAccessibilityManagerWin()->MaybeCallNotifyWinEvent( |
| 3573 EVENT_OBJECT_LOCATIONCHANGE, this); | 3610 EVENT_OBJECT_LOCATIONCHANGE, this); |
| 3574 } | 3611 } |
| 3575 | 3612 |
| 3613 std::vector<base::string16> BrowserAccessibilityWin::ComputeTextAttributes() |
| 3614 const { |
| 3615 std::vector<base::string16> attributes; |
| 3616 |
| 3617 // We include list markers for now, but there might be other objects that are |
| 3618 // auto generated. |
| 3619 // TODO(nektar): Compute what objects are auto-generated in Blink. |
| 3620 if (GetRole() == ui::AX_ROLE_LIST_MARKER) |
| 3621 attributes.push_back(L"auto-generated:true"); |
| 3622 else |
| 3623 attributes.push_back(L"auto-generated:false"); |
| 3624 |
| 3625 int color; |
| 3626 base::string16 color_value(L"transparent"); |
| 3627 if (GetIntAttribute(ui::AX_ATTR_BACKGROUND_COLOR, &color)) { |
| 3628 unsigned int alpha = SkColorGetA(color); |
| 3629 unsigned int red = SkColorGetR(color); |
| 3630 unsigned int green = SkColorGetG(color); |
| 3631 unsigned int blue = SkColorGetB(color); |
| 3632 if (alpha) { |
| 3633 color_value = L"rgb(" + base::UintToString16(red) + L',' + |
| 3634 base::UintToString16(green) + L',' + |
| 3635 base::UintToString16(blue) + L')'; |
| 3636 } |
| 3637 } |
| 3638 SanitizeStringAttributeForIA2(color_value, &color_value); |
| 3639 attributes.push_back(L"background-color:" + color_value); |
| 3640 |
| 3641 if (GetIntAttribute(ui::AX_ATTR_COLOR, &color)) { |
| 3642 unsigned int red = SkColorGetR(color); |
| 3643 unsigned int green = SkColorGetG(color); |
| 3644 unsigned int blue = SkColorGetB(color); |
| 3645 color_value = L"rgb(" + base::UintToString16(red) + L',' + |
| 3646 base::UintToString16(green) + L',' + |
| 3647 base::UintToString16(blue) + L')'; |
| 3648 } else { |
| 3649 color_value = L"rgb(0,0,0)"; |
| 3650 } |
| 3651 SanitizeStringAttributeForIA2(color_value, &color_value); |
| 3652 attributes.push_back(L"color:" + color_value); |
| 3653 |
| 3654 base::string16 font_family( |
| 3655 GetInheritedString16Attribute(ui::AX_ATTR_FONT_FAMILY)); |
| 3656 // Attribute has no default value. |
| 3657 if (!font_family.empty()) { |
| 3658 SanitizeStringAttributeForIA2(font_family, &font_family); |
| 3659 attributes.push_back(L"font-family:" + font_family); |
| 3660 } |
| 3661 |
| 3662 float font_size; |
| 3663 // Attribute has no default value. |
| 3664 if (GetFloatAttribute(ui::AX_ATTR_FONT_SIZE, &font_size)) { |
| 3665 // The IA2 Spec requires the value to be in pt, not in pixels. |
| 3666 // There are 72 points per inch. |
| 3667 // We assume that there are 96 pixels per inch on a standard display. |
| 3668 // TODO(nektar): Figure out the current value of pixels per inch. |
| 3669 float points = font_size * 72.0 / 96.0; |
| 3670 attributes.push_back(L"font-size:" + |
| 3671 base::UTF8ToUTF16(base::DoubleToString(points)) + |
| 3672 L"pt"); |
| 3673 } |
| 3674 |
| 3675 auto text_style = |
| 3676 static_cast<ui::AXTextStyle>(GetIntAttribute(ui::AX_ATTR_TEXT_STYLE)); |
| 3677 if (text_style == ui::AX_TEXT_STYLE_NONE) { |
| 3678 attributes.push_back(L"font-style:normal"); |
| 3679 attributes.push_back(L"font-weight:normal"); |
| 3680 } else { |
| 3681 if (text_style & ui::AX_TEXT_STYLE_BOLD) |
| 3682 attributes.push_back(L"font-weight:bold"); |
| 3683 |
| 3684 base::string16 font_style; |
| 3685 if (text_style & ui::AX_TEXT_STYLE_ITALIC) |
| 3686 font_style += L",italic"; |
| 3687 if (text_style & ui::AX_TEXT_STYLE_UNDERLINE) |
| 3688 font_style += L",underline"; |
| 3689 if (text_style & ui::AX_TEXT_STYLE_LINE_THROUGH) |
| 3690 font_style += L",line-through"; |
| 3691 // TODO(nektar): Support more font style attributes in Blink. |
| 3692 |
| 3693 if (font_style.empty()) { |
| 3694 font_style = L"normal"; |
| 3695 } else { |
| 3696 // Remove the leading comma. |
| 3697 font_style.erase(0, 1); |
| 3698 } |
| 3699 attributes.push_back(L"font-style:" + font_style); |
| 3700 } |
| 3701 |
| 3702 auto invalid_state = static_cast<ui::AXInvalidState>( |
| 3703 GetIntAttribute(ui::AX_ATTR_INVALID_STATE)); |
| 3704 switch (invalid_state) { |
| 3705 case ui::AX_INVALID_STATE_NONE: |
| 3706 case ui::AX_INVALID_STATE_FALSE: |
| 3707 attributes.push_back(L"invalid:false"); |
| 3708 break; |
| 3709 case ui::AX_INVALID_STATE_TRUE: |
| 3710 attributes.push_back(L"invalid:true"); |
| 3711 break; |
| 3712 case ui::AX_INVALID_STATE_SPELLING: |
| 3713 case ui::AX_INVALID_STATE_GRAMMAR: { |
| 3714 base::string16 spelling_grammar_value; |
| 3715 if (invalid_state & ui::AX_INVALID_STATE_SPELLING) |
| 3716 spelling_grammar_value = L"spelling"; |
| 3717 else if (invalid_state & ui::AX_INVALID_STATE_GRAMMAR) |
| 3718 spelling_grammar_value = L"grammar"; |
| 3719 else |
| 3720 spelling_grammar_value = L"spelling,grammar"; |
| 3721 attributes.push_back(L"invalid:" + spelling_grammar_value); |
| 3722 break; |
| 3723 } |
| 3724 case ui::AX_INVALID_STATE_OTHER: { |
| 3725 base::string16 aria_invalid_value; |
| 3726 if (GetString16Attribute(ui::AX_ATTR_ARIA_INVALID_VALUE, |
| 3727 &aria_invalid_value)) { |
| 3728 SanitizeStringAttributeForIA2(aria_invalid_value, &aria_invalid_value); |
| 3729 attributes.push_back(L"invalid:" + aria_invalid_value); |
| 3730 } else { |
| 3731 // Set the attribute to L"true", since we cannot be more specific. |
| 3732 attributes.push_back(L"invalid:true"); |
| 3733 } |
| 3734 break; |
| 3735 } |
| 3736 default: |
| 3737 NOTREACHED(); |
| 3738 } |
| 3739 |
| 3740 base::string16 language(GetInheritedString16Attribute(ui::AX_ATTR_LANGUAGE)); |
| 3741 // Default value should be L"en-US". |
| 3742 if (language.empty()) { |
| 3743 attributes.push_back(L"language:en-US"); |
| 3744 } else { |
| 3745 SanitizeStringAttributeForIA2(language, &language); |
| 3746 attributes.push_back(L"language:" + language); |
| 3747 } |
| 3748 |
| 3749 // TODO(nektar): Add Blink support for the following attributes. |
| 3750 // Currently set to their default values as dictated by the IA2 Spec. |
| 3751 attributes.push_back(L"text-line-through-mode:continuous"); |
| 3752 attributes.push_back(L"text-line-through-style:none"); |
| 3753 // Default value must be the empty string. |
| 3754 attributes.push_back(L"text-line-through-text:"); |
| 3755 attributes.push_back(L"text-line-through-type:none"); |
| 3756 attributes.push_back(L"text-line-through-width:auto"); |
| 3757 attributes.push_back(L"text-outline:false"); |
| 3758 attributes.push_back(L"text-position:baseline"); |
| 3759 attributes.push_back(L"text-shadow:none"); |
| 3760 attributes.push_back(L"text-underline-mode:continuous"); |
| 3761 attributes.push_back(L"text-underline-style:none"); |
| 3762 attributes.push_back(L"text-underline-type:none"); |
| 3763 attributes.push_back(L"text-underline-width:auto"); |
| 3764 |
| 3765 auto text_direction = static_cast<ui::AXTextDirection>( |
| 3766 GetIntAttribute(ui::AX_ATTR_TEXT_DIRECTION)); |
| 3767 switch (text_direction) { |
| 3768 case ui::AX_TEXT_DIRECTION_NONE: |
| 3769 case ui::AX_TEXT_DIRECTION_LTR: |
| 3770 attributes.push_back(L"writing-mode:lr"); |
| 3771 break; |
| 3772 case ui::AX_TEXT_DIRECTION_RTL: |
| 3773 attributes.push_back(L"writing-mode:rl"); |
| 3774 break; |
| 3775 case ui::AX_TEXT_DIRECTION_TTB: |
| 3776 attributes.push_back(L"writing-mode:tb"); |
| 3777 break; |
| 3778 case ui::AX_TEXT_DIRECTION_BTT: |
| 3779 // Not listed in the IA2 Spec. |
| 3780 attributes.push_back(L"writing-mode:bt"); |
| 3781 break; |
| 3782 default: |
| 3783 NOTREACHED(); |
| 3784 } |
| 3785 |
| 3786 return attributes; |
| 3787 } |
| 3788 |
| 3576 BrowserAccessibilityWin* BrowserAccessibilityWin::NewReference() { | 3789 BrowserAccessibilityWin* BrowserAccessibilityWin::NewReference() { |
| 3577 AddRef(); | 3790 AddRef(); |
| 3578 return this; | 3791 return this; |
| 3579 } | 3792 } |
| 3580 | 3793 |
| 3581 BrowserAccessibilityWin* BrowserAccessibilityWin::GetTargetFromChildID( | 3794 BrowserAccessibilityWin* BrowserAccessibilityWin::GetTargetFromChildID( |
| 3582 const VARIANT& var_id) { | 3795 const VARIANT& var_id) { |
| 3583 if (var_id.vt != VT_I4) | 3796 if (var_id.vt != VT_I4) |
| 3584 return NULL; | 3797 return NULL; |
| 3585 | 3798 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3665 if (parent) { | 3878 if (parent) { |
| 3666 hyperlink_index = | 3879 hyperlink_index = |
| 3667 ToBrowserAccessibilityWin(parent)->GetHyperlinkIndexFromChild(*this); | 3880 ToBrowserAccessibilityWin(parent)->GetHyperlinkIndexFromChild(*this); |
| 3668 } | 3881 } |
| 3669 | 3882 |
| 3670 if (hyperlink_index >= 0) | 3883 if (hyperlink_index >= 0) |
| 3671 return true; | 3884 return true; |
| 3672 return false; | 3885 return false; |
| 3673 } | 3886 } |
| 3674 | 3887 |
| 3888 BrowserAccessibilityWin* |
| 3889 BrowserAccessibilityWin::GetHyperlinkFromHypertextOffset(int offset) const { |
| 3890 std::map<int32_t, int32_t>::iterator iterator = |
| 3891 hyperlink_offset_to_index().find(offset); |
| 3892 if (iterator == hyperlink_offset_to_index().end()) |
| 3893 return nullptr; |
| 3894 |
| 3895 int32_t index = iterator->second; |
| 3896 DCHECK_GE(index, 0); |
| 3897 DCHECK_LT(index, static_cast<int32_t>(hyperlinks().size())); |
| 3898 int32_t id = hyperlinks()[index]; |
| 3899 BrowserAccessibilityWin* hyperlink = GetFromID(id); |
| 3900 if (!hyperlink) |
| 3901 return nullptr; |
| 3902 return hyperlink; |
| 3903 } |
| 3904 |
| 3675 int32_t BrowserAccessibilityWin::GetHyperlinkIndexFromChild( | 3905 int32_t BrowserAccessibilityWin::GetHyperlinkIndexFromChild( |
| 3676 const BrowserAccessibilityWin& child) const { | 3906 const BrowserAccessibilityWin& child) const { |
| 3677 if (hyperlinks().empty()) | 3907 if (hyperlinks().empty()) |
| 3678 return -1; | 3908 return -1; |
| 3679 | 3909 |
| 3680 auto iterator = std::find( | 3910 auto iterator = std::find( |
| 3681 hyperlinks().begin(), hyperlinks().end(), child.GetId()); | 3911 hyperlinks().begin(), hyperlinks().end(), child.GetId()); |
| 3682 if (iterator == hyperlinks().end()) | 3912 if (iterator == hyperlinks().end()) |
| 3683 return -1; | 3913 return -1; |
| 3684 | 3914 |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3808 return 0; | 4038 return 0; |
| 3809 if (endpoint_index_in_common_parent > index_in_common_parent) | 4039 if (endpoint_index_in_common_parent > index_in_common_parent) |
| 3810 return GetText().size(); | 4040 return GetText().size(); |
| 3811 | 4041 |
| 3812 NOTREACHED(); | 4042 NOTREACHED(); |
| 3813 return -1; | 4043 return -1; |
| 3814 } | 4044 } |
| 3815 | 4045 |
| 3816 int BrowserAccessibilityWin::GetSelectionAnchor() const { | 4046 int BrowserAccessibilityWin::GetSelectionAnchor() const { |
| 3817 int32_t anchor_id = manager()->GetTreeData().sel_anchor_object_id; | 4047 int32_t anchor_id = manager()->GetTreeData().sel_anchor_object_id; |
| 3818 const auto anchor_object = | 4048 const BrowserAccessibilityWin* anchor_object = GetFromID(anchor_id); |
| 3819 ToBrowserAccessibilityWin(manager()->GetFromID(anchor_id)); | |
| 3820 if (!anchor_object) | 4049 if (!anchor_object) |
| 3821 return -1; | 4050 return -1; |
| 3822 | 4051 |
| 3823 int anchor_offset = manager()->GetTreeData().sel_anchor_offset; | 4052 int anchor_offset = manager()->GetTreeData().sel_anchor_offset; |
| 3824 return GetHypertextOffsetFromEndpoint(*anchor_object, anchor_offset); | 4053 return GetHypertextOffsetFromEndpoint(*anchor_object, anchor_offset); |
| 3825 } | 4054 } |
| 3826 | 4055 |
| 3827 int BrowserAccessibilityWin::GetSelectionFocus() const { | 4056 int BrowserAccessibilityWin::GetSelectionFocus() const { |
| 3828 int32_t focus_id = manager()->GetTreeData().sel_focus_object_id; | 4057 int32_t focus_id = manager()->GetTreeData().sel_focus_object_id; |
| 3829 const auto focus_object = | 4058 const BrowserAccessibilityWin* focus_object = GetFromID(focus_id); |
| 3830 ToBrowserAccessibilityWin(manager()->GetFromID(focus_id)); | |
| 3831 if (!focus_object) | 4059 if (!focus_object) |
| 3832 return -1; | 4060 return -1; |
| 3833 | 4061 |
| 3834 int focus_offset = manager()->GetTreeData().sel_focus_offset; | 4062 int focus_offset = manager()->GetTreeData().sel_focus_offset; |
| 3835 return GetHypertextOffsetFromEndpoint(*focus_object, focus_offset); | 4063 return GetHypertextOffsetFromEndpoint(*focus_object, focus_offset); |
| 3836 } | 4064 } |
| 3837 | 4065 |
| 3838 void BrowserAccessibilityWin::GetSelectionOffsets( | 4066 void BrowserAccessibilityWin::GetSelectionOffsets( |
| 3839 int* selection_start, int* selection_end) const { | 4067 int* selection_start, int* selection_end) const { |
| 3840 DCHECK(selection_start && selection_end); | 4068 DCHECK(selection_start && selection_end); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 3870 } | 4098 } |
| 3871 | 4099 |
| 3872 // The IA2 Spec says that if the largest of the two offsets falls on an | 4100 // The IA2 Spec says that if the largest of the two offsets falls on an |
| 3873 // embedded object character and if there is a selection in that embedded | 4101 // embedded object character and if there is a selection in that embedded |
| 3874 // object, it should be incremented by one so that it points after the | 4102 // object, it should be incremented by one so that it points after the |
| 3875 // embedded object character. | 4103 // embedded object character. |
| 3876 // This is a signal to AT software that the embedded object is also part of | 4104 // This is a signal to AT software that the embedded object is also part of |
| 3877 // the selection. | 4105 // the selection. |
| 3878 int* largest_offset = | 4106 int* largest_offset = |
| 3879 (*selection_start <= *selection_end) ? selection_end : selection_start; | 4107 (*selection_start <= *selection_end) ? selection_end : selection_start; |
| 3880 auto current_object = const_cast<BrowserAccessibilityWin*>(this); | 4108 BrowserAccessibilityWin* hyperlink = |
| 3881 LONG hyperlink_index; | 4109 GetHyperlinkFromHypertextOffset(*largest_offset); |
| 3882 HRESULT hr = | 4110 if (!hyperlink) |
| 3883 current_object->get_hyperlinkIndex(*largest_offset, &hyperlink_index); | |
| 3884 if (hr != S_OK) | |
| 3885 return; | 4111 return; |
| 3886 | 4112 |
| 3887 DCHECK_GE(hyperlink_index, 0); | |
| 3888 base::win::ScopedComPtr<IAccessibleHyperlink> hyperlink; | |
| 3889 hr = current_object->get_hyperlink(hyperlink_index, hyperlink.Receive()); | |
| 3890 DCHECK(SUCCEEDED(hr)); | |
| 3891 base::win::ScopedComPtr<IAccessibleText> hyperlink_text; | |
| 3892 hr = hyperlink.QueryInterface(hyperlink_text.Receive()); | |
| 3893 DCHECK(SUCCEEDED(hr)); | |
| 3894 LONG n_selections = 0; | 4113 LONG n_selections = 0; |
| 3895 hr = hyperlink_text->get_nSelections(&n_selections); | 4114 HRESULT hr = hyperlink->get_nSelections(&n_selections); |
| 3896 DCHECK(SUCCEEDED(hr)); | 4115 DCHECK(SUCCEEDED(hr)); |
| 3897 if (n_selections > 0) | 4116 if (n_selections > 0) |
| 3898 ++(*largest_offset); | 4117 ++(*largest_offset); |
| 3899 } | 4118 } |
| 3900 | 4119 |
| 3901 base::string16 BrowserAccessibilityWin::GetValueText() { | 4120 base::string16 BrowserAccessibilityWin::GetValueText() { |
| 3902 float fval; | 4121 float fval; |
| 3903 base::string16 value = this->value(); | 4122 base::string16 value = this->value(); |
| 3904 | 4123 |
| 3905 if (value.empty() && | 4124 if (value.empty() && |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4017 if (ia2_boundary == IA2_TEXT_BOUNDARY_WORD) | 4236 if (ia2_boundary == IA2_TEXT_BOUNDARY_WORD) |
| 4018 return GetWordStartBoundary(static_cast<int>(start_offset), direction); | 4237 return GetWordStartBoundary(static_cast<int>(start_offset), direction); |
| 4019 | 4238 |
| 4020 ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary); | 4239 ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary); |
| 4021 const std::vector<int32_t>& line_breaks = | 4240 const std::vector<int32_t>& line_breaks = |
| 4022 GetIntListAttribute(ui::AX_ATTR_LINE_BREAKS); | 4241 GetIntListAttribute(ui::AX_ATTR_LINE_BREAKS); |
| 4023 return ui::FindAccessibleTextBoundary( | 4242 return ui::FindAccessibleTextBoundary( |
| 4024 text, line_breaks, boundary, start_offset, direction); | 4243 text, line_breaks, boundary, start_offset, direction); |
| 4025 } | 4244 } |
| 4026 | 4245 |
| 4027 BrowserAccessibilityWin* BrowserAccessibilityWin::GetFromID(int32_t id) { | 4246 LONG BrowserAccessibilityWin::FindStartOfStyle( |
| 4247 LONG start_offset, |
| 4248 ui::TextBoundaryDirection direction) const { |
| 4249 LONG text_length = static_cast<LONG>(GetText().length()); |
| 4250 DCHECK_GE(start_offset, 0); |
| 4251 DCHECK_LE(start_offset, text_length); |
| 4252 |
| 4253 switch (direction) { |
| 4254 case ui::BACKWARDS_DIRECTION: { |
| 4255 if (offset_to_text_attributes().empty()) |
| 4256 return 0; |
| 4257 |
| 4258 auto iterator = offset_to_text_attributes().upper_bound(start_offset); |
| 4259 --iterator; |
| 4260 return static_cast<LONG>(iterator->first); |
| 4261 } |
| 4262 case ui::FORWARDS_DIRECTION: { |
| 4263 const auto iterator = |
| 4264 offset_to_text_attributes().upper_bound(start_offset); |
| 4265 if (iterator == offset_to_text_attributes().end()) |
| 4266 return text_length; |
| 4267 return static_cast<LONG>(iterator->first); |
| 4268 } |
| 4269 default: |
| 4270 NOTREACHED(); |
| 4271 } |
| 4272 |
| 4273 return start_offset; |
| 4274 } |
| 4275 |
| 4276 BrowserAccessibilityWin* BrowserAccessibilityWin::GetFromID(int32_t id) const { |
| 4277 if (!instance_active()) |
| 4278 return nullptr; |
| 4028 return ToBrowserAccessibilityWin(manager()->GetFromID(id)); | 4279 return ToBrowserAccessibilityWin(manager()->GetFromID(id)); |
| 4029 } | 4280 } |
| 4030 | 4281 |
| 4031 bool BrowserAccessibilityWin::IsListBoxOptionOrMenuListOption() { | 4282 bool BrowserAccessibilityWin::IsListBoxOptionOrMenuListOption() { |
| 4032 if (!GetParent()) | 4283 if (!GetParent()) |
| 4033 return false; | 4284 return false; |
| 4034 | 4285 |
| 4035 int32_t role = GetRole(); | 4286 int32_t role = GetRole(); |
| 4036 int32_t parent_role = GetParent()->GetRole(); | 4287 int32_t parent_role = GetParent()->GetRole(); |
| 4037 | 4288 |
| 4038 if (role == ui::AX_ROLE_LIST_BOX_OPTION && | 4289 if (role == ui::AX_ROLE_LIST_BOX_OPTION && |
| 4039 parent_role == ui::AX_ROLE_LIST_BOX) { | 4290 parent_role == ui::AX_ROLE_LIST_BOX) { |
| 4040 return true; | 4291 return true; |
| 4041 } | 4292 } |
| 4042 | 4293 |
| 4043 if (role == ui::AX_ROLE_MENU_LIST_OPTION && | 4294 if (role == ui::AX_ROLE_MENU_LIST_OPTION && |
| 4044 parent_role == ui::AX_ROLE_MENU_LIST_POPUP) { | 4295 parent_role == ui::AX_ROLE_MENU_LIST_POPUP) { |
| 4045 return true; | 4296 return true; |
| 4046 } | 4297 } |
| 4047 | 4298 |
| 4048 return false; | 4299 return false; |
| 4049 } | 4300 } |
| 4050 | 4301 |
| 4302 void BrowserAccessibilityWin::AddRelations( |
| 4303 ui::AXIntListAttribute src_attr, |
| 4304 const base::string16& iaccessiblerelation_type) { |
| 4305 if (!HasIntListAttribute(src_attr)) |
| 4306 return; |
| 4307 |
| 4308 const std::vector<int32_t>& ids = GetIntListAttribute(src_attr); |
| 4309 for (size_t i = 0; i < ids.size(); ++i) { |
| 4310 CComObject<BrowserAccessibilityRelation>* relation; |
| 4311 HRESULT hr = |
| 4312 CComObject<BrowserAccessibilityRelation>::CreateInstance(&relation); |
| 4313 DCHECK(SUCCEEDED(hr)); |
| 4314 relation->AddRef(); |
| 4315 relation->Initialize(this, iaccessiblerelation_type); |
| 4316 relation->AddTarget(ids[i]); |
| 4317 relations_.push_back(relation); |
| 4318 } |
| 4319 } |
| 4320 |
| 4051 void BrowserAccessibilityWin::UpdateRequiredAttributes() { | 4321 void BrowserAccessibilityWin::UpdateRequiredAttributes() { |
| 4052 // Expose slider value. | 4322 // Expose slider value. |
| 4053 if (ia_role() == ROLE_SYSTEM_PROGRESSBAR || | 4323 if (ia_role() == ROLE_SYSTEM_PROGRESSBAR || |
| 4054 ia_role() == ROLE_SYSTEM_SCROLLBAR || | 4324 ia_role() == ROLE_SYSTEM_SCROLLBAR || |
| 4055 ia_role() == ROLE_SYSTEM_SLIDER) { | 4325 ia_role() == ROLE_SYSTEM_SLIDER) { |
| 4056 base::string16 value_text = GetValueText(); | 4326 base::string16 value_text = GetValueText(); |
| 4057 SanitizeStringAttributeForIA2(value_text, &value_text); | 4327 SanitizeStringAttributeForIA2(value_text, &value_text); |
| 4058 win_attributes_->ia2_attributes.push_back(L"valuetext:" + value_text); | 4328 win_attributes_->ia2_attributes.push_back(L"valuetext:" + value_text); |
| 4059 } | 4329 } |
| 4060 | 4330 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4104 // Expose input-text type attribute. | 4374 // Expose input-text type attribute. |
| 4105 base::string16 type; | 4375 base::string16 type; |
| 4106 base::string16 html_tag = GetString16Attribute(ui::AX_ATTR_HTML_TAG); | 4376 base::string16 html_tag = GetString16Attribute(ui::AX_ATTR_HTML_TAG); |
| 4107 if (IsSimpleTextControl() && html_tag == L"input" && | 4377 if (IsSimpleTextControl() && html_tag == L"input" && |
| 4108 GetHtmlAttribute("type", &type)) { | 4378 GetHtmlAttribute("type", &type)) { |
| 4109 SanitizeStringAttributeForIA2(type, &type); | 4379 SanitizeStringAttributeForIA2(type, &type); |
| 4110 win_attributes_->ia2_attributes.push_back(L"text-input-type:" + type); | 4380 win_attributes_->ia2_attributes.push_back(L"text-input-type:" + type); |
| 4111 } | 4381 } |
| 4112 } | 4382 } |
| 4113 | 4383 |
| 4114 void BrowserAccessibilityWin::AddRelations( | |
| 4115 ui::AXIntListAttribute src_attr, | |
| 4116 const base::string16& iaccessiblerelation_type) { | |
| 4117 if (!HasIntListAttribute(src_attr)) | |
| 4118 return; | |
| 4119 | |
| 4120 const std::vector<int32_t>& ids = GetIntListAttribute(src_attr); | |
| 4121 for (size_t i = 0; i < ids.size(); ++i) { | |
| 4122 CComObject<BrowserAccessibilityRelation>* relation; | |
| 4123 HRESULT hr = CComObject<BrowserAccessibilityRelation>::CreateInstance( | |
| 4124 &relation); | |
| 4125 DCHECK(SUCCEEDED(hr)); | |
| 4126 relation->AddRef(); | |
| 4127 relation->Initialize(this, iaccessiblerelation_type); | |
| 4128 relation->AddTarget(ids[i]); | |
| 4129 relations_.push_back(relation); | |
| 4130 } | |
| 4131 } | |
| 4132 | |
| 4133 void BrowserAccessibilityWin::InitRoleAndState() { | 4384 void BrowserAccessibilityWin::InitRoleAndState() { |
| 4134 int32_t ia_role = 0; | 4385 int32_t ia_role = 0; |
| 4135 int32_t ia_state = 0; | 4386 int32_t ia_state = 0; |
| 4136 base::string16 role_name; | 4387 base::string16 role_name; |
| 4137 int32_t ia2_role = 0; | 4388 int32_t ia2_role = 0; |
| 4138 int32_t ia2_state = IA2_STATE_OPAQUE; | 4389 int32_t ia2_state = IA2_STATE_OPAQUE; |
| 4139 | 4390 |
| 4140 if (HasState(ui::AX_STATE_BUSY)) | 4391 if (HasState(ui::AX_STATE_BUSY)) |
| 4141 ia_state |= STATE_SYSTEM_BUSY; | 4392 ia_state |= STATE_SYSTEM_BUSY; |
| 4142 if (HasState(ui::AX_STATE_CHECKED)) | 4393 if (HasState(ui::AX_STATE_CHECKED)) |
| (...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4685 return static_cast<BrowserAccessibilityWin*>(obj); | 4936 return static_cast<BrowserAccessibilityWin*>(obj); |
| 4686 } | 4937 } |
| 4687 | 4938 |
| 4688 const BrowserAccessibilityWin* | 4939 const BrowserAccessibilityWin* |
| 4689 ToBrowserAccessibilityWin(const BrowserAccessibility* obj) { | 4940 ToBrowserAccessibilityWin(const BrowserAccessibility* obj) { |
| 4690 DCHECK(!obj || obj->IsNative()); | 4941 DCHECK(!obj || obj->IsNative()); |
| 4691 return static_cast<const BrowserAccessibilityWin*>(obj); | 4942 return static_cast<const BrowserAccessibilityWin*>(obj); |
| 4692 } | 4943 } |
| 4693 | 4944 |
| 4694 } // namespace content | 4945 } // namespace content |
| OLD | NEW |