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 |