Home | History | Annotate | Download | only in DumpRenderTree
      1 /*
      2  * Copyright (C) 2008, 2009 Apple 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
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "AccessibilityUIElement.h"
     28 
     29 #include <JavaScriptCore/JSRetainPtr.h>
     30 
     31 // Static Functions
     32 
     33 static inline AccessibilityUIElement* toAXElement(JSObjectRef object)
     34 {
     35     // FIXME: We should ASSERT that it is the right class here.
     36     return static_cast<AccessibilityUIElement*>(JSObjectGetPrivate(object));
     37 }
     38 
     39 static JSValueRef allAttributesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
     40 {
     41     JSRetainPtr<JSStringRef> attributes(Adopt, toAXElement(thisObject)->allAttributes());
     42     return JSValueMakeString(context, attributes.get());
     43 }
     44 
     45 static JSValueRef attributesOfLinkedUIElementsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
     46 {
     47     JSRetainPtr<JSStringRef> linkedUIDescription(Adopt, toAXElement(thisObject)->attributesOfLinkedUIElements());
     48     return JSValueMakeString(context, linkedUIDescription.get());
     49 }
     50 
     51 static JSValueRef attributesOfDocumentLinksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
     52 {
     53     JSRetainPtr<JSStringRef> linkedUIDescription(Adopt, toAXElement(thisObject)->attributesOfDocumentLinks());
     54     return JSValueMakeString(context, linkedUIDescription.get());
     55 }
     56 
     57 static JSValueRef attributesOfChildrenCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
     58 {
     59     JSRetainPtr<JSStringRef> childrenDescription(Adopt, toAXElement(thisObject)->attributesOfChildren());
     60     return JSValueMakeString(context, childrenDescription.get());
     61 }
     62 
     63 static JSValueRef parameterizedAttributeNamesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
     64 {
     65     JSRetainPtr<JSStringRef> parameterizedAttributeNames(Adopt, toAXElement(thisObject)->parameterizedAttributeNames());
     66     return JSValueMakeString(context, parameterizedAttributeNames.get());
     67 }
     68 
     69 static JSValueRef attributesOfColumnHeadersCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
     70 {
     71     JSRetainPtr<JSStringRef> attributesOfColumnHeaders(Adopt, toAXElement(thisObject)->attributesOfColumnHeaders());
     72     return JSValueMakeString(context, attributesOfColumnHeaders.get());
     73 }
     74 
     75 static JSValueRef attributesOfRowHeadersCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
     76 {
     77     JSRetainPtr<JSStringRef> attributesOfRowHeaders(Adopt, toAXElement(thisObject)->attributesOfRowHeaders());
     78     return JSValueMakeString(context, attributesOfRowHeaders.get());
     79 }
     80 
     81 static JSValueRef attributesOfColumnsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
     82 {
     83     JSRetainPtr<JSStringRef> attributesOfColumns(Adopt, toAXElement(thisObject)->attributesOfColumns());
     84     return JSValueMakeString(context, attributesOfColumns.get());
     85 }
     86 
     87 static JSValueRef attributesOfRowsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
     88 {
     89     JSRetainPtr<JSStringRef> attributesOfRows(Adopt, toAXElement(thisObject)->attributesOfRows());
     90     return JSValueMakeString(context, attributesOfRows.get());
     91 }
     92 
     93 static JSValueRef attributesOfVisibleCellsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
     94 {
     95     JSRetainPtr<JSStringRef> attributesOfVisibleCells(Adopt, toAXElement(thisObject)->attributesOfVisibleCells());
     96     return JSValueMakeString(context, attributesOfVisibleCells.get());
     97 }
     98 
     99 static JSValueRef attributesOfHeaderCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    100 {
    101     JSRetainPtr<JSStringRef> attributesOfHeader(Adopt, toAXElement(thisObject)->attributesOfHeader());
    102     return JSValueMakeString(context, attributesOfHeader.get());
    103 }
    104 
    105 static JSValueRef indexInTableCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    106 {
    107     return JSValueMakeNumber(context, toAXElement(thisObject)->indexInTable());
    108 }
    109 
    110 static JSValueRef rowIndexRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    111 {
    112     JSRetainPtr<JSStringRef> rowIndexRange(Adopt, toAXElement(thisObject)->rowIndexRange());
    113     return JSValueMakeString(context, rowIndexRange.get());
    114 }
    115 
    116 static JSValueRef columnIndexRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    117 {
    118     JSRetainPtr<JSStringRef> columnIndexRange(Adopt, toAXElement(thisObject)->columnIndexRange());
    119     return JSValueMakeString(context, columnIndexRange.get());
    120 }
    121 
    122 static JSValueRef lineForIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    123 {
    124     int indexNumber = -1;
    125     if (argumentCount == 1)
    126         indexNumber = JSValueToNumber(context, arguments[0], exception);
    127 
    128     return JSValueMakeNumber(context, toAXElement(thisObject)->lineForIndex(indexNumber));
    129 }
    130 
    131 static JSValueRef boundsForRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    132 {
    133     unsigned location = UINT_MAX, length = 0;
    134     if (argumentCount == 2) {
    135         location = JSValueToNumber(context, arguments[0], exception);
    136         length = JSValueToNumber(context, arguments[1], exception);
    137     }
    138 
    139     JSRetainPtr<JSStringRef> boundsDescription(Adopt, toAXElement(thisObject)->boundsForRange(location, length));
    140     return JSValueMakeString(context, boundsDescription.get());
    141 }
    142 
    143 static JSValueRef stringForRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    144 {
    145     unsigned location = UINT_MAX, length = 0;
    146     if (argumentCount == 2) {
    147         location = JSValueToNumber(context, arguments[0], exception);
    148         length = JSValueToNumber(context, arguments[1], exception);
    149     }
    150 
    151     JSRetainPtr<JSStringRef> stringDescription(Adopt, toAXElement(thisObject)->stringForRange(location, length));
    152     return JSValueMakeString(context, stringDescription.get());
    153 }
    154 
    155 static JSValueRef indexOfChildCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    156 {
    157     if (argumentCount != 1)
    158         return 0;
    159 
    160     JSObjectRef otherElement = JSValueToObject(context, arguments[0], exception);
    161     AccessibilityUIElement* childElement = toAXElement(otherElement);
    162     return JSValueMakeNumber(context, (double)toAXElement(thisObject)->indexOfChild(childElement));
    163 }
    164 
    165 static JSValueRef childAtIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    166 {
    167     int indexNumber = -1;
    168     if (argumentCount == 1)
    169         indexNumber = JSValueToNumber(context, arguments[0], exception);
    170 
    171     return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->getChildAtIndex(indexNumber));
    172 }
    173 
    174 static JSValueRef disclosedRowAtIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    175 {
    176     int indexNumber = 0;
    177     if (argumentCount == 1)
    178         indexNumber = JSValueToNumber(context, arguments[0], exception);
    179 
    180     return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->disclosedRowAtIndex(indexNumber));
    181 }
    182 
    183 static JSValueRef ariaOwnsElementAtIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    184 {
    185     int indexNumber = 0;
    186     if (argumentCount == 1)
    187         indexNumber = JSValueToNumber(context, arguments[0], exception);
    188 
    189     return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->ariaOwnsElementAtIndex(indexNumber));
    190 }
    191 
    192 static JSValueRef ariaFlowToElementAtIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    193 {
    194     int indexNumber = 0;
    195     if (argumentCount == 1)
    196         indexNumber = JSValueToNumber(context, arguments[0], exception);
    197 
    198     return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->ariaFlowToElementAtIndex(indexNumber));
    199 }
    200 
    201 static JSValueRef selectedRowAtIndexCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    202 {
    203     int indexNumber = 0;
    204     if (argumentCount == 1)
    205         indexNumber = JSValueToNumber(context, arguments[0], exception);
    206 
    207     return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->selectedRowAtIndex(indexNumber));
    208 }
    209 
    210 static JSValueRef isEqualCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    211 {
    212     JSObjectRef otherElement = 0;
    213     if (argumentCount == 1)
    214         otherElement = JSValueToObject(context, arguments[0], exception);
    215     else
    216         return JSValueMakeBoolean(context, false);
    217 
    218     return JSValueMakeBoolean(context, toAXElement(thisObject)->isEqual(toAXElement(otherElement)));
    219 }
    220 
    221 static JSValueRef elementAtPointCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    222 {
    223     int x = 0;
    224     int y = 0;
    225     if (argumentCount == 2) {
    226         x = JSValueToNumber(context, arguments[0], exception);
    227         y = JSValueToNumber(context, arguments[1], exception);
    228     }
    229 
    230     return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->elementAtPoint(x, y));
    231 }
    232 
    233 static JSValueRef isAttributeSupportedCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    234 {
    235     JSStringRef attribute = 0;
    236     if (argumentCount == 1)
    237         attribute = JSValueToStringCopy(context, arguments[0], exception);
    238     JSValueRef result = JSValueMakeBoolean(context, toAXElement(thisObject)->isAttributeSupported(attribute));
    239     if (attribute)
    240         JSStringRelease(attribute);
    241     return result;
    242 }
    243 
    244 static JSValueRef isAttributeSettableCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    245 {
    246     JSStringRef attribute = 0;
    247     if (argumentCount == 1)
    248         attribute = JSValueToStringCopy(context, arguments[0], exception);
    249     JSValueRef result = JSValueMakeBoolean(context, toAXElement(thisObject)->isAttributeSettable(attribute));
    250     if (attribute)
    251         JSStringRelease(attribute);
    252     return result;
    253 }
    254 
    255 
    256 static JSValueRef isActionSupportedCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    257 {
    258     JSStringRef action = 0;
    259     if (argumentCount == 1)
    260         action = JSValueToStringCopy(context, arguments[0], exception);
    261     JSValueRef result = JSValueMakeBoolean(context, toAXElement(thisObject)->isActionSupported(action));
    262     if (action)
    263         JSStringRelease(action);
    264     return result;
    265 }
    266 
    267 static JSValueRef boolAttributeValueCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    268 {
    269     JSStringRef attribute = 0;
    270     if (argumentCount == 1)
    271         attribute = JSValueToStringCopy(context, arguments[0], exception);
    272     bool val = toAXElement(thisObject)->boolAttributeValue(attribute);
    273     JSValueRef result = JSValueMakeBoolean(context, val);
    274     if (attribute)
    275         JSStringRelease(attribute);
    276     return result;
    277 }
    278 
    279 static JSValueRef stringAttributeValueCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    280 {
    281     JSStringRef attribute = 0;
    282     if (argumentCount == 1)
    283         attribute = JSValueToStringCopy(context, arguments[0], exception);
    284     JSRetainPtr<JSStringRef> stringAttributeValue(Adopt, toAXElement(thisObject)->stringAttributeValue(attribute));
    285     JSValueRef result = JSValueMakeString(context, stringAttributeValue.get());
    286     if (attribute)
    287         JSStringRelease(attribute);
    288     return result;
    289 }
    290 
    291 static JSValueRef cellForColumnAndRowCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    292 {
    293     unsigned column = 0, row = 0;
    294     if (argumentCount == 2) {
    295         column = JSValueToNumber(context, arguments[0], exception);
    296         row = JSValueToNumber(context, arguments[1], exception);
    297     }
    298 
    299     return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->cellForColumnAndRow(column, row));
    300 }
    301 
    302 static JSValueRef titleUIElementCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    303 {
    304     return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->titleUIElement());
    305 }
    306 
    307 static JSValueRef parentElementCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    308 {
    309     return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->parentElement());
    310 }
    311 
    312 static JSValueRef disclosedByRowCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    313 {
    314     return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->disclosedByRow());
    315 }
    316 
    317 static JSValueRef setSelectedTextRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    318 {
    319     unsigned location = UINT_MAX, length = 0;
    320     if (argumentCount == 2) {
    321         location = JSValueToNumber(context, arguments[0], exception);
    322         length = JSValueToNumber(context, arguments[1], exception);
    323     }
    324 
    325     toAXElement(thisObject)->setSelectedTextRange(location, length);
    326     return JSValueMakeUndefined(context);
    327 }
    328 
    329 static JSValueRef incrementCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    330 {
    331     toAXElement(thisObject)->increment();
    332     return JSValueMakeUndefined(context);
    333 }
    334 
    335 static JSValueRef decrementCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    336 {
    337     toAXElement(thisObject)->decrement();
    338     return JSValueMakeUndefined(context);
    339 }
    340 
    341 static JSValueRef showMenuCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    342 {
    343     toAXElement(thisObject)->showMenu();
    344     return JSValueMakeUndefined(context);
    345 }
    346 
    347 static JSValueRef takeFocusCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    348 {
    349     toAXElement(thisObject)->takeFocus();
    350     return JSValueMakeUndefined(context);
    351 }
    352 
    353 static JSValueRef takeSelectionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    354 {
    355     toAXElement(thisObject)->takeSelection();
    356     return JSValueMakeUndefined(context);
    357 }
    358 
    359 static JSValueRef addSelectionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    360 {
    361     toAXElement(thisObject)->addSelection();
    362     return JSValueMakeUndefined(context);
    363 }
    364 
    365 static JSValueRef removeSelectionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    366 {
    367     toAXElement(thisObject)->removeSelection();
    368     return JSValueMakeUndefined(context);
    369 }
    370 
    371 
    372 // Static Value Getters
    373 
    374 static JSValueRef getARIADropEffectsCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    375 {
    376     JSRetainPtr<JSStringRef> dropEffects(Adopt, toAXElement(thisObject)->ariaDropEffects());
    377     return JSValueMakeString(context, dropEffects.get());
    378 }
    379 
    380 static JSValueRef getARIAIsGrabbedCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    381 {
    382     return JSValueMakeBoolean(context, toAXElement(thisObject)->ariaIsGrabbed());
    383 }
    384 
    385 static JSValueRef getIsValidCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    386 {
    387     AccessibilityUIElement* uiElement = toAXElement(thisObject);
    388     if (!uiElement->platformUIElement())
    389         return JSValueMakeBoolean(context, false);
    390 
    391     // There might be other platform logic that one could check here...
    392 
    393     return JSValueMakeBoolean(context, true);
    394 }
    395 
    396 static JSValueRef getRoleCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    397 {
    398     JSRetainPtr<JSStringRef> role(Adopt, toAXElement(thisObject)->role());
    399     return JSValueMakeString(context, role.get());
    400 }
    401 
    402 static JSValueRef getSubroleCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    403 {
    404     JSRetainPtr<JSStringRef> role(Adopt, toAXElement(thisObject)->subrole());
    405     return JSValueMakeString(context, role.get());
    406 }
    407 
    408 static JSValueRef getRoleDescriptionCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    409 {
    410     JSRetainPtr<JSStringRef> roleDesc(Adopt, toAXElement(thisObject)->roleDescription());
    411     return JSValueMakeString(context, roleDesc.get());
    412 }
    413 
    414 static JSValueRef getTitleCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    415 {
    416     JSRetainPtr<JSStringRef> title(Adopt, toAXElement(thisObject)->title());
    417     return JSValueMakeString(context, title.get());
    418 }
    419 
    420 static JSValueRef getDescriptionCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    421 {
    422     JSRetainPtr<JSStringRef> description(Adopt, toAXElement(thisObject)->description());
    423     return JSValueMakeString(context, description.get());
    424 }
    425 
    426 static JSValueRef getStringValueCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    427 {
    428     JSRetainPtr<JSStringRef> stringValue(Adopt, toAXElement(thisObject)->stringValue());
    429     return JSValueMakeString(context, stringValue.get());
    430 }
    431 
    432 static JSValueRef getLanguageCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    433 {
    434     JSRetainPtr<JSStringRef> language(Adopt, toAXElement(thisObject)->language());
    435     return JSValueMakeString(context, language.get());
    436 }
    437 
    438 static JSValueRef getOrientationCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    439 {
    440     JSRetainPtr<JSStringRef> orientation(Adopt, toAXElement(thisObject)->orientation());
    441     return JSValueMakeString(context, orientation.get());
    442 }
    443 
    444 static JSValueRef getChildrenCountCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    445 {
    446     return JSValueMakeNumber(context, toAXElement(thisObject)->childrenCount());
    447 }
    448 
    449 static JSValueRef getXCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    450 {
    451     return JSValueMakeNumber(context, toAXElement(thisObject)->x());
    452 }
    453 
    454 static JSValueRef getYCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    455 {
    456     return JSValueMakeNumber(context, toAXElement(thisObject)->y());
    457 }
    458 
    459 static JSValueRef getWidthCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    460 {
    461     return JSValueMakeNumber(context, toAXElement(thisObject)->width());
    462 }
    463 
    464 static JSValueRef getHeightCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    465 {
    466     return JSValueMakeNumber(context, toAXElement(thisObject)->height());
    467 }
    468 
    469 static JSValueRef getClickPointXCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    470 {
    471     return JSValueMakeNumber(context, toAXElement(thisObject)->clickPointX());
    472 }
    473 
    474 static JSValueRef getClickPointYCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    475 {
    476     return JSValueMakeNumber(context, toAXElement(thisObject)->clickPointY());
    477 }
    478 
    479 static JSValueRef getIntValueCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    480 {
    481     return JSValueMakeNumber(context, toAXElement(thisObject)->intValue());
    482 }
    483 
    484 static JSValueRef getMinValueCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    485 {
    486     return JSValueMakeNumber(context, toAXElement(thisObject)->minValue());
    487 }
    488 
    489 static JSValueRef getMaxValueCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    490 {
    491     return JSValueMakeNumber(context, toAXElement(thisObject)->maxValue());
    492 }
    493 
    494 static JSValueRef getInsertionPointLineNumberCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    495 {
    496     return JSValueMakeNumber(context, toAXElement(thisObject)->insertionPointLineNumber());
    497 }
    498 
    499 static JSValueRef getSelectedTextRangeCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    500 {
    501     JSRetainPtr<JSStringRef> selectedTextRange(Adopt, toAXElement(thisObject)->selectedTextRange());
    502     return JSValueMakeString(context, selectedTextRange.get());
    503 }
    504 
    505 static JSValueRef getIsEnabledCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    506 {
    507     return JSValueMakeBoolean(context, toAXElement(thisObject)->isEnabled());
    508 }
    509 
    510 static JSValueRef getIsRequiredCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef*)
    511 {
    512     return JSValueMakeBoolean(context, toAXElement(thisObject)->isRequired());
    513 }
    514 
    515 static JSValueRef getIsSelectedCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef*)
    516 {
    517     return JSValueMakeBoolean(context, toAXElement(thisObject)->isSelected());
    518 }
    519 
    520 static JSValueRef getIsSelectableCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef*)
    521 {
    522     return JSValueMakeBoolean(context, toAXElement(thisObject)->isSelectable());
    523 }
    524 
    525 static JSValueRef getIsMultiSelectableCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef*)
    526 {
    527     return JSValueMakeBoolean(context, toAXElement(thisObject)->isMultiSelectable());
    528 }
    529 
    530 static JSValueRef getIsExpandedCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef*)
    531 {
    532     return JSValueMakeBoolean(context, toAXElement(thisObject)->isExpanded());
    533 }
    534 
    535 static JSValueRef getIsCheckedCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef*)
    536 {
    537     return JSValueMakeBoolean(context, toAXElement(thisObject)->isChecked());
    538 }
    539 
    540 static JSValueRef getIsVisibleCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef*)
    541 {
    542     return JSValueMakeBoolean(context, toAXElement(thisObject)->isVisible());
    543 }
    544 
    545 static JSValueRef getIsOffScreenCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef*)
    546 {
    547     return JSValueMakeBoolean(context, toAXElement(thisObject)->isOffScreen());
    548 }
    549 
    550 static JSValueRef getIsCollapsedCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef*)
    551 {
    552     return JSValueMakeBoolean(context, toAXElement(thisObject)->isCollapsed());
    553 }
    554 
    555 static JSValueRef getHasPopupCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef*)
    556 {
    557     return JSValueMakeBoolean(context, toAXElement(thisObject)->hasPopup());
    558 }
    559 
    560 static JSValueRef hierarchicalLevelCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef*)
    561 {
    562     return JSValueMakeNumber(context, toAXElement(thisObject)->hierarchicalLevel());
    563 }
    564 
    565 static JSValueRef getValueDescriptionCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    566 {
    567     JSRetainPtr<JSStringRef> valueDescription(Adopt, toAXElement(thisObject)->valueDescription());
    568     return JSValueMakeString(context, valueDescription.get());
    569 }
    570 
    571 static JSValueRef getAccessibilityValueCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    572 {
    573     JSRetainPtr<JSStringRef> accessibilityValue(Adopt, toAXElement(thisObject)->accessibilityValue());
    574     return JSValueMakeString(context, accessibilityValue.get());
    575 }
    576 
    577 static JSValueRef getDocumentEncodingCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    578 {
    579     JSRetainPtr<JSStringRef> documentEncoding(Adopt, toAXElement(thisObject)->documentEncoding());
    580     return JSValueMakeString(context, documentEncoding.get());
    581 }
    582 
    583 static JSValueRef getDocumentURICallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    584 {
    585     JSRetainPtr<JSStringRef> documentURI(Adopt, toAXElement(thisObject)->documentURI());
    586     return JSValueMakeString(context, documentURI.get());
    587 }
    588 
    589 static JSValueRef getURLCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
    590 {
    591     JSRetainPtr<JSStringRef> url(Adopt, toAXElement(thisObject)->url());
    592     return JSValueMakeString(context, url.get());
    593 }
    594 
    595 static JSValueRef addNotificationListenerCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    596 {
    597     if (argumentCount != 1)
    598         return JSValueMakeBoolean(context, false);
    599 
    600     JSObjectRef callback = JSValueToObject(context, arguments[0], exception);
    601     bool succeeded = toAXElement(thisObject)->addNotificationListener(callback);
    602     return JSValueMakeBoolean(context, succeeded);
    603 }
    604 
    605 // Destruction
    606 
    607 static void finalize(JSObjectRef thisObject)
    608 {
    609     delete toAXElement(thisObject);
    610 }
    611 
    612 // Object Creation
    613 
    614 JSObjectRef AccessibilityUIElement::makeJSAccessibilityUIElement(JSContextRef context, const AccessibilityUIElement& element)
    615 {
    616     return JSObjectMake(context, AccessibilityUIElement::getJSClass(), new AccessibilityUIElement(element));
    617 }
    618 
    619 JSClassRef AccessibilityUIElement::getJSClass()
    620 {
    621     static JSStaticValue staticValues[] = {
    622         { "accessibilityValue", getAccessibilityValueCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    623         { "role", getRoleCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    624         { "subrole", getSubroleCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    625         { "roleDescription", getRoleDescriptionCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    626         { "title", getTitleCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    627         { "description", getDescriptionCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    628         { "language", getLanguageCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    629         { "stringValue", getStringValueCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    630         { "x", getXCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    631         { "y", getYCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    632         { "width", getWidthCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    633         { "height", getHeightCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    634         { "clickPointX", getClickPointXCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    635         { "clickPointY", getClickPointYCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    636         { "intValue", getIntValueCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    637         { "minValue", getMinValueCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    638         { "maxValue", getMaxValueCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    639         { "childrenCount", getChildrenCountCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    640         { "insertionPointLineNumber", getInsertionPointLineNumberCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    641         { "selectedTextRange", getSelectedTextRangeCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    642         { "isEnabled", getIsEnabledCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    643         { "isRequired", getIsRequiredCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    644         { "isSelected", getIsSelectedCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    645         { "isSelectable", getIsSelectableCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    646         { "isMultiSelectable", getIsMultiSelectableCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    647         { "isExpanded", getIsExpandedCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    648         { "isChecked", getIsCheckedCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    649         { "isVisible", getIsVisibleCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    650         { "isOffScreen", getIsOffScreenCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    651         { "isCollapsed", getIsCollapsedCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    652         { "hasPopup", getHasPopupCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    653         { "valueDescription", getValueDescriptionCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    654         { "hierarchicalLevel", hierarchicalLevelCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    655         { "documentEncoding", getDocumentEncodingCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    656         { "documentURI", getDocumentURICallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    657         { "url", getURLCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    658         { "isValid", getIsValidCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    659         { "orientation", getOrientationCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    660         { "ariaIsGrabbed", getARIAIsGrabbedCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    661         { "ariaDropEffects", getARIADropEffectsCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    662         { 0, 0, 0, 0 }
    663     };
    664 
    665     static JSStaticFunction staticFunctions[] = {
    666         { "allAttributes", allAttributesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    667         { "attributesOfLinkedUIElements", attributesOfLinkedUIElementsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    668         { "attributesOfDocumentLinks", attributesOfDocumentLinksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    669         { "attributesOfChildren", attributesOfChildrenCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    670         { "parameterizedAttributeNames", parameterizedAttributeNamesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    671         { "lineForIndex", lineForIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    672         { "boundsForRange", boundsForRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    673         { "stringForRange", stringForRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    674         { "childAtIndex", childAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    675         { "indexOfChild", indexOfChildCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    676         { "elementAtPoint", elementAtPointCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    677         { "attributesOfColumnHeaders", attributesOfColumnHeadersCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    678         { "attributesOfRowHeaders", attributesOfRowHeadersCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    679         { "attributesOfColumns", attributesOfColumnsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    680         { "attributesOfRows", attributesOfRowsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    681         { "attributesOfVisibleCells", attributesOfVisibleCellsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    682         { "attributesOfHeader", attributesOfHeaderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    683         { "indexInTable", indexInTableCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    684         { "rowIndexRange", rowIndexRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    685         { "columnIndexRange", columnIndexRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    686         { "cellForColumnAndRow", cellForColumnAndRowCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    687         { "titleUIElement", titleUIElementCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    688         { "setSelectedTextRange", setSelectedTextRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    689         { "stringAttributeValue", stringAttributeValueCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    690         { "boolAttributeValue", boolAttributeValueCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    691         { "isAttributeSupported", isAttributeSupportedCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    692         { "isAttributeSettable", isAttributeSettableCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    693         { "isActionSupported", isActionSupportedCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    694         { "parentElement", parentElementCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    695         { "disclosedByRow", disclosedByRowCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    696         { "increment", incrementCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    697         { "decrement", decrementCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    698         { "showMenu", showMenuCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    699         { "disclosedRowAtIndex", disclosedRowAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    700         { "ariaOwnsElementAtIndex", ariaOwnsElementAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    701         { "ariaFlowToElementAtIndex", ariaFlowToElementAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    702         { "selectedRowAtIndex", selectedRowAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    703         { "isEqual", isEqualCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    704         { "addNotificationListener", addNotificationListenerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    705         { "takeFocus", takeFocusCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    706         { "takeSelection", takeSelectionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    707         { "addSelection", addSelectionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    708         { "removeSelection", removeSelectionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    709         { 0, 0, 0 }
    710     };
    711 
    712     static JSClassDefinition classDefinition = {
    713         0, kJSClassAttributeNone, "AccessibilityUIElement", 0, staticValues, staticFunctions,
    714         0, finalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
    715     };
    716 
    717     static JSClassRef accessibilityUIElementClass = JSClassCreate(&classDefinition);
    718     return accessibilityUIElementClass;
    719 }
    720