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