Bug 961106 - Remove observers on frame script unload r=billm a=gavin
authorTim Taubert <ttaubert@mozilla.com>
Sat, 18 Jan 2014 00:47:58 +0100
changeset 175984 223f3962a4bffec3d2f40a504f4a2491320463dd
parent 175983 31da64bcc970f21938054aa8c73f0bd341f6f743
child 175985 e2600ecd9a9eb97a6a4dcd70e103e67c0dafdd3a
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm, gavin
bugs961106
milestone28.0a2
Bug 961106 - Remove observers on frame script unload r=billm a=gavin
browser/components/sessionstore/content/content-sessionStore.js
--- a/browser/components/sessionstore/content/content-sessionStore.js
+++ b/browser/components/sessionstore/content/content-sessionStore.js
@@ -203,28 +203,30 @@ let ProgressListener = {
  * selected or author styles are enabled/disabled we send a message with the
  * currently applied style to the chrome process.
  *
  * Causes a SessionStore:update message to be sent that contains the currently
  * selected pageStyle, if any. The pageStyle is represented by a string.
  */
 let PageStyleListener = {
   init: function () {
-    Services.obs.addObserver(this, "author-style-disabled-changed", true);
-    Services.obs.addObserver(this, "style-sheet-applicable-state-changed", true);
+    Services.obs.addObserver(this, "author-style-disabled-changed", false);
+    Services.obs.addObserver(this, "style-sheet-applicable-state-changed", false);
+  },
+
+  uninit: function () {
+    Services.obs.removeObserver(this, "author-style-disabled-changed");
+    Services.obs.removeObserver(this, "style-sheet-applicable-state-changed");
   },
 
   observe: function (subject, topic) {
     if (subject.defaultView && subject.defaultView.top == content) {
       MessageQueue.push("pageStyle", () => PageStyle.collect(docShell) || null);
     }
-  },
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
-                                         Ci.nsISupportsWeakReference])
+  }
 };
 
 /**
  * Listens for changes to docShell capabilities. Whenever a new load is started
  * we need to re-check the list of capabilities and send message when it has
  * changed.
  *
  * Causes a SessionStore:update message to be sent that contains the currently
@@ -278,18 +280,23 @@ let DocShellCapabilitiesListener = {
  *
  * Causes a SessionStore:update message to be sent that contains the current
  * DOMSessionStorage contents. The data is a nested object using host names
  * as keys and per-host DOMSessionStorage data as values.
  */
 let SessionStorageListener = {
   init: function () {
     addEventListener("MozStorageChanged", this);
-    Services.obs.addObserver(this, "browser:purge-domain-data", true);
-    Services.obs.addObserver(this, "browser:purge-session-history", true);
+    Services.obs.addObserver(this, "browser:purge-domain-data", false);
+    Services.obs.addObserver(this, "browser:purge-session-history", false);
+  },
+
+  uninit: function () {
+    Services.obs.removeObserver(this, "browser:purge-domain-data");
+    Services.obs.removeObserver(this, "browser:purge-session-history");
   },
 
   handleEvent: function (event) {
     // Ignore events triggered by localStorage or globalStorage changes.
     if (isSessionStorageEvent(event)) {
       this.collect();
     }
   },
@@ -297,20 +304,17 @@ let SessionStorageListener = {
   observe: function () {
     // Collect data on the next tick so that any other observer
     // that needs to purge data can do its work first.
     setTimeout(() => this.collect(), 0);
   },
 
   collect: function () {
     MessageQueue.push("storage", () => SessionStorage.collect(docShell));
-  },
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
-                                         Ci.nsISupportsWeakReference])
+  }
 };
 
 /**
  * A message queue that takes collected data and will take care of sending it
  * to the chrome process. It allows flushing using synchronous messages and
  * takes care of any race conditions that might occur because of that. Changes
  * will be batched if they're pushed in quick succession to avoid a message
  * flood.
@@ -456,8 +460,18 @@ let MessageQueue = {
 
 EventListener.init();
 MessageListener.init();
 SyncHandler.init();
 ProgressListener.init();
 PageStyleListener.init();
 SessionStorageListener.init();
 DocShellCapabilitiesListener.init();
+
+addEventListener("unload", () => {
+  // Remove all registered nsIObservers.
+  PageStyleListener.uninit();
+  SessionStorageListener.uninit();
+
+  // We don't need to take care of any gFrameTree observers as the gFrameTree
+  // will die with the content script. The same goes for the privacy transition
+  // observer that will die with the docShell when the tab is closed.
+});