diff --git a/common/content/abbreviations.js b/common/content/abbreviations.js index f0cd06d1..c1c8751c 100644 --- a/common/content/abbreviations.js +++ b/common/content/abbreviations.js @@ -1,6 +1,6 @@ // Copyright (c) 2006-2009 by Martin Stubenschrott // Copyright (c) 2010 by anekos -// Copyright (c) 2010-2013 Kris Maglione +// Copyright (c) 2010-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -132,7 +132,8 @@ var AbbrevHive = Class("AbbrevHive", Contexts.Hive, { */ get: function (mode, lhs) { let abbrevs = this._store[mode]; - return abbrevs && Set.has(abbrevs, lhs) ? abbrevs[lhs] : null; + return abbrevs && hasOwnProperty(abbrevs, lhs) ? abbrevs[lhs] + : null; }, /** diff --git a/common/content/bookmarks.js b/common/content/bookmarks.js index 09f088c5..381893f9 100644 --- a/common/content/bookmarks.js +++ b/common/content/bookmarks.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-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -73,7 +73,7 @@ var Bookmarks = Module("bookmarks", { if (id != null) var bmark = bookmarkcache.bookmarks[id]; else if (!force) { - if (keyword && Set.has(bookmarkcache.keywords, keyword)) + if (keyword && hasOwnProperty(bookmarkcache.keywords, keyword)) bmark = bookmarkcache.keywords[keyword]; else if (bookmarkcache.isBookmarked(uri)) for (bmark in bookmarkcache) @@ -223,7 +223,7 @@ var Bookmarks = Module("bookmarks", { if (!alias) alias = "search"; // for search engines which we can't find a suitable alias - if (Set.has(aliases, alias)) + if (hasOwnProperty(aliases, alias)) alias += ++aliases[alias]; else aliases[alias] = 0; @@ -251,10 +251,10 @@ var Bookmarks = Module("bookmarks", { getSuggestions: function getSuggestions(engineName, query, callback) { const responseType = "application/x-suggestions+json"; - if (Set.has(this.suggestionProviders, engineName)) + if (hasOwnProperty(this.suggestionProviders, engineName)) return this.suggestionProviders[engineName](query, callback); - let engine = Set.has(this.searchEngines, engineName) && this.searchEngines[engineName]; + let engine = hasOwnProperty(this.searchEngines, engineName) && this.searchEngines[engineName]; if (engine && engine.supportsResponseType(responseType)) var queryURI = engine.getSubmission(query, responseType).uri.spec; if (!queryURI) @@ -320,7 +320,7 @@ var Bookmarks = Module("bookmarks", { param = query.substr(offset + 1); } - var engine = Set.has(bookmarks.searchEngines, keyword) && bookmarks.searchEngines[keyword]; + var engine = hasOwnProperty(bookmarks.searchEngines, keyword) && bookmarks.searchEngines[keyword]; if (engine) { if (engine.searchForm && !param) return engine.searchForm; @@ -700,7 +700,7 @@ var Bookmarks = Module("bookmarks", { let engine = bookmarks.searchEngines[name]; if (engine) var desc = engine.description; - else if (!Set.has(bookmarks.suggestionProviders, name)) + else if (!hasOwnProperty(bookmarks.suggestionProviders, name)) return; let [, word] = /^\s*(\S+)/.exec(context.filter) || []; diff --git a/common/content/dactyl.js b/common/content/dactyl.js index 26248dd9..93b24e0f 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-2013 Kris Maglione +// Copyright (c) 2008-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -278,7 +278,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { let results = array((params.iterateIndex || params.iterate).call(params, commands.get(name).newArgs())) .array.sort((a, b) => String.localeCompare(a.name, b.name)); - let haveTag = Set.has(help.tags); + let haveTag = hasOwnProperty(help.tags); for (let obj in values(results)) { let res = dactyl.generateHelp(obj, null, null, true); if (!haveTag(obj.helpTag)) @@ -620,7 +620,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { * @param {string} feature The feature name. * @returns {boolean} */ - has: function has(feature) Set.has(config.features, feature), + has: function has(feature) config.has(feature), /** * @private diff --git a/common/content/editor.js b/common/content/editor.js index d98fa950..39e9a857 100644 --- a/common/content/editor.js +++ b/common/content/editor.js @@ -1,4 +1,4 @@ -// Copyright (c) 2008-2013 Kris Maglione +// Copyright (c) 2008-2014 Kris Maglione // Copyright (c) 2006-2009 by Martin Stubenschrott // // This work is licensed for reuse under an MIT license. Details are @@ -68,7 +68,7 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), { name = 0; if (name == "_") var res = null; - else if (Set.has(this.selectionRegisters, name)) + else if (hasOwnProperty(this.selectionRegisters, name)) res = { text: dactyl.clipboardRead(this.selectionRegisters[name]) || "" }; else if (!/^[0-9]$/.test(name)) res = this.registers.get(name); @@ -105,7 +105,7 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), { name = 0; if (name == "_") ; - else if (Set.has(this.selectionRegisters, name)) + else if (hasOwnProperty(this.selectionRegisters, name)) dactyl.clipboardWrite(value.text, verbose, this.selectionRegisters[name]); else if (!/^[0-9]$/.test(name)) this.registers.set(name, value); @@ -1363,11 +1363,12 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), { args.push(obj["file"]); return args; }, - has: function (key) Set.has(util.compileMacro(this.value).seen, key), + has: function (key) util.compileMacro(this.value).seen.has(key), validator: function (value) { this.format({}, value); - return Object.keys(util.compileMacro(value).seen) - .every(k => ["column", "file", "line"].indexOf(k) >= 0); + let allowed = RealSet(["column", "file", "line"]); + return [k for (k of util.compileMacro(value).seen)] + .every(k => allowed.has(k)); } }); diff --git a/common/content/events.js b/common/content/events.js index 8006c4cd..2460e6ed 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-2013 Kris Maglione +// Copyright (c) 2008-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -28,7 +28,7 @@ var EventHive = Class("EventHive", Contexts.Hive, { else [self, events] = [event, event[callback || "events"]]; - if (Set.has(events, "input") && !Set.has(events, "dactyl-input")) + if (hasOwnProperty(events, "input") && !hasOwnProperty(events, "dactyl-input")) events["dactyl-input"] = events.input; return [self, events]; @@ -79,7 +79,7 @@ var EventHive = Class("EventHive", Contexts.Hive, { let elem = args[0].get(); if (target == null || elem == target && self == args[1].get() - && Set.has(events, args[2]) + && hasOwnProperty(events, args[2]) && args[3].wrapped == events[args[2]] && args[4] == capture) { @@ -1124,12 +1124,12 @@ var Events = Module("events", { "sitemap", "", { flush: function flush() { memoize(this, "filters", function () this.value.filter(function (f) f(buffer.documentURI))); - memoize(this, "pass", function () Set(array.flatten(this.filters.map(function (f) f.keys)))); + memoize(this, "pass", function () 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")); }, - has: function (key) Set.has(this.pass, key) || Set.has(this.commandHive.stack.mappings, key), + has: function (key) this.pass.has(key) || hasOwnProperty(this.commandHive.stack.mappings, key), get pass() (this.flush(), this.pass), diff --git a/common/content/mappings.js b/common/content/mappings.js index fa113b4d..e6e47681 100644 --- a/common/content/mappings.js +++ b/common/content/mappings.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-2014 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 Map = Class("Map", { Object.freeze(this.modes); if (info) { - if (Set.has(Map.types, info.type)) + if (hasOwnProperty(Map.types, info.type)) this.update(Map.types[info.type]); this.update(info); } @@ -380,11 +380,13 @@ var Mappings = Module("mappings", { }, iterate: function (mode) { - let seen = {}; + let seen = RealSet(); for (let hive in this.hives.iterValues()) for (let map in array(hive.getStack(mode)).iterValues()) - if (!Set.add(seen, map.name)) + if (!seen.has(map.name)) { + seen.add(map.name); yield map; + } }, // NOTE: just normal mode for now @@ -638,11 +640,13 @@ var Mappings = Module("mappings", { } }; function userMappings(hive) { - let seen = {}; + let seen = RealSet(); for (let stack in values(hive.stacks)) for (let map in array.iterValues(stack)) - if (!Set.add(seen, map.id)) + if (!seen.has(map.id)) { + seen.add(map.id); yield map; + } } modeDescription = modeDescription ? " in " + modeDescription + " mode" : ""; @@ -748,13 +752,14 @@ var Mappings = Module("mappings", { if (!mainOnly) modes = modes[0].allBases; - let seen = {}; + let seen = 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)) - if (!Set.add(seen, name)) { + if (!seen.has(name)) { + seen.add(name); yield { name: name, columns: [ @@ -800,7 +805,7 @@ var Mappings = Module("mappings", { name: [mode.char + "listk[eys]", mode.char + "lk"], iterateIndex: function (args) let (self = this, prefix = /^[bCmn]$/.test(mode.char) ? "" : mode.char + "_", - haveTag = Set.has(help.tags)) + 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))), diff --git a/common/content/modes.js b/common/content/modes.js index 838eab65..cab9600e 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-2013 Kris Maglione +// Copyright (c) 2008-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -446,9 +446,12 @@ var Modes = Module("modes", { this.allBases.indexOf(obj) >= 0 || callable(obj) && this instanceof obj, allBases: Class.Memoize(function () { - let seen = {}, res = [], queue = [this].concat(this.bases); + let seen = RealSet(), + res = [], + queue = [this].concat(this.bases); for (let mode in array.iterValues(queue)) - if (!Set.add(seen, mode)) { + if (!seen.has(mode)) { + seen.add(mode); res.push(mode); queue.push.apply(queue, mode.bases); } @@ -491,7 +494,7 @@ var Modes = Module("modes", { StackElement.defaultValue("params", function () this.main.params); update(StackElement.prototype, { - get toStringParams() !loaded.modes ? this.main.name : [ + get toStringParams() !loaded.modes ? [this.main.name] : [ this.main.name, ["(", modes.all.filter(m => this.extended & m) .map(m => m.name) @@ -604,7 +607,7 @@ var Modes = Module("modes", { return (array.nth(this.value, v => val.some(m => m.name === v.mode), 0) || { result: default_ }).result; - return Set.has(this.valueMap, val) ? this.valueMap[val] : default_; + return hasOwnProperty(this.valueMap, val) ? this.valueMap[val] : default_; }, setter: function (vals) { @@ -622,7 +625,7 @@ var Modes = Module("modes", { }, validator: function validator(vals) vals.map(v => v.replace(/^!/, "")) - .every(Set.has(this.values)), + .every(k => hasOwnProperty(this.values, k)), get values() array.toObject([[m.name.toLowerCase(), m.description] for (m in values(modes._modes)) if (!m.hidden)]) }; diff --git a/common/content/tabs.js b/common/content/tabs.js index 5c7e3e06..b9674ca9 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-2013 Kris Maglione +// Copyright (c) 2008-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -1036,7 +1036,7 @@ var Tabs = Module("tabs", { tabs.getGroups(); tabs[visible ? "visibleTabs" : "allTabs"].forEach(function (tab, i) { let group = (tab.tabItem || tab._tabViewTabItem || defItem).parent || defItem.parent; - if (!Set.has(tabGroups, group.id)) + if (!hasOwnProperty(tabGroups, group.id)) tabGroups[group.id] = [group.getTitle(), []]; group = tabGroups[group.id]; @@ -1261,11 +1261,11 @@ var Tabs = Module("tabs", { values: activateGroups, has: Option.has.toggleAll, setter: function (newValues) { - let valueSet = Set(newValues); + let valueSet = RealSet(newValues); for (let group in values(activateGroups)) if (group[2]) prefs.safeSet("browser.tabs." + group[2], - !(valueSet["all"] ^ valueSet[group[0]]), + !(valueSet.has("all") ^ valueSet.has(group[0])), _("option.safeSet", "activate")); return newValues; } diff --git a/common/modules/addons.jsm b/common/modules/addons.jsm index c6a2c021..f6df9a67 100644 --- a/common/modules/addons.jsm +++ b/common/modules/addons.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2013 Kris Maglione +// Copyright (c) 2009-2014 Kris Maglione // Copyright (c) 2009-2010 by Doug Kearns // // This work is licensed for reuse under an MIT license. Details are @@ -164,7 +164,8 @@ var Addon = Class("Addon", { }, commandAllowed: function commandAllowed(cmd) { - util.assert(Set.has(actions, cmd), _("addon.unknownCommand")); + util.assert(hasOwnProperty(actions, cmd), + _("addon.unknownCommand")); let action = actions[cmd]; if ("perm" in action && !(this.permissions & AddonManager["PERM_CAN_" + action.perm.toUpperCase()])) diff --git a/common/modules/base.jsm b/common/modules/base.jsm index 979c491f..8543e5da 100644 --- a/common/modules/base.jsm +++ b/common/modules/base.jsm @@ -22,6 +22,9 @@ let objproto = Object.prototype; let { __lookupGetter__, __lookupSetter__, __defineGetter__, __defineSetter__, hasOwnProperty, propertyIsEnumerable } = objproto; +hasOwnProperty = Function.call.bind(hasOwnProperty); +propertyIsEnumerable = Function.call.bind(propertyIsEnumerable); + if (typeof XPCSafeJSObjectWrapper === "undefined") this.XPCSafeJSObjectWrapper = XPCNativeWrapper; @@ -147,11 +150,11 @@ defineModule("base", { "Timer", "UTF8", "XPCOM", "XPCOMShim", "XPCOMUtils", "XPCSafeJSObjectWrapper", "array", "bind", "call", "callable", "ctypes", "curry", "debuggerProperties", "defineModule", - "deprecated", "endModule", "forEach", "isArray", "isGenerator", - "isinstance", "isObject", "isString", "isSubclass", "isXML", - "iter", "iterAll", "iterOwnProperties", "keys", "literal", - "memoize", "modujle", "octal", "properties", "require", "set", - "update", "values", "update_" + "deprecated", "endModule", "forEach", "hasOwnProperty", + "isArray", "isGenerator", "isinstance", "isObject", "isString", + "isSubclass", "isXML", "iter", "iterAll", "iterOwnProperties", + "keys", "literal", "memoize", "modujle", "octal", "properties", + "require", "set", "update", "values", "update_" ] }); @@ -171,7 +174,7 @@ function literal(/* comment */) { let file = caller.filename.replace(/.* -> /, ""); let key = "literal:" + file + ":" + caller.lineNumber; - if (Set.has(literal.locations, key)) + if (hasOwnProperty(literal.locations, key)) return literal.locations[key]; let source = literal.files[file] || File.readURL(file); @@ -224,13 +227,15 @@ function prototype(obj) function properties(obj, prototypes, debugger_) { let orig = obj; - let seen = { dactylPropertyNames: true }; + let seen = RealSet(["dactylPropertyNames"]); try { if ("dactylPropertyNames" in obj && !prototypes) for (let key in values(obj.dactylPropertyNames)) - if (key in obj && !Set.add(seen, key)) + if (key in obj && !seen.has(key)) { + seen.add(key); yield key; + } } catch (e) {} @@ -276,8 +281,10 @@ function properties(obj, prototypes, debugger_) { iter = (prop.name.stringValue for (prop in values(debuggerProperties(obj)))); for (let key in iter) - if (!prototypes || !Set.add(seen, key) && obj != orig) + if (!prototypes || !seen.has(key) && obj != orig) { + seen.add(key); yield key; + } } } @@ -291,7 +298,9 @@ function deprecated(alternative, fn) { return Class.Property(iter(fn).map(([k, v]) => [k, callable(v) ? deprecated(alternative, v) : v]) .toObject()); - let name, func = callable(fn) ? fn : function () this[fn].apply(this, arguments); + let name, + func = callable(fn) ? fn + : function () this[fn].apply(this, arguments); function deprecatedMethod() { let obj = !this ? "" : @@ -299,7 +308,9 @@ function deprecated(alternative, fn) { this.constructor.className ? this.constructor.className + "#" : ""; - deprecated.warn(func, obj + (fn.name || name), alternative); + deprecated.warn(func, + obj + (fn.realName || fn.name || name || "").replace(/__/g, "."), + alternative); return func.apply(this, arguments); } @@ -310,16 +321,24 @@ function deprecated(alternative, fn) { } deprecated.warn = function warn(func, name, alternative, frame) { if (!func.seenCaller) - func.seenCaller = Set([ + func.seenCaller = RealSet([ "resource://dactyl/javascript.jsm", "resource://dactyl/util.jsm" ]); + if (!(loaded.util && util && loaded.config && config.protocolLoaded)) { + dump("DACTYL: deprecated method called too early [" + [name, alternative] + "]:\n" + Error().stack + "\n\n"); + return; + } + frame = frame || Components.stack.caller.caller; + let filename = util.fixURI(frame.filename || "unknown"); - if (!Set.add(func.seenCaller, filename)) + if (!func.seenCaller.has(filename)) { + func.seenCaller.add(filename); util.dactyl(func).warn([util.urlPath(filename), frame.lineNumber, " "].join(":") + _("warn.deprecated", name, alternative)); + } } /** @@ -335,7 +354,7 @@ function keys(obj) iter(function keys() { yield k; else for (var k in obj) - if (hasOwnProperty.call(obj, k)) + if (hasOwnProperty(obj, k)) yield k; }()); @@ -355,7 +374,7 @@ function values(obj) iter(function values() { yield k; else for (var k in obj) - if (hasOwnProperty.call(obj, k)) + if (hasOwnProperty(obj, k)) yield obj[k]; }()); @@ -371,13 +390,13 @@ var RealSet = Set; * @param {[string]} ary @optional * @returns {object} */ -this.Set = function Set(ary) { +this.Set = deprecated("RealSet", function Set(ary) { let obj = {}; if (ary) for (let val in values(ary)) obj[val] = true; return obj; -} +}); /** * Adds an element to a set and returns true if the element was * previously contained. @@ -386,11 +405,18 @@ this.Set = function Set(ary) { * @param {string} key The key to add. * @returns boolean */ -Set.add = curry(function set_add(set, key) { - let res = this.has(set, key); - set[key] = true; - return res; -}); +Set.add = deprecated("Set#add", + curry(function Set__add(set, key) { + if (isinstance(set, ["Set"])) { + let res = set.has(key); + set.add(key); + return res; + } + + let res = this.has(set, key); + set[key] = true; + return res; + })); /** * Returns true if the given set contains the given key. * @@ -398,8 +424,14 @@ Set.add = curry(function set_add(set, key) { * @param {string} key The key to check. * @returns {boolean} */ -Set.has = curry(function set_has(set, key) hasOwnProperty.call(set, key) && - propertyIsEnumerable.call(set, key)); +Set.has = deprecated("hasOwnProperty or Set#has", + curry(function Set__has(set, key) { + if (isinstance(set, ["Set"])) + return set.has(key); + + return hasOwnProperty(set, key) && + propertyIsEnumerable(set, key); + })); /** * Returns a new set containing the members of the first argument which * do not exist in any of the other given arguments. @@ -414,6 +446,7 @@ Set.subtract = function set_subtract(set) { delete set[k]; return set; }; + /** * Removes an element from a set and returns true if the element was * previously contained. @@ -422,11 +455,15 @@ Set.subtract = function set_subtract(set) { * @param {string} key The key to remove. * @returns boolean */ -Set.remove = curry(function set_remove(set, key) { - let res = set.has(set, key); - delete set[key]; - return res; -}); +Set.remove = deprecated("Set#delete", + curry(function Set__remove(set, key) { + if (isinstance(set, ["Set"])) + return set.delete(key); + + let res = set.has(set, key); + delete set[key]; + return res; + })); function set() { deprecated.warn(set, "set", "Set"); @@ -472,7 +509,7 @@ function curry(fn, length, self, acc) { if (acc == null) acc = []; - return function curried(...args) { + function curried(...args) { // The curried result should preserve 'this' if (args.length == 0) return close(self || this, curried); @@ -484,6 +521,8 @@ function curry(fn, length, self, acc) { return curry(fn, length, self || this, args); }; + curried.realName = fn.realName || fn.name; + return curried; } if (curry.bind) @@ -1009,7 +1048,7 @@ Class.prototype = { } try { - if ("value" in desc && (k in this.localizedProperties || k in this.magicalProperties)) + if ("value" in desc && (this.localizedProperties.has(k) || this.magicalProperties.has(k))) this[k] = desc.value; else Object.defineProperty(this, k, desc); @@ -1020,8 +1059,8 @@ Class.prototype = { return this; }, - localizedProperties: {}, - magicalProperties: {} + localizedProperties: RealSet(), + magicalProperties: RealSet() }; for (let name in properties(Class.prototype)) { let desc = Object.getOwnPropertyDescriptor(Class.prototype, name); @@ -1045,6 +1084,7 @@ Class.makeClosure = function makeClosure() { return _closure; } + let x = /commandline/i.test(this); iter(properties(this), properties(this, true)).forEach(function (k) { if (!__lookupGetter__.call(this, k) && callable(this[k])) closure[k] = closure(this[k]); @@ -1552,10 +1592,12 @@ update(iter, { array(this.toArray(iter).sort(fn, self)), uniq: function uniq(iter) { - let seen = {}; + let seen = RealSet(); for (let item in iter) - if (!Set.add(seen, item)) + if (!seen.has(item)) { + seen.add(item); yield item; + } }, /** diff --git a/common/modules/buffer.jsm b/common/modules/buffer.jsm index 561c4a5f..6da0ed2b 100644 --- a/common/modules/buffer.jsm +++ b/common/modules/buffer.jsm @@ -77,41 +77,42 @@ var Buffer = Module("Buffer", { /** * Content preference methods. */ - prefs: Class.Memoize(() => ({ - /** - * Returns a promise for the given preference name. - * - * @param {string} pref The name of the preference to return. - * @returns {Promise} - */ - get: promises.withCallback(function get(callback, pref) { - services.contentPrefs.getByDomainAndName( - this.uri.host, pref, this.loadContext, - callback); - }), + prefs: Class.Memoize(function () + let (self = this) ({ + /** + * Returns a promise for the given preference name. + * + * @param {string} pref The name of the preference to return. + * @returns {Promise} + */ + get: promises.withCallback(function get(callback, pref) { + services.contentPrefs.getByDomainAndName( + self.uri.host, pref, self.loadContext, + callback); + }), - /** - * Sets a content preference for the given buffer. - * - * @param {string} pref The preference to set. - * @param {string} value The value to store. - */ - set: promises.withCallback(function set(callback, pref, value) { - services.contentPrefs.set( - this.uri.host, pref, value, this.loadContext, - callback); - }), + /** + * Sets a content preference for the given buffer. + * + * @param {string} pref The preference to set. + * @param {string} value The value to store. + */ + set: promises.withCallback(function set(callback, pref, value) { + services.contentPrefs.set( + self.uri.host, pref, value, self.loadContext, + callback); + }), - /** - * Clear a content preference for the given buffer. - * - * @param {string} pref The preference to clear. - */ - clear: promises.withCallback(function clear(callback, pref) { - services.contentPrefs.removeByDomainAndName( - this.uri.domain, pref, this.loadContext, callback); - }), - })), + /** + * Clear a content preference for the given buffer. + * + * @param {string} pref The preference to clear. + */ + clear: promises.withCallback(function clear(callback, pref) { + services.contentPrefs.removeByDomainAndName( + self.uri.domain, pref, self.loadContext, callback); + }), + })), /** * Gets a content preference for the given buffer. diff --git a/common/modules/cache.jsm b/common/modules/cache.jsm index 3f8e2f1c..cfc2a45a 100644 --- a/common/modules/cache.jsm +++ b/common/modules/cache.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 Kris Maglione +// Copyright (c) 2011-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -18,7 +18,7 @@ var Cache = Module("Cache", XPCOM(Ci.nsIRequestObserver), { this.cache = {}; this.providers = {}; this.globalProviders = this.providers; - this.providing = {}; + this.providing = RealSet(); this.localProviders = {}; if (JSMLoader.cacheFlush) @@ -174,22 +174,24 @@ var Cache = Module("Cache", XPCOM(Ci.nsIRequestObserver), { this.cacheReader.getInputStream(name))); } - if (Set.has(this.localProviders, name) && !this.isLocal) { + if (hasOwnProperty(this.localProviders, name) && !this.isLocal) { for each (let { cache } in overlay.modules) if (cache._has(name)) return cache.force(name, true); } - if (Set.has(this.providers, name)) { - util.assert(!Set.add(this.providing, name), + if (hasOwnProperty(this.providers, name)) { + util.assert(!this.providing.has(name), "Already generating cache for " + name, false); + this.providing.add(name); + try { let [func, self] = this.providers[name]; this.cache[name] = func.call(self || this, name); } finally { - delete this.providing[name]; + this.providing.delete(name); } cache.queue.push([Date.now(), name]); @@ -203,9 +205,9 @@ var Cache = Module("Cache", XPCOM(Ci.nsIRequestObserver), { }, get: function get(name, callback, self) { - if (!Set.has(this.cache, name)) { - if (callback && !(Set.has(this.providers, name) || - Set.has(this.localProviders, name))) + if (!hasOwnProperty(this.cache, name)) { + if (callback && !(hasOwnProperty(this.providers, name) || + hasOwnProperty(this.localProviders, name))) this.register(name, callback, self); this.cache[name] = this.force(name); @@ -216,14 +218,15 @@ var Cache = Module("Cache", XPCOM(Ci.nsIRequestObserver), { return this.cache[name]; }, - _has: function _has(name) Set.has(this.providers, name) || set.has(this.cache, name), + _has: function _has(name) hasOwnProperty(this.providers, name) + || hasOwnProperty(this.cache, name), has: function has(name) [this.globalProviders, this.cache, this.localProviders] - .some(obj => Set.has(obj, name)), + .some(obj => hasOwnProperty(obj, name)), register: function register(name, callback, self) { if (this.isLocal) - Set.add(this.localProviders, name); + this.localProviders[name] = true; this.providers[name] = [callback, self]; }, @@ -244,7 +247,7 @@ var Cache = Module("Cache", XPCOM(Ci.nsIRequestObserver), { this.closeWriter(); this.queue.splice(0).forEach(function ([time, entry]) { - if (time && Set.has(this.cache, entry)) { + if (time && hasOwnProperty(this.cache, entry)) { let stream = services.CharsetConv("UTF-8") .convertToInputStream(this.stringify(this.cache[entry])); diff --git a/common/modules/commands.jsm b/common/modules/commands.jsm index 0e0d58fc..ade668fd 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-2013 Kris Maglione +// Copyright (c) 2008-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -210,7 +210,7 @@ var Command = Class("Command", { extra: extra }), - complained: Class.Memoize(function () ({})), + complained: Class.Memoize(function () RealSet()), /** * @property {[string]} All of this command's name specs. e.g., "com[mand]" @@ -325,7 +325,8 @@ var Command = Class("Command", { explicitOpts: Class.Memoize(function () ({})), - has: function AP_has(opt) Set.has(this.explicitOpts, opt) || typeof opt === "number" && Set.has(this, opt), + has: function AP_has(opt) hasOwnProperty(this.explicitOpts, opt) + || typeof opt === "number" && hasOwnProperty(this, opt), get literalArg() this.command.literal != null && this[this.command.literal] || "", @@ -402,8 +403,12 @@ var Command = Class("Command", { warn: function warn(context, type, message) { let loc = !context ? "" : [context.file, context.line, " "].join(":"); - if (!Set.add(this.complained, type + ":" + (context ? context.file : "[Command Line]"))) + let key = type + ":" + (context ? context.file : "[Command Line]"); + + if (!this.complained.has(key)) { + this.complained.add(key); this.modules.dactyl.warn(loc + message); + } } }, { hasName: function hasName(specs, name) @@ -1011,7 +1016,7 @@ var Commands = Module("commands", { let matchOpts = function matchOpts(arg) { // Push possible option matches into completions if (complete && !onlyArgumentsRemaining) - completeOpts = options.filter(opt => (opt.multiple || !Set.has(args, opt.names[0]))); + completeOpts = options.filter(opt => (opt.multiple || !hasOwnProperty(args, opt.names[0]))); }; let resetCompletions = function resetCompletions() { completeOpts = null; @@ -1721,7 +1726,7 @@ var Commands = Module("commands", { ] })), iterateIndex: function (args) let (tags = help.tags) - this.iterate(args).filter(cmd => (cmd.hive === commands.builtin || Set.has(tags, cmd.helpTag))), + 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 : "")), diff --git a/common/modules/completion.jsm b/common/modules/completion.jsm index 14b5feb7..7d4e04f7 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-2013 Kris Maglione +// Copyright (c) 2008-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -1183,9 +1183,10 @@ var Completion = Module("completion", { if (k.indexOf(services.AUTOCOMPLETE) == 0)]), setter: function setter(values) { - if (values.length == 1 && !Set.has(values[0], this.values) - && Array.every(values[0], Set.has(this.valueMap))) - return Array.map(values[0], function m(v) this[v], this.valueMap); + if (values.length == 1 && !hasOwnProperty(values[0], this.values) + && Array.every(values[0], v => hasOwnProperty(this.valueMap, v))) + return Array.map(values[0], v => this.valueMap[v]); + return values; }, diff --git a/common/modules/config.jsm b/common/modules/config.jsm index c04a57a0..44d3d252 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-2013 Kris Maglione +// Copyright (c) 2008-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -9,16 +9,19 @@ let global = this; defineModule("config", { exports: ["ConfigBase", "Config", "config"], - require: ["dom", "io", "protocol", "services", "util", "template"] + require: ["io", "protocol", "services"] }); lazyRequire("addons", ["AddonManager"]); lazyRequire("cache", ["cache"]); +lazyRequire("dom", ["DOM"]); lazyRequire("highlight", ["highlight"]); lazyRequire("messages", ["_"]); lazyRequire("prefs", ["localPrefs", "prefs"]); lazyRequire("storage", ["storage", "File"]); lazyRequire("styles", ["Styles"]); +lazyRequire("template", ["template"]); +lazyRequire("util", ["util"]); function AboutHandler() {} AboutHandler.prototype = { @@ -50,13 +53,12 @@ var ConfigBase = Class("ConfigBase", { this.loadConfig(); - this.features.push = deprecated("Set.add", function push(feature) Set.add(this, feature)); - JSMLoader.registerFactory(JSMLoader.Factory(AboutHandler)); JSMLoader.registerFactory(JSMLoader.Factory( Protocol("dactyl", "{9c8f2530-51c8-4d41-b356-319e0b155c44}", "resource://dactyl-content/"))); + this.protocolLoaded = true; this.timeout(function () { cache.register("config.dtd", () => util.makeDTD(config.dtd)); }); @@ -71,7 +73,7 @@ var ConfigBase = Class("ConfigBase", { get prefs() localPrefs, - get has() Set.has(this.features), + has: function (feature) this.features.has(feature), configFiles: [ "resource://dactyl-common/config.json", @@ -91,6 +93,9 @@ var ConfigBase = Class("ConfigBase", { if (isArray(this[prop])) this[prop] = [].concat(this[prop], value); + else if (isinstance(this[prop], ["Set"])) + for (let key of value) + this[prop].add(key); else if (isObject(this[prop])) { if (isArray(value)) value = Set(value); @@ -236,7 +241,7 @@ var ConfigBase = Class("ConfigBase", { bestLocale: function (list) { return values([this.appLocale, this.appLocale.replace(/-.*/, ""), "en", "en-US", list[0]]) - .nth(Set.has(Set(list)), 0); + .nth((function (l) this.has(l)).bind(RealSet(list)), 0); }, /** @@ -529,7 +534,7 @@ var ConfigBase = Class("ConfigBase", { * dactyl.has(feature) to check for a feature's presence * in this array. */ - features: {}, + features: RealSet(), /** * @property {string} The file extension used for command script files. diff --git a/common/modules/contexts.jsm b/common/modules/contexts.jsm index 3c0ca3a9..42feea94 100644 --- a/common/modules/contexts.jsm +++ b/common/modules/contexts.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2010-2013 Kris Maglione +// Copyright (c) 2010-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -189,7 +189,9 @@ var Contexts = Module("contexts", { { _hive: { value: name } }))); memoize(contexts.groupsProto, name, - function () [group[name] for (group in values(this.groups)) if (Set.has(group, name))]); + function () [group[name] + for (group in values(this.groups)) + if (hasOwnProperty(group, name))]); }, get toStringParams() [this.name, this.Hive] @@ -211,13 +213,13 @@ var Contexts = Module("contexts", { let id = util.camelCase(name.replace(/\.[^.]*$/, "")); let contextPath = file.path; - let self = Set.has(plugins, contextPath) && plugins.contexts[contextPath]; + let self = hasOwnProperty(plugins, contextPath) && plugins.contexts[contextPath]; if (!self && isPlugin && false) - self = Set.has(plugins, id) && plugins[id]; + self = hasOwnProperty(plugins, id) && plugins[id]; if (self) { - if (Set.has(self, "onUnload")) + if (hasOwnProperty(self, "onUnload")) util.trapErrors("onUnload", self); } else { @@ -310,7 +312,7 @@ var Contexts = Module("contexts", { .replace(File.PATH_SEP, "-"); let id = util.camelCase(name.replace(/\.[^.]*$/, "")); - let self = Set.has(this.pluginModules, canonical) && this.pluginModules[canonical]; + let self = hasOwnProperty(this.pluginModules, canonical) && this.pluginModules[canonical]; if (!self) { self = Object.create(jsmodules); @@ -411,7 +413,7 @@ var Contexts = Module("contexts", { initializedGroups: function (hive) let (need = hive ? [hive] : Object.keys(this.hives)) - this.groupList.filter(group => need.some(Set.has(group))), + this.groupList.filter(group => need.some(hasOwnProperty.bind(null, group))), addGroup: function addGroup(name, description, filter, persist, replace) { let group = this.getGroup(name); @@ -468,7 +470,7 @@ var Contexts = Module("contexts", { getGroup: function getGroup(name, hive) { if (name === "default") var group = this.context && this.context.context && this.context.context.GROUP; - else if (Set.has(this.groupMap, name)) + else if (hasOwnProperty(this.groupMap, name)) group = this.groupMap[name]; if (group && hive) @@ -644,7 +646,7 @@ var Contexts = Module("contexts", { util.assert(!group.builtin || !["-description", "-locations", "-nopersist"] - .some(Set.has(args.explicitOpts)), + .some(hasOwnProperty.bind(null, args.explicitOpts)), _("group.cantModifyBuiltin")); }, { diff --git a/common/modules/dom.jsm b/common/modules/dom.jsm index 42c3902b..8bce37f5 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-2013 Kris Maglione +// Copyright (c) 2008-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -627,7 +627,7 @@ var DOM = Class("DOM", { if (callable(v)) v = v.call(this, elem, i); - if (Set.has(hooks, k) && hooks[k].set) + if (hasOwnProperty(hooks, k) && hooks[k].set) hooks[k].set.call(this, elem, v, k); else if (v == null) elem.removeAttributeNS(ns, k); @@ -639,7 +639,7 @@ var DOM = Class("DOM", { if (!this.length) return null; - if (Set.has(hooks, key) && hooks[key].get) + if (hasOwnProperty(hooks, key) && hooks[key].get) return hooks[key].get.call(this, this[0], key); if (!this[0].hasAttributeNS(ns, key)) @@ -1071,7 +1071,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: Set(["count", "leader", "nop", "pass"]), + pseudoKeys: RealSet(["count", "leader", "nop", "pass"]), /** * Converts a user-input string of keys into a canonical @@ -1141,19 +1141,19 @@ var DOM = Class("DOM", { } else { let [match, modifier, keyname] = evt_str.match(/^<((?:[*12CASM⌘]-)*)(.+?)>$/i) || [false, '', '']; - modifier = Set(modifier.toUpperCase()); + modifier = RealSet(modifier.toUpperCase()); keyname = keyname.toLowerCase(); evt_obj.dactylKeyname = keyname; if (/^u[0-9a-f]+$/.test(keyname)) keyname = String.fromCharCode(parseInt(keyname.substr(1), 16)); if (keyname && (unknownOk || keyname.length == 1 || /mouse$/.test(keyname) || - this.key_code[keyname] || Set.has(this.pseudoKeys, keyname))) { - evt_obj.globKey ="*" in modifier; - evt_obj.ctrlKey ="C" in modifier; - evt_obj.altKey ="A" in modifier; - evt_obj.shiftKey ="S" in modifier; - evt_obj.metaKey ="M" in modifier || "⌘" in modifier; + this.key_code[keyname] || this.pseudoKeys.has(keyname))) { + evt_obj.globKey = modifier.has("*"); + evt_obj.ctrlKey = modifier.has("C"); + evt_obj.altKey = modifier.has("A"); + evt_obj.shiftKey = modifier.has("S"); + evt_obj.metaKey = modifier.has("M") || modifier.has("⌘"); evt_obj.dactylShift = evt_obj.shiftKey; if (keyname.length == 1) { // normal characters @@ -1164,11 +1164,11 @@ var DOM = Class("DOM", { evt_obj.charCode = keyname.charCodeAt(0); evt_obj.keyCode = this.key_code[keyname.toLowerCase()]; } - else if (Set.has(this.pseudoKeys, keyname)) { + else if (this.pseudoKeys.has(keyname)) { evt_obj.dactylString = "<" + this.key_key[keyname] + ">"; } else if (/mouse$/.test(keyname)) { // mouse events - evt_obj.type = (/2-/.test(modifier) ? "dblclick" : "click"); + evt_obj.type = (modifier.has("2") ? "dblclick" : "click"); evt_obj.button = ["leftmouse", "middlemouse", "rightmouse"].indexOf(keyname); delete evt_obj.keyCode; delete evt_obj.charCode; @@ -1398,9 +1398,9 @@ var DOM = Class("DOM", { * The set of input element type attribute values that mark the element as * an editable field. */ - editableInputs: Set(["date", "datetime", "datetime-local", "email", "file", - "month", "number", "password", "range", "search", - "tel", "text", "time", "url", "week"]), + editableInputs: 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 @@ -1633,7 +1633,7 @@ var DOM = Class("DOM", { toPrettyXML: function toPrettyXML(xml, asXML, indent, namespaces) { const INDENT = indent || " "; - const EMPTY = Set("area base basefont br col frame hr img input isindex link meta param" + const EMPTY = RealSet("area base basefont br col frame hr img input isindex link meta param" .split(" ")); function namespaced(namespaces, namespace, localName) { @@ -1742,7 +1742,7 @@ var DOM = Class("DOM", { let res = [indent, "<", name]; for (let [key, val] in Iterator(attr)) { - if (Set.has(skipAttr, key)) + if (hasOwnProperty(skipAttr, key)) continue; let vals = parseNamespace(key); @@ -1758,7 +1758,7 @@ var DOM = Class("DOM", { '="', DOM.escapeHTML(val), '"'); } - if ((vals[0] || namespaces[""]) == String(XHTML) && Set.has(EMPTY, vals[1]) + if ((vals[0] || namespaces[""]) == String(XHTML) && EMPTY.has(vals[1]) || asXML && !args.length) res.push("/>"); else { @@ -1881,7 +1881,7 @@ var DOM = Class("DOM", { Object.keys(DOM.Event.types).forEach(function (event) { let name = event.replace(/-(.)/g, (m, m1) => m1.toUpperCase()); - if (!Set.has(DOM.prototype, name)) + if (!hasOwnProperty(DOM.prototype, name)) DOM.prototype[name] = function _event(arg, extra) { return this[callable(arg) ? "listen" : "dispatch"](event, arg, extra); diff --git a/common/modules/downloads.jsm b/common/modules/downloads.jsm index 63d826eb..ff534265 100644 --- a/common/modules/downloads.jsm +++ b/common/modules/downloads.jsm @@ -87,10 +87,10 @@ var Download = Class("Download", { })), command: function command(name) { - util.assert(Set.has(this.allowedCommands, name), _("download.unknownCommand")); + util.assert(hasOwnProperty(this.allowedCommands, name), _("download.unknownCommand")); util.assert(this.allowedCommands[name], _("download.commandNotAllowed")); - if (Set.has(this.commands, name)) + if (hasOwnProperty(this.commands, name)) this.commands[name].call(this); }, @@ -523,9 +523,9 @@ var Downloads_ = Module("downloads", XPCOM(Ci.nsIDownloadProgressListener), { }, completer: function (context, extra) { - let seen = Set.has(Set(extra.values.map(val => val.substr(1)))); + let seen = RealSet(extra.values.map(val => val.substr(1))); - context.completions = iter(this.values).filter(([k, v]) => !seen(k)) + context.completions = iter(this.values).filter(([k, v]) => !seen.has(k)) .map(([k, v]) => [["+" + k, [v, " (", _("sort.ascending"), ")"].join("")], ["-" + k, [v, " (", _("sort.descending"), ")"].join("")]]) .flatten().array; @@ -535,7 +535,7 @@ var Downloads_ = Module("downloads", XPCOM(Ci.nsIDownloadProgressListener), { validator: function (value) { let seen = {}; - return value.every(val => /^[+-]/.test(val) && Set.has(this.values, val.substr(1)) + return value.every(val => /^[+-]/.test(val) && hasOwnProperty(this.values, val.substr(1)) && !Set.add(seen, val.substr(1))) && value.length; } diff --git a/common/modules/help.jsm b/common/modules/help.jsm index f477411e..1b5096e4 100644 --- a/common/modules/help.jsm +++ b/common/modules/help.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2008-2013 Kris Maglione +// Copyright (c) 2008-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -237,7 +237,7 @@ var Help = Module("Help", { * @returns {string} */ findHelp: function (topic, consolidated) { - if (!consolidated && Set.has(help.files, topic)) + if (!consolidated && hasOwnProperty(help.files, topic)) return topic; let items = modules.completion._runCompleter("help", topic, null, !!consolidated).items; let partialMatch = null; @@ -268,7 +268,7 @@ var Help = Module("Help", { if (!topic) { let helpFile = consolidated ? "all" : modules.options["helpfile"]; - if (Set.has(help.files, helpFile)) + if (hasOwnProperty(help.files, helpFile)) dactyl.open("dactyl://help/" + helpFile, { from: "help" }); else dactyl.echomsg(_("help.noFile", helpFile.quote())); @@ -304,7 +304,7 @@ var Help = Module("Help", { addURIEntry(file, "data:text/plain;charset=UTF-8," + encodeURI(data)); } - let empty = Set("area base basefont br col frame hr img input isindex link meta param" + let empty = RealSet("area base basefont br col frame hr img input isindex link meta param" .split(" ")); function fix(node) { switch (node.nodeType) { @@ -319,7 +319,7 @@ var Help = Module("Help", { for (let { name, value } in array.iterValues(node.attributes)) { if (name == "dactyl:highlight") { - Set.add(styles, value); + styles.add(value); name = "class"; value = "hl-" + value; } @@ -345,7 +345,7 @@ var Help = Module("Help", { data.push(" ", name, '="', DOM.escapeHTML(value), '"'); } - if (node.localName in empty) + if (empty.has(node.localName)) data.push(" />"); else { data.push(">"); @@ -362,7 +362,7 @@ var Help = Module("Help", { let { buffer, content, events } = modules; let chromeFiles = {}; - let styles = {}; + let styles = RealSet(); for (let [file, ] in Iterator(help.files)) { let url = "dactyl://help/" + file; @@ -380,7 +380,7 @@ var Help = Module("Help", { addDataEntry(file + ".xhtml", data.join("")); } - let data = [h for (h in highlight) if (Set.has(styles, h.class) || /^Help/.test(h.class))] + let data = [h for (h in highlight) if (styles.has(h.class) || /^Help/.test(h.class))] .map(h => h.selector .replace(/^\[.*?=(.*?)\]/, ".hl-$1") .replace(/html\|/g, "") + "\t" + "{" + h.cssText + "}") diff --git a/common/modules/io.jsm b/common/modules/io.jsm index 4a61d673..5d913c51 100644 --- a/common/modules/io.jsm +++ b/common/modules/io.jsm @@ -1,7 +1,6 @@ // Copyright (c) 2006-2008 by Martin Stubenschrott // Copyright (c) 2007-2012 by Doug Kearns -// Copyright (c) 2008-2013 Kris Maglione -// Some code based on Venkman +// Copyright (c) 2008-2014 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 +41,7 @@ var IO = Module("io", { this._oldcwd = null; this._lastRunCommand = ""; // updated whenever the users runs a command with :! - this._scriptNames = []; + this._scriptNames = RealSet(); }, CommandFileMode: Class("CommandFileMode", modules.CommandMode, { @@ -156,7 +155,7 @@ var IO = Module("io", { else if (/\.js$/.test(filename)) { try { var context = contexts.Script(file, params.group); - if (Set.has(this._scriptNames, file.path)) + if (this._scriptNames.has(file.path)) util.flushCache(); dactyl.loadScript(uri.spec, context); @@ -196,7 +195,7 @@ var IO = Module("io", { dactyl.triggerObserver("io.source", context, file, file.lastModifiedTime); } - Set.add(this._scriptNames, file.path); + this._scriptNames.add(file.path); dactyl.echomsg(_("io.sourcingEnd", filename.quote()), 2); dactyl.log(_("dactyl.sourced", filename), 3); @@ -865,7 +864,7 @@ unlet s:cpo_save commands.add(["scrip[tnames]"], "List all sourced script names", function () { - let names = Object.keys(io._scriptNames); + let names = [k for (k of io._scriptNames)]; if (!names.length) dactyl.echomsg(_("command.scriptnames.none")); else diff --git a/common/modules/javascript.jsm b/common/modules/javascript.jsm index 47f77ad4..686ffc3f 100644 --- a/common/modules/javascript.jsm +++ b/common/modules/javascript.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2008-2013 Kris Maglione +// Copyright (c) 2008-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -72,23 +72,29 @@ var JavaScript = Module("javascript", { if (obj == null) return; - let seen = isinstance(obj, ["Sandbox"]) ? Set(JavaScript.magicalNames) : {}; + let seen = RealSet(isinstance(obj, ["Sandbox"]) ? JavaScript.magicalNames : []); let globals = values(toplevel && this.window === obj ? this.globalNames : []); if (toplevel && isObject(obj) && "wrappedJSObject" in obj) - if (!Set.add(seen, "wrappedJSObject")) + if (!seen.has("wrappedJSObject")) { + seen.add("wrappedJSObject"); yield "wrappedJSObject"; + } for (let key in iter(globals, properties(obj, !toplevel, true))) - if (!Set.add(seen, key)) + if (!seen.has(key)) { + 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"), !toplevel, true)) try { - if (key in obj && !Set.has(seen, key)) + if (key in obj && !seen.has(key)) { + seen.add(key); yield key; + } } catch (e) {} }, diff --git a/common/modules/main.jsm b/common/modules/main.jsm index 19e36b46..be394946 100644 --- a/common/modules/main.jsm +++ b/common/modules/main.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2013 Kris Maglione +// Copyright (c) 2009-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -192,8 +192,8 @@ overlay.overlayWindow(Object.keys(config.overlays), this.startTime = Date.now(); this.deferredInit = { load: {} }; - this.seen = {}; - this.loaded = {}; + this.seen = RealSet(); + this.loaded = RealSet(); modules.loaded = this.loaded; this.modules = modules; @@ -258,11 +258,12 @@ overlay.overlayWindow(Object.keys(config.overlays), } try { - if (Set.has(loaded, module.className)) + if (loaded.has(module.className)) return; - if (Set.add(seen, module.className)) + if (seen.has(module.className)) throw Error("Module dependency loop."); + seen.add(module.className); for (let dep in values(module.requires)) this.loadModule(Module.constructors[dep], module.className); @@ -277,9 +278,9 @@ overlay.overlayWindow(Object.keys(config.overlays), let obj = defineModule.time(module.className, "init", module); Class.replaceProperty(modules, module.className, obj); - Set.add(loaded, module.className); + loaded.add(module.className); - if (loaded.dactyl && obj.signals) + if (loaded.has("dactyl") && obj.signals) modules.dactyl.registerObservers(obj); if (!module.lazyDepends) @@ -300,7 +301,7 @@ overlay.overlayWindow(Object.keys(config.overlays), let className = mod.className || mod.constructor.className; - if (!Set.has(init, className)) { + if (!hasOwnProperty(init, className)) { init[className] = function callee() { function finish() { this.currentDependency = className; @@ -324,11 +325,12 @@ overlay.overlayWindow(Object.keys(config.overlays), let { Module, modules } = this.modules; defineModule.modules.forEach((mod) => { - let names = Set(Object.keys(mod.INIT)); + let names = RealSet(Object.keys(mod.INIT)); if ("init" in mod.INIT) - Set.add(names, "init"); + names.add("init"); - keys(names).forEach((name) => { this.deferInit(name, mod.INIT, mod); }); + for (let name of names) + this.deferInit(name, mod.INIT, mod); }); Module.list.forEach((mod) => { diff --git a/common/modules/messages.jsm b/common/modules/messages.jsm index 36fead2c..c4b0dea8 100644 --- a/common/modules/messages.jsm +++ b/common/modules/messages.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 Kris Maglione +// Copyright (c) 2011-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -45,14 +45,24 @@ var Messages = Module("messages", { "resource://dactyl-locale-local/en-US/" + this.name + ".properties"], true) .map(services.stringBundle.createBundle) - .filter(function (bundle) { try { bundle.getSimpleEnumeration(); return true; } catch (e) { return false; } })), + .filter(function (bundle) { + try { + bundle.getSimpleEnumeration(); + return true; + } + catch (e) { + return false; + } + })), iterate: function () { - let seen = {}; + let seen = RealSet(); for (let bundle in values(this.bundles)) for (let { key, value } in iter(bundle.getSimpleEnumeration(), Ci.nsIPropertyElement)) - if (!Set.add(seen, key)) + if (!seen.has(key)) { + seen.add(key); yield [key, value]; + } }, get: function get(value, default_) { @@ -139,9 +149,9 @@ var Messages = Module("messages", { return { configurable: true, enumerable: true, value: this.default, writable: true }; */ - if (!Set.has(obj, "localizedProperties")) - obj.localizedProperties = { __proto__: obj.localizedProperties }; - obj.localizedProperties[prop] = true; + if (!hasOwnProperty(obj, "localizedProperties")) + obj.localizedProperties = RealSet(obj.localizedProperties); + obj.localizedProperties.add(prop); obj[_prop] = this.default; return { diff --git a/common/modules/options.jsm b/common/modules/options.jsm index 77439afe..241d746e 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-2013 by Kris Maglione +// Copyright (c) 2008-2014 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: Set(["cleanupValue"]), + magicalProperties: RealSet(["cleanupValue"]), /** * @property {string} This option's description, as shown in :listoptions. @@ -329,7 +329,7 @@ var Option = Class("Option", { let defaultValue = this._defaultValue; delete this._defaultValue; - if (Set.has(this.modules.config.optionDefaults, this.name)) + if (hasOwnProperty(this.modules.config.optionDefaults, this.name)) defaultValue = this.modules.config.optionDefaults[this.name]; if (defaultValue == null && this.getter) @@ -682,11 +682,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) !Set.has(this, item), Set(values)); + return this.value.filter(function (item) !this.has(item), RealSet(values)); case "=": if (invert) { - let keepValues = this.value.filter(function (item) !Set.has(this, item), Set(values)); - let addValues = values.filter(function (item) !Set.has(this, item), Set(this.value)); + let keepValues = this.value.filter(function (item) !this.has(item), RealSet(values)); + let addValues = values.filter(function (item) !this.has(item), RealSet(this.value)); return addValues.concat(keepValues); } return values; @@ -723,7 +723,9 @@ var Option = Class("Option", { if (isObject(vals) && !isArray(vals)) { let k = values(completions.call(this, { values: {} })).toObject(); let v = values(completions.call(this, { value: "" })).toObject(); - return Object.keys(vals).every(Set.has(k)) && values(vals).every(Set.has(v)); + + return Object.keys(vals).every(hasOwnProperty.bind(null, k)) && + values(vals).every(hasOwnProperty.bind(null, v)); } if (this.values) @@ -732,12 +734,14 @@ var Option = Class("Option", { acceptable = completions.call(this); if (isArray(acceptable)) - acceptable = Set(acceptable.map(([k]) => (k))); + acceptable = RealSet(acceptable.map(([k]) => (k))); + else + acceptable = RealSet(Object.keys(acceptable)); if (this.type === "regexpmap" || this.type === "sitemap") - return Array.concat(vals).every(re => Set.has(acceptable, re.result)); + return Array.concat(vals).every(re => acceptable.has(re.result)); - return Array.concat(vals).every(Set.has(acceptable)); + return Array.concat(vals).every(v => acceptable.has(v)); }, types: {} @@ -789,7 +793,7 @@ var OptionHive = Class("OptionHive", Contexts.Hive, { init: function init(group) { init.supercall(this, group); this.values = {}; - this.has = Set.has(this.values); + this.has = v => hasOwnProperty(this.values, v); }, add: function add(names, description, type, defaultValue, extraInfo) { @@ -1098,13 +1102,13 @@ var Options = Module("options", { let list = []; function flushList() { - let names = Set(list.map(opt => opt.option ? opt.option.name : "")); + let names = 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), list[0].scope); else - options.list(opt => Set.has(names, opt.name), + options.list(opt => names.has(opt.name), list[0].scope); list = []; } @@ -1279,12 +1283,12 @@ var Options = Module("options", { // Fill in the current values if we're removing if (opt.operator == "-" && isArray(opt.values)) { - let have = Set([i.text for (i in values(context.allItems.items))]); + let have = RealSet((i.text for (i in values(context.allItems.items)))); context = context.fork("current-values", 0); context.anchored = optcontext.anchored; context.maxItems = optcontext.maxItems; - context.filters.push(i => !Set.has(have, i.text)); + context.filters.push(i => !have.has(i.text)); modules.completion.optionValue(context, opt.name, opt.operator, null, function (context) { context.generate = () => option.value.map(o => [o, ""]); @@ -1313,7 +1317,7 @@ var Options = Module("options", { util.assert(scope == "g:" || scope == null, _("command.let.illegalVar", scope + name)); - util.assert(Set.has(globalVariables, name) || (expr && !op), + util.assert(hasOwnProperty(globalVariables, name) || (expr && !op), _("command.let.undefinedVar", fullName)); if (!expr) @@ -1411,7 +1415,7 @@ var Options = Module("options", { function (args) { for (let [, name] in args) { name = name.replace(/^g:/, ""); // throw away the scope prefix - if (!Set.has(dactyl._globalVariables, name)) { + if (!hasOwnProperty(dactyl._globalVariables, name)) { if (!args.bang) dactyl.echoerr(_("command.let.noSuch", name)); return; @@ -1497,7 +1501,7 @@ var Options = Module("options", { 0); return val && val.result; } - if (Set.has(opt.defaultValue, extra.key)) + if (hasOwnProperty(opt.defaultValue, extra.key)) return obj[extra.key]; } diff --git a/common/modules/sanitizer.jsm b/common/modules/sanitizer.jsm index 626f9e7e..057d6d5f 100644 --- a/common/modules/sanitizer.jsm +++ b/common/modules/sanitizer.jsm @@ -1,5 +1,5 @@ // Copyright (c) 2009 by Doug Kearns -// Copyright (c) 2009-2013 Kris Maglione +// Copyright (c) 2009-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -247,11 +247,11 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef if (!("value" in prop) || !callable(prop.value) && !(k in item)) Object.defineProperty(item, k, prop); - let names = Set([name].concat(params.contains || []).map(e => "clear-" + e)); + let names = RealSet([name].concat(params.contains || []).map(e => "clear-" + e)); if (params.action) storage.addObserver("sanitizer", function (key, event, arg) { - if (event in names) + if (names.has(event)) params.action.apply(params, arg); }, Class.objectGlobal(params.action)); @@ -618,7 +618,7 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef res && !/^!/.test(res), validator: function (values) values.length && - values.every(val => (val === "all" || Set.has(sanitizer.itemMap, val.replace(/^!/, "")))) + values.every(val => (val === "all" || hasOwnProperty(sanitizer.itemMap, val.replace(/^!/, "")))) }); options.add(["sanitizeshutdown", "ss"], @@ -636,10 +636,10 @@ var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakRef sanitizer.runAtShutdown = false; else { sanitizer.runAtShutdown = true; - let have = Set(value); + let have = RealSet(value); for (let item in values(sanitizer.itemMap)) prefs.set(item.shutdownPref, - Boolean(Set.has(have, item.name) ^ Set.has(have, "all"))); + Boolean(have.has(item.name) ^ have.has("all"))); } return value; } diff --git a/common/modules/services.jsm b/common/modules/services.jsm index 315f9518..1e26f69e 100644 --- a/common/modules/services.jsm +++ b/common/modules/services.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2008-2013 Kris Maglione +// Copyright (c) 2008-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -206,7 +206,7 @@ var Services = Module("Services", { * * @param {string} name The service's cache key. */ - has: function has(name) Set.has(this.services, name) && this.services[name].class in Cc && + has: function has(name) hasOwnProperty(this.services, name) && this.services[name].class in Cc && this.services[name].interfaces.every(iface => iface in Ci) }); diff --git a/common/modules/styles.jsm b/common/modules/styles.jsm index 6584a7ef..31756070 100644 --- a/common/modules/styles.jsm +++ b/common/modules/styles.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2008-2013 Kris Maglione +// Copyright (c) 2008-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -261,7 +261,7 @@ var Styles = Module("Styles", { update(services["dactyl:"].providers, { "style": function styleProvider(uri, path) { let id = parseInt(path); - if (Set.has(styles.allSheets, id)) + if (hasOwnProperty(styles.allSheets, id)) return ["text/css", styles.allSheets[id].fullCSS]; return null; } diff --git a/common/modules/template.jsm b/common/modules/template.jsm index 5b89f187..17c04cf3 100644 --- a/common/modules/template.jsm +++ b/common/modules/template.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2008-2013 Kris Maglione +// Copyright (c) 2008-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -106,7 +106,7 @@ var Template = Module("Template", { "click": function onClick(event) { event.preventDefault(); if (this.commandAllowed) { - if (Set.has(this.target.commands || {}, this.command)) + if (hasOwnProperty(this.target.commands || {}, this.command)) this.target.commands[this.command].call(this.target); else this.target.command(this.command); @@ -115,7 +115,7 @@ var Template = Module("Template", { }, get commandAllowed() { - if (Set.has(this.target.allowedCommands || {}, this.command)) + if (hasOwnProperty(this.target.allowedCommands || {}, this.command)) return this.target.allowedCommands[this.command]; if ("commandAllowed" in this.target) return this.target.commandAllowed(this.command); @@ -140,7 +140,7 @@ var Template = Module("Template", { let obj = params.eventTarget; let events = obj[this.getAttribute("events") || "events"]; - if (Set.has(events, "input")) + if (hasOwnProperty(events, "input")) events["dactyl-input"] = events["input"]; for (let [event, handler] in Iterator(events)) @@ -219,7 +219,7 @@ var Template = Module("Template", { else if (/^n_/.test(topic)) topic = topic.slice(2); - if (help.initialized && !Set.has(help.tags, topic)) + if (help.initialized && !hasOwnProperty(help.tags, topic)) return ["span", { highlight: type || ""}, text || token]; type = type || (/^'.*'$/.test(token) ? "HelpOpt" : @@ -241,7 +241,7 @@ var Template = Module("Template", { else if (/^n_/.test(topic)) topic = topic.slice(2); - if (help.initialized && !Set.has(help.tags, topic)) + if (help.initialized && !hasOwnProperty(help.tags, topic)) return token; let tag = (/^'.*'$/.test(token) ? "o" : diff --git a/common/modules/util.jsm b/common/modules/util.jsm index d6eaf80c..23a4088a 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 by Doug Kearns -// Copyright (c) 2008-2013 Kris Maglione +// Copyright (c) 2008-2014 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -138,7 +138,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), let cleanup = ["dactyl-cleanup-modules", "quit-application"]; function register(meth) { - for (let target in Set(cleanup.concat(Object.keys(obj.observers)))) + for (let target of RealSet(cleanup.concat(Object.keys(obj.observers)))) try { services.observer[meth](obj, target, true); } @@ -354,7 +354,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), : "", { elements: [], - seen: {}, + seen: RealSet(), valid: function valid(obj) this.elements.every(e => (!e.test || e.test(obj))) }); @@ -387,15 +387,15 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), } else { let [, flags, name] = /^((?:[a-z]-)*)(.*)/.exec(macro); - flags = Set(flags); + flags = RealSet(flags); let quote = util.identity; - if (flags.q) + if (flags.has("q")) quote = function quote(obj) typeof obj === "number" ? obj : String.quote(obj); - if (flags.e) + if (flags.has("e")) quote = function quote(obj) ""; - if (Set.has(defaults, name)) + if (hasOwnProperty(defaults, name)) stack.top.elements.push(quote(defaults[name])); else { let index = idx; @@ -403,7 +403,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), idx = Number(idx) - 1; stack.top.elements.push(update( obj => obj[name] != null && idx in obj[name] ? quote(obj[name][idx]) - : Set.has(obj, name) ? "" : unknown(full), + : hasOwnProperty(obj, name) ? "" : unknown(full), { test: function test(obj) obj[name] != null && idx in obj[name] && obj[name][idx] !== false @@ -413,7 +413,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), else { stack.top.elements.push(update( obj => obj[name] != null ? quote(obj[name]) - : Set.has(obj, name) ? "" : unknown(full), + : hasOwnProperty(obj, name) ? "" : unknown(full), { test: function test(obj) obj[name] != null && obj[name] !== false @@ -422,7 +422,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), } for (let elem in array.iterValues(stack)) - elem.seen[name] = true; + elem.seen.add(name); } } } @@ -757,7 +757,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), try { let xmlhttp = services.Xmlhttp(); - xmlhttp.mozBackgroundRequest = Set.has(params, "background") ? params.background : true; + xmlhttp.mozBackgroundRequest = hasOwnProperty(params, "background") ? params.background : true; let async = params.callback || params.onload || params.onerror; if (async) { @@ -1255,10 +1255,10 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), // Replace replacement . if (tokens) expr = String.replace(expr, /(\(?P)?<(\w+)>/g, - (m, n1, n2) => !n1 && Set.has(tokens, n2) ? tokens[n2].dactylSource - || tokens[n2].source - || tokens[n2] - : m); + (m, n1, n2) => !n1 && hasOwnProperty(tokens, n2) ? tokens[n2].dactylSource + || tokens[n2].source + || tokens[n2] + : m); // Strip comments and white space. if (/x/.test(flags))