Bug 1385071 - Add another method to EventTarget for detecting only non-passive key listeners. r=smaug draft
authorRyan Hunt <rhunt@eqrion.net>
Thu, 27 Jul 2017 19:46:44 -0400
changeset 620710 a6bb4b7fff3488dea62b9114aa164814c74561a4
parent 620112 d942ef54fdf726840a698d2ddcaf989d2c00edbc
child 620711 724b110fd55c5935df589f1cbcc0b3380028a1ed
push id72133
push userbmo:rhunt@eqrion.net
push dateThu, 03 Aug 2017 20:23:49 +0000
reviewerssmaug
bugs1385071
milestone57.0a1
Bug 1385071 - Add another method to EventTarget for detecting only non-passive key listeners. r=smaug This is for adding a pref that will allow web content to have key listeners and use keyboard APZ, if they are marked passive. This commit also reworks the function names and comments to make them more accurate. MozReview-Commit-ID: LGDaVQOK1CS
dom/events/EventListenerManager.cpp
dom/events/EventListenerManager.h
dom/events/EventTarget.cpp
dom/events/EventTarget.h
gfx/layers/apz/src/FocusTarget.cpp
--- a/dom/events/EventListenerManager.cpp
+++ b/dom/events/EventListenerManager.cpp
@@ -1760,33 +1760,51 @@ EventListenerManager::TraceListeners(JST
       mozilla::TraceScriptHolder(listener.mListener.GetWebIDLCallback(), aTrc);
     }
     // We might have eWrappedJSListener, but that is the legacy type for
     // JS implemented event listeners, and trickier to handle here.
   }
 }
 
 bool
-EventListenerManager::HasUntrustedOrNonSystemGroupKeyEventListeners()
+EventListenerManager::HasNonSystemGroupListenersForUntrustedKeyEvents()
 {
   uint32_t count = mListeners.Length();
   for (uint32_t i = 0; i < count; ++i) {
     Listener* listener = &mListeners.ElementAt(i);
     if (!listener->mFlags.mInSystemGroup &&
         listener->mFlags.mAllowUntrustedEvents &&
         (listener->mTypeAtom == nsGkAtoms::onkeydown ||
          listener->mTypeAtom == nsGkAtoms::onkeypress ||
          listener->mTypeAtom == nsGkAtoms::onkeyup)) {
       return true;
     }
   }
   return false;
 }
 
 bool
