1 /* 2 * Copyright (C) 2008 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 #import "config.h" 27 #import "DumpRenderTree.h" 28 #import "AccessibilityUIElement.h" 29 30 #import <Foundation/Foundation.h> 31 #import <JavaScriptCore/JSRetainPtr.h> 32 #import <JavaScriptCore/JSStringRef.h> 33 #import <JavaScriptCore/JSStringRefCF.h> 34 #import <WebKit/WebFrame.h> 35 #import <WebKit/WebHTMLView.h> 36 #import <WebKit/WebTypesInternal.h> 37 #import <wtf/RetainPtr.h> 38 #import <wtf/Vector.h> 39 40 #ifdef BUILDING_ON_TIGER 41 #define NSAccessibilityValueDescriptionAttribute @"AXValueDescription" 42 #endif 43 44 #ifndef NSAccessibilityOwnsAttribute 45 #define NSAccessibilityOwnsAttribute @"AXOwns" 46 #endif 47 48 #ifndef NSAccessibilityGrabbedAttribute 49 #define NSAccessibilityGrabbedAttribute @"AXGrabbed" 50 #endif 51 52 #ifndef NSAccessibilityDropEffectsAttribute 53 #define NSAccessibilityDropEffectsAttribute @"AXDropEffects" 54 #endif 55 56 // If an unsupported attribute is passed in, it will raise an accessibility exception. These are usually caught by the Accessibility Runtime to inform 57 // the AX client app of the error. However, DRT is the AX client app, so it must catch these exceptions. 58 #define BEGIN_AX_OBJC_EXCEPTIONS @try { 59 #define END_AX_OBJC_EXCEPTIONS } @catch(NSException *e) { if (![[e name] isEqualToString:NSAccessibilityException]) @throw; } 60 61 62 typedef void (*AXPostedNotificationCallback)(id element, NSString* notification, void* context); 63 64 @interface NSObject (WebKitAccessibilityAdditions) 65 - (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount; 66 - (void)accessibilitySetShouldRepostNotifications:(BOOL)repost; 67 - (NSUInteger)accessibilityIndexOfChild:(id)child; 68 - (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute; 69 @end 70 71 @interface NSString (JSStringRefAdditions) 72 + (NSString *)stringWithJSStringRef:(JSStringRef)jsStringRef; 73 - (JSStringRef)createJSStringRef; 74 @end 75 76 @implementation NSString (JSStringRefAdditions) 77 78 + (NSString *)stringWithJSStringRef:(JSStringRef)jsStringRef 79 { 80 if (!jsStringRef) 81 return NULL; 82 83 CFStringRef cfString = JSStringCopyCFString(kCFAllocatorDefault, jsStringRef); 84 return [(NSString *)cfString autorelease]; 85 } 86 87 - (JSStringRef)createJSStringRef 88 { 89 return JSStringCreateWithCFString((CFStringRef)self); 90 } 91 92 @end 93 94 @interface AccessibilityNotificationHandler : NSObject 95 { 96 id m_platformElement; 97 JSObjectRef m_notificationFunctionCallback; 98 } 99 100 @end 101 102 @implementation AccessibilityNotificationHandler 103 104 - (id)initWithPlatformElement:(id)platformElement 105 { 106 self = [super init]; 107 108 m_platformElement = platformElement; 109 110 // Once an object starts requesting notifications, it's on for the duration of the program. 111 // This is to avoid any race conditions between tests turning this flag on and off. Instead 112 // AccessibilityNotificationHandler can just listen when they want to. 113 [m_platformElement accessibilitySetShouldRepostNotifications:YES]; 114 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_notificationReceived:) name:@"AXDRTNotification" object:nil]; 115 116 return self; 117 } 118 119 - (void)dealloc 120 { 121 [[NSNotificationCenter defaultCenter] removeObserver:self]; 122 JSValueUnprotect([mainFrame globalContext], m_notificationFunctionCallback); 123 m_notificationFunctionCallback = 0; 124 125 [super dealloc]; 126 } 127 128 - (void)_notificationReceived:(NSNotification *)notification 129 { 130 NSString *notificationName = [[notification userInfo] objectForKey:@"notificationName"]; 131 if (!notificationName) 132 return; 133 134 JSRetainPtr<JSStringRef> jsNotification(Adopt, [notificationName createJSStringRef]); 135 JSValueRef argument = JSValueMakeString([mainFrame globalContext], jsNotification.get()); 136 JSObjectCallAsFunction([mainFrame globalContext], m_notificationFunctionCallback, 0, 1, &argument, 0); 137 } 138 139 - (void)setCallback:(JSObjectRef)callback 140 { 141 if (!callback) 142 return; 143 144 // Release the old callback. 145 if (m_notificationFunctionCallback) 146 JSValueUnprotect([mainFrame globalContext], m_notificationFunctionCallback); 147 148 m_notificationFunctionCallback = callback; 149 JSValueProtect([mainFrame globalContext], m_notificationFunctionCallback); 150 } 151 152 @end 153 154 AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element) 155 : m_element(element) 156 , m_notificationHandler(0) 157 { 158 // FIXME: ap (at) webkit.org says ObjC objects need to be CFRetained/CFRelease to be GC-compliant on the mac. 159 [m_element retain]; 160 } 161 162 AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other) 163 : m_element(other.m_element) 164 , m_notificationHandler(0) 165 { 166 [m_element retain]; 167 } 168 169 AccessibilityUIElement::~AccessibilityUIElement() 170 { 171 // The notification handler should be nil because removeNotificationListener() should have been called in the test. 172 ASSERT(!m_notificationHandler); 173 [m_element release]; 174 } 175 176 static NSString* descriptionOfValue(id valueObject, id focusedAccessibilityObject) 177 { 178 if (!valueObject) 179 return NULL; 180 181 if ([valueObject isKindOfClass:[NSArray class]]) 182 return [NSString stringWithFormat:@"<array of size %d>", [(NSArray*)valueObject count]]; 183 184 if ([valueObject isKindOfClass:[NSNumber class]]) 185 return [(NSNumber*)valueObject stringValue]; 186 187 if ([valueObject isKindOfClass:[NSValue class]]) { 188 NSString* type = [NSString stringWithCString:[valueObject objCType] encoding:NSASCIIStringEncoding]; 189 NSValue* value = (NSValue*)valueObject; 190 if ([type rangeOfString:@"NSRect"].length > 0) 191 return [NSString stringWithFormat:@"NSRect: %@", NSStringFromRect([value rectValue])]; 192 if ([type rangeOfString:@"NSPoint"].length > 0) 193 return [NSString stringWithFormat:@"NSPoint: %@", NSStringFromPoint([value pointValue])]; 194 if ([type rangeOfString:@"NSSize"].length > 0) 195 return [NSString stringWithFormat:@"NSSize: %@", NSStringFromSize([value sizeValue])]; 196 if ([type rangeOfString:@"NSRange"].length > 0) 197 return [NSString stringWithFormat:@"NSRange: %@", NSStringFromRange([value rangeValue])]; 198 } 199 200 // Strip absolute URL paths 201 NSString* description = [valueObject description]; 202 NSRange range = [description rangeOfString:@"LayoutTests"]; 203 if (range.length) 204 return [description substringFromIndex:range.location]; 205 206 // Strip pointer locations 207 if ([description rangeOfString:@"0x"].length) { 208 NSString* role = [focusedAccessibilityObject accessibilityAttributeValue:NSAccessibilityRoleAttribute]; 209 NSString* title = [focusedAccessibilityObject accessibilityAttributeValue:NSAccessibilityTitleAttribute]; 210 if ([title length]) 211 return [NSString stringWithFormat:@"<%@: '%@'>", role, title]; 212 return [NSString stringWithFormat:@"<%@>", role]; 213 } 214 215 return [valueObject description]; 216 } 217 218 static NSString* attributesOfElement(id accessibilityObject) 219 { 220 NSArray* supportedAttributes = [accessibilityObject accessibilityAttributeNames]; 221 222 NSMutableString* attributesString = [NSMutableString string]; 223 for (NSUInteger i = 0; i < [supportedAttributes count]; ++i) { 224 NSString* attribute = [supportedAttributes objectAtIndex:i]; 225 226 // Right now, position provides useless and screen-specific information, so we do not 227 // want to include it for the sake of universally passing tests. 228 if ([attribute isEqualToString:@"AXPosition"]) 229 continue; 230 231 // accessibilityAttributeValue: can throw an if an attribute is not returned. 232 // For DumpRenderTree's purpose, we should ignore those exceptions 233 BEGIN_AX_OBJC_EXCEPTIONS 234 id valueObject = [accessibilityObject accessibilityAttributeValue:attribute]; 235 NSString* value = descriptionOfValue(valueObject, accessibilityObject); 236 [attributesString appendFormat:@"%@: %@\n", attribute, value]; 237 END_AX_OBJC_EXCEPTIONS 238 } 239 240 return attributesString; 241 } 242 243 static JSStringRef concatenateAttributeAndValue(NSString* attribute, NSString* value) 244 { 245 Vector<UniChar> buffer([attribute length]); 246 [attribute getCharacters:buffer.data()]; 247 buffer.append(':'); 248 buffer.append(' '); 249 250 Vector<UniChar> valueBuffer([value length]); 251 [value getCharacters:valueBuffer.data()]; 252 buffer.append(valueBuffer); 253 254 return JSStringCreateWithCharacters(buffer.data(), buffer.size()); 255 } 256 257 static void convertNSArrayToVector(NSArray* array, Vector<AccessibilityUIElement>& elementVector) 258 { 259 NSUInteger count = [array count]; 260 for (NSUInteger i = 0; i < count; ++i) 261 elementVector.append(AccessibilityUIElement([array objectAtIndex:i])); 262 } 263 264 static JSStringRef descriptionOfElements(Vector<AccessibilityUIElement>& elementVector) 265 { 266 NSMutableString* allElementString = [NSMutableString string]; 267 size_t size = elementVector.size(); 268 for (size_t i = 0; i < size; ++i) { 269 NSString* attributes = attributesOfElement(elementVector[i].platformUIElement()); 270 [allElementString appendFormat:@"%@\n------------\n", attributes]; 271 } 272 273 return [allElementString createJSStringRef]; 274 } 275 276 void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>& elementVector) 277 { 278 BEGIN_AX_OBJC_EXCEPTIONS 279 NSArray* linkedElements = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute]; 280 convertNSArrayToVector(linkedElements, elementVector); 281 END_AX_OBJC_EXCEPTIONS 282 } 283 284 void AccessibilityUIElement::getDocumentLinks(Vector<AccessibilityUIElement>& elementVector) 285 { 286 BEGIN_AX_OBJC_EXCEPTIONS 287 NSArray* linkElements = [m_element accessibilityAttributeValue:@"AXLinkUIElements"]; 288 convertNSArrayToVector(linkElements, elementVector); 289 END_AX_OBJC_EXCEPTIONS 290 } 291 292 void AccessibilityUIElement::getChildren(Vector<AccessibilityUIElement>& elementVector) 293 { 294 BEGIN_AX_OBJC_EXCEPTIONS 295 NSArray* children = [m_element accessibilityAttributeValue:NSAccessibilityChildrenAttribute]; 296 convertNSArrayToVector(children, elementVector); 297 END_AX_OBJC_EXCEPTIONS 298 } 299 300 void AccessibilityUIElement::getChildrenWithRange(Vector<AccessibilityUIElement>& elementVector, unsigned location, unsigned length) 301 { 302 BEGIN_AX_OBJC_EXCEPTIONS 303 NSArray* children = [m_element accessibilityArrayAttributeValues:NSAccessibilityChildrenAttribute index:location maxCount:length]; 304 convertNSArrayToVector(children, elementVector); 305 END_AX_OBJC_EXCEPTIONS 306 } 307 308 int AccessibilityUIElement::childrenCount() 309 { 310 Vector<AccessibilityUIElement> children; 311 getChildren(children); 312 313 return children.size(); 314 } 315 316 AccessibilityUIElement AccessibilityUIElement::elementAtPoint(int x, int y) 317 { 318 id element = [m_element accessibilityHitTest:NSMakePoint(x, y)]; 319 if (!element) 320 return nil; 321 322 return AccessibilityUIElement(element); 323 } 324 325 unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element) 326 { 327 return [m_element accessibilityIndexOfChild:element->platformUIElement()]; 328 } 329 330 AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index) 331 { 332 Vector<AccessibilityUIElement> children; 333 getChildrenWithRange(children, index, 1); 334 335 if (children.size() == 1) 336 return children[0]; 337 return 0; 338 } 339 340 AccessibilityUIElement AccessibilityUIElement::linkedUIElementAtIndex(unsigned index) 341 { 342 BEGIN_AX_OBJC_EXCEPTIONS 343 NSArray* objects = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute]; 344 if (index < [objects count]) 345 return [objects objectAtIndex:index]; 346 END_AX_OBJC_EXCEPTIONS 347 348 return 0; 349 } 350 351 AccessibilityUIElement AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned index) 352 { 353 BEGIN_AX_OBJC_EXCEPTIONS 354 NSArray* objects = [m_element accessibilityAttributeValue:NSAccessibilityOwnsAttribute]; 355 if (index < [objects count]) 356 return [objects objectAtIndex:index]; 357 END_AX_OBJC_EXCEPTIONS 358 359 return 0; 360 } 361 362 AccessibilityUIElement AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned index) 363 { 364 BEGIN_AX_OBJC_EXCEPTIONS 365 NSArray* objects = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute]; 366 if (index < [objects count]) 367 return [objects objectAtIndex:index]; 368 END_AX_OBJC_EXCEPTIONS 369 370 return 0; 371 } 372 373 AccessibilityUIElement AccessibilityUIElement::disclosedRowAtIndex(unsigned index) 374 { 375 BEGIN_AX_OBJC_EXCEPTIONS 376 NSArray* rows = [m_element accessibilityAttributeValue:NSAccessibilityDisclosedRowsAttribute]; 377 if (index < [rows count]) 378 return [rows objectAtIndex:index]; 379 END_AX_OBJC_EXCEPTIONS 380 381 return 0; 382 } 383 384 AccessibilityUIElement AccessibilityUIElement::selectedChildAtIndex(unsigned index) const 385 { 386 BEGIN_AX_OBJC_EXCEPTIONS 387 NSArray* array = [m_element accessibilityAttributeValue:NSAccessibilitySelectedChildrenAttribute]; 388 if (index < [array count]) 389 return [array objectAtIndex:index]; 390 END_AX_OBJC_EXCEPTIONS 391 392 return 0; 393 } 394 395 unsigned AccessibilityUIElement::selectedChildrenCount() const 396 { 397 BEGIN_AX_OBJC_EXCEPTIONS 398 return [m_element accessibilityArrayAttributeCount:NSAccessibilitySelectedChildrenAttribute]; 399 END_AX_OBJC_EXCEPTIONS 400 401 return 0; 402 } 403 404 AccessibilityUIElement AccessibilityUIElement::selectedRowAtIndex(unsigned index) 405 { 406 BEGIN_AX_OBJC_EXCEPTIONS 407 NSArray* rows = [m_element accessibilityAttributeValue:NSAccessibilitySelectedRowsAttribute]; 408 if (index < [rows count]) 409 return [rows objectAtIndex:index]; 410 END_AX_OBJC_EXCEPTIONS 411 412 return 0; 413 } 414 415 AccessibilityUIElement AccessibilityUIElement::titleUIElement() 416 { 417 BEGIN_AX_OBJC_EXCEPTIONS 418 id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityTitleUIElementAttribute]; 419 if (accessibilityObject) 420 return AccessibilityUIElement(accessibilityObject); 421 END_AX_OBJC_EXCEPTIONS 422 423 return 0; 424 } 425 426 AccessibilityUIElement AccessibilityUIElement::parentElement() 427 { 428 BEGIN_AX_OBJC_EXCEPTIONS 429 id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityParentAttribute]; 430 if (accessibilityObject) 431 return AccessibilityUIElement(accessibilityObject); 432 END_AX_OBJC_EXCEPTIONS 433 434 return 0; 435 } 436 437 AccessibilityUIElement AccessibilityUIElement::disclosedByRow() 438 { 439 BEGIN_AX_OBJC_EXCEPTIONS 440 id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityDisclosedByRowAttribute]; 441 if (accessibilityObject) 442 return AccessibilityUIElement(accessibilityObject); 443 END_AX_OBJC_EXCEPTIONS 444 445 return 0; 446 } 447 448 JSStringRef AccessibilityUIElement::attributesOfLinkedUIElements() 449 { 450 Vector<AccessibilityUIElement> linkedElements; 451 getLinkedUIElements(linkedElements); 452 return descriptionOfElements(linkedElements); 453 } 454 455 JSStringRef AccessibilityUIElement::attributesOfDocumentLinks() 456 { 457 Vector<AccessibilityUIElement> linkElements; 458 getDocumentLinks(linkElements); 459 return descriptionOfElements(linkElements); 460 } 461 462 JSStringRef AccessibilityUIElement::attributesOfChildren() 463 { 464 Vector<AccessibilityUIElement> children; 465 getChildren(children); 466 return descriptionOfElements(children); 467 } 468 469 JSStringRef AccessibilityUIElement::allAttributes() 470 { 471 NSString* attributes = attributesOfElement(m_element); 472 return [attributes createJSStringRef]; 473 } 474 475 JSStringRef AccessibilityUIElement::stringAttributeValue(JSStringRef attribute) 476 { 477 BEGIN_AX_OBJC_EXCEPTIONS 478 id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]]; 479 if ([value isKindOfClass:[NSString class]]) 480 return [value createJSStringRef]; 481 END_AX_OBJC_EXCEPTIONS 482 483 return 0; 484 } 485 486 bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute) 487 { 488 BEGIN_AX_OBJC_EXCEPTIONS 489 id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]]; 490 if ([value isKindOfClass:[NSNumber class]]) 491 return [value boolValue]; 492 END_AX_OBJC_EXCEPTIONS 493 494 return false; 495 } 496 497 bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute) 498 { 499 BEGIN_AX_OBJC_EXCEPTIONS 500 return [m_element accessibilityIsAttributeSettable:[NSString stringWithJSStringRef:attribute]]; 501 END_AX_OBJC_EXCEPTIONS 502 503 return false; 504 } 505 506 bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute) 507 { 508 BEGIN_AX_OBJC_EXCEPTIONS 509 return [[m_element accessibilityAttributeNames] containsObject:[NSString stringWithJSStringRef:attribute]]; 510 END_AX_OBJC_EXCEPTIONS 511 512 return false; 513 } 514 515 JSStringRef AccessibilityUIElement::parameterizedAttributeNames() 516 { 517 NSArray* supportedParameterizedAttributes = [m_element accessibilityParameterizedAttributeNames]; 518 519 NSMutableString* attributesString = [NSMutableString string]; 520 for (NSUInteger i = 0; i < [supportedParameterizedAttributes count]; ++i) { 521 [attributesString appendFormat:@"%@\n", [supportedParameterizedAttributes objectAtIndex:i]]; 522 } 523 524 return [attributesString createJSStringRef]; 525 } 526 527 JSStringRef AccessibilityUIElement::role() 528 { 529 BEGIN_AX_OBJC_EXCEPTIONS 530 NSString *role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityRoleAttribute], m_element); 531 return concatenateAttributeAndValue(@"AXRole", role); 532 END_AX_OBJC_EXCEPTIONS 533 534 return 0; 535 } 536 537 JSStringRef AccessibilityUIElement::subrole() 538 { 539 BEGIN_AX_OBJC_EXCEPTIONS 540 NSString* role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilitySubroleAttribute], m_element); 541 return concatenateAttributeAndValue(@"AXSubrole", role); 542 END_AX_OBJC_EXCEPTIONS 543 544 return 0; 545 } 546 547 JSStringRef AccessibilityUIElement::roleDescription() 548 { 549 BEGIN_AX_OBJC_EXCEPTIONS 550 NSString* role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityRoleDescriptionAttribute], m_element); 551 return concatenateAttributeAndValue(@"AXRoleDescription", role); 552 END_AX_OBJC_EXCEPTIONS 553 554 return 0; 555 } 556 557 JSStringRef AccessibilityUIElement::title() 558 { 559 BEGIN_AX_OBJC_EXCEPTIONS 560 NSString* title = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityTitleAttribute], m_element); 561 return concatenateAttributeAndValue(@"AXTitle", title); 562 END_AX_OBJC_EXCEPTIONS 563 564 return 0; 565 } 566 567 JSStringRef AccessibilityUIElement::description() 568 { 569 BEGIN_AX_OBJC_EXCEPTIONS 570 id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityDescriptionAttribute], m_element); 571 return concatenateAttributeAndValue(@"AXDescription", description); 572 END_AX_OBJC_EXCEPTIONS 573 574 return 0; 575 } 576 577 JSStringRef AccessibilityUIElement::orientation() const 578 { 579 BEGIN_AX_OBJC_EXCEPTIONS 580 id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityOrientationAttribute], m_element); 581 return concatenateAttributeAndValue(@"AXOrientation", description); 582 END_AX_OBJC_EXCEPTIONS 583 584 return 0; 585 } 586 587 JSStringRef AccessibilityUIElement::stringValue() 588 { 589 BEGIN_AX_OBJC_EXCEPTIONS 590 id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityValueAttribute], m_element); 591 return concatenateAttributeAndValue(@"AXValue", description); 592 END_AX_OBJC_EXCEPTIONS 593 594 return 0; 595 } 596 597 JSStringRef AccessibilityUIElement::language() 598 { 599 BEGIN_AX_OBJC_EXCEPTIONS 600 id description = descriptionOfValue([m_element accessibilityAttributeValue:@"AXLanguage"], m_element); 601 return concatenateAttributeAndValue(@"AXLanguage", description); 602 END_AX_OBJC_EXCEPTIONS 603 604 return 0; 605 } 606 607 JSStringRef AccessibilityUIElement::helpText() const 608 { 609 BEGIN_AX_OBJC_EXCEPTIONS 610 id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityHelpAttribute], m_element); 611 return concatenateAttributeAndValue(@"AXHelp", description); 612 END_AX_OBJC_EXCEPTIONS 613 614 return 0; 615 } 616 617 double AccessibilityUIElement::x() 618 { 619 BEGIN_AX_OBJC_EXCEPTIONS 620 NSValue* positionValue = [m_element accessibilityAttributeValue:NSAccessibilityPositionAttribute]; 621 return static_cast<double>([positionValue pointValue].x); 622 END_AX_OBJC_EXCEPTIONS 623 624 return 0.0f; 625 } 626 627 double AccessibilityUIElement::y() 628 { 629 BEGIN_AX_OBJC_EXCEPTIONS 630 NSValue* positionValue = [m_element accessibilityAttributeValue:NSAccessibilityPositionAttribute]; 631 return static_cast<double>([positionValue pointValue].y); 632 END_AX_OBJC_EXCEPTIONS 633 634 return 0.0f; 635 } 636 637 double AccessibilityUIElement::width() 638 { 639 BEGIN_AX_OBJC_EXCEPTIONS 640 NSValue* sizeValue = [m_element accessibilityAttributeValue:NSAccessibilitySizeAttribute]; 641 return static_cast<double>([sizeValue sizeValue].width); 642 END_AX_OBJC_EXCEPTIONS 643 644 return 0.0f; 645 } 646 647 double AccessibilityUIElement::height() 648 { 649 BEGIN_AX_OBJC_EXCEPTIONS 650 NSValue* sizeValue = [m_element accessibilityAttributeValue:NSAccessibilitySizeAttribute]; 651 return static_cast<double>([sizeValue sizeValue].height); 652 END_AX_OBJC_EXCEPTIONS 653 654 return 0.0f; 655 } 656 657 double AccessibilityUIElement::clickPointX() 658 { 659 BEGIN_AX_OBJC_EXCEPTIONS 660 NSValue* positionValue = [m_element accessibilityAttributeValue:@"AXClickPoint"]; 661 return static_cast<double>([positionValue pointValue].x); 662 END_AX_OBJC_EXCEPTIONS 663 664 return 0.0f; 665 } 666 667 double AccessibilityUIElement::clickPointY() 668 { 669 BEGIN_AX_OBJC_EXCEPTIONS 670 NSValue* positionValue = [m_element accessibilityAttributeValue:@"AXClickPoint"]; 671 return static_cast<double>([positionValue pointValue].y); 672 END_AX_OBJC_EXCEPTIONS 673 674 return 0.0f; 675 } 676 677 double AccessibilityUIElement::intValue() const 678 { 679 BEGIN_AX_OBJC_EXCEPTIONS 680 id value = [m_element accessibilityAttributeValue:NSAccessibilityValueAttribute]; 681 if ([value isKindOfClass:[NSNumber class]]) 682 return [(NSNumber*)value doubleValue]; 683 END_AX_OBJC_EXCEPTIONS 684 685 return 0.0f; 686 } 687 688 double AccessibilityUIElement::minValue() 689 { 690 BEGIN_AX_OBJC_EXCEPTIONS 691 id value = [m_element accessibilityAttributeValue:NSAccessibilityMinValueAttribute]; 692 if ([value isKindOfClass:[NSNumber class]]) 693 return [(NSNumber*)value doubleValue]; 694 END_AX_OBJC_EXCEPTIONS 695 696 return 0.0f; 697 } 698 699 double AccessibilityUIElement::maxValue() 700 { 701 BEGIN_AX_OBJC_EXCEPTIONS 702 id value = [m_element accessibilityAttributeValue:NSAccessibilityMaxValueAttribute]; 703 if ([value isKindOfClass:[NSNumber class]]) 704 return [(NSNumber*)value doubleValue]; 705 END_AX_OBJC_EXCEPTIONS 706 707 return 0.0; 708 } 709 710 JSStringRef AccessibilityUIElement::valueDescription() 711 { 712 BEGIN_AX_OBJC_EXCEPTIONS 713 NSString* valueDescription = [m_element accessibilityAttributeValue:NSAccessibilityValueDescriptionAttribute]; 714 if ([valueDescription isKindOfClass:[NSString class]]) 715 return [valueDescription createJSStringRef]; 716 717 END_AX_OBJC_EXCEPTIONS 718 return 0; 719 } 720 721 int AccessibilityUIElement::insertionPointLineNumber() 722 { 723 BEGIN_AX_OBJC_EXCEPTIONS 724 id value = [m_element accessibilityAttributeValue:NSAccessibilityInsertionPointLineNumberAttribute]; 725 if ([value isKindOfClass:[NSNumber class]]) 726 return [(NSNumber *)value intValue]; 727 END_AX_OBJC_EXCEPTIONS 728 729 return -1; 730 } 731 732 bool AccessibilityUIElement::isActionSupported(JSStringRef action) 733 { 734 BEGIN_AX_OBJC_EXCEPTIONS 735 NSArray* actions = [m_element accessibilityActionNames]; 736 return [actions containsObject:[NSString stringWithJSStringRef:action]]; 737 END_AX_OBJC_EXCEPTIONS 738 739 return false; 740 } 741 742 bool AccessibilityUIElement::isEnabled() 743 { 744 BEGIN_AX_OBJC_EXCEPTIONS 745 id value = [m_element accessibilityAttributeValue:NSAccessibilityEnabledAttribute]; 746 if ([value isKindOfClass:[NSNumber class]]) 747 return [value boolValue]; 748 END_AX_OBJC_EXCEPTIONS 749 750 return false; 751 } 752 753 bool AccessibilityUIElement::isRequired() const 754 { 755 BEGIN_AX_OBJC_EXCEPTIONS 756 id value = [m_element accessibilityAttributeValue:@"AXRequired"]; 757 if ([value isKindOfClass:[NSNumber class]]) 758 return [value boolValue]; 759 END_AX_OBJC_EXCEPTIONS 760 761 return false; 762 } 763 764 bool AccessibilityUIElement::isFocused() const 765 { 766 // FIXME: implement 767 return false; 768 } 769 770 bool AccessibilityUIElement::isSelected() const 771 { 772 BEGIN_AX_OBJC_EXCEPTIONS 773 id value = [m_element accessibilityAttributeValue:NSAccessibilitySelectedAttribute]; 774 if ([value isKindOfClass:[NSNumber class]]) 775 return [value boolValue]; 776 END_AX_OBJC_EXCEPTIONS 777 778 return false; 779 } 780 781 bool AccessibilityUIElement::isExpanded() const 782 { 783 BEGIN_AX_OBJC_EXCEPTIONS 784 id value = [m_element accessibilityAttributeValue:NSAccessibilityExpandedAttribute]; 785 if ([value isKindOfClass:[NSNumber class]]) 786 return [value boolValue]; 787 END_AX_OBJC_EXCEPTIONS 788 789 return false; 790 } 791 792 bool AccessibilityUIElement::isChecked() const 793 { 794 // On the Mac, intValue()==1 if a a checkable control is checked. 795 return intValue() == 1; 796 } 797 798 int AccessibilityUIElement::hierarchicalLevel() const 799 { 800 BEGIN_AX_OBJC_EXCEPTIONS 801 id value = [m_element accessibilityAttributeValue:NSAccessibilityDisclosureLevelAttribute]; 802 if ([value isKindOfClass:[NSNumber class]]) 803 return [value intValue]; 804 END_AX_OBJC_EXCEPTIONS 805 806 return 0; 807 } 808 809 JSStringRef AccessibilityUIElement::speak() 810 { 811 BEGIN_AX_OBJC_EXCEPTIONS 812 id value = [m_element accessibilityAttributeValue:@"AXDRTSpeechAttribute"]; 813 if ([value isKindOfClass:[NSString class]]) 814 return [value createJSStringRef]; 815 END_AX_OBJC_EXCEPTIONS 816 817 return 0; 818 } 819 820 bool AccessibilityUIElement::ariaIsGrabbed() const 821 { 822 BEGIN_AX_OBJC_EXCEPTIONS 823 id value = [m_element accessibilityAttributeValue:NSAccessibilityGrabbedAttribute]; 824 if ([value isKindOfClass:[NSNumber class]]) 825 return [value boolValue]; 826 END_AX_OBJC_EXCEPTIONS 827 828 return false; 829 } 830 831 JSStringRef AccessibilityUIElement::ariaDropEffects() const 832 { 833 BEGIN_AX_OBJC_EXCEPTIONS 834 id value = [m_element accessibilityAttributeValue:NSAccessibilityDropEffectsAttribute]; 835 if (![value isKindOfClass:[NSArray class]]) 836 return 0; 837 838 NSMutableString* dropEffects = [NSMutableString string]; 839 NSInteger length = [value count]; 840 for (NSInteger k = 0; k < length; ++k) { 841 [dropEffects appendString:[value objectAtIndex:k]]; 842 if (k < length - 1) 843 [dropEffects appendString:@","]; 844 } 845 846 return [dropEffects createJSStringRef]; 847 END_AX_OBJC_EXCEPTIONS 848 849 return 0; 850 } 851 852 // parameterized attributes 853 int AccessibilityUIElement::lineForIndex(int index) 854 { 855 BEGIN_AX_OBJC_EXCEPTIONS 856 id value = [m_element accessibilityAttributeValue:NSAccessibilityLineForIndexParameterizedAttribute forParameter:[NSNumber numberWithInt:index]]; 857 if ([value isKindOfClass:[NSNumber class]]) 858 return [(NSNumber *)value intValue]; 859 END_AX_OBJC_EXCEPTIONS 860 861 return -1; 862 } 863 864 JSStringRef AccessibilityUIElement::rangeForLine(int line) 865 { 866 BEGIN_AX_OBJC_EXCEPTIONS 867 id value = [m_element accessibilityAttributeValue:NSAccessibilityRangeForLineParameterizedAttribute forParameter:[NSNumber numberWithInt:line]]; 868 if ([value isKindOfClass:[NSValue class]]) { 869 return [NSStringFromRange([value rangeValue]) createJSStringRef]; 870 } 871 END_AX_OBJC_EXCEPTIONS 872 873 return 0; 874 } 875 876 JSStringRef AccessibilityUIElement::boundsForRange(unsigned location, unsigned length) 877 { 878 NSRange range = NSMakeRange(location, length); 879 BEGIN_AX_OBJC_EXCEPTIONS 880 id value = [m_element accessibilityAttributeValue:NSAccessibilityBoundsForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]]; 881 NSRect rect = NSMakeRect(0,0,0,0); 882 if ([value isKindOfClass:[NSValue class]]) 883 rect = [value rectValue]; 884 885 // don't return position information because it is platform dependent 886 NSMutableString* boundsDescription = [NSMutableString stringWithFormat:@"{{%f, %f}, {%f, %f}}",-1.0f,-1.0f,rect.size.width,rect.size.height]; 887 return [boundsDescription createJSStringRef]; 888 END_AX_OBJC_EXCEPTIONS 889 890 return 0; 891 } 892 893 JSStringRef AccessibilityUIElement::stringForRange(unsigned location, unsigned length) 894 { 895 NSRange range = NSMakeRange(location, length); 896 BEGIN_AX_OBJC_EXCEPTIONS 897 id string = [m_element accessibilityAttributeValue:NSAccessibilityStringForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]]; 898 if (![string isKindOfClass:[NSString class]]) 899 return 0; 900 901 return [string createJSStringRef]; 902 END_AX_OBJC_EXCEPTIONS 903 904 return 0; 905 } 906 907 JSStringRef AccessibilityUIElement::attributedStringForRange(unsigned location, unsigned length) 908 { 909 NSRange range = NSMakeRange(location, length); 910 BEGIN_AX_OBJC_EXCEPTIONS 911 NSAttributedString* string = [m_element accessibilityAttributeValue:NSAccessibilityAttributedStringForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]]; 912 if (![string isKindOfClass:[NSAttributedString class]]) 913 return 0; 914 915 NSString* stringWithAttrs = [string description]; 916 return [stringWithAttrs createJSStringRef]; 917 END_AX_OBJC_EXCEPTIONS 918 919 return 0; 920 } 921 922 bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location, unsigned length) 923 { 924 NSRange range = NSMakeRange(location, length); 925 BEGIN_AX_OBJC_EXCEPTIONS 926 NSAttributedString* string = [m_element accessibilityAttributeValue:NSAccessibilityAttributedStringForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]]; 927 if (![string isKindOfClass:[NSAttributedString class]]) 928 return false; 929 930 NSDictionary* attrs = [string attributesAtIndex:0 effectiveRange:nil]; 931 if([[attrs objectForKey:NSAccessibilityMisspelledTextAttribute] boolValue]) 932 return true; 933 END_AX_OBJC_EXCEPTIONS 934 935 return false; 936 } 937 938 JSStringRef AccessibilityUIElement::attributesOfColumnHeaders() 939 { 940 // not yet defined in AppKit... odd 941 BEGIN_AX_OBJC_EXCEPTIONS 942 NSArray* columnHeadersArray = [m_element accessibilityAttributeValue:@"AXColumnHeaderUIElements"]; 943 Vector<AccessibilityUIElement> columnHeadersVector; 944 convertNSArrayToVector(columnHeadersArray, columnHeadersVector); 945 return descriptionOfElements(columnHeadersVector); 946 END_AX_OBJC_EXCEPTIONS 947 948 return 0; 949 } 950 951 JSStringRef AccessibilityUIElement::attributesOfRowHeaders() 952 { 953 BEGIN_AX_OBJC_EXCEPTIONS 954 NSArray* rowHeadersArray = [m_element accessibilityAttributeValue:@"AXRowHeaderUIElements"]; 955 Vector<AccessibilityUIElement> rowHeadersVector; 956 convertNSArrayToVector(rowHeadersArray, rowHeadersVector); 957 return descriptionOfElements(rowHeadersVector); 958 END_AX_OBJC_EXCEPTIONS 959 960 return 0; 961 } 962 963 JSStringRef AccessibilityUIElement::attributesOfColumns() 964 { 965 BEGIN_AX_OBJC_EXCEPTIONS 966 NSArray* columnsArray = [m_element accessibilityAttributeValue:NSAccessibilityColumnsAttribute]; 967 Vector<AccessibilityUIElement> columnsVector; 968 convertNSArrayToVector(columnsArray, columnsVector); 969 return descriptionOfElements(columnsVector); 970 END_AX_OBJC_EXCEPTIONS 971 972 return 0; 973 } 974 975 JSStringRef AccessibilityUIElement::attributesOfRows() 976 { 977 BEGIN_AX_OBJC_EXCEPTIONS 978 NSArray* rowsArray = [m_element accessibilityAttributeValue:NSAccessibilityRowsAttribute]; 979 Vector<AccessibilityUIElement> rowsVector; 980 convertNSArrayToVector(rowsArray, rowsVector); 981 return descriptionOfElements(rowsVector); 982 END_AX_OBJC_EXCEPTIONS 983 984 return 0; 985 } 986 987 JSStringRef AccessibilityUIElement::attributesOfVisibleCells() 988 { 989 BEGIN_AX_OBJC_EXCEPTIONS 990 NSArray* cellsArray = [m_element accessibilityAttributeValue:@"AXVisibleCells"]; 991 Vector<AccessibilityUIElement> cellsVector; 992 convertNSArrayToVector(cellsArray, cellsVector); 993 return descriptionOfElements(cellsVector); 994 END_AX_OBJC_EXCEPTIONS 995 996 return 0; 997 } 998 999 JSStringRef AccessibilityUIElement::attributesOfHeader() 1000 { 1001 BEGIN_AX_OBJC_EXCEPTIONS 1002 id headerObject = [m_element accessibilityAttributeValue:NSAccessibilityHeaderAttribute]; 1003 if (!headerObject) 1004 return [@"" createJSStringRef]; 1005 1006 Vector<AccessibilityUIElement> headerVector; 1007 headerVector.append(headerObject); 1008 return descriptionOfElements(headerVector); 1009 END_AX_OBJC_EXCEPTIONS 1010 1011 return 0; 1012 } 1013 1014 int AccessibilityUIElement::rowCount() 1015 { 1016 BEGIN_AX_OBJC_EXCEPTIONS 1017 return [m_element accessibilityArrayAttributeCount:NSAccessibilityRowsAttribute]; 1018 END_AX_OBJC_EXCEPTIONS 1019 1020 return 0; 1021 } 1022 1023 int AccessibilityUIElement::columnCount() 1024 { 1025 BEGIN_AX_OBJC_EXCEPTIONS 1026 return [m_element accessibilityArrayAttributeCount:NSAccessibilityColumnsAttribute]; 1027 END_AX_OBJC_EXCEPTIONS 1028 1029 return 0; 1030 } 1031 1032 int AccessibilityUIElement::indexInTable() 1033 { 1034 BEGIN_AX_OBJC_EXCEPTIONS 1035 NSNumber* indexNumber = [m_element accessibilityAttributeValue:NSAccessibilityIndexAttribute]; 1036 if (indexNumber) 1037 return [indexNumber intValue]; 1038 END_AX_OBJC_EXCEPTIONS 1039 1040 return -1; 1041 } 1042 1043 JSStringRef AccessibilityUIElement::rowIndexRange() 1044 { 1045 NSRange range = NSMakeRange(0,0); 1046 BEGIN_AX_OBJC_EXCEPTIONS 1047 NSValue* indexRange = [m_element accessibilityAttributeValue:@"AXRowIndexRange"]; 1048 if (indexRange) 1049 range = [indexRange rangeValue]; 1050 NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length]; 1051 return [rangeDescription createJSStringRef]; 1052 END_AX_OBJC_EXCEPTIONS 1053 1054 return 0; 1055 } 1056 1057 JSStringRef AccessibilityUIElement::columnIndexRange() 1058 { 1059 NSRange range = NSMakeRange(0,0); 1060 BEGIN_AX_OBJC_EXCEPTIONS 1061 NSNumber* indexRange = [m_element accessibilityAttributeValue:@"AXColumnIndexRange"]; 1062 if (indexRange) 1063 range = [indexRange rangeValue]; 1064 NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length]; 1065 return [rangeDescription createJSStringRef]; 1066 END_AX_OBJC_EXCEPTIONS 1067 1068 return 0; 1069 } 1070 1071 AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned col, unsigned row) 1072 { 1073 NSArray *colRowArray = [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:col], [NSNumber numberWithUnsignedInt:row], nil]; 1074 BEGIN_AX_OBJC_EXCEPTIONS 1075 return [m_element accessibilityAttributeValue:@"AXCellForColumnAndRow" forParameter:colRowArray]; 1076 END_AX_OBJC_EXCEPTIONS 1077 1078 return 0; 1079 } 1080 1081 JSStringRef AccessibilityUIElement::selectedTextRange() 1082 { 1083 NSRange range = NSMakeRange(NSNotFound, 0); 1084 BEGIN_AX_OBJC_EXCEPTIONS 1085 NSValue *indexRange = [m_element accessibilityAttributeValue:NSAccessibilitySelectedTextRangeAttribute]; 1086 if (indexRange) 1087 range = [indexRange rangeValue]; 1088 NSMutableString *rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length]; 1089 return [rangeDescription createJSStringRef]; 1090 END_AX_OBJC_EXCEPTIONS 1091 1092 return 0; 1093 } 1094 1095 void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length) 1096 { 1097 NSRange textRange = NSMakeRange(location, length); 1098 NSValue *textRangeValue = [NSValue valueWithRange:textRange]; 1099 BEGIN_AX_OBJC_EXCEPTIONS 1100 [m_element accessibilitySetValue:textRangeValue forAttribute:NSAccessibilitySelectedTextRangeAttribute]; 1101 END_AX_OBJC_EXCEPTIONS 1102 } 1103 1104 void AccessibilityUIElement::increment() 1105 { 1106 BEGIN_AX_OBJC_EXCEPTIONS 1107 [m_element accessibilityPerformAction:NSAccessibilityIncrementAction]; 1108 END_AX_OBJC_EXCEPTIONS 1109 } 1110 1111 void AccessibilityUIElement::decrement() 1112 { 1113 BEGIN_AX_OBJC_EXCEPTIONS 1114 [m_element accessibilityPerformAction:NSAccessibilityDecrementAction]; 1115 END_AX_OBJC_EXCEPTIONS 1116 } 1117 1118 void AccessibilityUIElement::showMenu() 1119 { 1120 BEGIN_AX_OBJC_EXCEPTIONS 1121 [m_element accessibilityPerformAction:NSAccessibilityShowMenuAction]; 1122 END_AX_OBJC_EXCEPTIONS 1123 } 1124 1125 void AccessibilityUIElement::press() 1126 { 1127 BEGIN_AX_OBJC_EXCEPTIONS 1128 [m_element accessibilityPerformAction:NSAccessibilityPressAction]; 1129 END_AX_OBJC_EXCEPTIONS 1130 } 1131 1132 void AccessibilityUIElement::setSelectedChild(AccessibilityUIElement* element) const 1133 { 1134 BEGIN_AX_OBJC_EXCEPTIONS 1135 NSArray* array = [NSArray arrayWithObject:element->platformUIElement()]; 1136 [m_element accessibilitySetValue:array forAttribute:NSAccessibilitySelectedChildrenAttribute]; 1137 END_AX_OBJC_EXCEPTIONS 1138 } 1139 1140 JSStringRef AccessibilityUIElement::accessibilityValue() const 1141 { 1142 // FIXME: implement 1143 return JSStringCreateWithCharacters(0, 0); 1144 } 1145 1146 JSStringRef AccessibilityUIElement::documentEncoding() 1147 { 1148 return JSStringCreateWithCharacters(0, 0); 1149 } 1150 1151 JSStringRef AccessibilityUIElement::documentURI() 1152 { 1153 return JSStringCreateWithCharacters(0, 0); 1154 } 1155 1156 JSStringRef AccessibilityUIElement::url() 1157 { 1158 BEGIN_AX_OBJC_EXCEPTIONS 1159 NSURL *url = [m_element accessibilityAttributeValue:NSAccessibilityURLAttribute]; 1160 return [[url absoluteString] createJSStringRef]; 1161 END_AX_OBJC_EXCEPTIONS 1162 1163 return nil; 1164 } 1165 1166 bool AccessibilityUIElement::addNotificationListener(JSObjectRef functionCallback) 1167 { 1168 if (!functionCallback) 1169 return false; 1170 1171 // Mac programmers should not be adding more than one notification listener per element. 1172 // Other platforms may be different. 1173 if (m_notificationHandler) 1174 return false; 1175 m_notificationHandler = [[AccessibilityNotificationHandler alloc] initWithPlatformElement:platformUIElement()]; 1176 [m_notificationHandler setCallback:functionCallback]; 1177 1178 return true; 1179 } 1180 1181 void AccessibilityUIElement::removeNotificationListener() 1182 { 1183 // Mac programmers should not be trying to remove a listener that's already removed. 1184 ASSERT(m_notificationHandler); 1185 1186 [m_notificationHandler release]; 1187 m_notificationHandler = nil; 1188 } 1189 1190 bool AccessibilityUIElement::isFocusable() const 1191 { 1192 // FIXME: implement 1193 return false; 1194 } 1195 1196 bool AccessibilityUIElement::isSelectable() const 1197 { 1198 // FIXME: implement 1199 return false; 1200 } 1201 1202 bool AccessibilityUIElement::isMultiSelectable() const 1203 { 1204 // FIXME: implement 1205 return false; 1206 } 1207 1208 bool AccessibilityUIElement::isVisible() const 1209 { 1210 // FIXME: implement 1211 return false; 1212 } 1213 1214 bool AccessibilityUIElement::isOffScreen() const 1215 { 1216 // FIXME: implement 1217 return false; 1218 } 1219 1220 bool AccessibilityUIElement::isCollapsed() const 1221 { 1222 // FIXME: implement 1223 return false; 1224 } 1225 1226 bool AccessibilityUIElement::isIgnored() const 1227 { 1228 BOOL result = NO; 1229 BEGIN_AX_OBJC_EXCEPTIONS 1230 result = [m_element accessibilityIsIgnored]; 1231 END_AX_OBJC_EXCEPTIONS 1232 return result; 1233 } 1234 1235 bool AccessibilityUIElement::hasPopup() const 1236 { 1237 BEGIN_AX_OBJC_EXCEPTIONS 1238 id value = [m_element accessibilityAttributeValue:@"AXHasPopup"]; 1239 if ([value isKindOfClass:[NSNumber class]]) 1240 return [value boolValue]; 1241 END_AX_OBJC_EXCEPTIONS 1242 1243 return false; 1244 } 1245 1246 void AccessibilityUIElement::takeFocus() 1247 { 1248 // FIXME: implement 1249 } 1250 1251 void AccessibilityUIElement::takeSelection() 1252 { 1253 // FIXME: implement 1254 } 1255 1256 void AccessibilityUIElement::addSelection() 1257 { 1258 // FIXME: implement 1259 } 1260 1261 void AccessibilityUIElement::removeSelection() 1262 { 1263 // FIXME: implement 1264 } 1265 1266 #if SUPPORTS_AX_TEXTMARKERS 1267 1268 // Text markers 1269 AccessibilityTextMarkerRange AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement* element) 1270 { 1271 BEGIN_AX_OBJC_EXCEPTIONS 1272 id textMarkerRange = [m_element accessibilityAttributeValue:@"AXTextMarkerRangeForUIElement" forParameter:element->platformUIElement()]; 1273 return AccessibilityTextMarkerRange(textMarkerRange); 1274 END_AX_OBJC_EXCEPTIONS 1275 1276 return 0; 1277 } 1278 1279 int AccessibilityUIElement::textMarkerRangeLength(AccessibilityTextMarkerRange* range) 1280 { 1281 BEGIN_AX_OBJC_EXCEPTIONS 1282 NSNumber* lengthValue = [m_element accessibilityAttributeValue:@"AXLengthForTextMarkerRange" forParameter:(id)range->platformTextMarkerRange()]; 1283 return [lengthValue intValue]; 1284 END_AX_OBJC_EXCEPTIONS 1285 1286 return 0; 1287 } 1288 1289 1290 AccessibilityTextMarkerRange AccessibilityUIElement::textMarkerRangeForMarkers(AccessibilityTextMarker* startMarker, AccessibilityTextMarker* endMarker) 1291 { 1292 BEGIN_AX_OBJC_EXCEPTIONS 1293 NSArray* textMarkers = [NSArray arrayWithObjects:(id)startMarker->platformTextMarker(), (id)endMarker->platformTextMarker(), nil]; 1294 id textMarkerRange = [m_element accessibilityAttributeValue:@"AXTextMarkerRangeForUnorderedTextMarkers" forParameter:textMarkers]; 1295 return AccessibilityTextMarkerRange(textMarkerRange); 1296 END_AX_OBJC_EXCEPTIONS 1297 1298 return 0; 1299 } 1300 1301 AccessibilityTextMarker AccessibilityUIElement::startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range) 1302 { 1303 BEGIN_AX_OBJC_EXCEPTIONS 1304 id textMarker = [m_element accessibilityAttributeValue:@"AXStartTextMarkerForTextMarkerRange" forParameter:(id)range->platformTextMarkerRange()]; 1305 return AccessibilityTextMarker(textMarker); 1306 END_AX_OBJC_EXCEPTIONS 1307 1308 return 0; 1309 } 1310 1311 AccessibilityTextMarker AccessibilityUIElement::endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range) 1312 { 1313 BEGIN_AX_OBJC_EXCEPTIONS 1314 id textMarker = [m_element accessibilityAttributeValue:@"AXEndTextMarkerForTextMarkerRange" forParameter:(id)range->platformTextMarkerRange()]; 1315 return AccessibilityTextMarker(textMarker); 1316 END_AX_OBJC_EXCEPTIONS 1317 1318 return 0; 1319 } 1320 1321 AccessibilityTextMarker AccessibilityUIElement::textMarkerForPoint(int x, int y) 1322 { 1323 BEGIN_AX_OBJC_EXCEPTIONS 1324 id textMarker = [m_element accessibilityAttributeValue:@"AXTextMarkerForPosition" forParameter:[NSValue valueWithPoint:NSMakePoint(x, y)]]; 1325 return AccessibilityTextMarker(textMarker); 1326 END_AX_OBJC_EXCEPTIONS 1327 1328 return 0; 1329 } 1330 1331 AccessibilityUIElement AccessibilityUIElement::accessibilityElementForTextMarker(AccessibilityTextMarker* marker) 1332 { 1333 BEGIN_AX_OBJC_EXCEPTIONS 1334 id uiElement = [m_element accessibilityAttributeValue:@"AXUIElementForTextMarker" forParameter:(id)marker->platformTextMarker()]; 1335 return AccessibilityUIElement(uiElement); 1336 END_AX_OBJC_EXCEPTIONS 1337 1338 return 0; 1339 } 1340 1341 #endif // SUPPORTS_AX_TEXTMARKERS 1342