9e074d1497fe2221766e751cd03ab13dfe0c4816
[WebKit.git] / Tools / WebKitTestRunner / InjectedBundle / mac / AccessibilityUIElementMac.mm
1 /*
2  * Copyright (C) 2011 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 "AccessibilityCommonMac.h"
28
29 #if HAVE(ACCESSIBILITY)
30
31 #import "AccessibilityNotificationHandler.h"
32 #import "AccessibilityUIElement.h"
33 #import "InjectedBundle.h"
34 #import "InjectedBundlePage.h"
35
36 #import <AppKit/NSAccessibility.h>
37 #import <Foundation/Foundation.h>
38 #import <JavaScriptCore/JSRetainPtr.h>
39 #import <JavaScriptCore/JSStringRef.h>
40 #import <JavaScriptCore/JSStringRefCF.h>
41 #import <JavaScriptCore/JSObjectRef.h>
42 #import <WebKit/WKBundleFrame.h>
43 #import <wtf/RetainPtr.h>
44 #import <wtf/Vector.h>
45
46
47 #ifndef NSAccessibilityOwnsAttribute
48 #define NSAccessibilityOwnsAttribute @"AXOwns"
49 #endif
50
51 #ifndef NSAccessibilityGrabbedAttribute
52 #define NSAccessibilityGrabbedAttribute @"AXGrabbed"
53 #endif
54
55 #ifndef NSAccessibilityDropEffectsAttribute
56 #define NSAccessibilityDropEffectsAttribute @"AXDropEffects"
57 #endif
58
59 #ifndef NSAccessibilityPathAttribute
60 #define NSAccessibilityPathAttribute @"AXPath"
61 #endif
62
63 // Text
64 #ifndef NSAccessibilityEndTextMarkerForBoundsParameterizedAttribute
65 #define NSAccessibilityEndTextMarkerForBoundsParameterizedAttribute @"AXEndTextMarkerForBounds"
66 #endif
67
68 #ifndef NSAccessibilityStartTextMarkerForBoundsParameterizedAttribute
69 #define NSAccessibilityStartTextMarkerForBoundsParameterizedAttribute @"AXStartTextMarkerForBounds"
70 #endif
71
72 #ifndef NSAccessibilitySelectedTextMarkerRangeAttribute
73 #define NSAccessibilitySelectedTextMarkerRangeAttribute @"AXSelectedTextMarkerRange"
74 #endif
75
76 typedef void (*AXPostedNotificationCallback)(id element, NSString* notification, void* context);
77
78 @interface NSObject (WebKitAccessibilityAdditions)
79 - (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount;
80 - (NSUInteger)accessibilityIndexOfChild:(id)child;
81 - (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute;
82 - (void)_accessibilitySetTestValue:(id)value forAttribute:(NSString*)attributeName;
83 - (void)_accessibilityScrollToMakeVisibleWithSubFocus:(NSRect)rect;
84 - (void)_accessibilityScrollToGlobalPoint:(NSPoint)point;
85 - (void)_accessibilitySetValue:(id)value forAttribute:(NSString*)attributeName;
86 @end
87
88 namespace WTR {
89
90 AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
91     : m_element(element)
92     , m_notificationHandler(0)
93 {
94     // FIXME: ap@webkit.org says ObjC objects need to be CFRetained/CFRelease to be GC-compliant on the mac.
95     [m_element retain];
96 }
97
98 AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other)
99     : JSWrappable()
100     , m_element(other.m_element)
101     , m_notificationHandler(0)
102 {
103     [m_element retain];
104 }
105
106 AccessibilityUIElement::~AccessibilityUIElement()
107 {
108     // The notification handler should be nil because removeNotificationListener() should have been called in the test.
109     ASSERT(!m_notificationHandler);
110     [m_element release];
111 }
112
113 bool AccessibilityUIElement::isEqual(AccessibilityUIElement* otherElement)
114 {
115     if (!otherElement)
116         return false;
117     return platformUIElement() == otherElement->platformUIElement();
118 }
119     
120 static NSString* descriptionOfValue(id valueObject, id focusedAccessibilityObject)
121 {
122     if (!valueObject)
123         return NULL;
124
125     if ([valueObject isKindOfClass:[NSArray class]])
126         return [NSString stringWithFormat:@"<array of size %lu>", static_cast<unsigned long>([(NSArray*)valueObject count])];
127
128     if ([valueObject isKindOfClass:[NSNumber class]])
129         return [(NSNumber*)valueObject stringValue];
130
131     if ([valueObject isKindOfClass:[NSValue class]]) {
132         NSString* type = [NSString stringWithCString:[valueObject objCType] encoding:NSASCIIStringEncoding];
133         NSValue* value = (NSValue*)valueObject;
134         if ([type rangeOfString:@"NSRect"].length > 0)
135             return [NSString stringWithFormat:@"NSRect: %@", NSStringFromRect([value rectValue])];
136         if ([type rangeOfString:@"NSPoint"].length > 0)
137             return [NSString stringWithFormat:@"NSPoint: %@", NSStringFromPoint([value pointValue])];
138         if ([type rangeOfString:@"NSSize"].length > 0)
139             return [NSString stringWithFormat:@"NSSize: %@", NSStringFromSize([value sizeValue])];
140         if ([type rangeOfString:@"NSRange"].length > 0)
141             return [NSString stringWithFormat:@"NSRange: %@", NSStringFromRange([value rangeValue])];
142     }
143
144     // Strip absolute URL paths
145     NSString* description = [valueObject description];
146     NSRange range = [description rangeOfString:@"LayoutTests"];
147     if (range.length)
148         return [description substringFromIndex:range.location];
149
150     // Strip pointer locations
151     if ([description rangeOfString:@"0x"].length) {
152         NSString* role = [focusedAccessibilityObject accessibilityAttributeValue:NSAccessibilityRoleAttribute];
153         NSString* title = [focusedAccessibilityObject accessibilityAttributeValue:NSAccessibilityTitleAttribute];
154         if ([title length])
155             return [NSString stringWithFormat:@"<%@: '%@'>", role, title];
156         return [NSString stringWithFormat:@"<%@>", role];
157     }
158     
159     return [valueObject description];
160 }
161
162 static NSString* attributesOfElement(id accessibilityObject)
163 {
164     NSArray* supportedAttributes = [accessibilityObject accessibilityAttributeNames];
165
166     NSMutableString* attributesString = [NSMutableString string];
167     for (NSUInteger i = 0; i < [supportedAttributes count]; ++i) {
168         NSString* attribute = [supportedAttributes objectAtIndex:i];
169         
170         // Right now, position provides useless and screen-specific information, so we do not
171         // want to include it for the sake of universally passing tests.
172         if ([attribute isEqualToString:@"AXPosition"])
173             continue;
174         
175         // Skip screen-specific information.
176         if ([attribute isEqualToString:@"_AXPrimaryScreenHeight"])
177             continue;
178         
179         // accessibilityAttributeValue: can throw an if an attribute is not returned.
180         // For DumpRenderTree's purpose, we should ignore those exceptions
181         BEGIN_AX_OBJC_EXCEPTIONS
182         id valueObject = [accessibilityObject accessibilityAttributeValue:attribute];
183         NSString* value = descriptionOfValue(valueObject, accessibilityObject);
184         [attributesString appendFormat:@"%@: %@\n", attribute, value];
185         END_AX_OBJC_EXCEPTIONS
186     }
187     
188     return attributesString;
189 }
190
191 static JSValueRef convertElementsToObjectArray(JSContextRef context, Vector<RefPtr<AccessibilityUIElement>>& elements)
192 {
193     JSValueRef arrayResult = JSObjectMakeArray(context, 0, 0, 0);
194     JSObjectRef arrayObj = JSValueToObject(context, arrayResult, 0);
195     size_t elementCount = elements.size();
196     for (size_t i = 0; i < elementCount; ++i)
197         JSObjectSetPropertyAtIndex(context, arrayObj, i, JSObjectMake(context, elements[i]->wrapperClass(), elements[i].get()), 0);
198     
199     return arrayResult;
200 }
201
202 static JSStringRef concatenateAttributeAndValue(NSString* attribute, NSString* value)
203 {
204     Vector<UniChar> buffer([attribute length]);
205     [attribute getCharacters:buffer.data()];
206     buffer.append(':');
207     buffer.append(' ');
208
209     Vector<UniChar> valueBuffer([value length]);
210     [value getCharacters:valueBuffer.data()];
211     buffer.appendVector(valueBuffer);
212
213     return JSStringCreateWithCharacters(buffer.data(), buffer.size());
214 }
215
216 static void convertNSArrayToVector(NSArray* array, Vector<RefPtr<AccessibilityUIElement> >& elementVector)
217 {
218     NSUInteger count = [array count];
219     for (NSUInteger i = 0; i < count; ++i)
220         elementVector.append(AccessibilityUIElement::create([array objectAtIndex:i]));
221 }
222
223 static JSStringRef descriptionOfElements(Vector<RefPtr<AccessibilityUIElement> >& elementVector)
224 {
225     NSMutableString* allElementString = [NSMutableString string];
226     size_t size = elementVector.size();
227     for (size_t i = 0; i < size; ++i) {
228         RefPtr<AccessibilityUIElement> uiElement = elementVector[i];
229         NSString* attributes = attributesOfElement(uiElement->platformUIElement());
230         [allElementString appendFormat:@"%@\n------------\n", attributes];
231     }
232     
233     return [allElementString createJSStringRef];
234 }
235
236 static NSDictionary *selectTextParameterizedAttributeForCriteria(JSContextRef context, JSStringRef ambiguityResolution, JSValueRef searchStrings, JSStringRef replacementString, JSStringRef activity)
237 {
238     NSMutableDictionary *parameterizedAttribute = [NSMutableDictionary dictionary];
239     
240     if (ambiguityResolution)
241         [parameterizedAttribute setObject:[NSString stringWithJSStringRef:ambiguityResolution] forKey:@"AXSelectTextAmbiguityResolution"];
242     
243     if (searchStrings) {
244         NSMutableArray *searchStringsParameter = [NSMutableArray array];
245         if (JSValueIsString(context, searchStrings)) {
246             JSRetainPtr<JSStringRef> searchStringsString(Adopt, JSValueToStringCopy(context, searchStrings, nullptr));
247             if (searchStringsString)
248                 [searchStringsParameter addObject:[NSString stringWithJSStringRef:searchStringsString.get()]];
249         }
250         else if (JSValueIsObject(context, searchStrings)) {
251             JSObjectRef searchStringsArray = JSValueToObject(context, searchStrings, nullptr);
252             unsigned searchStringsArrayLength = 0;
253             
254             JSRetainPtr<JSStringRef> lengthPropertyString(Adopt, JSStringCreateWithUTF8CString("length"));
255             JSValueRef searchStringsArrayLengthValue = JSObjectGetProperty(context, searchStringsArray, lengthPropertyString.get(), nullptr);
256             if (searchStringsArrayLengthValue && JSValueIsNumber(context, searchStringsArrayLengthValue))
257                 searchStringsArrayLength = static_cast<unsigned>(JSValueToNumber(context, searchStringsArrayLengthValue, nullptr));
258             
259             for (unsigned i = 0; i < searchStringsArrayLength; ++i) {
260                 JSRetainPtr<JSStringRef> searchStringsString(Adopt, JSValueToStringCopy(context, JSObjectGetPropertyAtIndex(context, searchStringsArray, i, nullptr), nullptr));
261                 if (searchStringsString)
262                     [searchStringsParameter addObject:[NSString stringWithJSStringRef:searchStringsString.get()]];
263             }
264         }
265         [parameterizedAttribute setObject:searchStringsParameter forKey:@"AXSelectTextSearchStrings"];
266     }
267     
268     if (replacementString) {
269         [parameterizedAttribute setObject:@"AXSelectTextActivityFindAndReplace" forKey:@"AXSelectTextActivity"];
270         [parameterizedAttribute setObject:[NSString stringWithJSStringRef:replacementString] forKey:@"AXSelectTextReplacementString"];
271     } else
272         [parameterizedAttribute setObject:@"AXSelectTextActivityFindAndSelect" forKey:@"AXSelectTextActivity"];
273     
274     if (activity)
275         [parameterizedAttribute setObject:[NSString stringWithJSStringRef:activity] forKey:@"AXSelectTextActivity"];
276     
277     return parameterizedAttribute;
278 }
279
280 void AccessibilityUIElement::getLinkedUIElements(Vector<RefPtr<AccessibilityUIElement> >& elementVector)
281 {
282     BEGIN_AX_OBJC_EXCEPTIONS
283     NSArray* linkedElements = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute];
284     convertNSArrayToVector(linkedElements, elementVector);
285     END_AX_OBJC_EXCEPTIONS
286 }
287
288 void AccessibilityUIElement::getDocumentLinks(Vector<RefPtr<AccessibilityUIElement> >& elementVector)
289 {
290     BEGIN_AX_OBJC_EXCEPTIONS
291     NSArray* linkElements = [m_element accessibilityAttributeValue:@"AXLinkUIElements"];
292     convertNSArrayToVector(linkElements, elementVector);
293     END_AX_OBJC_EXCEPTIONS
294 }
295
296 void AccessibilityUIElement::getUIElementsWithAttribute(JSStringRef attribute, Vector<RefPtr<AccessibilityUIElement> >& elements) const
297 {
298     BEGIN_AX_OBJC_EXCEPTIONS
299     id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]];
300     if ([value isKindOfClass:[NSArray class]])
301         convertNSArrayToVector(value, elements);
302     END_AX_OBJC_EXCEPTIONS
303 }
304
305 void AccessibilityUIElement::getChildren(Vector<RefPtr<AccessibilityUIElement> >& elementVector)
306 {
307     BEGIN_AX_OBJC_EXCEPTIONS
308     NSArray* children = [m_element accessibilityAttributeValue:NSAccessibilityChildrenAttribute];
309     convertNSArrayToVector(children, elementVector);
310     END_AX_OBJC_EXCEPTIONS
311 }
312
313 void AccessibilityUIElement::getChildrenWithRange(Vector<RefPtr<AccessibilityUIElement> >& elementVector, unsigned location, unsigned length)
314 {
315     BEGIN_AX_OBJC_EXCEPTIONS
316     NSArray* children = [m_element accessibilityArrayAttributeValues:NSAccessibilityChildrenAttribute index:location maxCount:length];
317     convertNSArrayToVector(children, elementVector);
318     END_AX_OBJC_EXCEPTIONS
319 }
320
321 JSValueRef AccessibilityUIElement::rowHeaders() const
322 {
323     WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
324     JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
325     
326     BEGIN_AX_OBJC_EXCEPTIONS
327     Vector<RefPtr<AccessibilityUIElement>> elements;
328     id value = [m_element accessibilityAttributeValue:NSAccessibilityRowHeaderUIElementsAttribute];
329     if ([value isKindOfClass:[NSArray class]])
330         convertNSArrayToVector(value, elements);
331     return convertElementsToObjectArray(context, elements);
332     END_AX_OBJC_EXCEPTIONS
333 }
334
335 JSValueRef AccessibilityUIElement::columnHeaders() const
336 {
337     WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
338     JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
339
340     BEGIN_AX_OBJC_EXCEPTIONS
341     Vector<RefPtr<AccessibilityUIElement>> elements;
342     id value = [m_element accessibilityAttributeValue:NSAccessibilityColumnHeaderUIElementsAttribute];
343     if ([value isKindOfClass:[NSArray class]])
344         convertNSArrayToVector(value, elements);
345     return convertElementsToObjectArray(context, elements);
346     END_AX_OBJC_EXCEPTIONS
347 }
348     
349 int AccessibilityUIElement::childrenCount()
350 {
351     Vector<RefPtr<AccessibilityUIElement> > children;
352     getChildren(children);
353     
354     return children.size();
355 }
356
357 RefPtr<AccessibilityUIElement> AccessibilityUIElement::elementAtPoint(int x, int y)
358 {
359     id element = [m_element accessibilityHitTest:NSMakePoint(x, y)];
360     if (!element)
361         return nullptr;
362     
363     return AccessibilityUIElement::create(element);
364 }
365
366 unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element)
367 {
368     return [m_element accessibilityIndexOfChild:element->platformUIElement()];
369 }
370
371 RefPtr<AccessibilityUIElement> AccessibilityUIElement::childAtIndex(unsigned index)
372 {
373     Vector<RefPtr<AccessibilityUIElement>> children;
374     getChildrenWithRange(children, index, 1);
375
376     if (children.size() == 1)
377         return children[0];
378     return nullptr;
379 }
380
381 RefPtr<AccessibilityUIElement> AccessibilityUIElement::linkedUIElementAtIndex(unsigned index)
382 {
383     BEGIN_AX_OBJC_EXCEPTIONS
384     NSArray* objects = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute];
385     if (index < [objects count])
386         return AccessibilityUIElement::create([objects objectAtIndex:index]);
387     END_AX_OBJC_EXCEPTIONS
388     
389     return nullptr;
390 }
391
392 RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned index)
393 {
394     BEGIN_AX_OBJC_EXCEPTIONS
395     NSArray* objects = [m_element accessibilityAttributeValue:NSAccessibilityOwnsAttribute];
396     if (index < [objects count])
397         return AccessibilityUIElement::create([objects objectAtIndex:index]);
398     END_AX_OBJC_EXCEPTIONS
399     
400     return nullptr;
401 }
402
403 RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned index)
404 {
405     BEGIN_AX_OBJC_EXCEPTIONS
406     NSArray* objects = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute];
407     if (index < [objects count])
408         return AccessibilityUIElement::create([objects objectAtIndex:index]);
409     END_AX_OBJC_EXCEPTIONS
410     
411     return nullptr;
412 }
413
414 RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaControlsElementAtIndex(unsigned index)
415 {
416     BEGIN_AX_OBJC_EXCEPTIONS
417     NSArray* ariaControls = [m_element accessibilityAttributeValue:@"AXARIAControls"];
418     if (index < [ariaControls count])
419         return AccessibilityUIElement::create([ariaControls objectAtIndex:index]);
420     END_AX_OBJC_EXCEPTIONS
421     return nullptr;
422 }
423
424 RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaDetailsElementAtIndex(unsigned index)
425 {
426     BEGIN_AX_OBJC_EXCEPTIONS
427     NSArray* details = [m_element accessibilityAttributeValue:@"AXDetailsElements"];
428     if (index < [details count])
429         return AccessibilityUIElement::create([details objectAtIndex:index]);
430     END_AX_OBJC_EXCEPTIONS
431     return nullptr;
432 }
433
434 RefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaErrorMessageElementAtIndex(unsigned index)
435 {
436     BEGIN_AX_OBJC_EXCEPTIONS
437     NSArray* errorMessages = [m_element accessibilityAttributeValue:@"AXErrorMessageElements"];
438     if (index < [errorMessages count])
439         return AccessibilityUIElement::create([errorMessages objectAtIndex:index]);
440     END_AX_OBJC_EXCEPTIONS
441     return nullptr;
442 }
443
444 RefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedRowAtIndex(unsigned index)
445 {
446     BEGIN_AX_OBJC_EXCEPTIONS
447     NSArray* rows = [m_element accessibilityAttributeValue:NSAccessibilityDisclosedRowsAttribute];
448     if (index < [rows count])
449         return AccessibilityUIElement::create([rows objectAtIndex:index]);
450     END_AX_OBJC_EXCEPTIONS
451
452     return nullptr;
453 }
454     
455 RefPtr<AccessibilityUIElement> AccessibilityUIElement::rowAtIndex(unsigned index)
456 {
457     BEGIN_AX_OBJC_EXCEPTIONS
458     NSArray* rows = [m_element accessibilityAttributeValue:NSAccessibilityRowsAttribute];
459     if (index < [rows count])
460         return AccessibilityUIElement::create([rows objectAtIndex:index]);
461     END_AX_OBJC_EXCEPTIONS
462     
463     return nullptr;
464 }
465
466 RefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedChildAtIndex(unsigned index) const
467 {
468     BEGIN_AX_OBJC_EXCEPTIONS
469     NSArray* array = [m_element accessibilityAttributeValue:NSAccessibilitySelectedChildrenAttribute];
470     if (index < [array count])
471         return AccessibilityUIElement::create([array objectAtIndex:index]);
472     END_AX_OBJC_EXCEPTIONS
473     
474     return nullptr;
475 }
476
477 unsigned AccessibilityUIElement::selectedChildrenCount() const
478 {
479     BEGIN_AX_OBJC_EXCEPTIONS
480     return [m_element accessibilityArrayAttributeCount:NSAccessibilitySelectedChildrenAttribute];
481     END_AX_OBJC_EXCEPTIONS
482
483     return 0;
484 }
485
486 RefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedRowAtIndex(unsigned index)
487 {
488     BEGIN_AX_OBJC_EXCEPTIONS
489     NSArray* rows = [m_element accessibilityAttributeValue:NSAccessibilitySelectedRowsAttribute];
490     if (index < [rows count])
491         return AccessibilityUIElement::create([rows objectAtIndex:index]);
492     END_AX_OBJC_EXCEPTIONS
493     
494     return nullptr;
495 }
496
497 RefPtr<AccessibilityUIElement> AccessibilityUIElement::titleUIElement()
498 {
499     BEGIN_AX_OBJC_EXCEPTIONS
500     id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityTitleUIElementAttribute];
501     if (accessibilityObject)
502         return AccessibilityUIElement::create(accessibilityObject);
503     END_AX_OBJC_EXCEPTIONS
504     
505     return nullptr;
506 }
507
508 RefPtr<AccessibilityUIElement> AccessibilityUIElement::parentElement()
509 {
510     BEGIN_AX_OBJC_EXCEPTIONS
511     id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityParentAttribute];
512     if (accessibilityObject)
513         return AccessibilityUIElement::create(accessibilityObject);
514     END_AX_OBJC_EXCEPTIONS
515     
516     return nullptr;
517 }
518
519 RefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedByRow()
520 {
521     BEGIN_AX_OBJC_EXCEPTIONS
522     id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityDisclosedByRowAttribute];
523     if (accessibilityObject)
524         return AccessibilityUIElement::create(accessibilityObject);
525     END_AX_OBJC_EXCEPTIONS
526     
527     return nullptr;
528 }
529
530 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfLinkedUIElements()
531 {
532     Vector<RefPtr<AccessibilityUIElement> > linkedElements;
533     getLinkedUIElements(linkedElements);
534     return descriptionOfElements(linkedElements);
535 }
536
537 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfDocumentLinks()
538 {
539     Vector<RefPtr<AccessibilityUIElement> > linkElements;
540     getDocumentLinks(linkElements);
541     return descriptionOfElements(linkElements);
542 }
543
544 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfChildren()
545 {
546     Vector<RefPtr<AccessibilityUIElement> > children;
547     getChildren(children);
548     return descriptionOfElements(children);
549 }
550
551 JSRetainPtr<JSStringRef> AccessibilityUIElement::allAttributes()
552 {
553     NSString* attributes = attributesOfElement(m_element);
554     return [attributes createJSStringRef];
555 }
556
557 JSRetainPtr<JSStringRef> AccessibilityUIElement::stringAttributeValue(JSStringRef attribute)
558 {
559     BEGIN_AX_OBJC_EXCEPTIONS
560     id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]];
561     if ([value isKindOfClass:[NSString class]])
562         return [value createJSStringRef];
563     END_AX_OBJC_EXCEPTIONS
564
565     return nullptr;
566 }
567
568 double AccessibilityUIElement::numberAttributeValue(JSStringRef attribute)
569 {
570     BEGIN_AX_OBJC_EXCEPTIONS
571     id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]];
572     if ([value isKindOfClass:[NSNumber class]])
573         return [value doubleValue];
574     END_AX_OBJC_EXCEPTIONS
575     
576     return 0;
577 }
578
579 JSValueRef AccessibilityUIElement::uiElementArrayAttributeValue(JSStringRef attribute) const
580 {
581     WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
582     JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
583     
584     Vector<RefPtr<AccessibilityUIElement>> elements;
585     getUIElementsWithAttribute(attribute, elements);
586     return convertElementsToObjectArray(context, elements);
587 }
588
589 RefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementAttributeValue(JSStringRef attribute) const
590 {
591     BEGIN_AX_OBJC_EXCEPTIONS
592     id uiElement = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]];
593     return AccessibilityUIElement::create(uiElement);
594     END_AX_OBJC_EXCEPTIONS
595     
596     return nullptr;
597 }
598     
599 bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute)
600 {
601     BEGIN_AX_OBJC_EXCEPTIONS
602     id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]];
603     if ([value isKindOfClass:[NSNumber class]])
604         return [value boolValue];
605     END_AX_OBJC_EXCEPTIONS
606     
607     return false;
608 }
609
610 void AccessibilityUIElement::setBoolAttributeValue(JSStringRef attribute, bool value)
611 {
612     BEGIN_AX_OBJC_EXCEPTIONS
613     [m_element _accessibilitySetTestValue:@(value) forAttribute:[NSString stringWithJSStringRef:attribute]];
614     END_AX_OBJC_EXCEPTIONS
615 }
616     
617 void AccessibilityUIElement::setValue(JSStringRef value)
618 {
619     BEGIN_AX_OBJC_EXCEPTIONS
620     [m_element accessibilitySetValue:[NSString stringWithJSStringRef:value] forAttribute:NSAccessibilityValueAttribute];
621     END_AX_OBJC_EXCEPTIONS
622 }
623     
624 bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute)
625 {
626     BEGIN_AX_OBJC_EXCEPTIONS
627     return [m_element accessibilityIsAttributeSettable:[NSString stringWithJSStringRef:attribute]];
628     END_AX_OBJC_EXCEPTIONS
629     
630     return false;
631 }
632
633 bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute)
634 {
635     BEGIN_AX_OBJC_EXCEPTIONS
636     return [[m_element accessibilityAttributeNames] containsObject:[NSString stringWithJSStringRef:attribute]];
637     END_AX_OBJC_EXCEPTIONS
638     
639     return false;
640 }
641
642 JSRetainPtr<JSStringRef> AccessibilityUIElement::parameterizedAttributeNames()
643 {
644     NSArray* supportedParameterizedAttributes = [m_element accessibilityParameterizedAttributeNames];
645     
646     NSMutableString* attributesString = [NSMutableString string];
647     for (NSUInteger i = 0; i < [supportedParameterizedAttributes count]; ++i) {
648         [attributesString appendFormat:@"%@\n", [supportedParameterizedAttributes objectAtIndex:i]];
649     }
650     
651     return [attributesString createJSStringRef];
652 }
653
654 JSRetainPtr<JSStringRef> AccessibilityUIElement::role()
655 {
656     BEGIN_AX_OBJC_EXCEPTIONS
657     NSString *role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityRoleAttribute], m_element);
658     return concatenateAttributeAndValue(@"AXRole", role);
659     END_AX_OBJC_EXCEPTIONS
660     
661     return nullptr;
662 }
663
664 JSRetainPtr<JSStringRef> AccessibilityUIElement::subrole()
665 {
666     BEGIN_AX_OBJC_EXCEPTIONS
667     NSString* role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilitySubroleAttribute], m_element);
668     return concatenateAttributeAndValue(@"AXSubrole", role);
669     END_AX_OBJC_EXCEPTIONS
670
671     return nullptr;
672 }
673
674 JSRetainPtr<JSStringRef> AccessibilityUIElement::roleDescription()
675 {
676     BEGIN_AX_OBJC_EXCEPTIONS
677     NSString* role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityRoleDescriptionAttribute], m_element);
678     return concatenateAttributeAndValue(@"AXRoleDescription", role);
679     END_AX_OBJC_EXCEPTIONS
680     
681     return nullptr;
682 }
683
684 JSRetainPtr<JSStringRef> AccessibilityUIElement::computedRoleString()
685 {
686     BEGIN_AX_OBJC_EXCEPTIONS
687     NSString *computedRoleString = descriptionOfValue([m_element accessibilityAttributeValue:@"AXARIARole"], m_element);
688     return [computedRoleString createJSStringRef];
689     END_AX_OBJC_EXCEPTIONS
690     
691     return nullptr;
692 }
693
694 JSRetainPtr<JSStringRef> AccessibilityUIElement::title()
695 {
696     BEGIN_AX_OBJC_EXCEPTIONS
697     NSString* title = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityTitleAttribute], m_element);
698     return concatenateAttributeAndValue(@"AXTitle", title);
699     END_AX_OBJC_EXCEPTIONS
700
701     return nullptr;
702 }
703
704 JSRetainPtr<JSStringRef> AccessibilityUIElement::description()
705 {
706     BEGIN_AX_OBJC_EXCEPTIONS
707     id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityDescriptionAttribute], m_element);
708     return concatenateAttributeAndValue(@"AXDescription", description);
709     END_AX_OBJC_EXCEPTIONS
710
711     return nullptr;
712 }
713
714 JSRetainPtr<JSStringRef> AccessibilityUIElement::orientation() const
715 {
716     BEGIN_AX_OBJC_EXCEPTIONS
717     id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityOrientationAttribute], m_element);
718     return concatenateAttributeAndValue(@"AXOrientation", description);    
719     END_AX_OBJC_EXCEPTIONS
720
721     return nullptr;
722 }
723
724 JSRetainPtr<JSStringRef> AccessibilityUIElement::stringValue()
725 {
726     BEGIN_AX_OBJC_EXCEPTIONS
727     id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityValueAttribute], m_element);
728     if (description)
729         return concatenateAttributeAndValue(@"AXValue", description);
730     END_AX_OBJC_EXCEPTIONS
731
732     return nullptr;
733 }
734
735 JSRetainPtr<JSStringRef> AccessibilityUIElement::language()
736 {
737     BEGIN_AX_OBJC_EXCEPTIONS
738     id description = descriptionOfValue([m_element accessibilityAttributeValue:@"AXLanguage"], m_element);
739     return concatenateAttributeAndValue(@"AXLanguage", description);
740     END_AX_OBJC_EXCEPTIONS
741
742     return nullptr;
743 }
744
745 JSRetainPtr<JSStringRef> AccessibilityUIElement::helpText() const
746 {
747     BEGIN_AX_OBJC_EXCEPTIONS
748     id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityHelpAttribute], m_element);
749     return concatenateAttributeAndValue(@"AXHelp", description);
750     END_AX_OBJC_EXCEPTIONS
751     
752     return nullptr;
753 }
754
755 double AccessibilityUIElement::x()
756 {
757     BEGIN_AX_OBJC_EXCEPTIONS
758     NSValue* positionValue = [m_element accessibilityAttributeValue:NSAccessibilityPositionAttribute];
759     return static_cast<double>([positionValue pointValue].x);    
760     END_AX_OBJC_EXCEPTIONS
761     
762     return 0.0f;
763 }
764
765 double AccessibilityUIElement::y()
766 {
767     BEGIN_AX_OBJC_EXCEPTIONS
768     NSValue* positionValue = [m_element accessibilityAttributeValue:NSAccessibilityPositionAttribute];
769     return static_cast<double>([positionValue pointValue].y);    
770     END_AX_OBJC_EXCEPTIONS
771     
772     return 0.0f;
773 }
774
775 double AccessibilityUIElement::width()
776 {
777     BEGIN_AX_OBJC_EXCEPTIONS
778     NSValue* sizeValue = [m_element accessibilityAttributeValue:NSAccessibilitySizeAttribute];
779     return static_cast<double>([sizeValue sizeValue].width);
780     END_AX_OBJC_EXCEPTIONS
781     
782     return 0.0f;
783 }
784
785 double AccessibilityUIElement::height()
786 {
787     BEGIN_AX_OBJC_EXCEPTIONS
788     NSValue* sizeValue = [m_element accessibilityAttributeValue:NSAccessibilitySizeAttribute];
789     return static_cast<double>([sizeValue sizeValue].height);
790     END_AX_OBJC_EXCEPTIONS
791     
792     return 0.0f;
793 }
794
795 double AccessibilityUIElement::clickPointX()
796 {
797     BEGIN_AX_OBJC_EXCEPTIONS
798     NSValue* positionValue = [m_element accessibilityAttributeValue:@"AXClickPoint"];
799     return static_cast<double>([positionValue pointValue].x);        
800     END_AX_OBJC_EXCEPTIONS
801     
802     return 0.0f;
803 }
804
805 double AccessibilityUIElement::clickPointY()
806 {
807     BEGIN_AX_OBJC_EXCEPTIONS
808     NSValue* positionValue = [m_element accessibilityAttributeValue:@"AXClickPoint"];
809     return static_cast<double>([positionValue pointValue].y);
810     END_AX_OBJC_EXCEPTIONS
811     
812     return 0.0f;
813 }
814
815 double AccessibilityUIElement::intValue() const
816 {
817     BEGIN_AX_OBJC_EXCEPTIONS
818     id value = [m_element accessibilityAttributeValue:NSAccessibilityValueAttribute];
819     if ([value isKindOfClass:[NSNumber class]])
820         return [(NSNumber*)value doubleValue]; 
821     END_AX_OBJC_EXCEPTIONS
822
823     return 0.0f;
824 }
825
826 double AccessibilityUIElement::minValue()
827 {
828     BEGIN_AX_OBJC_EXCEPTIONS
829     id value = [m_element accessibilityAttributeValue:NSAccessibilityMinValueAttribute];
830     if ([value isKindOfClass:[NSNumber class]])
831         return [(NSNumber*)value doubleValue]; 
832     END_AX_OBJC_EXCEPTIONS
833
834     return 0.0f;
835 }
836
837 double AccessibilityUIElement::maxValue()
838 {
839     BEGIN_AX_OBJC_EXCEPTIONS
840     id value = [m_element accessibilityAttributeValue:NSAccessibilityMaxValueAttribute];
841     if ([value isKindOfClass:[NSNumber class]])
842         return [(NSNumber*)value doubleValue]; 
843     END_AX_OBJC_EXCEPTIONS
844
845     return 0.0;
846 }
847
848 JSRetainPtr<JSStringRef> AccessibilityUIElement::valueDescription()
849 {
850     BEGIN_AX_OBJC_EXCEPTIONS
851     NSString* valueDescription = [m_element accessibilityAttributeValue:NSAccessibilityValueDescriptionAttribute];
852     if ([valueDescription isKindOfClass:[NSString class]])
853         return concatenateAttributeAndValue(@"AXValueDescription", valueDescription);
854     END_AX_OBJC_EXCEPTIONS
855     
856     return nullptr;
857 }
858
859 int AccessibilityUIElement::insertionPointLineNumber()
860 {
861     BEGIN_AX_OBJC_EXCEPTIONS
862     id value = [m_element accessibilityAttributeValue:NSAccessibilityInsertionPointLineNumberAttribute];
863     if ([value isKindOfClass:[NSNumber class]])
864         return [(NSNumber *)value intValue]; 
865     END_AX_OBJC_EXCEPTIONS
866     
867     return -1;
868 }
869
870 bool AccessibilityUIElement::isPressActionSupported()
871 {
872     BEGIN_AX_OBJC_EXCEPTIONS
873     NSArray* actions = [m_element accessibilityActionNames];
874     return [actions containsObject:NSAccessibilityPressAction];
875     END_AX_OBJC_EXCEPTIONS
876     
877     return false;
878 }
879
880 bool AccessibilityUIElement::isIncrementActionSupported()
881 {
882     BEGIN_AX_OBJC_EXCEPTIONS
883     NSArray* actions = [m_element accessibilityActionNames];
884     return [actions containsObject:NSAccessibilityIncrementAction];
885     END_AX_OBJC_EXCEPTIONS
886     
887     return false;
888 }
889
890 bool AccessibilityUIElement::isDecrementActionSupported()
891 {
892     BEGIN_AX_OBJC_EXCEPTIONS
893     NSArray* actions = [m_element accessibilityActionNames];
894     return [actions containsObject:NSAccessibilityDecrementAction];
895     END_AX_OBJC_EXCEPTIONS
896     
897     return false;
898 }
899
900 bool AccessibilityUIElement::isEnabled()
901 {
902     BEGIN_AX_OBJC_EXCEPTIONS
903     id value = [m_element accessibilityAttributeValue:NSAccessibilityEnabledAttribute];
904     if ([value isKindOfClass:[NSNumber class]])
905         return [value boolValue];
906     END_AX_OBJC_EXCEPTIONS
907     
908     return false;
909 }
910
911 bool AccessibilityUIElement::isRequired() const
912 {
913     BEGIN_AX_OBJC_EXCEPTIONS
914     id value = [m_element accessibilityAttributeValue:@"AXRequired"];
915     if ([value isKindOfClass:[NSNumber class]])
916         return [value boolValue];
917     END_AX_OBJC_EXCEPTIONS
918     
919     return false;
920 }
921
922 bool AccessibilityUIElement::isFocused() const
923 {
924     BEGIN_AX_OBJC_EXCEPTIONS
925     id value = [m_element accessibilityAttributeValue:NSAccessibilityFocusedAttribute];
926     if ([value isKindOfClass:[NSNumber class]])
927         return [value boolValue];
928     END_AX_OBJC_EXCEPTIONS
929     
930     return false;
931 }
932
933 bool AccessibilityUIElement::isSelected() const
934 {
935     BEGIN_AX_OBJC_EXCEPTIONS
936     id value = [m_element accessibilityAttributeValue:NSAccessibilitySelectedAttribute];
937     if ([value isKindOfClass:[NSNumber class]])
938         return [value boolValue];
939     END_AX_OBJC_EXCEPTIONS
940     
941     return false;
942 }
943
944 bool AccessibilityUIElement::isSelectedOptionActive() const
945 {
946     // FIXME: implement
947     return false;
948 }
949
950 bool AccessibilityUIElement::isIndeterminate() const
951 {
952     BOOL result = NO;
953     BEGIN_AX_OBJC_EXCEPTIONS
954     id value = [m_element accessibilityAttributeValue:NSAccessibilityValueAttribute];
955     if ([value isKindOfClass:[NSNumber class]])
956         result = [value intValue] == 2;
957     END_AX_OBJC_EXCEPTIONS
958     return result;
959 }
960
961 bool AccessibilityUIElement::isExpanded() const
962 {
963     BEGIN_AX_OBJC_EXCEPTIONS
964     id value = [m_element accessibilityAttributeValue:NSAccessibilityExpandedAttribute];
965     if ([value isKindOfClass:[NSNumber class]])
966         return [value boolValue];
967     END_AX_OBJC_EXCEPTIONS
968     
969     return false;
970 }
971
972 bool AccessibilityUIElement::isChecked() const
973 {
974     // On the Mac, intValue()==1 if a a checkable control is checked.
975     return intValue() == 1;
976 }
977
978 int AccessibilityUIElement::hierarchicalLevel() const
979 {
980     BEGIN_AX_OBJC_EXCEPTIONS
981     id value = [m_element accessibilityAttributeValue:NSAccessibilityDisclosureLevelAttribute];
982     if ([value isKindOfClass:[NSNumber class]])
983         return [value intValue];
984     END_AX_OBJC_EXCEPTIONS
985
986     return 0;
987 }
988     
989 JSRetainPtr<JSStringRef> AccessibilityUIElement::classList() const
990 {
991     BEGIN_AX_OBJC_EXCEPTIONS
992     id value = [m_element accessibilityAttributeValue:@"AXDOMClassList"];
993     if (![value isKindOfClass:[NSArray class]])
994         return nullptr;
995     
996     NSMutableString* classList = [NSMutableString string];
997     NSInteger length = [value count];
998     for (NSInteger k = 0; k < length; ++k) {
999         [classList appendString:[value objectAtIndex:k]];
1000         if (k < length - 1)
1001             [classList appendString:@", "];
1002     }
1003     
1004     return [classList createJSStringRef];
1005     END_AX_OBJC_EXCEPTIONS
1006     
1007     return nullptr;
1008 }
1009
1010 JSRetainPtr<JSStringRef> AccessibilityUIElement::speakAs()
1011 {
1012     BEGIN_AX_OBJC_EXCEPTIONS
1013     id value = [m_element accessibilityAttributeValue:@"AXDRTSpeechAttribute"];
1014     if ([value isKindOfClass:[NSArray class]])
1015         return [[(NSArray *)value componentsJoinedByString:@", "] createJSStringRef];
1016     END_AX_OBJC_EXCEPTIONS
1017         
1018     return nullptr;
1019 }
1020
1021 bool AccessibilityUIElement::ariaIsGrabbed() const
1022 {
1023     BEGIN_AX_OBJC_EXCEPTIONS
1024     id value = [m_element accessibilityAttributeValue:NSAccessibilityGrabbedAttribute];
1025     if ([value isKindOfClass:[NSNumber class]])
1026         return [value boolValue];
1027     END_AX_OBJC_EXCEPTIONS
1028
1029     return false;
1030 }
1031
1032 JSRetainPtr<JSStringRef> AccessibilityUIElement::ariaDropEffects() const
1033 {
1034     BEGIN_AX_OBJC_EXCEPTIONS
1035     id value = [m_element accessibilityAttributeValue:NSAccessibilityDropEffectsAttribute];
1036     if (![value isKindOfClass:[NSArray class]])
1037         return nullptr;
1038
1039     NSMutableString* dropEffects = [NSMutableString string];
1040     NSInteger length = [value count];
1041     for (NSInteger k = 0; k < length; ++k) {
1042         [dropEffects appendString:[value objectAtIndex:k]];
1043         if (k < length - 1)
1044             [dropEffects appendString:@","];
1045     }
1046     
1047     return [dropEffects createJSStringRef];
1048     END_AX_OBJC_EXCEPTIONS
1049     
1050     return nullptr;
1051 }
1052
1053 // parameterized attributes
1054 int AccessibilityUIElement::lineForIndex(int index)
1055 {
1056     BEGIN_AX_OBJC_EXCEPTIONS
1057     id value = [m_element accessibilityAttributeValue:NSAccessibilityLineForIndexParameterizedAttribute forParameter:[NSNumber numberWithInt:index]];
1058     if ([value isKindOfClass:[NSNumber class]])
1059         return [(NSNumber *)value intValue]; 
1060     END_AX_OBJC_EXCEPTIONS
1061
1062     return -1;
1063 }
1064
1065 JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForLine(int line)
1066 {
1067     BEGIN_AX_OBJC_EXCEPTIONS
1068     id value = [m_element accessibilityAttributeValue:NSAccessibilityRangeForLineParameterizedAttribute forParameter:[NSNumber numberWithInt:line]];
1069     if ([value isKindOfClass:[NSValue class]])
1070         return [NSStringFromRange([value rangeValue]) createJSStringRef];
1071     END_AX_OBJC_EXCEPTIONS
1072     
1073     return nullptr;
1074 }
1075
1076 JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForPosition(int x, int y)
1077 {
1078     BEGIN_AX_OBJC_EXCEPTIONS
1079     id value = [m_element accessibilityAttributeValue:NSAccessibilityRangeForPositionParameterizedAttribute forParameter:[NSValue valueWithPoint:NSMakePoint(x, y)]];
1080     if ([value isKindOfClass:[NSValue class]])
1081         return [NSStringFromRange([value rangeValue]) createJSStringRef];
1082     END_AX_OBJC_EXCEPTIONS
1083
1084     return nullptr;
1085 }
1086
1087 JSRetainPtr<JSStringRef> AccessibilityUIElement::boundsForRange(unsigned location, unsigned length)
1088 {
1089     NSRange range = NSMakeRange(location, length);
1090     BEGIN_AX_OBJC_EXCEPTIONS
1091     id value = [m_element accessibilityAttributeValue:NSAccessibilityBoundsForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]];
1092     NSRect rect = NSMakeRect(0,0,0,0);
1093     if ([value isKindOfClass:[NSValue class]])
1094         rect = [value rectValue]; 
1095     
1096     // don't return position information because it is platform dependent
1097     NSMutableString* boundsDescription = [NSMutableString stringWithFormat:@"{{%f, %f}, {%f, %f}}",-1.0f,-1.0f,rect.size.width,rect.size.height];
1098     return [boundsDescription createJSStringRef];
1099     END_AX_OBJC_EXCEPTIONS
1100     
1101     return nullptr;
1102 }
1103
1104 JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForRange(unsigned location, unsigned length)
1105 {
1106     NSRange range = NSMakeRange(location, length);
1107     BEGIN_AX_OBJC_EXCEPTIONS
1108     id string = [m_element accessibilityAttributeValue:NSAccessibilityStringForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]];
1109     if (![string isKindOfClass:[NSString class]])
1110         return nullptr;
1111     
1112     return [string createJSStringRef];
1113     END_AX_OBJC_EXCEPTIONS
1114     
1115     return nullptr;
1116 }
1117
1118 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForRange(unsigned location, unsigned length)
1119 {
1120     NSRange range = NSMakeRange(location, length);
1121     BEGIN_AX_OBJC_EXCEPTIONS
1122     NSAttributedString* string = [m_element accessibilityAttributeValue:NSAccessibilityAttributedStringForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]];
1123     if (![string isKindOfClass:[NSAttributedString class]])
1124         return nullptr;
1125     
1126     NSString* stringWithAttrs = [string description];
1127     return [stringWithAttrs createJSStringRef];
1128     END_AX_OBJC_EXCEPTIONS
1129     
1130     return nullptr;
1131 }
1132
1133 bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location, unsigned length)
1134 {
1135     NSRange range = NSMakeRange(location, length);
1136     BEGIN_AX_OBJC_EXCEPTIONS
1137     NSAttributedString* string = [m_element accessibilityAttributeValue:NSAccessibilityAttributedStringForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]];
1138     if (![string isKindOfClass:[NSAttributedString class]])
1139         return false;
1140
1141     NSDictionary* attrs = [string attributesAtIndex:0 effectiveRange:nil];
1142     BOOL misspelled = [[attrs objectForKey:NSAccessibilityMisspelledTextAttribute] boolValue];
1143 #if PLATFORM(MAC)
1144     if (misspelled)
1145         misspelled = [[attrs objectForKey:NSAccessibilityMarkedMisspelledTextAttribute] boolValue];
1146 #endif
1147     return misspelled;
1148     END_AX_OBJC_EXCEPTIONS
1149     
1150     return false;
1151 }
1152
1153 unsigned AccessibilityUIElement::uiElementCountForSearchPredicate(JSContextRef context, AccessibilityUIElement *startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly)
1154 {
1155     BEGIN_AX_OBJC_EXCEPTIONS
1156     NSDictionary *parameterizedAttribute = searchPredicateParameterizedAttributeForSearchCriteria(context, startElement, isDirectionNext, UINT_MAX, searchKey, searchText, visibleOnly, immediateDescendantsOnly);
1157     id value = [m_element accessibilityAttributeValue:@"AXUIElementCountForSearchPredicate" forParameter:parameterizedAttribute];
1158     if ([value isKindOfClass:[NSNumber class]])
1159         return [value unsignedIntValue];
1160     END_AX_OBJC_EXCEPTIONS
1161     
1162     return 0;
1163 }
1164
1165 RefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement *startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly)
1166 {
1167     BEGIN_AX_OBJC_EXCEPTIONS
1168     NSDictionary *parameterizedAttribute = searchPredicateParameterizedAttributeForSearchCriteria(context, startElement, isDirectionNext, 1, searchKey, searchText, visibleOnly, immediateDescendantsOnly);
1169     id value = [m_element accessibilityAttributeValue:@"AXUIElementsForSearchPredicate" forParameter:parameterizedAttribute];
1170     if ([value isKindOfClass:[NSArray class]])
1171         return AccessibilityUIElement::create([value lastObject]);
1172     END_AX_OBJC_EXCEPTIONS
1173     
1174     return nullptr;
1175 }
1176
1177 JSRetainPtr<JSStringRef> AccessibilityUIElement::selectTextWithCriteria(JSContextRef context, JSStringRef ambiguityResolution, JSValueRef searchStrings, JSStringRef replacementString, JSStringRef activity)
1178 {
1179     BEGIN_AX_OBJC_EXCEPTIONS
1180     NSDictionary *parameterizedAttribute = selectTextParameterizedAttributeForCriteria(context, ambiguityResolution, searchStrings, replacementString, activity);
1181     id result = [m_element accessibilityAttributeValue:@"AXSelectTextWithCriteria" forParameter:parameterizedAttribute];
1182     if ([result isKindOfClass:[NSString class]])
1183         return [result createJSStringRef];
1184     END_AX_OBJC_EXCEPTIONS
1185     
1186     return nullptr;
1187 }
1188
1189 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumnHeaders()
1190 {
1191     // not yet defined in AppKit... odd
1192     BEGIN_AX_OBJC_EXCEPTIONS
1193     NSArray* columnHeadersArray = [m_element accessibilityAttributeValue:@"AXColumnHeaderUIElements"];
1194     Vector<RefPtr<AccessibilityUIElement> > columnHeadersVector;
1195     convertNSArrayToVector(columnHeadersArray, columnHeadersVector);
1196     return descriptionOfElements(columnHeadersVector);
1197     END_AX_OBJC_EXCEPTIONS
1198     
1199     return nullptr;
1200 }
1201
1202 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRowHeaders()
1203 {
1204     BEGIN_AX_OBJC_EXCEPTIONS
1205     NSArray* rowHeadersArray = [m_element accessibilityAttributeValue:@"AXRowHeaderUIElements"];
1206     Vector<RefPtr<AccessibilityUIElement> > rowHeadersVector;
1207     convertNSArrayToVector(rowHeadersArray, rowHeadersVector);
1208     return descriptionOfElements(rowHeadersVector);
1209     END_AX_OBJC_EXCEPTIONS
1210     
1211     return nullptr;
1212 }
1213
1214 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumns()
1215 {
1216     BEGIN_AX_OBJC_EXCEPTIONS
1217     NSArray* columnsArray = [m_element accessibilityAttributeValue:NSAccessibilityColumnsAttribute];
1218     Vector<RefPtr<AccessibilityUIElement> > columnsVector;
1219     convertNSArrayToVector(columnsArray, columnsVector);
1220     return descriptionOfElements(columnsVector);
1221     END_AX_OBJC_EXCEPTIONS
1222     
1223     return nullptr;
1224 }
1225
1226 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRows()
1227 {
1228     BEGIN_AX_OBJC_EXCEPTIONS
1229     NSArray* rowsArray = [m_element accessibilityAttributeValue:NSAccessibilityRowsAttribute];
1230     Vector<RefPtr<AccessibilityUIElement> > rowsVector;
1231     convertNSArrayToVector(rowsArray, rowsVector);
1232     return descriptionOfElements(rowsVector);
1233     END_AX_OBJC_EXCEPTIONS
1234     
1235     return nullptr;
1236 }
1237
1238 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfVisibleCells()
1239 {
1240     BEGIN_AX_OBJC_EXCEPTIONS
1241     NSArray* cellsArray = [m_element accessibilityAttributeValue:@"AXVisibleCells"];
1242     Vector<RefPtr<AccessibilityUIElement> > cellsVector;
1243     convertNSArrayToVector(cellsArray, cellsVector);
1244     return descriptionOfElements(cellsVector);
1245     END_AX_OBJC_EXCEPTIONS
1246     
1247     return nullptr;
1248 }
1249
1250 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfHeader()
1251 {
1252     BEGIN_AX_OBJC_EXCEPTIONS
1253     id headerObject = [m_element accessibilityAttributeValue:NSAccessibilityHeaderAttribute];
1254     if (!headerObject)
1255         return [@"" createJSStringRef];
1256     
1257     Vector<RefPtr<AccessibilityUIElement> > headerVector;
1258     headerVector.append(AccessibilityUIElement::create(headerObject));
1259     return descriptionOfElements(headerVector);
1260     END_AX_OBJC_EXCEPTIONS
1261     
1262     return nullptr;
1263 }
1264
1265 int AccessibilityUIElement::rowCount()
1266 {
1267     BEGIN_AX_OBJC_EXCEPTIONS
1268     return [m_element accessibilityArrayAttributeCount:NSAccessibilityRowsAttribute];
1269     END_AX_OBJC_EXCEPTIONS
1270     
1271     return 0;
1272 }
1273
1274 int AccessibilityUIElement::columnCount()
1275 {
1276     BEGIN_AX_OBJC_EXCEPTIONS
1277     return [m_element accessibilityArrayAttributeCount:NSAccessibilityColumnsAttribute];
1278     END_AX_OBJC_EXCEPTIONS
1279     
1280     return 0;
1281 }
1282
1283 int AccessibilityUIElement::indexInTable()
1284 {
1285     BEGIN_AX_OBJC_EXCEPTIONS
1286     NSNumber* indexNumber = [m_element accessibilityAttributeValue:NSAccessibilityIndexAttribute];
1287     if (indexNumber)
1288         return [indexNumber intValue];
1289     END_AX_OBJC_EXCEPTIONS
1290
1291     return -1;
1292 }
1293
1294 JSRetainPtr<JSStringRef> AccessibilityUIElement::rowIndexRange()
1295 {
1296     NSRange range = NSMakeRange(0, 0);
1297     BEGIN_AX_OBJC_EXCEPTIONS
1298     NSValue* indexRange = [m_element accessibilityAttributeValue:@"AXRowIndexRange"];
1299     if (indexRange)
1300         range = [indexRange rangeValue];
1301     NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%lu, %lu}", static_cast<unsigned long>(range.location), static_cast<unsigned long>(range.length)];
1302     return [rangeDescription createJSStringRef];
1303     END_AX_OBJC_EXCEPTIONS
1304     
1305     return nullptr;
1306 }
1307
1308 JSRetainPtr<JSStringRef> AccessibilityUIElement::columnIndexRange()
1309 {
1310     NSRange range = NSMakeRange(0, 0);
1311     BEGIN_AX_OBJC_EXCEPTIONS
1312     NSNumber* indexRange = [m_element accessibilityAttributeValue:@"AXColumnIndexRange"];
1313     if (indexRange)
1314         range = [indexRange rangeValue];
1315     NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%lu, %lu}", static_cast<unsigned long>(range.location), static_cast<unsigned long>(range.length)];
1316     return [rangeDescription createJSStringRef];
1317     END_AX_OBJC_EXCEPTIONS
1318     
1319     return nullptr;
1320 }
1321
1322 RefPtr<AccessibilityUIElement> AccessibilityUIElement::cellForColumnAndRow(unsigned col, unsigned row)
1323 {
1324     NSArray *colRowArray = [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:col], [NSNumber numberWithUnsignedInt:row], nil];
1325     BEGIN_AX_OBJC_EXCEPTIONS
1326     return AccessibilityUIElement::create([m_element accessibilityAttributeValue:@"AXCellForColumnAndRow" forParameter:colRowArray]);
1327     END_AX_OBJC_EXCEPTIONS    
1328
1329     return nullptr;
1330 }
1331
1332 RefPtr<AccessibilityUIElement> AccessibilityUIElement::horizontalScrollbar() const
1333 {
1334     if (!m_element)
1335         return nullptr;
1336
1337     BEGIN_AX_OBJC_EXCEPTIONS
1338     return AccessibilityUIElement::create([m_element accessibilityAttributeValue:NSAccessibilityHorizontalScrollBarAttribute]);
1339     END_AX_OBJC_EXCEPTIONS    
1340     
1341     return nullptr;
1342 }
1343
1344 RefPtr<AccessibilityUIElement> AccessibilityUIElement::verticalScrollbar() const
1345 {
1346     if (!m_element)
1347         return nullptr;
1348     
1349     BEGIN_AX_OBJC_EXCEPTIONS
1350     return AccessibilityUIElement::create([m_element accessibilityAttributeValue:NSAccessibilityVerticalScrollBarAttribute]);
1351     END_AX_OBJC_EXCEPTIONS        
1352
1353     return nullptr;
1354 }
1355
1356 void AccessibilityUIElement::scrollToMakeVisible()
1357 {
1358     BEGIN_AX_OBJC_EXCEPTIONS
1359     [m_element accessibilityPerformAction:@"AXScrollToVisible"];
1360     END_AX_OBJC_EXCEPTIONS
1361 }
1362     
1363 void AccessibilityUIElement::scrollToGlobalPoint(int x, int y)
1364 {
1365     BEGIN_AX_OBJC_EXCEPTIONS
1366     [m_element _accessibilityScrollToGlobalPoint:NSMakePoint(x, y)];
1367     END_AX_OBJC_EXCEPTIONS
1368 }
1369
1370 void AccessibilityUIElement::scrollToMakeVisibleWithSubFocus(int x, int y, int width, int height)
1371 {
1372     BEGIN_AX_OBJC_EXCEPTIONS
1373     [m_element _accessibilityScrollToMakeVisibleWithSubFocus:NSMakeRect(x, y, width, height)];
1374     END_AX_OBJC_EXCEPTIONS
1375 }
1376
1377 JSRetainPtr<JSStringRef> AccessibilityUIElement::selectedTextRange()
1378 {
1379     NSRange range = NSMakeRange(NSNotFound, 0);
1380     BEGIN_AX_OBJC_EXCEPTIONS
1381     NSValue *indexRange = [m_element accessibilityAttributeValue:NSAccessibilitySelectedTextRangeAttribute];
1382     if (indexRange)
1383         range = [indexRange rangeValue];
1384     NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%lu, %lu}", static_cast<unsigned long>(range.location), static_cast<unsigned long>(range.length)];
1385     return [rangeDescription createJSStringRef];
1386     END_AX_OBJC_EXCEPTIONS
1387     
1388     return nullptr;
1389 }
1390
1391 bool AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length)
1392 {
1393     NSRange textRange = NSMakeRange(location, length);
1394     NSValue *textRangeValue = [NSValue valueWithRange:textRange];
1395     BEGIN_AX_OBJC_EXCEPTIONS
1396     [m_element accessibilitySetValue:textRangeValue forAttribute:NSAccessibilitySelectedTextRangeAttribute];
1397     END_AX_OBJC_EXCEPTIONS
1398
1399     return true;
1400 }
1401
1402 bool AccessibilityUIElement::setSelectedVisibleTextRange(AccessibilityTextMarkerRange* markerRange)
1403 {
1404     BEGIN_AX_OBJC_EXCEPTIONS
1405     [m_element accessibilitySetValue:(__bridge id)markerRange->platformTextMarkerRange() forAttribute:NSAccessibilitySelectedTextMarkerRangeAttribute];
1406     END_AX_OBJC_EXCEPTIONS
1407
1408     return true;
1409 }
1410
1411 void AccessibilityUIElement::increment()
1412 {
1413     BEGIN_AX_OBJC_EXCEPTIONS
1414     [m_element accessibilityPerformAction:@"AXSyncIncrementAction"];
1415     END_AX_OBJC_EXCEPTIONS
1416 }
1417
1418 void AccessibilityUIElement::decrement()
1419 {
1420     BEGIN_AX_OBJC_EXCEPTIONS
1421     [m_element accessibilityPerformAction:@"AXSyncDecrementAction"];
1422     END_AX_OBJC_EXCEPTIONS
1423 }
1424
1425 void AccessibilityUIElement::asyncIncrement()
1426 {
1427     BEGIN_AX_OBJC_EXCEPTIONS
1428     [m_element accessibilityPerformAction:NSAccessibilityIncrementAction];
1429     END_AX_OBJC_EXCEPTIONS
1430 }
1431
1432 void AccessibilityUIElement::asyncDecrement()
1433 {
1434     BEGIN_AX_OBJC_EXCEPTIONS
1435     [m_element accessibilityPerformAction:NSAccessibilityDecrementAction];
1436     END_AX_OBJC_EXCEPTIONS
1437 }
1438
1439 void AccessibilityUIElement::showMenu()
1440 {
1441     BEGIN_AX_OBJC_EXCEPTIONS
1442     [m_element accessibilityPerformAction:NSAccessibilityShowMenuAction];
1443     END_AX_OBJC_EXCEPTIONS
1444 }
1445
1446 void AccessibilityUIElement::press()
1447 {
1448     BEGIN_AX_OBJC_EXCEPTIONS
1449     [m_element accessibilityPerformAction:NSAccessibilityPressAction];
1450     END_AX_OBJC_EXCEPTIONS
1451 }
1452
1453 void AccessibilityUIElement::syncPress()
1454 {
1455     BEGIN_AX_OBJC_EXCEPTIONS
1456     [m_element accessibilityPerformAction:@"AXSyncPressAction"];
1457     END_AX_OBJC_EXCEPTIONS
1458 }
1459
1460 void AccessibilityUIElement::setSelectedChild(AccessibilityUIElement* element) const
1461 {
1462     BEGIN_AX_OBJC_EXCEPTIONS
1463     NSArray* array = element ? [NSArray arrayWithObject:element->platformUIElement()] : [NSArray array];
1464     [m_element accessibilitySetValue:array forAttribute:NSAccessibilitySelectedChildrenAttribute];
1465     END_AX_OBJC_EXCEPTIONS    
1466 }
1467
1468 void AccessibilityUIElement::setSelectedChildAtIndex(unsigned index) const
1469 {
1470     BEGIN_AX_OBJC_EXCEPTIONS
1471     RefPtr<AccessibilityUIElement> element = const_cast<AccessibilityUIElement*>(this)->childAtIndex(index);
1472     if (!element)
1473         return;
1474     NSArray *selectedChildren = [m_element accessibilityAttributeValue:NSAccessibilitySelectedChildrenAttribute];
1475     NSArray *array = [NSArray arrayWithObject:element->platformUIElement()];
1476     if (selectedChildren)
1477         array = [selectedChildren arrayByAddingObjectsFromArray:array];
1478     [m_element _accessibilitySetValue:array forAttribute:NSAccessibilitySelectedChildrenAttribute];
1479     END_AX_OBJC_EXCEPTIONS
1480 }
1481
1482 void AccessibilityUIElement::removeSelectionAtIndex(unsigned index) const
1483 {
1484     BEGIN_AX_OBJC_EXCEPTIONS
1485     RefPtr<AccessibilityUIElement> element = const_cast<AccessibilityUIElement*>(this)->childAtIndex(index);
1486     NSArray *selectedChildren = [m_element accessibilityAttributeValue:NSAccessibilitySelectedChildrenAttribute];
1487     if (!element || !selectedChildren)
1488         return;
1489     NSMutableArray *array = [NSMutableArray arrayWithArray:selectedChildren];
1490     [array removeObject:element->platformUIElement()];
1491     [m_element _accessibilitySetValue:array forAttribute:NSAccessibilitySelectedChildrenAttribute];
1492     END_AX_OBJC_EXCEPTIONS
1493 }
1494
1495 void AccessibilityUIElement::clearSelectedChildren() const
1496 {
1497     // FIXME: implement
1498 }
1499
1500 JSRetainPtr<JSStringRef> AccessibilityUIElement::accessibilityValue() const
1501 {
1502     // FIXME: implement
1503     return JSStringCreateWithCharacters(0, 0);
1504 }
1505
1506 JSRetainPtr<JSStringRef> AccessibilityUIElement::documentEncoding()
1507 {
1508     BEGIN_AX_OBJC_EXCEPTIONS
1509     id value = [m_element accessibilityAttributeValue:@"AXDocumentEncoding"];
1510     if ([value isKindOfClass:[NSString class]])
1511         return [value createJSStringRef];
1512     END_AX_OBJC_EXCEPTIONS
1513     
1514     return JSStringCreateWithCharacters(0, 0);
1515 }
1516
1517 JSRetainPtr<JSStringRef> AccessibilityUIElement::documentURI()
1518 {
1519     BEGIN_AX_OBJC_EXCEPTIONS
1520     id value = [m_element accessibilityAttributeValue:@"AXDocumentURI"];
1521     if ([value isKindOfClass:[NSString class]])
1522         return [value createJSStringRef];
1523     END_AX_OBJC_EXCEPTIONS
1524     
1525     return JSStringCreateWithCharacters(0, 0);
1526 }
1527
1528 JSRetainPtr<JSStringRef> AccessibilityUIElement::url()
1529 {
1530     BEGIN_AX_OBJC_EXCEPTIONS
1531     NSURL *url = [m_element accessibilityAttributeValue:NSAccessibilityURLAttribute];
1532     return [[url absoluteString] createJSStringRef];    
1533     END_AX_OBJC_EXCEPTIONS
1534     
1535     return nullptr;
1536 }
1537
1538 bool AccessibilityUIElement::addNotificationListener(JSValueRef functionCallback)
1539 {
1540     if (!functionCallback)
1541         return false;
1542  
1543     // Mac programmers should not be adding more than one notification listener per element.
1544     // Other platforms may be different.
1545     if (m_notificationHandler)
1546         return false;
1547     m_notificationHandler = [[AccessibilityNotificationHandler alloc] init];
1548     [m_notificationHandler setPlatformElement:platformUIElement()];
1549     [m_notificationHandler setCallback:functionCallback];
1550     [m_notificationHandler startObserving];
1551
1552     return true;
1553 }
1554
1555 bool AccessibilityUIElement::removeNotificationListener()
1556 {
1557     // Mac programmers should not be trying to remove a listener that's already removed.
1558     ASSERT(m_notificationHandler);
1559
1560     [m_notificationHandler stopObserving];
1561     [m_notificationHandler release];
1562     m_notificationHandler = nil;
1563     
1564     return true;
1565 }
1566
1567 bool AccessibilityUIElement::isFocusable() const
1568 {
1569     bool result = false;
1570     BEGIN_AX_OBJC_EXCEPTIONS
1571     result = [m_element accessibilityIsAttributeSettable:NSAccessibilityFocusedAttribute];
1572     END_AX_OBJC_EXCEPTIONS
1573     
1574     return result;
1575 }
1576
1577 bool AccessibilityUIElement::isSelectable() const
1578 {
1579     bool result = false;
1580     BEGIN_AX_OBJC_EXCEPTIONS
1581     result = [m_element accessibilityIsAttributeSettable:NSAccessibilitySelectedAttribute];
1582     END_AX_OBJC_EXCEPTIONS
1583     return result;
1584 }
1585
1586 bool AccessibilityUIElement::isMultiSelectable() const
1587 {
1588     BOOL result = NO;
1589     BEGIN_AX_OBJC_EXCEPTIONS
1590     id value = [m_element accessibilityAttributeValue:@"AXIsMultiSelectable"];
1591     if ([value isKindOfClass:[NSNumber class]])
1592         result = [value boolValue];
1593     END_AX_OBJC_EXCEPTIONS
1594     return result;
1595 }
1596
1597 bool AccessibilityUIElement::isVisible() const
1598 {
1599     // FIXME: implement
1600     return false;
1601 }
1602
1603 bool AccessibilityUIElement::isOffScreen() const
1604 {
1605     // FIXME: implement
1606     return false;
1607 }
1608
1609 bool AccessibilityUIElement::isCollapsed() const
1610 {
1611     // FIXME: implement
1612     return false;
1613 }
1614
1615 bool AccessibilityUIElement::isIgnored() const
1616 {
1617     BOOL result = NO;
1618     BEGIN_AX_OBJC_EXCEPTIONS
1619     result = [m_element accessibilityIsIgnored];
1620     END_AX_OBJC_EXCEPTIONS
1621     return result;
1622 }
1623
1624 bool AccessibilityUIElement::isSingleLine() const
1625 {
1626     // FIXME: implement
1627     return false;
1628 }
1629
1630 bool AccessibilityUIElement::isMultiLine() const
1631 {
1632     // FIXME: implement
1633     return false;
1634 }
1635
1636 bool AccessibilityUIElement::hasPopup() const
1637 {
1638     BEGIN_AX_OBJC_EXCEPTIONS
1639     id value = [m_element accessibilityAttributeValue:@"AXHasPopup"];
1640     if ([value isKindOfClass:[NSNumber class]])
1641         return [value boolValue];
1642     END_AX_OBJC_EXCEPTIONS
1643
1644     return false;
1645 }
1646
1647 void AccessibilityUIElement::takeFocus()
1648 {
1649     BEGIN_AX_OBJC_EXCEPTIONS
1650     [m_element accessibilitySetValue:@YES forAttribute:NSAccessibilityFocusedAttribute];
1651     END_AX_OBJC_EXCEPTIONS
1652 }
1653
1654 void AccessibilityUIElement::takeSelection()
1655 {
1656     // FIXME: implement
1657 }
1658
1659 void AccessibilityUIElement::addSelection()
1660 {
1661     // FIXME: implement
1662 }
1663
1664 void AccessibilityUIElement::removeSelection()
1665 {
1666     // FIXME: implement
1667 }
1668
1669 // Text markers
1670 RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::lineTextMarkerRangeForTextMarker(AccessibilityTextMarker* textMarker)
1671 {
1672     BEGIN_AX_OBJC_EXCEPTIONS
1673     id textMarkerRange = [m_element accessibilityAttributeValue:@"AXLineTextMarkerRangeForTextMarker" forParameter:(__bridge id)textMarker->platformTextMarker()];
1674     return AccessibilityTextMarkerRange::create(textMarkerRange);
1675     END_AX_OBJC_EXCEPTIONS
1676     
1677     return nullptr;
1678 }
1679
1680 RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement* element)
1681 {
1682     BEGIN_AX_OBJC_EXCEPTIONS
1683     id textMarkerRange = [m_element accessibilityAttributeValue:@"AXTextMarkerRangeForUIElement" forParameter:element->platformUIElement()];
1684     return AccessibilityTextMarkerRange::create(textMarkerRange);
1685     END_AX_OBJC_EXCEPTIONS
1686     
1687     return nullptr;
1688 }
1689
1690 int AccessibilityUIElement::textMarkerRangeLength(AccessibilityTextMarkerRange* range)
1691 {
1692     BEGIN_AX_OBJC_EXCEPTIONS
1693     NSNumber* lengthValue = [m_element accessibilityAttributeValue:@"AXLengthForTextMarkerRange" forParameter:(__bridge id)range->platformTextMarkerRange()];
1694     return [lengthValue intValue];
1695     END_AX_OBJC_EXCEPTIONS
1696     
1697     return 0;
1698 }
1699
1700 RefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousTextMarker(AccessibilityTextMarker* textMarker)
1701 {
1702     BEGIN_AX_OBJC_EXCEPTIONS
1703     id previousMarker = [m_element accessibilityAttributeValue:@"AXPreviousTextMarkerForTextMarker" forParameter:(__bridge id)textMarker->platformTextMarker()];
1704     return AccessibilityTextMarker::create(previousMarker);
1705     END_AX_OBJC_EXCEPTIONS
1706     
1707     return nullptr;
1708 }
1709
1710 RefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextTextMarker(AccessibilityTextMarker* textMarker)
1711 {
1712     BEGIN_AX_OBJC_EXCEPTIONS
1713     id nextMarker = [m_element accessibilityAttributeValue:@"AXNextTextMarkerForTextMarker" forParameter:(__bridge id)textMarker->platformTextMarker()];
1714     return AccessibilityTextMarker::create(nextMarker);
1715     END_AX_OBJC_EXCEPTIONS
1716     
1717     return nullptr;
1718 }
1719
1720 JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForTextMarkerRange(AccessibilityTextMarkerRange* markerRange)
1721 {
1722     BEGIN_AX_OBJC_EXCEPTIONS
1723     id textString = [m_element accessibilityAttributeValue:@"AXStringForTextMarkerRange" forParameter:(__bridge id)markerRange->platformTextMarkerRange()];
1724     return [textString createJSStringRef];
1725     END_AX_OBJC_EXCEPTIONS
1726     
1727     return nullptr;
1728 }
1729
1730 RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForMarkers(AccessibilityTextMarker* startMarker, AccessibilityTextMarker* endMarker)
1731 {
1732     BEGIN_AX_OBJC_EXCEPTIONS
1733     NSArray* textMarkers = [NSArray arrayWithObjects:(__bridge id)startMarker->platformTextMarker(), (__bridge id)endMarker->platformTextMarker(), nil];
1734     id textMarkerRange = [m_element accessibilityAttributeValue:@"AXTextMarkerRangeForUnorderedTextMarkers" forParameter:textMarkers];
1735     return AccessibilityTextMarkerRange::create(textMarkerRange);
1736     END_AX_OBJC_EXCEPTIONS
1737     
1738     return nullptr;
1739 }
1740     
1741 RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::selectedTextMarkerRange()
1742 {
1743     BEGIN_AX_OBJC_EXCEPTIONS
1744     id textMarkerRange = [m_element accessibilityAttributeValue:NSAccessibilitySelectedTextMarkerRangeAttribute];
1745     return AccessibilityTextMarkerRange::create(textMarkerRange);
1746     END_AX_OBJC_EXCEPTIONS
1747     
1748     return nullptr;
1749 }
1750
1751 void AccessibilityUIElement::resetSelectedTextMarkerRange()
1752 {
1753     id start = [m_element accessibilityAttributeValue:@"AXStartTextMarker"];
1754     if (!start)
1755         return;
1756     
1757     NSArray* textMarkers = @[start, start];
1758     id textMarkerRange = [m_element accessibilityAttributeValue:@"AXTextMarkerRangeForUnorderedTextMarkers" forParameter:textMarkers];
1759     if (!textMarkerRange)
1760         return;
1761     
1762     BEGIN_AX_OBJC_EXCEPTIONS
1763     [m_element _accessibilitySetTestValue:textMarkerRange forAttribute:NSAccessibilitySelectedTextMarkerRangeAttribute];
1764     END_AX_OBJC_EXCEPTIONS
1765 }
1766
1767 RefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
1768 {
1769     BEGIN_AX_OBJC_EXCEPTIONS
1770     id textMarker = [m_element accessibilityAttributeValue:@"AXStartTextMarkerForTextMarkerRange" forParameter:(__bridge id)range->platformTextMarkerRange()];
1771     return AccessibilityTextMarker::create(textMarker);
1772     END_AX_OBJC_EXCEPTIONS
1773     
1774     return nullptr;
1775 }
1776
1777 RefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
1778 {
1779     BEGIN_AX_OBJC_EXCEPTIONS
1780     id textMarker = [m_element accessibilityAttributeValue:@"AXEndTextMarkerForTextMarkerRange" forParameter:(__bridge id)range->platformTextMarkerRange()];
1781     return AccessibilityTextMarker::create(textMarker);
1782     END_AX_OBJC_EXCEPTIONS
1783     
1784     return nullptr;
1785 }
1786
1787 RefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForBounds(int x, int y, int width, int height)
1788 {
1789     BEGIN_AX_OBJC_EXCEPTIONS
1790     id textMarker = [m_element accessibilityAttributeValue:NSAccessibilityEndTextMarkerForBoundsParameterizedAttribute forParameter:[NSValue valueWithRect:NSMakeRect(x, y, width, height)]];
1791     return AccessibilityTextMarker::create(textMarker);
1792     END_AX_OBJC_EXCEPTIONS
1793     
1794     return nullptr;
1795 }
1796
1797 RefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForBounds(int x, int y, int width, int height)
1798 {
1799     BEGIN_AX_OBJC_EXCEPTIONS
1800     id textMarker = [m_element accessibilityAttributeValue:NSAccessibilityStartTextMarkerForBoundsParameterizedAttribute forParameter:[NSValue valueWithRect:NSMakeRect(x, y, width, height)]];
1801     return AccessibilityTextMarker::create(textMarker);
1802     END_AX_OBJC_EXCEPTIONS
1803     
1804     return nullptr;
1805 }
1806
1807 RefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForPoint(int x, int y)
1808 {
1809     BEGIN_AX_OBJC_EXCEPTIONS
1810     id textMarker = [m_element accessibilityAttributeValue:@"AXTextMarkerForPosition" forParameter:[NSValue valueWithPoint:NSMakePoint(x, y)]];
1811     return AccessibilityTextMarker::create(textMarker);
1812     END_AX_OBJC_EXCEPTIONS
1813     
1814     return nullptr;
1815 }
1816
1817 RefPtr<AccessibilityUIElement> AccessibilityUIElement::accessibilityElementForTextMarker(AccessibilityTextMarker* marker)
1818 {
1819     BEGIN_AX_OBJC_EXCEPTIONS
1820     id uiElement = [m_element accessibilityAttributeValue:@"AXUIElementForTextMarker" forParameter:(__bridge id)marker->platformTextMarker()];
1821     if (uiElement)
1822         return AccessibilityUIElement::create(uiElement);
1823     END_AX_OBJC_EXCEPTIONS
1824     
1825     return nullptr;
1826 }
1827
1828 static JSStringRef createJSStringRef(id string)
1829 {
1830     id mutableString = [[[NSMutableString alloc] init] autorelease];
1831     id attributes = [string attributesAtIndex:0 effectiveRange:nil];
1832     id attributeEnumerationBlock = ^(NSDictionary<NSString *, id> *attrs, NSRange range, BOOL *stop) {
1833         BOOL misspelled = [[attrs objectForKey:NSAccessibilityMisspelledTextAttribute] boolValue];
1834         if (misspelled)
1835             misspelled = [[attrs objectForKey:NSAccessibilityMarkedMisspelledTextAttribute] boolValue];
1836         if (misspelled)
1837             [mutableString appendString:@"Misspelled, "];
1838         id font = [attributes objectForKey:(__bridge id)kAXFontTextAttribute];
1839         if (font)
1840             [mutableString appendFormat:@"%@ - %@, ", (__bridge id)kAXFontTextAttribute, font];
1841     };
1842     [string enumerateAttributesInRange:NSMakeRange(0, [string length]) options:(NSAttributedStringEnumerationOptions)0 usingBlock:attributeEnumerationBlock];
1843     [mutableString appendString:[string string]];
1844     return [mutableString createJSStringRef];
1845 }
1846
1847 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForTextMarkerRange(AccessibilityTextMarkerRange* markerRange)
1848 {
1849     NSAttributedString* string = nil;
1850
1851     BEGIN_AX_OBJC_EXCEPTIONS
1852     string = [m_element accessibilityAttributeValue:@"AXAttributedStringForTextMarkerRange" forParameter:(__bridge id)markerRange->platformTextMarkerRange()];
1853     END_AX_OBJC_EXCEPTIONS
1854
1855     if (![string isKindOfClass:[NSAttributedString class]])
1856         return nil;
1857
1858     return createJSStringRef(string);
1859 }
1860
1861 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForTextMarkerRangeWithOptions(AccessibilityTextMarkerRange* markerRange, bool includeSpellCheck)
1862 {
1863     NSAttributedString* string = nil;
1864
1865     id parameter = nil;
1866     if (includeSpellCheck)
1867         parameter = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:includeSpellCheck], @"AXSpellCheck", (__bridge id)markerRange->platformTextMarkerRange(), @"AXTextMarkerRange", nil];
1868     else
1869         parameter = (__bridge id)markerRange->platformTextMarkerRange();
1870
1871     BEGIN_AX_OBJC_EXCEPTIONS
1872     string = [m_element accessibilityAttributeValue:@"AXAttributedStringForTextMarkerRangeWithOptions" forParameter:parameter];
1873     END_AX_OBJC_EXCEPTIONS
1874
1875     if (![string isKindOfClass:[NSAttributedString class]])
1876         return nil;
1877
1878     return createJSStringRef(string);
1879 }
1880
1881 bool AccessibilityUIElement::attributedStringForTextMarkerRangeContainsAttribute(JSStringRef attribute, AccessibilityTextMarkerRange* range)
1882 {
1883     BEGIN_AX_OBJC_EXCEPTIONS
1884     NSAttributedString* string = [m_element accessibilityAttributeValue:@"AXAttributedStringForTextMarkerRange" forParameter:(__bridge id)range->platformTextMarkerRange()];
1885     if (![string isKindOfClass:[NSAttributedString class]])
1886         return false;
1887     
1888     NSDictionary* attrs = [string attributesAtIndex:0 effectiveRange:nil];
1889     if ([attrs objectForKey:[NSString stringWithJSStringRef:attribute]])
1890         return true;    
1891     END_AX_OBJC_EXCEPTIONS
1892     
1893     return false;
1894 }
1895     
1896 int AccessibilityUIElement::indexForTextMarker(AccessibilityTextMarker* marker)
1897 {
1898     BEGIN_AX_OBJC_EXCEPTIONS
1899     NSNumber* indexNumber = [m_element accessibilityAttributeValue:@"AXIndexForTextMarker" forParameter:(__bridge id)marker->platformTextMarker()];
1900     return [indexNumber intValue];
1901     END_AX_OBJC_EXCEPTIONS
1902     
1903     return -1;
1904 }
1905
1906 bool AccessibilityUIElement::isTextMarkerValid(AccessibilityTextMarker* textMarker)
1907 {
1908     BEGIN_AX_OBJC_EXCEPTIONS
1909     NSNumber* validNumber = [m_element accessibilityAttributeValue:@"AXTextMarkerIsValid" forParameter:(__bridge id)textMarker->platformTextMarker()];
1910     return [validNumber boolValue];
1911     END_AX_OBJC_EXCEPTIONS
1912     
1913     return false;
1914 }
1915
1916 RefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForIndex(int textIndex)
1917 {
1918     BEGIN_AX_OBJC_EXCEPTIONS
1919     id textMarker = [m_element accessibilityAttributeValue:@"AXTextMarkerForIndex" forParameter:[NSNumber numberWithInteger:textIndex]];
1920     return AccessibilityTextMarker::create(textMarker);
1921     END_AX_OBJC_EXCEPTIONS
1922     
1923     return nullptr;
1924 }
1925     
1926 RefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarker()
1927 {
1928     BEGIN_AX_OBJC_EXCEPTIONS
1929     id textMarker = [m_element accessibilityAttributeValue:@"AXStartTextMarker"];
1930     return AccessibilityTextMarker::create(textMarker);
1931     END_AX_OBJC_EXCEPTIONS
1932     
1933     return nullptr;
1934 }
1935
1936 RefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarker()
1937 {
1938     BEGIN_AX_OBJC_EXCEPTIONS
1939     id textMarker = [m_element accessibilityAttributeValue:@"AXEndTextMarker"];
1940     return AccessibilityTextMarker::create(textMarker);
1941     END_AX_OBJC_EXCEPTIONS
1942     
1943     return nullptr;
1944 }
1945
1946 RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::leftWordTextMarkerRangeForTextMarker(AccessibilityTextMarker* textMarker)
1947 {
1948     BEGIN_AX_OBJC_EXCEPTIONS
1949     id textMarkerRange = [m_element accessibilityAttributeValue:@"AXLeftWordTextMarkerRangeForTextMarker" forParameter:(__bridge id)textMarker->platformTextMarker()];
1950     return AccessibilityTextMarkerRange::create(textMarkerRange);
1951     END_AX_OBJC_EXCEPTIONS
1952     
1953     return nullptr;
1954 }
1955
1956 RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::rightWordTextMarkerRangeForTextMarker(AccessibilityTextMarker* textMarker)
1957 {
1958     BEGIN_AX_OBJC_EXCEPTIONS
1959     id textMarkerRange = [m_element accessibilityAttributeValue:@"AXRightWordTextMarkerRangeForTextMarker" forParameter:(__bridge id)textMarker->platformTextMarker()];
1960     return AccessibilityTextMarkerRange::create(textMarkerRange);
1961     END_AX_OBJC_EXCEPTIONS
1962     
1963     return nullptr;
1964 }
1965
1966 RefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousWordStartTextMarkerForTextMarker(AccessibilityTextMarker* textMarker)
1967 {
1968     BEGIN_AX_OBJC_EXCEPTIONS
1969     id previousWordStartMarker = [m_element accessibilityAttributeValue:@"AXPreviousWordStartTextMarkerForTextMarker" forParameter:(__bridge id)textMarker->platformTextMarker()];
1970     return AccessibilityTextMarker::create(previousWordStartMarker);
1971     END_AX_OBJC_EXCEPTIONS
1972     
1973     return nullptr;
1974 }
1975
1976 RefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextWordEndTextMarkerForTextMarker(AccessibilityTextMarker* textMarker)
1977 {
1978     BEGIN_AX_OBJC_EXCEPTIONS
1979     id nextWordEndMarker = [m_element accessibilityAttributeValue:@"AXNextWordEndTextMarkerForTextMarker" forParameter:(__bridge id)textMarker->platformTextMarker()];
1980     return AccessibilityTextMarker::create(nextWordEndMarker);
1981     END_AX_OBJC_EXCEPTIONS
1982     
1983     return nullptr;
1984 }
1985
1986 RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::paragraphTextMarkerRangeForTextMarker(AccessibilityTextMarker* textMarker)
1987 {
1988     BEGIN_AX_OBJC_EXCEPTIONS
1989     id textMarkerRange = [m_element accessibilityAttributeValue:@"AXParagraphTextMarkerRangeForTextMarker" forParameter:(__bridge id)textMarker->platformTextMarker()];
1990     return AccessibilityTextMarkerRange::create(textMarkerRange);
1991     END_AX_OBJC_EXCEPTIONS
1992     
1993     return nullptr;
1994 }
1995
1996 RefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousParagraphStartTextMarkerForTextMarker(AccessibilityTextMarker* textMarker)
1997 {
1998     BEGIN_AX_OBJC_EXCEPTIONS
1999     id previousParagraphStartMarker = [m_element accessibilityAttributeValue:@"AXPreviousParagraphStartTextMarkerForTextMarker" forParameter:(__bridge id)textMarker->platformTextMarker()];
2000     return AccessibilityTextMarker::create(previousParagraphStartMarker);
2001     END_AX_OBJC_EXCEPTIONS
2002     
2003     return nullptr;
2004 }
2005
2006 RefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextParagraphEndTextMarkerForTextMarker(AccessibilityTextMarker* textMarker)
2007 {
2008     BEGIN_AX_OBJC_EXCEPTIONS
2009     id nextParagraphEndMarker = [m_element accessibilityAttributeValue:@"AXNextParagraphEndTextMarkerForTextMarker" forParameter:(__bridge id)textMarker->platformTextMarker()];
2010     return AccessibilityTextMarker::create(nextParagraphEndMarker);
2011     END_AX_OBJC_EXCEPTIONS
2012     
2013     return nullptr;
2014 }
2015
2016 RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::sentenceTextMarkerRangeForTextMarker(AccessibilityTextMarker* textMarker)
2017 {
2018     BEGIN_AX_OBJC_EXCEPTIONS
2019     id textMarkerRange = [m_element accessibilityAttributeValue:@"AXSentenceTextMarkerRangeForTextMarker" forParameter:(__bridge id)textMarker->platformTextMarker()];
2020     return AccessibilityTextMarkerRange::create(textMarkerRange);
2021     END_AX_OBJC_EXCEPTIONS
2022     
2023     return nullptr;
2024 }
2025
2026 RefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousSentenceStartTextMarkerForTextMarker(AccessibilityTextMarker* textMarker)
2027 {
2028     BEGIN_AX_OBJC_EXCEPTIONS
2029     id previousParagraphStartMarker = [m_element accessibilityAttributeValue:@"AXPreviousSentenceStartTextMarkerForTextMarker" forParameter:(__bridge id)textMarker->platformTextMarker()];
2030     return AccessibilityTextMarker::create(previousParagraphStartMarker);
2031     END_AX_OBJC_EXCEPTIONS
2032     
2033     return nullptr;
2034 }
2035
2036 RefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextSentenceEndTextMarkerForTextMarker(AccessibilityTextMarker* textMarker)
2037 {
2038     BEGIN_AX_OBJC_EXCEPTIONS
2039     id nextParagraphEndMarker = [m_element accessibilityAttributeValue:@"AXNextSentenceEndTextMarkerForTextMarker" forParameter:(__bridge id)textMarker->platformTextMarker()];
2040     return AccessibilityTextMarker::create(nextParagraphEndMarker);
2041     END_AX_OBJC_EXCEPTIONS
2042     
2043     return nullptr;
2044 }
2045
2046 static NSString *_convertMathMultiscriptPairsToString(NSArray *pairs)
2047 {
2048     __block NSMutableString *result = [NSMutableString string];
2049     [pairs enumerateObjectsUsingBlock:^(id pair, NSUInteger index, BOOL *stop) {
2050         for (NSString *key in pair)
2051             [result appendFormat:@"\t%lu. %@ = %@\n", (unsigned long)index, key, [[pair objectForKey:key] accessibilityAttributeValue:NSAccessibilitySubroleAttribute]];
2052     }];
2053     
2054     return result;
2055 }
2056     
2057 JSRetainPtr<JSStringRef> AccessibilityUIElement::mathPostscriptsDescription() const
2058 {
2059     BEGIN_AX_OBJC_EXCEPTIONS
2060     NSArray *pairs = [m_element accessibilityAttributeValue:@"AXMathPostscripts"];
2061     return [_convertMathMultiscriptPairsToString(pairs) createJSStringRef];
2062     END_AX_OBJC_EXCEPTIONS
2063     
2064     return nullptr;
2065 }
2066
2067 JSRetainPtr<JSStringRef> AccessibilityUIElement::mathPrescriptsDescription() const
2068 {
2069     BEGIN_AX_OBJC_EXCEPTIONS
2070     NSArray *pairs = [m_element accessibilityAttributeValue:@"AXMathPrescripts"];
2071     return [_convertMathMultiscriptPairsToString(pairs) createJSStringRef];
2072     END_AX_OBJC_EXCEPTIONS
2073     
2074     return nullptr;
2075 }
2076     
2077 JSRetainPtr<JSStringRef> AccessibilityUIElement::pathDescription() const
2078 {
2079     BEGIN_AX_OBJC_EXCEPTIONS
2080     NSMutableString *result = [NSMutableString stringWithString:@"\nStart Path\n"];
2081     NSBezierPath *bezierPath = [m_element accessibilityAttributeValue:NSAccessibilityPathAttribute];
2082     
2083     NSUInteger elementCount = [bezierPath elementCount];
2084     NSPoint points[3];
2085     for (NSUInteger i = 0; i < elementCount; i++) {
2086         switch ([bezierPath elementAtIndex:i associatedPoints:points]) {
2087         case NSMoveToBezierPathElement:
2088             [result appendString:@"\tMove to point\n"];
2089             break;
2090             
2091         case NSLineToBezierPathElement:
2092             [result appendString:@"\tLine to\n"];
2093             break;
2094             
2095         case NSCurveToBezierPathElement:
2096             [result appendString:@"\tCurve to\n"];
2097             break;
2098             
2099         case NSClosePathBezierPathElement:
2100             [result appendString:@"\tClose\n"];
2101             break;
2102         }
2103     }
2104     
2105     return [result createJSStringRef];
2106     END_AX_OBJC_EXCEPTIONS
2107     
2108     return nullptr;
2109 }
2110     
2111 JSRetainPtr<JSStringRef> AccessibilityUIElement::supportedActions() const
2112 {
2113     BEGIN_AX_OBJC_EXCEPTIONS
2114     NSArray *names = [m_element accessibilityActionNames];
2115     return [[names componentsJoinedByString:@","] createJSStringRef];
2116     END_AX_OBJC_EXCEPTIONS
2117     
2118     return nullptr;
2119 }
2120
2121 } // namespace WTR
2122
2123 #endif // HAVE(ACCESSIBILITY)