Bug 454376 add -lCrun -lCstd for Solaris OS_LIBS, r=bsmedberg
[wine-gecko.git] / accessible / src / html / nsHTMLTextAccessible.cpp
blob44fd29ff13112e2b869306ba36ed793225646d01
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
13 * License.
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.
22 * Contributor(s):
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"
44 #include "nsIFrame.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)
58 aName.Truncate();
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;
69 return NS_OK;
72 return nsTextAccessible::GetRole(aRole);
75 NS_IMETHODIMP
76 nsHTMLTextAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
78 nsresult rv = nsTextAccessible::GetState(aState, aExtraState);
79 NS_ENSURE_SUCCESS(rv, rv);
80 if (!mDOMNode)
81 return NS_OK;
83 nsCOMPtr<nsIAccessible> docAccessible =
84 do_QueryInterface(nsCOMPtr<nsIAccessibleDocument>(GetDocAccessible()));
85 if (docAccessible) {
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
93 return NS_OK;
96 nsresult
97 nsHTMLTextAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
99 if (!mDOMNode) {
100 return NS_ERROR_FAILURE; // Node already shut down
103 PRUint32 role;
104 GetRole(&role);
105 if (role == nsIAccessibleRole::ROLE_STATICTEXT) {
106 nsAutoString oldValueUnused;
107 aAttributes->SetStringProperty(NS_LITERAL_CSTRING("auto-generated"),
108 NS_LITERAL_STRING("true"), oldValueUnused);
111 return NS_OK;
114 nsHTMLHRAccessible::nsHTMLHRAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell):
115 nsLeafAccessible(aDomNode, aShell)
119 NS_IMETHODIMP nsHTMLHRAccessible::GetRole(PRUint32 *aRole)
121 *aRole = nsIAccessibleRole::ROLE_SEPARATOR;
122 return NS_OK;
125 nsHTMLBRAccessible::nsHTMLBRAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell):
126 nsLeafAccessible(aDomNode, aShell)
130 NS_IMETHODIMP nsHTMLBRAccessible::GetRole(PRUint32 *aRole)
132 *aRole = nsIAccessibleRole::ROLE_WHITESPACE;
133 return NS_OK;
136 NS_IMETHODIMP
137 nsHTMLBRAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
139 *aState = nsIAccessibleStates::STATE_READONLY;
140 if (aExtraState) {
141 *aExtraState = mDOMNode ? 0 : nsIAccessibleStates::EXT_STATE_DEFUNCT;
143 return NS_OK;
146 NS_IMETHODIMP nsHTMLBRAccessible::GetName(nsAString& aName)
148 aName = static_cast<PRUnichar>('\n'); // Newline char
149 return NS_OK;
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));
166 nsAutoString name;
167 if (content)
168 rv = AppendFlatStringFromSubtree(content, &name);
170 if (NS_SUCCEEDED(rv)) {
171 // Temp var needed until CompressWhitespace built for nsAString
172 name.CompressWhitespace();
173 aReturn = name;
176 return rv;
179 NS_IMETHODIMP nsHTMLLabelAccessible::GetRole(PRUint32 *aRole)
181 *aRole = nsIAccessibleRole::ROLE_LABEL;
182 return NS_OK;
185 NS_IMETHODIMP
186 nsHTMLLabelAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
188 nsresult rv = nsTextAccessible::GetState(aState, aExtraState);
189 NS_ENSURE_SUCCESS(rv, rv);
190 if (mDOMNode) {
191 *aState &= (nsIAccessibleStates::STATE_LINKED |
192 nsIAccessibleStates::STATE_TRAVERSED); // Only use link states
194 return NS_OK;
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,
223 aBulletText);
224 nsCOMPtr<nsPIAccessNode> bulletANode(mBulletAccessible);
225 if (bulletANode) {
226 bulletANode->Init();
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;
239 return rv;
242 NS_IMETHODIMP
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;
249 return NS_OK;
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) {
256 return rv;
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;
265 return NS_OK;
268 void nsHTMLLIAccessible::CacheChildren()
270 if (!mWeakShell || mAccChildCount != eChildCountUninitialized) {
271 return;
274 nsAccessibleWrap::CacheChildren();
276 if (mBulletAccessible) {
277 mBulletAccessible->SetNextSibling(mFirstChild);
278 mBulletAccessible->SetParent(this); // Set weak parent;
279 SetFirstChild(mBulletAccessible);
280 ++ mAccChildCount;
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
295 NS_IMETHODIMP
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);
300 return NS_OK;
303 NS_IMETHODIMP
304 nsHTMLListBulletAccessible::Shutdown()
306 mBulletText.Truncate();
307 mWeakParent = nsnull;
309 return nsLeafAccessible::Shutdown();
312 NS_IMETHODIMP
313 nsHTMLListBulletAccessible::GetName(nsAString &aName)
315 aName = mBulletText;
316 return NS_OK;
319 NS_IMETHODIMP
320 nsHTMLListBulletAccessible::GetRole(PRUint32 *aRole)
322 *aRole = nsIAccessibleRole::ROLE_STATICTEXT;
323 return NS_OK;
326 NS_IMETHODIMP
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;
334 return NS_OK;
337 NS_IMETHODIMP
338 nsHTMLListBulletAccessible::SetParent(nsIAccessible *aParentAccessible)
340 mParent = nsnull;
341 mWeakParent = aParentAccessible;
342 return NS_OK;
345 NS_IMETHODIMP
346 nsHTMLListBulletAccessible::GetParent(nsIAccessible **aParentAccessible)
348 NS_IF_ADDREF(*aParentAccessible = mWeakParent);
349 return NS_OK;
352 NS_IMETHODIMP
353 nsHTMLListBulletAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
354 PRUint32 aLength)
356 PRUint32 maxLength = mBulletText.Length() - aStartOffset;
357 if (aLength > maxLength) {
358 aLength = maxLength;
360 aText += nsDependentSubstring(mBulletText, aStartOffset, aLength);
361 return NS_OK;
364 // nsHTMLListAccessible
366 NS_IMETHODIMP
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;
373 return NS_OK;