KeySnail は Emacs ライクなキーバインドなものにしてくれ、さらに keyconfig のように独自コードを割り当てることができる拡張です。
KeySnail :: Add-ons for Firefox
タイトルと URL をコピーするものはあるのですが、大体どこかひとつのテンプレートにしか対応していません。色々なサービスを使っていると不便なことが多いので、テンプレートを選べるスクリプトをつくりました。
テンプレートは少ないので、個人個人利用しているテンプレートを templates 変数に追加、削除するとよいのではと思います。割り当てたキーバインドを実行するとクリップボードにコピーするフォーマット一覧が出力されるので、後は grep して対象のフォーマットのところで Enter キーを押すだけです。
よく利用するテンプレートを一番最初に持ってくると便利かもしれません。
key.setGlobalKey(['C-c', 't'], function () {
var templates = {
tdiary: "[[{0}|{1}]]",
text:"{0}\n{1}",
hatena: "[{1}:title={0}]",
mt: "[{0}]({1})",
pukiwiki: "[[{0}:{1}]]",
link: "<a href=\"{1}\">{0}</a>"
};
function getLineSeprator() {
var sysInfo = Cc['@mozilla.org/system-info;1'].getService(Ci.nsIPropertyBag2);
var platform = sysInfo.getProperty("name");
if (platform.indexOf("Windows") >= 0) {
return "\r\n";
} else {
return "\n";
}
}
var regexp = /\{(\d)\}/g;
function format() {
var args = Array.prototype.slice.apply(arguments);
var format = args.shift();
return format && format.replace(regexp, function () {
return args[arguments[1]] || "";
});
}
var promptList = [];
for (var key in templates) {
promptList.push([key, templates[key].replace(/\n/g, '\\n')]);
}
var title = window.content.document.title;
var url = window.content.location.href;
prompt.selector({
message: "copy from: ",
flags: [0, 0],
collection: promptList,
header: ["key", "format"],
callback: function (index) {
if (index < 0) {
return;
}
var key = promptList[index][0];
var template = templates[key].replace(/\n/g, getLineSeprator());
var text = format(template, title, url);
Cc['@mozilla.org/widget/clipboardhelper;1'].getService(Ci.nsIClipboardHelper).copyString(text);
}
});
}, 'URL とタイトルをコピー');
これまで Ubiquity で入力してフォーマットを変換するようにしていたのですが、 KeySnail の selector を使うと一覧から選択できることによって入力ミスがなくなりました。とても便利なので Ubiquity がいらなくなっちゃいました。
Emacs ユーザーでない方もキーバインドをカスタマイズすると、なかなか快適な Firefox 生活を送れるのではと思います。
実行した時点での URL とタイトルから目的のタブを検索するスクリプトです。
検索して選択するとフォーカスが移動します。
key.setGlobalKey(['C-c', 'l'], function () {
var promptList = [];
var w = Application.activeWindow;
var tabs = Array.apply(null, w.tabs);
for each (var tab in tabs) {
promptList.push([tab.document.title, tab.uri.spec]);
}
prompt.selector({
message: "select tab: ",
flags: [0, 0],
collection: promptList,
header: ["title", "url"],
callback: function (index) {
if (index < 0 || tabs.length < index) {
return;
}
tabs[index].focus();
}
});
}, 'タブを検索する');
ダイアログ上にある jQuery のボタンを操作したい場合は下みたくすればいいみたいです。
box.dialog({
buttons: {
'OK': function() {
$(this).dialog('close');
}
}
});
var input = $('.input');
input.keypress(function(e) {
if (e.which == 13) {
box.dialog('option', 'buttons')['OK'].apply(box);
}
});
モバイルプログラムやったことがなくて、ご飯食べられなくなるんじゃないかと不安になってきました。 iPhone か Android どっちかやろうと思って Android にしました。 Android 持っていることなので。
つくりたいアプリは決まっているので、少しずつやっていきます。ある程度動くものができたら公開したいと思います。趣味なので気ままにやりますけれど。
友人の方におすすめの Android 本を教えてもらったのがこれです。さらっと検索した感じ Android ってあまり日本語の情報がない気がしています。で、ぱらぱらとしかまだみられていませんが、ほんと基礎から応用まで学べそうでよさげそうです。何より開発環境が Mac というのが壊れている感じがしていいです。
それと Android で最低限の入力ですむ家計簿ソフト欲しいです。
$(document).click(function(e) {
var target = $(e.target);
if (target.is('#target') || target.parents().is('#target')) {
console.log('click');
}
});
parents と is の組み合わせが出てきませんでした。
jQuery の良さは複数要素を前提に処理が行われることだと思います。
ターミナルから SSH 接続するときに、毎回公開鍵のパスワードを入力するのが面倒です。
ターミナルからの SSH 認証は Leopard についている KeyChain からスルーされてしまうので、 MacPorts から keychain をインストールします。
$ sudo port install keychain $ rehash $ keychain ~/.ssh/id_rsa
ここで公開鍵のパスワードを入力すると、そのセッションでパスワードを聞かれなくなります。
というのを今までやっていたのですが、毎回入力するのが面倒です。
keychain ~/.ssh/id_rsa . $HOME/.keychain/$HOST-sh
こうしておくと screen で新しい仮想端末を開いても入力しなくてよくなりました。便利。
結論から言うと AbstractPlugin を継承したもので行うというのが今のところよいと考えています。
Servlet ではもっとも王道なやり方であろうフィルターは、ある URL 以下を一括で処理が行えることがメリットだと感じています。複数あれば URL をそれぞれ指定する必要がありますが Servlet 2.5 なら url-pattern も複数登録でき負担は減りそうです。
欠点としては公開用と非公開用ふたつの URL を別々にする必要があります。ある URL 以下の特定のものだけ認証をかけたくない場合つらいです。認証フィルターで URL をみて除外するコードをかくことになりそうです。
フィルターはアプリケーションが認証前提、またはある URL 以下をごっそり認証させたい場合はよいと思いますが、 URL が冗長になってしまい融通が利かないのが個人的につらいところです。
一方 Cubby は Plugin 機構を提供していてカスタマイズできます。 AbstractPlugin を継承してつくるのですが、 Plugin ではルーティングが決まったあとのアクションクラスに対して処理が行えます。認証用のアノテーションをつくってアクションのメソッドとクラスにつけられるようにしておくと、ある URL 以下の特定のパスにだけ認証をかけるといったことにも柔軟に対応ができます。
欠点はアクションの初期化直後に処理を行うので、その前のフィルターなどで認証情報を利用する場合は別途処理を書くことになります。また Action#initialize を使用している場合も、先にこちらが呼ばれますので注意が必要です。
すごく大ざっぱですが、認証処理を行うときの Action の流れは以下のようになると思います。
じゃあ Plugin ってどうつくるの?というのは [cubby-user:182] Re: Action#initialize への Interceptor 適用 に書かれています。 /src/main/resources など、クラスパスが通っている直下に /resources/META-INF/services/org.seasar.cubby.plugin.Plugin というファイルを作成後、一行おきに作成した Plugin クラス名を記述すればよいです。
net.pshared.example.plugin.AuthPlugin
package net.pshared.example.plugin;
public class AuthPlugin extends AbstractPlugin {
/**
* {@inheritDoc}
*/
@Override
public ActionResult invokeAction(ActionInvocation invocation) throws Exception {
ActionContext actionContext = invocation.getActionContext();
Class<?> actionClass = actionContext.getActionClass();
Method actionMethod = actionContext.getActionMethod();
if (認証対象処理) { // 対象のアノテーションやクラスであるか
if (認証検証) {
return new Redirect(Login.class);
}
}
return super.invokeAction(invocation);
}
}
ActionResult を返す仕組みなので認証エラー時に Redirect クラスを new します。 Class で指定できるのでリファクタリングに強いです。メソッド名もできるといいのですが、 GET のデフォルトのメソッド名を index にしておくと楽になります。
そんなわけで Cubby では Filter はごっそりかける場合、そうでない認証は Plugin でカスタマイズするのがよさげなのかなと思いました。