|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "BaseAccessibles.h" |
|
7 |
|
8 #include "Accessible-inl.h" |
|
9 #include "HyperTextAccessibleWrap.h" |
|
10 #include "nsAccessibilityService.h" |
|
11 #include "nsAccUtils.h" |
|
12 #include "nsCoreUtils.h" |
|
13 #include "Role.h" |
|
14 #include "States.h" |
|
15 #include "nsIURI.h" |
|
16 |
|
17 using namespace mozilla::a11y; |
|
18 |
|
19 //////////////////////////////////////////////////////////////////////////////// |
|
20 // LeafAccessible |
|
21 //////////////////////////////////////////////////////////////////////////////// |
|
22 |
|
23 LeafAccessible:: |
|
24 LeafAccessible(nsIContent* aContent, DocAccessible* aDoc) : |
|
25 AccessibleWrap(aContent, aDoc) |
|
26 { |
|
27 } |
|
28 |
|
29 NS_IMPL_ISUPPORTS_INHERITED0(LeafAccessible, Accessible) |
|
30 |
|
31 //////////////////////////////////////////////////////////////////////////////// |
|
32 // LeafAccessible: Accessible public |
|
33 |
|
34 Accessible* |
|
35 LeafAccessible::ChildAtPoint(int32_t aX, int32_t aY, |
|
36 EWhichChildAtPoint aWhichChild) |
|
37 { |
|
38 // Don't walk into leaf accessibles. |
|
39 return this; |
|
40 } |
|
41 |
|
42 bool |
|
43 LeafAccessible::InsertChildAt(uint32_t aIndex, Accessible* aChild) |
|
44 { |
|
45 NS_NOTREACHED("InsertChildAt called on leaf accessible!"); |
|
46 return false; |
|
47 } |
|
48 |
|
49 bool |
|
50 LeafAccessible::RemoveChild(Accessible* aChild) |
|
51 { |
|
52 NS_NOTREACHED("RemoveChild called on leaf accessible!"); |
|
53 return false; |
|
54 } |
|
55 |
|
56 //////////////////////////////////////////////////////////////////////////////// |
|
57 // LeafAccessible: Accessible private |
|
58 |
|
59 void |
|
60 LeafAccessible::CacheChildren() |
|
61 { |
|
62 // No children for leaf accessible. |
|
63 } |
|
64 |
|
65 |
|
66 //////////////////////////////////////////////////////////////////////////////// |
|
67 // LinkableAccessible |
|
68 //////////////////////////////////////////////////////////////////////////////// |
|
69 |
|
70 LinkableAccessible:: |
|
71 LinkableAccessible(nsIContent* aContent, DocAccessible* aDoc) : |
|
72 AccessibleWrap(aContent, aDoc), |
|
73 mActionAcc(nullptr), |
|
74 mIsLink(false), |
|
75 mIsOnclick(false) |
|
76 { |
|
77 } |
|
78 |
|
79 NS_IMPL_ISUPPORTS_INHERITED0(LinkableAccessible, AccessibleWrap) |
|
80 |
|
81 //////////////////////////////////////////////////////////////////////////////// |
|
82 // LinkableAccessible. nsIAccessible |
|
83 |
|
84 NS_IMETHODIMP |
|
85 LinkableAccessible::TakeFocus() |
|
86 { |
|
87 return mActionAcc ? mActionAcc->TakeFocus() : AccessibleWrap::TakeFocus(); |
|
88 } |
|
89 |
|
90 uint64_t |
|
91 LinkableAccessible::NativeLinkState() const |
|
92 { |
|
93 if (mIsLink) |
|
94 return states::LINKED | (mActionAcc->LinkState() & states::TRAVERSED); |
|
95 |
|
96 return 0; |
|
97 } |
|
98 |
|
99 void |
|
100 LinkableAccessible::Value(nsString& aValue) |
|
101 { |
|
102 aValue.Truncate(); |
|
103 |
|
104 Accessible::Value(aValue); |
|
105 if (!aValue.IsEmpty()) |
|
106 return; |
|
107 |
|
108 if (aValue.IsEmpty() && mIsLink) |
|
109 mActionAcc->Value(aValue); |
|
110 } |
|
111 |
|
112 |
|
113 uint8_t |
|
114 LinkableAccessible::ActionCount() |
|
115 { |
|
116 return (mIsOnclick || mIsLink) ? 1 : 0; |
|
117 } |
|
118 |
|
119 NS_IMETHODIMP |
|
120 LinkableAccessible::GetActionName(uint8_t aIndex, nsAString& aName) |
|
121 { |
|
122 aName.Truncate(); |
|
123 |
|
124 // Action 0 (default action): Jump to link |
|
125 if (aIndex == eAction_Jump) { |
|
126 if (mIsLink) { |
|
127 aName.AssignLiteral("jump"); |
|
128 return NS_OK; |
|
129 } |
|
130 else if (mIsOnclick) { |
|
131 aName.AssignLiteral("click"); |
|
132 return NS_OK; |
|
133 } |
|
134 return NS_ERROR_NOT_IMPLEMENTED; |
|
135 } |
|
136 return NS_ERROR_INVALID_ARG; |
|
137 } |
|
138 |
|
139 NS_IMETHODIMP |
|
140 LinkableAccessible::DoAction(uint8_t aIndex) |
|
141 { |
|
142 if (aIndex != eAction_Jump) |
|
143 return NS_ERROR_INVALID_ARG; |
|
144 |
|
145 return mActionAcc ? mActionAcc->DoAction(aIndex) : |
|
146 AccessibleWrap::DoAction(aIndex); |
|
147 } |
|
148 |
|
149 KeyBinding |
|
150 LinkableAccessible::AccessKey() const |
|
151 { |
|
152 return mActionAcc ? |
|
153 mActionAcc->AccessKey() : Accessible::AccessKey(); |
|
154 } |
|
155 |
|
156 //////////////////////////////////////////////////////////////////////////////// |
|
157 // LinkableAccessible. Accessible |
|
158 |
|
159 void |
|
160 LinkableAccessible::Shutdown() |
|
161 { |
|
162 mIsLink = false; |
|
163 mIsOnclick = false; |
|
164 mActionAcc = nullptr; |
|
165 AccessibleWrap::Shutdown(); |
|
166 } |
|
167 |
|
168 //////////////////////////////////////////////////////////////////////////////// |
|
169 // LinkableAccessible: HyperLinkAccessible |
|
170 |
|
171 already_AddRefed<nsIURI> |
|
172 LinkableAccessible::AnchorURIAt(uint32_t aAnchorIndex) |
|
173 { |
|
174 if (mIsLink) { |
|
175 NS_ASSERTION(mActionAcc->IsLink(), |
|
176 "nsIAccessibleHyperLink isn't implemented."); |
|
177 |
|
178 if (mActionAcc->IsLink()) |
|
179 return mActionAcc->AnchorURIAt(aAnchorIndex); |
|
180 } |
|
181 |
|
182 return nullptr; |
|
183 } |
|
184 |
|
185 //////////////////////////////////////////////////////////////////////////////// |
|
186 // LinkableAccessible: Accessible protected |
|
187 |
|
188 void |
|
189 LinkableAccessible::BindToParent(Accessible* aParent, |
|
190 uint32_t aIndexInParent) |
|
191 { |
|
192 AccessibleWrap::BindToParent(aParent, aIndexInParent); |
|
193 |
|
194 // Cache action content. |
|
195 mActionAcc = nullptr; |
|
196 mIsLink = false; |
|
197 mIsOnclick = false; |
|
198 |
|
199 if (nsCoreUtils::HasClickListener(mContent)) { |
|
200 mIsOnclick = true; |
|
201 return; |
|
202 } |
|
203 |
|
204 // XXX: The logic looks broken since the click listener may be registered |
|
205 // on non accessible node in parent chain but this node is skipped when tree |
|
206 // is traversed. |
|
207 Accessible* walkUpAcc = this; |
|
208 while ((walkUpAcc = walkUpAcc->Parent()) && !walkUpAcc->IsDoc()) { |
|
209 if (walkUpAcc->LinkState() & states::LINKED) { |
|
210 mIsLink = true; |
|
211 mActionAcc = walkUpAcc; |
|
212 return; |
|
213 } |
|
214 |
|
215 if (nsCoreUtils::HasClickListener(walkUpAcc->GetContent())) { |
|
216 mActionAcc = walkUpAcc; |
|
217 mIsOnclick = true; |
|
218 return; |
|
219 } |
|
220 } |
|
221 } |
|
222 |
|
223 void |
|
224 LinkableAccessible::UnbindFromParent() |
|
225 { |
|
226 mActionAcc = nullptr; |
|
227 mIsLink = false; |
|
228 mIsOnclick = false; |
|
229 |
|
230 AccessibleWrap::UnbindFromParent(); |
|
231 } |
|
232 |
|
233 //////////////////////////////////////////////////////////////////////////////// |
|
234 // EnumRoleAccessible |
|
235 //////////////////////////////////////////////////////////////////////////////// |
|
236 |
|
237 EnumRoleAccessible:: |
|
238 EnumRoleAccessible(nsIContent* aNode, DocAccessible* aDoc, roles::Role aRole) : |
|
239 AccessibleWrap(aNode, aDoc), mRole(aRole) |
|
240 { |
|
241 } |
|
242 |
|
243 NS_IMPL_ISUPPORTS_INHERITED0(EnumRoleAccessible, Accessible) |
|
244 |
|
245 role |
|
246 EnumRoleAccessible::NativeRole() |
|
247 { |
|
248 return mRole; |
|
249 } |
|
250 |
|
251 //////////////////////////////////////////////////////////////////////////////// |
|
252 // DummyAccessible |
|
253 //////////////////////////////////////////////////////////////////////////////// |
|
254 |
|
255 uint64_t |
|
256 DummyAccessible::NativeState() |
|
257 { |
|
258 return 0; |
|
259 } |
|
260 uint64_t |
|
261 DummyAccessible::NativeInteractiveState() const |
|
262 { |
|
263 return 0; |
|
264 } |
|
265 |
|
266 uint64_t |
|
267 DummyAccessible::NativeLinkState() const |
|
268 { |
|
269 return 0; |
|
270 } |
|
271 |
|
272 bool |
|
273 DummyAccessible::NativelyUnavailable() const |
|
274 { |
|
275 return false; |
|
276 } |
|
277 |
|
278 void |
|
279 DummyAccessible::ApplyARIAState(uint64_t* aState) const |
|
280 { |
|
281 } |