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/renderer/accessibility/accessibility_node_serializer.h" | 5 #include "content/renderer/accessibility/accessibility_node_serializer.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
12 #include "third_party/WebKit/public/platform/WebRect.h" | 12 #include "third_party/WebKit/public/platform/WebRect.h" |
13 #include "third_party/WebKit/public/platform/WebSize.h" | 13 #include "third_party/WebKit/public/platform/WebSize.h" |
14 #include "third_party/WebKit/public/platform/WebString.h" | 14 #include "third_party/WebKit/public/platform/WebString.h" |
15 #include "third_party/WebKit/public/platform/WebVector.h" | 15 #include "third_party/WebKit/public/platform/WebVector.h" |
16 #include "third_party/WebKit/public/web/WebAXEnums.h" | 16 #include "third_party/WebKit/public/web/WebAXEnums.h" |
17 #include "third_party/WebKit/public/web/WebAXObject.h" | 17 #include "third_party/WebKit/public/web/WebAXObject.h" |
18 #include "third_party/WebKit/public/web/WebDocument.h" | 18 #include "third_party/WebKit/public/web/WebDocument.h" |
19 #include "third_party/WebKit/public/web/WebDocumentType.h" | 19 #include "third_party/WebKit/public/web/WebDocumentType.h" |
20 #include "third_party/WebKit/public/web/WebElement.h" | 20 #include "third_party/WebKit/public/web/WebElement.h" |
21 #include "third_party/WebKit/public/web/WebFormControlElement.h" | 21 #include "third_party/WebKit/public/web/WebFormControlElement.h" |
22 #include "third_party/WebKit/public/web/WebFrame.h" | 22 #include "third_party/WebKit/public/web/WebFrame.h" |
23 #include "third_party/WebKit/public/web/WebInputElement.h" | 23 #include "third_party/WebKit/public/web/WebInputElement.h" |
24 #include "third_party/WebKit/public/web/WebNode.h" | 24 #include "third_party/WebKit/public/web/WebNode.h" |
25 | 25 |
26 using WebKit::WebAXObject; | 26 using blink::WebAXObject; |
27 using WebKit::WebDocument; | 27 using blink::WebDocument; |
28 using WebKit::WebDocumentType; | 28 using blink::WebDocumentType; |
29 using WebKit::WebElement; | 29 using blink::WebElement; |
30 using WebKit::WebNode; | 30 using blink::WebNode; |
31 using WebKit::WebVector; | 31 using blink::WebVector; |
32 | 32 |
33 namespace content { | 33 namespace content { |
34 namespace { | 34 namespace { |
35 | 35 |
36 // Returns true if |ancestor| is the first unignored parent of |child|, | 36 // Returns true if |ancestor| is the first unignored parent of |child|, |
37 // which means that when walking up the parent chain from |child|, | 37 // which means that when walking up the parent chain from |child|, |
38 // |ancestor| is the *first* ancestor that isn't marked as | 38 // |ancestor| is the *first* ancestor that isn't marked as |
39 // accessibilityIsIgnored(). | 39 // accessibilityIsIgnored(). |
40 bool IsParentUnignoredOf(const WebAXObject& ancestor, | 40 bool IsParentUnignoredOf(const WebAXObject& ancestor, |
41 const WebAXObject& child) { | 41 const WebAXObject& child) { |
42 WebAXObject parent = child.parentObject(); | 42 WebAXObject parent = child.parentObject(); |
43 while (!parent.isDetached() && parent.accessibilityIsIgnored()) | 43 while (!parent.isDetached() && parent.accessibilityIsIgnored()) |
44 parent = parent.parentObject(); | 44 parent = parent.parentObject(); |
45 return parent.equals(ancestor); | 45 return parent.equals(ancestor); |
46 } | 46 } |
47 | 47 |
48 bool IsTrue(std::string html_value) { | 48 bool IsTrue(std::string html_value) { |
49 return LowerCaseEqualsASCII(html_value, "true"); | 49 return LowerCaseEqualsASCII(html_value, "true"); |
50 } | 50 } |
51 | 51 |
52 // Provides a conversion between the WebAXObject state | 52 // Provides a conversion between the WebAXObject state |
53 // accessors and a state bitmask that can be serialized and sent to the | 53 // accessors and a state bitmask that can be serialized and sent to the |
54 // Browser process. Rare state are sent as boolean attributes instead. | 54 // Browser process. Rare state are sent as boolean attributes instead. |
55 uint32 ConvertState(const WebAXObject& o) { | 55 uint32 ConvertState(const WebAXObject& o) { |
56 uint32 state = 0; | 56 uint32 state = 0; |
57 if (o.isChecked()) | 57 if (o.isChecked()) |
58 state |= (1 << WebKit::WebAXStateChecked); | 58 state |= (1 << blink::WebAXStateChecked); |
59 | 59 |
60 if (o.isCollapsed()) | 60 if (o.isCollapsed()) |
61 state |= (1 << WebKit::WebAXStateCollapsed); | 61 state |= (1 << blink::WebAXStateCollapsed); |
62 | 62 |
63 if (o.canSetFocusAttribute()) | 63 if (o.canSetFocusAttribute()) |
64 state |= (1 << WebKit::WebAXStateFocusable); | 64 state |= (1 << blink::WebAXStateFocusable); |
65 | 65 |
66 if (o.isFocused()) | 66 if (o.isFocused()) |
67 state |= (1 << WebKit::WebAXStateFocused); | 67 state |= (1 << blink::WebAXStateFocused); |
68 | 68 |
69 if (o.role() == WebKit::WebAXRolePopUpButton || | 69 if (o.role() == blink::WebAXRolePopUpButton || |
70 o.ariaHasPopup()) { | 70 o.ariaHasPopup()) { |
71 state |= (1 << WebKit::WebAXStateHaspopup); | 71 state |= (1 << blink::WebAXStateHaspopup); |
72 if (!o.isCollapsed()) | 72 if (!o.isCollapsed()) |
73 state |= (1 << WebKit::WebAXStateExpanded); | 73 state |= (1 << blink::WebAXStateExpanded); |
74 } | 74 } |
75 | 75 |
76 if (o.isHovered()) | 76 if (o.isHovered()) |
77 state |= (1 << WebKit::WebAXStateHovered); | 77 state |= (1 << blink::WebAXStateHovered); |
78 | 78 |
79 if (o.isIndeterminate()) | 79 if (o.isIndeterminate()) |
80 state |= (1 << WebKit::WebAXStateIndeterminate); | 80 state |= (1 << blink::WebAXStateIndeterminate); |
81 | 81 |
82 if (!o.isVisible()) | 82 if (!o.isVisible()) |
83 state |= (1 << WebKit::WebAXStateInvisible); | 83 state |= (1 << blink::WebAXStateInvisible); |
84 | 84 |
85 if (o.isLinked()) | 85 if (o.isLinked()) |
86 state |= (1 << WebKit::WebAXStateLinked); | 86 state |= (1 << blink::WebAXStateLinked); |
87 | 87 |
88 if (o.isMultiSelectable()) | 88 if (o.isMultiSelectable()) |
89 state |= (1 << WebKit::WebAXStateMultiselectable); | 89 state |= (1 << blink::WebAXStateMultiselectable); |
90 | 90 |
91 if (o.isOffScreen()) | 91 if (o.isOffScreen()) |
92 state |= (1 << WebKit::WebAXStateOffscreen); | 92 state |= (1 << blink::WebAXStateOffscreen); |
93 | 93 |
94 if (o.isPressed()) | 94 if (o.isPressed()) |
95 state |= (1 << WebKit::WebAXStatePressed); | 95 state |= (1 << blink::WebAXStatePressed); |
96 | 96 |
97 if (o.isPasswordField()) | 97 if (o.isPasswordField()) |
98 state |= (1 << WebKit::WebAXStateProtected); | 98 state |= (1 << blink::WebAXStateProtected); |
99 | 99 |
100 if (o.isReadOnly()) | 100 if (o.isReadOnly()) |
101 state |= (1 << WebKit::WebAXStateReadonly); | 101 state |= (1 << blink::WebAXStateReadonly); |
102 | 102 |
103 if (o.isRequired()) | 103 if (o.isRequired()) |
104 state |= (1 << WebKit::WebAXStateRequired); | 104 state |= (1 << blink::WebAXStateRequired); |
105 | 105 |
106 if (o.canSetSelectedAttribute()) | 106 if (o.canSetSelectedAttribute()) |
107 state |= (1 << WebKit::WebAXStateSelectable); | 107 state |= (1 << blink::WebAXStateSelectable); |
108 | 108 |
109 if (o.isSelected()) | 109 if (o.isSelected()) |
110 state |= (1 << WebKit::WebAXStateSelected); | 110 state |= (1 << blink::WebAXStateSelected); |
111 | 111 |
112 if (o.isVisited()) | 112 if (o.isVisited()) |
113 state |= (1 << WebKit::WebAXStateVisited); | 113 state |= (1 << blink::WebAXStateVisited); |
114 | 114 |
115 if (o.isEnabled()) | 115 if (o.isEnabled()) |
116 state |= (1 << WebKit::WebAXStateEnabled); | 116 state |= (1 << blink::WebAXStateEnabled); |
117 | 117 |
118 if (o.isVertical()) | 118 if (o.isVertical()) |
119 state |= (1 << WebKit::WebAXStateVertical); | 119 state |= (1 << blink::WebAXStateVertical); |
120 | 120 |
121 if (o.isVisited()) | 121 if (o.isVisited()) |
122 state |= (1 << WebKit::WebAXStateVisited); | 122 state |= (1 << blink::WebAXStateVisited); |
123 | 123 |
124 return state; | 124 return state; |
125 } | 125 } |
126 | 126 |
127 } // Anonymous namespace | 127 } // Anonymous namespace |
128 | 128 |
129 void SerializeAccessibilityNode( | 129 void SerializeAccessibilityNode( |
130 const WebAXObject& src, | 130 const WebAXObject& src, |
131 AccessibilityNodeData* dst) { | 131 AccessibilityNodeData* dst) { |
132 dst->role = src.role(); | 132 dst->role = src.role(); |
133 dst->state = ConvertState(src); | 133 dst->state = ConvertState(src); |
134 dst->location = src.boundingBoxRect(); | 134 dst->location = src.boundingBoxRect(); |
135 dst->id = src.axID(); | 135 dst->id = src.axID(); |
136 std::string name = UTF16ToUTF8(src.title()); | 136 std::string name = UTF16ToUTF8(src.title()); |
137 | 137 |
138 std::string value; | 138 std::string value; |
139 if (src.valueDescription().length()) { | 139 if (src.valueDescription().length()) { |
140 dst->AddStringAttribute(dst->ATTR_VALUE, | 140 dst->AddStringAttribute(dst->ATTR_VALUE, |
141 UTF16ToUTF8(src.valueDescription())); | 141 UTF16ToUTF8(src.valueDescription())); |
142 } else { | 142 } else { |
143 dst->AddStringAttribute(dst->ATTR_VALUE, UTF16ToUTF8(src.stringValue())); | 143 dst->AddStringAttribute(dst->ATTR_VALUE, UTF16ToUTF8(src.stringValue())); |
144 } | 144 } |
145 | 145 |
146 if (dst->role == WebKit::WebAXRoleColorWell) { | 146 if (dst->role == blink::WebAXRoleColorWell) { |
147 int r, g, b; | 147 int r, g, b; |
148 src.colorValue(r, g, b); | 148 src.colorValue(r, g, b); |
149 dst->AddIntAttribute(dst->ATTR_COLOR_VALUE_RED, r); | 149 dst->AddIntAttribute(dst->ATTR_COLOR_VALUE_RED, r); |
150 dst->AddIntAttribute(dst->ATTR_COLOR_VALUE_GREEN, g); | 150 dst->AddIntAttribute(dst->ATTR_COLOR_VALUE_GREEN, g); |
151 dst->AddIntAttribute(dst->ATTR_COLOR_VALUE_BLUE, b); | 151 dst->AddIntAttribute(dst->ATTR_COLOR_VALUE_BLUE, b); |
152 } | 152 } |
153 | 153 |
154 if (dst->role == WebKit::WebAXRoleInlineTextBox) { | 154 if (dst->role == blink::WebAXRoleInlineTextBox) { |
155 dst->AddIntAttribute(dst->ATTR_TEXT_DIRECTION, src.textDirection()); | 155 dst->AddIntAttribute(dst->ATTR_TEXT_DIRECTION, src.textDirection()); |
156 | 156 |
157 WebVector<int> src_character_offsets; | 157 WebVector<int> src_character_offsets; |
158 src.characterOffsets(src_character_offsets); | 158 src.characterOffsets(src_character_offsets); |
159 std::vector<int32> character_offsets; | 159 std::vector<int32> character_offsets; |
160 character_offsets.reserve(src_character_offsets.size()); | 160 character_offsets.reserve(src_character_offsets.size()); |
161 for (size_t i = 0; i < src_character_offsets.size(); ++i) | 161 for (size_t i = 0; i < src_character_offsets.size(); ++i) |
162 character_offsets.push_back(src_character_offsets[i]); | 162 character_offsets.push_back(src_character_offsets[i]); |
163 dst->AddIntListAttribute(dst->ATTR_CHARACTER_OFFSETS, character_offsets); | 163 dst->AddIntListAttribute(dst->ATTR_CHARACTER_OFFSETS, character_offsets); |
164 | 164 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 dst->AddStringAttribute(dst->ATTR_SHORTCUT, | 201 dst->AddStringAttribute(dst->ATTR_SHORTCUT, |
202 UTF16ToUTF8(src.keyboardShortcut())); | 202 UTF16ToUTF8(src.keyboardShortcut())); |
203 } | 203 } |
204 if (!src.titleUIElement().isDetached()) { | 204 if (!src.titleUIElement().isDetached()) { |
205 dst->AddIntAttribute(dst->ATTR_TITLE_UI_ELEMENT, | 205 dst->AddIntAttribute(dst->ATTR_TITLE_UI_ELEMENT, |
206 src.titleUIElement().axID()); | 206 src.titleUIElement().axID()); |
207 } | 207 } |
208 if (!src.url().isEmpty()) | 208 if (!src.url().isEmpty()) |
209 dst->AddStringAttribute(dst->ATTR_URL, src.url().spec()); | 209 dst->AddStringAttribute(dst->ATTR_URL, src.url().spec()); |
210 | 210 |
211 if (dst->role == WebKit::WebAXRoleHeading) | 211 if (dst->role == blink::WebAXRoleHeading) |
212 dst->AddIntAttribute(dst->ATTR_HIERARCHICAL_LEVEL, src.headingLevel()); | 212 dst->AddIntAttribute(dst->ATTR_HIERARCHICAL_LEVEL, src.headingLevel()); |
213 else if ((dst->role == WebKit::WebAXRoleTreeItem || | 213 else if ((dst->role == blink::WebAXRoleTreeItem || |
214 dst->role == WebKit::WebAXRoleRow) && | 214 dst->role == blink::WebAXRoleRow) && |
215 src.hierarchicalLevel() > 0) { | 215 src.hierarchicalLevel() > 0) { |
216 dst->AddIntAttribute(dst->ATTR_HIERARCHICAL_LEVEL, src.hierarchicalLevel()); | 216 dst->AddIntAttribute(dst->ATTR_HIERARCHICAL_LEVEL, src.hierarchicalLevel()); |
217 } | 217 } |
218 | 218 |
219 // Treat the active list box item as focused. | 219 // Treat the active list box item as focused. |
220 if (dst->role == WebKit::WebAXRoleListBoxOption && | 220 if (dst->role == blink::WebAXRoleListBoxOption && |
221 src.isSelectedOptionActive()) { | 221 src.isSelectedOptionActive()) { |
222 dst->state |= (1 << WebKit::WebAXStateFocused); | 222 dst->state |= (1 << blink::WebAXStateFocused); |
223 } | 223 } |
224 | 224 |
225 if (src.canvasHasFallbackContent()) | 225 if (src.canvasHasFallbackContent()) |
226 dst->AddBoolAttribute(dst->ATTR_CANVAS_HAS_FALLBACK, true); | 226 dst->AddBoolAttribute(dst->ATTR_CANVAS_HAS_FALLBACK, true); |
227 | 227 |
228 WebNode node = src.node(); | 228 WebNode node = src.node(); |
229 bool is_iframe = false; | 229 bool is_iframe = false; |
230 std::string live_atomic; | 230 std::string live_atomic; |
231 std::string live_busy; | 231 std::string live_busy; |
232 std::string live_status; | 232 std::string live_status; |
233 std::string live_relevant; | 233 std::string live_relevant; |
234 | 234 |
235 if (!node.isNull() && node.isElementNode()) { | 235 if (!node.isNull() && node.isElementNode()) { |
236 WebElement element = node.to<WebElement>(); | 236 WebElement element = node.to<WebElement>(); |
237 is_iframe = (element.tagName() == ASCIIToUTF16("IFRAME")); | 237 is_iframe = (element.tagName() == ASCIIToUTF16("IFRAME")); |
238 | 238 |
239 if (LowerCaseEqualsASCII(element.getAttribute("aria-expanded"), "true")) | 239 if (LowerCaseEqualsASCII(element.getAttribute("aria-expanded"), "true")) |
240 dst->state |= (1 << WebKit::WebAXStateExpanded); | 240 dst->state |= (1 << blink::WebAXStateExpanded); |
241 | 241 |
242 // TODO(ctguil): The tagName in WebKit is lower cased but | 242 // TODO(ctguil): The tagName in WebKit is lower cased but |
243 // HTMLElement::nodeName calls localNameUpper. Consider adding | 243 // HTMLElement::nodeName calls localNameUpper. Consider adding |
244 // a WebElement method that returns the original lower cased tagName. | 244 // a WebElement method that returns the original lower cased tagName. |
245 dst->AddStringAttribute( | 245 dst->AddStringAttribute( |
246 dst->ATTR_HTML_TAG, | 246 dst->ATTR_HTML_TAG, |
247 StringToLowerASCII(UTF16ToUTF8(element.tagName()))); | 247 StringToLowerASCII(UTF16ToUTF8(element.tagName()))); |
248 for (unsigned i = 0; i < element.attributeCount(); ++i) { | 248 for (unsigned i = 0; i < element.attributeCount(); ++i) { |
249 std::string name = StringToLowerASCII(UTF16ToUTF8( | 249 std::string name = StringToLowerASCII(UTF16ToUTF8( |
250 element.attributeLocalName(i))); | 250 element.attributeLocalName(i))); |
251 std::string value = UTF16ToUTF8(element.attributeValue(i)); | 251 std::string value = UTF16ToUTF8(element.attributeValue(i)); |
252 dst->html_attributes.push_back(std::make_pair(name, value)); | 252 dst->html_attributes.push_back(std::make_pair(name, value)); |
253 } | 253 } |
254 | 254 |
255 if (dst->role == WebKit::WebAXRoleEditableText || | 255 if (dst->role == blink::WebAXRoleEditableText || |
256 dst->role == WebKit::WebAXRoleTextArea || | 256 dst->role == blink::WebAXRoleTextArea || |
257 dst->role == WebKit::WebAXRoleTextField) { | 257 dst->role == blink::WebAXRoleTextField) { |
258 dst->AddIntAttribute(dst->ATTR_TEXT_SEL_START, src.selectionStart()); | 258 dst->AddIntAttribute(dst->ATTR_TEXT_SEL_START, src.selectionStart()); |
259 dst->AddIntAttribute(dst->ATTR_TEXT_SEL_END, src.selectionEnd()); | 259 dst->AddIntAttribute(dst->ATTR_TEXT_SEL_END, src.selectionEnd()); |
260 | 260 |
261 WebVector<int> src_line_breaks; | 261 WebVector<int> src_line_breaks; |
262 src.lineBreaks(src_line_breaks); | 262 src.lineBreaks(src_line_breaks); |
263 if (src_line_breaks.size() > 0) { | 263 if (src_line_breaks.size() > 0) { |
264 std::vector<int32> line_breaks; | 264 std::vector<int32> line_breaks; |
265 line_breaks.reserve(src_line_breaks.size()); | 265 line_breaks.reserve(src_line_breaks.size()); |
266 for (size_t i = 0; i < src_line_breaks.size(); ++i) | 266 for (size_t i = 0; i < src_line_breaks.size(); ++i) |
267 line_breaks.push_back(src_line_breaks[i]); | 267 line_breaks.push_back(src_line_breaks[i]); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 } | 335 } |
336 if (!container_live_status.empty()) { | 336 if (!container_live_status.empty()) { |
337 dst->AddStringAttribute(dst->ATTR_CONTAINER_LIVE_STATUS, | 337 dst->AddStringAttribute(dst->ATTR_CONTAINER_LIVE_STATUS, |
338 container_live_status); | 338 container_live_status); |
339 } | 339 } |
340 if (!container_live_relevant.empty()) { | 340 if (!container_live_relevant.empty()) { |
341 dst->AddStringAttribute(dst->ATTR_CONTAINER_LIVE_RELEVANT, | 341 dst->AddStringAttribute(dst->ATTR_CONTAINER_LIVE_RELEVANT, |
342 container_live_relevant); | 342 container_live_relevant); |
343 } | 343 } |
344 | 344 |
345 if (dst->role == WebKit::WebAXRoleProgressIndicator || | 345 if (dst->role == blink::WebAXRoleProgressIndicator || |
346 dst->role == WebKit::WebAXRoleScrollBar || | 346 dst->role == blink::WebAXRoleScrollBar || |
347 dst->role == WebKit::WebAXRoleSlider || | 347 dst->role == blink::WebAXRoleSlider || |
348 dst->role == WebKit::WebAXRoleSpinButton) { | 348 dst->role == blink::WebAXRoleSpinButton) { |
349 dst->AddFloatAttribute(dst->ATTR_VALUE_FOR_RANGE, src.valueForRange()); | 349 dst->AddFloatAttribute(dst->ATTR_VALUE_FOR_RANGE, src.valueForRange()); |
350 dst->AddFloatAttribute(dst->ATTR_MAX_VALUE_FOR_RANGE, | 350 dst->AddFloatAttribute(dst->ATTR_MAX_VALUE_FOR_RANGE, |
351 src.maxValueForRange()); | 351 src.maxValueForRange()); |
352 dst->AddFloatAttribute(dst->ATTR_MIN_VALUE_FOR_RANGE, | 352 dst->AddFloatAttribute(dst->ATTR_MIN_VALUE_FOR_RANGE, |
353 src.minValueForRange()); | 353 src.minValueForRange()); |
354 } | 354 } |
355 | 355 |
356 if (dst->role == WebKit::WebAXRoleDocument || | 356 if (dst->role == blink::WebAXRoleDocument || |
357 dst->role == WebKit::WebAXRoleWebArea) { | 357 dst->role == blink::WebAXRoleWebArea) { |
358 dst->AddStringAttribute(dst->ATTR_HTML_TAG, "#document"); | 358 dst->AddStringAttribute(dst->ATTR_HTML_TAG, "#document"); |
359 const WebDocument& document = src.document(); | 359 const WebDocument& document = src.document(); |
360 if (name.empty()) | 360 if (name.empty()) |
361 name = UTF16ToUTF8(document.title()); | 361 name = UTF16ToUTF8(document.title()); |
362 dst->AddStringAttribute(dst->ATTR_DOC_TITLE, UTF16ToUTF8(document.title())); | 362 dst->AddStringAttribute(dst->ATTR_DOC_TITLE, UTF16ToUTF8(document.title())); |
363 dst->AddStringAttribute(dst->ATTR_DOC_URL, document.url().spec()); | 363 dst->AddStringAttribute(dst->ATTR_DOC_URL, document.url().spec()); |
364 dst->AddStringAttribute( | 364 dst->AddStringAttribute( |
365 dst->ATTR_DOC_MIMETYPE, | 365 dst->ATTR_DOC_MIMETYPE, |
366 document.isXHTMLDocument() ? "text/xhtml" : "text/html"); | 366 document.isXHTMLDocument() ? "text/xhtml" : "text/html"); |
367 dst->AddBoolAttribute(dst->ATTR_DOC_LOADED, src.isLoaded()); | 367 dst->AddBoolAttribute(dst->ATTR_DOC_LOADED, src.isLoaded()); |
(...skipping 12 matching lines...) Expand all Loading... |
380 | 380 |
381 const gfx::Size& min_offset = document.frame()->minimumScrollOffset(); | 381 const gfx::Size& min_offset = document.frame()->minimumScrollOffset(); |
382 dst->AddIntAttribute(dst->ATTR_SCROLL_X_MIN, min_offset.width()); | 382 dst->AddIntAttribute(dst->ATTR_SCROLL_X_MIN, min_offset.width()); |
383 dst->AddIntAttribute(dst->ATTR_SCROLL_Y_MIN, min_offset.height()); | 383 dst->AddIntAttribute(dst->ATTR_SCROLL_Y_MIN, min_offset.height()); |
384 | 384 |
385 const gfx::Size& max_offset = document.frame()->maximumScrollOffset(); | 385 const gfx::Size& max_offset = document.frame()->maximumScrollOffset(); |
386 dst->AddIntAttribute(dst->ATTR_SCROLL_X_MAX, max_offset.width()); | 386 dst->AddIntAttribute(dst->ATTR_SCROLL_X_MAX, max_offset.width()); |
387 dst->AddIntAttribute(dst->ATTR_SCROLL_Y_MAX, max_offset.height()); | 387 dst->AddIntAttribute(dst->ATTR_SCROLL_Y_MAX, max_offset.height()); |
388 } | 388 } |
389 | 389 |
390 if (dst->role == WebKit::WebAXRoleTable) { | 390 if (dst->role == blink::WebAXRoleTable) { |
391 int column_count = src.columnCount(); | 391 int column_count = src.columnCount(); |
392 int row_count = src.rowCount(); | 392 int row_count = src.rowCount(); |
393 if (column_count > 0 && row_count > 0) { | 393 if (column_count > 0 && row_count > 0) { |
394 std::set<int32> unique_cell_id_set; | 394 std::set<int32> unique_cell_id_set; |
395 std::vector<int32> cell_ids; | 395 std::vector<int32> cell_ids; |
396 std::vector<int32> unique_cell_ids; | 396 std::vector<int32> unique_cell_ids; |
397 dst->AddIntAttribute(dst->ATTR_TABLE_COLUMN_COUNT, column_count); | 397 dst->AddIntAttribute(dst->ATTR_TABLE_COLUMN_COUNT, column_count); |
398 dst->AddIntAttribute(dst->ATTR_TABLE_ROW_COUNT, row_count); | 398 dst->AddIntAttribute(dst->ATTR_TABLE_ROW_COUNT, row_count); |
399 WebAXObject header = src.headerContainerObject(); | 399 WebAXObject header = src.headerContainerObject(); |
400 if (!header.isDetached()) | 400 if (!header.isDetached()) |
401 dst->AddIntAttribute(dst->ATTR_TABLE_HEADER_ID, header.axID()); | 401 dst->AddIntAttribute(dst->ATTR_TABLE_HEADER_ID, header.axID()); |
402 for (int i = 0; i < column_count * row_count; ++i) { | 402 for (int i = 0; i < column_count * row_count; ++i) { |
403 WebAXObject cell = src.cellForColumnAndRow( | 403 WebAXObject cell = src.cellForColumnAndRow( |
404 i % column_count, i / column_count); | 404 i % column_count, i / column_count); |
405 int cell_id = -1; | 405 int cell_id = -1; |
406 if (!cell.isDetached()) { | 406 if (!cell.isDetached()) { |
407 cell_id = cell.axID(); | 407 cell_id = cell.axID(); |
408 if (unique_cell_id_set.find(cell_id) == unique_cell_id_set.end()) { | 408 if (unique_cell_id_set.find(cell_id) == unique_cell_id_set.end()) { |
409 unique_cell_id_set.insert(cell_id); | 409 unique_cell_id_set.insert(cell_id); |
410 unique_cell_ids.push_back(cell_id); | 410 unique_cell_ids.push_back(cell_id); |
411 } | 411 } |
412 } | 412 } |
413 cell_ids.push_back(cell_id); | 413 cell_ids.push_back(cell_id); |
414 } | 414 } |
415 dst->AddIntListAttribute(dst->ATTR_CELL_IDS, cell_ids); | 415 dst->AddIntListAttribute(dst->ATTR_CELL_IDS, cell_ids); |
416 dst->AddIntListAttribute(dst->ATTR_UNIQUE_CELL_IDS, unique_cell_ids); | 416 dst->AddIntListAttribute(dst->ATTR_UNIQUE_CELL_IDS, unique_cell_ids); |
417 } | 417 } |
418 } | 418 } |
419 | 419 |
420 if (dst->role == WebKit::WebAXRoleRow) { | 420 if (dst->role == blink::WebAXRoleRow) { |
421 dst->AddIntAttribute(dst->ATTR_TABLE_ROW_INDEX, src.rowIndex()); | 421 dst->AddIntAttribute(dst->ATTR_TABLE_ROW_INDEX, src.rowIndex()); |
422 WebAXObject header = src.rowHeader(); | 422 WebAXObject header = src.rowHeader(); |
423 if (!header.isDetached()) | 423 if (!header.isDetached()) |
424 dst->AddIntAttribute(dst->ATTR_TABLE_ROW_HEADER_ID, header.axID()); | 424 dst->AddIntAttribute(dst->ATTR_TABLE_ROW_HEADER_ID, header.axID()); |
425 } | 425 } |
426 | 426 |
427 if (dst->role == WebKit::WebAXRoleColumn) { | 427 if (dst->role == blink::WebAXRoleColumn) { |
428 dst->AddIntAttribute(dst->ATTR_TABLE_COLUMN_INDEX, src.columnIndex()); | 428 dst->AddIntAttribute(dst->ATTR_TABLE_COLUMN_INDEX, src.columnIndex()); |
429 WebAXObject header = src.columnHeader(); | 429 WebAXObject header = src.columnHeader(); |
430 if (!header.isDetached()) | 430 if (!header.isDetached()) |
431 dst->AddIntAttribute(dst->ATTR_TABLE_COLUMN_HEADER_ID, header.axID()); | 431 dst->AddIntAttribute(dst->ATTR_TABLE_COLUMN_HEADER_ID, header.axID()); |
432 } | 432 } |
433 | 433 |
434 if (dst->role == WebKit::WebAXRoleCell || | 434 if (dst->role == blink::WebAXRoleCell || |
435 dst->role == WebKit::WebAXRoleRowHeader || | 435 dst->role == blink::WebAXRoleRowHeader || |
436 dst->role == WebKit::WebAXRoleColumnHeader) { | 436 dst->role == blink::WebAXRoleColumnHeader) { |
437 dst->AddIntAttribute(dst->ATTR_TABLE_CELL_COLUMN_INDEX, | 437 dst->AddIntAttribute(dst->ATTR_TABLE_CELL_COLUMN_INDEX, |
438 src.cellColumnIndex()); | 438 src.cellColumnIndex()); |
439 dst->AddIntAttribute(dst->ATTR_TABLE_CELL_COLUMN_SPAN, | 439 dst->AddIntAttribute(dst->ATTR_TABLE_CELL_COLUMN_SPAN, |
440 src.cellColumnSpan()); | 440 src.cellColumnSpan()); |
441 dst->AddIntAttribute(dst->ATTR_TABLE_CELL_ROW_INDEX, src.cellRowIndex()); | 441 dst->AddIntAttribute(dst->ATTR_TABLE_CELL_ROW_INDEX, src.cellRowIndex()); |
442 dst->AddIntAttribute(dst->ATTR_TABLE_CELL_ROW_SPAN, src.cellRowSpan()); | 442 dst->AddIntAttribute(dst->ATTR_TABLE_CELL_ROW_SPAN, src.cellRowSpan()); |
443 } | 443 } |
444 | 444 |
445 dst->AddStringAttribute(dst->ATTR_NAME, name); | 445 dst->AddStringAttribute(dst->ATTR_NAME, name); |
446 | 446 |
(...skipping 12 matching lines...) Expand all Loading... |
459 dst->AddIntListAttribute( | 459 dst->AddIntListAttribute( |
460 dst->ATTR_INDIRECT_CHILD_IDS, indirect_child_ids); | 460 dst->ATTR_INDIRECT_CHILD_IDS, indirect_child_ids); |
461 } | 461 } |
462 } | 462 } |
463 } | 463 } |
464 | 464 |
465 bool ShouldIncludeChildNode( | 465 bool ShouldIncludeChildNode( |
466 const WebAXObject& parent, | 466 const WebAXObject& parent, |
467 const WebAXObject& child) { | 467 const WebAXObject& child) { |
468 switch(parent.role()) { | 468 switch(parent.role()) { |
469 case WebKit::WebAXRoleSlider: | 469 case blink::WebAXRoleSlider: |
470 case WebKit::WebAXRoleEditableText: | 470 case blink::WebAXRoleEditableText: |
471 case WebKit::WebAXRoleTextArea: | 471 case blink::WebAXRoleTextArea: |
472 case WebKit::WebAXRoleTextField: | 472 case blink::WebAXRoleTextField: |
473 return false; | 473 return false; |
474 default: | 474 default: |
475 break; | 475 break; |
476 } | 476 } |
477 | 477 |
478 // The child may be invalid due to issues in webkit accessibility code. | 478 // The child may be invalid due to issues in webkit accessibility code. |
479 // Don't add children that are invalid thus preventing a crash. | 479 // Don't add children that are invalid thus preventing a crash. |
480 // https://bugs.webkit.org/show_bug.cgi?id=44149 | 480 // https://bugs.webkit.org/show_bug.cgi?id=44149 |
481 // TODO(ctguil): We may want to remove this check as webkit stabilizes. | 481 // TODO(ctguil): We may want to remove this check as webkit stabilizes. |
482 if (child.isDetached()) | 482 if (child.isDetached()) |
483 return false; | 483 return false; |
484 | 484 |
485 // Skip children whose parent isn't this - see indirect_child_ids, above. | 485 // Skip children whose parent isn't this - see indirect_child_ids, above. |
486 // As an exception, include children of an iframe element. | 486 // As an exception, include children of an iframe element. |
487 bool is_iframe = false; | 487 bool is_iframe = false; |
488 WebNode node = parent.node(); | 488 WebNode node = parent.node(); |
489 if (!node.isNull() && node.isElementNode()) { | 489 if (!node.isNull() && node.isElementNode()) { |
490 WebElement element = node.to<WebElement>(); | 490 WebElement element = node.to<WebElement>(); |
491 is_iframe = (element.tagName() == ASCIIToUTF16("IFRAME")); | 491 is_iframe = (element.tagName() == ASCIIToUTF16("IFRAME")); |
492 } | 492 } |
493 | 493 |
494 return (is_iframe || IsParentUnignoredOf(parent, child)); | 494 return (is_iframe || IsParentUnignoredOf(parent, child)); |
495 } | 495 } |
496 | 496 |
497 } // namespace content | 497 } // namespace content |
OLD | NEW |