Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(241)

Side by Side Diff: components/test_runner/web_ax_object_proxy.cc

Issue 2707183003: Move //components/test_runner back into //content/shell (Closed)
Patch Set: Trim DEPS Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698