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