[Pkg-mozext-commits] [requestpolicy] 97/280: add ObserverManager module and use it

David Prévot taffit at moszumanska.debian.org
Sat May 2 20:30:05 UTC 2015


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository requestpolicy.

commit a68376a9db44fa26a8c6c545425d5dd09a6ef273
Author: Martin Kimmerle <dev at 256k.de>
Date:   Thu Jan 1 23:00:10 2015 +0100

    add ObserverManager module and use it
---
 src/content/lib/observer-manager.js            | 133 +++++++++++++++++++++----
 src/content/lib/observer-manager.jsm           |  39 ++++++++
 src/content/lib/request-processor.redirects.js |  33 ++----
 src/content/lib/requestpolicy-service.jsm      |  26 ++---
 src/content/lib/utils.jsm                      |  17 ----
 src/content/settings/subscriptions.js          |   4 +-
 src/content/settings/yourpolicy.js             |  11 +-
 7 files changed, 177 insertions(+), 86 deletions(-)

diff --git a/src/content/lib/observer-manager.js b/src/content/lib/observer-manager.js
index bae6e34..22f34a0 100644
--- a/src/content/lib/observer-manager.js
+++ b/src/content/lib/observer-manager.js
@@ -21,43 +21,132 @@
  * ***** END LICENSE BLOCK *****
  */
 
