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 357240 2c34737c57e5f47d981d79eacb447732b90dbb29
parent 357230 82d0a583a9a39bf0b0000bccbf6d5c9ec2596bcc
child 357241 805d466424e474ca3c984202449c0a08031c325b
push id1324
push usermtabara@mozilla.com
push dateMon, 16 Jan 2017 13:07:44 +0000
treeherdermozilla-release@a01c49833940 [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>