Bumping manifests a=b2g-bump
[gecko.git] / dom / base / nsWindowRoot.cpp
blob65c53951d06ec12d61b354aa858e47051c2deae9
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"
9 #include "nsCOMPtr.h"
10 #include "nsWindowRoot.h"
11 #include "nsPIDOMWindow.h"
12 #include "nsPresContext.h"
13 #include "nsLayoutCID.h"
14 #include "nsContentCID.h"
15 #include "nsString.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"
26 #ifdef MOZ_XUL
27 #include "nsIDOMXULElement.h"
28 #endif
30 using namespace mozilla;
31 using namespace mozilla::dom;
33 nsWindowRoot::nsWindowRoot(nsPIDOMWindow* aWindow)
35 mWindow = aWindow;
38 nsWindowRoot::~nsWindowRoot()
40 if (mListenerManager) {
41 mListenerManager->Disconnect();
45 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsWindowRoot,
46 mWindow,
47 mListenerManager,
48 mPopupNode,
49 mParent)
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)
57 NS_INTERFACE_MAP_END
59 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsWindowRoot)
60 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsWindowRoot)
62 NS_IMPL_DOMTARGET_DEFAULTS(nsWindowRoot)
64 NS_IMETHODIMP
65 nsWindowRoot::RemoveEventListener(const nsAString& aType, nsIDOMEventListener* aListener, bool aUseCapture)
67 if (nsRefPtr<EventListenerManager> elm = GetExistingListenerManager()) {
68 elm->RemoveEventListener(aType, aListener, aUseCapture);
70 return NS_OK;
73 NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(nsWindowRoot)
75 NS_IMETHODIMP
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);
82 return rv;
85 nsresult
86 nsWindowRoot::DispatchDOMEvent(WidgetEvent* aEvent,
87 nsIDOMEvent* aDOMEvent,
88 nsPresContext* aPresContext,
89 nsEventStatus* aEventStatus)
91 return EventDispatcher::DispatchDOMEvent(static_cast<EventTarget*>(this),
92 aEvent, aDOMEvent,
93 aPresContext, aEventStatus);
96 NS_IMETHODIMP
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);
110 return NS_OK;
113 void
114 nsWindowRoot::AddEventListener(const nsAString& aType,
115 EventListener* aListener,
116 bool aUseCapture,
117 const Nullable<bool>& aWantsUntrusted,
118 ErrorResult& aRv)
120 bool wantsUntrusted = !aWantsUntrusted.IsNull() && aWantsUntrusted.Value();
121 EventListenerManager* elm = GetOrCreateListenerManager();
122 if (!elm) {
123 aRv.Throw(NS_ERROR_UNEXPECTED);
124 return;
126 elm->AddEventListener(aType, aListener, aUseCapture, wantsUntrusted);
130 NS_IMETHODIMP
131 nsWindowRoot::AddSystemEventListener(const nsAString& aType,
132 nsIDOMEventListener *aListener,
133 bool aUseCapture,
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,
143 aWantsUntrusted);
146 EventListenerManager*
147 nsWindowRoot::GetOrCreateListenerManager()
149 if (!mListenerManager) {
150 mListenerManager =
151 new EventListenerManager(static_cast<EventTarget*>(this));
154 return mListenerManager;
157 EventListenerManager*
158 nsWindowRoot::GetExistingListenerManager() const
160 return mListenerManager;
163 nsIScriptContext*
164 nsWindowRoot::GetContextForEventHandlers(nsresult* aRv)
166 *aRv = NS_OK;
167 return nullptr;
170 nsresult
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;
178 return NS_OK;
181 nsresult
182 nsWindowRoot::PostHandleEvent(EventChainPostVisitor& aVisitor)
184 return NS_OK;
187 nsIDOMWindow*
188 nsWindowRoot::GetOwnerGlobal()
190 return GetWindow();
193 nsPIDOMWindow*
194 nsWindowRoot::GetWindow()
196 return mWindow;
199 nsresult
200 nsWindowRoot::GetControllers(nsIControllers** aResult)
202 *aResult = nullptr;
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) {
212 #ifdef MOZ_XUL
213 nsCOMPtr<nsIDOMXULElement> xulElement(do_QueryInterface(focusedContent));
214 if (xulElement)
215 return xulElement->GetControllers(aResult);
216 #endif
218 nsCOMPtr<nsIDOMHTMLTextAreaElement> htmlTextArea =
219 do_QueryInterface(focusedContent);
220 if (htmlTextArea)
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);
231 else {
232 nsCOMPtr<nsIDOMWindow> domWindow = do_QueryInterface(focusedWindow);
233 if (domWindow)
234 return domWindow->GetControllers(aResult);
237 return NS_OK;
240 nsresult
241 nsWindowRoot::GetControllerForCommand(const char * aCommand,
242 nsIController** _retval)
244 NS_ENSURE_ARG_POINTER(_retval);
245 *_retval = nullptr;
248 nsCOMPtr<nsIControllers> controllers;
249 GetControllers(getter_AddRefs(controllers));
250 if (controllers) {
251 nsCOMPtr<nsIController> controller;
252 controllers->GetControllerForCommand(aCommand, getter_AddRefs(controller));
253 if (controller) {
254 controller.forget(_retval);
255 return NS_OK;
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));
265 if (controllers) {
266 nsCOMPtr<nsIController> controller;
267 controllers->GetControllerForCommand(aCommand,
268 getter_AddRefs(controller));
269 if (controller) {
270 controller.forget(_retval);
271 return NS_OK;
275 // XXXndeakin P3 is this casting safe?
276 nsGlobalWindow *win = static_cast<nsGlobalWindow*>(focusedWindow.get());
277 focusedWindow = win->GetPrivateParent();
280 return NS_OK;
283 nsIDOMNode*
284 nsWindowRoot::GetPopupNode()
286 return mPopupNode;
289 void
290 nsWindowRoot::SetPopupNode(nsIDOMNode* aNode)
292 mPopupNode = aNode;
295 ///////////////////////////////////////////////////////////////////////////////////
297 already_AddRefed<EventTarget>
298 NS_NewWindowRoot(nsPIDOMWindow* aWindow)
300 nsCOMPtr<EventTarget> result = new nsWindowRoot(aWindow);
301 return result.forget();