summaryrefslogtreecommitdiff
path: root/common/modules/dom.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'common/modules/dom.jsm')
-rw-r--r--common/modules/dom.jsm236
1 files changed, 137 insertions, 99 deletions
diff --git a/common/modules/dom.jsm b/common/modules/dom.jsm
index 72d80135..5a4d2598 100644
--- a/common/modules/dom.jsm
+++ b/common/modules/dom.jsm
@@ -1,5 +1,5 @@
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
-// Copyright (c) 2008-2014 Kris Maglione <maglione.k@gmail.com>
+// Copyright (c) 2008-2015 Kris Maglione <maglione.k@gmail.com>
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
@@ -63,7 +63,10 @@ var DOM = Class("DOM", {
}
else if (val instanceof Ci.nsIDOMNode || val instanceof Ci.nsIDOMWindow)
this[length++] = val;
- else if ("__iterator__" in val || isinstance(val, ["Iterator", "Generator"]))
+ else if (Symbol.iterator in val)
+ for (let elem of val)
+ this[length++] = elem;
+ else if (isinstance(val, ["Iterator", "Generator"]))
for (let elem in val)
this[length++] = elem;
else if ("length" in val)
@@ -76,7 +79,7 @@ var DOM = Class("DOM", {
return self || this;
},
- __iterator__: function __iterator__() {
+ "@@iterator": function* __iterator__() {
for (let i = 0; i < this.length; i++)
yield this[i];
},
@@ -85,20 +88,21 @@ var DOM = Class("DOM", {
nodes: Class.Memoize(function () ({})),
- get items() {
+ get items() (function* () {
for (let i = 0; i < this.length; i++)
+ /* FIXME: Symbols */
yield this.eq(i);
- },
+ })(),
get document() this._document || this[0] && (this[0].ownerDocument || this[0].document || this[0]),
set document(val) this._document = val,
attrHooks: array.toObject([
["", {
- href: { get: function (elem) elem.href || elem.getAttribute("href") },
- src: { get: function (elem) elem.src || elem.getAttribute("src") },
- checked: { get: function (elem) elem.hasAttribute("checked") ? elem.getAttribute("checked") == "true" : elem.checked,
- set: function (elem, val) { elem.setAttribute("checked", !!val); elem.checked = val; } },
+ href: { get: elem => elem.href || elem.getAttribute("href") },
+ src: { get: elem => elem.src || elem.getAttribute("src") },
+ checked: { get: elem => elem.hasAttribute("checked") ? elem.getAttribute("checked") == "true" : elem.checked,
+ set: (elem, val) => { elem.setAttribute("checked", !!val); elem.checked = val; } },
collapsed: BooleanAttribute("collapsed"),
disabled: BooleanAttribute("disabled"),
hidden: BooleanAttribute("hidden"),
@@ -261,58 +265,71 @@ var DOM = Class("DOM", {
get allSiblingsBefore() this.all(elem => elem.previousSibling),
get allSiblingsAfter() this.all(elem => elem.nextSibling),
- get class() let (self = this) ({
- toString: function () self[0].className,
+ get class() {
+ let self = this;
- get list() Array.slice(self[0].classList),
- set list(val) self.attr("class", val.join(" ")),
+ return {
+ toString: function () self[0].className,
- each: function each(meth, arg) {
- return self.each(function (elem) {
- elem.classList[meth](arg);
- });
- },
+ get list() Array.slice(self[0].classList),
+ set list(val) self.attr("class", val.join(" ")),
- add: function add(cls) this.each("add", cls),
- remove: function remove(cls) this.each("remove", cls),
- toggle: function toggle(cls, val, thisObj) {
- if (callable(val))
- return self.each(function (elem, i) {
- this.class.toggle(cls, val.call(thisObj || this, elem, i));
+ each: function each(meth, arg) {
+ return self.each(function (elem) {
+ elem.classList[meth](arg);
});
- return this.each(val == null ? "toggle" : val ? "add" : "remove", cls);
- },
+ },
+
+ add: function add(cls) this.each("add", cls),
+ remove: function remove(cls) this.each("remove", cls),
+ toggle: function toggle(cls, val, thisObj) {
+ if (callable(val))
+ return self.each(function (elem, i) {
+ this.class.toggle(cls, val.call(thisObj || this, elem, i));
+ });
+ return this.each(val == null ? "toggle" : val ? "add" : "remove", cls);
+ },
- has: function has(cls) this[0].classList.has(cls)
- }),
+ has: function has(cls) this[0].classList.has(cls)
+ };
+ },
- get highlight() let (self = this) ({
- toString: function () self.attrNS(NS, "highlight") || "",
+ get highlight() {
+ let self = this;
- get list() let (s = this.toString().trim()) s ? s.split(/\s+/) : [],
- set list(val) {
- let str = array.uniq(val).join(" ").trim();
- self.attrNS(NS, "highlight", str || null);
- },
+ return {
+ toString: function () self.attrNS(NS, "highlight") || "",
- has: function has(hl) ~this.list.indexOf(hl),
+ get list() {
+ let s = this.toString().trim();
- add: function add(hl) self.each(function () {
- highlight.loaded[hl] = true;
- this.highlight.list = this.highlight.list.concat(hl);
- }),
+ return s ? s.split(/\s+/) : [];
+ },
- remove: function remove(hl) self.each(function () {
- this.highlight.list = this.highlight.list.filter(h => h != hl);
- }),
+ set list(val) {
+ let str = array.uniq(val).join(" ").trim();
+ self.attrNS(NS, "highlight", str || null);
+ },
- toggle: function toggle(hl, val, thisObj) self.each(function (elem, i) {
- let { highlight } = this;
- let v = callable(val) ? val.call(thisObj || this, elem, i) : val;
+ has: function has(hl) ~this.list.indexOf(hl),
- highlight[(v == null ? highlight.has(hl) : !v) ? "remove" : "add"](hl);
- }),
- }),
+ add: function add(hl) self.each(function () {
+ highlight.loaded[hl] = true;
+ this.highlight.list = this.highlight.list.concat(hl);
+ }),
+
+ remove: function remove(hl) self.each(function () {
+ this.highlight.list = this.highlight.list.filter(h => h != hl);
+ }),
+
+ toggle: function toggle(hl, val, thisObj) self.each(function (elem, i) {
+ let { highlight } = this;
+ let v = callable(val) ? val.call(thisObj || this, elem, i) : val;
+
+ highlight[(v == null ? highlight.has(hl) : !v) ? "remove" : "add"](hl);
+ }),
+ };
+ },
get rect() this[0] instanceof Ci.nsIDOMWindow ? { width: this[0].scrollMaxX + this[0].innerWidth,
height: this[0].scrollMaxY + this[0].innerHeight,
@@ -496,7 +513,7 @@ var DOM = Class("DOM", {
if (field instanceof Ci.nsIDOMHTMLInputElement && field.type == "submit")
elems.push(encode(field.name, field.value));
- for (let [, elem] in iter(form.elements))
+ for (let elem of form.elements)
if (elem.name && !elem.disabled) {
if (DOM(elem).isInput
|| /^(?:hidden|textarea)$/.test(elem.type)
@@ -511,7 +528,7 @@ var DOM = Class("DOM", {
elems.push(encode(elem.name, "", true));
}
else if (elem instanceof Ci.nsIDOMHTMLSelectElement) {
- for (let [, opt] in Iterator(elem.options))
+ for (let opt of elem.options)
if (opt.selected)
elems.push(encode(elem.name, opt.value));
}
@@ -596,7 +613,7 @@ var DOM = Class("DOM", {
else {
let tag = "<" + [namespaced(elem)].concat(
[namespaced(a) + '="' + String.replace(a.value, /["<]/, DOM.escapeHTML) + '"'
- for ([i, a] in array.iterItems(elem.attributes))]).join(" ");
+ for ([i, a] of array.iterItems(elem.attributes))]).join(" ");
res.push(tag + (!hasChildren ? "/>" : ">...</" + namespaced(elem) + ">"));
}
@@ -621,7 +638,7 @@ var DOM = Class("DOM", {
if (isObject(key))
return this.each(function (elem, i) {
- for (let [k, v] in Iterator(key)) {
+ for (let [k, v] of iter(key)) {
if (callable(v))
v = v.call(this, elem, i);
@@ -652,7 +669,7 @@ var DOM = Class("DOM", {
if (isObject(key))
return this.each(function (elem) {
- for (let [k, v] in Iterator(key))
+ for (let [k, v] of iter(key))
elem.style[css.property(k)] = v;
});
@@ -789,20 +806,20 @@ var DOM = Class("DOM", {
}, this);
},
- html: function html(txt, self) {
- return this.getSet(arguments,
+ html: function html(...args) {
+ return this.getSet(args,
elem => elem.innerHTML,
util.wrapCallback((elem, val) => { elem.innerHTML = val; }));
},
- text: function text(txt, self) {
- return this.getSet(arguments,
+ text: function text(...args) {
+ return this.getSet(args,
elem => elem.textContent,
(elem, val) => { elem.textContent = val; });
},
- val: function val(txt) {
- return this.getSet(arguments,
+ val: function val(...args) {
+ return this.getSet(args,
elem => elem.value,
(elem, val) => { elem.value = val == null ? "" : val; });
},
@@ -813,11 +830,11 @@ var DOM = Class("DOM", {
else
event = array.toObject([[event, listener]]);
- for (let [evt, callback] in Iterator(event))
+ for (let [evt, callback] of iter(event))
event[evt] = util.wrapCallback(callback, true);
return this.each(function (elem) {
- for (let [evt, callback] in Iterator(event))
+ for (let [evt, callback] of iter(event))
elem.addEventListener(evt, callback, capture);
});
},
@@ -828,7 +845,7 @@ var DOM = Class("DOM", {
event = array.toObject([[event, listener]]);
return this.each(function (elem) {
- for (let [k, v] in Iterator(event))
+ for (let [k, v] of iter(event))
elem.removeEventListener(k, v.wrapper || v, capture);
});
},
@@ -838,7 +855,7 @@ var DOM = Class("DOM", {
else
event = array.toObject([[event, listener]]);
- for (let pair in Iterator(event)) {
+ for (let pair of iter(event)) {
let [evt, callback] = pair;
event[evt] = util.wrapCallback(function wrapper(event) {
this.removeEventListener(evt, wrapper.wrapper, capture);
@@ -847,7 +864,7 @@ var DOM = Class("DOM", {
}
return this.each(function (elem) {
- for (let [k, v] in Iterator(event))
+ for (let [k, v] of iter(event))
elem.addEventListener(k, v, capture);
});
},
@@ -926,7 +943,7 @@ var DOM = Class("DOM", {
}
}
- for (let parent in this.ancestors.items)
+ for (let parent of this.ancestors.items)
fix(parent);
fix(DOM(this.document.defaultView));
@@ -981,9 +998,16 @@ var DOM = Class("DOM", {
let params = DEFAULTS[t || "HTML"];
let args = Object.keys(params);
update(params, this.constructor.defaults[type],
- iter.toObject([k, opts[k]] for (k in opts) if (k in params)));
+ iter.toObject([k, opts[k]]
+ for (k in opts)
+ if (k in params)));
- evt["init" + t + "Event"].apply(evt, args.map(k => params[k]));
+ // Because security boundaries :/
+ let ary = new doc.defaultView.Array;
+ for (let arg of args)
+ ary.push(params[arg]);
+
+ evt["init" + t + "Event"].apply(evt, ary);
return evt;
}
}, {
@@ -1024,14 +1048,14 @@ var DOM = Class("DOM", {
this.key_code = {};
this.code_nativeKey = {};
- for (let list in values(this.keyTable))
- for (let v in values(list)) {
+ for (let list of values(this.keyTable))
+ for (let v of values(list)) {
if (v.length == 1)
v = v.toLowerCase();
this.key_key[v.toLowerCase()] = v;
}
- for (let [k, v] in Iterator(Ci.nsIDOMKeyEvent)) {
+ for (let [k, v] of iter(Ci.nsIDOMKeyEvent)) {
if (!/^DOM_VK_/.test(k))
continue;
@@ -1048,7 +1072,7 @@ var DOM = Class("DOM", {
names = this.keyTable[k];
this.code_key[v] = names[0];
- for (let [, name] in Iterator(names)) {
+ for (let name of names) {
this.key_key[name.toLowerCase()] = name;
this.key_code[name.toLowerCase()] = v;
}
@@ -1069,7 +1093,7 @@ var DOM = Class("DOM", {
keyTable: Class.Memoize(function (prop) this.init()[prop]),
key_code: Class.Memoize(function (prop) this.init()[prop]),
key_key: Class.Memoize(function (prop) this.init()[prop]),
- pseudoKeys: RealSet(["count", "leader", "nop", "pass"]),
+ pseudoKeys: new RealSet(["count", "leader", "nop", "pass"]),
/**
* Converts a user-input string of keys into a canonical
@@ -1095,11 +1119,13 @@ var DOM = Class("DOM", {
return this.parse(keys, unknownOk).map(this.bound.stringify).join("");
},
- iterKeys: function iterKeys(keys) iter(function () {
- let match, re = /<.*?>?>|[^<]/g;
- while (match = re.exec(keys))
- yield match[0];
- }()),
+ iterKeys: function iterKeys(keys) {
+ return iter(function* () {
+ let match, re = /<.*?>?>|[^<]/g;
+ while (match = re.exec(keys))
+ yield match[0];
+ }());
+ },
/**
* Converts an event string into an array of pseudo-event objects.
@@ -1126,7 +1152,7 @@ var DOM = Class("DOM", {
return array.flatten(input.map(k => this.parse(k, unknownOk)));
let out = [];
- for (let match in util.regexp.iterate(/<.*?>?>|[^<]|<(?!.*>)/g, input)) {
+ for (let match of util.regexp.iterate(/<.*?>?>|[^<]|<(?!.*>)/g, input)) {
let evt_str = match[0];
let evt_obj = { ctrlKey: false, shiftKey: false, altKey: false, metaKey: false,
@@ -1139,7 +1165,7 @@ var DOM = Class("DOM", {
}
else {
let [match, modifier, keyname] = evt_str.match(/^<((?:[*12CASM⌘]-)*)(.+?)>$/i) || [false, '', ''];
- modifier = RealSet(modifier.toUpperCase());
+ modifier = new RealSet(modifier.toUpperCase());
keyname = keyname.toLowerCase();
evt_obj.dactylKeyname = keyname;
if (/^u[0-9a-f]+$/.test(keyname))
@@ -1286,8 +1312,10 @@ var DOM = Class("DOM", {
// or if the shift has been forced for a non-alphabetical character by the user while :map-ping
if (key !== key.toLowerCase() && (event.ctrlKey || event.altKey || event.metaKey) || event.dactylShift)
modifier += "S-";
- if (/^\s$/.test(key))
- key = let (s = charCode.toString(16)) "U" + "0000".substr(4 - s.length) + s;
+ if (/^\s$/.test(key)) {
+ let s = charCode.toString(16);
+ key = "U" + "0000".substr(4 - s.length) + s;
+ }
else if (modifier.length == 0)
return key;
}
@@ -1396,9 +1424,9 @@ var DOM = Class("DOM", {
* The set of input element type attribute values that mark the element as
* an editable field.
*/
- editableInputs: RealSet(["date", "datetime", "datetime-local", "email", "file",
- "month", "number", "password", "range", "search",
- "tel", "text", "time", "url", "week"]),
+ editableInputs: new RealSet(["date", "datetime", "datetime-local", "email", "file",
+ "month", "number", "password", "range", "search",
+ "tel", "text", "time", "url", "week"]),
/**
* Converts a given DOM Node, Range, or Selection to a string. If
@@ -1450,20 +1478,20 @@ var DOM = Class("DOM", {
*/
compileMatcher: function compileMatcher(list) {
let xpath = [], css = [];
- for (let elem in values(list))
+ for (let elem of values(list))
if (/^xpath:/.test(elem))
xpath.push(elem.substr(6));
else
css.push(elem);
return update(
- function matcher(node) {
+ function* matcher(node) {
if (matcher.xpath)
- for (let elem in DOM.XPath(matcher.xpath, node))
+ for (let elem of DOM.XPath(matcher.xpath, node))
yield elem;
if (matcher.css)
- for (let [, elem] in iter(util.withProperErrors("querySelectorAll", node, matcher.css)))
+ for (let [, elem] of iter(util.withProperErrors("querySelectorAll", node, matcher.css)))
yield elem;
}, {
css: css.join(", "),
@@ -1614,11 +1642,11 @@ var DOM = Class("DOM", {
toPrettyXML: function toPrettyXML(xml, asXML, indent, namespaces) {
const INDENT = indent || " ";
- const EMPTY = RealSet("area base basefont br col frame hr img input isindex link meta param"
- .split(" "));
+ const EMPTY = new RealSet("area base basefont br col frame hr img input isindex link meta param"
+ .split(" "));
function namespaced(namespaces, namespace, localName) {
- for (let [k, v] in Iterator(namespaces))
+ for (let [k, v] of iter(namespaces))
if (v == namespace)
return (k ? k + ":" + localName : localName);
@@ -1631,10 +1659,12 @@ var DOM = Class("DOM", {
return args.some(a => (isString(a) || isFragment(a) && hasString(a)));
}
+ const STRING_TYPES = ["String", "Number", "Boolean", _, DOM.DOMString];
+
function isStrings(args) {
if (!isArray(args))
return util.dump("ARGS: " + {}.toString.call(args) + " " + args), false;
- return args.every(a => (isinstance(a, ["String", DOM.DOMString]) || isFragment(a) && isStrings(a)));
+ return args.every(a => (isinstance(a, STRING_TYPES) || isFragment(a) && isStrings(a)));
}
function tag(args, namespaces, indent) {
@@ -1643,7 +1673,7 @@ var DOM = Class("DOM", {
if (args == "")
return "";
- if (isinstance(args, ["String", "Number", "Boolean", _, DOM.DOMString]))
+ if (isinstance(args, STRING_TYPES))
return indent +
DOM.escapeHTML(String(args), true);
@@ -1717,7 +1747,7 @@ var DOM = Class("DOM", {
let res = [indent, "<", name];
- for (let [key, val] in Iterator(attr)) {
+ for (let [key, val] of iter(attr)) {
if (hasOwnProperty(skipAttr, key))
continue;
@@ -1813,10 +1843,18 @@ var DOM = Class("DOM", {
get resultType() result.resultType,
get snapshotLength() result.snapshotLength,
snapshotItem: function (i) result.snapshotItem(i),
- __iterator__:
- asIterator ? function () { let elem; while ((elem = this.iterateNext())) yield elem; }
- : function () { for (let i = 0; i < this.snapshotLength; i++) yield this.snapshotItem(i); }
- };
+ }
+ if (asIterator)
+ res[Symbol.iterator] = function* () {
+ let elem;
+ while ((elem = this.iterateNext()))
+ yield elem;
+ };
+ else
+ res[Symbol.iterator] = function* () {
+ for (let i = 0; i < this.snapshotLength; i++)
+ yield this.snapshotItem(i);
+ };
return res;
}
catch (e) {