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 "nsIDOMWindow.h"
43 #include "nsIDOMDocument.h"
44 #include "nsIDocument.h"
45 #include "nsIEventListenerManager.h"
46 #include "nsIPresShell.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"
53 #include "nsFocusController.h"
55 #include "nsEventDispatcher.h"
56 #include "nsIProgrammingLanguage.h"
58 #include "nsCycleCollectionParticipant.h"
60 static NS_DEFINE_CID(kEventListenerManagerCID
, NS_EVENTLISTENERMANAGER_CID
);
62 nsWindowRoot::nsWindowRoot(nsIDOMWindow
* aWindow
)
66 // Create and init our focus controller.
67 nsFocusController::Create(getter_AddRefs(mFocusController
));
69 nsCOMPtr
<nsIDOMFocusListener
> focusListener(do_QueryInterface(mFocusController
));
70 mRefCnt
.incr(static_cast<nsIDOMEventTarget
*>(this));
71 AddEventListener(NS_LITERAL_STRING("focus"), focusListener
, PR_TRUE
);
72 AddEventListener(NS_LITERAL_STRING("blur"), focusListener
, PR_TRUE
);
73 mRefCnt
.decr(static_cast<nsIDOMEventTarget
*>(this));
76 nsWindowRoot::~nsWindowRoot()
78 if (mListenerManager
) {
79 mListenerManager
->Disconnect();
83 NS_IMPL_CYCLE_COLLECTION_2(nsWindowRoot
, mListenerManager
, mFocusController
)
85 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsWindowRoot
)
86 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsIDOMEventTarget
)
87 NS_INTERFACE_MAP_ENTRY(nsPIDOMEventTarget
)
88 NS_INTERFACE_MAP_ENTRY(nsPIWindowRoot
)
89 NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget
)
90 NS_INTERFACE_MAP_ENTRY(nsIDOM3EventTarget
)
91 NS_INTERFACE_MAP_ENTRY(nsIDOMNSEventTarget
)
94 NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsWindowRoot
, nsIDOMEventTarget
)
95 NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsWindowRoot
, nsIDOMEventTarget
)
98 nsWindowRoot::AddEventListener(const nsAString
& aType
, nsIDOMEventListener
* aListener
, PRBool aUseCapture
)
100 return AddGroupedEventListener(aType
, aListener
, aUseCapture
, nsnull
);
104 nsWindowRoot::RemoveEventListener(const nsAString
& aType
, nsIDOMEventListener
* aListener
, PRBool aUseCapture
)
106 return RemoveGroupedEventListener(aType
, aListener
, aUseCapture
, nsnull
);
110 nsWindowRoot::DispatchEvent(nsIDOMEvent
* aEvt
, PRBool
*_retval
)
112 nsEventStatus status
= nsEventStatus_eIgnore
;
113 nsresult rv
= nsEventDispatcher::DispatchDOMEvent(
114 static_cast<nsPIDOMEventTarget
*>(this), nsnull
, aEvt
, nsnull
, &status
);
115 *_retval
= (status
!= nsEventStatus_eConsumeNoDefault
);
120 nsWindowRoot::DispatchDOMEvent(nsEvent
* aEvent
,
121 nsIDOMEvent
* aDOMEvent
,
122 nsPresContext
* aPresContext
,
123 nsEventStatus
* aEventStatus
)
125 return nsEventDispatcher::DispatchDOMEvent(static_cast<nsPIDOMEventTarget
*>(this),
127 aPresContext
, aEventStatus
);
131 nsWindowRoot::AddGroupedEventListener(const nsAString
& aType
, nsIDOMEventListener
*aListener
,
132 PRBool aUseCapture
, nsIDOMEventGroup
*aEvtGrp
)
134 nsCOMPtr
<nsIEventListenerManager
> manager
;
136 if (NS_SUCCEEDED(GetListenerManager(PR_TRUE
, getter_AddRefs(manager
)))) {
137 PRInt32 flags
= aUseCapture
? NS_EVENT_FLAG_CAPTURE
: NS_EVENT_FLAG_BUBBLE
;
138 manager
->AddEventListenerByType(aListener
, aType
, flags
, aEvtGrp
);
141 return NS_ERROR_FAILURE
;
145 nsWindowRoot::RemoveGroupedEventListener(const nsAString
& aType
, nsIDOMEventListener
*aListener
,
146 PRBool aUseCapture
, nsIDOMEventGroup
*aEvtGrp
)
148 if (mListenerManager
) {
149 PRInt32 flags
= aUseCapture
? NS_EVENT_FLAG_CAPTURE
: NS_EVENT_FLAG_BUBBLE
;
150 mListenerManager
->RemoveEventListenerByType(aListener
, aType
, flags
, aEvtGrp
);
153 return NS_ERROR_FAILURE
;
157 nsWindowRoot::CanTrigger(const nsAString
& type
, PRBool
*_retval
)
159 return NS_ERROR_NOT_IMPLEMENTED
;
163 nsWindowRoot::IsRegisteredHere(const nsAString
& type
, PRBool
*_retval
)
165 return NS_ERROR_NOT_IMPLEMENTED
;
169 nsWindowRoot::AddEventListener(const nsAString
& aType
,
170 nsIDOMEventListener
*aListener
,
171 PRBool aUseCapture
, PRBool aWantsUntrusted
)
173 nsCOMPtr
<nsIEventListenerManager
> manager
;
174 nsresult rv
= GetListenerManager(PR_TRUE
, getter_AddRefs(manager
));
175 NS_ENSURE_SUCCESS(rv
, rv
);
177 PRInt32 flags
= aUseCapture
? NS_EVENT_FLAG_CAPTURE
: NS_EVENT_FLAG_BUBBLE
;
179 if (aWantsUntrusted
) {
180 flags
|= NS_PRIV_EVENT_UNTRUSTED_PERMITTED
;
183 return manager
->AddEventListenerByType(aListener
, aType
, flags
, nsnull
);
187 nsWindowRoot::AddEventListenerByIID(nsIDOMEventListener
*aListener
, const nsIID
& aIID
)
189 nsCOMPtr
<nsIEventListenerManager
> manager
;
190 GetListenerManager(PR_TRUE
, getter_AddRefs(manager
));
192 manager
->AddEventListenerByIID(aListener
, aIID
, NS_EVENT_FLAG_BUBBLE
);
195 return NS_ERROR_FAILURE
;
199 nsWindowRoot::RemoveEventListenerByIID(nsIDOMEventListener
*aListener
, const nsIID
& aIID
)
201 nsCOMPtr
<nsIEventListenerManager
> manager
;
202 GetListenerManager(PR_TRUE
, getter_AddRefs(manager
));
204 manager
->RemoveEventListenerByIID(aListener
, aIID
, NS_EVENT_FLAG_BUBBLE
);
207 return NS_ERROR_FAILURE
;
211 nsWindowRoot::GetListenerManager(PRBool aCreateIfNotFound
,
212 nsIEventListenerManager
** aResult
)
214 if (!mListenerManager
) {
215 if (!aCreateIfNotFound
) {
220 mListenerManager
= do_CreateInstance(kEventListenerManagerCID
, &rv
);
221 if (NS_FAILED(rv
)) return rv
;
222 mListenerManager
->SetListenerTarget(
223 static_cast<nsPIDOMEventTarget
*>(this));
226 *aResult
= mListenerManager
;
232 nsWindowRoot::GetSystemEventGroup(nsIDOMEventGroup
**aGroup
)
234 nsCOMPtr
<nsIEventListenerManager
> manager
;
235 if (NS_SUCCEEDED(GetListenerManager(PR_TRUE
, getter_AddRefs(manager
))) &&
237 return manager
->GetSystemEventGroupLM(aGroup
);
239 return NS_ERROR_FAILURE
;
244 nsWindowRoot::PreHandleEvent(nsEventChainPreVisitor
& aVisitor
)
246 aVisitor
.mCanHandle
= PR_TRUE
;
247 aVisitor
.mForceContentDispatch
= PR_TRUE
; //FIXME! Bug 329119
248 // To keep mWindow alive
249 aVisitor
.mItemData
= mWindow
;
254 nsWindowRoot::PostHandleEvent(nsEventChainPostVisitor
& aVisitor
)
260 nsWindowRoot::GetFocusController(nsIFocusController
** aResult
)
262 *aResult
= mFocusController
;
263 NS_IF_ADDREF(*aResult
);
268 nsWindowRoot::GetWindow()
274 nsWindowRoot::GetScriptTypeID(PRUint32
*aScriptType
)
276 NS_ERROR("No default script type here - ask some element");
277 return nsIProgrammingLanguage::UNKNOWN
;
281 nsWindowRoot::SetScriptTypeID(PRUint32 aScriptType
)
283 NS_ERROR("Can't change default script type for a document");
284 return NS_ERROR_NOT_IMPLEMENTED
;
287 ///////////////////////////////////////////////////////////////////////////////////
290 NS_NewWindowRoot(nsIDOMWindow
* aWindow
, nsPIDOMEventTarget
** aResult
)
292 *aResult
= new nsWindowRoot(aWindow
);
294 return NS_ERROR_OUT_OF_MEMORY
;