-var ObserverManager = (function() {
-  var self = {};
 
-  // an object holding all observers for unregistering when unloading the page
-  var observers = [];
+/**
+ * The ObserverManager provides an interface to `nsIObserverService` which takes
+ * care of unregistering the observed topics.
+ * There are two ways how to get an instance of this manager.
+ *   (a) if the topics should be observed only as long as a DOM Window lives,
+ *       then this *.js file should be loaded **directly** into that window.
+ *   (b) if the topics should be observed as long as RP is activated, then the
+ *       **module** `observer-manager.jsm` has to be used instead.
+ *
+ * Note that when this file is loaded directly (case (a)), the ObserverManager
+ * is created only once, i.e. if it is not existant yet!
+ */
+var ObserverManager = ObserverManager || (function() {
+  let self = {};
 
-  function Observer(aTopic, aFunctionToCall) {
+
+  const Ci = Components.interfaces;
+  const Cc = Components.classes;
+  const Cu = Components.utils;
+
+  let ScriptLoader;
+  {
+    let mod = {};
+    Cu.import("chrome://requestpolicy/content/lib/script-loader.jsm", mod);
+    ScriptLoader = mod.ScriptLoader;
+  }
+  let {isMainProcess} = ScriptLoader.importModule("utils/process-info");
+  let {Logger} = ScriptLoader.importModule("logger");
+
+
+
+  /**
+   * This Object registers itself to `nsIObserverService` on behalf of some other
+   * object. The `observe` function called by `nsIObserverService` is handed over
+   * by the *real* observer.
+   */
+  function SingleTopicObserver(aTopic, aFunctionToCall) {
+    // save the parameters
     this.topic = aTopic;
     this.observe = aFunctionToCall;
+
+    // currently this obserer is not rgistered yet
+    this.isRegistered = false;
+
+    // register this observer
     this.register();
-    observers.push(this);
   }
-  Observer.prototype.register = function() {
-    Services.obs.addObserver(this, this.topic, false);
+  SingleTopicObserver.prototype.register = function() {
+    if (!this.isRegistered) {
+      Services.obs.addObserver(this, this.topic, false);
+      this.isRegistered = true;
+    }
   };
-  Observer.prototype.unregister = function() {
-    Services.obs.removeObserver(this, this.topic);
+  SingleTopicObserver.prototype.unregister = function() {
+    if (this.isRegistered) {
+      Services.obs.removeObserver(this, this.topic);
+      this.isRegistered = false;
+    }
   };
 
 
-  let unregisterObservers = function(event) {
-    while (observers.length > 0) {
-      var observer = observers.pop();
-      Logger.dump("Unregistering observer for topic " + observer.topic);
-      observer.unregister();
+  // an object holding all observers for unregistering when unloading the page
+  let observers = [];
+
+  /**
+   * This function can be called from anywhere; the caller hands over an object
+   * with the keys being the *topic* and the values being the function that
+   * should be called when the topic is observed.
+   */
+  self.observe = function(aList) {
+    for (let topic in aList) {
+      if (aList.hasOwnProperty(topic)) {
+        observers.push(new SingleTopicObserver(topic, aList[topic]));
+      }
     }
   };
-  // unregister all observers before the window is unloaded
-  window.addEventListener("unload", unregisterObservers);
 
+  self.observePrefChanges = self.observe.bind(self,
+      "requestpolicy-prefs-changed");
 
-  self.observe = function(aTopic, aFunctionToCall) {
-    return new Observer(aTopic, aFunctionToCall);
-  };
 
-  self.observePrefChanges = self.observe.bind(this,
-      "requestpolicy-prefs-changed");
+  //
+  // The following section is about unregistering the observers.
+  //
+  {
+    /**
+     * This function unregisters all registered observers. It will be called
+     * before the obserers and their enironment is destroyed, see below.
+     */
+    let unregisterObservers = function(event) {
+      while (observers.length > 0) {
+        let observer = observers.pop();
+        Logger.dump("Unregistering observer for topic " + observer.topic);
+        observer.unregister();
+      }
+    };
+
+    // Now it's necessary to detect the environment. Two possibilities:
+    // (a) Either the script has been loaded directly into a window's scope
+    // (b) or it has been loaded by a *.jsm file.
+    //
+    // In case (a) the Observers will be unregistered at the window's `unload`, in
+    // the other case this will happen on RP shutdown.
+    if (typeof content !== 'undefined') {
+      // case (a), a `content` object exists
+      // (see https://developer.mozilla.org/en-US/docs/Web/API/window.content)
+      content.addEventListener("unload", unregisterObservers);
+    } else {
+      // case (b)
+
+      // if: Is this a child process or the main process?
+      if (!isMainProcess) {
+        Logger.warning(Logger.TYPE_INTERNAL, "It won't be possible to " +
+                       "unregister the observers; this is a child process, " +
+                       "so there has to be a `content` object in " +
+                       "ObserverManager's environment, but there is no " +
+                       "`content` object!",
+                       new Error());
+      } else {
+        // it's the main process
+        let {BootstrapManager} = ScriptLoader.importModule("bootstrap-manager");
+        BootstrapManager.registerShutdownFunction(unregisterObservers);
+      }
+    }
+  }
 
   return self;
 }());
diff --git a/src/content/lib/observer-manager.jsm b/src/content/lib/observer-manager.jsm
new file mode 100644
index 0000000..8154a6e
--- /dev/null
+++ b/src/content/lib/observer-manager.jsm
@@ -0,0 +1,39 @@
+/*
+ * ***** BEGIN LICENSE BLOCK *****
+ *
+ * RequestPolicy - A Firefox extension for control over cross-site requests.
+ * Copyright (c) 2008-2012 Justin Samuel
+ * Copyright (c) 2014 Martin Kimmerle
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LICENSE BLOCK *****
+ */
+
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+const Cu = Components.utils;
+
+let EXPORTED_SYMBOLS = ["ObserverManager"];
+
+Cu.import("resource://gre/modules/Services.jsm");
+
+// create the ObserverManager's scope
+let obmanScope = {};
+
+// load ObserverManager
+Services.scriptloader.loadSubScript(
+    "chrome://requestpolicy/content/lib/observer-manager.js", obmanScope);
+
+let ObserverManager = obmanScope.ObserverManager;
diff --git a/src/content/lib/request-processor.redirects.js b/src/content/lib/request-processor.redirects.js
index 51d9c89..3c42479 100644
--- a/src/content/lib/request-processor.redirects.js
+++ b/src/content/lib/request-processor.redirects.js
@@ -35,7 +35,8 @@ ScriptLoader.importModules([
   "utils",
   "request",
   "request-result",
-  "http-response"
+  "http-response",
+  "observer-manager"
 ], this);
 ScriptLoader.defineLazyModuleGetters({
   "requestpolicy-service": ["rpService"]
@@ -57,30 +58,14 @@ let RequestProcessor = (function(self) {
 
 
 
-  Utils.observeNotifications(
-    // the observer
-    {
-      observe: function(subject, topic, data) {
-        switch (topic) {
-          case "http-on-examine-response":
-            examineHttpResponse(subject);
-            break;
-
-          case HTTPS_EVERYWHERE_REWRITE_TOPIC:
-            handleHttpsEverywhereUriRewrite(subject, data);
-            break;
-        }
-      }
+  ObserverManager.observe({
+    "http-on-examine-response": function(subject) {
+      examineHttpResponse(subject);
     },
-    // observer topics
-    [
-      "http-on-examine-response",
-      HTTPS_EVERYWHERE_REWRITE_TOPIC
-    ]
-  );
-
-
-
+    HTTPS_EVERYWHERE_REWRITE_TOPIC: function(subject, topic, data) {
+      handleHttpsEverywhereUriRewrite(subject, data);
+    }
+  });
 
 
 
diff --git a/src/content/lib/requestpolicy-service.jsm b/src/content/lib/requestpolicy-service.jsm
index 81e8ba6..d6e77a6 100644
--- a/src/content/lib/requestpolicy-service.jsm
+++ b/src/content/lib/requestpolicy-service.jsm
@@ -42,7 +42,8 @@ ScriptLoader.importModules([
   "utils",
   "content-policy",
   "constants",
-  "bootstrap-manager"
+  "bootstrap-manager",
+  "observer-manager"
 ], this);
 
 
@@ -382,25 +383,18 @@ let rpService = (function() {
   }
 
   function register() {
-    let obs = Services.obs;
-    obs.addObserver(self, "http-on-modify-request", false);
-    obs.addObserver(self, "sessionstore-windows-restored", false);
-    obs.addObserver(self, "private-browsing", false);
-    obs.addObserver(self, SUBSCRIPTION_UPDATED_TOPIC, false);
-    obs.addObserver(self, SUBSCRIPTION_ADDED_TOPIC, false);
-    obs.addObserver(self, SUBSCRIPTION_REMOVED_TOPIC, false);
-
+    ObserverManager.observe({
+      "http-on-modify-request": self.observe,
+      "sessionstore-windows-restored": self.observe,
+      "private-browsing": self.observe,
+      SUBSCRIPTION_UPDATED_TOPIC: self.observe,
+      SUBSCRIPTION_ADDED_TOPIC: self.observe,
+      SUBSCRIPTION_REMOVED_TOPIC: self.observe
+    });
     AddonManager.addAddonListener(addonListener);
   }
 
   function unregister() {
-    let obs = Services.obs;
-    obs.removeObserver(self, "http-on-modify-request");
-    obs.removeObserver(self, "sessionstore-windows-restored");
-    obs.removeObserver(self, SUBSCRIPTION_UPDATED_TOPIC);
-    obs.removeObserver(self, SUBSCRIPTION_ADDED_TOPIC);
-    obs.removeObserver(self, SUBSCRIPTION_REMOVED_TOPIC);
-
     AddonManager.removeAddonListener(addonListener);
   }
 
diff --git a/src/content/lib/utils.jsm b/src/content/lib/utils.jsm
index dc3adde..447cb14 100644
--- a/src/content/lib/utils.jsm
+++ b/src/content/lib/utils.jsm
@@ -151,23 +151,6 @@ let Utils = (function() {
 
 
 
-  self.observeNotifications = function(observer, observerTopics) {
-    BootstrapManager.registerStartupFunction(function() {
-      for (let i = 0, len = observerTopics.length; i < len; ++i) {
-        Services.obs.addObserver(observer, observerTopics[i], false);
-      }
-    });
-    BootstrapManager.registerShutdownFunction(function(data, reason) {
-      for (let i = 0, len = observerTopics.length; i < len; ++i) {
-        Services.obs.removeObserver(observer, observerTopics[i], false);
-      }
-    });
-  };
-  self.unregisterObservers = function(observer, observerTopics) {
-  };
-
-
-
   /**
    * This function returns and eventually creates a module's `internal`
    * variable. The `internal` can be accessed from all submodules of that
diff --git a/src/content/settings/subscriptions.js b/src/content/settings/subscriptions.js
index cb08a8a..379811e 100644
--- a/src/content/settings/subscriptions.js
+++ b/src/content/settings/subscriptions.js
@@ -135,6 +135,6 @@ function onload() {
   }
 
   // call updateDisplay() every time a subscription is added or removed
-  ObserverManager.observe(SUBSCRIPTION_ADDED_TOPIC, updateDisplay);
-  ObserverManager.observe(SUBSCRIPTION_REMOVED_TOPIC, updateDisplay);
+  ObserverManager.observe({SUBSCRIPTION_ADDED_TOPIC: updateDisplay});
+  ObserverManager.observe({SUBSCRIPTION_REMOVED_TOPIC: updateDisplay});
 }
diff --git a/src/content/settings/yourpolicy.js b/src/content/settings/yourpolicy.js
index a8bf84b..3776639 100644
--- a/src/content/settings/yourpolicy.js
+++ b/src/content/settings/yourpolicy.js
@@ -230,9 +230,10 @@ function onload() {
   }
 
   // observe rule changes and update the table then
-  ObserverManager.observe("requestpolicy-rules-changed",
-      function(subject, topic, data) {
-        var search = document.getElementById('rulesearch');
-        populateRuleTable(search.value);
-      });
+  ObserverManager.observe({
+    "requestpolicy-rules-changed": function(subject, topic, data) {
+      var search = document.getElementById('rulesearch');
+      populateRuleTable(search.value);
+    }
+  });
 }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/requestpolicy.git



More information about the Pkg-mozext-commits mailing list