[GTK] accessibility/editable-webarea-context-menu-point.html is failing
[WebKit-https.git] / Tools / DumpRenderTree / gtk / AccessibilityUIElementGtk.cpp
1 /*
2  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3  * Copyright (C) 2009 Jan Michael Alonzo
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 #include "WebCoreSupport/DumpRenderTreeSupportGtk.h"
31 #include <JavaScriptCore/JSStringRef.h>
32 #include <atk/atk.h>
33 #include <gtk/gtk.h>
34 #include <wtf/Assertions.h>
35 #include <wtf/gobject/GOwnPtr.h>
36 #include <wtf/gobject/GRefPtr.h>
37 #include <wtf/text/WTFString.h>
38 #include <wtf/unicode/CharacterNames.h>
39
40 static String coreAttributeToAtkAttribute(JSStringRef attribute)
41 {
42     size_t bufferSize = JSStringGetMaximumUTF8CStringSize(attribute);
43     GOwnPtr<gchar> buffer(static_cast<gchar*>(g_malloc(bufferSize)));
44     JSStringGetUTF8CString(attribute, buffer.get(), bufferSize);
45
46     String attributeString = String::fromUTF8(buffer.get());
47     if (attributeString == "AXPlaceholderValue")
48         return "placeholder-text";
49
50     return "";
51 }
52
53 static inline String roleToString(AtkRole role)
54 {
55     switch (role) {
56     case ATK_ROLE_ALERT:
57         return "AXRole: AXAlert";
58     case ATK_ROLE_CANVAS:
59         return "AXRole: AXCanvas";
60     case ATK_ROLE_CHECK_BOX:
61         return "AXRole: AXCheckBox";
62     case ATK_ROLE_COLUMN_HEADER:
63         return "AXRole: AXColumnHeader";
64     case ATK_ROLE_COMBO_BOX:
65         return "AXRole: AXComboBox";
66     case ATK_ROLE_DOCUMENT_FRAME:
67         return "AXRole: AXWebArea";
68     case ATK_ROLE_ENTRY:
69         return "AXRole: AXTextField";
70     case ATK_ROLE_FOOTER:
71         return "AXRole: AXFooter";
72     case ATK_ROLE_FORM:
73         return "AXRole: AXForm";
74     case ATK_ROLE_GROUPING:
75         return "AXRole: AXGroup";
76     case ATK_ROLE_HEADING:
77         return "AXRole: AXHeading";
78     case ATK_ROLE_IMAGE:
79         return "AXRole: AXImage";
80     case ATK_ROLE_IMAGE_MAP:
81         return "AXRole: AXImageMap";
82     case ATK_ROLE_LABEL:
83         return "AXRole: AXLabel";
84     case ATK_ROLE_LINK:
85         return "AXRole: AXLink";
86     case ATK_ROLE_LIST:
87         return "AXRole: AXList";
88     case ATK_ROLE_LIST_BOX:
89         return "AXRole: AXListBox";
90     case ATK_ROLE_LIST_ITEM:
91         return "AXRole: AXListItem";
92     case ATK_ROLE_MENU:
93         return "AXRole: AXMenu";
94     case ATK_ROLE_MENU_BAR:
95         return "AXRole: AXMenuBar";
96     case ATK_ROLE_MENU_ITEM:
97         return "AXRole: AXMenuItem";
98     case ATK_ROLE_PAGE_TAB:
99         return "AXRole: AXTab";
100     case ATK_ROLE_PAGE_TAB_LIST:
101         return "AXRole: AXTabGroup";
102     case ATK_ROLE_PANEL:
103         return "AXRole: AXGroup";
104     case ATK_ROLE_PARAGRAPH:
105         return "AXRole: AXParagraph";
106     case ATK_ROLE_PASSWORD_TEXT:
107         return "AXRole: AXPasswordField";
108     case ATK_ROLE_PUSH_BUTTON:
109         return "AXRole: AXButton";
110     case ATK_ROLE_RADIO_BUTTON:
111         return "AXRole: AXRadioButton";
112     case ATK_ROLE_ROW_HEADER:
113         return "AXRole: AXRowHeader";
114     case ATK_ROLE_RULER:
115         return "AXRole: AXRuler";
116     case ATK_ROLE_SCROLL_BAR:
117         return "AXRole: AXScrollBar";
118     case ATK_ROLE_SCROLL_PANE:
119         return "AXRole: AXScrollArea";
120     case ATK_ROLE_SECTION:
121         return "AXRole: AXDiv";
122     case ATK_ROLE_SEPARATOR:
123         return "AXRole: AXHorizontalRule";
124     case ATK_ROLE_SLIDER:
125         return "AXRole: AXSlider";
126     case ATK_ROLE_SPIN_BUTTON:
127         return "AXRole: AXSpinButton";
128     case ATK_ROLE_TABLE:
129         return "AXRole: AXTable";
130     case ATK_ROLE_TABLE_CELL:
131         return "AXRole: AXCell";
132     case ATK_ROLE_TABLE_COLUMN_HEADER:
133         return "AXRole: AXColumnHeader";
134     case ATK_ROLE_TABLE_ROW:
135         return "AXRole: AXRow";
136     case ATK_ROLE_TABLE_ROW_HEADER:
137         return "AXRole: AXRowHeader";
138     case ATK_ROLE_TOGGLE_BUTTON:
139         return "AXRole: AXToggleButton";
140     case ATK_ROLE_TOOL_BAR:
141         return "AXRole: AXToolbar";
142     case ATK_ROLE_TOOL_TIP:
143         return "AXRole: AXUserInterfaceTooltip";
144     case ATK_ROLE_TREE:
145         return "AXRole: AXTree";
146     case ATK_ROLE_TREE_TABLE:
147         return "AXRole: AXTreeGrid";
148     case ATK_ROLE_TREE_ITEM:
149         return "AXRole: AXTreeItem";
150     case ATK_ROLE_WINDOW:
151         return "AXRole: AXWindow";
152     case ATK_ROLE_UNKNOWN:
153         return "AXRole: AXUnknown";
154     default:
155         // We want to distinguish ATK_ROLE_UNKNOWN from a known AtkRole which
156         // our DRT isn't properly handling.
157         return "AXRole: FIXME not identified";
158     }
159 }
160
161 static inline gchar* replaceCharactersForResults(gchar* str)
162 {
163     String uString = String::fromUTF8(str);
164
165     // The object replacement character is passed along to ATs so we need to be
166     // able to test for their presence and do so without causing test failures.
167     uString.replace(objectReplacementCharacter, "<obj>");
168
169     // The presence of newline characters in accessible text of a single object
170     // is appropriate, but it makes test results (especially the accessible tree)
171     // harder to read.
172     uString.replace("\n", "<\\n>");
173
174     return g_strdup(uString.utf8().data());
175 }
176
177 AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
178     : m_element(element)
179 {
180     if (m_element)
181         g_object_ref(m_element);
182 }
183
184 AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other)
185     : m_element(other.m_element)
186 {
187     if (m_element)
188         g_object_ref(m_element);
189 }
190
191 AccessibilityUIElement::~AccessibilityUIElement()
192 {
193     if (m_element)
194         g_object_unref(m_element);
195 }
196
197 void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>& elements)
198 {
199     // FIXME: implement
200 }
201
202 void AccessibilityUIElement::getDocumentLinks(Vector<AccessibilityUIElement>&)
203 {
204     // FIXME: implement
205 }
206
207 void AccessibilityUIElement::getChildren(Vector<AccessibilityUIElement>& children)
208 {
209     int count = childrenCount();
210     for (int i = 0; i < count; i++) {
211         AtkObject* child = atk_object_ref_accessible_child(ATK_OBJECT(m_element), i);
212         children.append(AccessibilityUIElement(child));
213     }
214 }
215
216 void AccessibilityUIElement::getChildrenWithRange(Vector<AccessibilityUIElement>& elementVector, unsigned start, unsigned end)
217 {
218     for (unsigned i = start; i < end; i++) {
219         AtkObject* child = atk_object_ref_accessible_child(ATK_OBJECT(m_element), i);
220         elementVector.append(AccessibilityUIElement(child));
221     }
222 }
223
224 int AccessibilityUIElement::rowCount()
225 {
226     if (!m_element)
227         return 0;
228
229     ASSERT(ATK_IS_TABLE(m_element));
230
231     return atk_table_get_n_rows(ATK_TABLE(m_element));
232 }
233
234 int AccessibilityUIElement::columnCount()
235 {
236     if (!m_element)
237         return 0;
238
239     ASSERT(ATK_IS_TABLE(m_element));
240
241     return atk_table_get_n_columns(ATK_TABLE(m_element));
242 }
243
244 int AccessibilityUIElement::childrenCount()
245 {
246     if (!m_element)
247         return 0;
248
249     ASSERT(ATK_IS_OBJECT(m_element));
250
251     return atk_object_get_n_accessible_children(ATK_OBJECT(m_element));
252 }
253
254 AccessibilityUIElement AccessibilityUIElement::elementAtPoint(int x, int y)
255 {
256     if (!m_element)
257         return 0;
258
259     return AccessibilityUIElement(atk_component_ref_accessible_at_point(ATK_COMPONENT(m_element), x, y, ATK_XY_WINDOW));
260 }
261
262 AccessibilityUIElement AccessibilityUIElement::linkedUIElementAtIndex(unsigned index)
263 {
264     // FIXME: implement
265     return 0;
266 }
267
268 AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index)
269 {
270     Vector<AccessibilityUIElement> children;
271     getChildrenWithRange(children, index, index + 1);
272
273     if (children.size() == 1)
274         return children.at(0);
275
276     return 0;
277 }
278
279 unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element)
280
281     // FIXME: implement
282     return 0;
283 }
284
285 gchar* attributeSetToString(AtkAttributeSet* attributeSet)
286 {
287     GString* str = g_string_new(0);
288     for (GSList* attributes = attributeSet; attributes; attributes = attributes->next) {
289         AtkAttribute* attribute = static_cast<AtkAttribute*>(attributes->data);
290         GOwnPtr<gchar> attributeData(g_strconcat(attribute->name, ":", attribute->value, NULL));
291         g_string_append(str, attributeData.get());
292         if (attributes->next)
293             g_string_append(str, ", ");
294     }
295
296     return g_string_free(str, FALSE);
297 }
298
299 JSStringRef AccessibilityUIElement::allAttributes()
300 {
301     if (!m_element)
302         return JSStringCreateWithCharacters(0, 0);
303
304     ASSERT(ATK_IS_OBJECT(m_element));
305     GOwnPtr<gchar> attributeData(attributeSetToString(atk_object_get_attributes(ATK_OBJECT(m_element))));
306     return JSStringCreateWithUTF8CString(attributeData.get());
307 }
308
309 JSStringRef AccessibilityUIElement::attributesOfLinkedUIElements()
310 {
311     // FIXME: implement
312     return JSStringCreateWithCharacters(0, 0);
313 }
314
315 JSStringRef AccessibilityUIElement::attributesOfDocumentLinks()
316 {
317     // FIXME: implement
318     return JSStringCreateWithCharacters(0, 0);
319 }
320
321 AccessibilityUIElement AccessibilityUIElement::titleUIElement()
322 {
323
324     if (!m_element)
325         return 0;
326
327     AtkRelationSet* set = atk_object_ref_relation_set(ATK_OBJECT(m_element));
328     if (!set)
329         return 0;
330
331     AtkObject* target = 0;
332     int count = atk_relation_set_get_n_relations(set);
333     for (int i = 0; i < count; i++) {
334         AtkRelation* relation = atk_relation_set_get_relation(set, i);
335         if (atk_relation_get_relation_type(relation) == ATK_RELATION_LABELLED_BY) {
336             GPtrArray* targetList = atk_relation_get_target(relation);
337             if (targetList->len)
338                 target = static_cast<AtkObject*>(g_ptr_array_index(targetList, 0));
339         }
340         g_object_unref(set);
341     }
342
343     return target ? AccessibilityUIElement(target) : 0;
344 }
345
346 AccessibilityUIElement AccessibilityUIElement::parentElement()
347 {
348     if (!m_element)
349         return 0;
350
351     ASSERT(ATK_IS_OBJECT(m_element));
352
353     AtkObject* parent =  atk_object_get_parent(ATK_OBJECT(m_element));
354     return parent ? AccessibilityUIElement(parent) : 0;
355 }
356
357 JSStringRef AccessibilityUIElement::attributesOfChildren()
358 {
359     // FIXME: implement
360     return JSStringCreateWithCharacters(0, 0);
361 }
362
363 JSStringRef AccessibilityUIElement::parameterizedAttributeNames()
364 {
365     // FIXME: implement
366     return JSStringCreateWithCharacters(0, 0);
367 }
368
369 JSStringRef AccessibilityUIElement::role()
370 {
371     AtkRole role = atk_object_get_role(ATK_OBJECT(m_element));
372     if (!role)
373         return JSStringCreateWithCharacters(0, 0);
374
375     String roleString = roleToString(role);
376     return JSStringCreateWithUTF8CString(roleString.utf8().data());
377 }
378
379 JSStringRef AccessibilityUIElement::subrole()
380 {
381     return 0;
382 }
383
384 JSStringRef AccessibilityUIElement::roleDescription()
385 {
386     return 0;
387 }
388
389 JSStringRef AccessibilityUIElement::title()
390 {
391     const gchar* name = atk_object_get_name(ATK_OBJECT(m_element));
392
393     if (!name)
394         return JSStringCreateWithCharacters(0, 0);
395
396     GOwnPtr<gchar> axTitle(g_strdup_printf("AXTitle: %s", name));
397
398     return JSStringCreateWithUTF8CString(axTitle.get());
399 }
400
401 JSStringRef AccessibilityUIElement::description()
402 {
403     const gchar* description = atk_object_get_description(ATK_OBJECT(m_element));
404
405     if (!description)
406         return JSStringCreateWithCharacters(0, 0);
407
408     GOwnPtr<gchar> axDesc(g_strdup_printf("AXDescription: %s", description));
409
410     return JSStringCreateWithUTF8CString(axDesc.get());
411 }
412
413 JSStringRef AccessibilityUIElement::stringValue()
414 {
415     if (!m_element || !ATK_IS_TEXT(m_element))
416         return JSStringCreateWithCharacters(0, 0);
417
418     gchar* text = atk_text_get_text(ATK_TEXT(m_element), 0, -1);
419     GOwnPtr<gchar> axValue(g_strdup_printf("AXValue: %s", replaceCharactersForResults(text)));
420     g_free(text);
421
422     return JSStringCreateWithUTF8CString(axValue.get());
423 }
424
425 JSStringRef AccessibilityUIElement::language()
426 {
427     // FIXME: implement
428     return JSStringCreateWithCharacters(0, 0);
429 }
430
431 JSStringRef AccessibilityUIElement::helpText() const
432 {
433     if (!m_element)
434         return JSStringCreateWithCharacters(0, 0);
435
436     ASSERT(ATK_IS_OBJECT(m_element));
437
438     CString helpText = DumpRenderTreeSupportGtk::accessibilityHelpText(ATK_OBJECT(m_element));
439     GOwnPtr<gchar> axHelpText(g_strdup_printf("AXHelp: %s", helpText.data()));
440     return JSStringCreateWithUTF8CString(axHelpText.get());
441 }
442
443 double AccessibilityUIElement::x()
444 {
445     int x, y;
446
447     atk_component_get_position(ATK_COMPONENT(m_element), &x, &y, ATK_XY_SCREEN);
448
449     return x;
450 }
451
452 double AccessibilityUIElement::y()
453 {
454     int x, y;
455
456     atk_component_get_position(ATK_COMPONENT(m_element), &x, &y, ATK_XY_SCREEN);
457
458     return y;
459 }
460
461 double AccessibilityUIElement::width()
462 {
463     int width, height;
464
465     atk_component_get_size(ATK_COMPONENT(m_element), &width, &height);
466
467     return width;
468 }
469
470 double AccessibilityUIElement::height()
471 {
472     int width, height;
473
474     atk_component_get_size(ATK_COMPONENT(m_element), &width, &height);
475
476     return height;
477 }
478
479 double AccessibilityUIElement::clickPointX()
480 {
481     // Note: This is not something we have in ATK.
482     return 0.f;
483 }
484
485 double AccessibilityUIElement::clickPointY()
486 {
487     // Note: This is not something we have in ATK.
488     return 0.f;
489 }
490
491 JSStringRef AccessibilityUIElement::orientation() const
492 {
493     return 0;
494 }
495
496 double AccessibilityUIElement::intValue() const
497 {
498     GValue value = { 0, { { 0 } } };
499
500     if (!ATK_IS_VALUE(m_element))
501         return 0.0f;
502
503     atk_value_get_current_value(ATK_VALUE(m_element), &value);
504     if (!G_VALUE_HOLDS_FLOAT(&value))
505         return 0.0f;
506     return g_value_get_float(&value);
507 }
508
509 double AccessibilityUIElement::minValue()
510 {
511     GValue value = { 0, { { 0 } } };
512
513     if (!ATK_IS_VALUE(m_element))
514         return 0.0f;
515
516     atk_value_get_minimum_value(ATK_VALUE(m_element), &value);
517     if (!G_VALUE_HOLDS_FLOAT(&value))
518         return 0.0f;
519     return g_value_get_float(&value);
520 }
521
522 double AccessibilityUIElement::maxValue()
523 {
524     GValue value = { 0, { { 0 } } };
525
526     if (!ATK_IS_VALUE(m_element))
527         return 0.0f;
528
529     atk_value_get_maximum_value(ATK_VALUE(m_element), &value);
530     if (!G_VALUE_HOLDS_FLOAT(&value))
531         return 0.0f;
532     return g_value_get_float(&value);
533 }
534
535 JSStringRef AccessibilityUIElement::valueDescription()
536 {
537     // FIXME: implement after it has been implemented in ATK.
538     // See: https://bugzilla.gnome.org/show_bug.cgi?id=684576
539     return JSStringCreateWithCharacters(0, 0);
540 }
541
542 static bool checkElementState(PlatformUIElement element, AtkStateType stateType)
543 {
544     if (!ATK_IS_OBJECT(element))
545          return false;
546
547     GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(element)));
548     return atk_state_set_contains_state(stateSet.get(), stateType);
549 }
550
551 bool AccessibilityUIElement::isEnabled()
552 {
553     return checkElementState(m_element, ATK_STATE_ENABLED);
554 }
555
556 int AccessibilityUIElement::insertionPointLineNumber()
557 {
558     // FIXME: implement
559     return 0;
560 }
561
562 bool AccessibilityUIElement::isActionSupported(JSStringRef action)
563 {
564     // FIXME: implement
565     return false;
566 }
567
568 bool AccessibilityUIElement::isRequired() const
569 {
570     // FIXME: implement
571     return false;
572 }
573
574 bool AccessibilityUIElement::isFocused() const
575 {
576     if (!ATK_IS_OBJECT(m_element))
577         return false;
578
579     GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(m_element)));
580     gboolean isFocused = atk_state_set_contains_state(stateSet.get(), ATK_STATE_FOCUSED);
581
582     return isFocused;
583 }
584
585 bool AccessibilityUIElement::isSelected() const
586 {
587     return checkElementState(m_element, ATK_STATE_SELECTED);
588 }
589
590 int AccessibilityUIElement::hierarchicalLevel() const
591 {
592     // FIXME: implement
593     return 0;
594 }
595
596 bool AccessibilityUIElement::ariaIsGrabbed() const
597 {
598     return false;
599 }
600  
601 JSStringRef AccessibilityUIElement::ariaDropEffects() const
602 {   
603     return 0; 
604 }
605
606 bool AccessibilityUIElement::isExpanded() const
607 {
608     if (!ATK_IS_OBJECT(m_element))
609         return false;
610
611     GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(m_element)));
612     gboolean isExpanded = atk_state_set_contains_state(stateSet.get(), ATK_STATE_EXPANDED);
613
614     return isExpanded;
615 }
616
617 bool AccessibilityUIElement::isChecked() const
618 {
619     if (!ATK_IS_OBJECT(m_element))
620         return false;
621
622     GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(m_element)));
623     gboolean isChecked = atk_state_set_contains_state(stateSet.get(), ATK_STATE_CHECKED);
624
625     return isChecked;
626 }
627
628 JSStringRef AccessibilityUIElement::attributesOfColumnHeaders()
629 {
630     // FIXME: implement
631     return JSStringCreateWithCharacters(0, 0);
632 }
633
634 JSStringRef AccessibilityUIElement::attributesOfRowHeaders()
635 {
636     // FIXME: implement
637     return JSStringCreateWithCharacters(0, 0);
638 }
639
640 JSStringRef AccessibilityUIElement::attributesOfColumns()
641 {
642     // FIXME: implement
643     return JSStringCreateWithCharacters(0, 0);
644 }
645
646 JSStringRef AccessibilityUIElement::attributesOfRows()
647 {
648     // FIXME: implement
649     return JSStringCreateWithCharacters(0, 0);
650 }
651
652 JSStringRef AccessibilityUIElement::attributesOfVisibleCells()
653 {
654     // FIXME: implement
655     return JSStringCreateWithCharacters(0, 0);
656 }
657
658 JSStringRef AccessibilityUIElement::attributesOfHeader()
659 {
660     // FIXME: implement
661     return JSStringCreateWithCharacters(0, 0);
662 }
663
664 int AccessibilityUIElement::indexInTable()
665 {
666     // FIXME: implement
667     return 0;
668 }
669
670 static JSStringRef indexRangeInTable(PlatformUIElement element, bool isRowRange)
671 {
672     GOwnPtr<gchar> rangeString(g_strdup("{0, 0}"));
673
674     if (!element)
675         return JSStringCreateWithUTF8CString(rangeString.get());
676
677     ASSERT(ATK_IS_OBJECT(element));
678
679     AtkObject* axTable = atk_object_get_parent(ATK_OBJECT(element));
680     if (!axTable || !ATK_IS_TABLE(axTable))
681         return JSStringCreateWithUTF8CString(rangeString.get());
682
683     // Look for the cell in the table.
684     gint indexInParent = atk_object_get_index_in_parent(ATK_OBJECT(element));
685     if (indexInParent == -1)
686         return JSStringCreateWithUTF8CString(rangeString.get());
687
688     int row = -1;
689     int column = -1;
690     row = atk_table_get_row_at_index(ATK_TABLE(axTable), indexInParent);
691     column = atk_table_get_column_at_index(ATK_TABLE(axTable), indexInParent);
692
693     // Get the actual values, if row and columns are valid values.
694     if (row != -1 && column != -1) {
695         int base = 0;
696         int length = 0;
697         if (isRowRange) {
698             base = row;
699             length = atk_table_get_row_extent_at(ATK_TABLE(axTable), row, column);
700         } else {
701             base = column;
702             length = atk_table_get_column_extent_at(ATK_TABLE(axTable), row, column);
703         }
704         rangeString.set(g_strdup_printf("{%d, %d}", base, length));
705     }
706
707     return JSStringCreateWithUTF8CString(rangeString.get());
708 }
709
710 JSStringRef AccessibilityUIElement::rowIndexRange()
711 {
712     // Range in table for rows.
713     return indexRangeInTable(m_element, true);
714 }
715
716 JSStringRef AccessibilityUIElement::columnIndexRange()
717 {
718     // Range in table for columns.
719     return indexRangeInTable(m_element, false);
720 }
721
722 int AccessibilityUIElement::lineForIndex(int)
723 {
724     // FIXME: implement
725     return 0;
726 }
727
728 JSStringRef AccessibilityUIElement::boundsForRange(unsigned location, unsigned length)
729 {
730     // FIXME: implement
731     return JSStringCreateWithCharacters(0, 0);
732 }
733
734 JSStringRef AccessibilityUIElement::stringForRange(unsigned, unsigned) 
735 {
736     // FIXME: implement
737     return JSStringCreateWithCharacters(0, 0);
738
739
740 JSStringRef AccessibilityUIElement::attributedStringForRange(unsigned, unsigned)
741 {
742     // FIXME: implement
743     return JSStringCreateWithCharacters(0, 0);
744 }
745
746 bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location, unsigned length)
747 {
748     // FIXME: implement
749     return false;
750 }
751
752 AccessibilityUIElement AccessibilityUIElement::uiElementForSearchPredicate(AccessibilityUIElement* startElement, bool isDirectionNext, JSStringRef searchKey, JSStringRef searchText)
753 {
754     // FIXME: implement
755     return 0;
756 }
757
758 AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned column, unsigned row)
759 {
760     if (!m_element)
761         return 0;
762
763     ASSERT(ATK_IS_TABLE(m_element));
764
765     AtkObject* foundCell = atk_table_ref_at(ATK_TABLE(m_element), row, column);
766     return foundCell ? AccessibilityUIElement(foundCell) : 0;
767 }
768
769 JSStringRef AccessibilityUIElement::selectedTextRange()
770 {
771     // FIXME: implement
772     return JSStringCreateWithCharacters(0, 0);
773 }
774
775 void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length)
776 {
777     // FIXME: implement
778 }
779
780 JSStringRef AccessibilityUIElement::stringAttributeValue(JSStringRef attribute)
781 {
782     if (!m_element)
783         return JSStringCreateWithCharacters(0, 0);
784
785     String atkAttributeName = coreAttributeToAtkAttribute(attribute);
786     if (atkAttributeName.isEmpty())
787         return JSStringCreateWithCharacters(0, 0);
788
789     for (GSList* atkAttributes = atk_object_get_attributes(ATK_OBJECT(m_element)); atkAttributes; atkAttributes = atkAttributes->next) {
790         AtkAttribute* atkAttribute = static_cast<AtkAttribute*>(atkAttributes->data);
791         if (!strcmp(atkAttribute->name, atkAttributeName.utf8().data()))
792             return JSStringCreateWithUTF8CString(atkAttribute->value);
793     }
794
795     return JSStringCreateWithCharacters(0, 0);
796 }
797
798 double AccessibilityUIElement::numberAttributeValue(JSStringRef attribute)
799 {
800     // FIXME: implement
801     return 0.0f;
802 }
803
804 bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute)
805 {
806     // FIXME: implement
807     return false;
808 }
809
810 bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute)
811 {
812     // FIXME: implement
813     return false;
814 }
815
816 bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute)
817 {
818     return false;
819 }
820
821 static void alterCurrentValue(PlatformUIElement element, int factor)
822 {
823     if (!element)
824         return;
825
826     ASSERT(ATK_IS_VALUE(element));
827
828     GValue currentValue = G_VALUE_INIT;
829     atk_value_get_current_value(ATK_VALUE(element), &currentValue);
830
831     GValue increment = G_VALUE_INIT;
832     atk_value_get_minimum_increment(ATK_VALUE(element), &increment);
833
834     GValue newValue = G_VALUE_INIT;
835     g_value_init(&newValue, G_TYPE_FLOAT);
836
837     g_value_set_float(&newValue, g_value_get_float(&currentValue) + factor * g_value_get_float(&increment));
838     atk_value_set_current_value(ATK_VALUE(element), &newValue);
839
840     g_value_unset(&newValue);
841     g_value_unset(&increment);
842     g_value_unset(&currentValue);
843 }
844
845 void AccessibilityUIElement::increment()
846 {
847     alterCurrentValue(m_element, 1);
848 }
849
850 void AccessibilityUIElement::decrement()
851 {
852     alterCurrentValue(m_element, -1);
853 }
854
855 void AccessibilityUIElement::press()
856 {
857     if (!m_element)
858         return;
859
860     ASSERT(ATK_IS_OBJECT(m_element));
861
862     if (!ATK_IS_ACTION(m_element))
863         return;
864
865     // Only one action per object is supported so far.
866     atk_action_do_action(ATK_ACTION(m_element), 0);
867 }
868
869 void AccessibilityUIElement::showMenu()
870 {
871     // FIXME: implement
872 }
873
874 AccessibilityUIElement AccessibilityUIElement::disclosedRowAtIndex(unsigned index)
875 {
876     return 0;
877 }
878
879 AccessibilityUIElement AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned index)
880 {
881     return 0;
882 }
883
884 AccessibilityUIElement AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned index)
885 {
886     return 0;
887 }
888
889 AccessibilityUIElement AccessibilityUIElement::selectedRowAtIndex(unsigned index)
890 {
891     return 0;
892 }
893
894 AccessibilityUIElement AccessibilityUIElement::rowAtIndex(unsigned index)
895 {
896     return 0;
897 }
898
899 AccessibilityUIElement AccessibilityUIElement::disclosedByRow()
900 {
901     return 0;
902 }
903
904 JSStringRef AccessibilityUIElement::accessibilityValue() const
905 {
906     // FIXME: implement
907     return JSStringCreateWithCharacters(0, 0);
908 }
909
910 JSStringRef AccessibilityUIElement::documentEncoding()
911 {
912     AtkRole role = atk_object_get_role(ATK_OBJECT(m_element));
913     if (role != ATK_ROLE_DOCUMENT_FRAME)
914         return JSStringCreateWithCharacters(0, 0);
915
916     return JSStringCreateWithUTF8CString(atk_document_get_attribute_value(ATK_DOCUMENT(m_element), "Encoding"));
917 }
918
919 JSStringRef AccessibilityUIElement::documentURI()
920 {
921     AtkRole role = atk_object_get_role(ATK_OBJECT(m_element));
922     if (role != ATK_ROLE_DOCUMENT_FRAME)
923         return JSStringCreateWithCharacters(0, 0);
924
925     return JSStringCreateWithUTF8CString(atk_document_get_attribute_value(ATK_DOCUMENT(m_element), "URI"));
926 }
927
928 JSStringRef AccessibilityUIElement::url()
929 {
930     // FIXME: implement
931     return JSStringCreateWithCharacters(0, 0);
932 }
933
934 bool AccessibilityUIElement::addNotificationListener(JSObjectRef functionCallback)
935 {
936     // FIXME: implement
937     return false;
938 }
939
940 void AccessibilityUIElement::removeNotificationListener()
941 {
942     // FIXME: implement
943 }
944
945 bool AccessibilityUIElement::isFocusable() const
946 {
947     if (!ATK_IS_OBJECT(m_element))
948         return false;
949
950     GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(m_element)));
951     gboolean isFocusable = atk_state_set_contains_state(stateSet.get(), ATK_STATE_FOCUSABLE);
952
953     return isFocusable;
954 }
955
956 bool AccessibilityUIElement::isSelectable() const
957 {
958     return checkElementState(m_element, ATK_STATE_SELECTABLE);
959 }
960
961 bool AccessibilityUIElement::isMultiSelectable() const
962 {
963     return checkElementState(m_element, ATK_STATE_MULTISELECTABLE);
964 }
965
966 bool AccessibilityUIElement::isSelectedOptionActive() const
967 {
968     // FIXME: implement
969     return false;
970 }
971
972 bool AccessibilityUIElement::isVisible() const
973 {
974     // FIXME: implement
975     return false;
976 }
977
978 bool AccessibilityUIElement::isOffScreen() const
979 {
980     // FIXME: implement
981     return false;
982 }
983
984 bool AccessibilityUIElement::isCollapsed() const
985 {
986     // FIXME: implement
987     return false;
988 }
989
990 bool AccessibilityUIElement::isIgnored() const
991 {
992     // FIXME: implement
993     return false;
994 }
995
996 bool AccessibilityUIElement::hasPopup() const
997 {
998     // FIXME: implement
999     return false;
1000 }
1001
1002 void AccessibilityUIElement::takeFocus()
1003 {
1004     // FIXME: implement
1005 }
1006
1007 void AccessibilityUIElement::takeSelection()
1008 {
1009     // FIXME: implement
1010 }
1011
1012 void AccessibilityUIElement::addSelection()
1013 {
1014     // FIXME: implement
1015 }
1016
1017 void AccessibilityUIElement::removeSelection()
1018 {
1019     // FIXME: implement
1020 }
1021
1022 void AccessibilityUIElement::scrollToMakeVisible()
1023 {
1024     // FIXME: implement
1025 }
1026
1027 void AccessibilityUIElement::scrollToMakeVisibleWithSubFocus(int x, int y, int width, int height)
1028 {
1029     // FIXME: implement
1030 }
1031
1032 void AccessibilityUIElement::scrollToGlobalPoint(int x, int y)
1033 {
1034     // FIXME: implement
1035 }