1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "mozilla/BasicEvents.h"
7 #include "mozilla/EventDispatcher.h"
8 #include "mozilla/EventListenerManager.h"
10 #include "nsWindowRoot.h"
11 #include "nsPIDOMWindow.h"
12 #include "nsPresContext.h"
13 #include "nsLayoutCID.h"
14 #include "nsContentCID.h"
16 #include "nsGlobalWindow.h"
17 #include "nsFocusManager.h"
18 #include "nsIContent.h"
19 #include "nsIDOMHTMLInputElement.h"
20 #include "nsIDOMHTMLTextAreaElement.h"
21 #include "nsIControllers.h"
22 #include "nsIController.h"
24 #include "nsCycleCollectionParticipant.h"
27 #include "nsIDOMXULElement.h"
30 using namespace mozilla
;
31 using namespace mozilla::dom
;
33 nsWindowRoot::nsWindowRoot(nsPIDOMWindow
* aWindow
)
38 nsWindowRoot::~nsWindowRoot()
40 if (mListenerManager
) {
41 mListenerManager
->Disconnect();
45 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsWindowRoot
,
51 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsWindowRoot
)
52 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
53 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsIDOMEventTarget
)
54 NS_INTERFACE_MAP_ENTRY(nsPIWindowRoot
)
55 NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget
)
56 NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget
)
59 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsWindowRoot
)
60 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsWindowRoot
)
62 NS_IMPL_DOMTARGET_DEFAULTS(nsWindowRoot
)
65 nsWindowRoot::RemoveEventListener(const nsAString
& aType
, nsIDOMEventListener
* aListener
, bool aUseCapture
)
67 if (nsRefPtr
<EventListenerManager
> elm
= GetExistingListenerManager()) {
68 elm
->RemoveEventListener(aType
, aListener
, aUseCapture
);
73 NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(nsWindowRoot
)
76 nsWindowRoot::DispatchEvent(nsIDOMEvent
* aEvt
, bool *aRetVal
)
78 nsEventStatus status
= nsEventStatus_eIgnore
;
79 nsresult rv
= EventDispatcher::DispatchDOMEvent(
80 static_cast<EventTarget
*>(this), nullptr, aEvt
, nullptr, &status
);
81 *aRetVal
= (status
!= nsEventStatus_eConsumeNoDefault
);
86 nsWindowRoot::DispatchDOMEvent(WidgetEvent
* aEvent
,
87 nsIDOMEvent
* aDOMEvent
,
88 nsPresContext
* aPresContext
,
89 nsEventStatus
* aEventStatus
)
91 return EventDispatcher::DispatchDOMEvent(static_cast<EventTarget
*>(this),
93 aPresContext
, aEventStatus
);
97 nsWindowRoot::AddEventListener(const nsAString
& aType
,
98 nsIDOMEventListener
*aListener
,
99 bool aUseCapture
, bool aWantsUntrusted
,
100 uint8_t aOptionalArgc
)
102 NS_ASSERTION(!aWantsUntrusted
|| aOptionalArgc
> 1,
103 "Won't check if this is chrome, you want to set "
104 "aWantsUntrusted to false or make the aWantsUntrusted "
105 "explicit by making optional_argc non-zero.");
107 EventListenerManager
* elm
= GetOrCreateListenerManager();
108 NS_ENSURE_STATE(elm
);
109 elm
->AddEventListener(aType
, aListener
, aUseCapture
, aWantsUntrusted
);
114 nsWindowRoot::AddEventListener(const nsAString
& aType
,
115 EventListener
* aListener
,
117 const Nullable
<bool>& aWantsUntrusted
,
120 bool wantsUntrusted
= !aWantsUntrusted
.IsNull() && aWantsUntrusted
.Value();
121 EventListenerManager
* elm
= GetOrCreateListenerManager();
123 aRv
.Throw(NS_ERROR_UNEXPECTED
);
126 elm
->AddEventListener(aType
, aListener
, aUseCapture
, wantsUntrusted
);
131 nsWindowRoot::AddSystemEventListener(const nsAString
& aType
,
132 nsIDOMEventListener
*aListener
,
134 bool aWantsUntrusted
,
135 uint8_t aOptionalArgc
)
137 NS_ASSERTION(!aWantsUntrusted
|| aOptionalArgc
> 1,
138 "Won't check if this is chrome, you want to set "
139 "aWantsUntrusted to false or make the aWantsUntrusted "
140 "explicit by making optional_argc non-zero.");
142 return NS_AddSystemEventListener(this, aType
, aListener
, aUseCapture
,
146 EventListenerManager
*
147 nsWindowRoot::GetOrCreateListenerManager()
149 if (!mListenerManager
) {
151 new EventListenerManager(static_cast<EventTarget
*>(this));
154 return mListenerManager
;
157 EventListenerManager
*
158 nsWindowRoot::GetExistingListenerManager() const
160 return mListenerManager
;
164 nsWindowRoot::GetContextForEventHandlers(nsresult
* aRv
)
171 nsWindowRoot::PreHandleEvent(EventChainPreVisitor
& aVisitor
)
173 aVisitor
.mCanHandle
= true;
174 aVisitor
.mForceContentDispatch
= true; //FIXME! Bug 329119
175 // To keep mWindow alive
176 aVisitor
.mItemData
= static_cast<nsISupports
*>(mWindow
);
177 aVisitor
.mParentTarget
= mParent
;
182 nsWindowRoot::PostHandleEvent(EventChainPostVisitor
& aVisitor
)
188 nsWindowRoot::GetOwnerGlobal()
194 nsWindowRoot::GetWindow()
200 nsWindowRoot::GetControllers(nsIControllers
** aResult
)
204 // XXX: we should fix this so there's a generic interface that
205 // describes controllers, so this code would have no special
206 // knowledge of what object might have controllers.
208 nsCOMPtr
<nsPIDOMWindow
> focusedWindow
;
209 nsIContent
* focusedContent
=
210 nsFocusManager::GetFocusedDescendant(mWindow
, true, getter_AddRefs(focusedWindow
));
211 if (focusedContent
) {
213 nsCOMPtr
<nsIDOMXULElement
> xulElement(do_QueryInterface(focusedContent
));
215 return xulElement
->GetControllers(aResult
);
218 nsCOMPtr
<nsIDOMHTMLTextAreaElement
> htmlTextArea
=
219 do_QueryInterface(focusedContent
);
221 return htmlTextArea
->GetControllers(aResult
);
223 nsCOMPtr
<nsIDOMHTMLInputElement
> htmlInputElement
=
224 do_QueryInterface(focusedContent
);
225 if (htmlInputElement
)
226 return htmlInputElement
->GetControllers(aResult
);
228 if (focusedContent
->IsEditable() && focusedWindow
)
229 return focusedWindow
->GetControllers(aResult
);
232 nsCOMPtr
<nsIDOMWindow
> domWindow
= do_QueryInterface(focusedWindow
);
234 return domWindow
->GetControllers(aResult
);
241 nsWindowRoot::GetControllerForCommand(const char * aCommand
,
242 nsIController
** _retval
)
244 NS_ENSURE_ARG_POINTER(_retval
);
248 nsCOMPtr
<nsIControllers
> controllers
;
249 GetControllers(getter_AddRefs(controllers
));
251 nsCOMPtr
<nsIController
> controller
;
252 controllers
->GetControllerForCommand(aCommand
, getter_AddRefs(controller
));
254 controller
.forget(_retval
);
260 nsCOMPtr
<nsPIDOMWindow
> focusedWindow
;
261 nsFocusManager::GetFocusedDescendant(mWindow
, true, getter_AddRefs(focusedWindow
));
262 while (focusedWindow
) {
263 nsCOMPtr
<nsIControllers
> controllers
;
264 focusedWindow
->GetControllers(getter_AddRefs(controllers
));
266 nsCOMPtr
<nsIController
> controller
;
267 controllers
->GetControllerForCommand(aCommand
,
268 getter_AddRefs(controller
));
270 controller
.forget(_retval
);
275 // XXXndeakin P3 is this casting safe?
276 nsGlobalWindow
*win
= static_cast<nsGlobalWindow
*>(focusedWindow
.get());
277 focusedWindow
= win
->GetPrivateParent();
284 nsWindowRoot::GetPopupNode()
290 nsWindowRoot::SetPopupNode(nsIDOMNode
* aNode
)
295 ///////////////////////////////////////////////////////////////////////////////////
297 already_AddRefed
<EventTarget
>
298 NS_NewWindowRoot(nsPIDOMWindow
* aWindow
)
300 nsCOMPtr
<EventTarget
> result
= new nsWindowRoot(aWindow
);
301 return result
.forget();