Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / accessible / src / base / nsApplicationAccessible.cpp
blobf1c679186b63f086ddcbe587acbbfc82fdb9d61e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
3 */
4 /* ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
17 * The Original Code is mozilla.org code.
19 * The Initial Developer of the Original Code is
20 * Mozilla Foundation.
21 * Portions created by the Initial Developer are Copyright (C) 2007
22 * the Initial Developer. All Rights Reserved.
24 * Contributor(s):
25 * Bolian Yin <bolian.yin@sun.com>
26 * Ginn Chen <ginn.chen@sun.com>
27 * Alexander Surkov <surkov.alexander@gmail.com>
29 * Alternatively, the contents of this file may be used under the terms of
30 * either the GNU General Public License Version 2 or later (the "GPL"), or
31 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
32 * in which case the provisions of the GPL or the LGPL are applicable instead
33 * of those above. If you wish to allow use of your version of this file only
34 * under the terms of either the GPL or the LGPL, and not to allow others to
35 * use your version of this file under the terms of the MPL, indicate your
36 * decision by deleting the provisions above and replace them with the notice
37 * and other provisions required by the GPL or the LGPL. If you do not delete
38 * the provisions above, a recipient may use your version of this file under
39 * the terms of any one of the MPL, the GPL or the LGPL.
41 * ***** END LICENSE BLOCK ***** */
43 #include "nsApplicationAccessible.h"
45 #include "nsIComponentManager.h"
46 #include "nsServiceManagerUtils.h"
48 nsApplicationAccessible::nsApplicationAccessible():
49 nsAccessibleWrap(nsnull, nsnull), mChildren(nsnull)
53 ////////////////////////////////////////////////////////////////////////////////
54 // nsISupports
56 NS_IMPL_CYCLE_COLLECTION_CLASS(nsApplicationAccessible)
58 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsApplicationAccessible,
59 nsAccessible)
61 nsCOMPtr<nsISimpleEnumerator> enumerator;
62 tmp->mChildren->Enumerate(getter_AddRefs(enumerator));
64 nsCOMPtr<nsIWeakReference> childWeakRef;
65 nsCOMPtr<nsIAccessible> accessible;
67 PRBool hasMoreElements;
68 while(NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreElements))
69 && hasMoreElements) {
71 enumerator->GetNext(getter_AddRefs(childWeakRef));
72 accessible = do_QueryReferent(childWeakRef);
73 if (accessible) {
74 NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "nsApplicationAccessible child");
75 cb.NoteXPCOMChild(accessible);
79 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
81 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsApplicationAccessible,
82 nsAccessible)
83 tmp->mChildren->Clear();
84 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
86 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsApplicationAccessible)
87 NS_INTERFACE_MAP_END_INHERITING(nsAccessible)
89 NS_IMPL_ADDREF_INHERITED(nsApplicationAccessible, nsAccessible)
90 NS_IMPL_RELEASE_INHERITED(nsApplicationAccessible, nsAccessible)
92 ////////////////////////////////////////////////////////////////////////////////
93 // nsIAccessNode
95 nsresult
96 nsApplicationAccessible::Init()
98 nsresult rv;
99 mChildren = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
100 return rv;
103 // nsIAccessible
105 NS_IMETHODIMP
106 nsApplicationAccessible::GetName(nsAString& aName)
108 aName.Truncate();
110 nsCOMPtr<nsIStringBundleService> bundleService =
111 do_GetService(NS_STRINGBUNDLE_CONTRACTID);
113 NS_ASSERTION(bundleService, "String bundle service must be present!");
114 NS_ENSURE_STATE(bundleService);
116 nsCOMPtr<nsIStringBundle> bundle;
117 nsresult rv = bundleService->CreateBundle("chrome://branding/locale/brand.properties",
118 getter_AddRefs(bundle));
119 NS_ENSURE_SUCCESS(rv, rv);
121 nsXPIDLString appName;
122 rv = bundle->GetStringFromName(NS_LITERAL_STRING("brandShortName").get(),
123 getter_Copies(appName));
124 if (NS_FAILED(rv) || appName.IsEmpty()) {
125 NS_WARNING("brandShortName not found, using default app name");
126 appName.AssignLiteral("Gecko based application");
129 aName.Assign(appName);
130 return NS_OK;
133 NS_IMETHODIMP
134 nsApplicationAccessible::GetRole(PRUint32 *aRole)
136 *aRole = nsIAccessibleRole::ROLE_APP_ROOT;
137 return NS_OK;
140 NS_IMETHODIMP
141 nsApplicationAccessible::GetFinalRole(PRUint32 *aFinalRole)
143 return GetRole(aFinalRole);
146 nsresult
147 nsApplicationAccessible::GetStateInternal(PRUint32 *aState,
148 PRUint32 *aExtraState)
150 *aState = 0;
151 if (aExtraState)
152 *aExtraState = 0;
154 return NS_OK;
157 NS_IMETHODIMP
158 nsApplicationAccessible::GetParent(nsIAccessible **aParent)
160 *aParent = nsnull;
161 return NS_OK;
164 NS_IMETHODIMP
165 nsApplicationAccessible::GetChildAt(PRInt32 aChildNum, nsIAccessible **aChild)
167 NS_ENSURE_ARG_POINTER(aChild);
168 *aChild = nsnull;
170 PRUint32 count = 0;
171 nsresult rv = NS_OK;
173 if (mChildren) {
174 rv = mChildren->GetLength(&count);
175 NS_ENSURE_SUCCESS(rv, rv);
178 if (aChildNum >= static_cast<PRInt32>(count) || count == 0)
179 return NS_ERROR_INVALID_ARG;
181 if (aChildNum < 0)
182 aChildNum = count - 1;
184 nsCOMPtr<nsIWeakReference> childWeakRef;
185 rv = mChildren->QueryElementAt(aChildNum, NS_GET_IID(nsIWeakReference),
186 getter_AddRefs(childWeakRef));
187 NS_ENSURE_SUCCESS(rv, rv);
189 if (childWeakRef) {
190 nsCOMPtr<nsIAccessible> childAcc(do_QueryReferent(childWeakRef));
191 NS_IF_ADDREF(*aChild = childAcc);
194 return NS_OK;
197 NS_IMETHODIMP
198 nsApplicationAccessible::GetNextSibling(nsIAccessible **aNextSibling)
200 NS_ENSURE_ARG_POINTER(aNextSibling);
202 *aNextSibling = nsnull;
203 return NS_OK;
206 NS_IMETHODIMP
207 nsApplicationAccessible::GetPreviousSibling(nsIAccessible **aPreviousSibling)
209 NS_ENSURE_ARG_POINTER(aPreviousSibling);
211 *aPreviousSibling = nsnull;
212 return NS_OK;
215 NS_IMETHODIMP
216 nsApplicationAccessible::GetIndexInParent(PRInt32 *aIndexInParent)
218 NS_ENSURE_ARG_POINTER(aIndexInParent);
220 *aIndexInParent = -1;
221 return NS_OK;
224 void
225 nsApplicationAccessible::CacheChildren()
227 if (!mChildren) {
228 mAccChildCount = eChildCountUninitialized;
229 return;
232 if (mAccChildCount == eChildCountUninitialized) {
233 mAccChildCount = 0;// Prevent reentry
234 nsCOMPtr<nsISimpleEnumerator> enumerator;
235 mChildren->Enumerate(getter_AddRefs(enumerator));
237 nsCOMPtr<nsIWeakReference> childWeakRef;
238 nsCOMPtr<nsIAccessible> accessible;
239 nsCOMPtr<nsPIAccessible> previousAccessible;
240 PRBool hasMoreElements;
241 while(NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreElements))
242 && hasMoreElements) {
243 enumerator->GetNext(getter_AddRefs(childWeakRef));
244 accessible = do_QueryReferent(childWeakRef);
245 if (accessible) {
246 if (previousAccessible)
247 previousAccessible->SetNextSibling(accessible);
248 else
249 SetFirstChild(accessible);
251 previousAccessible = do_QueryInterface(accessible);
252 previousAccessible->SetParent(this);
256 PRUint32 count = 0;
257 mChildren->GetLength(&count);
258 mAccChildCount = static_cast<PRInt32>(count);
262 // nsApplicationAccessible
264 nsresult
265 nsApplicationAccessible::AddRootAccessible(nsIAccessible *aRootAccessible)
267 NS_ENSURE_ARG_POINTER(aRootAccessible);
269 // add by weak reference
270 nsresult rv = mChildren->AppendElement(aRootAccessible, PR_TRUE);
271 NS_ENSURE_SUCCESS(rv, rv);
273 InvalidateChildren();
274 return NS_OK;
277 nsresult
278 nsApplicationAccessible::RemoveRootAccessible(nsIAccessible *aRootAccessible)
280 NS_ENSURE_ARG_POINTER(aRootAccessible);
282 PRUint32 index = 0;
284 // we must use weak ref to get the index
285 nsCOMPtr<nsIWeakReference> weakPtr = do_GetWeakReference(aRootAccessible);
286 nsresult rv = mChildren->IndexOf(0, weakPtr, &index);
287 NS_ENSURE_SUCCESS(rv, rv);
289 rv = mChildren->RemoveElementAt(index);
290 NS_ENSURE_SUCCESS(rv, rv);
292 InvalidateChildren();
293 return NS_OK;