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 the Mozilla browser.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications, Inc.
19 : * Portions created by the Initial Developer are Copyright (C) 1999
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * David W. Hyatt <hyatt@netscape.com> (Original Author)
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #include "nsCOMPtr.h"
40 : #include "nsWindowRoot.h"
41 : #include "nsPIDOMWindow.h"
42 : #include "nsIDOMDocument.h"
43 : #include "nsIDocument.h"
44 : #include "nsEventListenerManager.h"
45 : #include "nsPresContext.h"
46 : #include "nsLayoutCID.h"
47 : #include "nsContentCID.h"
48 : #include "nsIPrivateDOMEvent.h"
49 : #include "nsString.h"
50 : #include "nsEventDispatcher.h"
51 : #include "nsGUIEvent.h"
52 : #include "nsGlobalWindow.h"
53 : #include "nsFocusManager.h"
54 : #include "nsIDOMHTMLInputElement.h"
55 : #include "nsIDOMHTMLTextAreaElement.h"
56 : #include "nsIControllers.h"
57 :
58 : #include "nsCycleCollectionParticipant.h"
59 :
60 : #ifdef MOZ_XUL
61 : #include "nsIDOMXULElement.h"
62 : #endif
63 :
64 : static NS_DEFINE_CID(kEventListenerManagerCID, NS_EVENTLISTENERMANAGER_CID);
65 :
66 0 : nsWindowRoot::nsWindowRoot(nsPIDOMWindow* aWindow)
67 : {
68 0 : mWindow = aWindow;
69 0 : }
70 :
71 0 : nsWindowRoot::~nsWindowRoot()
72 : {
73 0 : if (mListenerManager) {
74 0 : mListenerManager->Disconnect();
75 : }
76 0 : }
77 :
78 1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsWindowRoot)
79 :
80 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsWindowRoot)
81 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mListenerManager,
82 : nsEventListenerManager)
83 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mPopupNode)
84 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParent)
85 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
86 :
87 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsWindowRoot)
88 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mListenerManager)
89 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mPopupNode)
90 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParent)
91 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
92 :
93 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsWindowRoot)
94 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEventTarget)
95 0 : NS_INTERFACE_MAP_ENTRY(nsPIWindowRoot)
96 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
97 0 : NS_INTERFACE_MAP_END
98 :
99 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsWindowRoot)
100 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsWindowRoot)
101 :
102 0 : NS_IMPL_DOMTARGET_DEFAULTS(nsWindowRoot)
103 :
104 : NS_IMETHODIMP
105 0 : nsWindowRoot::RemoveEventListener(const nsAString& aType, nsIDOMEventListener* aListener, bool aUseCapture)
106 : {
107 0 : nsRefPtr<nsEventListenerManager> elm = GetListenerManager(false);
108 0 : if (elm) {
109 0 : elm->RemoveEventListener(aType, aListener, aUseCapture);
110 : }
111 0 : return NS_OK;
112 : }
113 :
114 0 : NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(nsWindowRoot)
115 :
116 : NS_IMETHODIMP
117 0 : nsWindowRoot::DispatchEvent(nsIDOMEvent* aEvt, bool *aRetVal)
118 : {
119 0 : nsEventStatus status = nsEventStatus_eIgnore;
120 : nsresult rv = nsEventDispatcher::DispatchDOMEvent(
121 0 : static_cast<nsIDOMEventTarget*>(this), nsnull, aEvt, nsnull, &status);
122 0 : *aRetVal = (status != nsEventStatus_eConsumeNoDefault);
123 0 : return rv;
124 : }
125 :
126 : nsresult
127 0 : nsWindowRoot::DispatchDOMEvent(nsEvent* aEvent,
128 : nsIDOMEvent* aDOMEvent,
129 : nsPresContext* aPresContext,
130 : nsEventStatus* aEventStatus)
131 : {
132 : return nsEventDispatcher::DispatchDOMEvent(static_cast<nsIDOMEventTarget*>(this),
133 : aEvent, aDOMEvent,
134 0 : aPresContext, aEventStatus);
135 : }
136 :
137 : NS_IMETHODIMP
138 0 : nsWindowRoot::AddEventListener(const nsAString& aType,
139 : nsIDOMEventListener *aListener,
140 : bool aUseCapture, bool aWantsUntrusted,
141 : PRUint8 aOptionalArgc)
142 : {
143 0 : NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1,
144 : "Won't check if this is chrome, you want to set "
145 : "aWantsUntrusted to false or make the aWantsUntrusted "
146 : "explicit by making optional_argc non-zero.");
147 :
148 0 : nsEventListenerManager* elm = GetListenerManager(true);
149 0 : NS_ENSURE_STATE(elm);
150 0 : elm->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted);
151 0 : return NS_OK;
152 : }
153 :
154 : NS_IMETHODIMP
155 0 : nsWindowRoot::AddSystemEventListener(const nsAString& aType,
156 : nsIDOMEventListener *aListener,
157 : bool aUseCapture,
158 : bool aWantsUntrusted,
159 : PRUint8 aOptionalArgc)
160 : {
161 0 : NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1,
162 : "Won't check if this is chrome, you want to set "
163 : "aWantsUntrusted to false or make the aWantsUntrusted "
164 : "explicit by making optional_argc non-zero.");
165 :
166 : return NS_AddSystemEventListener(this, aType, aListener, aUseCapture,
167 0 : aWantsUntrusted);
168 : }
169 :
170 : nsEventListenerManager*
171 0 : nsWindowRoot::GetListenerManager(bool aCreateIfNotFound)
172 : {
173 0 : if (!mListenerManager && aCreateIfNotFound) {
174 : mListenerManager =
175 0 : new nsEventListenerManager(static_cast<nsIDOMEventTarget*>(this));
176 : }
177 :
178 0 : return mListenerManager;
179 : }
180 :
181 : nsIScriptContext*
182 0 : nsWindowRoot::GetContextForEventHandlers(nsresult* aRv)
183 : {
184 0 : *aRv = NS_OK;
185 0 : return nsnull;
186 : }
187 :
188 : nsresult
189 0 : nsWindowRoot::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
190 : {
191 0 : aVisitor.mCanHandle = true;
192 0 : aVisitor.mForceContentDispatch = true; //FIXME! Bug 329119
193 : // To keep mWindow alive
194 0 : aVisitor.mItemData = static_cast<nsISupports *>(mWindow);
195 0 : aVisitor.mParentTarget = mParent;
196 0 : return NS_OK;
197 : }
198 :
199 : nsresult
200 0 : nsWindowRoot::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
201 : {
202 0 : return NS_OK;
203 : }
204 :
205 : nsPIDOMWindow*
206 0 : nsWindowRoot::GetWindow()
207 : {
208 0 : return mWindow;
209 : }
210 :
211 : nsresult
212 0 : nsWindowRoot::GetControllers(nsIControllers** aResult)
213 : {
214 0 : *aResult = nsnull;
215 :
216 : // XXX: we should fix this so there's a generic interface that
217 : // describes controllers, so this code would have no special
218 : // knowledge of what object might have controllers.
219 :
220 0 : nsCOMPtr<nsPIDOMWindow> focusedWindow;
221 : nsIContent* focusedContent =
222 0 : nsFocusManager::GetFocusedDescendant(mWindow, true, getter_AddRefs(focusedWindow));
223 0 : if (focusedContent) {
224 : #ifdef MOZ_XUL
225 0 : nsCOMPtr<nsIDOMXULElement> xulElement(do_QueryInterface(focusedContent));
226 0 : if (xulElement)
227 0 : return xulElement->GetControllers(aResult);
228 : #endif
229 :
230 : nsCOMPtr<nsIDOMHTMLTextAreaElement> htmlTextArea =
231 0 : do_QueryInterface(focusedContent);
232 0 : if (htmlTextArea)
233 0 : return htmlTextArea->GetControllers(aResult);
234 :
235 : nsCOMPtr<nsIDOMHTMLInputElement> htmlInputElement =
236 0 : do_QueryInterface(focusedContent);
237 0 : if (htmlInputElement)
238 0 : return htmlInputElement->GetControllers(aResult);
239 :
240 0 : if (focusedContent->IsEditable() && focusedWindow)
241 0 : return focusedWindow->GetControllers(aResult);
242 : }
243 : else {
244 0 : nsCOMPtr<nsIDOMWindow> domWindow = do_QueryInterface(focusedWindow);
245 0 : if (domWindow)
246 0 : return domWindow->GetControllers(aResult);
247 : }
248 :
249 0 : return NS_OK;
250 : }
251 :
252 : nsresult
253 0 : nsWindowRoot::GetControllerForCommand(const char * aCommand,
254 : nsIController** _retval)
255 : {
256 0 : NS_ENSURE_ARG_POINTER(_retval);
257 0 : *_retval = nsnull;
258 :
259 : {
260 0 : nsCOMPtr<nsIControllers> controllers;
261 0 : GetControllers(getter_AddRefs(controllers));
262 0 : if (controllers) {
263 0 : nsCOMPtr<nsIController> controller;
264 0 : controllers->GetControllerForCommand(aCommand, getter_AddRefs(controller));
265 0 : if (controller) {
266 0 : controller.forget(_retval);
267 0 : return NS_OK;
268 : }
269 : }
270 : }
271 :
272 0 : nsCOMPtr<nsPIDOMWindow> focusedWindow;
273 0 : nsFocusManager::GetFocusedDescendant(mWindow, true, getter_AddRefs(focusedWindow));
274 0 : while (focusedWindow) {
275 0 : nsCOMPtr<nsIControllers> controllers;
276 0 : focusedWindow->GetControllers(getter_AddRefs(controllers));
277 0 : if (controllers) {
278 0 : nsCOMPtr<nsIController> controller;
279 0 : controllers->GetControllerForCommand(aCommand,
280 0 : getter_AddRefs(controller));
281 0 : if (controller) {
282 0 : controller.forget(_retval);
283 0 : return NS_OK;
284 : }
285 : }
286 :
287 : // XXXndeakin P3 is this casting safe?
288 0 : nsGlobalWindow *win = static_cast<nsGlobalWindow*>(focusedWindow.get());
289 0 : focusedWindow = win->GetPrivateParent();
290 : }
291 :
292 0 : return NS_OK;
293 : }
294 :
295 : nsIDOMNode*
296 0 : nsWindowRoot::GetPopupNode()
297 : {
298 0 : return mPopupNode;
299 : }
300 :
301 : void
302 0 : nsWindowRoot::SetPopupNode(nsIDOMNode* aNode)
303 : {
304 0 : mPopupNode = aNode;
305 0 : }
306 :
307 : ///////////////////////////////////////////////////////////////////////////////////
308 :
309 : nsresult
310 0 : NS_NewWindowRoot(nsPIDOMWindow* aWindow, nsIDOMEventTarget** aResult)
311 : {
312 0 : *aResult = new nsWindowRoot(aWindow);
313 0 : NS_ADDREF(*aResult);
314 0 : return NS_OK;
315 4392 : }
|