OLD | NEW |
| (Empty) |
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 | |
24 #include "RenderObject.h" | |
25 #include "RenderText.h" | |
26 #include <glib-object.h> | |
27 | |
28 #if HAVE(ACCESSIBILITY) | |
29 | |
30 namespace WebCore { | |
31 | |
32 bool AccessibilityObject::accessibilityIgnoreAttachment() const | |
33 { | |
34 return false; | |
35 } | |
36 | |
37 AccessibilityObjectInclusion AccessibilityObject::accessibilityPlatformIncludesO
bject() const | |
38 { | |
39 AccessibilityObject* parent = parentObject(); | |
40 if (!parent) | |
41 return DefaultBehavior; | |
42 | |
43 AccessibilityRole role = roleValue(); | |
44 if (role == HorizontalRuleRole) | |
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 ign
ore. | |
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 // The object containing the text should implement AtkText itself. | |
65 if (role == StaticTextRole) | |
66 return IgnoreObject; | |
67 | |
68 // Include all list items, regardless they have or not inline children | |
69 if (role == ListItemRole) | |
70 return IncludeObject; | |
71 | |
72 // Bullets/numbers for list items shouldn't be exposed as AtkObjects. | |
73 if (role == ListMarkerRole) | |
74 return IgnoreObject; | |
75 | |
76 // Never expose an unknown object, since AT's won't know what to | |
77 // do with them. This is what is done on the Mac as well. | |
78 if (role == UnknownRole) | |
79 return IgnoreObject; | |
80 | |
81 // Given a paragraph or div containing a non-nested anonymous block, WebCore | |
82 // ignores the paragraph or div and includes the block. We want the opposite
: | |
83 // ATs are expecting accessible objects associated with textual elements. Th
ey | |
84 // usually have no need for the anonymous block. And when the wrong objects | |
85 // get included or ignored, needed accessibility signals do not get emitted. | |
86 if (role == ParagraphRole || role == DivRole) { | |
87 // Don't call textUnderElement() here, because it's slow and it can | |
88 // crash when called while we're in the middle of a subtree being delete
d. | |
89 if (!renderer()->firstChild()) | |
90 return DefaultBehavior; | |
91 | |
92 if (!parent->renderer() || parent->renderer()->isAnonymousBlock()) | |
93 return DefaultBehavior; | |
94 | |
95 for (RenderObject* r = renderer()->firstChild(); r; r = r->nextSibling()
) { | |
96 if (r->isAnonymousBlock()) | |
97 return IncludeObject; | |
98 } | |
99 } | |
100 | |
101 // Block spans result in objects of ATK_ROLE_PANEL which are almost always u
nwanted. | |
102 // However, if we ignore block spans whose parent is the body, the child con
trols | |
103 // will become immediate children of the ATK_ROLE_DOCUMENT_FRAME and any tex
t will | |
104 // become text within the document frame itself. This ultimately may be what
we want | |
105 // and would largely be consistent with what we see from Gecko. However, ign
oring | |
106 // spans whose parent is the body changes the current behavior we see from W
ebCore. | |
107 // Until we have sufficient time to properly analyze these cases, we will de
fer to | |
108 // WebCore. We only check that the parent is not aria because we do not expe
ct | |
109 // anonymous blocks which are aria-related to themselves have an aria role,
nor | |
110 // have we encountered instances where the parent of an anonymous block also
lacked | |
111 // an aria role but the grandparent had one. | |
112 if (renderer() && renderer()->isAnonymousBlock() && !parent->renderer()->isB
ody() | |
113 && parent->ariaRoleAttribute() == UnknownRole) | |
114 return IgnoreObject; | |
115 | |
116 return DefaultBehavior; | |
117 } | |
118 | |
119 AccessibilityObjectWrapper* AccessibilityObject::wrapper() const | |
120 { | |
121 return m_wrapper; | |
122 } | |
123 | |
124 void AccessibilityObject::setWrapper(AccessibilityObjectWrapper* wrapper) | |
125 { | |
126 if (wrapper == m_wrapper) | |
127 return; | |
128 | |
129 if (m_wrapper) | |
130 g_object_unref(m_wrapper); | |
131 | |
132 m_wrapper = wrapper; | |
133 | |
134 if (m_wrapper) | |
135 g_object_ref(m_wrapper); | |
136 } | |
137 | |
138 bool AccessibilityObject::allowsTextRanges() const | |
139 { | |
140 // Check type for the AccessibilityObject. | |
141 if (isTextControl() || isWebArea() || isGroup() || isLink() || isHeading() |
| isListItem() || isTableCell()) | |
142 return true; | |
143 | |
144 // Check roles as the last fallback mechanism. | |
145 AccessibilityRole role = roleValue(); | |
146 return role == ParagraphRole || role == LabelRole || role == DivRole || role
== FormRole; | |
147 } | |
148 | |
149 unsigned AccessibilityObject::getLengthForTextRange() const | |
150 { | |
151 unsigned textLength = text().length(); | |
152 | |
153 if (textLength) | |
154 return textLength; | |
155 | |
156 // Gtk ATs need this for all text objects; not just text controls. | |
157 Node* node = this->node(); | |
158 RenderObject* renderer = node ? node->renderer() : 0; | |
159 if (renderer && renderer->isText()) { | |
160 RenderText* renderText = toRenderText(renderer); | |
161 textLength = renderText ? renderText->textLength() : 0; | |
162 } | |
163 | |
164 // Get the text length from the elements under the | |
165 // accessibility object if the value is still zero. | |
166 if (!textLength && allowsTextRanges()) | |
167 textLength = textUnderElement().length(); | |
168 | |
169 return textLength; | |
170 } | |
171 | |
172 } // namespace WebCore | |
173 | |
174 #endif // HAVE(ACCESSIBILITY) | |
OLD | NEW |