Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / content / xul / document / src / nsXULControllers.cpp
blob3af8d9cc2af547cacc5a433b553103e513096972
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 * Original Author: David W. Hyatt (hyatt@netscape.com)
24 * Mark Hammond <MarkH@ActiveState.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 ***** */
42 This file provides the implementation for the XUL "controllers"
43 object.
47 #include "nsString.h"
49 #include "nsIControllers.h"
50 #include "nsIDOMElement.h"
51 #include "nsXULControllers.h"
52 #include "nsString.h"
53 #include "nsContentUtils.h"
55 //----------------------------------------------------------------------
57 nsXULControllers::nsXULControllers()
58 : mCurControllerID(0)
62 nsXULControllers::~nsXULControllers(void)
64 DeleteControllers();
67 void
68 nsXULControllers::DeleteControllers()
70 PRUint32 count = mControllers.Count();
71 for (PRUint32 i = 0; i < count; i++)
73 nsXULControllerData* controllerData = static_cast<nsXULControllerData*>(mControllers.ElementAt(i));
74 if (controllerData)
75 delete controllerData; // releases the nsIController
78 mControllers.Clear();
82 NS_IMETHODIMP
83 NS_NewXULControllers(nsISupports* aOuter, REFNSIID aIID, void** aResult)
85 NS_PRECONDITION(aOuter == nsnull, "no aggregation");
86 if (aOuter)
87 return NS_ERROR_NO_AGGREGATION;
89 nsXULControllers* controllers = new nsXULControllers();
90 if (! controllers)
91 return NS_ERROR_OUT_OF_MEMORY;
93 nsresult rv;
94 NS_ADDREF(controllers);
95 rv = controllers->QueryInterface(aIID, aResult);
96 NS_RELEASE(controllers);
97 return rv;
100 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULControllers)
101 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULControllers)
102 tmp->DeleteControllers();
103 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
104 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULControllers)
106 PRUint32 i, count = tmp->mControllers.Count();
107 for (i = 0; i < count; ++i) {
108 nsXULControllerData* controllerData =
109 static_cast<nsXULControllerData*>(tmp->mControllers[i]);
110 if (controllerData) {
111 cb.NoteXPCOMChild(controllerData->mController);
115 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
117 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULControllers)
118 NS_INTERFACE_MAP_ENTRY(nsIControllers)
119 NS_INTERFACE_MAP_ENTRY(nsISecurityCheckedComponent)
120 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIControllers)
121 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(XULControllers)
122 NS_INTERFACE_MAP_END
124 NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsXULControllers, nsIControllers)
125 NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsXULControllers, nsIControllers)
127 NS_IMETHODIMP
128 nsXULControllers::GetControllerForCommand(const char *aCommand, nsIController** _retval)
130 NS_ENSURE_ARG_POINTER(_retval);
131 *_retval = nsnull;
133 PRUint32 count = mControllers.Count();
134 for (PRUint32 i=0; i < count; i++)
136 nsXULControllerData* controllerData = static_cast<nsXULControllerData*>(mControllers.ElementAt(i));
137 if (controllerData)
139 nsCOMPtr<nsIController> controller;
140 controllerData->GetController(getter_AddRefs(controller));
141 if (controller)
143 PRBool supportsCommand;
144 controller->SupportsCommand(aCommand, &supportsCommand);
145 if (supportsCommand) {
146 *_retval = controller;
147 NS_ADDREF(*_retval);
148 return NS_OK;
154 return NS_OK;
157 NS_IMETHODIMP
158 nsXULControllers::InsertControllerAt(PRUint32 aIndex, nsIController *controller)
160 nsXULControllerData* controllerData = new nsXULControllerData(++mCurControllerID, controller);
161 if (!controllerData) return NS_ERROR_OUT_OF_MEMORY;
162 #ifdef DEBUG
163 PRBool inserted =
164 #endif
165 mControllers.InsertElementAt((void *)controllerData, aIndex);
166 NS_ASSERTION(inserted, "Insertion of controller failed");
167 return NS_OK;
170 NS_IMETHODIMP
171 nsXULControllers::RemoveControllerAt(PRUint32 aIndex, nsIController **_retval)
173 NS_ENSURE_ARG_POINTER(_retval);
174 *_retval = nsnull;
176 nsXULControllerData* controllerData = static_cast<nsXULControllerData*>(mControllers.SafeElementAt(aIndex));
177 if (!controllerData) return NS_ERROR_FAILURE;
179 #ifdef DEBUG
180 PRBool removed =
181 #endif
182 mControllers.RemoveElementAt(aIndex);
183 NS_ASSERTION(removed, "Removal of controller failed");
185 controllerData->GetController(_retval);
186 delete controllerData;
188 return NS_OK;
192 NS_IMETHODIMP
193 nsXULControllers::GetControllerAt(PRUint32 aIndex, nsIController **_retval)
195 NS_ENSURE_ARG_POINTER(_retval);
196 *_retval = nsnull;
198 nsXULControllerData* controllerData = static_cast<nsXULControllerData*>(mControllers.SafeElementAt(aIndex));
199 if (!controllerData) return NS_ERROR_FAILURE;
201 return controllerData->GetController(_retval); // does the addref
204 NS_IMETHODIMP
205 nsXULControllers::AppendController(nsIController *controller)
207 // This assigns controller IDs starting at 1 so we can use 0 to test if an ID was obtained
208 nsXULControllerData* controllerData = new nsXULControllerData(++mCurControllerID, controller);
209 if (!controllerData) return NS_ERROR_OUT_OF_MEMORY;
211 #ifdef DEBUG
212 PRBool appended =
213 #endif
214 mControllers.AppendElement((void *)controllerData);
215 NS_ASSERTION(appended, "Appending controller failed");
216 return NS_OK;
219 NS_IMETHODIMP
220 nsXULControllers::RemoveController(nsIController *controller)
222 // first get the identity pointer
223 nsCOMPtr<nsISupports> controllerSup(do_QueryInterface(controller));
224 // then find it
225 PRUint32 count = mControllers.Count();
226 for (PRUint32 i = 0; i < count; i++)
228 nsXULControllerData* controllerData = static_cast<nsXULControllerData*>(mControllers.ElementAt(i));
229 if (controllerData)
231 nsCOMPtr<nsIController> thisController;
232 controllerData->GetController(getter_AddRefs(thisController));
233 nsCOMPtr<nsISupports> thisControllerSup(do_QueryInterface(thisController)); // get identity
234 if (thisControllerSup == controllerSup)
236 mControllers.RemoveElementAt(i);
237 delete controllerData;
238 return NS_OK;
242 return NS_ERROR_FAILURE; // right thing to return if no controller found?
245 /* unsigned long getControllerId (in nsIController controller); */
246 NS_IMETHODIMP
247 nsXULControllers::GetControllerId(nsIController *controller, PRUint32 *_retval)
249 NS_ENSURE_ARG_POINTER(_retval);
251 PRUint32 count = mControllers.Count();
252 for (PRUint32 i = 0; i < count; i++)
254 nsXULControllerData* controllerData = static_cast<nsXULControllerData*>(mControllers.ElementAt(i));
255 if (controllerData)
257 nsCOMPtr<nsIController> thisController;
258 controllerData->GetController(getter_AddRefs(thisController));
259 if (thisController.get() == controller)
261 *_retval = controllerData->GetControllerID();
262 return NS_OK;
266 return NS_ERROR_FAILURE; // none found
269 /* nsIController getControllerById (in unsigned long controllerID); */
270 NS_IMETHODIMP
271 nsXULControllers::GetControllerById(PRUint32 controllerID, nsIController **_retval)
273 NS_ENSURE_ARG_POINTER(_retval);
275 PRUint32 count = mControllers.Count();
276 for (PRUint32 i = 0; i < count; i++)
278 nsXULControllerData* controllerData = static_cast<nsXULControllerData*>(mControllers.ElementAt(i));
279 if (controllerData && controllerData->GetControllerID() == controllerID)
281 return controllerData->GetController(_retval);
284 return NS_ERROR_FAILURE; // none found
287 NS_IMETHODIMP
288 nsXULControllers::GetControllerCount(PRUint32 *_retval)
290 NS_ENSURE_ARG_POINTER(_retval);
291 *_retval = mControllers.Count();
292 return NS_OK;
295 // nsISecurityCheckedComponent implementation
297 static char* cloneAllAccess()
299 static const char allAccess[] = "AllAccess";
300 return (char*)nsMemory::Clone(allAccess, sizeof(allAccess));
303 static char* cloneUniversalXPConnect()
305 static const char universalXPConnect[] = "UniversalXPConnect";
306 return (char*)nsMemory::Clone(universalXPConnect, sizeof(universalXPConnect));
309 NS_IMETHODIMP
310 nsXULControllers::CanCreateWrapper(const nsIID * iid, char **_retval)
312 *_retval = cloneAllAccess();
313 return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
316 NS_IMETHODIMP
317 nsXULControllers::CanCallMethod(const nsIID * iid, const PRUnichar *methodName,
318 char **_retval)
320 // OK if you're cool enough
321 *_retval = cloneUniversalXPConnect();
322 return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
325 NS_IMETHODIMP
326 nsXULControllers::CanGetProperty(const nsIID * iid,
327 const PRUnichar *propertyName,
328 char **_retval)
330 // OK if you're cool enough
331 *_retval = cloneUniversalXPConnect();
332 return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
336 NS_IMETHODIMP
337 nsXULControllers::CanSetProperty(const nsIID * iid,
338 const PRUnichar *propertyName,
339 char **_retval)
341 // OK if you're cool enough
342 *_retval = cloneUniversalXPConnect();
343 return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;