dom/events/EventListenerService.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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 "EventListenerService.h"
     7 #ifdef MOZ_JSDEBUGGER
     8 #include "jsdIDebuggerService.h"
     9 #endif
    10 #include "mozilla/BasicEvents.h"
    11 #include "mozilla/EventDispatcher.h"
    12 #include "mozilla/EventListenerManager.h"
    13 #include "mozilla/JSEventHandler.h"
    14 #include "mozilla/Maybe.h"
    15 #include "nsCOMArray.h"
    16 #include "nsCxPusher.h"
    17 #include "nsDOMClassInfoID.h"
    18 #include "nsIXPConnect.h"
    19 #include "nsJSUtils.h"
    20 #include "nsMemory.h"
    21 #include "nsServiceManagerUtils.h"
    23 namespace mozilla {
    25 using namespace dom;
    27 /******************************************************************************
    28  * mozilla::EventListenerInfo
    29  ******************************************************************************/
    31 NS_IMPL_CYCLE_COLLECTION(EventListenerInfo, mListener)
    33 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(EventListenerInfo)
    34   NS_INTERFACE_MAP_ENTRY(nsIEventListenerInfo)
    35   NS_INTERFACE_MAP_ENTRY(nsISupports)
    36 NS_INTERFACE_MAP_END
    38 NS_IMPL_CYCLE_COLLECTING_ADDREF(EventListenerInfo)
    39 NS_IMPL_CYCLE_COLLECTING_RELEASE(EventListenerInfo)
    41 NS_IMETHODIMP
    42 EventListenerInfo::GetType(nsAString& aType)
    43 {
    44   aType = mType;
    45   return NS_OK;
    46 }
    48 NS_IMETHODIMP
    49 EventListenerInfo::GetCapturing(bool* aCapturing)
    50 {
    51   *aCapturing = mCapturing;
    52   return NS_OK;
    53 }
    55 NS_IMETHODIMP
    56 EventListenerInfo::GetAllowsUntrusted(bool* aAllowsUntrusted)
    57 {
    58   *aAllowsUntrusted = mAllowsUntrusted;
    59   return NS_OK;
    60 }
    62 NS_IMETHODIMP
    63 EventListenerInfo::GetInSystemEventGroup(bool* aInSystemEventGroup)
    64 {
    65   *aInSystemEventGroup = mInSystemEventGroup;
    66   return NS_OK;
    67 }
    69 NS_IMETHODIMP
    70 EventListenerInfo::GetListenerObject(JSContext* aCx,
    71                                      JS::MutableHandle<JS::Value> aObject)
    72 {
    73   Maybe<JSAutoCompartment> ac;
    74   GetJSVal(aCx, ac, aObject);
    75   return NS_OK;
    76 }
    78 /******************************************************************************
    79  * mozilla::EventListenerService
    80  ******************************************************************************/
    82 NS_IMPL_ISUPPORTS(EventListenerService, nsIEventListenerService)
    84 bool
    85 EventListenerInfo::GetJSVal(JSContext* aCx,
    86                             Maybe<JSAutoCompartment>& aAc,
    87                             JS::MutableHandle<JS::Value> aJSVal)
    88 {
    89   aJSVal.setNull();
    90   nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS = do_QueryInterface(mListener);
    91   if (wrappedJS) {
    92     JS::Rooted<JSObject*> object(aCx, wrappedJS->GetJSObject());
    93     if (!object) {
    94       return false;
    95     }
    96     aAc.construct(aCx, object);
    97     aJSVal.setObject(*object);
    98     return true;
    99   }
   101   nsCOMPtr<JSEventHandler> jsHandler = do_QueryInterface(mListener);
   102   if (jsHandler && jsHandler->GetTypedEventHandler().HasEventHandler()) {
   103     JS::Handle<JSObject*> handler =
   104       jsHandler->GetTypedEventHandler().Ptr()->Callable();
   105     if (handler) {
   106       aAc.construct(aCx, handler);
   107       aJSVal.setObject(*handler);
   108       return true;
   109     }
   110   }
   111   return false;
   112 }
   114 NS_IMETHODIMP
   115 EventListenerInfo::ToSource(nsAString& aResult)
   116 {
   117   aResult.SetIsVoid(true);
   119   AutoSafeJSContext cx;
   120   Maybe<JSAutoCompartment> ac;
   121   JS::Rooted<JS::Value> v(cx);
   122   if (GetJSVal(cx, ac, &v)) {
   123     JSString* str = JS_ValueToSource(cx, v);
   124     if (str) {
   125       nsDependentJSString depStr;
   126       if (depStr.init(cx, str)) {
   127         aResult.Assign(depStr);
   128       }
   129     }
   130   }
   131   return NS_OK;
   132 }
   134 NS_IMETHODIMP
   135 EventListenerInfo::GetDebugObject(nsISupports** aRetVal)
   136 {
   137   *aRetVal = nullptr;
   139 #ifdef MOZ_JSDEBUGGER
   140   nsresult rv = NS_OK;
   141   nsCOMPtr<jsdIDebuggerService> jsd =
   142     do_GetService("@mozilla.org/js/jsd/debugger-service;1", &rv);
   143   NS_ENSURE_SUCCESS(rv, NS_OK);
   145   bool isOn = false;
   146   jsd->GetIsOn(&isOn);
   147   NS_ENSURE_TRUE(isOn, NS_OK);
   149   AutoSafeJSContext cx;
   150   Maybe<JSAutoCompartment> ac;
   151   JS::Rooted<JS::Value> v(cx);
   152   if (GetJSVal(cx, ac, &v)) {
   153     nsCOMPtr<jsdIValue> jsdValue;
   154     rv = jsd->WrapValue(v, getter_AddRefs(jsdValue));
   155     NS_ENSURE_SUCCESS(rv, rv);
   156     jsdValue.forget(aRetVal);
   157   }
   158 #endif
   160   return NS_OK;
   161 }
   163 NS_IMETHODIMP
   164 EventListenerService::GetListenerInfoFor(nsIDOMEventTarget* aEventTarget,
   165                                          uint32_t* aCount,
   166                                          nsIEventListenerInfo*** aOutArray)
   167 {
   168   NS_ENSURE_ARG_POINTER(aEventTarget);
   169   *aCount = 0;
   170   *aOutArray = nullptr;
   171   nsCOMArray<nsIEventListenerInfo> listenerInfos;
   173   nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aEventTarget);
   174   NS_ENSURE_TRUE(eventTarget, NS_ERROR_NO_INTERFACE);
   176   EventListenerManager* elm = eventTarget->GetExistingListenerManager();
   177   if (elm) {
   178     elm->GetListenerInfo(&listenerInfos);
   179   }
   181   int32_t count = listenerInfos.Count();
   182   if (count == 0) {
   183     return NS_OK;
   184   }
   186   *aOutArray =
   187     static_cast<nsIEventListenerInfo**>(
   188       nsMemory::Alloc(sizeof(nsIEventListenerInfo*) * count));
   189   NS_ENSURE_TRUE(*aOutArray, NS_ERROR_OUT_OF_MEMORY);
   191   for (int32_t i = 0; i < count; ++i) {
   192     NS_ADDREF((*aOutArray)[i] = listenerInfos[i]);
   193   }
   194   *aCount = count;
   195   return NS_OK;
   196 }
   198 NS_IMETHODIMP
   199 EventListenerService::GetEventTargetChainFor(nsIDOMEventTarget* aEventTarget,
   200                                              uint32_t* aCount,
   201                                              nsIDOMEventTarget*** aOutArray)
   202 {
   203   *aCount = 0;
   204   *aOutArray = nullptr;
   205   NS_ENSURE_ARG(aEventTarget);
   206   WidgetEvent event(true, NS_EVENT_NULL);
   207   nsCOMArray<EventTarget> targets;
   208   nsresult rv = EventDispatcher::Dispatch(aEventTarget, nullptr, &event,
   209                                           nullptr, nullptr, nullptr, &targets);
   210   NS_ENSURE_SUCCESS(rv, rv);
   211   int32_t count = targets.Count();
   212   if (count == 0) {
   213     return NS_OK;
   214   }
   216   *aOutArray =
   217     static_cast<nsIDOMEventTarget**>(
   218       nsMemory::Alloc(sizeof(nsIDOMEventTarget*) * count));
   219   NS_ENSURE_TRUE(*aOutArray, NS_ERROR_OUT_OF_MEMORY);
   221   for (int32_t i = 0; i < count; ++i) {
   222     NS_ADDREF((*aOutArray)[i] = targets[i]);
   223   }
   224   *aCount = count;
   226   return NS_OK;
   227 }
   229 NS_IMETHODIMP
   230 EventListenerService::HasListenersFor(nsIDOMEventTarget* aEventTarget,
   231                                       const nsAString& aType,
   232                                       bool* aRetVal)
   233 {
   234   nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aEventTarget);
   235   NS_ENSURE_TRUE(eventTarget, NS_ERROR_NO_INTERFACE);
   237   EventListenerManager* elm = eventTarget->GetExistingListenerManager();
   238   *aRetVal = elm && elm->HasListenersFor(aType);
   239   return NS_OK;
   240 }
   242 NS_IMETHODIMP
   243 EventListenerService::AddSystemEventListener(nsIDOMEventTarget *aTarget,
   244                                              const nsAString& aType,
   245                                              nsIDOMEventListener* aListener,
   246                                              bool aUseCapture)
   247 {
   248   NS_PRECONDITION(aTarget, "Missing target");
   249   NS_PRECONDITION(aListener, "Missing listener");
   251   nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aTarget);
   252   NS_ENSURE_TRUE(eventTarget, NS_ERROR_NO_INTERFACE);
   254   EventListenerManager* manager = eventTarget->GetOrCreateListenerManager();
   255   NS_ENSURE_STATE(manager);
   257   EventListenerFlags flags =
   258     aUseCapture ? TrustedEventsAtSystemGroupCapture() :
   259                   TrustedEventsAtSystemGroupBubble();
   260   manager->AddEventListenerByType(aListener, aType, flags);
   261   return NS_OK;
   262 }
   264 NS_IMETHODIMP
   265 EventListenerService::RemoveSystemEventListener(nsIDOMEventTarget *aTarget,
   266                                                 const nsAString& aType,
   267                                                 nsIDOMEventListener* aListener,
   268                                                 bool aUseCapture)
   269 {
   270   NS_PRECONDITION(aTarget, "Missing target");
   271   NS_PRECONDITION(aListener, "Missing listener");
   273   nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aTarget);
   274   NS_ENSURE_TRUE(eventTarget, NS_ERROR_NO_INTERFACE);
   276   EventListenerManager* manager = eventTarget->GetExistingListenerManager();
   277   if (manager) {
   278     EventListenerFlags flags =
   279       aUseCapture ? TrustedEventsAtSystemGroupCapture() :
   280                     TrustedEventsAtSystemGroupBubble();
   281     manager->RemoveEventListenerByType(aListener, aType, flags);
   282   }
   284   return NS_OK;
   285 }
   287 NS_IMETHODIMP
   288 EventListenerService::AddListenerForAllEvents(nsIDOMEventTarget* aTarget,
   289                                               nsIDOMEventListener* aListener,
   290                                               bool aUseCapture,
   291                                               bool aWantsUntrusted,
   292                                               bool aSystemEventGroup)
   293 {
   294   NS_ENSURE_STATE(aTarget && aListener);
   296   nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aTarget);
   297   NS_ENSURE_TRUE(eventTarget, NS_ERROR_NO_INTERFACE);
   299   EventListenerManager* manager = eventTarget->GetOrCreateListenerManager();
   300   NS_ENSURE_STATE(manager);
   301   manager->AddListenerForAllEvents(aListener, aUseCapture, aWantsUntrusted,
   302                                aSystemEventGroup);
   303   return NS_OK;
   304 }
   306 NS_IMETHODIMP
   307 EventListenerService::RemoveListenerForAllEvents(nsIDOMEventTarget* aTarget,
   308                                                  nsIDOMEventListener* aListener,
   309                                                  bool aUseCapture,
   310                                                  bool aSystemEventGroup)
   311 {
   312   NS_ENSURE_STATE(aTarget && aListener);
   314   nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aTarget);
   315   NS_ENSURE_TRUE(eventTarget, NS_ERROR_NO_INTERFACE);
   317   EventListenerManager* manager = eventTarget->GetExistingListenerManager();
   318   if (manager) {
   319     manager->RemoveListenerForAllEvents(aListener, aUseCapture, aSystemEventGroup);
   320   }
   321   return NS_OK;
   322 }
   324 } // namespace mozilla
   326 nsresult
   327 NS_NewEventListenerService(nsIEventListenerService** aResult)
   328 {
   329   *aResult = new mozilla::EventListenerService();
   330   NS_ADDREF(*aResult);
   331   return NS_OK;
   332 }

mercurial