[ATK] Expose aria-invalid as a text attribute (not object attribute)
[WebKit-https.git] / Tools / WebKitTestRunner / InjectedBundle / atk / AccessibilityUIElementAtk.cpp
1 /*
2  * Copyright (C) 2011 Apple Inc. All Rights Reserved.
3  * Copyright (C) 2012 Igalia S.L.
4  * Copyright (C) 2013 Samsung Electronics. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "config.h"
29 #include "AccessibilityUIElement.h"
30
31 #if HAVE(ACCESSIBILITY)
32
33 #include "InjectedBundle.h"
34 #include "InjectedBundlePage.h"
35 #include "NotImplemented.h"
36 #include <JavaScriptCore/JSStringRef.h>
37 #include <JavaScriptCore/OpaqueJSString.h>
38 #include <atk/atk.h>
39 #include <wtf/Assertions.h>
40 #include <wtf/gobject/GOwnPtr.h>
41 #include <wtf/gobject/GRefPtr.h>
42 #include <wtf/text/CString.h>
43 #include <wtf/text/StringBuilder.h>
44 #include <wtf/text/WTFString.h>
45 #include <wtf/unicode/CharacterNames.h>
46
47 namespace WTR {
48
49 namespace {
50
51 enum AtkAttributeType {
52     ObjectAttributeType,
53     TextAttributeType
54 };
55
56 enum AttributeDomain {
57     CoreDomain = 0,
58     AtkDomain
59 };
60
61 enum AttributesIndex {
62     // Attribute names.
63     InvalidNameIndex = 0,
64     PlaceholderNameIndex,
65     SortNameIndex,
66
67     // Attribute values.
68     SortAscendingValueIndex,
69     SortDescendingValueIndex,
70     SortUnknownValueIndex,
71
72     NumberOfAttributes
73 };
74
75 // Attribute names & Values (keep on sync with enum AttributesIndex).
76 const String attributesMap[][2] = {
77     // Attribute names.
78     { "AXInvalid", "invalid" },
79     { "AXPlaceholderValue", "placeholder-text" } ,
80     { "AXSortDirection", "sort" },
81
82     // Attribute values.
83     { "AXAscendingSortDirection", "ascending" },
84     { "AXDescendingSortDirection", "descending" },
85     { "AXUnknownSortDirection", "unknown" }
86 };
87
88 String coreAttributeToAtkAttribute(JSStringRef attribute)
89 {
90     size_t bufferSize = JSStringGetMaximumUTF8CStringSize(attribute);
91     GOwnPtr<gchar> buffer(static_cast<gchar*>(g_malloc(bufferSize)));
92     JSStringGetUTF8CString(attribute, buffer.get(), bufferSize);
93
94     String attributeString = String::fromUTF8(buffer.get());
95     for (int i = 0; i < NumberOfAttributes; ++i) {
96         if (attributesMap[i][CoreDomain] == attributeString)
97             return attributesMap[i][AtkDomain];
98     }
99
100     return attributeString;
101 }
102
103 String atkAttributeValueToCoreAttributeValue(AtkAttributeType type, const String& id, const String& value)
104 {
105     if (type == ObjectAttributeType) {
106         // We need to translate ATK values exposed for 'aria-sort' (e.g. 'ascending')
107         // into those expected by the layout tests (e.g. 'AXAscendingSortDirection').
108         if (id == attributesMap[SortNameIndex][AtkDomain] && !value.isEmpty()) {
109             if (value == attributesMap[SortAscendingValueIndex][AtkDomain])
110                 return attributesMap[SortAscendingValueIndex][CoreDomain];
111             if (value == attributesMap[SortDescendingValueIndex][AtkDomain])
112                 return attributesMap[SortDescendingValueIndex][CoreDomain];
113
114             return attributesMap[SortUnknownValueIndex][CoreDomain];
115         }
116     } else if (type == TextAttributeType) {
117         // In case of 'aria-invalid' when the attribute empty or has "false" for ATK
118         // it should not be mapped at all, but layout tests will expect 'false'.
119         if (id == attributesMap[InvalidNameIndex][AtkDomain] && value.isEmpty())
120             return "false";
121     }
122
123     return value;
124 }
125
126 AtkAttributeSet* getAttributeSet(AtkObject* accessible, AtkAttributeType type)
127 {
128     if (type == ObjectAttributeType)
129         return atk_object_get_attributes(accessible);
130
131     if (type == TextAttributeType) {
132         if (!ATK_IS_TEXT(accessible))
133             return 0;
134
135         return atk_text_get_default_attributes(ATK_TEXT(accessible));
136     }
137
138     ASSERT_NOT_REACHED();
139     return 0;
140 }
141
142 String getAttributeSetValueForId(AtkObject* accessible, AtkAttributeType type, String id)
143 {
144     AtkAttributeSet* attributeSet = getAttributeSet(accessible, type);
145     if (!attributeSet)
146         return String();
147
148     String attributeValue;
149     for (AtkAttributeSet* attributes = attributeSet; attributes; attributes = attributes->next) {
150         AtkAttribute* atkAttribute = static_cast<AtkAttribute*>(attributes->data);
151         if (id == atkAttribute->name) {
152             attributeValue = String::fromUTF8(atkAttribute->value);
153             break;
154         }
155     }
156     atk_attribute_set_free(attributeSet);
157
158     return atkAttributeValueToCoreAttributeValue(type, id, attributeValue);
159 }
160
161 String getAtkAttributeSetAsString(AtkObject* accessible, AtkAttributeType type)
162 {
163     AtkAttributeSet* attributeSet = getAttributeSet(accessible, type);
164     if (!attributeSet)
165         return String();
166
167     StringBuilder builder;
168     for (AtkAttributeSet* attributes = attributeSet; attributes; attributes = attributes->next) {
169         AtkAttribute* attribute = static_cast<AtkAttribute*>(attributes->data);
170         GOwnPtr<gchar> attributeData(g_strconcat(attribute->name, ":", attribute->value, NULL));
171         builder.append(attributeData.get());
172         if (attributes->next)
173             builder.append(", ");
174     }
175     atk_attribute_set_free(attributeSet);
176
177     return builder.toString();
178 }
179
180 bool checkElementState(PlatformUIElement element, AtkStateType stateType)
181 {
182     if (!ATK_IS_OBJECT(element.get()))
183         return false;
184
185     GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(element.get())));
186     return atk_state_set_contains_state(stateSet.get(), stateType);
187 }
188
189 JSStringRef indexRangeInTable(PlatformUIElement element, bool isRowRange)
190 {
191     GOwnPtr<gchar> rangeString(g_strdup("{0, 0}"));
192
193     if (!ATK_IS_OBJECT(element.get()))
194         return JSStringCreateWithUTF8CString(rangeString.get());
195
196     AtkObject* axTable = atk_object_get_parent(ATK_OBJECT(element.get()));
197     if (!axTable || !ATK_IS_TABLE(axTable))
198         return JSStringCreateWithUTF8CString(rangeString.get());
199
200     // Look for the cell in the table.
201     gint indexInParent = atk_object_get_index_in_parent(ATK_OBJECT(element.get()));
202     if (indexInParent == -1)
203         return JSStringCreateWithUTF8CString(rangeString.get());
204
205     int row = -1;
206     int column = -1;
207     row = atk_table_get_row_at_index(ATK_TABLE(axTable), indexInParent);
208     column = atk_table_get_column_at_index(ATK_TABLE(axTable), indexInParent);
209
210     // Get the actual values, if row and columns are valid values.
211     if (row != -1 && column != -1) {
212         int base = 0;
213         int length = 0;
214         if (isRowRange) {
215             base = row;
216             length = atk_table_get_row_extent_at(ATK_TABLE(axTable), row, column);
217         } else {
218             base = column;
219             length = atk_table_get_column_extent_at(ATK_TABLE(axTable), row, column);
220         }
221         rangeString.set(g_strdup_printf("{%d, %d}", base, length));
222     }
223
224     return JSStringCreateWithUTF8CString(rangeString.get());
225 }
226
227 void alterCurrentValue(PlatformUIElement element, int factor)
228 {
229     if (!ATK_IS_VALUE(element.get()))
230         return;
231
232     GValue currentValue = G_VALUE_INIT;
233     atk_value_get_current_value(ATK_VALUE(element.get()), &currentValue);
234
235     GValue increment = G_VALUE_INIT;
236     atk_value_get_minimum_increment(ATK_VALUE(element.get()), &increment);
237
238     GValue newValue = G_VALUE_INIT;
239     g_value_init(&newValue, G_TYPE_FLOAT);
240
241     g_value_set_float(&newValue, g_value_get_float(&currentValue) + factor * g_value_get_float(&increment));
242     atk_value_set_current_value(ATK_VALUE(element.get()), &newValue);
243
244     g_value_unset(&newValue);
245     g_value_unset(&increment);
246     g_value_unset(&currentValue);
247 }
248
249 gchar* replaceCharactersForResults(gchar* str)
250 {
251     WTF::String uString = WTF::String::fromUTF8(str);
252
253     // The object replacement character is passed along to ATs so we need to be
254     // able to test for their presence and do so without causing test failures.
255     uString.replace(objectReplacementCharacter, "<obj>");
256
257     // The presence of newline characters in accessible text of a single object
258     // is appropriate, but it makes test results (especially the accessible tree)
259     // harder to read.
260     uString.replace("\n", "<\\n>");
261
262     return g_strdup(uString.utf8().data());
263 }
264
265 const gchar* roleToString(AtkRole role)
266 {
267     switch (role) {
268     case ATK_ROLE_ALERT:
269         return "AXAlert";
270     case ATK_ROLE_CANVAS:
271         return "AXCanvas";
272     case ATK_ROLE_CHECK_BOX:
273         return "AXCheckBox";
274     case ATK_ROLE_COLOR_CHOOSER:
275         return "AXColorWell";
276     case ATK_ROLE_COLUMN_HEADER:
277         return "AXColumnHeader";
278     case ATK_ROLE_COMBO_BOX:
279         return "AXComboBox";
280     case ATK_ROLE_DOCUMENT_FRAME:
281         return "AXWebArea";
282     case ATK_ROLE_ENTRY:
283         return "AXTextField";
284     case ATK_ROLE_FOOTER:
285         return "AXFooter";
286     case ATK_ROLE_FORM:
287         return "AXForm";
288     case ATK_ROLE_GROUPING:
289         return "AXGroup";
290     case ATK_ROLE_HEADING:
291         return "AXHeading";
292     case ATK_ROLE_IMAGE:
293         return "AXImage";
294     case ATK_ROLE_IMAGE_MAP:
295         return "AXImageMap";
296     case ATK_ROLE_LABEL:
297         return "AXLabel";
298     case ATK_ROLE_LINK:
299         return "AXLink";
300     case ATK_ROLE_LIST:
301         return "AXList";
302     case ATK_ROLE_LIST_BOX:
303         return "AXListBox";
304     case ATK_ROLE_LIST_ITEM:
305         return "AXListItem";
306     case ATK_ROLE_MENU:
307         return "AXMenu";
308     case ATK_ROLE_MENU_BAR:
309         return "AXMenuBar";
310     case ATK_ROLE_MENU_ITEM:
311         return "AXMenuItem";
312     case ATK_ROLE_PAGE_TAB:
313         return "AXTab";
314     case ATK_ROLE_PAGE_TAB_LIST:
315         return "AXTabGroup";
316     case ATK_ROLE_PANEL:
317         return "AXGroup";
318     case ATK_ROLE_PARAGRAPH:
319         return "AXParagraph";
320     case ATK_ROLE_PASSWORD_TEXT:
321         return "AXPasswordField";
322     case ATK_ROLE_PROGRESS_BAR:
323         return "AXProgressIndicator";
324     case ATK_ROLE_PUSH_BUTTON:
325         return "AXButton";
326     case ATK_ROLE_RADIO_BUTTON:
327         return "AXRadioButton";
328     case ATK_ROLE_RADIO_MENU_ITEM:
329         return "AXRadioMenuItem";
330     case ATK_ROLE_ROW_HEADER:
331         return "AXRowHeader";
332     case ATK_ROLE_RULER:
333         return "AXRuler";
334     case ATK_ROLE_SCROLL_BAR:
335         return "AXScrollBar";
336     case ATK_ROLE_SCROLL_PANE:
337         return "AXScrollArea";
338     case ATK_ROLE_SECTION:
339         return "AXDiv";
340     case ATK_ROLE_SEPARATOR:
341         return "AXHorizontalRule";
342     case ATK_ROLE_SLIDER:
343         return "AXSlider";
344     case ATK_ROLE_SPIN_BUTTON:
345         return "AXSpinButton";
346     case ATK_ROLE_TABLE:
347         return "AXTable";
348     case ATK_ROLE_TABLE_CELL:
349         return "AXCell";
350     case ATK_ROLE_TABLE_COLUMN_HEADER:
351         return "AXColumnHeader";
352     case ATK_ROLE_TABLE_ROW:
353         return "AXRow";
354     case ATK_ROLE_TABLE_ROW_HEADER:
355         return "AXRowHeader";
356     case ATK_ROLE_TOGGLE_BUTTON:
357         return "AXToggleButton";
358     case ATK_ROLE_TOOL_BAR:
359         return "AXToolbar";
360     case ATK_ROLE_TOOL_TIP:
361         return "AXUserInterfaceTooltip";
362     case ATK_ROLE_TREE:
363         return "AXTree";
364     case ATK_ROLE_TREE_TABLE:
365         return "AXTreeGrid";
366     case ATK_ROLE_TREE_ITEM:
367         return "AXTreeItem";
368     case ATK_ROLE_WINDOW:
369         return "AXWindow";
370     case ATK_ROLE_UNKNOWN:
371         return "AXUnknown";
372     default:
373         // We want to distinguish ATK_ROLE_UNKNOWN from a known AtkRole which
374         // our DRT isn't properly handling.
375         return "FIXME not identified";
376     }
377 }
378
379 String attributesOfElement(AccessibilityUIElement* element)
380 {
381     StringBuilder builder;
382
383     builder.append(String::format("%s\n", element->role()->string().utf8().data()));
384
385     // For the parent we print its role and its name, if available.
386     builder.append("AXParent: ");
387     RefPtr<AccessibilityUIElement> parent = element->parentElement();
388     AtkObject* atkParent = parent ? parent->platformUIElement().get() : 0;
389     if (atkParent) {
390         builder.append(roleToString(atk_object_get_role(atkParent)));
391         const char* parentName = atk_object_get_name(atkParent);
392         if (parentName && g_utf8_strlen(parentName, -1))
393             builder.append(String::format(": %s", parentName));
394     } else
395         builder.append("(null)");
396     builder.append("\n");
397
398     builder.append(String::format("AXChildren: %d\n", element->childrenCount()));
399     builder.append(String::format("AXPosition: { %f, %f }\n", element->x(), element->y()));
400     builder.append(String::format("AXSize: { %f, %f }\n", element->width(), element->height()));
401
402     String title = element->title()->string();
403     if (!title.isEmpty())
404         builder.append(String::format("%s\n", title.utf8().data()));
405
406     String description = element->description()->string();
407     if (!description.isEmpty())
408         builder.append(String::format("%s\n", description.utf8().data()));
409
410     String value = element->stringValue()->string();
411     if (!value.isEmpty())
412         builder.append(String::format("%s\n", value.utf8().data()));
413
414     builder.append(String::format("AXFocusable: %d\n", element->isFocusable()));
415     builder.append(String::format("AXFocused: %d\n", element->isFocused()));
416     builder.append(String::format("AXSelectable: %d\n", element->isSelectable()));
417     builder.append(String::format("AXSelected: %d\n", element->isSelected()));
418     builder.append(String::format("AXMultiSelectable: %d\n", element->isMultiSelectable()));
419     builder.append(String::format("AXEnabled: %d\n", element->isEnabled()));
420     builder.append(String::format("AXExpanded: %d\n", element->isExpanded()));
421     builder.append(String::format("AXRequired: %d\n", element->isRequired()));
422     builder.append(String::format("AXChecked: %d\n", element->isChecked()));
423
424     // We append the ATK specific attributes as a single line at the end.
425     builder.append("AXPlatformAttributes: ");
426     builder.append(getAtkAttributeSetAsString(element->platformUIElement().get(), ObjectAttributeType));
427
428     return builder.toString();
429 }
430
431 } // namespace
432
433 AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
434     : m_element(element)
435 {
436 }
437
438 AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other)
439     : JSWrappable()
440     , m_element(other.m_element)
441 {
442 }
443
444 AccessibilityUIElement::~AccessibilityUIElement()
445 {
446 }
447
448 bool AccessibilityUIElement::isEqual(AccessibilityUIElement* otherElement)
449 {
450     return m_element == otherElement->platformUIElement();
451 }
452
453 void AccessibilityUIElement::getChildren(Vector<RefPtr<AccessibilityUIElement> >& children)
454 {
455     if (!ATK_IS_OBJECT(m_element.get()))
456         return;
457
458     int count = childrenCount();
459     for (int i = 0; i < count; i++) {
460         GRefPtr<AtkObject> child = adoptGRef(atk_object_ref_accessible_child(ATK_OBJECT(m_element.get()), i));
461         children.append(AccessibilityUIElement::create(child.get()));
462     }
463 }
464
465 void AccessibilityUIElement::getChildrenWithRange(Vector<RefPtr<AccessibilityUIElement> >& children, unsigned location, unsigned length)
466 {
467     if (!ATK_IS_OBJECT(m_element.get()))
468         return;
469     unsigned end = location + length;
470     for (unsigned i = location; i < end; i++) {
471         GRefPtr<AtkObject> child = adoptGRef(atk_object_ref_accessible_child(ATK_OBJECT(m_element.get()), i));
472         children.append(AccessibilityUIElement::create(child.get()));
473     }
474 }
475
476 int AccessibilityUIElement::childrenCount()
477 {
478     if (!ATK_IS_OBJECT(m_element.get()))
479         return 0;
480
481     return atk_object_get_n_accessible_children(ATK_OBJECT(m_element.get()));
482 }
483
484 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::elementAtPoint(int x, int y)
485 {
486     if (!ATK_IS_COMPONENT(m_element.get()))
487         return 0;
488
489     GRefPtr<AtkObject> objectAtPoint = adoptGRef(atk_component_ref_accessible_at_point(ATK_COMPONENT(m_element.get()), x, y, ATK_XY_WINDOW));
490     return objectAtPoint ? AccessibilityUIElement::create(objectAtPoint.get()) : 0;
491 }
492
493 unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element)
494 {
495     if (!ATK_IS_OBJECT(m_element.get()))
496         return 0;
497
498     Vector<RefPtr<AccessibilityUIElement> > children;
499     getChildren(children);
500
501     unsigned count = children.size();
502     for (unsigned i = 0; i < count; i++)
503         if (children[i]->isEqual(element))
504             return i;
505
506     return 0;
507 }
508
509 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::childAtIndex(unsigned index)
510 {
511     if (!ATK_IS_OBJECT(m_element.get()))
512         return 0;
513
514     Vector<RefPtr<AccessibilityUIElement> > children;
515     getChildrenWithRange(children, index, 1);
516
517     if (children.size() == 1)
518         return children[0];
519
520     return 0;
521 }
522
523 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::linkedUIElementAtIndex(unsigned index)
524 {
525     // FIXME: implement
526     return 0;
527 }
528
529 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned index)
530 {
531     // FIXME: implement
532     return 0;
533 }
534
535 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned index)
536 {
537     // FIXME: implement
538     return 0;
539 }
540
541 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedRowAtIndex(unsigned index)
542 {
543     // FIXME: implement
544     return 0;
545 }
546
547 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::rowAtIndex(unsigned index)
548 {
549     // FIXME: implement
550     return 0;
551 }
552
553 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedChildAtIndex(unsigned index) const
554 {
555     // FIXME: implement
556     return 0;
557 }
558
559 unsigned AccessibilityUIElement::selectedChildrenCount() const
560 {
561     // FIXME: implement
562     return 0;
563 }
564
565 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedRowAtIndex(unsigned index)
566 {
567     // FIXME: implement
568     return 0;
569 }
570
571 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::titleUIElement()
572 {
573     if (!ATK_IS_OBJECT(m_element.get()))
574         return 0;
575
576     AtkRelationSet* set = atk_object_ref_relation_set(ATK_OBJECT(m_element.get()));
577     if (!set)
578         return 0;
579
580     AtkObject* target = 0;
581     int count = atk_relation_set_get_n_relations(set);
582     for (int i = 0; i < count; i++) {
583         AtkRelation* relation = atk_relation_set_get_relation(set, i);
584         if (atk_relation_get_relation_type(relation) == ATK_RELATION_LABELLED_BY) {
585             GPtrArray* targetList = atk_relation_get_target(relation);
586             if (targetList->len)
587                 target = static_cast<AtkObject*>(g_ptr_array_index(targetList, 0));
588         }
589     }
590
591     g_object_unref(set);
592     return target ? AccessibilityUIElement::create(target) : 0;
593 }
594
595 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::parentElement()
596 {
597     if (!ATK_IS_OBJECT(m_element.get()))
598         return 0;
599
600     AtkObject* parent = atk_object_get_parent(ATK_OBJECT(m_element.get()));
601     return parent ? AccessibilityUIElement::create(parent) : 0;
602 }
603
604 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedByRow()
605 {
606     // FIXME: implement
607     return 0;
608 }
609
610 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfLinkedUIElements()
611 {
612     // FIXME: implement
613     return JSStringCreateWithCharacters(0, 0);
614 }
615
616 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfDocumentLinks()
617 {
618     // FIXME: implement
619     return JSStringCreateWithCharacters(0, 0);
620 }
621
622 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfChildren()
623 {
624     if (!ATK_IS_OBJECT(m_element.get()))
625         return JSStringCreateWithCharacters(0, 0);
626
627     Vector<RefPtr<AccessibilityUIElement> > children;
628     getChildren(children);
629
630     StringBuilder builder;
631     for (Vector<RefPtr<AccessibilityUIElement> >::iterator it = children.begin(); it != children.end(); ++it) {
632         builder.append(attributesOfElement(it->get()));
633         builder.append("\n------------\n");
634     }
635
636     return JSStringCreateWithUTF8CString(builder.toString().utf8().data());
637 }
638
639 JSRetainPtr<JSStringRef> AccessibilityUIElement::allAttributes()
640 {
641     if (!ATK_IS_OBJECT(m_element.get()))
642         return JSStringCreateWithCharacters(0, 0);
643
644     return JSStringCreateWithUTF8CString(attributesOfElement(this).utf8().data());
645 }
646
647 JSRetainPtr<JSStringRef> AccessibilityUIElement::stringAttributeValue(JSStringRef attribute)
648 {
649     if (!ATK_IS_OBJECT(m_element.get()))
650         return JSStringCreateWithCharacters(0, 0);
651
652     String atkAttributeName = coreAttributeToAtkAttribute(attribute);
653
654     // Try object attributes first.
655     String attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, atkAttributeName);
656
657     // Try text attributes if the requested one was not found and we have an AtkText object.
658     if (attributeValue.isEmpty() && ATK_IS_TEXT(m_element.get()))
659         attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), TextAttributeType, atkAttributeName);
660
661     return JSStringCreateWithUTF8CString(attributeValue.utf8().data());
662 }
663
664 double AccessibilityUIElement::numberAttributeValue(JSStringRef attribute)
665 {
666     // FIXME: implement
667     return 0;
668 }
669
670 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementAttributeValue(JSStringRef attribute) const
671 {
672     // FIXME: implement
673     return 0;
674 }
675
676 bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute)
677 {
678     // FIXME: implement
679     return false;
680 }
681
682 bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute)
683 {
684     // FIXME: implement
685     return false;
686 }
687
688 bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute)
689 {
690     if (!ATK_IS_OBJECT(m_element.get()))
691         return false;
692
693     String atkAttributeName = coreAttributeToAtkAttribute(attribute);
694     if (atkAttributeName.isEmpty())
695         return false;
696
697     // For now, an attribute is supported whether it's exposed as a object or a text attribute.
698     String attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, atkAttributeName);
699     if (attributeValue.isEmpty())
700         attributeValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), TextAttributeType, atkAttributeName);
701
702     return !attributeValue.isEmpty();
703 }
704
705 JSRetainPtr<JSStringRef> AccessibilityUIElement::parameterizedAttributeNames()
706 {
707     // FIXME: implement
708     return JSStringCreateWithCharacters(0, 0);
709 }
710
711 JSRetainPtr<JSStringRef> AccessibilityUIElement::role()
712 {
713     if (!ATK_IS_OBJECT(m_element.get()))
714         return JSStringCreateWithCharacters(0, 0);
715
716     AtkRole role = atk_object_get_role(ATK_OBJECT(m_element.get()));
717     if (!role)
718         return JSStringCreateWithCharacters(0, 0);
719
720     GOwnPtr<char> roleStringWithPrefix(g_strdup_printf("AXRole: %s", roleToString(role)));
721     return JSStringCreateWithUTF8CString(roleStringWithPrefix.get());
722 }
723
724 JSRetainPtr<JSStringRef> AccessibilityUIElement::subrole()
725 {
726     // FIXME: implement
727     return JSStringCreateWithCharacters(0, 0);
728 }
729
730 JSRetainPtr<JSStringRef> AccessibilityUIElement::roleDescription()
731 {
732     // FIXME: implement
733     return JSStringCreateWithCharacters(0, 0);
734 }
735
736 JSRetainPtr<JSStringRef> AccessibilityUIElement::title()
737 {
738     if (!ATK_IS_OBJECT(m_element.get()))
739         return JSStringCreateWithCharacters(0, 0);
740
741     const gchar* name = atk_object_get_name(ATK_OBJECT(m_element.get()));
742     GOwnPtr<gchar> axTitle(g_strdup_printf("AXTitle: %s", name ? name : ""));
743
744     return JSStringCreateWithUTF8CString(axTitle.get());
745 }
746
747 JSRetainPtr<JSStringRef> AccessibilityUIElement::description()
748 {
749     if (!ATK_IS_OBJECT(m_element.get()))
750         return JSStringCreateWithCharacters(0, 0);
751
752     const gchar* description = atk_object_get_description(ATK_OBJECT(m_element.get()));
753     if (!description)
754         return JSStringCreateWithCharacters(0, 0);
755
756     GOwnPtr<gchar> axDesc(g_strdup_printf("AXDescription: %s", description));
757
758     return JSStringCreateWithUTF8CString(axDesc.get());
759 }
760
761 JSRetainPtr<JSStringRef> AccessibilityUIElement::orientation() const
762 {
763     if (!ATK_IS_OBJECT(m_element.get()))
764         return JSStringCreateWithCharacters(0, 0);
765
766     const gchar* axOrientation = 0;
767     if (checkElementState(m_element.get(), ATK_STATE_HORIZONTAL))
768         axOrientation = "AXOrientation: AXHorizontalOrientation";
769     else if (checkElementState(m_element.get(), ATK_STATE_VERTICAL))
770         axOrientation = "AXOrientation: AXVerticalOrientation";
771
772     if (!axOrientation)
773         return JSStringCreateWithCharacters(0, 0);
774
775     return JSStringCreateWithUTF8CString(axOrientation);
776 }
777
778 JSRetainPtr<JSStringRef> AccessibilityUIElement::stringValue()
779 {
780     if (!ATK_IS_TEXT(m_element.get()))
781         return JSStringCreateWithCharacters(0, 0);
782
783     GOwnPtr<gchar> text(atk_text_get_text(ATK_TEXT(m_element.get()), 0, -1));
784     GOwnPtr<gchar> textWithReplacedCharacters(replaceCharactersForResults(text.get()));
785     GOwnPtr<gchar> axValue(g_strdup_printf("AXValue: %s", textWithReplacedCharacters.get()));
786
787     return JSStringCreateWithUTF8CString(axValue.get());
788 }
789
790 JSRetainPtr<JSStringRef> AccessibilityUIElement::language()
791 {
792     if (!ATK_IS_OBJECT(m_element.get()))
793         return JSStringCreateWithCharacters(0, 0);
794
795     const gchar* locale = atk_object_get_object_locale(ATK_OBJECT(m_element.get()));
796     if (!locale)
797         return JSStringCreateWithCharacters(0, 0);
798
799     GOwnPtr<char> axValue(g_strdup_printf("AXLanguage: %s", locale));
800     return JSStringCreateWithUTF8CString(axValue.get());
801 }
802
803 JSRetainPtr<JSStringRef> AccessibilityUIElement::helpText() const
804 {
805     // FIXME: We need to provide a proper implementation for this that does
806     // not depend on Mac specific concepts such as ATK_RELATION_DESCRIBED_BY,
807     // once it's implemented (see http://webkit.org/b/121684).
808     return JSStringCreateWithCharacters(0, 0);
809 }
810
811 double AccessibilityUIElement::x()
812 {
813     if (!ATK_IS_COMPONENT(m_element.get()))
814         return 0;
815
816     int x, y;
817     atk_component_get_position(ATK_COMPONENT(m_element.get()), &x, &y, ATK_XY_SCREEN);
818     return x;
819 }
820
821 double AccessibilityUIElement::y()
822 {
823     if (!ATK_IS_COMPONENT(m_element.get()))
824         return 0;
825
826     int x, y;
827     atk_component_get_position(ATK_COMPONENT(m_element.get()), &x, &y, ATK_XY_SCREEN);
828     return y;
829 }
830
831 double AccessibilityUIElement::width()
832 {
833     if (!ATK_IS_COMPONENT(m_element.get()))
834         return 0;
835
836     int width, height;
837     atk_component_get_size(ATK_COMPONENT(m_element.get()), &width, &height);
838     return width;
839 }
840
841 double AccessibilityUIElement::height()
842 {
843     if (!ATK_IS_COMPONENT(m_element.get()))
844         return 0;
845
846     int width, height;
847     atk_component_get_size(ATK_COMPONENT(m_element.get()), &width, &height);
848     return height;
849 }
850
851 double AccessibilityUIElement::clickPointX()
852 {
853     // FIXME: implement
854     return 0;
855 }
856
857 double AccessibilityUIElement::clickPointY()
858 {
859     // FIXME: implement
860     return 0;
861 }
862
863 double AccessibilityUIElement::intValue() const
864 {
865     if (!ATK_IS_OBJECT(m_element.get()))
866         return 0;
867
868     if (ATK_IS_VALUE(m_element.get())) {
869         GValue value = G_VALUE_INIT;
870         atk_value_get_current_value(ATK_VALUE(m_element.get()), &value);
871         if (!G_VALUE_HOLDS_FLOAT(&value))
872             return 0;
873         return g_value_get_float(&value);
874     }
875
876     // Consider headings as an special case when returning the "int value" of
877     // an AccessibilityUIElement, so we can reuse some tests to check the level
878     // both for HTML headings and objects with the aria-level attribute.
879     if (atk_object_get_role(ATK_OBJECT(m_element.get())) == ATK_ROLE_HEADING) {
880         String headingLevel = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, "level");
881         bool ok;
882         double headingLevelValue = headingLevel.toDouble(&ok);
883         if (ok)
884             return headingLevelValue;
885     }
886
887     return 0;
888 }
889
890 double AccessibilityUIElement::minValue()
891 {
892     if (!ATK_IS_VALUE(m_element.get()))
893         return 0;
894
895     GValue value = G_VALUE_INIT;
896     atk_value_get_minimum_value(ATK_VALUE(m_element.get()), &value);
897     if (!G_VALUE_HOLDS_FLOAT(&value))
898         return 0;
899
900     return g_value_get_float(&value);
901 }
902
903 double AccessibilityUIElement::maxValue()
904 {
905     if (!ATK_IS_VALUE(m_element.get()))
906         return 0;
907
908     GValue value = G_VALUE_INIT;
909     atk_value_get_maximum_value(ATK_VALUE(m_element.get()), &value);
910     if (!G_VALUE_HOLDS_FLOAT(&value))
911         return 0;
912
913     return g_value_get_float(&value);
914 }
915
916 JSRetainPtr<JSStringRef> AccessibilityUIElement::valueDescription()
917 {
918     // FIXME: implement
919     return JSStringCreateWithCharacters(0, 0);
920 }
921
922 int AccessibilityUIElement::insertionPointLineNumber()
923 {
924     // FIXME: implement
925     return -1;
926 }
927
928 bool AccessibilityUIElement::isPressActionSupported()
929 {
930     // FIXME: implement
931     return false;
932 }
933
934 bool AccessibilityUIElement::isIncrementActionSupported()
935 {
936     // FIXME: implement
937     return false;
938 }
939
940 bool AccessibilityUIElement::isDecrementActionSupported()
941 {
942     // FIXME: implement
943     return false;
944 }
945
946 bool AccessibilityUIElement::isEnabled()
947 {
948     return checkElementState(m_element.get(), ATK_STATE_ENABLED);
949 }
950
951 bool AccessibilityUIElement::isRequired() const
952 {
953     return checkElementState(m_element.get(), ATK_STATE_REQUIRED);
954 }
955
956 bool AccessibilityUIElement::isFocused() const
957 {
958     return checkElementState(m_element.get(), ATK_STATE_FOCUSED);
959 }
960
961 bool AccessibilityUIElement::isSelected() const
962 {
963     return checkElementState(m_element.get(), ATK_STATE_SELECTED);
964 }
965
966 bool AccessibilityUIElement::isExpanded() const
967 {
968     return checkElementState(m_element.get(), ATK_STATE_EXPANDED);
969 }
970
971 bool AccessibilityUIElement::isChecked() const
972 {
973     return checkElementState(m_element.get(), ATK_STATE_CHECKED);
974 }
975
976 int AccessibilityUIElement::hierarchicalLevel() const
977 {
978     // FIXME: implement
979     return 0;
980 }
981
982 JSRetainPtr<JSStringRef> AccessibilityUIElement::speak()
983 {
984     // FIXME: implement
985     return JSStringCreateWithCharacters(0, 0);
986 }
987
988 bool AccessibilityUIElement::ariaIsGrabbed() const
989 {
990     // FIXME: implement
991     return false;
992 }
993
994 JSRetainPtr<JSStringRef> AccessibilityUIElement::ariaDropEffects() const
995 {
996     // FIXME: implement
997     return JSStringCreateWithCharacters(0, 0);
998 }
999
1000 // parameterized attributes
1001 int AccessibilityUIElement::lineForIndex(int index)
1002 {
1003     // FIXME: implement
1004     return 0;
1005 }
1006
1007 JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForLine(int line)
1008 {
1009     // FIXME: implement
1010     return JSStringCreateWithCharacters(0, 0);
1011 }
1012
1013 JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForPosition(int x, int y)
1014 {
1015     // FIXME: implement
1016     return JSStringCreateWithCharacters(0, 0);
1017 }
1018
1019 JSRetainPtr<JSStringRef> AccessibilityUIElement::boundsForRange(unsigned location, unsigned length)
1020 {
1021     // FIXME: implement
1022     return JSStringCreateWithCharacters(0, 0);
1023 }
1024
1025 JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForRange(unsigned location, unsigned length)
1026 {
1027     // FIXME: implement
1028     return JSStringCreateWithCharacters(0, 0);
1029 }
1030
1031 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForRange(unsigned location, unsigned length)
1032 {
1033     // FIXME: implement
1034     return JSStringCreateWithCharacters(0, 0);
1035 }
1036
1037 bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location, unsigned length)
1038 {
1039     // FIXME: implement
1040     return false;
1041 }
1042
1043 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly)
1044 {
1045     // FIXME: implement
1046     return 0;
1047 }
1048
1049 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumnHeaders()
1050 {
1051     // FIXME: implement
1052     return JSStringCreateWithCharacters(0, 0);
1053 }
1054
1055 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRowHeaders()
1056 {
1057     // FIXME: implement
1058     return JSStringCreateWithCharacters(0, 0);
1059 }
1060
1061 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumns()
1062 {
1063     // FIXME: implement
1064     return JSStringCreateWithCharacters(0, 0);
1065 }
1066
1067 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRows()
1068 {
1069     // FIXME: implement
1070     return JSStringCreateWithCharacters(0, 0);
1071 }
1072
1073 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfVisibleCells()
1074 {
1075     // FIXME: implement
1076     return JSStringCreateWithCharacters(0, 0);
1077 }
1078
1079 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfHeader()
1080 {
1081     // FIXME: implement
1082     return JSStringCreateWithCharacters(0, 0);
1083 }
1084
1085 int AccessibilityUIElement::rowCount()
1086 {
1087     if (!ATK_IS_TABLE(m_element.get()))
1088         return 0;
1089
1090     return atk_table_get_n_rows(ATK_TABLE(m_element.get()));
1091 }
1092
1093 int AccessibilityUIElement::columnCount()
1094 {
1095     if (!ATK_IS_TABLE(m_element.get()))
1096         return 0;
1097
1098     return atk_table_get_n_columns(ATK_TABLE(m_element.get()));
1099 }
1100
1101 int AccessibilityUIElement::indexInTable()
1102 {
1103     // FIXME: implement
1104     return -1;
1105 }
1106
1107 JSRetainPtr<JSStringRef> AccessibilityUIElement::rowIndexRange()
1108 {
1109     // Range in table for rows.
1110     return indexRangeInTable(m_element.get(), true);
1111 }
1112
1113 JSRetainPtr<JSStringRef> AccessibilityUIElement::columnIndexRange()
1114 {
1115     // Range in table for columns.
1116     return indexRangeInTable(m_element.get(), false);
1117 }
1118
1119 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::cellForColumnAndRow(unsigned col, unsigned row)
1120 {
1121     if (!ATK_IS_TABLE(m_element.get()))
1122         return 0;
1123
1124     // Adopt the AtkObject representing the cell because
1125     // at_table_ref_at() transfers full ownership.
1126     GRefPtr<AtkObject> foundCell = adoptGRef(atk_table_ref_at(ATK_TABLE(m_element.get()), row, col));
1127     return foundCell ? AccessibilityUIElement::create(foundCell.get()) : 0;
1128 }
1129
1130 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::horizontalScrollbar() const
1131 {
1132     // FIXME: implement
1133     return 0;
1134 }
1135
1136 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::verticalScrollbar() const
1137 {
1138     // FIXME: implement
1139     return 0;
1140 }
1141
1142 JSRetainPtr<JSStringRef> AccessibilityUIElement::selectedTextRange()
1143 {
1144     // FIXME: implement
1145     return JSStringCreateWithCharacters(0, 0);
1146 }
1147
1148 void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length)
1149 {
1150     // FIXME: implement
1151 }
1152
1153 void AccessibilityUIElement::increment()
1154 {
1155     alterCurrentValue(m_element.get(), 1);
1156 }
1157
1158 void AccessibilityUIElement::decrement()
1159 {
1160     alterCurrentValue(m_element.get(), -1);
1161 }
1162
1163 void AccessibilityUIElement::showMenu()
1164 {
1165     // FIXME: implement
1166 }
1167
1168 void AccessibilityUIElement::press()
1169 {
1170     if (!ATK_IS_ACTION(m_element.get()))
1171         return;
1172
1173     // Only one action per object is supported so far.
1174     atk_action_do_action(ATK_ACTION(m_element.get()), 0);
1175 }
1176
1177 void AccessibilityUIElement::setSelectedChild(AccessibilityUIElement* element) const
1178 {
1179     // FIXME: implement
1180 }
1181
1182 JSRetainPtr<JSStringRef> AccessibilityUIElement::accessibilityValue() const
1183 {
1184     // FIXME: implement
1185     return JSStringCreateWithCharacters(0, 0);
1186 }
1187
1188 JSRetainPtr<JSStringRef> AccessibilityUIElement::documentEncoding()
1189 {
1190     if (!ATK_IS_DOCUMENT(m_element.get()))
1191         return JSStringCreateWithCharacters(0, 0);
1192
1193     AtkRole role = atk_object_get_role(ATK_OBJECT(m_element.get()));
1194     if (role != ATK_ROLE_DOCUMENT_FRAME)
1195         return JSStringCreateWithCharacters(0, 0);
1196
1197     return JSStringCreateWithUTF8CString(atk_document_get_attribute_value(ATK_DOCUMENT(m_element.get()), "Encoding"));
1198 }
1199
1200 JSRetainPtr<JSStringRef> AccessibilityUIElement::documentURI()
1201 {
1202     if (!ATK_IS_DOCUMENT(m_element.get()))
1203         return JSStringCreateWithCharacters(0, 0);
1204
1205     AtkRole role = atk_object_get_role(ATK_OBJECT(m_element.get()));
1206     if (role != ATK_ROLE_DOCUMENT_FRAME)
1207         return JSStringCreateWithCharacters(0, 0);
1208
1209     return JSStringCreateWithUTF8CString(atk_document_get_attribute_value(ATK_DOCUMENT(m_element.get()), "URI"));
1210 }
1211
1212 JSRetainPtr<JSStringRef> AccessibilityUIElement::url()
1213 {
1214     // FIXME: implement
1215     return JSStringCreateWithCharacters(0, 0);
1216 }
1217
1218 bool AccessibilityUIElement::addNotificationListener(JSValueRef functionCallback)
1219 {
1220     if (!functionCallback)
1221         return false;
1222
1223     // Only one notification listener per element.
1224     if (m_notificationHandler)
1225         return false;
1226
1227     m_notificationHandler = AccessibilityNotificationHandler::create();
1228     m_notificationHandler->setPlatformElement(platformUIElement());
1229     m_notificationHandler->setNotificationFunctionCallback(functionCallback);
1230
1231     return true;
1232 }
1233
1234 bool AccessibilityUIElement::removeNotificationListener()
1235 {
1236     // Programmers should not be trying to remove a listener that's already removed.
1237     ASSERT(m_notificationHandler);
1238     m_notificationHandler = 0;
1239
1240     return true;
1241 }
1242
1243 bool AccessibilityUIElement::isFocusable() const
1244 {
1245     return checkElementState(m_element.get(), ATK_STATE_FOCUSABLE);
1246 }
1247
1248 bool AccessibilityUIElement::isSelectable() const
1249 {
1250     return checkElementState(m_element.get(), ATK_STATE_SELECTABLE);
1251 }
1252
1253 bool AccessibilityUIElement::isMultiSelectable() const
1254 {
1255     return checkElementState(m_element.get(), ATK_STATE_MULTISELECTABLE);
1256 }
1257
1258 bool AccessibilityUIElement::isVisible() const
1259 {
1260     return checkElementState(m_element.get(), ATK_STATE_VISIBLE);
1261 }
1262
1263 bool AccessibilityUIElement::isOffScreen() const
1264 {
1265     // FIXME: implement
1266     return false;
1267 }
1268
1269 bool AccessibilityUIElement::isCollapsed() const
1270 {
1271     // FIXME: implement
1272     return false;
1273 }
1274
1275 bool AccessibilityUIElement::isIgnored() const
1276 {
1277     // FIXME: implement
1278     return false;
1279 }
1280
1281 bool AccessibilityUIElement::hasPopup() const
1282 {
1283     if (!ATK_IS_OBJECT(m_element.get()))
1284         return false;
1285
1286     String hasPopupValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, "haspopup");
1287     return equalIgnoringCase(hasPopupValue, "true");
1288 }
1289
1290 void AccessibilityUIElement::takeFocus()
1291 {
1292     // FIXME: implement
1293 }
1294
1295 void AccessibilityUIElement::takeSelection()
1296 {
1297     // FIXME: implement
1298 }
1299
1300 void AccessibilityUIElement::addSelection()
1301 {
1302     // FIXME: implement
1303 }
1304
1305 void AccessibilityUIElement::removeSelection()
1306 {
1307     // FIXME: implement
1308 }
1309
1310 // Text markers
1311 PassRefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement* element)
1312 {
1313     // FIXME: implement
1314     return 0;
1315 }
1316
1317 int AccessibilityUIElement::textMarkerRangeLength(AccessibilityTextMarkerRange* range)
1318 {
1319     // FIXME: implement
1320     return 0;
1321 }
1322
1323 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousTextMarker(AccessibilityTextMarker* textMarker)
1324 {
1325     // FIXME: implement
1326     return 0;
1327 }
1328
1329 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextTextMarker(AccessibilityTextMarker* textMarker)
1330 {
1331     // FIXME: implement
1332     return 0;
1333 }
1334
1335 JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForTextMarkerRange(AccessibilityTextMarkerRange* markerRange)
1336 {
1337     // FIXME: implement
1338     return JSStringCreateWithCharacters(0, 0);
1339 }
1340
1341 PassRefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForMarkers(AccessibilityTextMarker* startMarker, AccessibilityTextMarker* endMarker)
1342 {
1343     // FIXME: implement
1344     return 0;
1345 }
1346
1347 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
1348 {
1349     // FIXME: implement
1350     return 0;
1351 }
1352
1353 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
1354 {
1355     // FIXME: implement
1356     return 0;
1357 }
1358
1359 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForPoint(int x, int y)
1360 {
1361     // FIXME: implement
1362     return 0;
1363 }
1364
1365 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::accessibilityElementForTextMarker(AccessibilityTextMarker* marker)
1366 {
1367     // FIXME: implement
1368     return 0;
1369 }
1370
1371 bool AccessibilityUIElement::attributedStringForTextMarkerRangeContainsAttribute(JSStringRef attribute, AccessibilityTextMarkerRange* range)
1372 {
1373     // FIXME: implement
1374     return false;
1375 }
1376
1377 int AccessibilityUIElement::indexForTextMarker(AccessibilityTextMarker* marker)
1378 {
1379     // FIXME: implement
1380     return -1;
1381 }
1382
1383 bool AccessibilityUIElement::isTextMarkerValid(AccessibilityTextMarker* textMarker)
1384 {
1385     // FIXME: implement
1386     return false;
1387 }
1388
1389 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForIndex(int textIndex)
1390 {
1391     // FIXME: implement
1392     return 0;
1393 }
1394
1395 void AccessibilityUIElement::scrollToMakeVisible()
1396 {
1397     // FIXME: implement
1398 }
1399
1400 JSRetainPtr<JSStringRef> AccessibilityUIElement::supportedActions() const
1401 {
1402     // FIXME: implement
1403     return 0;
1404 }
1405
1406 JSRetainPtr<JSStringRef> AccessibilityUIElement::pathDescription() const
1407 {
1408     notImplemented();
1409     return 0;
1410 }
1411
1412 JSRetainPtr<JSStringRef> AccessibilityUIElement::mathPostscriptsDescription() const
1413 {
1414     notImplemented();
1415     return 0;
1416 }
1417
1418 JSRetainPtr<JSStringRef> AccessibilityUIElement::mathPrescriptsDescription() const
1419 {
1420     notImplemented();
1421     return 0;
1422 }
1423
1424 JSRetainPtr<JSStringRef> AccessibilityUIElement::classList() const
1425 {
1426     notImplemented();
1427     return 0;
1428 }
1429
1430 } // namespace WTR
1431
1432 #endif