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 MayBeComputeStyles(); | |
dmazzoni
2016/03/14 17:38:21
nit: no capital B in maybe, just spell it MaybeCom
| |
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 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3310 table->GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS); | 3347 table->GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS); |
3311 for (size_t i = 0; i < unique_cell_ids.size(); ++i) { | 3348 for (size_t i = 0; i < unique_cell_ids.size(); ++i) { |
3312 if (unique_cell_ids[i] == GetId()) { | 3349 if (unique_cell_ids[i] == GetId()) { |
3313 win_attributes_->ia2_attributes.push_back( | 3350 win_attributes_->ia2_attributes.push_back( |
3314 base::string16(L"table-cell-index:") + base::IntToString16(i)); | 3351 base::string16(L"table-cell-index:") + base::IntToString16(i)); |
3315 } | 3352 } |
3316 } | 3353 } |
3317 } | 3354 } |
3318 } | 3355 } |
3319 | 3356 |
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. | 3357 // Expose row or column header sort direction. |
3359 int32_t sort_direction; | 3358 int32_t sort_direction; |
3360 if ((ia_role() == ROLE_SYSTEM_COLUMNHEADER || | 3359 if ((ia_role() == ROLE_SYSTEM_COLUMNHEADER || |
3361 ia_role() == ROLE_SYSTEM_ROWHEADER) && | 3360 ia_role() == ROLE_SYSTEM_ROWHEADER) && |
3362 GetIntAttribute(ui::AX_ATTR_SORT_DIRECTION, &sort_direction)) { | 3361 GetIntAttribute(ui::AX_ATTR_SORT_DIRECTION, &sort_direction)) { |
3363 switch (sort_direction) { | 3362 switch (sort_direction) { |
3364 case ui::AX_SORT_DIRECTION_UNSORTED: | 3363 case ui::AX_SORT_DIRECTION_UNSORTED: |
3365 win_attributes_->ia2_attributes.push_back(L"sort:none"); | 3364 win_attributes_->ia2_attributes.push_back(L"sort:none"); |
3366 break; | 3365 break; |
3367 case ui::AX_SORT_DIRECTION_ASCENDING: | 3366 case ui::AX_SORT_DIRECTION_ASCENDING: |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3427 | 3426 |
3428 return; | 3427 return; |
3429 } | 3428 } |
3430 | 3429 |
3431 // Construct the hypertext for this node, which contains the concatenation | 3430 // 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 | 3431 // 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 | 3432 // 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 | 3433 // the character index of each embedded object character to the id of the |
3435 // child object it points to. | 3434 // child object it points to. |
3436 for (unsigned int i = 0; i < PlatformChildCount(); ++i) { | 3435 for (unsigned int i = 0; i < PlatformChildCount(); ++i) { |
3437 BrowserAccessibilityWin* child = | 3436 const auto child = ToBrowserAccessibilityWin(PlatformGetChild(i)); |
3438 ToBrowserAccessibilityWin(PlatformGetChild(i)); | |
3439 DCHECK(child); | 3437 DCHECK(child); |
3440 // Similar to Firefox, we don't expose text-only objects in IA2 hypertext. | 3438 // Similar to Firefox, we don't expose text-only objects in IA2 hypertext. |
3441 if (child->IsTextOnlyObject()) { | 3439 if (child->IsTextOnlyObject()) { |
3442 win_attributes_->hypertext += child->name(); | 3440 win_attributes_->hypertext += child->name(); |
3443 } else { | 3441 } else { |
3444 int32_t char_offset = static_cast<int32_t>(GetText().size()); | 3442 int32_t char_offset = static_cast<int32_t>(GetText().size()); |
3445 int32_t child_id = child->GetId(); | 3443 int32_t child_id = child->GetId(); |
3446 int32_t index = hyperlinks().size(); | 3444 int32_t index = hyperlinks().size(); |
3447 win_attributes_->hyperlink_offset_to_index[char_offset] = index; | 3445 win_attributes_->hyperlink_offset_to_index[char_offset] = index; |
3448 win_attributes_->hyperlinks.push_back(child_id); | 3446 win_attributes_->hyperlinks.push_back(child_id); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3566 | 3564 |
3567 bool BrowserAccessibilityWin::IsNative() const { | 3565 bool BrowserAccessibilityWin::IsNative() const { |
3568 return true; | 3566 return true; |
3569 } | 3567 } |
3570 | 3568 |
3571 void BrowserAccessibilityWin::OnLocationChanged() { | 3569 void BrowserAccessibilityWin::OnLocationChanged() { |
3572 manager()->ToBrowserAccessibilityManagerWin()->MaybeCallNotifyWinEvent( | 3570 manager()->ToBrowserAccessibilityManagerWin()->MaybeCallNotifyWinEvent( |
3573 EVENT_OBJECT_LOCATIONCHANGE, this); | 3571 EVENT_OBJECT_LOCATIONCHANGE, this); |
3574 } | 3572 } |
3575 | 3573 |
3574 std::vector<base::string16> BrowserAccessibilityWin::ComputeTextAttributes() | |
3575 const { | |
3576 std::vector<base::string16> attributes; | |
3577 | |
3578 // We include list markers for now, but there might be other objects that are | |
3579 // auto generated. | |
3580 // TODO(nektar): Compute what objects are auto-generated in Blink. | |
3581 if (GetRole() == ui::AX_ROLE_LIST_MARKER) | |
3582 attributes.push_back(L"auto-generated:true"); | |
3583 else | |
3584 attributes.push_back(L"auto-generated:false"); | |
3585 | |
3586 int color; | |
3587 base::string16 color_value(L"transparent"); | |
3588 if (GetIntAttribute(ui::AX_ATTR_BACKGROUND_COLOR, &color)) { | |
3589 unsigned int alpha = SkColorGetA(color); | |
3590 unsigned int red = SkColorGetR(color); | |
3591 unsigned int green = SkColorGetG(color); | |
3592 unsigned int blue = SkColorGetB(color); | |
3593 if (alpha) { | |
3594 color_value = L"rgb(" + base::UintToString16(red) + L',' + | |
3595 base::UintToString16(blue) + L',' + | |
3596 base::UintToString16(green) + L')'; | |
3597 } | |
3598 } | |
3599 attributes.push_back(L"background-color:" + color_value); | |
3600 | |
3601 if (GetIntAttribute(ui::AX_ATTR_COLOR, &color)) { | |
3602 unsigned int red = SkColorGetR(color); | |
3603 unsigned int green = SkColorGetG(color); | |
3604 unsigned int blue = SkColorGetB(color); | |
3605 color_value = L"rgb(" + base::UintToString16(red) + L',' + | |
3606 base::UintToString16(blue) + L',' + | |
3607 base::UintToString16(green) + L')'; | |
3608 } else { | |
3609 color_value = L"rgb(0,0,0)"; | |
3610 } | |
3611 attributes.push_back(L"color:" + color_value); | |
3612 | |
3613 base::string16 font_family( | |
3614 GetInheritedString16Attribute(ui::AX_ATTR_FONT_FAMILY)); | |
3615 // Attribute has no default value. | |
3616 if (!font_family.empty()) { | |
3617 SanitizeStringAttributeForIA2(font_family, &font_family); | |
3618 attributes.push_back(L"font-family:" + font_family); | |
3619 } | |
3620 | |
3621 float font_size; | |
3622 // Attribute has no default value. | |
3623 if (GetFloatAttribute(ui::AX_ATTR_FONT_SIZE, &font_size)) { | |
3624 // The IA2 Spec requires the value to be in pt, not in pixels. | |
3625 // There are 72 points per inch. | |
3626 // We assume that there are 96 pixels per inch on a standard display. | |
3627 // TODO(nektar): Figure out the current value of pixels per inch. | |
3628 float points = font_size * 72.0 / 96.0; | |
3629 attributes.push_back(L"font-size:" + | |
3630 base::UTF8ToUTF16(base::DoubleToString(points))); | |
3631 } | |
3632 | |
3633 auto text_style = | |
3634 static_cast<ui::AXTextStyle>(GetIntAttribute(ui::AX_ATTR_TEXT_STYLE)); | |
3635 if (text_style == ui::AX_TEXT_STYLE_NONE) { | |
3636 attributes.push_back(L"font-style:normal"); | |
3637 attributes.push_back(L"font-weight:normal"); | |
3638 } else { | |
3639 if (text_style & ui::AX_TEXT_STYLE_BOLD) | |
3640 attributes.push_back(L"font-weight:bold"); | |
3641 | |
3642 base::string16 font_style; | |
3643 if (text_style & ui::AX_TEXT_STYLE_ITALIC) | |
3644 font_style += L",italic"; | |
3645 if (text_style & ui::AX_TEXT_STYLE_UNDERLINE) | |
3646 font_style += L",underline"; | |
3647 if (text_style & ui::AX_TEXT_STYLE_LINE_THROUGH) | |
3648 font_style += L",line-through"; | |
3649 // TODO(nektar): Support more font style attributes in Blink. | |
3650 | |
3651 if (font_style.empty()) { | |
3652 font_style = L"normal"; | |
3653 } else { | |
3654 // Remove the leading comma. | |
3655 font_style.erase(0, 1); | |
3656 } | |
3657 attributes.push_back(L"font-style:" + font_style); | |
3658 } | |
3659 | |
3660 auto invalid_state = static_cast<ui::AXInvalidState>( | |
3661 GetIntAttribute(ui::AX_ATTR_INVALID_STATE)); | |
3662 switch (invalid_state) { | |
3663 case ui::AX_INVALID_STATE_NONE: | |
3664 case ui::AX_INVALID_STATE_FALSE: | |
3665 attributes.push_back(L"invalid:false"); | |
3666 break; | |
3667 case ui::AX_INVALID_STATE_TRUE: | |
3668 attributes.push_back(L"invalid:true"); | |
3669 break; | |
3670 case ui::AX_INVALID_STATE_SPELLING: | |
3671 case ui::AX_INVALID_STATE_GRAMMAR: { | |
3672 base::string16 spelling_grammar_value; | |
3673 if (invalid_state & ui::AX_INVALID_STATE_SPELLING) | |
3674 spelling_grammar_value = L"spelling"; | |
3675 else if (invalid_state & ui::AX_INVALID_STATE_GRAMMAR) | |
3676 spelling_grammar_value = L"grammar"; | |
3677 else | |
3678 spelling_grammar_value = L"spelling,grammar"; | |
3679 attributes.push_back(L"invalid:" + spelling_grammar_value); | |
3680 break; | |
3681 } | |
3682 case ui::AX_INVALID_STATE_OTHER: { | |
3683 base::string16 aria_invalid_value; | |
3684 if (GetString16Attribute(ui::AX_ATTR_ARIA_INVALID_VALUE, | |
3685 &aria_invalid_value)) { | |
3686 SanitizeStringAttributeForIA2(aria_invalid_value, &aria_invalid_value); | |
3687 attributes.push_back(L"invalid:" + aria_invalid_value); | |
3688 } else { | |
3689 // Set the attribute to L"true", since we cannot be more specific. | |
3690 attributes.push_back(L"invalid:true"); | |
3691 } | |
3692 break; | |
3693 } | |
3694 default: | |
3695 NOTREACHED(); | |
3696 } | |
3697 | |
3698 base::string16 language(GetInheritedString16Attribute(ui::AX_ATTR_LANGUAGE)); | |
3699 // Default value should be L"en-US". | |
3700 if (language.empty()) { | |
3701 attributes.push_back(L"language:en-US"); | |
3702 } else { | |
3703 SanitizeStringAttributeForIA2(language, &language); | |
3704 attributes.push_back(L"language:" + language); | |
3705 } | |
3706 | |
3707 // TODO(nektar): Add Blink support for the following attributes. | |
3708 // Currently set to their default values as dictated by the IA2 Spec. | |
3709 attributes.push_back(L"text-line-through-mode:continuous"); | |
3710 attributes.push_back(L"text-line-through-style:none"); | |
3711 // Default value must be the empty string. | |
3712 attributes.push_back(L"text-line-through-text:"); | |
3713 attributes.push_back(L"text-line-through-type:none"); | |
3714 attributes.push_back(L"text-line-through-width:auto"); | |
3715 attributes.push_back(L"text-outline:false"); | |
3716 attributes.push_back(L"text-position:baseline"); | |
3717 attributes.push_back(L"text-shadow:none"); | |
3718 attributes.push_back(L"text-underline-mode:continuous"); | |
3719 attributes.push_back(L"text-underline-style:none"); | |
3720 attributes.push_back(L"text-underline-type:none"); | |
3721 attributes.push_back(L"text-underline-width:auto"); | |
3722 | |
3723 auto text_direction = static_cast<ui::AXTextDirection>( | |
3724 GetIntAttribute(ui::AX_ATTR_TEXT_DIRECTION)); | |
3725 switch (text_direction) { | |
3726 case ui::AX_TEXT_DIRECTION_NONE: | |
3727 case ui::AX_TEXT_DIRECTION_LTR: | |
3728 attributes.push_back(L"writing-mode:lr"); | |
3729 break; | |
3730 case ui::AX_TEXT_DIRECTION_RTL: | |
3731 attributes.push_back(L"writing-mode:rl"); | |
3732 break; | |
3733 case ui::AX_TEXT_DIRECTION_TTB: | |
3734 attributes.push_back(L"writing-mode:tb"); | |
3735 break; | |
3736 case ui::AX_TEXT_DIRECTION_BTT: | |
3737 // Not listed in the IA2 Spec. | |
3738 attributes.push_back(L"writing-mode:bt"); | |
3739 break; | |
3740 default: | |
3741 NOTREACHED(); | |
3742 } | |
3743 | |
3744 return attributes; | |
3745 } | |
3746 | |
3576 BrowserAccessibilityWin* BrowserAccessibilityWin::NewReference() { | 3747 BrowserAccessibilityWin* BrowserAccessibilityWin::NewReference() { |
3577 AddRef(); | 3748 AddRef(); |
3578 return this; | 3749 return this; |
3579 } | 3750 } |
3580 | 3751 |
3581 BrowserAccessibilityWin* BrowserAccessibilityWin::GetTargetFromChildID( | 3752 BrowserAccessibilityWin* BrowserAccessibilityWin::GetTargetFromChildID( |
3582 const VARIANT& var_id) { | 3753 const VARIANT& var_id) { |
3583 if (var_id.vt != VT_I4) | 3754 if (var_id.vt != VT_I4) |
3584 return NULL; | 3755 return NULL; |
3585 | 3756 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3665 if (parent) { | 3836 if (parent) { |
3666 hyperlink_index = | 3837 hyperlink_index = |
3667 ToBrowserAccessibilityWin(parent)->GetHyperlinkIndexFromChild(*this); | 3838 ToBrowserAccessibilityWin(parent)->GetHyperlinkIndexFromChild(*this); |
3668 } | 3839 } |
3669 | 3840 |
3670 if (hyperlink_index >= 0) | 3841 if (hyperlink_index >= 0) |
3671 return true; | 3842 return true; |
3672 return false; | 3843 return false; |
3673 } | 3844 } |
3674 | 3845 |
3846 BrowserAccessibilityWin* | |
3847 BrowserAccessibilityWin::GetHyperlinkFromHypertextOffset(int offset) const { | |
3848 std::map<int32_t, int32_t>::iterator iterator = | |
3849 hyperlink_offset_to_index().find(offset); | |
3850 if (iterator == hyperlink_offset_to_index().end()) | |
3851 return nullptr; | |
3852 | |
3853 int32_t index = iterator->second; | |
3854 DCHECK_GE(index, 0); | |
3855 DCHECK_LT(index, static_cast<int32_t>(hyperlinks().size())); | |
3856 int32_t id = hyperlinks()[index]; | |
3857 BrowserAccessibilityWin* hyperlink = GetFromID(id); | |
3858 if (!hyperlink) | |
3859 return nullptr; | |
3860 return hyperlink; | |
3861 } | |
3862 | |
3675 int32_t BrowserAccessibilityWin::GetHyperlinkIndexFromChild( | 3863 int32_t BrowserAccessibilityWin::GetHyperlinkIndexFromChild( |
3676 const BrowserAccessibilityWin& child) const { | 3864 const BrowserAccessibilityWin& child) const { |
3677 if (hyperlinks().empty()) | 3865 if (hyperlinks().empty()) |
3678 return -1; | 3866 return -1; |
3679 | 3867 |
3680 auto iterator = std::find( | 3868 auto iterator = std::find( |
3681 hyperlinks().begin(), hyperlinks().end(), child.GetId()); | 3869 hyperlinks().begin(), hyperlinks().end(), child.GetId()); |
3682 if (iterator == hyperlinks().end()) | 3870 if (iterator == hyperlinks().end()) |
3683 return -1; | 3871 return -1; |
3684 | 3872 |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3808 return 0; | 3996 return 0; |
3809 if (endpoint_index_in_common_parent > index_in_common_parent) | 3997 if (endpoint_index_in_common_parent > index_in_common_parent) |
3810 return GetText().size(); | 3998 return GetText().size(); |
3811 | 3999 |
3812 NOTREACHED(); | 4000 NOTREACHED(); |
3813 return -1; | 4001 return -1; |
3814 } | 4002 } |
3815 | 4003 |
3816 int BrowserAccessibilityWin::GetSelectionAnchor() const { | 4004 int BrowserAccessibilityWin::GetSelectionAnchor() const { |
3817 int32_t anchor_id = manager()->GetTreeData().sel_anchor_object_id; | 4005 int32_t anchor_id = manager()->GetTreeData().sel_anchor_object_id; |
3818 const auto anchor_object = | 4006 const BrowserAccessibilityWin* anchor_object = GetFromID(anchor_id); |
3819 ToBrowserAccessibilityWin(manager()->GetFromID(anchor_id)); | |
3820 if (!anchor_object) | 4007 if (!anchor_object) |
3821 return -1; | 4008 return -1; |
3822 | 4009 |
3823 int anchor_offset = manager()->GetTreeData().sel_anchor_offset; | 4010 int anchor_offset = manager()->GetTreeData().sel_anchor_offset; |
3824 return GetHypertextOffsetFromEndpoint(*anchor_object, anchor_offset); | 4011 return GetHypertextOffsetFromEndpoint(*anchor_object, anchor_offset); |
3825 } | 4012 } |
3826 | 4013 |
3827 int BrowserAccessibilityWin::GetSelectionFocus() const { | 4014 int BrowserAccessibilityWin::GetSelectionFocus() const { |
3828 int32_t focus_id = manager()->GetTreeData().sel_focus_object_id; | 4015 int32_t focus_id = manager()->GetTreeData().sel_focus_object_id; |
3829 const auto focus_object = | 4016 const BrowserAccessibilityWin* focus_object = GetFromID(focus_id); |
3830 ToBrowserAccessibilityWin(manager()->GetFromID(focus_id)); | |
3831 if (!focus_object) | 4017 if (!focus_object) |
3832 return -1; | 4018 return -1; |
3833 | 4019 |
3834 int focus_offset = manager()->GetTreeData().sel_focus_offset; | 4020 int focus_offset = manager()->GetTreeData().sel_focus_offset; |
3835 return GetHypertextOffsetFromEndpoint(*focus_object, focus_offset); | 4021 return GetHypertextOffsetFromEndpoint(*focus_object, focus_offset); |
3836 } | 4022 } |
3837 | 4023 |
3838 void BrowserAccessibilityWin::GetSelectionOffsets( | 4024 void BrowserAccessibilityWin::GetSelectionOffsets( |
3839 int* selection_start, int* selection_end) const { | 4025 int* selection_start, int* selection_end) const { |
3840 DCHECK(selection_start && selection_end); | 4026 DCHECK(selection_start && selection_end); |
(...skipping 29 matching lines...) Expand all Loading... | |
3870 } | 4056 } |
3871 | 4057 |
3872 // The IA2 Spec says that if the largest of the two offsets falls on an | 4058 // 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 | 4059 // 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 | 4060 // object, it should be incremented by one so that it points after the |
3875 // embedded object character. | 4061 // embedded object character. |
3876 // This is a signal to AT software that the embedded object is also part of | 4062 // This is a signal to AT software that the embedded object is also part of |
3877 // the selection. | 4063 // the selection. |
3878 int* largest_offset = | 4064 int* largest_offset = |
3879 (*selection_start <= *selection_end) ? selection_end : selection_start; | 4065 (*selection_start <= *selection_end) ? selection_end : selection_start; |
3880 auto current_object = const_cast<BrowserAccessibilityWin*>(this); | 4066 BrowserAccessibilityWin* hyperlink = |
3881 LONG hyperlink_index; | 4067 GetHyperlinkFromHypertextOffset(*largest_offset); |
3882 HRESULT hr = | 4068 if (!hyperlink) |
3883 current_object->get_hyperlinkIndex(*largest_offset, &hyperlink_index); | |
3884 if (hr != S_OK) | |
3885 return; | 4069 return; |
3886 | 4070 |
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; | 4071 LONG n_selections = 0; |
3895 hr = hyperlink_text->get_nSelections(&n_selections); | 4072 HRESULT hr = hyperlink->get_nSelections(&n_selections); |
3896 DCHECK(SUCCEEDED(hr)); | 4073 DCHECK(SUCCEEDED(hr)); |
3897 if (n_selections > 0) | 4074 if (n_selections > 0) |
3898 ++(*largest_offset); | 4075 ++(*largest_offset); |
3899 } | 4076 } |
3900 | 4077 |
3901 base::string16 BrowserAccessibilityWin::GetValueText() { | 4078 base::string16 BrowserAccessibilityWin::GetValueText() { |
3902 float fval; | 4079 float fval; |
3903 base::string16 value = this->value(); | 4080 base::string16 value = this->value(); |
3904 | 4081 |
3905 if (value.empty() && | 4082 if (value.empty() && |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3971 old_text.size() - common_suffix - 1, | 4148 old_text.size() - common_suffix - 1, |
3972 new_text.size() - common_suffix - 1)) { | 4149 new_text.size() - common_suffix - 1)) { |
3973 ++common_suffix; | 4150 ++common_suffix; |
3974 } | 4151 } |
3975 | 4152 |
3976 *start = common_prefix; | 4153 *start = common_prefix; |
3977 *old_len = old_text.size() - common_prefix - common_suffix; | 4154 *old_len = old_text.size() - common_prefix - common_suffix; |
3978 *new_len = new_text.size() - common_prefix - common_suffix; | 4155 *new_len = new_text.size() - common_prefix - common_suffix; |
3979 } | 4156 } |
3980 | 4157 |
4158 void BrowserAccessibilityWin::MayBeComputeStyles() { | |
4159 if (!offset_to_text_attributes().empty()) | |
4160 return; | |
4161 | |
4162 base::hash_map<int, std::vector<base::string16>> attributes_map; | |
4163 if (PlatformIsLeaf()) { | |
4164 attributes_map[0] = ComputeTextAttributes(); | |
4165 win_attributes_->offset_to_text_attributes = attributes_map; | |
dmazzoni
2016/03/14 17:38:21
This is a deep copy. Instead you could either make
| |
4166 return; | |
4167 } | |
4168 | |
4169 int start_offset = 0; | |
4170 for (size_t i = 0; i < PlatformChildCount(); ++i) { | |
4171 const auto child = ToBrowserAccessibilityWin(PlatformGetChild(i)); | |
4172 DCHECK(child); | |
4173 std::vector<base::string16> attributes(child->ComputeTextAttributes()); | |
4174 | |
4175 if (attributes_map.empty()) { | |
4176 attributes_map[start_offset] = attributes; | |
4177 } else { | |
4178 // Only add the attributes for this child if we are at the start of a new | |
4179 // style span. | |
4180 std::vector<base::string16> previous_attributes = | |
4181 attributes_map.rbegin()->second; | |
4182 if (!std::equal(attributes.begin(), attributes.end(), | |
4183 previous_attributes.begin())) { | |
4184 attributes_map[start_offset] = attributes; | |
4185 } | |
4186 } | |
4187 | |
4188 if (child->IsTextOnlyObject()) | |
4189 start_offset += child->GetText().length(); | |
4190 else | |
4191 start_offset += 1; | |
4192 } | |
4193 | |
4194 win_attributes_->offset_to_text_attributes = attributes_map; | |
4195 } | |
4196 | |
3981 void BrowserAccessibilityWin::HandleSpecialTextOffset( | 4197 void BrowserAccessibilityWin::HandleSpecialTextOffset( |
3982 const base::string16& text, | 4198 const base::string16& text, |
3983 LONG* offset) { | 4199 LONG* offset) { |
3984 if (*offset == IA2_TEXT_OFFSET_LENGTH) | 4200 if (*offset == IA2_TEXT_OFFSET_LENGTH) |
3985 *offset = static_cast<LONG>(text.size()); | 4201 *offset = static_cast<LONG>(text.size()); |
3986 else if (*offset == IA2_TEXT_OFFSET_CARET) | 4202 else if (*offset == IA2_TEXT_OFFSET_CARET) |
3987 get_caretOffset(offset); | 4203 get_caretOffset(offset); |
3988 } | 4204 } |
3989 | 4205 |
3990 ui::TextBoundaryType BrowserAccessibilityWin::IA2TextBoundaryToTextBoundary( | 4206 ui::TextBoundaryType BrowserAccessibilityWin::IA2TextBoundaryToTextBoundary( |
(...skipping 26 matching lines...) Expand all Loading... | |
4017 if (ia2_boundary == IA2_TEXT_BOUNDARY_WORD) | 4233 if (ia2_boundary == IA2_TEXT_BOUNDARY_WORD) |
4018 return GetWordStartBoundary(static_cast<int>(start_offset), direction); | 4234 return GetWordStartBoundary(static_cast<int>(start_offset), direction); |
4019 | 4235 |
4020 ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary); | 4236 ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary); |
4021 const std::vector<int32_t>& line_breaks = | 4237 const std::vector<int32_t>& line_breaks = |
4022 GetIntListAttribute(ui::AX_ATTR_LINE_BREAKS); | 4238 GetIntListAttribute(ui::AX_ATTR_LINE_BREAKS); |
4023 return ui::FindAccessibleTextBoundary( | 4239 return ui::FindAccessibleTextBoundary( |
4024 text, line_breaks, boundary, start_offset, direction); | 4240 text, line_breaks, boundary, start_offset, direction); |
4025 } | 4241 } |
4026 | 4242 |
4027 BrowserAccessibilityWin* BrowserAccessibilityWin::GetFromID(int32_t id) { | 4243 LONG BrowserAccessibilityWin::FindStartOfStyle( |
4244 LONG start_offset, | |
4245 ui::TextBoundaryDirection direction) const { | |
4246 LONG text_length = static_cast<LONG>(GetText().length()); | |
4247 DCHECK_GE(start_offset, 0); | |
4248 DCHECK_LE(start_offset, text_length); | |
4249 | |
4250 switch (direction) { | |
4251 case ui::BACKWARDS_DIRECTION: { | |
4252 if (offset_to_text_attributes().empty()) | |
4253 return 0; | |
4254 | |
4255 auto iterator = offset_to_text_attributes().upper_bound(start_offset); | |
4256 --iterator; | |
4257 return static_cast<LONG>(iterator->first); | |
4258 } | |
4259 case ui::FORWARDS_DIRECTION: { | |
4260 const auto iterator = | |
4261 offset_to_text_attributes().upper_bound(start_offset); | |
dmazzoni
2016/03/14 17:38:20
Just checking, is it correct that both BACKWARDS a
| |
4262 if (iterator == offset_to_text_attributes().end()) | |
4263 return text_length; | |
4264 return static_cast<LONG>(iterator->first); | |
4265 } | |
4266 default: | |
4267 NOTREACHED(); | |
4268 } | |
4269 | |
4270 return start_offset; | |
4271 } | |
4272 | |
4273 BrowserAccessibilityWin* BrowserAccessibilityWin::GetFromID(int32_t id) const { | |
4274 if (!instance_active()) | |
4275 return nullptr; | |
4028 return ToBrowserAccessibilityWin(manager()->GetFromID(id)); | 4276 return ToBrowserAccessibilityWin(manager()->GetFromID(id)); |
4029 } | 4277 } |
4030 | 4278 |
4031 bool BrowserAccessibilityWin::IsListBoxOptionOrMenuListOption() { | 4279 bool BrowserAccessibilityWin::IsListBoxOptionOrMenuListOption() { |
4032 if (!GetParent()) | 4280 if (!GetParent()) |
4033 return false; | 4281 return false; |
4034 | 4282 |
4035 int32_t role = GetRole(); | 4283 int32_t role = GetRole(); |
4036 int32_t parent_role = GetParent()->GetRole(); | 4284 int32_t parent_role = GetParent()->GetRole(); |
4037 | 4285 |
4038 if (role == ui::AX_ROLE_LIST_BOX_OPTION && | 4286 if (role == ui::AX_ROLE_LIST_BOX_OPTION && |
4039 parent_role == ui::AX_ROLE_LIST_BOX) { | 4287 parent_role == ui::AX_ROLE_LIST_BOX) { |
4040 return true; | 4288 return true; |
4041 } | 4289 } |
4042 | 4290 |
4043 if (role == ui::AX_ROLE_MENU_LIST_OPTION && | 4291 if (role == ui::AX_ROLE_MENU_LIST_OPTION && |
4044 parent_role == ui::AX_ROLE_MENU_LIST_POPUP) { | 4292 parent_role == ui::AX_ROLE_MENU_LIST_POPUP) { |
4045 return true; | 4293 return true; |
4046 } | 4294 } |
4047 | 4295 |
4048 return false; | 4296 return false; |
4049 } | 4297 } |
4050 | 4298 |
4299 void BrowserAccessibilityWin::AddRelations( | |
4300 ui::AXIntListAttribute src_attr, | |
4301 const base::string16& iaccessiblerelation_type) { | |
4302 if (!HasIntListAttribute(src_attr)) | |
4303 return; | |
4304 | |
4305 const std::vector<int32_t>& ids = GetIntListAttribute(src_attr); | |
4306 for (size_t i = 0; i < ids.size(); ++i) { | |
4307 CComObject<BrowserAccessibilityRelation>* relation; | |
4308 HRESULT hr = | |
4309 CComObject<BrowserAccessibilityRelation>::CreateInstance(&relation); | |
4310 DCHECK(SUCCEEDED(hr)); | |
4311 relation->AddRef(); | |
4312 relation->Initialize(this, iaccessiblerelation_type); | |
4313 relation->AddTarget(ids[i]); | |
4314 relations_.push_back(relation); | |
4315 } | |
4316 } | |
4317 | |
4051 void BrowserAccessibilityWin::UpdateRequiredAttributes() { | 4318 void BrowserAccessibilityWin::UpdateRequiredAttributes() { |
4052 // Expose slider value. | 4319 // Expose slider value. |
4053 if (ia_role() == ROLE_SYSTEM_PROGRESSBAR || | 4320 if (ia_role() == ROLE_SYSTEM_PROGRESSBAR || |
4054 ia_role() == ROLE_SYSTEM_SCROLLBAR || | 4321 ia_role() == ROLE_SYSTEM_SCROLLBAR || |
4055 ia_role() == ROLE_SYSTEM_SLIDER) { | 4322 ia_role() == ROLE_SYSTEM_SLIDER) { |
4056 base::string16 value_text = GetValueText(); | 4323 base::string16 value_text = GetValueText(); |
4057 SanitizeStringAttributeForIA2(value_text, &value_text); | 4324 SanitizeStringAttributeForIA2(value_text, &value_text); |
4058 win_attributes_->ia2_attributes.push_back(L"valuetext:" + value_text); | 4325 win_attributes_->ia2_attributes.push_back(L"valuetext:" + value_text); |
4059 } | 4326 } |
4060 | 4327 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4104 // Expose input-text type attribute. | 4371 // Expose input-text type attribute. |
4105 base::string16 type; | 4372 base::string16 type; |
4106 base::string16 html_tag = GetString16Attribute(ui::AX_ATTR_HTML_TAG); | 4373 base::string16 html_tag = GetString16Attribute(ui::AX_ATTR_HTML_TAG); |
4107 if (IsSimpleTextControl() && html_tag == L"input" && | 4374 if (IsSimpleTextControl() && html_tag == L"input" && |
4108 GetHtmlAttribute("type", &type)) { | 4375 GetHtmlAttribute("type", &type)) { |
4109 SanitizeStringAttributeForIA2(type, &type); | 4376 SanitizeStringAttributeForIA2(type, &type); |
4110 win_attributes_->ia2_attributes.push_back(L"text-input-type:" + type); | 4377 win_attributes_->ia2_attributes.push_back(L"text-input-type:" + type); |
4111 } | 4378 } |
4112 } | 4379 } |
4113 | 4380 |
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() { | 4381 void BrowserAccessibilityWin::InitRoleAndState() { |
4134 int32_t ia_role = 0; | 4382 int32_t ia_role = 0; |
4135 int32_t ia_state = 0; | 4383 int32_t ia_state = 0; |
4136 base::string16 role_name; | 4384 base::string16 role_name; |
4137 int32_t ia2_role = 0; | 4385 int32_t ia2_role = 0; |
4138 int32_t ia2_state = IA2_STATE_OPAQUE; | 4386 int32_t ia2_state = IA2_STATE_OPAQUE; |
4139 | 4387 |
4140 if (HasState(ui::AX_STATE_BUSY)) | 4388 if (HasState(ui::AX_STATE_BUSY)) |
4141 ia_state |= STATE_SYSTEM_BUSY; | 4389 ia_state |= STATE_SYSTEM_BUSY; |
4142 if (HasState(ui::AX_STATE_CHECKED)) | 4390 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); | 4933 return static_cast<BrowserAccessibilityWin*>(obj); |
4686 } | 4934 } |
4687 | 4935 |
4688 const BrowserAccessibilityWin* | 4936 const BrowserAccessibilityWin* |
4689 ToBrowserAccessibilityWin(const BrowserAccessibility* obj) { | 4937 ToBrowserAccessibilityWin(const BrowserAccessibility* obj) { |
4690 DCHECK(!obj || obj->IsNative()); | 4938 DCHECK(!obj || obj->IsNative()); |
4691 return static_cast<const BrowserAccessibilityWin*>(obj); | 4939 return static_cast<const BrowserAccessibilityWin*>(obj); |
4692 } | 4940 } |
4693 | 4941 |
4694 } // namespace content | 4942 } // namespace content |
OLD | NEW |