[Pkg-mozext-commits] [requestpolicy] 239/257: [ref] WindowListener --> "Windows" model

David Prévot taffit at moszumanska.debian.org
Thu Jan 28 03:20:17 UTC 2016


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

taffit pushed a commit to branch master
in repository requestpolicy.

commit a480b76e4cf190727b40503cc5a6dec2d2d35d8f
Author: Martin Kimmerle <dev at 256k.de>
Date:   Wed Dec 23 20:24:09 2015 +0100

    [ref] WindowListener --> "Windows" model
---
 src/content/main/window-manager.jsm         |  36 +-----
 src/content/main/window-manager.listener.js | 152 ----------------------
 src/content/models/windows.jsm              | 190 ++++++++++++++++++++++++++++
 3 files changed, 197 insertions(+), 181 deletions(-)

diff --git a/src/content/main/window-manager.jsm b/src/content/main/window-manager.jsm
index 4f5a526..4f14325 100644
--- a/src/content/main/window-manager.jsm
+++ b/src/content/main/window-manager.jsm
@@ -27,28 +27,16 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 /* exported rpWindowManager */
 this.EXPORTED_SYMBOLS = ["rpWindowManager"];
 
-let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
-
 let {ScriptLoader: {importModule}} = Cu.import(
     "chrome://rpcontinued/content/lib/script-loader.jsm", {});
 let {Environment, ProcessEnvironment} = importModule("lib/environment");
+let {Windows} = importModule("models/windows");
 let {OverlayController} = importModule("controllers/windows.overlay");
 let {ToolbarButtonController} = importModule(
     "controllers/windows.toolbarbutton");
 let {StyleSheetsController} = importModule("controllers/windows.style-sheets");
 
 //==============================================================================
-// WindowListener
-//==============================================================================
-
-let WindowListener = (function() {
-  let scope = {};
-  Services.scriptloader.loadSubScript(
-      "chrome://rpcontinued/content/main/window-manager.listener.js", scope);
-  return scope.WindowListener;
-}());
-
-//==============================================================================
 // WindowSubControllers
 //==============================================================================
 
