Linux: Depend on liberation-fonts package for RPMs.
[chromium-blink-merge.git] / components / test_runner / web_ax_object_proxy.cc
blob38c6afd513946392debf477c2e2d80ac40809b2d
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.
5 #include "components/test_runner/web_ax_object_proxy.h"
7 #include "base/strings/stringprintf.h"
8 #include "gin/handle.h"
9 #include "third_party/WebKit/public/platform/WebPoint.h"
10 #include "third_party/WebKit/public/platform/WebRect.h"
11 #include "third_party/WebKit/public/platform/WebString.h"
12 #include "third_party/WebKit/public/web/WebFrame.h"
13 #include "third_party/WebKit/public/web/WebKit.h"
15 namespace test_runner {
17 namespace {
19 // Map role value to string, matching Safari/Mac platform implementation to
20 // avoid rebaselining layout tests.
21 std::string RoleToString(blink::WebAXRole role)
23 std::string result = "AXRole: AX";
24 switch (role) {
25 case blink::WebAXRoleAlertDialog:
26 return result.append("AlertDialog");
27 case blink::WebAXRoleAlert:
28 return result.append("Alert");
29 case blink::WebAXRoleAnnotation:
30 return result.append("Annotation");
31 case blink::WebAXRoleApplication:
32 return result.append("Application");
33 case blink::WebAXRoleArticle:
34 return result.append("Article");
35 case blink::WebAXRoleBanner:
36 return result.append("Banner");
37 case blink::WebAXRoleBlockquote:
38 return result.append("Blockquote");
39 case blink::WebAXRoleBusyIndicator:
40 return result.append("BusyIndicator");
41 case blink::WebAXRoleButton:
42 return result.append("Button");
43 case blink::WebAXRoleCanvas:
44 return result.append("Canvas");
45 case blink::WebAXRoleCaption:
46 return result.append("Caption");
47 case blink::WebAXRoleCell:
48 return result.append("Cell");
49 case blink::WebAXRoleCheckBox:
50 return result.append("CheckBox");
51 case blink::WebAXRoleColorWell:
52 return result.append("ColorWell");
53 case blink::WebAXRoleColumnHeader:
54 return result.append("ColumnHeader");
55 case blink::WebAXRoleColumn:
56 return result.append("Column");
57 case blink::WebAXRoleComboBox:
58 return result.append("ComboBox");
59 case blink::WebAXRoleComplementary:
60 return result.append("Complementary");
61 case blink::WebAXRoleContentInfo:
62 return result.append("ContentInfo");
63 case blink::WebAXRoleDate:
64 return result.append("DateField");
65 case blink::WebAXRoleDateTime:
66 return result.append("DateTimeField");
67 case blink::WebAXRoleDefinition:
68 return result.append("Definition");
69 case blink::WebAXRoleDescriptionListDetail:
70 return result.append("DescriptionListDetail");
71 case blink::WebAXRoleDescriptionList:
72 return result.append("DescriptionList");
73 case blink::WebAXRoleDescriptionListTerm:
74 return result.append("DescriptionListTerm");
75 case blink::WebAXRoleDetails:
76 return result.append("Details");
77 case blink::WebAXRoleDialog:
78 return result.append("Dialog");
79 case blink::WebAXRoleDirectory:
80 return result.append("Directory");
81 case blink::WebAXRoleDisclosureTriangle:
82 return result.append("DisclosureTriangle");
83 case blink::WebAXRoleDiv:
84 return result.append("Div");
85 case blink::WebAXRoleDocument:
86 return result.append("Document");
87 case blink::WebAXRoleEmbeddedObject:
88 return result.append("EmbeddedObject");
89 case blink::WebAXRoleFigcaption:
90 return result.append("Figcaption");
91 case blink::WebAXRoleFigure:
92 return result.append("Figure");
93 case blink::WebAXRoleFooter:
94 return result.append("Footer");
95 case blink::WebAXRoleForm:
96 return result.append("Form");
97 case blink::WebAXRoleGrid:
98 return result.append("Grid");
99 case blink::WebAXRoleGroup:
100 return result.append("Group");
101 case blink::WebAXRoleHeading:
102 return result.append("Heading");
103 case blink::WebAXRoleIgnored:
104 return result.append("Ignored");
105 case blink::WebAXRoleImageMapLink:
106 return result.append("ImageMapLink");
107 case blink::WebAXRoleImageMap:
108 return result.append("ImageMap");
109 case blink::WebAXRoleImage:
110 return result.append("Image");
111 case blink::WebAXRoleInlineTextBox:
112 return result.append("InlineTextBox");
113 case blink::WebAXRoleInputTime:
114 return result.append("InputTime");
115 case blink::WebAXRoleLabel:
116 return result.append("Label");
117 case blink::WebAXRoleLegend:
118 return result.append("Legend");
119 case blink::WebAXRoleLink:
120 return result.append("Link");
121 case blink::WebAXRoleListBoxOption:
122 return result.append("ListBoxOption");
123 case blink::WebAXRoleListBox:
124 return result.append("ListBox");
125 case blink::WebAXRoleListItem:
126 return result.append("ListItem");
127 case blink::WebAXRoleListMarker:
128 return result.append("ListMarker");
129 case blink::WebAXRoleList:
130 return result.append("List");
131 case blink::WebAXRoleLog:
132 return result.append("Log");
133 case blink::WebAXRoleMain:
134 return result.append("Main");
135 case blink::WebAXRoleMark:
136 return result.append("Mark");
137 case blink::WebAXRoleMarquee:
138 return result.append("Marquee");
139 case blink::WebAXRoleMath:
140 return result.append("Math");
141 case blink::WebAXRoleMenuBar:
142 return result.append("MenuBar");
143 case blink::WebAXRoleMenuButton:
144 return result.append("MenuButton");
145 case blink::WebAXRoleMenuItem:
146 return result.append("MenuItem");
147 case blink::WebAXRoleMenuItemCheckBox:
148 return result.append("MenuItemCheckBox");
149 case blink::WebAXRoleMenuItemRadio:
150 return result.append("MenuItemRadio");
151 case blink::WebAXRoleMenuListOption:
152 return result.append("MenuListOption");
153 case blink::WebAXRoleMenuListPopup:
154 return result.append("MenuListPopup");
155 case blink::WebAXRoleMenu:
156 return result.append("Menu");
157 case blink::WebAXRoleMeter:
158 return result.append("Meter");
159 case blink::WebAXRoleNavigation:
160 return result.append("Navigation");
161 case blink::WebAXRoleNone:
162 return result.append("None");
163 case blink::WebAXRoleNote:
164 return result.append("Note");
165 case blink::WebAXRoleOutline:
166 return result.append("Outline");
167 case blink::WebAXRoleParagraph:
168 return result.append("Paragraph");
169 case blink::WebAXRolePopUpButton:
170 return result.append("PopUpButton");
171 case blink::WebAXRolePre:
172 return result.append("Pre");
173 case blink::WebAXRolePresentational:
174 return result.append("Presentational");
175 case blink::WebAXRoleProgressIndicator:
176 return result.append("ProgressIndicator");
177 case blink::WebAXRoleRadioButton:
178 return result.append("RadioButton");
179 case blink::WebAXRoleRadioGroup:
180 return result.append("RadioGroup");
181 case blink::WebAXRoleRegion:
182 return result.append("Region");
183 case blink::WebAXRoleRootWebArea:
184 return result.append("RootWebArea");
185 case blink::WebAXRoleRowHeader:
186 return result.append("RowHeader");
187 case blink::WebAXRoleRow:
188 return result.append("Row");
189 case blink::WebAXRoleRuby:
190 return result.append("Ruby");
191 case blink::WebAXRoleRuler:
192 return result.append("Ruler");
193 case blink::WebAXRoleSVGRoot:
194 return result.append("SVGRoot");
195 case blink::WebAXRoleScrollArea:
196 return result.append("ScrollArea");
197 case blink::WebAXRoleScrollBar:
198 return result.append("ScrollBar");
199 case blink::WebAXRoleSeamlessWebArea:
200 return result.append("SeamlessWebArea");
201 case blink::WebAXRoleSearch:
202 return result.append("Search");
203 case blink::WebAXRoleSearchBox:
204 return result.append("SearchBox");
205 case blink::WebAXRoleSlider:
206 return result.append("Slider");
207 case blink::WebAXRoleSliderThumb:
208 return result.append("SliderThumb");
209 case blink::WebAXRoleSpinButtonPart:
210 return result.append("SpinButtonPart");
211 case blink::WebAXRoleSpinButton:
212 return result.append("SpinButton");
213 case blink::WebAXRoleSplitter:
214 return result.append("Splitter");
215 case blink::WebAXRoleStaticText:
216 return result.append("StaticText");
217 case blink::WebAXRoleStatus:
218 return result.append("Status");
219 case blink::WebAXRoleSwitch:
220 return result.append("Switch");
221 case blink::WebAXRoleTabGroup:
222 return result.append("TabGroup");
223 case blink::WebAXRoleTabList:
224 return result.append("TabList");
225 case blink::WebAXRoleTabPanel:
226 return result.append("TabPanel");
227 case blink::WebAXRoleTab:
228 return result.append("Tab");
229 case blink::WebAXRoleTableHeaderContainer:
230 return result.append("TableHeaderContainer");
231 case blink::WebAXRoleTable:
232 return result.append("Table");
233 case blink::WebAXRoleTextField:
234 return result.append("TextField");
235 case blink::WebAXRoleTime:
236 return result.append("Time");
237 case blink::WebAXRoleTimer:
238 return result.append("Timer");
239 case blink::WebAXRoleToggleButton:
240 return result.append("ToggleButton");
241 case blink::WebAXRoleToolbar:
242 return result.append("Toolbar");
243 case blink::WebAXRoleTreeGrid:
244 return result.append("TreeGrid");
245 case blink::WebAXRoleTreeItem:
246 return result.append("TreeItem");
247 case blink::WebAXRoleTree:
248 return result.append("Tree");
249 case blink::WebAXRoleUnknown:
250 return result.append("Unknown");
251 case blink::WebAXRoleUserInterfaceTooltip:
252 return result.append("UserInterfaceTooltip");
253 case blink::WebAXRoleWebArea:
254 return result.append("WebArea");
255 case blink::WebAXRoleWindow:
256 return result.append("Window");
257 default:
258 return result.append("Unknown");
262 std::string DeprecatedGetDescription(const blink::WebAXObject& object) {
263 std::string description = object.deprecatedAccessibilityDescription().utf8();
264 return description.insert(0, "AXDescription: ");
267 std::string DeprecatedGetHelpText(const blink::WebAXObject& object) {
268 std::string help_text = object.deprecatedHelpText().utf8();
269 return help_text.insert(0, "AXHelp: ");
272 std::string GetStringValue(const blink::WebAXObject& object) {
273 std::string value;
274 if (object.role() == blink::WebAXRoleColorWell) {
275 unsigned int color = object.colorValue();
276 unsigned int red = (color >> 16) & 0xFF;
277 unsigned int green = (color >> 8) & 0xFF;
278 unsigned int blue = color & 0xFF;
279 value = base::StringPrintf("rgba(%d, %d, %d, 1)",
280 red, green, blue);
281 } else {
282 value = object.stringValue().utf8();
284 return value.insert(0, "AXValue: ");
287 std::string GetRole(const blink::WebAXObject& object) {
288 std::string role_string = RoleToString(object.role());
290 // Special-case canvas with fallback content because Chromium wants to treat
291 // this as essentially a separate role that it can map differently depending
292 // on the platform.
293 if (object.role() == blink::WebAXRoleCanvas &&
294 object.canvasHasFallbackContent()) {
295 role_string += "WithFallbackContent";
298 return role_string;
301 std::string DeprecatedGetTitle(const blink::WebAXObject& object) {
302 std::string title = object.deprecatedTitle().utf8();
303 return title.insert(0, "AXTitle: ");
306 std::string GetValueDescription(const blink::WebAXObject& object) {
307 std::string value_description = object.valueDescription().utf8();
308 return value_description.insert(0, "AXValueDescription: ");
311 std::string GetLanguage(const blink::WebAXObject& object) {
312 std::string language = object.language().utf8();
313 return language.insert(0, "AXLanguage: ");
316 std::string GetAttributes(const blink::WebAXObject& object) {
317 // FIXME: Concatenate all attributes of the AXObject.
318 std::string attributes(DeprecatedGetTitle(object));
319 attributes.append("\n");
320 attributes.append(GetRole(object));
321 attributes.append("\n");
322 attributes.append(DeprecatedGetDescription(object));
323 return attributes;
326 blink::WebRect BoundsForCharacter(const blink::WebAXObject& object,
327 int characterIndex) {
328 DCHECK_EQ(object.role(), blink::WebAXRoleStaticText);
329 int end = 0;
330 for (unsigned i = 0; i < object.childCount(); i++) {
331 blink::WebAXObject inline_text_box = object.childAt(i);
332 DCHECK_EQ(inline_text_box.role(), blink::WebAXRoleInlineTextBox);
333 int start = end;
334 end += inline_text_box.stringValue().length();
335 if (characterIndex < start || characterIndex >= end)
336 continue;
337 blink::WebRect inline_text_box_rect = inline_text_box.boundingBoxRect();
338 int localIndex = characterIndex - start;
339 blink::WebVector<int> character_offsets;
340 inline_text_box.characterOffsets(character_offsets);
341 DCHECK(character_offsets.size() > 0 &&
342 character_offsets.size() == inline_text_box.stringValue().length());
343 switch (inline_text_box.textDirection()) {
344 case blink::WebAXTextDirectionLR: {
345 if (localIndex) {
346 int left = inline_text_box_rect.x + character_offsets[localIndex - 1];
347 int width = character_offsets[localIndex] -
348 character_offsets[localIndex - 1];
349 return blink::WebRect(left, inline_text_box_rect.y,
350 width, inline_text_box_rect.height);
352 return blink::WebRect(
353 inline_text_box_rect.x, inline_text_box_rect.y,
354 character_offsets[0], inline_text_box_rect.height);
356 case blink::WebAXTextDirectionRL: {
357 int right = inline_text_box_rect.x + inline_text_box_rect.width;
359 if (localIndex) {
360 int left = right - character_offsets[localIndex];
361 int width = character_offsets[localIndex] -
362 character_offsets[localIndex - 1];
363 return blink::WebRect(left, inline_text_box_rect.y,
364 width, inline_text_box_rect.height);
366 int left = right - character_offsets[0];
367 return blink::WebRect(
368 left, inline_text_box_rect.y,
369 character_offsets[0], inline_text_box_rect.height);
371 case blink::WebAXTextDirectionTB: {
372 if (localIndex) {
373 int top = inline_text_box_rect.y + character_offsets[localIndex - 1];
374 int height = character_offsets[localIndex] -
375 character_offsets[localIndex - 1];
376 return blink::WebRect(inline_text_box_rect.x, top,
377 inline_text_box_rect.width, height);
379 return blink::WebRect(inline_text_box_rect.x, inline_text_box_rect.y,
380 inline_text_box_rect.width, character_offsets[0]);
382 case blink::WebAXTextDirectionBT: {
383 int bottom = inline_text_box_rect.y + inline_text_box_rect.height;
385 if (localIndex) {
386 int top = bottom - character_offsets[localIndex];
387 int height = character_offsets[localIndex] -
388 character_offsets[localIndex - 1];
389 return blink::WebRect(inline_text_box_rect.x, top,
390 inline_text_box_rect.width, height);
392 int top = bottom - character_offsets[0];
393 return blink::WebRect(inline_text_box_rect.x, top,
394 inline_text_box_rect.width, character_offsets[0]);
399 DCHECK(false);
400 return blink::WebRect();
403 void GetBoundariesForOneWord(const blink::WebAXObject& object,
404 int character_index,
405 int& word_start,
406 int& word_end) {
407 int end = 0;
408 for (unsigned i = 0; i < object.childCount(); i++) {
409 blink::WebAXObject inline_text_box = object.childAt(i);
410 DCHECK_EQ(inline_text_box.role(), blink::WebAXRoleInlineTextBox);
411 int start = end;
412 end += inline_text_box.stringValue().length();
413 if (end <= character_index)
414 continue;
415 int localIndex = character_index - start;
417 blink::WebVector<int> starts;
418 blink::WebVector<int> ends;
419 inline_text_box.wordBoundaries(starts, ends);
420 size_t word_count = starts.size();
421 DCHECK_EQ(ends.size(), word_count);
423 // If there are no words, use the InlineTextBox boundaries.
424 if (!word_count) {
425 word_start = start;
426 word_end = end;
427 return;
430 // Look for a character within any word other than the last.
431 for (size_t j = 0; j < word_count - 1; j++) {
432 if (localIndex <= ends[j]) {
433 word_start = start + starts[j];
434 word_end = start + ends[j];
435 return;
439 // Return the last word by default.
440 word_start = start + starts[word_count - 1];
441 word_end = start + ends[word_count - 1];
442 return;
446 // Collects attributes into a string, delimited by dashes. Used by all methods
447 // that output lists of attributes: attributesOfLinkedUIElementsCallback,
448 // AttributesOfChildrenCallback, etc.
449 class AttributesCollector {
450 public:
451 AttributesCollector() {}
452 ~AttributesCollector() {}
454 void CollectAttributes(const blink::WebAXObject& object) {
455 attributes_.append("\n------------\n");
456 attributes_.append(GetAttributes(object));
459 std::string attributes() const { return attributes_; }
461 private:
462 std::string attributes_;
464 DISALLOW_COPY_AND_ASSIGN(AttributesCollector);
467 } // namespace
469 gin::WrapperInfo WebAXObjectProxy::kWrapperInfo = {
470 gin::kEmbedderNativeGin};
472 WebAXObjectProxy::WebAXObjectProxy(const blink::WebAXObject& object,
473 WebAXObjectProxy::Factory* factory)
474 : accessibility_object_(object),
475 factory_(factory) {
478 WebAXObjectProxy::~WebAXObjectProxy() {}
480 gin::ObjectTemplateBuilder
481 WebAXObjectProxy::GetObjectTemplateBuilder(v8::Isolate* isolate) {
482 return gin::Wrappable<WebAXObjectProxy>::GetObjectTemplateBuilder(isolate)
483 .SetProperty("role", &WebAXObjectProxy::Role)
484 .SetProperty("stringValue", &WebAXObjectProxy::StringValue)
485 .SetProperty("language", &WebAXObjectProxy::Language)
486 .SetProperty("x", &WebAXObjectProxy::X)
487 .SetProperty("y", &WebAXObjectProxy::Y)
488 .SetProperty("width", &WebAXObjectProxy::Width)
489 .SetProperty("height", &WebAXObjectProxy::Height)
490 .SetProperty("intValue", &WebAXObjectProxy::IntValue)
491 .SetProperty("minValue", &WebAXObjectProxy::MinValue)
492 .SetProperty("maxValue", &WebAXObjectProxy::MaxValue)
493 .SetProperty("valueDescription", &WebAXObjectProxy::ValueDescription)
494 .SetProperty("childrenCount", &WebAXObjectProxy::ChildrenCount)
495 .SetProperty("selectionAnchorObject",
496 &WebAXObjectProxy::SelectionAnchorObject)
497 .SetProperty("selectionAnchorOffset",
498 &WebAXObjectProxy::SelectionAnchorOffset)
499 .SetProperty("selectionFocusObject",
500 &WebAXObjectProxy::SelectionFocusObject)
501 .SetProperty("selectionFocusOffset",
502 &WebAXObjectProxy::SelectionFocusOffset)
503 .SetProperty("selectionStart", &WebAXObjectProxy::SelectionStart)
504 .SetProperty("selectionEnd", &WebAXObjectProxy::SelectionEnd)
505 .SetProperty("selectionStartLineNumber",
506 &WebAXObjectProxy::SelectionStartLineNumber)
507 .SetProperty("selectionEndLineNumber",
508 &WebAXObjectProxy::SelectionEndLineNumber)
509 .SetProperty("isEnabled", &WebAXObjectProxy::IsEnabled)
510 .SetProperty("isRequired", &WebAXObjectProxy::IsRequired)
511 .SetProperty("isEditable", &WebAXObjectProxy::IsEditable)
512 .SetProperty("isRichlyEditable", &WebAXObjectProxy::IsRichlyEditable)
513 .SetProperty("isFocused", &WebAXObjectProxy::IsFocused)
514 .SetProperty("isFocusable", &WebAXObjectProxy::IsFocusable)
515 .SetProperty("isSelected", &WebAXObjectProxy::IsSelected)
516 .SetProperty("isSelectable", &WebAXObjectProxy::IsSelectable)
517 .SetProperty("isMultiSelectable", &WebAXObjectProxy::IsMultiSelectable)
518 .SetProperty("isSelectedOptionActive",
519 &WebAXObjectProxy::IsSelectedOptionActive)
520 .SetProperty("isExpanded", &WebAXObjectProxy::IsExpanded)
521 .SetProperty("isChecked", &WebAXObjectProxy::IsChecked)
522 .SetProperty("isVisible", &WebAXObjectProxy::IsVisible)
523 .SetProperty("isOffScreen", &WebAXObjectProxy::IsOffScreen)
524 .SetProperty("isCollapsed", &WebAXObjectProxy::IsCollapsed)
525 .SetProperty("hasPopup", &WebAXObjectProxy::HasPopup)
526 .SetProperty("isValid", &WebAXObjectProxy::IsValid)
527 .SetProperty("isReadOnly", &WebAXObjectProxy::IsReadOnly)
528 .SetProperty("backgroundColor", &WebAXObjectProxy::BackgroundColor)
529 .SetProperty("color", &WebAXObjectProxy::Color)
530 .SetProperty("colorValue", &WebAXObjectProxy::ColorValue)
531 .SetProperty("fontSize", &WebAXObjectProxy::FontSize)
532 .SetProperty("orientation", &WebAXObjectProxy::Orientation)
533 .SetProperty("posInSet", &WebAXObjectProxy::PosInSet)
534 .SetProperty("setSize", &WebAXObjectProxy::SetSize)
535 .SetProperty("clickPointX", &WebAXObjectProxy::ClickPointX)
536 .SetProperty("clickPointY", &WebAXObjectProxy::ClickPointY)
537 .SetProperty("rowCount", &WebAXObjectProxy::RowCount)
538 .SetProperty("rowHeadersCount", &WebAXObjectProxy::RowHeadersCount)
539 .SetProperty("columnCount", &WebAXObjectProxy::ColumnCount)
540 .SetProperty("columnHeadersCount", &WebAXObjectProxy::ColumnHeadersCount)
541 .SetProperty("isClickable", &WebAXObjectProxy::IsClickable)
542 .SetProperty("isButtonStateMixed", &WebAXObjectProxy::IsButtonStateMixed)
543 .SetMethod("allAttributes", &WebAXObjectProxy::AllAttributes)
544 .SetMethod("attributesOfChildren",
545 &WebAXObjectProxy::AttributesOfChildren)
546 .SetMethod("ariaControlsElementAtIndex",
547 &WebAXObjectProxy::AriaControlsElementAtIndex)
548 .SetMethod("ariaFlowToElementAtIndex",
549 &WebAXObjectProxy::AriaFlowToElementAtIndex)
550 .SetMethod("ariaOwnsElementAtIndex",
551 &WebAXObjectProxy::AriaOwnsElementAtIndex)
552 .SetMethod("lineForIndex", &WebAXObjectProxy::LineForIndex)
553 .SetMethod("boundsForRange", &WebAXObjectProxy::BoundsForRange)
554 .SetMethod("childAtIndex", &WebAXObjectProxy::ChildAtIndex)
555 .SetMethod("elementAtPoint", &WebAXObjectProxy::ElementAtPoint)
556 .SetMethod("tableHeader", &WebAXObjectProxy::TableHeader)
557 .SetMethod("rowHeaderAtIndex", &WebAXObjectProxy::RowHeaderAtIndex)
558 .SetMethod("columnHeaderAtIndex", &WebAXObjectProxy::ColumnHeaderAtIndex)
559 .SetMethod("rowIndexRange", &WebAXObjectProxy::RowIndexRange)
560 .SetMethod("columnIndexRange", &WebAXObjectProxy::ColumnIndexRange)
561 .SetMethod("cellForColumnAndRow", &WebAXObjectProxy::CellForColumnAndRow)
562 .SetMethod("setSelectedTextRange",
563 &WebAXObjectProxy::SetSelectedTextRange)
564 .SetMethod("setSelection",
565 &WebAXObjectProxy::SetSelection)
566 .SetMethod("isAttributeSettable", &WebAXObjectProxy::IsAttributeSettable)
567 .SetMethod("isPressActionSupported",
568 &WebAXObjectProxy::IsPressActionSupported)
569 .SetMethod("isIncrementActionSupported",
570 &WebAXObjectProxy::IsIncrementActionSupported)
571 .SetMethod("isDecrementActionSupported",
572 &WebAXObjectProxy::IsDecrementActionSupported)
573 .SetMethod("parentElement", &WebAXObjectProxy::ParentElement)
574 .SetMethod("increment", &WebAXObjectProxy::Increment)
575 .SetMethod("decrement", &WebAXObjectProxy::Decrement)
576 .SetMethod("showMenu", &WebAXObjectProxy::ShowMenu)
577 .SetMethod("press", &WebAXObjectProxy::Press)
578 .SetMethod("setValue", &WebAXObjectProxy::SetValue)
579 .SetMethod("isEqual", &WebAXObjectProxy::IsEqual)
580 .SetMethod("setNotificationListener",
581 &WebAXObjectProxy::SetNotificationListener)
582 .SetMethod("unsetNotificationListener",
583 &WebAXObjectProxy::UnsetNotificationListener)
584 .SetMethod("takeFocus", &WebAXObjectProxy::TakeFocus)
585 .SetMethod("scrollToMakeVisible", &WebAXObjectProxy::ScrollToMakeVisible)
586 .SetMethod("scrollToMakeVisibleWithSubFocus",
587 &WebAXObjectProxy::ScrollToMakeVisibleWithSubFocus)
588 .SetMethod("scrollToGlobalPoint", &WebAXObjectProxy::ScrollToGlobalPoint)
589 .SetMethod("wordStart", &WebAXObjectProxy::WordStart)
590 .SetMethod("wordEnd", &WebAXObjectProxy::WordEnd)
591 .SetMethod("nextOnLine", &WebAXObjectProxy::NextOnLine)
592 .SetMethod("previousOnLine", &WebAXObjectProxy::PreviousOnLine)
593 // TODO(hajimehoshi): This is for backward compatibility. Remove them.
594 .SetMethod("addNotificationListener",
595 &WebAXObjectProxy::SetNotificationListener)
596 .SetMethod("removeNotificationListener",
597 &WebAXObjectProxy::UnsetNotificationListener)
599 // DEPRECATED accessible name and description accessors
601 .SetProperty("title", &WebAXObjectProxy::DeprecatedTitle)
602 .SetProperty("description", &WebAXObjectProxy::DeprecatedDescription)
603 .SetProperty("helpText", &WebAXObjectProxy::DeprecatedHelpText)
604 .SetMethod("titleUIElement", &WebAXObjectProxy::DeprecatedTitleUIElement)
605 .SetProperty("deprecatedTitle",
606 &WebAXObjectProxy::DeprecatedTitle)
607 .SetProperty("deprecatedDescription",
608 &WebAXObjectProxy::DeprecatedDescription)
609 .SetProperty("deprecatedHelpText",
610 &WebAXObjectProxy::DeprecatedHelpText)
611 .SetMethod("deprecatedTitleUIElement",
612 &WebAXObjectProxy::DeprecatedTitleUIElement)
614 // NEW accessible name and description accessors
616 .SetProperty("name", &WebAXObjectProxy::Name)
617 .SetProperty("nameFrom", &WebAXObjectProxy::NameFrom)
618 .SetMethod("nameElementCount", &WebAXObjectProxy::NameElementCount)
619 .SetMethod("nameElementAtIndex", &WebAXObjectProxy::NameElementAtIndex);
620 // TODO(dmazzoni): add "description", etc. once LayoutTests have
621 // been updated to call deprecatedDescription instead.
625 v8::Local<v8::Object> WebAXObjectProxy::GetChildAtIndex(unsigned index) {
626 return factory_->GetOrCreate(accessibility_object_.childAt(index));
629 bool WebAXObjectProxy::IsRoot() const {
630 return false;
633 bool WebAXObjectProxy::IsEqualToObject(const blink::WebAXObject& other) {
634 return accessibility_object_.equals(other);
637 void WebAXObjectProxy::NotificationReceived(
638 blink::WebFrame* frame,
639 const std::string& notification_name) {
640 if (notification_callback_.IsEmpty())
641 return;
643 v8::Local<v8::Context> context = frame->mainWorldScriptContext();
644 if (context.IsEmpty())
645 return;
647 v8::Isolate* isolate = blink::mainThreadIsolate();
649 v8::Local<v8::Value> argv[] = {
650 v8::String::NewFromUtf8(isolate, notification_name.data(),
651 v8::String::kNormalString,
652 notification_name.size()),
654 frame->callFunctionEvenIfScriptDisabled(
655 v8::Local<v8::Function>::New(isolate, notification_callback_),
656 context->Global(),
657 arraysize(argv),
658 argv);
661 void WebAXObjectProxy::Reset() {
662 notification_callback_.Reset();
665 std::string WebAXObjectProxy::Role() {
666 accessibility_object_.updateLayoutAndCheckValidity();
667 return GetRole(accessibility_object_);
670 std::string WebAXObjectProxy::DeprecatedTitle() {
671 accessibility_object_.updateLayoutAndCheckValidity();
672 return DeprecatedGetTitle(accessibility_object_);
675 std::string WebAXObjectProxy::DeprecatedDescription() {
676 accessibility_object_.updateLayoutAndCheckValidity();
677 return DeprecatedGetDescription(accessibility_object_);
680 std::string WebAXObjectProxy::DeprecatedHelpText() {
681 accessibility_object_.updateLayoutAndCheckValidity();
682 return DeprecatedGetHelpText(accessibility_object_);
685 std::string WebAXObjectProxy::StringValue() {
686 accessibility_object_.updateLayoutAndCheckValidity();
687 return GetStringValue(accessibility_object_);
690 std::string WebAXObjectProxy::Language() {
691 accessibility_object_.updateLayoutAndCheckValidity();
692 return GetLanguage(accessibility_object_);
695 int WebAXObjectProxy::X() {
696 accessibility_object_.updateLayoutAndCheckValidity();
697 return accessibility_object_.boundingBoxRect().x;
700 int WebAXObjectProxy::Y() {
701 accessibility_object_.updateLayoutAndCheckValidity();
702 return accessibility_object_.boundingBoxRect().y;
705 int WebAXObjectProxy::Width() {
706 accessibility_object_.updateLayoutAndCheckValidity();
707 return accessibility_object_.boundingBoxRect().width;
710 int WebAXObjectProxy::Height() {
711 accessibility_object_.updateLayoutAndCheckValidity();
712 return accessibility_object_.boundingBoxRect().height;
715 int WebAXObjectProxy::IntValue() {
716 accessibility_object_.updateLayoutAndCheckValidity();
717 if (accessibility_object_.supportsRangeValue())
718 return accessibility_object_.valueForRange();
719 else if (accessibility_object_.role() == blink::WebAXRoleHeading)
720 return accessibility_object_.headingLevel();
721 else
722 return atoi(accessibility_object_.stringValue().utf8().data());
725 int WebAXObjectProxy::MinValue() {
726 accessibility_object_.updateLayoutAndCheckValidity();
727 return accessibility_object_.minValueForRange();
730 int WebAXObjectProxy::MaxValue() {
731 accessibility_object_.updateLayoutAndCheckValidity();
732 return accessibility_object_.maxValueForRange();
735 std::string WebAXObjectProxy::ValueDescription() {
736 accessibility_object_.updateLayoutAndCheckValidity();
737 return GetValueDescription(accessibility_object_);
740 int WebAXObjectProxy::ChildrenCount() {
741 accessibility_object_.updateLayoutAndCheckValidity();
742 int count = 1; // Root object always has only one child, the WebView.
743 if (!IsRoot())
744 count = accessibility_object_.childCount();
745 return count;
748 v8::Local<v8::Value> WebAXObjectProxy::SelectionAnchorObject() {
749 accessibility_object_.updateLayoutAndCheckValidity();
751 blink::WebAXObject anchorObject;
752 int anchorOffset = -1;
753 blink::WebAXObject focusObject;
754 int focusOffset = -1;
755 accessibility_object_.selection(anchorObject, anchorOffset,
756 focusObject, focusOffset);
757 if (anchorObject.isNull())
758 return v8::Null(blink::mainThreadIsolate());
760 return factory_->GetOrCreate(anchorObject);
763 int WebAXObjectProxy::SelectionAnchorOffset() {
764 accessibility_object_.updateLayoutAndCheckValidity();
766 blink::WebAXObject anchorObject;
767 int anchorOffset = -1;
768 blink::WebAXObject focusObject;
769 int focusOffset = -1;
770 accessibility_object_.selection(anchorObject, anchorOffset,
771 focusObject, focusOffset);
772 if (anchorOffset < 0)
773 return -1;
775 return anchorOffset;
778 v8::Local<v8::Value> WebAXObjectProxy::SelectionFocusObject() {
779 accessibility_object_.updateLayoutAndCheckValidity();
781 blink::WebAXObject anchorObject;
782 int anchorOffset = -1;
783 blink::WebAXObject focusObject;
784 int focusOffset = -1;
785 accessibility_object_.selection(anchorObject, anchorOffset,
786 focusObject, focusOffset);
787 if (focusObject.isNull())
788 return v8::Null(blink::mainThreadIsolate());
790 return factory_->GetOrCreate(focusObject);
793 int WebAXObjectProxy::SelectionFocusOffset() {
794 accessibility_object_.updateLayoutAndCheckValidity();
796 blink::WebAXObject anchorObject;
797 int anchorOffset = -1;
798 blink::WebAXObject focusObject;
799 int focusOffset = -1;
800 accessibility_object_.selection(anchorObject, anchorOffset,
801 focusObject, focusOffset);
802 if (focusOffset < 0)
803 return -1;
805 return focusOffset;
808 int WebAXObjectProxy::SelectionStart() {
809 accessibility_object_.updateLayoutAndCheckValidity();
810 return accessibility_object_.selectionStart();
813 int WebAXObjectProxy::SelectionEnd() {
814 accessibility_object_.updateLayoutAndCheckValidity();
815 return accessibility_object_.selectionEnd();
818 int WebAXObjectProxy::SelectionStartLineNumber() {
819 accessibility_object_.updateLayoutAndCheckValidity();
820 return accessibility_object_.selectionStartLineNumber();
823 int WebAXObjectProxy::SelectionEndLineNumber() {
824 accessibility_object_.updateLayoutAndCheckValidity();
825 return accessibility_object_.selectionEndLineNumber();
828 bool WebAXObjectProxy::IsEnabled() {
829 accessibility_object_.updateLayoutAndCheckValidity();
830 return accessibility_object_.isEnabled();
833 bool WebAXObjectProxy::IsRequired() {
834 accessibility_object_.updateLayoutAndCheckValidity();
835 return accessibility_object_.isRequired();
838 bool WebAXObjectProxy::IsEditable() {
839 accessibility_object_.updateLayoutAndCheckValidity();
840 return accessibility_object_.isEditable();
843 bool WebAXObjectProxy::IsRichlyEditable() {
844 accessibility_object_.updateLayoutAndCheckValidity();
845 return accessibility_object_.isRichlyEditable();
848 bool WebAXObjectProxy::IsFocused() {
849 accessibility_object_.updateLayoutAndCheckValidity();
850 return accessibility_object_.isFocused();
853 bool WebAXObjectProxy::IsFocusable() {
854 accessibility_object_.updateLayoutAndCheckValidity();
855 return accessibility_object_.canSetFocusAttribute();
858 bool WebAXObjectProxy::IsSelected() {
859 accessibility_object_.updateLayoutAndCheckValidity();
860 return accessibility_object_.isSelected();
863 bool WebAXObjectProxy::IsSelectable() {
864 accessibility_object_.updateLayoutAndCheckValidity();
865 return accessibility_object_.canSetSelectedAttribute();
868 bool WebAXObjectProxy::IsMultiSelectable() {
869 accessibility_object_.updateLayoutAndCheckValidity();
870 return accessibility_object_.isMultiSelectable();
873 bool WebAXObjectProxy::IsSelectedOptionActive() {
874 accessibility_object_.updateLayoutAndCheckValidity();
875 return accessibility_object_.isSelectedOptionActive();
878 bool WebAXObjectProxy::IsExpanded() {
879 accessibility_object_.updateLayoutAndCheckValidity();
880 return accessibility_object_.isExpanded() == blink::WebAXExpandedExpanded;
883 bool WebAXObjectProxy::IsChecked() {
884 accessibility_object_.updateLayoutAndCheckValidity();
885 return accessibility_object_.isChecked();
888 bool WebAXObjectProxy::IsCollapsed() {
889 accessibility_object_.updateLayoutAndCheckValidity();
890 return accessibility_object_.isExpanded() == blink::WebAXExpandedCollapsed;
893 bool WebAXObjectProxy::IsVisible() {
894 accessibility_object_.updateLayoutAndCheckValidity();
895 return accessibility_object_.isVisible();
898 bool WebAXObjectProxy::IsOffScreen() {
899 accessibility_object_.updateLayoutAndCheckValidity();
900 return accessibility_object_.isOffScreen();
903 bool WebAXObjectProxy::HasPopup() {
904 accessibility_object_.updateLayoutAndCheckValidity();
905 return accessibility_object_.ariaHasPopup();
908 bool WebAXObjectProxy::IsValid() {
909 accessibility_object_.updateLayoutAndCheckValidity();
910 return !accessibility_object_.isDetached();
913 bool WebAXObjectProxy::IsReadOnly() {
914 accessibility_object_.updateLayoutAndCheckValidity();
915 return accessibility_object_.isReadOnly();
918 unsigned int WebAXObjectProxy::BackgroundColor() {
919 accessibility_object_.updateLayoutAndCheckValidity();
920 return accessibility_object_.backgroundColor();
923 unsigned int WebAXObjectProxy::Color() {
924 accessibility_object_.updateLayoutAndCheckValidity();
925 unsigned int color = accessibility_object_.color();
926 // Remove the alpha because it's always 1 and thus not informative.
927 return color & 0xFFFFFF;
930 // For input elements of type color.
931 unsigned int WebAXObjectProxy::ColorValue() {
932 accessibility_object_.updateLayoutAndCheckValidity();
933 return accessibility_object_.colorValue();
936 float WebAXObjectProxy::FontSize() {
937 accessibility_object_.updateLayoutAndCheckValidity();
938 return accessibility_object_.fontSize();
941 std::string WebAXObjectProxy::Orientation() {
942 accessibility_object_.updateLayoutAndCheckValidity();
943 if (accessibility_object_.orientation() == blink::WebAXOrientationVertical)
944 return "AXOrientation: AXVerticalOrientation";
945 else if (accessibility_object_.orientation()
946 == blink::WebAXOrientationHorizontal)
947 return "AXOrientation: AXHorizontalOrientation";
949 return std::string();
952 int WebAXObjectProxy::PosInSet() {
953 accessibility_object_.updateLayoutAndCheckValidity();
954 return accessibility_object_.posInSet();
957 int WebAXObjectProxy::SetSize() {
958 accessibility_object_.updateLayoutAndCheckValidity();
959 return accessibility_object_.setSize();
962 int WebAXObjectProxy::ClickPointX() {
963 accessibility_object_.updateLayoutAndCheckValidity();
964 return accessibility_object_.clickPoint().x;
967 int WebAXObjectProxy::ClickPointY() {
968 accessibility_object_.updateLayoutAndCheckValidity();
969 return accessibility_object_.clickPoint().y;
972 int32_t WebAXObjectProxy::RowCount() {
973 accessibility_object_.updateLayoutAndCheckValidity();
974 return static_cast<int32_t>(accessibility_object_.rowCount());
977 int32_t WebAXObjectProxy::RowHeadersCount() {
978 accessibility_object_.updateLayoutAndCheckValidity();
979 blink::WebVector<blink::WebAXObject> headers;
980 accessibility_object_.rowHeaders(headers);
981 return static_cast<int32_t>(headers.size());
984 int32_t WebAXObjectProxy::ColumnCount() {
985 accessibility_object_.updateLayoutAndCheckValidity();
986 return static_cast<int32_t>(accessibility_object_.columnCount());
989 int32_t WebAXObjectProxy::ColumnHeadersCount()
991 accessibility_object_.updateLayoutAndCheckValidity();
992 blink::WebVector<blink::WebAXObject> headers;
993 accessibility_object_.columnHeaders(headers);
994 return static_cast<int32_t>(headers.size());
997 bool WebAXObjectProxy::IsClickable() {
998 accessibility_object_.updateLayoutAndCheckValidity();
999 return accessibility_object_.isClickable();
1002 bool WebAXObjectProxy::IsButtonStateMixed() {
1003 accessibility_object_.updateLayoutAndCheckValidity();
1004 return accessibility_object_.isButtonStateMixed();
1007 v8::Local<v8::Object> WebAXObjectProxy::AriaControlsElementAtIndex(
1008 unsigned index)
1010 accessibility_object_.updateLayoutAndCheckValidity();
1011 blink::WebVector<blink::WebAXObject> elements;
1012 accessibility_object_.ariaControls(elements);
1013 size_t elementCount = elements.size();
1014 if (index >= elementCount)
1015 return v8::Local<v8::Object>();
1017 return factory_->GetOrCreate(elements[index]);
1020 v8::Local<v8::Object> WebAXObjectProxy::AriaFlowToElementAtIndex(
1021 unsigned index)
1023 accessibility_object_.updateLayoutAndCheckValidity();
1024 blink::WebVector<blink::WebAXObject> elements;
1025 accessibility_object_.ariaFlowTo(elements);
1026 size_t elementCount = elements.size();
1027 if (index >= elementCount)
1028 return v8::Local<v8::Object>();
1030 return factory_->GetOrCreate(elements[index]);
1033 v8::Local<v8::Object> WebAXObjectProxy::AriaOwnsElementAtIndex(unsigned index)
1035 accessibility_object_.updateLayoutAndCheckValidity();
1036 blink::WebVector<blink::WebAXObject> elements;
1037 accessibility_object_.ariaOwns(elements);
1038 size_t elementCount = elements.size();
1039 if (index >= elementCount)
1040 return v8::Local<v8::Object>();
1042 return factory_->GetOrCreate(elements[index]);
1045 std::string WebAXObjectProxy::AllAttributes() {
1046 accessibility_object_.updateLayoutAndCheckValidity();
1047 return GetAttributes(accessibility_object_);
1050 std::string WebAXObjectProxy::AttributesOfChildren() {
1051 accessibility_object_.updateLayoutAndCheckValidity();
1052 AttributesCollector collector;
1053 unsigned size = accessibility_object_.childCount();
1054 for (unsigned i = 0; i < size; ++i)
1055 collector.CollectAttributes(accessibility_object_.childAt(i));
1056 return collector.attributes();
1059 int WebAXObjectProxy::LineForIndex(int index) {
1060 accessibility_object_.updateLayoutAndCheckValidity();
1061 blink::WebVector<int> line_breaks;
1062 accessibility_object_.lineBreaks(line_breaks);
1063 int line = 0;
1064 int vector_size = static_cast<int>(line_breaks.size());
1065 while (line < vector_size && line_breaks[line] <= index)
1066 line++;
1067 return line;
1070 std::string WebAXObjectProxy::BoundsForRange(int start, int end) {
1071 accessibility_object_.updateLayoutAndCheckValidity();
1072 if (accessibility_object_.role() != blink::WebAXRoleStaticText)
1073 return std::string();
1075 if (!accessibility_object_.updateLayoutAndCheckValidity())
1076 return std::string();
1078 int len = end - start;
1080 // Get the bounds for each character and union them into one large rectangle.
1081 // This is just for testing so it doesn't need to be efficient.
1082 blink::WebRect bounds = BoundsForCharacter(accessibility_object_, start);
1083 for (int i = 1; i < len; i++) {
1084 blink::WebRect next = BoundsForCharacter(accessibility_object_, start + i);
1085 int right = std::max(bounds.x + bounds.width, next.x + next.width);
1086 int bottom = std::max(bounds.y + bounds.height, next.y + next.height);
1087 bounds.x = std::min(bounds.x, next.x);
1088 bounds.y = std::min(bounds.y, next.y);
1089 bounds.width = right - bounds.x;
1090 bounds.height = bottom - bounds.y;
1093 return base::StringPrintf("{x: %d, y: %d, width: %d, height: %d}",
1094 bounds.x, bounds.y, bounds.width, bounds.height);
1097 v8::Local<v8::Object> WebAXObjectProxy::ChildAtIndex(int index) {
1098 accessibility_object_.updateLayoutAndCheckValidity();
1099 return GetChildAtIndex(index);
1102 v8::Local<v8::Object> WebAXObjectProxy::ElementAtPoint(int x, int y) {
1103 accessibility_object_.updateLayoutAndCheckValidity();
1104 blink::WebPoint point(x, y);
1105 blink::WebAXObject obj = accessibility_object_.hitTest(point);
1106 if (obj.isNull())
1107 return v8::Local<v8::Object>();
1109 return factory_->GetOrCreate(obj);
1112 v8::Local<v8::Object> WebAXObjectProxy::TableHeader() {
1113 accessibility_object_.updateLayoutAndCheckValidity();
1114 blink::WebAXObject obj = accessibility_object_.headerContainerObject();
1115 if (obj.isNull())
1116 return v8::Local<v8::Object>();
1118 return factory_->GetOrCreate(obj);
1121 v8::Local<v8::Object> WebAXObjectProxy::RowHeaderAtIndex(unsigned index) {
1122 accessibility_object_.updateLayoutAndCheckValidity();
1123 blink::WebVector<blink::WebAXObject> headers;
1124 accessibility_object_.rowHeaders(headers);
1125 size_t headerCount = headers.size();
1126 if (index >= headerCount)
1127 return v8::Local<v8::Object>();
1129 return factory_->GetOrCreate(headers[index]);
1132 v8::Local<v8::Object> WebAXObjectProxy::ColumnHeaderAtIndex(unsigned index) {
1133 accessibility_object_.updateLayoutAndCheckValidity();
1134 blink::WebVector<blink::WebAXObject> headers;
1135 accessibility_object_.columnHeaders(headers);
1136 size_t headerCount = headers.size();
1137 if (index >= headerCount)
1138 return v8::Local<v8::Object>();
1140 return factory_->GetOrCreate(headers[index]);
1143 std::string WebAXObjectProxy::RowIndexRange() {
1144 accessibility_object_.updateLayoutAndCheckValidity();
1145 unsigned row_index = accessibility_object_.cellRowIndex();
1146 unsigned row_span = accessibility_object_.cellRowSpan();
1147 return base::StringPrintf("{%d, %d}", row_index, row_span);
1150 std::string WebAXObjectProxy::ColumnIndexRange() {
1151 accessibility_object_.updateLayoutAndCheckValidity();
1152 unsigned column_index = accessibility_object_.cellColumnIndex();
1153 unsigned column_span = accessibility_object_.cellColumnSpan();
1154 return base::StringPrintf("{%d, %d}", column_index, column_span);
1157 v8::Local<v8::Object> WebAXObjectProxy::CellForColumnAndRow(
1158 int column, int row) {
1159 accessibility_object_.updateLayoutAndCheckValidity();
1160 blink::WebAXObject obj =
1161 accessibility_object_.cellForColumnAndRow(column, row);
1162 if (obj.isNull())
1163 return v8::Local<v8::Object>();
1165 return factory_->GetOrCreate(obj);
1168 v8::Local<v8::Object> WebAXObjectProxy::DeprecatedTitleUIElement() {
1169 accessibility_object_.updateLayoutAndCheckValidity();
1170 blink::WebAXObject obj = accessibility_object_.deprecatedTitleUIElement();
1171 if (obj.isNull())
1172 return v8::Local<v8::Object>();
1174 return factory_->GetOrCreate(obj);
1177 void WebAXObjectProxy::SetSelectedTextRange(int selection_start,
1178 int length) {
1179 accessibility_object_.updateLayoutAndCheckValidity();
1180 accessibility_object_.setSelectedTextRange(selection_start,
1181 selection_start + length);
1184 void WebAXObjectProxy::SetSelection(
1185 v8::Local<v8::Value> anchor_object, int anchor_offset,
1186 v8::Local<v8::Value> focus_object, int focus_offset) {
1187 if (anchor_object.IsEmpty() || focus_object.IsEmpty() ||
1188 !anchor_object->IsObject() || !focus_object->IsObject() ||
1189 anchor_offset < 0 || focus_offset < 0) {
1190 return;
1193 WebAXObjectProxy* web_ax_anchor = nullptr;
1194 if (!gin::ConvertFromV8(
1195 blink::mainThreadIsolate(), anchor_object, &web_ax_anchor)) {
1196 return;
1198 DCHECK(web_ax_anchor);
1200 WebAXObjectProxy* web_ax_focus = nullptr;
1201 if (!gin::ConvertFromV8(
1202 blink::mainThreadIsolate(), focus_object, &web_ax_focus)) {
1203 return;
1205 DCHECK(web_ax_focus);
1207 accessibility_object_.updateLayoutAndCheckValidity();
1208 accessibility_object_.setSelection(
1209 web_ax_anchor->accessibility_object_, anchor_offset,
1210 web_ax_focus->accessibility_object_, focus_offset);
1213 bool WebAXObjectProxy::IsAttributeSettable(const std::string& attribute) {
1214 accessibility_object_.updateLayoutAndCheckValidity();
1215 bool settable = false;
1216 if (attribute == "AXValue")
1217 settable = accessibility_object_.canSetValueAttribute();
1218 return settable;
1221 bool WebAXObjectProxy::IsPressActionSupported() {
1222 accessibility_object_.updateLayoutAndCheckValidity();
1223 return accessibility_object_.canPress();
1226 bool WebAXObjectProxy::IsIncrementActionSupported() {
1227 accessibility_object_.updateLayoutAndCheckValidity();
1228 return accessibility_object_.canIncrement();
1231 bool WebAXObjectProxy::IsDecrementActionSupported() {
1232 accessibility_object_.updateLayoutAndCheckValidity();
1233 return accessibility_object_.canDecrement();
1236 v8::Local<v8::Object> WebAXObjectProxy::ParentElement() {
1237 accessibility_object_.updateLayoutAndCheckValidity();
1238 blink::WebAXObject parent_object = accessibility_object_.parentObject();
1239 while (parent_object.accessibilityIsIgnored())
1240 parent_object = parent_object.parentObject();
1241 return factory_->GetOrCreate(parent_object);
1244 void WebAXObjectProxy::Increment() {
1245 accessibility_object_.updateLayoutAndCheckValidity();
1246 accessibility_object_.increment();
1249 void WebAXObjectProxy::Decrement() {
1250 accessibility_object_.updateLayoutAndCheckValidity();
1251 accessibility_object_.decrement();
1254 void WebAXObjectProxy::ShowMenu() {
1255 accessibility_object_.showContextMenu();
1258 void WebAXObjectProxy::Press() {
1259 accessibility_object_.updateLayoutAndCheckValidity();
1260 accessibility_object_.press();
1263 bool WebAXObjectProxy::SetValue(const std::string& value) {
1264 accessibility_object_.updateLayoutAndCheckValidity();
1265 if (!accessibility_object_.canSetValueAttribute())
1266 return false;
1268 accessibility_object_.setValue(blink::WebString::fromUTF8(value));
1269 return true;
1272 bool WebAXObjectProxy::IsEqual(v8::Local<v8::Object> proxy) {
1273 WebAXObjectProxy* unwrapped_proxy = NULL;
1274 if (!gin::ConvertFromV8(blink::mainThreadIsolate(), proxy, &unwrapped_proxy))
1275 return false;
1276 return unwrapped_proxy->IsEqualToObject(accessibility_object_);
1279 void WebAXObjectProxy::SetNotificationListener(
1280 v8::Local<v8::Function> callback) {
1281 v8::Isolate* isolate = blink::mainThreadIsolate();
1282 notification_callback_.Reset(isolate, callback);
1285 void WebAXObjectProxy::UnsetNotificationListener() {
1286 notification_callback_.Reset();
1289 void WebAXObjectProxy::TakeFocus() {
1290 accessibility_object_.updateLayoutAndCheckValidity();
1291 accessibility_object_.setFocused(true);
1294 void WebAXObjectProxy::ScrollToMakeVisible() {
1295 accessibility_object_.updateLayoutAndCheckValidity();
1296 accessibility_object_.scrollToMakeVisible();
1299 void WebAXObjectProxy::ScrollToMakeVisibleWithSubFocus(int x, int y,
1300 int width, int height) {
1301 accessibility_object_.updateLayoutAndCheckValidity();
1302 accessibility_object_.scrollToMakeVisibleWithSubFocus(
1303 blink::WebRect(x, y, width, height));
1306 void WebAXObjectProxy::ScrollToGlobalPoint(int x, int y) {
1307 accessibility_object_.updateLayoutAndCheckValidity();
1308 accessibility_object_.scrollToGlobalPoint(blink::WebPoint(x, y));
1311 int WebAXObjectProxy::WordStart(int character_index) {
1312 accessibility_object_.updateLayoutAndCheckValidity();
1313 if (accessibility_object_.role() != blink::WebAXRoleStaticText)
1314 return -1;
1316 int word_start = 0, word_end = 0;
1317 GetBoundariesForOneWord(accessibility_object_, character_index,
1318 word_start, word_end);
1319 return word_start;
1322 int WebAXObjectProxy::WordEnd(int character_index) {
1323 accessibility_object_.updateLayoutAndCheckValidity();
1324 if (accessibility_object_.role() != blink::WebAXRoleStaticText)
1325 return -1;
1327 int word_start = 0, word_end = 0;
1328 GetBoundariesForOneWord(accessibility_object_, character_index,
1329 word_start, word_end);
1330 return word_end;
1333 v8::Local<v8::Object> WebAXObjectProxy::NextOnLine() {
1334 accessibility_object_.updateLayoutAndCheckValidity();
1335 blink::WebAXObject obj = accessibility_object_.nextOnLine();
1336 if (obj.isNull())
1337 return v8::Local<v8::Object>();
1339 return factory_->GetOrCreate(obj);
1342 v8::Local<v8::Object> WebAXObjectProxy::PreviousOnLine() {
1343 accessibility_object_.updateLayoutAndCheckValidity();
1344 blink::WebAXObject obj = accessibility_object_.previousOnLine();
1345 if (obj.isNull())
1346 return v8::Local<v8::Object>();
1348 return factory_->GetOrCreate(obj);
1351 std::string WebAXObjectProxy::Name() {
1352 accessibility_object_.updateLayoutAndCheckValidity();
1353 blink::WebAXNameFrom nameFrom;
1354 blink::WebVector<blink::WebAXObject> nameObjects;
1355 return accessibility_object_.name(nameFrom, nameObjects).utf8();
1358 std::string WebAXObjectProxy::NameFrom() {
1359 accessibility_object_.updateLayoutAndCheckValidity();
1360 blink::WebAXNameFrom nameFrom = blink::WebAXNameFromContents;
1361 blink::WebVector<blink::WebAXObject> nameObjects;
1362 accessibility_object_.name(nameFrom, nameObjects);
1363 switch(nameFrom) {
1364 case blink::WebAXNameFromAttribute:
1365 return "attribute";
1366 case blink::WebAXNameFromContents:
1367 return "contents";
1368 case blink::WebAXNameFromPlaceholder:
1369 return "placeholder";
1370 case blink::WebAXNameFromRelatedElement:
1371 return "relatedElement";
1372 default:
1373 return "unknown";
1377 int WebAXObjectProxy::NameElementCount() {
1378 accessibility_object_.updateLayoutAndCheckValidity();
1379 blink::WebAXNameFrom nameFrom;
1380 blink::WebVector<blink::WebAXObject> nameObjects;
1381 accessibility_object_.name(nameFrom, nameObjects);
1382 return static_cast<int>(nameObjects.size());
1385 v8::Local<v8::Object> WebAXObjectProxy::NameElementAtIndex(unsigned index) {
1386 accessibility_object_.updateLayoutAndCheckValidity();
1387 blink::WebAXNameFrom nameFrom;
1388 blink::WebVector<blink::WebAXObject> nameObjects;
1389 accessibility_object_.name(nameFrom, nameObjects);
1390 if (index >= nameObjects.size())
1391 return v8::Local<v8::Object>();
1392 return factory_->GetOrCreate(nameObjects[index]);
1395 RootWebAXObjectProxy::RootWebAXObjectProxy(
1396 const blink::WebAXObject &object, Factory *factory)
1397 : WebAXObjectProxy(object, factory) {
1400 v8::Local<v8::Object> RootWebAXObjectProxy::GetChildAtIndex(unsigned index) {
1401 if (index)
1402 return v8::Local<v8::Object>();
1404 return factory()->GetOrCreate(accessibility_object());
1407 bool RootWebAXObjectProxy::IsRoot() const {
1408 return true;
1411 WebAXObjectProxyList::WebAXObjectProxyList()
1412 : elements_(blink::mainThreadIsolate()) {
1415 WebAXObjectProxyList::~WebAXObjectProxyList() {
1416 Clear();
1419 void WebAXObjectProxyList::Clear() {
1420 v8::Isolate* isolate = blink::mainThreadIsolate();
1421 v8::HandleScope handle_scope(isolate);
1422 size_t elementCount = elements_.Size();
1423 for (size_t i = 0; i < elementCount; i++) {
1424 WebAXObjectProxy* unwrapped_object = NULL;
1425 bool result = gin::ConvertFromV8(isolate, elements_.Get(i),
1426 &unwrapped_object);
1427 DCHECK(result);
1428 DCHECK(unwrapped_object);
1429 unwrapped_object->Reset();
1431 elements_.Clear();
1434 v8::Local<v8::Object> WebAXObjectProxyList::GetOrCreate(
1435 const blink::WebAXObject& object) {
1436 if (object.isNull())
1437 return v8::Local<v8::Object>();
1439 v8::Isolate* isolate = blink::mainThreadIsolate();
1441 size_t elementCount = elements_.Size();
1442 for (size_t i = 0; i < elementCount; i++) {
1443 WebAXObjectProxy* unwrapped_object = NULL;
1444 bool result = gin::ConvertFromV8(isolate, elements_.Get(i),
1445 &unwrapped_object);
1446 DCHECK(result);
1447 DCHECK(unwrapped_object);
1448 if (unwrapped_object->IsEqualToObject(object))
1449 return elements_.Get(i);
1452 v8::Local<v8::Value> value_handle = gin::CreateHandle(
1453 isolate, new WebAXObjectProxy(object, this)).ToV8();
1454 if (value_handle.IsEmpty())
1455 return v8::Local<v8::Object>();
1456 v8::Local<v8::Object> handle = value_handle->ToObject(isolate);
1457 elements_.Append(handle);
1458 return handle;
1461 } // namespace test_runner