+EventListenerManager::HasNonPassiveNonSystemGroupListenersForUntrustedKeyEvents()
+{
+  uint32_t count = mListeners.Length();
+  for (uint32_t i = 0; i < count; ++i) {
+    Listener* listener = &mListeners.ElementAt(i);
+    if (!listener->mFlags.mPassive &&
+        !listener->mFlags.mInSystemGroup &&
+        listener->mFlags.mAllowUntrustedEvents &&
+        (listener->mTypeAtom == nsGkAtoms::onkeydown ||
+         listener->mTypeAtom == nsGkAtoms::onkeypress ||
+         listener->mTypeAtom == nsGkAtoms::onkeyup)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool
 EventListenerManager::HasApzAwareListeners()
 {
   uint32_t count = mListeners.Length();
   for (uint32_t i = 0; i < count; ++i) {
     Listener* listener = &mListeners.ElementAt(i);
     if (IsApzAwareListener(listener)) {
       return true;
     }
--- a/dom/events/EventListenerManager.h
+++ b/dom/events/EventListenerManager.h
@@ -465,17 +465,18 @@ public:
   }
 
   void MarkForCC();
 
   void TraceListeners(JSTracer* aTrc);
 
   dom::EventTarget* GetTarget() { return mTarget; }
 
-  bool HasUntrustedOrNonSystemGroupKeyEventListeners();
+  bool HasNonSystemGroupListenersForUntrustedKeyEvents();
+  bool HasNonPassiveNonSystemGroupListenersForUntrustedKeyEvents();
 
   bool HasApzAwareListeners();
   bool IsApzAwareListener(Listener* aListener);
   bool IsApzAwareEvent(nsIAtom* aEvent);
 
 protected:
   void HandleEventInternal(nsPresContext* aPresContext,
                            WidgetEvent* aEvent,
--- a/dom/events/EventTarget.cpp
+++ b/dom/events/EventTarget.cpp
@@ -53,20 +53,27 @@ EventTarget::SetEventHandler(const nsASt
 void
 EventTarget::SetEventHandler(nsIAtom* aType, const nsAString& aTypeString,
                              EventHandlerNonNull* aHandler)
 {
   GetOrCreateListenerManager()->SetEventHandler(aType, aTypeString, aHandler);
 }
 
 bool
-EventTarget::HasUntrustedOrNonSystemGroupKeyEventListeners() const
+EventTarget::HasNonSystemGroupListenersForUntrustedKeyEvents() const
 {
   EventListenerManager* elm = GetExistingListenerManager();
-  return elm && elm->HasUntrustedOrNonSystemGroupKeyEventListeners();
+  return elm && elm->HasNonSystemGroupListenersForUntrustedKeyEvents();
+}
+
+bool
+EventTarget::HasNonPassiveNonSystemGroupListenersForUntrustedKeyEvents() const
+{
+  EventListenerManager* elm = GetExistingListenerManager();
+  return elm && elm->HasNonPassiveNonSystemGroupListenersForUntrustedKeyEvents();
 }
 
 bool
 EventTarget::IsApzAware() const
 {
   EventListenerManager* elm = GetExistingListenerManager();
   return elm && elm->HasApzAwareListeners();
 }
--- a/dom/events/EventTarget.h
+++ b/dom/events/EventTarget.h
@@ -94,19 +94,23 @@ public:
    * Get the event listener manager, returning null if it does not already
    * exist.
    */
   virtual EventListenerManager* GetExistingListenerManager() const = 0;
 
   // Called from AsyncEventDispatcher to notify it is running.
   virtual void AsyncEventRunning(AsyncEventDispatcher* aEvent) {}
 
-  // Used by FocusTarget to determine whether this event target has listeners
-  // for untrusted or non system group key events.
-  bool HasUntrustedOrNonSystemGroupKeyEventListeners() const;
+  // Used by APZ to determine whether this event target has non-chrome event
+  // listeners for untrusted key events.
+  bool HasNonSystemGroupListenersForUntrustedKeyEvents() const;
+
+  // Used by APZ to determine whether this event target has non-chrome and
+  // non-passive event listeners for untrusted key events.
+  bool HasNonPassiveNonSystemGroupListenersForUntrustedKeyEvents() const;
 
   virtual bool IsApzAware() const;
 
 protected:
   EventHandlerNonNull* GetEventHandler(nsIAtom* aType,
                                        const nsAString& aTypeString);
   void SetEventHandler(nsIAtom* aType, const nsAString& aTypeString,
                        EventHandlerNonNull* aHandler);
--- a/gfx/layers/apz/src/FocusTarget.cpp
+++ b/gfx/layers/apz/src/FocusTarget.cpp
@@ -59,17 +59,17 @@ HasListenersForKeyEvents(nsIContent* aCo
   }
 
   WidgetEvent event(true, eVoidEvent);
   nsTArray<EventTarget*> targets;
   nsresult rv = EventDispatcher::Dispatch(aContent, nullptr, &event, nullptr,
       nullptr, nullptr, &targets);
   NS_ENSURE_SUCCESS(rv, false);
   for (size_t i = 0; i < targets.Length(); i++) {
-    if (targets[i]->HasUntrustedOrNonSystemGroupKeyEventListeners()) {
+    if (targets[i]->HasNonSystemGroupListenersForUntrustedKeyEvents()) {
       return true;
     }
   }
   return false;
 }
 
 static bool
 IsEditableNode(nsINode* aNode)