diff --git a/common/content/completion.js b/common/content/completion.js index 7c7f9b5e..5c5d72e9 100644 --- a/common/content/completion.js +++ b/common/content/completion.js @@ -171,6 +171,7 @@ const CompletionContext = Class("CompletionContext", { * cache data between calls. */ this.cache = {}; + this._cache = {}; /** * @private * @property {Object} A cache for return values of {@link #generate}. @@ -352,7 +353,7 @@ const CompletionContext = Class("CompletionContext", { * must be regenerated. May be set to true to invalidate the current * completions. */ - get regenerate() this._generate && (!this.completions || !this.itemCache[this.key] || this.cache.offset != this.offset), + get regenerate() this._generate && (!this.completions || !this.itemCache[this.key] || this._cache.offset != this.offset), set regenerate(val) { if (val) delete this.itemCache[this.key]; }, /** @@ -372,12 +373,12 @@ const CompletionContext = Class("CompletionContext", { * longer valid. */ generateCompletions: function generateCompletions() { - if (this.offset != this.cache.offset || this.lastActivated != this.top.runCount) { + if (this.offset != this._cache.offset || this.lastActivated != this.top.runCount) { this.itemCache = {}; - this.cache.offset = this.offset; + this._cache.offset = this.offset; this.lastActivated = this.top.runCount; } - if (!this.itemCache[this.key]) + if (!this.itemCache[this.key]) { try { let res = this._generate(); if (res != null) @@ -387,6 +388,7 @@ const CompletionContext = Class("CompletionContext", { dactyl.reportError(e); this.message = "Error: " + e; } + } // XXX this.noUpdate = true; this.completions = this.itemCache[this.key]; @@ -426,9 +428,9 @@ const CompletionContext = Class("CompletionContext", { let items = this.completions; // Check for cache miss - if (this.cache.completions !== this.completions) { - this.cache.completions = this.completions; - this.cache.constructed = null; + if (this._cache.completions !== this.completions) { + this._cache.completions = this.completions; + this._cache.constructed = null; this.cache.filtered = null; } @@ -464,13 +466,13 @@ const CompletionContext = Class("CompletionContext", { try { // Item prototypes - if (!this.cache.constructed) { + if (!this._cache.constructed) { let proto = this.itemPrototype; - this.cache.constructed = items.map(function (item) ({ __proto__: proto, item: item })); + this._cache.constructed = items.map(function (item) ({ __proto__: proto, item: item })); } // Filters - let filtered = this.filterFunc(this.cache.constructed); + let filtered = this.filterFunc(this._cache.constructed); if (this.maxItems) filtered = filtered.slice(0, this.maxItems); @@ -660,6 +662,27 @@ const CompletionContext = Class("CompletionContext", { return context; }, + split: function split(name, obj, fn) { + const self = this; + + let context = this.fork(name); + function alias(prop) { + context.__defineGetter__(prop, function () self[prop]); + context.__defineSetter__(prop, function (val) self[prop] = val); + } + alias("_cache"); + alias("_completions"); + alias("_generate"); + alias("_regenerate"); + alias("itemCache"); + alias("lastActivated"); + context.hasItems = true; + this.hasItems = false; + if (fn) + return fn.apply(obj || this, [context].concat(Array.slice(arguments, split.length))); + return context; + }, + /** * Highlights text in the nsIEditor associated with this completion * context. *length* characters are highlighted from the position diff --git a/common/modules/styles.jsm b/common/modules/styles.jsm index acd3a64d..525bcec2 100644 --- a/common/modules/styles.jsm +++ b/common/modules/styles.jsm @@ -291,7 +291,9 @@ const Styles = Module("Styles", { * @returns {nsIURI -> boolean} */ matchFilter: function (filter) { - if (/[*]$/.test(filter)) { + if (filter === "*") + function test(uri) true; + else if (/[*]$/.test(filter)) { let re = RegExp("^" + util.regexp.escape(filter.substr(0, filter.length - 1))); function test(uri) re.test(uri.spec); } @@ -441,63 +443,64 @@ const Styles = Module("Styles", { ].forEach(function (cmd) { function splitContext(context, generate) { - let uris = util.visibleURIs(window.content); - if (!generate) { - context.keys.active = function (sheet) sheet.sites.some(function (site) uris.some(Styles.matchFilter(site))); - context.keys.description = function (sheet) <>{sheet.formatSites(uris)}: {sheet.css.replace("\n", "\\n")}; - if (cmd.filter) - context.filters.push(function ({ item }) cmd.filter(item)); - } - for (let item in Iterator({ Active: true, Inactive: false })) { let [name, active] = item; - context.fork(name, 0, null, function (context) { + context.split(name, null, function (context) { context.title[0] = name + " Sheets"; - context.generate = generate || function () styles.userSheets; context.filters.push(function (item) item.active == active); }); } } + function sheets(context) { + let uris = util.visibleURIs(window.content); + context.compare = modules.CompletionContext.Sort.number; + context.generate = function () styles.userSheets; + context.keys.active = function (sheet) sheet.sites.some(function (site) uris.some(Styles.matchFilter(site))), + context.keys.description = function (sheet) <>{sheet.formatSites(uris)}: {sheet.css.replace("\n", "\\n")} + if (cmd.filter) + context.filters.push(function ({ item }) cmd.filter(item)); + splitContext(context); + } commands.add(cmd.name, cmd.desc, function (args) { styles.findSheets(false, args["-name"], args[0], args.literalArg, args["-index"]) .forEach(cmd.action); - }, - { - completer: function (context) { - let uris = util.visibleURIs(window.content); - context.keys = { - text: util.identity, description: util.identity, - active: function (site) uris.some(Styles.matchFilter(site)) - }; - if (cmd.filter) - context.filters.push(function ({ item }) - styles.userSheets.some(function (sheet) sheet.sites.indexOf(item) >= 0 && cmd.filter(sheet))); - splitContext(context, function () styles.sites); - }, - literal: 1, - options: [ - { - names: ["-index", "-i"], - type: modules.CommandOption.INT, - completer: function (context) { - context.compare = modules.CompletionContext.Sort.number; - context.keys.text = function (sheet) styles.userSheets.indexOf(sheet); - splitContext(context); - }, - }, { - names: ["-name", "-n"], - type: modules.CommandOption.STRING, - completer: function (context) { - context.compare = modules.CompletionContext.Sort.number; - context.keys.text = function (sheet) sheet.name; - context.filters.push(function ({ item }) item.name); - splitContext(context); + }, { + completer: function (context) { + let uris = util.visibleURIs(window.content); + context.generate = function () styles.sites; + context.keys.text = util.identity; + context.keys.description = function (site) this.sheets.length + " sheet" + (this.sheets.length == 1 ? "" : "s") + ": " + + array.compact(this.sheets.map(function (s) s.name)).join(", ") + context.keys.sheets = function (site) styles.userSheets.filter(function (s) s.sites.indexOf(site) >= 0); + context.keys.active = function (site) uris.some(Styles.matchFilter(site)); + + if (cmd.filter) + context.filters.push(function ({ sheets }) sheets.some(cmd.filter)); + + splitContext(context); + }, + literal: 1, + options: [ + { + names: ["-index", "-i"], + type: modules.CommandOption.INT, + completer: function (context) { + context.keys.text = function (sheet) styles.userSheets.indexOf(sheet); + sheets(context); + }, + }, { + names: ["-name", "-n"], + type: modules.CommandOption.STRING, + completer: function (context) { + context.keys.text = function (sheet) sheet.name; + context.filters.push(function ({ item }) item.name); + sheets(context); + } } - } - ] - }); + ] + }); }); }, completion: function (dactyl, modules, window) {