Home | History | Annotate | Download | only in runner
      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 "AccessibilityUIElementChromium.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 #include "public/web/WebAccessibilityObject.h"
     39 
     40 using namespace WebKit;
     41 using namespace std;
     42 
     43 namespace WebTestRunner {
     44 
     45 namespace {
     46 
     47 // Map role value to string, matching Safari/Mac platform implementation to
     48 // avoid rebaselining layout tests.
     49 string roleToString(WebAccessibilityRole role)
     50 {
     51     string result = "AXRole: AX";
     52     switch (role) {
     53     case WebAccessibilityRoleButton:
     54         return result.append("Button");
     55     case WebAccessibilityRoleRadioButton:
     56         return result.append("RadioButton");
     57     case WebAccessibilityRoleCheckBox:
     58         return result.append("CheckBox");
     59     case WebAccessibilityRoleSlider:
     60         return result.append("Slider");
     61     case WebAccessibilityRoleTabGroup:
     62         return result.append("TabGroup");
     63     case WebAccessibilityRoleTextField:
     64         return result.append("TextField");
     65     case WebAccessibilityRoleStaticText:
     66         return result.append("StaticText");
     67     case WebAccessibilityRoleTextArea:
     68         return result.append("TextArea");
     69     case WebAccessibilityRoleScrollArea:
     70         return result.append("ScrollArea");
     71     case WebAccessibilityRolePopUpButton:
     72         return result.append("PopUpButton");
     73     case WebAccessibilityRoleMenuButton:
     74         return result.append("MenuButton");
     75     case WebAccessibilityRoleTable:
     76         return result.append("Table");
     77     case WebAccessibilityRoleApplication:
     78         return result.append("Application");
     79     case WebAccessibilityRoleGroup:
     80         return result.append("Group");
     81     case WebAccessibilityRoleRadioGroup:
     82         return result.append("RadioGroup");
     83     case WebAccessibilityRoleList:
     84         return result.append("List");
     85     case WebAccessibilityRoleScrollBar:
     86         return result.append("ScrollBar");
     87     case WebAccessibilityRoleValueIndicator:
     88         return result.append("ValueIndicator");
     89     case WebAccessibilityRoleImage:
     90         return result.append("Image");
     91     case WebAccessibilityRoleMenuBar:
     92         return result.append("MenuBar");
     93     case WebAccessibilityRoleMenu:
     94         return result.append("Menu");
     95     case WebAccessibilityRoleMenuItem:
     96         return result.append("MenuItem");
     97     case WebAccessibilityRoleColumn:
     98         return result.append("Column");
     99     case WebAccessibilityRoleRow:
    100         return result.append("Row");
    101     case WebAccessibilityRoleToolbar:
    102         return result.append("Toolbar");
    103     case WebAccessibilityRoleBusyIndicator:
    104         return result.append("BusyIndicator");
    105     case WebAccessibilityRoleProgressIndicator:
    106         return result.append("ProgressIndicator");
    107     case WebAccessibilityRoleWindow:
    108         return result.append("Window");
    109     case WebAccessibilityRoleDrawer:
    110         return result.append("Drawer");
    111     case WebAccessibilityRoleSystemWide:
    112         return result.append("SystemWide");
    113     case WebAccessibilityRoleOutline:
    114         return result.append("Outline");
    115     case WebAccessibilityRoleIncrementor:
    116         return result.append("Incrementor");
    117     case WebAccessibilityRoleBrowser:
    118         return result.append("Browser");
    119     case WebAccessibilityRoleComboBox:
    120         return result.append("ComboBox");
    121     case WebAccessibilityRoleSplitGroup:
    122         return result.append("SplitGroup");
    123     case WebAccessibilityRoleSplitter:
    124         return result.append("Splitter");
    125     case WebAccessibilityRoleColorWell:
    126         return result.append("ColorWell");
    127     case WebAccessibilityRoleGrowArea:
    128         return result.append("GrowArea");
    129     case WebAccessibilityRoleSheet:
    130         return result.append("Sheet");
    131     case WebAccessibilityRoleHelpTag:
    132         return result.append("HelpTag");
    133     case WebAccessibilityRoleMatte:
    134         return result.append("Matte");
    135     case WebAccessibilityRoleRuler:
    136         return result.append("Ruler");
    137     case WebAccessibilityRoleRulerMarker:
    138         return result.append("RulerMarker");
    139     case WebAccessibilityRoleLink:
    140         return result.append("Link");
    141     case WebAccessibilityRoleDisclosureTriangle:
    142         return result.append("DisclosureTriangle");
    143     case WebAccessibilityRoleGrid:
    144         return result.append("Grid");
    145     case WebAccessibilityRoleCell:
    146         return result.append("Cell");
    147     case WebAccessibilityRoleColumnHeader:
    148         return result.append("ColumnHeader");
    149     case WebAccessibilityRoleRowHeader:
    150         return result.append("RowHeader");
    151     case WebAccessibilityRoleWebCoreLink:
    152         // Maps to Link role.
    153         return result.append("Link");
    154     case WebAccessibilityRoleImageMapLink:
    155         return result.append("ImageMapLink");
    156     case WebAccessibilityRoleImageMap:
    157         return result.append("ImageMap");
    158     case WebAccessibilityRoleListMarker:
    159         return result.append("ListMarker");
    160     case WebAccessibilityRoleWebArea:
    161         return result.append("WebArea");
    162     case WebAccessibilityRoleHeading:
    163         return result.append("Heading");
    164     case WebAccessibilityRoleListBox:
    165         return result.append("ListBox");
    166     case WebAccessibilityRoleListBoxOption:
    167         return result.append("ListBoxOption");
    168     case WebAccessibilityRoleTableHeaderContainer:
    169         return result.append("TableHeaderContainer");
    170     case WebAccessibilityRoleDefinition:
    171         return result.append("Definition");
    172     case WebAccessibilityRoleDescriptionListTerm:
    173         return result.append("DescriptionListTerm");
    174     case WebAccessibilityRoleDescriptionListDetail:
    175         return result.append("DescriptionListDetail");
    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     WEBKIT_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     bindProperty("rowCount", &AccessibilityUIElement::rowCountGetterCallback);
    411     bindProperty("columnCount", &AccessibilityUIElement::columnCountGetterCallback);
    412 
    413     //
    414     // Methods
    415     //
    416 
    417     bindMethod("allAttributes", &AccessibilityUIElement::allAttributesCallback);
    418     bindMethod("attributesOfLinkedUIElements", &AccessibilityUIElement::attributesOfLinkedUIElementsCallback);
    419     bindMethod("attributesOfDocumentLinks", &AccessibilityUIElement::attributesOfDocumentLinksCallback);
    420     bindMethod("attributesOfChildren", &AccessibilityUIElement::attributesOfChildrenCallback);
    421     bindMethod("lineForIndex", &AccessibilityUIElement::lineForIndexCallback);
    422     bindMethod("boundsForRange", &AccessibilityUIElement::boundsForRangeCallback);
    423     bindMethod("stringForRange", &AccessibilityUIElement::stringForRangeCallback);
    424     bindMethod("childAtIndex", &AccessibilityUIElement::childAtIndexCallback);
    425     bindMethod("elementAtPoint", &AccessibilityUIElement::elementAtPointCallback);
    426     bindMethod("attributesOfColumnHeaders", &AccessibilityUIElement::attributesOfColumnHeadersCallback);
    427     bindMethod("attributesOfRowHeaders", &AccessibilityUIElement::attributesOfRowHeadersCallback);
    428     bindMethod("attributesOfColumns", &AccessibilityUIElement::attributesOfColumnsCallback);
    429     bindMethod("attributesOfRows", &AccessibilityUIElement::attributesOfRowsCallback);
    430     bindMethod("attributesOfVisibleCells", &AccessibilityUIElement::attributesOfVisibleCellsCallback);
    431     bindMethod("attributesOfHeader", &AccessibilityUIElement::attributesOfHeaderCallback);
    432     bindMethod("tableHeader", &AccessibilityUIElement::tableHeaderCallback);
    433     bindMethod("indexInTable", &AccessibilityUIElement::indexInTableCallback);
    434     bindMethod("rowIndexRange", &AccessibilityUIElement::rowIndexRangeCallback);
    435     bindMethod("columnIndexRange", &AccessibilityUIElement::columnIndexRangeCallback);
    436     bindMethod("cellForColumnAndRow", &AccessibilityUIElement::cellForColumnAndRowCallback);
    437     bindMethod("titleUIElement", &AccessibilityUIElement::titleUIElementCallback);
    438     bindMethod("setSelectedTextRange", &AccessibilityUIElement::setSelectedTextRangeCallback);
    439     bindMethod("attributeValue", &AccessibilityUIElement::attributeValueCallback);
    440     bindMethod("isAttributeSettable", &AccessibilityUIElement::isAttributeSettableCallback);
    441     bindMethod("isPressActionSupported", &AccessibilityUIElement::isPressActionSupportedCallback);
    442     bindMethod("isIncrementActionSupported", &AccessibilityUIElement::isIncrementActionSupportedCallback);
    443     bindMethod("isDecrementActionSupported", &AccessibilityUIElement::isDecrementActionSupportedCallback);
    444     bindMethod("parentElement", &AccessibilityUIElement::parentElementCallback);
    445     bindMethod("increment", &AccessibilityUIElement::incrementCallback);
    446     bindMethod("decrement", &AccessibilityUIElement::decrementCallback);
    447     bindMethod("showMenu", &AccessibilityUIElement::showMenuCallback);
    448     bindMethod("press", &AccessibilityUIElement::pressCallback);
    449     bindMethod("isEqual", &AccessibilityUIElement::isEqualCallback);
    450     bindMethod("addNotificationListener", &AccessibilityUIElement::addNotificationListenerCallback);
    451     bindMethod("removeNotificationListener", &AccessibilityUIElement::removeNotificationListenerCallback);
    452     bindMethod("takeFocus", &AccessibilityUIElement::takeFocusCallback);
    453     bindMethod("scrollToMakeVisible", &AccessibilityUIElement::scrollToMakeVisibleCallback);
    454     bindMethod("scrollToMakeVisibleWithSubFocus", &AccessibilityUIElement::scrollToMakeVisibleWithSubFocusCallback);
    455     bindMethod("scrollToGlobalPoint", &AccessibilityUIElement::scrollToGlobalPointCallback);
    456 
    457     bindFallbackMethod(&AccessibilityUIElement::fallbackCallback);
    458 }
    459 
    460 AccessibilityUIElement* AccessibilityUIElement::getChildAtIndex(unsigned index)
    461 {
    462     return m_factory->getOrCreate(accessibilityObject().childAt(index));
    463 }
    464 
    465 bool AccessibilityUIElement::isEqual(const WebKit::WebAccessibilityObject& other)
    466 {
    467     return accessibilityObject().equals(other);
    468 }
    469 
    470 void AccessibilityUIElement::notificationReceived(const char* notificationName)
    471 {
    472     size_t callbackCount = m_notificationCallbacks.size();
    473     for (size_t i = 0; i < callbackCount; i++) {
    474         CppVariant notificationNameArgument;
    475         notificationNameArgument.set(notificationName);
    476         CppVariant invokeResult;
    477         m_notificationCallbacks[i].invokeDefault(&notificationNameArgument, 1, invokeResult);
    478     }
    479 }
    480 
    481 //
    482 // Properties
    483 //
    484 
    485 void AccessibilityUIElement::roleGetterCallback(CppVariant* result)
    486 {
    487     result->set(getRole(accessibilityObject()));
    488 }
    489 
    490 void AccessibilityUIElement::titleGetterCallback(CppVariant* result)
    491 {
    492     result->set(getTitle(accessibilityObject()));
    493 }
    494 
    495 void AccessibilityUIElement::descriptionGetterCallback(CppVariant* result)
    496 {
    497     result->set(getDescription(accessibilityObject()));
    498 }
    499 
    500 void AccessibilityUIElement::helpTextGetterCallback(CppVariant* result)
    501 {
    502     result->set(getHelpText(accessibilityObject()));
    503 }
    504 
    505 void AccessibilityUIElement::stringValueGetterCallback(CppVariant* result)
    506 {
    507     result->set(getStringValue(accessibilityObject()));
    508 }
    509 
    510 void AccessibilityUIElement::xGetterCallback(CppVariant* result)
    511 {
    512     result->set(accessibilityObject().boundingBoxRect().x);
    513 }
    514 
    515 void AccessibilityUIElement::yGetterCallback(CppVariant* result)
    516 {
    517     result->set(accessibilityObject().boundingBoxRect().y);
    518 }
    519 
    520 void AccessibilityUIElement::widthGetterCallback(CppVariant* result)
    521 {
    522     result->set(accessibilityObject().boundingBoxRect().width);
    523 }
    524 
    525 void AccessibilityUIElement::heightGetterCallback(CppVariant* result)
    526 {
    527     result->set(accessibilityObject().boundingBoxRect().height);
    528 }
    529 
    530 void AccessibilityUIElement::intValueGetterCallback(CppVariant* result)
    531 {
    532     if (accessibilityObject().supportsRangeValue())
    533         result->set(accessibilityObject().valueForRange());
    534     else if (accessibilityObject().roleValue() == WebAccessibilityRoleHeading)
    535         result->set(accessibilityObject().headingLevel());
    536     else
    537         result->set(atoi(accessibilityObject().stringValue().utf8().data()));
    538 }
    539 
    540 void AccessibilityUIElement::minValueGetterCallback(CppVariant* result)
    541 {
    542     result->set(accessibilityObject().minValueForRange());
    543 }
    544 
    545 void AccessibilityUIElement::maxValueGetterCallback(CppVariant* result)
    546 {
    547     result->set(accessibilityObject().maxValueForRange());
    548 }
    549 
    550 void AccessibilityUIElement::valueDescriptionGetterCallback(CppVariant* result)
    551 {
    552     result->set(getValueDescription(accessibilityObject()));
    553 }
    554 
    555 void AccessibilityUIElement::childrenCountGetterCallback(CppVariant* result)
    556 {
    557     int count = 1; // Root object always has only one child, the WebView.
    558     if (!isRoot())
    559         count = accessibilityObject().childCount();
    560     result->set(count);
    561 }
    562 
    563 void AccessibilityUIElement::insertionPointLineNumberGetterCallback(CppVariant* result)
    564 {
    565     if (!accessibilityObject().isFocused()) {
    566         result->set(-1);
    567         return;
    568     }
    569 
    570     int lineNumber = accessibilityObject().selectionEndLineNumber();
    571     result->set(lineNumber);
    572 }
    573 
    574 void AccessibilityUIElement::selectedTextRangeGetterCallback(CppVariant* result)
    575 {
    576     unsigned selectionStart = accessibilityObject().selectionStart();
    577     unsigned selectionEnd = accessibilityObject().selectionEnd();
    578     char buffer[100];
    579     snprintf(buffer, sizeof(buffer), "{%d, %d}", selectionStart, selectionEnd - selectionStart);
    580 
    581     result->set(std::string(buffer));
    582 }
    583 
    584 void AccessibilityUIElement::isEnabledGetterCallback(CppVariant* result)
    585 {
    586     result->set(accessibilityObject().isEnabled());
    587 }
    588 
    589 void AccessibilityUIElement::isRequiredGetterCallback(CppVariant* result)
    590 {
    591     result->set(accessibilityObject().isRequired());
    592 }
    593 
    594 void AccessibilityUIElement::isFocusedGetterCallback(CppVariant* result)
    595 {
    596     result->set(accessibilityObject().isFocused());
    597 }
    598 
    599 void AccessibilityUIElement::isFocusableGetterCallback(CppVariant* result)
    600 {
    601     result->set(accessibilityObject().canSetFocusAttribute());
    602 }
    603 
    604 void AccessibilityUIElement::isSelectedGetterCallback(CppVariant* result)
    605 {
    606     result->set(accessibilityObject().isSelected());
    607 }
    608 
    609 void AccessibilityUIElement::isSelectableGetterCallback(CppVariant* result)
    610 {
    611     result->set(accessibilityObject().canSetSelectedAttribute());
    612 }
    613 
    614 void AccessibilityUIElement::isMultiSelectableGetterCallback(CppVariant* result)
    615 {
    616     result->set(accessibilityObject().isMultiSelectable());
    617 }
    618 
    619 void AccessibilityUIElement::isSelectedOptionActiveGetterCallback(CppVariant* result)
    620 {
    621     result->set(accessibilityObject().isSelectedOptionActive());
    622 }
    623 
    624 void AccessibilityUIElement::isExpandedGetterCallback(CppVariant* result)
    625 {
    626     result->set(!accessibilityObject().isCollapsed());
    627 }
    628 
    629 void AccessibilityUIElement::isCheckedGetterCallback(CppVariant* result)
    630 {
    631     result->set(accessibilityObject().isChecked());
    632 }
    633 
    634 void AccessibilityUIElement::isVisibleGetterCallback(CppVariant* result)
    635 {
    636     result->set(accessibilityObject().isVisible());
    637 }
    638 
    639 void AccessibilityUIElement::isOffScreenGetterCallback(CppVariant* result)
    640 {
    641     result->set(accessibilityObject().isOffScreen());
    642 }
    643 
    644 void AccessibilityUIElement::isCollapsedGetterCallback(CppVariant* result)
    645 {
    646     result->set(accessibilityObject().isCollapsed());
    647 }
    648 
    649 void AccessibilityUIElement::hasPopupGetterCallback(CppVariant* result)
    650 {
    651     result->set(accessibilityObject().ariaHasPopup());
    652 }
    653 
    654 void AccessibilityUIElement::isValidGetterCallback(CppVariant* result)
    655 {
    656     result->set(!accessibilityObject().isDetached());
    657 }
    658 
    659 void AccessibilityUIElement::isReadOnlyGetterCallback(CppVariant* result)
    660 {
    661     result->set(accessibilityObject().isReadOnly());
    662 }
    663 
    664 void AccessibilityUIElement::orientationGetterCallback(CppVariant* result)
    665 {
    666     result->set(getOrientation(accessibilityObject()));
    667 }
    668 
    669 void AccessibilityUIElement::clickPointXGetterCallback(CppVariant* result)
    670 {
    671     result->set(accessibilityObject().clickPoint().x);
    672 }
    673 
    674 void AccessibilityUIElement::clickPointYGetterCallback(CppVariant* result)
    675 {
    676     result->set(accessibilityObject().clickPoint().y);
    677 }
    678 
    679 void AccessibilityUIElement::rowCountGetterCallback(CppVariant* result)
    680 {
    681     result->set(static_cast<int32_t>(accessibilityObject().rowCount()));
    682 }
    683 
    684 void AccessibilityUIElement::columnCountGetterCallback(CppVariant* result)
    685 {
    686     result->set(static_cast<int32_t>(accessibilityObject().columnCount()));
    687 }
    688 
    689 //
    690 // Methods
    691 //
    692 
    693 void AccessibilityUIElement::allAttributesCallback(const CppArgumentList&, CppVariant* result)
    694 {
    695     result->set(getAttributes(accessibilityObject()));
    696 }
    697 
    698 void AccessibilityUIElement::attributesOfLinkedUIElementsCallback(const CppArgumentList&, CppVariant* result)
    699 {
    700     result->setNull();
    701 }
    702 
    703 void AccessibilityUIElement::attributesOfDocumentLinksCallback(const CppArgumentList&, CppVariant* result)
    704 {
    705     result->setNull();
    706 }
    707 
    708 void AccessibilityUIElement::attributesOfChildrenCallback(const CppArgumentList& arguments, CppVariant* result)
    709 {
    710     AttributesCollector collector;
    711     unsigned size = accessibilityObject().childCount();
    712     for (unsigned i = 0; i < size; ++i)
    713         collector.collectAttributes(accessibilityObject().childAt(i));
    714     result->set(collector.attributes());
    715 }
    716 
    717 void AccessibilityUIElement::parametrizedAttributeNamesCallback(const CppArgumentList&, CppVariant* result)
    718 {
    719     result->setNull();
    720 }
    721 
    722 void AccessibilityUIElement::lineForIndexCallback(const CppArgumentList& arguments, CppVariant* result)
    723 {
    724     if (!arguments.size() || !arguments[0].isNumber()) {
    725         result->setNull();
    726         return;
    727     }
    728 
    729     int index = arguments[0].toInt32();
    730 
    731     WebVector<int> lineBreaks;
    732     accessibilityObject().lineBreaks(lineBreaks);
    733     int line = 0;
    734     int vectorSize = static_cast<int>(lineBreaks.size());
    735     while (line < vectorSize && lineBreaks[line] <= index)
    736         line++;
    737     result->set(line);
    738 }
    739 
    740 void AccessibilityUIElement::boundsForRangeCallback(const CppArgumentList&, CppVariant* result)
    741 {
    742     result->setNull();
    743 }
    744 
    745 void AccessibilityUIElement::stringForRangeCallback(const CppArgumentList&, CppVariant* result)
    746 {
    747     result->setNull();
    748 }
    749 
    750 void AccessibilityUIElement::childAtIndexCallback(const CppArgumentList& arguments, CppVariant* result)
    751 {
    752     if (!arguments.size() || !arguments[0].isNumber()) {
    753         result->setNull();
    754         return;
    755     }
    756 
    757     AccessibilityUIElement* child = getChildAtIndex(arguments[0].toInt32());
    758     if (!child) {
    759         result->setNull();
    760         return;
    761     }
    762 
    763     result->set(*(child->getAsCppVariant()));
    764 }
    765 
    766 void AccessibilityUIElement::elementAtPointCallback(const CppArgumentList& arguments, CppVariant* result)
    767 {
    768     result->setNull();
    769 
    770     if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNumber())
    771         return;
    772 
    773     int x = arguments[0].toInt32();
    774     int y = arguments[1].toInt32();
    775     WebPoint point(x, y);
    776     WebAccessibilityObject obj = accessibilityObject().hitTest(point);
    777     if (obj.isNull())
    778         return;
    779 
    780     result->set(*(m_factory->getOrCreate(obj)->getAsCppVariant()));
    781 }
    782 
    783 void AccessibilityUIElement::attributesOfColumnHeadersCallback(const CppArgumentList&, CppVariant* result)
    784 {
    785     result->setNull();
    786 }
    787 
    788 void AccessibilityUIElement::attributesOfRowHeadersCallback(const CppArgumentList&, CppVariant* result)
    789 {
    790     result->setNull();
    791 }
    792 
    793 void AccessibilityUIElement::attributesOfColumnsCallback(const CppArgumentList&, CppVariant* result)
    794 {
    795     result->setNull();
    796 }
    797 
    798 void AccessibilityUIElement::attributesOfRowsCallback(const CppArgumentList&, CppVariant* result)
    799 {
    800     result->setNull();
    801 }
    802 
    803 void AccessibilityUIElement::attributesOfVisibleCellsCallback(const CppArgumentList&, CppVariant* result)
    804 {
    805     result->setNull();
    806 }
    807 
    808 void AccessibilityUIElement::attributesOfHeaderCallback(const CppArgumentList&, CppVariant* result)
    809 {
    810     result->setNull();
    811 }
    812 
    813 void AccessibilityUIElement::tableHeaderCallback(const CppArgumentList&, CppVariant* result)
    814 {
    815     WebAccessibilityObject obj = accessibilityObject().headerContainerObject();
    816     if (obj.isNull()) {
    817         result->setNull();
    818         return;
    819     }
    820 
    821     result->set(*(m_factory->getOrCreate(obj)->getAsCppVariant()));
    822 }
    823 
    824 void AccessibilityUIElement::indexInTableCallback(const CppArgumentList&, CppVariant* result)
    825 {
    826     result->setNull();
    827 }
    828 
    829 void AccessibilityUIElement::rowIndexRangeCallback(const CppArgumentList&, CppVariant* result)
    830 {
    831     unsigned rowIndex = accessibilityObject().cellRowIndex();
    832     unsigned rowSpan = accessibilityObject().cellRowSpan();
    833     char buffer[100];
    834     snprintf(buffer, sizeof(buffer), "{%d, %d}", rowIndex, rowSpan);
    835     string value = buffer;
    836     result->set(std::string(buffer));
    837 }
    838 
    839 void AccessibilityUIElement::columnIndexRangeCallback(const CppArgumentList&, CppVariant* result)
    840 {
    841     unsigned columnIndex = accessibilityObject().cellColumnIndex();
    842     unsigned columnSpan = accessibilityObject().cellColumnSpan();
    843     char buffer[100];
    844     snprintf(buffer, sizeof(buffer), "{%d, %d}", columnIndex, columnSpan);
    845     result->set(std::string(buffer));
    846 }
    847 
    848 void AccessibilityUIElement::cellForColumnAndRowCallback(const CppArgumentList& arguments, CppVariant* result)
    849 {
    850     if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNumber())
    851         return;
    852 
    853     int column = arguments[0].toInt32();
    854     int row = arguments[1].toInt32();
    855     WebAccessibilityObject obj = accessibilityObject().cellForColumnAndRow(column, row);
    856     if (obj.isNull()) {
    857         result->setNull();
    858         return;
    859     }
    860 
    861     result->set(*(m_factory->getOrCreate(obj)->getAsCppVariant()));
    862 }
    863 
    864 void AccessibilityUIElement::titleUIElementCallback(const CppArgumentList&, CppVariant* result)
    865 {
    866     WebAccessibilityObject obj = accessibilityObject().titleUIElement();
    867     if (obj.isNull()) {
    868         result->setNull();
    869         return;
    870     }
    871 
    872     result->set(*(m_factory->getOrCreate(obj)->getAsCppVariant()));
    873 }
    874 
    875 void AccessibilityUIElement::setSelectedTextRangeCallback(const CppArgumentList&arguments, CppVariant* result)
    876 {
    877     result->setNull();
    878     if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNumber())
    879         return;
    880 
    881     int selectionStart = arguments[0].toInt32();
    882     int selectionEnd = selectionStart + arguments[1].toInt32();
    883     accessibilityObject().setSelectedTextRange(selectionStart, selectionEnd);
    884 }
    885 
    886 void AccessibilityUIElement::attributeValueCallback(const CppArgumentList&, CppVariant* result)
    887 {
    888     result->setNull();
    889 }
    890 
    891 void AccessibilityUIElement::isAttributeSettableCallback(const CppArgumentList& arguments, CppVariant* result)
    892 {
    893     if (arguments.size() < 1 && !arguments[0].isString()) {
    894         result->setNull();
    895         return;
    896     }
    897 
    898     string attribute = arguments[0].toString();
    899     bool settable = false;
    900     if (attribute == "AXValue")
    901         settable = accessibilityObject().canSetValueAttribute();
    902     result->set(settable);
    903 }
    904 
    905 void AccessibilityUIElement::isPressActionSupportedCallback(const CppArgumentList&, CppVariant* result)
    906 {
    907     result->set(accessibilityObject().canPress());
    908 }
    909 
    910 void AccessibilityUIElement::isIncrementActionSupportedCallback(const CppArgumentList&, CppVariant* result)
    911 {
    912     result->set(accessibilityObject().canIncrement());
    913 }
    914 
    915 void AccessibilityUIElement::isDecrementActionSupportedCallback(const CppArgumentList&, CppVariant* result)
    916 {
    917     result->set(accessibilityObject().canDecrement());
    918 }
    919 
    920 void AccessibilityUIElement::parentElementCallback(const CppArgumentList&, CppVariant* result)
    921 {
    922     AccessibilityUIElement* parent = m_factory->getOrCreate(accessibilityObject().parentObject());
    923     if (!parent) {
    924         result->setNull();
    925         return;
    926     }
    927 
    928     result->set(*(parent->getAsCppVariant()));
    929 }
    930 
    931 void AccessibilityUIElement::incrementCallback(const CppArgumentList&, CppVariant* result)
    932 {
    933     accessibilityObject().increment();
    934     result->setNull();
    935 }
    936 
    937 void AccessibilityUIElement::decrementCallback(const CppArgumentList&, CppVariant* result)
    938 {
    939     accessibilityObject().decrement();
    940     result->setNull();
    941 }
    942 
    943 void AccessibilityUIElement::showMenuCallback(const CppArgumentList&, CppVariant* result)
    944 {
    945     result->setNull();
    946 }
    947 
    948 void AccessibilityUIElement::pressCallback(const CppArgumentList&, CppVariant* result)
    949 {
    950     accessibilityObject().press();
    951     result->setNull();
    952 }
    953 
    954 void AccessibilityUIElement::isEqualCallback(const CppArgumentList& arguments, CppVariant* result)
    955 {
    956     if (arguments.size() < 1 || !arguments[0].isObject()) {
    957         result->setNull();
    958         return;
    959     }
    960 
    961     result->set(arguments[0].isEqual(*getAsCppVariant()));
    962 }
    963 
    964 void AccessibilityUIElement::addNotificationListenerCallback(const CppArgumentList& arguments, CppVariant* result)
    965 {
    966     if (arguments.size() < 1 || !arguments[0].isObject()) {
    967         result->setNull();
    968         return;
    969     }
    970 
    971     m_notificationCallbacks.push_back(arguments[0]);
    972     result->setNull();
    973 }
    974 
    975 void AccessibilityUIElement::removeNotificationListenerCallback(const CppArgumentList&, CppVariant* result)
    976 {
    977     // FIXME: Implement this.
    978     result->setNull();
    979 }
    980 
    981 void AccessibilityUIElement::takeFocusCallback(const CppArgumentList&, CppVariant* result)
    982 {
    983     accessibilityObject().setFocused(true);
    984     result->setNull();
    985 }
    986 
    987 void AccessibilityUIElement::scrollToMakeVisibleCallback(const CppArgumentList&, CppVariant* result)
    988 {
    989     accessibilityObject().scrollToMakeVisible();
    990     result->setNull();
    991 }
    992 
    993 void AccessibilityUIElement::scrollToMakeVisibleWithSubFocusCallback(const CppArgumentList& arguments, CppVariant* result)
    994 {
    995     result->setNull();
    996 
    997     if (arguments.size() != 4
    998         || !arguments[0].isNumber()
    999         || !arguments[1].isNumber()
   1000         || !arguments[2].isNumber()
   1001         || !arguments[3].isNumber())
   1002         return;
   1003 
   1004     int x = arguments[0].toInt32();
   1005     int y = arguments[1].toInt32();
   1006     int width = arguments[2].toInt32();
   1007     int height = arguments[3].toInt32();
   1008     accessibilityObject().scrollToMakeVisibleWithSubFocus(WebRect(x, y, width, height));
   1009     result->setNull();
   1010 }
   1011 
   1012 void AccessibilityUIElement::scrollToGlobalPointCallback(const CppArgumentList& arguments, CppVariant* result)
   1013 {
   1014     result->setNull();
   1015 
   1016     if (arguments.size() != 2
   1017         || !arguments[0].isNumber()
   1018         || !arguments[1].isNumber())
   1019         return;
   1020 
   1021     int x = arguments[0].toInt32();
   1022     int y = arguments[1].toInt32();
   1023 
   1024     accessibilityObject().scrollToGlobalPoint(WebPoint(x, y));
   1025     result->setNull();
   1026 }
   1027 
   1028 void AccessibilityUIElement::fallbackCallback(const CppArgumentList &, CppVariant* result)
   1029 {
   1030     // FIXME: Implement this.
   1031     result->setNull();
   1032 }
   1033 
   1034 RootAccessibilityUIElement::RootAccessibilityUIElement(const WebAccessibilityObject &object, Factory *factory)
   1035     : AccessibilityUIElement(object, factory) { }
   1036 
   1037 AccessibilityUIElement* RootAccessibilityUIElement::getChildAtIndex(unsigned index)
   1038 {
   1039     if (index)
   1040         return 0;
   1041 
   1042     return factory()->getOrCreate(accessibilityObject());
   1043 }
   1044 
   1045 
   1046 AccessibilityUIElementList ::~AccessibilityUIElementList()
   1047 {
   1048     clear();
   1049 }
   1050 
   1051 void AccessibilityUIElementList::clear()
   1052 {
   1053     for (ElementList::iterator i = m_elements.begin(); i != m_elements.end(); ++i)
   1054         delete (*i);
   1055     m_elements.clear();
   1056 }
   1057 
   1058 AccessibilityUIElement* AccessibilityUIElementList::getOrCreate(const WebAccessibilityObject& object)
   1059 {
   1060     if (object.isNull())
   1061         return 0;
   1062 
   1063     size_t elementCount = m_elements.size();
   1064     for (size_t i = 0; i < elementCount; i++) {
   1065         if (m_elements[i]->isEqual(object))
   1066             return m_elements[i];
   1067     }
   1068 
   1069     AccessibilityUIElement* element = new AccessibilityUIElement(object, this);
   1070     m_elements.push_back(element);
   1071     return element;
   1072 }
   1073 
   1074 AccessibilityUIElement* AccessibilityUIElementList::createRoot(const WebAccessibilityObject& object)
   1075 {
   1076     AccessibilityUIElement* element = new RootAccessibilityUIElement(object, this);
   1077     m_elements.push_back(element);
   1078     return element;
   1079 }
   1080 
   1081 }
   1082