| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "webkit/glue/webaccessibility.h" | 5 #include "webkit/glue/webaccessibility.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| 11 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
| 12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityCache
.h" | |
| 13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityObjec
t.h" | 12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityObjec
t.h" |
| 14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityRole.
h" | 13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityRole.
h" |
| 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAttribute.h" | 14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAttribute.h" |
| 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" | 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" |
| 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocumentType.h" | 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocumentType.h" |
| 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" | 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" |
| 19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormControlElement
.h" | 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormControlElement
.h" |
| 20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
| 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h" | 20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h" |
| 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNamedNodeMap.h" | 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNamedNodeMap.h" |
| 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h" | 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h" |
| 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h" | 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h" |
| 25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h" | 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h" |
| 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" | 25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" |
| 27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h" | 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h" |
| 28 | 27 |
| 29 #ifndef NDEBUG | 28 #ifndef NDEBUG |
| 30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityNotif
ication.h" | 29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityNotif
ication.h" |
| 31 #endif | 30 #endif |
| 32 | 31 |
| 33 using base::DoubleToString; | 32 using base::DoubleToString; |
| 34 using base::IntToString; | 33 using base::IntToString; |
| 35 using WebKit::WebAccessibilityCache; | |
| 36 using WebKit::WebAccessibilityRole; | 34 using WebKit::WebAccessibilityRole; |
| 37 using WebKit::WebAccessibilityObject; | 35 using WebKit::WebAccessibilityObject; |
| 38 | 36 |
| 39 #ifndef NDEBUG | 37 #ifndef NDEBUG |
| 40 using WebKit::WebAccessibilityNotification; | 38 using WebKit::WebAccessibilityNotification; |
| 41 #endif | 39 #endif |
| 42 | 40 |
| 43 namespace { | 41 namespace { |
| 44 | 42 |
| 45 std::string IntVectorToString(const std::vector<int>& items) { | 43 std::string IntVectorToString(const std::vector<int>& items) { |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 state |= (1 << WebAccessibility::STATE_VERTICAL); | 320 state |= (1 << WebAccessibility::STATE_VERTICAL); |
| 323 | 321 |
| 324 if (o.isVisited()) | 322 if (o.isVisited()) |
| 325 state |= (1 << WebAccessibility::STATE_VISITED); | 323 state |= (1 << WebAccessibility::STATE_VISITED); |
| 326 | 324 |
| 327 return state; | 325 return state; |
| 328 } | 326 } |
| 329 | 327 |
| 330 WebAccessibility::WebAccessibility() | 328 WebAccessibility::WebAccessibility() |
| 331 : id(-1), | 329 : id(-1), |
| 332 role(ROLE_NONE), | 330 role(ROLE_UNKNOWN), |
| 333 state(-1) { | 331 state(-1) { |
| 334 } | 332 } |
| 335 | 333 |
| 336 WebAccessibility::WebAccessibility(const WebKit::WebAccessibilityObject& src, | 334 WebAccessibility::WebAccessibility(const WebKit::WebAccessibilityObject& src, |
| 337 WebKit::WebAccessibilityCache* cache, | |
| 338 bool include_children) { | 335 bool include_children) { |
| 339 Init(src, cache, include_children); | 336 Init(src, include_children); |
| 340 } | 337 } |
| 341 | 338 |
| 342 WebAccessibility::~WebAccessibility() { | 339 WebAccessibility::~WebAccessibility() { |
| 343 } | 340 } |
| 344 | 341 |
| 345 #ifndef NDEBUG | 342 #ifndef NDEBUG |
| 346 std::string WebAccessibility::DebugString(bool recursive, | 343 std::string WebAccessibility::DebugString(bool recursive, |
| 347 int render_routing_id, | 344 int render_routing_id, |
| 348 int notification) { | 345 int notification) { |
| 349 std::string result; | 346 std::string result; |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 case ROLE_MENU_ITEM: result += " MENU_ITEM"; break; | 469 case ROLE_MENU_ITEM: result += " MENU_ITEM"; break; |
| 473 case ROLE_MENU_LIST_OPTION: result += " MENU_LIST_OPTION"; break; | 470 case ROLE_MENU_LIST_OPTION: result += " MENU_LIST_OPTION"; break; |
| 474 case ROLE_MENU_LIST_POPUP: result += " MENU_LIST_POPUP"; break; | 471 case ROLE_MENU_LIST_POPUP: result += " MENU_LIST_POPUP"; break; |
| 475 case ROLE_NOTE: result += " NOTE"; break; | 472 case ROLE_NOTE: result += " NOTE"; break; |
| 476 case ROLE_OUTLINE: result += " OUTLINE"; break; | 473 case ROLE_OUTLINE: result += " OUTLINE"; break; |
| 477 case ROLE_POPUP_BUTTON: result += " POPUP_BUTTON"; break; | 474 case ROLE_POPUP_BUTTON: result += " POPUP_BUTTON"; break; |
| 478 case ROLE_PROGRESS_INDICATOR: result += " PROGRESS_INDICATOR"; break; | 475 case ROLE_PROGRESS_INDICATOR: result += " PROGRESS_INDICATOR"; break; |
| 479 case ROLE_RADIO_BUTTON: result += " RADIO_BUTTON"; break; | 476 case ROLE_RADIO_BUTTON: result += " RADIO_BUTTON"; break; |
| 480 case ROLE_RADIO_GROUP: result += " RADIO_GROUP"; break; | 477 case ROLE_RADIO_GROUP: result += " RADIO_GROUP"; break; |
| 481 case ROLE_REGION: result += " REGION"; break; | 478 case ROLE_REGION: result += " REGION"; break; |
| 479 case ROLE_ROOT_WEB_AREA: result += " ROOT_WEB_AREA"; break; |
| 482 case ROLE_ROW: result += " ROW"; break; | 480 case ROLE_ROW: result += " ROW"; break; |
| 483 case ROLE_ROW_HEADER: result += " ROW_HEADER"; break; | 481 case ROLE_ROW_HEADER: result += " ROW_HEADER"; break; |
| 484 case ROLE_RULER: result += " RULER"; break; | 482 case ROLE_RULER: result += " RULER"; break; |
| 485 case ROLE_RULER_MARKER: result += " RULER_MARKER"; break; | 483 case ROLE_RULER_MARKER: result += " RULER_MARKER"; break; |
| 486 case ROLE_SCROLLAREA: result += " SCROLLAREA"; break; | 484 case ROLE_SCROLLAREA: result += " SCROLLAREA"; break; |
| 487 case ROLE_SCROLLBAR: result += " SCROLLBAR"; break; | 485 case ROLE_SCROLLBAR: result += " SCROLLBAR"; break; |
| 488 case ROLE_SHEET: result += " SHEET"; break; | 486 case ROLE_SHEET: result += " SHEET"; break; |
| 489 case ROLE_SLIDER: result += " SLIDER"; break; | 487 case ROLE_SLIDER: result += " SLIDER"; break; |
| 490 case ROLE_SLIDER_THUMB: result += " SLIDER_THUMB"; break; | 488 case ROLE_SLIDER_THUMB: result += " SLIDER_THUMB"; break; |
| 491 case ROLE_SPLITTER: result += " SPLITTER"; break; | 489 case ROLE_SPLITTER: result += " SPLITTER"; break; |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 749 for (size_t i = 0; i < children.size(); ++i) | 747 for (size_t i = 0; i < children.size(); ++i) |
| 750 result += children[i].DebugString(true, 0, 0); | 748 result += children[i].DebugString(true, 0, 0); |
| 751 --indent; | 749 --indent; |
| 752 } | 750 } |
| 753 | 751 |
| 754 return result; | 752 return result; |
| 755 } | 753 } |
| 756 #endif // ifndef NDEBUG | 754 #endif // ifndef NDEBUG |
| 757 | 755 |
| 758 void WebAccessibility::Init(const WebKit::WebAccessibilityObject& src, | 756 void WebAccessibility::Init(const WebKit::WebAccessibilityObject& src, |
| 759 WebKit::WebAccessibilityCache* cache, | |
| 760 bool include_children) { | 757 bool include_children) { |
| 761 name = src.title(); | 758 name = src.title(); |
| 762 role = ConvertRole(src.roleValue()); | 759 role = ConvertRole(src.roleValue()); |
| 763 state = ConvertState(src); | 760 state = ConvertState(src); |
| 764 location = src.boundingBoxRect(); | 761 location = src.boundingBoxRect(); |
| 762 id = src.axID(); |
| 765 | 763 |
| 766 if (src.valueDescription().length()) | 764 if (src.valueDescription().length()) |
| 767 value = src.valueDescription(); | 765 value = src.valueDescription(); |
| 768 else | 766 else |
| 769 value = src.stringValue(); | 767 value = src.stringValue(); |
| 770 | 768 |
| 771 if (src.accessKey().length()) | 769 if (src.accessKey().length()) |
| 772 string_attributes[ATTR_ACCESS_KEY] = src.accessKey(); | 770 string_attributes[ATTR_ACCESS_KEY] = src.accessKey(); |
| 773 if (src.actionVerb().length()) | 771 if (src.actionVerb().length()) |
| 774 string_attributes[ATTR_ACTION] = src.actionVerb(); | 772 string_attributes[ATTR_ACTION] = src.actionVerb(); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 928 int row_count = src.rowCount(); | 926 int row_count = src.rowCount(); |
| 929 if (column_count > 0 && row_count > 0) { | 927 if (column_count > 0 && row_count > 0) { |
| 930 std::set<int> unique_cell_id_set; | 928 std::set<int> unique_cell_id_set; |
| 931 int_attributes[ATTR_TABLE_COLUMN_COUNT] = column_count; | 929 int_attributes[ATTR_TABLE_COLUMN_COUNT] = column_count; |
| 932 int_attributes[ATTR_TABLE_ROW_COUNT] = row_count; | 930 int_attributes[ATTR_TABLE_ROW_COUNT] = row_count; |
| 933 for (int i = 0; i < column_count * row_count; ++i) { | 931 for (int i = 0; i < column_count * row_count; ++i) { |
| 934 WebAccessibilityObject cell = src.cellForColumnAndRow( | 932 WebAccessibilityObject cell = src.cellForColumnAndRow( |
| 935 i % column_count, i / column_count); | 933 i % column_count, i / column_count); |
| 936 int cell_id = -1; | 934 int cell_id = -1; |
| 937 if (!cell.isNull()) { | 935 if (!cell.isNull()) { |
| 938 cell_id = cache->addOrGetId(cell); | 936 cell_id = cell.axID(); |
| 939 if (unique_cell_id_set.find(cell_id) == unique_cell_id_set.end()) { | 937 if (unique_cell_id_set.find(cell_id) == unique_cell_id_set.end()) { |
| 940 unique_cell_id_set.insert(cell_id); | 938 unique_cell_id_set.insert(cell_id); |
| 941 unique_cell_ids.push_back(cell_id); | 939 unique_cell_ids.push_back(cell_id); |
| 942 } | 940 } |
| 943 } | 941 } |
| 944 cell_ids.push_back(cell_id); | 942 cell_ids.push_back(cell_id); |
| 945 } | 943 } |
| 946 } | 944 } |
| 947 } | 945 } |
| 948 | 946 |
| 949 if (role == WebAccessibility::ROLE_CELL || | 947 if (role == WebAccessibility::ROLE_CELL || |
| 950 role == WebAccessibility::ROLE_ROW_HEADER || | 948 role == WebAccessibility::ROLE_ROW_HEADER || |
| 951 role == WebAccessibility::ROLE_COLUMN_HEADER) { | 949 role == WebAccessibility::ROLE_COLUMN_HEADER) { |
| 952 int_attributes[ATTR_TABLE_CELL_COLUMN_INDEX] = src.cellColumnIndex(); | 950 int_attributes[ATTR_TABLE_CELL_COLUMN_INDEX] = src.cellColumnIndex(); |
| 953 int_attributes[ATTR_TABLE_CELL_COLUMN_SPAN] = src.cellColumnSpan(); | 951 int_attributes[ATTR_TABLE_CELL_COLUMN_SPAN] = src.cellColumnSpan(); |
| 954 int_attributes[ATTR_TABLE_CELL_ROW_INDEX] = src.cellRowIndex(); | 952 int_attributes[ATTR_TABLE_CELL_ROW_INDEX] = src.cellRowIndex(); |
| 955 int_attributes[ATTR_TABLE_CELL_ROW_SPAN] = src.cellRowSpan(); | 953 int_attributes[ATTR_TABLE_CELL_ROW_SPAN] = src.cellRowSpan(); |
| 956 } | 954 } |
| 957 | 955 |
| 958 // Add the source object to the cache and store its id. | |
| 959 id = cache->addOrGetId(src); | |
| 960 | |
| 961 if (include_children) { | 956 if (include_children) { |
| 962 // Recursively create children. | 957 // Recursively create children. |
| 963 int child_count = src.childCount(); | 958 int child_count = src.childCount(); |
| 964 std::set<int32> child_ids; | 959 std::set<int32> child_ids; |
| 965 for (int i = 0; i < child_count; ++i) { | 960 for (int i = 0; i < child_count; ++i) { |
| 966 WebAccessibilityObject child = src.childAt(i); | 961 WebAccessibilityObject child = src.childAt(i); |
| 967 int32 child_id = cache->addOrGetId(child); | 962 int32 child_id = child.axID(); |
| 968 | 963 |
| 969 // The child may be invalid due to issues in webkit accessibility code. | 964 // The child may be invalid due to issues in webkit accessibility code. |
| 970 // Don't add children that are invalid thus preventing a crash. | 965 // Don't add children that are invalid thus preventing a crash. |
| 971 // https://bugs.webkit.org/show_bug.cgi?id=44149 | 966 // https://bugs.webkit.org/show_bug.cgi?id=44149 |
| 972 // TODO(ctguil): We may want to remove this check as webkit stabilizes. | 967 // TODO(ctguil): We may want to remove this check as webkit stabilizes. |
| 973 if (!child.isValid()) | 968 if (!child.isValid()) |
| 974 continue; | 969 continue; |
| 975 | 970 |
| 976 // Children may duplicated in the webkit accessibility tree. Only add a | 971 // Children may duplicated in the webkit accessibility tree. Only add a |
| 977 // child once for the web accessibility tree. | 972 // child once for the web accessibility tree. |
| 978 // https://bugs.webkit.org/show_bug.cgi?id=58930 | 973 // https://bugs.webkit.org/show_bug.cgi?id=58930 |
| 979 if (child_ids.find(child_id) != child_ids.end()) | 974 if (child_ids.find(child_id) != child_ids.end()) |
| 980 continue; | 975 continue; |
| 981 child_ids.insert(child_id); | 976 child_ids.insert(child_id); |
| 982 | 977 |
| 983 // Some nodes appear in the tree in more than one place: for example, | 978 // Some nodes appear in the tree in more than one place: for example, |
| 984 // a cell in a table appears as a child of both a row and a column. | 979 // a cell in a table appears as a child of both a row and a column. |
| 985 // Only recursively add child nodes that have this node as its | 980 // Only recursively add child nodes that have this node as its |
| 986 // unignored parent. For child nodes that are actually parented to | 981 // unignored parent. For child nodes that are actually parented to |
| 987 // somethinng else, store only the ID. | 982 // somethinng else, store only the ID. |
| 988 // | 983 // |
| 989 // As an exception, also add children of an iframe element. | 984 // As an exception, also add children of an iframe element. |
| 990 // https://bugs.webkit.org/show_bug.cgi?id=57066 | 985 // https://bugs.webkit.org/show_bug.cgi?id=57066 |
| 991 if (is_iframe || IsParentUnignoredOf(src, child)) { | 986 if (is_iframe || IsParentUnignoredOf(src, child)) { |
| 992 children.push_back(WebAccessibility(child, cache, include_children)); | 987 children.push_back(WebAccessibility(child, include_children)); |
| 993 } else { | 988 } else { |
| 994 indirect_child_ids.push_back(child_id); | 989 indirect_child_ids.push_back(child_id); |
| 995 } | 990 } |
| 996 } | 991 } |
| 997 } | 992 } |
| 998 } | 993 } |
| 999 | 994 |
| 1000 bool WebAccessibility::IsParentUnignoredOf( | 995 bool WebAccessibility::IsParentUnignoredOf( |
| 1001 const WebKit::WebAccessibilityObject& ancestor, | 996 const WebKit::WebAccessibilityObject& ancestor, |
| 1002 const WebKit::WebAccessibilityObject& child) { | 997 const WebKit::WebAccessibilityObject& child) { |
| 1003 WebKit::WebAccessibilityObject parent = child.parentObject(); | 998 WebKit::WebAccessibilityObject parent = child.parentObject(); |
| 1004 while (!parent.isNull() && parent.accessibilityIsIgnored()) | 999 while (!parent.isNull() && parent.accessibilityIsIgnored()) |
| 1005 parent = parent.parentObject(); | 1000 parent = parent.parentObject(); |
| 1006 return parent.equals(ancestor); | 1001 return parent.equals(ancestor); |
| 1007 } | 1002 } |
| 1008 | 1003 |
| 1009 } // namespace webkit_glue | 1004 } // namespace webkit_glue |
| OLD | NEW |