AX: Need to implement ColorWellRole
[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;
289     if (object.roleValue() == WebAccessibilityRoleColorWell) {
290         int r, g, b;
291         char buffer[100];
292         object.colorValue(r, g, b);
293         snprintf(buffer, sizeof(buffer), "rgb %7.5f %7.5f %7.5f 1", r / 255., g / 255., b / 255.);
294         value = buffer;
295     } else
296         value = object.stringValue().utf8();
297     return value.insert(0, "AXValue: ");
298 }
299
300 string getRole(const WebAccessibilityObject& object)
301 {
302     string roleString = roleToString(object.roleValue());
303
304     // Special-case canvas with fallback content because Chromium wants to
305     // treat this as essentially a separate role that it can map differently depending
306     // on the platform.
307     if (object.roleValue() == WebAccessibilityRoleCanvas && object.canvasHasFallbackContent())
308         roleString += "WithFallbackContent";
309
310     return roleString;
311 }
312
313 string getTitle(const WebAccessibilityObject& object)
314 {
315     string title = object.title().utf8();
316     return title.insert(0, "AXTitle: ");
317 }
318
319 string getOrientation(const WebAccessibilityObject& object)
320 {
321     if (object.isVertical())
322         return "AXOrientation: AXVerticalOrientation";
323
324     return "AXOrientation: AXHorizontalOrientation";
325 }
326
327 string getValueDescription(const WebAccessibilityObject& object)
328 {
329     string valueDescription = object.valueDescription().utf8();
330     return valueDescription.insert(0, "AXValueDescription: ");
331 }
332
333 string getAttributes(const WebAccessibilityObject& object)
334 {
335     // FIXME: Concatenate all attributes of the AccessibilityObject.
336     string attributes(getTitle(object));
337     attributes.append("\n");
338     attributes.append(getRole(object));
339     attributes.append("\n");
340     attributes.append(getDescription(object));
341     return attributes;
342 }
343
344
345 // Collects attributes into a string, delimited by dashes. Used by all methods
346 // that output lists of attributes: attributesOfLinkedUIElementsCallback,
347 // AttributesOfChildrenCallback, etc.
348 class AttributesCollector {
349 public:
350     void collectAttributes(const WebAccessibilityObject& object)
351     {
352         m_attributes.append("\n------------\n");
353         m_attributes.append(getAttributes(object));
354     }
355
356     string attributes() const { return m_attributes; }
357
358 private:
359     string m_attributes;
360 };
361
362 }
363
364 AccessibilityUIElement::AccessibilityUIElement(const WebAccessibilityObject& object, Factory* factory)
365     : m_accessibilityObject(object)
366     , m_factory(factory)
367 {
368
369     ASSERT(factory);
370
371     //
372     // Properties
373     //
374
375     bindProperty("role", &AccessibilityUIElement::roleGetterCallback);
376     bindProperty("title", &AccessibilityUIElement::titleGetterCallback);
377     bindProperty("description", &AccessibilityUIElement::descriptionGetterCallback);
378     bindProperty("helpText", &AccessibilityUIElement::helpTextGetterCallback);
379     bindProperty("stringValue", &AccessibilityUIElement::stringValueGetterCallback);
380     bindProperty("x", &AccessibilityUIElement::xGetterCallback);
381     bindProperty("y", &AccessibilityUIElement::yGetterCallback);
382     bindProperty("width", &AccessibilityUIElement::widthGetterCallback);
383     bindProperty("height", &AccessibilityUIElement::heightGetterCallback);
384     bindProperty("intValue", &AccessibilityUIElement::intValueGetterCallback);
385     bindProperty("minValue", &AccessibilityUIElement::minValueGetterCallback);
386     bindProperty("maxValue", &AccessibilityUIElement::maxValueGetterCallback);
387     bindProperty("valueDescription", &AccessibilityUIElement::valueDescriptionGetterCallback);
388     bindProperty("childrenCount", &AccessibilityUIElement::childrenCountGetterCallback);
389     bindProperty("insertionPointLineNumber", &AccessibilityUIElement::insertionPointLineNumberGetterCallback);
390     bindProperty("selectedTextRange", &AccessibilityUIElement::selectedTextRangeGetterCallback);
391     bindProperty("isEnabled", &AccessibilityUIElement::isEnabledGetterCallback);
392     bindProperty("isRequired", &AccessibilityUIElement::isRequiredGetterCallback);
393     bindProperty("isFocused", &AccessibilityUIElement::isFocusedGetterCallback);
394     bindProperty("isFocusable", &AccessibilityUIElement::isFocusableGetterCallback);
395     bindProperty("isSelected", &AccessibilityUIElement::isSelectedGetterCallback);
396     bindProperty("isSelectable", &AccessibilityUIElement::isSelectableGetterCallback);
397     bindProperty("isMultiSelectable", &AccessibilityUIElement::isMultiSelectableGetterCallback);
398     bindProperty("isSelectedOptionActive", &AccessibilityUIElement::isSelectedOptionActiveGetterCallback);
399     bindProperty("isExpanded", &AccessibilityUIElement::isExpandedGetterCallback);
400     bindProperty("isChecked", &AccessibilityUIElement::isCheckedGetterCallback);
401     bindProperty("isVisible", &AccessibilityUIElement::isVisibleGetterCallback);
402     bindProperty("isOffScreen", &AccessibilityUIElement::isOffScreenGetterCallback);
403     bindProperty("isCollapsed", &AccessibilityUIElement::isCollapsedGetterCallback);
404     bindProperty("hasPopup", &AccessibilityUIElement::hasPopupGetterCallback);
405     bindProperty("isValid", &AccessibilityUIElement::isValidGetterCallback);
406     bindProperty("isReadOnly", &AccessibilityUIElement::isReadOnlyGetterCallback);
407     bindProperty("orientation", &AccessibilityUIElement::orientationGetterCallback);
408     bindProperty("clickPointX", &AccessibilityUIElement::clickPointXGetterCallback);
409     bindProperty("clickPointY", &AccessibilityUIElement::clickPointYGetterCallback);
410
411     //
412     // Methods
413     //
414
415     bindMethod("allAttributes", &AccessibilityUIElement::allAttributesCallback);
416     bindMethod("attributesOfLinkedUIElements", &AccessibilityUIElement::attributesOfLinkedUIElementsCallback);
417     bindMethod("attributesOfDocumentLinks", &AccessibilityUIElement::attributesOfDocumentLinksCallback);
418     bindMethod("attributesOfChildren", &AccessibilityUIElement::attributesOfChildrenCallback);
419     bindMethod("lineForIndex", &AccessibilityUIElement::lineForIndexCallback);
420     bindMethod("boundsForRange", &AccessibilityUIElement::boundsForRangeCallback);
421     bindMethod("stringForRange", &AccessibilityUIElement::stringForRangeCallback);
422     bindMethod("childAtIndex", &AccessibilityUIElement::childAtIndexCallback);
423     bindMethod("elementAtPoint", &AccessibilityUIElement::elementAtPointCallback);
424     bindMethod("attributesOfColumnHeaders", &AccessibilityUIElement::attributesOfColumnHeadersCallback);
425     bindMethod("attributesOfRowHeaders", &AccessibilityUIElement::attributesOfRowHeadersCallback);
426     bindMethod("attributesOfColumns", &AccessibilityUIElement::attributesOfColumnsCallback);
427     bindMethod("attributesOfRows", &AccessibilityUIElement::attributesOfRowsCallback);
428     bindMethod("attributesOfVisibleCells", &AccessibilityUIElement::attributesOfVisibleCellsCallback);
429     bindMethod("attributesOfHeader", &AccessibilityUIElement::attributesOfHeaderCallback);
430     bindMethod("indexInTable", &AccessibilityUIElement::indexInTableCallback);
431     bindMethod("rowIndexRange", &AccessibilityUIElement::rowIndexRangeCallback);
432     bindMethod("columnIndexRange", &AccessibilityUIElement::columnIndexRangeCallback);
433     bindMethod("cellForColumnAndRow", &AccessibilityUIElement::cellForColumnAndRowCallback);
434     bindMethod("titleUIElement", &AccessibilityUIElement::titleUIElementCallback);
435     bindMethod("setSelectedTextRange", &AccessibilityUIElement::setSelectedTextRangeCallback);
436     bindMethod("attributeValue", &AccessibilityUIElement::attributeValueCallback);
437     bindMethod("isAttributeSettable", &AccessibilityUIElement::isAttributeSettableCallback);
438     bindMethod("isPressActionSupported", &AccessibilityUIElement::isPressActionSupportedCallback);
439     bindMethod("isIncrementActionSupported", &AccessibilityUIElement::isIncrementActionSupportedCallback);
440     bindMethod("isDecrementActionSupported", &AccessibilityUIElement::isDecrementActionSupportedCallback);
441     bindMethod("parentElement", &AccessibilityUIElement::parentElementCallback);
442     bindMethod("increment", &AccessibilityUIElement::incrementCallback);
443     bindMethod("decrement", &AccessibilityUIElement::decrementCallback);
444     bindMethod("showMenu", &AccessibilityUIElement::showMenuCallback);
445     bindMethod("press", &AccessibilityUIElement::pressCallback);
446     bindMethod("isEqual", &AccessibilityUIElement::isEqualCallback);
447     bindMethod("addNotificationListener", &AccessibilityUIElement::addNotificationListenerCallback);
448     bindMethod("removeNotificationListener", &AccessibilityUIElement::removeNotificationListenerCallback);
449     bindMethod("takeFocus", &AccessibilityUIElement::takeFocusCallback);
450     bindMethod("scrollToMakeVisible", &AccessibilityUIElement::scrollToMakeVisibleCallback);
451     bindMethod("scrollToMakeVisibleWithSubFocus", &AccessibilityUIElement::scrollToMakeVisibleWithSubFocusCallback);
452     bindMethod("scrollToGlobalPoint", &AccessibilityUIElement::scrollToGlobalPointCallback);
453
454     bindFallbackMethod(&AccessibilityUIElement::fallbackCallback);
455 }
456
457 AccessibilityUIElement* AccessibilityUIElement::getChildAtIndex(unsigned index)
458 {
459     return m_factory->getOrCreate(accessibilityObject().childAt(index));
460 }
461
462 bool AccessibilityUIElement::isEqual(const WebKit::WebAccessibilityObject& other)
463 {
464     return accessibilityObject().equals(other);
465 }
466
467 void AccessibilityUIElement::notificationReceived(const char* notificationName)
468 {
469     size_t callbackCount = m_notificationCallbacks.size();
470     for (size_t i = 0; i < callbackCount; i++) {
471         CppVariant notificationNameArgument;
472         notificationNameArgument.set(notificationName);
473         CppVariant invokeResult;
474         m_notificationCallbacks[i].invokeDefault(&notificationNameArgument, 1, invokeResult);
475     }
476 }
477
478 //
479 // Properties
480 //
481
482 void AccessibilityUIElement::roleGetterCallback(CppVariant* result)
483 {
484     result->set(getRole(accessibilityObject()));
485 }
486
487 void AccessibilityUIElement::titleGetterCallback(CppVariant* result)
488 {
489     result->set(getTitle(accessibilityObject()));
490 }
491
492 void AccessibilityUIElement::descriptionGetterCallback(CppVariant* result)
493 {
494     result->set(getDescription(accessibilityObject()));
495 }
496
497 void AccessibilityUIElement::helpTextGetterCallback(CppVariant* result)
498 {
499     result->set(getHelpText(accessibilityObject()));
500 }
501
502 void AccessibilityUIElement::stringValueGetterCallback(CppVariant* result)
503 {
504     result->set(getStringValue(accessibilityObject()));
505 }
506
507 void AccessibilityUIElement::xGetterCallback(CppVariant* result)
508 {
509     result->set(accessibilityObject().boundingBoxRect().x);
510 }
511
512 void AccessibilityUIElement::yGetterCallback(CppVariant* result)
513 {
514     result->set(accessibilityObject().boundingBoxRect().y);
515 }
516
517 void AccessibilityUIElement::widthGetterCallback(CppVariant* result)
518 {
519     result->set(accessibilityObject().boundingBoxRect().width);
520 }
521
522 void AccessibilityUIElement::heightGetterCallback(CppVariant* result)
523 {
524     result->set(accessibilityObject().boundingBoxRect().height);
525 }
526
527 void AccessibilityUIElement::intValueGetterCallback(CppVariant* result)
528 {
529     if (accessibilityObject().supportsRangeValue())
530         result->set(accessibilityObject().valueForRange());
531     else if (accessibilityObject().roleValue() == WebAccessibilityRoleHeading)
532         result->set(accessibilityObject().headingLevel());
533     else
534         result->set(atoi(accessibilityObject().stringValue().utf8().data()));
535 }
536
537 void AccessibilityUIElement::minValueGetterCallback(CppVariant* result)
538 {
539     result->set(accessibilityObject().minValueForRange());
540 }
541
542 void AccessibilityUIElement::maxValueGetterCallback(CppVariant* result)
543 {
544     result->set(accessibilityObject().maxValueForRange());
545 }
546
547 void AccessibilityUIElement::valueDescriptionGetterCallback(CppVariant* result)
548 {
549     result->set(getValueDescription(accessibilityObject()));
550 }
551
552 void AccessibilityUIElement::childrenCountGetterCallback(CppVariant* result)
553 {
554     int count = 1; // Root object always has only one child, the WebView.
555     if (!isRoot())
556         count = accessibilityObject().childCount();
557     result->set(count);
558 }
559
560 void AccessibilityUIElement::insertionPointLineNumberGetterCallback(CppVariant* result)
561 {
562     if (!accessibilityObject().isFocused()) {
563         result->set(-1);
564         return;
565     }
566
567     int lineNumber = accessibilityObject().selectionEndLineNumber();
568     result->set(lineNumber);
569 }
570
571 void AccessibilityUIElement::selectedTextRangeGetterCallback(CppVariant* result)
572 {
573     unsigned selectionStart = accessibilityObject().selectionStart();
574     unsigned selectionEnd = accessibilityObject().selectionEnd();
575     char buffer[100];
576     snprintf(buffer, sizeof(buffer), "{%d, %d}", selectionStart, selectionEnd - selectionStart);
577
578     result->set(std::string(buffer));
579 }
580
581 void AccessibilityUIElement::isEnabledGetterCallback(CppVariant* result)
582 {
583     result->set(accessibilityObject().isEnabled());
584 }
585
586 void AccessibilityUIElement::isRequiredGetterCallback(CppVariant* result)
587 {
588     result->set(accessibilityObject().isRequired());
589 }
590
591 void AccessibilityUIElement::isFocusedGetterCallback(CppVariant* result)
592 {
593     result->set(accessibilityObject().isFocused());
594 }
595
596 void AccessibilityUIElement::isFocusableGetterCallback(CppVariant* result)
597 {
598     result->set(accessibilityObject().canSetFocusAttribute());
599 }
600
601 void AccessibilityUIElement::isSelectedGetterCallback(CppVariant* result)
602 {
603     result->set(accessibilityObject().isSelected());
604 }
605
606 void AccessibilityUIElement::isSelectableGetterCallback(CppVariant* result)
607 {
608     result->set(accessibilityObject().canSetSelectedAttribute());
609 }
610
611 void AccessibilityUIElement::isMultiSelectableGetterCallback(CppVariant* result)
612 {
613     result->set(accessibilityObject().isMultiSelectable());
614 }
615
616 void AccessibilityUIElement::isSelectedOptionActiveGetterCallback(CppVariant* result)
617 {
618     result->set(accessibilityObject().isSelectedOptionActive());
619 }
620
621 void AccessibilityUIElement::isExpandedGetterCallback(CppVariant* result)
622 {
623     result->set(!accessibilityObject().isCollapsed());
624 }
625
626 void AccessibilityUIElement::isCheckedGetterCallback(CppVariant* result)
627 {
628     result->set(accessibilityObject().isChecked());
629 }
630
631 void AccessibilityUIElement::isVisibleGetterCallback(CppVariant* result)
632 {
633     result->set(accessibilityObject().isVisible());
634 }
635
636 void AccessibilityUIElement::isOffScreenGetterCallback(CppVariant* result)
637 {
638     result->set(accessibilityObject().isOffScreen());
639 }
640
641 void AccessibilityUIElement::isCollapsedGetterCallback(CppVariant* result)
642 {
643     result->set(accessibilityObject().isCollapsed());
644 }
645
646 void AccessibilityUIElement::hasPopupGetterCallback(CppVariant* result)
647 {
648     result->set(accessibilityObject().ariaHasPopup());
649 }
650
651 void AccessibilityUIElement::isValidGetterCallback(CppVariant* result)
652 {
653     result->set(!accessibilityObject().isDetached());
654 }
655
656 void AccessibilityUIElement::isReadOnlyGetterCallback(CppVariant* result)
657 {
658     result->set(accessibilityObject().isReadOnly());
659 }
660
661 void AccessibilityUIElement::orientationGetterCallback(CppVariant* result)
662 {
663     result->set(getOrientation(accessibilityObject()));
664 }
665
666 void AccessibilityUIElement::clickPointXGetterCallback(CppVariant* result)
667 {
668     result->set(accessibilityObject().clickPoint().x);
669 }
670
671 void AccessibilityUIElement::clickPointYGetterCallback(CppVariant* result)
672 {
673     result->set(accessibilityObject().clickPoint().y);
674 }
675
676 //
677 // Methods
678 //
679
680 void AccessibilityUIElement::allAttributesCallback(const CppArgumentList&, CppVariant* result)
681 {
682     result->set(getAttributes(accessibilityObject()));
683 }
684
685 void AccessibilityUIElement::attributesOfLinkedUIElementsCallback(const CppArgumentList&, CppVariant* result)
686 {
687     result->setNull();
688 }
689
690 void AccessibilityUIElement::attributesOfDocumentLinksCallback(const CppArgumentList&, CppVariant* result)
691 {
692     result->setNull();
693 }
694
695 void AccessibilityUIElement::attributesOfChildrenCallback(const CppArgumentList& arguments, CppVariant* result)
696 {
697     AttributesCollector collector;
698     unsigned size = accessibilityObject().childCount();
699     for (unsigned i = 0; i < size; ++i)
700         collector.collectAttributes(accessibilityObject().childAt(i));
701     result->set(collector.attributes());
702 }
703
704 void AccessibilityUIElement::parametrizedAttributeNamesCallback(const CppArgumentList&, CppVariant* result)
705 {
706     result->setNull();
707 }
708
709 void AccessibilityUIElement::lineForIndexCallback(const CppArgumentList& arguments, CppVariant* result)
710 {
711     if (!arguments.size() || !arguments[0].isNumber()) {
712         result->setNull();
713         return;
714     }
715
716     int index = arguments[0].toInt32();
717
718     WebVector<int> lineBreaks;
719     accessibilityObject().lineBreaks(lineBreaks);
720     int line = 0;
721     int vectorSize = static_cast<int>(lineBreaks.size());
722     while (line < vectorSize && lineBreaks[line] <= index)
723         line++;
724     result->set(line);
725 }
726
727 void AccessibilityUIElement::boundsForRangeCallback(const CppArgumentList&, CppVariant* result)
728 {
729     result->setNull();
730 }
731
732 void AccessibilityUIElement::stringForRangeCallback(const CppArgumentList&, CppVariant* result)
733 {
734     result->setNull();
735 }
736
737 void AccessibilityUIElement::childAtIndexCallback(const CppArgumentList& arguments, CppVariant* result)
738 {
739     if (!arguments.size() || !arguments[0].isNumber()) {
740         result->setNull();
741         return;
742     }
743
744     AccessibilityUIElement* child = getChildAtIndex(arguments[0].toInt32());
745     if (!child) {
746         result->setNull();
747         return;
748     }
749
750     result->set(*(child->getAsCppVariant()));
751 }
752
753 void AccessibilityUIElement::elementAtPointCallback(const CppArgumentList& arguments, CppVariant* result)
754 {
755     result->setNull();
756
757     if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNumber())
758         return;
759
760     int x = arguments[0].toInt32();
761     int y = arguments[1].toInt32();
762     WebPoint point(x, y);
763     WebAccessibilityObject obj = accessibilityObject().hitTest(point);
764     if (obj.isNull())
765         return;
766
767     result->set(*(m_factory->getOrCreate(obj)->getAsCppVariant()));
768 }
769
770 void AccessibilityUIElement::attributesOfColumnHeadersCallback(const CppArgumentList&, CppVariant* result)
771 {
772     result->setNull();
773 }
774
775 void AccessibilityUIElement::attributesOfRowHeadersCallback(const CppArgumentList&, CppVariant* result)
776 {
777     result->setNull();
778 }
779
780 void AccessibilityUIElement::attributesOfColumnsCallback(const CppArgumentList&, CppVariant* result)
781 {
782     result->setNull();
783 }
784
785 void AccessibilityUIElement::attributesOfRowsCallback(const CppArgumentList&, CppVariant* result)
786 {
787     result->setNull();
788 }
789
790 void AccessibilityUIElement::attributesOfVisibleCellsCallback(const CppArgumentList&, CppVariant* result)
791 {
792     result->setNull();
793 }
794
795 void AccessibilityUIElement::attributesOfHeaderCallback(const CppArgumentList&, CppVariant* result)
796 {
797     result->setNull();
798 }
799
800 void AccessibilityUIElement::indexInTableCallback(const CppArgumentList&, CppVariant* result)
801 {
802     result->setNull();
803 }
804
805 void AccessibilityUIElement::rowIndexRangeCallback(const CppArgumentList&, CppVariant* result)
806 {
807     result->setNull();
808 }
809
810 void AccessibilityUIElement::columnIndexRangeCallback(const CppArgumentList&, CppVariant* result)
811 {
812     result->setNull();
813 }
814
815 void AccessibilityUIElement::cellForColumnAndRowCallback(const CppArgumentList&, CppVariant* result)
816 {
817     result->setNull();
818 }
819
820 void AccessibilityUIElement::titleUIElementCallback(const CppArgumentList&, CppVariant* result)
821 {
822     WebAccessibilityObject obj = accessibilityObject().titleUIElement();
823     if (obj.isNull()) {
824         result->setNull();
825         return;
826     }
827
828     result->set(*(m_factory->getOrCreate(obj)->getAsCppVariant()));
829 }
830
831 void AccessibilityUIElement::setSelectedTextRangeCallback(const CppArgumentList&arguments, CppVariant* result)
832 {
833     result->setNull();
834     if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNumber())
835         return;
836
837     int selectionStart = arguments[0].toInt32();
838     int selectionEnd = selectionStart + arguments[1].toInt32();
839     accessibilityObject().setSelectedTextRange(selectionStart, selectionEnd);
840 }
841
842 void AccessibilityUIElement::attributeValueCallback(const CppArgumentList&, CppVariant* result)
843 {
844     result->setNull();
845 }
846
847 void AccessibilityUIElement::isAttributeSettableCallback(const CppArgumentList& arguments, CppVariant* result)
848 {
849     if (arguments.size() < 1 && !arguments[0].isString()) {
850         result->setNull();
851         return;
852     }
853
854     string attribute = arguments[0].toString();
855     bool settable = false;
856     if (attribute == "AXValue")
857         settable = accessibilityObject().canSetValueAttribute();
858     result->set(settable);
859 }
860
861 void AccessibilityUIElement::isPressActionSupportedCallback(const CppArgumentList&, CppVariant* result)
862 {
863     result->set(accessibilityObject().canPress());
864 }
865
866 void AccessibilityUIElement::isIncrementActionSupportedCallback(const CppArgumentList&, CppVariant* result)
867 {
868     result->set(accessibilityObject().canIncrement());
869 }
870
871 void AccessibilityUIElement::isDecrementActionSupportedCallback(const CppArgumentList&, CppVariant* result)
872 {
873     result->set(accessibilityObject().canDecrement());
874 }
875
876 void AccessibilityUIElement::parentElementCallback(const CppArgumentList&, CppVariant* result)
877 {
878     result->setNull();
879 }
880
881 void AccessibilityUIElement::incrementCallback(const CppArgumentList&, CppVariant* result)
882 {
883     accessibilityObject().increment();
884     result->setNull();
885 }
886
887 void AccessibilityUIElement::decrementCallback(const CppArgumentList&, CppVariant* result)
888 {
889     accessibilityObject().decrement();
890     result->setNull();
891 }
892
893 void AccessibilityUIElement::showMenuCallback(const CppArgumentList&, CppVariant* result)
894 {
895     result->setNull();
896 }
897
898 void AccessibilityUIElement::pressCallback(const CppArgumentList&, CppVariant* result)
899 {
900     accessibilityObject().press();
901     result->setNull();
902 }
903
904 void AccessibilityUIElement::isEqualCallback(const CppArgumentList& arguments, CppVariant* result)
905 {
906     if (arguments.size() < 1 || !arguments[0].isObject()) {
907         result->setNull();
908         return;
909     }
910
911     result->set(arguments[0].isEqual(*getAsCppVariant()));
912 }
913
914 void AccessibilityUIElement::addNotificationListenerCallback(const CppArgumentList& arguments, CppVariant* result)
915 {
916     if (arguments.size() < 1 || !arguments[0].isObject()) {
917         result->setNull();
918         return;
919     }
920
921     m_notificationCallbacks.push_back(arguments[0]);
922     result->setNull();
923 }
924
925 void AccessibilityUIElement::removeNotificationListenerCallback(const CppArgumentList&, CppVariant* result)
926 {
927     // FIXME: Implement this.
928     result->setNull();
929 }
930
931 void AccessibilityUIElement::takeFocusCallback(const CppArgumentList&, CppVariant* result)
932 {
933     accessibilityObject().setFocused(true);
934     result->setNull();
935 }
936
937 void AccessibilityUIElement::scrollToMakeVisibleCallback(const CppArgumentList&, CppVariant* result)
938 {
939     accessibilityObject().scrollToMakeVisible();
940     result->setNull();
941 }
942
943 void AccessibilityUIElement::scrollToMakeVisibleWithSubFocusCallback(const CppArgumentList& arguments, CppVariant* result)
944 {
945     result->setNull();
946
947     if (arguments.size() != 4
948         || !arguments[0].isNumber()
949         || !arguments[1].isNumber()
950         || !arguments[2].isNumber()
951         || !arguments[3].isNumber())
952         return;
953
954     int x = arguments[0].toInt32();
955     int y = arguments[1].toInt32();
956     int width = arguments[2].toInt32();
957     int height = arguments[3].toInt32();
958     accessibilityObject().scrollToMakeVisibleWithSubFocus(WebRect(x, y, width, height));
959     result->setNull();
960 }
961
962 void AccessibilityUIElement::scrollToGlobalPointCallback(const CppArgumentList& arguments, CppVariant* result)
963 {
964     result->setNull();
965
966     if (arguments.size() != 2
967         || !arguments[0].isNumber()
968         || !arguments[1].isNumber())
969         return;
970
971     int x = arguments[0].toInt32();
972     int y = arguments[1].toInt32();
973
974     accessibilityObject().scrollToGlobalPoint(WebPoint(x, y));
975     result->setNull();
976 }
977
978 void AccessibilityUIElement::fallbackCallback(const CppArgumentList &, CppVariant* result)
979 {
980     // FIXME: Implement this.
981     result->setNull();
982 }
983
984 RootAccessibilityUIElement::RootAccessibilityUIElement(const WebAccessibilityObject &object, Factory *factory)
985     : AccessibilityUIElement(object, factory) { }
986
987 AccessibilityUIElement* RootAccessibilityUIElement::getChildAtIndex(unsigned index)
988 {
989     if (index)
990         return 0;
991
992     return factory()->getOrCreate(accessibilityObject());
993 }
994
995
996 AccessibilityUIElementList ::~AccessibilityUIElementList()
997 {
998     clear();
999 }
1000
1001 void AccessibilityUIElementList::clear()
1002 {
1003     for (ElementList::iterator i = m_elements.begin(); i != m_elements.end(); ++i)
1004         delete (*i);
1005     m_elements.clear();
1006 }
1007
1008 AccessibilityUIElement* AccessibilityUIElementList::getOrCreate(const WebAccessibilityObject& object)
1009 {
1010     if (object.isNull())
1011         return 0;
1012
1013     size_t elementCount = m_elements.size();
1014     for (size_t i = 0; i < elementCount; i++) {
1015         if (m_elements[i]->isEqual(object))
1016             return m_elements[i];
1017     }
1018
1019     AccessibilityUIElement* element = new AccessibilityUIElement(object, this);
1020     m_elements.append(element);
1021     return element;
1022 }
1023
1024 AccessibilityUIElement* AccessibilityUIElementList::createRoot(const WebAccessibilityObject& object)
1025 {
1026     AccessibilityUIElement* element = new RootAccessibilityUIElement(object, this);
1027     m_elements.append(element);
1028     return element;
1029 }
1030
1031 }