1 /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is the Mozilla browser.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications, Inc.
20 * Portions created by the Initial Developer are Copyright (C) 1999
21 * the Initial Developer. All Rights Reserved.
24 * David W. Hyatt <hyatt@netscape.com> (Original Author)
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 ***** */
41 #include "nsWindowRoot.h"
42 #include "nsPIDOMWindow.h"
43 #include "nsIDOMWindow.h"
44 #include "nsIDOMDocument.h"
45 #include "nsIDocument.h"
46 #include "nsIEventListenerManager.h"
47 #include "nsPresContext.h"
48 #include "nsLayoutCID.h"
49 #include "nsContentCID.h"
50 #include "nsIEventStateManager.h"
51 #include "nsIPrivateDOMEvent.h"
52 #include "nsIDOMWindowInternal.h"
54 #include "nsEventDispatcher.h"
55 #include "nsIProgrammingLanguage.h"
56 #include "nsGUIEvent.h"
57 #include "nsGlobalWindow.h"
58 #include "nsFocusManager.h"
59 #include "nsIDOMHTMLInputElement.h"
60 #include "nsIDOMNSHTMLTextAreaElement.h"
61 #include "nsIControllers.h"
63 #include "nsCycleCollectionParticipant.h"
66 #include "nsIDOMXULElement.h"
69 static NS_DEFINE_CID(kEventListenerManagerCID
, NS_EVENTLISTENERMANAGER_CID
);
71 nsWindowRoot::nsWindowRoot(nsPIDOMWindow
* aWindow
)
76 nsWindowRoot::~nsWindowRoot()
78 if (mListenerManager
) {
79 mListenerManager
->Disconnect();
83 NS_IMPL_CYCLE_COLLECTION_3(nsWindowRoot
, mListenerManager
, mPopupNode
,
86 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsWindowRoot
)
87 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsIDOMEventTarget
)
88 NS_INTERFACE_MAP_ENTRY(nsPIDOMEventTarget
)
89 NS_INTERFACE_MAP_ENTRY(nsPIWindowRoot
)
90 NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget
)
91 NS_INTERFACE_MAP_ENTRY(nsIDOM3EventTarget
)
92 NS_INTERFACE_MAP_ENTRY(nsIDOMNSEventTarget
)
95 NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsWindowRoot
, nsIDOMEventTarget
)
96 NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsWindowRoot
, nsIDOMEventTarget
)
99 nsWindowRoot::AddEventListener(const nsAString
& aType
, nsIDOMEventListener
* aListener
, PRBool aUseCapture
)
101 return AddEventListener(aType
, aListener
, aUseCapture
, PR_FALSE
, 0);
105 nsWindowRoot::RemoveEventListener(const nsAString
& aType
, nsIDOMEventListener
* aListener
, PRBool aUseCapture
)
107 return RemoveGroupedEventListener(aType
, aListener
, aUseCapture
, nsnull
);
111 nsWindowRoot::DispatchEvent(nsIDOMEvent
* aEvt
, PRBool
*_retval
)
113 nsEventStatus status
= nsEventStatus_eIgnore
;
114 nsresult rv
= nsEventDispatcher::DispatchDOMEvent(
115 static_cast<nsPIDOMEventTarget
*>(this), nsnull
, aEvt
, nsnull
, &status
);
116 *_retval
= (status
!= nsEventStatus_eConsumeNoDefault
);
121 nsWindowRoot::DispatchDOMEvent(nsEvent
* aEvent
,
122 nsIDOMEvent
* aDOMEvent
,
123 nsPresContext
* aPresContext
,
124 nsEventStatus
* aEventStatus
)
126 return nsEventDispatcher::DispatchDOMEvent(static_cast<nsPIDOMEventTarget
*>(this),
128 aPresContext
, aEventStatus
);
132 nsWindowRoot::AddGroupedEventListener(const nsAString
& aType
, nsIDOMEventListener
*aListener
,
133 PRBool aUseCapture
, nsIDOMEventGroup
*aEvtGrp
)
135 nsCOMPtr
<nsIEventListenerManager
> manager
= GetListenerManager(PR_TRUE
);
136 NS_ENSURE_STATE(manager
);
137 PRInt32 flags
= aUseCapture
? NS_EVENT_FLAG_CAPTURE
: NS_EVENT_FLAG_BUBBLE
;
138 return manager
->AddEventListenerByType(aListener
, aType
, flags
, aEvtGrp
);
142 nsWindowRoot::RemoveGroupedEventListener(const nsAString
& aType
, nsIDOMEventListener
*aListener
,
143 PRBool aUseCapture
, nsIDOMEventGroup
*aEvtGrp
)
145 if (mListenerManager
) {
146 PRInt32 flags
= aUseCapture
? NS_EVENT_FLAG_CAPTURE
: NS_EVENT_FLAG_BUBBLE
;
147 return mListenerManager
->RemoveEventListenerByType(aListener
, aType
, flags
,
154 nsWindowRoot::CanTrigger(const nsAString
& type
, PRBool
*_retval
)
156 return NS_ERROR_NOT_IMPLEMENTED
;
160 nsWindowRoot::IsRegisteredHere(const nsAString
& type
, PRBool
*_retval
)
162 return NS_ERROR_NOT_IMPLEMENTED
;
166 nsWindowRoot::AddEventListener(const nsAString
& aType
,
167 nsIDOMEventListener
*aListener
,
168 PRBool aUseCapture
, PRBool aWantsUntrusted
,
169 PRUint8 optional_argc
)
171 NS_ASSERTION(!aWantsUntrusted
|| optional_argc
> 0,
172 "Won't check if this is chrome, you want to set "
173 "aWantsUntrusted to PR_FALSE or make the aWantsUntrusted "
174 "explicit by making optional_argc non-zero.");
176 nsIEventListenerManager
* manager
= GetListenerManager(PR_TRUE
);
177 NS_ENSURE_STATE(manager
);
179 PRInt32 flags
= aUseCapture
? NS_EVENT_FLAG_CAPTURE
: NS_EVENT_FLAG_BUBBLE
;
181 if (aWantsUntrusted
) {
182 flags
|= NS_PRIV_EVENT_UNTRUSTED_PERMITTED
;
185 return manager
->AddEventListenerByType(aListener
, aType
, flags
, nsnull
);
189 nsWindowRoot::AddEventListenerByIID(nsIDOMEventListener
*aListener
, const nsIID
& aIID
)
191 nsIEventListenerManager
* manager
= GetListenerManager(PR_TRUE
);
192 NS_ENSURE_STATE(manager
);
193 return manager
->AddEventListenerByIID(aListener
, aIID
, NS_EVENT_FLAG_BUBBLE
);
197 nsWindowRoot::RemoveEventListenerByIID(nsIDOMEventListener
*aListener
, const nsIID
& aIID
)
199 nsIEventListenerManager
* manager
= GetListenerManager(PR_TRUE
);
201 return manager
->RemoveEventListenerByIID(aListener
, aIID
,
202 NS_EVENT_FLAG_BUBBLE
);
207 nsIEventListenerManager
*
208 nsWindowRoot::GetListenerManager(PRBool aCreateIfNotFound
)
210 if (!mListenerManager
) {
211 if (!aCreateIfNotFound
) {
215 mListenerManager
= do_CreateInstance(kEventListenerManagerCID
);
216 if (mListenerManager
) {
217 mListenerManager
->SetListenerTarget(
218 static_cast<nsPIDOMEventTarget
*>(this));
222 return mListenerManager
;
226 nsWindowRoot::GetSystemEventGroup(nsIDOMEventGroup
**aGroup
)
228 nsIEventListenerManager
* manager
= GetListenerManager(PR_TRUE
);
229 NS_ENSURE_STATE(manager
);
230 return manager
->GetSystemEventGroupLM(aGroup
);
235 nsWindowRoot::PreHandleEvent(nsEventChainPreVisitor
& aVisitor
)
237 aVisitor
.mCanHandle
= PR_TRUE
;
238 aVisitor
.mForceContentDispatch
= PR_TRUE
; //FIXME! Bug 329119
239 // To keep mWindow alive
240 aVisitor
.mItemData
= static_cast<nsISupports
*>(mWindow
);
241 aVisitor
.mParentTarget
= mParent
;
246 nsWindowRoot::PostHandleEvent(nsEventChainPostVisitor
& aVisitor
)
252 nsWindowRoot::GetWindow()
258 nsWindowRoot::GetScriptTypeID(PRUint32
*aScriptType
)
260 NS_ERROR("No default script type here - ask some element");
261 return nsIProgrammingLanguage::UNKNOWN
;
265 nsWindowRoot::SetScriptTypeID(PRUint32 aScriptType
)
267 NS_ERROR("Can't change default script type for a document");
268 return NS_ERROR_NOT_IMPLEMENTED
;
272 nsWindowRoot::GetControllers(nsIControllers
** aResult
)
276 // XXX: we should fix this so there's a generic interface that
277 // describes controllers, so this code would have no special
278 // knowledge of what object might have controllers.
280 nsCOMPtr
<nsPIDOMWindow
> focusedWindow
;
281 nsIContent
* focusedContent
=
282 nsFocusManager::GetFocusedDescendant(mWindow
, PR_TRUE
, getter_AddRefs(focusedWindow
));
283 if (focusedContent
) {
285 nsCOMPtr
<nsIDOMXULElement
> xulElement(do_QueryInterface(focusedContent
));
287 return xulElement
->GetControllers(aResult
);
290 nsCOMPtr
<nsIDOMNSHTMLTextAreaElement
> htmlTextArea
=
291 do_QueryInterface(focusedContent
);
293 return htmlTextArea
->GetControllers(aResult
);
295 nsCOMPtr
<nsIDOMHTMLInputElement
> htmlInputElement
=
296 do_QueryInterface(focusedContent
);
297 if (htmlInputElement
)
298 return htmlInputElement
->GetControllers(aResult
);
300 if (focusedContent
->IsEditable() && focusedWindow
)
301 return focusedWindow
->GetControllers(aResult
);
304 nsCOMPtr
<nsIDOMWindowInternal
> domWindow
= do_QueryInterface(focusedWindow
);
306 return domWindow
->GetControllers(aResult
);
313 nsWindowRoot::GetControllerForCommand(const char * aCommand
,
314 nsIController
** _retval
)
316 NS_ENSURE_ARG_POINTER(_retval
);
319 nsCOMPtr
<nsIControllers
> controllers
;
320 nsCOMPtr
<nsIController
> controller
;
322 GetControllers(getter_AddRefs(controllers
));
324 controllers
->GetControllerForCommand(aCommand
, getter_AddRefs(controller
));
326 controller
.swap(*_retval
);
331 nsCOMPtr
<nsPIDOMWindow
> focusedWindow
;
332 nsFocusManager::GetFocusedDescendant(mWindow
, PR_TRUE
, getter_AddRefs(focusedWindow
));
333 while (focusedWindow
) {
334 nsCOMPtr
<nsIDOMWindowInternal
> domWindow(do_QueryInterface(focusedWindow
));
336 nsCOMPtr
<nsIControllers
> controllers2
;
337 domWindow
->GetControllers(getter_AddRefs(controllers2
));
339 controllers2
->GetControllerForCommand(aCommand
,
340 getter_AddRefs(controller
));
342 controller
.swap(*_retval
);
347 // XXXndeakin P3 is this casting safe?
348 nsCOMPtr
<nsPIDOMWindow
> piWindow
= do_QueryInterface(focusedWindow
);
349 nsGlobalWindow
*win
=
350 static_cast<nsGlobalWindow
*>
351 (static_cast<nsIDOMWindowInternal
*>(piWindow
));
352 focusedWindow
= win
->GetPrivateParent();
359 nsWindowRoot::GetPopupNode()
365 nsWindowRoot::SetPopupNode(nsIDOMNode
* aNode
)
370 ///////////////////////////////////////////////////////////////////////////////////
373 NS_NewWindowRoot(nsPIDOMWindow
* aWindow
, nsPIDOMEventTarget
** aResult
)
375 *aResult
= new nsWindowRoot(aWindow
);
377 return NS_ERROR_OUT_OF_MEMORY
;