1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * John Gaunt (jgaunt@netscape.com)
24 : * Alexander Surkov <surkov.alexander@gmail.com>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either of the GNU General Public License Version 2 or later (the "GPL"),
28 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #include "nsBaseWidgetAccessible.h"
41 :
42 : #include "nsAccessibilityService.h"
43 : #include "nsAccUtils.h"
44 : #include "nsCoreUtils.h"
45 : #include "nsHyperTextAccessibleWrap.h"
46 : #include "Role.h"
47 : #include "States.h"
48 :
49 : #include "nsGUIEvent.h"
50 : #include "nsILink.h"
51 : #include "nsIFrame.h"
52 : #include "nsINameSpaceManager.h"
53 : #include "nsIURI.h"
54 :
55 : using namespace mozilla::a11y;
56 :
57 : ////////////////////////////////////////////////////////////////////////////////
58 : // nsLeafAccessible
59 : ////////////////////////////////////////////////////////////////////////////////
60 :
61 0 : nsLeafAccessible::
62 : nsLeafAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
63 0 : nsAccessibleWrap(aContent, aDoc)
64 : {
65 0 : }
66 :
67 0 : NS_IMPL_ISUPPORTS_INHERITED0(nsLeafAccessible, nsAccessible)
68 :
69 : ////////////////////////////////////////////////////////////////////////////////
70 : // nsLeafAccessible: nsAccessible public
71 :
72 : nsAccessible*
73 0 : nsLeafAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
74 : EWhichChildAtPoint aWhichChild)
75 : {
76 : // Don't walk into leaf accessibles.
77 0 : return this;
78 : }
79 :
80 : ////////////////////////////////////////////////////////////////////////////////
81 : // nsLeafAccessible: nsAccessible private
82 :
83 : void
84 0 : nsLeafAccessible::CacheChildren()
85 : {
86 : // No children for leaf accessible.
87 0 : }
88 :
89 :
90 : ////////////////////////////////////////////////////////////////////////////////
91 : // nsLinkableAccessible
92 : ////////////////////////////////////////////////////////////////////////////////
93 :
94 0 : nsLinkableAccessible::
95 : nsLinkableAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
96 : nsAccessibleWrap(aContent, aDoc),
97 : mActionAcc(nsnull),
98 : mIsLink(false),
99 0 : mIsOnclick(false)
100 : {
101 0 : }
102 :
103 0 : NS_IMPL_ISUPPORTS_INHERITED0(nsLinkableAccessible, nsAccessibleWrap)
104 :
105 : ////////////////////////////////////////////////////////////////////////////////
106 : // nsLinkableAccessible. nsIAccessible
107 :
108 : NS_IMETHODIMP
109 0 : nsLinkableAccessible::TakeFocus()
110 : {
111 0 : return mActionAcc ? mActionAcc->TakeFocus() : nsAccessibleWrap::TakeFocus();
112 : }
113 :
114 : PRUint64
115 0 : nsLinkableAccessible::NativeState()
116 : {
117 0 : PRUint64 states = nsAccessibleWrap::NativeState();
118 0 : if (mIsLink) {
119 0 : states |= states::LINKED;
120 0 : if (mActionAcc->State() & states::TRAVERSED)
121 0 : states |= states::TRAVERSED;
122 : }
123 :
124 0 : return states;
125 : }
126 :
127 : NS_IMETHODIMP
128 0 : nsLinkableAccessible::GetValue(nsAString& aValue)
129 : {
130 0 : aValue.Truncate();
131 :
132 0 : nsAccessible::GetValue(aValue);
133 0 : if (!aValue.IsEmpty())
134 0 : return NS_OK;
135 :
136 0 : return mIsLink ? mActionAcc->GetValue(aValue) : NS_ERROR_NOT_IMPLEMENTED;
137 : }
138 :
139 :
140 : PRUint8
141 0 : nsLinkableAccessible::ActionCount()
142 : {
143 0 : return (mIsOnclick || mIsLink) ? 1 : 0;
144 : }
145 :
146 : NS_IMETHODIMP
147 0 : nsLinkableAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
148 : {
149 0 : aName.Truncate();
150 :
151 : // Action 0 (default action): Jump to link
152 0 : if (aIndex == eAction_Jump) {
153 0 : if (mIsLink) {
154 0 : aName.AssignLiteral("jump");
155 0 : return NS_OK;
156 : }
157 0 : else if (mIsOnclick) {
158 0 : aName.AssignLiteral("click");
159 0 : return NS_OK;
160 : }
161 0 : return NS_ERROR_NOT_IMPLEMENTED;
162 : }
163 0 : return NS_ERROR_INVALID_ARG;
164 : }
165 :
166 : NS_IMETHODIMP
167 0 : nsLinkableAccessible::DoAction(PRUint8 aIndex)
168 : {
169 0 : if (aIndex != eAction_Jump)
170 0 : return NS_ERROR_INVALID_ARG;
171 :
172 0 : return mActionAcc ? mActionAcc->DoAction(aIndex) :
173 0 : nsAccessibleWrap::DoAction(aIndex);
174 : }
175 :
176 : KeyBinding
177 0 : nsLinkableAccessible::AccessKey() const
178 : {
179 : return mActionAcc ?
180 0 : mActionAcc->AccessKey() : nsAccessible::AccessKey();
181 : }
182 :
183 : ////////////////////////////////////////////////////////////////////////////////
184 : // nsLinkableAccessible. nsAccessNode
185 :
186 : void
187 0 : nsLinkableAccessible::Shutdown()
188 : {
189 0 : mIsLink = false;
190 0 : mIsOnclick = false;
191 0 : mActionAcc = nsnull;
192 0 : nsAccessibleWrap::Shutdown();
193 0 : }
194 :
195 : ////////////////////////////////////////////////////////////////////////////////
196 : // nsLinkableAccessible: HyperLinkAccessible
197 :
198 : already_AddRefed<nsIURI>
199 0 : nsLinkableAccessible::AnchorURIAt(PRUint32 aAnchorIndex)
200 : {
201 0 : if (mIsLink) {
202 0 : NS_ASSERTION(mActionAcc->IsLink(),
203 : "nsIAccessibleHyperLink isn't implemented.");
204 :
205 0 : if (mActionAcc->IsLink())
206 0 : return mActionAcc->AnchorURIAt(aAnchorIndex);
207 : }
208 :
209 0 : return nsnull;
210 : }
211 :
212 : ////////////////////////////////////////////////////////////////////////////////
213 : // nsLinkableAccessible: nsAccessible protected
214 :
215 : void
216 0 : nsLinkableAccessible::BindToParent(nsAccessible* aParent,
217 : PRUint32 aIndexInParent)
218 : {
219 0 : nsAccessibleWrap::BindToParent(aParent, aIndexInParent);
220 :
221 : // Cache action content.
222 0 : mActionAcc = nsnull;
223 0 : mIsLink = false;
224 0 : mIsOnclick = false;
225 :
226 0 : if (nsCoreUtils::HasClickListener(mContent)) {
227 0 : mIsOnclick = true;
228 0 : return;
229 : }
230 :
231 : // XXX: The logic looks broken since the click listener may be registered
232 : // on non accessible node in parent chain but this node is skipped when tree
233 : // is traversed.
234 0 : nsAccessible* walkUpAcc = this;
235 0 : while ((walkUpAcc = walkUpAcc->Parent()) && !walkUpAcc->IsDoc()) {
236 0 : if (walkUpAcc->Role() == roles::LINK &&
237 0 : walkUpAcc->State() & states::LINKED) {
238 0 : mIsLink = true;
239 0 : mActionAcc = walkUpAcc;
240 0 : return;
241 : }
242 :
243 0 : if (nsCoreUtils::HasClickListener(walkUpAcc->GetContent())) {
244 0 : mActionAcc = walkUpAcc;
245 0 : mIsOnclick = true;
246 0 : return;
247 : }
248 : }
249 : }
250 :
251 : void
252 0 : nsLinkableAccessible::UnbindFromParent()
253 : {
254 0 : mActionAcc = nsnull;
255 0 : mIsLink = false;
256 0 : mIsOnclick = nsnull;
257 :
258 0 : nsAccessibleWrap::UnbindFromParent();
259 0 : }
260 :
261 : ////////////////////////////////////////////////////////////////////////////////
262 : // nsEnumRoleAccessible
263 : ////////////////////////////////////////////////////////////////////////////////
264 :
265 0 : nsEnumRoleAccessible::
266 : nsEnumRoleAccessible(nsIContent* aNode, nsDocAccessible* aDoc,
267 : roles::Role aRole) :
268 0 : nsAccessibleWrap(aNode, aDoc), mRole(aRole)
269 : {
270 0 : }
271 :
272 0 : NS_IMPL_ISUPPORTS_INHERITED0(nsEnumRoleAccessible, nsAccessible)
273 :
274 : role
275 0 : nsEnumRoleAccessible::NativeRole()
276 : {
277 0 : return mRole;
278 : }
|