1a7d3fffaa6f1f440bc553e557e9d62eac5246c9
[WebKit-https.git] / Tools / DumpRenderTree / chromium / TestRunner / src / AccessibilityUIElementChromium.cpp
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 "config.h"
32 #include "AccessibilityUIElementChromium.h"
33
34 #include "WebAccessibilityObject.h"
35 #include "platform/WebCString.h"
36 #include "platform/WebPoint.h"
37 #include "platform/WebRect.h"
38 #include "platform/WebString.h"
39 #include <wtf/Assertions.h>
40 #include <wtf/StringExtras.h>
41
42 using namespace WebKit;
43 using namespace std;
44
45 namespace WebTestRunner {
46
47 namespace {
48
49 // Map role value to string, matching Safari/Mac platform implementation to
50 // avoid rebaselining layout tests.
51 string roleToString(WebAccessibilityRole role)
52 {
53     string result = "AXRole: AX";
54     switch (role) {
55     case WebAccessibilityRoleButton:
56         return result.append("Button");
57     case WebAccessibilityRoleRadioButton:
58         return result.append("RadioButton");
59     case WebAccessibilityRoleCheckBox:
60         return result.append("CheckBox");
61     case WebAccessibilityRoleSlider:
62         return result.append("Slider");
63     case WebAccessibilityRoleTabGroup:
64         return result.append("TabGroup");
65     case WebAccessibilityRoleTextField:
66         return result.append("TextField");
67     case WebAccessibilityRoleStaticText:
68         return result.append("StaticText");
69     case WebAccessibilityRoleTextArea:
70         return result.append("TextArea");
71     case WebAccessibilityRoleScrollArea:
72         return result.append("ScrollArea");
73     case WebAccessibilityRolePopUpButton:
74         return result.append("PopUpButton");
75     case WebAccessibilityRoleMenuButton:
76         return result.append("MenuButton");
77     case WebAccessibilityRoleTable:
78         return result.append("Table");
79     case WebAccessibilityRoleApplication:
80         return result.append("Application");
81     case WebAccessibilityRoleGroup:
82         return result.append("Group");
83     case WebAccessibilityRoleRadioGroup:
84         return result.append("RadioGroup");
85     case WebAccessibilityRoleList:
86         return result.append("List");
87     case WebAccessibilityRoleScrollBar:
88         return result.append("ScrollBar");
89     case WebAccessibilityRoleValueIndicator:
90         return result.append("ValueIndicator");
91     case WebAccessibilityRoleImage:
92         return result.append("Image");
93     case WebAccessibilityRoleMenuBar:
94         return result.append("MenuBar");
95     case WebAccessibilityRoleMenu:
96         return result.append("Menu");
97     case WebAccessibilityRoleMenuItem:
98         return result.append("MenuItem");
99     case WebAccessibilityRoleColumn:
100         return result.append("Column");
101     case WebAccessibilityRoleRow:
102         return result.append("Row");
103     case WebAccessibilityRoleToolbar:
104         return result.append("Toolbar");
105     case WebAccessibilityRoleBusyIndicator:
106         return result.append("BusyIndicator");
107     case WebAccessibilityRoleProgressIndicator:
108         return result.append("ProgressIndicator");
109     case WebAccessibilityRoleWindow:
110         return result.append("Window");
111     case WebAccessibilityRoleDrawer:
112         return result.append("Drawer");
113     case WebAccessibilityRoleSystemWide:
114         return result.append("SystemWide");
115     case WebAccessibilityRoleOutline:
116         return result.append("Outline");
117     case WebAccessibilityRoleIncrementor:
118         return result.append("Incrementor");
119     case WebAccessibilityRoleBrowser:
120         return result.append("Browser");
121     case WebAccessibilityRoleComboBox:
122         return result.append("ComboBox");
123     case WebAccessibilityRoleSplitGroup:
124         return result.append("SplitGroup");
125     case WebAccessibilityRoleSplitter:
126         return result.append("Splitter");
127     case WebAccessibilityRoleColorWell:
128         return result.append("ColorWell");
129     case WebAccessibilityRoleGrowArea:
130         return result.append("GrowArea");
131     case WebAccessibilityRoleSheet:
132         return result.append("Sheet");
133     case WebAccessibilityRoleHelpTag:
134         return result.append("HelpTag");
135     case WebAccessibilityRoleMatte:
136         return result.append("Matte");
137     case WebAccessibilityRoleRuler:
138         return result.append("Ruler");
139     case WebAccessibilityRoleRulerMarker:
140         return result.append("RulerMarker");
141     case WebAccessibilityRoleLink:
142         return result.append("Link");
143     case WebAccessibilityRoleDisclosureTriangle:
144         return result.append("DisclosureTriangle");
145     case WebAccessibilityRoleGrid:
146         return result.append("Grid");
147     case WebAccessibilityRoleCell:
148         return result.append("Cell");
149     case WebAccessibilityRoleColumnHeader:
150         return result.append("ColumnHeader");
151     case WebAccessibilityRoleRowHeader:
152         return result.append("RowHeader");
153     case WebAccessibilityRoleWebCoreLink:
154         // Maps to Link role.
155         return result.append("Link");
156     case WebAccessibilityRoleImageMapLink:
157         return result.append("ImageMapLink");
158     case WebAccessibilityRoleImageMap:
159         return result.append("ImageMap");
160     case WebAccessibilityRoleListMarker:
161         return result.append("ListMarker");
162     case WebAccessibilityRoleWebArea:
163         return result.append("WebArea");
164     case WebAccessibilityRoleHeading:
165         return result.append("Heading");
166     case WebAccessibilityRoleListBox:
167         return result.append("ListBox");
168     case WebAccessibilityRoleListBoxOption:
169         return result.append("ListBoxOption");
170     case WebAccessibilityRoleTableHeaderContainer:
171         return result.append("TableHeaderContainer");
172     case WebAccessibilityRoleDefinitionListTerm:
173         return result.append("DefinitionListTerm");
174     case WebAccessibilityRoleDefinitionListDefinition:
175         return result.append("DefinitionListDefinition");
176     case WebAccessibilityRoleAnnotation:
177         return result.append("Annotation");
178     case WebAccessibilityRoleSliderThumb:
179         return result.append("SliderThumb");
180     case WebAccessibilityRoleLandmarkApplication:
181         return result.append("LandmarkApplication");
182     case WebAccessibilityRoleLandmarkBanner:
183         return result.append("LandmarkBanner");
184     case WebAccessibilityRoleLandmarkComplementary:
185         return result.append("LandmarkComplementary");
186     case WebAccessibilityRoleLandmarkContentInfo:
187         return result.append("LandmarkContentInfo");
188     case WebAccessibilityRoleLandmarkMain:
189         return result.append("LandmarkMain");
190     case WebAccessibilityRoleLandmarkNavigation:
191         return result.append("LandmarkNavigation");
192     case WebAccessibilityRoleLandmarkSearch:
193         return result.append("LandmarkSearch");
194     case WebAccessibilityRoleApplicationLog:
195         return result.append("ApplicationLog");
196     case WebAccessibilityRoleApplicationMarquee:
197         return result.append("ApplicationMarquee");
198     case WebAccessibilityRoleApplicationStatus:
199         return result.append("ApplicationStatus");
200     case WebAccessibilityRoleApplicationTimer:
201         return result.append("ApplicationTimer");
202     case WebAccessibilityRoleDocument:
203         return result.append("Document");
204     case WebAccessibilityRoleDocumentArticle:
205         return result.append("DocumentArticle");
206     case WebAccessibilityRoleDocumentNote:
207         return result.append("DocumentNote");
208     case WebAccessibilityRoleDocumentRegion:
209         return result.append("DocumentRegion");
210     case WebAccessibilityRoleUserInterfaceTooltip:
211         return result.append("UserInterfaceTooltip");
212     case WebAccessibilityRoleToggleButton:
213         return result.append("ToggleButton");
214     case WebAccessibilityRoleCanvas:
215         return result.append("Canvas");
216     case WebAccessibilityRoleParagraph:
217         return result.append("Paragraph");
218     case WebAccessibilityRoleDiv:
219         return result.append("Div");
220     case WebAccessibilityRoleLabel:
221         return result.append("Label");
222     case WebAccessibilityRoleForm:
223         return result.append("Form");
224     case WebAccessibilityRoleHorizontalRule:
225         return result.append("HorizontalRule");
226     case WebAccessibilityRoleLegend:
227         return result.append("Legend");
228     case WebAccessibilityRoleApplicationAlert:
229         return result.append("Alert");
230     case WebAccessibilityRoleApplicationAlertDialog:
231         return result.append("AlertDialog");
232     case WebAccessibilityRoleApplicationDialog:
233         return result.append("ApplicationDialog");
234     case WebAccessibilityRoleDirectory:
235         return result.append("Directory");
236     case WebAccessibilityRoleDocumentMath:
237         return result.append("Math");
238     case WebAccessibilityRoleEditableText:
239         return result.append("EditableText");
240     case WebAccessibilityRoleFooter:
241         return result.append("Footer");
242     case WebAccessibilityRoleIgnored:
243         return result.append("Ignored");
244     case WebAccessibilityRoleListItem:
245         return result.append("ListItem");
246     case WebAccessibilityRoleMenuListPopup:
247         return result.append("MenuListPopup");
248     case WebAccessibilityRoleMenuListOption:
249         return result.append("MenuListOption");
250     case WebAccessibilityRolePresentational:
251         return result.append("Presentational");
252     case WebAccessibilityRoleSpinButton:
253         return result.append("SpinButton");
254     case WebAccessibilityRoleSpinButtonPart:
255         return result.append("SpinButtonPart");
256     case WebAccessibilityRoleTabList:
257         return result.append("TabList");
258     case WebAccessibilityRoleTabPanel:
259         return result.append("TabPanel");
260     case WebAccessibilityRoleTab:
261         return result.append("Tab");
262     case WebAccessibilityRoleTreeRole:
263         return result.append("Tree");
264     case WebAccessibilityRoleTreeGrid:
265         return result.append("TreeGrid");
266     case WebAccessibilityRoleTreeItemRole:
267         return result.append("TreeItem");
268     case WebAccessibilityRoleUnknown:
269     default:
270         return result.append("Unknown");
271     }
272 }
273
274 string getDescription(const WebAccessibilityObject& object)
275 {
276     string description = object.accessibilityDescription().utf8();
277     return description.insert(0, "AXDescription: ");
278 }
279
280 string getHelpText(const WebAccessibilityObject& object)
281 {
282     string helpText = object.helpText().utf8();
283     return helpText.insert(0, "AXHelp: ");
284 }
285
286 string getStringValue(const WebAccessibilityObject& object)
287 {
288     string value = object.stringValue().utf8();
289     return value.insert(0, "AXValue: ");
290 }
291
292 string getRole(const WebAccessibilityObject& object)
293 {
294     string roleString = roleToString(object.roleValue());
295
296     // Special-case canvas with fallback content because Chromium wants to
297     // treat this as essentially a separate role that it can map differently depending
298     // on the platform.
299     if (object.roleValue() == WebAccessibilityRoleCanvas && object.canvasHasFallbackContent())
300         roleString += "WithFallbackContent";
301
302     return roleString;
303 }
304
305 string getTitle(const WebAccessibilityObject& object)
306 {
307     string title = object.title().utf8();
308     return title.insert(0, "AXTitle: ");
309 }
310
311 string getOrientation(const WebAccessibilityObject& object)
312 {
313     if (object.isVertical())
314         return "AXOrientation: AXVerticalOrientation";
315
316     return "AXOrientation: AXHorizontalOrientation";
317 }
318
319 string getValueDescription(const WebAccessibilityObject& object)
320 {
321     string valueDescription = object.valueDescription().utf8();
322     return valueDescription.insert(0, "AXValueDescription: ");
323 }
324
325 string getAttributes(const WebAccessibilityObject& object)
326 {
327     // FIXME: Concatenate all attributes of the AccessibilityObject.
328     string attributes(getTitle(object));
329     attributes.append("\n");
330     attributes.append(getRole(object));
331     attributes.append("\n");
332     attributes.append(getDescription(object));
333     return attributes;
334 }
335
336
337 // Collects attributes into a string, delimited by dashes. Used by all methods
338 // that output lists of attributes: attributesOfLinkedUIElementsCallback,
339 // AttributesOfChildrenCallback, etc.
340 class AttributesCollector {
341 public:
342     void collectAttributes(const WebAccessibilityObject& object)
343     {
344         m_attributes.append("\n------------\n");
345         m_attributes.append(getAttributes(object));
346     }
347
348     string attributes() const { return m_attributes; }
349
350 private:
351     string m_attributes;
352 };
353
354 }
355
356 AccessibilityUIElement::AccessibilityUIElement(const WebAccessibilityObject& object, Factory* factory)
357     : m_accessibilityObject(object)
358     , m_factory(factory)
359 {
360
361     ASSERT(factory);
362
363     //
364     // Properties
365     //
366
367     bindProperty("role", &AccessibilityUIElement::roleGetterCallback);
368     bindProperty("title", &AccessibilityUIElement::titleGetterCallback);
369     bindProperty("description", &AccessibilityUIElement::descriptionGetterCallback);
370     bindProperty("helpText", &AccessibilityUIElement::helpTextGetterCallback);
371     bindProperty("stringValue", &AccessibilityUIElement::stringValueGetterCallback);
372     bindProperty("x", &AccessibilityUIElement::xGetterCallback);
373     bindProperty("y", &AccessibilityUIElement::yGetterCallback);
374     bindProperty("width", &AccessibilityUIElement::widthGetterCallback);
375     bindProperty("height", &AccessibilityUIElement::heightGetterCallback);
376     bindProperty("intValue", &AccessibilityUIElement::intValueGetterCallback);
377     bindProperty("minValue", &AccessibilityUIElement::minValueGetterCallback);
378     bindProperty("maxValue", &AccessibilityUIElement::maxValueGetterCallback);
379     bindProperty("valueDescription", &AccessibilityUIElement::valueDescriptionGetterCallback);
380     bindProperty("childrenCount", &AccessibilityUIElement::childrenCountGetterCallback);
381     bindProperty("insertionPointLineNumber", &AccessibilityUIElement::insertionPointLineNumberGetterCallback);
382     bindProperty("selectedTextRange", &AccessibilityUIElement::selectedTextRangeGetterCallback);
383     bindProperty("isEnabled", &AccessibilityUIElement::isEnabledGetterCallback);
384     bindProperty("isRequired", &AccessibilityUIElement::isRequiredGetterCallback);
385     bindProperty("isFocused", &AccessibilityUIElement::isFocusedGetterCallback);
386     bindProperty("isFocusable", &AccessibilityUIElement::isFocusableGetterCallback);
387     bindProperty("isSelected", &AccessibilityUIElement::isSelectedGetterCallback);
388     bindProperty("isSelectable", &AccessibilityUIElement::isSelectableGetterCallback);
389     bindProperty("isMultiSelectable", &AccessibilityUIElement::isMultiSelectableGetterCallback);
390     bindProperty("isSelectedOptionActive", &AccessibilityUIElement::isSelectedOptionActiveGetterCallback);
391     bindProperty("isExpanded", &AccessibilityUIElement::isExpandedGetterCallback);
392     bindProperty("isChecked", &AccessibilityUIElement::isCheckedGetterCallback);
393     bindProperty("isVisible", &AccessibilityUIElement::isVisibleGetterCallback);
394     bindProperty("isOffScreen", &AccessibilityUIElement::isOffScreenGetterCallback);
395     bindProperty("isCollapsed", &AccessibilityUIElement::isCollapsedGetterCallback);
396     bindProperty("hasPopup", &AccessibilityUIElement::hasPopupGetterCallback);
397     bindProperty("isValid", &AccessibilityUIElement::isValidGetterCallback);
398     bindProperty("isReadOnly", &AccessibilityUIElement::isReadOnlyGetterCallback);
399     bindProperty("orientation", &AccessibilityUIElement::orientationGetterCallback);
400     bindProperty("clickPointX", &AccessibilityUIElement::clickPointXGetterCallback);
401     bindProperty("clickPointY", &AccessibilityUIElement::clickPointYGetterCallback);
402
403     //
404     // Methods
405     //
406
407     bindMethod("allAttributes", &AccessibilityUIElement::allAttributesCallback);
408     bindMethod("attributesOfLinkedUIElements", &AccessibilityUIElement::attributesOfLinkedUIElementsCallback);
409     bindMethod("attributesOfDocumentLinks", &AccessibilityUIElement::attributesOfDocumentLinksCallback);
410     bindMethod("attributesOfChildren", &AccessibilityUIElement::attributesOfChildrenCallback);
411     bindMethod("lineForIndex", &AccessibilityUIElement::lineForIndexCallback);
412     bindMethod("boundsForRange", &AccessibilityUIElement::boundsForRangeCallback);
413     bindMethod("stringForRange", &AccessibilityUIElement::stringForRangeCallback);
414     bindMethod("childAtIndex", &AccessibilityUIElement::childAtIndexCallback);
415     bindMethod("elementAtPoint", &AccessibilityUIElement::elementAtPointCallback);
416     bindMethod("attributesOfColumnHeaders", &AccessibilityUIElement::attributesOfColumnHeadersCallback);
417     bindMethod("attributesOfRowHeaders", &AccessibilityUIElement::attributesOfRowHeadersCallback);
418     bindMethod("attributesOfColumns", &AccessibilityUIElement::attributesOfColumnsCallback);
419     bindMethod("attributesOfRows", &AccessibilityUIElement::attributesOfRowsCallback);
420     bindMethod("attributesOfVisibleCells", &AccessibilityUIElement::attributesOfVisibleCellsCallback);
421     bindMethod("attributesOfHeader", &AccessibilityUIElement::attributesOfHeaderCallback);
422     bindMethod("indexInTable", &AccessibilityUIElement::indexInTableCallback);
423     bindMethod("rowIndexRange", &AccessibilityUIElement::rowIndexRangeCallback);
424     bindMethod("columnIndexRange", &AccessibilityUIElement::columnIndexRangeCallback);
425     bindMethod("cellForColumnAndRow", &AccessibilityUIElement::cellForColumnAndRowCallback);
426     bindMethod("titleUIElement", &AccessibilityUIElement::titleUIElementCallback);
427     bindMethod("setSelectedTextRange", &AccessibilityUIElement::setSelectedTextRangeCallback);
428     bindMethod("attributeValue", &AccessibilityUIElement::attributeValueCallback);
429     bindMethod("isAttributeSettable", &AccessibilityUIElement::isAttributeSettableCallback);
430     bindMethod("isPressActionSupported", &AccessibilityUIElement::isPressActionSupportedCallback);
431     bindMethod("isIncrementActionSupported", &AccessibilityUIElement::isIncrementActionSupportedCallback);
432     bindMethod("isDecrementActionSupported", &AccessibilityUIElement::isDecrementActionSupportedCallback);
433     bindMethod("parentElement", &AccessibilityUIElement::parentElementCallback);
434     bindMethod("increment", &AccessibilityUIElement::incrementCallback);
435     bindMethod("decrement", &AccessibilityUIElement::decrementCallback);
436     bindMethod("showMenu", &AccessibilityUIElement::showMenuCallback);
437     bindMethod("press", &AccessibilityUIElement::pressCallback);
438     bindMethod("isEqual", &AccessibilityUIElement::isEqualCallback);
439     bindMethod("addNotificationListener", &AccessibilityUIElement::addNotificationListenerCallback);
440     bindMethod("removeNotificationListener", &AccessibilityUIElement::removeNotificationListenerCallback);
441     bindMethod("takeFocus", &AccessibilityUIElement::takeFocusCallback);
442     bindMethod("scrollToMakeVisible", &AccessibilityUIElement::scrollToMakeVisibleCallback);
443     bindMethod("scrollToMakeVisibleWithSubFocus", &AccessibilityUIElement::scrollToMakeVisibleWithSubFocusCallback);
444     bindMethod("scrollToGlobalPoint", &AccessibilityUIElement::scrollToGlobalPointCallback);
445
446     bindFallbackMethod(&AccessibilityUIElement::fallbackCallback);
447 }
448
449 AccessibilityUIElement* AccessibilityUIElement::getChildAtIndex(unsigned index)
450 {
451     return m_factory->getOrCreate(accessibilityObject().childAt(index));
452 }
453
454 bool AccessibilityUIElement::isEqual(const WebKit::WebAccessibilityObject& other)
455 {
456     return accessibilityObject().equals(other);
457 }
458
459 void AccessibilityUIElement::notificationReceived(const char* notificationName)
460 {
461     size_t callbackCount = m_notificationCallbacks.size();
462     for (size_t i = 0; i < callbackCount; i++) {
463         CppVariant notificationNameArgument;
464         notificationNameArgument.set(notificationName);
465         CppVariant invokeResult;
466         m_notificationCallbacks[i].invokeDefault(&notificationNameArgument, 1, invokeResult);
467     }
468 }
469
470 //
471 // Properties
472 //
473
474 void AccessibilityUIElement::roleGetterCallback(CppVariant* result)
475 {
476     result->set(getRole(accessibilityObject()));
477 }
478
479 void AccessibilityUIElement::titleGetterCallback(CppVariant* result)
480 {
481     result->set(getTitle(accessibilityObject()));
482 }
483
484 void AccessibilityUIElement::descriptionGetterCallback(CppVariant* result)
485 {
486     result->set(getDescription(accessibilityObject()));
487 }
488
489 void AccessibilityUIElement::helpTextGetterCallback(CppVariant* result)
490 {
491     result->set(getHelpText(accessibilityObject()));
492 }
493
494 void AccessibilityUIElement::stringValueGetterCallback(CppVariant* result)
495 {
496     result->set(getStringValue(accessibilityObject()));
497 }
498
499 void AccessibilityUIElement::xGetterCallback(CppVariant* result)
500 {
501     result->set(accessibilityObject().boundingBoxRect().x);
502 }
503
504 void AccessibilityUIElement::yGetterCallback(CppVariant* result)
505 {
506     result->set(accessibilityObject().boundingBoxRect().y);
507 }
508
509 void AccessibilityUIElement::widthGetterCallback(CppVariant* result)
510 {
511     result->set(accessibilityObject().boundingBoxRect().width);
512 }
513
514 void AccessibilityUIElement::heightGetterCallback(CppVariant* result)
515 {
516     result->set(accessibilityObject().boundingBoxRect().height);
517 }
518
519 void AccessibilityUIElement::intValueGetterCallback(CppVariant* result)
520 {
521     if (accessibilityObject().supportsRangeValue())
522         result->set(accessibilityObject().valueForRange());
523     else if (accessibilityObject().roleValue() == WebAccessibilityRoleHeading)
524         result->set(accessibilityObject().headingLevel());
525     else
526         result->set(atoi(accessibilityObject().stringValue().utf8().data()));
527 }
528
529 void AccessibilityUIElement::minValueGetterCallback(CppVariant* result)
530 {
531     result->set(accessibilityObject().minValueForRange());
532 }
533
534 void AccessibilityUIElement::maxValueGetterCallback(CppVariant* result)
535 {
536     result->set(accessibilityObject().maxValueForRange());
537 }
538
539 void AccessibilityUIElement::valueDescriptionGetterCallback(CppVariant* result)
540 {
541     result->set(getValueDescription(accessibilityObject()));
542 }
543
544 void AccessibilityUIElement::childrenCountGetterCallback(CppVariant* result)
545 {
546     int count = 1; // Root object always has only one child, the WebView.
547     if (!isRoot())
548         count = accessibilityObject().childCount();
549     result->set(count);
550 }
551
552 void AccessibilityUIElement::insertionPointLineNumberGetterCallback(CppVariant* result)
553 {
554     if (!accessibilityObject().isFocused()) {
555         result->set(-1);
556         return;
557     }
558
559     int lineNumber = accessibilityObject().selectionEndLineNumber();
560     result->set(lineNumber);
561 }
562
563 void AccessibilityUIElement::selectedTextRangeGetterCallback(CppVariant* result)
564 {
565     unsigned selectionStart = accessibilityObject().selectionStart();
566     unsigned selectionEnd = accessibilityObject().selectionEnd();
567     char buffer[100];
568     snprintf(buffer, sizeof(buffer), "{%d, %d}", selectionStart, selectionEnd - selectionStart);
569
570     result->set(std::string(buffer));
571 }
572
573 void AccessibilityUIElement::isEnabledGetterCallback(CppVariant* result)
574 {
575     result->set(accessibilityObject().isEnabled());
576 }
577
578 void AccessibilityUIElement::isRequiredGetterCallback(CppVariant* result)
579 {
580     result->set(accessibilityObject().isRequired());
581 }
582
583 void AccessibilityUIElement::isFocusedGetterCallback(CppVariant* result)
584 {
585     result->set(accessibilityObject().isFocused());
586 }
587
588 void AccessibilityUIElement::isFocusableGetterCallback(CppVariant* result)
589 {
590     result->set(accessibilityObject().canSetFocusAttribute());
591 }
592
593 void AccessibilityUIElement::isSelectedGetterCallback(CppVariant* result)
594 {
595     result->set(accessibilityObject().isSelected());
596 }
597
598 void AccessibilityUIElement::isSelectableGetterCallback(CppVariant* result)
599 {
600     result->set(accessibilityObject().canSetSelectedAttribute());
601 }
602
603 void AccessibilityUIElement::isMultiSelectableGetterCallback(CppVariant* result)
604 {
605     result->set(accessibilityObject().isMultiSelectable());
606 }
607
608 void AccessibilityUIElement::isSelectedOptionActiveGetterCallback(CppVariant* result)
609 {
610     result->set(accessibilityObject().isSelectedOptionActive());
611 }
612
613 void AccessibilityUIElement::isExpandedGetterCallback(CppVariant* result)
614 {
615     result->set(!accessibilityObject().isCollapsed());
616 }
617
618 void AccessibilityUIElement::isCheckedGetterCallback(CppVariant* result)
619 {
620     result->set(accessibilityObject().isChecked());
621 }
622
623 void AccessibilityUIElement::isVisibleGetterCallback(CppVariant* result)
624 {
625     result->set(accessibilityObject().isVisible());
626 }
627
628 void AccessibilityUIElement::isOffScreenGetterCallback(CppVariant* result)
629 {
630     result->set(accessibilityObject().isOffScreen());
631 }
632
633 void AccessibilityUIElement::isCollapsedGetterCallback(CppVariant* result)
634 {
635     result->set(accessibilityObject().isCollapsed());
636 }
637
638 void AccessibilityUIElement::hasPopupGetterCallback(CppVariant* result)
639 {
640     result->set(accessibilityObject().ariaHasPopup());
641 }
642
643 void AccessibilityUIElement::isValidGetterCallback(CppVariant* result)
644 {
645     result->set(!accessibilityObject().isDetached());
646 }
647
648 void AccessibilityUIElement::isReadOnlyGetterCallback(CppVariant* result)
649 {
650     result->set(accessibilityObject().isReadOnly());
651 }
652
653 void AccessibilityUIElement::orientationGetterCallback(CppVariant* result)
654 {
655     result->set(getOrientation(accessibilityObject()));
656 }
657
658 void AccessibilityUIElement::clickPointXGetterCallback(CppVariant* result)
659 {
660     result->set(accessibilityObject().clickPoint().x);
661 }
662
663 void AccessibilityUIElement::clickPointYGetterCallback(CppVariant* result)
664 {
665     result->set(accessibilityObject().clickPoint().y);
666 }
667
668 //
669 // Methods
670 //
671
672 void AccessibilityUIElement::allAttributesCallback(const CppArgumentList&, CppVariant* result)
673 {
674     result->set(getAttributes(accessibilityObject()));
675 }
676
677 void AccessibilityUIElement::attributesOfLinkedUIElementsCallback(const CppArgumentList&, CppVariant* result)
678 {
679     result->setNull();
680 }
681
682 void AccessibilityUIElement::attributesOfDocumentLinksCallback(const CppArgumentList&, CppVariant* result)
683 {
684     result->setNull();
685 }
686
687 void AccessibilityUIElement::attributesOfChildrenCallback(const CppArgumentList& arguments, CppVariant* result)
688 {
689     AttributesCollector collector;
690     unsigned size = accessibilityObject().childCount();
691     for (unsigned i = 0; i < size; ++i)
692         collector.collectAttributes(accessibilityObject().childAt(i));
693     result->set(collector.attributes());
694 }
695
696 void AccessibilityUIElement::parametrizedAttributeNamesCallback(const CppArgumentList&, CppVariant* result)
697 {
698     result->setNull();
699 }
700
701 void AccessibilityUIElement::lineForIndexCallback(const CppArgumentList& arguments, CppVariant* result)
702 {
703     if (!arguments.size() || !arguments[0].isNumber()) {
704         result->setNull();
705         return;
706     }
707
708     int index = arguments[0].toInt32();
709
710     WebVector<int> lineBreaks;
711     accessibilityObject().lineBreaks(lineBreaks);
712     int line = 0;
713     int vectorSize = static_cast<int>(lineBreaks.size());
714     while (line < vectorSize && lineBreaks[line] <= index)
715         line++;
716     result->set(line);
717 }
718
719 void AccessibilityUIElement::boundsForRangeCallback(const CppArgumentList&, CppVariant* result)
720 {
721     result->setNull();
722 }
723
724 void AccessibilityUIElement::stringForRangeCallback(const CppArgumentList&, CppVariant* result)
725 {
726     result->setNull();
727 }
728
729 void AccessibilityUIElement::childAtIndexCallback(const CppArgumentList& arguments, CppVariant* result)
730 {
731     if (!arguments.size() || !arguments[0].isNumber()) {
732         result->setNull();
733         return;
734     }
735
736     AccessibilityUIElement* child = getChildAtIndex(arguments[0].toInt32());
737     if (!child) {
738         result->setNull();
739         return;
740     }
741
742     result->set(*(child->getAsCppVariant()));
743 }
744
745 void AccessibilityUIElement::elementAtPointCallback(const CppArgumentList& arguments, CppVariant* result)
746 {
747     result->setNull();
748
749     if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNumber())
750         return;
751
752     int x = arguments[0].toInt32();
753     int y = arguments[1].toInt32();
754     WebPoint point(x, y);
755     WebAccessibilityObject obj = accessibilityObject().hitTest(point);
756     if (obj.isNull())
757         return;
758
759     result->set(*(m_factory->getOrCreate(obj)->getAsCppVariant()));
760 }
761
762 void AccessibilityUIElement::attributesOfColumnHeadersCallback(const CppArgumentList&, CppVariant* result)
763 {
764     result->setNull();
765 }
766
767 void AccessibilityUIElement::attributesOfRowHeadersCallback(const CppArgumentList&, CppVariant* result)
768 {
769     result->setNull();
770 }
771
772 void AccessibilityUIElement::attributesOfColumnsCallback(const CppArgumentList&, CppVariant* result)
773 {
774     result->setNull();
775 }
776
777 void AccessibilityUIElement::attributesOfRowsCallback(const CppArgumentList&, CppVariant* result)
778 {
779     result->setNull();
780 }
781
782 void AccessibilityUIElement::attributesOfVisibleCellsCallback(const CppArgumentList&, CppVariant* result)
783 {
784     result->setNull();
785 }
786
787 void AccessibilityUIElement::attributesOfHeaderCallback(const CppArgumentList&, CppVariant* result)
788 {
789     result->setNull();
790 }
791
792 void AccessibilityUIElement::indexInTableCallback(const CppArgumentList&, CppVariant* result)
793 {
794     result->setNull();
795 }
796
797 void AccessibilityUIElement::rowIndexRangeCallback(const CppArgumentList&, CppVariant* result)
798 {
799     result->setNull();
800 }
801
802 void AccessibilityUIElement::columnIndexRangeCallback(const CppArgumentList&, CppVariant* result)
803 {
804     result->setNull();
805 }
806
807 void AccessibilityUIElement::cellForColumnAndRowCallback(const CppArgumentList&, CppVariant* result)
808 {
809     result->setNull();
810 }
811
812 void AccessibilityUIElement::titleUIElementCallback(const CppArgumentList&, CppVariant* result)
813 {
814     WebAccessibilityObject obj = accessibilityObject().titleUIElement();
815     if (obj.isNull()) {
816         result->setNull();
817         return;
818     }
819
820     result->set(*(m_factory->getOrCreate(obj)->getAsCppVariant()));
821 }
822
823 void AccessibilityUIElement::setSelectedTextRangeCallback(const CppArgumentList&arguments, CppVariant* result)
824 {
825     result->setNull();
826     if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNumber())
827         return;
828
829     int selectionStart = arguments[0].toInt32();
830     int selectionEnd = selectionStart + arguments[1].toInt32();
831     accessibilityObject().setSelectedTextRange(selectionStart, selectionEnd);
832 }
833
834 void AccessibilityUIElement::attributeValueCallback(const CppArgumentList&, CppVariant* result)
835 {
836     result->setNull();
837 }
838
839 void AccessibilityUIElement::isAttributeSettableCallback(const CppArgumentList& arguments, CppVariant* result)
840 {
841     if (arguments.size() < 1 && !arguments[0].isString()) {
842         result->setNull();
843         return;
844     }
845
846     string attribute = arguments[0].toString();
847     bool settable = false;
848     if (attribute == "AXValue")
849         settable = accessibilityObject().canSetValueAttribute();
850     result->set(settable);
851 }
852
853 void AccessibilityUIElement::isPressActionSupportedCallback(const CppArgumentList&, CppVariant* result)
854 {
855     result->set(accessibilityObject().canPress());
856 }
857
858 void AccessibilityUIElement::isIncrementActionSupportedCallback(const CppArgumentList&, CppVariant* result)
859 {
860     result->set(accessibilityObject().canIncrement());
861 }
862
863 void AccessibilityUIElement::isDecrementActionSupportedCallback(const CppArgumentList&, CppVariant* result)
864 {
865     result->set(accessibilityObject().canDecrement());
866 }
867
868 void AccessibilityUIElement::parentElementCallback(const CppArgumentList&, CppVariant* result)
869 {
870     result->setNull();
871 }
872
873 void AccessibilityUIElement::incrementCallback(const CppArgumentList&, CppVariant* result)
874 {
875     accessibilityObject().increment();
876     result->setNull();
877 }
878
879 void AccessibilityUIElement::decrementCallback(const CppArgumentList&, CppVariant* result)
880 {
881     accessibilityObject().decrement();
882     result->setNull();
883 }
884
885 void AccessibilityUIElement::showMenuCallback(const CppArgumentList&, CppVariant* result)
886 {
887     result->setNull();
888 }
889
890 void AccessibilityUIElement::pressCallback(const CppArgumentList&, CppVariant* result)
891 {
892     accessibilityObject().press();
893     result->setNull();
894 }
895
896 void AccessibilityUIElement::isEqualCallback(const CppArgumentList& arguments, CppVariant* result)
897 {
898     if (arguments.size() < 1 || !arguments[0].isObject()) {
899         result->setNull();
900         return;
901     }
902
903     result->set(arguments[0].isEqual(*getAsCppVariant()));
904 }
905
906 void AccessibilityUIElement::addNotificationListenerCallback(const CppArgumentList& arguments, CppVariant* result)
907 {
908     if (arguments.size() < 1 || !arguments[0].isObject()) {
909         result->setNull();
910         return;
911     }
912
913     m_notificationCallbacks.push_back(arguments[0]);
914     result->setNull();
915 }
916
917 void AccessibilityUIElement::removeNotificationListenerCallback(const CppArgumentList&, CppVariant* result)
918 {
919     // FIXME: Implement this.
920     result->setNull();
921 }
922
923 void AccessibilityUIElement::takeFocusCallback(const CppArgumentList&, CppVariant* result)
924 {
925     accessibilityObject().setFocused(true);
926     result->setNull();
927 }
928
929 void AccessibilityUIElement::scrollToMakeVisibleCallback(const CppArgumentList&, CppVariant* result)
930 {
931     accessibilityObject().scrollToMakeVisible();
932     result->setNull();
933 }
934
935 void AccessibilityUIElement::scrollToMakeVisibleWithSubFocusCallback(const CppArgumentList& arguments, CppVariant* result)
936 {
937     result->setNull();
938
939     if (arguments.size() != 4
940         || !arguments[0].isNumber()
941         || !arguments[1].isNumber()
942         || !arguments[2].isNumber()
943         || !arguments[3].isNumber())
944         return;
945
946     int x = arguments[0].toInt32();
947     int y = arguments[1].toInt32();
948     int width = arguments[2].toInt32();
949     int height = arguments[3].toInt32();
950     accessibilityObject().scrollToMakeVisibleWithSubFocus(WebRect(x, y, width, height));
951     result->setNull();
952 }
953
954 void AccessibilityUIElement::scrollToGlobalPointCallback(const CppArgumentList& arguments, CppVariant* result)
955 {
956     result->setNull();
957
958     if (arguments.size() != 2
959         || !arguments[0].isNumber()
960         || !arguments[1].isNumber())
961         return;
962
963     int x = arguments[0].toInt32();
964     int y = arguments[1].toInt32();
965
966     accessibilityObject().scrollToGlobalPoint(WebPoint(x, y));
967     result->setNull();
968 }
969
970 void AccessibilityUIElement::fallbackCallback(const CppArgumentList &, CppVariant* result)
971 {
972     // FIXME: Implement this.
973     result->setNull();
974 }
975
976 RootAccessibilityUIElement::RootAccessibilityUIElement(const WebAccessibilityObject &object, Factory *factory)
977     : AccessibilityUIElement(object, factory) { }
978
979 AccessibilityUIElement* RootAccessibilityUIElement::getChildAtIndex(unsigned index)
980 {
981     if (index)
982         return 0;
983
984     return factory()->getOrCreate(accessibilityObject());
985 }
986
987
988 AccessibilityUIElementList ::~AccessibilityUIElementList()
989 {
990     clear();
991 }
992
993 void AccessibilityUIElementList::clear()
994 {
995     for (ElementList::iterator i = m_elements.begin(); i != m_elements.end(); ++i)
996         delete (*i);
997     m_elements.clear();
998 }
999
1000 AccessibilityUIElement* AccessibilityUIElementList::getOrCreate(const WebAccessibilityObject& object)
1001 {
1002     if (object.isNull())
1003         return 0;
1004
1005     size_t elementCount = m_elements.size();
1006     for (size_t i = 0; i < elementCount; i++) {
1007         if (m_elements[i]->isEqual(object))
1008             return m_elements[i];
1009     }
1010
1011     AccessibilityUIElement* element = new AccessibilityUIElement(object, this);
1012     m_elements.append(element);
1013     return element;
1014 }
1015
1016 AccessibilityUIElement* AccessibilityUIElementList::createRoot(const WebAccessibilityObject& object)
1017 {
1018     AccessibilityUIElement* element = new RootAccessibilityUIElement(object, this);
1019     m_elements.append(element);
1020     return element;
1021 }
1022
1023 }