Bug 961793 - unregister observers in BrowserElementPanning.js at global unload; r=fabrice
authorNathan Froyd <froydnj@mozilla.com>
Wed, 22 Jan 2014 16:55:42 -0500
changeset 180853 b10b085ab73c804f01f38fd150d95bb0314115c7
parent 180852 cd9d8ef6c3efcc996039ecc0669a7f7665fd4461
child 180854 d97cb0a0873a4843919f1d3a26bd58d6ccb740b9
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfabrice
bugs961793
milestone29.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 961793 - unregister observers in BrowserElementPanning.js at global unload; r=fabrice
dom/browser-element/BrowserElementPanning.js
--- a/dom/browser-element/BrowserElementPanning.js
+++ b/dom/browser-element/BrowserElementPanning.js
@@ -9,16 +9,22 @@
 dump("############################### browserElementPanning.js loaded\n");
 
 let { classes: Cc, interfaces: Ci, results: Cr, utils: Cu }  = Components;
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Geometry.jsm");
 
 var global = this;
 
+const kObservedEvents = [
+  "BEC:ShownModalPrompt",
+  "Activity:Success",
+  "Activity:Error"
+];
+
 const ContentPanning = {
   // Are we listening to touch or mouse events?
   watchedEventsType: '',
 
   // Are mouse events being delivered to this content along with touch
   // events, in violation of spec?
   hybridEvents: false,
 
@@ -50,22 +56,27 @@ const ContentPanning = {
     events.forEach(function(type) {
       // Using the system group for mouse/touch events to avoid
       // missing events if .stopPropagation() has been called.
       els.addSystemEventListener(global, type,
                                  this.handleEvent.bind(this),
                                  /* useCapture = */ false);
     }.bind(this));
 
+    addEventListener("unload",
+		     this._unloadHandler.bind(this),
+		     /* useCapture = */ false,
+		     /* wantsUntrusted = */ false);
+
     addMessageListener("Viewport:Change", this._recvViewportChange.bind(this));
     addMessageListener("Gesture:DoubleTap", this._recvDoubleTap.bind(this));
     addEventListener("visibilitychange", this._handleVisibilityChange.bind(this));
-    Services.obs.addObserver(this, "BEC:ShownModalPrompt", false);
-    Services.obs.addObserver(this, "Activity:Success", false);
-    Services.obs.addObserver(this, "Activity:Error", false);
+    kObservedEvents.forEach((topic) => {
+      Services.obs.addObserver(this, topic, false);
+    });
   },
 
   handleEvent: function cp_handleEvent(evt) {
     this._tryDelayMouseEvents();
 
     if (evt.defaultPrevented || evt.multipleActionsPrevented) {
       // clean up panning state even if touchend/mouseup has been preventDefault.
       if(evt.type === 'touchend' || evt.type === 'mouseup') {
@@ -591,16 +602,22 @@ const ContentPanning = {
     delete this.primaryPointerId;
     this._activationTimer.cancel();
 
     // If there is a scroll action but the application is not managed by
     // the AsyncPanZoom controller, let's do a manual kinetic panning action.
     if (this.panning && docShell.asyncPanZoomEnabled === false) {
       KineticPanning.start(this);
     }
+  },
+
+  _unloadHandler: function() {
+    kObservedEvents.forEach((topic) => {
+      Services.obs.removeObserver(this, topic);
+    });
   }
 };
 
 // Min/max velocity of kinetic panning. This is in pixels/millisecond.
 const kMinVelocity = 0.2;
 const kMaxVelocity = 6;
 
 // Constants that affect the "friction" of the scroll pane.