1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "WebAXObjectProxy.h"
32
33 #include "TestCommon.h"
34 #include "public/platform/WebCString.h"
35 #include "public/platform/WebPoint.h"
36 #include "public/platform/WebRect.h"
37 #include "public/platform/WebString.h"
38
39 using namespace blink;
40 using namespace std;
41
42 namespace WebTestRunner {
43
44 namespace {
45
46 // Map role value to string, matching Safari/Mac platform implementation to
47 // avoid rebaselining layout tests.
roleToString(WebAXRole role)48 string roleToString(WebAXRole role)
49 {
50 string result = "AXRole: AX";
51 switch (role) {
52 case WebAXRoleAlertDialog:
53 return result.append("AlertDialog");
54 case WebAXRoleAlert:
55 return result.append("Alert");
56 case WebAXRoleAnnotation:
57 return result.append("Annotation");
58 case WebAXRoleApplication:
59 return result.append("Application");
60 case WebAXRoleArticle:
61 return result.append("Article");
62 case WebAXRoleBanner:
63 return result.append("Banner");
64 case WebAXRoleBrowser:
65 return result.append("Browser");
66 case WebAXRoleBusyIndicator:
67 return result.append("BusyIndicator");
68 case WebAXRoleButton:
69 return result.append("Button");
70 case WebAXRoleCanvas:
71 return result.append("Canvas");
72 case WebAXRoleCell:
73 return result.append("Cell");
74 case WebAXRoleCheckBox:
75 return result.append("CheckBox");
76 case WebAXRoleColorWell:
77 return result.append("ColorWell");
78 case WebAXRoleColumnHeader:
79 return result.append("ColumnHeader");
80 case WebAXRoleColumn:
81 return result.append("Column");
82 case WebAXRoleComboBox:
83 return result.append("ComboBox");
84 case WebAXRoleComplementary:
85 return result.append("Complementary");
86 case WebAXRoleContentInfo:
87 return result.append("ContentInfo");
88 case WebAXRoleDefinition:
89 return result.append("Definition");
90 case WebAXRoleDescriptionListDetail:
91 return result.append("DescriptionListDetail");
92 case WebAXRoleDescriptionListTerm:
93 return result.append("DescriptionListTerm");
94 case WebAXRoleDialog:
95 return result.append("Dialog");
96 case WebAXRoleDirectory:
97 return result.append("Directory");
98 case WebAXRoleDisclosureTriangle:
99 return result.append("DisclosureTriangle");
100 case WebAXRoleDiv:
101 return result.append("Div");
102 case WebAXRoleDocument:
103 return result.append("Document");
104 case WebAXRoleDrawer:
105 return result.append("Drawer");
106 case WebAXRoleEditableText:
107 return result.append("EditableText");
108 case WebAXRoleFooter:
109 return result.append("Footer");
110 case WebAXRoleForm:
111 return result.append("Form");
112 case WebAXRoleGrid:
113 return result.append("Grid");
114 case WebAXRoleGroup:
115 return result.append("Group");
116 case WebAXRoleGrowArea:
117 return result.append("GrowArea");
118 case WebAXRoleHeading:
119 return result.append("Heading");
120 case WebAXRoleHelpTag:
121 return result.append("HelpTag");
122 case WebAXRoleHorizontalRule:
123 return result.append("HorizontalRule");
124 case WebAXRoleIgnored:
125 return result.append("Ignored");
126 case WebAXRoleImageMapLink:
127 return result.append("ImageMapLink");
128 case WebAXRoleImageMap:
129 return result.append("ImageMap");
130 case WebAXRoleImage:
131 return result.append("Image");
132 case WebAXRoleIncrementor:
133 return result.append("Incrementor");
134 case WebAXRoleInlineTextBox:
135 return result.append("InlineTextBox");
136 case WebAXRoleLabel:
137 return result.append("Label");
138 case WebAXRoleLegend:
139 return result.append("Legend");
140 case WebAXRoleLink:
141 return result.append("Link");
142 case WebAXRoleListBoxOption:
143 return result.append("ListBoxOption");
144 case WebAXRoleListBox:
145 return result.append("ListBox");
146 case WebAXRoleListItem:
147 return result.append("ListItem");
148 case WebAXRoleListMarker:
149 return result.append("ListMarker");
150 case WebAXRoleList:
151 return result.append("List");
152 case WebAXRoleLog:
153 return result.append("Log");
154 case WebAXRoleMain:
155 return result.append("Main");
156 case WebAXRoleMarquee:
157 return result.append("Marquee");
158 case WebAXRoleMathElement:
159 return result.append("MathElement");
160 case WebAXRoleMath:
161 return result.append("Math");
162 case WebAXRoleMatte:
163 return result.append("Matte");
164 case WebAXRoleMenuBar:
165 return result.append("MenuBar");
166 case WebAXRoleMenuButton:
167 return result.append("MenuButton");
168 case WebAXRoleMenuItem:
169 return result.append("MenuItem");
170 case WebAXRoleMenuListOption:
171 return result.append("MenuListOption");
172 case WebAXRoleMenuListPopup:
173 return result.append("MenuListPopup");
174 case WebAXRoleMenu:
175 return result.append("Menu");
176 case WebAXRoleNavigation:
177 return result.append("Navigation");
178 case WebAXRoleNote:
179 return result.append("Note");
180 case WebAXRoleOutline:
181 return result.append("Outline");
182 case WebAXRoleParagraph:
183 return result.append("Paragraph");
184 case WebAXRolePopUpButton:
185 return result.append("PopUpButton");
186 case WebAXRolePresentational:
187 return result.append("Presentational");
188 case WebAXRoleProgressIndicator:
189 return result.append("ProgressIndicator");
190 case WebAXRoleRadioButton:
191 return result.append("RadioButton");
192 case WebAXRoleRadioGroup:
193 return result.append("RadioGroup");
194 case WebAXRoleRegion:
195 return result.append("Region");
196 case WebAXRoleRootWebArea:
197 return result.append("RootWebArea");
198 case WebAXRoleRowHeader:
199 return result.append("RowHeader");
200 case WebAXRoleRow:
201 return result.append("Row");
202 case WebAXRoleRulerMarker:
203 return result.append("RulerMarker");
204 case WebAXRoleRuler:
205 return result.append("Ruler");
206 case WebAXRoleSVGRoot:
207 return result.append("SVGRoot");
208 case WebAXRoleScrollArea:
209 return result.append("ScrollArea");
210 case WebAXRoleScrollBar:
211 return result.append("ScrollBar");
212 case WebAXRoleSeamlessWebArea:
213 return result.append("SeamlessWebArea");
214 case WebAXRoleSearch:
215 return result.append("Search");
216 case WebAXRoleSheet:
217 return result.append("Sheet");
218 case WebAXRoleSlider:
219 return result.append("Slider");
220 case WebAXRoleSliderThumb:
221 return result.append("SliderThumb");
222 case WebAXRoleSpinButtonPart:
223 return result.append("SpinButtonPart");
224 case WebAXRoleSpinButton:
225 return result.append("SpinButton");
226 case WebAXRoleSplitGroup:
227 return result.append("SplitGroup");
228 case WebAXRoleSplitter:
229 return result.append("Splitter");
230 case WebAXRoleStaticText:
231 return result.append("StaticText");
232 case WebAXRoleStatus:
233 return result.append("Status");
234 case WebAXRoleSystemWide:
235 return result.append("SystemWide");
236 case WebAXRoleTabGroup:
237 return result.append("TabGroup");
238 case WebAXRoleTabList:
239 return result.append("TabList");
240 case WebAXRoleTabPanel:
241 return result.append("TabPanel");
242 case WebAXRoleTab:
243 return result.append("Tab");
244 case WebAXRoleTableHeaderContainer:
245 return result.append("TableHeaderContainer");
246 case WebAXRoleTable:
247 return result.append("Table");
248 case WebAXRoleTextArea:
249 return result.append("TextArea");
250 case WebAXRoleTextField:
251 return result.append("TextField");
252 case WebAXRoleTimer:
253 return result.append("Timer");
254 case WebAXRoleToggleButton:
255 return result.append("ToggleButton");
256 case WebAXRoleToolbar:
257 return result.append("Toolbar");
258 case WebAXRoleTreeGrid:
259 return result.append("TreeGrid");
260 case WebAXRoleTreeItem:
261 return result.append("TreeItem");
262 case WebAXRoleTree:
263 return result.append("Tree");
264 case WebAXRoleUnknown:
265 return result.append("Unknown");
266 case WebAXRoleUserInterfaceTooltip:
267 return result.append("UserInterfaceTooltip");
268 case WebAXRoleValueIndicator:
269 return result.append("ValueIndicator");
270 case WebAXRoleWebArea:
271 return result.append("WebArea");
272 case WebAXRoleWindow:
273 return result.append("Window");
274 default:
275 return result.append("Unknown");
276 }
277 }
278
getDescription(const WebAXObject & object)279 string getDescription(const WebAXObject& object)
280 {
281 string description = object.accessibilityDescription().utf8();
282 return description.insert(0, "AXDescription: ");
283 }
284
getHelpText(const WebAXObject & object)285 string getHelpText(const WebAXObject& object)
286 {
287 string helpText = object.helpText().utf8();
288 return helpText.insert(0, "AXHelp: ");
289 }
290
getStringValue(const WebAXObject & object)291 string getStringValue(const WebAXObject& object)
292 {
293 string value;
294 if (object.role() == WebAXRoleColorWell) {
295 int r, g, b;
296 char buffer[100];
297 object.colorValue(r, g, b);
298 snprintf(buffer, sizeof(buffer), "rgb %7.5f %7.5f %7.5f 1", r / 255., g / 255., b / 255.);
299 value = buffer;
300 } else {
301 value = object.stringValue().utf8();
302 }
303 return value.insert(0, "AXValue: ");
304 }
305
getRole(const WebAXObject & object)306 string getRole(const WebAXObject& object)
307 {
308 string roleString = roleToString(object.role());
309
310 // Special-case canvas with fallback content because Chromium wants to
311 // treat this as essentially a separate role that it can map differently depending
312 // on the platform.
313 if (object.role() == WebAXRoleCanvas && object.canvasHasFallbackContent())
314 roleString += "WithFallbackContent";
315
316 return roleString;
317 }
318
getTitle(const WebAXObject & object)319 string getTitle(const WebAXObject& object)
320 {
321 string title = object.title().utf8();
322 return title.insert(0, "AXTitle: ");
323 }
324
getOrientation(const WebAXObject & object)325 string getOrientation(const WebAXObject& object)
326 {
327 if (object.isVertical())
328 return "AXOrientation: AXVerticalOrientation";
329
330 return "AXOrientation: AXHorizontalOrientation";
331 }
332
getValueDescription(const WebAXObject & object)333 string getValueDescription(const WebAXObject& object)
334 {
335 string valueDescription = object.valueDescription().utf8();
336 return valueDescription.insert(0, "AXValueDescription: ");
337 }
338
getAttributes(const WebAXObject & object)339 string getAttributes(const WebAXObject& object)
340 {
341 // FIXME: Concatenate all attributes of the AXObject.
342 string attributes(getTitle(object));
343 attributes.append("\n");
344 attributes.append(getRole(object));
345 attributes.append("\n");
346 attributes.append(getDescription(object));
347 return attributes;
348 }
349
boundsForCharacter(const WebAXObject & object,int characterIndex)350 WebRect boundsForCharacter(const WebAXObject& object, int characterIndex)
351 {
352 BLINK_ASSERT(object.role() == WebAXRoleStaticText);
353 int end = 0;
354 for (unsigned i = 0; i < object.childCount(); i++) {
355 WebAXObject inlineTextBox = object.childAt(i);
356 BLINK_ASSERT(inlineTextBox.role() == WebAXRoleInlineTextBox);
357 int start = end;
358 end += inlineTextBox.stringValue().length();
359 if (end <= characterIndex)
360 continue;
361 WebRect inlineTextBoxRect = inlineTextBox.boundingBoxRect();
362 int localIndex = characterIndex - start;
363 WebVector<int> characterOffsets;
364 inlineTextBox.characterOffsets(characterOffsets);
365 BLINK_ASSERT(characterOffsets.size() > 0 && characterOffsets.size() == inlineTextBox.stringValue().length());
366 switch (inlineTextBox.textDirection()) {
367 case WebAXTextDirectionLR: {
368 if (localIndex) {
369 int left = inlineTextBoxRect.x + characterOffsets[localIndex - 1];
370 int width = characterOffsets[localIndex] - characterOffsets[localIndex - 1];
371 return WebRect(left, inlineTextBoxRect.y, width, inlineTextBoxRect.height);
372 }
373 return WebRect(inlineTextBoxRect.x, inlineTextBoxRect.y, characterOffsets[0], inlineTextBoxRect.height);
374 }
375 case WebAXTextDirectionRL: {
376 int right = inlineTextBoxRect.x + inlineTextBoxRect.width;
377
378 if (localIndex) {
379 int left = right - characterOffsets[localIndex];
380 int width = characterOffsets[localIndex] - characterOffsets[localIndex - 1];
381 return WebRect(left, inlineTextBoxRect.y, width, inlineTextBoxRect.height);
382 }
383 int left = right - characterOffsets[0];
384 return WebRect(left, inlineTextBoxRect.y, characterOffsets[0], inlineTextBoxRect.height);
385 }
386 case WebAXTextDirectionTB: {
387 if (localIndex) {
388 int top = inlineTextBoxRect.y + characterOffsets[localIndex - 1];
389 int height = characterOffsets[localIndex] - characterOffsets[localIndex - 1];
390 return WebRect(inlineTextBoxRect.x, top, inlineTextBoxRect.width, height);
391 }
392 return WebRect(inlineTextBoxRect.x, inlineTextBoxRect.y, inlineTextBoxRect.width, characterOffsets[0]);
393 }
394 case WebAXTextDirectionBT: {
395 int bottom = inlineTextBoxRect.y + inlineTextBoxRect.height;
396
397 if (localIndex) {
398 int top = bottom - characterOffsets[localIndex];
399 int height = characterOffsets[localIndex] - characterOffsets[localIndex - 1];
400 return WebRect(inlineTextBoxRect.x, top, inlineTextBoxRect.width, height);
401 }
402 int top = bottom - characterOffsets[0];
403 return WebRect(inlineTextBoxRect.x, top, inlineTextBoxRect.width, characterOffsets[0]);
404 }
405 }
406 }
407
408 BLINK_ASSERT(false);
409 return WebRect();
410 }
411
getBoundariesForOneWord(const WebAXObject & object,int characterIndex,int & wordStart,int & wordEnd)412 void getBoundariesForOneWord(const WebAXObject& object, int characterIndex, int& wordStart, int& wordEnd)
413 {
414 int end = 0;
415 for (unsigned i = 0; i < object.childCount(); i++) {
416 WebAXObject inlineTextBox = object.childAt(i);
417 BLINK_ASSERT(inlineTextBox.role() == WebAXRoleInlineTextBox);
418 int start = end;
419 end += inlineTextBox.stringValue().length();
420 if (end <= characterIndex)
421 continue;
422 int localIndex = characterIndex - start;
423
424 WebVector<int> starts;
425 WebVector<int> ends;
426 inlineTextBox.wordBoundaries(starts, ends);
427 size_t wordCount = starts.size();
428 BLINK_ASSERT(ends.size() == wordCount);
429
430 // If there are no words, use the InlineTextBox boundaries.
431 if (!wordCount) {
432 wordStart = start;
433 wordEnd = end;
434 return;
435 }
436
437 // Look for a character within any word other than the last.
438 for (size_t j = 0; j < wordCount - 1; j++) {
439 if (localIndex <= ends[j]) {
440 wordStart = start + starts[j];
441 wordEnd = start + ends[j];
442 return;
443 }
444 }
445
446 // Return the last word by default.
447 wordStart = start + starts[wordCount - 1];
448 wordEnd = start + ends[wordCount - 1];
449 return;
450 }
451 }
452
453 // Collects attributes into a string, delimited by dashes. Used by all methods
454 // that output lists of attributes: attributesOfLinkedUIElementsCallback,
455 // AttributesOfChildrenCallback, etc.
456 class AttributesCollector {
457 public:
collectAttributes(const WebAXObject & object)458 void collectAttributes(const WebAXObject& object)
459 {
460 m_attributes.append("\n------------\n");
461 m_attributes.append(getAttributes(object));
462 }
463
attributes() const464 string attributes() const { return m_attributes; }
465
466 private:
467 string m_attributes;
468 };
469
470 }
471
WebAXObjectProxy(const WebAXObject & object,Factory * factory)472 WebAXObjectProxy::WebAXObjectProxy(const WebAXObject& object, Factory* factory)
473 : m_accessibilityObject(object)
474 , m_factory(factory)
475 {
476
477 BLINK_ASSERT(factory);
478
479 //
480 // Properties
481 //
482
483 bindProperty("role", &WebAXObjectProxy::roleGetterCallback);
484 bindProperty("title", &WebAXObjectProxy::titleGetterCallback);
485 bindProperty("description", &WebAXObjectProxy::descriptionGetterCallback);
486 bindProperty("helpText", &WebAXObjectProxy::helpTextGetterCallback);
487 bindProperty("stringValue", &WebAXObjectProxy::stringValueGetterCallback);
488 bindProperty("x", &WebAXObjectProxy::xGetterCallback);
489 bindProperty("y", &WebAXObjectProxy::yGetterCallback);
490 bindProperty("width", &WebAXObjectProxy::widthGetterCallback);
491 bindProperty("height", &WebAXObjectProxy::heightGetterCallback);
492 bindProperty("intValue", &WebAXObjectProxy::intValueGetterCallback);
493 bindProperty("minValue", &WebAXObjectProxy::minValueGetterCallback);
494 bindProperty("maxValue", &WebAXObjectProxy::maxValueGetterCallback);
495 bindProperty("valueDescription", &WebAXObjectProxy::valueDescriptionGetterCallback);
496 bindProperty("childrenCount", &WebAXObjectProxy::childrenCountGetterCallback);
497 bindProperty("insertionPointLineNumber", &WebAXObjectProxy::insertionPointLineNumberGetterCallback);
498 bindProperty("selectedTextRange", &WebAXObjectProxy::selectedTextRangeGetterCallback);
499 bindProperty("isEnabled", &WebAXObjectProxy::isEnabledGetterCallback);
500 bindProperty("isRequired", &WebAXObjectProxy::isRequiredGetterCallback);
501 bindProperty("isFocused", &WebAXObjectProxy::isFocusedGetterCallback);
502 bindProperty("isFocusable", &WebAXObjectProxy::isFocusableGetterCallback);
503 bindProperty("isSelected", &WebAXObjectProxy::isSelectedGetterCallback);
504 bindProperty("isSelectable", &WebAXObjectProxy::isSelectableGetterCallback);
505 bindProperty("isMultiSelectable", &WebAXObjectProxy::isMultiSelectableGetterCallback);
506 bindProperty("isSelectedOptionActive", &WebAXObjectProxy::isSelectedOptionActiveGetterCallback);
507 bindProperty("isExpanded", &WebAXObjectProxy::isExpandedGetterCallback);
508 bindProperty("isChecked", &WebAXObjectProxy::isCheckedGetterCallback);
509 bindProperty("isVisible", &WebAXObjectProxy::isVisibleGetterCallback);
510 bindProperty("isOffScreen", &WebAXObjectProxy::isOffScreenGetterCallback);
511 bindProperty("isCollapsed", &WebAXObjectProxy::isCollapsedGetterCallback);
512 bindProperty("hasPopup", &WebAXObjectProxy::hasPopupGetterCallback);
513 bindProperty("isValid", &WebAXObjectProxy::isValidGetterCallback);
514 bindProperty("isReadOnly", &WebAXObjectProxy::isReadOnlyGetterCallback);
515 bindProperty("orientation", &WebAXObjectProxy::orientationGetterCallback);
516 bindProperty("clickPointX", &WebAXObjectProxy::clickPointXGetterCallback);
517 bindProperty("clickPointY", &WebAXObjectProxy::clickPointYGetterCallback);
518 bindProperty("rowCount", &WebAXObjectProxy::rowCountGetterCallback);
519 bindProperty("columnCount", &WebAXObjectProxy::columnCountGetterCallback);
520 bindProperty("isClickable", &WebAXObjectProxy::isClickableGetterCallback);
521
522 //
523 // Methods
524 //
525
526 bindMethod("allAttributes", &WebAXObjectProxy::allAttributesCallback);
527 bindMethod("attributesOfChildren", &WebAXObjectProxy::attributesOfChildrenCallback);
528 bindMethod("lineForIndex", &WebAXObjectProxy::lineForIndexCallback);
529 bindMethod("boundsForRange", &WebAXObjectProxy::boundsForRangeCallback);
530 bindMethod("childAtIndex", &WebAXObjectProxy::childAtIndexCallback);
531 bindMethod("elementAtPoint", &WebAXObjectProxy::elementAtPointCallback);
532 bindMethod("tableHeader", &WebAXObjectProxy::tableHeaderCallback);
533 bindMethod("rowIndexRange", &WebAXObjectProxy::rowIndexRangeCallback);
534 bindMethod("columnIndexRange", &WebAXObjectProxy::columnIndexRangeCallback);
535 bindMethod("cellForColumnAndRow", &WebAXObjectProxy::cellForColumnAndRowCallback);
536 bindMethod("titleUIElement", &WebAXObjectProxy::titleUIElementCallback);
537 bindMethod("setSelectedTextRange", &WebAXObjectProxy::setSelectedTextRangeCallback);
538 bindMethod("isAttributeSettable", &WebAXObjectProxy::isAttributeSettableCallback);
539 bindMethod("isPressActionSupported", &WebAXObjectProxy::isPressActionSupportedCallback);
540 bindMethod("isIncrementActionSupported", &WebAXObjectProxy::isIncrementActionSupportedCallback);
541 bindMethod("isDecrementActionSupported", &WebAXObjectProxy::isDecrementActionSupportedCallback);
542 bindMethod("parentElement", &WebAXObjectProxy::parentElementCallback);
543 bindMethod("increment", &WebAXObjectProxy::incrementCallback);
544 bindMethod("decrement", &WebAXObjectProxy::decrementCallback);
545 bindMethod("showMenu", &WebAXObjectProxy::showMenuCallback);
546 bindMethod("press", &WebAXObjectProxy::pressCallback);
547 bindMethod("isEqual", &WebAXObjectProxy::isEqualCallback);
548 bindMethod("addNotificationListener", &WebAXObjectProxy::addNotificationListenerCallback);
549 bindMethod("removeNotificationListener", &WebAXObjectProxy::removeNotificationListenerCallback);
550 bindMethod("takeFocus", &WebAXObjectProxy::takeFocusCallback);
551 bindMethod("scrollToMakeVisible", &WebAXObjectProxy::scrollToMakeVisibleCallback);
552 bindMethod("scrollToMakeVisibleWithSubFocus", &WebAXObjectProxy::scrollToMakeVisibleWithSubFocusCallback);
553 bindMethod("scrollToGlobalPoint", &WebAXObjectProxy::scrollToGlobalPointCallback);
554 bindMethod("wordStart", &WebAXObjectProxy::wordStartCallback);
555 bindMethod("wordEnd", &WebAXObjectProxy::wordEndCallback);
556
557 bindFallbackMethod(&WebAXObjectProxy::fallbackCallback);
558 }
559
getChildAtIndex(unsigned index)560 WebAXObjectProxy* WebAXObjectProxy::getChildAtIndex(unsigned index)
561 {
562 return m_factory->getOrCreate(accessibilityObject().childAt(index));
563 }
564
isEqual(const blink::WebAXObject & other)565 bool WebAXObjectProxy::isEqual(const blink::WebAXObject& other)
566 {
567 return accessibilityObject().equals(other);
568 }
569
notificationReceived(const char * notificationName)570 void WebAXObjectProxy::notificationReceived(const char* notificationName)
571 {
572 size_t callbackCount = m_notificationCallbacks.size();
573 for (size_t i = 0; i < callbackCount; i++) {
574 CppVariant notificationNameArgument;
575 notificationNameArgument.set(notificationName);
576 CppVariant invokeResult;
577 m_notificationCallbacks[i].invokeDefault(¬ificationNameArgument, 1, invokeResult);
578 }
579 }
580
581 //
582 // Properties
583 //
584
roleGetterCallback(CppVariant * result)585 void WebAXObjectProxy::roleGetterCallback(CppVariant* result)
586 {
587 result->set(getRole(accessibilityObject()));
588 }
589
titleGetterCallback(CppVariant * result)590 void WebAXObjectProxy::titleGetterCallback(CppVariant* result)
591 {
592 result->set(getTitle(accessibilityObject()));
593 }
594
descriptionGetterCallback(CppVariant * result)595 void WebAXObjectProxy::descriptionGetterCallback(CppVariant* result)
596 {
597 result->set(getDescription(accessibilityObject()));
598 }
599
helpTextGetterCallback(CppVariant * result)600 void WebAXObjectProxy::helpTextGetterCallback(CppVariant* result)
601 {
602 result->set(getHelpText(accessibilityObject()));
603 }
604
stringValueGetterCallback(CppVariant * result)605 void WebAXObjectProxy::stringValueGetterCallback(CppVariant* result)
606 {
607 result->set(getStringValue(accessibilityObject()));
608 }
609
xGetterCallback(CppVariant * result)610 void WebAXObjectProxy::xGetterCallback(CppVariant* result)
611 {
612 result->set(accessibilityObject().boundingBoxRect().x);
613 }
614
yGetterCallback(CppVariant * result)615 void WebAXObjectProxy::yGetterCallback(CppVariant* result)
616 {
617 result->set(accessibilityObject().boundingBoxRect().y);
618 }
619
widthGetterCallback(CppVariant * result)620 void WebAXObjectProxy::widthGetterCallback(CppVariant* result)
621 {
622 result->set(accessibilityObject().boundingBoxRect().width);
623 }
624
heightGetterCallback(CppVariant * result)625 void WebAXObjectProxy::heightGetterCallback(CppVariant* result)
626 {
627 result->set(accessibilityObject().boundingBoxRect().height);
628 }
629
intValueGetterCallback(CppVariant * result)630 void WebAXObjectProxy::intValueGetterCallback(CppVariant* result)
631 {
632 if (accessibilityObject().supportsRangeValue())
633 result->set(accessibilityObject().valueForRange());
634 else if (accessibilityObject().role() == WebAXRoleHeading)
635 result->set(accessibilityObject().headingLevel());
636 else
637 result->set(atoi(accessibilityObject().stringValue().utf8().data()));
638 }
639
minValueGetterCallback(CppVariant * result)640 void WebAXObjectProxy::minValueGetterCallback(CppVariant* result)
641 {
642 result->set(accessibilityObject().minValueForRange());
643 }
644
maxValueGetterCallback(CppVariant * result)645 void WebAXObjectProxy::maxValueGetterCallback(CppVariant* result)
646 {
647 result->set(accessibilityObject().maxValueForRange());
648 }
649
valueDescriptionGetterCallback(CppVariant * result)650 void WebAXObjectProxy::valueDescriptionGetterCallback(CppVariant* result)
651 {
652 result->set(getValueDescription(accessibilityObject()));
653 }
654
childrenCountGetterCallback(CppVariant * result)655 void WebAXObjectProxy::childrenCountGetterCallback(CppVariant* result)
656 {
657 int count = 1; // Root object always has only one child, the WebView.
658 if (!isRoot())
659 count = accessibilityObject().childCount();
660 result->set(count);
661 }
662
insertionPointLineNumberGetterCallback(CppVariant * result)663 void WebAXObjectProxy::insertionPointLineNumberGetterCallback(CppVariant* result)
664 {
665 if (!accessibilityObject().isFocused()) {
666 result->set(-1);
667 return;
668 }
669
670 int lineNumber = accessibilityObject().selectionEndLineNumber();
671 result->set(lineNumber);
672 }
673
selectedTextRangeGetterCallback(CppVariant * result)674 void WebAXObjectProxy::selectedTextRangeGetterCallback(CppVariant* result)
675 {
676 unsigned selectionStart = accessibilityObject().selectionStart();
677 unsigned selectionEnd = accessibilityObject().selectionEnd();
678 char buffer[100];
679 snprintf(buffer, sizeof(buffer), "{%d, %d}", selectionStart, selectionEnd - selectionStart);
680
681 result->set(std::string(buffer));
682 }
683
isEnabledGetterCallback(CppVariant * result)684 void WebAXObjectProxy::isEnabledGetterCallback(CppVariant* result)
685 {
686 result->set(accessibilityObject().isEnabled());
687 }
688
isRequiredGetterCallback(CppVariant * result)689 void WebAXObjectProxy::isRequiredGetterCallback(CppVariant* result)
690 {
691 result->set(accessibilityObject().isRequired());
692 }
693
isFocusedGetterCallback(CppVariant * result)694 void WebAXObjectProxy::isFocusedGetterCallback(CppVariant* result)
695 {
696 result->set(accessibilityObject().isFocused());
697 }
698
isFocusableGetterCallback(CppVariant * result)699 void WebAXObjectProxy::isFocusableGetterCallback(CppVariant* result)
700 {
701 result->set(accessibilityObject().canSetFocusAttribute());
702 }
703
isSelectedGetterCallback(CppVariant * result)704 void WebAXObjectProxy::isSelectedGetterCallback(CppVariant* result)
705 {
706 result->set(accessibilityObject().isSelected());
707 }
708
isSelectableGetterCallback(CppVariant * result)709 void WebAXObjectProxy::isSelectableGetterCallback(CppVariant* result)
710 {
711 result->set(accessibilityObject().canSetSelectedAttribute());
712 }
713
isMultiSelectableGetterCallback(CppVariant * result)714 void WebAXObjectProxy::isMultiSelectableGetterCallback(CppVariant* result)
715 {
716 result->set(accessibilityObject().isMultiSelectable());
717 }
718
isSelectedOptionActiveGetterCallback(CppVariant * result)719 void WebAXObjectProxy::isSelectedOptionActiveGetterCallback(CppVariant* result)
720 {
721 result->set(accessibilityObject().isSelectedOptionActive());
722 }
723
isExpandedGetterCallback(CppVariant * result)724 void WebAXObjectProxy::isExpandedGetterCallback(CppVariant* result)
725 {
726 result->set(!accessibilityObject().isCollapsed());
727 }
728
isCheckedGetterCallback(CppVariant * result)729 void WebAXObjectProxy::isCheckedGetterCallback(CppVariant* result)
730 {
731 result->set(accessibilityObject().isChecked());
732 }
733
isVisibleGetterCallback(CppVariant * result)734 void WebAXObjectProxy::isVisibleGetterCallback(CppVariant* result)
735 {
736 result->set(accessibilityObject().isVisible());
737 }
738
isOffScreenGetterCallback(CppVariant * result)739 void WebAXObjectProxy::isOffScreenGetterCallback(CppVariant* result)
740 {
741 result->set(accessibilityObject().isOffScreen());
742 }
743
isCollapsedGetterCallback(CppVariant * result)744 void WebAXObjectProxy::isCollapsedGetterCallback(CppVariant* result)
745 {
746 result->set(accessibilityObject().isCollapsed());
747 }
748
hasPopupGetterCallback(CppVariant * result)749 void WebAXObjectProxy::hasPopupGetterCallback(CppVariant* result)
750 {
751 result->set(accessibilityObject().ariaHasPopup());
752 }
753
isValidGetterCallback(CppVariant * result)754 void WebAXObjectProxy::isValidGetterCallback(CppVariant* result)
755 {
756 result->set(!accessibilityObject().isDetached());
757 }
758
isReadOnlyGetterCallback(CppVariant * result)759 void WebAXObjectProxy::isReadOnlyGetterCallback(CppVariant* result)
760 {
761 result->set(accessibilityObject().isReadOnly());
762 }
763
orientationGetterCallback(CppVariant * result)764 void WebAXObjectProxy::orientationGetterCallback(CppVariant* result)
765 {
766 result->set(getOrientation(accessibilityObject()));
767 }
768
clickPointXGetterCallback(CppVariant * result)769 void WebAXObjectProxy::clickPointXGetterCallback(CppVariant* result)
770 {
771 result->set(accessibilityObject().clickPoint().x);
772 }
773
clickPointYGetterCallback(CppVariant * result)774 void WebAXObjectProxy::clickPointYGetterCallback(CppVariant* result)
775 {
776 result->set(accessibilityObject().clickPoint().y);
777 }
778
rowCountGetterCallback(CppVariant * result)779 void WebAXObjectProxy::rowCountGetterCallback(CppVariant* result)
780 {
781 result->set(static_cast<int32_t>(accessibilityObject().rowCount()));
782 }
783
columnCountGetterCallback(CppVariant * result)784 void WebAXObjectProxy::columnCountGetterCallback(CppVariant* result)
785 {
786 result->set(static_cast<int32_t>(accessibilityObject().columnCount()));
787 }
788
isClickableGetterCallback(CppVariant * result)789 void WebAXObjectProxy::isClickableGetterCallback(CppVariant* result)
790 {
791 result->set(accessibilityObject().isClickable());
792 }
793
794 //
795 // Methods
796 //
797
allAttributesCallback(const CppArgumentList &,CppVariant * result)798 void WebAXObjectProxy::allAttributesCallback(const CppArgumentList&, CppVariant* result)
799 {
800 result->set(getAttributes(accessibilityObject()));
801 }
802
attributesOfChildrenCallback(const CppArgumentList & arguments,CppVariant * result)803 void WebAXObjectProxy::attributesOfChildrenCallback(const CppArgumentList& arguments, CppVariant* result)
804 {
805 AttributesCollector collector;
806 unsigned size = accessibilityObject().childCount();
807 for (unsigned i = 0; i < size; ++i)
808 collector.collectAttributes(accessibilityObject().childAt(i));
809 result->set(collector.attributes());
810 }
811
lineForIndexCallback(const CppArgumentList & arguments,CppVariant * result)812 void WebAXObjectProxy::lineForIndexCallback(const CppArgumentList& arguments, CppVariant* result)
813 {
814 if (!arguments.size() || !arguments[0].isNumber()) {
815 result->setNull();
816 return;
817 }
818
819 int index = arguments[0].toInt32();
820
821 WebVector<int> lineBreaks;
822 accessibilityObject().lineBreaks(lineBreaks);
823 int line = 0;
824 int vectorSize = static_cast<int>(lineBreaks.size());
825 while (line < vectorSize && lineBreaks[line] <= index)
826 line++;
827 result->set(line);
828 }
829
boundsForRangeCallback(const CppArgumentList & arguments,CppVariant * result)830 void WebAXObjectProxy::boundsForRangeCallback(const CppArgumentList& arguments, CppVariant* result)
831 {
832 result->setNull();
833
834 if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNumber())
835 return;
836
837 if (accessibilityObject().role() != WebAXRoleStaticText)
838 return;
839
840 int start = arguments[0].toInt32();
841 int end = arguments[1].toInt32();
842 int len = end - start;
843
844 // Get the bounds for each character and union them into one large rectangle.
845 // This is just for testing so it doesn't need to be efficient.
846 WebRect bounds = boundsForCharacter(accessibilityObject(), start);
847 for (int i = 1; i < len; i++) {
848 WebRect next = boundsForCharacter(accessibilityObject(), start + i);
849 int right = std::max(bounds.x + bounds.width, next.x + next.width);
850 int bottom = std::max(bounds.y + bounds.height, next.y + next.height);
851 bounds.x = std::min(bounds.x, next.x);
852 bounds.y = std::min(bounds.y, next.y);
853 bounds.width = right - bounds.x;
854 bounds.height = bottom - bounds.y;
855 }
856
857 char buffer[100];
858 snprintf(buffer, sizeof(buffer), "{x: %d, y: %d, width: %d, height: %d}", bounds.x, bounds.y, bounds.width, bounds.height);
859 result->set(string(buffer));
860 }
861
childAtIndexCallback(const CppArgumentList & arguments,CppVariant * result)862 void WebAXObjectProxy::childAtIndexCallback(const CppArgumentList& arguments, CppVariant* result)
863 {
864 if (!arguments.size() || !arguments[0].isNumber()) {
865 result->setNull();
866 return;
867 }
868
869 WebAXObjectProxy* child = getChildAtIndex(arguments[0].toInt32());
870 if (!child) {
871 result->setNull();
872 return;
873 }
874
875 result->set(*(child->getAsCppVariant()));
876 }
877
elementAtPointCallback(const CppArgumentList & arguments,CppVariant * result)878 void WebAXObjectProxy::elementAtPointCallback(const CppArgumentList& arguments, CppVariant* result)
879 {
880 result->setNull();
881
882 if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNumber())
883 return;
884
885 int x = arguments[0].toInt32();
886 int y = arguments[1].toInt32();
887 WebPoint point(x, y);
888 WebAXObject obj = accessibilityObject().hitTest(point);
889 if (obj.isNull())
890 return;
891
892 result->set(*(m_factory->getOrCreate(obj)->getAsCppVariant()));
893 }
894
tableHeaderCallback(const CppArgumentList &,CppVariant * result)895 void WebAXObjectProxy::tableHeaderCallback(const CppArgumentList&, CppVariant* result)
896 {
897 WebAXObject obj = accessibilityObject().headerContainerObject();
898 if (obj.isNull()) {
899 result->setNull();
900 return;
901 }
902
903 result->set(*(m_factory->getOrCreate(obj)->getAsCppVariant()));
904 }
905
rowIndexRangeCallback(const CppArgumentList &,CppVariant * result)906 void WebAXObjectProxy::rowIndexRangeCallback(const CppArgumentList&, CppVariant* result)
907 {
908 unsigned rowIndex = accessibilityObject().cellRowIndex();
909 unsigned rowSpan = accessibilityObject().cellRowSpan();
910 char buffer[100];
911 snprintf(buffer, sizeof(buffer), "{%d, %d}", rowIndex, rowSpan);
912 string value = buffer;
913 result->set(std::string(buffer));
914 }
915
columnIndexRangeCallback(const CppArgumentList &,CppVariant * result)916 void WebAXObjectProxy::columnIndexRangeCallback(const CppArgumentList&, CppVariant* result)
917 {
918 unsigned columnIndex = accessibilityObject().cellColumnIndex();
919 unsigned columnSpan = accessibilityObject().cellColumnSpan();
920 char buffer[100];
921 snprintf(buffer, sizeof(buffer), "{%d, %d}", columnIndex, columnSpan);
922 result->set(std::string(buffer));
923 }
924
cellForColumnAndRowCallback(const CppArgumentList & arguments,CppVariant * result)925 void WebAXObjectProxy::cellForColumnAndRowCallback(const CppArgumentList& arguments, CppVariant* result)
926 {
927 if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNumber())
928 return;
929
930 int column = arguments[0].toInt32();
931 int row = arguments[1].toInt32();
932 WebAXObject obj = accessibilityObject().cellForColumnAndRow(column, row);
933 if (obj.isNull()) {
934 result->setNull();
935 return;
936 }
937
938 result->set(*(m_factory->getOrCreate(obj)->getAsCppVariant()));
939 }
940
titleUIElementCallback(const CppArgumentList &,CppVariant * result)941 void WebAXObjectProxy::titleUIElementCallback(const CppArgumentList&, CppVariant* result)
942 {
943 WebAXObject obj = accessibilityObject().titleUIElement();
944 if (obj.isNull()) {
945 result->setNull();
946 return;
947 }
948
949 result->set(*(m_factory->getOrCreate(obj)->getAsCppVariant()));
950 }
951
setSelectedTextRangeCallback(const CppArgumentList & arguments,CppVariant * result)952 void WebAXObjectProxy::setSelectedTextRangeCallback(const CppArgumentList&arguments, CppVariant* result)
953 {
954 result->setNull();
955 if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNumber())
956 return;
957
958 int selectionStart = arguments[0].toInt32();
959 int selectionEnd = selectionStart + arguments[1].toInt32();
960 accessibilityObject().setSelectedTextRange(selectionStart, selectionEnd);
961 }
962
isAttributeSettableCallback(const CppArgumentList & arguments,CppVariant * result)963 void WebAXObjectProxy::isAttributeSettableCallback(const CppArgumentList& arguments, CppVariant* result)
964 {
965 if (arguments.size() < 1 && !arguments[0].isString()) {
966 result->setNull();
967 return;
968 }
969
970 string attribute = arguments[0].toString();
971 bool settable = false;
972 if (attribute == "AXValue")
973 settable = accessibilityObject().canSetValueAttribute();
974 result->set(settable);
975 }
976
isPressActionSupportedCallback(const CppArgumentList &,CppVariant * result)977 void WebAXObjectProxy::isPressActionSupportedCallback(const CppArgumentList&, CppVariant* result)
978 {
979 result->set(accessibilityObject().canPress());
980 }
981
isIncrementActionSupportedCallback(const CppArgumentList &,CppVariant * result)982 void WebAXObjectProxy::isIncrementActionSupportedCallback(const CppArgumentList&, CppVariant* result)
983 {
984 result->set(accessibilityObject().canIncrement());
985 }
986
isDecrementActionSupportedCallback(const CppArgumentList &,CppVariant * result)987 void WebAXObjectProxy::isDecrementActionSupportedCallback(const CppArgumentList&, CppVariant* result)
988 {
989 result->set(accessibilityObject().canDecrement());
990 }
991
parentElementCallback(const CppArgumentList &,CppVariant * result)992 void WebAXObjectProxy::parentElementCallback(const CppArgumentList&, CppVariant* result)
993 {
994 WebAXObject parentObject = accessibilityObject().parentObject();
995 while (parentObject.accessibilityIsIgnored())
996 parentObject = parentObject.parentObject();
997 WebAXObjectProxy* parent = m_factory->getOrCreate(parentObject);
998 if (!parent) {
999 result->setNull();
1000 return;
1001 }
1002
1003 result->set(*(parent->getAsCppVariant()));
1004 }
1005
incrementCallback(const CppArgumentList &,CppVariant * result)1006 void WebAXObjectProxy::incrementCallback(const CppArgumentList&, CppVariant* result)
1007 {
1008 accessibilityObject().increment();
1009 result->setNull();
1010 }
1011
decrementCallback(const CppArgumentList &,CppVariant * result)1012 void WebAXObjectProxy::decrementCallback(const CppArgumentList&, CppVariant* result)
1013 {
1014 accessibilityObject().decrement();
1015 result->setNull();
1016 }
1017
showMenuCallback(const CppArgumentList &,CppVariant * result)1018 void WebAXObjectProxy::showMenuCallback(const CppArgumentList&, CppVariant* result)
1019 {
1020 result->setNull();
1021 }
1022
pressCallback(const CppArgumentList &,CppVariant * result)1023 void WebAXObjectProxy::pressCallback(const CppArgumentList&, CppVariant* result)
1024 {
1025 accessibilityObject().press();
1026 result->setNull();
1027 }
1028
isEqualCallback(const CppArgumentList & arguments,CppVariant * result)1029 void WebAXObjectProxy::isEqualCallback(const CppArgumentList& arguments, CppVariant* result)
1030 {
1031 if (arguments.size() < 1 || !arguments[0].isObject()) {
1032 result->setNull();
1033 return;
1034 }
1035
1036 result->set(arguments[0].isEqual(*getAsCppVariant()));
1037 }
1038
addNotificationListenerCallback(const CppArgumentList & arguments,CppVariant * result)1039 void WebAXObjectProxy::addNotificationListenerCallback(const CppArgumentList& arguments, CppVariant* result)
1040 {
1041 if (arguments.size() < 1 || !arguments[0].isObject()) {
1042 result->setNull();
1043 return;
1044 }
1045
1046 m_notificationCallbacks.push_back(arguments[0]);
1047 result->setNull();
1048 }
1049
removeNotificationListenerCallback(const CppArgumentList &,CppVariant * result)1050 void WebAXObjectProxy::removeNotificationListenerCallback(const CppArgumentList&, CppVariant* result)
1051 {
1052 // FIXME: Implement this.
1053 result->setNull();
1054 }
1055
takeFocusCallback(const CppArgumentList &,CppVariant * result)1056 void WebAXObjectProxy::takeFocusCallback(const CppArgumentList&, CppVariant* result)
1057 {
1058 accessibilityObject().setFocused(true);
1059 result->setNull();
1060 }
1061
scrollToMakeVisibleCallback(const CppArgumentList &,CppVariant * result)1062 void WebAXObjectProxy::scrollToMakeVisibleCallback(const CppArgumentList&, CppVariant* result)
1063 {
1064 accessibilityObject().scrollToMakeVisible();
1065 result->setNull();
1066 }
1067
scrollToMakeVisibleWithSubFocusCallback(const CppArgumentList & arguments,CppVariant * result)1068 void WebAXObjectProxy::scrollToMakeVisibleWithSubFocusCallback(const CppArgumentList& arguments, CppVariant* result)
1069 {
1070 result->setNull();
1071
1072 if (arguments.size() != 4
1073 || !arguments[0].isNumber()
1074 || !arguments[1].isNumber()
1075 || !arguments[2].isNumber()
1076 || !arguments[3].isNumber())
1077 return;
1078
1079 int x = arguments[0].toInt32();
1080 int y = arguments[1].toInt32();
1081 int width = arguments[2].toInt32();
1082 int height = arguments[3].toInt32();
1083 accessibilityObject().scrollToMakeVisibleWithSubFocus(WebRect(x, y, width, height));
1084 result->setNull();
1085 }
1086
scrollToGlobalPointCallback(const CppArgumentList & arguments,CppVariant * result)1087 void WebAXObjectProxy::scrollToGlobalPointCallback(const CppArgumentList& arguments, CppVariant* result)
1088 {
1089 result->setNull();
1090
1091 if (arguments.size() != 2
1092 || !arguments[0].isNumber()
1093 || !arguments[1].isNumber())
1094 return;
1095
1096 int x = arguments[0].toInt32();
1097 int y = arguments[1].toInt32();
1098
1099 accessibilityObject().scrollToGlobalPoint(WebPoint(x, y));
1100 result->setNull();
1101 }
1102
wordStartCallback(const CppArgumentList & arguments,CppVariant * result)1103 void WebAXObjectProxy::wordStartCallback(const CppArgumentList& arguments, CppVariant* result)
1104 {
1105 result->setNull();
1106
1107 if (arguments.size() != 1 || !arguments[0].isNumber())
1108 return;
1109
1110 if (accessibilityObject().role() != WebAXRoleStaticText)
1111 return;
1112
1113 int characterIndex = arguments[0].toInt32();
1114 int wordStart, wordEnd;
1115 getBoundariesForOneWord(accessibilityObject(), characterIndex, wordStart, wordEnd);
1116 result->set(wordStart);
1117 }
1118
wordEndCallback(const CppArgumentList & arguments,CppVariant * result)1119 void WebAXObjectProxy::wordEndCallback(const CppArgumentList& arguments, CppVariant* result)
1120 {
1121 result->setNull();
1122
1123 if (arguments.size() != 1 || !arguments[0].isNumber())
1124 return;
1125
1126 if (accessibilityObject().role() != WebAXRoleStaticText)
1127 return;
1128
1129 int characterIndex = arguments[0].toInt32();
1130 int wordStart, wordEnd;
1131 getBoundariesForOneWord(accessibilityObject(), characterIndex, wordStart, wordEnd);
1132 result->set(wordEnd);
1133 }
1134
fallbackCallback(const CppArgumentList &,CppVariant * result)1135 void WebAXObjectProxy::fallbackCallback(const CppArgumentList &, CppVariant* result)
1136 {
1137 result->setNull();
1138 }
1139
RootWebAXObjectProxy(const WebAXObject & object,Factory * factory)1140 RootWebAXObjectProxy::RootWebAXObjectProxy(const WebAXObject &object, Factory *factory)
1141 : WebAXObjectProxy(object, factory) { }
1142
getChildAtIndex(unsigned index)1143 WebAXObjectProxy* RootWebAXObjectProxy::getChildAtIndex(unsigned index)
1144 {
1145 if (index)
1146 return 0;
1147
1148 return factory()->getOrCreate(accessibilityObject());
1149 }
1150
1151
~WebAXObjectProxyList()1152 WebAXObjectProxyList ::~WebAXObjectProxyList()
1153 {
1154 clear();
1155 }
1156
clear()1157 void WebAXObjectProxyList::clear()
1158 {
1159 for (ElementList::iterator i = m_elements.begin(); i != m_elements.end(); ++i)
1160 delete (*i);
1161 m_elements.clear();
1162 }
1163
getOrCreate(const WebAXObject & object)1164 WebAXObjectProxy* WebAXObjectProxyList::getOrCreate(const WebAXObject& object)
1165 {
1166 if (object.isNull())
1167 return 0;
1168
1169 size_t elementCount = m_elements.size();
1170 for (size_t i = 0; i < elementCount; i++) {
1171 if (m_elements[i]->isEqual(object))
1172 return m_elements[i];
1173 }
1174
1175 WebAXObjectProxy* element = new WebAXObjectProxy(object, this);
1176 m_elements.push_back(element);
1177 return element;
1178 }
1179
createRoot(const WebAXObject & object)1180 WebAXObjectProxy* WebAXObjectProxyList::createRoot(const WebAXObject& object)
1181 {
1182 WebAXObjectProxy* element = new RootWebAXObjectProxy(object, this);
1183 m_elements.push_back(element);
1184 return element;
1185 }
1186
1187 }
1188