Bug 1450167. Stop using atom-or-string for event names in the listener manager. r=smaug

Now that we support atoms off the the main thread, we can just use atoms.
This commit is contained in:
Boris Zbarsky
2018-07-24 18:15:19 -04:00
parent abb348fc6e
commit df3b83f98c
22 changed files with 149 additions and 256 deletions

View File

@@ -4255,6 +4255,7 @@ nsContentUtils::IsEventAttributeName(nsAtom* aName, int32_t aType)
EventMessage
nsContentUtils::GetEventMessage(nsAtom* aName)
{
MOZ_ASSERT(NS_IsMainThread(), "sAtomEventTable is not threadsafe");
if (aName) {
EventNameMapping mapping;
if (sAtomEventTable->Get(aName, &mapping)) {
@@ -4281,6 +4282,7 @@ nsContentUtils::GetEventMessageAndAtom(const nsAString& aName,
mozilla::EventClassID aEventClassID,
EventMessage* aEventMessage)
{
MOZ_ASSERT(NS_IsMainThread(), "Our hashtables are not threadsafe");
EventNameMapping mapping;
if (sStringEventTable->Get(aName, &mapping)) {
*aEventMessage =
@@ -4322,6 +4324,8 @@ EventMessage
nsContentUtils::GetEventMessageAndAtomForListener(const nsAString& aName,
nsAtom** aOnName)
{
MOZ_ASSERT(NS_IsMainThread(), "Our hashtables are not threadsafe");
// Because of SVG/SMIL sStringEventTable contains a subset of the event names
// comparing to the sAtomEventTable. However, usually sStringEventTable
// contains the information we need, so in order to reduce hashtable

View File

@@ -578,14 +578,13 @@ public:
mozilla::dom::EventHandlerNonNull* GetOn##name_() \
{ \
mozilla::EventListenerManager* elm = GetExistingListenerManager(); \
return elm ? elm->GetEventHandler(nsGkAtoms::on##name_, EmptyString()) \
: nullptr; \
return elm ? elm->GetEventHandler(nsGkAtoms::on##name_) : nullptr; \
} \
void SetOn##name_(mozilla::dom::EventHandlerNonNull* handler) \
{ \
mozilla::EventListenerManager* elm = GetOrCreateListenerManager(); \
if (elm) { \
elm->SetEventHandler(nsGkAtoms::on##name_, EmptyString(), handler); \
elm->SetEventHandler(nsGkAtoms::on##name_, handler); \
} \
}
#define ERROR_EVENT(name_, id_, type_, struct_) \

View File

@@ -518,14 +518,13 @@ public:
mozilla::dom::EventHandlerNonNull* GetOn##name_() \
{ \
mozilla::EventListenerManager* elm = GetExistingListenerManager(); \
return elm ? elm->GetEventHandler(nsGkAtoms::on##name_, EmptyString()) \
: nullptr; \
return elm ? elm->GetEventHandler(nsGkAtoms::on##name_) : nullptr; \
} \
void SetOn##name_(mozilla::dom::EventHandlerNonNull* handler) \
{ \
mozilla::EventListenerManager* elm = GetOrCreateListenerManager(); \
if (elm) { \
elm->SetEventHandler(nsGkAtoms::on##name_, EmptyString(), handler); \
elm->SetEventHandler(nsGkAtoms::on##name_, handler); \
} \
}
#define ERROR_EVENT(name_, id_, type_, struct_) \

View File

@@ -2361,14 +2361,13 @@ nsINode::AddSizeOfIncludingThis(nsWindowSizes& aSizes, size_t* aNodeSize) const
#define EVENT(name_, id_, type_, struct_) \
EventHandlerNonNull* nsINode::GetOn##name_() { \
EventListenerManager *elm = GetExistingListenerManager(); \
return elm ? elm->GetEventHandler(nsGkAtoms::on##name_, EmptyString()) \
: nullptr; \
return elm ? elm->GetEventHandler(nsGkAtoms::on##name_) : nullptr; \
} \
void nsINode::SetOn##name_(EventHandlerNonNull* handler) \
{ \
EventListenerManager *elm = GetOrCreateListenerManager(); \
if (elm) { \
elm->SetEventHandler(nsGkAtoms::on##name_, EmptyString(), handler); \
elm->SetEventHandler(nsGkAtoms::on##name_, handler); \
} \
}
#define TOUCH_EVENT EVENT

View File

@@ -256,24 +256,12 @@ DOMEventTargetHelper::EventListenerAdded(nsAtom* aType)
MaybeUpdateKeepAlive();
}
void
DOMEventTargetHelper::EventListenerAdded(const nsAString& aType)
{
MaybeUpdateKeepAlive();
}
void
DOMEventTargetHelper::EventListenerRemoved(nsAtom* aType)
{
MaybeUpdateKeepAlive();
}
void
DOMEventTargetHelper::EventListenerRemoved(const nsAString& aType)
{
MaybeUpdateKeepAlive();
}
void
DOMEventTargetHelper::KeepAliveIfHasListenersFor(const nsAString& aType)
{

View File

@@ -180,10 +180,8 @@ public:
bool HasOrHasHadOwner() { return mHasOrHasHadOwnerWindow; }
virtual void EventListenerAdded(nsAtom* aType) override;
virtual void EventListenerAdded(const nsAString& aType) override;
virtual void EventListenerRemoved(nsAtom* aType) override;
virtual void EventListenerRemoved(const nsAString& aType) override;
// Dispatch a trusted, non-cancellable and non-bubbling event to |this|.
nsresult DispatchTrustedEvent(const nsAString& aEventName);
@@ -244,18 +242,11 @@ NS_DEFINE_STATIC_IID_ACCESSOR(DOMEventTargetHelper,
#define IMPL_EVENT_HANDLER(_event) \
inline mozilla::dom::EventHandlerNonNull* GetOn##_event() \
{ \
if (NS_IsMainThread()) { \
return GetEventHandler(nsGkAtoms::on##_event, EmptyString()); \
} \
return GetEventHandler(nullptr, NS_LITERAL_STRING(#_event)); \
return GetEventHandler(nsGkAtoms::on##_event); \
} \
inline void SetOn##_event(mozilla::dom::EventHandlerNonNull* aCallback) \
{ \
if (NS_IsMainThread()) { \
SetEventHandler(nsGkAtoms::on##_event, EmptyString(), aCallback); \
} else { \
SetEventHandler(nullptr, NS_LITERAL_STRING(#_event), aCallback); \
} \
SetEventHandler(nsGkAtoms::on##_event, aCallback); \
}
#endif // mozilla_DOMEventTargetHelper_h_

View File

@@ -225,10 +225,6 @@ Event::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
void
Event::GetType(nsAString& aType) const
{
if (!mIsMainThreadEvent) {
aType = mEvent->mSpecifiedEventTypeString;
return;
}
GetWidgetEventType(mEvent, aType);
}
@@ -456,16 +452,16 @@ Event::PreventDefaultInternal(bool aCalledByDefaultHandler,
void
Event::SetEventType(const nsAString& aEventTypeArg)
{
mEvent->mSpecifiedEventTypeString.Truncate();
if (mIsMainThreadEvent) {
mEvent->mSpecifiedEventTypeString.Truncate();
mEvent->mSpecifiedEventType =
nsContentUtils::GetEventMessageAndAtom(aEventTypeArg, mEvent->mClass,
&(mEvent->mMessage));
mEvent->SetDefaultComposed();
} else {
mEvent->mSpecifiedEventType = nullptr;
mEvent->mSpecifiedEventType =
NS_Atomize(NS_LITERAL_STRING("on") + aEventTypeArg);
mEvent->mMessage = eUnidentifiedEvent;
mEvent->mSpecifiedEventTypeString = aEventTypeArg;
mEvent->SetComposed(aEventTypeArg);
}
mEvent->SetDefaultComposedInNativeAnonymousContent();

View File

@@ -61,11 +61,10 @@ namespace mozilla {
using namespace dom;
using namespace hal;
#define EVENT_TYPE_EQUALS(ls, message, userType, typeString, allEvents) \
#define EVENT_TYPE_EQUALS(ls, message, userType, allEvents) \
((ls->mEventMessage == message && \
(ls->mEventMessage != eUnidentifiedEvent || \
(mIsMainThreadELM && ls->mTypeAtom == userType) || \
(!mIsMainThreadELM && ls->mTypeString.Equals(typeString)))) || \
ls->mTypeAtom == userType)) || \
(allEvents && ls->mAllEvents))
static const uint32_t kAllMutationBits =
@@ -244,16 +243,13 @@ EventListenerManager::AddEventListenerInternal(
EventListenerHolder aListenerHolder,
EventMessage aEventMessage,
nsAtom* aTypeAtom,
const nsAString& aTypeString,
const EventListenerFlags& aFlags,
bool aHandler,
bool aAllEvents)
{
MOZ_ASSERT(// Main thread
(NS_IsMainThread() && aEventMessage && aTypeAtom) ||
// non-main-thread
(!NS_IsMainThread() && aEventMessage) ||
aAllEvents, "Missing type"); // all-events listener
MOZ_ASSERT((aEventMessage && aTypeAtom) ||
aAllEvents, // all-events listener
"Missing type");
if (!aListenerHolder || mClearingListeners) {
return;
@@ -270,8 +266,7 @@ EventListenerManager::AddEventListenerInternal(
// mListener == aListenerHolder is the last one, since it can be a bit slow.
if (listener->mListenerIsHandler == aHandler &&
listener->mFlags.EqualsForAddition(aFlags) &&
EVENT_TYPE_EQUALS(listener, aEventMessage, aTypeAtom, aTypeString,
aAllEvents) &&
EVENT_TYPE_EQUALS(listener, aEventMessage, aTypeAtom, aAllEvents) &&
listener->mListener == aListenerHolder) {
return;
}
@@ -283,7 +278,6 @@ EventListenerManager::AddEventListenerInternal(
listener = aAllEvents ? mListeners.InsertElementAt(0) :
mListeners.AppendElement();
listener->mEventMessage = aEventMessage;
listener->mTypeString = aTypeString;
listener->mTypeAtom = aTypeAtom;
listener->mFlags = aFlags;
listener->mListenerIsHandler = aHandler;
@@ -442,11 +436,7 @@ EventListenerManager::AddEventListenerInternal(
}
if (mTarget) {
if (aTypeAtom) {
mTarget->EventListenerAdded(aTypeAtom);
} else if (!aTypeString.IsEmpty()) {
mTarget->EventListenerAdded(aTypeString);
}
mTarget->EventListenerAdded(aTypeAtom);
}
if (mIsMainThreadELM && mTarget) {
@@ -610,19 +600,14 @@ EventListenerManager::DisableDevice(EventMessage aEventMessage)
}
void
EventListenerManager::NotifyEventListenerRemoved(nsAtom* aUserType,
const nsAString& aTypeString)
EventListenerManager::NotifyEventListenerRemoved(nsAtom* aUserType)
{
// If the following code is changed, other callsites of EventListenerRemoved
// and NotifyAboutMainThreadListenerChange should be changed too.
mNoListenerForEvent = eVoidEvent;
mNoListenerForEventAtom = nullptr;
if (mTarget) {
if (aUserType) {
mTarget->EventListenerRemoved(aUserType);
} else if (!aTypeString.IsEmpty()) {
mTarget->EventListenerRemoved(aTypeString);
}
mTarget->EventListenerRemoved(aUserType);
}
if (mIsMainThreadELM && mTarget) {
EventListenerService::NotifyAboutMainThreadListenerChange(mTarget,
@@ -635,7 +620,6 @@ EventListenerManager::RemoveEventListenerInternal(
EventListenerHolder aListenerHolder,
EventMessage aEventMessage,
nsAtom* aUserType,
const nsAString& aTypeString,
const EventListenerFlags& aFlags,
bool aAllEvents)
{
@@ -652,12 +636,11 @@ EventListenerManager::RemoveEventListenerInternal(
for (uint32_t i = 0; i < count; ++i) {
listener = &mListeners.ElementAt(i);
if (EVENT_TYPE_EQUALS(listener, aEventMessage, aUserType, aTypeString,
aAllEvents)) {
if (EVENT_TYPE_EQUALS(listener, aEventMessage, aUserType, aAllEvents)) {
if (listener->mListener == aListenerHolder &&
listener->mFlags.EqualsForRemoval(aFlags)) {
mListeners.RemoveElementAt(i);
NotifyEventListenerRemoved(aUserType, aTypeString);
NotifyEventListenerRemoved(aUserType);
if (!aAllEvents && deviceType) {
DisableDevice(aEventMessage);
}
@@ -690,10 +673,7 @@ EventListenerManager::ListenerCanHandle(const Listener* aListener,
return true;
}
if (aEvent->mMessage == eUnidentifiedEvent) {
if (mIsMainThreadELM) {
return aListener->mTypeAtom == aEvent->mSpecifiedEventType;
}
return aListener->mTypeString.Equals(aEvent->mSpecifiedEventTypeString);
return aListener->mTypeAtom == aEvent->mSpecifiedEventType;
}
if (MOZ_UNLIKELY(!nsContentUtils::IsUnprefixedFullscreenApiEnabled() &&
aEvent->IsTrusted() && (aEventMessage == eFullscreenChange ||
@@ -731,10 +711,8 @@ EventListenerManager::AddEventListenerByType(
const Optional<bool>& aPassive)
{
RefPtr<nsAtom> atom;
EventMessage message = mIsMainThreadELM ?
nsContentUtils::GetEventMessageAndAtomForListener(aType,
getter_AddRefs(atom)) :
eUnidentifiedEvent;
EventMessage message =
GetEventMessageAndAtomForListener(aType, getter_AddRefs(atom));
EventListenerFlags flags = aFlags;
if (aPassive.WasPassed()) {
@@ -752,8 +730,7 @@ EventListenerManager::AddEventListenerByType(
}
}
AddEventListenerInternal(std::move(aListenerHolder),
message, atom, aType, flags);
AddEventListenerInternal(std::move(aListenerHolder), message, atom, flags);
}
void
@@ -763,18 +740,15 @@ EventListenerManager::RemoveEventListenerByType(
const EventListenerFlags& aFlags)
{
RefPtr<nsAtom> atom;
EventMessage message = mIsMainThreadELM ?
nsContentUtils::GetEventMessageAndAtomForListener(aType,
getter_AddRefs(atom)) :
eUnidentifiedEvent;
EventMessage message =
GetEventMessageAndAtomForListener(aType, getter_AddRefs(atom));
RemoveEventListenerInternal(std::move(aListenerHolder),
message, atom, aType, aFlags);
message, atom, aFlags);
}
EventListenerManager::Listener*
EventListenerManager::FindEventHandler(EventMessage aEventMessage,
nsAtom* aTypeAtom,
const nsAString& aTypeString)
nsAtom* aTypeAtom)
{
// Run through the listeners for this type and see if a script
// listener is registered
@@ -783,8 +757,7 @@ EventListenerManager::FindEventHandler(EventMessage aEventMessage,
for (uint32_t i = 0; i < count; ++i) {
listener = &mListeners.ElementAt(i);
if (listener->mListenerIsHandler &&
EVENT_TYPE_EQUALS(listener, aEventMessage, aTypeAtom, aTypeString,
false)) {
EVENT_TYPE_EQUALS(listener, aEventMessage, aTypeAtom, false)) {
return listener;
}
}
@@ -794,14 +767,13 @@ EventListenerManager::FindEventHandler(EventMessage aEventMessage,
EventListenerManager::Listener*
EventListenerManager::SetEventHandlerInternal(
nsAtom* aName,
const nsAString& aTypeString,
const TypedEventHandler& aTypedHandler,
bool aPermitUntrustedEvents)
{
MOZ_ASSERT(aName || !aTypeString.IsEmpty());
MOZ_ASSERT(aName);
EventMessage eventMessage = nsContentUtils::GetEventMessage(aName);
Listener* listener = FindEventHandler(eventMessage, aName, aTypeString);
EventMessage eventMessage = GetEventMessage(aName);
Listener* listener = FindEventHandler(eventMessage, aName);
if (!listener) {
// If we didn't find a script listener or no listeners existed
@@ -813,9 +785,9 @@ EventListenerManager::SetEventHandlerInternal(
NS_NewJSEventHandler(mTarget, aName,
aTypedHandler, getter_AddRefs(jsEventHandler));
AddEventListenerInternal(EventListenerHolder(jsEventHandler),
eventMessage, aName, aTypeString, flags, true);
eventMessage, aName, flags, true);
listener = FindEventHandler(eventMessage, aName, aTypeString);
listener = FindEventHandler(eventMessage, aName);
} else {
JSEventHandler* jsEventHandler = listener->GetJSEventHandler();
MOZ_ASSERT(jsEventHandler,
@@ -825,13 +797,8 @@ EventListenerManager::SetEventHandlerInternal(
// Possibly the same listener, but update still the context and scope.
jsEventHandler->SetHandler(aTypedHandler);
if (mTarget && !same) {
if (aName) {
mTarget->EventListenerRemoved(aName);
mTarget->EventListenerAdded(aName);
} else if (!aTypeString.IsEmpty()) {
mTarget->EventListenerRemoved(aTypeString);
mTarget->EventListenerAdded(aTypeString);
}
mTarget->EventListenerRemoved(aName);
mTarget->EventListenerAdded(aName);
}
if (mIsMainThreadELM && mTarget) {
EventListenerService::NotifyAboutMainThreadListenerChange(mTarget, aName);
@@ -918,7 +885,6 @@ EventListenerManager::SetEventHandler(nsAtom* aName,
NS_ENSURE_STATE(global->GetGlobalJSObject());
Listener* listener = SetEventHandlerInternal(aName,
EmptyString(),
TypedEventHandler(),
aPermitUntrustedEvents);
@@ -930,19 +896,18 @@ EventListenerManager::SetEventHandler(nsAtom* aName,
}
void
EventListenerManager::RemoveEventHandler(nsAtom* aName,
const nsAString& aTypeString)
EventListenerManager::RemoveEventHandler(nsAtom* aName)
{
if (mClearingListeners) {
return;
}
EventMessage eventMessage = nsContentUtils::GetEventMessage(aName);
Listener* listener = FindEventHandler(eventMessage, aName, aTypeString);
EventMessage eventMessage = GetEventMessage(aName);
Listener* listener = FindEventHandler(eventMessage, aName);
if (listener) {
mListeners.RemoveElementAt(uint32_t(listener - &mListeners.ElementAt(0)));
NotifyEventListenerRemoved(aName, aTypeString);
NotifyEventListenerRemoved(aName);
if (IsDeviceType(eventMessage)) {
DisableDevice(eventMessage);
}
@@ -1173,6 +1138,31 @@ EventListenerManager::GetLegacyEventMessage(EventMessage aEventMessage) const
}
}
EventMessage
EventListenerManager::GetEventMessage(nsAtom* aEventName) const
{
if (mIsMainThreadELM) {
return nsContentUtils::GetEventMessage(aEventName);
}
// The nsContentUtils event message hashtables aren't threadsafe, so just fall
// back to eUnidentifiedEvent.
return eUnidentifiedEvent;
}
EventMessage
EventListenerManager::GetEventMessageAndAtomForListener(const nsAString& aType,
nsAtom** aAtom)
{
if (mIsMainThreadELM) {
return nsContentUtils::GetEventMessageAndAtomForListener(aType, aAtom);
}
*aAtom = NS_Atomize(NS_LITERAL_STRING("on") + aType).take();
return eUnidentifiedEvent;
}
already_AddRefed<nsPIDOMWindowInner>
EventListenerManager::WindowFromListener(Listener* aListener,
bool aItemInShadowTree)
@@ -1391,8 +1381,7 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
mListeners.RemoveElementsBy([](const Listener& aListener) {
return aListener.mListenerType == Listener::eNoListener;
});
NotifyEventListenerRemoved(aEvent->mSpecifiedEventType,
aEvent->mSpecifiedEventTypeString);
NotifyEventListenerRemoved(aEvent->mSpecifiedEventType);
if (IsDeviceType(aEvent->mMessage)) {
// This is a device-type event, we need to check whether we can
// disable device after removing the once listeners.
@@ -1402,7 +1391,6 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
Listener* listener = &iter.GetNext();
if (EVENT_TYPE_EQUALS(listener, aEvent->mMessage,
aEvent->mSpecifiedEventType,
aEvent->mSpecifiedEventTypeString,
/* all events */ false)) {
hasAnyListener = true;
break;
@@ -1507,7 +1495,7 @@ EventListenerManager::AddListenerForAllEvents(EventListener* aDOMListener,
flags.mAllowUntrustedEvents = aWantsUntrusted;
flags.mInSystemGroup = aSystemEventGroup;
AddEventListenerInternal(EventListenerHolder(aDOMListener), eAllEvents,
nullptr, EmptyString(), flags, false, true);
nullptr, flags, false, true);
}
void
@@ -1519,7 +1507,7 @@ EventListenerManager::RemoveListenerForAllEvents(EventListener* aDOMListener,
flags.mCapture = aUseCapture;
flags.mInSystemGroup = aSystemEventGroup;
RemoveEventListenerInternal(EventListenerHolder(aDOMListener), eAllEvents,
nullptr, EmptyString(), flags, true);
nullptr, flags, true);
}
bool
@@ -1562,19 +1550,8 @@ EventListenerManager::MutationListenerBits()
bool
EventListenerManager::HasListenersFor(const nsAString& aEventName) const
{
if (mIsMainThreadELM) {
RefPtr<nsAtom> atom = NS_Atomize(NS_LITERAL_STRING("on") + aEventName);
return HasListenersFor(atom);
}
uint32_t count = mListeners.Length();
for (uint32_t i = 0; i < count; ++i) {
const Listener* listener = &mListeners.ElementAt(i);
if (listener->mTypeString == aEventName) {
return true;
}
}
return false;
RefPtr<nsAtom> atom = NS_Atomize(NS_LITERAL_STRING("on") + aEventName);
return HasListenersFor(atom);
}
bool
@@ -1672,17 +1649,16 @@ EventListenerManager::HasUnloadListeners()
void
EventListenerManager::SetEventHandler(nsAtom* aEventName,
const nsAString& aTypeString,
EventHandlerNonNull* aHandler)
{
if (!aHandler) {
RemoveEventHandler(aEventName, aTypeString);
RemoveEventHandler(aEventName);
return;
}
// Untrusted events are always permitted for non-chrome script
// handlers.
SetEventHandlerInternal(aEventName, aTypeString, TypedEventHandler(aHandler),
SetEventHandlerInternal(aEventName, TypedEventHandler(aHandler),
!mIsMainThreadELM ||
!nsContentUtils::IsCallerChrome());
}
@@ -1690,27 +1666,17 @@ EventListenerManager::SetEventHandler(nsAtom* aEventName,
void
EventListenerManager::SetEventHandler(OnErrorEventHandlerNonNull* aHandler)
{
if (mIsMainThreadELM) {
if (!aHandler) {
RemoveEventHandler(nsGkAtoms::onerror, EmptyString());
return;
}
// Untrusted events are always permitted for non-chrome script
// handlers.
SetEventHandlerInternal(nsGkAtoms::onerror, EmptyString(),
TypedEventHandler(aHandler),
!nsContentUtils::IsCallerChrome());
} else {
if (!aHandler) {
RemoveEventHandler(nullptr, NS_LITERAL_STRING("error"));
return;
}
// Untrusted events are always permitted.
SetEventHandlerInternal(nullptr, NS_LITERAL_STRING("error"),
TypedEventHandler(aHandler), true);
if (!aHandler) {
RemoveEventHandler(nsGkAtoms::onerror);
return;
}
// Untrusted events are always permitted on workers and for non-chrome script
// on the main thread.
bool allowUntrusted = !mIsMainThreadELM || !nsContentUtils::IsCallerChrome();
SetEventHandlerInternal(nsGkAtoms::onerror, TypedEventHandler(aHandler),
allowUntrusted);
}
void
@@ -1718,24 +1684,23 @@ EventListenerManager::SetEventHandler(
OnBeforeUnloadEventHandlerNonNull* aHandler)
{
if (!aHandler) {
RemoveEventHandler(nsGkAtoms::onbeforeunload, EmptyString());
RemoveEventHandler(nsGkAtoms::onbeforeunload);
return;
}
// Untrusted events are always permitted for non-chrome script
// handlers.
SetEventHandlerInternal(nsGkAtoms::onbeforeunload, EmptyString(),
SetEventHandlerInternal(nsGkAtoms::onbeforeunload,
TypedEventHandler(aHandler),
!mIsMainThreadELM ||
!nsContentUtils::IsCallerChrome());
}
const TypedEventHandler*
EventListenerManager::GetTypedEventHandler(nsAtom* aEventName,
const nsAString& aTypeString)
EventListenerManager::GetTypedEventHandler(nsAtom* aEventName)
{
EventMessage eventMessage = nsContentUtils::GetEventMessage(aEventName);
Listener* listener = FindEventHandler(eventMessage, aEventName, aTypeString);
EventMessage eventMessage = GetEventMessage(aEventName);
Listener* listener = FindEventHandler(eventMessage, aEventName);
if (!listener) {
return nullptr;

View File

@@ -183,8 +183,7 @@ public:
struct Listener
{
EventListenerHolder mListener;
RefPtr<nsAtom> mTypeAtom; // for the main thread
nsString mTypeString; // for non-main-threads
RefPtr<nsAtom> mTypeAtom;
EventMessage mEventMessage;
enum ListenerType : uint8_t
@@ -227,7 +226,6 @@ public:
Listener(Listener&& aOther)
: mListener(std::move(aOther.mListener))
, mTypeAtom(aOther.mTypeAtom.forget())
, mTypeString(aOther.mTypeString)
, mEventMessage(aOther.mEventMessage)
, mListenerType(aOther.mListenerType)
, mListenerIsHandler(aOther.mListenerIsHandler)
@@ -235,7 +233,6 @@ public:
, mAllEvents(aOther.mAllEvents)
, mIsChrome(aOther.mIsChrome)
{
aOther.mTypeString.Truncate();
aOther.mEventMessage = eVoidEvent;
aOther.mListenerType = eNoListener;
aOther.mListenerIsHandler = false;
@@ -363,7 +360,7 @@ public:
/**
* Remove the current "inline" event listener for aName.
*/
void RemoveEventHandler(nsAtom *aName, const nsAString& aTypeString);
void RemoveEventHandler(nsAtom *aName);
void HandleEvent(nsPresContext* aPresContext,
WidgetEvent* aEvent,
@@ -514,6 +511,17 @@ protected:
*/
EventMessage GetLegacyEventMessage(EventMessage aEventMessage) const;
/**
* Get the event message for the given event name.
*/
EventMessage GetEventMessage(nsAtom* aEventName) const;
/**
* Get the event message and atom for the given event type.
*/
EventMessage GetEventMessageAndAtomForListener(const nsAString& aType,
nsAtom** aAtom);
void ProcessApzAwareEventListenerAdd();
/**
@@ -530,8 +538,7 @@ protected:
* Find the Listener for the "inline" event listener for aTypeAtom.
*/
Listener* FindEventHandler(EventMessage aEventMessage,
nsAtom* aTypeAtom,
const nsAString& aTypeString);
nsAtom* aTypeAtom);
/**
* Set the "inline" event listener for aName to aHandler. aHandler may be
@@ -541,7 +548,6 @@ protected:
* allowed to be null.
*/
Listener* SetEventHandlerInternal(nsAtom* aName,
const nsAString& aTypeString,
const TypedEventHandler& aHandler,
bool aPermitUntrustedEvents);
@@ -555,7 +561,6 @@ public:
* aHandler is null, this will actually remove the event listener
*/
void SetEventHandler(nsAtom* aEventName,
const nsAString& aTypeString,
dom::EventHandlerNonNull* aHandler);
void SetEventHandler(dom::OnErrorEventHandlerNonNull* aHandler);
void SetEventHandler(dom::OnBeforeUnloadEventHandlerNonNull* aHandler);
@@ -569,26 +574,23 @@ public:
* OnErrorEventHandlerNonNull for some event targets and EventHandlerNonNull
* for others.
*/
dom::EventHandlerNonNull* GetEventHandler(nsAtom* aEventName,
const nsAString& aTypeString)
dom::EventHandlerNonNull* GetEventHandler(nsAtom* aEventName)
{
const TypedEventHandler* typedHandler =
GetTypedEventHandler(aEventName, aTypeString);
const TypedEventHandler* typedHandler = GetTypedEventHandler(aEventName);
return typedHandler ? typedHandler->NormalEventHandler() : nullptr;
}
dom::OnErrorEventHandlerNonNull* GetOnErrorEventHandler()
{
const TypedEventHandler* typedHandler = mIsMainThreadELM ?
GetTypedEventHandler(nsGkAtoms::onerror, EmptyString()) :
GetTypedEventHandler(nullptr, NS_LITERAL_STRING("error"));
const TypedEventHandler* typedHandler =
GetTypedEventHandler(nsGkAtoms::onerror);
return typedHandler ? typedHandler->OnErrorEventHandler() : nullptr;
}
dom::OnBeforeUnloadEventHandlerNonNull* GetOnBeforeUnloadEventHandler()
{
const TypedEventHandler* typedHandler =
GetTypedEventHandler(nsGkAtoms::onbeforeunload, EmptyString());
GetTypedEventHandler(nsGkAtoms::onbeforeunload);
return typedHandler ? typedHandler->OnBeforeUnloadEventHandler() : nullptr;
}
@@ -601,8 +603,7 @@ protected:
* Helper method for implementing the various Get*EventHandler above. Will
* return null if we don't have an event handler for this event name.
*/
const TypedEventHandler* GetTypedEventHandler(nsAtom* aEventName,
const nsAString& aTypeString);
const TypedEventHandler* GetTypedEventHandler(nsAtom* aEventName);
void AddEventListener(const nsAString& aType,
EventListenerHolder aListener,
@@ -622,19 +623,16 @@ protected:
void AddEventListenerInternal(EventListenerHolder aListener,
EventMessage aEventMessage,
nsAtom* aTypeAtom,
const nsAString& aTypeString,
const EventListenerFlags& aFlags,
bool aHandler = false,
bool aAllEvents = false);
void RemoveEventListenerInternal(EventListenerHolder aListener,
EventMessage aEventMessage,
nsAtom* aUserType,
const nsAString& aTypeString,
const EventListenerFlags& aFlags,
bool aAllEvents = false);
void RemoveAllListeners();
void NotifyEventListenerRemoved(nsAtom* aUserType,
const nsAString& aTypeString);
void NotifyEventListenerRemoved(nsAtom* aUserType);
const EventTypeData* GetTypeDataForIID(const nsIID& aIID);
const EventTypeData* GetTypeDataForEventName(nsAtom* aName);
nsPIDOMWindowInner* GetInnerWindowForTarget();

View File

@@ -143,10 +143,10 @@ EventTarget::RemoveSystemEventListener(const nsAString& aType,
}
EventHandlerNonNull*
EventTarget::GetEventHandler(nsAtom* aType, const nsAString& aTypeString)
EventTarget::GetEventHandler(nsAtom* aType)
{
EventListenerManager* elm = GetExistingListenerManager();
return elm ? elm->GetEventHandler(aType, aTypeString) : nullptr;
return elm ? elm->GetEventHandler(aType) : nullptr;
}
void
@@ -158,21 +158,14 @@ EventTarget::SetEventHandler(const nsAString& aType,
aRv.Throw(NS_ERROR_INVALID_ARG);
return;
}
if (NS_IsMainThread()) {
RefPtr<nsAtom> type = NS_Atomize(aType);
SetEventHandler(type, EmptyString(), aHandler);
return;
}
SetEventHandler(nullptr,
Substring(aType, 2), // Remove "on"
aHandler);
RefPtr<nsAtom> type = NS_Atomize(aType);
SetEventHandler(type, aHandler);
}
void
EventTarget::SetEventHandler(nsAtom* aType, const nsAString& aTypeString,
EventHandlerNonNull* aHandler)
EventTarget::SetEventHandler(nsAtom* aType, EventHandlerNonNull* aHandler)
{
GetOrCreateListenerManager()->SetEventHandler(aType, aTypeString, aHandler);
GetOrCreateListenerManager()->SetEventHandler(aType, aHandler);
}
bool

View File

@@ -178,28 +178,18 @@ public:
EventHandlerNonNull* GetEventHandler(const nsAString& aType)
{
RefPtr<nsAtom> type = NS_Atomize(aType);
return GetEventHandler(type, EmptyString());
return GetEventHandler(type);
}
// Note, this takes the type in onfoo form!
void SetEventHandler(const nsAString& aType, EventHandlerNonNull* aHandler,
ErrorResult& rv);
// The nsAtom version of EventListenerAdded is called on the main
// thread. The string version is called on workers.
//
// For an event 'foo' aType will be 'onfoo' when it's an atom and
// 'foo' when it's a string..
// For an event 'foo' aType will be 'onfoo'.
virtual void EventListenerAdded(nsAtom* aType) {}
virtual void EventListenerAdded(const nsAString& aType) {}
// The nsAtom version of EventListenerRemoved is called on the main
// thread. The string version is called on workers.
//
// For an event 'foo' aType will be 'onfoo' when it's an atom and
// 'foo' when it's a string..
// For an event 'foo' aType will be 'onfoo'.
virtual void EventListenerRemoved(nsAtom* aType) {}
virtual void EventListenerRemoved(const nsAString& aType) {}
// Returns an outer window that corresponds to the inner window this event
// target is associated with. Will return null if the inner window is not the
@@ -281,10 +271,8 @@ public:
virtual nsresult PostHandleEvent(EventChainPostVisitor& aVisitor) = 0;
protected:
EventHandlerNonNull* GetEventHandler(nsAtom* aType,
const nsAString& aTypeString);
void SetEventHandler(nsAtom* aType, const nsAString& aTypeString,
EventHandlerNonNull* aHandler);
EventHandlerNonNull* GetEventHandler(nsAtom* aType);
void SetEventHandler(nsAtom* aType, EventHandlerNonNull* aHandler);
/**
* Hook for AddEventListener that allows it to compute the right

View File

@@ -7372,28 +7372,25 @@ HTMLMediaElement::SetMediaKeys(mozilla::dom::MediaKeys* aMediaKeys,
EventHandlerNonNull*
HTMLMediaElement::GetOnencrypted()
{
return EventTarget::GetEventHandler(nsGkAtoms::onencrypted, EmptyString());
return EventTarget::GetEventHandler(nsGkAtoms::onencrypted);
}
void
HTMLMediaElement::SetOnencrypted(EventHandlerNonNull* aCallback)
{
EventTarget::SetEventHandler(
nsGkAtoms::onencrypted, EmptyString(), aCallback);
EventTarget::SetEventHandler(nsGkAtoms::onencrypted, aCallback);
}
EventHandlerNonNull*
HTMLMediaElement::GetOnwaitingforkey()
{
return EventTarget::GetEventHandler(nsGkAtoms::onwaitingforkey,
EmptyString());
return EventTarget::GetEventHandler(nsGkAtoms::onwaitingforkey);
}
void
HTMLMediaElement::SetOnwaitingforkey(EventHandlerNonNull* aCallback)
{
EventTarget::SetEventHandler(
nsGkAtoms::onwaitingforkey, EmptyString(), aCallback);
EventTarget::SetEventHandler(nsGkAtoms::onwaitingforkey, aCallback);
}
void

View File

@@ -628,7 +628,7 @@ nsGenericHTMLElement::BeforeSetAttr(int32_t aNamespaceID, nsAtom* aName,
}
if (!aValue && IsEventAttributeName(aName)) {
if (EventListenerManager* manager = GetExistingListenerManager()) {
manager->RemoveEventHandler(aName, EmptyString());
manager->RemoveEventHandler(aName);
}
}
}

View File

@@ -249,20 +249,13 @@ MediaDevices::OnDeviceChange()
mozilla::dom::EventHandlerNonNull*
MediaDevices::GetOndevicechange()
{
if (NS_IsMainThread()) {
return GetEventHandler(nsGkAtoms::ondevicechange, EmptyString());
}
return GetEventHandler(nullptr, NS_LITERAL_STRING("devicechange"));
return GetEventHandler(nsGkAtoms::ondevicechange);
}
void
MediaDevices::SetOndevicechange(mozilla::dom::EventHandlerNonNull* aCallback)
{
if (NS_IsMainThread()) {
SetEventHandler(nsGkAtoms::ondevicechange, EmptyString(), aCallback);
} else {
SetEventHandler(nullptr, NS_LITERAL_STRING("devicechange"), aCallback);
}
SetEventHandler(nsGkAtoms::ondevicechange, aCallback);
MediaManager::Get()->AddDeviceChangeCallback(this);
}

View File

@@ -645,25 +645,25 @@ MediaKeySession::SetExpiration(double aExpiration)
EventHandlerNonNull*
MediaKeySession::GetOnkeystatuseschange()
{
return GetEventHandler(nsGkAtoms::onkeystatuseschange, EmptyString());
return GetEventHandler(nsGkAtoms::onkeystatuseschange);
}
void
MediaKeySession::SetOnkeystatuseschange(EventHandlerNonNull* aCallback)
{
SetEventHandler(nsGkAtoms::onkeystatuseschange, EmptyString(), aCallback);
SetEventHandler(nsGkAtoms::onkeystatuseschange, aCallback);
}
EventHandlerNonNull*
MediaKeySession::GetOnmessage()
{
return GetEventHandler(nsGkAtoms::onmessage, EmptyString());
return GetEventHandler(nsGkAtoms::onmessage);
}
void
MediaKeySession::SetOnmessage(EventHandlerNonNull* aCallback)
{
SetEventHandler(nsGkAtoms::onmessage, EmptyString(), aCallback);
SetEventHandler(nsGkAtoms::onmessage, aCallback);
}
nsCString

View File

@@ -562,20 +562,13 @@ MessagePort::CloseInternal(bool aSoftly)
EventHandlerNonNull*
MessagePort::GetOnmessage()
{
if (NS_IsMainThread()) {
return GetEventHandler(nsGkAtoms::onmessage, EmptyString());
}
return GetEventHandler(nullptr, NS_LITERAL_STRING("message"));
return GetEventHandler(nsGkAtoms::onmessage);
}
void
MessagePort::SetOnmessage(EventHandlerNonNull* aCallback)
{
if (NS_IsMainThread()) {
SetEventHandler(nsGkAtoms::onmessage, EmptyString(), aCallback);
} else {
SetEventHandler(nullptr, NS_LITERAL_STRING("message"), aCallback);
}
SetEventHandler(nsGkAtoms::onmessage, aCallback);
// When using onmessage, the call to start() is implied.
Start();

View File

@@ -56,20 +56,13 @@ MIDIInput::Receive(const nsTArray<MIDIMessage>& aMsgs)
EventHandlerNonNull*
MIDIInput::GetOnmidimessage()
{
if (NS_IsMainThread()) {
return GetEventHandler(nsGkAtoms::onmidimessage, EmptyString());
}
return GetEventHandler(nullptr, NS_LITERAL_STRING("midimessage"));
return GetEventHandler(nsGkAtoms::onmidimessage);
}
void
MIDIInput::SetOnmidimessage(EventHandlerNonNull* aCallback)
{
if (NS_IsMainThread()) {
SetEventHandler(nsGkAtoms::onmidimessage, EmptyString(), aCallback);
} else {
SetEventHandler(nullptr, NS_LITERAL_STRING("midimessage"), aCallback);
}
SetEventHandler(nsGkAtoms::onmidimessage, aCallback);
if (mPort->ConnectionState() != MIDIPortConnectionState::Open) {
mPort->SendOpen();
}

View File

@@ -671,7 +671,7 @@ nsSVGElement::UnsetAttrInternal(int32_t aNamespaceID, nsAtom* aName,
EventListenerManager* manager = GetExistingListenerManager();
if (manager) {
nsAtom* eventName = GetEventNameForAttr(aName);
manager->RemoveEventHandler(eventName, EmptyString());
manager->RemoveEventHandler(eventName);
}
return;
}

View File

@@ -2324,14 +2324,14 @@ WebSocketImpl::UpdateURI()
void
WebSocket::EventListenerAdded(nsAtom* aType)
{
AssertIsOnMainThread();
AssertIsOnTargetThread();
UpdateMustKeepAlive();
}
void
WebSocket::EventListenerRemoved(nsAtom* aType)
{
AssertIsOnMainThread();
AssertIsOnTargetThread();
UpdateMustKeepAlive();
}

View File

@@ -735,7 +735,7 @@ ServiceWorkerGlobalScope::GetOnfetch()
MOZ_ASSERT(mWorkerPrivate);
mWorkerPrivate->AssertIsOnWorkerThread();
return GetEventHandler(nullptr, NS_LITERAL_STRING("fetch"));
return GetEventHandler(nsGkAtoms::onfetch);
}
namespace {
@@ -788,16 +788,16 @@ ServiceWorkerGlobalScope::SetOnfetch(mozilla::dom::EventHandlerNonNull* aCallbac
}
mWorkerPrivate->SetFetchHandlerWasAdded();
}
SetEventHandler(nullptr, NS_LITERAL_STRING("fetch"), aCallback);
SetEventHandler(nsGkAtoms::onfetch, aCallback);
}
void
ServiceWorkerGlobalScope::EventListenerAdded(const nsAString& aType)
ServiceWorkerGlobalScope::EventListenerAdded(nsAtom* aType)
{
MOZ_ASSERT(mWorkerPrivate);
mWorkerPrivate->AssertIsOnWorkerThread();
if (!aType.EqualsLiteral("fetch")) {
if (aType != nsGkAtoms::onfetch) {
return;
}

View File

@@ -352,11 +352,7 @@ public:
void
SetOnfetch(mozilla::dom::EventHandlerNonNull* aCallback);
// We only need to override the string version of EventListenerAdded, because
// the atom version should never be called on workers. Until bug 1450167 is
// fixed, at least.
using DOMEventTargetHelper::EventListenerAdded;
void EventListenerAdded(const nsAString& aType) override;
void EventListenerAdded(nsAtom* aType) override;
};
class WorkerDebuggerGlobalScope final : public DOMEventTargetHelper,

View File

@@ -1893,6 +1893,7 @@ GK_ATOM(ongamepadbuttonup, "ongamepadbuttonup")
GK_ATOM(ongamepadaxismove, "ongamepadaxismove")
GK_ATOM(ongamepadconnected, "ongamepadconnected")
GK_ATOM(ongamepaddisconnected, "ongamepaddisconnected")
GK_ATOM(onfetch, "onfetch")
// Content property names
GK_ATOM(afterPseudoProperty, "afterPseudoProperty") // nsXMLElement*