#399: passive event listener support M1266066
This commit is contained in:
parent
fbde989ca7
commit
034fda860a
|
@ -522,6 +522,14 @@ Event::PreventDefaultInternal(bool aCalledByDefaultHandler)
|
||||||
if (!mEvent->mFlags.mCancelable) {
|
if (!mEvent->mFlags.mCancelable) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (mEvent->mFlags.mInPassiveListener) {
|
||||||
|
#if DEBUG
|
||||||
|
// XXX: There should be a warning here, but we don't have the string.
|
||||||
|
// https://hg.mozilla.org/mozilla-central/rev/cda76e80a47c
|
||||||
|
fprintf(stderr, "** PreventDefaultInternal called on Passive Listener\n");
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mEvent->mFlags.mDefaultPrevented = true;
|
mEvent->mFlags.mDefaultPrevented = true;
|
||||||
|
|
||||||
|
|
|
@ -250,7 +250,7 @@ EventListenerManager::AddEventListenerInternal(
|
||||||
listener = &mListeners.ElementAt(i);
|
listener = &mListeners.ElementAt(i);
|
||||||
// mListener == aListenerHolder is the last one, since it can be a bit slow.
|
// mListener == aListenerHolder is the last one, since it can be a bit slow.
|
||||||
if (listener->mListenerIsHandler == aHandler &&
|
if (listener->mListenerIsHandler == aHandler &&
|
||||||
listener->mFlags == aFlags &&
|
listener->mFlags.EqualsForAddition(aFlags) &&
|
||||||
EVENT_TYPE_EQUALS(listener, aEventMessage, aTypeAtom, aTypeString,
|
EVENT_TYPE_EQUALS(listener, aEventMessage, aTypeAtom, aTypeString,
|
||||||
aAllEvents) &&
|
aAllEvents) &&
|
||||||
listener->mListener == aListenerHolder) {
|
listener->mListener == aListenerHolder) {
|
||||||
|
@ -409,7 +409,7 @@ EventListenerManager::AddEventListenerInternal(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsApzAwareEvent(aTypeAtom)) {
|
if (IsApzAwareListener(listener)) {
|
||||||
nsCOMPtr<nsINode> node = do_QueryInterface(mTarget);
|
nsCOMPtr<nsINode> node = do_QueryInterface(mTarget);
|
||||||
if (node) {
|
if (node) {
|
||||||
node->SetMayHaveApzAwareListeners();
|
node->SetMayHaveApzAwareListeners();
|
||||||
|
@ -545,7 +545,7 @@ EventListenerManager::RemoveEventListenerInternal(
|
||||||
aAllEvents)) {
|
aAllEvents)) {
|
||||||
++typeCount;
|
++typeCount;
|
||||||
if (listener->mListener == aListenerHolder &&
|
if (listener->mListener == aListenerHolder &&
|
||||||
listener->mFlags.EqualsIgnoringTrustness(aFlags)) {
|
listener->mFlags.EqualsForRemoval(aFlags)) {
|
||||||
RefPtr<EventListenerManager> kungFuDeathGrip(this);
|
RefPtr<EventListenerManager> kungFuDeathGrip(this);
|
||||||
mListeners.RemoveElementAt(i);
|
mListeners.RemoveElementAt(i);
|
||||||
--count;
|
--count;
|
||||||
|
@ -1152,9 +1152,11 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aEvent->mFlags.mInPassiveListener = listener->mFlags.mPassive;
|
||||||
if (NS_FAILED(HandleEventSubType(listener, *aDOMEvent, aCurrentTarget))) {
|
if (NS_FAILED(HandleEventSubType(listener, *aDOMEvent, aCurrentTarget))) {
|
||||||
aEvent->mFlags.mExceptionHasBeenRisen = true;
|
aEvent->mFlags.mExceptionHasBeenRisen = true;
|
||||||
}
|
}
|
||||||
|
aEvent->mFlags.mInPassiveListener = false;
|
||||||
|
|
||||||
if (needsEndEventMarker) {
|
if (needsEndEventMarker) {
|
||||||
timelines->AddMarkerForDocShell(
|
timelines->AddMarkerForDocShell(
|
||||||
|
@ -1205,9 +1207,12 @@ EventListenerManager::AddEventListener(
|
||||||
bool aWantsUntrusted)
|
bool aWantsUntrusted)
|
||||||
{
|
{
|
||||||
EventListenerFlags flags;
|
EventListenerFlags flags;
|
||||||
flags.mCapture =
|
if (aOptions.IsBoolean()) {
|
||||||
aOptions.IsBoolean() ? aOptions.GetAsBoolean()
|
flags.mCapture = aOptions.GetAsBoolean();
|
||||||
: aOptions.GetAsAddEventListenerOptions().mCapture;
|
} else {
|
||||||
|
flags.mCapture = aOptions.GetAsAddEventListenerOptions().mCapture;
|
||||||
|
flags.mPassive = aOptions.GetAsAddEventListenerOptions().mPassive;
|
||||||
|
}
|
||||||
flags.mAllowUntrustedEvents = aWantsUntrusted;
|
flags.mAllowUntrustedEvents = aWantsUntrusted;
|
||||||
return AddEventListenerByType(aListenerHolder, aType, flags);
|
return AddEventListenerByType(aListenerHolder, aType, flags);
|
||||||
}
|
}
|
||||||
|
@ -1542,13 +1547,19 @@ EventListenerManager::HasApzAwareListeners()
|
||||||
uint32_t count = mListeners.Length();
|
uint32_t count = mListeners.Length();
|
||||||
for (uint32_t i = 0; i < count; ++i) {
|
for (uint32_t i = 0; i < count; ++i) {
|
||||||
Listener* listener = &mListeners.ElementAt(i);
|
Listener* listener = &mListeners.ElementAt(i);
|
||||||
if (IsApzAwareEvent(listener->mTypeAtom)) {
|
if (IsApzAwareListener(listener)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
EventListenerManager::IsApzAwareListener(Listener* aListener)
|
||||||
|
{
|
||||||
|
return !aListener->mFlags.mPassive && IsApzAwareEvent(aListener->mTypeAtom);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EventListenerManager::IsApzAwareEvent(nsIAtom* aEvent)
|
EventListenerManager::IsApzAwareEvent(nsIAtom* aEvent)
|
||||||
{
|
{
|
||||||
|
|
|
@ -58,31 +58,32 @@ public:
|
||||||
// If mAllowUntrustedEvents is true, the listener is listening to the
|
// If mAllowUntrustedEvents is true, the listener is listening to the
|
||||||
// untrusted events too.
|
// untrusted events too.
|
||||||
bool mAllowUntrustedEvents : 1;
|
bool mAllowUntrustedEvents : 1;
|
||||||
|
// If mPassive is true, the listener will not be calling preventDefault on the
|
||||||
|
// event. (If it does call preventDefault, we should ignore it).
|
||||||
|
bool mPassive : 1;
|
||||||
|
|
||||||
EventListenerFlags() :
|
EventListenerFlags() :
|
||||||
mListenerIsJSListener(false),
|
mListenerIsJSListener(false),
|
||||||
mCapture(false), mInSystemGroup(false), mAllowUntrustedEvents(false)
|
mCapture(false), mInSystemGroup(false), mAllowUntrustedEvents(false),
|
||||||
|
mPassive(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Equals(const EventListenerFlags& aOther) const
|
bool EqualsForAddition(const EventListenerFlags& aOther) const
|
||||||
{
|
{
|
||||||
return (mCapture == aOther.mCapture &&
|
return (mCapture == aOther.mCapture &&
|
||||||
mInSystemGroup == aOther.mInSystemGroup &&
|
mInSystemGroup == aOther.mInSystemGroup &&
|
||||||
mListenerIsJSListener == aOther.mListenerIsJSListener &&
|
mListenerIsJSListener == aOther.mListenerIsJSListener &&
|
||||||
mAllowUntrustedEvents == aOther.mAllowUntrustedEvents);
|
mAllowUntrustedEvents == aOther.mAllowUntrustedEvents);
|
||||||
|
// Don't compare mPassive
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EqualsIgnoringTrustness(const EventListenerFlags& aOther) const
|
bool EqualsForRemoval(const EventListenerFlags& aOther) const
|
||||||
{
|
{
|
||||||
return (mCapture == aOther.mCapture &&
|
return (mCapture == aOther.mCapture &&
|
||||||
mInSystemGroup == aOther.mInSystemGroup &&
|
mInSystemGroup == aOther.mInSystemGroup &&
|
||||||
mListenerIsJSListener == aOther.mListenerIsJSListener);
|
mListenerIsJSListener == aOther.mListenerIsJSListener);
|
||||||
}
|
// Don't compare mAllowUntrustedEvents or mPassive
|
||||||
|
|
||||||
bool operator==(const EventListenerFlags& aOther) const
|
|
||||||
{
|
|
||||||
return Equals(aOther);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -444,7 +445,7 @@ public:
|
||||||
dom::EventTarget* GetTarget() { return mTarget; }
|
dom::EventTarget* GetTarget() { return mTarget; }
|
||||||
|
|
||||||
bool HasApzAwareListeners();
|
bool HasApzAwareListeners();
|
||||||
|
bool IsApzAwareListener(Listener* aListener);
|
||||||
bool IsApzAwareEvent(nsIAtom* aEvent);
|
bool IsApzAwareEvent(nsIAtom* aEvent);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -16,7 +16,8 @@ dictionary EventListenerOptions {
|
||||||
};
|
};
|
||||||
|
|
||||||
dictionary AddEventListenerOptions : EventListenerOptions {
|
dictionary AddEventListenerOptions : EventListenerOptions {
|
||||||
// boolean passive = false;
|
boolean passive = false;
|
||||||
|
// XXX: this is bug 1287706 and follow-on 1367372
|
||||||
// boolean once = false;
|
// boolean once = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,9 @@ public:
|
||||||
// perform its associated action. This is currently only relevant for
|
// perform its associated action. This is currently only relevant for
|
||||||
// wheel and touch events.
|
// wheel and touch events.
|
||||||
bool mHandledByAPZ : 1;
|
bool mHandledByAPZ : 1;
|
||||||
|
// True if the event is currently being handled by an event listener that
|
||||||
|
// was registered as a passive listener.
|
||||||
|
bool mInPassiveListener: 1;
|
||||||
|
|
||||||
// If the event is being handled in target phase, returns true.
|
// If the event is being handled in target phase, returns true.
|
||||||
inline bool InTargetPhase() const
|
inline bool InTargetPhase() const
|
||||||
|
|
Loading…
Reference in New Issue