2015-05-03 22:32:37 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
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"
|
2018-04-11 17:27:01 +03:00
|
|
|
#include "mozilla/dom/EventListenerBinding.h"
|
|
|
|
#include "mozilla/dom/ScriptSettings.h"
|
2017-09-25 09:38:04 +03:00
|
|
|
#include "nsArrayUtils.h"
|
2014-03-17 10:56:50 +04:00
|
|
|
#include "nsCOMArray.h"
|
|
|
|
#include "nsJSUtils.h"
|
|
|
|
#include "nsMemory.h"
|
2013-08-30 01:18:25 +04:00
|
|
|
#include "nsServiceManagerUtils.h"
|
2015-04-28 23:10:05 +03:00
|
|
|
#include "nsArray.h"
|
|
|
|
#include "nsThreadUtils.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
|
|
|
|
2015-07-17 18:07:37 +03:00
|
|
|
/******************************************************************************
|
|
|
|
* mozilla::EventListenerChange
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS(EventListenerChange, nsIEventListenerChange)
|
|
|
|
|
2020-02-20 18:56:28 +03:00
|
|
|
EventListenerChange::~EventListenerChange() = default;
|
2015-07-17 18:07:37 +03:00
|
|
|
|
2018-04-20 07:49:30 +03:00
|
|
|
EventListenerChange::EventListenerChange(EventTarget* aTarget)
|
2015-07-17 18:07:37 +03:00
|
|
|
: mTarget(aTarget) {}
|
|
|
|
|
2017-10-03 01:05:19 +03:00
|
|
|
void EventListenerChange::AddChangedListenerName(nsAtom* aEventName) {
|
2017-09-26 01:33:21 +03:00
|
|
|
mChangedListenerNames.AppendElement(aEventName);
|
2015-07-17 18:07:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2018-04-20 07:49:30 +03:00
|
|
|
EventListenerChange::GetTarget(EventTarget** aTarget) {
|
2015-07-17 18:07:37 +03:00
|
|
|
NS_ENSURE_ARG_POINTER(aTarget);
|
|
|
|
NS_ADDREF(*aTarget = mTarget);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2017-09-25 09:38:04 +03:00
|
|
|
EventListenerChange::GetCountOfEventListenerChangesAffectingAccessibility(
|
|
|
|
uint32_t* aCount) {
|
|
|
|
*aCount = 0;
|
|
|
|
|
2017-09-26 01:33:21 +03:00
|
|
|
size_t length = mChangedListenerNames.Length();
|
2017-09-25 09:38:04 +03:00
|
|
|
for (size_t i = 0; i < length; i++) {
|
2017-10-03 01:05:19 +03:00
|
|
|
RefPtr<nsAtom> listenerName = mChangedListenerNames[i];
|
2017-09-25 09:38:04 +03:00
|
|
|
|
|
|
|
// These are the event listener changes which may make an element
|
|
|
|
// accessible or inaccessible.
|
|
|
|
if (listenerName == nsGkAtoms::onclick ||
|
|
|
|
listenerName == nsGkAtoms::onmousedown ||
|
|
|
|
listenerName == nsGkAtoms::onmouseup) {
|
|
|
|
*aCount += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-17 18:07:37 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2014-03-17 10:56:50 +04:00
|
|
|
/******************************************************************************
|
|
|
|
* mozilla::EventListenerInfo
|
|
|
|
******************************************************************************/
|
|
|
|
|
2018-04-12 07:03:44 +03:00
|
|
|
EventListenerInfo::EventListenerInfo(
|
|
|
|
const nsAString& aType, JS::Handle<JSObject*> aScriptedListener,
|
2018-08-07 15:06:44 +03:00
|
|
|
JS::Handle<JSObject*> aScriptedListenerGlobal, bool aCapturing,
|
2018-04-12 07:03:44 +03:00
|
|
|
bool aAllowsUntrusted, bool aInSystemEventGroup)
|
|
|
|
: mType(aType),
|
|
|
|
mScriptedListener(aScriptedListener),
|
2018-08-07 15:06:44 +03:00
|
|
|
mScriptedListenerGlobal(aScriptedListenerGlobal),
|
2018-04-12 07:03:44 +03:00
|
|
|
mCapturing(aCapturing),
|
|
|
|
mAllowsUntrusted(aAllowsUntrusted),
|
|
|
|
mInSystemEventGroup(aInSystemEventGroup) {
|
2018-08-07 15:06:44 +03:00
|
|
|
if (aScriptedListener) {
|
|
|
|
MOZ_ASSERT(JS_IsGlobalObject(aScriptedListenerGlobal));
|
|
|
|
js::AssertSameCompartment(aScriptedListener, aScriptedListenerGlobal);
|
|
|
|
}
|
|
|
|
|
2018-04-12 07:03:44 +03:00
|
|
|
HoldJSObjects(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
EventListenerInfo::~EventListenerInfo() { DropJSObjects(this); }
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(EventListenerInfo)
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(EventListenerInfo)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(EventListenerInfo)
|
|
|
|
tmp->mScriptedListener = nullptr;
|
2018-08-07 15:06:44 +03:00
|
|
|
tmp->mScriptedListenerGlobal = nullptr;
|
2018-04-12 07:03:44 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(EventListenerInfo)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mScriptedListener)
|
2018-08-07 15:06:44 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mScriptedListenerGlobal)
|
2018-04-12 07:03:44 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
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) {
|
2018-08-07 15:06:44 +03:00
|
|
|
Maybe<JSAutoRealm> ar;
|
2018-05-16 11:53:16 +03:00
|
|
|
GetJSVal(aCx, ar, 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
|
|
|
|
2014-03-17 10:56:50 +04:00
|
|
|
bool EventListenerInfo::GetJSVal(JSContext* aCx, Maybe<JSAutoRealm>& aAr,
|
|
|
|
JS::MutableHandle<JS::Value> aJSVal) {
|
2018-04-12 07:03:44 +03:00
|
|
|
if (mScriptedListener) {
|
|
|
|
aJSVal.setObject(*mScriptedListener);
|
2018-08-07 15:06:44 +03:00
|
|
|
aAr.emplace(aCx, mScriptedListenerGlobal);
|
2011-10-10 14:38:14 +04:00
|
|
|
return true;
|
2009-10-17 18:40:44 +04:00
|
|
|
}
|
|
|
|
|
2018-04-12 07:03:44 +03:00
|
|
|
aJSVal.setNull();
|
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) {
|
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;
|
2018-08-07 15:06:44 +03:00
|
|
|
Maybe<JSAutoRealm> ar;
|
2014-01-23 23:49:40 +04:00
|
|
|
JS::Rooted<JS::Value> v(cx);
|
2018-05-16 11:53:16 +03:00
|
|
|
if (GetJSVal(cx, ar, &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;
|
|
|
|
}
|
|
|
|
|
2015-04-28 23:10:05 +03:00
|
|
|
EventListenerService* EventListenerService::sInstance = nullptr;
|
|
|
|
|
|
|
|
EventListenerService::EventListenerService() {
|
|
|
|
MOZ_ASSERT(!sInstance);
|
|
|
|
sInstance = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
EventListenerService::~EventListenerService() {
|
|
|
|
MOZ_ASSERT(sInstance == this);
|
|
|
|
sInstance = nullptr;
|
|
|
|
}
|
|
|
|
|
2009-10-16 12:57:32 +04:00
|
|
|
NS_IMETHODIMP
|
2019-05-11 11:28:29 +03:00
|
|
|
EventListenerService::GetListenerInfoFor(
|
|
|
|
EventTarget* aEventTarget,
|
|
|
|
nsTArray<RefPtr<nsIEventListenerInfo>>& aOutArray) {
|
2011-10-10 14:38:14 +04:00
|
|
|
NS_ENSURE_ARG_POINTER(aEventTarget);
|
2013-10-23 03:32:04 +04:00
|
|
|
|
2018-04-20 07:49:30 +03:00
|
|
|
EventListenerManager* elm = aEventTarget->GetExistingListenerManager();
|
2011-06-24 06:18:01 +04:00
|
|
|
if (elm) {
|
2019-05-11 11:28:29 +03:00
|
|
|
elm->GetListenerInfo(aOutArray);
|
2009-10-16 12:57:32 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2019-05-11 11:28:29 +03:00
|
|
|
EventListenerService::GetEventTargetChainFor(
|
|
|
|
EventTarget* aEventTarget, bool aComposed,
|
|
|
|
nsTArray<RefPtr<EventTarget>>& aOutArray) {
|
2011-06-24 06:18:01 +04:00
|
|
|
NS_ENSURE_ARG(aEventTarget);
|
2015-08-29 02:58:26 +03:00
|
|
|
WidgetEvent event(true, eVoidEvent);
|
2016-09-13 12:29:08 +03:00
|
|
|
event.SetComposed(aComposed);
|
2015-02-11 00:28:07 +03:00
|
|
|
nsTArray<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);
|
2019-05-11 11:28:29 +03:00
|
|
|
aOutArray.AppendElements(targets);
|
2009-10-16 12:57:32 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-06-24 06:18:02 +04:00
|
|
|
NS_IMETHODIMP
|
2018-04-20 07:49:30 +03:00
|
|
|
EventListenerService::HasListenersFor(EventTarget* aEventTarget,
|
2014-03-17 10:56:50 +04:00
|
|
|
const nsAString& aType, bool* aRetVal) {
|
2018-04-20 07:49:30 +03:00
|
|
|
NS_ENSURE_TRUE(aEventTarget, NS_ERROR_UNEXPECTED);
|
2013-10-23 03:32:04 +04:00
|
|
|
|
2018-04-20 07:49:30 +03:00
|
|
|
EventListenerManager* elm = aEventTarget->GetExistingListenerManager();
|
2011-06-24 06:18:02 +04:00
|
|
|
*aRetVal = elm && elm->HasListenersFor(aType);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2018-04-11 17:27:01 +03:00
|
|
|
static already_AddRefed<EventListener> ToEventListener(
|
|
|
|
JSContext* aCx, JS::Handle<JS::Value> aValue) {
|
|
|
|
if (NS_WARN_IF(!aValue.isObject())) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
|
2018-08-04 00:11:39 +03:00
|
|
|
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
|
2018-04-11 17:27:01 +03:00
|
|
|
RefPtr<EventListener> listener =
|
2018-08-04 00:11:39 +03:00
|
|
|
new EventListener(aCx, obj, global, GetIncumbentGlobal());
|
2018-04-11 17:27:01 +03:00
|
|
|
return listener.forget();
|
|
|
|
}
|
|
|
|
|
2010-06-10 05:16:58 +04:00
|
|
|
NS_IMETHODIMP
|
2018-04-20 07:49:30 +03:00
|
|
|
EventListenerService::AddSystemEventListener(EventTarget* aTarget,
|
2014-03-17 10:56:50 +04:00
|
|
|
const nsAString& aType,
|
2018-04-11 17:27:01 +03:00
|
|
|
JS::Handle<JS::Value> aListener,
|
|
|
|
bool aUseCapture, JSContext* aCx) {
|
2018-04-28 22:50:58 +03:00
|
|
|
MOZ_ASSERT(aTarget, "Missing target");
|
2011-06-24 06:18:02 +04:00
|
|
|
|
2018-04-20 07:49:30 +03:00
|
|
|
NS_ENSURE_TRUE(aTarget, NS_ERROR_UNEXPECTED);
|
2013-10-23 03:32:04 +04:00
|
|
|
|
2018-04-11 17:27:01 +03:00
|
|
|
RefPtr<EventListener> listener = ToEventListener(aCx, aListener);
|
|
|
|
if (!listener) {
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
2018-04-20 07:49:30 +03:00
|
|
|
EventListenerManager* manager = aTarget->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();
|
2018-04-11 17:27:01 +03:00
|
|
|
manager->AddEventListenerByType(listener, aType, flags);
|
2011-08-18 13:45:00 +04:00
|
|
|
return NS_OK;
|
2011-06-24 06:18:02 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2018-04-20 07:49:30 +03:00
|
|
|
EventListenerService::RemoveSystemEventListener(EventTarget* aTarget,
|
2014-03-17 10:56:50 +04:00
|
|
|
const nsAString& aType,
|
2018-04-11 17:27:01 +03:00
|
|
|
JS::Handle<JS::Value> aListener,
|
|
|
|
bool aUseCapture,
|
|
|
|
JSContext* aCx) {
|
2018-04-28 22:50:58 +03:00
|
|
|
MOZ_ASSERT(aTarget, "Missing target");
|
2011-06-24 06:18:02 +04:00
|
|
|
|
2018-04-20 07:49:30 +03:00
|
|
|
NS_ENSURE_TRUE(aTarget, NS_ERROR_UNEXPECTED);
|
2013-10-23 03:32:04 +04:00
|
|
|
|
2018-04-11 17:27:01 +03:00
|
|
|
RefPtr<EventListener> listener = ToEventListener(aCx, aListener);
|
|
|
|
if (!listener) {
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
2018-04-20 07:49:30 +03:00
|
|
|
EventListenerManager* manager = aTarget->GetExistingListenerManager();
|
2011-06-24 06:18:02 +04:00
|
|
|
if (manager) {
|
2012-12-16 05:26:05 +04:00
|
|
|
EventListenerFlags flags = aUseCapture ? TrustedEventsAtSystemGroupCapture()
|
|
|
|
: TrustedEventsAtSystemGroupBubble();
|
2018-04-11 17:27:01 +03:00
|
|
|
manager->RemoveEventListenerByType(listener, 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
|
2018-04-20 07:49:30 +03:00
|
|
|
EventListenerService::AddListenerForAllEvents(
|
2018-04-11 17:27:01 +03:00
|
|
|
EventTarget* aTarget, JS::Handle<JS::Value> aListener, bool aUseCapture,
|
|
|
|
bool aWantsUntrusted, bool aSystemEventGroup, JSContext* aCx) {
|
|
|
|
NS_ENSURE_STATE(aTarget);
|
2013-10-23 03:32:04 +04:00
|
|
|
|
2018-04-11 17:27:01 +03:00
|
|
|
RefPtr<EventListener> listener = ToEventListener(aCx, aListener);
|
|
|
|
if (!listener) {
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
2018-04-20 07:49:30 +03:00
|
|
|
EventListenerManager* manager = aTarget->GetOrCreateListenerManager();
|
2012-11-01 16:42:29 +04:00
|
|
|
NS_ENSURE_STATE(manager);
|
2018-04-11 17:27:01 +03:00
|
|
|
manager->AddListenerForAllEvents(listener, aUseCapture, aWantsUntrusted,
|
|
|
|
aSystemEventGroup);
|
2012-11-01 16:42:29 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2018-04-20 07:49:30 +03:00
|
|
|
EventListenerService::RemoveListenerForAllEvents(
|
2018-04-11 17:27:01 +03:00
|
|
|
EventTarget* aTarget, JS::Handle<JS::Value> aListener, bool aUseCapture,
|
|
|
|
bool aSystemEventGroup, JSContext* aCx) {
|
|
|
|
NS_ENSURE_STATE(aTarget);
|
2013-10-23 03:32:04 +04:00
|
|
|
|
2018-04-11 17:27:01 +03:00
|
|
|
RefPtr<EventListener> listener = ToEventListener(aCx, aListener);
|
|
|
|
if (!listener) {
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
2018-04-20 07:49:30 +03:00
|
|
|
EventListenerManager* manager = aTarget->GetExistingListenerManager();
|
2012-11-01 16:42:29 +04:00
|
|
|
if (manager) {
|
2018-04-11 17:27:01 +03:00
|
|
|
manager->RemoveListenerForAllEvents(listener, aUseCapture,
|
|
|
|
aSystemEventGroup);
|
2012-11-01 16:42:29 +04:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2015-04-28 23:10:05 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
EventListenerService::AddListenerChangeListener(
|
|
|
|
nsIListenerChangeListener* aListener) {
|
|
|
|
if (!mChangeListeners.Contains(aListener)) {
|
|
|
|
mChangeListeners.AppendElement(aListener);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
};
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
EventListenerService::RemoveListenerChangeListener(
|
|
|
|
nsIListenerChangeListener* aListener) {
|
|
|
|
mChangeListeners.RemoveElement(aListener);
|
|
|
|
return NS_OK;
|
|
|
|
};
|
|
|
|
|
2015-07-17 18:07:37 +03:00
|
|
|
void EventListenerService::NotifyAboutMainThreadListenerChangeInternal(
|
|
|
|
dom::EventTarget* aTarget, nsAtom* aName) {
|
2015-04-28 23:10:05 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
2017-03-16 03:11:50 +03:00
|
|
|
MOZ_ASSERT(aTarget);
|
2015-04-28 23:10:05 +03:00
|
|
|
if (mChangeListeners.IsEmpty()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mPendingListenerChanges) {
|
|
|
|
mPendingListenerChanges = nsArrayBase::Create();
|
2017-03-16 03:11:50 +03:00
|
|
|
nsCOMPtr<nsIRunnable> runnable =
|
|
|
|
NewRunnableMethod("EventListenerService::NotifyPendingChanges", this,
|
|
|
|
&EventListenerService::NotifyPendingChanges);
|
|
|
|
if (nsCOMPtr<nsIGlobalObject> global = aTarget->GetOwnerGlobal()) {
|
2017-07-26 11:13:35 +03:00
|
|
|
global->Dispatch(TaskCategory::Other, runnable.forget());
|
2017-03-16 03:11:50 +03:00
|
|
|
} else if (nsCOMPtr<nsINode> node = do_QueryInterface(aTarget)) {
|
2017-07-26 11:13:35 +03:00
|
|
|
node->OwnerDoc()->Dispatch(TaskCategory::Other, runnable.forget());
|
2017-03-16 03:11:50 +03:00
|
|
|
} else {
|
|
|
|
NS_DispatchToCurrentThread(runnable);
|
|
|
|
}
|
2015-04-28 23:10:05 +03:00
|
|
|
}
|
|
|
|
|
2017-06-14 18:27:25 +03:00
|
|
|
RefPtr<EventListenerChange> changes =
|
|
|
|
mPendingListenerChangesSet.LookupForAdd(aTarget).OrInsert(
|
|
|
|
[this, aTarget]() {
|
|
|
|
EventListenerChange* c = new EventListenerChange(aTarget);
|
2017-10-21 17:53:02 +03:00
|
|
|
mPendingListenerChanges->AppendElement(c);
|
2017-06-14 18:27:25 +03:00
|
|
|
return c;
|
|
|
|
});
|
2015-07-17 18:07:37 +03:00
|
|
|
changes->AddChangedListenerName(aName);
|
2015-04-28 23:10:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void EventListenerService::NotifyPendingChanges() {
|
|
|
|
nsCOMPtr<nsIMutableArray> changes;
|
|
|
|
mPendingListenerChanges.swap(changes);
|
|
|
|
mPendingListenerChangesSet.Clear();
|
|
|
|
|
2020-06-16 13:15:22 +03:00
|
|
|
for (nsCOMPtr<nsIListenerChangeListener> listener :
|
|
|
|
mChangeListeners.EndLimitedRange()) {
|
2015-04-28 23:10:05 +03:00
|
|
|
listener->ListenersChanged(changes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|