diff options
author | Kris Maglione <maglione.k@gmail.com> | 2011-08-07 14:36:22 -0400 |
---|---|---|
committer | Kris Maglione <maglione.k@gmail.com> | 2011-08-07 14:36:22 -0400 |
commit | fc09e4828fd7e642cb5b41eeda818865d5f3e5ae (patch) | |
tree | 03b04be07a32761a60d1543b02cbcde5bedbb1aa /common | |
parent | 16394c75a535cdc830271f034f66a5e4df3adff0 (diff) | |
download | pentadactyl-fc09e4828fd7e642cb5b41eeda818865d5f3e5ae.tar.gz |
Add a basic XPath generator.
Diffstat (limited to 'common')
-rw-r--r-- | common/modules/util.jsm | 58 |
1 files changed, 46 insertions, 12 deletions
diff --git a/common/modules/util.jsm b/common/modules/util.jsm index d9727442..d07980c0 100644 --- a/common/modules/util.jsm +++ b/common/modules/util.jsm @@ -748,14 +748,53 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), } }, { - resolver: function lookupNamespaceURI(prefix) ({ - xul: XUL.uri, - xhtml: XHTML.uri, - xhtml2: "http://www.w3.org/2002/06/xhtml2", - dactyl: NS.uri - }[prefix] || null) + resolver: function lookupNamespaceURI(prefix) (util.namespaces[prefix] || null) }), + /** + * Generates an XPath expression for the given element. + * + * @param {Element} elem The element for which to generate an XPath. + * @returns {string} + */ + generateXPath: function generateXPath(elem) { + function quote(val) "'" + val.replace(/[\\']/g, "\\$&") + "'"; + + let res = []; + let doc = elem.ownerDocument; + for (;; elem = elem.parentNode) { + if (!(elem instanceof Ci.nsIDOMElement)) + res.push(""); + else if (elem.id) + res.push("id(" + quote(elem.id) + ")"); + else { + let name = elem.localName; + if (elem.namespaceURI && (elem.namespaceURI != XHTML || doc.xmlVersion)) + if (elem.namespaceURI in this.namespaceNames) + name = this.namespaceNames[elem.namespaceURI] + ":" + name; + else + name = "*:" + name + "[namespace-uri()=" + quote(elem.namespaceURI) + "]"; + + res.push(name + "[" + (1 + iter(this.evaluateXPath("./" + name, elem.parentNode)).indexOf(elem)) + "]"); + continue; + } + break; + } + + return res.reverse().join("/"); + }, + + namespaces: { + xul: XUL.uri, + html: XHTML.uri, + xhtml: XHTML.uri, + xhtml2: "http://www.w3.org/2002/06/xhtml2", + dactyl: NS.uri + }, + + namespaceNames: Class.memoize(function () + iter(this.namespaces).map(function ([k, v]) [v, k]).toObject()), + extend: function extend(dest) { Array.slice(arguments, 1).filter(util.identity).forEach(function (src) { for (let [k, v] in Iterator(src)) { @@ -1131,7 +1170,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), return String(object); function namespaced(node) { - var ns = NAMESPACES[node.namespaceURI] || /^(?:(.*?):)?/.exec(node.name)[0]; + var ns = util.namespaceNames[node.namespaceURI] || /^(?:(.*?):)?/.exec(node.name)[0]; if (!ns) return node.localName; if (color) @@ -1140,11 +1179,6 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), } if (object instanceof Ci.nsIDOMElement) { - const NAMESPACES = array.toObject([ - [NS, "dactyl"], - [XHTML, "html"], - [XUL, "xul"] - ]); let elem = object; if (elem.nodeType == elem.TEXT_NODE) return elem.data; |