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
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/
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
15 * The Original Code is mozilla.org code.
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.
23 * Aaron Leventhal (aaronl@netscape.com)
24 * Kyle Yuan (kyle.yuan@sun.com)
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.
38 * ***** END LICENSE BLOCK ***** */
40 #include "nsHTMLTextAccessible.h"
41 #include "nsAccessibleTreeWalker.h"
42 #include "nsIAccessibleDocument.h"
43 #include "nsIAccessibleEvent.h"
45 #include "nsPresContext.h"
46 #include "nsIPresShell.h"
47 #include "nsISelection.h"
48 #include "nsISelectionController.h"
49 #include "nsComponentManagerUtils.h"
51 nsHTMLTextAccessible::nsHTMLTextAccessible(nsIDOMNode
* aDomNode
, nsIWeakReference
* aShell
):
52 nsTextAccessibleWrap(aDomNode
, aShell
)
56 NS_IMETHODIMP
nsHTMLTextAccessible::GetName(nsAString
& aName
)
59 return AppendTextTo(aName
, 0, PR_UINT32_MAX
);
62 NS_IMETHODIMP
nsHTMLTextAccessible::GetRole(PRUint32
*aRole
)
64 nsIFrame
*frame
= GetFrame();
65 // Don't return on null frame -- we still return a role
66 // after accessible is shutdown/DEFUNCT
67 if (frame
&& frame
->IsGeneratedContentFrame()) {
68 *aRole
= nsIAccessibleRole::ROLE_STATICTEXT
;
72 return nsTextAccessible::GetRole(aRole
);
76 nsHTMLTextAccessible::GetState(PRUint32
*aState
, PRUint32
*aExtraState
)
78 nsresult rv
= nsTextAccessible::GetState(aState
, aExtraState
);
79 NS_ENSURE_SUCCESS(rv
, rv
);
83 nsCOMPtr
<nsIAccessible
> docAccessible
=
84 do_QueryInterface(nsCOMPtr
<nsIAccessibleDocument
>(GetDocAccessible()));
86 PRUint32 state
, extState
;
87 docAccessible
->GetFinalState(&state
, &extState
);
88 if (0 == (extState
& nsIAccessibleStates::EXT_STATE_EDITABLE
)) {
89 *aState
|= nsIAccessibleStates::STATE_READONLY
; // Links not focusable in editor
97 nsHTMLTextAccessible::GetAttributesInternal(nsIPersistentProperties
*aAttributes
)
100 return NS_ERROR_FAILURE
; // Node already shut down
105 if (role
== nsIAccessibleRole::ROLE_STATICTEXT
) {
106 nsAutoString oldValueUnused
;
107 aAttributes
->SetStringProperty(NS_LITERAL_CSTRING("auto-generated"),
108 NS_LITERAL_STRING("true"), oldValueUnused
);
114 nsHTMLHRAccessible::nsHTMLHRAccessible(nsIDOMNode
* aDomNode
, nsIWeakReference
* aShell
):
115 nsLeafAccessible(aDomNode
, aShell
)
119 NS_IMETHODIMP
nsHTMLHRAccessible::GetRole(PRUint32
*aRole
)
121 *aRole
= nsIAccessibleRole::ROLE_SEPARATOR
;
125 nsHTMLBRAccessible::nsHTMLBRAccessible(nsIDOMNode
* aDomNode
, nsIWeakReference
* aShell
):
126 nsLeafAccessible(aDomNode
, aShell
)
130 NS_IMETHODIMP
nsHTMLBRAccessible::GetRole(PRUint32
*aRole
)
132 *aRole
= nsIAccessibleRole::ROLE_WHITESPACE
;
137 nsHTMLBRAccessible::GetState(PRUint32
*aState
, PRUint32
*aExtraState
)
139 *aState
= nsIAccessibleStates::STATE_READONLY
;
141 *aExtraState
= mDOMNode
? 0 : nsIAccessibleStates::EXT_STATE_DEFUNCT
;
146 NS_IMETHODIMP
nsHTMLBRAccessible::GetName(nsAString
& aName
)
148 aName
= static_cast<PRUnichar
>('\n'); // Newline char
152 // A label is an element (not a leaf) and thus can support advanced interfaces.
153 // We need to skip over nsTextAccessible QI which prevents that
154 NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLLabelAccessible
, nsLinkableAccessible
)
156 nsHTMLLabelAccessible::nsHTMLLabelAccessible(nsIDOMNode
* aDomNode
, nsIWeakReference
* aShell
):
157 nsTextAccessible(aDomNode
, aShell
)
161 NS_IMETHODIMP
nsHTMLLabelAccessible::GetName(nsAString
& aReturn
)
163 nsresult rv
= NS_ERROR_FAILURE
;
164 nsCOMPtr
<nsIContent
> content(do_QueryInterface(mDOMNode
));
168 rv
= AppendFlatStringFromSubtree(content
, &name
);
170 if (NS_SUCCEEDED(rv
)) {
171 // Temp var needed until CompressWhitespace built for nsAString
172 name
.CompressWhitespace();
179 NS_IMETHODIMP
nsHTMLLabelAccessible::GetRole(PRUint32
*aRole
)
181 *aRole
= nsIAccessibleRole::ROLE_LABEL
;
186 nsHTMLLabelAccessible::GetState(PRUint32
*aState
, PRUint32
*aExtraState
)
188 nsresult rv
= nsTextAccessible::GetState(aState
, aExtraState
);
189 NS_ENSURE_SUCCESS(rv
, rv
);
191 *aState
&= (nsIAccessibleStates::STATE_LINKED
|
192 nsIAccessibleStates::STATE_TRAVERSED
); // Only use link states
197 NS_IMETHODIMP
nsHTMLLabelAccessible::GetFirstChild(nsIAccessible
**aFirstChild
)
199 // A <label> is not necessarily a leaf!
200 return nsAccessible::GetFirstChild(aFirstChild
);
203 /* readonly attribute nsIAccessible accFirstChild; */
204 NS_IMETHODIMP
nsHTMLLabelAccessible::GetLastChild(nsIAccessible
**aLastChild
)
206 // A <label> is not necessarily a leaf!
207 return nsAccessible::GetLastChild(aLastChild
);
210 /* readonly attribute long accChildCount; */
211 NS_IMETHODIMP
nsHTMLLabelAccessible::GetChildCount(PRInt32
*aAccChildCount
)
213 // A <label> is not necessarily a leaf!
214 return nsAccessible::GetChildCount(aAccChildCount
);
217 nsHTMLLIAccessible::nsHTMLLIAccessible(nsIDOMNode
*aDOMNode
, nsIWeakReference
* aShell
,
218 const nsAString
& aBulletText
):
219 nsLinkableAccessible(aDOMNode
, aShell
)
221 if (!aBulletText
.IsEmpty()) {
222 mBulletAccessible
= new nsHTMLListBulletAccessible(mDOMNode
, mWeakShell
,
224 nsCOMPtr
<nsPIAccessNode
> bulletANode(mBulletAccessible
);
231 NS_IMETHODIMP
nsHTMLLIAccessible::Shutdown()
233 if (mBulletAccessible
) {
234 // Ensure that weak pointer to this is nulled out
235 mBulletAccessible
->Shutdown();
237 nsresult rv
= nsLinkableAccessible::Shutdown();
238 mBulletAccessible
= nsnull
;
243 nsHTMLLIAccessible::GetState(PRUint32
*aState
, PRUint32
*aExtraState
)
245 nsresult rv
= nsAccessibleWrap::GetState(aState
, aExtraState
);
246 NS_ENSURE_SUCCESS(rv
, rv
);
248 *aState
|= nsIAccessibleStates::STATE_READONLY
;
252 NS_IMETHODIMP
nsHTMLLIAccessible::GetBounds(PRInt32
*x
, PRInt32
*y
, PRInt32
*width
, PRInt32
*height
)
254 nsresult rv
= nsAccessibleWrap::GetBounds(x
, y
, width
, height
);
255 if (NS_FAILED(rv
) || !mBulletAccessible
) {
259 PRInt32 bulletX
, bulletY
, bulletWidth
, bulletHeight
;
260 rv
= mBulletAccessible
->GetBounds(&bulletX
, &bulletY
, &bulletWidth
, &bulletHeight
);
261 NS_ENSURE_SUCCESS(rv
, rv
);
263 *x
= bulletX
; // Move x coordinate of list item over to cover bullet as well
264 *width
+= bulletWidth
;
268 void nsHTMLLIAccessible::CacheChildren()
270 if (!mWeakShell
|| mAccChildCount
!= eChildCountUninitialized
) {
274 nsAccessibleWrap::CacheChildren();
276 if (mBulletAccessible
) {
277 mBulletAccessible
->SetNextSibling(mFirstChild
);
278 mBulletAccessible
->SetParent(this); // Set weak parent;
279 SetFirstChild(mBulletAccessible
);
285 // nsHTMLListBulletAccessible
286 nsHTMLListBulletAccessible::
287 nsHTMLListBulletAccessible(nsIDOMNode
* aDomNode
, nsIWeakReference
* aShell
,
288 const nsAString
& aBulletText
) :
289 nsLeafAccessible(aDomNode
, aShell
), mWeakParent(nsnull
),
290 mBulletText(aBulletText
)
292 mBulletText
+= ' '; // Otherwise bullets are jammed up against list text
296 nsHTMLListBulletAccessible::GetUniqueID(void **aUniqueID
)
298 // Since mDOMNode is same as for list item, use |this| pointer as the unique Id
299 *aUniqueID
= static_cast<void*>(this);
304 nsHTMLListBulletAccessible::Shutdown()
306 mBulletText
.Truncate();
307 mWeakParent
= nsnull
;
309 return nsLeafAccessible::Shutdown();
313 nsHTMLListBulletAccessible::GetName(nsAString
&aName
)
320 nsHTMLListBulletAccessible::GetRole(PRUint32
*aRole
)
322 *aRole
= nsIAccessibleRole::ROLE_STATICTEXT
;
327 nsHTMLListBulletAccessible::GetState(PRUint32
*aState
, PRUint32
*aExtraState
)
329 nsresult rv
= nsLeafAccessible::GetState(aState
, aExtraState
);
330 NS_ENSURE_SUCCESS(rv
, rv
);
332 *aState
&= ~nsIAccessibleStates::STATE_FOCUSABLE
;
333 *aState
|= nsIAccessibleStates::STATE_READONLY
;
338 nsHTMLListBulletAccessible::SetParent(nsIAccessible
*aParentAccessible
)
341 mWeakParent
= aParentAccessible
;
346 nsHTMLListBulletAccessible::GetParent(nsIAccessible
**aParentAccessible
)
348 NS_IF_ADDREF(*aParentAccessible
= mWeakParent
);
353 nsHTMLListBulletAccessible::AppendTextTo(nsAString
& aText
, PRUint32 aStartOffset
,
356 PRUint32 maxLength
= mBulletText
.Length() - aStartOffset
;
357 if (aLength
> maxLength
) {
360 aText
+= nsDependentSubstring(mBulletText
, aStartOffset
, aLength
);
364 // nsHTMLListAccessible
367 nsHTMLListAccessible::GetState(PRUint32
*aState
, PRUint32
*aExtraState
)
369 nsresult rv
= nsHyperTextAccessibleWrap::GetState(aState
, aExtraState
);
370 NS_ENSURE_SUCCESS(rv
, rv
);
372 *aState
|= nsIAccessibleStates::STATE_READONLY
;