This commit is contained in:
satyr 2010-04-13 09:19:14 +09:00
Родитель 6fff878f9b
Коммит 9a64cd2c32
3 изменённых файлов: 130 добавлений и 95 удалений

Просмотреть файл

@ -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;
}