2009-10-16 12:57:32 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2014-03-17 10:56:50 +04:00
|
|
|
|
|
|
|
#include "EventListenerService.h"
|
2013-09-25 15:21:22 +04:00
|
|
|
#include "mozilla/BasicEvents.h"
|
2014-03-18 08:48:21 +04:00
|
|
|
#include "mozilla/EventDispatcher.h"
|
2014-03-17 10:56:53 +04:00
|
|
|
#include "mozilla/EventListenerManager.h"
|
2014-04-02 06:00:45 +04:00
|
|
|
#include "mozilla/JSEventHandler.h"
|
2013-08-28 02:10:28 +04:00
|
|
|
#include "mozilla/Maybe.h"
|
2014-03-17 10:56:50 +04:00
|
|
|
#include "nsCOMArray.h"
|
|
|
|
#include "nsCxPusher.h"
|
|
|
|
#include "nsDOMClassInfoID.h"
|
|
|
|
#include "nsIXPConnect.h"
|
|
|
|
#include "nsJSUtils.h"
|
|
|
|
#include "nsMemory.h"
|
2013-08-30 01:18:25 +04:00
|
|
|
#include "nsServiceManagerUtils.h"
|
2009-10-16 12:57:32 +04:00
|
|
|
|
2014-03-17 10:56:50 +04:00
|
|
|
namespace mozilla {
|
2009-10-16 12:57:32 +04:00
|
|
|
|
2014-03-17 10:56:50 +04:00
|
|
|
using namespace dom;
|
2010-01-12 16:08:43 +03:00
|
|
|
|
2014-03-17 10:56:50 +04:00
|
|
|
/******************************************************************************
|
|
|
|
* mozilla::EventListenerInfo
|
|
|
|
******************************************************************************/
|
|
|
|
|
2014-04-25 20:49:00 +04:00
|
|
|
NS_IMPL_CYCLE_COLLECTION(EventListenerInfo, mListener)
|
2014-03-17 10:56:50 +04:00
|
|
|
|
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(EventListenerInfo)
|
2009-10-16 12:57:32 +04:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIEventListenerInfo)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
|
|
|
NS_INTERFACE_MAP_END
|
|
|
|
|
2014-03-17 10:56:50 +04:00
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(EventListenerInfo)
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(EventListenerInfo)
|
2009-10-16 12:57:32 +04:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2014-03-17 10:56:50 +04:00
|
|
|
EventListenerInfo::GetType(nsAString& aType)
|
2009-10-16 12:57:32 +04:00
|
|
|
{
|
|
|
|
aType = mType;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2014-03-17 10:56:50 +04:00
|
|
|
EventListenerInfo::GetCapturing(bool* aCapturing)
|
2009-10-16 12:57:32 +04:00
|
|
|
{
|
|
|
|
*aCapturing = mCapturing;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2014-03-17 10:56:50 +04:00
|
|
|
EventListenerInfo::GetAllowsUntrusted(bool* aAllowsUntrusted)
|
2009-10-16 12:57:32 +04:00
|
|
|
{
|
|
|
|
*aAllowsUntrusted = mAllowsUntrusted;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2014-03-17 10:56:50 +04:00
|
|
|
EventListenerInfo::GetInSystemEventGroup(bool* aInSystemEventGroup)
|
2009-10-16 12:57:32 +04:00
|
|
|
{
|
|
|
|
*aInSystemEventGroup = mInSystemEventGroup;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2013-04-02 01:17:56 +04:00
|
|
|
NS_IMETHODIMP
|
2014-03-17 10:56:50 +04:00
|
|
|
EventListenerInfo::GetListenerObject(JSContext* aCx,
|
|
|
|
JS::MutableHandle<JS::Value> aObject)
|
2013-04-02 01:17:56 +04:00
|
|
|
{
|
2014-03-17 10:56:50 +04:00
|
|
|
Maybe<JSAutoCompartment> ac;
|
2014-01-23 23:49:40 +04:00
|
|
|
GetJSVal(aCx, ac, aObject);
|
2013-04-02 01:17:56 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2014-03-17 10:56:50 +04:00
|
|
|
/******************************************************************************
|
|
|
|
* mozilla::EventListenerService
|
|
|
|
******************************************************************************/
|
|
|
|
|
2014-04-27 11:06:00 +04:00
|
|
|
NS_IMPL_ISUPPORTS(EventListenerService, nsIEventListenerService)
|
2009-10-16 12:57:32 +04:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2014-03-17 10:56:50 +04:00
|
|
|
EventListenerInfo::GetJSVal(JSContext* aCx,
|
|
|
|
Maybe<JSAutoCompartment>& aAc,
|
|
|
|
JS::MutableHandle<JS::Value> aJSVal)
|
2009-10-16 12:57:32 +04:00
|
|
|
{
|
2014-01-23 23:49:40 +04:00
|
|
|
aJSVal.setNull();
|
2009-10-16 12:57:32 +04:00
|
|
|
nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS = do_QueryInterface(mListener);
|
|
|
|
if (wrappedJS) {
|
2013-05-20 16:44:18 +04:00
|
|
|
JS::Rooted<JSObject*> object(aCx, wrappedJS->GetJSObject());
|
|
|
|
if (!object) {
|
2011-10-10 14:38:14 +04:00
|
|
|
return false;
|
|
|
|
}
|
2012-08-22 05:42:53 +04:00
|
|
|
aAc.construct(aCx, object);
|
2014-01-23 23:49:40 +04:00
|
|
|
aJSVal.setObject(*object);
|
2011-10-10 14:38:14 +04:00
|
|
|
return true;
|
2009-10-17 18:40:44 +04:00
|
|
|
}
|
|
|
|
|
2014-04-02 06:00:46 +04:00
|
|
|
nsCOMPtr<JSEventHandler> jsHandler = do_QueryInterface(mListener);
|
|
|
|
if (jsHandler && jsHandler->GetTypedEventHandler().HasEventHandler()) {
|
2014-04-02 06:00:45 +04:00
|
|
|
JS::Handle<JSObject*> handler =
|
2014-04-02 06:00:46 +04:00
|
|
|
jsHandler->GetTypedEventHandler().Ptr()->Callable();
|
2011-08-24 23:49:25 +04:00
|
|
|
if (handler) {
|
2012-08-22 05:42:53 +04:00
|
|
|
aAc.construct(aCx, handler);
|
2014-01-23 23:49:40 +04:00
|
|
|
aJSVal.setObject(*handler);
|
2011-10-10 14:38:14 +04:00
|
|
|
return true;
|
2009-10-17 18:40:44 +04:00
|
|
|
}
|
|
|
|
}
|
2011-10-10 14:38:14 +04:00
|
|
|
return false;
|
2009-10-17 18:40:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2014-03-17 10:56:50 +04:00
|
|
|
EventListenerInfo::ToSource(nsAString& aResult)
|
2009-10-17 18:40:44 +04:00
|
|
|
{
|
2011-10-17 18:59:28 +04:00
|
|
|
aResult.SetIsVoid(true);
|
2009-10-17 18:40:44 +04:00
|
|
|
|
2013-05-06 17:04:17 +04:00
|
|
|
AutoSafeJSContext cx;
|
2014-03-17 10:56:50 +04:00
|
|
|
Maybe<JSAutoCompartment> ac;
|
2014-01-23 23:49:40 +04:00
|
|
|
JS::Rooted<JS::Value> v(cx);
|
|
|
|
if (GetJSVal(cx, ac, &v)) {
|
2013-05-22 20:05:28 +04:00
|
|
|
JSString* str = JS_ValueToSource(cx, v);
|
|
|
|
if (str) {
|
2014-07-05 19:30:54 +04:00
|
|
|
nsAutoJSString autoStr;
|
|
|
|
if (autoStr.init(cx, str)) {
|
|
|
|
aResult.Assign(autoStr);
|
2009-10-16 12:57:32 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-10-17 18:40:44 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2009-10-16 12:57:32 +04:00
|
|
|
NS_IMETHODIMP
|
2014-03-17 10:56:50 +04:00
|
|
|
EventListenerService::GetListenerInfoFor(nsIDOMEventTarget* aEventTarget,
|
|
|
|
uint32_t* aCount,
|
|
|
|
nsIEventListenerInfo*** aOutArray)
|
2009-10-16 12:57:32 +04:00
|
|
|
{
|
2011-10-10 14:38:14 +04:00
|
|
|
NS_ENSURE_ARG_POINTER(aEventTarget);
|
2009-10-16 12:57:32 +04:00
|
|
|
*aCount = 0;
|
2012-07-30 18:20:58 +04:00
|
|
|
*aOutArray = nullptr;
|
2009-10-16 12:57:32 +04:00
|
|
|
nsCOMArray<nsIEventListenerInfo> listenerInfos;
|
2013-10-23 03:32:04 +04:00
|
|
|
|
|
|
|
nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aEventTarget);
|
|
|
|
NS_ENSURE_TRUE(eventTarget, NS_ERROR_NO_INTERFACE);
|
|
|
|
|
2014-03-17 10:56:53 +04:00
|
|
|
EventListenerManager* elm = eventTarget->GetExistingListenerManager();
|
2011-06-24 06:18:01 +04:00
|
|
|
if (elm) {
|
|
|
|
elm->GetListenerInfo(&listenerInfos);
|
2009-10-16 12:57:32 +04:00
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t count = listenerInfos.Count();
|
2009-10-16 12:57:32 +04:00
|
|
|
if (count == 0) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
*aOutArray =
|
|
|
|
static_cast<nsIEventListenerInfo**>(
|
|
|
|
nsMemory::Alloc(sizeof(nsIEventListenerInfo*) * count));
|
|
|
|
NS_ENSURE_TRUE(*aOutArray, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
for (int32_t i = 0; i < count; ++i) {
|
2009-10-16 12:57:32 +04:00
|
|
|
NS_ADDREF((*aOutArray)[i] = listenerInfos[i]);
|
|
|
|
}
|
|
|
|
*aCount = count;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2014-03-17 10:56:50 +04:00
|
|
|
EventListenerService::GetEventTargetChainFor(nsIDOMEventTarget* aEventTarget,
|
|
|
|
uint32_t* aCount,
|
|
|
|
nsIDOMEventTarget*** aOutArray)
|
2009-10-16 12:57:32 +04:00
|
|
|
{
|
|
|
|
*aCount = 0;
|
2012-07-30 18:20:58 +04:00
|
|
|
*aOutArray = nullptr;
|
2011-06-24 06:18:01 +04:00
|
|
|
NS_ENSURE_ARG(aEventTarget);
|
2013-10-02 07:46:04 +04:00
|
|
|
WidgetEvent event(true, NS_EVENT_NULL);
|
2013-04-06 04:44:26 +04:00
|
|
|
nsCOMArray<EventTarget> targets;
|
2014-03-18 08:48:21 +04:00
|
|
|
nsresult rv = EventDispatcher::Dispatch(aEventTarget, nullptr, &event,
|
|
|
|
nullptr, nullptr, nullptr, &targets);
|
2009-10-16 12:57:32 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t count = targets.Count();
|
2009-10-16 12:57:32 +04:00
|
|
|
if (count == 0) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
*aOutArray =
|
|
|
|
static_cast<nsIDOMEventTarget**>(
|
2011-06-24 06:18:00 +04:00
|
|
|
nsMemory::Alloc(sizeof(nsIDOMEventTarget*) * count));
|
2009-10-16 12:57:32 +04:00
|
|
|
NS_ENSURE_TRUE(*aOutArray, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
for (int32_t i = 0; i < count; ++i) {
|
2011-06-24 06:18:01 +04:00
|
|
|
NS_ADDREF((*aOutArray)[i] = targets[i]);
|
2009-10-16 12:57:32 +04:00
|
|
|
}
|
|
|
|
*aCount = count;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-06-24 06:18:02 +04:00
|
|
|
NS_IMETHODIMP
|
2014-03-17 10:56:50 +04:00
|
|
|
EventListenerService::HasListenersFor(nsIDOMEventTarget* aEventTarget,
|
|
|
|
const nsAString& aType,
|
|
|
|
bool* aRetVal)
|
2011-06-24 06:18:02 +04:00
|
|
|
{
|
2013-10-23 03:32:04 +04:00
|
|
|
nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aEventTarget);
|
|
|
|
NS_ENSURE_TRUE(eventTarget, NS_ERROR_NO_INTERFACE);
|
|
|
|
|
2014-03-17 10:56:53 +04:00
|
|
|
EventListenerManager* elm = eventTarget->GetExistingListenerManager();
|
2011-06-24 06:18:02 +04:00
|
|
|
*aRetVal = elm && elm->HasListenersFor(aType);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-06-10 05:16:58 +04:00
|
|
|
NS_IMETHODIMP
|
2014-03-17 10:56:50 +04:00
|
|
|
EventListenerService::AddSystemEventListener(nsIDOMEventTarget *aTarget,
|
|
|
|
const nsAString& aType,
|
|
|
|
nsIDOMEventListener* aListener,
|
|
|
|
bool aUseCapture)
|
2010-06-10 05:16:58 +04:00
|
|
|
{
|
2011-06-24 06:18:02 +04:00
|
|
|
NS_PRECONDITION(aTarget, "Missing target");
|
|
|
|
NS_PRECONDITION(aListener, "Missing listener");
|
|
|
|
|
2013-10-23 03:32:04 +04:00
|
|
|
nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aTarget);
|
|
|
|
NS_ENSURE_TRUE(eventTarget, NS_ERROR_NO_INTERFACE);
|
|
|
|
|
2014-03-17 10:56:53 +04:00
|
|
|
EventListenerManager* manager = eventTarget->GetOrCreateListenerManager();
|
2011-06-24 06:18:02 +04:00
|
|
|
NS_ENSURE_STATE(manager);
|
|
|
|
|
2012-12-16 05:26:05 +04:00
|
|
|
EventListenerFlags flags =
|
|
|
|
aUseCapture ? TrustedEventsAtSystemGroupCapture() :
|
|
|
|
TrustedEventsAtSystemGroupBubble();
|
2011-08-18 13:45:00 +04:00
|
|
|
manager->AddEventListenerByType(aListener, aType, flags);
|
|
|
|
return NS_OK;
|
2011-06-24 06:18:02 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2014-03-17 10:56:50 +04:00
|
|
|
EventListenerService::RemoveSystemEventListener(nsIDOMEventTarget *aTarget,
|
|
|
|
const nsAString& aType,
|
|
|
|
nsIDOMEventListener* aListener,
|
|
|
|
bool aUseCapture)
|
2011-06-24 06:18:02 +04:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(aTarget, "Missing target");
|
|
|
|
NS_PRECONDITION(aListener, "Missing listener");
|
|
|
|
|
2013-10-23 03:32:04 +04:00
|
|
|
nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aTarget);
|
|
|
|
NS_ENSURE_TRUE(eventTarget, NS_ERROR_NO_INTERFACE);
|
|
|
|
|
2014-03-17 10:56:53 +04:00
|
|
|
EventListenerManager* manager = eventTarget->GetExistingListenerManager();
|
2011-06-24 06:18:02 +04:00
|
|
|
if (manager) {
|
2012-12-16 05:26:05 +04:00
|
|
|
EventListenerFlags flags =
|
|
|
|
aUseCapture ? TrustedEventsAtSystemGroupCapture() :
|
|
|
|
TrustedEventsAtSystemGroupBubble();
|
2011-06-24 06:18:02 +04:00
|
|
|
manager->RemoveEventListenerByType(aListener, aType, flags);
|
2011-06-24 06:18:02 +04:00
|
|
|
}
|
|
|
|
|
2010-06-10 05:16:58 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-11-01 16:42:29 +04:00
|
|
|
NS_IMETHODIMP
|
2014-03-17 10:56:50 +04:00
|
|
|
EventListenerService::AddListenerForAllEvents(nsIDOMEventTarget* aTarget,
|
|
|
|
nsIDOMEventListener* aListener,
|
|
|
|
bool aUseCapture,
|
|
|
|
bool aWantsUntrusted,
|
|
|
|
bool aSystemEventGroup)
|
2012-11-01 16:42:29 +04:00
|
|
|
{
|
|
|
|
NS_ENSURE_STATE(aTarget && aListener);
|
2013-10-23 03:32:04 +04:00
|
|
|
|
|
|
|
nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aTarget);
|
|
|
|
NS_ENSURE_TRUE(eventTarget, NS_ERROR_NO_INTERFACE);
|
|
|
|
|
2014-03-17 10:56:53 +04:00
|
|
|
EventListenerManager* manager = eventTarget->GetOrCreateListenerManager();
|
2012-11-01 16:42:29 +04:00
|
|
|
NS_ENSURE_STATE(manager);
|
|
|
|
manager->AddListenerForAllEvents(aListener, aUseCapture, aWantsUntrusted,
|
|
|
|
aSystemEventGroup);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2014-03-17 10:56:50 +04:00
|
|
|
EventListenerService::RemoveListenerForAllEvents(nsIDOMEventTarget* aTarget,
|
|
|
|
nsIDOMEventListener* aListener,
|
|
|
|
bool aUseCapture,
|
|
|
|
bool aSystemEventGroup)
|
2012-11-01 16:42:29 +04:00
|
|
|
{
|
|
|
|
NS_ENSURE_STATE(aTarget && aListener);
|
2013-10-23 03:32:04 +04:00
|
|
|
|
|
|
|
nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aTarget);
|
|
|
|
NS_ENSURE_TRUE(eventTarget, NS_ERROR_NO_INTERFACE);
|
|
|
|
|
2014-03-17 10:56:53 +04:00
|
|
|
EventListenerManager* manager = eventTarget->GetExistingListenerManager();
|
2012-11-01 16:42:29 +04:00
|
|
|
if (manager) {
|
|
|
|
manager->RemoveListenerForAllEvents(aListener, aUseCapture, aSystemEventGroup);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2014-03-17 10:56:50 +04:00
|
|
|
} // namespace mozilla
|
|
|
|
|
2009-10-16 12:57:32 +04:00
|
|
|
nsresult
|
|
|
|
NS_NewEventListenerService(nsIEventListenerService** aResult)
|
|
|
|
{
|
2014-03-17 10:56:50 +04:00
|
|
|
*aResult = new mozilla::EventListenerService();
|
2009-10-16 12:57:32 +04:00
|
|
|
NS_ADDREF(*aResult);
|
|
|
|
return NS_OK;
|
|
|
|
}
|