Chromium Code Reviews| 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 |