@@ -105,11 +93,10 @@ var rpWindowManager = (function() {
       Environment.LEVELS.INTERFACE,
       function(data, reason) {
         WindowSubControllers.startup();
-        forEachOpenWindow(loadIntoWindow);
-
-        WindowListener.setLoadFunction(loadIntoWindow);
-        WindowListener.setUnloadFunction(unloadFromWindow);
-        WindowListener.startListening();
+        Windows.forEachOpenWindow(loadIntoWindow);
+        Windows.addListener("load", loadIntoWindow);
+        Windows.addListener("unload", unloadFromWindow);
+        Windows._startListening();
 
         // Load the framescript into all existing tabs.
         // Also tell the globalMM to load it into each new
@@ -135,19 +122,10 @@ var rpWindowManager = (function() {
             .getService(Ci.nsIMessageListenerManager);
         globalMM.removeDelayedFrameScript(frameScriptURI);
 
-        forEachOpenWindow(unloadFromWindow);
+        Windows._stopListening();
+        Windows.forEachOpenWindow(unloadFromWindow);
         WindowSubControllers.shutdown();
-
-        WindowListener.stopListening();
       });
 
-  function forEachOpenWindow(functionToCall) {
-    // Apply a function to all open browser windows
-    let windows = Services.wm.getEnumerator("navigator:browser");
-    while (windows.hasMoreElements()) {
-      functionToCall(windows.getNext().QueryInterface(Ci.nsIDOMWindow));
-    }
-  }
-
   return self;
 }());
diff --git a/src/content/main/window-manager.listener.js b/src/content/main/window-manager.listener.js
deleted file mode 100644
index 4f732d5..0000000
--- a/src/content/main/window-manager.listener.js
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * ***** BEGIN LICENSE BLOCK *****
- *
- * RequestPolicy - A Firefox extension for control over cross-site requests.
- * Copyright (c) 2008-2012 Justin Samuel
- * Copyright (c) 2014-2015 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 {tag: "http"://www.gnu.org/licenses}.
- *
- * ***** END LICENSE BLOCK *****
- */
-
-/* global Components */
-const {interfaces: Ci, utils: Cu} = Components;
-
-/* exported WindowListener */
-
-let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
-
-//==============================================================================
-// WindowListener
-//==============================================================================
-
-var WindowListener = (function() {
-  let self = {};
-
-  let nextWinID = 0;
-  let listeners = {};
-
-  let addEvLis = function(eventName, winID) {
-    if (typeof listeners[winID] !== "undefined" &&
-        listeners[winID][eventName] !== null) {
-      listeners[winID].window.addEventListener(eventName,
-                                               listeners[winID][eventName],
-                                               false);
-    }
-  };
-
-  let removeEvLis = function(eventName, winID) {
-    if (typeof listeners[winID] !== "undefined" &&
-        listeners[winID][eventName] !== null) {
-      listeners[winID].window.removeEventListener(eventName,
-                                                  listeners[winID][eventName]);
-      if (eventName === "unload") {
-        // when removing the 'unload' listener, also remove the 'load'
-        // listener and then delete listener[winID].
-        removeEvLis("load", winID);
-        // cleaning up -- listeners[winID] is not needed anymore
-        delete listeners[winID];
-      }
-    }
-  };
-
-  // external functions to be called on "load" or "unload" events
-  let externalLoadFunction = null;
-  let externalUnloadFunction = null;
-  self.setLoadFunction = function(f) {
-    externalLoadFunction = f;
-  };
-  self.setUnloadFunction = function(f) {
-    externalUnloadFunction = f;
-  };
-
-  let addEventListenersToWindow = function(window) {
-    let winID = nextWinID++;
-
-    // ===========================
-    // create new functions specific for each window.
-    // ----------------------------------------------
-    let onLoad = function(event) {
-      removeEvLis("load", winID);
-
-      if (window.document.documentElement.getAttribute("windowtype") ===
-          "navigator:browser") {
-        if (!!externalLoadFunction) {
-          externalLoadFunction(window);
-        }
-      } else {
-        removeEvLis("unload", winID);
-      }
-    };
-    let onUnload = function(event) {
-      removeEvLis("unload", onUnload);
-
-      if (window.document.documentElement.getAttribute("windowtype") ===
-          "navigator:browser") {
-        if (!!externalUnloadFunction) {
-          externalUnloadFunction(window);
-        }
-      }
-    };
-    // ===========================
-
-    listeners[winID] = {window: window, load: onLoad, unload: onUnload};
-
-    // Event handler for when the window is closed. We listen for "unload"
-    // rather than "close" because "close" will fire when a print preview
-    // opened from this window is closed.
-    addEvLis("unload", winID);
-
-    // Registers event handlers for documents loaded in the window.
-    addEvLis("load", winID);
-
-    return winID;
-  };
-
-  function removeAllEventListeners() {
-    for (let winID in listeners) {
-      removeEvLis("load", winID);
-      removeEvLis("unload", winID);
-    }
-    listeners = {};
-    nextWinID = 0;
-  }
-
-  let listening = false;
-  self.startListening = function() {
-    if (listening === false) {
-      Services.wm.addListener(WindowListener);
-      listening = true;
-    }
-  };
-  self.stopListening = function() {
-    if (listening === true) {
-      Services.wm.removeListener(WindowListener);
-      listening = false;
-    }
-    // remove all "load" and "unload" event listeners.
-    removeAllEventListeners();
-  };
-
-  self.onOpenWindow = function(xulWindow) {
-    let window = xulWindow.QueryInterface(Ci.nsIInterfaceRequestor)
-        .getInterface(Ci.nsIDOMWindow);
-    addEventListenersToWindow(window);
-  };
-  self.onCloseWindow = function(xulWindow) {};
-  self.onWindowTitleChange = function(xulWindow, newTitle) {};
-
-  return self;
-}());
diff --git a/src/content/models/windows.jsm b/src/content/models/windows.jsm
new file mode 100644
index 0000000..063f66d
--- /dev/null
+++ b/src/content/models/windows.jsm
@@ -0,0 +1,190 @@
+/*
+ * ***** BEGIN LICENSE BLOCK *****
+ *
+ * RequestPolicy - A Firefox extension for control over cross-site requests.
+ * Copyright (c) 2008-2012 Justin Samuel
+ * Copyright (c) 2014-2015 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 {tag: "http"://www.gnu.org/licenses}.
+ *
+ * ***** END LICENSE BLOCK *****
+ */
+
+/* global Components */
+const {interfaces: Ci, utils: Cu} = Components;
+
+/* exported Windows */
+this.EXPORTED_SYMBOLS = ["Windows"];
+
+let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
+
+let {ScriptLoader: {importModule}} = Cu.import(
+    "chrome://rpcontinued/content/lib/script-loader.jsm", {});
+let {MapOfSets} = importModule("lib/classes/map-of-sets");
+
+//==============================================================================
+// LoadAndUnloadListener
+//==============================================================================
+
+function LoadAndUnloadListener(callback) {
+  let windows = new Set();
+
+  function _onEvent(event) {
+    let document = event.target;
+    let window = document.defaultView;
+
+    let windowtype = document.documentElement.getAttribute("windowtype");
+    if (windowtype !== "navigator:browser") {
+      // stop listening on this window
+      _removeEventListener("load", window);
+      _removeEventListener("unload", window);
+      windows.delete(window);
+      return;
+    }
+
+    switch (event.type) {
+      case "load": {
+        _removeEventListener("load", window);
+        _addEventListener("unload", window);
+        callback.call(null, "load", window);
+        break;
+      }
+
+      case "unload": {
+        _removeEventListener("unload", window);
+        windows.delete(window);
+        callback.call(null, "unload", window);
+        break;
+      }
+
+      default:
+        break;
+    }
+  }
+
+  function _addEventListener(eventName, window) {
+    window.addEventListener(eventName, _onEvent, false);
+  }
+
+  function _removeEventListener(eventName, window) {
+    window.removeEventListener(eventName, _onEvent);
+  }
+
+  this.listenTo = function(eventName, window) {
+    if (eventName !== "load" && eventName !== "unload") {
+      throw "incorrect event type!";
+    }
+    windows.add(window);
+    _addEventListener(eventName, window);
+  };
+
+  this.stopListeningOnAllWindows = function() {
+    for (let window of windows.values()) {
+      _removeEventListener("load", window);
+      _removeEventListener("unload", window);
+      windows.delete(window);
+    }
+    windows.clear();
+  };
+}
+
+//==============================================================================
+// Windows
+//==============================================================================
+
+var Windows = (function() {
+  let self = {};
+
+  self.forEachOpenWindow = function(aCallback) {
+    // Apply a function to all open browser windows
+    let windows = Services.wm.getEnumerator("navigator:browser");
+    while (windows.hasMoreElements()) {
+      let window = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
+      aCallback.call(null, window);
+    }
+  };
+
+  return self;
+}());
+
+//==============================================================================
+// Windows (listening functionality)
+//==============================================================================
+
+(function(self) {
+  let topicsToListeners = new MapOfSets();
+
+  function onEvent(eventType, window) {
+    if (topicsToListeners.has(eventType)) {
+      let listeners = topicsToListeners.get(eventType);
+      for (let listener of listeners.values()) {
+        listener.call(null, window);
+      }
+    }
+  }
+
+  let loadAndUnloadListener = new LoadAndUnloadListener(onEvent);
+
+  let windowMediatorListener = {
+    onOpenWindow: function(xulWindow) {
+      let window = xulWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+          .getInterface(Ci.nsIDOMWindow);
+      loadAndUnloadListener.listenTo("load", window);
+    },
+    onCloseWindow: function(xulWindow) {},
+    onWindowTitleChange: function(xulWindow, newTitle) {}
+  };
+
+  //----------------------------------------------------------------------------
+  // exported functions
+  //----------------------------------------------------------------------------
+
+  self.addListener = function(aEventType, aListener) {
+    if (aEventType !== "load" && aEventType !== "unload") {
+      throw "incorrect event type!";
+    }
+    topicsToListeners.addToSet(aEventType, aListener);
+  };
+
+  self.removeListener = function(aEventType, aListener) {
+    topicsToListeners.deleteFromSet(aEventType, aListener);
+  };
+
+  //----------------------------------------------------------------------------
+  // bootstrap functions, called by the controller
+  //----------------------------------------------------------------------------
+
+  let listening = false;
+
+  self._startListening = function() {
+    if (listening === false) {
+      Services.wm.addListener(windowMediatorListener);
+      listening = true;
+
+      self.forEachOpenWindow(function(window) {
+        loadAndUnloadListener.listenTo("unload", window);
+      });
+    }
+  };
+
+  self._stopListening = function() {
+    if (listening === true) {
+      Services.wm.removeListener(windowMediatorListener);
+      listening = false;
+      loadAndUnloadListener.stopListeningOnAllWindows();
+    }
+  };
+
+  return self;
+}(Windows));

-- 
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