[Pkg-mozext-commits] [requestpolicy] 25/257: [ref] xul-trees, xulutils: use `addEventListener`

David Prévot taffit at moszumanska.debian.org
Thu Jan 28 03:19:53 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 8103d60892e6f04981ebb50849876fc46be962d5
Author: Martin Kimmerle <dev at 256k.de>
Date:   Sun Aug 9 11:35:04 2015 +0200

    [ref] xul-trees, xulutils: use `addEventListener`
    
    All event listeners in the xulTrees will now be registered
    and unregistered via `addEventListener()` and
    `removeEventListener()`.
---
 src/content/lib/utils/xul.jsm       | 172 +++++++++++++++++++++++++++++++++---
 src/content/main/window-manager.jsm |  36 ++++----
 src/content/ui/xul-trees.js         |  64 +++++++-------
 3 files changed, 211 insertions(+), 61 deletions(-)

diff --git a/src/content/lib/utils/xul.jsm b/src/content/lib/utils/xul.jsm
index 639bfb4..f480d61 100644
--- a/src/content/lib/utils/xul.jsm
+++ b/src/content/lib/utils/xul.jsm
@@ -40,15 +40,73 @@ var XULUtils = {};
 
 var xulTrees = XULUtils.xulTrees = {};
 
-var xulTreesScope = {
-  "exports": xulTrees,
-  "C": C,
-  "appID": Services.appinfo.ID
-};
 
-Services.scriptloader.loadSubScript(
-    'chrome://rpcontinued/content/ui/xul-trees.js',
-    xulTreesScope);
+/**
+ * IIFE: Import the XUL trees and ensure their integrity.
+ */
+(function importXulTrees() {
+  var xulTreesScope = {
+    "exports": xulTrees,
+    "C": C,
+    "appID": Services.appinfo.ID
+  };
+
+  Services.scriptloader.loadSubScript(
+      'chrome://rpcontinued/content/ui/xul-trees.js',
+      xulTreesScope);
+
+  // For ensuring that each Element Spec has an ID.
+  var nextID = 1;
+
+  // Call the "ensureIntegrity" function on _all_ element specs
+  // of _all_ trees.
+  for (let treeName in xulTrees) {
+    recursivelyGetAllElementSpecs(xulTrees[treeName]).forEach(ensureIntegrity);
+  }
+
+  function ensureIntegrity(aElementSpec) {
+    // Ensure "attributes" exists.
+    if (!aElementSpec.hasOwnProperty("attributes")) {
+      aElementSpec.attributes = {};
+    }
+
+    // Ensure the Element Spec has an ID attribute.
+    if (!aElementSpec.attributes.hasOwnProperty("id")) {
+      aElementSpec.attributes.id = "rpc-autoid-" + (nextID++);
+      //Logger.dump("Automatically created ID '" + aElementSpec.attributes.id +
+      //            "' for element <" + aElementSpec.tag + ">");
+    }
+  }
+})();
+
+
+/**
+ * @param {Array<Object>} aElementSpecList
+ *
+ * @return {Array<Object>}
+ */
+function recursivelyGetAllElementSpecs(aElementSpecList) {
+  // Create a new array.
+  var allElementSpecs = [];
+
+  for (let elementSpec of aElementSpecList) {
+    if (!elementSpec) {
+      Logger.warning(Logger.TYPE_ERROR, "An element spec is null!");
+      continue;
+    }
+
+    // Add this element spec.
+    allElementSpecs.push(elementSpec);
+
+    // Add all children recursively.
+    if (elementSpec.hasOwnProperty("children")) {
+      let allChildrenSpecs = recursivelyGetAllElementSpecs(elementSpec.children)
+      allElementSpecs = allElementSpecs.concat(allChildrenSpecs);
+    }
+  }
+
+  return allElementSpecs;
+}
 
 
 function getParentElement(aDocument, aElementSpec) {
@@ -104,6 +162,10 @@ function getLocalizedValue(aRawValue) {
   }
 }
 
