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