AX: Expose table size and cell indexes on iOS
[WebKit-https.git] / Tools / WebKitTestRunner / InjectedBundle / ios / AccessibilityUIElementIOS.mm
1 /*
2  * Copyright (C) 2014 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. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "AccessibilityNotificationHandler.h"
28 #import "AccessibilityUIElement.h"
29 #import "InjectedBundle.h"
30 #import "InjectedBundlePage.h"
31 #import <Foundation/Foundation.h>
32 #import <JavaScriptCore/JSRetainPtr.h>
33 #import <JavaScriptCore/JSStringRef.h>
34 #import <JavaScriptCore/JSStringRefCF.h>
35 #import <UIKit/UIKit.h>
36 #import <WebCore/TextGranularity.h>
37 #import <WebKit/WKBundleFrame.h>
38 #import <wtf/RetainPtr.h>
39 #import <wtf/Vector.h>
40
41 typedef void (*AXPostedNotificationCallback)(id element, NSString* notification, void* context);
42
43 @interface NSObject (UIAccessibilityHidden)
44 - (id)accessibilityHitTest:(CGPoint)point;
45 - (id)accessibilityLinkedElement;
46 - (NSRange)accessibilityColumnRange;
47 - (NSRange)accessibilityRowRange;
48 - (id)accessibilityElementForRow:(NSInteger)row andColumn:(NSInteger)column;
49 - (NSURL *)accessibilityURL;
50 - (NSArray *)accessibilityHeaderElements;
51 - (NSString *)accessibilityPlaceholderValue;
52 - (NSString *)stringForRange:(NSRange)range;
53 - (NSArray *)elementsForRange:(NSRange)range;
54 - (NSString *)selectionRangeString;
55 - (CGPoint)accessibilityClickPoint;
56 - (void)accessibilityModifySelection:(WebCore::TextGranularity)granularity increase:(BOOL)increase;
57 - (void)accessibilitySetPostedNotificationCallback:(AXPostedNotificationCallback)function withContext:(void*)context;
58 - (CGFloat)_accessibilityMinValue;
59 - (CGFloat)_accessibilityMaxValue;
60 - (void)_accessibilitySetValue:(NSString *)value;
61 - (void)_accessibilityActivate;
62 - (UIAccessibilityTraits)_axSelectedTrait;
63 - (NSString *)accessibilityARIACurrentStatus;
64 - (NSUInteger)accessibilityRowCount;
65 - (NSUInteger)accessibilityColumnCount;
66 - (NSUInteger)accessibilityARIARowCount;
67 - (NSUInteger)accessibilityARIAColumnCount;
68 - (NSUInteger)accessibilityARIARowIndex;
69 - (NSUInteger)accessibilityARIAColumnIndex;
70 @end
71
72 @interface NSObject (WebAccessibilityObjectWrapperPrivate)
73 - (CGPathRef)_accessibilityPath;
74 @end
75
76 @implementation NSString (JSStringRefAdditions)
77
78 + (NSString *)stringWithJSStringRef:(JSStringRef)jsStringRef
79 {
80     if (!jsStringRef)
81         return nil;
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 namespace WTR {
95
96 static void convertNSArrayToVector(NSArray* array, Vector<RefPtr<AccessibilityUIElement> >& elementVector)
97 {
98     NSUInteger count = [array count];
99     for (NSUInteger i = 0; i < count; ++i)
100         elementVector.append(AccessibilityUIElement::create([array objectAtIndex:i]));
101 }    
102
103 static JSStringRef concatenateAttributeAndValue(NSString* attribute, NSString* value)
104 {
105     Vector<UniChar> buffer([attribute length]);
106     [attribute getCharacters:buffer.data()];
107     buffer.append(':');
108     buffer.append(' ');
109     
110     Vector<UniChar> valueBuffer([value length]);
111     [value getCharacters:valueBuffer.data()];
112     buffer.appendVector(valueBuffer);
113     
114     return JSStringCreateWithCharacters(buffer.data(), buffer.size());
115 }
116     
117 AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
118     : m_element(element)
119     , m_notificationHandler(0)
120 {
121     // FIXME: ap@webkit.org says ObjC objects need to be CFRetained/CFRelease to be GC-compliant on the mac.
122     [m_element retain];
123 }
124
125 AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other)
126     : JSWrappable()
127     , m_element(other.m_element)
128     , m_notificationHandler(0)
129 {
130     [m_element retain];
131 }
132
133 AccessibilityUIElement::~AccessibilityUIElement()
134 {
135     [m_element release];
136 }
137
138 bool AccessibilityUIElement::isEqual(AccessibilityUIElement* otherElement)
139 {
140     if (!otherElement)
141         return false;
142     return platformUIElement() == otherElement->platformUIElement();
143 }
144
145 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::headerElementAtIndex(unsigned index)
146 {
147     NSArray *headers = [m_element accessibilityHeaderElements];
148     if (index < [headers count])
149         return AccessibilityUIElement::create([headers objectAtIndex:index]);
150     
151     return nullptr;
152 }
153
154 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::linkedElement()
155 {
156     id linkedElement = [m_element accessibilityLinkedElement];
157     if (linkedElement)
158         return AccessibilityUIElement::create(linkedElement);
159     
160     return nullptr;
161 }
162
163 void AccessibilityUIElement::getLinkedUIElements(Vector<RefPtr<AccessibilityUIElement> >& elementVector)
164 {
165 }
166
167 void AccessibilityUIElement::getDocumentLinks(Vector<RefPtr<AccessibilityUIElement> >& elementVector)
168 {
169 }
170
171 void AccessibilityUIElement::getChildren(Vector<RefPtr<AccessibilityUIElement> >& elementVector)
172 {
173     NSInteger childCount = [m_element accessibilityElementCount];
174     for (NSInteger k = 0; k < childCount; ++k)
175         elementVector.append(AccessibilityUIElement::create([m_element accessibilityElementAtIndex:k]));
176 }
177
178 void AccessibilityUIElement::getChildrenWithRange(Vector<RefPtr<AccessibilityUIElement> >& elementVector, unsigned location, unsigned length)
179 {
180     NSUInteger childCount = [m_element accessibilityElementCount];
181     for (NSUInteger k = location; k < childCount && k < (location+length); ++k)
182         elementVector.append(AccessibilityUIElement::create([m_element accessibilityElementAtIndex:k]));
183 }
184
185 int AccessibilityUIElement::childrenCount()
186 {
187     Vector<RefPtr<AccessibilityUIElement>> children;
188     getChildren(children);
189
190     return children.size();
191 }
192
193 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::elementAtPoint(int x, int y)
194 {
195     id element = [m_element accessibilityHitTest:CGPointMake(x, y)];
196     if (!element)
197         return nil;
198     
199     return AccessibilityUIElement::create(element);
200 }
201     
202 static JSValueRef convertElementsToObjectArray(JSContextRef context, Vector<RefPtr<AccessibilityUIElement>>& elements)
203 {
204     JSValueRef arrayResult = JSObjectMakeArray(context, 0, nullptr, nullptr);
205     JSObjectRef arrayObj = JSValueToObject(context, arrayResult, nullptr);
206     size_t elementCount = elements.size();
207     for (size_t i = 0; i < elementCount; ++i)
208         JSObjectSetPropertyAtIndex(context, arrayObj, i, JSObjectMake(context, elements[i]->wrapperClass(), elements[i].get()), nullptr);
209     
210     return arrayResult;
211 }
212
213 JSValueRef AccessibilityUIElement::elementsForRange(unsigned location, unsigned length)
214 {
215     WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
216     JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
217
218     NSArray *elementsForRange = [m_element elementsForRange:NSMakeRange(location, length)];
219     Vector<RefPtr<AccessibilityUIElement>> elements;
220     convertNSArrayToVector(elementsForRange, elements);
221     return convertElementsToObjectArray(context, elements);
222 }
223
224 unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element)
225 {
226     return 0;
227 }
228
229 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::childAtIndex(unsigned index)
230 {
231     Vector<RefPtr<AccessibilityUIElement> > children;
232     getChildrenWithRange(children, index, 1);
233
234     if (children.size() == 1)
235         return children[0];
236     return 0;
237 }
238
239 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::linkedUIElementAtIndex(unsigned index)
240 {
241     return 0;
242 }
243
244 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned index)
245 {
246     return 0;
247 }
248
249 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned index)
250 {
251     return 0;
252 }
253
254 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaControlsElementAtIndex(unsigned index)
255 {
256     return 0;
257 }
258
259 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedRowAtIndex(unsigned index)
260 {
261     return 0;
262 }
263
264 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::rowAtIndex(unsigned index)
265 {
266     return 0;
267 }
268
269 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedChildAtIndex(unsigned index) const
270 {
271     return 0;
272 }
273
274 unsigned AccessibilityUIElement::selectedChildrenCount() const
275 {
276     return 0;
277 }
278
279 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedRowAtIndex(unsigned index)
280 {
281     return 0;
282 }
283
284 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::titleUIElement()
285 {
286     return 0;
287 }
288
289 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::parentElement()
290 {
291     return nil;
292 }
293
294 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedByRow()
295 {
296     return 0;
297 }
298
299 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfLinkedUIElements()
300 {
301     return JSStringCreateWithCharacters(0, 0);
302 }
303
304 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfDocumentLinks()
305 {
306     return JSStringCreateWithCharacters(0, 0);
307 }
308
309 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfChildren()
310 {
311     return JSStringCreateWithCharacters(0, 0);
312 }
313
314 JSRetainPtr<JSStringRef> AccessibilityUIElement::allAttributes()
315 {
316     return JSStringCreateWithCharacters(0, 0);
317 }
318
319 JSRetainPtr<JSStringRef> AccessibilityUIElement::stringAttributeValue(JSStringRef attribute)
320 {
321     if (JSStringIsEqualToUTF8CString(attribute, "AXPlaceholderValue"))
322         return [[m_element accessibilityPlaceholderValue] createJSStringRef];
323     
324     if (JSStringIsEqualToUTF8CString(attribute, "AXARIACurrent"))
325         return [[m_element accessibilityARIACurrentStatus] createJSStringRef];
326     
327     return JSStringCreateWithCharacters(0, 0);
328 }
329
330 double AccessibilityUIElement::numberAttributeValue(JSStringRef attribute)
331 {
332     // Support test for table related attributes.
333     if (JSStringIsEqualToUTF8CString(attribute, "AXARIAColumnCount"))
334         return [m_element accessibilityARIAColumnCount];
335     if (JSStringIsEqualToUTF8CString(attribute, "AXARIARowCount"))
336         return [m_element accessibilityARIARowCount];
337     if (JSStringIsEqualToUTF8CString(attribute, "AXARIAColumnIndex"))
338         return [m_element accessibilityARIAColumnIndex];
339     if (JSStringIsEqualToUTF8CString(attribute, "AXARIARowIndex"))
340         return [m_element accessibilityARIARowIndex];
341     
342     return 0;
343 }
344
345 JSValueRef AccessibilityUIElement::uiElementArrayAttributeValue(JSStringRef attribute) const
346 {
347     return 0;
348 }
349
350 JSValueRef AccessibilityUIElement::rowHeaders() const
351 {
352     return nullptr;
353 }
354
355 JSValueRef AccessibilityUIElement::columnHeaders() const
356 {
357     return nullptr;
358 }
359
360 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementAttributeValue(JSStringRef attribute) const
361 {
362     return 0;
363 }
364
365 bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute)
366 {
367     return false;
368 }
369
370 bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute)
371 {
372     return false;
373 }
374
375 bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute)
376 {
377     return false;
378 }
379
380 JSRetainPtr<JSStringRef> AccessibilityUIElement::parameterizedAttributeNames()
381 {
382     return JSStringCreateWithCharacters(0, 0);
383 }
384
385 JSRetainPtr<JSStringRef> AccessibilityUIElement::role()
386 {
387     return JSStringCreateWithCharacters(0, 0);
388 }
389
390 JSRetainPtr<JSStringRef> AccessibilityUIElement::subrole()
391 {
392     return JSStringCreateWithCharacters(0, 0);
393 }
394
395 JSRetainPtr<JSStringRef> AccessibilityUIElement::roleDescription()
396 {
397     return JSStringCreateWithCharacters(0, 0);
398 }
399
400 JSRetainPtr<JSStringRef> AccessibilityUIElement::computedRoleString()
401 {
402     // FIXME: implement
403     return JSStringCreateWithCharacters(0, 0);
404 }
405
406 JSRetainPtr<JSStringRef> AccessibilityUIElement::title()
407 {
408     return JSStringCreateWithCharacters(0, 0);
409 }
410
411 JSRetainPtr<JSStringRef> AccessibilityUIElement::description()
412 {
413     return concatenateAttributeAndValue(@"AXLabel", [m_element accessibilityLabel]);
414 }
415
416 JSRetainPtr<JSStringRef> AccessibilityUIElement::orientation() const
417 {
418     return JSStringCreateWithCharacters(0, 0);
419 }
420
421 JSRetainPtr<JSStringRef> AccessibilityUIElement::stringValue()
422 {
423     return concatenateAttributeAndValue(@"AXValue", [m_element accessibilityValue]);
424 }
425
426 JSRetainPtr<JSStringRef> AccessibilityUIElement::language()
427 {
428     return JSStringCreateWithCharacters(0, 0);
429 }
430
431 JSRetainPtr<JSStringRef> AccessibilityUIElement::helpText() const
432 {
433     return concatenateAttributeAndValue(@"AXHint", [m_element accessibilityHint]);
434 }
435
436 double AccessibilityUIElement::x()
437 {
438     CGRect frame = [m_element accessibilityFrame];
439     return frame.origin.x;
440 }
441
442 double AccessibilityUIElement::y()
443 {
444     CGRect frame = [m_element accessibilityFrame];
445     return frame.origin.y;
446 }
447
448 double AccessibilityUIElement::width()
449 {
450     CGRect frame = [m_element accessibilityFrame];
451     return frame.size.width;
452 }
453
454 double AccessibilityUIElement::height()
455 {
456     CGRect frame = [m_element accessibilityFrame];
457     return frame.size.height;
458 }
459
460 double AccessibilityUIElement::clickPointX()
461 {
462     return [m_element accessibilityClickPoint].x;
463 }
464
465 double AccessibilityUIElement::clickPointY()
466 {
467     return [m_element accessibilityClickPoint].y;
468 }
469
470 double AccessibilityUIElement::intValue() const
471 {
472     return 0;
473 }
474
475 double AccessibilityUIElement::minValue()
476 {
477     return [m_element _accessibilityMinValue];
478 }
479
480 double AccessibilityUIElement::maxValue()
481 {
482     return [m_element _accessibilityMaxValue];
483 }
484
485
486 JSRetainPtr<JSStringRef> AccessibilityUIElement::valueDescription()
487 {
488     return JSStringCreateWithCharacters(0, 0);
489 }
490
491 int AccessibilityUIElement::insertionPointLineNumber()
492 {
493     return -1;
494 }
495
496 bool AccessibilityUIElement::isPressActionSupported()
497 {
498     return false;
499 }
500
501 bool AccessibilityUIElement::isIncrementActionSupported()
502 {
503     return false;
504 }
505
506 bool AccessibilityUIElement::isDecrementActionSupported()
507 {
508     return false;
509 }
510
511 bool AccessibilityUIElement::isEnabled()
512 {
513     return false;
514 }
515
516 bool AccessibilityUIElement::isRequired() const
517 {
518     return false;
519 }
520
521 bool AccessibilityUIElement::isFocused() const
522 {
523     // FIXME: implement
524     return false;
525 }
526
527 bool AccessibilityUIElement::isSelected() const
528 {
529     UIAccessibilityTraits traits = [m_element accessibilityTraits];
530     return (traits & [m_element _axSelectedTrait]) == [m_element _axSelectedTrait];
531 }
532
533 bool AccessibilityUIElement::isSelectedOptionActive() const
534 {
535     // FIXME: implement
536     return false;
537 }
538
539 bool AccessibilityUIElement::isIndeterminate() const
540 {
541     // FIXME: implement
542     return false;
543 }
544
545 bool AccessibilityUIElement::isExpanded() const
546 {
547     return false;
548 }
549
550 bool AccessibilityUIElement::isChecked() const
551 {
552     return false;
553 }
554
555 int AccessibilityUIElement::hierarchicalLevel() const
556 {
557     return 0;
558 }
559
560 JSRetainPtr<JSStringRef> AccessibilityUIElement::classList() const
561 {
562     return nullptr;
563 }
564
565 JSRetainPtr<JSStringRef> AccessibilityUIElement::speak()
566 {
567     return nullptr;
568 }
569
570 bool AccessibilityUIElement::ariaIsGrabbed() const
571 {
572     return false;
573 }
574
575 JSRetainPtr<JSStringRef> AccessibilityUIElement::ariaDropEffects() const
576 {
577     return JSStringCreateWithCharacters(0, 0);
578 }
579
580 // parameterized attributes
581 int AccessibilityUIElement::lineForIndex(int index)
582 {
583     return -1;
584 }
585
586 JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForLine(int line)
587 {
588     return 0;
589 }
590
591 JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForPosition(int x, int y)
592 {
593     return 0;
594 }
595
596 JSRetainPtr<JSStringRef> AccessibilityUIElement::boundsForRange(unsigned location, unsigned length)
597 {
598     return JSStringCreateWithCharacters(0, 0);
599 }
600
601 JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForRange(unsigned location, unsigned length)
602 {
603     NSString *stringForRange = [m_element stringForRange:NSMakeRange(location, length)];
604     if (!stringForRange)
605         return nullptr;
606     
607     return [stringForRange createJSStringRef];
608 }
609
610 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForRange(unsigned location, unsigned length)
611 {
612     return JSStringCreateWithCharacters(0, 0);
613 }
614
615 bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location, unsigned length)
616 {
617     return false;
618 }
619
620 unsigned AccessibilityUIElement::uiElementCountForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly)
621 {
622     return 0;
623 }
624
625 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly)
626 {
627     return nullptr;
628 }
629
630 JSRetainPtr<JSStringRef> AccessibilityUIElement::selectTextWithCriteria(JSContextRef, JSStringRef ambiguityResolution, JSValueRef searchStrings, JSStringRef replacementString, JSStringRef activity)
631 {
632     return nullptr;
633 }
634
635 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumnHeaders()
636 {
637     return JSStringCreateWithCharacters(0, 0);
638 }
639
640 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRowHeaders()
641 {
642     return JSStringCreateWithCharacters(0, 0);
643 }
644
645 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumns()
646 {
647     return JSStringCreateWithCharacters(0, 0);
648 }
649
650 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRows()
651 {
652     return JSStringCreateWithCharacters(0, 0);
653 }
654
655 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfVisibleCells()
656 {
657     return JSStringCreateWithCharacters(0, 0);
658 }
659
660 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfHeader()
661 {
662     return JSStringCreateWithCharacters(0, 0);
663 }
664
665 JSRetainPtr<JSStringRef> AccessibilityUIElement::traits()
666 {
667     return concatenateAttributeAndValue(@"AXTraits", [NSString stringWithFormat:@"%qu", [m_element accessibilityTraits]]);
668 }
669
670 JSRetainPtr<JSStringRef> AccessibilityUIElement::identifier()
671 {
672     return concatenateAttributeAndValue(@"AXIdentifier", [m_element accessibilityIdentifier]);
673 }
674
675 int AccessibilityUIElement::rowCount()
676 {
677     return [m_element accessibilityRowCount];
678 }
679
680 int AccessibilityUIElement::columnCount()
681 {
682     return [m_element accessibilityColumnCount];
683 }
684
685 int AccessibilityUIElement::indexInTable()
686 {
687     return -1;
688 }
689
690 JSRetainPtr<JSStringRef> AccessibilityUIElement::rowIndexRange()
691 {
692     NSRange range = [m_element accessibilityRowRange];
693     NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%lu, %lu}", (unsigned long)range.location, (unsigned long)range.length];
694     return [rangeDescription createJSStringRef];
695 }
696
697 JSRetainPtr<JSStringRef> AccessibilityUIElement::columnIndexRange()
698 {
699     NSRange range = [m_element accessibilityColumnRange];
700     NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%lu, %lu}", (unsigned long)range.location, (unsigned long)range.length];
701     return [rangeDescription createJSStringRef];
702 }
703
704 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::cellForColumnAndRow(unsigned col, unsigned row)
705 {
706     return AccessibilityUIElement::create([m_element accessibilityElementForRow:row andColumn:col]);
707 }
708
709 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::horizontalScrollbar() const
710 {
711     return 0;
712 }
713
714 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::verticalScrollbar() const
715 {
716     return 0;
717 }
718
719 void AccessibilityUIElement::scrollToMakeVisible()
720 {
721 }
722     
723 void AccessibilityUIElement::scrollToGlobalPoint(int x, int y)
724 {
725 }
726     
727 void AccessibilityUIElement::scrollToMakeVisibleWithSubFocus(int x, int y, int width, int height)
728 {
729 }
730
731 JSRetainPtr<JSStringRef> AccessibilityUIElement::selectedTextRange()
732 {
733     return JSStringCreateWithCharacters(0, 0);
734 }
735
736 bool AccessibilityUIElement::setSelectedVisibleTextRange(AccessibilityTextMarkerRange*)
737 {
738     return false;
739 }
740
741 bool AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length)
742 {
743     return false;
744 }
745
746 void AccessibilityUIElement::increment()
747 {
748     [m_element accessibilityIncrement];
749 }
750
751 void AccessibilityUIElement::decrement()
752 {
753     [m_element accessibilityDecrement];
754 }
755
756 void AccessibilityUIElement::showMenu()
757 {
758 }
759
760 void AccessibilityUIElement::press()
761 {
762 }
763
764 void AccessibilityUIElement::setSelectedChild(AccessibilityUIElement* element) const
765 {
766 }
767
768 void AccessibilityUIElement::setSelectedChildAtIndex(unsigned index) const
769 {
770 }
771
772 void AccessibilityUIElement::removeSelectionAtIndex(unsigned index) const
773 {
774 }
775
776 JSRetainPtr<JSStringRef> AccessibilityUIElement::accessibilityValue() const
777 {
778     // FIXME: implement
779     return JSStringCreateWithCharacters(0, 0);
780 }
781
782 JSRetainPtr<JSStringRef> AccessibilityUIElement::documentEncoding()
783 {
784     return JSStringCreateWithCharacters(0, 0);
785 }
786
787 JSRetainPtr<JSStringRef> AccessibilityUIElement::documentURI()
788 {
789     return JSStringCreateWithCharacters(0, 0);
790 }
791
792 void AccessibilityUIElement::assistiveTechnologySimulatedFocus()
793 {
794     [m_element accessibilityElementDidBecomeFocused];
795 }
796     
797 bool AccessibilityUIElement::scrollPageUp()
798 {
799     return [m_element accessibilityScroll:UIAccessibilityScrollDirectionUp];
800 }
801
802 bool AccessibilityUIElement::scrollPageDown()
803 {
804     return [m_element accessibilityScroll:UIAccessibilityScrollDirectionDown];
805 }
806 bool AccessibilityUIElement::scrollPageLeft()
807 {
808     return [m_element accessibilityScroll:UIAccessibilityScrollDirectionLeft];
809 }
810
811 bool AccessibilityUIElement::scrollPageRight()
812 {
813     return [m_element accessibilityScroll:UIAccessibilityScrollDirectionRight];
814 }
815
816 void AccessibilityUIElement::increaseTextSelection()
817 {
818     [m_element accessibilityModifySelection:WebCore::CharacterGranularity increase:YES];
819 }
820
821 void AccessibilityUIElement::decreaseTextSelection()
822 {
823     [m_element accessibilityModifySelection:WebCore::CharacterGranularity increase:NO];
824 }
825
826 JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForSelection()
827 {
828     NSString *stringForRange = [m_element selectionRangeString];
829     if (!stringForRange)
830         return nullptr;
831     
832     return [stringForRange createJSStringRef];
833 }
834     
835 int AccessibilityUIElement::elementTextPosition()
836 {
837     NSRange range = [[m_element valueForKey:@"elementTextRange"] rangeValue];
838     return range.location;
839 }
840
841 int AccessibilityUIElement::elementTextLength()
842 {
843     NSRange range = [[m_element valueForKey:@"elementTextRange"] rangeValue];
844     return range.length;    
845 }
846     
847 JSRetainPtr<JSStringRef> AccessibilityUIElement::url()
848 {
849     NSURL *url = [m_element accessibilityURL];
850     return [[url absoluteString] createJSStringRef];
851 }
852
853 bool AccessibilityUIElement::addNotificationListener(JSValueRef functionCallback)
854 {
855     if (!functionCallback)
856         return false;
857     
858     // iOS programmers should not be adding more than one notification listener per element.
859     // Other platforms may be different.
860     if (m_notificationHandler)
861         return false;
862     m_notificationHandler = [[AccessibilityNotificationHandler alloc] init];
863     [m_notificationHandler setPlatformElement:platformUIElement()];
864     [m_notificationHandler setCallback:functionCallback];
865     [m_notificationHandler startObserving];
866     
867     return true;
868 }
869
870 bool AccessibilityUIElement::removeNotificationListener()
871 {
872     // iOS programmers should not be trying to remove a listener that's already removed.
873     ASSERT(m_notificationHandler);
874     
875     [m_notificationHandler stopObserving];
876     [m_notificationHandler release];
877     m_notificationHandler = nil;
878     
879     return true;
880 }
881
882 bool AccessibilityUIElement::isFocusable() const
883 {
884     return false;
885 }
886
887 bool AccessibilityUIElement::isSelectable() const
888 {
889     // FIXME: implement
890     return false;
891 }
892
893 bool AccessibilityUIElement::isMultiSelectable() const
894 {
895     // FIXME: implement
896     return false;
897 }
898
899 bool AccessibilityUIElement::isVisible() const
900 {
901     // FIXME: implement
902     return false;
903 }
904
905 bool AccessibilityUIElement::isOffScreen() const
906 {
907     // FIXME: implement
908     return false;
909 }
910
911 bool AccessibilityUIElement::isCollapsed() const
912 {
913     // FIXME: implement
914     return false;
915 }
916
917 bool AccessibilityUIElement::isIgnored() const
918 {
919     bool isAccessibilityElement = [m_element isAccessibilityElement];
920     return !isAccessibilityElement;
921 }
922
923 bool AccessibilityUIElement::hasPopup() const
924 {
925     return false;
926 }
927
928 void AccessibilityUIElement::takeFocus()
929 {
930     // FIXME: implement
931 }
932
933 void AccessibilityUIElement::takeSelection()
934 {
935     // FIXME: implement
936 }
937
938 void AccessibilityUIElement::addSelection()
939 {
940     // FIXME: implement
941 }
942
943 void AccessibilityUIElement::removeSelection()
944 {
945     // FIXME: implement
946 }
947
948 // Text markers
949 PassRefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::lineTextMarkerRangeForTextMarker(AccessibilityTextMarker* textMarker)
950 {
951     return nullptr;
952 }
953
954 PassRefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement* element)
955 {
956     return 0;
957 }
958
959 int AccessibilityUIElement::textMarkerRangeLength(AccessibilityTextMarkerRange* range)
960 {
961     return 0;
962 }
963
964 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousTextMarker(AccessibilityTextMarker* textMarker)
965 {
966     return 0;
967 }
968
969 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextTextMarker(AccessibilityTextMarker* textMarker)
970 {
971     return 0;
972 }
973
974 JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForTextMarkerRange(AccessibilityTextMarkerRange* markerRange)
975 {
976     return 0;
977 }
978
979 PassRefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForMarkers(AccessibilityTextMarker* startMarker, AccessibilityTextMarker* endMarker)
980 {
981     return 0;
982 }
983
984 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
985 {
986     return 0;
987 }
988
989 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
990 {
991     return 0;
992 }
993
994 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForBounds(int x, int y, int width, int height)
995 {
996     return nullptr;
997 }
998
999 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForBounds(int x, int y, int width, int height)
1000 {
1001     return nullptr;
1002 }
1003
1004 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForPoint(int x, int y)
1005 {
1006     return 0;
1007 }
1008
1009 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::accessibilityElementForTextMarker(AccessibilityTextMarker* marker)
1010 {
1011     return 0;
1012 }
1013
1014 bool AccessibilityUIElement::attributedStringForTextMarkerRangeContainsAttribute(JSStringRef attribute, AccessibilityTextMarkerRange* range)
1015 {
1016     return false;
1017 }
1018
1019 int AccessibilityUIElement::indexForTextMarker(AccessibilityTextMarker* marker)
1020 {
1021     return -1;
1022 }
1023
1024 bool AccessibilityUIElement::isTextMarkerValid(AccessibilityTextMarker* textMarker)
1025 {
1026     return false;
1027 }
1028
1029 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForIndex(int textIndex)
1030 {
1031     return 0;
1032 }
1033
1034 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarker()
1035 {
1036     return nullptr;
1037 }
1038
1039 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarker()
1040 {
1041     return nullptr;
1042 }
1043
1044 JSRetainPtr<JSStringRef> AccessibilityUIElement::mathPostscriptsDescription() const
1045 {
1046     return 0;
1047 }
1048
1049 JSRetainPtr<JSStringRef> AccessibilityUIElement::mathPrescriptsDescription() const
1050 {
1051     return 0;
1052 }
1053
1054 static void _CGPathEnumerationIteration(void *info, const CGPathElement *element)
1055 {
1056     NSMutableString *result = (NSMutableString *)info;
1057     switch (element->type) {
1058     case kCGPathElementMoveToPoint:
1059         [result appendString:@"\tMove to point\n"];
1060         break;
1061     case kCGPathElementAddLineToPoint:
1062         [result appendString:@"\tLine to\n"];
1063         break;
1064     case kCGPathElementAddQuadCurveToPoint:
1065         [result appendString:@"\tQuad curve to\n"];
1066         break;
1067     case kCGPathElementAddCurveToPoint:
1068         [result appendString:@"\tCurve to\n"];
1069         break;
1070     case kCGPathElementCloseSubpath:
1071         [result appendString:@"\tClose\n"];
1072         break;
1073     }
1074 }
1075
1076 JSRetainPtr<JSStringRef> AccessibilityUIElement::pathDescription() const
1077 {
1078     NSMutableString *result = [NSMutableString stringWithString:@"\nStart Path\n"];
1079     CGPathRef pathRef = [m_element _accessibilityPath];
1080     
1081     CGPathApply(pathRef, result, _CGPathEnumerationIteration);
1082     
1083     return [result createJSStringRef];
1084 }
1085
1086 JSRetainPtr<JSStringRef> AccessibilityUIElement::supportedActions() const
1087 {
1088     return 0;
1089 }
1090
1091 } // namespace WTR
1092