зеркало из https://github.com/mozilla/ubiquity.git
Modularized command history.
This commit is contained in:
Родитель
6fff878f9b
Коммит
9a64cd2c32
|
@ -55,6 +55,7 @@ const BugReport = (
|
|||
const {prefs} = Utils;
|
||||
|
||||
Cu.import("resource://ubiquity/modules/setup.js");
|
||||
Cu.import("resource://ubiquity/modules/cmdhistory.js");
|
||||
|
||||
XML.prettyPrinting = XML.ignoreWhitespace = false;
|
||||
|
||||
|
@ -172,7 +173,7 @@ CmdUtils.CreateCommand({
|
|||
},
|
||||
});
|
||||
|
||||
(function toggleCommand(names, desc, nt, disabled, tmpl) {
|
||||
(function ToggleCommand(names, desc, nt, disabled, tmpl) {
|
||||
CmdUtils.CreateCommand({
|
||||
names: names,
|
||||
icon: "chrome://ubiquity/skin/icons/favicon.ico",
|
||||
|
@ -192,7 +193,7 @@ CmdUtils.CreateCommand({
|
|||
: this.description);
|
||||
}
|
||||
});
|
||||
return arguments.callee;
|
||||
return ToggleCommand;
|
||||
})
|
||||
(["disable command"],
|
||||
("Disables a Ubiquity command, so that it will no longer " +
|
||||
|
@ -206,37 +207,6 @@ CmdUtils.CreateCommand({
|
|||
false,
|
||||
_("Enables ${name}."));
|
||||
|
||||
var CmdHst = {
|
||||
PREF_BIN: "extensions.ubiquity.history.bin",
|
||||
PREF_MAX: "extensions.ubiquity.history.max",
|
||||
DEFAULT_MAX: 42,
|
||||
SEPARATOR: "\n",
|
||||
add: function CH_add(str) {
|
||||
if (!str) return this;
|
||||
var bin = this.get(), idx = bin.indexOf(str);
|
||||
if (~idx) bin.unshift(bin.splice(idx, 1)[0]);
|
||||
else {
|
||||
var max = prefs.getValue(this.PREF_MAX, this.DEFAULT_MAX);
|
||||
if (bin.unshift(str) > max) bin.length = max;
|
||||
}
|
||||
return this._save();
|
||||
},
|
||||
get: function CH_get() {
|
||||
if ("_bin" in this) return this._bin;
|
||||
var a = prefs.getValue(this.PREF_BIN, "").split(this.SEPARATOR);
|
||||
return this._bin = [h for each (h in a) if (h)];
|
||||
},
|
||||
set: function CH_set(arr) {
|
||||
var bin = this.get();
|
||||
bin.splice.apply(bin, [0, 1/0].concat(arr));
|
||||
return this._save();
|
||||
},
|
||||
_save: function CH__save() {
|
||||
prefs.setValue(this.PREF_BIN, this._bin.join(this.SEPARATOR));
|
||||
return this;
|
||||
},
|
||||
};
|
||||
|
||||
CmdUtils.CreateCommand({
|
||||
names: ["command history", "vita"],
|
||||
arguments: {"object filter": noun_arb_text},
|
||||
|
@ -246,25 +216,25 @@ CmdUtils.CreateCommand({
|
|||
<li>Use accesskey or click to reuse.</li>
|
||||
<li>Type to filter.</li>
|
||||
<li>Execute to delete all matched histories.</li>
|
||||
<li>Edit <a href="about:config"><code>{CmdHst.PREF_MAX}</code></a> to
|
||||
set max number of histories.</li></ul>),
|
||||
<li>Edit <a href="about:config"><code>{CommandHistory.PREF_MAX}</code></a
|
||||
> to set max number of histories.</li></ul>),
|
||||
author: {name: "satyr", email: "murky.satyr@gmail.com"},
|
||||
license: "MIT",
|
||||
icon: "chrome://ubiquity/skin/icons/favicon.ico",
|
||||
execute: function cmdh_execute({object: {text}}) {
|
||||
var bin = CmdHst.get();
|
||||
var bin = CommandHistory.get();
|
||||
if (!bin.length) return;
|
||||
if (text) {
|
||||
var rem = this._filter(bin, text, true);
|
||||
if (rem.length === bin.length) return;
|
||||
CmdHst.set(rem);
|
||||
CommandHistory.set(rem);
|
||||
this._say(_("Deleted matched histories. Click here to undo."),
|
||||
function cmdh__undo() { CmdHst.set(bin) });
|
||||
function cmdh__undo() { CommandHistory.set(bin) });
|
||||
}
|
||||
else this._say(_('Type "^" to delete all.'));
|
||||
},
|
||||
preview: function cmdh_preview(pb, args) {
|
||||
var his = this._filter(CmdHst.get(), args.object.text);
|
||||
var his = this._filter(CommandHistory.get(), args.object.text);
|
||||
if (!his.length) {
|
||||
pb.innerHTML = "<em>" + _("No histories match.") + "</em>" + this.help;
|
||||
return;
|
||||
|
@ -288,56 +258,6 @@ CmdUtils.CreateCommand({
|
|||
},
|
||||
});
|
||||
|
||||
function ubiquityLoad_commandHistory(U) {
|
||||
var cursor = -1, {textBox} = U;
|
||||
function go(num){
|
||||
var bin = CmdHst.get();
|
||||
if (cursor < 0 && textBox.value) {
|
||||
CmdHst.add(textBox.value);
|
||||
cursor = 0;
|
||||
}
|
||||
cursor -= num;
|
||||
if (cursor < -1 || bin.length <= cursor) cursor = -1;
|
||||
U.preview(bin[cursor] || "");
|
||||
}
|
||||
function halt(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
textBox.parentNode.addEventListener("keydown", function cmdh_onKey(ev) {
|
||||
if (!ev.ctrlKey || ev.altKey || ev.metaKey) return;
|
||||
switch (ev.keyCode) {
|
||||
case 38: case 40: // UP DOWN
|
||||
go(ev.keyCode - 39);
|
||||
return halt(ev);
|
||||
}
|
||||
if (ev.keyCode === KeyEvent.DOM_VK_TAB) {
|
||||
var text = Utils.trim(textBox.value);
|
||||
if (!text) return;
|
||||
var bin = CmdHst.get();
|
||||
if (ev.shiftKey) bin = bin.slice().reverse();
|
||||
var vi = bin.indexOf(text) + 1;
|
||||
if (vi) bin = bin.slice(vi);
|
||||
var keyEnd = textBox.selectionStart || text.length;
|
||||
var re = RegExp("^" + Utils.regexp.quote(text.slice(0, keyEnd)), "i");
|
||||
for each (var his in bin) if (re.test(his)) {
|
||||
U.preview(his);
|
||||
textBox.selectionStart = keyEnd;
|
||||
textBox.selectionEnd = textBox.textLength;
|
||||
break;
|
||||
}
|
||||
return halt(ev);
|
||||
}
|
||||
}, true);
|
||||
textBox.addEventListener("DOMMouseScroll", function cmdh_onWheel(ev) {
|
||||
go(ev.detail > 0 ? 1 : -1);
|
||||
}, false);
|
||||
textBox.addEventListener("blur", function cmdh_saveEntry() {
|
||||
CmdHst.add(textBox.value);
|
||||
cursor = -1;
|
||||
}, false);
|
||||
}
|
||||
|
||||
function startup_openUbiquityWelcomePage() {
|
||||
if (UbiquitySetup.isNewlyInstalledOrUpgraded)
|
||||
Utils.focusUrlInBrowser(Help);
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
|
||||
function Ubiquity(msgPanel, textBox, cmdManager) {
|
||||
Cu.import("resource://ubiquity/modules/utils.js", this);
|
||||
Cu.import("resource://ubiquity/modules/cmdhistory.js", this);
|
||||
|
||||
this.__msgPanel = msgPanel;
|
||||
this.__textBox = textBox;
|
||||
|
@ -67,6 +68,8 @@ function Ubiquity(msgPanel, textBox, cmdManager) {
|
|||
textBox.addEventListener("keydown", this, false);
|
||||
textBox.addEventListener("keypress", this, false);
|
||||
textBox.addEventListener("keyup", this, false);
|
||||
textBox.addEventListener("blur", this, false);
|
||||
textBox.addEventListener("DOMMouseScroll", this, false);
|
||||
|
||||
msgPanel.addEventListener("popupshowing", this, false);
|
||||
msgPanel.addEventListener("popupshown", this, false);
|
||||
|
@ -165,18 +168,25 @@ Ubiquity.prototype = {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (ctrlKey || altKey || event.metaKey) return;
|
||||
if (altKey || event.metaKey) return;
|
||||
|
||||
if (keyCode === this.__KEYCODE_COMPLETE) {
|
||||
var {completionText} = this.__cmdManager.hilitedSuggestion || 0;
|
||||
if (completionText) this.__textBox.value = completionText;
|
||||
if (ctrlKey) this.CommandHistory.complete(this, event.shiftKey);
|
||||
else {
|
||||
let {completionText} = this.__cmdManager.hilitedSuggestion || 0;
|
||||
if (completionText) this.__textBox.value = completionText;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
var move = this.__KEYMAP_MOVE_INDICATION[keyCode];
|
||||
if (move) {
|
||||
this.__cmdManager[move](this.__makeContext());
|
||||
if (ctrlKey) this.CommandHistory.go(this, keyCode - 39);
|
||||
else this.__cmdManager[move](this.__makeContext());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ctrlKey) return;
|
||||
|
||||
var rate = this.__KEYMAP_SCROLL_RATE[keyCode];
|
||||
if (rate) {
|
||||
let [x, y] = event.shiftKey ? [rate, 0] : [0, rate];
|
||||
|
@ -185,6 +195,14 @@ Ubiquity.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
__onblur: function U__onBlur() {
|
||||
this.CommandHistory.add(this.__textBox.value);
|
||||
},
|
||||
|
||||
__onDOMMouseScroll: function U__onMouseScroll(event) {
|
||||
this.CommandHistory.go(this, event.detail > 0 ? 1 : -1);
|
||||
},
|
||||
|
||||
__delayedProcessInput: function U__delayedProcessInput(self, context) {
|
||||
var input = self.__textBox.value;
|
||||
if (input.length > self.inputLimit ||
|
||||
|
@ -229,6 +247,8 @@ Ubiquity.prototype = {
|
|||
var unfocused = this.__focusedWindow;
|
||||
if (unfocused) unfocused.focus();
|
||||
this.__focusedWindow = this.__focusedElement = null;
|
||||
|
||||
gBrowser.mTabBox.handleCtrlTab = this.__handleCtrlTab;
|
||||
},
|
||||
|
||||
__onpopupshowing: function U__onShowing() {
|
||||
|
@ -238,8 +258,14 @@ Ubiquity.prototype = {
|
|||
},
|
||||
|
||||
__onpopupshown: function U__onShown() {
|
||||
this.__textBox.focus();
|
||||
this.__textBox.select();
|
||||
// prevent the tabbox from capturing our ctrl+tab
|
||||
var tabox = gBrowser.mTabBox;
|
||||
this.__handleCtrlTab = tabox.handleCtrlTab;
|
||||
tabox.handleCtrlTab = false;
|
||||
|
||||
var {__textBox} = this;
|
||||
__textBox.focus();
|
||||
__textBox.select();
|
||||
},
|
||||
|
||||
__onclick: function U__onClick(event) {
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Ubiquity.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Satoshi Murakami <murky.satyr@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
Components.utils.import("resource://ubiquity/modules/utils.js");
|
||||
|
||||
const EXPORTED_SYMBOLS = ["CommandHistory"];
|
||||
const PREF_BIN = "extensions.ubiquity.history.bin";
|
||||
const PREF_MAX = "extensions.ubiquity.history.max";
|
||||
const SEPARATOR = "\n";
|
||||
|
||||
var CommandHistory = this, cursor = -1, _bin = null;
|
||||
|
||||
function get() _bin || (_bin = Utils.prefs.get(PREF_BIN).split(SEPARATOR));
|
||||
function set(arr) {
|
||||
_bin = arr;
|
||||
return save();
|
||||
}
|
||||
function add(txt) {
|
||||
if (!(txt = txt.trim())) return this;
|
||||
var bin = get(), idx = bin.indexOf(txt);
|
||||
if (~idx) bin.unshift(bin.splice(idx, 1)[0]);
|
||||
else {
|
||||
let max = Utils.prefs.get(PREF_MAX);
|
||||
if (bin.unshift(txt) > max) bin.length = max;
|
||||
}
|
||||
return save();
|
||||
}
|
||||
function save() {
|
||||
Utils.prefs.set(PREF_BIN, _bin.join(SEPARATOR));
|
||||
return this;
|
||||
}
|
||||
function go(U, num) {
|
||||
var {textBox} = U = U || Utils.currentChromeWindow.gUbiquity;
|
||||
var bin = get();
|
||||
if (cursor < 0 && textBox.value) {
|
||||
add(textBox.value);
|
||||
cursor = 0;
|
||||
}
|
||||
cursor -= num;
|
||||
if (cursor < -1 || bin.length <= cursor) cursor = -1;
|
||||
U.preview(bin[cursor] || "");
|
||||
return this;
|
||||
}
|
||||
function complete(U, rev) {
|
||||
var {textBox} = U = U || Utils.currentChromeWindow.gUbiquity;
|
||||
var {value: txt, selectionStart: pos} = textBox, bin = get();
|
||||
if (rev) bin = bin.slice().reverse();
|
||||
pos -= txt.length - (txt = txt.trimLeft()).length;
|
||||
var key = txt.slice(0, pos), re = RegExp("^" + Utils.regexp.quote(key), "i");
|
||||
for (let h, i = bin.indexOf(txt) + 1; h = bin[i++];) if (re.test(h)) {
|
||||
U.preview(h);
|
||||
textBox.setSelectionRange(key.length, textBox.textLength);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
Загрузка…
Ссылка в новой задаче