+/**
+ * @param {Element} aElement
+ * @param {!Object} aElementSpec
+ */
 function setAttributes(aElement, aElementSpec) {
   if (!aElementSpec.hasOwnProperty("attributes")) {
     return;
@@ -116,26 +178,102 @@ function setAttributes(aElement, aElementSpec) {
   }
 }
 
+var {addEventListeners, removeEventListeners} = (function () {
+  /**
+   * @param {!Object} aRootObject
+   * @param {Array<string>} aListenerSpec
+   *
+   * @return {Function} The listener function.
+   */
+  function getEventListener(aRootObject, aListenerSpec) {
+    var object = aRootObject;
+    for (let propertyName of aListenerSpec) {
+      if (!object.hasOwnProperty(propertyName)) {
+        return null;
+      }
+      object = object[propertyName];
+    }
+    return object;
+  }
+
+  /**
+   * @param {Element} aEventTarget
+   * @param {Object} aEventList
+   *
+   * @return {Array}
+   */
+  function getEventInfoList(aEventTarget, aEventList) {
+    if (!aEventList) {
+      return [];
+    }
+    var rootObject = aEventTarget.ownerDocument.defaultView.rpcontinued;
+
+    return Object.keys(aEventList).map(function (eventName) {
+      return [
+        eventName,
+        getEventListener(rootObject, aEventList[eventName])
+      ];
+    });
+  }
+
+  /**
+   * @param {Element} aEventTarget The event target.
+   * @param {!Object} aElementSpec
+   * @param {Object} aElementSpec.events
+   */
+  function addEventListeners(aEventTarget, {events}) {
+    var listeners = getEventInfoList(aEventTarget, events);
+    listeners.forEach(function ([eventName, listener]) {
+      aEventTarget.addEventListener(eventName, listener, false);
+    });
+  }
+
+  function removeEventListeners(aEventTarget, {events}) {
+    var listeners = getEventInfoList(aEventTarget, events);
+    listeners.forEach(function ([eventName, listener]) {
+      aEventTarget.removeEventListener(eventName, listener, false);
+    });
+  }
+
+  return {
+    addEventListeners: addEventListeners,
+    removeEventListeners: removeEventListeners
+  };
+})();
+
 
 function recursivelyAddXULElements(aDocument, aElementSpecList,
                                    aParentElement = null) {
   for (let elementSpec of aElementSpecList) {
     if (!elementSpec || !elementSpec.tag) {
+      Logger.warning(Logger.TYPE_ERROR, "Element spec incomplete!");
       continue;
     }
     let parentElement = !!aParentElement ? aParentElement :
         getParentElement(aDocument, elementSpec);
     if (false === parentElement) {
+      Logger.warning(Logger.TYPE_ERROR, "The parent element could not " +
+                     "be determined. Tag: " + elementSpec.tag + "; " +
+                     "ID: " + elementSpec.attributes.id);
       continue;
     }
     if (parentElement === null) {
       Logger.warning(Logger.TYPE_ERROR,
-                     "parentElement of '" + elementSpec.id + "' is null!");
+                     "parentElement of '" + elementSpec.attributes.id +
+                     "' is null!");
       continue;
     }
 
+    // Create the new element.
     let newElement = aDocument.createElement(elementSpec.tag);
+
+    // Set all attributes.
     setAttributes(newElement, elementSpec);
+
+    // Add all event listeners.
+    addEventListeners(newElement, elementSpec);
+
+    // Recurse.
     if (elementSpec.children) {
       recursivelyAddXULElements(aDocument, elementSpec.children, newElement);
     }
@@ -164,12 +302,22 @@ function getRootElementIDs(aTreeName) {
 
 XULUtils.removeTreeElementsFromWindow = function(aWin, aTreeName) {
   if (!xulTrees.hasOwnProperty(aTreeName)) {
+    Logger.warning(Logger.TYPE_ERROR, "There's no tree with name '" +
+                   aTreeName + "'.");
     return;
   }
-  var elementIDs = getRootElementIDs(aTreeName);
 
-  for (let id of elementIDs) {
-    let node = aWin.document.getElementById(id);
+  var $id = aWin.document.getElementById.bind(aWin.document);
+
+  // Recursively remove all event listeners.
+  for (let elementSpec of recursivelyGetAllElementSpecs(xulTrees[aTreeName])) {
+    let eventTarget = $id(elementSpec.attributes.id);
+    removeEventListeners(eventTarget, elementSpec);
+  }
+
+  // Remove the root elements.
+  for (let id of getRootElementIDs(aTreeName)) {
+    let node = $id(id);
     if (node && node.parentNode) {
       node.parentNode.removeChild(node);
     }
diff --git a/src/content/main/window-manager.jsm b/src/content/main/window-manager.jsm
index d088651..03aca24 100644
--- a/src/content/main/window-manager.jsm
+++ b/src/content/main/window-manager.jsm
@@ -64,24 +64,13 @@ let rpWindowManager = (function(self) {
 
   function loadIntoWindow(window) {
     // ==================================
-    // # 1 : add all XUL elements
-    // --------------------------
-    try {
-      XULUtils.addTreeElementsToWindow(window, "mainTree");
-    } catch (e) {
-      Logger.warning(Logger.TYPE_ERROR,
-                     "Couldn't add tree elements to window. " + e, e);
-    }
-
-
-    // ==================================
-    // # 2 : create a scope variable for RP for this window
+    // # 1 : create a scope variable for RP for this window
     // ----------------------------------------------------
     window.rpcontinued = {};
 
 
     // ==================================
-    // # 3 : load the overlay's and menu's javascript
+    // # 2 : load the overlay's and menu's javascript
     // ----------------------------------------------
     try {
       Services.scriptloader.loadSubScript(
@@ -100,6 +89,17 @@ let rpWindowManager = (function(self) {
 
 
     // ==================================
+    // # 3 : add all XUL elements
+    // --------------------------
+    try {
+      XULUtils.addTreeElementsToWindow(window, "mainTree");
+    } catch (e) {
+      Logger.warning(Logger.TYPE_ERROR,
+                     "Couldn't add tree elements to window. " + e, e);
+    }
+
+
+    // ==================================
     // # 4 : toolbar button
     // --------------------
     try {
@@ -133,15 +133,15 @@ let rpWindowManager = (function(self) {
     self.removeToolbarButtonFromWindow(window);
 
 
-    // # 3 and 2 : remove the `rpcontinued` variable from the window
+    // # 3 : remove all XUL elements
+    XULUtils.removeTreeElementsFromWindow(window, "mainTree");
+
+
+    // # 2 and 1 : remove the `rpcontinued` variable from the window
     // ---------------------------------------------------------
     // This wouldn't be needed when the window is closed, but this has to be
     // done when RP is being disabled.
     delete window.rpcontinued;
-
-
-    // # 1 : remove all XUL elements
-    XULUtils.removeTreeElementsFromWindow(window, "mainTree");
   }
 
 
diff --git a/src/content/ui/xul-trees.js b/src/content/ui/xul-trees.js
index 70aa4b1..7770a78 100644
--- a/src/content/ui/xul-trees.js
+++ b/src/content/ui/xul-trees.js
@@ -61,20 +61,20 @@ exports.mainTree = [
           {
             tag: "menuitem",
             attributes: {label: "&rp.menu.managePolicies;",
-                         accesskey: "m",
-                         oncommand: "rpcontinued.overlay.openPolicyManager();"}
+                         accesskey: "m"},
+            events: {command: ["overlay", "openPolicyManager"]}
           },
           {
             tag: "menuitem",
             attributes: {label: "&rp.requestLog.title;",
-                         accesskey: "l",
-                         oncommand: "rpcontinued.overlay.toggleRequestLog(event);"}
+                         accesskey: "l"},
+            events: {command: ["overlay", "toggleRequestLog"]}
           },
           {
             tag: "menuitem",
             attributes: {label: "&rp.menu.preferences;",
-                         accesskey: "p",
-                         oncommand: "rpcontinued.overlay.openPrefs(event);"}
+                         accesskey: "p"},
+            events: {command: ["overlay", "openPrefs"]}
           }
         ]
       }
@@ -91,8 +91,8 @@ exports.mainTree = [
       {
         tag: "key",
         attributes: {key: "r",
-                     modifiers: "accel alt",
-                     oncommand: "rpcontinued.overlay.openMenuByHotkey()"}
+                     modifiers: "accel alt"},
+        events: {command: ["overlay", "openMenuByHotkey"]}
       }
     ]
   },
@@ -111,9 +111,9 @@ exports.mainTree = [
         tag: "menupopup",
         attributes: {id: "rpc-popup",
                      noautohide: "true",
-                     position: "after_start",
-                     onpopupshowing: "rpcontinued.overlay.onPopupShowing(event);",
-                     onpopuphidden: "rpcontinued.overlay.onPopupHidden(event);"},
+                     position: "after_start"},
+        events: {popupshowing: ["overlay", "onPopupShowing"],
+                 popuphidden: ["overlay", "onPopupHidden"]},
         children: [
           {
             tag: "vbox",
@@ -131,8 +131,8 @@ exports.mainTree = [
                       {
                         tag: "hbox",
                         attributes: {id: "rpc-origin",
-                                     "class": "rpc-od-item",
-                                     onclick: "rpcontinued.menu.itemSelected(event);"},
+                                     "class": "rpc-od-item"},
+                        events: {click: ["menu", "itemSelected"]},
                         children: [
                           {
                             tag: "label",
@@ -233,8 +233,8 @@ exports.mainTree = [
                 children: [
                   {
                     tag: "label",
-                    attributes: {value: "&rp.menu.revokeTemporaryPermissions;",
-                                 onclick: "rpcontinued.overlay.revokeTemporaryPermissions();"}
+                    attributes: {value: "&rp.menu.revokeTemporaryPermissions;"},
+                    events: {click: ["overlay", "revokeTemporaryPermissions"]}
                   }
                 ]
               },
@@ -251,38 +251,40 @@ exports.mainTree = [
                         tag: "label",
                         attributes: {id: "rpc-link-enable-blocking",
                                      "class": "rpc-footer-link",
-                                     value: "&rp.menu.enableBlocking;",
-                                     onclick: "rpcontinued.overlay.toggleTemporarilyAllowAll();"}
+                                     value: "&rp.menu.enableBlocking;"},
+                        events: {click: ["overlay",
+                                         "toggleTemporarilyAllowAll"]}
                       }, {
                         tag: "label",
                         attributes: {id: "rpc-link-disable-blocking",
                                      "class": "rpc-footer-link",
-                                     value: "&rp.menu.disableBlocking;",
-                                     onclick: "rpcontinued.overlay.toggleTemporarilyAllowAll();"}
+                                     value: "&rp.menu.disableBlocking;"},
+                        events: {click: ["overlay",
+                                         "toggleTemporarilyAllowAll"]}
                       }, {
                         tag: "label",
                         attributes: {id: "rpc-link-help",
                                      "class": "rpc-footer-link",
-                                     value: "&rp.menu.help;",
-                                     onclick: "rpcontinued.overlay.openHelp();"}
+                                     value: "&rp.menu.help;"},
+                        events: {click: ["overlay", "openHelp"]}
                       }, {
                         tag: "label",
                         attributes: {id: "rpc-link-prefs",
                                      "class": "rpc-footer-link",
-                                     value: "&rp.menu.preferences;",
-                                     onclick: "rpcontinued.overlay.openPrefs(event);"}
+                                     value: "&rp.menu.preferences;"},
+                        events: {click: ["overlay", "openPrefs"]}
                       }, {
                         tag: "label",
                         attributes: {id: "rpc-link-policies",
                                      "class": "rpc-footer-link",
-                                     value: "&rp.menu.managePolicies;",
-                                     onclick: "rpcontinued.overlay.openPolicyManager();"}
+                                     value: "&rp.menu.managePolicies;"},
+                        events: {click: ["overlay", "openPolicyManager"]}
                       }, {
                         tag: "label",
                         attributes: {id: "rpc-link-request-log",
                                      "class": "rpc-footer-link",
-                                     value: "&rp.requestLog.title;",
-                                     onclick: "rpcontinued.overlay.toggleRequestLog(event);"}
+                                     value: "&rp.requestLog.title;"},
+                        events: {click: ["overlay", "toggleRequestLog"]}
                       }
                     ]
                   }
@@ -329,16 +331,16 @@ exports.mainTree = [
               }, {
                 tag: "button",
                 attributes: {id: "rpcontinued-requestLog-clear",
-                             label: "&rp.requestLog.clear;",
-                             oncommand: "rpcontinued.overlay.clearRequestLog();"}
+                             label: "&rp.requestLog.clear;"},
+                events: {command: ["overlay", "clearRequestLog"]}
               }, {
                 tag: "vbox",
                 attributes: {flex: "1"}
               }, {
                 tag: "toolbarbutton",
                 attributes: {id: "rpcontinued-requestLog-close",
-                             align: "right",
-                             oncommand: "rpcontinued.overlay.toggleRequestLog()"}
+                             align: "right"},
+                events: {command: ["overlay", "toggleRequestLog"]}
               }
             ]
           }

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