[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