[GTK] Missing call to g_object_ref while retrieving accessible table cells
[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  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "config.h"
28 #include "AccessibilityUIElement.h"
29
30 #if HAVE(ACCESSIBILITY)
31
32 #include "InjectedBundle.h"
33 #include "InjectedBundlePage.h"
34 #include <JavaScriptCore/JSStringRef.h>
35 #include <atk/atk.h>
36 #include <wtf/Assertions.h>
37 #include <wtf/gobject/GOwnPtr.h>
38 #include <wtf/gobject/GRefPtr.h>
39 #include <wtf/text/CString.h>
40 #include <wtf/text/WTFString.h>
41 #include <wtf/unicode/CharacterNames.h>
42
43 namespace WTR {
44
45 static gchar* attributeSetToString(AtkAttributeSet* attributeSet)
46 {
47     GString* str = g_string_new(0);
48     for (GSList* attributes = attributeSet; attributes; attributes = attributes->next) {
49         AtkAttribute* attribute = static_cast<AtkAttribute*>(attributes->data);
50         GOwnPtr<gchar> attributeData(g_strconcat(attribute->name, ":", attribute->value, NULL));
51         g_string_append(str, attributeData.get());
52         if (attributes->next)
53             g_string_append(str, ", ");
54     }
55
56     return g_string_free(str, FALSE);
57 }
58
59 static bool checkElementState(PlatformUIElement element, AtkStateType stateType)
60 {
61     if (!ATK_IS_OBJECT(element))
62         return false;
63
64     GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(element)));
65     return atk_state_set_contains_state(stateSet.get(), stateType);
66 }
67
68 static JSStringRef indexRangeInTable(PlatformUIElement element, bool isRowRange)
69 {
70     GOwnPtr<gchar> rangeString(g_strdup("{0, 0}"));
71
72     if (!element || !ATK_IS_OBJECT(element))
73         return JSStringCreateWithUTF8CString(rangeString.get());
74
75     AtkObject* axTable = atk_object_get_parent(ATK_OBJECT(element));
76     if (!axTable || !ATK_IS_TABLE(axTable))
77         return JSStringCreateWithUTF8CString(rangeString.get());
78
79     // Look for the cell in the table.
80     gint indexInParent = atk_object_get_index_in_parent(ATK_OBJECT(element));
81     if (indexInParent == -1)
82         return JSStringCreateWithUTF8CString(rangeString.get());
83
84     int row = -1;
85     int column = -1;
86     row = atk_table_get_row_at_index(ATK_TABLE(axTable), indexInParent);
87     column = atk_table_get_column_at_index(ATK_TABLE(axTable), indexInParent);
88
89     // Get the actual values, if row and columns are valid values.
90     if (row != -1 && column != -1) {
91         int base = 0;
92         int length = 0;
93         if (isRowRange) {
94             base = row;
95             length = atk_table_get_row_extent_at(ATK_TABLE(axTable), row, column);
96         } else {
97             base = column;
98             length = atk_table_get_column_extent_at(ATK_TABLE(axTable), row, column);
99         }
100         rangeString.set(g_strdup_printf("{%d, %d}", base, length));
101     }
102
103     return JSStringCreateWithUTF8CString(rangeString.get());
104 }
105
106 static void alterCurrentValue(PlatformUIElement element, int factor)
107 {
108     if (!element || !ATK_IS_VALUE(element))
109         return;
110
111     GValue currentValue = G_VALUE_INIT;
112     atk_value_get_current_value(ATK_VALUE(element), &currentValue);
113
114     GValue increment = G_VALUE_INIT;
115     atk_value_get_minimum_increment(ATK_VALUE(element), &increment);
116
117     GValue newValue = G_VALUE_INIT;
118     g_value_init(&newValue, G_TYPE_DOUBLE);
119
120     g_value_set_float(&newValue, g_value_get_float(&currentValue) + factor * g_value_get_float(&increment));
121     atk_value_set_current_value(ATK_VALUE(element), &newValue);
122
123     g_value_unset(&newValue);
124     g_value_unset(&increment);
125     g_value_unset(&currentValue);
126 }
127
128 static gchar* replaceCharactersForResults(gchar* str)
129 {
130     WTF::String uString = WTF::String::fromUTF8(str);
131
132     // The object replacement character is passed along to ATs so we need to be
133     // able to test for their presence and do so without causing test failures.
134     uString.replace(objectReplacementCharacter, "<obj>");
135
136     // The presence of newline characters in accessible text of a single object
137     // is appropriate, but it makes test results (especially the accessible tree)
138     // harder to read.
139     uString.replace("\n", "<\\n>");
140
141     return g_strdup(uString.utf8().data());
142 }
143
144 static const gchar* roleToString(AtkRole role)
145 {
146     switch (role) {
147     case ATK_ROLE_ALERT:
148         return "AXRole: AXAlert";
149     case ATK_ROLE_CANVAS:
150         return "AXRole: AXCanvas";
151     case ATK_ROLE_CHECK_BOX:
152         return "AXRole: AXCheckBox";
153     case ATK_ROLE_COLUMN_HEADER:
154         return "AXRole: AXColumnHeader";
155     case ATK_ROLE_COMBO_BOX:
156         return "AXRole: AXComboBox";
157     case ATK_ROLE_DOCUMENT_FRAME:
158         return "AXRole: AXWebArea";
159     case ATK_ROLE_ENTRY:
160         return "AXRole: AXTextField";
161     case ATK_ROLE_FOOTER:
162         return "AXRole: AXFooter";
163     case ATK_ROLE_FORM:
164         return "AXRole: AXForm";
165     case ATK_ROLE_GROUPING:
166         return "AXRole: AXGroup";
167     case ATK_ROLE_HEADING:
168         return "AXRole: AXHeading";
169     case ATK_ROLE_IMAGE:
170         return "AXRole: AXImage";
171     case ATK_ROLE_IMAGE_MAP:
172         return "AXRole: AXImageMap";
173     case ATK_ROLE_LABEL:
174         return "AXRole: AXLabel";
175     case ATK_ROLE_LINK:
176         return "AXRole: AXLink";
177     case ATK_ROLE_LIST:
178         return "AXRole: AXList";
179     case ATK_ROLE_LIST_BOX:
180         return "AXRole: AXListBox";
181     case ATK_ROLE_LIST_ITEM:
182         return "AXRole: AXListItem";
183     case ATK_ROLE_MENU:
184         return "AXRole: AXMenu";
185     case ATK_ROLE_MENU_BAR:
186         return "AXRole: AXMenuBar";
187     case ATK_ROLE_MENU_ITEM:
188         return "AXRole: AXMenuItem";
189     case ATK_ROLE_PAGE_TAB:
190         return "AXRole: AXTab";
191     case ATK_ROLE_PAGE_TAB_LIST:
192         return "AXRole: AXTabGroup";
193     case ATK_ROLE_PANEL:
194         return "AXRole: AXGroup";
195     case ATK_ROLE_PARAGRAPH:
196         return "AXRole: AXParagraph";
197     case ATK_ROLE_PASSWORD_TEXT:
198         return "AXRole: AXPasswordField";
199     case ATK_ROLE_PUSH_BUTTON:
200         return "AXRole: AXButton";
201     case ATK_ROLE_RADIO_BUTTON:
202         return "AXRole: AXRadioButton";
203     case ATK_ROLE_ROW_HEADER:
204         return "AXRole: AXRowHeader";
205     case ATK_ROLE_RULER:
206         return "AXRole: AXRuler";
207     case ATK_ROLE_SCROLL_BAR:
208         return "AXRole: AXScrollBar";
209     case ATK_ROLE_SCROLL_PANE:
210         return "AXRole: AXScrollArea";
211     case ATK_ROLE_SECTION:
212         return "AXRole: AXDiv";
213     case ATK_ROLE_SEPARATOR:
214         return "AXRole: AXHorizontalRule";
215     case ATK_ROLE_SLIDER:
216         return "AXRole: AXSlider";
217     case ATK_ROLE_SPIN_BUTTON:
218         return "AXRole: AXSpinButton";
219     case ATK_ROLE_TABLE:
220         return "AXRole: AXTable";
221     case ATK_ROLE_TABLE_CELL:
222         return "AXRole: AXCell";
223     case ATK_ROLE_TABLE_COLUMN_HEADER:
224         return "AXRole: AXColumnHeader";
225     case ATK_ROLE_TABLE_ROW:
226         return "AXRole: AXRow";
227     case ATK_ROLE_TABLE_ROW_HEADER:
228         return "AXRole: AXRowHeader";
229     case ATK_ROLE_TOGGLE_BUTTON:
230         return "AXRole: AXToggleButton";
231     case ATK_ROLE_TOOL_BAR:
232         return "AXRole: AXToolbar";
233     case ATK_ROLE_TOOL_TIP:
234         return "AXRole: AXUserInterfaceTooltip";
235     case ATK_ROLE_TREE:
236         return "AXRole: AXTree";
237     case ATK_ROLE_TREE_TABLE:
238         return "AXRole: AXTreeGrid";
239     case ATK_ROLE_TREE_ITEM:
240         return "AXRole: AXTreeItem";
241     case ATK_ROLE_WINDOW:
242         return "AXRole: AXWindow";
243     case ATK_ROLE_UNKNOWN:
244         return "AXRole: AXUnknown";
245     default:
246         // We want to distinguish ATK_ROLE_UNKNOWN from a known AtkRole which
247         // our DRT isn't properly handling.
248         return "AXRole: FIXME not identified";
249     }
250 }
251
252 AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
253     : m_element(element)
254 {
255 }
256
257 AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other)
258     : JSWrappable()
259     , m_element(other.m_element)
260 {
261 }
262
263 AccessibilityUIElement::~AccessibilityUIElement()
264 {
265 }
266
267 bool AccessibilityUIElement::isEqual(AccessibilityUIElement* otherElement)
268 {
269     return m_element == otherElement->platformUIElement();
270 }
271
272 void AccessibilityUIElement::getChildren(Vector<RefPtr<AccessibilityUIElement> >& children)
273 {
274     if (!m_element || !ATK_IS_OBJECT(m_element))
275         return;
276
277     int count = childrenCount();
278     for (int i = 0; i < count; i++) {
279         AtkObject* child = atk_object_ref_accessible_child(ATK_OBJECT(m_element), i);
280         children.append(AccessibilityUIElement::create(child));
281     }
282 }
283
284 void AccessibilityUIElement::getChildrenWithRange(Vector<RefPtr<AccessibilityUIElement> >& children, unsigned location, unsigned length)
285 {
286     if (!m_element || !ATK_IS_OBJECT(m_element))
287         return;
288     unsigned end = location + length;
289     for (unsigned i = location; i < end; i++) {
290         AtkObject* child = atk_object_ref_accessible_child(ATK_OBJECT(m_element), i);
291         children.append(AccessibilityUIElement::create(child));
292     }
293 }
294
295 int AccessibilityUIElement::childrenCount()
296 {
297     if (!m_element)
298         return 0;
299
300     return atk_object_get_n_accessible_children(ATK_OBJECT(m_element));
301 }
302
303 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::elementAtPoint(int x, int y)
304 {
305     // FIXME: implement
306     return 0;
307 }
308
309 unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element)
310 {
311     if (!m_element || !ATK_IS_OBJECT(m_element))
312         return 0;
313
314     Vector<RefPtr<AccessibilityUIElement> > children;
315     getChildren(children);
316
317     unsigned count = children.size();
318     for (unsigned i = 0; i < count; i++)
319         if (children[i]->isEqual(element))
320             return i;
321
322     return 0;
323 }
324
325 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::childAtIndex(unsigned index)
326 {
327     Vector<RefPtr<AccessibilityUIElement> > children;
328     getChildrenWithRange(children, index, 1);
329
330     if (children.size() == 1)
331         return children[0];
332
333     return 0;
334 }
335
336 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::linkedUIElementAtIndex(unsigned index)
337 {
338     // FIXME: implement
339     return 0;
340 }
341
342 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned index)
343 {
344     // FIXME: implement
345     return 0;
346 }
347
348 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned index)
349 {
350     // FIXME: implement
351     return 0;
352 }
353
354 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedRowAtIndex(unsigned index)
355 {
356     // FIXME: implement
357     return 0;
358 }
359
360 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::rowAtIndex(unsigned index)
361 {
362     // FIXME: implement
363     return 0;
364 }
365
366 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedChildAtIndex(unsigned index) const
367 {
368     // FIXME: implement
369     return 0;
370 }
371
372 unsigned AccessibilityUIElement::selectedChildrenCount() const
373 {
374     // FIXME: implement
375     return 0;
376 }
377
378 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::selectedRowAtIndex(unsigned index)
379 {
380     // FIXME: implement
381     return 0;
382 }
383
384 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::titleUIElement()
385 {
386     if (!m_element)
387         return 0;
388
389     AtkRelationSet* set = atk_object_ref_relation_set(ATK_OBJECT(m_element));
390     if (!set)
391         return 0;
392
393     AtkObject* target = 0;
394     int count = atk_relation_set_get_n_relations(set);
395     for (int i = 0; i < count; i++) {
396         AtkRelation* relation = atk_relation_set_get_relation(set, i);
397         if (atk_relation_get_relation_type(relation) == ATK_RELATION_LABELLED_BY) {
398             GPtrArray* targetList = atk_relation_get_target(relation);
399             if (targetList->len)
400                 target = static_cast<AtkObject*>(g_ptr_array_index(targetList, 0));
401         }
402     }
403
404     g_object_unref(set);
405     return target ? AccessibilityUIElement::create(target) : 0;
406 }
407
408 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::parentElement()
409 {
410     if (!m_element || !ATK_IS_OBJECT(m_element))
411         return 0;
412
413     AtkObject* parent = atk_object_get_parent(ATK_OBJECT(m_element));
414     return parent ? AccessibilityUIElement::create(parent) : 0;
415 }
416
417 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::disclosedByRow()
418 {
419     // FIXME: implement
420     return 0;
421 }
422
423 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfLinkedUIElements()
424 {
425     // FIXME: implement
426     return JSStringCreateWithCharacters(0, 0);
427 }
428
429 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfDocumentLinks()
430 {
431     // FIXME: implement
432     return JSStringCreateWithCharacters(0, 0);
433 }
434
435 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfChildren()
436 {
437     // FIXME: implement
438     return JSStringCreateWithCharacters(0, 0);
439 }
440
441 JSRetainPtr<JSStringRef> AccessibilityUIElement::allAttributes()
442 {
443     if (!m_element || !ATK_IS_OBJECT(m_element))
444         return JSStringCreateWithCharacters(0, 0);
445
446     GOwnPtr<gchar> attributeData(attributeSetToString(atk_object_get_attributes(ATK_OBJECT(m_element))));
447     return JSStringCreateWithUTF8CString(attributeData.get());
448 }
449
450 JSRetainPtr<JSStringRef> AccessibilityUIElement::stringAttributeValue(JSStringRef attribute)
451 {
452     // FIXME: implement
453     return JSStringCreateWithCharacters(0, 0);
454 }
455
456 double AccessibilityUIElement::numberAttributeValue(JSStringRef attribute)
457 {
458     // FIXME: implement
459     return 0.0f;
460 }
461
462 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementAttributeValue(JSStringRef attribute) const
463 {
464     // FIXME: implement
465     return 0;
466 }
467
468 bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute)
469 {
470     // FIXME: implement
471     return false;
472 }
473
474 bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute)
475 {
476     // FIXME: implement
477     return false;
478 }
479
480 bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute)
481 {
482     // FIXME: implement
483     return false;
484 }
485
486 JSRetainPtr<JSStringRef> AccessibilityUIElement::parameterizedAttributeNames()
487 {
488     // FIXME: implement
489     return JSStringCreateWithCharacters(0, 0);
490 }
491
492 JSRetainPtr<JSStringRef> AccessibilityUIElement::role()
493 {
494     if (!m_element || !ATK_IS_OBJECT(m_element))
495         return JSStringCreateWithCharacters(0, 0);
496
497     AtkRole role = atk_object_get_role(ATK_OBJECT(m_element));
498     if (!role)
499         return JSStringCreateWithCharacters(0, 0);
500
501     GOwnPtr<gchar> axRole(g_strdup(roleToString(role)));
502     return JSStringCreateWithUTF8CString(axRole.get());
503 }
504
505 JSRetainPtr<JSStringRef> AccessibilityUIElement::subrole()
506 {
507     // FIXME: implement
508     return JSStringCreateWithCharacters(0, 0);
509 }
510
511 JSRetainPtr<JSStringRef> AccessibilityUIElement::roleDescription()
512 {
513     // FIXME: implement
514     return JSStringCreateWithCharacters(0, 0);
515 }
516
517 JSRetainPtr<JSStringRef> AccessibilityUIElement::title()
518 {
519     if (!m_element || !ATK_IS_OBJECT(m_element))
520         return JSStringCreateWithCharacters(0, 0);
521
522     const gchar* name = atk_object_get_name(ATK_OBJECT(m_element));
523     GOwnPtr<gchar> axTitle(g_strdup_printf("AXTitle: %s", name ? name : ""));
524
525     return JSStringCreateWithUTF8CString(axTitle.get());
526 }
527
528 JSRetainPtr<JSStringRef> AccessibilityUIElement::description()
529 {
530     if (!m_element || !ATK_IS_OBJECT(m_element))
531         return JSStringCreateWithCharacters(0, 0);
532
533     const gchar* description = atk_object_get_description(ATK_OBJECT(m_element));
534     if (!description)
535         return JSStringCreateWithCharacters(0, 0);
536
537     GOwnPtr<gchar> axDesc(g_strdup_printf("AXDescription: %s", description));
538
539     return JSStringCreateWithUTF8CString(axDesc.get());
540 }
541
542 JSRetainPtr<JSStringRef> AccessibilityUIElement::orientation() const
543 {
544     // FIXME: implement
545     return JSStringCreateWithCharacters(0, 0);
546 }
547
548 JSRetainPtr<JSStringRef> AccessibilityUIElement::stringValue()
549 {
550     if (!m_element || !ATK_IS_TEXT(m_element))
551         return JSStringCreateWithCharacters(0, 0);
552
553     GOwnPtr<gchar> text(atk_text_get_text(ATK_TEXT(m_element), 0, -1));
554     GOwnPtr<gchar> textWithReplacedCharacters(replaceCharactersForResults(text.get()));
555     GOwnPtr<gchar> axValue(g_strdup_printf("AXValue: %s", textWithReplacedCharacters.get()));
556
557     return JSStringCreateWithUTF8CString(axValue.get());
558 }
559
560 JSRetainPtr<JSStringRef> AccessibilityUIElement::language()
561 {
562     // FIXME: implement
563     return JSStringCreateWithCharacters(0, 0);
564 }
565
566 JSRetainPtr<JSStringRef> AccessibilityUIElement::helpText() const
567 {
568     // FIXME: implement
569     // We need a way to call WebCore::AccessibilityObject::helpText()
570     // from here, probably a new helper class in WebProcess/WebCoreSupport.
571     return JSStringCreateWithCharacters(0, 0);
572 }
573
574 double AccessibilityUIElement::x()
575 {
576     if (!m_element || !ATK_IS_OBJECT(m_element))
577         return 0.0f;
578
579     int x, y;
580     atk_component_get_position(ATK_COMPONENT(m_element), &x, &y, ATK_XY_SCREEN);
581     return x;
582 }
583
584 double AccessibilityUIElement::y()
585 {
586     if (!m_element || !ATK_IS_OBJECT(m_element))
587         return 0.0f;
588
589     int x, y;
590     atk_component_get_position(ATK_COMPONENT(m_element), &x, &y, ATK_XY_SCREEN);
591     return y;
592 }
593
594 double AccessibilityUIElement::width()
595 {
596     if (!m_element || !ATK_IS_OBJECT(m_element))
597         return 0.0f;
598
599     int width, height;
600     atk_component_get_size(ATK_COMPONENT(m_element), &width, &height);
601     return width;
602 }
603
604 double AccessibilityUIElement::height()
605 {
606     if (!m_element || !ATK_IS_OBJECT(m_element))
607         return 0.0f;
608
609     int width, height;
610     atk_component_get_size(ATK_COMPONENT(m_element), &width, &height);
611     return height;
612 }
613
614 double AccessibilityUIElement::clickPointX()
615 {
616     // FIXME: implement
617     return 0.0f;
618 }
619
620 double AccessibilityUIElement::clickPointY()
621 {
622     // FIXME: implement
623     return 0.0f;
624 }
625
626 double AccessibilityUIElement::intValue() const
627 {
628     if (!m_element || !ATK_IS_OBJECT(m_element))
629         return 0.0f;
630
631     GValue value = G_VALUE_INIT;
632     atk_value_get_current_value(ATK_VALUE(m_element), &value);
633     if (!G_VALUE_HOLDS_FLOAT(&value))
634         return 0.0f;
635
636     return g_value_get_float(&value);
637 }
638
639 double AccessibilityUIElement::minValue()
640 {
641     if (!m_element || !ATK_IS_OBJECT(m_element))
642         return 0.0f;
643
644     GValue value = G_VALUE_INIT;
645     atk_value_get_minimum_value(ATK_VALUE(m_element), &value);
646     if (!G_VALUE_HOLDS_FLOAT(&value))
647         return 0.0f;
648
649     return g_value_get_float(&value);
650 }
651
652 double AccessibilityUIElement::maxValue()
653 {
654     if (!m_element || !ATK_IS_OBJECT(m_element))
655         return 0.0f;
656
657     GValue value = G_VALUE_INIT;
658     atk_value_get_maximum_value(ATK_VALUE(m_element), &value);
659     if (!G_VALUE_HOLDS_FLOAT(&value))
660         return 0.0f;
661
662     return g_value_get_float(&value);
663 }
664
665 JSRetainPtr<JSStringRef> AccessibilityUIElement::valueDescription()
666 {
667     // FIXME: implement
668     return JSStringCreateWithCharacters(0, 0);
669 }
670
671 int AccessibilityUIElement::insertionPointLineNumber()
672 {
673     // FIXME: implement
674     return -1;
675 }
676
677 bool AccessibilityUIElement::isPressActionSupported()
678 {
679     // FIXME: implement
680     return false;
681 }
682
683 bool AccessibilityUIElement::isIncrementActionSupported()
684 {
685     // FIXME: implement
686     return false;
687 }
688
689 bool AccessibilityUIElement::isDecrementActionSupported()
690 {
691     // FIXME: implement
692     return false;
693 }
694
695 bool AccessibilityUIElement::isEnabled()
696 {
697     return checkElementState(m_element, ATK_STATE_ENABLED);
698 }
699
700 bool AccessibilityUIElement::isRequired() const
701 {
702     // FIXME: implement
703     return false;
704 }
705
706 bool AccessibilityUIElement::isFocused() const
707 {
708     return checkElementState(m_element, ATK_STATE_FOCUSED);
709 }
710
711 bool AccessibilityUIElement::isSelected() const
712 {
713     return checkElementState(m_element, ATK_STATE_SELECTED);
714 }
715
716 bool AccessibilityUIElement::isExpanded() const
717 {
718     return checkElementState(m_element, ATK_STATE_EXPANDED);
719 }
720
721 bool AccessibilityUIElement::isChecked() const
722 {
723     return checkElementState(m_element, ATK_STATE_CHECKED);
724 }
725
726 int AccessibilityUIElement::hierarchicalLevel() const
727 {
728     // FIXME: implement
729     return 0;
730 }
731
732 JSRetainPtr<JSStringRef> AccessibilityUIElement::speak()
733 {
734     // FIXME: implement
735     return JSStringCreateWithCharacters(0, 0);
736 }
737
738 bool AccessibilityUIElement::ariaIsGrabbed() const
739 {
740     // FIXME: implement
741     return false;
742 }
743
744 JSRetainPtr<JSStringRef> AccessibilityUIElement::ariaDropEffects() const
745 {
746     // FIXME: implement
747     return JSStringCreateWithCharacters(0, 0);
748 }
749
750 // parameterized attributes
751 int AccessibilityUIElement::lineForIndex(int index)
752 {
753     // FIXME: implement
754     return 0;
755 }
756
757 JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForLine(int line)
758 {
759     // FIXME: implement
760     return JSStringCreateWithCharacters(0, 0);
761 }
762
763 JSRetainPtr<JSStringRef> AccessibilityUIElement::rangeForPosition(int x, int y)
764 {
765     // FIXME: implement
766     return JSStringCreateWithCharacters(0, 0);
767 }
768
769 JSRetainPtr<JSStringRef> AccessibilityUIElement::boundsForRange(unsigned location, unsigned length)
770 {
771     // FIXME: implement
772     return JSStringCreateWithCharacters(0, 0);
773 }
774
775 JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForRange(unsigned location, unsigned length)
776 {
777     // FIXME: implement
778     return JSStringCreateWithCharacters(0, 0);
779 }
780
781 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForRange(unsigned location, unsigned length)
782 {
783     // FIXME: implement
784     return JSStringCreateWithCharacters(0, 0);
785 }
786
787 bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location, unsigned length)
788 {
789     // FIXME: implement
790     return false;
791 }
792
793 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementForSearchPredicate(AccessibilityUIElement* startElement, bool isDirectionNext, JSStringRef searchKey, JSStringRef searchText)
794 {
795     // FIXME: implement
796     return 0;
797 }
798
799 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumnHeaders()
800 {
801     // FIXME: implement
802     return JSStringCreateWithCharacters(0, 0);
803 }
804
805 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRowHeaders()
806 {
807     // FIXME: implement
808     return JSStringCreateWithCharacters(0, 0);
809 }
810
811 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumns()
812 {
813     // FIXME: implement
814     return JSStringCreateWithCharacters(0, 0);
815 }
816
817 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfRows()
818 {
819     // FIXME: implement
820     return JSStringCreateWithCharacters(0, 0);
821 }
822
823 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfVisibleCells()
824 {
825     // FIXME: implement
826     return JSStringCreateWithCharacters(0, 0);
827 }
828
829 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfHeader()
830 {
831     // FIXME: implement
832     return JSStringCreateWithCharacters(0, 0);
833 }
834
835 int AccessibilityUIElement::rowCount()
836 {
837     if (!m_element || !ATK_IS_TABLE(m_element))
838         return 0;
839
840     return atk_table_get_n_rows(ATK_TABLE(m_element));
841 }
842
843 int AccessibilityUIElement::columnCount()
844 {
845     if (!m_element || !ATK_IS_TABLE(m_element))
846         return 0;
847
848     return atk_table_get_n_columns(ATK_TABLE(m_element));
849 }
850
851 int AccessibilityUIElement::indexInTable()
852 {
853     // FIXME: implement
854     return -1;
855 }
856
857 JSRetainPtr<JSStringRef> AccessibilityUIElement::rowIndexRange()
858 {
859     // Range in table for rows.
860     return indexRangeInTable(m_element, true);
861 }
862
863 JSRetainPtr<JSStringRef> AccessibilityUIElement::columnIndexRange()
864 {
865     // Range in table for columns.
866     return indexRangeInTable(m_element, false);
867 }
868
869 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::cellForColumnAndRow(unsigned col, unsigned row)
870 {
871     if (!m_element || !ATK_IS_TABLE(m_element))
872         return 0;
873
874     // Adopt the AtkObject representing the cell because
875     // at_table_ref_at() transfers full ownership.
876     GRefPtr<AtkObject> foundCell = adoptGRef(atk_table_ref_at(ATK_TABLE(m_element), row, col));
877     return foundCell ? AccessibilityUIElement::create(foundCell.get()) : 0;
878 }
879
880 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::horizontalScrollbar() const
881 {
882     // FIXME: implement
883     return 0;
884 }
885
886 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::verticalScrollbar() const
887 {
888     // FIXME: implement
889     return 0;
890 }
891
892 JSRetainPtr<JSStringRef> AccessibilityUIElement::selectedTextRange()
893 {
894     // FIXME: implement
895     return JSStringCreateWithCharacters(0, 0);
896 }
897
898 void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length)
899 {
900     // FIXME: implement
901 }
902
903 void AccessibilityUIElement::increment()
904 {
905     alterCurrentValue(m_element, 1);
906 }
907
908 void AccessibilityUIElement::decrement()
909 {
910     alterCurrentValue(m_element, -1);
911 }
912
913 void AccessibilityUIElement::showMenu()
914 {
915     // FIXME: implement
916 }
917
918 void AccessibilityUIElement::press()
919 {
920     if (!m_element || !ATK_IS_OBJECT(m_element))
921         return;
922
923     if (!ATK_IS_ACTION(m_element))
924         return;
925
926     // Only one action per object is supported so far.
927     atk_action_do_action(ATK_ACTION(m_element), 0);
928 }
929
930 void AccessibilityUIElement::setSelectedChild(AccessibilityUIElement* element) const
931 {
932     // FIXME: implement
933 }
934
935 JSRetainPtr<JSStringRef> AccessibilityUIElement::accessibilityValue() const
936 {
937     // FIXME: implement
938     return JSStringCreateWithCharacters(0, 0);
939 }
940
941 JSRetainPtr<JSStringRef> AccessibilityUIElement::documentEncoding()
942 {
943     if (!m_element || !ATK_IS_OBJECT(m_element))
944         return JSStringCreateWithCharacters(0, 0);
945
946     AtkRole role = atk_object_get_role(ATK_OBJECT(m_element));
947     if (role != ATK_ROLE_DOCUMENT_FRAME)
948         return JSStringCreateWithCharacters(0, 0);
949
950     return JSStringCreateWithUTF8CString(atk_document_get_attribute_value(ATK_DOCUMENT(m_element), "Encoding"));
951 }
952
953 JSRetainPtr<JSStringRef> AccessibilityUIElement::documentURI()
954 {
955     if (!m_element || !ATK_IS_OBJECT(m_element))
956         return JSStringCreateWithCharacters(0, 0);
957
958     AtkRole role = atk_object_get_role(ATK_OBJECT(m_element));
959     if (role != ATK_ROLE_DOCUMENT_FRAME)
960         return JSStringCreateWithCharacters(0, 0);
961
962     return JSStringCreateWithUTF8CString(atk_document_get_attribute_value(ATK_DOCUMENT(m_element), "URI"));
963 }
964
965 JSRetainPtr<JSStringRef> AccessibilityUIElement::url()
966 {
967     // FIXME: implement
968     return JSStringCreateWithCharacters(0, 0);
969 }
970
971 bool AccessibilityUIElement::addNotificationListener(JSValueRef functionCallback)
972 {
973     // FIXME: implement
974     return true;
975 }
976
977 bool AccessibilityUIElement::removeNotificationListener()
978 {
979     // FIXME: implement
980     return true;
981 }
982
983 bool AccessibilityUIElement::isFocusable() const
984 {
985     return checkElementState(m_element, ATK_STATE_FOCUSABLE);
986 }
987
988 bool AccessibilityUIElement::isSelectable() const
989 {
990     return checkElementState(m_element, ATK_STATE_SELECTABLE);
991 }
992
993 bool AccessibilityUIElement::isMultiSelectable() const
994 {
995     return checkElementState(m_element, ATK_STATE_MULTISELECTABLE);
996 }
997
998 bool AccessibilityUIElement::isVisible() const
999 {
1000     return checkElementState(m_element, ATK_STATE_VISIBLE);
1001 }
1002
1003 bool AccessibilityUIElement::isOffScreen() const
1004 {
1005     // FIXME: implement
1006     return false;
1007 }
1008
1009 bool AccessibilityUIElement::isCollapsed() const
1010 {
1011     // FIXME: implement
1012     return false;
1013 }
1014
1015 bool AccessibilityUIElement::isIgnored() const
1016 {
1017     // FIXME: implement
1018     return false;
1019 }
1020
1021 bool AccessibilityUIElement::hasPopup() const
1022 {
1023     // FIXME: implement
1024     return false;
1025 }
1026
1027 void AccessibilityUIElement::takeFocus()
1028 {
1029     // FIXME: implement
1030 }
1031
1032 void AccessibilityUIElement::takeSelection()
1033 {
1034     // FIXME: implement
1035 }
1036
1037 void AccessibilityUIElement::addSelection()
1038 {
1039     // FIXME: implement
1040 }
1041
1042 void AccessibilityUIElement::removeSelection()
1043 {
1044     // FIXME: implement
1045 }
1046
1047 // Text markers
1048 PassRefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement* element)
1049 {
1050     // FIXME: implement
1051     return 0;
1052 }
1053
1054 int AccessibilityUIElement::textMarkerRangeLength(AccessibilityTextMarkerRange* range)
1055 {
1056     // FIXME: implement
1057     return 0;
1058 }
1059
1060 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousTextMarker(AccessibilityTextMarker* textMarker)
1061 {
1062     // FIXME: implement
1063     return 0;
1064 }
1065
1066 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextTextMarker(AccessibilityTextMarker* textMarker)
1067 {
1068     // FIXME: implement
1069     return 0;
1070 }
1071
1072 JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForTextMarkerRange(AccessibilityTextMarkerRange* markerRange)
1073 {
1074     // FIXME: implement
1075     return JSStringCreateWithCharacters(0, 0);
1076 }
1077
1078 PassRefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForMarkers(AccessibilityTextMarker* startMarker, AccessibilityTextMarker* endMarker)
1079 {
1080     // FIXME: implement
1081     return 0;
1082 }
1083
1084 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
1085 {
1086     // FIXME: implement
1087     return 0;
1088 }
1089
1090 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
1091 {
1092     // FIXME: implement
1093     return 0;
1094 }
1095
1096 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForPoint(int x, int y)
1097 {
1098     // FIXME: implement
1099     return 0;
1100 }
1101
1102 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::accessibilityElementForTextMarker(AccessibilityTextMarker* marker)
1103 {
1104     // FIXME: implement
1105     return 0;
1106 }
1107
1108 bool AccessibilityUIElement::attributedStringForTextMarkerRangeContainsAttribute(JSStringRef attribute, AccessibilityTextMarkerRange* range)
1109 {
1110     // FIXME: implement
1111     return false;
1112 }
1113
1114 int AccessibilityUIElement::indexForTextMarker(AccessibilityTextMarker* marker)
1115 {
1116     // FIXME: implement
1117     return -1;
1118 }
1119
1120 bool AccessibilityUIElement::isTextMarkerValid(AccessibilityTextMarker* textMarker)
1121 {
1122     // FIXME: implement
1123     return false;
1124 }
1125
1126 PassRefPtr<AccessibilityTextMarker> AccessibilityUIElement::textMarkerForIndex(int textIndex)
1127 {
1128     // FIXME: implement
1129     return 0;
1130 }
1131
1132
1133 } // namespace WTR
1134
1135 #endif