summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKris Maglione <maglione.k@gmail.com>2011-01-23 23:25:08 -0500
committerKris Maglione <maglione.k@gmail.com>2011-01-23 23:25:08 -0500
commit3cd40141f92abd39a0512a486ad3308a539adf36 (patch)
tree2706fff30c2f17b87d8a0acaa4bcc823197da677
parentdf4fc6510246afead463cec96550b1fb016b566c (diff)
downloadpentadactyl-3cd40141f92abd39a0512a486ad3308a539adf36.tar.gz
Move :downloads button logic into binding classes.
--HG-- branch : key-processing
-rw-r--r--common/content/commandline.js1
-rw-r--r--common/content/events.js8
-rw-r--r--common/modules/downloads.jsm26
-rw-r--r--common/modules/template.jsm81
-rw-r--r--common/modules/util.jsm16
5 files changed, 100 insertions, 32 deletions
diff --git a/common/content/commandline.js b/common/content/commandline.js
index febd98cd..8f03cbf6 100644
--- a/common/content/commandline.js
+++ b/common/content/commandline.js
@@ -1083,7 +1083,6 @@ var CommandLine = Module("commandline", {
// TODO: Wouldn't multiple handlers be cleaner? --djk
if (event.type == "click" && event.target instanceof HTMLAnchorElement) {
- util.dump(event.getPreventDefault(), event.target);
if (event.getPreventDefault())
return;
diff --git a/common/content/events.js b/common/content/events.js
index 186464aa..29a8086c 100644
--- a/common/content/events.js
+++ b/common/content/events.js
@@ -92,7 +92,11 @@ var ProcessorStack = Class("ProcessorStack", {
else if (this.actions.length) {
if (actions.length == 0)
dactyl.beep();
- result = this.actions[0]() === Events.PASS ? Events.PASS : Events.KILL;
+
+ if (modes.replaying && !events.waitForPageLoad())
+ result = Events.KILL;
+ else
+ result = this.actions[0]() === Events.PASS ? Events.PASS : Events.KILL;
}
else if (result !== Events.KILL && processors.some(function (p) !p.main.passUnknown)) {
result = Events.KILL;
@@ -175,8 +179,6 @@ var KeyProcessor = Class("KeyProcessor", {
return KeyArgProcessor(this, map, false, "arg");
else if (map.motion)
return KeyArgProcessor(this, map, true, "motion");
- else if (modes.replaying && !events.waitForPageLoad())
- return Events.KILL;
return this.execute(map, { count: this.count, command: this.command, events: this.events });
}
diff --git a/common/modules/downloads.jsm b/common/modules/downloads.jsm
index aff156fe..cfb322e7 100644
--- a/common/modules/downloads.jsm
+++ b/common/modules/downloads.jsm
@@ -25,7 +25,9 @@ var Download = Class("Download", {
this.instance = this;
this.list = list;
- this.nodes = {};
+ this.nodes = {
+ commandTarget: self
+ };
util.xmlToDom(
<li highlight="Download" key="row" xmlns:dactyl={NS} xmlns={XHTML}>
<span highlight="DownloadTitle">
@@ -54,22 +56,6 @@ var Download = Class("Download", {
</li>,
this.list.document, this.nodes);
- for (let [key, node] in Iterator(this.nodes)) {
- node.dactylDownload = self;
- if (node.getAttributeNS(NS, "highlight") == "Button") {
- node.setAttributeNS(NS, "command", "download.command");
- update(node, {
- set collapsed(collapsed) {
- if (collapsed)
- this.setAttribute("collapsed", "true");
- else
- this.removeAttribute("collapsed");
- },
- get collapsed() !!this.getAttribute("collapsed")
- });
- }
- }
-
self.updateStatus();
return self;
},
@@ -289,12 +275,6 @@ var Downloads = Module("downloads", {
if (modules.commandline.savingOutput)
util.waitFor(function () downloads.document);
});
- },
- dactyl: function (dactyl, modules, window) {
- dactyl.commands["download.command"] = function (event) {
- let elem = event.originalTarget;
- elem.dactylDownload.command(elem.getAttribute("key"));
- }
}
});
diff --git a/common/modules/template.jsm b/common/modules/template.jsm
index 36847f6d..565cfbf6 100644
--- a/common/modules/template.jsm
+++ b/common/modules/template.jsm
@@ -13,6 +13,68 @@ defineModule("template", {
default xml namespace = XHTML;
+var Binding = Class("Binding", {
+ init: function (node) {
+ this.node = node;
+ node.dactylBinding = this;
+
+ Object.defineProperties(node, this.constructor.properties);
+
+ for (let [event, handler] in values(this.constructor.events))
+ node.addEventListener(event, handler, false);
+ },
+
+ set collapsed(collapsed) {
+ if (collapsed)
+ this.setAttribute("collapsed", "true");
+ else
+ this.removeAttribute("collapsed");
+ },
+ get collapsed() !!this.getAttribute("collapsed"),
+
+ __noSuchMethod__: function __noSuchMethod__(meth, args) {
+ return this.node[meth].apply(this.node, args);
+ }
+}, {
+ get bindings() {
+ let bindingProto = Object.getPrototypeOf(Binding.prototype);
+ for (let obj = this.prototype; obj !== bindingProto; obj = Object.getPrototypeOf(obj))
+ yield obj;
+ },
+
+ bind: function bind(func) function bound() {
+ try {
+ return func.apply(this.dactylBinding, arguments);
+ }
+ catch (e) {
+ util.reportError(e);
+ throw e;
+ }
+ },
+
+ events: Class.memoize(function () {
+ let res = [];
+ for (let obj in this.bindings)
+ if (Object.getOwnPropertyDescriptor(obj, "events"))
+ for (let [event, handler] in Iterator(obj.events))
+ res.push([event, this.bind(handler)]);
+ return res;
+ }),
+
+ properties: Class.memoize(function () {
+ let res = {};
+ for (let obj in this.bindings)
+ for (let prop in properties(obj)) {
+ let desc = Object.getOwnPropertyDescriptor(obj, prop);
+ for (let k in values(["get", "set", "value"]))
+ if (typeof desc[k] === "function")
+ desc[k] = this.bind(desc[k]);
+ res[prop] = desc;
+ }
+ return res;
+ })
+});
+
var Template = Module("Template", {
add: function add(a, b) a + b,
join: function join(c) function (a, b) a + c + b,
@@ -36,6 +98,25 @@ var Template = Module("Template", {
return ret;
},
+ bindings: {
+ Button: Class("Button", Binding, {
+ init: function init(node, params) {
+ init.supercall(this, node);
+
+ this.target = params.commandTarget;
+ if (callable(this.target))
+ this.target = { command: this.target }
+ },
+
+ events: {
+ "click": function onClick(event) {
+ event.preventDefault();
+ this.target.command(this.getAttribute("key"));
+ }
+ }
+ })
+ },
+
bookmarkDescription: function (item, text)
<>
{
diff --git a/common/modules/util.jsm b/common/modules/util.jsm
index 52debe7a..664f93de 100644
--- a/common/modules/util.jsm
+++ b/common/modules/util.jsm
@@ -1587,27 +1587,33 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
XML.prettyPrinting = false;
if (typeof node === "string") // Sandboxes can't currently pass us XML objects.
node = XML(node);
+
if (node.length() != 1) {
let domnode = doc.createDocumentFragment();
for each (let child in node)
domnode.appendChild(xmlToDom(child, doc, nodes));
return domnode;
}
+
switch (node.nodeKind()) {
case "text":
return doc.createTextNode(String(node));
case "element":
let domnode = doc.createElementNS(node.namespace(), node.localName());
- for each (let attr in node.@*::*)
- if (attr.name() != "highlight")
- domnode.setAttributeNS(attr.namespace(), attr.localName(), String(attr));
- else
- highlight.highlightNode(domnode, String(attr));
for each (let child in node.*::*)
domnode.appendChild(xmlToDom(child, doc, nodes));
if (nodes && node.@key)
nodes[node.@key] = domnode;
+
+ for each (let attr in node.@*::*)
+ if (attr.name() != "highlight")
+ domnode.setAttributeNS(attr.namespace(), attr.localName(), String(attr));
+ else {
+ highlight.highlightNode(domnode, String(attr));
+ if (attr in template.bindings)
+ template.bindings[attr](domnode, nodes);
+ }
return domnode;
default:
return null;