From 7ee579200f5f49748418fc06b8c37cadea609610 Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Sat, 21 Feb 2015 21:59:37 -0800 Subject: Fix all the things. And break most of the other things, in all likelihood. --- common/content/abbreviations.js | 31 ++-- common/content/autocommands.js | 10 +- common/content/bookmarks.js | 14 +- common/content/browser.js | 2 +- common/content/commandline.js | 46 +++-- common/content/dactyl.js | 83 +++++---- common/content/editor.js | 29 +-- common/content/events.js | 70 +++---- common/content/hints.js | 45 +++-- common/content/history.js | 14 +- common/content/key-processors.js | 10 +- common/content/mappings.js | 108 ++++++----- common/content/marks.js | 20 +- common/content/modes.js | 32 ++-- common/content/mow.js | 11 +- common/content/quickmarks.js | 12 +- common/content/statusline.js | 2 +- common/content/tabs.js | 48 ++--- common/modules/addons.jsm | 6 +- common/modules/base.jsm | 267 ++++++++++++++++----------- common/modules/bookmarkcache.jsm | 10 +- common/modules/buffer.jsm | 160 ++++++++-------- common/modules/cache.jsm | 4 +- common/modules/commands.jsm | 357 ++++++++++++++++++----------------- common/modules/completion.jsm | 42 +++-- common/modules/config.jsm | 39 ++-- common/modules/contexts.jsm | 67 ++++--- common/modules/dom.jsm | 236 +++++++++++++---------- common/modules/downloads.jsm | 50 ++--- common/modules/finder.jsm | 32 ++-- common/modules/help.jsm | 35 ++-- common/modules/highlight.jsm | 21 ++- common/modules/io.jsm | 390 ++++++++++++++++++++------------------- common/modules/javascript.jsm | 64 +++---- common/modules/main.jsm | 16 +- common/modules/messages.jsm | 28 +-- common/modules/options.jsm | 344 +++++++++++++++++----------------- common/modules/overlay.jsm | 103 ++++++++--- common/modules/prefs.jsm | 10 +- common/modules/promises.jsm | 6 +- common/modules/protocol.jsm | 18 +- common/modules/sanitizer.jsm | 100 +++++----- common/modules/storage.jsm | 52 +++--- common/modules/styles.jsm | 58 +++--- common/modules/template.jsm | 76 ++++---- common/modules/util.jsm | 155 ++++++++-------- 46 files changed, 1812 insertions(+), 1521 deletions(-) (limited to 'common') diff --git a/common/content/abbreviations.js b/common/content/abbreviations.js index f81b35a3..a3e351e8 100644 --- a/common/content/abbreviations.js +++ b/common/content/abbreviations.js @@ -116,7 +116,7 @@ var AbbrevHive = Class("AbbrevHive", Contexts.Hive, { if (!(abbr instanceof Abbreviation)) abbr = Abbreviation.apply(null, arguments); - for (let [, mode] in Iterator(abbr.modes)) { + for (let mode of abbr.modes) { if (!this._store[mode]) this._store[mode] = {}; this._store[mode][abbr.lhs] = abbr; @@ -156,7 +156,7 @@ var AbbrevHive = Class("AbbrevHive", Contexts.Hive, { */ remove: function (modes, lhs) { let result = false; - for (let [, mode] in Iterator(modes)) { + for (let mode of modes) { if ((mode in this._store) && (lhs in this._store[mode])) { result = true; this._store[mode][lhs].removeMode(mode); @@ -172,8 +172,8 @@ var AbbrevHive = Class("AbbrevHive", Contexts.Hive, { * @param {Array} modes List of modes. */ clear: function (modes) { - for (let mode in values(modes)) { - for (let abbr in values(this._store[mode])) + for (let mode of values(modes)) { + for (let abbr of values(this._store[mode])) abbr.removeMode(mode); delete this._store[mode]; } @@ -276,15 +276,18 @@ var Abbreviations = Module("abbreviations", { ["td", { style: "padding-right: 1em;" }, _("title.Abbrev")], ["td", { style: "padding-right: 1em;" }, _("title.Replacement")]], ["col", { style: "min-width: 6em; padding-right: 1em;" }], - hives.map(hive => let (i = 0) [ - ["tr", { style: "height: .5ex;" }], - abbrevs(hive).map(abbrev => - ["tr", {}, - ["td", { highlight: "Title" }, !i++ ? String(hive.name) : ""], - ["td", {}, abbrev.modeChar], - ["td", {}, abbrev.lhs], - ["td", {}, abbrev.rhs]]), - ["tr", { style: "height: .5ex;" }]])]; + hives.map(hive => { + let i = 0; + return [ + ["tr", { style: "height: .5ex;" }], + abbrevs(hive).map(abbrev => + ["tr", {}, + ["td", { highlight: "Title" }, !i++ ? String(hive.name) : ""], + ["td", {}, abbrev.modeChar], + ["td", {}, abbrev.lhs], + ["td", {}, abbrev.rhs]]), + ["tr", { style: "height: .5ex;" }]]; + })]; // FIXME? // // TODO: Move this to an ItemList to show this automatically @@ -361,7 +364,7 @@ var Abbreviations = Module("abbreviations", { "-javascript": callable(abbr.rhs) ? null : undefined } } - for ([, abbr] in Iterator(hive.merged)) + for (abbr of hive.merged) if (abbr.modesEqual(modes)) ]). flatten().array diff --git a/common/content/autocommands.js b/common/content/autocommands.js index 73cdd20c..7451689a 100644 --- a/common/content/autocommands.js +++ b/common/content/autocommands.js @@ -23,7 +23,7 @@ var AutoCmdHive = Class("AutoCmdHive", Contexts.Hive, { this._store = []; }, - __iterator__: function () array.iterValues(this._store), + "@@iterator": function () array.iterValues(this._store), /** * Adds a new autocommand. *cmd* will be executed when one of the specified @@ -38,7 +38,7 @@ var AutoCmdHive = Class("AutoCmdHive", Contexts.Hive, { if (!callable(pattern)) pattern = Group.compileFilter(pattern); - for (let event in values(events)) + for (let event of values(events)) this._store.push(AutoCommand(event, pattern, cmd)); }, @@ -134,7 +134,7 @@ var AutoCommands = Module("autocommands", { if (options.get("eventignore").has(event)) return; - dactyl.echomsg(_("autocmd.executing", event, "*".quote()), 8); + dactyl.echomsg(_("autocmd.executing", event, '"*"'), 8); let lastPattern = null; var { url, doc } = args; @@ -144,10 +144,10 @@ var AutoCommands = Module("autocommands", { var { uri, doc } = buffer; event = event.toLowerCase(); - for (let hive in values(this.matchingHives(uri, doc))) { + for (let hive of values(this.matchingHives(uri, doc))) { let args = hive.makeArgs(doc, null, arguments[1]); - for (let autoCmd in values(hive._store)) + for (let autoCmd of values(hive._store)) if (autoCmd.eventName === event && autoCmd.filter(uri, doc)) { if (!lastPattern || lastPattern !== String(autoCmd.filter)) dactyl.echomsg(_("autocmd.executing", event, autoCmd.filter), 8); diff --git a/common/content/bookmarks.js b/common/content/bookmarks.js index 1754ac05..c755a6bf 100644 --- a/common/content/bookmarks.js +++ b/common/content/bookmarks.js @@ -76,7 +76,7 @@ var Bookmarks = Module("bookmarks", { if (keyword && hasOwnProperty(bookmarkcache.keywords, keyword)) bmark = bookmarkcache.keywords[keyword]; else if (bookmarkcache.isBookmarked(uri)) - for (bmark in bookmarkcache) + for (bmark of bookmarkcache) if (bmark.url == uri.spec) break; } @@ -421,11 +421,11 @@ var Bookmarks = Module("bookmarks", { return dactyl.open(items.map(i => i.url), dactyl.NEW_TAB); if (filter.length > 0 && tags.length > 0) - dactyl.echoerr(_("bookmark.noMatching", tags.map(String.quote), filter.quote())); + dactyl.echoerr(_("bookmark.noMatching", tags.map(JSON.stringify), JSON.stringify(filter))); else if (filter.length > 0) - dactyl.echoerr(_("bookmark.noMatchingString", filter.quote())); + dactyl.echoerr(_("bookmark.noMatchingString", JSON.stringify(filter))); else if (tags.length > 0) - dactyl.echoerr(_("bookmark.noMatchingTags", tags.map(String.quote))); + dactyl.echoerr(_("bookmark.noMatchingTags", tags.map(JSON.stringify))); else dactyl.echoerr(_("bookmark.none")); return null; @@ -455,7 +455,7 @@ var Bookmarks = Module("bookmarks", { if (!args.bang) return [ [win.document.title, frames.length == 1 ? /*L*/"Current Location" : /*L*/"Frame: " + win.location.href] - for ([, win] in Iterator(frames))]; + for (win of frames)]; context.keys.text = "title"; context.keys.description = "url"; return bookmarks.get(args.join(" "), args["-tags"], null, { keyword: args["-keyword"], title: context.filter }); @@ -519,7 +519,7 @@ var Bookmarks = Module("bookmarks", { let frames = buffer.allFrames(); context.completions = [ [win.document.documentURI, frames.length == 1 ? /*L*/"Current Location" : /*L*/"Frame: " + win.document.title] - for ([, win] in Iterator(frames))]; + for (win of frames)]; return; } completion.bookmark(context, args["-tags"], { keyword: args["-keyword"], title: args["-title"] }); @@ -695,7 +695,7 @@ var Bookmarks = Module("bookmarks", { context.generate = function () { let [begin, end] = item.url.split("%s"); - let seen = RealSet(); + let seen = new RealSet; return history.get({ uri: util.newURI(begin), uriIsPrefix: true }).map(function (item) { let rest = item.url.length - end.length; let query = item.url.substring(begin.length, rest); diff --git a/common/content/browser.js b/common/content/browser.js index 2db10105..4641d61d 100644 --- a/common/content/browser.js +++ b/common/content/browser.js @@ -160,7 +160,7 @@ var Browser = Module("browser", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), let oldURI = overlay.getData(win.document)["uri"]; if (overlay.getData(win.document)["load-idx"] === webProgress.loadedTransIndex || !oldURI || uri.spec.replace(/#.*/, "") !== oldURI.replace(/#.*/, "")) - for (let frame in values(buffer.allFrames(win))) + for (let frame of values(buffer.allFrames(win))) overlay.setData(frame.document, "focus-allowed", false); overlay.setData(win.document, "uri", uri.spec); diff --git a/common/content/commandline.js b/common/content/commandline.js index 9cc34a02..f876e413 100644 --- a/common/content/commandline.js +++ b/common/content/commandline.js @@ -1,6 +1,6 @@ // Copyright (c) 2006-2008 by Martin Stubenschrott // Copyright (c) 2007-2011 by Doug Kearns -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -231,13 +231,13 @@ var CommandWidgets = Class("CommandWidgets", { updateVisibility: function updateVisibility() { let changed = 0; - for (let elem in values(this.elements)) + for (let elem of values(this.elements)) if (elem.getGroup) { let value = elem.getValue ? elem.getValue.call(this) : elem.noValue || this[elem.name]; let activeGroup = this.getGroup(elem.name, value); - for (let group in values([this.commandbar, this.statusbar])) { + for (let group of [this.commandbar, this.statusbar]) { let meth, node = group[elem.name]; let visible = (value && group === activeGroup); if (node && !node.collapsed == !visible) { @@ -277,7 +277,7 @@ var CommandWidgets = Class("CommandWidgets", { ["viewable", "complete"].indexOf(elem.contentDocument.readyState) >= 0; }, - _whenReady: function _whenReady(id, init) { + _whenReady: function* _whenReady(id, init) { let elem = document.getElementById(id); while (!this._ready(elem)) yield 10; @@ -502,11 +502,11 @@ var CommandLine = Module("commandline", { memoize(this, "_store", function () storage.newMap("command-history", { store: true, privateData: true })); - for (let name in values(["command", "search"])) + for (let name of ["command", "search"]) if (storage.exists("history-" + name)) { let ary = storage.newArray("history-" + name, { store: true, privateData: true }); - this._store.set(name, [v for ([k, v] in ary)]); + this._store.set(name, [v for ([k, v] of ary)]); ary.delete(); this._store.changed(); } @@ -632,7 +632,7 @@ var CommandLine = Module("commandline", { }, hideCompletions: function hideCompletions() { - for (let nodeSet in values([this.widgets.statusbar, this.widgets.commandbar])) + for (let nodeSet of values([this.widgets.statusbar, this.widgets.commandbar])) if (nodeSet.commandline.completionList) nodeSet.commandline.completionList.visible = false; }, @@ -1882,7 +1882,7 @@ var CommandLine = Module("commandline", { persistent: true, action: function (timespan, host) { let store = commandline._store; - for (let [k, v] in store) { + for (let [k, v] of store) { if (k == "command") store.set(k, v.filter(item => !(timespan.contains(item.timestamp) && (!host || commands.hasDomain(item.value, host))))); @@ -1974,8 +1974,11 @@ var ItemList = Class("ItemList", { .filter(c => c.items.length || c.message || c.incomplete) .map(this.getGroup, this), - get selected() let (g = this.selectedGroup) g && g.selectedIdx != null - ? [g.context, g.selectedIdx] : null, + get selected() { + let g = this.selectedGroup; + return g && g.selectedIdx != null ? [g.context, g.selectedIdx] + : null; + }, getRelativeItem: function getRelativeItem(offset, tuple, noWrap) { let groups = this.activeGroups; @@ -2021,7 +2024,11 @@ var ItemList = Class("ItemList", { if (start < 0 || start >= this.itemCount) return null; - group = groups.find(g => let (i = start - g.offsets.start) i >= 0 && i < g.itemCount); + group = groups.find(g => { + let i = start - g.offsets.start; + return i >= 0 && i < g.itemCount; + }); + return [group.context, start - group.offsets.start]; }, @@ -2075,7 +2082,7 @@ var ItemList = Class("ItemList", { updateOffsets: function updateOffsets() { let total = this.itemCount; let count = 0; - for (let group in values(this.activeGroups)) { + for (let group of values(this.activeGroups)) { group.offsets = { start: count, end: total - count - group.itemCount }; count += group.itemCount; } @@ -2090,7 +2097,7 @@ var ItemList = Class("ItemList", { let container = DOM(this.nodes.completions); let groups = this.activeGroups; - for (let group in values(groups)) { + for (let group of values(groups)) { group.reset(); container.append(group.nodes.root); } @@ -2133,7 +2140,7 @@ var ItemList = Class("ItemList", { * @private */ draw: function draw() { - for (let group in values(this.activeGroups)) + for (let group of values(this.activeGroups)) group.draw(); // We need to collect all of the rescrolling functions in @@ -2244,7 +2251,7 @@ var ItemList = Class("ItemList", { } let count = this.maxItems; - for (let group in values(groups)) { + for (let group of groups) { let off = Math.max(0, start - group.offsets.start); group.count = Math.constrain(group.itemCount - off, 0, count); @@ -2379,7 +2386,7 @@ var ItemList = Class("ItemList", { if (!this.generatedRange.contains(this.range)) { if (this.generatedRange.end == 0) - var [start, end] = this.range; + var [start, end] = Array.slice(this.range); else { start = this.range.start - (this.range.start <= this.generatedRange.start ? this.maxItems / 2 : 0); @@ -2391,19 +2398,20 @@ var ItemList = Class("ItemList", { Math.min(this.itemCount, end)); let first; - for (let [i, row] in this.context.getRows(this.generatedRange.start, + for (let [i, row] of this.context.getRows(this.generatedRange.start, this.generatedRange.end, - this.doc)) + this.doc)) { if (!range.contains(i)) DOM(row).remove(); else if (!first) first = row; + } let container = DOM(this.nodes.items); let before = first ? DOM(first).bound.before : DOM(this.nodes.items).bound.append; - for (let [i, row] in this.context.getRows(range.start, range.end, + for (let [i, row] of this.context.getRows(range.start, range.end, this.doc)) { if (i < this.generatedRange.start) before(row); diff --git a/common/content/dactyl.js b/common/content/dactyl.js index a9f93574..f98c9692 100644 --- a/common/content/dactyl.js +++ b/common/content/dactyl.js @@ -1,6 +1,6 @@ // Copyright (c) 2006-2008 by Martin Stubenschrott // Copyright (c) 2007-2011 by Doug Kearns -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -47,7 +47,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { }, cleanup: function () { - for (let cleanup in values(this.cleanups)) + for (let cleanup of values(this.cleanups)) cleanup.call(this); delete window.dactyl; @@ -73,7 +73,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { // has :set go= or something similar in his config hideGUI: function () { let guioptions = config.guioptions; - for (let option in guioptions) { + for (let option of guioptions) { guioptions[option].forEach(function (elem) { try { document.getElementById(elem).collapsed = true; @@ -87,7 +87,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { "dactyl-cleanup": function dactyl_cleanup(subject, reason) { let modules = dactyl.modules; - for (let mod in values(modules.moduleList.reverse())) { + for (let mod of values(modules.moduleList.reverse())) { mod.stale = true; if ("cleanup" in mod) this.trapErrors("cleanup", mod, reason); @@ -97,7 +97,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { modules.moduleManager.initDependencies("cleanup"); - for (let name in values(Object.getOwnPropertyNames(modules).reverse())) + for (let name of values(Object.getOwnPropertyNames(modules).reverse())) try { delete modules[name]; } @@ -131,7 +131,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { if (~["menu", "menupopup"].indexOf(node.localName) && node.children.length) DOM(node).popupshowing({ bubbles: false }); - for (let [, item] in Iterator(node.childNodes)) { + for (let item of node.childNodes) { if (item.childNodes.length == 0 && item.localName == "menuitem" && !item.hidden && !/rdf:http:/.test(item.getAttribute("label"))) { // FIXME @@ -169,7 +169,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { get forceOpen() ({ background: this.forceBackground, target: this.forceTarget }), set forceOpen(val) { - for (let [k, v] in Iterator({ background: "forceBackground", target: "forceTarget" })) + for (let [k, v] of iter({ background: "forceBackground", target: "forceTarget" })) if (k in val) this[v] = val[k]; }, @@ -205,7 +205,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { }, registerObservers: function registerObservers(obj, prop) { - for (let [signal, func] in Iterator(obj[prop || "signals"])) + for (let [signal, func] of iter(obj[prop || "signals"])) this.registerObserver(signal, func.bind(obj), false); }, @@ -238,8 +238,11 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { let results = array(params.iterate(args)) .sort((a, b) => String.localeCompare(a.name, b.name)); - let filters = args.map(arg => let (re = util.regexp.escape(arg)) - util.regexp("\\b" + re + "\\b|(?:^|[()\\s])" + re + "(?:$|[()\\s])", "i")); + let filters = args.map(arg => { + let re = util.regexp.escape(arg); + return util.regexp("\\b" + re + "\\b|(?:^|[()\\s])" + re + "(?:$|[()\\s])", "i"); + }); + if (filters.length) results = results.filter(item => filters.every(re => keys(item).some(re.bound.test))); @@ -254,7 +257,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { context.ignoreCase = true; let seen = {}; context.completions = array(keys(item).join(" ").toLowerCase().split(/[()\s]+/) - for (item in params.iterate(args))) + for (item of params.iterate(args))) .flatten() .map(function (k) { seen[k] = (seen[k] || 0) + 1; @@ -265,11 +268,11 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { }); if (params.index) - this.indices[params.index] = function () { + this.indices[params.index] = function* () { let results = array((params.iterateIndex || params.iterate).call(params, commands.get(name).newArgs())) .array.sort((a, b) => String.localeCompare(a.name, b.name)); - for (let obj in values(results)) { + for (let obj of values(results)) { let res = dactyl.generateHelp(obj, null, null, true); if (!hasOwnProperty(help.tags, obj.helpTag)) res[0][1].tag = obj.helpTag; @@ -536,7 +539,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { if (!silent) commands.lastCommand = str.replace(/^\s*:\s*/, ""); let res = true; - for (let [command, args] in commands.parseCommands(str.replace(/^'(.*)'$/, "$1"))) { + for (let [command, args] of commands.parseCommands(str.replace(/^'(.*)'$/, "$1"))) { if (command === null) throw FailedAssertion(_("dactyl.notCommand", config.appName, args.commandString)); @@ -667,10 +670,12 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { else if (obj instanceof Map) { spec = map => (obj.count ? [["oa", {}, "count"], map] : DOM.DOMString(map)); - tag = map => [ - let (c = obj.modes[0].char) c ? c + "_" : "", - map - ]; + tag = map => { + let c = obj.modes[0].char; + return [c ? c + "_" : "", + map]; + }; + link = map => { let [, mode, name, extra] = /^(?:(.)_)?(?:<([^>]+)>)?(.*)$/.exec(map); let k = ["k", {}, extra]; @@ -700,17 +705,16 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { extraHelp ? extraHelp : "", !(extraHelp || obj.description) ? ["p", {}, /*L*/ "Sorry, no help available."] : ""]; + let name = (obj.specs || obj.names)[0]; res.push( ["item", {}, ["tags", {}, template.map(obj.names.slice().reverse(), tag, " ").join("")], - ["spec", {}, - let (name = (obj.specs || obj.names)[0]) - spec(template.highlightRegexp(tag(name), - /\[(.*?)\]/g, - (m, n0) => ["oa", {}, n0]), - name)], + ["spec", {}, spec(template.highlightRegexp(tag(name), + /\[(.*?)\]/g, + (m, n0) => ["oa", {}, n0]), + name)], !obj.type ? "" : [ ["type", {}, obj.type], ["default", {}, obj.stringDefaultValue]], @@ -790,13 +794,14 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { dactyl.echomsg( _("plugin.searchingForIn", - ("plugins/**/*.{js," + config.fileExtension + "}").quote(), - [dir.path.replace(/.plugins$/, "") for ([, dir] in Iterator(dirs))] - .join(",").quote()), + JSON.stringify("plugins/**/*.{js," + config.fileExtension + "}"), + JSON.stringify([dir.path.replace(/.plugins$/, "") + for (dir of dirs)] + .join(","))), 2); dirs.forEach(function (dir) { - dactyl.echomsg(_("plugin.searchingFor", (dir.path + "/**/*.{js," + config.fileExtension + "}").quote()), 3); + dactyl.echomsg(_("plugin.searchingFor", JSON.stringify(dir.path + "/**/*.{js," + config.fileExtension + "}")), 3); sourceDirectory(dir); }); }, @@ -909,7 +914,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { params = { where: params }; let flags = 0; - for (let [opt, flag] in Iterator({ replace: "REPLACE_HISTORY", hide: "BYPASS_HISTORY" })) + for (let [opt, flag] of iter({ replace: "REPLACE_HISTORY", hide: "BYPASS_HISTORY" })) flags |= params[opt] && Ci.nsIWebNavigation["LOAD_FLAGS_" + flag]; let where = params.where || dactyl.CURRENT_TAB; @@ -1220,7 +1225,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { // Process plugin help entries. let body = []; - for (let [, context] in Iterator(plugins.contexts)) + for (let context of values(plugins.contexts)) try { let info = contexts.getDocs(context); if (DOM.isJSONXML(info)) { @@ -1371,7 +1376,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { N: ["Tab number over icon", highlight.selector("TabIconNumber")] }, setter: function (opts) { - let classes = [v[1] for ([k, v] in Iterator(this.opts)) if (opts.indexOf(k) < 0)]; + let classes = [v[1] for ([k, v] of iter(this.opts)) if (opts.indexOf(k) < 0)]; styles.system.add("taboptions", "chrome://*", classes.length ? classes.join(",") + "{ display: none; }" : ""); @@ -1392,14 +1397,14 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { // FIXME: cleanup cleanupValue: config.cleanups.guioptions || - "rb" + [k for ([k, v] in iter(groups[1].opts)) + "rb" + [k for ([k, v] of iter(groups[1].opts)) if (!Dactyl.toolbarHidden(document.getElementById(v[1][0])))].join(""), - values: array(groups).map(g => [[k, v[0]] for ([k, v] in Iterator(g.opts))]) + values: array(groups).map(g => [[k, v[0]] for ([k, v] of iter(g.opts))]) .flatten(), setter: function (value) { - for (let group in values(groups)) + for (let group of values(groups)) group.setter(value); events.checkFocus(); return value; @@ -1494,7 +1499,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { config.dialogs[dialog][1](); } catch (e) { - dactyl.echoerr(_("error.cantOpen", dialog.quote(), e.message || e)); + dactyl.echoerr(_("error.cantOpen", JSON.stringify(dialog), e.message || e)); } }, { argCount: "1", @@ -1513,7 +1518,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { dactyl.assert(items.some(i => i.dactylPath == arg), _("emenu.notFound", arg)); - for (let [, item] in Iterator(items)) { + for (let item of items) { if (item.dactylPath == arg) { dactyl.assert(!item.disabled, _("error.disabled", item.dactylPath)); item.doCommand(); @@ -1716,7 +1721,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { let each, eachUnits, totalUnits; let total = 0; - for (let i in util.interruptibleRange(0, count, 500)) { + for (let i of util.interruptibleRange(0, count, 500)) { let now = Date.now(); func(); total += Date.now() - now; @@ -1843,7 +1848,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { completion.dialog = function dialog(context) { context.title = ["Dialog"]; context.filters.push(({ item }) => !item[2] || item[2]()); - context.completions = [[k, v[0], v[2]] for ([k, v] in Iterator(config.dialogs))]; + context.completions = [[k, v[0], v[2]] for ([k, v] of iter(config.dialogs))]; }; completion.menuItem = function menuItem(context) { @@ -1988,7 +1993,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { // after sourcing the initialization files, this function will set // all gui options to their default values, if they have not been // set before by any RC file - for (let option in values(options.needInit)) + for (let option of values(options.needInit)) option.initValue(); if (dactyl.commandLineOptions.postCommands) diff --git a/common/content/editor.js b/common/content/editor.js index 0bad993c..8344b7ed 100644 --- a/common/content/editor.js +++ b/common/content/editor.js @@ -245,7 +245,7 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), { range[container]); let delta = 0; - for (let node in Editor.TextsIterator(range)) { + for (let node of Editor.TextsIterator(range)) { let text = node.textContent; let start = 0, end = text.length; if (node == range.startContainer) @@ -427,7 +427,7 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), { column = 1 + pre.replace(/[^]*\n/, "").length; let origGroup = DOM(textBox).highlight.toString(); - let cleanup = promises.task(function cleanup(error) { + let cleanup = promises.task(function* cleanup(error) { if (timer) timer.cancel(); @@ -447,7 +447,7 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), { if (!keepFocus) dactyl.focus(textBox); - for (let group in values(blink.concat(blink, ""))) { + for (let group of values(blink.concat(blink, ""))) { highlight.highlightNode(textBox, origGroup + " " + group); yield promises.sleep(100); @@ -548,7 +548,7 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), { this.range = range; }, - __iterator__: function __iterator__() { + "@@iterator": function* __iterator__() { while (this.nextNode()) yield this.context; }, @@ -1122,14 +1122,15 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), { bind([""], "Edit text field in Text Edit mode", function () { dactyl.assert(!editor.isTextEdit && editor.editor); - dactyl.assert(dactyl.focusedElement || - // Sites like Google like to use a - // hidden, editable window for keyboard - // focus and use their own WYSIWYG editor - // implementations for the visible area, - // which we can't handle. - let (f = document.commandDispatcher.focusedWindow.frameElement) - f && Hints.isVisible(f, true)); + if (!dactyl.focusedElement) { + // Sites like Google like to use a + // hidden, editable window for keyboard + // focus and use their own WYSIWYG editor + // implementations for the visible area, + // which we can't handle. + let f = document.commandDispatcher.focusedWindow.frameElement; + dactyl.assert(f && Hints.isVisible(f, true)); + } modes.push(modes.TEXT_EDIT); }); @@ -1371,7 +1372,7 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), { has: function (key) util.compileMacro(this.value).seen.has(key), validator: function (value) { this.format({}, value); - let allowed = RealSet(["column", "file", "line"]); + let allowed = new RealSet(["column", "file", "line"]); return [k for (k of util.compileMacro(value).seen)] .every(k => allowed.has(k)); } @@ -1409,7 +1410,7 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), { persistent: true, action: function (timespan, host) { if (!host) { - for (let [k, v] in editor.registers) + for (let [k, v] of editor.registers) if (timespan.contains(v.timestamp)) editor.registers.remove(k); editor.registerRing.truncate(0); diff --git a/common/content/events.js b/common/content/events.js index 844a5b51..80599821 100644 --- a/common/content/events.js +++ b/common/content/events.js @@ -1,6 +1,6 @@ // Copyright (c) 2006-2008 by Martin Stubenschrott // Copyright (c) 2007-2011 by Doug Kearns -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -49,7 +49,7 @@ var EventHive = Class("EventHive", Contexts.Hive, { listen: function (target, event, callback, capture, allowUntrusted) { var [self, events] = this._events(event, callback); - for (let [event, callback] in Iterator(events)) { + for (let [event, callback] of iter(events)) { let args = [util.weakReference(target), util.weakReference(self), event, @@ -119,7 +119,7 @@ var Events = Module("events", { this._macros = storage.newMap("registers", { privateData: true, store: true }); if (storage.exists("macros")) { - for (let [k, m] in storage.newMap("macros", { store: true })) + for (let [k, m] of storage.newMap("macros", { store: true })) this._macros.set(k, { text: m.keys, timestamp: m.timeRecorded * 1000 }); storage.remove("macros"); } @@ -308,7 +308,7 @@ var Events = Module("events", { */ getMacros: function (filter) { let re = RegExp(filter || ""); - return ([k, m.text] for ([k, m] in editor.registers) if (re.test(k))); + return ([k, m.text] for ([k, m] of editor.registers) if (re.test(k))); }, /** @@ -319,7 +319,7 @@ var Events = Module("events", { */ deleteMacros: function (filter) { let re = RegExp(filter || ""); - for (let [item, ] in editor.registers) { + for (let [item, ] of editor.registers) { if (!filter || re.test(item)) editor.registers.remove(item); } @@ -373,10 +373,10 @@ var Events = Module("events", { if (quiet) commandline.quiet = quiet; - for (let [, evt_obj] in Iterator(DOM.Event.parse(keys))) { + for (let evt_obj of DOM.Event.parse(keys)) { let now = Date.now(); let key = DOM.Event.stringify(evt_obj); - for (let type in values(["keydown", "keypress", "keyup"])) { + for (let type of values(["keydown", "keypress", "keyup"])) { let evt = update({}, evt_obj, { type: type }); if (type !== "keypress" && !evt.keyCode) evt.keyCode = evt._keyCode || 0; @@ -475,13 +475,13 @@ var Events = Module("events", { .toObject(); outer: - for (let [, key] in iter(elements)) + for (let [, key] of iter(elements)) if (filters.some(([k, v]) => key.getAttribute(k) == v)) { let keys = { ctrlKey: false, altKey: false, shiftKey: false, metaKey: false }; let needed = { ctrlKey: event.ctrlKey, altKey: event.altKey, shiftKey: event.shiftKey, metaKey: event.metaKey }; let modifiers = (key.getAttribute("modifiers") || "").trim().split(/[\s,]+/); - for (let modifier in values(modifiers)) + for (let modifier of values(modifiers)) switch (modifier) { case "access": update(keys, access); break; case "accel": keys[accel] = true; break; @@ -489,7 +489,7 @@ var Events = Module("events", { case "any": if (!iter.some(keys, ([k, v]) => v && needed[k])) continue outer; - for (let [k, v] in iter(keys)) { + for (let [k, v] of iter(keys)) { if (v) needed[k] = false; keys[k] = false; @@ -677,7 +677,7 @@ var Events = Module("events", { let ourEvent = DOM.Event.feedingEvent; DOM.Event.feedingEvent = null; if (ourEvent) - for (let [k, v] in Iterator(ourEvent)) + for (let [k, v] of iter(ourEvent)) if (!(k in event)) event[k] = v; @@ -781,7 +781,7 @@ var Events = Module("events", { if (this.feedingKeys) this.duringFeed = this.duringFeed.concat(duringFeed); else - for (let event in values(duringFeed)) + for (let event of values(duringFeed)) try { DOM.Event.dispatch(event.originalTarget, event, event); } @@ -797,6 +797,8 @@ var Events = Module("events", { else if (!this.processor) this.keyEvents = []; + let key = DOM.Event.stringify(event); + let pass = this.passing && !event.isMacro || DOM.Event.feedingEvent && DOM.Event.feedingEvent.isReplay || event.isReplay || @@ -807,14 +809,13 @@ var Events = Module("events", { !modes.passThrough && this.shouldPass(event) || !this.processor && event.type === "keydown" && options.get("passunknown").getKey(modes.main.allBases) - && let (key = DOM.Event.stringify(event)) - !(modes.main.count && /^\d$/.test(key) || - modes.main.allBases.some( - mode => mappings.hives - .some(hive => hive.get(mode, key) - || hive.getCandidates(mode, key)))); - - events.dbg("ON " + event.type.toUpperCase() + " " + DOM.Event.stringify(event) + + && !(modes.main.count && /^\d$/.test(key) || + modes.main.allBases.some( + mode => mappings.hives + .some(hive => hive.get(mode, key) + || hive.getCandidates(mode, key)))); + + events.dbg("ON " + event.type.toUpperCase() + " " + key + " passing: " + this.passing + " " + " pass: " + pass + " replay: " + event.isReplay + @@ -924,12 +925,18 @@ var Events = Module("events", { if (elem == null && urlbar && urlbar.inputField == this._lastFocus.get()) util.threadYield(true); // Why? --Kris - while (modes.main.ownsFocus - && let ({ ownsFocus } = modes.topOfStack.params) - (!ownsFocus || - ownsFocus.get() != elem && - ownsFocus.get() != win) - && !modes.topOfStack.params.holdFocus) + let ownsFocus = () => { + if (!modes.main.ownsFocus) + return false; + + let { ownsFocus } = modes.topOfStack.params; + if (ownsFocus && ~[elem, win].indexOf(ownsFocus.get())) + return false; + + return !modes.topOfStack.params.holdFocus; + }; + + while (ownsFocus()) modes.pop(null, { fromFocus: true }); } finally { @@ -966,9 +973,10 @@ var Events = Module("events", { PASS_THROUGH: {}, WAIT: null, - isEscape: function isEscape(event) - let (key = isString(event) ? event : DOM.Event.stringify(event)) - key === "" || key === "", + isEscape: function isEscape(event) { + let key = isString(event) ? event : DOM.Event.stringify(event); + return key === "" || key === ""; + }, isHidden: function isHidden(elem, aggressive) { if (DOM(elem).style.visibility !== "visible") @@ -1033,7 +1041,7 @@ var Events = Module("events", { completion: function initCompletion() { completion.macro = function macro(context) { context.title = ["Macro", "Keys"]; - context.completions = [item for (item in events.getMacros())]; + context.completions = [item for (item of events.getMacros())]; }; }, mappings: function initMappings() { @@ -1140,7 +1148,7 @@ var Events = Module("events", { "sitemap", "", { flush: function flush() { memoize(this, "filters", function () this.value.filter(function (f) f(buffer.documentURI))); - memoize(this, "pass", function () RealSet(array.flatten(this.filters.map(function (f) f.keys)))); + memoize(this, "pass", function () new RealSet(array.flatten(this.filters.map(function (f) f.keys)))); memoize(this, "commandHive", function hive() Hive(this.filters, "command")); memoize(this, "inputHive", function hive() Hive(this.filters, "input")); }, diff --git a/common/content/hints.js b/common/content/hints.js index 4a39252a..781f06e5 100644 --- a/common/content/hints.js +++ b/common/content/hints.js @@ -179,7 +179,7 @@ var HintSession = Class("HintSession", CommandMode, { getHintNumber: function getHintNumber(str) { let base = this.hintKeys.length; let res = 0; - for (let char in values(str)) + for (let char of values(str)) res = res * base + this.hintKeys.indexOf(char); return res; }, @@ -286,7 +286,7 @@ var HintSession = Class("HintSession", CommandMode, { memoize(doc, "dactylLabels", () => iter([l.getAttribute("for"), l] - for (l in array.iterValues(doc.querySelectorAll("label[for]")))) + for (l of array.iterValues(doc.querySelectorAll("label[for]")))) .toObject()); let [offsetX, offsetY] = this.getContainerOffsets(doc); @@ -330,7 +330,7 @@ var HintSession = Class("HintSession", CommandMode, { let start = this.pageHints.length; let _hints = []; - for (let elem in res) + for (let elem of res) if (isVisible(elem) && (!mode.filter || mode.filter(elem))) _hints.push({ elem: elem, @@ -545,14 +545,14 @@ var HintSession = Class("HintSession", CommandMode, { * hint disappears. */ removeHints: function _removeHints(timeout) { - for (let { doc, start, end } in values(this.docs)) { + for (let { doc, start, end } of values(this.docs)) { DOM(doc.documentElement).highlight.remove("Hinting"); // Goddamn stupid fucking Gecko 1.x security manager bullshit. try { delete doc.dactylLabels; } catch (e) { doc.dactylLabels = undefined; } - for (let elem in DOM.XPath("//*[@dactyl:highlight='hints']", doc)) + for (let elem of DOM.XPath("//*[@dactyl:highlight='hints']", doc)) elem.parentNode.removeChild(elem); - for (let i in util.range(start, end + 1)) { + for (let i of util.range(start, end + 1)) { this.pageHints[i].ambiguous = false; this.pageHints[i].valid = false; } @@ -590,12 +590,12 @@ var HintSession = Class("HintSession", CommandMode, { let activeHint = this.hintNumber || 1; this.validHints = []; - for (let { doc, start, end } in values(this.docs)) { + for (let { doc, start, end } of values(this.docs)) { DOM(doc.documentElement).highlight.add("Hinting"); let [offsetX, offsetY] = this.getContainerOffsets(doc); inner: - for (let i in (util.interruptibleRange(start, end + 1, 500))) { + for (let i of util.interruptibleRange(start, end + 1, 500)) { if (this.showCount != count) return; @@ -644,13 +644,13 @@ var HintSession = Class("HintSession", CommandMode, { } let base = this.hintKeys.length; - for (let [i, hint] in Iterator(this.validHints)) + for (let [i, hint] of iter(this.validHints)) hint.ambiguous = (i + 1) * base <= this.validHints.length; if (options["usermode"]) { let css = []; - for (let hint in values(this.pageHints)) { - let selector = highlight.selector("Hint") + "[number=" + hint.span.getAttribute("number").quote() + "]"; + for (let hint of values(this.pageHints)) { + let selector = highlight.selector("Hint") + "[number=" + JSON.stringify(hint.span.getAttribute("number")) + "]"; let imgSpan = "[dactyl|hl=HintImage]"; css.push(selector + ":not(" + imgSpan + ") { " + hint.span.style.cssText + " }"); if (hint.imgSpan) @@ -699,7 +699,7 @@ var HintSession = Class("HintSession", CommandMode, { updateValidNumbers: function updateValidNumbers(always) { let string = this.getHintString(this.hintNumber); - for (let hint in values(this.validHints)) + for (let hint of values(this.validHints)) hint.valid = always || hint.span.getAttribute("number").startsWith(string); }, @@ -866,7 +866,7 @@ var Hints = Module("hints", { if (DOM(elem).isInput) return [elem.value, false]; else { - for (let [, option] in Iterator(options["hintinputs"])) { + for (let option of options["hintinputs"]) { if (option == "value") { if (elem instanceof Ci.nsIDOMHTMLSelectElement) { if (elem.selectedIndex >= 0) @@ -1022,7 +1022,7 @@ var Hints = Module("hints", { */ function stringsAtBeginningOfWords(strings, words, allowWordOverleaping) { let strIdx = 0; - for (let [, word] in Iterator(words)) { + for (let word of words) { if (word.length == 0) continue; @@ -1077,7 +1077,8 @@ var Hints = Module("hints", { autocomplete: false, completer: function (context) { context.compare = () => 0; - context.completions = [[k, v.prompt] for ([k, v] in Iterator(hints.modes))]; + context.completions = [[k, v.prompt] + for ([k, v] of iter(hints.modes))]; }, onCancel: mappings.bound.popCommand, onSubmit: function (arg) { @@ -1315,14 +1316,18 @@ var Hints = Module("hints", { { keepQuotes: true, - getKey: function (val, default_) - let (res = this.value.find(re => let (match = re.exec(val)) match && match[0] == val)) - res ? res.matcher - : default_, + getKey: function (val, default_) { + let res = this.value.find(re => { + let match = re.exec(val); + return match && match[0] == val; + }); + return res ? res.matcher + : default_; + }, parse: function parse(val) { let vals = parse.supercall(this, val); - for (let value in values(vals)) + for (let value of values(vals)) value.matcher = DOM.compileMatcher(Option.splitList(value.result)); return vals; }, diff --git a/common/content/history.js b/common/content/history.js index 5b2c6d3f..0e2883e6 100644 --- a/common/content/history.js +++ b/common/content/history.js @@ -21,7 +21,7 @@ var History = Module("history", { let query = services.history.getNewQuery(); let options = services.history.getNewQueryOptions(); - for (let [k, v] in Iterator(filter)) + for (let [k, v] of iter(filter)) query[k] = v; let res = /^([+-])(.+)/.exec(sort); @@ -65,9 +65,9 @@ var History = Module("history", { let obj = []; obj.__defineGetter__("index", () => sh.index); obj.__defineSetter__("index", function (val) { webNav.gotoIndex(val); }); - obj.__iterator__ = function () array.iterItems(this); + obj[Symbol.iterator] = function () array.iterItems(this); - for (let item in iter(sh.SHistoryEnumerator, Ci.nsISHEntry)) + for (let item of iter(sh.SHistoryEnumerator, Ci.nsISHEntry)) obj.push(update(Object.create(item), { index: obj.length, icon: Class.Memoize(function () services.favicon.getFaviconImageForPage(this.URI).spec) @@ -166,7 +166,7 @@ var History = Module("history", { return dactyl.open(items.map(i => i.url), dactyl.NEW_TAB); if (filter.length > 0) - dactyl.echoerr(_("history.noMatching", filter.quote())); + dactyl.echoerr(_("history.noMatching", JSON.stringify(filter))); else dactyl.echoerr(_("history.none")); return null; @@ -187,7 +187,7 @@ var History = Module("history", { if (/^\d+(:|$)/.test(url) && sh.index - parseInt(url) in sh) return void window.getWebNavigation().gotoIndex(sh.index - parseInt(url)); - for (let [i, ent] in Iterator(sh.slice(0, sh.index).reverse())) + for (let [i, ent] of iter(sh.slice(0, sh.index).reverse())) if (ent.URI.spec == url) return void window.getWebNavigation().gotoIndex(i); dactyl.echoerr(_("history.noURL")); @@ -229,7 +229,7 @@ var History = Module("history", { if (/^\d+(:|$)/.test(url) && sh.index + parseInt(url) in sh) return void window.getWebNavigation().gotoIndex(sh.index + parseInt(url)); - for (let [i, ent] in Iterator(sh.slice(sh.index + 1))) + for (let [i, ent] of iter(sh.slice(sh.index + 1))) if (ent.URI.spec == url) return void window.getWebNavigation().gotoIndex(i); dactyl.echoerr(_("history.noURL")); @@ -333,7 +333,7 @@ var History = Module("history", { // FIXME: Schema-specific context.generate = () => [ Array.slice(row.rev_host).reverse().join("").slice(1) - for (row in iter(services.history.DBConnection + for (row of iter(services.history.DBConnection .createStatement("SELECT DISTINCT rev_host FROM moz_places WHERE rev_host IS NOT NULL;"))) ].slice(2); }; diff --git a/common/content/key-processors.js b/common/content/key-processors.js index d1a51d21..5487d7cf 100644 --- a/common/content/key-processors.js +++ b/common/content/key-processors.js @@ -26,7 +26,7 @@ var ProcessorStack = Class("ProcessorStack", { .flatten().array; this.ownsBuffer = !this.processors.some(p => p.main.ownsBuffer); - for (let [i, input] in Iterator(this.processors)) { + for (let input of this.processors) { let params = input.main.params; if (params.preExecute) @@ -82,7 +82,7 @@ var ProcessorStack = Class("ProcessorStack", { // those waiting on further arguments. Execute actions as // long as they continue to return PASS. - for (var action in values(this.actions)) { + for (var action of values(this.actions)) { while (callable(action)) { length = action.eventLength; action = dactyl.trapErrors(action); @@ -171,7 +171,7 @@ var ProcessorStack = Class("ProcessorStack", { events.dbg("PROCESS(" + key + ") skipmap: " + event.skipmap + " macro: " + event.isMacro + " replay: " + event.isReplay); - for (let [i, input] in Iterator(this.processors)) { + for (let input of this.processors) { let res = input.process(event); if (res !== Events.ABORT) var result = res; @@ -197,14 +197,14 @@ var ProcessorStack = Class("ProcessorStack", { this._actions = actions; this.actions = actions.concat(this.actions); - for (let action in values(actions)) + for (let action of values(actions)) if (!("eventLength" in action)) action.eventLength = this.events.length; if (result === Events.KILL) this.actions = []; else if (!this.actions.length && !processors.length) - for (let input in values(this.processors)) + for (let input of values(this.processors)) if (input.fallthrough) { if (result === Events.KILL) break; diff --git a/common/content/mappings.js b/common/content/mappings.js index 5a1d6b26..11d73c9b 100644 --- a/common/content/mappings.js +++ b/common/content/mappings.js @@ -197,11 +197,11 @@ var MapHive = Class("MapHive", Contexts.Hive, { map.hive = this; if (this.name !== "builtin") - for (let [, name] in Iterator(map.names)) - for (let [, mode] in Iterator(map.modes)) + for (let name of map.names) + for (let mode of map.modes) this.remove(mode, name); - for (let mode in values(map.modes)) + for (let mode of values(map.modes)) this.getStack(mode).add(map); return map; }, @@ -255,13 +255,13 @@ var MapHive = Class("MapHive", Contexts.Hive, { */ remove: function (mode, cmd) { let stack = this.getStack(mode); - for (let [i, map] in array.iterItems(stack)) { + for (let map of stack) { let j = map.names.indexOf(cmd); if (j >= 0) { delete stack.states; map.names.splice(j, 1); if (map.names.length == 0) // FIX ME. - for (let [mode, stack] in Iterator(this.stacks)) + for (let [mode, stack] of iter(this.stacks)) this.stacks[mode] = MapHive.Stack(stack.filter(m => m != map)); return; } @@ -284,7 +284,7 @@ var MapHive = Class("MapHive", Contexts.Hive, { return self; }, - __iterator__: function () array.iterValues(this), + "@@iterator": function () array.iterValues(this), get candidates() this.states.candidates, get mappings() this.states.mappings, @@ -300,11 +300,11 @@ var MapHive = Class("MapHive", Contexts.Hive, { mappings: {} }; - for (let map in this) - for (let name in values(map.keys)) { + for (let map of this) + for (let name of values(map.keys)) { states.mappings[name] = map; let state = ""; - for (let key in DOM.Event.iterKeys(name)) { + for (let key of DOM.Event.iterKeys(name)) { state += key; if (state !== name) states.candidates[state] = (states.candidates[state] || 0) + 1; @@ -379,17 +379,17 @@ var Mappings = Module("mappings", { return keys; }, - iterate: function (mode) { - let seen = RealSet(); - for (let hive in this.hives.iterValues()) - for (let map in array(hive.getStack(mode)).iterValues()) + iterate: function* (mode) { + let seen = new RealSet; + for (let hive of this.hives.iterValues()) + for (let map of array(hive.getStack(mode)).iterValues()) if (!seen.add(map.name)) yield map; }, // NOTE: just normal mode for now /** @property {Iterator(Map)} */ - __iterator__: function () this.iterate(modes.NORMAL), + "@@iterator": function () this.iterate(modes.NORMAL), getDefault: deprecated("mappings.builtin.get", function getDefault(mode, cmd) this.builtin.get(mode, cmd)), getUserIterator: deprecated("mappings.user.iterator", function getUserIterator(modes) this.user.iterator(modes)), @@ -488,16 +488,19 @@ var Mappings = Module("mappings", { ["td", { style: "padding-right: 1em;" }, _("title.Command")], ["td", { style: "padding-right: 1em;" }, _("title.Action")]], ["col", { style: "min-width: 6em; padding-right: 1em;" }], - hives.map(([hive, maps]) => let (i = 0) [ - ["tr", { style: "height: .5ex;" }], - maps.map(map => - map.names.map(name => - ["tr", {}, - ["td", { highlight: "Title" }, !i++ ? hive.name : ""], - ["td", {}, modeSign], - ["td", {}, name], - ["td", {}, map.rhs || map.action.toSource()]])), - ["tr", { style: "height: .5ex;" }]])]; + hives.map(([hive, maps]) => { + let i = 0; + return [ + ["tr", { style: "height: .5ex;" }], + maps.map(map => + map.names.map(name => + ["tr", {}, + ["td", { highlight: "Title" }, !i++ ? hive.name : ""], + ["td", {}, modeSign], + ["td", {}, name], + ["td", {}, map.rhs || map.action.toSource()]])), + ["tr", { style: "height: .5ex;" }]]; + })]; // E4X-FIXME // // TODO: Move this to an ItemList to show this automatically @@ -631,16 +634,16 @@ var Mappings = Module("mappings", { literalArg: map.rhs, ignoreDefaults: true } - for (map in userMappings(hive)) + for (map of userMappings(hive)) if (map.persist) ]) .flatten().array; } }; - function userMappings(hive) { - let seen = RealSet(); - for (let stack in values(hive.stacks)) - for (let map in array.iterValues(stack)) + function* userMappings(hive) { + let seen = new RealSet; + for (let stack of values(hive.stacks)) + for (let map of array.iterValues(stack)) if (!seen.add(map.id)) yield map; } @@ -666,7 +669,7 @@ var Mappings = Module("mappings", { let mapmodes = array.uniq(args["-modes"].map(findMode)); let found = 0; - for (let mode in values(mapmodes)) + for (let mode of values(mapmodes)) if (args.bang) args["-group"].clear(mode); else if (args["-group"].has(mode, args[0])) { @@ -699,20 +702,20 @@ var Mappings = Module("mappings", { type: CommandOption.STRING, validator: function (value) Array.concat(value).every(findMode), completer: function () [[array.compact([mode.name.toLowerCase().replace(/_/g, "-"), mode.char]), mode.description] - for (mode in values(modes.all)) + for (mode of values(modes.all)) if (!mode.hidden)] }; function findMode(name) { if (name) - for (let mode in values(modes.all)) + for (let mode of values(modes.all)) if (name == mode || name == mode.char || String.toLowerCase(name).replace(/-/g, "_") == mode.name.toLowerCase()) return mode; return null; } function uniqueModes(modes) { - let chars = [k for ([k, v] in Iterator(modules.modes.modeChars)) + let chars = [k for ([k, v] of iter(modules.modes.modeChars)) if (v.every(mode => modes.indexOf(mode) >= 0))]; return array.uniq(modes.filter(m => chars.indexOf(m.char) < 0) @@ -736,25 +739,25 @@ var Mappings = Module("mappings", { addMapCommands("", [modes.NORMAL, modes.VISUAL], ""); - for (let mode in modes.mainModes) + for (let mode of modes.mainModes) if (mode.char && !commands.get(mode.char + "map", true)) addMapCommands(mode.char, - [m.mask for (m in modes.mainModes) if (m.char == mode.char)], + [m.mask for (m of modes.mainModes) if (m.char == mode.char)], mode.displayName); let args = { getMode: function (args) findMode(args["-mode"]), - iterate: function (args, mainOnly) { + iterate: function* (args, mainOnly) { let modes = [this.getMode(args)]; if (!mainOnly) modes = modes[0].allBases; - let seen = RealSet(); + let seen = new RealSet; // Bloody hell. --Kris - for (let [i, mode] in Iterator(modes)) - for (let hive in mappings.hives.iterValues()) - for (let map in array.iterValues(hive.getStack(mode))) - for (let name in values(map.names)) + for (let [i, mode] of iter(modes)) + for (let hive of mappings.hives.iterValues()) + for (let map of array.iterValues(hive.getStack(mode))) + for (let name of values(map.names)) if (!seen.add(name)) yield { name: name, @@ -775,8 +778,10 @@ var Mappings = Module("mappings", { : [], template.linkifyHelp(map.description + (map.rhs ? ": " + map.rhs : "")) ], - help: function (map) let (char = array.compact(map.modes.map(m => m.char))[0]) - char === "n" ? map.name : char ? char + "_" + map.name : "", + help: function (map) { + let char = array.compact(map.modes.map(m => m.char))[0]; + return char === "n" ? map.name : char ? char + "_" + map.name : ""; + }, headings: ["Command", "Mode", "Group", "Description"] } }; @@ -798,12 +803,15 @@ var Mappings = Module("mappings", { dactyl.addUsageCommand({ __proto__: args, name: [mode.char + "listk[eys]", mode.char + "lk"], - iterateIndex: function (args) - let (self = this, prefix = /^[bCmn]$/.test(mode.char) ? "" : mode.char + "_", - haveTag = k => hasOwnProperty(help.tags, k)) - ({ helpTag: prefix + map.name, __proto__: map } - for (map in self.iterate(args, true)) - if (map.hive === mappings.builtin || haveTag(prefix + map.name))), + iterateIndex: function (args) { + let self = this; + let prefix = /^[bCmn]$/.test(mode.char) ? "" : mode.char + "_"; + let haveTag = k => hasOwnProperty(help.tags, k); + + return ({ helpTag: prefix + map.name, __proto__: map } + for (map of self.iterate(args, true)) + if (map.hive === mappings.builtin || haveTag(prefix + map.name))); + }, description: "List all " + mode.displayName + " mode mappings along with their short descriptions", index: mode.char + "-map", getMode: function (args) mode, @@ -823,7 +831,7 @@ var Mappings = Module("mappings", { [ null, function (context, obj, args) [[m.names, m.description] - for (m in this.iterate(args[0]))] + for (m of this.iterate(args[0]))] ]); }, mappings: function initMappings(dactyl, modules, window) { diff --git a/common/content/marks.js b/common/content/marks.js index 7f6e256e..2d87bb50 100644 --- a/common/content/marks.js +++ b/common/content/marks.js @@ -181,7 +181,7 @@ var Marks = Module("marks", { let tab = mark.tab && mark.tab.get(); if (!tab || !tab.linkedBrowser || tabs.allTabs.indexOf(tab) == -1) - for ([, tab] in iter(tabs.visibleTabs, tabs.allTabs)) { + for ([, tab] of iter(tabs.visibleTabs, tabs.allTabs)) { if (tab.linkedBrowser.contentDocument.documentURI.replace(/#.*/, "") === mark.location) break; tab = null; @@ -205,7 +205,7 @@ var Marks = Module("marks", { a.length = b.length = Math.max(a.length, b.length); items = array(a).zip(b).flatten().compact(); - for (let i in items.iterValues()) { + for (let i of items.iterValues()) { let entry = sh.getEntryAtIndex(i, false); if (entry.URI.spec.replace(/#.*/, "") == mark.location) return void tab.linkedBrowser.webNavigation.gotoIndex(i); @@ -234,7 +234,7 @@ var Marks = Module("marks", { if (!mark.path) var node = buffer.findScrollable(0, (mark.offset || mark.position).x); else - for (node in DOM.XPath(mark.path, buffer.focusedFrame.document)) + for (node of DOM.XPath(mark.path, buffer.focusedFrame.document)) break; util.assert(node); @@ -260,7 +260,7 @@ var Marks = Module("marks", { if (filter.length > 0) { let pattern = util.charListToRegexp(filter, "a-zA-Z"); marks = marks.filter(([k]) => (pattern.test(k))); - dactyl.assert(marks.length > 0, _("mark.noMatching", filter.quote())); + dactyl.assert(marks.length > 0, _("mark.noMatching", JSON.stringify(filter))); } commandline.commandOutput( @@ -273,7 +273,7 @@ var Marks = Module("marks", { mark.offset ? Math.round(mark.offset.y) : Math.round(mark.position.y * 100) + "%", mark.location] - for ([, [name, mark]] in Iterator(marks))))); + for ([name, mark] of marks)))); }, _onPageLoad: function _onPageLoad(event) { @@ -388,18 +388,20 @@ var Marks = Module("marks", { contains: ["history"], action: function (timespan, host) { function matchhost(url) !host || util.isDomainURL(url, host); - function match(marks) (k for ([k, v] in Iterator(marks)) if (timespan.contains(v.timestamp) && matchhost(v.location))); + function match(marks) (k + for ([k, v] in iter(marks)) + if (timespan.contains(v.timestamp) && matchhost(v.location))); - for (let [url, local] in marks._localMarks) + for (let [url, local] of marks._localMarks) if (matchhost(url)) { - for (let key in match(local)) + for (let key of match(local)) delete local[key]; if (!Object.keys(local).length) marks._localMarks.remove(url); } marks._localMarks.changed(); - for (let key in match(marks._urlMarks)) + for (let key of match(marks._urlMarks)) marks._urlMarks.remove(key); } }); diff --git a/common/content/modes.js b/common/content/modes.js index d4cd2739..bd534030 100644 --- a/common/content/modes.js +++ b/common/content/modes.js @@ -1,6 +1,6 @@ // Copyright (c) 2006-2008 by Martin Stubenschrott // Copyright (c) 2007-2011 by Doug Kearns -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -150,7 +150,7 @@ var Modes = Module("modes", { dactyl.focusContent(true); if (prev.main == modes.NORMAL) { dactyl.focusContent(true); - for (let frame in values(buffer.allFrames())) { + for (let frame of values(buffer.allFrames())) { // clear any selection made let selection = frame.getSelection(); if (selection && !selection.isCollapsed) @@ -194,11 +194,13 @@ var Modes = Module("modes", { NONE: 0, - __iterator__: function __iterator__() array.iterValues(this.all), + "@@iterator": function __iterator__() array.iterValues(this.all), get all() this._modes.slice(), - get mainModes() (mode for ([k, mode] in Iterator(modes._modeMap)) if (!mode.extended && mode.name == k)), + get mainModes() (mode + for ([k, mode] of iter(modes._modeMap)) + if (!mode.extended && mode.name == k)), get mainMode() this._modeMap[this._main], @@ -236,7 +238,7 @@ var Modes = Module("modes", { dumpStack: function dumpStack() { util.dump("Mode stack:"); - for (let [i, mode] in array.iterItems(this._modeStack)) + for (let [i, mode] of array.iterItems(this._modeStack)) util.dump(" " + i + ": " + mode); }, @@ -283,7 +285,7 @@ var Modes = Module("modes", { save: function save(id, obj, prop, test) { if (!(id in this.boundProperties)) - for (let elem in array.iterValues(this._modeStack)) + for (let elem of array.iterValues(this._modeStack)) elem.saved[id] = { obj: obj, prop: prop, value: obj[prop], test: test }; this.boundProperties[id] = { obj: util.weakReference(obj), prop: prop, test: test }; }, @@ -328,7 +330,7 @@ var Modes = Module("modes", { dactyl.trapErrors("leave", this.topOfStack.params, { push: push }, push); - for (let [id, { obj, prop, test }] in Iterator(this.boundProperties)) { + for (let [id, { obj, prop, test }] of iter(this.boundProperties)) { obj = obj.get(); if (!obj) delete this.boundProperties[id]; @@ -346,7 +348,7 @@ var Modes = Module("modes", { }); if (stack && stack.pop) - for (let { obj, prop, value, test } in values(this.topOfStack.saved)) + for (let { obj, prop, value, test } of values(this.topOfStack.saved)) if (!test || !test(stack, prev)) dactyl.trapErrors(function () { obj[prop] = value }); @@ -442,10 +444,10 @@ var Modes = Module("modes", { this.allBases.indexOf(obj) >= 0 || callable(obj) && this instanceof obj, allBases: Class.Memoize(function () { - let seen = RealSet(), + let seen = new RealSet, res = [], queue = [this].concat(this.bases); - for (let mode in array.iterValues(queue)) + for (let mode of array.iterValues(queue)) if (!seen.add(mode)) { res.push(mode); queue.push.apply(queue, mode.bases); @@ -537,15 +539,15 @@ var Modes = Module("modes", { let tree = {}; - for (let mode in values(list)) + for (let mode of values(list)) tree[mode.name] = {}; - for (let mode in values(list)) - for (let base in values(mode.bases)) + for (let mode of values(list)) + for (let base of values(mode.bases)) tree[base.name][mode.name] = tree[mode.name]; let roots = iter([m.name, tree[m.name]] - for (m in values(list)) + for (m of values(list)) if (!m.bases.length)).toObject(); function rec(obj) { @@ -632,7 +634,7 @@ var Modes = Module("modes", { .every(k => hasOwnProperty(this.values, k)), get values() array.toObject([[m.name.toLowerCase(), m.description] - for (m in values(modes._modes)) if (!m.hidden)]) + for (m of values(modes._modes)) if (!m.hidden)]) }; options.add(["passunknown", "pu"], diff --git a/common/content/mow.js b/common/content/mow.js index d3889916..fa30fc22 100644 --- a/common/content/mow.js +++ b/common/content/mow.js @@ -1,6 +1,6 @@ // Copyright (c) 2006-2008 by Martin Stubenschrott // Copyright (c) 2007-2011 by Doug Kearns -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -69,6 +69,7 @@ var MOW = Module("mow", { __noSuchMethod__: function (meth, args) Buffer[meth].apply(Buffer, [this.body].concat(args)), get widget() this.widgets.multilineOutput, + widgets: Class.Memoize(function widgets() commandline.widgets), body: Class.Memoize(function body() this.widget.contentDocument.documentElement), @@ -94,7 +95,7 @@ var MOW = Module("mow", { leave: stack => { if (stack.pop) - for (let message in values(this.messages)) + for (let message of values(this.messages)) if (message.leave) message.leave(stack); }, @@ -198,7 +199,7 @@ var MOW = Module("mow", { selection: !window.document.commandDispatcher.focusedWindow.getSelection().isCollapsed }; - for (let node in array.iterValues(menu.children)) { + for (let node of array.iterValues(menu.children)) { let group = node.getAttributeNS(NS, "group"); node.hidden = group && !group.split(/\s+/).every(g => enabled[g]); } @@ -228,7 +229,7 @@ var MOW = Module("mow", { if (!(open || this.visible)) return; - let doc = this.widget.contentDocument; + let doc = this.document; let trim = this.spaceNeeded; let availableHeight = config.outputHeight - trim; @@ -270,7 +271,7 @@ var MOW = Module("mow", { if (!this.visible || !isinstance(modes.main, modes.OUTPUT_MULTILINE)) return this.widgets.message = null; - let elem = this.widget.contentDocument.documentElement; + let elem = this.document.documentElement; if (showHelp) this.widgets.message = ["MoreMsg", _("mow.moreHelp")]; diff --git a/common/content/quickmarks.js b/common/content/quickmarks.js index 0fc4dc3d..9073b994 100644 --- a/common/content/quickmarks.js +++ b/common/content/quickmarks.js @@ -1,6 +1,6 @@ // Copyright (c) 2006-2008 by Martin Stubenschrott // Copyright (c) 2007-2011 by Doug Kearns -// Copyright (c) 2008-2013 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -39,7 +39,7 @@ var QuickMarks = Module("quickmarks", { */ find: function find(url) { let res = []; - for (let [k, v] in this._qmarks) + for (let [k, v] of this._qmarks) if (dactyl.parseURLs(v).some(u => String.replace(u, /#.*/, "") == url)) res.push(k); return res; @@ -63,7 +63,7 @@ var QuickMarks = Module("quickmarks", { remove: function remove(filter) { let pattern = util.charListToRegexp(filter, "a-zA-Z0-9"); - for (let [qmark, ] in this._qmarks) { + for (let [qmark, ] of this._qmarks) { if (pattern.test(qmark)) this._qmarks.remove(qmark); } @@ -98,7 +98,7 @@ var QuickMarks = Module("quickmarks", { * @param {string} filter The list of quickmarks to display, e.g. "a-c i O-X". */ list: function list(filter) { - let marks = [k for ([k, v] in this._qmarks)]; + let marks = [k for ([k, v] of this._qmarks)]; let lowercaseMarks = marks.filter(bind("test", /[a-z]/)).sort(); let uppercaseMarks = marks.filter(bind("test", /[A-Z]/)).sort(); let numberMarks = marks.filter(bind("test", /[0-9]/)).sort(); @@ -110,11 +110,11 @@ var QuickMarks = Module("quickmarks", { if (filter.length > 0) { let pattern = util.charListToRegexp(filter, "a-zA-Z0-9"); marks = marks.filter(qmark => pattern.test(qmark)); - dactyl.assert(marks.length >= 0, _("quickmark.noMatching", filter.quote())); + dactyl.assert(marks.length >= 0, _("quickmark.noMatching", JSON.stringify(filter))); } commandline.commandOutput(template.tabular(["QuickMark", "URL"], [], - ([mark, quickmarks._qmarks.get(mark)] for ([k, mark] in Iterator(marks))))); + ([mark, quickmarks._qmarks.get(mark)] for (mark of marks)))); } }, { }, { diff --git a/common/content/statusline.js b/common/content/statusline.js index 20ecf1cd..c83a98db 100644 --- a/common/content/statusline.js +++ b/common/content/statusline.js @@ -1,6 +1,6 @@ // Copyright (c) 2006-2008 by Martin Stubenschrott // Copyright (c) 2007-2011 by Doug Kearns -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. diff --git a/common/content/tabs.js b/common/content/tabs.js index 308ca377..4bc436cc 100644 --- a/common/content/tabs.js +++ b/common/content/tabs.js @@ -1,6 +1,6 @@ // Copyright (c) 2006-2008 by Martin Stubenschrott // Copyright (c) 2007-2011 by Doug Kearns -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -42,7 +42,7 @@ var Tabs = Module("tabs", { false, true); this.timeout(function () { - for (let { linkedBrowser: { contentDocument } } in values(this.allTabs)) + for (let { linkedBrowser: { contentDocument } } of this.allTabs) if (contentDocument.readyState === "complete") dactyl.initDocument(contentDocument); }, 1000); @@ -61,9 +61,9 @@ var Tabs = Module("tabs", { _alternates: Class.Memoize(() => [config.tabbrowser.mCurrentTab, null]), cleanup: function cleanup() { - for (let [i, tab] in Iterator(this.allTabs)) { + for (let tab of this.allTabs) { let node = function node(class_) document.getAnonymousElementByAttribute(tab, "class", class_); - for (let elem in values(["dactyl-tab-icon-number", "dactyl-tab-number"].map(node))) + for (let elem of values(["dactyl-tab-icon-number", "dactyl-tab-number"].map(node))) if (elem) elem.parentNode.parentNode.removeChild(elem.parentNode); @@ -73,7 +73,7 @@ var Tabs = Module("tabs", { }, updateTabCount: function updateTabCount() { - for (let [i, tab] in Iterator(this.visibleTabs)) { + for (let [i, tab] of iter(this.visibleTabs)) { let node = function node(class_) document.getAnonymousElementByAttribute(tab, "class", class_); if (!node("dactyl-tab-number")) { let img = node("tab-icon-image"); @@ -101,7 +101,7 @@ var Tabs = Module("tabs", { statusline.updateTabCount(true); }, - _onTabSelect: function _onTabSelect() { + _onTabSelect: function* _onTabSelect() { // TODO: is all of that necessary? // I vote no. --Kris modes.reset(); @@ -214,7 +214,7 @@ var Tabs = Module("tabs", { */ // FIXME: Only called once...necessary? getContentIndex: function getContentIndex(content) { - for (let [i, browser] in this.browsers) { + for (let browser of this.browsers) { if (browser.contentWindow == content || browser.contentDocument == content) return i; } @@ -353,7 +353,7 @@ var Tabs = Module("tabs", { * @param {boolean} all If true, match against all tabs. If * false, match only tabs in the current tab group. */ - match: function match(filter, count, regexp, all) { + match: function* match(filter, count, regexp, all) { if (!filter && count == null) yield tabs.getTab(); else if (!filter) @@ -369,7 +369,7 @@ var Tabs = Module("tabs", { else var matcher = Styles.matchFilter(filter); - for (let tab in values(tabs[all ? "allTabs" : "visibleTabs"])) { + for (let tab of values(tabs[all ? "allTabs" : "visibleTabs"])) { let browser = tab.linkedBrowser; let uri = browser.currentURI; let title; @@ -510,7 +510,7 @@ var Tabs = Module("tabs", { * Stops loading all tabs. */ stopAll: function stopAll() { - for (let [, browser] in this.browsers) + for (let browser of this.browsers) browser.stop(); }, @@ -620,7 +620,7 @@ var Tabs = Module("tabs", { commands.add(params.name, params.description, function (args) { let removed = 0; - for (let tab in tabs.match(args[0], args.count, args.bang, !params.visible)) { + for (let tab of tabs.match(args[0], args.count, args.bang, !params.visible)) { config.removeTab(tab); removed++; } @@ -643,7 +643,7 @@ var Tabs = Module("tabs", { commands.add(["pin[tab]"], "Pin tab as an application tab", function (args) { - for (let tab in tabs.match(args[0], args.count)) + for (let tab of tabs.match(args[0], args.count)) config.browser[!args.bang || !tab.pinned ? "pinTab" : "unpinTab"](tab); }, { @@ -660,7 +660,7 @@ var Tabs = Module("tabs", { commands.add(["unpin[tab]"], "Unpin tab as an application tab", function (args) { - for (let tab in tabs.match(args[0], args.count)) + for (let tab of tabs.match(args[0], args.count)) config.browser.unpinTab(tab); }, { @@ -719,7 +719,7 @@ var Tabs = Module("tabs", { commands.add(["tabd[o]", "bufd[o]"], "Execute a command in each tab", function (args) { - for (let tab in values(tabs.visibleTabs)) { + for (let tab of values(tabs.visibleTabs)) { tabs.select(tab); dactyl.execute(args[0], null, true); } @@ -841,7 +841,7 @@ var Tabs = Module("tabs", { let arg = args[0]; if (tabs.indexFromSpec(arg) == -1) { - let list = [tab for (tab in tabs.match(args[0], args.count, true))]; + let list = [tab for (tab of tabs.match(args[0], args.count, true))]; dactyl.assert(list.length, _("error.invalidArgument", arg)); dactyl.assert(list.length == 1, _("buffer.multipleMatching", arg)); arg = list[0]; @@ -886,7 +886,7 @@ var Tabs = Module("tabs", { if (options.get("activate").has("tabopen")) activate = !activate; - for (let i in util.range(0, Math.max(1, args.count))) + for (let i of util.range(0, Math.max(1, args.count))) tabs.cloneTab(tab, activate); }, { argCount: "0", @@ -982,7 +982,7 @@ var Tabs = Module("tabs", { if (m) window.undoCloseTab(Number(m[1]) - 1); else if (args) { - for (let [i, item] in Iterator(tabs.closedTabs)) + for (let [i, item] of iter(tabs.closedTabs)) if (item.state.entries[item.state.index - 1].url == args) { window.undoCloseTab(i); return; @@ -1009,7 +1009,7 @@ var Tabs = Module("tabs", { commands.add(["undoa[ll]"], "Undo closing of all closed tabs", function (args) { - for (let i in Iterator(tabs.closedTabs)) + for (let i of iter(tabs.closedTabs)) window.undoCloseTab(0); }, @@ -1064,7 +1064,7 @@ var Tabs = Module("tabs", { context.compare = CompletionContext.Sort.number; context.filters[0] = CompletionContext.Filter.textDescription; - for (let [id, vals] in Iterator(tabGroups)) + for (let [id, vals] of iter(tabGroups)) context.fork(id, 0, this, function (context, [name, browsers]) { context.title = [name || "Buffers"]; context.generate = () => @@ -1111,7 +1111,7 @@ var Tabs = Module("tabs", { function callback() { tabs.timeout(function () { this.updateTabCount(); }); } - for (let event in values(["TabMove", "TabOpen", "TabClose"])) + for (let event of ["TabMove", "TabOpen", "TabClose"]) events.listen(tabContainer, event, callback, false); events.listen(tabContainer, "TabSelect", tabs.bound._onTabSelect, false); }, @@ -1257,13 +1257,13 @@ var Tabs = Module("tabs", { ]; options.add(["activate", "act"], "Define when newly created tabs are automatically activated", - "stringlist", [g[0] for (g in values(activateGroups.slice(1))) if (!g[2] || !prefs.get("browser.tabs." + g[2]))].join(","), + "stringlist", [g[0] for (g of values(activateGroups.slice(1))) if (!g[2] || !prefs.get("browser.tabs." + g[2]))].join(","), { values: activateGroups, has: Option.has.toggleAll, setter: function (newValues) { - let valueSet = RealSet(newValues); - for (let group in values(activateGroups)) + let valueSet = new RealSet(newValues); + for (let group of values(activateGroups)) if (group[2]) prefs.safeSet("browser.tabs." + group[2], !(valueSet.has("all") ^ valueSet.has(group[0])), @@ -1292,7 +1292,7 @@ var Tabs = Module("tabs", { { setter: function (values) { let open = 1, restriction = 0; - for (let [, opt] in Iterator(values)) { + for (let opt of values) { if (opt == "tab") open = 3; else if (opt == "window") diff --git a/common/modules/addons.jsm b/common/modules/addons.jsm index b42db8d7..60973dd7 100644 --- a/common/modules/addons.jsm +++ b/common/modules/addons.jsm @@ -54,7 +54,7 @@ var updateAddons = Class("UpgradeListener", AddonListener, { this.remaining = addons; this.upgrade = []; this.dactyl.echomsg(_("addon.check", addons.map(a => a.name).join(", "))); - for (let addon in values(addons)) + for (let addon of values(addons)) addon.findUpdates(this, AddonManager.UPDATE_WHEN_USER_REQUESTED, null, null); }, @@ -226,7 +226,7 @@ var Addon = Class("Addon", { this.nodes.description.textContent = this.description; DOM(this.nodes.row).attr("active", this.isActive || null); - for (let node in values(this.nodes)) + for (let node of values(this.nodes)) if (node.update && node.update !== callee) node.update(); @@ -394,7 +394,7 @@ var Addons = Module("addons", { else if (file.isReadable() && file.isFile()) AddonManager.getInstallForFile(file.file, install, "application/x-xpinstall"); else if (file.isDirectory()) - dactyl.echoerr(_("addon.cantInstallDir", file.path.quote())); + dactyl.echoerr(_("addon.cantInstallDir", JSON.stringify(file.path))); else dactyl.echoerr(_("io.notReadable", file.path)); }, { diff --git a/common/modules/base.jsm b/common/modules/base.jsm index 024be9d9..7e5de80c 100644 --- a/common/modules/base.jsm +++ b/common/modules/base.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 Kris Maglione +// Copyright (c) 2009-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -36,7 +36,7 @@ if (!("find" in Array.prototype)) configurable: true, writable: true, value: function Array_find(pred, self) { - for (let [i, elem] in Iterator(this)) + for (let [i, elem] of this.entries()) if (pred.call(self, elem, i, this)) return elem; } @@ -47,7 +47,7 @@ if (!("findIndex" in Array.prototype)) configurable: true, writable: true, value: function Array_findIndex(pred, self) { - for (let [i, elem] in Iterator(this)) + for (let [i, elem] of this.entries()) if (pred.call(self, elem, i, this)) return i; return -1; @@ -86,7 +86,7 @@ function defineModule(name, params, module) { defineModule.loadLog.push("[Begin " + name + "]"); defineModule.prefix += " "; - for (let [, mod] in Iterator(params.require || [])) + for (let mod of (params.require || [])) require(mod, module); module._lastModule = currentModule; @@ -105,13 +105,20 @@ Object.defineProperty(defineModule.loadLog, "push", { }); defineModule.prefix = ""; defineModule.dump = function dump_(...args) { - let msg = args.map(function (msg) { - if (loaded.util && typeof msg == "object") - msg = util.objectToString(msg); - return msg; - }).join(", "); - dump(String.replace(msg, /\n?$/, "\n") - .replace(/^./gm, JSMLoader.name + ": $&")); + try { + let msg = args.map(function (msg) { + if (loaded.util && typeof msg == "object") + msg = util.objectToString(msg); + return msg; + }).join(", "); + dump(String.replace(msg, /\n?$/, "\n") + .replace(/^./gm, JSMLoader.name + ": $&")); + } + catch (e) { + let msg = "Error dumping object: " + e + "\n" + (e && e.stack || Error.stack); + dump(String.replace(msg, /\n?$/, "\n") + .replace(/^./gm, JSMLoader.name + ": $&")); + } } defineModule.modules = []; defineModule.time = function time(major, minor, func, self, ...args) { @@ -175,6 +182,7 @@ defineModule("base", { "Cr", "Cs", "Cu", + "DOMPromise", "ErrorBase", "Finished", "JSMLoader", @@ -184,6 +192,7 @@ defineModule("base", { "Set", "Struct", "StructBase", + "Symbol", "TextEncoder", "TextDecoder", "Timer", @@ -191,6 +200,7 @@ defineModule("base", { "XPCOM", "XPCOMShim", "XPCOMUtils", + "apply", "array", "bind", "call", @@ -200,7 +210,6 @@ defineModule("base", { "defineModule", "deprecated", "endModule", - "forEach", "hasOwnProperty", "isArray", "isGenerator", @@ -209,12 +218,11 @@ defineModule("base", { "isSubclass", "isinstance", "iter", - "iterAll", "iterOwnProperties", "keys", "literal", "memoize", - "modujle", + "module", "octal", "properties", "require", @@ -232,6 +240,11 @@ this.lazyRequire("services", ["services"]); this.lazyRequire("storage", ["File"]); this.lazyRequire("util", ["FailedAssertion", "util"]); +if (typeof Symbol == "undefined") + this.Symbol = { + iterator: "@@iterator", + }; + literal.files = {}; literal.locations = {}; function literal(comment) { @@ -254,6 +267,12 @@ function literal(comment) { }); } +function apply(obj, meth, args) { + // The function's own apply method breaks in strange ways + // when using CPOWs. + Function.prototype.apply.call(obj[meth], obj, args); +} + /** * Iterates over the names of all of the top-level properties of an * object or, if prototypes is given, all of the properties in the @@ -269,13 +288,13 @@ function prototype(obj) XPCNativeWrapper.unwrap(obj).__proto__ || Object.getPrototypeOf(XPCNativeWrapper.unwrap(obj)); -function properties(obj, prototypes) { +function* properties(obj, prototypes) { let orig = obj; - let seen = RealSet(["dactylPropertyNames"]); + let seen = new RealSet(["dactylPropertyNames"]); try { if ("dactylPropertyNames" in obj && !prototypes) - for (let key in values(obj.dactylPropertyNames)) + for (let key of obj.dactylPropertyNames) if (key in obj && !seen.add(key)) yield key; } @@ -321,8 +340,8 @@ function properties(obj, prototypes) { } } -function iterOwnProperties(obj) { - for (let prop in properties(obj)) +function* iterOwnProperties(obj) { + for (let prop of properties(obj)) yield [prop, Object.getOwnPropertyDescriptor(obj, prop)]; } @@ -358,7 +377,7 @@ function deprecated(alternative, fn) { } deprecated.warn = function warn(func, name, alternative, frame) { if (!func.seenCaller) - func.seenCaller = RealSet([ + func.seenCaller = new RealSet([ "resource://dactyl/javascript.jsm", "resource://dactyl/util.jsm" ]); @@ -383,15 +402,13 @@ deprecated.warn = function warn(func, name, alternative, frame) { * @param {object} obj The object to inspect. * @returns {Generator} */ -function keys(obj) iter(function keys() { +function keys(obj) { if (isinstance(obj, ["Map"])) - for (let [k, v] of obj) - yield k; - else - for (var k in obj) - if (hasOwnProperty(obj, k)) - yield k; -}()); + return iter(obj.keys()); + + return iter(k for (k in obj) + if (hasOwnProperty(obj, k))); +} /** * Iterates over all of the top-level, iterable property values of an @@ -400,24 +417,19 @@ function keys(obj) iter(function keys() { * @param {object} obj The object to inspect. * @returns {Generator} */ -function values(obj) iter(function values() { +function values(obj) { if (isinstance(obj, ["Map"])) - for (let [k, v] of obj) - yield v; - else if (isinstance(obj, ["Generator", "Iterator", Iter])) - for (let k in obj) - yield k; - else if (iter.iteratorProp in obj) - for (let v of obj) - yield v; - else - for (var k in obj) - if (hasOwnProperty(obj, k)) - yield obj[k]; -}()); - -var forEach = deprecated("iter.forEach", function forEach() iter.forEach.apply(iter, arguments)); -var iterAll = deprecated("iter", function iterAll() iter.apply(null, arguments)); + return iter(obj.values()); + + if (isinstance(obj, ["Generator", "Iterator", Iter])) + return iter(k for (k of obj)); + + if (Symbol.iterator in obj) + return iter(obj[Symbol.iterator]()); + + return iter(obj[k] for (k in obj) + if (hasOwnProperty(obj, k))); +} var RealSet = Set; let Set_add = RealSet.prototype.add; @@ -436,7 +448,7 @@ Object.defineProperty(RealSet.prototype, "difference", { configurable: true, writable: true, value: function RealSet_difference(set) { - return RealSet(i for (i of this) if (!set.has(i))); + return new RealSet(i for (i of this) if (!set.has(i))); }, }); @@ -444,7 +456,7 @@ Object.defineProperty(RealSet.prototype, "intersection", { configurable: true, writable: true, value: function RealSet_intersection(set) { - return RealSet(i for (i of this) if (set.has(i))); + return new RealSet(i for (i of this) if (set.has(i))); }, }); @@ -452,7 +464,7 @@ Object.defineProperty(RealSet.prototype, "union", { configurable: true, writable: true, value: function RealSet_union(set) { - let res = RealSet(this); + let res = new RealSet(this); for (let item of set) res.add(item); return res; @@ -469,7 +481,7 @@ Object.defineProperty(RealSet.prototype, "union", { this.Set = deprecated("RealSet", function Set(ary) { let obj = {}; if (ary) - for (let val in values(ary)) + for (let val of values(ary)) obj[val] = true; return obj; }); @@ -519,7 +531,7 @@ Set.subtract = deprecated("RealSet#difference", function set_subtract(set) { set = update({}, set); for (let i = 1; i < arguments.length; i++) - for (let k in keys(arguments[i])) + for (let k of keys(arguments[i])) delete set[k]; return set; }); @@ -602,9 +614,11 @@ function curry(fn, length, self, acc) { return curried; } -var bind = function bind(meth, self, ...args) - let (func = callable(meth) ? meth : self[meth]) - func.bind.apply(func, [self].concat(args)); +var bind = function bind(meth, self, ...args) { + let func = callable(meth) ? meth : self[meth]; + + return func.bind.apply(func, [self].concat(args)); +} /** * Returns true if both arguments are functions and @@ -748,12 +762,11 @@ function memoize(obj, key, getter) { } } - let sandbox = Cu.Sandbox(Cc["@mozilla.org/systemprincipal;1"].createInstance(), - { wantGlobalProperties: ["TextDecoder", "TextEncoder"] }); -sandbox.__proto__ = this; + { wantGlobalProperties: ["TextDecoder", "TextEncoder"], + sandboxPrototype: this }); -var { TextEncoder, TextDecoder } = sandbox; +var { TextEncoder, TextDecoder, Promise: DOMPromise } = sandbox; /** * Updates an object with the properties of another object. Getters @@ -787,13 +800,21 @@ function update(target) { let func = desc.value.wrapped || desc.value; if (!func.superapply) { func.__defineGetter__("super", function get_super() Object.getPrototypeOf(target)[k]); - func.superapply = function superapply(self, args) - let (meth = Object.getPrototypeOf(target)[k]) - meth && meth.apply(self, args); - func.supercall = function supercall(self, ...args) - func.superapply(self, args); + + func.superapply = function superapply(self, args) { + let meth = Object.getPrototypeOf(target)[k]; + return meth && meth.apply(self, args); + } + + func.supercall = function supercall(self, ...args) { + return func.superapply(self, args); + } } } + + if (k.startsWith("@@") && k.slice(2) in Symbol) + k = Symbol[k.slice(2)]; + Object.defineProperty(target, k, desc); } catch (e) {} @@ -952,9 +973,9 @@ Class.Memoize = function Memoize(getter, wait) } }); - Task.spawn(function () { + Task.spawn(function* () { let wait; - for (var res in getter.call(obj)) { + for (var res of getter.call(obj)) { if (wait !== undefined) yield promises.sleep(wait); wait = res; @@ -981,8 +1002,6 @@ Class.Memoize = function Memoize(getter, wait) } }); -Class.memoize = deprecated("Class.Memoize", function memoize() Class.Memoize.apply(this, arguments)); - /** * Updates the given object with the object in the target class's * prototype. @@ -1025,7 +1044,7 @@ Class.prototype = { toString: function C_toString() { if (this.toStringParams) var params = "(" + this.toStringParams.map(m => (isArray(m) ? "[" + m + "]" : - isString(m) ? m.quote() : String(m))) + isString(m) ? JSON.stringify(m) : String(m))) .join(", ") + ")"; return "[instance " + this.constructor.className + (params || "") + "]"; }, @@ -1077,6 +1096,9 @@ Class.prototype = { for (let i = 0; i < arguments.length; i++) { let src = arguments[i]; Object.getOwnPropertyNames(src || {}).forEach((k) => { + if (k.startsWith("@@") && k.slice(2) in Symbol) + k = Symbol[k.slice(2)]; + let desc = Object.getOwnPropertyDescriptor(src, k); if (desc.value instanceof Class.Property) desc = desc.value.init(k, this) || desc.value; @@ -1098,6 +1120,9 @@ Class.prototype = { } try { + if (k.startsWith("@@") && k.slice(2) in Symbol) + k = Symbol[k.slice(2)]; + if ("value" in desc && (this.localizedProperties.has(k) || this.magicalProperties.has(k))) this[k] = desc.value; else @@ -1109,10 +1134,19 @@ Class.prototype = { return this; }, - localizedProperties: RealSet(), - magicalProperties: RealSet() + localizedProperties: new RealSet, + magicalProperties: new RealSet }; -for (let name in properties(Class.prototype)) { + +/* +Object.defineProperty(Class.prototype, Symbol.iterator, { + get: function () this.__iterator__, + set: function (val) { this.__iterator__ = val }, + configurable: true +}); +*/ + +for (let name of properties(Class.prototype)) { let desc = Object.getOwnPropertyDescriptor(Class.prototype, name); desc.enumerable = false; Object.defineProperty(Class.prototype, name, desc); @@ -1165,14 +1199,22 @@ function XPCOM(interfaces, superClass) { let shim = XPCOMShim(interfaces); - let res = Class("XPCOM(" + interfaces + ")", superClass || Class, - update(iter([k, - v === undefined || callable(v) ? stub : v] - for ([k, v] in Iterator(shim))).toObject(), - { QueryInterface: XPCOMUtils.generateQI(interfaces) })); + let base = { QueryInterface: XPCOMUtils.generateQI(interfaces) }; + + for (let [k, v] of iter(shim)) { + if (v === undefined || callable(v)) + base[k] = stub; + else + base[k] = v; + } + + let res = Class("XPCOM(" + interfaces + ")", + superClass || Class, + base); return res; } + function XPCOMShim(interfaces) { let ip = services.InterfacePointer({ QueryInterface: function (iid) { @@ -1336,9 +1378,9 @@ var StructBase = Class("StructBase", Array, { toString: function struct_toString() Class.prototype.toString.apply(this, arguments), // Iterator over our named members - __iterator__: function struct__iterator__() { - let self = this; - return ([k, self[k]] for (k in keys(self.members))) + "@@iterator": function* struct__iterator__() { + for (let k of keys(this.members)) + yield [k, this[k]]; } }, { fromArray: function fromArray(ary) { @@ -1486,59 +1528,60 @@ var octal = deprecated("octal integer literals", function octal(decimal) parseIn * @param {nsIJSIID} iface The interface to which to query all elements. * @returns {Generator} */ -iter.iteratorProp = "@@iterator" in [] ? "@@iterator" : "iterator"; function iter(obj, iface) { if (arguments.length == 2 && iface instanceof Ci.nsIJSIID) return iter(obj).map(item => item.QueryInterface(iface)); let args = arguments; - let res = Iterator(obj); + let res; if (args.length > 1) - res = (function () { + res = (function* () { for (let i = 0; i < args.length; i++) - for (let j in iter(args[i])) + for (let j of iter(args[i])) yield j; })(); - else if (isinstance(obj, ["Iterator", "Generator", "Array"])) - ; + else if (isinstance(obj, ["Array"])) + res = obj.entries(); + else if (Symbol.iterator in obj) + res = obj[Symbol.iterator](); else if (isinstance(obj, [Ci.nsIDOMHTMLCollection, Ci.nsIDOMNodeList])) res = array.iterItems(obj); - else if (iter.iteratorProp in obj && callable(obj[iter.iteratorProp]) && !("__iterator__" in obj)) - res = (x for (x of obj)); else if (ctypes && ctypes.CData && obj instanceof ctypes.CData) { while (obj.constructor instanceof ctypes.PointerType) obj = obj.contents; if (obj.constructor instanceof ctypes.ArrayType) res = array.iterItems(obj); else if (obj.constructor instanceof ctypes.StructType) - res = (function () { - for (let prop in values(obj.constructor.fields)) - yield let ([name, type] = Iterator(prop).next()) [name, obj[name]]; + res = (function* () { + for (let prop of values(obj.constructor.fields)) { + let [name, type] = Iterator(prop).next(); + yield [name, obj[name]]; + } })(); else return iter({}); } else if (Ci.nsIDOMNamedNodeMap && obj instanceof Ci.nsIDOMNamedNodeMap || Ci.nsIDOMMozNamedAttrMap && obj instanceof Ci.nsIDOMMozNamedAttrMap) - res = (function () { + res = (function* () { for (let i = 0; i < obj.length; i++) yield [obj.name, obj]; })(); else if (obj instanceof Ci.mozIStorageStatement) - res = (function (obj) { + res = (function* (obj) { while (obj.executeStep()) yield obj.row; obj.reset(); })(obj); else if ("getNext" in obj) { if ("hasMoreElements" in obj) - res = (function () { + res = (function* () { while (obj.hasMoreElements()) yield obj.getNext(); })(); else if ("hasMore" in obj) - res = (function () { + res = (function* () { while (obj.hasMore()) yield obj.getNext(); })(); @@ -1548,6 +1591,10 @@ function iter(obj, iface) { return iter(obj.enumerator()); return iter(obj.enumerator); } + + if (res === undefined) + res = Iterator(obj)[Symbol.iterator](); + return Iter(res); } update(iter, { @@ -1556,7 +1603,7 @@ update(iter, { // See array.prototype for API docs. toObject: function toObject(iter) { let obj = {}; - for (let [k, v] in iter) + for (let [k, v] of iter) if (v instanceof Class.Property) Object.defineProperty(obj, k, v.init(k, obj) || v); else @@ -1564,7 +1611,7 @@ update(iter, { return obj; }, - compact: function compact(iter) (item for (item in iter) if (item != null)), + compact: function compact(iter) (item for (item of iter) if (item != null)), every: function every(iter, pred, self) { pred = pred || util.identity; @@ -1581,7 +1628,7 @@ update(iter, { return false; }, - filter: function filter(iter, pred, self) { + filter: function* filter(iter, pred, self) { for (let elem of iter) if (pred.call(self, elem)) yield elem; @@ -1618,7 +1665,7 @@ update(iter, { * @param {function} func * @returns {Array} */ - map: function map(iter, func, self) { + map: function* map(iter, func, self) { for (let i of iter) yield func.call(self, i); }, @@ -1651,8 +1698,8 @@ update(iter, { sort: function sort(iter, fn, self) array(this.toArray(iter).sort(fn, self)), - uniq: function uniq(iter) { - let seen = RealSet(); + uniq: function* uniq(iter) { + let seen = new RealSet; for (let item of iter) if (!seen.add(item)) yield item; @@ -1666,7 +1713,7 @@ update(iter, { * @param {Array} ary2 * @returns {Array} */ - zip: function zip(iter1, iter2) { + zip: function* zip(iter1, iter2) { try { yield [iter1.next(), iter2.next()]; } @@ -1688,7 +1735,7 @@ const Iter = Class("Iter", { send: function send() this.iter.send.apply(this.iter, arguments), - __iterator__: function () this.iter + "@@iterator": function () this.iter, }); iter.Iter = Iter; @@ -1710,8 +1757,10 @@ function arrayWrap(fn) { */ var array = Class("array", Array, { init: function (ary) { - if (isinstance(ary, ["Iterator", "Generator"]) || "__iterator__" in ary) - ary = [k for (k in ary)]; + if (Symbol.iterator in ary) + ary = [k for (k of ary)]; + else if (isinstance(ary, ["Iterator", "Generator"]) || Symbol.iterator in ary) + ary = [k for (k of ary)]; else if (ary.length) ary = Array.slice(ary); @@ -1793,7 +1842,7 @@ var array = Class("array", Array, { * @param {Array} ary * @returns {Iterator(Object)} */ - iterValues: function iterValues(ary) { + iterValues: function* iterValues(ary) { for (let i = 0; i < ary.length; i++) yield ary[i]; }, @@ -1804,7 +1853,7 @@ var array = Class("array", Array, { * @param {Array} ary * @returns {Iterator([{number}, {Object}])} */ - iterItems: function iterItems(ary) { + iterItems: function* iterItems(ary) { let length = ary.length; for (let i = 0; i < length; i++) yield [i, ary[i]]; @@ -1815,7 +1864,7 @@ var array = Class("array", Array, { * given predicate. */ nth: function nth(ary, pred, n, self) { - for (let elem in values(ary)) + for (let elem of values(ary)) if (pred.call(self, elem) && n-- === 0) return elem; return undefined; @@ -1832,12 +1881,12 @@ var array = Class("array", Array, { uniq: function uniq(ary, unsorted) { let res = []; if (unsorted) { - for (let item in values(ary)) + for (let item of ary) if (res.indexOf(item) == -1) res.push(item); } else { - for (let [, item] in Iterator(ary.sort())) { + for (let item of ary.sort()) { if (item != last || !res.length) res.push(item); var last = item; @@ -1856,7 +1905,7 @@ var array = Class("array", Array, { */ zip: function zip(ary1, ary2) { let res = []; - for (let [i, item] in Iterator(ary1)) + for (let [i, item] of iter(ary1)) res.push([item, i in ary2 ? ary2[i] : ""]); return res; } diff --git a/common/modules/bookmarkcache.jsm b/common/modules/bookmarkcache.jsm index 66d056c8..b5f6613c 100644 --- a/common/modules/bookmarkcache.jsm +++ b/common/modules/bookmarkcache.jsm @@ -1,4 +1,4 @@ -// Copyright ©2008-2014 Kris Maglione +// Copyright ©2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -83,11 +83,13 @@ var BookmarkCache = Module("BookmarkCache", XPCOM(Ci.nsINavBookmarkObserver), { services.bookmarks.removeObserver(this); }, - __iterator__: function () (val for ([, val] in Iterator(bookmarkcache.bookmarks))), + "@@iterator": function () values(bookmarkcache.bookmarks), bookmarks: Class.Memoize(function () this.load()), - keywords: Class.Memoize(function () array.toObject([[b.keyword, b] for (b in this) if (b.keyword)])), + keywords: Class.Memoize(function () array.toObject([[b.keyword, b] + for (b of this) + if (b.keyword)])), rootFolders: ["toolbarFolder", "bookmarksMenuFolder", "unfiledBookmarksFolder"] .map(s => services.bookmarks[s]), @@ -123,7 +125,7 @@ var BookmarkCache = Module("BookmarkCache", XPCOM(Ci.nsINavBookmarkObserver), { get: function (url) { let ids = services.bookmarks.getBookmarkIdsForURI(newURI(url), {}); - for (let id in values(ids)) + for (let id of values(ids)) if (id in this.bookmarks) return this.bookmarks[id]; return null; diff --git a/common/modules/buffer.jsm b/common/modules/buffer.jsm index 839a7f7d..79c44281 100644 --- a/common/modules/buffer.jsm +++ b/common/modules/buffer.jsm @@ -1,6 +1,6 @@ // Copyright (c) 2006-2008 by Martin Stubenschrott // Copyright (c) 2007-2011 by Doug Kearns -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -77,8 +77,9 @@ var Buffer = Module("Buffer", { /** * Content preference methods. */ - prefs: Class.Memoize(function () - let (self = this) ({ + prefs: Class.Memoize(function () { + let self = this; + return { /** * Returns a promise for the given preference name. * @@ -132,7 +133,8 @@ var Buffer = Module("Buffer", { handleResult: resolve, handleError: reject }); }) - })), + }; + }), /** * Gets a content preference for the given buffer. @@ -495,15 +497,15 @@ var Buffer = Module("Buffer", { let relRev = ["next", "prev"]; let rev = relRev[1 - relRev.indexOf(rel)]; - function followFrame(frame) { - function iter(elems) { + function* followFrame(frame) { + function* iter(elems) { for (let i = 0; i < elems.length; i++) if (elems[i].rel.toLowerCase() === rel || elems[i].rev.toLowerCase() === rev) yield elems[i]; } let elems = frame.document.getElementsByTagName("link"); - for (let elem in iter(elems)) + for (let elem of iter(elems)) yield elem; function a(regexp, elem) regexp.test(elem.textContent) === regexp.result || @@ -516,14 +518,14 @@ var Buffer = Module("Buffer", { Hints.isVisible); for (let test of [a, b]) - for (let regexp in values(regexps)) - for (let i in util.range(res.length, 0, -1)) + for (let regexp of values(regexps)) + for (let i of util.range(res.length, 0, -1)) if (test(regexp, res[i])) yield res[i]; } - for (let frame in values(this.allFrames(null, true))) - for (let elem in followFrame(frame)) + for (let frame of values(this.allFrames(null, true))) + for (let elem of followFrame(frame)) if (count-- === 0) { if (follow) this.followLink(elem, dactyl.CURRENT_TAB); @@ -936,7 +938,7 @@ var Buffer = Module("Buffer", { if (!elem) { let area = -1; - for (let e in DOM(Buffer.SCROLLABLE_SEARCH_SELECTOR, + for (let e of DOM(Buffer.SCROLLABLE_SEARCH_SELECTOR, this.focusedFrame.document)) { if (Buffer.isScrollable(e, dir, horizontal)) { let r = DOM(e).rect; @@ -980,7 +982,7 @@ var Buffer = Module("Buffer", { if (win.scrollMaxX > 0 || win.scrollMaxY > 0) return win; - for (let frame in array.iterValues(win.frames)) + for (let frame of array.iterValues(win.frames)) if (frame.scrollMaxX > 0 || frame.scrollMaxY > 0) return frame; @@ -1011,7 +1013,7 @@ var Buffer = Module("Buffer", { : rect => rect.top; let elems = [[e, distance(e.getBoundingClientRect())] - for (e in path.matcher(this.focusedFrame.document))] + for (e of path.matcher(this.focusedFrame.document))] .filter(e => e[1] > FUDGE) .sort((a, b) => a[1] - b[1]); @@ -1048,9 +1050,12 @@ var Buffer = Module("Buffer", { // remove all hidden frames frames = frames.filter(frame => !(frame.document.body instanceof Ci.nsIDOMHTMLFrameSetElement)) - .filter(frame => !frame.frameElement || - let (rect = frame.frameElement.getBoundingClientRect()) - rect.width && rect.height); + .filter(frame => { + if (!frame.frameElement) + return false; + let rect = frame.frameElement.getBoundingClientRect(); + return rect.width && rect.height; + }); // find the currently focused frame index let current = Math.max(0, frames.indexOf(this.focusedFrame)); @@ -1115,7 +1120,7 @@ var Buffer = Module("Buffer", { if (bookmarkcache.isBookmarked(this.URL)) info += ", " + _("buffer.bookmarked"); - let pageInfoText = [file.quote(), " [", info, "] ", title].join(""); + let pageInfoText = [JSON.stringify(file), " [", info, "] ", title].join(""); dactyl.echo(pageInfoText, commandline.FORCE_SINGLELINE); return; } @@ -1357,7 +1362,7 @@ var Buffer = Module("Buffer", { /** * Updates the zoom level of this buffer from a content preference. */ - updateZoom: promises.task(function updateZoom() { + updateZoom: promises.task(function* updateZoom() { let uri = this.uri; if (prefs.get("browser.zoom.siteSpecific")) { @@ -1482,10 +1487,10 @@ var Buffer = Module("Buffer", { get ZOOM_MIN() prefs.get("zoom.minPercent"), get ZOOM_MAX() prefs.get("zoom.maxPercent"), - setZoom: deprecated("buffer.setZoom", function setZoom() - let ({ buffer } = overlay.activeModules) buffer.setZoom.apply(buffer, arguments)), - bumpZoomLevel: deprecated("buffer.bumpZoomLevel", function bumpZoomLevel() - let ({ buffer } = overlay.activeModules) buffer.bumpZoomLevel.apply(buffer, arguments)), + setZoom: deprecated("buffer.setZoom", + function setZoom(...args) apply(overlay.activeModules.buffer, "setZoom", args)), + bumpZoomLevel: deprecated("buffer.bumpZoomLevel", + function bumpZoomLevel(...args) apply(overlay.activeModules.buffer, "bumpZoomLevel", args)), /** * Returns the currently selected word in *win*. If the selection is @@ -1554,10 +1559,10 @@ var Buffer = Module("Buffer", { .replace(re, ext), title]); }, - findScrollableWindow: deprecated("buffer.findScrollableWindow", function findScrollableWindow() - let ({ buffer } = overlay.activeModules) buffer.findScrollableWindow.apply(buffer, arguments)), - findScrollable: deprecated("buffer.findScrollable", function findScrollable() - let ({ buffer } = overlay.activeModules) buffer.findScrollable.apply(buffer, arguments)), + findScrollableWindow: deprecated("buffer.findScrollableWindow", + function findScrollableWindow() apply(overlay.activeModules, "findScrollableWindow", arguments)), + findScrollable: deprecated("buffer.findScrollable", + function findScrollable() apply(overlay.activeModules, "findScrollable", arguments)), isScrollable: function isScrollable(elem, dir, horizontal) { if (!DOM(elem).isScrollable(horizontal ? "horizontal" : "vertical")) @@ -1632,40 +1637,43 @@ var Buffer = Module("Buffer", { * Like scrollTo, but scrolls more smoothly and does not update * marks. */ - smoothScrollTo: let (timers = WeakMap()) - function smoothScrollTo(node, x, y) { - let { options } = overlay.activeModules; + smoothScrollTo: new function () { + let timers = new WeakMap; - let time = options["scrolltime"]; - let steps = options["scrollsteps"]; + return function smoothScrollTo(node, x, y) { + let { options } = overlay.activeModules; - let elem = Buffer.Scrollable(node); + let time = options["scrolltime"]; + let steps = options["scrollsteps"]; - if (timers.has(node)) - timers.get(node).cancel(); - - if (x == null) - x = elem.scrollLeft; - if (y == null) - y = elem.scrollTop; - - x = node.dactylScrollDestX = Math.min(x, elem.scrollWidth - elem.clientWidth); - y = node.dactylScrollDestY = Math.min(y, elem.scrollHeight - elem.clientHeight); - let [startX, startY] = [elem.scrollLeft, elem.scrollTop]; - let n = 0; - (function next() { - if (n++ === steps) { - elem.scrollLeft = x; - elem.scrollTop = y; - delete node.dactylScrollDestX; - delete node.dactylScrollDestY; - } - else { - elem.scrollLeft = startX + (x - startX) / steps * n; - elem.scrollTop = startY + (y - startY) / steps * n; - timers.set(node, util.timeout(next, time / steps)); - } - }).call(this); + let elem = Buffer.Scrollable(node); + + if (timers.has(node)) + timers.get(node).cancel(); + + if (x == null) + x = elem.scrollLeft; + if (y == null) + y = elem.scrollTop; + + x = node.dactylScrollDestX = Math.min(x, elem.scrollWidth - elem.clientWidth); + y = node.dactylScrollDestY = Math.min(y, elem.scrollHeight - elem.clientHeight); + let [startX, startY] = [elem.scrollLeft, elem.scrollTop]; + let n = 0; + (function next() { + if (n++ === steps) { + elem.scrollLeft = x; + elem.scrollTop = y; + delete node.dactylScrollDestX; + delete node.dactylScrollDestY; + } + else { + elem.scrollLeft = startX + (x - startX) / steps * n; + elem.scrollTop = startY + (y - startY) / steps * n; + timers.set(node, util.timeout(next, time / steps)); + } + }).call(this); + }; }, /** @@ -1946,7 +1954,7 @@ var Buffer = Module("Buffer", { if (/^>>/.test(filename)) { let file = io.File(filename.replace(/^>>\s*/, "")); dactyl.assert(args.bang || file.exists() && file.isWritable(), - _("io.notWriteable", file.path.quote())); + _("io.notWriteable", JSON.stringify(file.path))); return buffer.viewSourceExternally(buffer.focusedFrame.document, function (tmpFile) { @@ -1954,7 +1962,7 @@ var Buffer = Module("Buffer", { file.write(tmpFile, ">>"); } catch (e) { - dactyl.echoerr(_("io.notWriteable", file.path.quote())); + dactyl.echoerr(_("io.notWriteable", JSON.stringify(file.path))); } }); } @@ -2046,13 +2054,13 @@ var Buffer = Module("Buffer", { context.title = ["Stylesheet", "Location"]; // unify split style sheets - let styles = iter([s.title, []] for (s in values(buffer.alternateStyleSheets))).toObject(); + let styles = iter([s.title, []] for (s of values(buffer.alternateStyleSheets))).toObject(); buffer.alternateStyleSheets.forEach(function (style) { styles[style.title].push(style.href || _("style.inline")); }); - context.completions = [[title, href.join(", ")] for ([title, href] in Iterator(styles))]; + context.completions = [[title, href.join(", ")] for ([title, href] of iter(styles))]; }; completion.savePage = function savePage(context, node) { @@ -2131,7 +2139,7 @@ var Buffer = Module("Buffer", { "Repeat the last key event", function ({ count }) { if (mappings.repeat) { - for (let i in util.interruptibleRange(0, Math.max(count, 1), 100)) + for (let i of util.interruptibleRange(0, Math.max(count, 1), 100)) mappings.repeat(); } }, @@ -2304,7 +2312,7 @@ var Buffer = Module("Buffer", { let frames = buffer.allFrames(null, true); - let elements = array.flatten(frames.map(win => [m for (m in DOM.XPath(xpath, win.document))])) + let elements = array.flatten(frames.map(win => [m for (m of DOM.XPath(xpath, win.document))])) .filter(function (elem) { if (isinstance(elem, [Ci.nsIDOMHTMLFrameElement, Ci.nsIDOMHTMLIFrameElement])) @@ -2450,7 +2458,7 @@ var Buffer = Module("Buffer", { return val; // Stolen from browser.jar/content/browser/browser.js, more or less. - Task.spawn(function () { + Task.spawn(function* () { try { buffer.docShell.QueryInterface(Ci.nsIDocCharset).charset = val; yield window.PlacesUtils.setCharsetForURI(buffer.uri, val); @@ -2483,7 +2491,7 @@ var Buffer = Module("Buffer", { { keepQuotes: true, setter: function (vals) { - for (let [k, v] in Iterator(vals)) + for (let [k, v] of iter(vals)) vals[k] = update(new String(v), { matcher: DOM.compileMatcher(Option.splitList(v)) }); return vals; }, @@ -2507,7 +2515,7 @@ var Buffer = Module("Buffer", { { getLine: function getLine(doc, line) { let uri = util.newURI(doc.documentURI); - for (let filter in values(this.value)) + for (let filter of values(this.value)) if (filter(uri, doc)) { if (/^func:/.test(filter.result)) var res = dactyl.userEval("(" + Option.dequote(filter.result.substr(5)) + ")")(doc, line); @@ -2526,7 +2534,7 @@ var Buffer = Module("Buffer", { keepQuotes: true, setter: function (vals) { - for (let value in values(vals)) + for (let value of values(vals)) if (!/^func:/.test(value.result)) value.matcher = DOM.compileMatcher(Option.splitList(value.result)); return vals; @@ -2610,16 +2618,16 @@ var Buffer = Module("Buffer", { } }); -Buffer.addPageInfoSection("e", "Search Engines", function (verbose) { +Buffer.addPageInfoSection("e", "Search Engines", function* (verbose) { let n = 1; let nEngines = 0; - for (let { document: doc } in values(this.allFrames())) { + for (let { document: doc } of values(this.allFrames())) { let engines = DOM("link[href][rel=search][type='application/opensearchdescription+xml']", doc); nEngines += engines.length; if (verbose) - for (let link in engines) + for (let link of engines) yield [link.title || /*L*/ "Engine " + n++, ["a", { href: link.href, highlight: "URL", onclick: "if (event.button == 0) { window.external.AddSearchProvider(this.href); return false; }" }, @@ -2630,7 +2638,7 @@ Buffer.addPageInfoSection("e", "Search Engines", function (verbose) { yield nEngines + /*L*/" engine" + (nEngines > 1 ? "s" : ""); }); -Buffer.addPageInfoSection("f", "Feeds", function (verbose) { +Buffer.addPageInfoSection("f", "Feeds", function* (verbose) { const feedTypes = { "application/rss+xml": "RSS", "application/atom+xml": "Atom", @@ -2669,10 +2677,10 @@ Buffer.addPageInfoSection("f", "Feeds", function (verbose) { } let nFeed = 0; - for (let [i, win] in Iterator(this.allFrames())) { + for (let win of this.allFrames()) { let doc = win.document; - for (let link in DOM("link[href][rel=feed], link[href][rel=alternate][type]", doc)) { + for (let link of DOM("link[href][rel=feed], link[href][rel=alternate][type]", doc)) { let rel = link.rel.toLowerCase(); let feed = { title: link.title, href: link.href, type: link.type || "" }; if (isValidFeed(feed, doc.nodePrincipal, rel == "feed")) { @@ -2690,7 +2698,7 @@ Buffer.addPageInfoSection("f", "Feeds", function (verbose) { yield nFeed + /*L*/" feed" + (nFeed > 1 ? "s" : ""); }); -Buffer.addPageInfoSection("g", "General Info", function (verbose) { +Buffer.addPageInfoSection("g", "General Info", function* (verbose) { let doc = this.focusedFrame.document; // get file size @@ -2758,7 +2766,7 @@ Buffer.addPageInfoSection("m", "Meta Tags", function (verbose) { .sort((a, b) => util.compareIgnoreCase(a[0], b[0])); }); -Buffer.addPageInfoSection("s", "Security", function (verbose) { +Buffer.addPageInfoSection("s", "Security", function* (verbose) { let { statusline } = this.modules; let identity = this.topWindow.gIdentityHandler; diff --git a/common/modules/cache.jsm b/common/modules/cache.jsm index 398d3c9d..fbb8013d 100644 --- a/common/modules/cache.jsm +++ b/common/modules/cache.jsm @@ -18,8 +18,8 @@ var Cache = Module("Cache", XPCOM(Ci.nsIRequestObserver), { this.storage = storage.newMap("cache", { store: true }); this.providers = {}; this.globalProviders = this.providers; - this.providing = RealSet(); - this.localProviders = RealSet(); + this.providing = new RealSet; + this.localProviders = new RealSet; if (JSMLoader.cacheFlush) this.flush(); diff --git a/common/modules/commands.jsm b/common/modules/commands.jsm index 0e58b6b0..297bd0e1 100644 --- a/common/modules/commands.jsm +++ b/common/modules/commands.jsm @@ -1,6 +1,6 @@ // Copyright (c) 2006-2008 by Martin Stubenschrott // Copyright (c) 2007-2011 by Doug Kearns -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -172,7 +172,7 @@ var Command = Class("Command", { return !dactyl.trapErrors(function exec() { let extra = this.hive.argsExtra(args); - for (let k in properties(extra)) + for (let k of properties(extra)) if (!(k in args)) Object.defineProperty(args, k, Object.getOwnPropertyDescriptor(extra, k)); @@ -204,13 +204,14 @@ var Command = Class("Command", { * @returns {Args} * @see Commands#parseArgs */ - parseArgs: function parseArgs(args, complete, extra) this.modules.commands.parseArgs(args, { - __proto__: this, - complete: complete, - extra: extra - }), + parseArgs: function parseArgs(args, complete, extra) + this.modules.commands.parseArgs(args, { + __proto__: this, + complete: complete, + extra: extra + }), - complained: Class.Memoize(function () RealSet()), + complained: Class.Memoize(() => new RealSet), /** * @property {[string]} All of this command's name specs. e.g., "com[mand]" @@ -311,16 +312,13 @@ var Command = Class("Command", { .flatten().toObject()), newArgs: function newArgs(base) { - let res = []; + let res = Object.create(this.argsPrototype); update(res, base); - res.__proto__ = this.argsPrototype; return res; }, argsPrototype: Class.Memoize(function argsPrototype() { let res = update([], { - __iterator__: function AP__iterator__() array.iterItems(this), - command: this, explicitOpts: Class.Memoize(function () ({})), @@ -442,7 +440,7 @@ var Ex = Module("Ex", { let res = cmd.newArgs({ context: this.context }); if (isObject(args[0])) - for (let [k, v] in Iterator(args.shift())) + for (let [k, v] of iter(args.shift())) if (k == "!") res.bang = v; else if (k == "#") @@ -457,18 +455,19 @@ var Ex = Module("Ex", { Class.replaceProperty(res, opt.names[0], val); res.explicitOpts[opt.names[0]] = val; } - for (let [i, val] in array.iterItems(args)) + for (let [i, val] of array.iterItems(args)) res[i] = String(val); return res; }, - _complete: function E_complete(cmd) let (self = this) - function _complete(context, func, obj, args) { - args = self._args(cmd, args); + _complete: function E_complete(cmd) { + return (context, func, obj, args) => { + args = this._args(cmd, args); args.completeArg = args.length - 1; if (cmd.completer && args.length) return cmd.completer(context, args); - }, + }; + }, _run: function E_run(name) { const self = this; @@ -509,7 +508,7 @@ var CommandHive = Class("CommandHive", Contexts.Hive, { this.modules.moduleManager.initDependencies("commands"); let map = {}; - for (let [name, cmd] in Iterator(this._map)) + for (let [name, cmd] of iter(this._map)) if (cmd.sourceModule) map[name] = { sourceModule: cmd.sourceModule, isPlaceholder: true }; @@ -524,7 +523,7 @@ var CommandHive = Class("CommandHive", Contexts.Hive, { cached = cache.get(this.cacheKey); if (this.cached) { this._specs = cached.specs; - for (let [k, v] in Iterator(cached.map)) + for (let [k, v] of iter(cached.map)) this._map[k] = v; } }, @@ -532,7 +531,7 @@ var CommandHive = Class("CommandHive", Contexts.Hive, { get cacheKey() "commands/hives/" + this.name + ".json", /** @property {Iterator(Command)} @private */ - __iterator__: function __iterator__() { + "@@iterator": function __iterator__() { if (this.cached) this.modules.initDependencies("commands"); this.cached = false; @@ -577,7 +576,7 @@ var CommandHive = Class("CommandHive", Contexts.Hive, { _("command.wontReplace", name)); } - for (let name in values(names)) { + for (let name of values(names)) { ex.__defineGetter__(name, function () this._run(name)); if (name in this._map && !this._map[name].isPlaceholder) this.remove(name); @@ -588,7 +587,7 @@ var CommandHive = Class("CommandHive", Contexts.Hive, { memoize(this._map, name, () => commands.Command(specs, description, action, extra)); if (!extra.hidden) memoize(this._list, this._list.length, closure); - for (let alias in values(names.slice(1))) + for (let alias of values(names.slice(1))) memoize(this._map, alias, closure); return name; @@ -648,7 +647,7 @@ var CommandHive = Class("CommandHive", Contexts.Hive, { let cmd = this.get(name); this._list = this._list.filter(c => c !== cmd); - for (let name in values(cmd.names)) + for (let name of values(cmd.names)) delete this._map[name]; } }); @@ -660,144 +659,153 @@ var Commands = Module("commands", { lazyInit: true, lazyDepends: true, - Local: function Local(dactyl, modules, window) let ({ Group, contexts } = modules) ({ - init: function init() { - this.Command = Class("Command", Command, { modules: modules }); - update(this, { - hives: contexts.Hives("commands", Class("CommandHive", CommandHive, { modules: modules })), - user: contexts.hives.commands.user, - builtin: contexts.hives.commands.builtin - }); - }, + Local: function Local(dactyl, modules, window) { + let { Group, contexts } = modules; + return { + init: function init() { + this.Command = Class("Command", Command, { modules: modules }); + update(this, { + hives: contexts.Hives("commands", Class("CommandHive", CommandHive, { modules: modules })), + user: contexts.hives.commands.user, + builtin: contexts.hives.commands.builtin + }); + }, - reallyInit: function reallyInit() { - if (false) - this.builtin.cache(); - else - this.modules.moduleManager.initDependencies("commands"); - }, - - get context() contexts.context, - - get readHeredoc() modules.io.readHeredoc, - - get allHives() contexts.allGroups.commands, - - get userHives() this.allHives.filter(h => h !== this.builtin), - - /** - * Executes an Ex command script. - * - * @param {string} string A string containing the commands to execute. - * @param {object} tokens An optional object containing tokens to be - * interpolated into the command string. - * @param {object} args Optional arguments object to be passed to - * command actions. - * @param {object} context An object containing information about - * the file that is being or has been sourced to obtain the - * command string. - */ - execute: function execute(string, tokens, silent, args, context) { - contexts.withContext(context || this.context || { file: "[Command Line]", line: 1 }, - function (context) { - modules.io.withSavedValues(["readHeredoc"], function () { - this.readHeredoc = function readHeredoc(end) { - let res = []; - contexts.context.line++; - while (++i < lines.length) { - if (lines[i] === end) - return res.join("\n"); - res.push(lines[i]); - } - util.assert(false, _("command.eof", end)); - }; + reallyInit: function reallyInit() { + if (false) + this.builtin.cache(); + else + this.modules.moduleManager.initDependencies("commands"); + }, - args = update({}, args || {}); + get context() contexts.context, + + get readHeredoc() modules.io.readHeredoc, + + get allHives() contexts.allGroups.commands, + + get userHives() this.allHives.filter(h => h !== this.builtin), + + /** + * Executes an Ex command script. + * + * @param {string} string A string containing the commands to execute. + * @param {object} tokens An optional object containing tokens to be + * interpolated into the command string. + * @param {object} args Optional arguments object to be passed to + * command actions. + * @param {object} context An object containing information about + * the file that is being or has been sourced to obtain the + * command string. + */ + execute: function execute(string, tokens, silent, args, context) { + contexts.withContext(context || this.context || { file: "[Command Line]", line: 1 }, + function (context) { + modules.io.withSavedValues(["readHeredoc"], function () { + this.readHeredoc = function readHeredoc(end) { + let res = []; + contexts.context.line++; + while (++i < lines.length) { + if (lines[i] === end) + return res.join("\n"); + res.push(lines[i]); + } + util.assert(false, _("command.eof", end)); + }; - if (tokens && !callable(string)) - string = util.compileMacro(string, true); - if (callable(string)) - string = string(tokens || {}); + args = update({}, args || {}); - let lines = string.split(/\r\n|[\r\n]/); - let startLine = context.line; + if (tokens && !callable(string)) + string = util.compileMacro(string, true); + if (callable(string)) + string = string(tokens || {}); - for (var i = 0; i < lines.length && !context.finished; i++) { - // Deal with editors from Silly OSs. - let line = lines[i].replace(/\r$/, ""); + let lines = string.split(/\r\n|[\r\n]/); + let startLine = context.line; - context.line = startLine + i; + for (var i = 0; i < lines.length && !context.finished; i++) { + // Deal with editors from Silly OSs. + let line = lines[i].replace(/\r$/, ""); - // Process escaped new lines - while (i < lines.length && /^\s*\\/.test(lines[i + 1])) - line += "\n" + lines[++i].replace(/^\s*\\/, ""); + context.line = startLine + i; - try { - dactyl.execute(line, args); - } - catch (e) { - if (!silent) { - e.message = context.file + ":" + context.line + ": " + e.message; - dactyl.reportError(e, true); + // Process escaped new lines + while (i < lines.length && /^\s*\\/.test(lines[i + 1])) + line += "\n" + lines[++i].replace(/^\s*\\/, ""); + + try { + dactyl.execute(line, args); + } + catch (e) { + if (!silent) { + e.message = context.file + ":" + context.line + ": " + e.message; + dactyl.reportError(e, true); + } } } - } + }); }); - }); - }, - - /** - * Lists all user-defined commands matching *filter* and optionally - * *hives*. - * - * @param {string} filter Limits the list to those commands with a name - * matching this anchored substring. - * @param {[Hive]} hives List of hives. - * @optional - */ - list: function list(filter, hives) { - const { commandline, completion } = this.modules; - function completerToString(completer) { - if (completer) - return [k for ([k, v] in Iterator(config.completers)) if (completer == completion.bound[v])][0] || "custom"; - return ""; + }, + + /** + * Lists all user-defined commands matching *filter* and optionally + * *hives*. + * + * @param {string} filter Limits the list to those commands with a name + * matching this anchored substring. + * @param {[Hive]} hives List of hives. + * @optional + */ + list: function list(filter, hives) { + const { commandline, completion } = this.modules; + function completerToString(completer) { + if (completer) + return [k + for ([k, v] of iter(config.completers)) + if (completer == completion.bound[v])][0] || "custom"; + + return ""; + } + // TODO: allow matching of aliases? + function cmds(hive) hive._list.filter(cmd => cmd.name.startsWith(filter || "")) + + hives = (hives || this.userHives).map(h => [h, cmds(h)]) + .filter(([h, c]) => c.length); + + let list = ["table", {}, + ["tr", { highlight: "Title" }, + ["td"], + ["td", { style: "padding-right: 1em;" }], + ["td", { style: "padding-right: 1ex;" }, _("title.Name")], + ["td", { style: "padding-right: 1ex;" }, _("title.Args")], + ["td", { style: "padding-right: 1ex;" }, _("title.Range")], + ["td", { style: "padding-right: 1ex;" }, _("title.Complete")], + ["td", { style: "padding-right: 1ex;" }, _("title.Definition")]], + ["col", { style: "min-width: 6em; padding-right: 1em;" }], + hives.map(([hive, cmds]) => { + let i = 0; + return [ + ["tr", { style: "height: .5ex;" }], + cmds.map(cmd => + ["tr", {}, + ["td", { highlight: "Title" }, !i++ ? hive.name : ""], + ["td", {}, cmd.bang ? "!" : " "], + ["td", {}, cmd.name], + ["td", {}, cmd.argCount], + ["td", {}, cmd.count ? "0c" : ""], + ["td", {}, completerToString(cmd.completer)], + ["td", {}, cmd.replacementText || "function () { ... }"]]), + ["tr", { style: "height: .5ex;" }]]; + })]; + + // E4X-FIXME + // if (list.*.length() === list.text().length() + 2) + // dactyl.echomsg(_("command.none")); + // else + commandline.commandOutput(list); } - // TODO: allow matching of aliases? - function cmds(hive) hive._list.filter(cmd => cmd.name.startsWith(filter || "")) - - hives = (hives || this.userHives).map(h => [h, cmds(h)]) - .filter(([h, c]) => c.length); - - let list = ["table", {}, - ["tr", { highlight: "Title" }, - ["td"], - ["td", { style: "padding-right: 1em;" }], - ["td", { style: "padding-right: 1ex;" }, _("title.Name")], - ["td", { style: "padding-right: 1ex;" }, _("title.Args")], - ["td", { style: "padding-right: 1ex;" }, _("title.Range")], - ["td", { style: "padding-right: 1ex;" }, _("title.Complete")], - ["td", { style: "padding-right: 1ex;" }, _("title.Definition")]], - ["col", { style: "min-width: 6em; padding-right: 1em;" }], - hives.map(([hive, cmds]) => let (i = 0) [ - ["tr", { style: "height: .5ex;" }], - cmds.map(cmd => - ["tr", {}, - ["td", { highlight: "Title" }, !i++ ? hive.name : ""], - ["td", {}, cmd.bang ? "!" : " "], - ["td", {}, cmd.name], - ["td", {}, cmd.argCount], - ["td", {}, cmd.count ? "0c" : ""], - ["td", {}, completerToString(cmd.completer)], - ["td", {}, cmd.replacementText || "function () { ... }"]]), - ["tr", { style: "height: .5ex;" }]])]; - - // E4X-FIXME - // if (list.*.length() === list.text().length() + 2) - // dactyl.echomsg(_("command.none")); - // else - commandline.commandOutput(list); - } - }), + }; + }, /** * @property Indicates that no count was specified for this @@ -850,7 +858,7 @@ var Commands = Module("commands", { defaults = array(this.options).map(opt => [opt.names[0], opt.default]) .toObject(); - for (let [opt, val] in Iterator(args.options || {})) { + for (let [opt, val] of iter(args.options || {})) { if (val === undefined) continue; if (val != null && defaults[opt] === val) @@ -864,7 +872,7 @@ var Commands = Module("commands", { res.push(opt); } - for (let [, arg] in Iterator(args.arguments || [])) + for (let arg of (args.arguments || [])) res.push(Commands.quote(arg)); let str = args.literalArg; @@ -895,7 +903,7 @@ var Commands = Module("commands", { */ hasDomain: function hasDomain(command, host) { try { - for (let [cmd, args] in this.subCommands(command)) + for (let [cmd, args] of this.subCommands(command)) if (Array.concat(cmd.domains(args)).some(domain => util.isSubdomain(domain, host))) return true; } @@ -913,7 +921,7 @@ var Commands = Module("commands", { * @returns {boolean} */ hasPrivateData: function hasPrivateData(command) { - for (let [cmd, args] in this.subCommands(command)) + for (let [cmd, args] of this.subCommands(command)) if (cmd.privateData) return !callable(cmd.privateData) ? cmd.privateData : cmd.privateData(args); @@ -1002,7 +1010,7 @@ var Commands = Module("commands", { args.string = str; // for access to the unparsed string // FIXME! - for (let [k, v] in Iterator(extra || [])) + for (let [k, v] of iter(extra || {})) args[k] = v; // FIXME: best way to specify these requirements? @@ -1065,8 +1073,8 @@ var Commands = Module("commands", { var optname = ""; if (!onlyArgumentsRemaining) { - for (let [, opt] in Iterator(options)) { - for (let [, optname] in Iterator(opt.names)) { + for (let opt of options) { + for (let optname of opt.names) { if (sub.startsWith(optname)) { let count = 0; let invalid = false; @@ -1166,10 +1174,10 @@ var Commands = Module("commands", { sub = re.exec(str)[1]; // Hack. - if (sub.substr(0, 2) === "<<" && hereDoc) - let ([count, arg] = getNextArg(sub)) { - sub = arg + sub.substr(count); - }; + if (sub.substr(0, 2) === "<<" && hereDoc) { + let [count, arg] = getNextArg(sub); + sub = arg + sub.substr(count); + } args.push(sub); args.quote = null; @@ -1333,7 +1341,7 @@ var Commands = Module("commands", { return [count, cmd, !!bang, args || "", spec.length, group]; }, - parseCommands: function parseCommands(str, complete) { + parseCommands: function* parseCommands(str, complete) { const { contexts } = this.modules; do { let [count, cmd, bang, args, len, group] = commands.parseCommand(str); @@ -1365,11 +1373,11 @@ var Commands = Module("commands", { while (str); }, - subCommands: function subCommands(command) { + subCommands: function* subCommands(command) { let commands = [command]; while (command = commands.shift()) try { - for (let [command, args] in this.parseCommands(command)) { + for (let [command, args] of this.parseCommands(command)) { if (command) { yield [command, args]; if (command.subCommand && args[command.subCommand]) @@ -1447,7 +1455,7 @@ var Commands = Module("commands", { // if there is no space between the command name and the cursor // then get completions of the command name - for (var [command, args] in commands.parseCommands(context.filter, context)) + for (var [command, args] of commands.parseCommands(context.filter, context)) if (args.trailing) context.advance(args.commandString.length + 1); if (!args) @@ -1622,7 +1630,7 @@ var Commands = Module("commands", { // TODO: "E180: invalid complete value: " + arg names: ["-complete", "-C"], description: "The argument completion function", - completer: function (context) [[k, ""] for ([k, v] in Iterator(config.completers))], + completer: function (context) [[k, ""] for ([k, v] of iter(config.completers))], type: CommandOption.STRING, validator: function (arg) arg in config.completers || /^custom,/.test(arg), }, @@ -1669,7 +1677,7 @@ var Commands = Module("commands", { bang: true, options: iter([v, typeof cmd[k] == "boolean" ? null : cmd[k]] // FIXME: this map is expressed multiple times - for ([k, v] in Iterator({ + for ([k, v] of iter({ argCount: "-nargs", bang: "-bang", count: "-count", @@ -1680,7 +1688,7 @@ var Commands = Module("commands", { literalArg: cmd.action, ignoreDefaults: true } - for (cmd in hive) if (cmd.persist) + for (cmd of hive) if (cmd.persist) ]) .flatten().array }); @@ -1724,8 +1732,11 @@ var Commands = Module("commands", { cmd.hive.name] ] })), - iterateIndex: function (args) let (tags = help.tags) - this.iterate(args).filter(cmd => (cmd.hive === commands.builtin || hasOwnProperty(tags, cmd.helpTag))), + iterateIndex: function (args) { + let tags = help.tags; + return this.iterate(args).filter(cmd => (cmd.hive === commands.builtin || + hasOwnProperty(tags, cmd.helpTag))); + }, format: { headings: ["Command", "Group", "Description"], description: function (cmd) template.linkifyHelp(cmd.description + (cmd.replacementText ? ": " + cmd.action : "")), @@ -1755,9 +1766,9 @@ var Commands = Module("commands", { const { JavaScript, commands } = modules; JavaScript.setCompleter([CommandHive.prototype.get, CommandHive.prototype.remove], - [function () [[c.names, c.description] for (c in this)]]); + [function () [[c.names, c.description] for (c of this)]]); JavaScript.setCompleter([Commands.prototype.get], - [function () [[c.names, c.description] for (c in this.iterator())]]); + [function () [[c.names, c.description] for (c of this.iterator())]]); }, mappings: function initMappings(dactyl, modules, window) { const { commands, mappings, modes } = modules; @@ -1766,7 +1777,7 @@ var Commands = Module("commands", { ["@:"], "Repeat the last Ex command", function ({ count }) { if (commands.repeat) { - for (let i in util.interruptibleRange(0, Math.max(count, 1), 100)) + for (let i of util.interruptibleRange(0, Math.max(count, 1), 100)) dactyl.execute(commands.repeat); } else diff --git a/common/modules/completion.jsm b/common/modules/completion.jsm index 6840b231..fe96ce6b 100644 --- a/common/modules/completion.jsm +++ b/common/modules/completion.jsm @@ -1,6 +1,6 @@ // Copyright (c) 2006-2008 by Martin Stubenschrott // Copyright (c) 2007-2011 by Doug Kearns -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -304,7 +304,7 @@ var CompletionContext = Class("CompletionContext", { items = items.array; // Accept a generator if (!isArray(items)) - items = [x for (x in Iterator(items || []))]; + items = [x for (x of iter(items || []))]; if (this._completions !== items) { delete this.cache.filtered; delete this.cache.filter; @@ -360,14 +360,14 @@ var CompletionContext = Class("CompletionContext", { let self = this; let res = { highlight: "" }; - function result(quote) { + function* result(quote) { yield ["context", function p_context() self]; yield ["result", quote ? function p_result() quote[0] + util.trapErrors(1, quote, this.text) + quote[2] : function p_result() this.text]; yield ["texts", function p_texts() Array.concat(this.text)]; }; - for (let i in iter(this.keys, result(this.quote))) { + for (let i of iter(this.keys, result(this.quote))) { let [k, v] = i; if (typeof v == "string" && /^[.[]/.test(v)) // This is only allowed to be a simple accessor, and shouldn't @@ -622,7 +622,7 @@ var CompletionContext = Class("CompletionContext", { * sub-contexts. */ cancelAll: function cancelAll() { - for (let [, context] in Iterator(this.contextList)) { + for (let context of this.contextList) { if (context.cancel) context.cancel(); } @@ -670,7 +670,7 @@ var CompletionContext = Class("CompletionContext", { } }, - getRows: function getRows(start, end, doc) { + getRows: function* getRows(start, end, doc) { let items = this.items; let cache = this.cache.rows; let step = start > end ? -1 : 1; @@ -679,7 +679,7 @@ var CompletionContext = Class("CompletionContext", { end = Math.min(items.length, end != null ? end : items.length); this.doc = doc; - for (let i in util.range(start, end, step)) + for (let i of util.range(start, end, step)) yield [i, this.getRow(i)]; }, @@ -717,8 +717,10 @@ var CompletionContext = Class("CompletionContext", { context.waitingForTab = true; else if (completer) { let res = completer.apply(self || this, [context].concat(args)); + if (res && !isArray(res) && !isArray(res.__proto__)) - res = [k for (k in res)]; + res = [k for (k of res)]; + if (res) context.completions = res; return res; @@ -766,6 +768,7 @@ var CompletionContext = Class("CompletionContext", { if (arguments.length == 0) { for (let type in this.selectionTypes) this.highlight(0, 0, type); + this.selectionTypes = {}; } try { @@ -837,7 +840,7 @@ var CompletionContext = Class("CompletionContext", { } //for (let key in (k for ([k, v] in Iterator(this.contexts)) if (v.offset > this.caret))) // delete this.contexts[key]; - for each (let context in this.contexts) { + for (let context of values(this.contexts)) { context.hasItems = false; context.incomplete = false; } @@ -870,7 +873,7 @@ var CompletionContext = Class("CompletionContext", { Filter: { text: function F_text(item) { let text = item.texts; - for (let [i, str] in Iterator(text)) { + for (let [i, str] of iter(text)) { if (this.match(String(str))) { item.text = String(text[i]); return true; @@ -1042,7 +1045,7 @@ var Completion = Module("completion", { context.incomplete = result.searchResult >= result.RESULT_NOMATCH_ONGOING; context.completions = [ { url: result.getValueAt(i), title: result.getCommentAt(i), icon: result.getImageAt(i) } - for (i in util.range(0, result.matchCount)) + for (i of util.range(0, result.matchCount)) ]; }), get onUpdateSearchResult() this.onSearchResult @@ -1126,7 +1129,7 @@ var Completion = Module("completion", { completer: function (context) { let PREFIX = "/ex/contexts"; context.fork("ex", 0, completion, "ex"); - completion.contextList = [[k.substr(PREFIX.length), v.title[0]] for ([k, v] in iter(context.contexts)) if (k.substr(0, PREFIX.length) == PREFIX)]; + completion.contextList = [[k.substr(PREFIX.length), v.title[0]] for ([k, v] of iter(context.contexts)) if (k.substr(0, PREFIX.length) == PREFIX)]; }, literal: 0 }); @@ -1176,11 +1179,16 @@ var Completion = Module("completion", { s: "search" }, - get values() values(completion.urlCompleters).toArray() - .concat([let (name = k.substr(services.AUTOCOMPLETE.length)) - ["native:" + name, _("autocomplete.description", name)] - for (k in Cc) - if (k.startsWith(services.AUTOCOMPLETE))]), + get values() { + let builtin = Object.keys(Cc) + .filter(k => k.startsWith(services.AUTOCOMPLETE)) + .map(key => { + let name = key.substr(services.AUTOCOMPLETE.length) + return ["native:" + name, _("autocomplete.description", name)]; + }); + + return values(completion.urlCompleters).toArray().concat(builtin); + }, setter: function setter(values) { if (values.length == 1 && !hasOwnProperty(values[0], this.values) diff --git a/common/modules/config.jsm b/common/modules/config.jsm index 5622126c..7ba778b3 100644 --- a/common/modules/config.jsm +++ b/common/modules/config.jsm @@ -1,6 +1,6 @@ // Copyright (c) 2006-2008 by Martin Stubenschrott // Copyright (c) 2007-2011 by Doug Kearns -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -96,7 +96,7 @@ var ConfigBase = Class("ConfigBase", { if (documentURL) config = config.overlays && config.overlays[documentURL] || {}; - for (let [name, value] in Iterator(config)) { + for (let [name, value] of iter(config)) { let prop = util.camelCase(name); if (isArray(this[prop])) @@ -223,13 +223,13 @@ var ConfigBase = Class("ConfigBase", { if (jar) { let prefix = getDir(jar.JAREntry); var res = iter(s.slice(prefix.length).replace(/\/.*/, "") - for (s in io.listJar(jar.JARFile, prefix))) + for (s of io.listJar(jar.JARFile, prefix))) .toArray(); } else { res = array(f.leafName - // Fails on FF3: for (f in util.getFile(uri).iterDirectory()) - for (f in values(util.getFile(uri).readDirectory())) + // Fails on FF3: for (f of util.getFile(uri).iterDirectory()) + for (f of util.getFile(uri).readDirectory()) if (f.isDirectory())).array; } @@ -250,7 +250,7 @@ var ConfigBase = Class("ConfigBase", { bestLocale: function (list) { return values([this.appLocale, this.appLocale.replace(/-.*/, ""), "en", "en-US", list[0]]) - .find(bind("has", RealSet(list))); + .find(bind("has", new RealSet(list))); }, /** @@ -281,19 +281,19 @@ var ConfigBase = Class("ConfigBase", { for (let dir of ["UChrm", "AChrom"]) { dir = File(services.directory.get(dir, Ci.nsIFile)); if (dir.exists() && dir.isDirectory()) - for (let file in dir.iterDirectory()) + for (let file of dir.iterDirectory()) if (/\.manifest$/.test(file.leafName)) process(file.read()); dir = File(dir.parent); if (dir.exists() && dir.isDirectory()) - for (let file in dir.iterDirectory()) + for (let file of dir.iterDirectory()) if (/\.jar$/.test(file.leafName)) processJar(file); dir = dir.child("extensions"); if (dir.exists() && dir.isDirectory()) - for (let ext in dir.iterDirectory()) { + for (let ext of dir.iterDirectory()) { if (/\.xpi$/.test(ext.leafName)) processJar(ext); else { @@ -316,10 +316,13 @@ var ConfigBase = Class("ConfigBase", { * @param {string} max The maximum required version. @optional * @returns {boolean} */ - haveGecko: function (min, max) let ({ compare } = services.versionCompare, - { platformVersion } = services.runtime) - (min == null || compare(platformVersion, min) >= 0) && - (max == null || compare(platformVersion, max) < 0), + haveGecko: function (min, max) { + let { compare } = services.versionCompare; + let { platformVersion } = services.runtime; + + return (min == null || compare(platformVersion, min) >= 0) && + (max == null || compare(platformVersion, max) < 0); + }, /** Dactyl's notion of the current operating system platform. */ OS: memoize({ @@ -377,7 +380,7 @@ var ConfigBase = Class("ConfigBase", { // without explicitly selecting a profile. let dir = services.directory.get("ProfD", Ci.nsIFile); - for (let prof in iter(services.profile.profiles)) + for (let prof of iter(services.profile.profiles)) if (prof.QueryInterface(Ci.nsIToolkitProfile).rootDir.path === dir.path) return prof.name; return "unknown"; @@ -404,7 +407,7 @@ var ConfigBase = Class("ConfigBase", { dtd: Class.Memoize(function () iter(this.dtdExtra, - (["dactyl." + k, v] for ([k, v] in iter(config.dtdDactyl))), + (["dactyl." + k, v] for ([k, v] of iter(config.dtdDactyl))), (["dactyl." + s, config[s]] for (s of config.dtdStrings))) .toObject()), @@ -447,7 +450,7 @@ var ConfigBase = Class("ConfigBase", { helpStyles: /^(Help|StatusLine|REPL)|^(Boolean|Dense|Indicator|MoreMsg|Number|Object|Logo|Key(word)?|String)$/, styleHelp: function styleHelp() { if (!this.helpStyled) { - for (let k in keys(highlight.loaded)) + for (let k of keys(highlight.loaded)) if (this.helpStyles.test(k)) highlight.loaded[k] = true; } @@ -462,7 +465,7 @@ var ConfigBase = Class("ConfigBase", { ["menupopup", { id: "viewSidebarMenu", xmlns: "xul" }], ["broadcasterset", { id: "mainBroadcasterSet", xmlns: "xul" }]]; - for (let [id, [name, key, uri]] in Iterator(this.sidebars)) { + for (let [id, [name, key, uri]] of iter(this.sidebars)) { append[0].push( ["menuitem", { observes: "pentadactyl-" + id + "Sidebar", label: name, accesskey: key }]); @@ -543,7 +546,7 @@ var ConfigBase = Class("ConfigBase", { * dactyl.has(feature) to check for a feature's presence * in this array. */ - features: RealSet(["default-theme"]), + features: new RealSet(["default-theme"]), /** * @property {string} The file extension used for command script files. diff --git a/common/modules/contexts.jsm b/common/modules/contexts.jsm index 8af3e919..1eed3b5f 100644 --- a/common/modules/contexts.jsm +++ b/common/modules/contexts.jsm @@ -35,18 +35,18 @@ var Group = Class("Group", { modifiable: true, cleanup: function cleanup(reason) { - for (let hive in values(this.hives)) + for (let hive of values(this.hives)) util.trapErrors("cleanup", hive); this.hives = []; - for (let hive in keys(this.hiveMap)) + for (let hive of keys(this.hiveMap)) delete this[hive]; if (reason != "shutdown") this.children.splice(0).forEach(this.contexts.bound.removeGroup); }, destroy: function destroy(reason) { - for (let hive in values(this.hives)) + for (let hive of values(this.hives)) util.trapErrors("destroy", hive); if (reason != "shutdown") @@ -66,20 +66,25 @@ var Group = Class("Group", { }, { compileFilter: function (patterns, default_=false) { - function siteFilter(uri) - let (match = siteFilter.filters.find(f => f(uri))) - match ? match.result - : default_; + function siteFilter(uri) { + let match = siteFilter.filters.find(f => f(uri)); + return match ? match.result + : default_; + } return update(siteFilter, { toString: function () this.filters.join(","), - toJSONXML: function (modules) let (uri = modules && modules.buffer.uri) - template.map(this.filters, - f => ["span", { highlight: uri && f(uri) ? "Filter" : "" }, - ("toJSONXML" in f ? f.toJSONXML() - : String(f))], - ","), + toJSONXML: function (modules) { + let uri = modules && modules.buffer.uri; + + return template.map( + this.filters, + f => ["span", { highlight: uri && f(uri) ? "Filter" : "" }, + ("toJSONXML" in f ? f.toJSONXML() + : String(f))], + ","); + }, filters: Option.parse.sitelist(patterns) }); @@ -94,7 +99,7 @@ var Contexts = Module("contexts", { }, cleanup: function () { - for each (let module in this.pluginModules) + for (let module of values(this.pluginModules)) util.trapErrors("unload", module); this.pluginModules = {}; @@ -152,7 +157,7 @@ var Contexts = Module("contexts", { for (let hive of values(this.groupList.slice())) util.trapErrors("destroy", hive, "shutdown"); - for each (let plugin in this.modules.plugins.contexts) { + for (let plugin of values(this.modules.plugins.contexts)) { if (plugin && "onUnload" in plugin && callable(plugin.onUnload)) util.trapErrors("onUnload", plugin); @@ -195,7 +200,7 @@ var Contexts = Module("contexts", { memoize(contexts.groupsProto, name, function () [group[name] - for (group in values(this.groups)) + for (group of values(this.groups)) if (hasOwnProperty(group, name))]); }, @@ -413,9 +418,12 @@ var Contexts = Module("contexts", { delete this.allGroups; }, - initializedGroups: function (hive) - let (need = hive ? [hive] : Object.keys(this.hives)) - this.groupList.filter(group => need.some(hasOwnProperty.bind(null, group))), + initializedGroups: function (hive) { + let need = hive ? [hive] + : Object.keys(this.hives); + + return this.groupList.filter(group => need.some(hasOwnProperty.bind(null, group))); + }, addGroup: function addGroup(name, description, filter, persist, replace) { let group = this.getGroup(name); @@ -502,13 +510,18 @@ var Contexts = Module("contexts", { let process = util.identity; if (callable(params)) - var makeParams = function makeParams(self, args) - let (obj = params.apply(self, args)) - iter.toObject([k, Proxy(obj, k)] for (k in properties(obj))); + var makeParams = function makeParams(self, args) { + let obj = params.apply(self, args); + + return iter.toObject([k, Proxy(obj, k)] + for (k of properties(obj))); + }; + else if (params) - makeParams = function makeParams(self, args) - iter.toObject([name, process(args[i])] - for ([i, name] in Iterator(params))); + makeParams = function makeParams(self, args) { + return iter.toObject([name, process(args[i])] + for ([i, name] of iter(params))); + }; let rhs = args.literalArg; let type = ["-builtin", "-ex", "-javascript", "-keys"].reduce((a, b) => args[b] ? b : a, default_); @@ -684,7 +697,7 @@ var Contexts = Module("contexts", { bang: true, options: iter([v, typeof group[k] == "boolean" ? null : group[k]] // FIXME: this map is expressed multiple times - for ([k, v] in Iterator({ + for ([k, v] of iter({ args: "-args", description: "-description", filter: "-locations" @@ -693,7 +706,7 @@ var Contexts = Module("contexts", { arguments: [group.name], ignoreDefaults: true } - for (group in values(contexts.initializedGroups())) + for (group of values(contexts.initializedGroups())) if (!group.builtin && group.persist) ].concat([{ command: this.name, arguments: ["user"] }]) }); 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 -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // 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 ? "/>" : ">...")); } @@ -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) { diff --git a/common/modules/downloads.jsm b/common/modules/downloads.jsm index 3f4a3501..3f39e5ff 100644 --- a/common/modules/downloads.jsm +++ b/common/modules/downloads.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 Kris Maglione +// Copyright (c) 2011-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -19,7 +19,7 @@ var MAX_LOAD_TIME = 10 * 1000; let prefix = "DOWNLOAD_"; var states = iter([v, k.slice(prefix.length).toLowerCase()] - for ([k, v] in Iterator(Ci.nsIDownloadManager)) + for ([k, v] of iter(Ci.nsIDownloadManager)) if (k.startsWith(prefix))) .toObject(); @@ -78,13 +78,16 @@ var Download = Class("Download", { inState: function inState(states) states.indexOf(this.status) >= 0, - allowedCommands: Class.Memoize(function () let (self = this) ({ - get delete() !self.active && (self.targetFile.exists() || self.hasPartialData), - get launch() self.targetFile.exists() && self.succeeded, - get stop() self.active, - get remove() !self.active, - get resume() self.canceled - })), + allowedCommands: Class.Memoize(function () { + let self = this; + return { + get delete() !self.active && (self.targetFile.exists() || self.hasPartialData), + get launch() self.targetFile.exists() && self.succeeded, + get stop() self.active, + get remove() !self.active, + get resume() self.canceled + }; + }), command: function command(name) { util.assert(hasOwnProperty(this.allowedCommands, name), _("download.unknownCommand")); @@ -95,7 +98,7 @@ var Download = Class("Download", { }, commands: { - delete: promises.task(function delete_() { + delete: promises.task(function* delete_() { if (this.hasPartialData) yield this.removePartialData(); else if (this.targetFile.exists()) @@ -133,7 +136,7 @@ var Download = Class("Download", { resume: function resume() { this.download.start(); }, - remove: promises.task(function remove() { + remove: promises.task(function* remove() { yield this.list.list.remove(this.download); yield this.download.finalize(true); }), @@ -201,7 +204,7 @@ var Download = Class("Download", { this.nodes.row.setAttribute("status", this.status); this.nodes.state.textContent = util.capitalize(this.status); - for (let node in values(this.nodes)) + for (let node of values(this.nodes)) if (node.update) node.update(); @@ -266,7 +269,7 @@ var DownloadList = Class("DownloadList", this.index = Array.indexOf(this.nodes.list.childNodes, this.nodes.head); - Task.spawn(function () { + Task.spawn(function* () { this.list = yield Downloads.getList(Downloads.ALL); let start = Date.now(); @@ -312,9 +315,12 @@ var DownloadList = Class("DownloadList", this.cleanup(); }, - allowedCommands: Class.Memoize(function () let (self = this) ({ - get clear() iter(self.downloads.values()).some(dl => dl.allowedCommands.remove) - })), + allowedCommands: Class.Memoize(function () { + let self = this; + return { + get clear() iter(self.downloads.values()).some(dl => dl.allowedCommands.remove) + }; + }), commands: { clear: function () { @@ -325,7 +331,7 @@ var DownloadList = Class("DownloadList", sort: function sort() { let list = iter(this.downloads.values()).sort((a, b) => a.compare(b)); - for (let [i, download] in iter(list)) + for (let [i, download] of iter(list)) if (this.nodes.list.childNodes[i + 1] != download.nodes.row) this.nodes.list.insertBefore(download.nodes.row, this.nodes.list.childNodes[i + 1]); @@ -334,7 +340,7 @@ var DownloadList = Class("DownloadList", shouldSort: function shouldSort() Array.some(arguments, val => this.sortOrder.some(v => v.substr(1) == val)), update: function update() { - for (let node in values(this.nodes)) + for (let node of values(this.nodes)) if (node.update && node.update != update) node.update(); this.updateProgress(); @@ -351,7 +357,7 @@ var DownloadList = Class("DownloadList", let active = downloads.filter(d => d.active); let self = Object.create(this); - for (let prop in values(["currentBytes", "totalBytes", "speed", "timeRemaining"])) + for (let prop of values(["currentBytes", "totalBytes", "speed", "timeRemaining"])) this[prop] = active.reduce((acc, dl) => dl[prop] + acc, 0); this.hasProgress = active.every(d => d.hasProgress); @@ -362,7 +368,7 @@ var DownloadList = Class("DownloadList", if (active.length) this.nodes.total.textContent = _("download.nActive", active.length); - else for (let key in values(["total", "percent", "speed", "time"])) + else for (let key of values(["total", "percent", "speed", "time"])) this.nodes[key].textContent = ""; if (this.shouldSort("complete", "size", "speed", "time")) @@ -523,7 +529,7 @@ var Downloads_ = Module("downloads", XPCOM(Ci.nsIDownloadProgressListener), { }, completer: function (context, extra) { - let seen = RealSet(extra.values.map(val => val.substr(1))); + let seen = new RealSet(extra.values.map(val => val.substr(1))); context.completions = iter(this.values).filter(([k, v]) => !seen.has(k)) .map(([k, v]) => [["+" + k, [v, " (", _("sort.ascending"), ")"].join("")], @@ -534,7 +540,7 @@ var Downloads_ = Module("downloads", XPCOM(Ci.nsIDownloadProgressListener), { has: function () Array.some(arguments, val => this.value.some(v => v.substr(1) == val)), validator: function (value) { - let seen = RealSet(); + let seen = new RealSet(); return value.every(val => /^[+-]/.test(val) && hasOwnProperty(this.values, val.substr(1)) && !seen.add(val.substr(1))) && value.length; diff --git a/common/modules/finder.jsm b/common/modules/finder.jsm index 2f263ba0..fad4266c 100644 --- a/common/modules/finder.jsm +++ b/common/modules/finder.jsm @@ -50,7 +50,7 @@ var RangeFinder = Module("rangefinder", { }, cleanup: function cleanup() { - for (let doc in util.iterDocuments()) { + for (let doc of util.iterDocuments()) { let find = overlay.getData(doc, "range-find", null); if (find) find.highlight(true); @@ -436,9 +436,9 @@ var RangeFind = Class("RangeFind", { return ranges[0]; }, - findSubRanges: function findSubRanges(range) { + findSubRanges: function* findSubRanges(range) { let doc = range.startContainer.ownerDocument; - for (let elem in this.elementPath(doc)) { + for (let elem of this.elementPath(doc)) { let r = RangeFind.nodeRange(elem); if (RangeFind.contains(range, r)) yield r; @@ -475,7 +475,7 @@ var RangeFind = Class("RangeFind", { else { this.selections = []; let string = this.lastString; - for (let r in this.iter(string)) { + for (let r of this.iter(string)) { let controller = this.range.selectionController; for (let node = r.startContainer; node; node = node.parentNode) if (node instanceof Ci.nsIDOMNSEditableElement) { @@ -495,25 +495,25 @@ var RangeFind = Class("RangeFind", { } }, - indexIter: function indexIter(private_) { + indexIter: function* indexIter(private_) { let idx = this.range.index; if (this.backward) var groups = [util.range(idx + 1, 0, -1), util.range(this.ranges.length, idx, -1)]; else var groups = [util.range(idx, this.ranges.length), util.range(0, idx + 1)]; - for (let i in groups[0]) + for (let i of groups[0]) yield i; if (!private_) { this.wrapped = true; this.lastRange = null; - for (let i in groups[1]) + for (let i of groups[1]) yield i; } }, - iter: function iter(word) { + iter: function* iter(word) { let saved = ["lastRange", "lastString", "range", "regexp"].map(s => [s, this[s]]); let res; try { @@ -522,8 +522,8 @@ var RangeFind = Class("RangeFind", { this.regexp = false; if (regexp) { let re = RegExp(word, "gm" + this.flags); - for (this.range in array.iterValues(this.ranges)) { - for (let match in util.regexp.iterate(re, DOM.stringify(this.range.range, true))) { + for (this.range of array.iterValues(this.ranges)) { + for (let match of util.regexp.iterate(re, DOM.stringify(this.range.range, true))) { let lastRange = this.lastRange; if (res = this.find(null, this.reverse, true)) yield res; @@ -565,7 +565,7 @@ var RangeFind = Class("RangeFind", { if (!self.elementPath) push(range); else - for (let r in self.findSubRanges(range)) + for (let r of self.findSubRanges(range)) push(r); } function rec(win) { @@ -575,7 +575,7 @@ var RangeFind = Class("RangeFind", { let pageStart = RangeFind.endpoint(pageRange, true); let pageEnd = RangeFind.endpoint(pageRange, false); - for (let frame in array.iterValues(win.frames)) { + for (let frame of array.iterValues(win.frames)) { let range = doc.createRange(); if (DOM(frame.frameElement).style.visibility == "visible") { range.selectNode(frame.frameElement); @@ -588,7 +588,7 @@ var RangeFind = Class("RangeFind", { let anonNodes = doc.getAnonymousNodes(doc.documentElement); if (anonNodes) { - for (let [, elem] in iter(anonNodes)) { + for (let [, elem] of iter(anonNodes)) { let range = RangeFind.nodeContents(elem); pushRange(RangeFind.endpoint(range, true), RangeFind.endpoint(range, false)); } @@ -649,7 +649,7 @@ var RangeFind = Class("RangeFind", { if (pattern == "") var range = this.startRange; else - for (let i in this.indexIter(private_)) { + for (let i of this.indexIter(private_)) { if (!private_ && this.range.window != this.ranges[i].window && this.range.window != this.ranges[i].window.parent) { this.range.descroll(); this.range.deselect(); @@ -706,11 +706,11 @@ var RangeFind = Class("RangeFind", { set stale(val) this._stale = val, addListeners: function addListeners() { - for (let range in array.iterValues(this.ranges)) + for (let range of array.iterValues(this.ranges)) range.window.addEventListener("unload", this.bound.onUnload, true); }, purgeListeners: function purgeListeners() { - for (let range in array.iterValues(this.ranges)) + for (let range of array.iterValues(this.ranges)) try { range.window.removeEventListener("unload", this.bound.onUnload, true); } diff --git a/common/modules/help.jsm b/common/modules/help.jsm index 298309d4..35bab00a 100644 --- a/common/modules/help.jsm +++ b/common/modules/help.jsm @@ -28,7 +28,7 @@ var HelpBuilder = Class("HelpBuilder", { // Scrape the list of help files from all.xml this.tags["all"] = this.tags["all.xml"] = "all"; let files = this.findHelpFile("all").map(doc => - [f.value for (f in DOM.XPath("//dactyl:include/@href", doc))]); + [f.value for (f of DOM.XPath("//dactyl:include/@href", doc))]); // Scrape the tags from the rest of the help files. array.flatten(files).forEach(function (file) { @@ -51,8 +51,8 @@ var HelpBuilder = Class("HelpBuilder", { // Find the tags in the document. addTags: function addTags(file, doc) { - for (let elem in DOM.XPath("//@tag|//dactyl:tags/text()|//dactyl:tag/text()", doc)) - for (let tag in values((elem.value || elem.textContent).split(/\s+/))) + for (let elem of DOM.XPath("//@tag|//dactyl:tags/text()|//dactyl:tag/text()", doc)) + for (let tag of values((elem.value || elem.textContent).split(/\s+/))) this.tags[tag] = file; }, @@ -61,7 +61,7 @@ var HelpBuilder = Class("HelpBuilder", { // Find help and overlay files with the given name. findHelpFile: function findHelpFile(file) { let result = []; - for (let base in values(this.bases)) { + for (let base of values(this.bases)) { let url = [base, file, ".xml"].join(""); let res = util.httpGet(url, { quiet: true }); if (res) { @@ -135,7 +135,7 @@ var Help = Module("Help", { let res = []; let list, space, i = 0; - for (let match in re.iterate(text)) { + for (let match of re.iterate(text)) { if (match.comment) continue; else if (match.char) { @@ -211,7 +211,7 @@ var Help = Module("Help", { flush: function flush(entries, time) { cache.flushEntry("help.json", time); - for (let entry in values(Array.concat(entries || []))) + for (let entry of values(Array.concat(entries || []))) cache.flushEntry(entry, time); }, @@ -244,7 +244,7 @@ var Help = Module("Help", { function format(item) item.description + "#" + encodeURIComponent(item.text); - for (let [i, item] in Iterator(items)) { + for (let item of items) { if (item.text == topic) return format(item); else if (!partialMatch && topic) @@ -271,7 +271,7 @@ var Help = Module("Help", { if (hasOwnProperty(help.files, helpFile)) dactyl.open("dactyl://help/" + helpFile, { from: "help" }); else - dactyl.echomsg(_("help.noFile", helpFile.quote())); + dactyl.echomsg(_("help.noFile", JSON.stringify(helpFile))); return; } @@ -304,8 +304,8 @@ var Help = Module("Help", { addURIEntry(file, "data:text/plain;charset=UTF-8," + encodeURI(data)); } - let empty = RealSet("area base basefont br col frame hr img input isindex link meta param" - .split(" ")); + let empty = new RealSet("area base basefont br col frame hr img input isindex link meta param" + .split(" ")); function fix(node) { switch (node.nodeType) { case Ci.nsIDOMNode.ELEMENT_NODE: @@ -314,10 +314,10 @@ var Help = Module("Help", { data.push("<", node.localName); if (node instanceof Ci.nsIDOMHTMLHtmlElement) - data.push(" xmlns=" + XHTML.quote(), - " xmlns:dactyl=" + NS.quote()); + data.push(" xmlns=" + JSON.stringify(XHTML), + " xmlns:dactyl=" + JSON.stringify(NS)); - for (let { name, value } in array.iterValues(node.attributes)) { + for (let { name, value } of array.iterValues(node.attributes)) { if (name == "dactyl:highlight") { styles.add(value); name = "class"; @@ -362,9 +362,9 @@ var Help = Module("Help", { let { buffer, content, events } = modules; let chromeFiles = {}; - let styles = RealSet(); + let styles = new RealSet; - for (let [file, ] in Iterator(help.files)) { + for (let [file, ] of iter(help.files)) { let url = "dactyl://help/" + file; dactyl.open(url); util.waitFor(() => (content.location.href == url && buffer.loaded && @@ -380,7 +380,8 @@ var Help = Module("Help", { addDataEntry(file + ".xhtml", data.join("")); } - data = [h for (h in highlight) if (styles.has(h.class) || /^Help/.test(h.class))] + data = [h for (h of highlight) + if (styles.has(h.class) || /^Help/.test(h.class))] .map(h => h.selector .replace(/^\[.*?=(.*?)\]/, ".hl-$1") .replace(/html\|/g, "") + "\t" + "{" + h.cssText + "}") @@ -393,7 +394,7 @@ var Help = Module("Help", { while ((m = re.exec(data))) chromeFiles[m[0]] = m[2]; - for (let [uri, leaf] in Iterator(chromeFiles)) + for (let [uri, leaf] of iter(chromeFiles)) addURIEntry(leaf, uri); if (zip) diff --git a/common/modules/highlight.jsm b/common/modules/highlight.jsm index ab03dec7..2a73f423 100644 --- a/common/modules/highlight.jsm +++ b/common/modules/highlight.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -29,7 +29,7 @@ Highlight.liveProperty = function (name, prop) { this.set(name, val); if (name === "value" || name === "extends") - for (let h in highlight) + for (let h of highlight) if (h.extends.indexOf(this.class) >= 0) h.style.css = h.css; @@ -84,7 +84,8 @@ update(Highlight.prototype, { get cssText() this.inheritedCSS + this.value, toString: function () "Highlight(" + this.class + ")\n\t" + - [k + ": " + String(v).quote() for ([k, v] in this)] .join("\n\t") + [k + ": " + JSON.stringify(String(v)) + for ([k, v] of this)].join("\n\t") }); /** @@ -100,7 +101,7 @@ var Highlights = Module("Highlight", { keys: function keys() Object.keys(this.highlight).sort(), - __iterator__: function () values(this.highlight).sort((a, b) => String.localeCompare(a.class, b.class)) + "@@iterator": function () values(this.highlight).sort((a, b) => String.localeCompare(a.class, b.class)) .iterValues(), _create: function _create(agent, args) { @@ -142,7 +143,7 @@ var Highlights = Module("Highlight", { }); if (obj.class === obj.baseClass) - for (let h in highlight) + for (let h of highlight) if (h.baseClass === obj.class) this[h.class] = true; obj.style.enabled = true; @@ -189,7 +190,7 @@ var Highlights = Module("Highlight", { * reset. */ clear: function clear() { - for (let [k, v] in Iterator(this.highlight)) + for (let [k, v] of iter(this.highlight)) this.set(k, null, true); }, @@ -296,7 +297,7 @@ var Highlights = Module("Highlight", { if (bang) highlight.style.enabled = true; }, this); - for (let h in this) + for (let h of this) h.style.css = h.css; } }, { @@ -360,7 +361,7 @@ var Highlights = Module("Highlight", { template.highlightRegexp(h.value, /\b[-\w]+(?=:)|\/\*.*?\*\//g, match => ["span", { highlight: match[0] == "/" ? "Comment" : "Key" }, match]) ] - for (h in highlight) + for (h of highlight) if (!key || h.class.indexOf(key) > -1)))); else if (!key && clear) highlight.clear(); @@ -416,7 +417,7 @@ var Highlights = Module("Highlight", { "-link": v.extends.length ? v.extends : undefined } } - for (v in Iterator(highlight)) + for (v of highlight) if (v.value != v.defaultValue) ] }); @@ -443,7 +444,7 @@ var Highlights = Module("Highlight", { completion.highlightGroup = function highlightGroup(context) { context.title = ["Highlight Group", "Value"]; - context.completions = [[v.class, v.value] for (v in highlight)]; + context.completions = [[v.class, v.value] for (v of highlight)]; }; }, javascript: function initJavascript(dactyl, modules, window) { diff --git a/common/modules/io.jsm b/common/modules/io.jsm index c1a28320..6b062500 100644 --- a/common/modules/io.jsm +++ b/common/modules/io.jsm @@ -1,6 +1,6 @@ // Copyright (c) 2006-2008 by Martin Stubenschrott // Copyright (c) 2007-2012 by Doug Kearns -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -33,188 +33,191 @@ var IO = Module("io", { lazyRequire("config", ["config"], this); }, - Local: function Local(dactyl, modules, window) let ({ io, plugins } = modules) ({ + Local: function Local(dactyl, modules, window) { + let { io, plugins } = modules; + return { - init: function init() { - this.config = modules.config; - this._processDir = services.directory.get("CurWorkD", Ci.nsIFile); - this._cwd = this._processDir.path; - this._oldcwd = null; + init: function init() { + this.config = modules.config; + this._processDir = services.directory.get("CurWorkD", Ci.nsIFile); + this._cwd = this._processDir.path; + this._oldcwd = null; - this._lastRunCommand = ""; // updated whenever the users runs a command with :! - this._scriptNames = RealSet(); - }, - - CommandFileMode: Class("CommandFileMode", modules.CommandMode, { - init: function init(prompt, params) { - init.supercall(this); - this.prompt = isArray(prompt) ? prompt : ["Question", prompt]; - update(this, params); + this._lastRunCommand = ""; // updated whenever the users runs a command with :! + this._scriptNames = new RealSet; }, - historyKey: "file", + CommandFileMode: Class("CommandFileMode", modules.CommandMode, { + init: function init(prompt, params) { + init.supercall(this); + this.prompt = isArray(prompt) ? prompt : ["Question", prompt]; + update(this, params); + }, - get mode() modules.modes.FILE_INPUT, + historyKey: "file", - complete: function (context) { - if (this.completer) - this.completer(context); + get mode() modules.modes.FILE_INPUT, - context = context.fork("files", 0); - modules.completion.file(context); - context.filters = context.filters.concat(this.filters || []); - } - }), - - /** - * Returns all directories named *name* in 'runtimepath'. - * - * @param {string} name - * @returns {nsIFile[]) - */ - getRuntimeDirectories: function getRuntimeDirectories(name) { - return modules.options.get("runtimepath").files - .map(dir => dir.child(name)) - .filter(dir => (dir.exists() && dir.isDirectory() && dir.isReadable())); - }, - - // FIXME: multiple paths? - /** - * Sources files found in 'runtimepath'. For each relative path in *paths* - * each directory in 'runtimepath' is searched and if a matching file is - * found it is sourced. Only the first file found (per specified path) is - * sourced unless *all* is specified, then all found files are sourced. - * - * @param {[string]} paths An array of relative paths to source. - * @param {boolean} all Whether all found files should be sourced. - */ - sourceFromRuntimePath: function sourceFromRuntimePath(paths, all) { - let dirs = modules.options.get("runtimepath").files; - let found = null; - - dactyl.echomsg(_("io.searchingFor", paths.join(" ").quote(), modules.options.get("runtimepath").stringValue), 2); - - outer: - for (let dir in values(dirs)) { - for (let [, path] in Iterator(paths)) { - let file = dir.child(path); - - dactyl.echomsg(_("io.searchingFor", file.path.quote()), 3); - - if (file.exists() && file.isFile() && file.isReadable()) { - found = io.source(file.path, false) || true; - - if (!all) - break outer; + complete: function (context) { + if (this.completer) + this.completer(context); + + context = context.fork("files", 0); + modules.completion.file(context); + context.filters = context.filters.concat(this.filters || []); + } + }), + + /** + * Returns all directories named *name* in 'runtimepath'. + * + * @param {string} name + * @returns {nsIFile[] + */ + getRuntimeDirectories: function getRuntimeDirectories(name) { + return modules.options.get("runtimepath").files + .map(dir => dir.child(name)) + .filter(dir => (dir.exists() && dir.isDirectory() && dir.isReadable())); + }, + + // FIXME: multiple paths? + /** + * Sources files found in 'runtimepath'. For each relative path in *paths* + * each directory in 'runtimepath' is searched and if a matching file is + * found it is sourced. Only the first file found (per specified path) is + * sourced unless *all* is specified, then all found files are sourced. + * + * @param {[string]} paths An array of relative paths to source. + * @param {boolean} all Whether all found files should be sourced. + */ + sourceFromRuntimePath: function sourceFromRuntimePath(paths, all) { + let dirs = modules.options.get("runtimepath").files; + let found = null; + + dactyl.echomsg(_("io.searchingFor", JSON.stringify(paths.join(" ")), modules.options.get("runtimepath").stringValue), 2); + + outer: + for (let dir of values(dirs)) { + for (let [, path] of iter(paths)) { + let file = dir.child(path); + + dactyl.echomsg(_("io.searchingFor", JSON.stringify(file.path)), 3); + + if (file.exists() && file.isFile() && file.isReadable()) { + found = io.source(file.path, false) || true; + + if (!all) + break outer; + } } } - } - if (!found) - dactyl.echomsg(_("io.notInRTP", paths.join(" ").quote()), 1); - - return found; - }, - - /** - * Reads Ex commands, JavaScript or CSS from *filename*. - * - * @param {string} filename The name of the file to source. - * @param {object} params Extra parameters: - * group: The group in which to execute commands. - * silent: Whether errors should not be reported. - */ - source: function source(filename, params) { - const { contexts } = modules; - defineModule.loadLog.push("sourcing " + filename); - - if (!isObject(params)) - params = { silent: params }; - - let time = Date.now(); - return contexts.withContext(null, function () { - try { - var file = util.getFile(filename) || io.File(filename); + if (!found) + dactyl.echomsg(_("io.notInRTP", JSON.stringify(paths.join(" "))), 1); - if (!file.exists() || !file.isReadable() || file.isDirectory()) { - if (!params.silent) - dactyl.echoerr(_("io.notReadable", filename.quote())); - return; - } + return found; + }, - dactyl.echomsg(_("io.sourcing", filename.quote()), 2); + /** + * Reads Ex commands, JavaScript or CSS from *filename*. + * + * @param {string} filename The name of the file to source. + * @param {object} params Extra parameters: + * group: The group in which to execute commands. + * silent: Whether errors should not be reported. + */ + source: function source(filename, params) { + const { contexts } = modules; + defineModule.loadLog.push("sourcing " + filename); + + if (!isObject(params)) + params = { silent: params }; + + let time = Date.now(); + return contexts.withContext(null, function () { + try { + var file = util.getFile(filename) || io.File(filename); - let uri = file.URI; + if (!file.exists() || !file.isReadable() || file.isDirectory()) { + if (!params.silent) + dactyl.echoerr(_("io.notReadable", JSON.stringify(filename))); + return; + } - let sourceJSM = function sourceJSM() { - context = contexts.Module(uri); - dactyl.triggerObserver("io.source", context, file, file.lastModifiedTime); - }; + dactyl.echomsg(_("io.sourcing", JSON.stringify(filename)), 2); - if (/\.jsm$/.test(filename)) - sourceJSM(); - else if (/\.js$/.test(filename)) { - try { - var context = contexts.Script(file, params.group); - if (this._scriptNames.has(file.path)) - util.flushCache(); + let uri = file.URI; - dactyl.loadScript(uri.spec, context); + let sourceJSM = function sourceJSM() { + context = contexts.Module(uri); dactyl.triggerObserver("io.source", context, file, file.lastModifiedTime); - } - catch (e) { - if (e == Contexts) { // Hack; - context.unload(); - sourceJSM(); + }; + + if (/\.jsm$/.test(filename)) + sourceJSM(); + else if (/\.js$/.test(filename)) { + try { + var context = contexts.Script(file, params.group); + if (this._scriptNames.has(file.path)) + util.flushCache(); + + dactyl.loadScript(uri.spec, context); + dactyl.triggerObserver("io.source", context, file, file.lastModifiedTime); } - else { - if (e instanceof Finished) - return; - if (e.fileName && !(e instanceof FailedAssertion)) - try { - e.fileName = util.fixURI(e.fileName); - if (e.fileName == uri.spec) - e.fileName = filename; - e.echoerr = [e.fileName, ":", e.lineNumber, ": ", e].join(""); - } - catch (e) {} - throw e; + catch (e) { + if (e == Contexts) { // Hack; + context.unload(); + sourceJSM(); + } + else { + if (e instanceof Finished) + return; + if (e.fileName && !(e instanceof FailedAssertion)) + try { + e.fileName = util.fixURI(e.fileName); + if (e.fileName == uri.spec) + e.fileName = filename; + e.echoerr = [e.fileName, ":", e.lineNumber, ": ", e].join(""); + } + catch (e) {} + throw e; + } } } - } - else if (/\.css$/.test(filename)) - styles.registerSheet(uri.spec, false, true); - else { - context = contexts.Context(file, params.group); - modules.commands.execute(file.read(), null, params.silent, - null, { - context: context, - file: file.path, - group: context.GROUP, - line: 1 - }); - dactyl.triggerObserver("io.source", context, file, file.lastModifiedTime); - } + else if (/\.css$/.test(filename)) + styles.registerSheet(uri.spec, false, true); + else { + context = contexts.Context(file, params.group); + modules.commands.execute(file.read(), null, params.silent, + null, { + context: context, + file: file.path, + group: context.GROUP, + line: 1 + }); + dactyl.triggerObserver("io.source", context, file, file.lastModifiedTime); + } - this._scriptNames.add(file.path); + this._scriptNames.add(file.path); - dactyl.echomsg(_("io.sourcingEnd", filename.quote()), 2); - dactyl.log(_("dactyl.sourced", filename), 3); + dactyl.echomsg(_("io.sourcingEnd", JSON.stringify(filename)), 2); + dactyl.log(_("dactyl.sourced", filename), 3); - return context; - } - catch (e) { - util.reportError(e); - let message = _("io.sourcingError", e.echoerr || (file ? file.path : filename) + ": " + e); - if (!params.silent) - dactyl.echoerr(message); - } - finally { - defineModule.loadLog.push("done sourcing " + filename + ": " + (Date.now() - time) + "ms"); - } - }, this); - } - }), + return context; + } + catch (e) { + util.reportError(e); + let message = _("io.sourcingError", e.echoerr || (file ? file.path : filename) + ": " + e); + if (!params.silent) + dactyl.echoerr(message); + } + finally { + defineModule.loadLog.push("done sourcing " + filename + ": " + (Date.now() - time) + "ms"); + } + }, this); + } + }; + }, charsets: Class.Memoize(function () { const BASE = "@mozilla.org/intl/unicode/decoder;1?charset="; @@ -277,7 +280,7 @@ var IO = Module("io", { } else { let dir = io.File(newDir); - util.assert(dir.exists() && dir.isDirectory(), _("io.noSuchDir", dir.path.quote())); + util.assert(dir.exists() && dir.isDirectory(), _("io.noSuchDir", JSON.stringify(dir.path))); dir.normalize(); [this._cwd, this._oldcwd] = [dir.path, this.cwd]; } @@ -288,11 +291,13 @@ var IO = Module("io", { * @property {function} File class. * @final */ - File: Class.Memoize(function () let (io = this) - Class("File", File, { + File: Class.Memoize(function () { + let io = this; + return Class("File", File, { init: function init(path, checkCWD=true) init.supercall(this, path, checkCWD && io.cwd) - })), + }); + }), /** * @property {Object} The current file sourcing context. As a file is @@ -380,7 +385,7 @@ var IO = Module("io", { * @param {nsIURI|string} file The URI of the JAR file to list. * @param {string} path The prefix path to search. */ - listJar: function listJar(file, path) { + listJar: function* listJar(file, path) { file = util.getFile(file); if (file && file.exists() && file.isFile() && file.isReadable()) { // let jar = services.zipReader.getZip(file); Crashes. @@ -389,7 +394,7 @@ var IO = Module("io", { let filter = RegExp("^" + util.regexp.escape(decodeURI(path)) + "[^/]*/?$"); - for (let entry in iter(jar.findEntries("*"))) + for (let entry of iter(jar.findEntries("*"))) if (filter.test(entry)) yield entry; } @@ -426,7 +431,7 @@ var IO = Module("io", { if (config.OS.isWindows) dirs = [io.cwd].concat(dirs); - for (let [, dir] in Iterator(dirs)) + for (let dir of dirs) try { dir = this.File(dir, true); @@ -438,7 +443,7 @@ var IO = Module("io", { // automatically try to add the executable path extensions on windows if (config.OS.isWindows) { let extensions = services.environment.get("PATHEXT").split(";"); - for (let [, extension] in Iterator(extensions)) { + for (let extension of extensions) { file = dir.child(bin + extension); if (file.exists()) return file; @@ -494,8 +499,6 @@ var IO = Module("io", { return deferred.promise; }, - // TODO: when https://bugzilla.mozilla.org/show_bug.cgi?id=68702 is - // fixed use that instead of a tmpfile /** * Runs *command* in a subshell and returns the output. The shell used is * that specified by the 'shell' option. @@ -624,7 +627,7 @@ var IO = Module("io", { } else { let dirs = modules.options.get("cdpath").files; - for (let dir in values(dirs)) { + for (let dir of values(dirs)) { dir = dir.child(arg); if (dir.exists() && dir.isDirectory() && dir.isReadable()) { @@ -634,7 +637,7 @@ var IO = Module("io", { } } - dactyl.echoerr(_("io.noSuchDir", arg.quote())); + dactyl.echoerr(_("io.noSuchDir", JSON.stringify(arg))); dactyl.echoerr(_("io.commandFailed")); } }, { @@ -655,10 +658,13 @@ var IO = Module("io", { let file = io.File(args[0] || io.getRCFile(null, true)); - dactyl.assert(!file.exists() || args.bang, _("io.exists", file.path.quote())); + dactyl.assert(!file.exists() || args.bang, _("io.exists", JSON.stringify(file.path))); // TODO: Use a set/specifiable list here: - let lines = [cmd.serialize().map(commands.commandToString, cmd) for (cmd in commands.iterator()) if (cmd.serialize)]; + let lines = [cmd.serialize().map(commands.commandToString, cmd) + for (cmd of commands.iterator()) + if (cmd.serialize)]; + lines = array.flatten(lines); lines.unshift('"' + config.version + "\n"); @@ -666,10 +672,10 @@ var IO = Module("io", { try { file.write(lines.join("\n").concat("\n")); - dactyl.echomsg(_("io.writing", file.path.quote()), 2); + dactyl.echomsg(_("io.writing", JSON.stringify(file.path)), 2); } catch (e) { - dactyl.echoerr(_("io.notWriteable", file.path.quote())); + dactyl.echoerr(_("io.notWriteable", JSON.stringify(file.path))); dactyl.log(_("error.notWriteable", file.path, e.message)); // XXX } }, { @@ -685,19 +691,19 @@ var IO = Module("io", { if (args.length) { var rtDir = io.File(args[0]); - dactyl.assert(rtDir.exists(), _("io.noSuchDir", rtDir.path.quote())); + dactyl.assert(rtDir.exists(), _("io.noSuchDir", JSON.stringify(rtDir.path))); } else rtDir = io.File(config.OS.isWindows ? "~/vimfiles/" : "~/.vim/"); - dactyl.assert(!rtDir.exists() || rtDir.isDirectory(), _("io.eNotDir", rtDir.path.quote())); + dactyl.assert(!rtDir.exists() || rtDir.isDirectory(), _("io.eNotDir", JSON.stringify(rtDir.path))); let rtItems = { ftdetect: {}, ftplugin: {}, syntax: {} }; // require bang if any of the paths exist - for (let [type, item] in iter(rtItems)) { + for (let [type, item] of iter(rtItems)) { let file = io.File(rtDir).child(type, config.name + ".vim"); - dactyl.assert(!file.exists() || args.bang, _("io.exists", file.path.quote())); + dactyl.assert(!file.exists() || args.bang, _("io.exists", JSON.stringify(file.path))); item.file = file; } @@ -825,7 +831,7 @@ unlet s:cpo_save let lines = []; lines.__defineGetter__("last", function () this[this.length - 1]); - for (let item in values(items.array || items)) { + for (let item of values(items.array || items)) { if (item.length > width && (!lines.length || lines.last.length > 1)) { lines.push([prefix]); width = WIDTH - prefix.length; @@ -851,22 +857,22 @@ unlet s:cpo_save autocommands: wrap("syn keyword " + config.name + "AutoEvent ", keys(config.autocommands)), commands: wrap("syn keyword " + config.name + "Command ", - array(c.specs for (c in commands.iterator())).flatten()), + array(c.specs for (c of commands.iterator())).flatten()), options: wrap("syn keyword " + config.name + "Option ", - array(o.names for (o in options) if (o.type != "boolean")).flatten()), + array(o.names for (o of options) if (o.type != "boolean")).flatten()), toggleoptions: wrap("let s:toggleOptions = [", - array(o.realNames for (o in options) if (o.type == "boolean")) + array(o.realNames for (o of options) if (o.type == "boolean")) .flatten().map(String.quote), ", ") + "]" }; //}}} - for (let { file, template } in values(rtItems)) { + for (let { file, template } of values(rtItems)) { try { file.write(util.compileMacro(template, true)(params)); - dactyl.echomsg(_("io.writing", file.path.quote()), 2); + dactyl.echomsg(_("io.writing", JSON.stringify(file.path)), 2); } catch (e) { - dactyl.echoerr(_("io.notWriteable", file.path.quote())); + dactyl.echoerr(_("io.notWriteable", JSON.stringify(file.path))); dactyl.log(_("error.notWriteable", file.path, e.message)); } } @@ -896,7 +902,7 @@ unlet s:cpo_save else modules.commandline.commandOutput( template.tabular(["", "Filename"], ["text-align: right; padding-right: 1em;"], - ([i + 1, file] for ([i, file] in Iterator(names))))); + ([i + 1, file] for ([i, file] of iter(names))))); }, { argCount: "0" }); @@ -1022,7 +1028,7 @@ unlet s:cpo_save isDirectory: function () s.substr(-1) == "/", leafName: /([^\/]*)\/?$/.exec(s)[1] } - for (s in io.listJar(uri.JARFile, getDir(uri.JAREntry)))] + for (s of io.listJar(uri.JARFile, getDir(uri.JAREntry)))] }; else context.generate = function generate_file() { @@ -1035,7 +1041,7 @@ unlet s:cpo_save }; completion.runtime = function (context) { - for (let [, dir] in Iterator(modules.options["runtimepath"])) + for (let dir of modules.options["runtimepath"]) context.fork(dir, 0, this, function (context) { dir = dir.replace("/+$", "") + "/"; completion.file(context, true, dir + context.filter); @@ -1050,10 +1056,10 @@ unlet s:cpo_save let dirNames = services.environment.get("PATH").split(config.OS.pathListSep); let commands = []; - for (let [, dirName] in Iterator(dirNames)) { + for (let dirName of dirNames) { let dir = io.File(dirName); if (dir.exists() && dir.isDirectory()) - commands.push([[file.leafName, dir.path] for (file in iter(dir.directoryEntries)) + commands.push([[file.leafName, dir.path] for (file of iter(dir.directoryEntries)) if (file.isFile() && file.isExecutable())]); } diff --git a/common/modules/javascript.jsm b/common/modules/javascript.jsm index 8b23315d..de163acf 100644 --- a/common/modules/javascript.jsm +++ b/common/modules/javascript.jsm @@ -69,24 +69,24 @@ var JavaScript = Module("javascript", { return undefined; }, - iter: function iter_(obj, toplevel) { + iter: function* iter_(obj, toplevel) { if (obj == null) return; - let seen = RealSet(isinstance(obj, ["Sandbox"]) ? JavaScript.magicalNames : []); + let seen = new RealSet(isinstance(obj, ["Sandbox"]) ? JavaScript.magicalNames : []); let globals = values(toplevel && this.window === obj ? this.globalNames : []); if (toplevel && isObject(obj) && "wrappedJSObject" in obj) if (!seen.add("wrappedJSObject")) yield "wrappedJSObject"; - for (let key in iter(globals, properties(obj, !toplevel))) + for (let key of iter(globals, properties(obj, !toplevel))) if (!seen.add(key)) yield key; // Properties aren't visible in an XPCNativeWrapper until // they're accessed. - for (let key in properties(this.getKey(obj, "wrappedJSObject"), + for (let key of properties(this.getKey(obj, "wrappedJSObject"), !toplevel)) try { if (key in obj && !seen.has(key)) @@ -104,9 +104,9 @@ var JavaScript = Module("javascript", { if (isPrototypeOf.call(this.toplevel, obj) && !toplevel) return []; - let completions = [k for (k in this.iter(obj, toplevel))]; + let completions = [k for (k of this.iter(obj, toplevel))]; if (obj === this.modules) // Hack. - completions = array.uniq(completions.concat([k for (k in this.iter(this.modules.jsmodules, toplevel))])); + completions = array.uniq(completions.concat([k for (k of this.iter(this.modules.jsmodules, toplevel))])); return completions; }, @@ -294,7 +294,7 @@ var JavaScript = Module("javascript", { let prev = statement; let obj = this.window; let cacheKey; - for (let [, dot] in Iterator(this._get(frame).dots.concat(stop))) { + for (let dot of this._get(frame).dots.concat(stop)) { if (dot < statement) continue; if (dot > stop || dot <= prev) @@ -308,7 +308,7 @@ var JavaScript = Module("javascript", { if (this._checkFunction(prev, dot, cacheKey)) return []; if (prev != statement && obj == null) { - this.context.message = /*L*/"Error: " + cacheKey.quote() + " is " + String(obj); + this.context.message = /*L*/"Error: " + JSON.stringify(cacheKey) + " is " + String(obj); return []; } @@ -471,7 +471,7 @@ var JavaScript = Module("javascript", { // This allows for things like: // let doc = content.document; let elem = doc.createEle ... let prev = 0; - for (let [, v] in Iterator(this._get(0).fullStatements)) { + for (let v of this._get(0).fullStatements) { let key = this._str.substring(prev, v + 1); if (this._checkFunction(prev, v, key)) return null; @@ -560,7 +560,7 @@ var JavaScript = Module("javascript", { // Split up the arguments let prev = this._get(-2).offset; let args = []; - for (let [i, idx] in Iterator(this._get(-2).comma)) { + for (let [i, idx] of iter(this._get(-2).comma)) { let arg = this._str.substring(prev + 1, idx); prev = idx; memoize(args, i, () => self.evalled(arg)); @@ -622,26 +622,28 @@ var JavaScript = Module("javascript", { * A list of properties of the global object which are not * enumerable by any standard method. */ - globalNames: Class.Memoize(function () let (self = this) array.uniq([ - "Array", "ArrayBuffer", "AttributeName", "Audio", "Boolean", "Components", - "CSSFontFaceStyleDecl", "CSSGroupRuleRuleList", "CSSNameSpaceRule", - "CSSRGBColor", "CSSRect", "ComputedCSSStyleDeclaration", "Date", "Error", - "EvalError", "File", "Float32Array", "Float64Array", "Function", - "HTMLDelElement", "HTMLInsElement", "HTMLSpanElement", "Infinity", - "InnerModalContentWindow", "InnerWindow", "Int16Array", "Int32Array", - "Int8Array", "InternalError", "Iterator", "JSON", "KeyboardEvent", - "Math", "NaN", "Namespace", "Number", "Object", "Proxy", "QName", - "ROCSSPrimitiveValue", "RangeError", "ReferenceError", "RegExp", - "StopIteration", "String", "SyntaxError", "TypeError", "URIError", - "Uint16Array", "Uint32Array", "Uint8Array", "XML", "XMLHttpProgressEvent", - "XMLList", "XMLSerializer", "XPCNativeWrapper", - "XULControllers", "constructor", "decodeURI", "decodeURIComponent", - "encodeURI", "encodeURIComponent", "escape", "eval", "isFinite", "isNaN", - "isXMLName", "parseFloat", "parseInt", "undefined", "unescape", "uneval" - ].concat([k.substr(6) for (k in keys(Ci)) if (/^nsIDOM/.test(k))]) - .concat([k.substr(3) for (k in keys(Ci)) if (/^nsI/.test(k))]) - .concat(this.magicalNames) - .filter(k => k in self.window))), + globalNames: Class.Memoize(function () { + return array.uniq([ + "Array", "ArrayBuffer", "AttributeName", "Audio", "Boolean", "Components", + "CSSFontFaceStyleDecl", "CSSGroupRuleRuleList", "CSSNameSpaceRule", + "CSSRGBColor", "CSSRect", "ComputedCSSStyleDeclaration", "Date", "Error", + "EvalError", "File", "Float32Array", "Float64Array", "Function", + "HTMLDelElement", "HTMLInsElement", "HTMLSpanElement", "Infinity", + "InnerModalContentWindow", "InnerWindow", "Int16Array", "Int32Array", + "Int8Array", "InternalError", "Iterator", "JSON", "KeyboardEvent", + "Math", "NaN", "Namespace", "Number", "Object", "Proxy", "QName", + "ROCSSPrimitiveValue", "RangeError", "ReferenceError", "RegExp", + "StopIteration", "String", "SyntaxError", "TypeError", "URIError", + "Uint16Array", "Uint32Array", "Uint8Array", "XML", "XMLHttpProgressEvent", + "XMLList", "XMLSerializer", "XPCNativeWrapper", + "XULControllers", "constructor", "decodeURI", "decodeURIComponent", + "encodeURI", "encodeURIComponent", "escape", "eval", "isFinite", "isNaN", + "isXMLName", "parseFloat", "parseInt", "undefined", "unescape", "uneval" + ].concat([k.substr(6) for (k of keys(Ci)) if (/^nsIDOM/.test(k))]) + .concat([k.substr(3) for (k of keys(Ci)) if (/^nsI/.test(k))]) + .concat(this.magicalNames) + .filter(k => k in this.window)); + }), }, { EVAL_TMP: "__dactyl_eval_tmp", @@ -675,7 +677,7 @@ var JavaScript = Module("javascript", { */ setCompleter: function (funcs, completers) { funcs = Array.concat(funcs); - for (let [, func] in Iterator(funcs)) { + for (let func of funcs) { func.dactylCompleter = function (context, func, obj, args) { let completer = completers[args.length - 1]; if (!completer) diff --git a/common/modules/main.jsm b/common/modules/main.jsm index c58789f9..e5dade2b 100644 --- a/common/modules/main.jsm +++ b/common/modules/main.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 Kris Maglione +// Copyright (c) 2009-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -136,6 +136,8 @@ var Modules = function Modules(window) { const create = bind("create", jsmodules.Object); const modules = update(create(jsmodules), { + Symbol: Symbol, + yes_i_know_i_should_not_report_errors_in_these_branches_thanks: [], jsmodules: jsmodules, @@ -143,7 +145,7 @@ var Modules = function Modules(window) { Module: Module, load: function load(script) { - for (let [i, base] in Iterator(BASES)) { + for (let base of BASES) { try { JSMLoader.loadSubScript(base + script + ".js", modules, "UTF-8"); return; @@ -212,8 +214,8 @@ overlay.overlayWindow(Object.keys(config.overlays), this.startTime = Date.now(); this.deferredInit = { load: {} }; - this.seen = RealSet(); - this.loaded = RealSet(); + this.seen = new RealSet; + this.loaded = new RealSet; modules.loaded = this.loaded; this.modules = modules; @@ -286,7 +288,7 @@ overlay.overlayWindow(Object.keys(config.overlays), if (seen.add(module.className)) throw Error("Module dependency loop."); - for (let dep in values(module.requires)) + for (let dep of values(module.requires)) this.loadModule(Module.constructors[dep], module.className); defineModule.loadLog.push( @@ -346,7 +348,7 @@ overlay.overlayWindow(Object.keys(config.overlays), let { Module, modules } = this.modules; defineModule.modules.forEach((mod) => { - let names = RealSet(Object.keys(mod.INIT)); + let names = new RealSet(Object.keys(mod.INIT)); if ("init" in mod.INIT) names.add("init"); @@ -368,7 +370,7 @@ overlay.overlayWindow(Object.keys(config.overlays), }, initDependencies: function initDependencies(name, parents) { - for (let [k, v] in Iterator(this.deferredInit[name] || {})) + for (let [k, v] of iter(this.deferredInit[name] || {})) if (!parents || ~parents.indexOf(k)) util.trapErrors(v); } diff --git a/common/modules/messages.jsm b/common/modules/messages.jsm index 82c0f3c6..1cbf3be3 100644 --- a/common/modules/messages.jsm +++ b/common/modules/messages.jsm @@ -55,16 +55,16 @@ var Messages = Module("messages", { } })), - iterate: function () { - let seen = RealSet(); - for (let bundle in values(this.bundles)) - for (let { key, value } in iter(bundle.getSimpleEnumeration(), Ci.nsIPropertyElement)) + iterate: function* () { + let seen = new RealSet; + for (let bundle of this.bundles) + for (let { key, value } of iter(bundle.getSimpleEnumeration(), Ci.nsIPropertyElement)) if (!seen.add(key)) yield [key, value]; }, get: function get(value, default_) { - for (let bundle in values(this.bundles)) + for (let bundle of this.bundles) try { let res = bundle.GetStringFromName(value); if (res.slice(0, 2) == "+ ") @@ -80,7 +80,7 @@ var Messages = Module("messages", { }, format: function format(value, args, default_) { - for (let bundle in values(this.bundles)) + for (let bundle of this.bundles) try { let res = bundle.formatStringFromName(value, args, args.length); if (res.slice(0, 2) == "+ ") @@ -105,18 +105,22 @@ var Messages = Module("messages", { let { Buffer, commands, hints, io, mappings, modes, options, sanitizer } = overlay.activeModules; file = io.File(file); - function properties(base, iter_, prop="description") iter(function _properties() { + function properties(base, iter_, prop="description") iter(function* _properties() { function key(...args) [base, obj.identifier || obj.name].concat(args).join(".").replace(/[\\:=]/g, "\\$&"); - for (var obj in iter_) { + for (var obj of iter_) { if (!obj.hive || obj.hive.name !== "user") { yield key(prop) + " = " + obj[prop]; - if (iter_.values) - for (let [k, v] in isArray(obj.values) ? array.iterValues(obj.values) : iter(obj.values)) + if (iter_.values) { + let iter_ = isArray(obj.values) ? array.iterValues(obj.values) + : iter(obj.values); + + for (let [k, v] of iter_) yield key("values", k) + " = " + v; + } - for (let opt in values(obj.options)) + for (let opt of values(obj.options)) yield key("options", opt.names[0]) + " = " + opt.description; if (obj.deprecated) @@ -148,7 +152,7 @@ var Messages = Module("messages", { */ if (!hasOwnProperty(obj, "localizedProperties")) - obj.localizedProperties = RealSet(obj.localizedProperties); + obj.localizedProperties = new RealSet(obj.localizedProperties); obj.localizedProperties.add(prop); obj[_prop] = this.default; diff --git a/common/modules/options.jsm b/common/modules/options.jsm index 302a1d34..32b32497 100644 --- a/common/modules/options.jsm +++ b/common/modules/options.jsm @@ -1,6 +1,6 @@ // Copyright (c) 2006-2008 by Martin Stubenschrott // Copyright (c) 2007-2011 by Doug Kearns -// Copyright (c) 2008-2014 by Kris Maglione +// Copyright (c) 2008-2015 by Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -65,7 +65,7 @@ var Option = Class("Option", { this.globalValue = this.defaultValue; }, - magicalProperties: RealSet(["cleanupValue"]), + magicalProperties: new RealSet(["cleanupValue"]), /** * @property {string} This option's description, as shown in :listoptions. @@ -489,7 +489,7 @@ var Option = Class("Option", { get charlist() this.stringlist, regexplist: function regexplist(k, default_=null) { - for (let re in values(this.value)) + for (let re of values(this.value)) if ((re.test || re).call(re, k)) return re.result; return default_; @@ -509,7 +509,7 @@ var Option = Class("Option", { stringlist: function (vals) vals.map(Option.quote).join(","), - stringmap: function (vals) [Option.quote(k, /:/) + ":" + Option.quote(v, /:/) for ([k, v] in Iterator(vals))].join(","), + stringmap: function (vals) [Option.quote(k, /:/) + ":" + Option.quote(v, /:/) for ([k, v] of iter(vals))].join(","), regexplist: function (vals) vals.join(","), get regexpmap() this.regexplist, @@ -518,8 +518,12 @@ var Option = Class("Option", { }, parse: { - number: function (value) let (val = Option.dequote(value)) - Option.validIf(Number(val) % 1 == 0, _("option.intRequired")) && parseInt(val), + number: function (value) { + let val = Option.dequote(value); + return (Option.validIf(Number(val) % 1 == 0, + _("option.intRequired")) && + parseInt(val)); + }, boolean: function boolean(value) Option.dequote(value) == "true" || value == true ? true : false, @@ -549,8 +553,10 @@ var Option = Class("Option", { sitemap: function sitemap(value) Option.parse.list.call(this, value, Option.parseSite), - list: function list(value, parse) let (prev = null) - array.compact(Option.splitList(value, true).map(function (v) { + list: function list(value, parse) { + let prev = null; + return array.compact(Option.splitList(value, true) + .map(function (v) { let [count, filter, quote] = Commands.parseArg(v, /:/, true); let val = v.substr(count + 1); @@ -563,7 +569,8 @@ var Option = Class("Option", { util.assert(prev, _("error.syntaxError"), false); prev.result += "," + v; } - }, this)) + }, this)); + }, }, parseKey: { @@ -662,13 +669,13 @@ var Option = Class("Option", { case "^": return update(res, values); case "-": - for (let [k, v] in Iterator(values)) + for (let [k, v] of iter(values)) if (v === res[k]) delete res[k]; return res; case "=": if (invert) { - for (let [k, v] in Iterator(values)) + for (let [k, v] of iter(values)) if (v === res[k]) delete res[k]; else @@ -684,7 +691,7 @@ var Option = Class("Option", { values = Array.concat(values); function uniq(ary) { - let seen = RealSet(); + let seen = new RealSet; return ary.filter(elem => !seen.add(elem)); } @@ -695,11 +702,11 @@ var Option = Class("Option", { // NOTE: Vim doesn't prepend if there's a match in the current value return uniq(Array.concat(values, this.value), true); case "-": - return this.value.filter(function (item) !this.has(item), RealSet(values)); + return this.value.filter(function (item) !this.has(item), new RealSet(values)); case "=": if (invert) { - let keepValues = this.value.filter(function (item) !this.has(item), RealSet(values)); - let addValues = values.filter(function (item) !this.has(item), RealSet(this.value)); + let keepValues = this.value.filter(function (item) !this.has(item), new RealSet(values)); + let addValues = values.filter(function (item) !this.has(item), new RealSet(this.value)); return addValues.concat(keepValues); } return values; @@ -747,10 +754,10 @@ var Option = Class("Option", { acceptable = completions.call(this); if (isArray(acceptable)) - acceptable = RealSet(acceptable.map(([k]) => k)); + acceptable = new RealSet(acceptable.map(([k]) => k)); else - acceptable = RealSet(this.parseKey(k) - for (k of Object.keys(acceptable))); + acceptable = new RealSet(this.parseKey(k) + for (k of Object.keys(acceptable))); if (this.type === "regexpmap" || this.type === "sitemap") return Array.concat(vals).every(re => acceptable.has(re.result)); @@ -803,7 +810,7 @@ var Option = Class("Option", { update(BooleanOption.prototype, { names: Class.Memoize(function () - array.flatten([[name, "no" + name] for (name in values(this.realNames))])) + array.flatten([[name, "no" + name] for (name of values(this.realNames))])) }); var OptionHive = Class("OptionHive", Contexts.Hive, { @@ -822,157 +829,160 @@ var OptionHive = Class("OptionHive", Contexts.Hive, { * @instance options */ var Options = Module("options", { - Local: function Local(dactyl, modules, window) let ({ contexts } = modules) ({ - init: function init() { - const self = this; - - update(this, { - hives: contexts.Hives("options", Class("OptionHive", OptionHive, { modules: modules })), - user: contexts.hives.options.user - }); - - this.needInit = []; - this._options = []; - this._optionMap = {}; - - storage.newMap("options", { store: false }); - storage.addObserver("options", function optionObserver(key, event, option) { - // Trigger any setters. - let opt = self.get(option); - if (event == "change" && opt) - opt.set(opt.globalValue, Option.SCOPE_GLOBAL, true); - }, window); - - modules.cache.register("options.dtd", - () => util.makeDTD( - iter(([["option", o.name, "default"].join("."), - o.type === "string" ? o.defaultValue.replace(/'/g, "''") : - o.defaultValue === true ? "on" : - o.defaultValue === false ? "off" : o.stringDefaultValue] - for (o in self)), - - ([["option", o.name, "type"].join("."), o.type] for (o in self)), - - config.dtd)), - true); - }, - - signals: { - "io.source": function ioSource(context, file, modTime) { - cache.flushEntry("options.dtd", modTime); - } - }, + Local: function Local(dactyl, modules, window) { + let { contexts } = modules; + return { + init: function init() { + const self = this; + + update(this, { + hives: contexts.Hives("options", Class("OptionHive", OptionHive, { modules: modules })), + user: contexts.hives.options.user + }); - dactyl: dactyl, + this.needInit = []; + this._options = []; + this._optionMap = {}; + + storage.newMap("options", { store: false }); + storage.addObserver("options", function optionObserver(key, event, option) { + // Trigger any setters. + let opt = self.get(option); + if (event == "change" && opt) + opt.set(opt.globalValue, Option.SCOPE_GLOBAL, true); + }, window); + + modules.cache.register("options.dtd", + () => util.makeDTD( + iter(([["option", o.name, "default"].join("."), + o.type === "string" ? o.defaultValue.replace(/'/g, "''") : + o.defaultValue === true ? "on" : + o.defaultValue === false ? "off" : o.stringDefaultValue] + for (o of self)), + + ([["option", o.name, "type"].join("."), o.type] for (o in self)), + + config.dtd)), + true); + }, - /** - * Lists all options in *scope* or only those with changed values if - * *onlyNonDefault* is specified. - * - * @param {function(Option)} filter Limit the list - * @param {number} scope Only list options in this scope (see - * {@link Option#scope}). - */ - list: function list(filter, scope) { - if (!scope) - scope = Option.SCOPE_BOTH; - - function opts(opt) { - for (let opt in Iterator(this)) { - if (filter && !filter(opt)) - continue; - if (!(opt.scope & scope)) - continue; - - let option = { - __proto__: opt, - isDefault: opt.isDefault, - default: opt.stringDefaultValue, - pre: "\u00a0\u00a0", // Unicode nonbreaking space. - value: [] - }; - - if (opt.type == "boolean") { - if (!opt.value) - option.pre = "no"; - option.default = (opt.defaultValue ? "" : "no") + opt.name; - } - else if (isArray(opt.value) && opt.type != "charlist") - option.value = ["", "=", - template.map(opt.value, - v => template.highlight(String(v)), - ["", ",", - ["span", { style: "width: 0; display: inline-block" }, " "]])]; - else - option.value = ["", "=", template.highlight(opt.stringValue)]; - yield option; + signals: { + "io.source": function ioSource(context, file, modTime) { + cache.flushEntry("options.dtd", modTime); } - }; - - modules.commandline.commandOutput( - template.options("Options", opts.call(this), this["verbose"] > 0)); - }, - - cleanup: function cleanup() { - for (let opt in this) - if (opt.cleanupValue != null) - opt.stringValue = opt.cleanupValue; - }, - - /** - * Adds a new option. - * - * @param {[string]} names All names for the option. - * @param {string} description A description of the option. - * @param {string} type The option type (see {@link Option#type}). - * @param {value} defaultValue The option's default value. - * @param {Object} extra An optional extra configuration hash (see - * {@link Map#extraInfo}). - * @optional - */ - add: function add(names, description, type, defaultValue, extraInfo) { - if (!util.isDactyl(Components.stack.caller)) - deprecated.warn(add, "options.add", "group.options.add"); + }, - util.assert(type in Option.types, _("option.noSuchType", type), - false); + dactyl: dactyl, + + /** + * Lists all options in *scope* or only those with changed values if + * *onlyNonDefault* is specified. + * + * @param {function(Option)} filter Limit the list + * @param {number} scope Only list options in this scope (see + * {@link Option#scope}). + */ + list: function list(filter, scope) { + if (!scope) + scope = Option.SCOPE_BOTH; + + function* opts(opt) { + for (let opt of this) { + if (filter && !filter(opt)) + continue; + if (!(opt.scope & scope)) + continue; + + let option = { + __proto__: opt, + isDefault: opt.isDefault, + default: opt.stringDefaultValue, + pre: "\u00a0\u00a0", // Unicode nonbreaking space. + value: [] + }; + + if (opt.type == "boolean") { + if (!opt.value) + option.pre = "no"; + option.default = (opt.defaultValue ? "" : "no") + opt.name; + } + else if (isArray(opt.value) && opt.type != "charlist") + option.value = ["", "=", + template.map(opt.value, + v => template.highlight(String(v)), + ["", ",", + ["span", { style: "width: 0; display: inline-block" }, " "]])]; + else + option.value = ["", "=", template.highlight(opt.stringValue)]; + yield option; + } + }; - if (!extraInfo) - extraInfo = {}; + modules.commandline.commandOutput( + template.options("Options", opts.call(this), this["verbose"] > 0)); + }, - extraInfo.definedAt = contexts.getCaller(Components.stack.caller); + cleanup: function cleanup() { + for (let opt of this) + if (opt.cleanupValue != null) + opt.stringValue = opt.cleanupValue; + }, - let name = names[0]; - if (name in this._optionMap) { - this.dactyl.log(_("option.replaceExisting", name.quote()), 1); - this.remove(name); - } + /** + * Adds a new option. + * + * @param {[string]} names All names for the option. + * @param {string} description A description of the option. + * @param {string} type The option type (see {@link Option#type}). + * @param {value} defaultValue The option's default value. + * @param {Object} extra An optional extra configuration hash (see + * {@link Map#extraInfo}). + * @optional + */ + add: function add(names, description, type, defaultValue, extraInfo) { + if (!util.isDactyl(Components.stack.caller)) + deprecated.warn(add, "options.add", "group.options.add"); + + util.assert(type in Option.types, _("option.noSuchType", type), + false); + + if (!extraInfo) + extraInfo = {}; + + extraInfo.definedAt = contexts.getCaller(Components.stack.caller); + + let name = names[0]; + if (name in this._optionMap) { + this.dactyl.log(_("option.replaceExisting", JSON.stringify(name)), 1); + this.remove(name); + } - let closure = () => this._optionMap[name]; + let closure = () => this._optionMap[name]; - memoize(this._optionMap, name, - function () Option.types[type](modules, names, description, defaultValue, extraInfo)); + memoize(this._optionMap, name, + function () Option.types[type](modules, names, description, defaultValue, extraInfo)); - for (let alias in values(names.slice(1))) - memoize(this._optionMap, alias, closure); + for (let alias of values(names.slice(1))) + memoize(this._optionMap, alias, closure); - if (extraInfo.setter && (!extraInfo.scope || extraInfo.scope & Option.SCOPE_GLOBAL)) - if (this.dactyl.initialized) - closure().initValue(); - else - memoize(this.needInit, this.needInit.length, closure); + if (extraInfo.setter && (!extraInfo.scope || extraInfo.scope & Option.SCOPE_GLOBAL)) + if (this.dactyl.initialized) + closure().initValue(); + else + memoize(this.needInit, this.needInit.length, closure); - this._floptions = (this._floptions || []).concat(name); - memoize(this._options, this._options.length, closure); + this._floptions = (this._floptions || []).concat(name); + memoize(this._options, this._options.length, closure); - // quickly access options with options["wildmode"]: - this.__defineGetter__(name, function () this._optionMap[name].value); - this.__defineSetter__(name, function (value) { this._optionMap[name].value = value; }); - } - }), + // quickly access options with options["wildmode"]: + this.__defineGetter__(name, function () this._optionMap[name].value); + this.__defineSetter__(name, function (value) { this._optionMap[name].value = value; }); + } + }; + }, /** @property {Iterator(Option)} @private */ - __iterator__: function __iterator__() + "@@iterator": function __iterator__() values(this._options.sort((a, b) => String.localeCompare(a.name, b.name))), allPrefs: deprecated("prefs.getNames", function allPrefs() prefs.getNames.apply(prefs, arguments)), @@ -1085,7 +1095,7 @@ var Options = Module("options", { remove: function remove(name) { let opt = this.get(name); this._options = this._options.filter(o => o != opt); - for (let name in values(opt.names)) + for (let name of values(opt.names)) delete this._optionMap[name]; }, @@ -1120,7 +1130,7 @@ var Options = Module("options", { let list = []; function flushList() { - let names = RealSet(list.map(opt => opt.option ? opt.option.name : "")); + let names = new RealSet(list.map(opt => opt.option ? opt.option.name : "")); if (list.length) if (list.some(opt => opt.all)) options.list(opt => !(list[0].onlyNonDefault && opt.isDefault), @@ -1131,7 +1141,7 @@ var Options = Module("options", { list = []; } - for (let [, arg] in args) { + for (let arg of args) { if (bang) { let onlyNonDefault = false; let reset = false; @@ -1153,7 +1163,7 @@ var Options = Module("options", { modules.commandline.input(_("pref.prompt.resetAll", config.host) + " ", function (resp) { if (resp == "yes") - for (let pref in values(prefs.getNames())) + for (let pref of values(prefs.getNames())) prefs.reset(pref); }, { promptHighlight: "WarningMsg" }); @@ -1195,7 +1205,7 @@ var Options = Module("options", { if (opt.reset) { flushList(); if (opt.all) { - for (let option in modules.options) + for (let option of modules.options) option.reset(); } else { @@ -1301,7 +1311,7 @@ var Options = Module("options", { // Fill in the current values if we're removing if (opt.operator == "-" && isArray(opt.values)) { - let have = RealSet((i.text for (i in values(context.allItems.items)))); + let have = new RealSet(i.text for (i of values(context.allItems.items))); context = context.fork("current-values", 0); context.anchored = optcontext.anchored; context.maxItems = optcontext.maxItems; @@ -1392,7 +1402,7 @@ var Options = Module("options", { literalArg: [opt.type == "boolean" ? (opt.value ? "" : "no") + opt.name : opt.name + "=" + opt.stringValue] } - for (opt in modules.options) + for (opt of modules.options) if (!opt.getter && !opt.isDefault && (opt.scope & Option.SCOPE_GLOBAL)) ] } @@ -1431,7 +1441,7 @@ var Options = Module("options", { commands.add(["unl[et]"], "Delete a variable", function (args) { - for (let [, name] in args) { + for (let name of args) { name = name.replace(/^g:/, ""); // throw away the scope prefix if (!hasOwnProperty(dactyl._globalVariables, name)) { if (!args.bang) @@ -1559,7 +1569,7 @@ var Options = Module("options", { }, javascript: function initJavascript(dactyl, modules, window) { const { options, JavaScript } = modules; - JavaScript.setCompleter(Options.prototype.get, [() => ([o.name, o.description] for (o in options))]); + JavaScript.setCompleter(Options.prototype.get, [() => ([o.name, o.description] for (o of options))]); }, sanitizer: function initSanitizer(dactyl, modules, window) { const { sanitizer } = modules; @@ -1568,7 +1578,7 @@ var Options = Module("options", { description: "Options containing hostname data", action: function sanitize_action(timespan, host) { if (host) - for (let opt in values(modules.options._options)) + for (let opt of values(modules.options._options)) if (timespan.contains(opt.lastSet * 1000) && opt.domains) try { opt.value = opt.filterDomain(host, opt.value); @@ -1578,12 +1588,12 @@ var Options = Module("options", { } }, privateEnter: function privateEnter() { - for (let opt in values(modules.options._options)) + for (let opt of values(modules.options._options)) if (opt.privateData && (!callable(opt.privateData) || opt.privateData(opt.value))) opt.oldValue = opt.value; }, privateLeave: function privateLeave() { - for (let opt in values(modules.options._options)) + for (let opt of values(modules.options._options)) if (opt.oldValue != null) { opt.value = opt.oldValue; opt.oldValue = null; diff --git a/common/modules/overlay.jsm b/common/modules/overlay.jsm index f52a23eb..a3f7cc53 100644 --- a/common/modules/overlay.jsm +++ b/common/modules/overlay.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 Kris Maglione +// Copyright (c) 2009-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -37,7 +37,7 @@ var Overlay = Class("Overlay", { $: function $(sel, node) DOM(sel, node || this.doc), cleanup: function cleanup(window, reason) { - for (let fn in values(this.cleanups)) + for (let fn of this.cleanups) util.trapErrors(fn, this, window, reason); } }); @@ -46,8 +46,8 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen init: function init() { util.addObserver(this); this.overlays = {}; - - this.weakMap = WeakMap(); + this.overlayMatchers = []; + this.weakMap = new WeakMap; this.onWindowVisible = []; }, @@ -75,8 +75,8 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen else [self, events] = [event, event[callback || "events"]]; - for (let [event, callback] in Iterator(events)) { - let args = [util.weakReference(target), + for (let [event, callback] of iter(events)) { + let args = [Cu.getWeakReference(target), event, util.wrapCallback(callback, self), capture, @@ -113,15 +113,15 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen }, cleanup: function cleanup(reason) { - for (let doc in util.iterDocuments()) { - for (let callback in values(this.getData(doc, "cleanup"))) + for (let doc of util.iterDocuments()) { + for (let callback of this.getData(doc, "cleanup")) util.trapErrors(callback, doc, reason); - for (let elem in values(this.getData(doc, "overlayElements"))) + for (let elem of this.getData(doc, "overlayElements")) if (elem.parentNode) elem.parentNode.removeChild(elem); - for (let [elem, ns, name, orig, value] in values(this.getData(doc, "overlayAttributes"))) + for (let [elem, ns, name, orig, value] of this.getData(doc, "overlayAttributes")) if (getAttr(elem, ns, name) === value) setAttr(elem, ns, name, orig); @@ -192,17 +192,65 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen delete data[key]; }, + /** + * A curried function which determines which host names match a + * given stylesheet filter. When presented with one argument, + * returns a matcher function which, given one nsIURI argument, + * returns true if that argument matches the given filter. When + * given two arguments, returns true if the second argument matches + * the given filter. + * + * @param {string|function(nsIURI):boolean} filter The URI filter to match against. + * @param {nsIURI} uri The location to test. + * @returns {nsIURI -> boolean} + */ + matchFilter: function matchFilter(filter) { + if (typeof filter == "function") + var test = filter; + else { + filter = filter.trim(); + + if (filter === "*") + var test = function test(uri) true; + else if (!/^(?:[a-z-]+:|[a-z-.]+$)/.test(filter)) { + let re = util.regexp(filter); + test = function test(uri) re.test(uri.spec); + } + else if (/[*]$/.test(filter)) { + let re = RegExp("^" + util.regexp.escape(filter.substr(0, filter.length - 1))); + test = function test(uri) re.test(uri.spec); + test.re = re; + } + else if (/[\/:]/.test(filter)) { + test = function test(uri) uri.spec === filter; + test.exact = true; + } + else + test = function test(uri) { try { return util.isSubdomain(uri.host, filter); } catch (e) { return false; } }; + test.toString = function toString() filter; + test.key = filter; + } + if (arguments.length < 2) + return test; + return test(arguments[1]); + }, + overlayWindow: function overlayWindow(url, fn) { if (url instanceof Ci.nsIDOMWindow) overlay._loadOverlay(url, fn); else { Array.concat(url).forEach(function (url) { - if (!this.overlays[url]) - this.overlays[url] = []; - this.overlays[url].push(fn); + let matcher = this.matchFilter(url); + if (!matcher.exact) + this.overlayMatchers.push([matcher, fn]); + else { + if (!this.overlays[url]) + this.overlays[url] = []; + this.overlays[url].push(fn); + } }, this); - for (let doc in util.iterDocuments()) + for (let doc of util.iterDocuments()) if (~["interactive", "complete"].indexOf(doc.readyState)) { this.observe(doc.defaultView, "xul-window-visible"); this._loadOverlays(doc.defaultView); @@ -215,10 +263,18 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen } }, + getOverlays: function* getOverlays(window) { + for (let overlay of this.overlays[window.document.documentURI] || []) + yield overlay; + for (let [matcher, overlay] of this.overlayMatchers) + if (matcher(window.document.documentURIObject)) + yield overlay; + }, + _loadOverlays: function _loadOverlays(window) { - let overlays = this.getData(window, "overlays"); + let overlays = this.getData(window.document, "overlays"); - for (let obj of overlay.overlays[window.document.documentURI] || []) { + for (let obj of this.getOverlays(window)) { if (~overlays.indexOf(obj)) continue; overlays.push(obj); @@ -233,19 +289,19 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen function insert(key, fn) { if (obj[key]) { - let iterator = Iterator(obj[key]); + let iterator = iter(obj[key]); if (isArray(obj[key])) { iterator = ([elem[1].id, elem.slice(2), elem[1]] - for each (elem in obj[key])); + for (elem of obj[key])); } - for (let [elem, xml, attrs] in iterator) { + for (let [elem, xml, attrs] of iterator) { if (elem = doc.getElementById(String(elem))) { // Urgh. Hack. let namespaces; if (attrs) namespaces = iter([k.slice(6), DOM.fromJSON.namespaces[v] || v] - for ([k, v] in Iterator(attrs)) + for ([k, v] of iter(attrs)) if (/^xmlns(?:$|:)/.test(k))).toObject(); let node = DOM.fromJSON(xml, doc, obj.objects, namespaces); @@ -253,15 +309,14 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen if (!(node instanceof Ci.nsIDOMDocumentFragment)) savedElems.push(node); else - for (let n in array.iterValues(node.childNodes)) + for (let n of array.iterValues(node.childNodes)) savedElems.push(n); fn(elem, node); - for (let attr in attrs || []) { + for (let [attr, val] of iter(attrs || {})) { let [ns, localName] = DOM.parseNamespace(attr); let name = attr; - let val = attrs[attr]; savedAttrs.push([elem, ns, name, getAttr(elem, ns, name), val]); if (name === "highlight") @@ -425,7 +480,7 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen /** * A list of extant dactyl windows. */ - windows: Class.Memoize(() => RealSet()) + windows: Class.Memoize(() => new RealSet) }); endModule(); diff --git a/common/modules/prefs.jsm b/common/modules/prefs.jsm index 5cdfc9b4..77003108 100644 --- a/common/modules/prefs.jsm +++ b/common/modules/prefs.jsm @@ -1,6 +1,6 @@ // Copyright (c) 2006-2008 by Martin Stubenschrott // Copyright (c) 2007-2011 by Doug Kearns -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -57,7 +57,7 @@ var Prefs = Module("prefs", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]) if (this == prefs) { if (~["uninstall", "disable"].indexOf(reason)) { - for (let name in values(this.branches.saved.getNames())) + for (let name of values(this.branches.saved.getNames())) this.safeReset(name, null, true); this.branches.original.resetBranch(); @@ -320,7 +320,7 @@ var Prefs = Module("prefs", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]) * @see #withContext */ popContext: function popContext() { - for (let [k, v] in Iterator(this._prefContexts.pop())) + for (let [k, v] of iter(this._prefContexts.pop())) this.set(k, v); }, @@ -396,8 +396,8 @@ var Prefs = Module("prefs", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]) let prefArray = this.getNames(); prefArray.sort(); - function prefs() { - for (let [, pref] in Iterator(prefArray)) { + function* prefs() { + for (let pref of prefArray) { let userValue = services.pref.prefHasUserValue(pref); if (onlyNonDefault && !userValue || !pref.contains(filter)) continue; diff --git a/common/modules/promises.jsm b/common/modules/promises.jsm index 9c9618ff..cb0b8d70 100644 --- a/common/modules/promises.jsm +++ b/common/modules/promises.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2014 Kris Maglione +// Copyright (c) 2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -25,10 +25,10 @@ function withCallbacks(fn) { } var Promises = Module("Promises", { - _cancel: WeakMap(), + _cancel: new WeakMap, /** - * Allows promises to be canceled.. + * Allows promises to be canceled. * * @param {Promise} promise The promise to cancel. * @param {*} arg Argument to be passed to the cancellation diff --git a/common/modules/protocol.jsm b/common/modules/protocol.jsm index 69adb6e1..e6558843 100644 --- a/common/modules/protocol.jsm +++ b/common/modules/protocol.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -19,11 +19,15 @@ function Channel(url, orig, noErrorChannel, unprivileged) { if (url instanceof Ci.nsIChannel) return url; - if (typeof url === "function") - return let ([type, data] = url(orig)) StringChannel(data, type, orig); + if (typeof url === "function") { + let [type, data] = url(orig); + return StringChannel(data, type, orig); + } - if (isArray(url)) - return let ([type, data] = url) StringChannel(data, type, orig); + if (isArray(url)) { + let [type, data] = url; + return StringChannel(data, type, orig); + } let uri = services.io.newURI(url, null, null); return (new XMLChannel(uri, null, noErrorChannel)).channel; @@ -101,7 +105,7 @@ ProtocolBase.prototype = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIProtocolHandler]), purge: function purge() { - for (let doc in util.iterDocuments()) + for (let doc of util.iterDocuments()) try { if (doc.documentURIObject.scheme == this.scheme) doc.defaultView.close(); @@ -208,7 +212,7 @@ function XMLChannel(uri, contentType, noErrorChannel, unprivileged) { if (!open) this.writes.push("\n]"); - for (let [, pre, url] in util.regexp.iterate(/([^]*?)(?:%include\s+"([^"]*)";|$)/gy, post)) { + for (let [, pre, url] of util.regexp.iterate(/([^]*?)(?:%include\s+"([^"]*)";|$)/gy, post)) { this.writes.push(pre); if (url) this.addChannel(url); diff --git a/common/modules/sanitizer.jsm b/common/modules/sanitizer.jsm index 8f08a127..a03a133a 100644 --- a/common/modules/sanitizer.jsm +++ b/common/modules/sanitizer.jsm @@ -93,7 +93,7 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef description: "Cookies", persistent: true, action: function (range, host) { - for (let c in Sanitizer.iterCookies(host)) + for (let c of Sanitizer.iterCookies(host)) if (range.contains(c.creationTime) || timespan.isSession && c.isSession) services.cookies.remove(c.host, c.name, c.path, false); }, @@ -140,11 +140,11 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef if (range.isSession) return; if (host) { - for (let p in Sanitizer.iterPermissions(host)) { + for (let p of Sanitizer.iterPermissions(host)) { services.permissions.remove(util.createURI(p.host), p.type); services.permissions.add(util.createURI(p.host), p.type, 0); } - for (let p in iter(services.contentPrefs.getPrefs(util.createURI(host)))) + for (let p of iter(services.contentPrefs.getPrefs(util.createURI(host)))) services.contentPrefs.removePref(util.createURI(host), p.QueryInterface(Ci.nsIProperty).name); } else { @@ -163,7 +163,7 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef }); function ourItems(persistent) [ - item for (item in values(self.itemMap)) + item for (item of values(self.itemMap)) if (!item.builtin && (!persistent || item.persistent) && item.name !== "all") ]; @@ -176,7 +176,7 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef ], init: function init(win) { let pane = win.document.getElementById("SanitizeDialogPane"); - for (let [, pref] in iter(pane.preferences)) + for (let [, pref] of iter(pane.preferences)) pref.updateElements(); init.superapply(this, arguments); } @@ -184,27 +184,35 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef util.timeout(function () { // Load order issue... - let (branch = Item.PREFIX + Item.SHUTDOWN_BRANCH) { + { + let branch = Item.PREFIX + Item.SHUTDOWN_BRANCH; + overlay.overlayWindow("chrome://browser/content/preferences/sanitize.xul", - function (win) prefOverlay(branch, true, { - append: { - SanitizeDialogPane: - ["groupbox", { orient: "horizontal", xmlns: "xul" }, - ["caption", { label: config.appName + /*L*/" (see :help privacy)" }], - ["grid", { flex: "1" }, - ["columns", {}, - ["column", { flex: "1" }], - ["column", { flex: "1" }]], - ["rows", {}, - let (items = ourItems(true)) - template.map(util.range(0, Math.ceil(items.length / 2)), i => - ["row", {}, - template.map(items.slice(i * 2, i * 2 + 2), item => - ["checkbox", { xmlns: XUL, label: item.description, preference: branch + item.name }])])]]] - } - })); + function (win) { + let items = ourItems(true); + + return prefOverlay(branch, true, { + append: { + SanitizeDialogPane: + ["groupbox", { orient: "horizontal", xmlns: "xul" }, + ["caption", { label: config.appName + /*L*/" (see :help privacy)" }], + ["grid", { flex: "1" }, + ["columns", {}, + ["column", { flex: "1" }], + ["column", { flex: "1" }]], + ["rows", {}, + template.map(util.range(0, Math.ceil(items.length / 2)), i => + ["row", {}, + template.map(items.slice(i * 2, i * 2 + 2), item => + ["checkbox", { xmlns: XUL, label: item.description, preference: branch + item.name }])])]]] + } + }); + }); } - let (branch = Item.PREFIX + Item.BRANCH) { + + { + let branch = Item.PREFIX + Item.BRANCH; + overlay.overlayWindow("chrome://browser/content/sanitize.xul", function (win) prefOverlay(branch, false, { append: { @@ -225,7 +233,7 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef self.withSavedValues(["sanitizing"], function () { self.sanitizing = true; sanitize.superapply(this, arguments); - sanitizer.sanitizeItems([item.name for (item in values(self.itemMap)) + sanitizer.sanitizeItems([item.name for (item of values(self.itemMap)) if (item.shouldSanitize(false))], Range.fromArray(this.range || [])); }, this); @@ -243,7 +251,7 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef let item = this.itemMap[name] || Item(name, params); this.itemMap[name] = item; - for (let [k, prop] in iterOwnProperties(params)) + for (let [k, prop] of iterOwnProperties(params)) if (!("value" in prop) || !callable(prop.value) && !(k in item)) Object.defineProperty(item, k, prop); @@ -252,7 +260,7 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef return obj.window || obj; } - let names = RealSet([name].concat(params.contains || []).map(e => "clear-" + e)); + let names = new RealSet([name].concat(params.contains || []).map(e => "clear-" + e)); if (params.action) storage.addObserver("sanitizer", function (key, event, arg) { @@ -328,7 +336,7 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef this.sanitizing = true; let errors = this.sanitizeItems(items, range, null); - for (let itemName in values(items)) { + for (let itemName of values(items)) { try { let item = this.items[Sanitizer.argToPref(itemName)]; if (item && !this.itemMap[itemName].override) { @@ -354,7 +362,7 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef items = Object.keys(this.itemMap); let errors; - for (let itemName in values(items)) + for (let itemName of values(items)) try { if (!key || this.itemMap[itemName][key]) storage.fireEvent("sanitizer", "clear-" + itemName, [range, host]); @@ -395,16 +403,16 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef argToPref: function (arg) Sanitizer.argPrefMap[arg] || arg, prefToArg: function (pref) pref.replace(/.*\./, "").toLowerCase(), - iterCookies: function iterCookies(host) { - for (let c in iter(services.cookies, Ci.nsICookie2)) + iterCookies: function* iterCookies(host) { + for (let c of iter(services.cookies, Ci.nsICookie2)) if (!host || util.isSubdomain(c.rawHost, host) || c.host[0] == "." && c.host.length < host.length && host.endsWith(c.host)) yield c; }, - iterPermissions: function iterPermissions(host) { - for (let p in iter(services.permissions, Ci.nsIPermission)) + iterPermissions: function* iterPermissions(host) { + for (let p of iter(services.permissions, Ci.nsIPermission)) if (!host || util.isSubdomain(p.host, host)) yield p; } @@ -543,16 +551,16 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef if (!args.length) args = modules.options["cookies"]; - for (let [, cmd] in Iterator(args)) + for (let cmd of args) switch (cmd) { case "clear": - for (let c in Sanitizer.iterCookies(host)) + for (let c of Sanitizer.iterCookies(host)) services.cookies.remove(c.host, c.name, c.path, false); break; case "clear-persistent": session = false; case "clear-session": - for (let c in Sanitizer.iterCookies(host)) + for (let c of Sanitizer.iterCookies(host)) if (c.isSession == session) services.cookies.remove(c.host, c.name, c.path, false); return; @@ -567,7 +575,7 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef c.path, c.name, c.value] - for (c in Sanitizer.iterCookies(host))))); + for (c of Sanitizer.iterCookies(host))))); return; default: util.assert(cmd in Sanitizer.PERMS, _("error.invalidArgument")); @@ -582,7 +590,7 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef context.title[1] = "Current Permissions"; context.keys.description = function desc(host) { let count = [0, 0]; - for (let c in Sanitizer.iterCookies(host)) + for (let c of Sanitizer.iterCookies(host)) count[c.isSession + 0]++; return [Sanitizer.COMMANDS[getPerms(host)], " (session: ", count[1], " persistent: ", count[0], ")"].join(""); }; @@ -622,9 +630,11 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef return completer.superapply(this, arguments); }, - has: function has(val) - let (res = this.value.find(v => (v == "all" || v.replace(/^!/, "") == val))) - res && !/^!/.test(res), + has: function has(val) { + let res = this.value.find(v => (v == "all" || v.replace(/^!/, "") == val)); + + return res && !/^!/.test(res); + }, validator: function (values) values.length && values.every(val => (val === "all" || hasOwnProperty(sanitizer.itemMap, val.replace(/^!/, "")))) @@ -635,9 +645,9 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef "stringlist", "", { initialValue: true, - get values() [i for (i in values(sanitizer.itemMap)) if (i.persistent || i.builtin)], + get values() [i for (i of values(sanitizer.itemMap)) if (i.persistent || i.builtin)], getter: function () !sanitizer.runAtShutdown ? [] : [ - item.name for (item in values(sanitizer.itemMap)) + item.name for (item of values(sanitizer.itemMap)) if (item.shouldSanitize(true)) ], setter: function (value) { @@ -645,8 +655,8 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef sanitizer.runAtShutdown = false; else { sanitizer.runAtShutdown = true; - let have = RealSet(value); - for (let item in values(sanitizer.itemMap)) + let have = new RealSet(value); + for (let item of values(sanitizer.itemMap)) prefs.set(item.shutdownPref, Boolean(have.has(item.name) ^ have.has("all"))); } diff --git a/common/modules/storage.jsm b/common/modules/storage.jsm index f1d1a30f..f269b011 100644 --- a/common/modules/storage.jsm +++ b/common/modules/storage.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -33,7 +33,7 @@ var StoreBase = Class("StoreBase", { this.__defineGetter__("store", () => store); this.__defineGetter__("name", () => name); - for (let [k, v] in Iterator(options)) + for (let [k, v] of iter(options)) if (this.OPTIONS.indexOf(k) >= 0) this[k] = v; this.reload(); @@ -70,7 +70,7 @@ var StoreBase = Class("StoreBase", { save: function () { (self.storage || storage)._saveData(this); }, - __iterator__: function () Iterator(this._object) + "@@iterator": function () iter(this._object) }); var ArrayStore = Class("ArrayStore", StoreBase, { @@ -200,12 +200,14 @@ var Storage = Module("Storage", { }, cleanup: function () { - this.saveAll(); + if (this.keys) { + this.saveAll(); - for (let key in keys(this.keys)) { - if (this[key].timer) - this[key].timer.flush(); - delete this[key]; + for (let key of keys(this.keys)) { + if (this[key].timer) + this[key].timer.flush(); + delete this[key]; + } } this.keys = {}; @@ -227,7 +229,7 @@ var Storage = Module("Storage", { } }, - _saveData: promises.task(function saveData(obj) { + _saveData: promises.task(function* saveData(obj) { if (obj.privateData && storage.privateMode) return; if (obj.store && storage.infoPath) { @@ -302,9 +304,12 @@ var Storage = Module("Storage", { }, get observerMaps() { - yield this.observers; - for (let window of overlay.windows) - yield overlay.getData(window, "storage-observers", Object); + return function *() { + /* FIXME: Symbols */ + yield this.observers; + for (let window of overlay.windows) + yield overlay.getData(window, "storage-observers", Object); + }.call(this); }, addObserver: function addObserver(key, callback, window) { @@ -313,19 +318,19 @@ var Storage = Module("Storage", { observers = overlay.getData(window, "storage-observers", Object); if (!hasOwnProperty(observers, key)) - observers[key] = RealSet(); + observers[key] = new RealSet; observers[key].add(callback); }, removeObserver: function (key, callback) { - for (let observers in this.observerMaps) + for (let observers of this.observerMaps) if (key in observers) observers[key].remove(callback); }, fireEvent: function fireEvent(key, event, arg) { - for (let observers in this.observerMaps) + for (let observers of this.observerMaps) for (let observer of observers[key] || []) observer(key, event, arg); @@ -343,8 +348,8 @@ var Storage = Module("Storage", { this._saveData(this.keys[key]); }, - saveAll: function storeAll() { - for each (let obj in this.keys) + saveAll: function saveAll() { + for (let obj of values(this.keys)) this._saveData(obj); }, @@ -361,7 +366,7 @@ var Storage = Module("Storage", { else { let { keys } = this; this.keys = {}; - for (let [k, v] in Iterator(keys)) + for (let [k, v] of iter(keys)) this.keys[k] = this._privatize(v); } } @@ -439,12 +444,12 @@ var File = Class("File", { /** * Iterates over the objects in this directory. */ - iterDirectory: function iterDirectory() { + iterDirectory: function* iterDirectory() { if (!this.exists()) throw Error(_("io.noSuchFile")); if (!this.isDirectory()) throw Error(_("io.eNotDir")); - for (let file in iter(this.directoryEntries)) + for (let file of iter(this.directoryEntries)) yield File(file); }, @@ -490,7 +495,7 @@ var File = Class("File", { if (!this.isDirectory()) throw Error(_("io.eNotDir")); - let array = [e for (e in this.iterDirectory())]; + let array = [e for (e of this.iterDirectory())]; if (sort) array.sort((a, b) => (b.isDirectory() - a.isDirectory() || String.localeCompare(a.path, b.path))); @@ -742,7 +747,7 @@ var File = Class("File", { } }, - readLines: function readLines(ifstream, encoding) { + readLines: function* readLines(ifstream, encoding) { try { var icstream = services.CharsetStream( ifstream, encoding || File.defaultEncoding, 4096, // buffer size @@ -783,7 +788,8 @@ var File = Class("File", { replacePathSep: function (path) path.replace("/", File.PATH_SEP, "g") }); -let (file = services.directory.get("ProfD", Ci.nsIFile)) { +{ + let file = services.directory.get("ProfD", Ci.nsIFile); Object.keys(file).forEach(function (prop) { if (!(prop in File.prototype)) { let isFunction; diff --git a/common/modules/styles.jsm b/common/modules/styles.jsm index 3689c116..c852e379 100644 --- a/common/modules/styles.jsm +++ b/common/modules/styles.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -13,9 +13,9 @@ lazyRequire("contexts", ["Contexts"]); lazyRequire("template", ["template"]); function cssUri(css) "chrome-data:text/css," + encodeURI(css); -var namespace = "@namespace html " + XHTML.quote() + ";\n" + - "@namespace xul " + XUL.quote() + ";\n" + - "@namespace dactyl " + NS.quote() + ";\n"; +var namespace = "@namespace html " + JSON.stringify(XHTML) + ";\n" + + "@namespace xul " + JSON.stringify(XUL) + ";\n" + + "@namespace dactyl " + JSON.stringify(NS) + ";\n"; var Sheet = Struct("name", "id", "sites", "css", "hive", "agent"); Sheet.liveProperty = function (name) { @@ -117,7 +117,7 @@ var Hive = Class("Hive", { }); }, - __iterator__: function () Iterator(this.sheets), + "@@iterator": function () iter(this.sheets), get sites() array(this.sheets).map(s => s.sites) .flatten() @@ -189,7 +189,7 @@ var Hive = Class("Hive", { */ find: function find(name, filter, css, index) { // Grossly inefficient. - let matches = [k for ([k, v] in Iterator(this.sheets))]; + let matches = [k for ([k, v] of iter(this.sheets))]; if (index) matches = String(index).split(",").filter(i => i in this.sheets); if (name) @@ -230,7 +230,7 @@ var Hive = Class("Hive", { if (matches.length == 0) return null; - for (let [, sheet] in Iterator(matches.reverse())) { + for (let sheet of matches.reverse()) { if (filter) { let sites = sheet.sites.filter(f => f != filter); if (sites.length) { @@ -294,11 +294,13 @@ var Styles = Module("Styles", { return hive; }, - __iterator__: function () Iterator(this.user.sheets.concat(this.system.sheets)), + "@@iterator": function () iter(this.user.sheets.concat(this.system.sheets)), - _proxy: function (name, args) - let (obj = this[args[0] ? "system" : "user"]) - obj[name].apply(obj, Array.slice(args, 1)), + _proxy: function (name, args) { + let obj = this[args[0] ? "system" : "user"]; + + return obj[name].apply(obj, Array.slice(args, 1)); + }, addSheet: deprecated("Styles#{user,system}.add", function addSheet() this._proxy("add", arguments)), findSheets: deprecated("Styles#{user,system}.find", function findSheets() this._proxy("find", arguments)), @@ -336,16 +338,19 @@ var Styles = Module("Styles", { ["col", { style: "min-width: 1em; text-align: center; color: red; font-weight: bold;" }], ["col", { style: "padding: 0 1em 0 1ex; vertical-align: top;" }], ["col", { style: "padding: 0 1em 0 0; vertical-align: top;" }], - template.map(hives, hive => let (i = 0) [ - ["tr", { style: "height: .5ex;" }], - template.map(sheets(hive), sheet => - ["tr", {}, - ["td", { highlight: "Title" }, !i++ ? hive.name : ""], - ["td", {}, sheet.enabled ? "" : UTF8("×")], - ["td", {}, sheet.name || hive.sheets.indexOf(sheet)], - ["td", {}, sheet.formatSites(uris)], - ["td", {}, sheet.css]]), - ["tr", { style: "height: .5ex;" }]])]; + template.map(hives, hive => { + let i = 0; + return [ + ["tr", { style: "height: .5ex;" }], + template.map(sheets(hive), sheet => + ["tr", {}, + ["td", { highlight: "Title" }, !i++ ? hive.name : ""], + ["td", {}, sheet.enabled ? "" : UTF8("×")], + ["td", {}, sheet.name || hive.sheets.indexOf(sheet)], + ["td", {}, sheet.formatSites(uris)], + ["td", {}, sheet.css]]), + ["tr", { style: "height: .5ex;" }]]; + })]; // E4X-FIXME // // TODO: Move this to an ItemList to show this automatically @@ -375,7 +380,7 @@ var Styles = Module("Styles", { append: function (dest, src, sort) { let props = {}; for (let str of [dest, src]) - for (let prop in Styles.propertyIter(str)) + for (let prop of Styles.propertyIter(str)) props[prop.name] = prop.value; let val = Object.keys(props)[sort ? "sort" : "slice"]() @@ -450,7 +455,7 @@ var Styles = Module("Styles", { }, splitContext: function splitContext(context, title) { - for (let item in Iterator({ Active: true, Inactive: false })) { + for (let item of iter({ Active: true, Inactive: false })) { let [name, active] = item; context.split(name, null, function (context) { context.title[0] = /*L*/name + " " + (title || "Sheets"); @@ -459,9 +464,10 @@ var Styles = Module("Styles", { } }, - propertyIter: function (str, always) { + propertyIter: function* (str, always) { let i = 0; - for (let match in this.propertyPattern.iterate(str)) { + let x = /The status bar/.test(str); + for (let match of this.propertyPattern.iterate(str)) { if (match.value || always && match.name || match.wholeMatch === match.preSpace && always && !i++) yield match; if (!/;/.test(match.postSpace)) @@ -729,7 +735,7 @@ var Styles = Module("Styles", { context.keys = { text: function (p) p + ":", description: function () "" }; - for (let match in Styles.propertyIter(context.filter, true)) + for (let match of Styles.propertyIter(context.filter, true)) var lastMatch = match; if (lastMatch != null && !lastMatch.value && !lastMatch.postSpace) { diff --git a/common/modules/template.jsm b/common/modules/template.jsm index 39a42ffd..3fdb6fc2 100644 --- a/common/modules/template.jsm +++ b/common/modules/template.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -20,7 +20,7 @@ var Binding = Class("Binding", { Object.defineProperties(node, this.constructor.properties); - for (let [event, handler] in values(this.constructor.events)) + for (let [event, handler] of values(this.constructor.events)) node.addEventListener(event, util.wrapCallback(handler, true), false); }, @@ -41,9 +41,12 @@ var Binding = Class("Binding", { }) }, { get bindings() { - let bindingProto = Object.getPrototypeOf(Binding.prototype); - for (let obj = this.prototype; obj !== bindingProto; obj = Object.getPrototypeOf(obj)) - yield obj; + return function* () { + let bindingProto = Object.getPrototypeOf(Binding.prototype); + for (let obj = this.prototype; obj !== bindingProto; obj = Object.getPrototypeOf(obj)) + /* FIXME: Symbols */ + yield obj; + }.call(this); }, bind: function bind(func) function bound() { @@ -58,20 +61,20 @@ var Binding = Class("Binding", { events: Class.Memoize(function () { let res = []; - for (let obj in this.bindings) + for (let obj of this.bindings) if (Object.getOwnPropertyDescriptor(obj, "events")) - for (let [event, handler] in Iterator(obj.events)) + for (let [event, handler] of iter(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)) { + for (let obj of this.bindings) + for (let prop of properties(obj)) { let desc = Object.getOwnPropertyDescriptor(obj, prop); if (desc.enumerable) { - for (let k in values(["get", "set", "value"])) + for (let k of values(["get", "set", "value"])) if (typeof desc[k] === "function") desc[k] = this.bind(desc[k]); res[prop] = desc; @@ -143,19 +146,19 @@ var Template = Module("Template", { if (hasOwnProperty(events, "input")) events["dactyl-input"] = events["input"]; - for (let [event, handler] in Iterator(events)) + for (let [event, handler] of iter(events)) node.addEventListener(event, util.wrapCallback(handler.bind(obj), true), false); } }) }, - map: function map(iter, func, sep, interruptable) { - if (typeof iter.length == "number") // FIXME: Kludge? - iter = array.iterValues(iter); + map: function map(iter_, func, sep, interruptable) { + if (typeof iter_.length == "number") // FIXME: Kludge? + iter_ = array.iterValues(iter_); let res = []; let n = 0; - for (let i in Iterator(iter)) { + for (let i of iter_) { let val = func(i, n); if (val == undefined) continue; @@ -257,8 +260,8 @@ var Template = Module("Template", { (?P '[\w-]+' | :(?:[\w-]+!?|!) | (?:._)?<[\w-]+>\w* | \b[a-zA-Z]_(?:[\w[\]]+|.) | \[[\w-;]+\] | E\d{3} ) (?= [[\)!,:;./\s]|$) */$), "gx"); - return this.highlightSubstrings(str, (function () { - for (let res in re.iterate(str)) + return this.highlightSubstrings(str, (function* () { + for (let res of re.iterate(str)) yield [res.index + res.pre.length, res.tag.length]; })(), this[help ? "HelpLink" : "helpLink"]); }, @@ -276,7 +279,7 @@ var Template = Module("Template", { return ["span", { highlight: "Number" }, str]; case "string": if (processStrings) - str = str.quote(); + str = JSON.stringify(str); return ["span", { highlight: "String" }, str]; case "boolean": return ["span", { highlight: "Boolean" }, str]; @@ -318,7 +321,7 @@ var Template = Module("Template", { if (isURI) str = util.losslessDecodeURI(str); - return this.highlightSubstrings(str, (function () { + return this.highlightSubstrings(str, (function* () { if (filter.length == 0) return; @@ -333,13 +336,13 @@ var Template = Module("Template", { }, highlightRegexp: function highlightRegexp(str, re, highlight) { - return this.highlightSubstrings(str, (function () { - for (let res in util.regexp.iterate(re, str)) + return this.highlightSubstrings(str, (function* () { + for (let res of util.regexp.iterate(re, str)) yield [res.index, res[0].length, res.wholeMatch ? [res] : res]; })(), highlight || template.filter); }, - highlightSubstrings: function highlightSubstrings(str, iter, highlight) { + highlightSubstrings: function highlightSubstrings(str, iter_, highlight) { if (!isString(str)) return str; @@ -349,7 +352,7 @@ var Template = Module("Template", { let s = [""]; let start = 0; let n = 0, _i; - for (let [i, length, args] in iter) { + for (let [i, length, args] of iter_) { if (i == _i || i < _i) break; _i = i; @@ -468,19 +471,22 @@ var Template = Module("Template", { this.map(format.columns, (c) => ["col", { style: c }])] : [], ["tbody", { highlight: "UsageBody" }, - this.map(iter, (item) => + this.map(iter, (item) => { // Urgh. - let (name = item.name || item.names[0], frame = item.definedAt) - ["tr", { highlight: "UsageItem" }, - ["td", { style: "padding-right: 2em;" }, - ["span", { highlight: "Usage Link" }, - !frame ? name : - [this.helpLink(help(item), name, "Title"), - ["span", { highlight: "LinkInfo" }, - _("io.definedAt"), " ", - sourceLink(frame)]]]], - item.columns ? this.map(item.columns, (c) => ["td", {}, c]) : [], - ["td", {}, desc(item)]])]]; + let name = item.name || item.names[0]; + let frame = item.definedAt; + + return ["tr", { highlight: "UsageItem" }, + ["td", { style: "padding-right: 2em;" }, + ["span", { highlight: "Usage Link" }, + !frame ? name : + [this.helpLink(help(item), name, "Title"), + ["span", { highlight: "LinkInfo" }, + _("io.definedAt"), " ", + sourceLink(frame)]]]], + item.columns ? this.map(item.columns, (c) => ["td", {}, c]) : [], + ["td", {}, desc(item)]]; + })]]; } }); diff --git a/common/modules/util.jsm b/common/modules/util.jsm index 5199a69b..95493500 100644 --- a/common/modules/util.jsm +++ b/common/modules/util.jsm @@ -1,6 +1,6 @@ // Copyright (c) 2006-2008 by Martin Stubenschrott // Copyright (c) 2007-2011 Doug Kearns -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -137,7 +137,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), let cleanup = ["dactyl-cleanup-modules", "quit-application"]; function register(meth) { - for (let target of RealSet(cleanup.concat(Object.keys(obj.observers)))) + for (let target of new RealSet(cleanup.concat(Object.keys(obj.observers)))) try { services.observer[meth](obj, target, true); } @@ -208,10 +208,10 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), // check for chars not in the accepted range this.assert(RegExp("^[" + accepted + "-]+$").test(list), - _("error.charactersOutsideRange", accepted.quote())); + _("error.charactersOutsideRange", JSON.stringify(accepted))); // check for illegal ranges - for (let [match] in this.regexp.iterate(/.-./g, list)) + for (let [match] of this.regexp.iterate(/.-./g, list)) this.assert(match.charCodeAt(0) <= match.charCodeAt(2), _("error.invalidCharacterRange", list.slice(list.indexOf(match)))); @@ -228,7 +228,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), if (isArray(obj)) return obj.slice(); let newObj = {}; - for (let [k, v] in Iterator(obj)) + for (let [k, v] of iter(obj)) newObj[k] = v; return newObj; }, @@ -272,7 +272,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), }); let end = 0; - for (let match in util.regexp.iterate(/(.*?)%(.)/gy, format)) { + for (let match of util.regexp.iterate(/(.*?)%(.)/gy, format)) { let [, prefix, char] = match; end += match[0].length; @@ -301,7 +301,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), : "", { test: function test(obj) obj[char] != null })); - for (let elem in array.iterValues(stack)) + for (let elem of array.iterValues(stack)) elem.seen[char] = true; } } @@ -353,7 +353,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), : "", { elements: [], - seen: RealSet(), + seen: new RealSet, valid: function valid(obj) this.elements.every(e => (!e.test || e.test(obj))) }); @@ -369,7 +369,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), */$), "gixy"); macro = String(macro); let end = 0; - for (let match in re.iterate(macro)) { + for (let match of re.iterate(macro)) { let [, prefix, open, full, macro, idx, close] = match; end += match[0].length; @@ -386,7 +386,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), } else { let [, flags, name] = /^((?:[a-z]-)*)(.*)/.exec(macro); - flags = RealSet(flags); + flags = new RealSet(flags); let quote = util.identity; if (flags.has("q")) @@ -420,7 +420,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), })); } - for (let elem in array.iterValues(stack)) + for (let elem of array.iterValues(stack)) elem.seen.add(name); } } @@ -474,7 +474,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), if (acc.length == pattern.length) this.res.push(acc.join("")); else - for (let val in values(vals)) + for (let val of values(vals)) this.rec(acc.concat(val)); } }); @@ -510,7 +510,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), if (acc.length == patterns.length) res.push(array(substrings).zip(acc).flatten().join("")); else - for (let [, pattern] in Iterator(patterns[acc.length])) + for (let [, pattern] of Iterator(patterns[acc.length])) rec(acc.concat(pattern)); }; rec([]); @@ -766,7 +766,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), if (isObject(params.params)) { let data = [encodeURIComponent(k) + "=" + encodeURIComponent(v) - for ([k, v] in iter(params.params))]; + for ([k, v] of iter(params.params))]; let uri = util.newURI(url); uri.query += (uri.query ? "&" : "") + data.join("&"); @@ -775,7 +775,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), if (isObject(params.data) && !(params.data instanceof Ci.nsISupports)) { let data = services.FormData(); - for (let [k, v] in iter(params.data)) + for (let [k, v] of iter(params.data)) data.append(k, v); params.data = data; } @@ -801,7 +801,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), args.push(prams.pass); xmlhttp.open.apply(xmlhttp, args); - for (let [header, val] in Iterator(params.headers || {})) + for (let [header, val] of iter(params.headers || {})) xmlhttp.setRequestHeader(header, val); if (params.responseType) @@ -899,7 +899,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), * Iterates over all currently open documents, including all * top-level window and sub-frames thereof. */ - iterDocuments: function iterDocuments(types) { + iterDocuments: function* iterDocuments(types) { types = types ? types.map(s => "type" + util.capitalize(s)) : ["typeChrome", "typeContent"]; @@ -909,11 +909,11 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), for (let type of types) { let docShells = window.docShell.getDocShellEnumerator(Ci.nsIDocShellTreeItem[type], Ci.nsIDocShell.ENUMERATE_FORWARDS); - while (docShells.hasMoreElements()) - let (viewer = docShells.getNext().QueryInterface(Ci.nsIDocShell).contentViewer) { - if (viewer) - yield viewer.DOMDocument; - }; + while (docShells.hasMoreElements()) { + let viewer = docShells.getNext().QueryInterface(Ci.nsIDocShell).contentViewer; + if (viewer) + yield viewer.DOMDocument; + } } } }, @@ -956,22 +956,16 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), * @returns {string} The DTD fragment containing entity declaration * for *obj*. */ - makeDTD: let (map = { "'": "'", '"': """, "%": "%", "&": "&", "<": "<", ">": ">" }) - function makeDTD(obj) { - function escape(val) { - let isDOM = DOM.isJSONXML(val); - return String.replace(val == null ? "null" : - isDOM ? DOM.toXML(val) - : val, - isDOM ? /['%]/g - : /['"%&<>]/g, - m => map[m]); - } - - return iter(obj).map(([k, v]) => - [""].join("")) - .join("\n"); - }, + makeDTD: function makeDTD(obj) { + let map = { "'": "'", '"': """, "%": "%", "&": "&", "<": "<", ">": ">" }; + + return iter(obj) + .map(([k, v]) => ["]/g, + function (m) map[m]), + "'>"].join("")) + .join("\n"); + }, /** * Converts a URI string into a URI object. @@ -1014,7 +1008,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), if (!isObject(object)) return String(object); - if (object instanceof Ci.nsIDOMElement) { + if (object instanceof Ci.nsIDOMElement || object instanceof DOM) { let elem = object; if (elem.nodeType == elem.TEXT_NODE) return elem.data; @@ -1039,26 +1033,22 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), else head = util.clip(obj, 150).replace(/\n/g, "^J") + "::\n"; - let keys = []; + let keys_ = []; // window.content often does not want to be queried with "var i in object" try { - let hasValue = !("__iterator__" in object || isinstance(object, ["Generator", "Iterator"])); + if (isArray(object)) + object = iter(object); + + let hasValue = !(Symbol.iterator in object || isinstance(object, ["Generator", "Iterator", Iter])); + let keyIter = hasValue ? keys(object) : object; if (object.dactyl && object.modules && object.modules.modules == object.modules) { object = Iterator(object); hasValue = false; } - let keyIter = object; - if (iter.iteratorProp in object) { - keyIter = (k for (k of object)); - hasValue = false; - } - else if ("__iterator__" in object && !callable(object.__iterator__)) - keyIter = keys(object); - - for (let i in keyIter) { + for (let i of keyIter) { let value = Magic(""); try { value = object[i]; @@ -1094,7 +1084,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), else val = key + ": " + value; - keys.push([i, val]); + keys_.push([i, val]); } } catch (e) { @@ -1108,7 +1098,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), String(b[0])); } - let vals = template.map(keys.sort(compare), f => f[1], + let vals = template.map(keys_.sort(compare), f => f[1], "\n"); if (color) { @@ -1122,7 +1112,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), function rec(data, level, seen) { if (isObject(data)) { - seen = RealSet(seen); + seen = new RealSet(seen); if (seen.add(data)) throw Error("Recursive object passed"); } @@ -1141,7 +1131,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), res.push("[]"); else { res.push("[\n"); - for (let [i, val] in Iterator(data)) { + for (let [i, val] of iter(data)) { if (i) res.push(",\n"); res.push(prefix); @@ -1154,7 +1144,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), res.push("{\n"); let i = 0; - for (let [key, val] in Iterator(data)) { + for (let [key, val] of iter(data)) { if (i++) res.push(",\n"); res.push(prefix, JSON.stringify(key), ": "); @@ -1172,7 +1162,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), } let res = []; - rec(data, "", RealSet()); + rec(data, "", new RealSet); return res.join(""); }, @@ -1180,7 +1170,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), "dactyl-cleanup-modules": function cleanupModules(subject, reason) { defineModule.loadLog.push("dactyl: util: observe: dactyl-cleanup-modules " + reason); - for (let module in values(defineModule.modules)) + for (let module of values(defineModule.modules)) if (module.cleanup) { util.dump("cleanup: " + module.constructor.className); util.trapErrors(module.cleanup, module, reason); @@ -1198,7 +1188,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), * negative. @default 1 * @returns {Iterator(Object)} */ - range: function range(start, end, step) { + range: function* range(start, end, step) { if (!step) step = 1; if (step > 0) { @@ -1220,7 +1210,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), * @param {number} time The time in milliseconds between thread yields. * @returns {Iterator(Object)} */ - interruptibleRange: function interruptibleRange(start, end, time) { + interruptibleRange: function* interruptibleRange(start, end, time) { let endTime = Date.now() + time; while (start < end) { if (Date.now() > endTime) { @@ -1249,7 +1239,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), * @returns {RegExp} A custom regexp object. */ regexp: update(function (expr, flags, tokens) { - flags = flags || [k for ([k, v] in Iterator({ g: "global", i: "ignorecase", m: "multiline", y: "sticky" })) + flags = flags || [k for ([k, v] of iter({ g: "global", i: "ignorecase", m: "multiline", y: "sticky" })) if (expr[v])].join(""); if (isinstance(expr, ["RegExp"])) @@ -1302,8 +1292,13 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), // have them. if (struct) update(res, { - exec: function exec() let (match = exec.superapply(this, arguments)) match && struct.fromArray(match), - dactylSource: source, struct: struct + exec: function exec() { + let match = exec.superapply(this, arguments); + + return match && struct.fromArray(match); + }, + dactylSource: source, + struct: struct }); return res; }, { @@ -1333,17 +1328,19 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), * @param {string} string The string to search. * @param {number} lastIndex The index at which to begin searching. @optional */ - iterate: function iterate(regexp, string, lastIndex) iter(function () { - regexp.lastIndex = lastIndex = lastIndex || 0; - let match; - while (match = regexp.exec(string)) { - lastIndex = regexp.lastIndex; - yield match; - regexp.lastIndex = lastIndex; - if (match[0].length == 0 || !regexp.global) - break; - } - }()) + iterate: function iterate(regexp, string, lastIndex) { + return iter(new function* () { + regexp.lastIndex = lastIndex = lastIndex || 0; + let match; + while (match = regexp.exec(string)) { + lastIndex = regexp.lastIndex; + yield match; + regexp.lastIndex = lastIndex; + if (match[0].length == 0 || !regexp.global) + break; + } + }); + } }), /** @@ -1400,7 +1397,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), this.errors.push([new Date, obj + "\n" + obj.stack]); this.errors = this.errors.slice(-this.maxErrors); - this.errors.toString = function () [k + "\n" + v for ([k, v] in array.iterValues(this))].join("\n\n"); + this.errors.toString = function () [k + "\n" + v for ([k, v] of array.iterValues(this))].join("\n\n"); this.dump(String(error)); this.dump(obj); @@ -1437,7 +1434,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), catch (e) {} let ary = host.split("."); - ary = [ary.slice(i).join(".") for (i in util.range(ary.length, 0, -1))]; + ary = [ary.slice(i).join(".") for (i of util.range(ary.length, 0, -1))]; return ary.filter(h => h.length >= base.length); }, @@ -1658,11 +1655,11 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), * @param {function} func The function to call * @param {object} self The 'this' object for the function. */ - trapErrors: function trapErrors(func, self, ...args) { + trapErrors: function trapErrors(func, self) { try { if (!callable(func)) func = self[func]; - return func.apply(self || this, args); + return func.apply(self || this, Array.slice(arguments, 2)); } catch (e) { this.reportError(e); @@ -1697,7 +1694,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), */ visibleHosts: function visibleHosts(win) { let res = [], - seen = RealSet(); + seen = new RealSet; (function rec(frame) { try { if (frame.location.hostname) @@ -1718,7 +1715,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), */ visibleURIs: function visibleURIs(win) { let res = [], - seen = RealSet(); + seen = new RealSet; (function rec(frame) { try { res = res.concat(util.newURI(frame.location.href)); -- cgit v1.2.3