diff --git a/common/content/buffer.js b/common/content/buffer.js index 4ee88ba2..c06017b1 100644 --- a/common/content/buffer.js +++ b/common/content/buffer.js @@ -1200,7 +1200,8 @@ var Buffer = Module("buffer", { events.dispatch(elem, events.create(elem.ownerDocument, "change", {})); }, { completer: function (context) completion.file(context), - default: elem.value + default: elem.value, + history: "file" }); } }, { diff --git a/common/content/commandline.js b/common/content/commandline.js index 80bed94b..5c9ce77a 100644 --- a/common/content/commandline.js +++ b/common/content/commandline.js @@ -310,8 +310,16 @@ var CommandLine = Module("commandline", { this._callbacks = {}; - storage.newArray("history-search", { store: true, privateData: true }); - storage.newArray("history-command", { store: true, privateData: true }); + this._store = storage.newMap("command-history", { store: true, privateData: true }); + + for (let name in values(["command", "search"])) + if (storage.exists("history-" + name)) { + let ary = storage.newArray("history-" + name, { store: true, privateData: true }); + + this._store.set(name, [v for ([k, v] in ary)]); + ary.remove(); + } + this._store.changed(); this._messageHistory = { //{{{ _messages: [], @@ -581,6 +589,7 @@ var CommandLine = Module("commandline", { modes.push(modes.COMMAND_LINE, this.currentExtendedMode, { onEvent: this.closure.onEvent, + history: (extendedMode || {}).params.history, leave: function (params) { if (params.pop) commandline.leave(); @@ -595,13 +604,7 @@ var CommandLine = Module("commandline", { this.widgets.prompt = prompt; this.widgets.command = cmd || ""; - let hist = // Hack: - extendedMode == modes.EX ? "command" : - extendedMode & (modes.FIND_FORWARD | modes.FIND_BACKWARD) ? "search" : null; - - if (hist) - this._history = CommandLine.History(this.widgets.active.command.inputField, hist); - this._completions = CommandLine.Completions(this.widgets.active.command.inputField); + this.enter(); // open the completion list automatically if wanted if (cmd.length) { @@ -610,6 +613,12 @@ var CommandLine = Module("commandline", { } }, + enter: function enter() { + if (modes.getStack(0).params.history) + this._history = CommandLine.History(this.widgets.active.command.inputField, modes.getStack(0).params.history); + this._completions = CommandLine.Completions(this.widgets.active.command.inputField); + }, + /** * Called when leaving a command-line mode. */ @@ -873,7 +882,7 @@ var CommandLine = Module("commandline", { this.widgets.command = extra.default || ""; this.widgets.active.commandline.collapsed = false; - this._completions = CommandLine.Completions(this.widgets.active.command.inputField); + this.enter(); }, readHeredoc: function (end) { @@ -1202,9 +1211,10 @@ var CommandLine = Module("commandline", { init: function (inputField, mode) { this.mode = mode; this.input = inputField; - this.store = storage["history-" + mode]; this.reset(); }, + get store() commandline._store.get(this.mode, []), + set store(ary) { commandline._store.set(this.mode, ary); }, /** * Reset the history index to the first entry. */ @@ -1221,14 +1231,14 @@ var CommandLine = Module("commandline", { let str = this.input.value; if (/^\s*$/.test(str)) return; - this.store.mutate("filter", function (line) (line.value || line) != str); + this.store = this.store.filter(function (line) (line.value || line) != str); try { this.store.push({ value: str, timestamp: Date.now()*1000, privateData: this.checkPrivate(str) }); } catch (e) { dactyl.reportError(e); } - this.store.truncate(options["history"], true); + this.store = this.store.slice(-options["history"]); }, /** * @property {function} Returns whether a data item should be @@ -1286,7 +1296,7 @@ var CommandLine = Module("commandline", { break; } - let hist = this.store.get(this.index); + let hist = this.store[this.index]; // user pressed DOWN when there is no newer history item if (!hist) hist = this.original; @@ -1813,17 +1823,24 @@ var CommandLine = Module("commandline", { description: "Command-line and search history", persistent: true, action: function (timespan, host) { - if (!host) - storage["history-search"].mutate("filter", function (item) !timespan.contains(item.timestamp)); - storage["history-command"].mutate("filter", function (item) - !(timespan.contains(item.timestamp) && (!host || commands.hasDomain(item.value, host)))); + let store = commandline._store; + for (let [k, v] in store) { + if (k == "command") + store.set(k, v.filter(function (item) + !(timespan.contains(item.timestamp) && (!host || commands.hasDomain(item.value, host))))); + else if (!host) + store.set(k, v.filter(function (item) !timespan.contains(item.timestamp))); + } } }); // Delete history-like items from the commandline and messages on history purge sanitizer.addItem("history", { action: function (timespan, host) { - storage["history-command"].mutate("filter", function (item) - !(timespan.contains(item.timestamp) && (host ? commands.hasDomain(item.value, host) : item.privateData))); + commandline._store.set("command", + commandline._store.get("command", []).filter(function (item) + !(timespan.contains(item.timestamp) && (host ? commands.hasDomain(item.value, host) + : item.privateData)))); + commandline._messageHistory.filter(function (item) !timespan.contains(item.timestamp * 1000) || !item.domains && !item.privateData || host && (!item.domains || !item.domains.some(function (d) util.isSubdomain(d, host)))); diff --git a/common/content/modes.js b/common/content/modes.js index 6fe1b111..c7b31a82 100644 --- a/common/content/modes.js +++ b/common/content/modes.js @@ -125,7 +125,7 @@ var Modes = Module("modes", { extended: true, description: "Ex command mode, active when the command line is open for Ex commands", input: true - }); + }, { history: "command" }); this.addMode("HINTS", { extended: true, description: "Active when selecting elements in QuickHint or ExtendedHint mode", diff --git a/common/modules/finder.jsm b/common/modules/finder.jsm index b7040770..a4fa3443 100644 --- a/common/modules/finder.jsm +++ b/common/modules/finder.jsm @@ -165,11 +165,11 @@ var RangeFinder = Module("rangefinder", { modes.addMode("FIND_FORWARD", { extended: true, description: "Forward Find mode, active when typing search input" - }); + }, { history: "search" }); modes.addMode("FIND_BACKWARD", { extended: true, description: "Backward Find mode, active when typing search input" - }); + }, { history: "search" }); }, commandline: function (dactyl, modules, window) { const { commandline, modes, rangefinder } = modules; diff --git a/common/modules/storage.jsm b/common/modules/storage.jsm index da2e97a6..220e284d 100644 --- a/common/modules/storage.jsm +++ b/common/modules/storage.jsm @@ -55,7 +55,15 @@ var StoreBase = Class("StoreBase", { this.fireEvent("change", null); }, + remove: function remove() { + delete storage.keys[this.name]; + delete storage[this.name]; + storage.infoPath.child(this.name).remove(false); + }, + save: function () { saveData(this); }, + + __iterator__: function () Iterator(this._object) }); var ArrayStore = Class("ArrayStore", StoreBase, { @@ -99,9 +107,7 @@ var ArrayStore = Class("ArrayStore", StoreBase, { this.fireEvent("change", null); }, - get: function get(index) index >= 0 ? this._object[index] : this._object[this._object.length + index], - - __iterator__: function () Iterator(this._object), + get: function get(index) index >= 0 ? this._object[index] : this._object[this._object.length + index] }); var ObjectStore = Class("ObjectStore", StoreBase, { @@ -135,9 +141,7 @@ var ObjectStore = Class("ObjectStore", StoreBase, { else if (orig != val) this.fireEvent("change", key); return val; - }, - - __iterator__: function () Iterator(this._object), + } }); var Storage = Module("Storage", { @@ -159,6 +163,8 @@ var Storage = Module("Storage", { this.observers = {}; }, + exists: function exists(name) this.infoPath.child(name).exists(), + newObject: function newObject(key, constructor, params) { if (params == null || !isObject(params)) throw Error("Invalid argument type"); diff --git a/common/skin/dactyl.css b/common/skin/dactyl.css index 6e611313..116df39b 100644 --- a/common/skin/dactyl.css +++ b/common/skin/dactyl.css @@ -16,6 +16,10 @@ z-index: 50000; position: absolute !important; } +input[type=file][dactyl|highlight~=HintActive], +input[type=file][dactyl|highlight~=HintElem] { + opacity: 1 !important; +} @-moz-document url-prefix(dactyl:) {