Bug 1300606 - DeviceType event handlers/listeners aren't removed properly, r=mccr8
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Tue, 13 Sep 2016 17:00:43 -0700
changeset 313827 2c34737c57e5f47d981d79eacb447732b90dbb29
parent 313808 82d0a583a9a39bf0b0000bccbf6d5c9ec2596bcc
child 313828 805d466424e474ca3c984202449c0a08031c325b
push id32264
push usercbook@mozilla.com
push dateWed, 14 Sep 2016 10:18:20 +0000
treeherderautoland@b9c4a0402a0a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1300606
milestone51.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1300606 - DeviceType event handlers/listeners aren't removed properly, r=mccr8
dom/events/EventListenerManager.cpp
dom/events/test/test_bug742376.html
--- a/dom/events/EventListenerManager.cpp
+++ b/dom/events/EventListenerManager.cpp
@@ -647,42 +647,36 @@ EventListenerManager::RemoveEventListene
 {
   if (!aListenerHolder || !aEventMessage || mClearingListeners) {
     return;
   }
 
   Listener* listener;
 
   uint32_t count = mListeners.Length();
-  uint32_t typeCount = 0;
   bool deviceType = IsDeviceType(aEventMessage);
 
   RefPtr<EventListenerManager> kungFuDeathGrip(this);
 
   for (uint32_t i = 0; i < count; ++i) {
     listener = &mListeners.ElementAt(i);
     if (EVENT_TYPE_EQUALS(listener, aEventMessage, aUserType, aTypeString,
                           aAllEvents)) {
-      ++typeCount;
       if (listener->mListener == aListenerHolder &&
           listener->mFlags.EqualsForRemoval(aFlags)) {
         mListeners.RemoveElementAt(i);
-        --count;
         NotifyEventListenerRemoved(aUserType);
-        if (!deviceType) {
-          return;
+        if (!aAllEvents && deviceType) {
+          DisableDevice(aEventMessage);
         }
-        --typeCount;
+        return;
       }
     }
   }
 
-  if (!aAllEvents && deviceType && typeCount == 0) {
-    DisableDevice(aEventMessage);
-  }
 }
 
 bool
 EventListenerManager::ListenerCanHandle(const Listener* aListener,
                                         const WidgetEvent* aEvent,
                                         EventMessage aEventMessage) const
 
 {
@@ -922,16 +916,19 @@ EventListenerManager::RemoveEventHandler
   }
 
   EventMessage eventMessage = nsContentUtils::GetEventMessage(aName);
   Listener* listener = FindEventHandler(eventMessage, aName, aTypeString);
 
   if (listener) {
     mListeners.RemoveElementAt(uint32_t(listener - &mListeners.ElementAt(0)));
     NotifyEventListenerRemoved(aName);
+    if (IsDeviceType(eventMessage)) {
+      DisableDevice(eventMessage);
+    }
   }
 }
 
 nsresult
 EventListenerManager::CompileEventHandlerInternal(Listener* aListener,
                                                   const nsAString* aBody,
                                                   Element* aElement)
 {
--- a/dom/events/test/test_bug742376.html
+++ b/dom/events/test/test_bug742376.html
@@ -26,35 +26,49 @@ function hasListeners() {
          dss.hasWindowListener(Ci.nsIDeviceSensorData.TYPE_ROTATION_VECTOR, window) ||
          dss.hasWindowListener(Ci.nsIDeviceSensorData.TYPE_GAME_ROTATION_VECTOR, window);
 }
 
 is(hasListeners(), false, "Must not have listeners before tests start");
 
 function dumbListener(event) {}
 function dumbListener2(event) {}
+function dumbListener3(event) {}
 
 window.addEventListener("deviceorientation", dumbListener, false);
+window.addEventListener("random_event_name", function() {}, false);
 window.addEventListener("deviceorientation", dumbListener2, false);
 
 is(hasListeners(), true, "Listeners should have been added");
 
 window.setTimeout(function() {
 
   window.removeEventListener("deviceorientation", dumbListener, false);
   is(hasListeners(), true, "Only some listeners should have been removed");
   window.setTimeout(function() {
 
     window.removeEventListener("deviceorientation", dumbListener2, false);
     window.setTimeout(function() {
       is(hasListeners(), false, "Listeners should have been removed");
-      SimpleTest.finish();
+      testEventHandler();
     }, 0);
   }, 0);
 }, 0);
 
+function testEventHandler() {
+  window.ondeviceorientation = function() {}
+  window.setTimeout(function() {
+    is(hasListeners(), true, "Handler should have been added");
+    window.ondeviceorientation = null;
+    window.setTimeout(function() {
+      is(hasListeners(), false, "Handler should have been removed");
+      SimpleTest.finish();
+    }, 0);
+  }, 0)
+}
+
 SimpleTest.waitForExplicitFinish();
 
 </script>
 </pre>
 </body>
 </html>