diff --git a/common/Makefile b/common/Makefile index 65328379..7dbdbfe3 100644 --- a/common/Makefile +++ b/common/Makefile @@ -174,7 +174,18 @@ xpi: $(CHROME) $(MAKE_JAR) "$(XPI)" "$(XPI_BASES)" "$(XPI_DIRS)" "$(XPI_TEXTS)" "$(XPI_BINS)" "$(XPI_FILES)" rm -r -- $(CHROME) - @echo "Built XPI: $(XPI)" + + @if ! which realpath >/dev/null 2>&1; \ + then realpah() { \ + local IFS="$$(echo)"; \ + local x="$$1"; \ + case "$$x" in \ + /*) ;; \ + *) x=$$(pwd);; \ + esac; \ + }; \ + fi; \ + echo "Built XPI: $$(realpath -s -- $(XPI))" #### jar diff --git a/common/content/bookmarks.js b/common/content/bookmarks.js index ff1768e6..a6d85c1e 100644 --- a/common/content/bookmarks.js +++ b/common/content/bookmarks.js @@ -449,13 +449,17 @@ var Bookmarks = Module("bookmarks", { description: "Bookmark page title or description", completer: function title(context, args) { let frames = buffer.allFrames(); + if (!args.bang) - return [ - [win.document.title, frames.length == 1 ? /*L*/"Current Location" : /*L*/"Frame: " + win.location.href] - for (win of frames)]; + return frames.map(win => [win.document.title, + frames.length == 1 ? /*L*/"Current Location" + : /*L*/"Frame: " + win.location.href]); + context.keys.text = "title"; context.keys.description = "url"; - return bookmarks.get(args.join(" "), args["-tags"], null, { keyword: args["-keyword"], title: context.filter }); + return bookmarks.get(args.join(" "), args["-tags"], null, + { keyword: args["-keyword"], + title: context.filter }); }, type: CommandOption.STRING }; @@ -514,12 +518,14 @@ var Bookmarks = Module("bookmarks", { if (!args.bang) { context.title = ["Page URL"]; let frames = buffer.allFrames(); - context.completions = [ - [win.document.documentURI, frames.length == 1 ? /*L*/"Current Location" : /*L*/"Frame: " + win.document.title] - for (win of frames)]; + context.completions = frames.map(win => [win.document.documentURI, + frames.length == 1 ? /*L*/"Current Location" + : /*L*/"Frame: " + win.document.title]); } else - completion.bookmark(context, args["-tags"], { keyword: args["-keyword"], title: args["-title"] }); + completion.bookmark(context, args["-tags"], + { keyword: args["-keyword"], + title: args["-title"] }); }, options: [keyword, title, tags, post, { diff --git a/common/content/commandline.js b/common/content/commandline.js index def05642..bb1d12c9 100644 --- a/common/content/commandline.js +++ b/common/content/commandline.js @@ -525,7 +525,8 @@ var CommandLine = Module("commandline", { if (storage.exists("history-" + name)) { let ary = storage.newArray("history-" + name, { store: true, privateData: true }); - this._store.set(name, [v for ([k, v] of ary)]); + this._store.set(name, Array.from(ary, ([key, val]) => val)); + ary.delete(); this._store.changed(); } diff --git a/common/content/dactyl.js b/common/content/dactyl.js index fefb8109..cb088ea5 100644 --- a/common/content/dactyl.js +++ b/common/content/dactyl.js @@ -775,19 +775,34 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { let loadplugins = options.get("loadplugins"); if (args) - loadplugins = { __proto__: loadplugins, value: args.map(Option.parseRegexp) }; + loadplugins = { __proto__: loadplugins, + value: args.map(Option.parseRegexp) }; - dir.readDirectory(true).forEach(function (file) { - if (file.leafName[0] == ".") + let shouldSource = file => { + if (!loadplugins.getKey(file.path)) + return false; + + if (force) + return true; + + if (file.path in dactyl.pluginFiles) + return dactyl.pluginFiles[file.path] < file.lastModifiedTime; + + return true; + }; + + dir.readDirectory(true).forEach(file => { + if (file.leafName.startsWith(".")) ; - else if (file.isFile() && loadplugins.getKey(file.path) - && !(!force && file.path in dactyl.pluginFiles && dactyl.pluginFiles[file.path] >= file.lastModifiedTime)) { - try { - io.source(file.path); - dactyl.pluginFiles[file.path] = file.lastModifiedTime; - } - catch (e) { - dactyl.reportError(e); + else if (file.isFile()) { + if (shouldSource(file)) { + try { + io.source(file.path); + dactyl.pluginFiles[file.path] = file.lastModifiedTime; + } + catch (e) { + dactyl.reportError(e); + } } } else if (file.isDirectory()) @@ -804,10 +819,9 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { dactyl.echomsg( _("plugin.searchingForIn", - JSON.stringify("plugins/**/*.{js," + config.fileExtension + "}"), - JSON.stringify([dir.path.replace(/.plugins$/, "") - for (dir of dirs)] - .join(","))), + JSON.stringify("plugins/**/*.{js," + config.fileExtension + "}"), + JSON.stringify(dirs.map(dir => dir.path.replace(/.plugins$/, "")) + .join(","))), 2); dirs.forEach(function (dir) { @@ -1226,7 +1240,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { * @property {[Window]} Returns an array of all the host application's * open windows. */ - get windows() { return [w for (w of overlay.windows)]; } + get windows() { return Array.from(overlay.windows); } }, { isToolbarHidden: function isToolbarHidden(toolbar) { @@ -1399,7 +1413,9 @@ 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] of iter(this.opts)) if (opts.indexOf(k) < 0)]; + let classes = Object.entries(this.opts) + .filter(([name]) => !opts.includes(name)) + .map(([name, data]) => data[1]); styles.system.add("taboptions", "chrome://*", classes.length ? classes.join(",") + "{ display: none; }" : ""); @@ -1876,7 +1892,10 @@ 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] of iter(config.dialogs))]; + + context.completions = ( + Object.entries(config.dialogs) + .map(([key, val]) => [k, v[0], v[2]])); }; completion.menuItem = function menuItem(context) { diff --git a/common/content/editor.js b/common/content/editor.js index e7750476..27c0c444 100644 --- a/common/content/editor.js +++ b/common/content/editor.js @@ -1,4 +1,4 @@ -// Copyright (c) 2008-2014 Kris Maglione +// Copyright (c) 2008-2015 Kris Maglione // Copyright (c) 2006-2009 by Martin Stubenschrott // // This work is licensed for reuse under an MIT license. Details are @@ -1399,9 +1399,11 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), { }, validator: function (value) { this.format({}, value); + let allowed = new RealSet(["column", "file", "line"]); - return [k for (k of util.compileMacro(value).seen)] - .every(k => allowed.has(k)); + return util.compileMacro(value) + .seen.difference(allowed) + .size == 0; } }); diff --git a/common/content/events.js b/common/content/events.js index 86391f4e..b4d94edb 100644 --- a/common/content/events.js +++ b/common/content/events.js @@ -306,9 +306,12 @@ var Events = Module("events", { * @param {string} filter A regular expression filter string. A null * filter selects all macros. */ - getMacros: function (filter) { + getMacros: function (filter = null) { let re = RegExp(filter || ""); - return ([k, m.text] for ([k, m] of editor.registers) if (re.test(k))); + + return Array.from(editor.registers, + ([key, macro]) => [key, macro.text]) + .filter(([key]) => re.test(key)); }, /** @@ -1026,7 +1029,7 @@ var Events = Module("events", { completion: function initCompletion() { completion.macro = function macro(context) { context.title = ["Macro", "Keys"]; - context.completions = [item for (item of events.getMacros())]; + context.completions = Array.from(events.getMacros()); }; }, mappings: function initMappings() { diff --git a/common/content/hints.js b/common/content/hints.js index 5a7f71a8..d2307657 100644 --- a/common/content/hints.js +++ b/common/content/hints.js @@ -1090,8 +1090,8 @@ var Hints = Module("hints", { autocomplete: false, completer: function (context) { context.compare = () => 0; - context.completions = [[k, v.prompt] - for ([k, v] of iter(hints.modes))]; + context.completions = Object.entries(hints.modes) + .map(([key, mode]) => [key, mode.prompt]); }, onCancel: mappings.bound.popCommand, onSubmit: function (arg) { @@ -1234,16 +1234,16 @@ var Hints = Module("hints", { }), indexOf: function indexOf(dest, src) { let table = this.translitTable; - var end = dest.length - src.length; + let end = dest.length - src.length; if (src.length == 0) return 0; outer: - for (var i = 0; i <= end; i++) { - var j = i; - for (var k = 0; k < src.length;) { - var s = dest[j++]; + for (let i = 0; i <= end; i++) { + let j = i; + for (let k = 0; k < src.length;) { + let s = dest[j++]; s = table[s] || s; - for (var l = 0; l < s.length; l++, k++) { + for (let l = 0; l < s.length; l++, k++) { if (s[l] != src[k]) continue outer; if (k == src.length - 1) diff --git a/common/content/history.js b/common/content/history.js index 39259ad3..d4ecc4d8 100644 --- a/common/content/history.js +++ b/common/content/history.js @@ -350,11 +350,20 @@ var History = Module("history", { }; // FIXME: Schema-specific - context.generate = () => [ - Array.slice(row.rev_host).reverse().join("").slice(1) - for (row of iter(services.history.DBConnection - .createStatement("SELECT DISTINCT rev_host FROM moz_places WHERE rev_host IS NOT NULL;"))) - ].slice(2); + context.generate = () => { + // FIXME: Synchronous. + let statement = services.history.DBConnection + .createStatement(`SELECT DISTINCT rev_host FROM moz_places + WHERE rev_host IS NOT NULL;`); + + let result = Array.from(iter(statement), + ({ rev_host }) => Array.from(rev_host) + .reverse().join("") + .slice(1)); + + statement.finalize(); + return result.slice(2); // Why slice 2?; + }; }; completion.history = function _history(context, maxItems, sort) { diff --git a/common/content/mappings.js b/common/content/mappings.js index 95c4428a..00bb4a77 100644 --- a/common/content/mappings.js +++ b/common/content/mappings.js @@ -746,12 +746,15 @@ var Mappings = Module("mappings", { return null; } function uniqueModes(modes) { - let chars = [k for ([k, v] of iter(modules.modes.modeChars)) - if (v.every(mode => modes.indexOf(mode) >= 0))]; + let chars = ( + Object.entries(modules.modes.modeChars) + .filter(([char, modes_]) => modes_.every(m => modes.includes(m))) + .map(([char]) => char)); - return Ary.uniq(modes.filter(m => chars.indexOf(m.char) < 0) - .map(m => m.name.toLowerCase()) - .concat(chars)); + let names = modes.filter(m => !chars.includes(m.char)) + .map(m => m.name.toLowerCase()); + + return [...new RealSet([...chars, ...names])]; } commands.add(["feedkeys", "fk"], @@ -773,7 +776,8 @@ var Mappings = Module("mappings", { for (let mode of modes.mainModes) if (mode.char && !commands.get(mode.char + "map", true)) addMapCommands(mode.char, - [m.mask for (m of modes.mainModes) if (m.char == mode.char)], + modes.mainModes.filter(m => m.char == mode.char) + .map(m => m.mask), mode.displayName); let args = { @@ -841,9 +845,11 @@ var Mappings = Module("mappings", { let prefix = /^[bCmn]$/.test(mode.char) ? "" : mode.char + "_"; let haveTag = k => hasOwnProp(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))); + return Array.from(self.iterate(args, true)) + .filter(map => (map.hive === mappings.builtin || + haveTag(prefix + map.name))) + .map(map => ({ helpTag: prefix + map.name, + __proto__: map })); }, description: "List all " + mode.displayName + " mode mappings along with their short descriptions", index: mode.char + "-map", @@ -870,8 +876,8 @@ var Mappings = Module("mappings", { [ null, function (context, obj, args) { - return [[m.names, m.description] - for (m of this.iterate(args[0]))]; + return Array.from(this.iterate(args[0]), + map => [map.names, map.description]); } ]); }, diff --git a/common/content/marks.js b/common/content/marks.js index 27737209..0479e60e 100644 --- a/common/content/marks.js +++ b/common/content/marks.js @@ -274,13 +274,14 @@ var Marks = Module("marks", { template.tabular( ["Mark", "HPos", "VPos", "File"], ["", "text-align: right", "text-align: right", "color: green"], - ([name, - mark.offset ? Math.round(mark.offset.x) - : Math.round(mark.position.x * 100) + "%", - mark.offset ? Math.round(mark.offset.y) - : Math.round(mark.position.y * 100) + "%", - mark.location] - for ([name, mark] of marks)))); + Array.from(marks, ([name, mark]) => [ + name, + mark.offset ? Math.round(mark.offset.x) + : Math.round(mark.position.x * 100) + "%", + mark.offset ? Math.round(mark.offset.y) + : Math.round(mark.position.y * 100) + "%", + mark.location, + ]))); }, _onPageLoad: function _onPageLoad(event) { @@ -399,9 +400,10 @@ var Marks = Module("marks", { return !host || util.isDomainURL(url, host); } function match(marks) { - return (k - for ([k, v] of iter(marks)) - if (timespan.contains(v.timestamp) && matchhost(v.location))); + return Array.from(marks) + .filter(([name, mark]) => (timespan.contains(marktimestamp) && + matchhost(marklocation))) + .map(([name]) => name); } for (let [url, local] of marks._localMarks) diff --git a/common/content/modes.js b/common/content/modes.js index c3cf2d34..7acc1bef 100644 --- a/common/content/modes.js +++ b/common/content/modes.js @@ -209,9 +209,9 @@ var Modes = Module("modes", { get all() { return this._modes.slice(); }, get mainModes() { - return (mode - for ([k, mode] of iter(modes._modeMap)) - if (!mode.extended && mode.name == k)); + return Object.entries(modes._modeMap) + .filter(([name, mode]) => !mode.extended && mode.name == name) + .map(([name, mode]) => mode); }, get mainMode() { return this._modeMap[this._main]; }, @@ -595,9 +595,9 @@ var Modes = Module("modes", { for (let base of mode.bases) tree[base.name][mode.name] = tree[mode.name]; - let roots = iter([m.name, tree[m.name]] - for (m of list) - if (!m.bases.length)).toObject(); + let roots = Ary.toObject( + list.filter(mode => !mode.bases.length) + .map(mode => [mode.name, tree[mode.name]])); function rec(obj) { let res = ["ul", { "dactyl:highlight": "Dense" }]; diff --git a/common/content/quickmarks.js b/common/content/quickmarks.js index b81b3936..e027948f 100644 --- a/common/content/quickmarks.js +++ b/common/content/quickmarks.js @@ -100,7 +100,8 @@ 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] of this._qmarks)]; + let marks = Array.from(this._qmarks, ([k]) => k); + 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(); @@ -115,8 +116,10 @@ var QuickMarks = Module("quickmarks", { dactyl.assert(marks.length >= 0, _("quickmark.noMatching", JSON.stringify(filter))); } - commandline.commandOutput(template.tabular(["QuickMark", "URL"], [], - ([mark, quickmarks._qmarks.get(mark)] for (mark of marks)))); + commandline.commandOutput(template.tabular( + ["QuickMark", "URL"], [], + Array.from(marks, + mark => [mark, quickmarks._qmarks.get(mark)]))); } }, { }, { diff --git a/common/content/tabs.js b/common/content/tabs.js index 256e13ec..0f705e8d 100644 --- a/common/content/tabs.js +++ b/common/content/tabs.js @@ -862,7 +862,8 @@ var Tabs = Module("tabs", { let arg = args[0]; if (tabs.indexFromSpec(arg) == -1) { - let list = [tab for (tab of tabs.match(args[0], args.count, true))]; + let list = Array.from(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]; @@ -1296,7 +1297,11 @@ var Tabs = Module("tabs", { ]; options.add(["activate", "act"], "Define when newly created tabs are automatically activated", - "stringlist", [g[0] for (g of activateGroups.slice(1)) if (!g[2] || !prefs.get("browser.tabs." + g[2]))].join(","), + "stringlist", activateGroups.slice(1) + .filter(g => (!g[2] || + !prefs.get("browser.tabs." + g[2]))) + .map(g => g[0]) + .join(","), { values: activateGroups, has: Option.has.toggleAll, diff --git a/common/modules/base.jsm b/common/modules/base.jsm index 409004b0..74136b68 100644 --- a/common/modules/base.jsm +++ b/common/modules/base.jsm @@ -332,10 +332,16 @@ function* properties(obj, prototypes) { return false; }; - return Ary.uniq([k for (k in obj)].concat( - Object.getOwnPropertyNames( - XPCNativeWrapper.unwrap(obj)) - .filter(filter))); + let keys_ = function* (obj) { + for (let key in object) + yield key; + }; + + return [...new RealSet( + [...keys_(obj), + ...Object.getOwnPropertyNames(Cu.waiveXrays(obj)) + .filter(filter)]) + ]; } else if (!e.stack) { throw Error(e); @@ -417,8 +423,11 @@ function keys(obj) { if (isinstance(obj, ["Map"])) return iter(obj.keys()); - return iter(k for (k in obj) - if (hasOwnProp(obj, k))); + return iter(function* () { + for (let k in obj) + if (hasOwnProp(obj, k)) + yield k; + }()); } /** @@ -433,13 +442,16 @@ function values(obj) { return iter(obj.values()); if (isinstance(obj, ["Generator", "Iterator", Iter])) - return iter(k for (k of obj)); + return iter(obj); if (Symbol.iterator in obj) return iter(obj[Symbol.iterator]()); - return iter(obj[k] for (k in obj) - if (hasOwnProp(obj, k))); + return iter(function* () { + for (let k in obj) + if (hasOwnProp(obj, k)) + yield obj[k]; + }()); } var RealSet = Set; @@ -459,7 +471,7 @@ Object.defineProperty(RealSet.prototype, "difference", { configurable: true, writable: true, value: function RealSet_difference(set) { - return new RealSet(i for (i of this) if (!set.has(i))); + return new RealSet(Array.from(this).filter(i => !set.has(i))); } }); @@ -467,7 +479,7 @@ Object.defineProperty(RealSet.prototype, "intersection", { configurable: true, writable: true, value: function RealSet_intersection(set) { - return new RealSet(i for (i of this) if (set.has(i))); + return new RealSet(Array.from(this).filter(i => set.has(i))); } }); @@ -1424,7 +1436,7 @@ var StructBase = Class("StructBase", Array, { }, toObject: function struct_toObject() { - return iter.toObject([k, this[k]] for (k of keys(this.members))); + return Ary.toObject(Object.keys(this.members).map(k => [k, this[k]])); }, toString: function struct_toString() { @@ -1670,8 +1682,10 @@ update(iter, { return obj; }, - compact: function compact(iter) { - return (item for (item of iter) if (item != null)); + compact: function* compact(iter) { + for (let item of iter) + if (item != null) + yield item; }, every: function every(iter, pred, self) { @@ -1838,7 +1852,7 @@ function arrayWrap(fn) { var Ary = Class("Ary", Array, { init: function (ary) { if (Symbol.iterator in ary && !isArray(ary)) - ary = [k for (k of ary)]; + ary = Array.from(ary); return new Proxy(ary, { get: function array_get(target, prop) { diff --git a/common/modules/buffer.jsm b/common/modules/buffer.jsm index 72e09314..3d8553cc 100644 --- a/common/modules/buffer.jsm +++ b/common/modules/buffer.jsm @@ -1110,10 +1110,10 @@ var Buffer = Module("Buffer", { let distance = reverse ? rect => -rect.top : rect => rect.top; - let elems = [[e, distance(e.getBoundingClientRect())] - for (e of path.matcher(this.focusedFrame.document))] - .filter(e => e[1] > FUDGE) - .sort((a, b) => a[1] - b[1]); + let elems = Array.from(path.matcher(this.focusedFrame.document), + elem => [e, distance(e.getBoundingClientRect())]) + .filter(([elem, dist]) => dist > FUDGE) + .sort((a, b) => a[1] - b[1]); if (offScreen && !reverse) elems = elems.filter(function (e) { @@ -2156,13 +2156,15 @@ var Buffer = Module("Buffer", { context.title = ["Stylesheet", "Location"]; // unify split style sheets - let styles = iter([s.title, []] for (s of buffer.alternateStyleSheets)).toObject(); + let styles = Ary.toObject(buffer.alternateStyleSheets + .map(sheet => [sheet.title, []])); buffer.alternateStyleSheets.forEach(function (style) { styles[style.title].push(style.href || _("style.inline")); }); - context.completions = [[title, href.join(", ")] for ([title, href] of iter(styles))]; + context.completions = Object.entries(styles) + .map(([title, href]) => [title, href.join(", ")]); }; completion.savePage = function savePage(context, node) { diff --git a/common/modules/commands.jsm b/common/modules/commands.jsm index 96f8f1af..270e6a64 100644 --- a/common/modules/commands.jsm +++ b/common/modules/commands.jsm @@ -798,7 +798,7 @@ var Commands = Module("commands", { let lines = string.split(/\r\n|[\r\n]/); let startLine = context.line; - for (var i = 0; i < lines.length && !context.finished; i++) { + for (let i = 0; i < lines.length && !context.finished; i++) { // Deal with editors from Silly OSs. let line = lines[i].replace(/\r$/, ""); @@ -834,10 +834,13 @@ var Commands = Module("commands", { 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"; + if (completer) { + for (let [key, val] of Object.entries(config.completers)) + if (completion.bound(val) === completer) + return key; + + return "custom"; + } return ""; } @@ -1567,6 +1570,7 @@ var Commands = Module("commands", { for (var [command, args] of commands.parseCommands(context.filter, context)) if (args.trailing) context.advance(args.commandString.length + 1); + if (!args) args = { commandString: context.filter }; @@ -1749,7 +1753,8 @@ var Commands = Module("commands", { names: ["-complete", "-C"], description: "The argument completion function", completer: function (context) { - return [[k, ""] for ([k, v] of iter(config.completers))]; + return Object.entries(config.completers) + .map(([k, v]) => [k, ""]); }, type: CommandOption.STRING, validator: function (arg) { @@ -1906,12 +1911,11 @@ var Commands = Module("commands", { setCompleter([CommandHive.prototype.get, CommandHive.prototype.remove], [function () { - return [[c.names, c.description] for (c of this)]; + return Array.from(this, cmd => [c.names, c.description]); }]); setCompleter([Commands.prototype.get], [function () { - return [[c.names, c.description] - for (c of this.iterator())]; + return Array.from(this.iterator(), cmd => [c.names, c.description]); }]); }, mappings: function initMappings(dactyl, modules, window) { diff --git a/common/modules/completion.jsm b/common/modules/completion.jsm index 27a6b998..265e881c 100644 --- a/common/modules/completion.jsm +++ b/common/modules/completion.jsm @@ -354,9 +354,11 @@ var CompletionContext = Class("CompletionContext", { set completions(items) { if (items && isArray(items.array)) items = items.array; + // Accept a generator if (!isArray(items)) - items = [x for (x of iter(items || []))]; + items = Array.from(items || []); + if (this._completions !== items) { delete this.cache.filtered; delete this.cache.filter; @@ -795,7 +797,7 @@ var CompletionContext = Class("CompletionContext", { let res = completer.apply(self || this, [context].concat(args)); if (res && !isArray(res) && !isArray(res.__proto__)) - res = [k for (k of res)]; + res = Array.from(res); if (res) context.completions = res; @@ -1073,9 +1075,9 @@ var Completion = Module("completion", { context.fork("about", 6, this, function fork_(context) { context.title = ["about:"]; context.generate = function generate_() { - return [[k.substr(services.ABOUT.length), ""] - for (k in Cc) - if (k.startsWith(services.ABOUT))]; + return Object.keys(Cc).filter(k => k.startsWith(services.ABOUT)) + .map(k => [k.substr(services.ABOUT.length), + ""]); }; }); @@ -1151,10 +1153,11 @@ var Completion = Module("completion", { running[provider] = null; context.incomplete = result.searchResult >= result.RESULT_NOMATCH_ONGOING; - context.completions = [ - { url: result.getValueAt(i), title: result.getCommentAt(i), icon: result.getImageAt(i) } - for (i of util.range(0, result.matchCount)) - ]; + context.completions = Array.from( + util.range(0, result.matchCount), + i => ({ url: result.getValueAt(i), + title: result.getCommentAt(i), + icon: result.getImageAt(i) })); }), get onUpdateSearchResult() { return this.onSearchResult; } }); @@ -1255,7 +1258,11 @@ 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] of iter(context.contexts)) if (k.substr(0, PREFIX.length) == PREFIX)]; + + completion.contextList = ( + Object.entries(context.contexts) + .filter(([k]) => k.substr(0, PREFIX.length) == PREFIX) + .map(([k, v]) => [k.substr(PREFIX.length), v.title[0]])); }, literal: 0 }); diff --git a/common/modules/contexts.jsm b/common/modules/contexts.jsm index a57471d3..09dee79c 100644 --- a/common/modules/contexts.jsm +++ b/common/modules/contexts.jsm @@ -215,12 +215,11 @@ var Contexts = Module("contexts", { memoize(contexts.hives, name, () => Object.create( Object.create(contexts.hiveProto, - { _hive: { value: name } }))); + { _hive: { value: name } }))); memoize(contexts.groupsProto, name, function () { - return [group[name] - for (group of values(this.groups)) - if (hasOwnProp(group, name))]; + return this.groups.filter(group => hasOwnProp(group, name)) + .map(group => group[name]); }); }, @@ -728,24 +727,25 @@ var Contexts = Module("contexts", { ], serialGroup: 20, serialize: function () { - return [ - { + return contexts.initializedGroups() + .filter(group => !group.builtin && group.persist) + .map(group => ({ command: this.name, bang: true, - options: iter([v, typeof group[k] == "boolean" ? null : group[k]] - // FIXME: this map is expressed multiple times - for ([k, v] of iter({ - args: "-args", - description: "-description", - filter: "-locations" - })) - if (group[k])).toObject(), + options: Ary.toObject( + Object.entries({ + args: "-args", + description: "-description", + filter: "-locations" + }) + .filter(([k]) => group[k]) + .map(([k, v]) => [v, + typeof group[k] == "boolean" ? null : group[k]]) + ), arguments: [group.name], ignoreDefaults: true - } - for (group of contexts.initializedGroups()) - if (!group.builtin && group.persist) - ].concat([{ command: this.name, arguments: ["user"] }]); + })) + .concat([{ command: this.name, arguments: ["user"] }]); } }); diff --git a/common/modules/dom.jsm b/common/modules/dom.jsm index eccfb85a..24e7dc21 100644 --- a/common/modules/dom.jsm +++ b/common/modules/dom.jsm @@ -671,9 +671,13 @@ var DOM = Class("DOM", { ["span", { highlight: "HtmlTagEnd" }, "<", namespaced(elem), ">"]] ]); else { - let tag = "<" + [namespaced(elem)].concat( - [namespaced(a) + '="' + String.replace(a.value, /["<]/, DOM.escapeHTML) + '"' - for (a of elem.attributes)]).join(" "); + let escape = val => val.replace(/["<]/g, DOM.escapeHTML); + + let tag = "<" + [ + namespaced(elem), + ...Array.from(elem.attributes, + attr => `${namespaced(attr)}="${escape(attr.value)}"`), + ].join(" "); res.push(tag + (!hasChildren ? "/>" : ">...")); } @@ -1076,10 +1080,10 @@ 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))); + Ary.toObject(Object.entries(opts) + .filter(([k]) => k in params))); apply(evt, "init" + t + "Event", args.map(arg => params[arg])); return evt; @@ -1672,7 +1676,7 @@ var DOM = Class("DOM", { } // FIXME: Surely we can do better. - for (var key in attr) { + for (let key in attr) { if (/^xmlns(?:$|:)/.test(key)) { if (_namespaces === namespaces) namespaces = Object.create(namespaces); @@ -1685,7 +1689,7 @@ var DOM = Class("DOM", { var elem = doc.createElementNS(vals[0] || namespaces[""], name); - for (var key in attr) + for (let key in attr) if (!/^xmlns(?:$|:)/.test(key)) { var val = attr[key]; if (nodes && key == "key") @@ -1699,6 +1703,7 @@ var DOM = Class("DOM", { else elem.setAttributeNS(vals[0] || "", key, val); } + args.forEach(function (e) { elem.appendChild(tag(e, namespaces)); }); @@ -1825,7 +1830,7 @@ var DOM = Class("DOM", { // FIXME: Surely we can do better. let skipAttr = {}; - for (var key in attr) { + for (let key in attr) { if (/^xmlns(?:$|:)/.test(key)) { if (_namespaces === namespaces) namespaces = update({}, namespaces); diff --git a/common/modules/downloads.jsm b/common/modules/downloads.jsm index f93204e3..9b322361 100644 --- a/common/modules/downloads.jsm +++ b/common/modules/downloads.jsm @@ -18,10 +18,10 @@ lazyRequire("resource://gre/modules/DownloadUtils.jsm", ["DownloadUtils"]); var MAX_LOAD_TIME = 10 * 1000; let prefix = "DOWNLOAD_"; -var states = iter([v, k.slice(prefix.length).toLowerCase()] - for ([k, v] of iter(Ci.nsIDownloadManager)) - if (k.startsWith(prefix))) - .toObject(); +var states = Ary.toObject( + Object.entries(Ci.nsIDownloadManager).filter(([key]) => key.startsWith(prefix)) + .map(([key, val]) => [val, + key.slice(prefix.length).toLowerCase()])); var Download = Class("Download", { init: function init(download, list) { diff --git a/common/modules/help.jsm b/common/modules/help.jsm index b5e77185..1c75bda2 100644 --- a/common/modules/help.jsm +++ b/common/modules/help.jsm @@ -301,21 +301,21 @@ var Help = Module("Help", { dactyl.initHelp(); if (FILE.isDirectory()) { - var addDataEntry = function addDataEntry(file, data) { + var addDataEntry = (file, data) => { FILE.child(file).write(data); }; - var addURIEntry = function addURIEntry(file, uri) { + var addURIEntry = (file, uri) => { addDataEntry(file, util.httpGet(uri).responseText); }; } else { var zip = services.ZipWriter(FILE.file, File.MODE_CREATE | File.MODE_WRONLY | File.MODE_TRUNCATE); - addURIEntry = function addURIEntry(file, uri) { + addURIEntry = (file, uri) => { zip.addEntryChannel(PATH + file, TIME, 9, services.io.newChannel(uri, null, null), false); }; - addDataEntry = function addDataEntry(file, data) {// Unideal to an extreme. + addDataEntry = (file, data) => {// Unideal to an extreme. addURIEntry(file, "data:text/plain;charset=UTF-8," + encodeURI(data)); }; } @@ -396,12 +396,14 @@ var Help = Module("Help", { addDataEntry(file + ".xhtml", data.join("")); } - 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 + "}") - .join("\n"); + data = Array.from(highlight) + .filter(h => styles.has(h.class) || /^Help/.test(h.class)) + .map(h => (h.selector + .replace(/^\[.*?=(.*?)\]/, ".hl-$1") + .replace(/html\|/g, "") + + "\t" + "{" + h.cssText + "}")) + .join("\n"); + addDataEntry("help.css", data.replace(/chrome:[^ ")]+\//g, "")); addDataEntry("tag-map.json", JSON.stringify(help.tags)); diff --git a/common/modules/highlight.jsm b/common/modules/highlight.jsm index 25ebca4b..f071445b 100644 --- a/common/modules/highlight.jsm +++ b/common/modules/highlight.jsm @@ -99,8 +99,8 @@ update(Highlight.prototype, { toString: function () { return "Highlight(" + this.class + ")\n\t" + - [k + ": " + JSON.stringify(String(v)) - for ([k, v] of this)].join("\n\t"); + Array.from(this, ([k, v]) => `${k}: ${JSON.stringify(String(v))}`) + .join("\n\t") } }); @@ -431,18 +431,16 @@ var Highlights = Module("Highlight", { } ], serialize: function () { - return [ - { - command: this.name, - arguments: [v.class], - literalArg: v.value, - options: { - "-link": v.extends.length ? v.extends : undefined - } - } - for (v of highlight) - if (v.value != v.defaultValue) - ]; + return Array.from(highlight) + .filter(v => v.value != v.defaultValue) + .map(v => ({ + command: this.name, + arguments: [v.class], + literalArg: v.value, + options: { + "-link": v.extends.length ? v.extends : undefined + } + })); } }); }, @@ -468,7 +466,8 @@ var Highlights = Module("Highlight", { completion.highlightGroup = function highlightGroup(context) { context.title = ["Highlight Group", "Value"]; - context.completions = [[v.class, v.value] for (v of highlight)]; + context.completions = Array.from(highlight, + v => [v.class, v.value]); }; }, javascript: function initJavascript(dactyl, modules, window) { diff --git a/common/modules/io.jsm b/common/modules/io.jsm index dfeaee06..883c85c4 100644 --- a/common/modules/io.jsm +++ b/common/modules/io.jsm @@ -221,9 +221,8 @@ var IO = Module("io", { charsets: Class.Memoize(function () { const BASE = "@mozilla.org/intl/unicode/decoder;1?charset="; - return [k.slice(BASE.length) - for (k of Object.keys(Cc)) - if (k.startsWith(BASE))]; + return Object.keys(Cc).filter(k.startsWith(BASE)) + .map(k => k.slice(BASE.length)); }), charsetBundle: Class.Memoize( @@ -930,13 +929,14 @@ unlet s:cpo_save commands.add(["scrip[tnames]"], "List all sourced script names", function () { - let names = [k for (k of io._scriptNames)]; + let names = Array.from(io._scriptNames); if (!names.length) dactyl.echomsg(_("command.scriptnames.none")); else modules.commandline.commandOutput( template.tabular(["", "Filename"], ["text-align: right; padding-right: 1em;"], - ([i + 1, file] for ([i, file] of iter(names))))); + Array.from(names.entries(), + ([i, file]) => [i + 1, file]))); }, { argCount: "0" }); diff --git a/common/modules/javascript.jsm b/common/modules/javascript.jsm index 387aed55..d16b8ac5 100644 --- a/common/modules/javascript.jsm +++ b/common/modules/javascript.jsm @@ -660,8 +660,8 @@ var JavaScript = Module("javascript", { "encodeURI", "encodeURIComponent", "escape", "eval", "isFinite", "isNaN", "isXMLName", "parseFloat", "parseInt", "undefined", "unescape", "uneval", - ...interfaces.filter(key => /^nsIDOM/.test(key)).map(key => k.substr(6)), - ...interfaces.filter(key => /^nsI/.test(key)).map(key => k.substr(3)), + ...interfaces.filter(key => /^nsIDOM/.test(key)).map(key => key.substr(6)), + ...interfaces.filter(key => /^nsI/.test(key)).map(key => key.substr(3)), ...this.magicalNames, ]); diff --git a/common/modules/options.jsm b/common/modules/options.jsm index 359962d5..3ad98efc 100644 --- a/common/modules/options.jsm +++ b/common/modules/options.jsm @@ -832,8 +832,7 @@ var Option = Class("Option", { if (isArray(acceptable)) acceptable = new RealSet(acceptable.map(v => v[0])); else - acceptable = new RealSet(this.parseKey(k) - for (k of Object.keys(acceptable))); + acceptable = new RealSet(Object.keys(acceptable).map(k => this.parseKey(k))); if (this.type === "regexpmap" || this.type === "sitemap") return Array.concat(vals).every(re => acceptable.has(re.result)); @@ -1483,15 +1482,16 @@ var Options = Module("options", { modifiers: {}, extra: { serialize: function () { - return [ - { + return Array.from(modules.options) + .filter(opt => (!opt.getter && + !opt.isDefault && + (opt.scope & Option.SCOPE_GLOBAL))) + .map( + opt => ({ command: this.name, literalArg: [opt.type == "boolean" ? (opt.value ? "" : "no") + opt.name : opt.name + "=" + opt.stringValue] - } - for (opt of modules.options) - if (!opt.getter && !opt.isDefault && (opt.scope & Option.SCOPE_GLOBAL)) - ]; + })); } } } @@ -1661,7 +1661,8 @@ 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 of options))]); + JavaScript.setCompleter(Options.prototype.get, [() => Array.from(options, + opt => [opt.name, opt.description])]); }, sanitizer: function initSanitizer(dactyl, modules, window) { const { sanitizer } = modules; diff --git a/common/modules/overlay.jsm b/common/modules/overlay.jsm index 0a2ba60e..0f82ed54 100644 --- a/common/modules/overlay.jsm +++ b/common/modules/overlay.jsm @@ -296,10 +296,8 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen function insert(key, fn) { if (obj[key]) { let iterator = iter(obj[key]); - if (isArray(obj[key])) { - iterator = ([elem[1].id, elem.slice(2), elem[1]] - for (elem of obj[key])); - } + if (isArray(obj[key])) + iterator = obj[key].map(elem => [elem[1].id, elem.slice(2), elem[1]]); for (let [elem, xml, attrs] of iterator) { if (elem = doc.getElementById(String(elem))) { @@ -479,7 +477,7 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen return this.activeWindow && this.activeWindow.dactyl.modules; }, - get modules() { return [w.dactyl.modules for (w of this.windows)]; }, + get modules() { return Array.from(this.windows, win => win.dactyl.modules) }, /** * The most recently active dactyl window. diff --git a/common/modules/sanitizer.jsm b/common/modules/sanitizer.jsm index adac8899..718d2c71 100644 --- a/common/modules/sanitizer.jsm +++ b/common/modules/sanitizer.jsm @@ -186,10 +186,10 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef }); function ourItems(persistent) { - return [ - item for (item of values(self.itemMap)) - if (!item.builtin && (!persistent || item.persistent) && item.name !== "all") - ]; + return Object.values(self.itemMap) + .filter(item => (!item.builtin && + (!persistent || item.persistent) && + item.name !== "all")); } function prefOverlay(branch, persistent, local) { @@ -261,13 +261,15 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef elem.setAttribute("rows", elem.itemCount); win.Sanitizer = Class("Sanitizer", win.Sanitizer, { sanitize: function sanitize() { - self.withSavedValues(["sanitizing"], function () { + self.withSavedValues(["sanitizing"], () => { self.sanitizing = true; sanitize.superapply(this, arguments); - sanitizer.sanitizeItems([item.name for (item of values(self.itemMap)) - if (item.shouldSanitize(false))], - Range.fromArray(this.range || [])); - }, this); + sanitizer.sanitizeItems( + Object.values(self.itemMap) + .filter(item => item.shouldSanitize(false)) + .map(item => item.name), + Range.fromArray(this.range || [])); + }); } }); } @@ -601,13 +603,15 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef modules.commandline.commandOutput(template.tabular( ["Host", "Expiry (UTC)", "Path", "Name", "Value"], ["padding-right: 1em", "padding-right: 1em", "padding-right: 1em", "max-width: 12em; overflow: hidden;", "padding-left: 1ex;"], - ([c.host, - c.isSession ? ["span", { highlight: "Enabled" }, "session"] - : (new Date(c.expiry * 1000).toJSON() || "Never").replace(/:\d\d\.000Z/, "").replace("T", " ").replace(/-/g, "/"), - c.path, - c.name, - c.value] - for (c of Sanitizer.iterCookies(host))))); + Array.from(Sanitizer.iterCookies(host), + c => [ + c.host, + c.isSession ? ["span", { highlight: "Enabled" }, "session"] + : (new Date(c.expiry * 1000).toJSON() || "Never").replace(/:\d\d\.000Z/, "").replace("T", " ").replace(/-/g, "/"), + c.path, + c.name, + c.value, + ]))); return; default: util.assert(cmd in Sanitizer.PERMS, _("error.invalidArgument")); @@ -680,17 +684,16 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef { initialValue: true, get values() { - return [i - for (i of values(sanitizer.itemMap)) - if (i.persistent || i.builtin)]; + return Object.values(sanitizer.itemMap) + .filter(i => i.persistent || i.builtin); }, getter: function () { if (!sanitizer.runAtShutdown) return []; else - return [item.name - for (item of values(sanitizer.itemMap)) - if (item.shouldSanitize(true))]; + return Object.values(sanitizer.itemMap) + .filter(item => item.shouldSanitize(true)) + .map(item => item.name); }, setter: function (value) { if (value.length === 0) diff --git a/common/modules/services.jsm b/common/modules/services.jsm index 93939cda..60dbd740 100644 --- a/common/modules/services.jsm +++ b/common/modules/services.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. @@ -175,17 +175,23 @@ var Services = Module("Services", { * @param {string} init Name of a property or method used to initialize the * class. */ - addClass: function addClass(name, class_, ifaces, init, quiet) { - this.services[name] = { class: class_, interfaces: Array.concat(ifaces || []), method: "createInstance", init: init, quiet: quiet }; + addClass: function addClass(name, class_, ifaces, init = null, quiet = false) { + this.services[name] = { class: class_, + interfaces: Array.concat(ifaces || []), + method: "createInstance", + init: init, + quiet: quiet }; + if (init) memoize(this.services[name], "callable", function () { return callable(XPCOMShim(this.interfaces)[this.init]); }); - this[name] = (function Create() { - return this._create(name, arguments); - }).bind(this); - update.apply(null, [this[name]].concat([Ci[i] for (i of Array.concat(ifaces))])); + this[name] = (...args) => this._create(name, args); + + update(this[name], + ...Array.concat(ifaces).map(iface => Ci[iface])); + return this[name]; }, diff --git a/common/modules/storage.jsm b/common/modules/storage.jsm index b885ec78..bf3b8ac6 100644 --- a/common/modules/storage.jsm +++ b/common/modules/storage.jsm @@ -550,7 +550,7 @@ var File = Class("File", { if (!this.isDirectory()) throw Error(_("io.eNotDir")); - let array = [e for (e of this.iterDirectory())]; + let array = Array.from(this.iterDirectory()); if (sort) array.sort((a, b) => (b.isDirectory() - a.isDirectory() || String.localeCompare(a.path, b.path))); diff --git a/common/modules/styles.jsm b/common/modules/styles.jsm index e7ef5a20..b4d1fdc5 100644 --- a/common/modules/styles.jsm +++ b/common/modules/styles.jsm @@ -196,7 +196,7 @@ var Hive = Class("Hive", { */ find: function find(name, filter, css, index) { // Grossly inefficient. - let matches = [k for ([k, v] of iter(this.sheets))]; + let matches = Object.keys(this.sheets); if (index) matches = String(index).split(",").filter(i => i in this.sheets); if (name) diff --git a/common/modules/util.jsm b/common/modules/util.jsm index 4099f220..a3d62171 100644 --- a/common/modules/util.jsm +++ b/common/modules/util.jsm @@ -818,8 +818,9 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), } if (isObject(params.params)) { - let data = [encodeURIComponent(k) + "=" + encodeURIComponent(v) - for ([k, v] of iter(params.params))]; + let encode = ([key, val]) => `${encodeURIComponent(key)}=${encodeURIComponent(val)}`; + let data = Object.entries(params).map(encode); + let uri = util.newURI(url); uri.query += (uri.query ? "&" : "") + data.join("&"); @@ -1307,8 +1308,14 @@ 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] of iter({ g: "global", i: "ignorecase", m: "multiline", y: "sticky" })) - if (expr[v])].join(""); + if (!flags) + flags = Object.entries({ g: "global", + i: "ignorecase", + m: "multiline", + y: "sticky" }) + .filter(([short, full]) => expr[full]) + .map(([short]) => short) + .join(""); if (isinstance(expr, ["RegExp"])) expr = expr.source; @@ -1472,7 +1479,8 @@ 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 () { - return [k + "\n" + v for ([k, v] of this)].join("\n\n"); + return this.map(([name, stack]) => `${name}\n${stack}\n`) + .join("\n"); }; this.dump(String(error)); @@ -1510,9 +1518,11 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), } catch (e) {} - let ary = host.split("."); - ary = [ary.slice(i).join(".") for (i of util.range(ary.length, 0, -1))]; - return ary.filter(h => h.length >= base.length); + let parts = host.split("."); + + return Array.from(util.range(parts.length, 0, -1), + i => parts.slice(i).join(".")) + .filter(host => host.length >= base.length); }, /** diff --git a/plugins/aardvark.js b/plugins/aardvark.js index f8f302b9..7380c66e 100755 --- a/plugins/aardvark.js +++ b/plugins/aardvark.js @@ -1153,13 +1153,13 @@ var Aardvark = Class("Aardvark", { // valid selectable element findValidElement: function findValidElement(elem) { for (; elem; elem = elem.parentNode) { - if (Set.has(this.alwaysValidElements, elem.localName)) + if (hasOwnProperty(this.alwaysValidElements, elem.localName)) break; let { display } = DOM(elem).style; - if (Set.has(this.validIfBlockElements, elem.localName) && display == "block") + if (hasOwnProperty(this.validIfBlockElements, elem.localName) && display == "block") break; - if (Set.has(this.validIfNotInlineElements, elem.localName) && display != "inline") + if (hasOwnProperty(this.validIfNotInlineElements, elem.localName) && display != "inline") break; } return elem; diff --git a/plugins/flashblock.js b/plugins/flashblock.js index 9ecb6901..f83945aa 100755 --- a/plugins/flashblock.js +++ b/plugins/flashblock.js @@ -404,7 +404,7 @@ var CSS = * * Change XBL binding for tags, click to view flash */ - String.literal` + String.raw` pseudoembed { display: inline-block; diff --git a/plugins/http-headers.js b/plugins/http-headers.js index c0c73f1d..90b8635d 100755 --- a/plugins/http-headers.js +++ b/plugins/http-headers.js @@ -31,6 +31,9 @@ var Controller = Class("Controller", XPCOM(Ci.nsIController), { supportsCommand: function (cmd) { return cmd === this.command; }, }); +var winMap = new WeakMap(); +var docMap = new WeakMap(); + var HttpObserver = Class("HttpObserver", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference, Ci.nsIWebProgressListener]), { @@ -58,7 +61,11 @@ var HttpObserver = Class("HttpObserver", getHeaders: function getHeaders(win, request) { request.QueryInterface(Ci.nsIChannel); - let headers = overlay.getData(win.document, "headers", Object); + let doc = win.document; + + let data = docMap.get(doc); + let headers = data && data.headers || {}; + if ("response" in headers) return; @@ -81,10 +88,9 @@ var HttpObserver = Class("HttpObserver", } catch (e) {} - let controller = this.getController(win); - if (controller) - win.controllers.removeController(controller); - win.controllers.appendController(Controller("dactyl-headers", { headers: headers, url: win.document.documentURI })); + let data = { headers: headers, url: doc.documentURI }; + winMap.set(win, data); + docMap.set(doc, data); } }, @@ -118,27 +124,19 @@ var HttpObserver = Class("HttpObserver", } catch (e) {} } }), - - getController: function getController(win) { - for (let i of util.range(0, win.controllers.getControllerCount())) { - let controller = win.controllers.getControllerAt(i); - if (controller.supportsCommand("dactyl-headers") && controller.wrappedJSObject instanceof Controller) - return controller.wrappedJSObject; - } - } }); let observer = HttpObserver(); -let onUnload = observer.closure.cleanup; +let onUnload = observer.bound.cleanup; function* iterHeaders(buffer, type) { let win = buffer.focusedFrame; - let store = win.document[overlay.id]; + let store = docMap.get(win.document); if (!store || !store.headers) - store = observer.getController(win); + store = winMap.get(win); if (store) - for (let [k, v] of values(store.headers[type] || [])) + for (let [k, v] of (store.headers[type] || [])) yield [k, v]; }