1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/base/nsWindowRoot.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,302 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "mozilla/BasicEvents.h" 1.10 +#include "mozilla/EventDispatcher.h" 1.11 +#include "mozilla/EventListenerManager.h" 1.12 +#include "nsCOMPtr.h" 1.13 +#include "nsWindowRoot.h" 1.14 +#include "nsPIDOMWindow.h" 1.15 +#include "nsPresContext.h" 1.16 +#include "nsLayoutCID.h" 1.17 +#include "nsContentCID.h" 1.18 +#include "nsString.h" 1.19 +#include "nsGlobalWindow.h" 1.20 +#include "nsFocusManager.h" 1.21 +#include "nsIContent.h" 1.22 +#include "nsIDOMHTMLInputElement.h" 1.23 +#include "nsIDOMHTMLTextAreaElement.h" 1.24 +#include "nsIControllers.h" 1.25 +#include "nsIController.h" 1.26 + 1.27 +#include "nsCycleCollectionParticipant.h" 1.28 + 1.29 +#ifdef MOZ_XUL 1.30 +#include "nsIDOMXULElement.h" 1.31 +#endif 1.32 + 1.33 +using namespace mozilla; 1.34 +using namespace mozilla::dom; 1.35 + 1.36 +nsWindowRoot::nsWindowRoot(nsPIDOMWindow* aWindow) 1.37 +{ 1.38 + mWindow = aWindow; 1.39 +} 1.40 + 1.41 +nsWindowRoot::~nsWindowRoot() 1.42 +{ 1.43 + if (mListenerManager) { 1.44 + mListenerManager->Disconnect(); 1.45 + } 1.46 +} 1.47 + 1.48 +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_4(nsWindowRoot, 1.49 + mWindow, 1.50 + mListenerManager, 1.51 + mPopupNode, 1.52 + mParent) 1.53 + 1.54 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsWindowRoot) 1.55 + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 1.56 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEventTarget) 1.57 + NS_INTERFACE_MAP_ENTRY(nsPIWindowRoot) 1.58 + NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget) 1.59 + NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget) 1.60 +NS_INTERFACE_MAP_END 1.61 + 1.62 +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsWindowRoot) 1.63 +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsWindowRoot) 1.64 + 1.65 +NS_IMPL_DOMTARGET_DEFAULTS(nsWindowRoot) 1.66 + 1.67 +NS_IMETHODIMP 1.68 +nsWindowRoot::RemoveEventListener(const nsAString& aType, nsIDOMEventListener* aListener, bool aUseCapture) 1.69 +{ 1.70 + if (nsRefPtr<EventListenerManager> elm = GetExistingListenerManager()) { 1.71 + elm->RemoveEventListener(aType, aListener, aUseCapture); 1.72 + } 1.73 + return NS_OK; 1.74 +} 1.75 + 1.76 +NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(nsWindowRoot) 1.77 + 1.78 +NS_IMETHODIMP 1.79 +nsWindowRoot::DispatchEvent(nsIDOMEvent* aEvt, bool *aRetVal) 1.80 +{ 1.81 + nsEventStatus status = nsEventStatus_eIgnore; 1.82 + nsresult rv = EventDispatcher::DispatchDOMEvent( 1.83 + static_cast<EventTarget*>(this), nullptr, aEvt, nullptr, &status); 1.84 + *aRetVal = (status != nsEventStatus_eConsumeNoDefault); 1.85 + return rv; 1.86 +} 1.87 + 1.88 +nsresult 1.89 +nsWindowRoot::DispatchDOMEvent(WidgetEvent* aEvent, 1.90 + nsIDOMEvent* aDOMEvent, 1.91 + nsPresContext* aPresContext, 1.92 + nsEventStatus* aEventStatus) 1.93 +{ 1.94 + return EventDispatcher::DispatchDOMEvent(static_cast<EventTarget*>(this), 1.95 + aEvent, aDOMEvent, 1.96 + aPresContext, aEventStatus); 1.97 +} 1.98 + 1.99 +NS_IMETHODIMP 1.100 +nsWindowRoot::AddEventListener(const nsAString& aType, 1.101 + nsIDOMEventListener *aListener, 1.102 + bool aUseCapture, bool aWantsUntrusted, 1.103 + uint8_t aOptionalArgc) 1.104 +{ 1.105 + NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1, 1.106 + "Won't check if this is chrome, you want to set " 1.107 + "aWantsUntrusted to false or make the aWantsUntrusted " 1.108 + "explicit by making optional_argc non-zero."); 1.109 + 1.110 + EventListenerManager* elm = GetOrCreateListenerManager(); 1.111 + NS_ENSURE_STATE(elm); 1.112 + elm->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted); 1.113 + return NS_OK; 1.114 +} 1.115 + 1.116 +void 1.117 +nsWindowRoot::AddEventListener(const nsAString& aType, 1.118 + EventListener* aListener, 1.119 + bool aUseCapture, 1.120 + const Nullable<bool>& aWantsUntrusted, 1.121 + ErrorResult& aRv) 1.122 +{ 1.123 + bool wantsUntrusted = !aWantsUntrusted.IsNull() && aWantsUntrusted.Value(); 1.124 + EventListenerManager* elm = GetOrCreateListenerManager(); 1.125 + if (!elm) { 1.126 + aRv.Throw(NS_ERROR_UNEXPECTED); 1.127 + return; 1.128 + } 1.129 + elm->AddEventListener(aType, aListener, aUseCapture, wantsUntrusted); 1.130 +} 1.131 + 1.132 + 1.133 +NS_IMETHODIMP 1.134 +nsWindowRoot::AddSystemEventListener(const nsAString& aType, 1.135 + nsIDOMEventListener *aListener, 1.136 + bool aUseCapture, 1.137 + bool aWantsUntrusted, 1.138 + uint8_t aOptionalArgc) 1.139 +{ 1.140 + NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1, 1.141 + "Won't check if this is chrome, you want to set " 1.142 + "aWantsUntrusted to false or make the aWantsUntrusted " 1.143 + "explicit by making optional_argc non-zero."); 1.144 + 1.145 + return NS_AddSystemEventListener(this, aType, aListener, aUseCapture, 1.146 + aWantsUntrusted); 1.147 +} 1.148 + 1.149 +EventListenerManager* 1.150 +nsWindowRoot::GetOrCreateListenerManager() 1.151 +{ 1.152 + if (!mListenerManager) { 1.153 + mListenerManager = 1.154 + new EventListenerManager(static_cast<EventTarget*>(this)); 1.155 + } 1.156 + 1.157 + return mListenerManager; 1.158 +} 1.159 + 1.160 +EventListenerManager* 1.161 +nsWindowRoot::GetExistingListenerManager() const 1.162 +{ 1.163 + return mListenerManager; 1.164 +} 1.165 + 1.166 +nsIScriptContext* 1.167 +nsWindowRoot::GetContextForEventHandlers(nsresult* aRv) 1.168 +{ 1.169 + *aRv = NS_OK; 1.170 + return nullptr; 1.171 +} 1.172 + 1.173 +nsresult 1.174 +nsWindowRoot::PreHandleEvent(EventChainPreVisitor& aVisitor) 1.175 +{ 1.176 + aVisitor.mCanHandle = true; 1.177 + aVisitor.mForceContentDispatch = true; //FIXME! Bug 329119 1.178 + // To keep mWindow alive 1.179 + aVisitor.mItemData = static_cast<nsISupports *>(mWindow); 1.180 + aVisitor.mParentTarget = mParent; 1.181 + return NS_OK; 1.182 +} 1.183 + 1.184 +nsresult 1.185 +nsWindowRoot::PostHandleEvent(EventChainPostVisitor& aVisitor) 1.186 +{ 1.187 + return NS_OK; 1.188 +} 1.189 + 1.190 +nsIDOMWindow* 1.191 +nsWindowRoot::GetOwnerGlobal() 1.192 +{ 1.193 + return GetWindow(); 1.194 +} 1.195 + 1.196 +nsPIDOMWindow* 1.197 +nsWindowRoot::GetWindow() 1.198 +{ 1.199 + return mWindow; 1.200 +} 1.201 + 1.202 +nsresult 1.203 +nsWindowRoot::GetControllers(nsIControllers** aResult) 1.204 +{ 1.205 + *aResult = nullptr; 1.206 + 1.207 + // XXX: we should fix this so there's a generic interface that 1.208 + // describes controllers, so this code would have no special 1.209 + // knowledge of what object might have controllers. 1.210 + 1.211 + nsCOMPtr<nsPIDOMWindow> focusedWindow; 1.212 + nsIContent* focusedContent = 1.213 + nsFocusManager::GetFocusedDescendant(mWindow, true, getter_AddRefs(focusedWindow)); 1.214 + if (focusedContent) { 1.215 +#ifdef MOZ_XUL 1.216 + nsCOMPtr<nsIDOMXULElement> xulElement(do_QueryInterface(focusedContent)); 1.217 + if (xulElement) 1.218 + return xulElement->GetControllers(aResult); 1.219 +#endif 1.220 + 1.221 + nsCOMPtr<nsIDOMHTMLTextAreaElement> htmlTextArea = 1.222 + do_QueryInterface(focusedContent); 1.223 + if (htmlTextArea) 1.224 + return htmlTextArea->GetControllers(aResult); 1.225 + 1.226 + nsCOMPtr<nsIDOMHTMLInputElement> htmlInputElement = 1.227 + do_QueryInterface(focusedContent); 1.228 + if (htmlInputElement) 1.229 + return htmlInputElement->GetControllers(aResult); 1.230 + 1.231 + if (focusedContent->IsEditable() && focusedWindow) 1.232 + return focusedWindow->GetControllers(aResult); 1.233 + } 1.234 + else { 1.235 + nsCOMPtr<nsIDOMWindow> domWindow = do_QueryInterface(focusedWindow); 1.236 + if (domWindow) 1.237 + return domWindow->GetControllers(aResult); 1.238 + } 1.239 + 1.240 + return NS_OK; 1.241 +} 1.242 + 1.243 +nsresult 1.244 +nsWindowRoot::GetControllerForCommand(const char * aCommand, 1.245 + nsIController** _retval) 1.246 +{ 1.247 + NS_ENSURE_ARG_POINTER(_retval); 1.248 + *_retval = nullptr; 1.249 + 1.250 + { 1.251 + nsCOMPtr<nsIControllers> controllers; 1.252 + GetControllers(getter_AddRefs(controllers)); 1.253 + if (controllers) { 1.254 + nsCOMPtr<nsIController> controller; 1.255 + controllers->GetControllerForCommand(aCommand, getter_AddRefs(controller)); 1.256 + if (controller) { 1.257 + controller.forget(_retval); 1.258 + return NS_OK; 1.259 + } 1.260 + } 1.261 + } 1.262 + 1.263 + nsCOMPtr<nsPIDOMWindow> focusedWindow; 1.264 + nsFocusManager::GetFocusedDescendant(mWindow, true, getter_AddRefs(focusedWindow)); 1.265 + while (focusedWindow) { 1.266 + nsCOMPtr<nsIControllers> controllers; 1.267 + focusedWindow->GetControllers(getter_AddRefs(controllers)); 1.268 + if (controllers) { 1.269 + nsCOMPtr<nsIController> controller; 1.270 + controllers->GetControllerForCommand(aCommand, 1.271 + getter_AddRefs(controller)); 1.272 + if (controller) { 1.273 + controller.forget(_retval); 1.274 + return NS_OK; 1.275 + } 1.276 + } 1.277 + 1.278 + // XXXndeakin P3 is this casting safe? 1.279 + nsGlobalWindow *win = static_cast<nsGlobalWindow*>(focusedWindow.get()); 1.280 + focusedWindow = win->GetPrivateParent(); 1.281 + } 1.282 + 1.283 + return NS_OK; 1.284 +} 1.285 + 1.286 +nsIDOMNode* 1.287 +nsWindowRoot::GetPopupNode() 1.288 +{ 1.289 + return mPopupNode; 1.290 +} 1.291 + 1.292 +void 1.293 +nsWindowRoot::SetPopupNode(nsIDOMNode* aNode) 1.294 +{ 1.295 + mPopupNode = aNode; 1.296 +} 1.297 + 1.298 +/////////////////////////////////////////////////////////////////////////////////// 1.299 + 1.300 +already_AddRefed<EventTarget> 1.301 +NS_NewWindowRoot(nsPIDOMWindow* aWindow) 1.302 +{ 1.303 + nsCOMPtr<EventTarget> result = new nsWindowRoot(aWindow); 1.304 + return result.forget(); 1.305 +}