Line data Source code
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 0 : LeafAccessible::
24 0 : LeafAccessible(nsIContent* aContent, DocAccessible* aDoc) :
25 0 : AccessibleWrap(aContent, aDoc)
26 : {
27 0 : mStateFlags |= eNoKidsFromDOM;
28 0 : }
29 :
30 0 : NS_IMPL_ISUPPORTS_INHERITED0(LeafAccessible, Accessible)
31 :
32 : ////////////////////////////////////////////////////////////////////////////////
33 : // LeafAccessible: Accessible public
34 :
35 : Accessible*
36 0 : LeafAccessible::ChildAtPoint(int32_t aX, int32_t aY,
37 : EWhichChildAtPoint aWhichChild)
38 : {
39 : // Don't walk into leaf accessibles.
40 0 : return this;
41 : }
42 :
43 : bool
44 0 : LeafAccessible::InsertChildAt(uint32_t aIndex, Accessible* aChild)
45 : {
46 0 : NS_NOTREACHED("InsertChildAt called on leaf accessible!");
47 0 : return false;
48 : }
49 :
50 : bool
51 0 : LeafAccessible::RemoveChild(Accessible* aChild)
52 : {
53 0 : NS_NOTREACHED("RemoveChild called on leaf accessible!");
54 0 : return false;
55 : }
56 :
57 : bool
58 0 : LeafAccessible::IsAcceptableChild(nsIContent* aEl) const
59 : {
60 : // No children for leaf accessible.
61 0 : return false;
62 : }
63 :
64 :
65 : ////////////////////////////////////////////////////////////////////////////////
66 : // LinkableAccessible
67 : ////////////////////////////////////////////////////////////////////////////////
68 :
69 0 : NS_IMPL_ISUPPORTS_INHERITED0(LinkableAccessible, AccessibleWrap)
70 :
71 : ////////////////////////////////////////////////////////////////////////////////
72 : // LinkableAccessible. nsIAccessible
73 :
74 : void
75 0 : LinkableAccessible::TakeFocus()
76 : {
77 0 : if (Accessible* actionAcc = ActionWalk()) {
78 0 : actionAcc->TakeFocus();
79 : } else {
80 0 : AccessibleWrap::TakeFocus();
81 : }
82 0 : }
83 :
84 : uint64_t
85 0 : LinkableAccessible::NativeLinkState() const
86 : {
87 : bool isLink;
88 : Accessible* actionAcc =
89 0 : const_cast<LinkableAccessible*>(this)->ActionWalk(&isLink);
90 0 : if (isLink) {
91 0 : return states::LINKED | (actionAcc->LinkState() & states::TRAVERSED);
92 : }
93 :
94 0 : return 0;
95 : }
96 :
97 : void
98 0 : LinkableAccessible::Value(nsString& aValue)
99 : {
100 0 : aValue.Truncate();
101 :
102 0 : Accessible::Value(aValue);
103 0 : if (!aValue.IsEmpty()) {
104 0 : return;
105 : }
106 :
107 : bool isLink;
108 0 : Accessible* actionAcc = ActionWalk(&isLink);
109 0 : if (isLink) {
110 0 : actionAcc->Value(aValue);
111 : }
112 : }
113 :
114 : uint8_t
115 0 : LinkableAccessible::ActionCount()
116 : {
117 : bool isLink, isOnclick, isLabelWithControl;
118 0 : ActionWalk(&isLink, &isOnclick, &isLabelWithControl);
119 0 : return (isLink || isOnclick || isLabelWithControl) ? 1 : 0;
120 : }
121 :
122 : Accessible*
123 0 : LinkableAccessible::ActionWalk(bool* aIsLink, bool* aIsOnclick,
124 : bool* aIsLabelWithControl)
125 : {
126 0 : if (aIsOnclick) {
127 0 : *aIsOnclick = false;
128 : }
129 0 : if (aIsLink) {
130 0 : *aIsLink = false;
131 : }
132 0 : if (aIsLabelWithControl) {
133 0 : *aIsLabelWithControl = false;
134 : }
135 :
136 0 : if (nsCoreUtils::HasClickListener(mContent)) {
137 0 : if (aIsOnclick) {
138 0 : *aIsOnclick = true;
139 : }
140 0 : return nullptr;
141 : }
142 :
143 : // XXX: The logic looks broken since the click listener may be registered
144 : // on non accessible node in parent chain but this node is skipped when tree
145 : // is traversed.
146 0 : Accessible* walkUpAcc = this;
147 0 : while ((walkUpAcc = walkUpAcc->Parent()) && !walkUpAcc->IsDoc()) {
148 0 : if (walkUpAcc->LinkState() & states::LINKED) {
149 0 : if (aIsLink) {
150 0 : *aIsLink = true;
151 : }
152 0 : return walkUpAcc;
153 : }
154 :
155 0 : if (nsCoreUtils::HasClickListener(walkUpAcc->GetContent())) {
156 0 : if (aIsOnclick) {
157 0 : *aIsOnclick = true;
158 : }
159 0 : return walkUpAcc;
160 : }
161 :
162 0 : if (nsCoreUtils::IsLabelWithControl(walkUpAcc->GetContent())) {
163 0 : if (aIsLabelWithControl) {
164 0 : *aIsLabelWithControl = true;
165 : }
166 0 : return walkUpAcc;
167 : }
168 : }
169 0 : return nullptr;
170 : }
171 :
172 : void
173 0 : LinkableAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName)
174 : {
175 0 : aName.Truncate();
176 :
177 : // Action 0 (default action): Jump to link
178 0 : if (aIndex == eAction_Jump) {
179 : bool isOnclick, isLink, isLabelWithControl;
180 0 : ActionWalk(&isLink, &isOnclick, &isLabelWithControl);
181 0 : if (isLink) {
182 0 : aName.AssignLiteral("jump");
183 0 : } else if (isOnclick || isLabelWithControl) {
184 0 : aName.AssignLiteral("click");
185 : }
186 : }
187 0 : }
188 :
189 : bool
190 0 : LinkableAccessible::DoAction(uint8_t aIndex)
191 : {
192 0 : if (aIndex != eAction_Jump) {
193 0 : return false;
194 : }
195 :
196 0 : if (Accessible* actionAcc = ActionWalk()) {
197 0 : return actionAcc->DoAction(aIndex);
198 : }
199 :
200 0 : return AccessibleWrap::DoAction(aIndex);
201 : }
202 :
203 : KeyBinding
204 0 : LinkableAccessible::AccessKey() const
205 : {
206 0 : if (const Accessible* actionAcc =
207 0 : const_cast<LinkableAccessible*>(this)->ActionWalk()) {
208 0 : return actionAcc->AccessKey();
209 : }
210 :
211 0 : return Accessible::AccessKey();
212 : }
213 :
214 : ////////////////////////////////////////////////////////////////////////////////
215 : // LinkableAccessible: HyperLinkAccessible
216 :
217 : already_AddRefed<nsIURI>
218 0 : LinkableAccessible::AnchorURIAt(uint32_t aAnchorIndex)
219 : {
220 : bool isLink;
221 0 : Accessible* actionAcc = ActionWalk(&isLink);
222 0 : if (isLink) {
223 0 : NS_ASSERTION(actionAcc->IsLink(), "HyperLink isn't implemented.");
224 :
225 0 : if (actionAcc->IsLink()) {
226 0 : return actionAcc->AnchorURIAt(aAnchorIndex);
227 : }
228 : }
229 :
230 0 : return nullptr;
231 : }
232 :
233 :
234 : ////////////////////////////////////////////////////////////////////////////////
235 : // DummyAccessible
236 : ////////////////////////////////////////////////////////////////////////////////
237 :
238 : uint64_t
239 0 : DummyAccessible::NativeState()
240 : {
241 0 : return 0;
242 : }
243 : uint64_t
244 0 : DummyAccessible::NativeInteractiveState() const
245 : {
246 0 : return 0;
247 : }
248 :
249 : uint64_t
250 0 : DummyAccessible::NativeLinkState() const
251 : {
252 0 : return 0;
253 : }
254 :
255 : bool
256 0 : DummyAccessible::NativelyUnavailable() const
257 : {
258 0 : return false;
259 : }
260 :
261 : void
262 0 : DummyAccessible::ApplyARIAState(uint64_t* aState) const
263 : {
264 0 : }
|