diff options
author | Kris Maglione <maglione.k@gmail.com> | 2011-01-23 23:25:08 -0500 |
---|---|---|
committer | Kris Maglione <maglione.k@gmail.com> | 2011-01-23 23:25:08 -0500 |
commit | 3cd40141f92abd39a0512a486ad3308a539adf36 (patch) | |
tree | 2706fff30c2f17b87d8a0acaa4bcc823197da677 | |
parent | df4fc6510246afead463cec96550b1fb016b566c (diff) | |
download | pentadactyl-3cd40141f92abd39a0512a486ad3308a539adf36.tar.gz |
Move :downloads button logic into binding classes.
--HG--
branch : key-processing
-rw-r--r-- | common/content/commandline.js | 1 | ||||
-rw-r--r-- | common/content/events.js | 8 | ||||
-rw-r--r-- | common/modules/downloads.jsm | 26 | ||||
-rw-r--r-- | common/modules/template.jsm | 81 | ||||
-rw-r--r-- | common/modules/util.jsm | 16 |
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; |