OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "components/test_runner/web_ax_object_proxy.h" | |
6 | |
7 #include <stddef.h> | |
8 | |
9 #include "base/macros.h" | |
10 #include "base/strings/stringprintf.h" | |
11 #include "gin/handle.h" | |
12 #include "third_party/WebKit/public/platform/WebFloatRect.h" | |
13 #include "third_party/WebKit/public/platform/WebPoint.h" | |
14 #include "third_party/WebKit/public/platform/WebRect.h" | |
15 #include "third_party/WebKit/public/platform/WebString.h" | |
16 #include "third_party/WebKit/public/web/WebFrame.h" | |
17 #include "third_party/WebKit/public/web/WebKit.h" | |
18 #include "third_party/skia/include/core/SkMatrix44.h" | |
19 #include "ui/gfx/geometry/rect_f.h" | |
20 #include "ui/gfx/transform.h" | |
21 | |
22 namespace test_runner { | |
23 | |
24 namespace { | |
25 | |
26 // Map role value to string, matching Safari/Mac platform implementation to | |
27 // avoid rebaselining layout tests. | |
28 std::string RoleToString(blink::WebAXRole role) | |
29 { | |
30 std::string result = "AXRole: AX"; | |
31 switch (role) { | |
32 case blink::WebAXRoleAbbr: | |
33 return result.append("Abbr"); | |
34 case blink::WebAXRoleAlertDialog: | |
35 return result.append("AlertDialog"); | |
36 case blink::WebAXRoleAlert: | |
37 return result.append("Alert"); | |
38 case blink::WebAXRoleAnnotation: | |
39 return result.append("Annotation"); | |
40 case blink::WebAXRoleApplication: | |
41 return result.append("Application"); | |
42 case blink::WebAXRoleArticle: | |
43 return result.append("Article"); | |
44 case blink::WebAXRoleAudio: | |
45 return result.append("Audio"); | |
46 case blink::WebAXRoleBanner: | |
47 return result.append("Banner"); | |
48 case blink::WebAXRoleBlockquote: | |
49 return result.append("Blockquote"); | |
50 case blink::WebAXRoleBusyIndicator: | |
51 return result.append("BusyIndicator"); | |
52 case blink::WebAXRoleButton: | |
53 return result.append("Button"); | |
54 case blink::WebAXRoleCanvas: | |
55 return result.append("Canvas"); | |
56 case blink::WebAXRoleCaption: | |
57 return result.append("Caption"); | |
58 case blink::WebAXRoleCell: | |
59 return result.append("Cell"); | |
60 case blink::WebAXRoleCheckBox: | |
61 return result.append("CheckBox"); | |
62 case blink::WebAXRoleColorWell: | |
63 return result.append("ColorWell"); | |
64 case blink::WebAXRoleColumnHeader: | |
65 return result.append("ColumnHeader"); | |
66 case blink::WebAXRoleColumn: | |
67 return result.append("Column"); | |
68 case blink::WebAXRoleComboBox: | |
69 return result.append("ComboBox"); | |
70 case blink::WebAXRoleComplementary: | |
71 return result.append("Complementary"); | |
72 case blink::WebAXRoleContentInfo: | |
73 return result.append("ContentInfo"); | |
74 case blink::WebAXRoleDate: | |
75 return result.append("DateField"); | |
76 case blink::WebAXRoleDateTime: | |
77 return result.append("DateTimeField"); | |
78 case blink::WebAXRoleDefinition: | |
79 return result.append("Definition"); | |
80 case blink::WebAXRoleDescriptionListDetail: | |
81 return result.append("DescriptionListDetail"); | |
82 case blink::WebAXRoleDescriptionList: | |
83 return result.append("DescriptionList"); | |
84 case blink::WebAXRoleDescriptionListTerm: | |
85 return result.append("DescriptionListTerm"); | |
86 case blink::WebAXRoleDetails: | |
87 return result.append("Details"); | |
88 case blink::WebAXRoleDialog: | |
89 return result.append("Dialog"); | |
90 case blink::WebAXRoleDirectory: | |
91 return result.append("Directory"); | |
92 case blink::WebAXRoleDisclosureTriangle: | |
93 return result.append("DisclosureTriangle"); | |
94 case blink::WebAXRoleDiv: | |
95 return result.append("Div"); | |
96 case blink::WebAXRoleDocument: | |
97 return result.append("Document"); | |
98 case blink::WebAXRoleEmbeddedObject: | |
99 return result.append("EmbeddedObject"); | |
100 case blink::WebAXRoleFigcaption: | |
101 return result.append("Figcaption"); | |
102 case blink::WebAXRoleFigure: | |
103 return result.append("Figure"); | |
104 case blink::WebAXRoleFooter: | |
105 return result.append("Footer"); | |
106 case blink::WebAXRoleForm: | |
107 return result.append("Form"); | |
108 case blink::WebAXRoleGrid: | |
109 return result.append("Grid"); | |
110 case blink::WebAXRoleGroup: | |
111 return result.append("Group"); | |
112 case blink::WebAXRoleHeading: | |
113 return result.append("Heading"); | |
114 case blink::WebAXRoleIgnored: | |
115 return result.append("Ignored"); | |
116 case blink::WebAXRoleImageMapLink: | |
117 return result.append("ImageMapLink"); | |
118 case blink::WebAXRoleImageMap: | |
119 return result.append("ImageMap"); | |
120 case blink::WebAXRoleImage: | |
121 return result.append("Image"); | |
122 case blink::WebAXRoleInlineTextBox: | |
123 return result.append("InlineTextBox"); | |
124 case blink::WebAXRoleInputTime: | |
125 return result.append("InputTime"); | |
126 case blink::WebAXRoleLabel: | |
127 return result.append("Label"); | |
128 case blink::WebAXRoleLegend: | |
129 return result.append("Legend"); | |
130 case blink::WebAXRoleLink: | |
131 return result.append("Link"); | |
132 case blink::WebAXRoleLineBreak: | |
133 return result.append("LineBreak"); | |
134 case blink::WebAXRoleListBoxOption: | |
135 return result.append("ListBoxOption"); | |
136 case blink::WebAXRoleListBox: | |
137 return result.append("ListBox"); | |
138 case blink::WebAXRoleListItem: | |
139 return result.append("ListItem"); | |
140 case blink::WebAXRoleListMarker: | |
141 return result.append("ListMarker"); | |
142 case blink::WebAXRoleList: | |
143 return result.append("List"); | |
144 case blink::WebAXRoleLog: | |
145 return result.append("Log"); | |
146 case blink::WebAXRoleMain: | |
147 return result.append("Main"); | |
148 case blink::WebAXRoleMark: | |
149 return result.append("Mark"); | |
150 case blink::WebAXRoleMarquee: | |
151 return result.append("Marquee"); | |
152 case blink::WebAXRoleMath: | |
153 return result.append("Math"); | |
154 case blink::WebAXRoleMenuBar: | |
155 return result.append("MenuBar"); | |
156 case blink::WebAXRoleMenuButton: | |
157 return result.append("MenuButton"); | |
158 case blink::WebAXRoleMenuItem: | |
159 return result.append("MenuItem"); | |
160 case blink::WebAXRoleMenuItemCheckBox: | |
161 return result.append("MenuItemCheckBox"); | |
162 case blink::WebAXRoleMenuItemRadio: | |
163 return result.append("MenuItemRadio"); | |
164 case blink::WebAXRoleMenuListOption: | |
165 return result.append("MenuListOption"); | |
166 case blink::WebAXRoleMenuListPopup: | |
167 return result.append("MenuListPopup"); | |
168 case blink::WebAXRoleMenu: | |
169 return result.append("Menu"); | |
170 case blink::WebAXRoleMeter: | |
171 return result.append("Meter"); | |
172 case blink::WebAXRoleNavigation: | |
173 return result.append("Navigation"); | |
174 case blink::WebAXRoleNone: | |
175 return result.append("None"); | |
176 case blink::WebAXRoleNote: | |
177 return result.append("Note"); | |
178 case blink::WebAXRoleOutline: | |
179 return result.append("Outline"); | |
180 case blink::WebAXRoleParagraph: | |
181 return result.append("Paragraph"); | |
182 case blink::WebAXRolePopUpButton: | |
183 return result.append("PopUpButton"); | |
184 case blink::WebAXRolePre: | |
185 return result.append("Pre"); | |
186 case blink::WebAXRolePresentational: | |
187 return result.append("Presentational"); | |
188 case blink::WebAXRoleProgressIndicator: | |
189 return result.append("ProgressIndicator"); | |
190 case blink::WebAXRoleRadioButton: | |
191 return result.append("RadioButton"); | |
192 case blink::WebAXRoleRadioGroup: | |
193 return result.append("RadioGroup"); | |
194 case blink::WebAXRoleRegion: | |
195 return result.append("Region"); | |
196 case blink::WebAXRoleRootWebArea: | |
197 return result.append("RootWebArea"); | |
198 case blink::WebAXRoleRowHeader: | |
199 return result.append("RowHeader"); | |
200 case blink::WebAXRoleRow: | |
201 return result.append("Row"); | |
202 case blink::WebAXRoleRuby: | |
203 return result.append("Ruby"); | |
204 case blink::WebAXRoleRuler: | |
205 return result.append("Ruler"); | |
206 case blink::WebAXRoleSVGRoot: | |
207 return result.append("SVGRoot"); | |
208 case blink::WebAXRoleScrollArea: | |
209 return result.append("ScrollArea"); | |
210 case blink::WebAXRoleScrollBar: | |
211 return result.append("ScrollBar"); | |
212 case blink::WebAXRoleSeamlessWebArea: | |
213 return result.append("SeamlessWebArea"); | |
214 case blink::WebAXRoleSearch: | |
215 return result.append("Search"); | |
216 case blink::WebAXRoleSearchBox: | |
217 return result.append("SearchBox"); | |
218 case blink::WebAXRoleSlider: | |
219 return result.append("Slider"); | |
220 case blink::WebAXRoleSliderThumb: | |
221 return result.append("SliderThumb"); | |
222 case blink::WebAXRoleSpinButtonPart: | |
223 return result.append("SpinButtonPart"); | |
224 case blink::WebAXRoleSpinButton: | |
225 return result.append("SpinButton"); | |
226 case blink::WebAXRoleSplitter: | |
227 return result.append("Splitter"); | |
228 case blink::WebAXRoleStaticText: | |
229 return result.append("StaticText"); | |
230 case blink::WebAXRoleStatus: | |
231 return result.append("Status"); | |
232 case blink::WebAXRoleSwitch: | |
233 return result.append("Switch"); | |
234 case blink::WebAXRoleTabGroup: | |
235 return result.append("TabGroup"); | |
236 case blink::WebAXRoleTabList: | |
237 return result.append("TabList"); | |
238 case blink::WebAXRoleTabPanel: | |
239 return result.append("TabPanel"); | |
240 case blink::WebAXRoleTab: | |
241 return result.append("Tab"); | |
242 case blink::WebAXRoleTableHeaderContainer: | |
243 return result.append("TableHeaderContainer"); | |
244 case blink::WebAXRoleTable: | |
245 return result.append("Table"); | |
246 case blink::WebAXRoleTextField: | |
247 return result.append("TextField"); | |
248 case blink::WebAXRoleTime: | |
249 return result.append("Time"); | |
250 case blink::WebAXRoleTimer: | |
251 return result.append("Timer"); | |
252 case blink::WebAXRoleToggleButton: | |
253 return result.append("ToggleButton"); | |
254 case blink::WebAXRoleToolbar: | |
255 return result.append("Toolbar"); | |
256 case blink::WebAXRoleTreeGrid: | |
257 return result.append("TreeGrid"); | |
258 case blink::WebAXRoleTreeItem: | |
259 return result.append("TreeItem"); | |
260 case blink::WebAXRoleTree: | |
261 return result.append("Tree"); | |
262 case blink::WebAXRoleUnknown: | |
263 return result.append("Unknown"); | |
264 case blink::WebAXRoleUserInterfaceTooltip: | |
265 return result.append("UserInterfaceTooltip"); | |
266 case blink::WebAXRoleVideo: | |
267 return result.append("Video"); | |
268 case blink::WebAXRoleWebArea: | |
269 return result.append("WebArea"); | |
270 case blink::WebAXRoleWindow: | |
271 return result.append("Window"); | |
272 default: | |
273 return result.append("Unknown"); | |
274 } | |
275 } | |
276 | |
277 std::string GetStringValue(const blink::WebAXObject& object) { | |
278 std::string value; | |
279 if (object.role() == blink::WebAXRoleColorWell) { | |
280 unsigned int color = object.colorValue(); | |
281 unsigned int red = (color >> 16) & 0xFF; | |
282 unsigned int green = (color >> 8) & 0xFF; | |
283 unsigned int blue = color & 0xFF; | |
284 value = base::StringPrintf("rgba(%d, %d, %d, 1)", | |
285 red, green, blue); | |
286 } else { | |
287 value = object.stringValue().utf8(); | |
288 } | |
289 return value.insert(0, "AXValue: "); | |
290 } | |
291 | |
292 std::string GetRole(const blink::WebAXObject& object) { | |
293 std::string role_string = RoleToString(object.role()); | |
294 | |
295 // Special-case canvas with fallback content because Chromium wants to treat | |
296 // this as essentially a separate role that it can map differently depending | |
297 // on the platform. | |
298 if (object.role() == blink::WebAXRoleCanvas && | |
299 object.canvasHasFallbackContent()) { | |
300 role_string += "WithFallbackContent"; | |
301 } | |
302 | |
303 return role_string; | |
304 } | |
305 | |
306 std::string GetValueDescription(const blink::WebAXObject& object) { | |
307 std::string value_description = object.valueDescription().utf8(); | |
308 return value_description.insert(0, "AXValueDescription: "); | |
309 } | |
310 | |
311 std::string GetLanguage(const blink::WebAXObject& object) { | |
312 std::string language = object.language().utf8(); | |
313 return language.insert(0, "AXLanguage: "); | |
314 } | |
315 | |
316 std::string GetAttributes(const blink::WebAXObject& object) { | |
317 std::string attributes(object.name().utf8()); | |
318 attributes.append("\n"); | |
319 attributes.append(GetRole(object)); | |
320 return attributes; | |
321 } | |
322 | |
323 // New bounds calculation algorithm. Retrieves the frame-relative bounds | |
324 // of an object by calling getRelativeBounds and then applying the offsets | |
325 // and transforms recursively on each container of this object. | |
326 blink::WebFloatRect BoundsForObject(const blink::WebAXObject& object) { | |
327 blink::WebAXObject container; | |
328 blink::WebFloatRect bounds; | |
329 SkMatrix44 matrix; | |
330 object.getRelativeBounds(container, bounds, matrix); | |
331 gfx::RectF computedBounds(0, 0, bounds.width, bounds.height); | |
332 while (!container.isDetached()) { | |
333 computedBounds.Offset(bounds.x, bounds.y); | |
334 computedBounds.Offset( | |
335 -container.getScrollOffset().x, -container.getScrollOffset().y); | |
336 if (!matrix.isIdentity()) { | |
337 gfx::Transform transform(matrix); | |
338 transform.TransformRect(&computedBounds); | |
339 } | |
340 container.getRelativeBounds(container, bounds, matrix); | |
341 } | |
342 return blink::WebFloatRect(computedBounds.x(), | |
343 computedBounds.y(), | |
344 computedBounds.width(), | |
345 computedBounds.height()); | |
346 } | |
347 | |
348 blink::WebRect BoundsForCharacter(const blink::WebAXObject& object, | |
349 int characterIndex) { | |
350 DCHECK_EQ(object.role(), blink::WebAXRoleStaticText); | |
351 int end = 0; | |
352 for (unsigned i = 0; i < object.childCount(); i++) { | |
353 blink::WebAXObject inline_text_box = object.childAt(i); | |
354 DCHECK_EQ(inline_text_box.role(), blink::WebAXRoleInlineTextBox); | |
355 int start = end; | |
356 blink::WebString name = inline_text_box.name(); | |
357 end += name.length(); | |
358 if (characterIndex < start || characterIndex >= end) | |
359 continue; | |
360 | |
361 blink::WebFloatRect inline_text_box_rect = BoundsForObject(inline_text_box); | |
362 | |
363 int localIndex = characterIndex - start; | |
364 blink::WebVector<int> character_offsets; | |
365 inline_text_box.characterOffsets(character_offsets); | |
366 if (character_offsets.size() != name.length()) | |
367 return blink::WebRect(); | |
368 | |
369 switch (inline_text_box.textDirection()) { | |
370 case blink::WebAXTextDirectionLR: { | |
371 if (localIndex) { | |
372 int left = inline_text_box_rect.x + character_offsets[localIndex - 1]; | |
373 int width = character_offsets[localIndex] - | |
374 character_offsets[localIndex - 1]; | |
375 return blink::WebRect(left, inline_text_box_rect.y, | |
376 width, inline_text_box_rect.height); | |
377 } | |
378 return blink::WebRect( | |
379 inline_text_box_rect.x, inline_text_box_rect.y, | |
380 character_offsets[0], inline_text_box_rect.height); | |
381 } | |
382 case blink::WebAXTextDirectionRL: { | |
383 int right = inline_text_box_rect.x + inline_text_box_rect.width; | |
384 | |
385 if (localIndex) { | |
386 int left = right - character_offsets[localIndex]; | |
387 int width = character_offsets[localIndex] - | |
388 character_offsets[localIndex - 1]; | |
389 return blink::WebRect(left, inline_text_box_rect.y, | |
390 width, inline_text_box_rect.height); | |
391 } | |
392 int left = right - character_offsets[0]; | |
393 return blink::WebRect( | |
394 left, inline_text_box_rect.y, | |
395 character_offsets[0], inline_text_box_rect.height); | |
396 } | |
397 case blink::WebAXTextDirectionTB: { | |
398 if (localIndex) { | |
399 int top = inline_text_box_rect.y + character_offsets[localIndex - 1]; | |
400 int height = character_offsets[localIndex] - | |
401 character_offsets[localIndex - 1]; | |
402 return blink::WebRect(inline_text_box_rect.x, top, | |
403 inline_text_box_rect.width, height); | |
404 } | |
405 return blink::WebRect(inline_text_box_rect.x, inline_text_box_rect.y, | |
406 inline_text_box_rect.width, character_offsets[0]); | |
407 } | |
408 case blink::WebAXTextDirectionBT: { | |
409 int bottom = inline_text_box_rect.y + inline_text_box_rect.height; | |
410 | |
411 if (localIndex) { | |
412 int top = bottom - character_offsets[localIndex]; | |
413 int height = character_offsets[localIndex] - | |
414 character_offsets[localIndex - 1]; | |
415 return blink::WebRect(inline_text_box_rect.x, top, | |
416 inline_text_box_rect.width, height); | |
417 } | |
418 int top = bottom - character_offsets[0]; | |
419 return blink::WebRect(inline_text_box_rect.x, top, | |
420 inline_text_box_rect.width, character_offsets[0]); | |
421 } | |
422 } | |
423 } | |
424 | |
425 DCHECK(false); | |
426 return blink::WebRect(); | |
427 } | |
428 | |
429 std::vector<std::string> GetMisspellings(blink::WebAXObject& object) { | |
430 std::vector<std::string> misspellings; | |
431 std::string text(object.name().utf8()); | |
432 | |
433 blink::WebVector<blink::WebAXMarkerType> marker_types; | |
434 blink::WebVector<int> marker_starts; | |
435 blink::WebVector<int> marker_ends; | |
436 object.markers(marker_types, marker_starts, marker_ends); | |
437 DCHECK_EQ(marker_types.size(), marker_starts.size()); | |
438 DCHECK_EQ(marker_starts.size(), marker_ends.size()); | |
439 | |
440 for (size_t i = 0; i < marker_types.size(); ++i) { | |
441 if (marker_types[i] & blink::WebAXMarkerTypeSpelling) { | |
442 misspellings.push_back( | |
443 text.substr(marker_starts[i], marker_ends[i] - marker_starts[i])); | |
444 } | |
445 } | |
446 | |
447 return misspellings; | |
448 } | |
449 | |
450 void GetBoundariesForOneWord(const blink::WebAXObject& object, | |
451 int character_index, | |
452 int& word_start, | |
453 int& word_end) { | |
454 int end = 0; | |
455 for (size_t i = 0; i < object.childCount(); i++) { | |
456 blink::WebAXObject inline_text_box = object.childAt(i); | |
457 DCHECK_EQ(inline_text_box.role(), blink::WebAXRoleInlineTextBox); | |
458 int start = end; | |
459 blink::WebString name = inline_text_box.name(); | |
460 end += name.length(); | |
461 if (end <= character_index) | |
462 continue; | |
463 int localIndex = character_index - start; | |
464 | |
465 blink::WebVector<int> starts; | |
466 blink::WebVector<int> ends; | |
467 inline_text_box.wordBoundaries(starts, ends); | |
468 size_t word_count = starts.size(); | |
469 DCHECK_EQ(ends.size(), word_count); | |
470 | |
471 // If there are no words, use the InlineTextBox boundaries. | |
472 if (!word_count) { | |
473 word_start = start; | |
474 word_end = end; | |
475 return; | |
476 } | |
477 | |
478 // Look for a character within any word other than the last. | |
479 for (size_t j = 0; j < word_count - 1; j++) { | |
480 if (localIndex <= ends[j]) { | |
481 word_start = start + starts[j]; | |
482 word_end = start + ends[j]; | |
483 return; | |
484 } | |
485 } | |
486 | |
487 // Return the last word by default. | |
488 word_start = start + starts[word_count - 1]; | |
489 word_end = start + ends[word_count - 1]; | |
490 return; | |
491 } | |
492 } | |
493 | |
494 // Collects attributes into a string, delimited by dashes. Used by all methods | |
495 // that output lists of attributes: attributesOfLinkedUIElementsCallback, | |
496 // AttributesOfChildrenCallback, etc. | |
497 class AttributesCollector { | |
498 public: | |
499 AttributesCollector() {} | |
500 ~AttributesCollector() {} | |
501 | |
502 void CollectAttributes(const blink::WebAXObject& object) { | |
503 attributes_.append("\n------------\n"); | |
504 attributes_.append(GetAttributes(object)); | |
505 } | |
506 | |
507 std::string attributes() const { return attributes_; } | |
508 | |
509 private: | |
510 std::string attributes_; | |
511 | |
512 DISALLOW_COPY_AND_ASSIGN(AttributesCollector); | |
513 }; | |
514 | |
515 class SparseAttributeAdapter : public blink::WebAXSparseAttributeClient { | |
516 public: | |
517 SparseAttributeAdapter() {} | |
518 ~SparseAttributeAdapter() override {} | |
519 | |
520 std::map<blink::WebAXBoolAttribute, bool> bool_attributes; | |
521 std::map<blink::WebAXStringAttribute, blink::WebString> string_attributes; | |
522 std::map<blink::WebAXObjectAttribute, blink::WebAXObject> object_attributes; | |
523 std::map<blink::WebAXObjectVectorAttribute, | |
524 blink::WebVector<blink::WebAXObject>> | |
525 object_vector_attributes; | |
526 | |
527 private: | |
528 void addBoolAttribute(blink::WebAXBoolAttribute attribute, | |
529 bool value) override { | |
530 bool_attributes[attribute] = value; | |
531 } | |
532 | |
533 void addStringAttribute(blink::WebAXStringAttribute attribute, | |
534 const blink::WebString& value) override { | |
535 string_attributes[attribute] = value; | |
536 } | |
537 | |
538 void addObjectAttribute(blink::WebAXObjectAttribute attribute, | |
539 const blink::WebAXObject& value) override { | |
540 object_attributes[attribute] = value; | |
541 } | |
542 | |
543 void addObjectVectorAttribute( | |
544 blink::WebAXObjectVectorAttribute attribute, | |
545 const blink::WebVector<blink::WebAXObject>& value) override { | |
546 object_vector_attributes[attribute] = value; | |
547 } | |
548 }; | |
549 | |
550 } // namespace | |
551 | |
552 gin::WrapperInfo WebAXObjectProxy::kWrapperInfo = { | |
553 gin::kEmbedderNativeGin}; | |
554 | |
555 WebAXObjectProxy::WebAXObjectProxy(const blink::WebAXObject& object, | |
556 WebAXObjectProxy::Factory* factory) | |
557 : accessibility_object_(object), | |
558 factory_(factory) { | |
559 } | |
560 | |
561 WebAXObjectProxy::~WebAXObjectProxy() {} | |
562 | |
563 gin::ObjectTemplateBuilder | |
564 WebAXObjectProxy::GetObjectTemplateBuilder(v8::Isolate* isolate) { | |
565 return gin::Wrappable<WebAXObjectProxy>::GetObjectTemplateBuilder(isolate) | |
566 .SetProperty("role", &WebAXObjectProxy::Role) | |
567 .SetProperty("stringValue", &WebAXObjectProxy::StringValue) | |
568 .SetProperty("language", &WebAXObjectProxy::Language) | |
569 .SetProperty("x", &WebAXObjectProxy::X) | |
570 .SetProperty("y", &WebAXObjectProxy::Y) | |
571 .SetProperty("width", &WebAXObjectProxy::Width) | |
572 .SetProperty("height", &WebAXObjectProxy::Height) | |
573 .SetProperty("intValue", &WebAXObjectProxy::IntValue) | |
574 .SetProperty("minValue", &WebAXObjectProxy::MinValue) | |
575 .SetProperty("maxValue", &WebAXObjectProxy::MaxValue) | |
576 .SetProperty("valueDescription", &WebAXObjectProxy::ValueDescription) | |
577 .SetProperty("childrenCount", &WebAXObjectProxy::ChildrenCount) | |
578 .SetProperty("selectionAnchorObject", | |
579 &WebAXObjectProxy::SelectionAnchorObject) | |
580 .SetProperty("selectionAnchorOffset", | |
581 &WebAXObjectProxy::SelectionAnchorOffset) | |
582 .SetProperty("selectionAnchorAffinity", | |
583 &WebAXObjectProxy::SelectionAnchorAffinity) | |
584 .SetProperty("selectionFocusObject", | |
585 &WebAXObjectProxy::SelectionFocusObject) | |
586 .SetProperty("selectionFocusOffset", | |
587 &WebAXObjectProxy::SelectionFocusOffset) | |
588 .SetProperty("selectionFocusAffinity", | |
589 &WebAXObjectProxy::SelectionFocusAffinity) | |
590 .SetProperty("selectionStart", &WebAXObjectProxy::SelectionStart) | |
591 .SetProperty("selectionEnd", &WebAXObjectProxy::SelectionEnd) | |
592 .SetProperty("selectionStartLineNumber", | |
593 &WebAXObjectProxy::SelectionStartLineNumber) | |
594 .SetProperty("selectionEndLineNumber", | |
595 &WebAXObjectProxy::SelectionEndLineNumber) | |
596 .SetProperty("isEnabled", &WebAXObjectProxy::IsEnabled) | |
597 .SetProperty("isRequired", &WebAXObjectProxy::IsRequired) | |
598 .SetProperty("isEditable", &WebAXObjectProxy::IsEditable) | |
599 .SetProperty("isRichlyEditable", &WebAXObjectProxy::IsRichlyEditable) | |
600 .SetProperty("isFocused", &WebAXObjectProxy::IsFocused) | |
601 .SetProperty("isFocusable", &WebAXObjectProxy::IsFocusable) | |
602 .SetProperty("isModal", &WebAXObjectProxy::IsModal) | |
603 .SetProperty("isSelected", &WebAXObjectProxy::IsSelected) | |
604 .SetProperty("isSelectable", &WebAXObjectProxy::IsSelectable) | |
605 .SetProperty("isMultiSelectable", &WebAXObjectProxy::IsMultiSelectable) | |
606 .SetProperty("isSelectedOptionActive", | |
607 &WebAXObjectProxy::IsSelectedOptionActive) | |
608 .SetProperty("isExpanded", &WebAXObjectProxy::IsExpanded) | |
609 .SetProperty("isChecked", &WebAXObjectProxy::IsChecked) | |
610 .SetProperty("isVisible", &WebAXObjectProxy::IsVisible) | |
611 .SetProperty("isOffScreen", &WebAXObjectProxy::IsOffScreen) | |
612 .SetProperty("isCollapsed", &WebAXObjectProxy::IsCollapsed) | |
613 .SetProperty("hasPopup", &WebAXObjectProxy::HasPopup) | |
614 .SetProperty("isValid", &WebAXObjectProxy::IsValid) | |
615 .SetProperty("isReadOnly", &WebAXObjectProxy::IsReadOnly) | |
616 .SetProperty("backgroundColor", &WebAXObjectProxy::BackgroundColor) | |
617 .SetProperty("color", &WebAXObjectProxy::Color) | |
618 .SetProperty("colorValue", &WebAXObjectProxy::ColorValue) | |
619 .SetProperty("fontFamily", &WebAXObjectProxy::FontFamily) | |
620 .SetProperty("fontSize", &WebAXObjectProxy::FontSize) | |
621 .SetProperty("orientation", &WebAXObjectProxy::Orientation) | |
622 .SetProperty("posInSet", &WebAXObjectProxy::PosInSet) | |
623 .SetProperty("setSize", &WebAXObjectProxy::SetSize) | |
624 .SetProperty("clickPointX", &WebAXObjectProxy::ClickPointX) | |
625 .SetProperty("clickPointY", &WebAXObjectProxy::ClickPointY) | |
626 .SetProperty("rowCount", &WebAXObjectProxy::RowCount) | |
627 .SetProperty("rowHeadersCount", &WebAXObjectProxy::RowHeadersCount) | |
628 .SetProperty("columnCount", &WebAXObjectProxy::ColumnCount) | |
629 .SetProperty("columnHeadersCount", &WebAXObjectProxy::ColumnHeadersCount) | |
630 .SetProperty("isClickable", &WebAXObjectProxy::IsClickable) | |
631 .SetProperty("isButtonStateMixed", &WebAXObjectProxy::IsButtonStateMixed) | |
632 // | |
633 // NEW bounding rect calculation - high-level interface | |
634 // | |
635 .SetProperty("boundsX", &WebAXObjectProxy::BoundsX) | |
636 .SetProperty("boundsY", &WebAXObjectProxy::BoundsY) | |
637 .SetProperty("boundsWidth", &WebAXObjectProxy::BoundsWidth) | |
638 .SetProperty("boundsHeight", &WebAXObjectProxy::BoundsHeight) | |
639 .SetMethod("allAttributes", &WebAXObjectProxy::AllAttributes) | |
640 .SetMethod("attributesOfChildren", | |
641 &WebAXObjectProxy::AttributesOfChildren) | |
642 .SetMethod("ariaControlsElementAtIndex", | |
643 &WebAXObjectProxy::AriaControlsElementAtIndex) | |
644 .SetMethod("ariaFlowToElementAtIndex", | |
645 &WebAXObjectProxy::AriaFlowToElementAtIndex) | |
646 .SetMethod("ariaOwnsElementAtIndex", | |
647 &WebAXObjectProxy::AriaOwnsElementAtIndex) | |
648 .SetMethod("lineForIndex", &WebAXObjectProxy::LineForIndex) | |
649 .SetMethod("boundsForRange", &WebAXObjectProxy::BoundsForRange) | |
650 .SetMethod("childAtIndex", &WebAXObjectProxy::ChildAtIndex) | |
651 .SetMethod("elementAtPoint", &WebAXObjectProxy::ElementAtPoint) | |
652 .SetMethod("tableHeader", &WebAXObjectProxy::TableHeader) | |
653 .SetMethod("rowHeaderAtIndex", &WebAXObjectProxy::RowHeaderAtIndex) | |
654 .SetMethod("columnHeaderAtIndex", &WebAXObjectProxy::ColumnHeaderAtIndex) | |
655 .SetMethod("rowIndexRange", &WebAXObjectProxy::RowIndexRange) | |
656 .SetMethod("columnIndexRange", &WebAXObjectProxy::ColumnIndexRange) | |
657 .SetMethod("cellForColumnAndRow", &WebAXObjectProxy::CellForColumnAndRow) | |
658 .SetMethod("setSelectedTextRange", | |
659 &WebAXObjectProxy::SetSelectedTextRange) | |
660 .SetMethod("setSelection", &WebAXObjectProxy::SetSelection) | |
661 .SetMethod("isAttributeSettable", &WebAXObjectProxy::IsAttributeSettable) | |
662 .SetMethod("isPressActionSupported", | |
663 &WebAXObjectProxy::IsPressActionSupported) | |
664 .SetMethod("isIncrementActionSupported", | |
665 &WebAXObjectProxy::IsIncrementActionSupported) | |
666 .SetMethod("isDecrementActionSupported", | |
667 &WebAXObjectProxy::IsDecrementActionSupported) | |
668 .SetMethod("parentElement", &WebAXObjectProxy::ParentElement) | |
669 .SetMethod("increment", &WebAXObjectProxy::Increment) | |
670 .SetMethod("decrement", &WebAXObjectProxy::Decrement) | |
671 .SetMethod("showMenu", &WebAXObjectProxy::ShowMenu) | |
672 .SetMethod("press", &WebAXObjectProxy::Press) | |
673 .SetMethod("setValue", &WebAXObjectProxy::SetValue) | |
674 .SetMethod("isEqual", &WebAXObjectProxy::IsEqual) | |
675 .SetMethod("setNotificationListener", | |
676 &WebAXObjectProxy::SetNotificationListener) | |
677 .SetMethod("unsetNotificationListener", | |
678 &WebAXObjectProxy::UnsetNotificationListener) | |
679 .SetMethod("takeFocus", &WebAXObjectProxy::TakeFocus) | |
680 .SetMethod("scrollToMakeVisible", &WebAXObjectProxy::ScrollToMakeVisible) | |
681 .SetMethod("scrollToMakeVisibleWithSubFocus", | |
682 &WebAXObjectProxy::ScrollToMakeVisibleWithSubFocus) | |
683 .SetMethod("scrollToGlobalPoint", &WebAXObjectProxy::ScrollToGlobalPoint) | |
684 .SetMethod("scrollX", &WebAXObjectProxy::ScrollX) | |
685 .SetMethod("scrollY", &WebAXObjectProxy::ScrollY) | |
686 .SetMethod("wordStart", &WebAXObjectProxy::WordStart) | |
687 .SetMethod("wordEnd", &WebAXObjectProxy::WordEnd) | |
688 .SetMethod("nextOnLine", &WebAXObjectProxy::NextOnLine) | |
689 .SetMethod("previousOnLine", &WebAXObjectProxy::PreviousOnLine) | |
690 .SetMethod("misspellingAtIndex", &WebAXObjectProxy::MisspellingAtIndex) | |
691 // TODO(hajimehoshi): This is for backward compatibility. Remove them. | |
692 .SetMethod("addNotificationListener", | |
693 &WebAXObjectProxy::SetNotificationListener) | |
694 .SetMethod("removeNotificationListener", | |
695 &WebAXObjectProxy::UnsetNotificationListener) | |
696 // | |
697 // NEW accessible name and description accessors | |
698 // | |
699 .SetProperty("name", &WebAXObjectProxy::Name) | |
700 .SetProperty("nameFrom", &WebAXObjectProxy::NameFrom) | |
701 .SetMethod("nameElementCount", &WebAXObjectProxy::NameElementCount) | |
702 .SetMethod("nameElementAtIndex", &WebAXObjectProxy::NameElementAtIndex) | |
703 .SetProperty("description", &WebAXObjectProxy::Description) | |
704 .SetProperty("descriptionFrom", &WebAXObjectProxy::DescriptionFrom) | |
705 .SetProperty("placeholder", &WebAXObjectProxy::Placeholder) | |
706 .SetProperty("misspellingsCount", &WebAXObjectProxy::MisspellingsCount) | |
707 .SetMethod("descriptionElementCount", | |
708 &WebAXObjectProxy::DescriptionElementCount) | |
709 .SetMethod("descriptionElementAtIndex", | |
710 &WebAXObjectProxy::DescriptionElementAtIndex) | |
711 // | |
712 // NEW bounding rect calculation - low-level interface | |
713 // | |
714 .SetMethod("offsetContainer", &WebAXObjectProxy::OffsetContainer) | |
715 .SetMethod("boundsInContainerX", &WebAXObjectProxy::BoundsInContainerX) | |
716 .SetMethod("boundsInContainerY", &WebAXObjectProxy::BoundsInContainerY) | |
717 .SetMethod("boundsInContainerWidth", | |
718 &WebAXObjectProxy::BoundsInContainerWidth) | |
719 .SetMethod("boundsInContainerHeight", | |
720 &WebAXObjectProxy::BoundsInContainerHeight) | |
721 .SetMethod("hasNonIdentityTransform", | |
722 &WebAXObjectProxy::HasNonIdentityTransform); | |
723 } | |
724 | |
725 v8::Local<v8::Object> WebAXObjectProxy::GetChildAtIndex(unsigned index) { | |
726 return factory_->GetOrCreate(accessibility_object_.childAt(index)); | |
727 } | |
728 | |
729 bool WebAXObjectProxy::IsRoot() const { | |
730 return false; | |
731 } | |
732 | |
733 bool WebAXObjectProxy::IsEqualToObject(const blink::WebAXObject& other) { | |
734 return accessibility_object_.equals(other); | |
735 } | |
736 | |
737 void WebAXObjectProxy::NotificationReceived( | |
738 blink::WebFrame* frame, | |
739 const std::string& notification_name) { | |
740 if (notification_callback_.IsEmpty()) | |
741 return; | |
742 | |
743 v8::Local<v8::Context> context = frame->mainWorldScriptContext(); | |
744 if (context.IsEmpty()) | |
745 return; | |
746 | |
747 v8::Isolate* isolate = blink::mainThreadIsolate(); | |
748 | |
749 v8::Local<v8::Value> argv[] = { | |
750 v8::String::NewFromUtf8(isolate, notification_name.data(), | |
751 v8::String::kNormalString, | |
752 notification_name.size()), | |
753 }; | |
754 frame->callFunctionEvenIfScriptDisabled( | |
755 v8::Local<v8::Function>::New(isolate, notification_callback_), | |
756 context->Global(), | |
757 arraysize(argv), | |
758 argv); | |
759 } | |
760 | |
761 void WebAXObjectProxy::Reset() { | |
762 notification_callback_.Reset(); | |
763 } | |
764 | |
765 std::string WebAXObjectProxy::Role() { | |
766 accessibility_object_.updateLayoutAndCheckValidity(); | |
767 return GetRole(accessibility_object_); | |
768 } | |
769 | |
770 std::string WebAXObjectProxy::StringValue() { | |
771 accessibility_object_.updateLayoutAndCheckValidity(); | |
772 return GetStringValue(accessibility_object_); | |
773 } | |
774 | |
775 std::string WebAXObjectProxy::Language() { | |
776 accessibility_object_.updateLayoutAndCheckValidity(); | |
777 return GetLanguage(accessibility_object_); | |
778 } | |
779 | |
780 int WebAXObjectProxy::X() { | |
781 accessibility_object_.updateLayoutAndCheckValidity(); | |
782 return BoundsForObject(accessibility_object_).x; | |
783 } | |
784 | |
785 int WebAXObjectProxy::Y() { | |
786 accessibility_object_.updateLayoutAndCheckValidity(); | |
787 return BoundsForObject(accessibility_object_).y; | |
788 } | |
789 | |
790 int WebAXObjectProxy::Width() { | |
791 accessibility_object_.updateLayoutAndCheckValidity(); | |
792 return BoundsForObject(accessibility_object_).width; | |
793 } | |
794 | |
795 int WebAXObjectProxy::Height() { | |
796 accessibility_object_.updateLayoutAndCheckValidity(); | |
797 return BoundsForObject(accessibility_object_).height; | |
798 } | |
799 | |
800 int WebAXObjectProxy::IntValue() { | |
801 accessibility_object_.updateLayoutAndCheckValidity(); | |
802 if (accessibility_object_.supportsRangeValue()) | |
803 return accessibility_object_.valueForRange(); | |
804 else if (accessibility_object_.role() == blink::WebAXRoleHeading) | |
805 return accessibility_object_.headingLevel(); | |
806 else | |
807 return atoi(accessibility_object_.stringValue().utf8().data()); | |
808 } | |
809 | |
810 int WebAXObjectProxy::MinValue() { | |
811 accessibility_object_.updateLayoutAndCheckValidity(); | |
812 return accessibility_object_.minValueForRange(); | |
813 } | |
814 | |
815 int WebAXObjectProxy::MaxValue() { | |
816 accessibility_object_.updateLayoutAndCheckValidity(); | |
817 return accessibility_object_.maxValueForRange(); | |
818 } | |
819 | |
820 std::string WebAXObjectProxy::ValueDescription() { | |
821 accessibility_object_.updateLayoutAndCheckValidity(); | |
822 return GetValueDescription(accessibility_object_); | |
823 } | |
824 | |
825 int WebAXObjectProxy::ChildrenCount() { | |
826 accessibility_object_.updateLayoutAndCheckValidity(); | |
827 int count = 1; // Root object always has only one child, the WebView. | |
828 if (!IsRoot()) | |
829 count = accessibility_object_.childCount(); | |
830 return count; | |
831 } | |
832 | |
833 v8::Local<v8::Value> WebAXObjectProxy::SelectionAnchorObject() { | |
834 accessibility_object_.updateLayoutAndCheckValidity(); | |
835 | |
836 blink::WebAXObject anchorObject; | |
837 int anchorOffset = -1; | |
838 blink::WebAXTextAffinity anchorAffinity; | |
839 blink::WebAXObject focusObject; | |
840 int focusOffset = -1; | |
841 blink::WebAXTextAffinity focusAffinity; | |
842 accessibility_object_.selection(anchorObject, anchorOffset, anchorAffinity, | |
843 focusObject, focusOffset, focusAffinity); | |
844 if (anchorObject.isNull()) | |
845 return v8::Null(blink::mainThreadIsolate()); | |
846 | |
847 return factory_->GetOrCreate(anchorObject); | |
848 } | |
849 | |
850 int WebAXObjectProxy::SelectionAnchorOffset() { | |
851 accessibility_object_.updateLayoutAndCheckValidity(); | |
852 | |
853 blink::WebAXObject anchorObject; | |
854 int anchorOffset = -1; | |
855 blink::WebAXTextAffinity anchorAffinity; | |
856 blink::WebAXObject focusObject; | |
857 int focusOffset = -1; | |
858 blink::WebAXTextAffinity focusAffinity; | |
859 accessibility_object_.selection(anchorObject, anchorOffset, anchorAffinity, | |
860 focusObject, focusOffset, focusAffinity); | |
861 if (anchorOffset < 0) | |
862 return -1; | |
863 | |
864 return anchorOffset; | |
865 } | |
866 | |
867 std::string WebAXObjectProxy::SelectionAnchorAffinity() { | |
868 accessibility_object_.updateLayoutAndCheckValidity(); | |
869 | |
870 blink::WebAXObject anchorObject; | |
871 int anchorOffset = -1; | |
872 blink::WebAXTextAffinity anchorAffinity; | |
873 blink::WebAXObject focusObject; | |
874 int focusOffset = -1; | |
875 blink::WebAXTextAffinity focusAffinity; | |
876 accessibility_object_.selection(anchorObject, anchorOffset, anchorAffinity, | |
877 focusObject, focusOffset, focusAffinity); | |
878 return anchorAffinity == blink::WebAXTextAffinityUpstream ? | |
879 "upstream" : "downstream"; | |
880 } | |
881 | |
882 v8::Local<v8::Value> WebAXObjectProxy::SelectionFocusObject() { | |
883 accessibility_object_.updateLayoutAndCheckValidity(); | |
884 | |
885 blink::WebAXObject anchorObject; | |
886 int anchorOffset = -1; | |
887 blink::WebAXTextAffinity anchorAffinity; | |
888 blink::WebAXObject focusObject; | |
889 int focusOffset = -1; | |
890 blink::WebAXTextAffinity focusAffinity; | |
891 accessibility_object_.selection(anchorObject, anchorOffset, anchorAffinity, | |
892 focusObject, focusOffset, focusAffinity); | |
893 if (focusObject.isNull()) | |
894 return v8::Null(blink::mainThreadIsolate()); | |
895 | |
896 return factory_->GetOrCreate(focusObject); | |
897 } | |
898 | |
899 int WebAXObjectProxy::SelectionFocusOffset() { | |
900 accessibility_object_.updateLayoutAndCheckValidity(); | |
901 | |
902 blink::WebAXObject anchorObject; | |
903 int anchorOffset = -1; | |
904 blink::WebAXTextAffinity anchorAffinity; | |
905 blink::WebAXObject focusObject; | |
906 int focusOffset = -1; | |
907 blink::WebAXTextAffinity focusAffinity; | |
908 accessibility_object_.selection(anchorObject, anchorOffset, anchorAffinity, | |
909 focusObject, focusOffset, focusAffinity); | |
910 if (focusOffset < 0) | |
911 return -1; | |
912 | |
913 return focusOffset; | |
914 } | |
915 | |
916 std::string WebAXObjectProxy::SelectionFocusAffinity() { | |
917 accessibility_object_.updateLayoutAndCheckValidity(); | |
918 | |
919 blink::WebAXObject anchorObject; | |
920 int anchorOffset = -1; | |
921 blink::WebAXTextAffinity anchorAffinity; | |
922 blink::WebAXObject focusObject; | |
923 int focusOffset = -1; | |
924 blink::WebAXTextAffinity focusAffinity; | |
925 accessibility_object_.selection(anchorObject, anchorOffset, anchorAffinity, | |
926 focusObject, focusOffset, focusAffinity); | |
927 return focusAffinity == blink::WebAXTextAffinityUpstream ? | |
928 "upstream" : "downstream"; | |
929 } | |
930 | |
931 int WebAXObjectProxy::SelectionStart() { | |
932 accessibility_object_.updateLayoutAndCheckValidity(); | |
933 return accessibility_object_.selectionStart(); | |
934 } | |
935 | |
936 int WebAXObjectProxy::SelectionEnd() { | |
937 accessibility_object_.updateLayoutAndCheckValidity(); | |
938 return accessibility_object_.selectionEnd(); | |
939 } | |
940 | |
941 int WebAXObjectProxy::SelectionStartLineNumber() { | |
942 accessibility_object_.updateLayoutAndCheckValidity(); | |
943 return accessibility_object_.selectionStartLineNumber(); | |
944 } | |
945 | |
946 int WebAXObjectProxy::SelectionEndLineNumber() { | |
947 accessibility_object_.updateLayoutAndCheckValidity(); | |
948 return accessibility_object_.selectionEndLineNumber(); | |
949 } | |
950 | |
951 bool WebAXObjectProxy::IsEnabled() { | |
952 accessibility_object_.updateLayoutAndCheckValidity(); | |
953 return accessibility_object_.isEnabled(); | |
954 } | |
955 | |
956 bool WebAXObjectProxy::IsRequired() { | |
957 accessibility_object_.updateLayoutAndCheckValidity(); | |
958 return accessibility_object_.isRequired(); | |
959 } | |
960 | |
961 bool WebAXObjectProxy::IsEditable() { | |
962 accessibility_object_.updateLayoutAndCheckValidity(); | |
963 return accessibility_object_.isEditable(); | |
964 } | |
965 | |
966 bool WebAXObjectProxy::IsRichlyEditable() { | |
967 accessibility_object_.updateLayoutAndCheckValidity(); | |
968 return accessibility_object_.isRichlyEditable(); | |
969 } | |
970 | |
971 bool WebAXObjectProxy::IsFocused() { | |
972 accessibility_object_.updateLayoutAndCheckValidity(); | |
973 return accessibility_object_.isFocused(); | |
974 } | |
975 | |
976 bool WebAXObjectProxy::IsFocusable() { | |
977 accessibility_object_.updateLayoutAndCheckValidity(); | |
978 return accessibility_object_.canSetFocusAttribute(); | |
979 } | |
980 | |
981 bool WebAXObjectProxy::IsModal() { | |
982 accessibility_object_.updateLayoutAndCheckValidity(); | |
983 return accessibility_object_.isModal(); | |
984 } | |
985 | |
986 bool WebAXObjectProxy::IsSelected() { | |
987 accessibility_object_.updateLayoutAndCheckValidity(); | |
988 return accessibility_object_.isSelected(); | |
989 } | |
990 | |
991 bool WebAXObjectProxy::IsSelectable() { | |
992 accessibility_object_.updateLayoutAndCheckValidity(); | |
993 return accessibility_object_.canSetSelectedAttribute(); | |
994 } | |
995 | |
996 bool WebAXObjectProxy::IsMultiSelectable() { | |
997 accessibility_object_.updateLayoutAndCheckValidity(); | |
998 return accessibility_object_.isMultiSelectable(); | |
999 } | |
1000 | |
1001 bool WebAXObjectProxy::IsSelectedOptionActive() { | |
1002 accessibility_object_.updateLayoutAndCheckValidity(); | |
1003 return accessibility_object_.isSelectedOptionActive(); | |
1004 } | |
1005 | |
1006 bool WebAXObjectProxy::IsExpanded() { | |
1007 accessibility_object_.updateLayoutAndCheckValidity(); | |
1008 return accessibility_object_.isExpanded() == blink::WebAXExpandedExpanded; | |
1009 } | |
1010 | |
1011 bool WebAXObjectProxy::IsChecked() { | |
1012 accessibility_object_.updateLayoutAndCheckValidity(); | |
1013 return accessibility_object_.isChecked(); | |
1014 } | |
1015 | |
1016 bool WebAXObjectProxy::IsCollapsed() { | |
1017 accessibility_object_.updateLayoutAndCheckValidity(); | |
1018 return accessibility_object_.isExpanded() == blink::WebAXExpandedCollapsed; | |
1019 } | |
1020 | |
1021 bool WebAXObjectProxy::IsVisible() { | |
1022 accessibility_object_.updateLayoutAndCheckValidity(); | |
1023 return accessibility_object_.isVisible(); | |
1024 } | |
1025 | |
1026 bool WebAXObjectProxy::IsOffScreen() { | |
1027 accessibility_object_.updateLayoutAndCheckValidity(); | |
1028 return accessibility_object_.isOffScreen(); | |
1029 } | |
1030 | |
1031 bool WebAXObjectProxy::HasPopup() { | |
1032 accessibility_object_.updateLayoutAndCheckValidity(); | |
1033 return accessibility_object_.ariaHasPopup(); | |
1034 } | |
1035 | |
1036 bool WebAXObjectProxy::IsValid() { | |
1037 accessibility_object_.updateLayoutAndCheckValidity(); | |
1038 return !accessibility_object_.isDetached(); | |
1039 } | |
1040 | |
1041 bool WebAXObjectProxy::IsReadOnly() { | |
1042 accessibility_object_.updateLayoutAndCheckValidity(); | |
1043 return accessibility_object_.isReadOnly(); | |
1044 } | |
1045 | |
1046 unsigned int WebAXObjectProxy::BackgroundColor() { | |
1047 accessibility_object_.updateLayoutAndCheckValidity(); | |
1048 return accessibility_object_.backgroundColor(); | |
1049 } | |
1050 | |
1051 unsigned int WebAXObjectProxy::Color() { | |
1052 accessibility_object_.updateLayoutAndCheckValidity(); | |
1053 unsigned int color = accessibility_object_.color(); | |
1054 // Remove the alpha because it's always 1 and thus not informative. | |
1055 return color & 0xFFFFFF; | |
1056 } | |
1057 | |
1058 // For input elements of type color. | |
1059 unsigned int WebAXObjectProxy::ColorValue() { | |
1060 accessibility_object_.updateLayoutAndCheckValidity(); | |
1061 return accessibility_object_.colorValue(); | |
1062 } | |
1063 | |
1064 std::string WebAXObjectProxy::FontFamily() { | |
1065 accessibility_object_.updateLayoutAndCheckValidity(); | |
1066 std::string font_family(accessibility_object_.fontFamily().utf8()); | |
1067 return font_family.insert(0, "AXFontFamily: "); | |
1068 } | |
1069 | |
1070 float WebAXObjectProxy::FontSize() { | |
1071 accessibility_object_.updateLayoutAndCheckValidity(); | |
1072 return accessibility_object_.fontSize(); | |
1073 } | |
1074 | |
1075 std::string WebAXObjectProxy::Orientation() { | |
1076 accessibility_object_.updateLayoutAndCheckValidity(); | |
1077 if (accessibility_object_.orientation() == blink::WebAXOrientationVertical) | |
1078 return "AXOrientation: AXVerticalOrientation"; | |
1079 else if (accessibility_object_.orientation() | |
1080 == blink::WebAXOrientationHorizontal) | |
1081 return "AXOrientation: AXHorizontalOrientation"; | |
1082 | |
1083 return std::string(); | |
1084 } | |
1085 | |
1086 int WebAXObjectProxy::PosInSet() { | |
1087 accessibility_object_.updateLayoutAndCheckValidity(); | |
1088 return accessibility_object_.posInSet(); | |
1089 } | |
1090 | |
1091 int WebAXObjectProxy::SetSize() { | |
1092 accessibility_object_.updateLayoutAndCheckValidity(); | |
1093 return accessibility_object_.setSize(); | |
1094 } | |
1095 | |
1096 int WebAXObjectProxy::ClickPointX() { | |
1097 accessibility_object_.updateLayoutAndCheckValidity(); | |
1098 blink::WebFloatRect bounds = BoundsForObject(accessibility_object_); | |
1099 return bounds.x + bounds.width / 2; | |
1100 } | |
1101 | |
1102 int WebAXObjectProxy::ClickPointY() { | |
1103 accessibility_object_.updateLayoutAndCheckValidity(); | |
1104 blink::WebFloatRect bounds = BoundsForObject(accessibility_object_); | |
1105 return bounds.y + bounds.height / 2; | |
1106 } | |
1107 | |
1108 int32_t WebAXObjectProxy::RowCount() { | |
1109 accessibility_object_.updateLayoutAndCheckValidity(); | |
1110 return static_cast<int32_t>(accessibility_object_.rowCount()); | |
1111 } | |
1112 | |
1113 int32_t WebAXObjectProxy::RowHeadersCount() { | |
1114 accessibility_object_.updateLayoutAndCheckValidity(); | |
1115 blink::WebVector<blink::WebAXObject> headers; | |
1116 accessibility_object_.rowHeaders(headers); | |
1117 return static_cast<int32_t>(headers.size()); | |
1118 } | |
1119 | |
1120 int32_t WebAXObjectProxy::ColumnCount() { | |
1121 accessibility_object_.updateLayoutAndCheckValidity(); | |
1122 return static_cast<int32_t>(accessibility_object_.columnCount()); | |
1123 } | |
1124 | |
1125 int32_t WebAXObjectProxy::ColumnHeadersCount() | |
1126 { | |
1127 accessibility_object_.updateLayoutAndCheckValidity(); | |
1128 blink::WebVector<blink::WebAXObject> headers; | |
1129 accessibility_object_.columnHeaders(headers); | |
1130 return static_cast<int32_t>(headers.size()); | |
1131 } | |
1132 | |
1133 bool WebAXObjectProxy::IsClickable() { | |
1134 accessibility_object_.updateLayoutAndCheckValidity(); | |
1135 return accessibility_object_.isClickable(); | |
1136 } | |
1137 | |
1138 bool WebAXObjectProxy::IsButtonStateMixed() { | |
1139 accessibility_object_.updateLayoutAndCheckValidity(); | |
1140 return accessibility_object_.isButtonStateMixed(); | |
1141 } | |
1142 | |
1143 v8::Local<v8::Object> WebAXObjectProxy::AriaControlsElementAtIndex( | |
1144 unsigned index) { | |
1145 accessibility_object_.updateLayoutAndCheckValidity(); | |
1146 SparseAttributeAdapter attribute_adapter; | |
1147 accessibility_object_.getSparseAXAttributes(attribute_adapter); | |
1148 blink::WebVector<blink::WebAXObject> elements = | |
1149 attribute_adapter.object_vector_attributes | |
1150 [blink::WebAXObjectVectorAttribute::AriaControls]; | |
1151 size_t elementCount = elements.size(); | |
1152 if (index >= elementCount) | |
1153 return v8::Local<v8::Object>(); | |
1154 | |
1155 return factory_->GetOrCreate(elements[index]); | |
1156 } | |
1157 | |
1158 v8::Local<v8::Object> WebAXObjectProxy::AriaFlowToElementAtIndex( | |
1159 unsigned index) { | |
1160 accessibility_object_.updateLayoutAndCheckValidity(); | |
1161 SparseAttributeAdapter attribute_adapter; | |
1162 accessibility_object_.getSparseAXAttributes(attribute_adapter); | |
1163 blink::WebVector<blink::WebAXObject> elements = | |
1164 attribute_adapter.object_vector_attributes | |
1165 [blink::WebAXObjectVectorAttribute::AriaFlowTo]; | |
1166 size_t elementCount = elements.size(); | |
1167 if (index >= elementCount) | |
1168 return v8::Local<v8::Object>(); | |
1169 | |
1170 return factory_->GetOrCreate(elements[index]); | |
1171 } | |
1172 | |
1173 v8::Local<v8::Object> WebAXObjectProxy::AriaOwnsElementAtIndex(unsigned index) | |
1174 { | |
1175 accessibility_object_.updateLayoutAndCheckValidity(); | |
1176 blink::WebVector<blink::WebAXObject> elements; | |
1177 accessibility_object_.ariaOwns(elements); | |
1178 size_t elementCount = elements.size(); | |
1179 if (index >= elementCount) | |
1180 return v8::Local<v8::Object>(); | |
1181 | |
1182 return factory_->GetOrCreate(elements[index]); | |
1183 } | |
1184 | |
1185 std::string WebAXObjectProxy::AllAttributes() { | |
1186 accessibility_object_.updateLayoutAndCheckValidity(); | |
1187 return GetAttributes(accessibility_object_); | |
1188 } | |
1189 | |
1190 std::string WebAXObjectProxy::AttributesOfChildren() { | |
1191 accessibility_object_.updateLayoutAndCheckValidity(); | |
1192 AttributesCollector collector; | |
1193 unsigned size = accessibility_object_.childCount(); | |
1194 for (unsigned i = 0; i < size; ++i) | |
1195 collector.CollectAttributes(accessibility_object_.childAt(i)); | |
1196 return collector.attributes(); | |
1197 } | |
1198 | |
1199 int WebAXObjectProxy::LineForIndex(int index) { | |
1200 accessibility_object_.updateLayoutAndCheckValidity(); | |
1201 blink::WebVector<int> line_breaks; | |
1202 accessibility_object_.lineBreaks(line_breaks); | |
1203 int line = 0; | |
1204 int vector_size = static_cast<int>(line_breaks.size()); | |
1205 while (line < vector_size && line_breaks[line] <= index) | |
1206 line++; | |
1207 return line; | |
1208 } | |
1209 | |
1210 std::string WebAXObjectProxy::BoundsForRange(int start, int end) { | |
1211 accessibility_object_.updateLayoutAndCheckValidity(); | |
1212 if (accessibility_object_.role() != blink::WebAXRoleStaticText) | |
1213 return std::string(); | |
1214 | |
1215 if (!accessibility_object_.updateLayoutAndCheckValidity()) | |
1216 return std::string(); | |
1217 | |
1218 int len = end - start; | |
1219 | |
1220 // Get the bounds for each character and union them into one large rectangle. | |
1221 // This is just for testing so it doesn't need to be efficient. | |
1222 blink::WebRect bounds = BoundsForCharacter(accessibility_object_, start); | |
1223 for (int i = 1; i < len; i++) { | |
1224 blink::WebRect next = BoundsForCharacter(accessibility_object_, start + i); | |
1225 int right = std::max(bounds.x + bounds.width, next.x + next.width); | |
1226 int bottom = std::max(bounds.y + bounds.height, next.y + next.height); | |
1227 bounds.x = std::min(bounds.x, next.x); | |
1228 bounds.y = std::min(bounds.y, next.y); | |
1229 bounds.width = right - bounds.x; | |
1230 bounds.height = bottom - bounds.y; | |
1231 } | |
1232 | |
1233 return base::StringPrintf("{x: %d, y: %d, width: %d, height: %d}", | |
1234 bounds.x, bounds.y, bounds.width, bounds.height); | |
1235 } | |
1236 | |
1237 v8::Local<v8::Object> WebAXObjectProxy::ChildAtIndex(int index) { | |
1238 accessibility_object_.updateLayoutAndCheckValidity(); | |
1239 return GetChildAtIndex(index); | |
1240 } | |
1241 | |
1242 v8::Local<v8::Object> WebAXObjectProxy::ElementAtPoint(int x, int y) { | |
1243 accessibility_object_.updateLayoutAndCheckValidity(); | |
1244 blink::WebPoint point(x, y); | |
1245 blink::WebAXObject obj = accessibility_object_.hitTest(point); | |
1246 if (obj.isNull()) | |
1247 return v8::Local<v8::Object>(); | |
1248 | |
1249 return factory_->GetOrCreate(obj); | |
1250 } | |
1251 | |
1252 v8::Local<v8::Object> WebAXObjectProxy::TableHeader() { | |
1253 accessibility_object_.updateLayoutAndCheckValidity(); | |
1254 blink::WebAXObject obj = accessibility_object_.headerContainerObject(); | |
1255 if (obj.isNull()) | |
1256 return v8::Local<v8::Object>(); | |
1257 | |
1258 return factory_->GetOrCreate(obj); | |
1259 } | |
1260 | |
1261 v8::Local<v8::Object> WebAXObjectProxy::RowHeaderAtIndex(unsigned index) { | |
1262 accessibility_object_.updateLayoutAndCheckValidity(); | |
1263 blink::WebVector<blink::WebAXObject> headers; | |
1264 accessibility_object_.rowHeaders(headers); | |
1265 size_t headerCount = headers.size(); | |
1266 if (index >= headerCount) | |
1267 return v8::Local<v8::Object>(); | |
1268 | |
1269 return factory_->GetOrCreate(headers[index]); | |
1270 } | |
1271 | |
1272 v8::Local<v8::Object> WebAXObjectProxy::ColumnHeaderAtIndex(unsigned index) { | |
1273 accessibility_object_.updateLayoutAndCheckValidity(); | |
1274 blink::WebVector<blink::WebAXObject> headers; | |
1275 accessibility_object_.columnHeaders(headers); | |
1276 size_t headerCount = headers.size(); | |
1277 if (index >= headerCount) | |
1278 return v8::Local<v8::Object>(); | |
1279 | |
1280 return factory_->GetOrCreate(headers[index]); | |
1281 } | |
1282 | |
1283 std::string WebAXObjectProxy::RowIndexRange() { | |
1284 accessibility_object_.updateLayoutAndCheckValidity(); | |
1285 unsigned row_index = accessibility_object_.cellRowIndex(); | |
1286 unsigned row_span = accessibility_object_.cellRowSpan(); | |
1287 return base::StringPrintf("{%d, %d}", row_index, row_span); | |
1288 } | |
1289 | |
1290 std::string WebAXObjectProxy::ColumnIndexRange() { | |
1291 accessibility_object_.updateLayoutAndCheckValidity(); | |
1292 unsigned column_index = accessibility_object_.cellColumnIndex(); | |
1293 unsigned column_span = accessibility_object_.cellColumnSpan(); | |
1294 return base::StringPrintf("{%d, %d}", column_index, column_span); | |
1295 } | |
1296 | |
1297 v8::Local<v8::Object> WebAXObjectProxy::CellForColumnAndRow( | |
1298 int column, int row) { | |
1299 accessibility_object_.updateLayoutAndCheckValidity(); | |
1300 blink::WebAXObject obj = | |
1301 accessibility_object_.cellForColumnAndRow(column, row); | |
1302 if (obj.isNull()) | |
1303 return v8::Local<v8::Object>(); | |
1304 | |
1305 return factory_->GetOrCreate(obj); | |
1306 } | |
1307 | |
1308 void WebAXObjectProxy::SetSelectedTextRange(int selection_start, | |
1309 int length) { | |
1310 accessibility_object_.updateLayoutAndCheckValidity(); | |
1311 accessibility_object_.setSelectedTextRange(selection_start, | |
1312 selection_start + length); | |
1313 } | |
1314 | |
1315 void WebAXObjectProxy::SetSelection( | |
1316 v8::Local<v8::Value> anchor_object, int anchor_offset, | |
1317 v8::Local<v8::Value> focus_object, int focus_offset) { | |
1318 if (anchor_object.IsEmpty() || focus_object.IsEmpty() || | |
1319 !anchor_object->IsObject() || !focus_object->IsObject() || | |
1320 anchor_offset < 0 || focus_offset < 0) { | |
1321 return; | |
1322 } | |
1323 | |
1324 WebAXObjectProxy* web_ax_anchor = nullptr; | |
1325 if (!gin::ConvertFromV8( | |
1326 blink::mainThreadIsolate(), anchor_object, &web_ax_anchor)) { | |
1327 return; | |
1328 } | |
1329 DCHECK(web_ax_anchor); | |
1330 | |
1331 WebAXObjectProxy* web_ax_focus = nullptr; | |
1332 if (!gin::ConvertFromV8( | |
1333 blink::mainThreadIsolate(), focus_object, &web_ax_focus)) { | |
1334 return; | |
1335 } | |
1336 DCHECK(web_ax_focus); | |
1337 | |
1338 accessibility_object_.updateLayoutAndCheckValidity(); | |
1339 accessibility_object_.setSelection( | |
1340 web_ax_anchor->accessibility_object_, anchor_offset, | |
1341 web_ax_focus->accessibility_object_, focus_offset); | |
1342 } | |
1343 | |
1344 bool WebAXObjectProxy::IsAttributeSettable(const std::string& attribute) { | |
1345 accessibility_object_.updateLayoutAndCheckValidity(); | |
1346 bool settable = false; | |
1347 if (attribute == "AXValue") | |
1348 settable = accessibility_object_.canSetValueAttribute(); | |
1349 return settable; | |
1350 } | |
1351 | |
1352 bool WebAXObjectProxy::IsPressActionSupported() { | |
1353 accessibility_object_.updateLayoutAndCheckValidity(); | |
1354 return accessibility_object_.canPress(); | |
1355 } | |
1356 | |
1357 bool WebAXObjectProxy::IsIncrementActionSupported() { | |
1358 accessibility_object_.updateLayoutAndCheckValidity(); | |
1359 return accessibility_object_.canIncrement(); | |
1360 } | |
1361 | |
1362 bool WebAXObjectProxy::IsDecrementActionSupported() { | |
1363 accessibility_object_.updateLayoutAndCheckValidity(); | |
1364 return accessibility_object_.canDecrement(); | |
1365 } | |
1366 | |
1367 v8::Local<v8::Object> WebAXObjectProxy::ParentElement() { | |
1368 accessibility_object_.updateLayoutAndCheckValidity(); | |
1369 blink::WebAXObject parent_object = accessibility_object_.parentObject(); | |
1370 while (parent_object.accessibilityIsIgnored()) | |
1371 parent_object = parent_object.parentObject(); | |
1372 return factory_->GetOrCreate(parent_object); | |
1373 } | |
1374 | |
1375 void WebAXObjectProxy::Increment() { | |
1376 accessibility_object_.updateLayoutAndCheckValidity(); | |
1377 accessibility_object_.increment(); | |
1378 } | |
1379 | |
1380 void WebAXObjectProxy::Decrement() { | |
1381 accessibility_object_.updateLayoutAndCheckValidity(); | |
1382 accessibility_object_.decrement(); | |
1383 } | |
1384 | |
1385 void WebAXObjectProxy::ShowMenu() { | |
1386 accessibility_object_.showContextMenu(); | |
1387 } | |
1388 | |
1389 void WebAXObjectProxy::Press() { | |
1390 accessibility_object_.updateLayoutAndCheckValidity(); | |
1391 accessibility_object_.press(); | |
1392 } | |
1393 | |
1394 bool WebAXObjectProxy::SetValue(const std::string& value) { | |
1395 accessibility_object_.updateLayoutAndCheckValidity(); | |
1396 if (!accessibility_object_.canSetValueAttribute()) | |
1397 return false; | |
1398 | |
1399 accessibility_object_.setValue(blink::WebString::fromUTF8(value)); | |
1400 return true; | |
1401 } | |
1402 | |
1403 bool WebAXObjectProxy::IsEqual(v8::Local<v8::Object> proxy) { | |
1404 WebAXObjectProxy* unwrapped_proxy = NULL; | |
1405 if (!gin::ConvertFromV8(blink::mainThreadIsolate(), proxy, &unwrapped_proxy)) | |
1406 return false; | |
1407 return unwrapped_proxy->IsEqualToObject(accessibility_object_); | |
1408 } | |
1409 | |
1410 void WebAXObjectProxy::SetNotificationListener( | |
1411 v8::Local<v8::Function> callback) { | |
1412 v8::Isolate* isolate = blink::mainThreadIsolate(); | |
1413 notification_callback_.Reset(isolate, callback); | |
1414 } | |
1415 | |
1416 void WebAXObjectProxy::UnsetNotificationListener() { | |
1417 notification_callback_.Reset(); | |
1418 } | |
1419 | |
1420 void WebAXObjectProxy::TakeFocus() { | |
1421 accessibility_object_.updateLayoutAndCheckValidity(); | |
1422 accessibility_object_.setFocused(true); | |
1423 } | |
1424 | |
1425 void WebAXObjectProxy::ScrollToMakeVisible() { | |
1426 accessibility_object_.updateLayoutAndCheckValidity(); | |
1427 accessibility_object_.scrollToMakeVisible(); | |
1428 } | |
1429 | |
1430 void WebAXObjectProxy::ScrollToMakeVisibleWithSubFocus(int x, int y, | |
1431 int width, int height) { | |
1432 accessibility_object_.updateLayoutAndCheckValidity(); | |
1433 accessibility_object_.scrollToMakeVisibleWithSubFocus( | |
1434 blink::WebRect(x, y, width, height)); | |
1435 } | |
1436 | |
1437 void WebAXObjectProxy::ScrollToGlobalPoint(int x, int y) { | |
1438 accessibility_object_.updateLayoutAndCheckValidity(); | |
1439 accessibility_object_.scrollToGlobalPoint(blink::WebPoint(x, y)); | |
1440 } | |
1441 | |
1442 int WebAXObjectProxy::ScrollX() { | |
1443 accessibility_object_.updateLayoutAndCheckValidity(); | |
1444 return accessibility_object_.getScrollOffset().x; | |
1445 } | |
1446 | |
1447 int WebAXObjectProxy::ScrollY() { | |
1448 accessibility_object_.updateLayoutAndCheckValidity(); | |
1449 return accessibility_object_.getScrollOffset().y; | |
1450 } | |
1451 | |
1452 float WebAXObjectProxy::BoundsX() { | |
1453 accessibility_object_.updateLayoutAndCheckValidity(); | |
1454 return BoundsForObject(accessibility_object_).x; | |
1455 } | |
1456 | |
1457 float WebAXObjectProxy::BoundsY() { | |
1458 accessibility_object_.updateLayoutAndCheckValidity(); | |
1459 return BoundsForObject(accessibility_object_).y; | |
1460 } | |
1461 | |
1462 float WebAXObjectProxy::BoundsWidth() { | |
1463 accessibility_object_.updateLayoutAndCheckValidity(); | |
1464 return BoundsForObject(accessibility_object_).width; | |
1465 } | |
1466 | |
1467 float WebAXObjectProxy::BoundsHeight() { | |
1468 accessibility_object_.updateLayoutAndCheckValidity(); | |
1469 return BoundsForObject(accessibility_object_).height; | |
1470 } | |
1471 | |
1472 int WebAXObjectProxy::WordStart(int character_index) { | |
1473 accessibility_object_.updateLayoutAndCheckValidity(); | |
1474 if (accessibility_object_.role() != blink::WebAXRoleStaticText) | |
1475 return -1; | |
1476 | |
1477 int word_start = 0, word_end = 0; | |
1478 GetBoundariesForOneWord(accessibility_object_, character_index, | |
1479 word_start, word_end); | |
1480 return word_start; | |
1481 } | |
1482 | |
1483 int WebAXObjectProxy::WordEnd(int character_index) { | |
1484 accessibility_object_.updateLayoutAndCheckValidity(); | |
1485 if (accessibility_object_.role() != blink::WebAXRoleStaticText) | |
1486 return -1; | |
1487 | |
1488 int word_start = 0, word_end = 0; | |
1489 GetBoundariesForOneWord(accessibility_object_, character_index, | |
1490 word_start, word_end); | |
1491 return word_end; | |
1492 } | |
1493 | |
1494 v8::Local<v8::Object> WebAXObjectProxy::NextOnLine() { | |
1495 accessibility_object_.updateLayoutAndCheckValidity(); | |
1496 blink::WebAXObject obj = accessibility_object_.nextOnLine(); | |
1497 if (obj.isNull()) | |
1498 return v8::Local<v8::Object>(); | |
1499 | |
1500 return factory_->GetOrCreate(obj); | |
1501 } | |
1502 | |
1503 v8::Local<v8::Object> WebAXObjectProxy::PreviousOnLine() { | |
1504 accessibility_object_.updateLayoutAndCheckValidity(); | |
1505 blink::WebAXObject obj = accessibility_object_.previousOnLine(); | |
1506 if (obj.isNull()) | |
1507 return v8::Local<v8::Object>(); | |
1508 | |
1509 return factory_->GetOrCreate(obj); | |
1510 } | |
1511 | |
1512 std::string WebAXObjectProxy::MisspellingAtIndex(int index) { | |
1513 accessibility_object_.updateLayoutAndCheckValidity(); | |
1514 if (index < 0 || index >= MisspellingsCount()) | |
1515 return std::string(); | |
1516 return GetMisspellings(accessibility_object_)[index]; | |
1517 } | |
1518 | |
1519 std::string WebAXObjectProxy::Name() { | |
1520 accessibility_object_.updateLayoutAndCheckValidity(); | |
1521 return accessibility_object_.name().utf8(); | |
1522 } | |
1523 | |
1524 std::string WebAXObjectProxy::NameFrom() { | |
1525 accessibility_object_.updateLayoutAndCheckValidity(); | |
1526 blink::WebAXNameFrom nameFrom = blink::WebAXNameFromUninitialized; | |
1527 blink::WebVector<blink::WebAXObject> nameObjects; | |
1528 accessibility_object_.name(nameFrom, nameObjects); | |
1529 switch(nameFrom) { | |
1530 case blink::WebAXNameFromUninitialized: | |
1531 return ""; | |
1532 case blink::WebAXNameFromAttribute: | |
1533 return "attribute"; | |
1534 case blink::WebAXNameFromCaption: | |
1535 return "caption"; | |
1536 case blink::WebAXNameFromContents: | |
1537 return "contents"; | |
1538 case blink::WebAXNameFromPlaceholder: | |
1539 return "placeholder"; | |
1540 case blink::WebAXNameFromRelatedElement: | |
1541 return "relatedElement"; | |
1542 case blink::WebAXNameFromValue: | |
1543 return "value"; | |
1544 case blink::WebAXNameFromTitle: | |
1545 return "title"; | |
1546 } | |
1547 | |
1548 NOTREACHED(); | |
1549 return std::string(); | |
1550 } | |
1551 | |
1552 int WebAXObjectProxy::NameElementCount() { | |
1553 accessibility_object_.updateLayoutAndCheckValidity(); | |
1554 blink::WebAXNameFrom nameFrom; | |
1555 blink::WebVector<blink::WebAXObject> nameObjects; | |
1556 accessibility_object_.name(nameFrom, nameObjects); | |
1557 return static_cast<int>(nameObjects.size()); | |
1558 } | |
1559 | |
1560 v8::Local<v8::Object> WebAXObjectProxy::NameElementAtIndex(unsigned index) { | |
1561 accessibility_object_.updateLayoutAndCheckValidity(); | |
1562 blink::WebAXNameFrom nameFrom; | |
1563 blink::WebVector<blink::WebAXObject> nameObjects; | |
1564 accessibility_object_.name(nameFrom, nameObjects); | |
1565 if (index >= nameObjects.size()) | |
1566 return v8::Local<v8::Object>(); | |
1567 return factory_->GetOrCreate(nameObjects[index]); | |
1568 } | |
1569 | |
1570 std::string WebAXObjectProxy::Description() { | |
1571 accessibility_object_.updateLayoutAndCheckValidity(); | |
1572 blink::WebAXNameFrom nameFrom; | |
1573 blink::WebVector<blink::WebAXObject> nameObjects; | |
1574 accessibility_object_.name(nameFrom, nameObjects); | |
1575 blink::WebAXDescriptionFrom descriptionFrom; | |
1576 blink::WebVector<blink::WebAXObject> descriptionObjects; | |
1577 return accessibility_object_.description( | |
1578 nameFrom, descriptionFrom, descriptionObjects).utf8(); | |
1579 } | |
1580 | |
1581 std::string WebAXObjectProxy::DescriptionFrom() { | |
1582 accessibility_object_.updateLayoutAndCheckValidity(); | |
1583 blink::WebAXNameFrom nameFrom; | |
1584 blink::WebVector<blink::WebAXObject> nameObjects; | |
1585 accessibility_object_.name(nameFrom, nameObjects); | |
1586 blink::WebAXDescriptionFrom descriptionFrom = | |
1587 blink::WebAXDescriptionFromUninitialized; | |
1588 blink::WebVector<blink::WebAXObject> descriptionObjects; | |
1589 accessibility_object_.description( | |
1590 nameFrom, descriptionFrom, descriptionObjects); | |
1591 switch(descriptionFrom) { | |
1592 case blink::WebAXDescriptionFromUninitialized: | |
1593 return ""; | |
1594 case blink::WebAXDescriptionFromAttribute: | |
1595 return "attribute"; | |
1596 case blink::WebAXDescriptionFromContents: | |
1597 return "contents"; | |
1598 case blink::WebAXDescriptionFromRelatedElement: | |
1599 return "relatedElement"; | |
1600 } | |
1601 | |
1602 NOTREACHED(); | |
1603 return std::string(); | |
1604 } | |
1605 | |
1606 std::string WebAXObjectProxy::Placeholder() { | |
1607 accessibility_object_.updateLayoutAndCheckValidity(); | |
1608 blink::WebAXNameFrom nameFrom; | |
1609 blink::WebVector<blink::WebAXObject> nameObjects; | |
1610 accessibility_object_.name(nameFrom, nameObjects); | |
1611 return accessibility_object_.placeholder(nameFrom).utf8(); | |
1612 } | |
1613 | |
1614 int WebAXObjectProxy::MisspellingsCount() { | |
1615 accessibility_object_.updateLayoutAndCheckValidity(); | |
1616 return GetMisspellings(accessibility_object_).size(); | |
1617 } | |
1618 | |
1619 int WebAXObjectProxy::DescriptionElementCount() { | |
1620 accessibility_object_.updateLayoutAndCheckValidity(); | |
1621 blink::WebAXNameFrom nameFrom; | |
1622 blink::WebVector<blink::WebAXObject> nameObjects; | |
1623 accessibility_object_.name(nameFrom, nameObjects); | |
1624 blink::WebAXDescriptionFrom descriptionFrom; | |
1625 blink::WebVector<blink::WebAXObject> descriptionObjects; | |
1626 accessibility_object_.description( | |
1627 nameFrom, descriptionFrom, descriptionObjects); | |
1628 return static_cast<int>(descriptionObjects.size()); | |
1629 } | |
1630 | |
1631 v8::Local<v8::Object> WebAXObjectProxy::DescriptionElementAtIndex( | |
1632 unsigned index) { | |
1633 accessibility_object_.updateLayoutAndCheckValidity(); | |
1634 blink::WebAXNameFrom nameFrom; | |
1635 blink::WebVector<blink::WebAXObject> nameObjects; | |
1636 accessibility_object_.name(nameFrom, nameObjects); | |
1637 blink::WebAXDescriptionFrom descriptionFrom; | |
1638 blink::WebVector<blink::WebAXObject> descriptionObjects; | |
1639 accessibility_object_.description( | |
1640 nameFrom, descriptionFrom, descriptionObjects); | |
1641 if (index >= descriptionObjects.size()) | |
1642 return v8::Local<v8::Object>(); | |
1643 return factory_->GetOrCreate(descriptionObjects[index]); | |
1644 } | |
1645 | |
1646 v8::Local<v8::Object> WebAXObjectProxy::OffsetContainer() { | |
1647 accessibility_object_.updateLayoutAndCheckValidity(); | |
1648 blink::WebAXObject container; | |
1649 blink::WebFloatRect bounds; | |
1650 SkMatrix44 matrix; | |
1651 accessibility_object_.getRelativeBounds(container, bounds, matrix); | |
1652 return factory_->GetOrCreate(container); | |
1653 } | |
1654 | |
1655 float WebAXObjectProxy::BoundsInContainerX() { | |
1656 accessibility_object_.updateLayoutAndCheckValidity(); | |
1657 blink::WebAXObject container; | |
1658 blink::WebFloatRect bounds; | |
1659 SkMatrix44 matrix; | |
1660 accessibility_object_.getRelativeBounds(container, bounds, matrix); | |
1661 return bounds.x; | |
1662 } | |
1663 | |
1664 float WebAXObjectProxy::BoundsInContainerY() { | |
1665 accessibility_object_.updateLayoutAndCheckValidity(); | |
1666 blink::WebAXObject container; | |
1667 blink::WebFloatRect bounds; | |
1668 SkMatrix44 matrix; | |
1669 accessibility_object_.getRelativeBounds(container, bounds, matrix); | |
1670 return bounds.y; | |
1671 } | |
1672 | |
1673 float WebAXObjectProxy::BoundsInContainerWidth() { | |
1674 accessibility_object_.updateLayoutAndCheckValidity(); | |
1675 blink::WebAXObject container; | |
1676 blink::WebFloatRect bounds; | |
1677 SkMatrix44 matrix; | |
1678 accessibility_object_.getRelativeBounds(container, bounds, matrix); | |
1679 return bounds.width; | |
1680 } | |
1681 | |
1682 float WebAXObjectProxy::BoundsInContainerHeight() { | |
1683 accessibility_object_.updateLayoutAndCheckValidity(); | |
1684 blink::WebAXObject container; | |
1685 blink::WebFloatRect bounds; | |
1686 SkMatrix44 matrix; | |
1687 accessibility_object_.getRelativeBounds(container, bounds, matrix); | |
1688 return bounds.height; | |
1689 } | |
1690 | |
1691 bool WebAXObjectProxy::HasNonIdentityTransform() { | |
1692 accessibility_object_.updateLayoutAndCheckValidity(); | |
1693 accessibility_object_.updateLayoutAndCheckValidity(); | |
1694 blink::WebAXObject container; | |
1695 blink::WebFloatRect bounds; | |
1696 SkMatrix44 matrix; | |
1697 accessibility_object_.getRelativeBounds(container, bounds, matrix); | |
1698 return !matrix.isIdentity(); | |
1699 } | |
1700 | |
1701 RootWebAXObjectProxy::RootWebAXObjectProxy( | |
1702 const blink::WebAXObject &object, Factory *factory) | |
1703 : WebAXObjectProxy(object, factory) { | |
1704 } | |
1705 | |
1706 v8::Local<v8::Object> RootWebAXObjectProxy::GetChildAtIndex(unsigned index) { | |
1707 if (index) | |
1708 return v8::Local<v8::Object>(); | |
1709 | |
1710 return factory()->GetOrCreate(accessibility_object()); | |
1711 } | |
1712 | |
1713 bool RootWebAXObjectProxy::IsRoot() const { | |
1714 return true; | |
1715 } | |
1716 | |
1717 WebAXObjectProxyList::WebAXObjectProxyList() | |
1718 : elements_(blink::mainThreadIsolate()) { | |
1719 } | |
1720 | |
1721 WebAXObjectProxyList::~WebAXObjectProxyList() { | |
1722 Clear(); | |
1723 } | |
1724 | |
1725 void WebAXObjectProxyList::Clear() { | |
1726 v8::Isolate* isolate = blink::mainThreadIsolate(); | |
1727 v8::HandleScope handle_scope(isolate); | |
1728 size_t elementCount = elements_.Size(); | |
1729 for (size_t i = 0; i < elementCount; i++) { | |
1730 WebAXObjectProxy* unwrapped_object = NULL; | |
1731 bool result = gin::ConvertFromV8(isolate, elements_.Get(i), | |
1732 &unwrapped_object); | |
1733 DCHECK(result); | |
1734 DCHECK(unwrapped_object); | |
1735 unwrapped_object->Reset(); | |
1736 } | |
1737 elements_.Clear(); | |
1738 } | |
1739 | |
1740 v8::Local<v8::Object> WebAXObjectProxyList::GetOrCreate( | |
1741 const blink::WebAXObject& object) { | |
1742 if (object.isNull()) | |
1743 return v8::Local<v8::Object>(); | |
1744 | |
1745 v8::Isolate* isolate = blink::mainThreadIsolate(); | |
1746 | |
1747 size_t elementCount = elements_.Size(); | |
1748 for (size_t i = 0; i < elementCount; i++) { | |
1749 WebAXObjectProxy* unwrapped_object = NULL; | |
1750 bool result = gin::ConvertFromV8(isolate, elements_.Get(i), | |
1751 &unwrapped_object); | |
1752 DCHECK(result); | |
1753 DCHECK(unwrapped_object); | |
1754 if (unwrapped_object->IsEqualToObject(object)) | |
1755 return elements_.Get(i); | |
1756 } | |
1757 | |
1758 v8::Local<v8::Value> value_handle = gin::CreateHandle( | |
1759 isolate, new WebAXObjectProxy(object, this)).ToV8(); | |
1760 if (value_handle.IsEmpty()) | |
1761 return v8::Local<v8::Object>(); | |
1762 v8::Local<v8::Object> handle = value_handle->ToObject(isolate); | |
1763 elements_.Append(handle); | |
1764 return handle; | |
1765 } | |
1766 | |
1767 } // namespace test_runner | |
OLD | NEW |