1/*
2 * Copyright (C) 2008 Apple Ltd.
3 * Copyright (C) 2008 Alp Toker <alp@atoker.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB.  If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21#include "config.h"
22#include "AccessibilityObject.h"
23#include "RenderObject.h"
24#include "RenderText.h"
25
26#include <glib-object.h>
27
28#if HAVE(ACCESSIBILITY)
29
30namespace WebCore {
31
32bool AccessibilityObject::accessibilityIgnoreAttachment() const
33{
34    return false;
35}
36
37AccessibilityObjectInclusion AccessibilityObject::accessibilityPlatformIncludesObject() const
38{
39    AccessibilityObject* parent = parentObject();
40    if (!parent)
41        return DefaultBehavior;
42
43    AccessibilityRole role = roleValue();
44    if (role == SplitterRole)
45        return IncludeObject;
46
47    // We expose the slider as a whole but not its value indicator.
48    if (role == SliderThumbRole)
49        return IgnoreObject;
50
51    // When a list item is made up entirely of children (e.g. paragraphs)
52    // the list item gets ignored. We need it.
53    if (isGroup() && parent->isList())
54        return IncludeObject;
55
56    // Entries and password fields have extraneous children which we want to ignore.
57    if (parent->isPasswordField() || parent->isTextControl())
58        return IgnoreObject;
59
60    // Include all tables, even layout tables. The AT can decide what to do with each.
61    if (role == CellRole || role == TableRole)
62        return IncludeObject;
63
64    // We at some point might have a need to expose a table row; but it's not standard Gtk+.
65    if (role == RowRole)
66        return IgnoreObject;
67
68    // The object containing the text should implement AtkText itself.
69    if (role == StaticTextRole)
70        return IgnoreObject;
71
72    // Include all list items, regardless they have or not inline children
73    if (role == ListItemRole)
74        return IncludeObject;
75
76    // Bullets/numbers for list items shouldn't be exposed as AtkObjects.
77    if (role == ListMarkerRole)
78        return IgnoreObject;
79
80    return DefaultBehavior;
81}
82
83AccessibilityObjectWrapper* AccessibilityObject::wrapper() const
84{
85    return m_wrapper;
86}
87
88void AccessibilityObject::setWrapper(AccessibilityObjectWrapper* wrapper)
89{
90    if (wrapper == m_wrapper)
91        return;
92
93    if (m_wrapper)
94        g_object_unref(m_wrapper);
95
96    m_wrapper = wrapper;
97
98    if (m_wrapper)
99        g_object_ref(m_wrapper);
100}
101
102bool AccessibilityObject::allowsTextRanges() const
103{
104    // Check type for the AccessibilityObject.
105    if (isTextControl() || isWebArea() || isGroup() || isLink() || isHeading() || isListItem())
106        return true;
107
108    // Check roles as the last fallback mechanism.
109    AccessibilityRole role = roleValue();
110    return role == ParagraphRole || role == LabelRole || role == DivRole || role == FormRole;
111}
112
113unsigned AccessibilityObject::getLengthForTextRange() const
114{
115    unsigned textLength = text().length();
116
117    if (textLength)
118        return textLength;
119
120    // Gtk ATs need this for all text objects; not just text controls.
121    Node* node = this->node();
122    RenderObject* renderer = node ? node->renderer() : 0;
123    if (renderer && renderer->isText()) {
124        RenderText* renderText = toRenderText(renderer);
125        textLength = renderText ? renderText->textLength() : 0;
126    }
127
128    // Get the text length from the elements under the
129    // accessibility object if the value is still zero.
130    if (!textLength && allowsTextRanges())
131        textLength = textUnderElement().length();
132
133    return textLength;
134}
135
136} // namespace WebCore
137
138#endif // HAVE(ACCESSIBILITY)
139