37a68c7c07329142ec4500fd7736bd63a82e20f0
[WebKit-https.git] / Tools / DumpRenderTree / ios / AccessibilityUIElementIOS.mm
1 /*
2  * Copyright (C) 2009 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #import "config.h"
27 #import "DumpRenderTree.h"
28 #import "AccessibilityUIElement.h"
29
30 #import "AccessibilityCommonMac.h"
31 #import "AccessibilityNotificationHandler.h"
32 #import <Foundation/Foundation.h>
33 #import <JavaScriptCore/JSRetainPtr.h>
34 #import <JavaScriptCore/JSStringRef.h>
35 #import <JavaScriptCore/JSStringRefCF.h>
36 #import <WebCore/TextGranularity.h>
37 #import <WebKit/WebFrame.h>
38 #import <WebKit/WebHTMLView.h>
39 #import <wtf/RetainPtr.h>
40 #import <wtf/Vector.h>
41
42 #import <UIKit/UIKit.h>
43
44 typedef void (*AXPostedNotificationCallback)(id element, NSString* notification, void* context);
45
46 AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
47     : m_element(element)
48     , m_notificationHandler(0)
49 {
50     [m_element retain];
51 }
52
53 AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other)
54     : m_element(other.m_element)
55     , m_notificationHandler(0)
56
57 {
58     [m_element retain];
59 }
60
61 AccessibilityUIElement::~AccessibilityUIElement()
62 {
63     [m_element release];
64 }
65
66 @interface NSObject (UIAccessibilityHidden)
67 - (id)accessibilityHitTest:(CGPoint)point;
68 - (id)accessibilityLinkedElement;
69 - (NSRange)accessibilityColumnRange;
70 - (NSRange)accessibilityRowRange;
71 - (id)accessibilityElementForRow:(NSInteger)row andColumn:(NSInteger)column;
72 - (NSURL *)accessibilityURL;
73 - (NSArray *)accessibilityHeaderElements;
74 - (NSString *)accessibilityPlaceholderValue;
75 - (NSString *)stringForRange:(NSRange)range;
76 - (NSArray *)elementsForRange:(NSRange)range;
77 - (NSString *)selectionRangeString;
78 - (CGPoint)accessibilityClickPoint;
79 - (void)accessibilityModifySelection:(WebCore::TextGranularity)granularity increase:(BOOL)increase;
80 - (void)accessibilitySetPostedNotificationCallback:(AXPostedNotificationCallback)function withContext:(void*)context;
81 - (CGFloat)_accessibilityMinValue;
82 - (CGFloat)_accessibilityMaxValue;
83 - (void)_accessibilitySetValue:(NSString *)value;
84 - (void)_accessibilityActivate;
85 - (UIAccessibilityTraits)_axSelectedTrait;
86 - (NSString *)accessibilityARIACurrentStatus;
87 @end
88
89 @interface NSObject (WebAccessibilityObjectWrapperPrivate)
90 - (CGPathRef)_accessibilityPath;
91 @end
92
93 static JSStringRef concatenateAttributeAndValue(NSString* attribute, NSString* value)
94 {
95     Vector<UniChar> buffer([attribute length]);
96     [attribute getCharacters:buffer.data()];
97     buffer.append(':');
98     buffer.append(' ');
99     
100     Vector<UniChar> valueBuffer([value length]);
101     [value getCharacters:valueBuffer.data()];
102     buffer.appendVector(valueBuffer);
103     
104     return JSStringCreateWithCharacters(buffer.data(), buffer.size());
105 }
106
107 #pragma mark iPhone Attributes
108
109 JSStringRef AccessibilityUIElement::identifier()
110 {
111     return concatenateAttributeAndValue(@"AXIdentifier", [m_element accessibilityIdentifier]);
112 }
113
114 JSStringRef AccessibilityUIElement::traits()
115 {
116     return concatenateAttributeAndValue(@"AXTraits", [NSString stringWithFormat:@"%qu", [m_element accessibilityTraits]]);
117 }
118
119 int AccessibilityUIElement::elementTextPosition()
120 {
121     NSRange range = [[m_element valueForKey:@"elementTextRange"] rangeValue];
122     return range.location;
123 }
124
125 int AccessibilityUIElement::elementTextLength()
126 {
127     NSRange range = [[m_element valueForKey:@"elementTextRange"] rangeValue];
128     return range.length;    
129 }
130
131 JSStringRef AccessibilityUIElement::url()
132 {
133     NSURL *url = [m_element accessibilityURL];
134     return [[url absoluteString] createJSStringRef];    
135 }
136
137 double AccessibilityUIElement::x()
138 {
139     CGRect frame = [m_element accessibilityFrame];
140     return frame.origin.x;
141 }
142
143 double AccessibilityUIElement::y()
144 {
145     CGRect frame = [m_element accessibilityFrame];
146     return frame.origin.y;
147 }
148
149 double AccessibilityUIElement::width()
150 {
151     CGRect frame = [m_element accessibilityFrame];
152     return frame.size.width;
153 }
154
155 double AccessibilityUIElement::height()
156 {
157     CGRect frame = [m_element accessibilityFrame];
158     return frame.size.height;
159 }
160
161 double AccessibilityUIElement::clickPointX()
162 {
163     CGPoint centerPoint = [m_element accessibilityClickPoint];
164     return centerPoint.x;
165 }
166
167 double AccessibilityUIElement::clickPointY()
168 {
169     CGPoint centerPoint = [m_element accessibilityClickPoint];
170     return centerPoint.y;
171 }
172
173 void AccessibilityUIElement::getChildren(Vector<AccessibilityUIElement>& elementVector)
174 {
175     NSInteger childCount = [m_element accessibilityElementCount];
176     for (NSInteger k = 0; k < childCount; ++k)
177         elementVector.append(AccessibilityUIElement([m_element accessibilityElementAtIndex:k]));
178 }
179
180 void AccessibilityUIElement::getChildrenWithRange(Vector<AccessibilityUIElement>& elementVector, unsigned location, unsigned length)
181 {
182     // accessibilityElementAtIndex: takes an NSInteger.
183     // We want to preserve that in order to test against invalid indexes being input.
184     NSInteger maxValue = static_cast<NSInteger>(location + length);
185     for (NSInteger k = location; k < maxValue; ++k)
186         elementVector.append(AccessibilityUIElement([m_element accessibilityElementAtIndex:k]));    
187 }
188
189 int AccessibilityUIElement::childrenCount()
190 {
191     Vector<AccessibilityUIElement> children;
192     getChildren(children);
193     
194     return children.size();
195 }
196
197 AccessibilityUIElement AccessibilityUIElement::elementAtPoint(int x, int y)
198 {
199     id element = [m_element accessibilityHitTest:NSMakePoint(x, y)];
200     if (!element)
201         return nil;
202     
203     return AccessibilityUIElement(element); 
204 }
205
206 unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element)
207 {
208     return 0;
209 }
210
211 AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index)
212 {
213     Vector<AccessibilityUIElement> children;
214     getChildrenWithRange(children, index, 1);
215     
216     if (children.size() == 1)
217         return children[0];
218     return nil;
219 }
220
221 AccessibilityUIElement AccessibilityUIElement::headerElementAtIndex(unsigned index)
222 {
223     NSArray *headers = [m_element accessibilityHeaderElements];
224     if (index < [headers count])
225         return [headers objectAtIndex:index];
226     
227     return 0;
228 }
229
230 AccessibilityUIElement AccessibilityUIElement::linkedElement()
231 {
232     id linkedElement = [m_element accessibilityLinkedElement];
233     if (linkedElement)
234         return AccessibilityUIElement(linkedElement);
235     
236     return 0;
237 }
238
239 AccessibilityUIElement AccessibilityUIElement::linkedUIElementAtIndex(unsigned index)
240 {
241     // FIXME: implement
242     return 0;
243 }
244
245 AccessibilityUIElement AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned index)
246 {
247     return 0;
248 }
249
250 AccessibilityUIElement AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned index)
251 {
252     return 0;
253 }
254
255 AccessibilityUIElement AccessibilityUIElement::ariaControlsElementAtIndex(unsigned index)
256 {
257     return 0;
258 }
259
260 AccessibilityUIElement AccessibilityUIElement::disclosedRowAtIndex(unsigned index)
261 {
262     return 0;
263 }
264
265 AccessibilityUIElement AccessibilityUIElement::selectedRowAtIndex(unsigned index)
266 {
267     return 0;
268 }
269
270 AccessibilityUIElement AccessibilityUIElement::rowAtIndex(unsigned index)
271 {
272     return 0;
273 }
274
275 AccessibilityUIElement AccessibilityUIElement::titleUIElement()
276 {
277     return 0;
278 }
279
280 AccessibilityUIElement AccessibilityUIElement::parentElement()
281 {
282     id accessibilityObject = [m_element accessibilityContainer];
283     if (accessibilityObject)
284         return AccessibilityUIElement(accessibilityObject);
285     
286     return nil;
287 }
288
289 AccessibilityUIElement AccessibilityUIElement::disclosedByRow()
290 {
291     return 0;
292 }
293
294 void AccessibilityUIElement::increaseTextSelection()
295 {
296     [m_element accessibilityModifySelection:WebCore::CharacterGranularity increase:YES];
297 }
298
299 void AccessibilityUIElement::decreaseTextSelection()
300 {
301     [m_element accessibilityModifySelection:WebCore::CharacterGranularity increase:NO];    
302 }
303
304 JSStringRef AccessibilityUIElement::stringForSelection() 
305
306     NSString *stringForRange = [m_element selectionRangeString];
307     if (!stringForRange)
308         return 0;
309     
310     return [stringForRange createJSStringRef];
311 }
312
313 JSStringRef AccessibilityUIElement::stringForRange(unsigned location, unsigned length) 
314
315     NSString *stringForRange = [m_element stringForRange:NSMakeRange(location, length)];
316     if (!stringForRange)
317         return 0;
318     
319     return [stringForRange createJSStringRef];
320 }
321
322 JSStringRef AccessibilityUIElement::attributedStringForRange(unsigned, unsigned)
323 {
324     return JSStringCreateWithCharacters(0, 0);
325 }
326
327 bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned, unsigned)
328 {
329     return false;
330 }
331
332
333 void AccessibilityUIElement::elementsForRange(unsigned location, unsigned length, Vector<AccessibilityUIElement>& elements)
334
335     NSArray *elementsForRange = [m_element elementsForRange:NSMakeRange(location, length)];
336     for (id object in elementsForRange) {
337         AccessibilityUIElement element = AccessibilityUIElement(object);
338         elements.append(element);
339     }
340 }
341
342 static void _CGPathEnumerationIteration(void *info, const CGPathElement *element)
343 {
344     NSMutableString *result = (NSMutableString *)info;
345     switch (element->type) {
346     case kCGPathElementMoveToPoint:
347         [result appendString:@"\tMove to point\n"];
348         break;
349         
350     case kCGPathElementAddLineToPoint:
351         [result appendString:@"\tLine to\n"];
352         break;
353         
354     case kCGPathElementAddQuadCurveToPoint:
355         [result appendString:@"\tQuad curve to\n"];
356         break;
357         
358     case kCGPathElementAddCurveToPoint:
359         [result appendString:@"\tCurve to\n"];
360         break;
361         
362     case kCGPathElementCloseSubpath:
363         [result appendString:@"\tClose\n"];
364         break;
365     }
366 }
367
368 JSStringRef AccessibilityUIElement::pathDescription() const
369 {
370     NSMutableString *result = [NSMutableString stringWithString:@"\nStart Path\n"];
371     CGPathRef pathRef = [m_element _accessibilityPath];
372     
373     CGPathApply(pathRef, result, _CGPathEnumerationIteration);
374     
375     return [result createJSStringRef];
376 }
377
378 #pragma mark Unused
379
380 void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>& elementVector)
381 {
382 }
383
384 void AccessibilityUIElement::getDocumentLinks(Vector<AccessibilityUIElement>& elementVector)
385 {
386 }
387
388 JSStringRef AccessibilityUIElement::attributesOfLinkedUIElements()
389 {
390     return JSStringCreateWithCharacters(0, 0);
391 }
392
393 JSStringRef AccessibilityUIElement::attributesOfDocumentLinks()
394 {
395     return JSStringCreateWithCharacters(0, 0);
396 }
397
398 JSStringRef AccessibilityUIElement::attributesOfChildren()
399 {
400     return JSStringCreateWithCharacters(0, 0);
401 }
402
403 JSStringRef AccessibilityUIElement::allAttributes()
404 {
405     return JSStringCreateWithCharacters(0, 0);
406 }
407
408 JSStringRef AccessibilityUIElement::stringAttributeValue(JSStringRef attribute)
409 {
410     if (JSStringIsEqualToUTF8CString(attribute, "AXPlaceholderValue"))
411         return [[m_element accessibilityPlaceholderValue] createJSStringRef];
412     
413     if (JSStringIsEqualToUTF8CString(attribute, "AXARIACurrent"))
414         return [[m_element accessibilityARIACurrentStatus] createJSStringRef];
415     
416     return JSStringCreateWithCharacters(0, 0);
417 }
418
419 bool AccessibilityUIElement::isPressActionSupported()
420 {
421     return false;
422 }
423
424 bool AccessibilityUIElement::isIncrementActionSupported()
425 {
426     return false;
427 }
428
429 bool AccessibilityUIElement::isDecrementActionSupported()
430 {
431     return false;
432 }
433
434 bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute)
435 {
436     return false;
437 }
438
439 bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute)
440 {
441     return false;
442 }
443
444 bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute)
445 {
446     return false;
447 }
448
449 JSStringRef AccessibilityUIElement::parameterizedAttributeNames()
450 {
451     return JSStringCreateWithCharacters(0, 0);
452 }
453
454 JSStringRef AccessibilityUIElement::role()
455 {
456     return JSStringCreateWithCharacters(0, 0);
457 }
458
459 JSStringRef AccessibilityUIElement::subrole()
460 {
461     return JSStringCreateWithCharacters(0, 0);
462 }
463
464 bool AccessibilityUIElement::scrollPageUp()
465 {
466     return [m_element accessibilityScroll:UIAccessibilityScrollDirectionUp];
467 }
468
469 bool AccessibilityUIElement::scrollPageDown()
470 {
471     return [m_element accessibilityScroll:UIAccessibilityScrollDirectionDown];
472 }
473 bool AccessibilityUIElement::scrollPageLeft()
474 {
475     return [m_element accessibilityScroll:UIAccessibilityScrollDirectionLeft];
476 }
477
478 bool AccessibilityUIElement::scrollPageRight()
479 {
480     return [m_element accessibilityScroll:UIAccessibilityScrollDirectionRight];
481 }
482
483 JSStringRef AccessibilityUIElement::roleDescription()
484 {
485     return JSStringCreateWithCharacters(0, 0);
486 }
487
488 JSStringRef AccessibilityUIElement::computedRoleString()
489 {
490     // FIXME: implement
491     return JSStringCreateWithCharacters(0, 0);
492 }
493
494 JSStringRef AccessibilityUIElement::title()
495 {
496     return JSStringCreateWithCharacters(0, 0);
497 }
498
499 JSStringRef AccessibilityUIElement::description()
500 {
501     return concatenateAttributeAndValue(@"AXLabel", [m_element accessibilityLabel]);
502 }
503
504 JSStringRef AccessibilityUIElement::orientation() const
505 {
506     return JSStringCreateWithCharacters(0, 0);
507 }
508
509 JSStringRef AccessibilityUIElement::stringValue()
510 {
511     return concatenateAttributeAndValue(@"AXValue", [m_element accessibilityValue]);
512 }
513
514 JSStringRef AccessibilityUIElement::language()
515 {
516     return JSStringCreateWithCharacters(0, 0);
517 }
518
519 JSStringRef AccessibilityUIElement::helpText() const
520 {
521     return concatenateAttributeAndValue(@"AXHint", [m_element accessibilityHint]);
522 }
523
524 double AccessibilityUIElement::intValue() const
525 {
526     return 0.0f;
527 }
528
529 double AccessibilityUIElement::minValue()
530 {
531     return [m_element _accessibilityMinValue];
532 }
533
534 double AccessibilityUIElement::maxValue()
535 {
536     return [m_element _accessibilityMaxValue];
537 }
538
539 void AccessibilityUIElement::setValue(JSStringRef valueText)
540 {
541     [m_element _accessibilitySetValue:[NSString stringWithJSStringRef:valueText]];
542 }
543
544 JSStringRef AccessibilityUIElement::valueDescription()
545 {
546     return JSStringCreateWithCharacters(0, 0);
547 }
548
549 int AccessibilityUIElement::insertionPointLineNumber()
550 {
551     return -1;
552 }
553
554 bool AccessibilityUIElement::isEnabled()
555 {
556     return false;
557 }
558
559 bool AccessibilityUIElement::isRequired() const
560 {
561     return false;
562 }
563
564 bool AccessibilityUIElement::isFocused() const
565 {
566     // FIXME: implement
567     return false;
568 }
569
570 bool AccessibilityUIElement::isSelected() const
571 {
572     UIAccessibilityTraits traits = [m_element accessibilityTraits];
573     bool result = (traits & [m_element _axSelectedTrait]) == [m_element _axSelectedTrait];
574     return result;
575 }
576
577 bool AccessibilityUIElement::isExpanded() const
578 {
579     return false;
580 }
581
582 bool AccessibilityUIElement::isChecked() const
583 {
584     return false;
585 }
586
587 bool AccessibilityUIElement::isIndeterminate() const
588 {
589     // FIXME: implement
590     return false;
591 }
592
593 int AccessibilityUIElement::hierarchicalLevel() const
594 {
595     return 0;
596 }
597
598 bool AccessibilityUIElement::ariaIsGrabbed() const
599 {
600     return false;
601 }
602
603 JSStringRef AccessibilityUIElement::ariaDropEffects() const
604 {
605     return JSStringCreateWithCharacters(0, 0);
606 }
607
608 int AccessibilityUIElement::lineForIndex(int index)
609 {
610     return -1;
611 }
612
613 JSStringRef AccessibilityUIElement::boundsForRange(unsigned location, unsigned length)
614 {
615     return JSStringCreateWithCharacters(0, 0);
616 }
617
618 JSStringRef AccessibilityUIElement::attributesOfColumnHeaders()
619 {
620     return JSStringCreateWithCharacters(0, 0);
621 }
622
623 JSStringRef AccessibilityUIElement::attributesOfRowHeaders()
624 {
625     return JSStringCreateWithCharacters(0, 0);
626 }
627
628 JSStringRef AccessibilityUIElement::attributesOfColumns()
629 {
630     return JSStringCreateWithCharacters(0, 0);
631 }
632
633 JSStringRef AccessibilityUIElement::attributesOfRows()
634 {
635     return JSStringCreateWithCharacters(0, 0);
636 }
637
638 JSStringRef AccessibilityUIElement::attributesOfVisibleCells()
639 {
640     return JSStringCreateWithCharacters(0, 0);
641 }
642
643 JSStringRef AccessibilityUIElement::attributesOfHeader()
644 {
645     return JSStringCreateWithCharacters(0, 0);
646 }
647
648 int AccessibilityUIElement::rowCount()
649 {
650     return -1;
651 }
652
653 int AccessibilityUIElement::columnCount()
654 {
655     return -1;
656 }
657
658 int AccessibilityUIElement::indexInTable()
659 {
660     return -1;
661 }
662
663 JSStringRef AccessibilityUIElement::rowIndexRange()
664 {
665     NSRange range = [m_element accessibilityRowRange];
666     NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%lu, %lu}", (unsigned long)range.location, (unsigned long)range.length];
667     return [rangeDescription createJSStringRef];
668 }
669
670 JSStringRef AccessibilityUIElement::columnIndexRange()
671 {
672     NSRange range = [m_element accessibilityColumnRange];
673     NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%lu, %lu}", (unsigned long)range.location, (unsigned long)range.length];
674     return [rangeDescription createJSStringRef];    
675 }
676
677 AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned col, unsigned row)
678 {
679     return AccessibilityUIElement([m_element accessibilityElementForRow:row andColumn:col]);
680 }
681
682 void AccessibilityUIElement::scrollToMakeVisible()
683 {
684     // FIXME: implement
685 }
686
687 void AccessibilityUIElement::scrollToMakeVisibleWithSubFocus(int x, int y, int width, int height)
688 {
689     // FIXME: implement
690 }
691
692 void AccessibilityUIElement::scrollToGlobalPoint(int x, int y)
693 {
694     // FIXME: implement
695 }
696
697 JSStringRef AccessibilityUIElement::selectedTextRange()
698 {
699     return JSStringCreateWithCharacters(0, 0);
700 }
701
702 void AccessibilityUIElement::assistiveTechnologySimulatedFocus()
703 {
704     [m_element accessibilityElementDidBecomeFocused];
705 }
706
707 void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length)
708 {
709 }
710
711 void AccessibilityUIElement::increment()
712 {
713     [m_element accessibilityIncrement];
714 }
715
716 void AccessibilityUIElement::decrement()
717 {
718     [m_element accessibilityDecrement];
719 }
720
721 void AccessibilityUIElement::showMenu()
722 {
723 }
724
725 void AccessibilityUIElement::press()
726 {
727     [m_element _accessibilityActivate];
728 }
729
730 JSStringRef AccessibilityUIElement::accessibilityValue() const
731 {
732     // FIXME: implement
733     return JSStringCreateWithCharacters(0, 0);
734 }
735
736 JSStringRef AccessibilityUIElement::documentEncoding()
737 {
738     return JSStringCreateWithCharacters(0, 0);
739 }
740
741 JSStringRef AccessibilityUIElement::documentURI()
742 {
743     return JSStringCreateWithCharacters(0, 0);
744 }
745
746 bool AccessibilityUIElement::addNotificationListener(JSObjectRef functionCallback)
747 {
748     if (!functionCallback)
749         return false;
750     
751     // iOS programmers should not be adding more than one notification listener per element.
752     // Other platforms may be different.
753     if (m_notificationHandler)
754         return false;
755     m_notificationHandler = [[AccessibilityNotificationHandler alloc] init];
756     [m_notificationHandler setPlatformElement:platformUIElement()];
757     [m_notificationHandler setCallback:functionCallback];
758     [m_notificationHandler startObserving];
759     
760     return true;
761 }
762
763 void AccessibilityUIElement::removeNotificationListener()
764 {
765     // iOS programmers should not be trying to remove a listener that's already removed.
766     ASSERT(m_notificationHandler);
767     
768     [m_notificationHandler stopObserving];
769     [m_notificationHandler release];
770     m_notificationHandler = nil;
771 }
772
773 bool AccessibilityUIElement::isFocusable() const
774 {
775     // FIXME: implement
776     return false;
777 }
778
779 bool AccessibilityUIElement::isSelectable() const
780 {
781     // FIXME: implement
782     return false;
783 }
784
785 bool AccessibilityUIElement::isMultiSelectable() const
786 {
787     // FIXME: implement
788     return false;
789 }
790
791 bool AccessibilityUIElement::isSelectedOptionActive() const
792 {
793     // FIXME: implement
794     return false;
795 }
796
797 bool AccessibilityUIElement::isVisible() const
798 {
799     // FIXME: implement
800     return false;
801 }
802
803 bool AccessibilityUIElement::isOffScreen() const
804 {
805     // FIXME: implement
806     return false;
807 }
808
809 bool AccessibilityUIElement::isCollapsed() const
810 {
811     // FIXME: implement
812     return false;
813 }
814
815 bool AccessibilityUIElement::isIgnored() const
816 {
817     return ![m_element isAccessibilityElement];
818 }
819
820 bool AccessibilityUIElement::hasPopup() const
821 {
822     // FIXME: implement
823     return false;
824 }
825
826 void AccessibilityUIElement::takeFocus()
827 {
828     // FIXME: implement
829 }
830
831 void AccessibilityUIElement::takeSelection()
832 {
833     // FIXME: implement
834 }
835
836 void AccessibilityUIElement::addSelection()
837 {
838     // FIXME: implement
839 }
840
841 void AccessibilityUIElement::removeSelection()
842 {
843     // FIXME: implement
844 }
845
846 unsigned AccessibilityUIElement::uiElementCountForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly)
847 {
848     // FIXME: implement
849     return 0;
850 }
851
852 AccessibilityUIElement AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly)
853 {
854     // FIXME: implement
855     return 0;
856 }
857
858 JSStringRef AccessibilityUIElement::selectTextWithCriteria(JSContextRef context, JSStringRef ambiguityResolution, JSValueRef searchStrings, JSStringRef replacementString, JSStringRef activity)
859 {
860     // FIXME: Implement.
861     return nullptr;
862 }
863
864 double AccessibilityUIElement::numberAttributeValue(JSStringRef attribute)
865 {
866     // FIXME: implement
867     return 0;
868 }
869
870 JSStringRef AccessibilityUIElement::classList() const
871 {
872     // FIXME: implement
873     return nullptr;
874 }
875
876 void AccessibilityUIElement::uiElementArrayAttributeValue(JSStringRef, Vector<AccessibilityUIElement>&) const
877 {
878     // FIXME: implement
879 }
880
881 void AccessibilityUIElement::columnHeaders(Vector<AccessibilityUIElement>&) const
882 {
883     // FIXME: implement
884 }
885
886 void AccessibilityUIElement::rowHeaders(Vector<AccessibilityUIElement>&) const
887 {
888     // FIXME: implement
889 }
890
891 unsigned AccessibilityUIElement::selectedChildrenCount() const
892 {
893     return 0;
894 }
895
896 AccessibilityUIElement AccessibilityUIElement::selectedChildAtIndex(unsigned) const
897 {
898     return 0;
899 }