Firefoxの最近のブログ記事

最近Firefoxの機能拡張で、vim風な操作でFirefoxを操ることができるvimperatorを使い始めました。

で、vimperatorのプラグインをいろいろ入れて楽しんでるのですが、Tomblooをvimperatorから使うのにtombloo.jsってのがあってそれを使ってたのですが、LDRからは使えないっぽかったのでLDRから使えるようにしてみました。(もしかしたら他に同じことできるものがあるかも。もしあったら教えてください><)

tombloo.jsはCodeReposにあるので直接変更しちゃおうかとも思ったのですがブランチとか切りづらかったので、ちょっと長いですがここに貼っておきます。

使い方はLDRでフィードを読んでいる時に「:tomblooReader」と打てば候補が出てくるので「Link\ -\ LDR」を選べばアクティブはエントリがクリップできます。ちなみに「:tomblooReader!」でやればTomblooのウィンドウも出せます。

JSは得意ではないので微妙なところがあるかも。
もしあったら修正をお願いします。

let PLUGIN_INFO =
<VimperatorPlugin>
<name>{NAME}</name>
<description>Tombloo integrate plugin</description>
<description lang="ja">Tombloo 統合プラグイン</description>
<author>Trapezoid</author>
<version>0.1e</version>
<minVersion>2.0pre</minVersion>
<maxVersion>2.0pre</maxVersion>
<updateURL>http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk/tombloo.js</updateURL>
<detail><![CDATA[

== EX-COMMANDS ==

:tombloo arg:
    post by Tombloo (don't use prompt)

:tombloo! arg:
    post by Tombloo (use prompt)

:tomblooAction arg:
    execute Tombloo's action in tool menu

:tomblooReader arg:
    post by Tombloo on LDR (don't use prompt)

:tomblooReader! arg:
    post by Tombloo on LDR (use prompt)

]]></detail>
<detail lang="ja"><![CDATA[
== EX-COMMANDS ==

:tombloo arg:
    Tombloo を使って投稿します ( ダイアログは出てきません )

:tombloo! arg:
    Tombloo を使って投稿します ( ダイアログが出てきます )

:tomblooAction arg:
    ツールバーから選択できる Tombloo のメニューを実行します

:tomblooReader arg:
    LDR で Tombloo を使って投稿します ( ダイアログは出てきません )

:tomblooReader! arg:
    LDR で Tombloo を使って投稿します ( ダイアログが出てきます )

]]></detail>
</VimperatorPlugin>;

(function () {

// ts: "T"ombloo "S"ervice
let tomblooService;
try { tomblooService = getTombloo(); }
catch (e) {
    liberator.log(e.message, 0);
    return;
}

with (tomblooService) {

commands.addUserCommand(
    ['tomblooAction'],
    'Execute Tombloo actions',
    function (arg) {
        let f = Tombloo.Service.actions[arg.string];
        (f instanceof Function)
            ? f.execute()
            : liberator.echoerr(arg.string + ' is not Tombloo Action.');
    },
    {
        completer: function (context) {
            context.title = ['Tombloo Actions'];

            let names = Tombloo.Service.actions.names;
            let candidates = [[n, n] for([, n] in Iterator(names))];
            context.completions = candidates.filter(
                function ($_) this.test($_[0]),
                new RegExp(context.filter, 'i')
            );
        },
    }
);

commands.addUserCommand(
    ['tombloo'],
    'Post by Tombloo',
    function (args, special) {
        //let f = Tombloo.Service.extractors[args.string];
        let arg = args.string.replace(/\\(?=\u0020)/g, '');
        liberator.log(args.string, 0);
        liberator.log(arg, 0);

        let f = Tombloo.Service.extractors[arg];
        (typeof f === 'object')
            ? Tombloo.Service.share(getContext(), f, special)
            : liberator.echoerr(args.string + ' is not Tombloo command');
    },
    {
        bang: true,
        completer: function (context) {
            context.title = ['Tombloo'];

            let extensions = Tombloo.Service.check(getContext());
            let candidates = [[e.name, e.name] for ([, e] in Iterator(extensions))];
            context.completions = candidates.filter(
                function($_) this.test($_[0]),
                new RegExp(context.filter, 'i')
            );
        }
    }
);

commands.addUserCommand(
    ['tomblooReader'],
    'Post by Tombloo on LDR',
    function (args, special) {
        let win = content.window.wrappedJSObject;
        let item;
        try {
            item = win.get_active_item(true);
        } catch(e) {
            liberator.echoerr('Use only on LDR');
            return;
        }
        let target = item.element;
        let ctx = getContextOnLDR(target);
        let arg = args.string.replace(/\\(?=\u0020)/g, '');
        liberator.log(args.string, 0);
        liberator.log(arg, 0);

        let f = Tombloo.Service.extractors[arg];
        (typeof f === 'object')
            ? Tombloo.Service.share(ctx, f, special)
            : liberator.echoerr(args.string + ' is not Tombloo command');
    },
    {
        bang: true,
        completer: function (context) {
            context.title = ['TomblooReader'];

            let win = content.window.wrappedJSObject;
            try {
                item = win.get_active_item(true);
            } catch(e) {
                liberator.echoerr('Use only on LDR');
                return;
            }
            let target = item.element;
            let ctx = getContextOnLDR(target);
            let extensions = Tombloo.Service.check(ctx);
            let candidates = [[e.name, e.name] for ([, e] in Iterator(extensions))];
            context.completions = candidates.filter(
                function($_) this.test($_[0]),
                new RegExp(context.filter, 'i')
            );
        }
    }
);

} // with (tomblooService)

// helper ---
function getTombloo() {
    const serviceId = '@brasil.to/tombloo-service;1';

    if (!Cc[serviceId])
        throw new Error('Tombloo is not found. install from http://github.com/to/tombloo/wikis');

    return Cc[serviceId].getService().wrappedJSObject;
}

function getContext() {
    const doc = content.window.document;
    const win = content.window.wrappedJSObject;
    return implant(
        implant(
            {
                document:   doc,
                window:     win,
                title:      doc.title.toString() || '',
                selection:  win.getSelection().toString(),
                target:     doc,
                //event     : event,
                //mouse     : mouse,
                //menu      : gContextMenu,
            },
            {}
        ),
        win.location
    );
}

function getContextOnLDR(target) {
    const doc = content.window.document;
    const win = content.window.wrappedJSObject;
    return implant(
        implant(
            {
                document  : doc,
                window    : win,
                title     : null,
                selection : win.getSelection().toString(),
                target    : target,
            },
            {}
        ),
        win.location
    );
}

// stuff ---
function implant(dst, src, keys){
    if (keys) {
        keys.forEach(function(key) { dst[key] = src[key]; });
    }
    else {
        for (let key in src) dst[key] = src[key];
    }

    return dst;
}

})();

// vim:sw=4 ts=4 et:
Firefoxってしばらく使ってるとどんどん起動が遅くなる。

入れてるExtensionの多さも関係してるのかもしれないけど、とにかく遅くなる。

その起動の遅さゆえ最近は起動が速いSafariを使っていたんだけど、そんなときこの記事を見付けました。

http://cheebow.info/chemt/archives/2009/05/firefox3.html
http://d.hatena.ne.jp/tanemori/20090514/SQLiteOptimizer

ここに紹介されているSQLite OptimizerというExtensionをFirefoxに入れて、REINDEXをするとあら不思議、Firefoxの起動が爆速になります。

これはなにやってるかというとFirefoxの履歴とかのデータが入ってるファイルの中身のインデックスを再構築してるんですが、それだけでこんだけ早くなるんだとちょっと驚いた。

さっき会社の開発ミーティングでその話になって、まだやってない人にその場でやってみてもらったら、みんなびびってました。

とりあえず遅いなぁという人は試してみる価値ありです。

Tomblooを愛用しているのですが、 最新にしてから20_model.jsの
1909行でエラるようになってしまいました。

調べてみると原因はpostkeyというのをlivedoorクリップから
取得するときにちゃんとクエリを渡せてないからでした。

具体的にはlinkというクエリに

http%3A%2F%2Ftombloo/

を渡してて、最後の「/」がエスケープされてないので
livedoorクリップがコケます。

ということで、

http%3A%2F%2Ftombloo%2F

に修正してやると問題なく動きます。
記事下にpatchを置いておきます。


ちなみにTomblooは、githubでソース管理をしてるんだけど、
こういった修正はどうお報せするのがいいんですかね。

github使ってるならこうしたら早いよ!っていうのがあれば教えて欲しいです。

--- 20_model.js.orig	2009-02-11 16:05:00.000000000 +0900
+++ 20_model.js	2009-02-11 16:03:48.000000000 +0900
@@ -1901,7 +1901,7 @@
 		
 		case 'changed':
 			var self = this;
-				return request(LivedoorClip.POST_URL+'?link=http%3A%2F%2Ftombloo/').addCallback(function(res){
+				return request(LivedoorClip.POST_URL+'?link=http%3A%2F%2Ftombloo%2F').addCallback(function(res){
 					if(res.responseText.match(/"postkey" value="(.*)"/)){
 						self.token = RegExp.$1;
 						return self.token;

今までスケジュール管理は、Mozilla.org のカレンダープロジェクトの Sunbird を使って、自宅サーバに WebDAV で接続してやっておりました(図にすると下のような感じ)。こうしておけば、いざというときにネットがつながってればどこでもスケジュール確認できるし、あと他人とスケジュールをシェアしてあぁ、この人は今日はこんなスケジュールなのねとわかったりするわけです。

[Sunbird(スケジュール管理ソフト)]
  |
WebDAV経由
  |
[自宅サーバ(スケジュールデータはここに置いてある)]

でもWebDAVが遅いのかなんなのか Sunbird は重くてぜんぜん快適とは言えませんでした。

そこで今回mozilla.orgの同じカレンダープロジェクトの1つで Sunbird より開発頻度の高いと思われる Mozilla Calendar に変えてみたのですが、これが快適。いい感じです。

インターフェイス的には Sunbird とほぼ変らないのですが、動きが軽快ですし、日本語も普通に使えるようですのでスケジュール管理をしたい方にはお勧めかと。

ちなみに Sunbird は単独のアプリケーションとして提供されていますが、今回自分がインストールしたのは Calendar for Mozilla Firefox というやつです。その他にも Calendar for Mozilla Thunderbird とか Calendar for Seamonkey/ Mozilla Application Suite といったバージョンのものがあるようですが、普段 Firefox 使ってる人であれば Calendar for Mozilla Firefox は Firefox のプラグインとして入るので試しやすいのではないかと思います。

あと1つ、Tips的なものなのですが、最近念願の iPod を買ったのでいろいろいじくっているのですが、 Mozilla Calendar で作ったカレンダーの ical 形式のファイル(普通ならばC:\Documents and Settings\USERNAME\Application Data\Mozilla\Firefox\Profiles\FOOBAR.default\Calendar\というフォルダに入っている)を、マウントした iPod のカレンダーディレクトリに置くだけで iPod でもそのカレンダーが閲覧できるようです。こりゃ便利だ。欲を言えば、iPodでもスケジュールが書き込めりゃもっといいのに…とは思いますが現状は無理のようです。

まぁこのTipsは知ってる人は知ってるんだろうと思いますし、 Mac OS X 使ってたら iCal あるし必要ないんですけどね…。

興味があるかたはぜひ使ってみてください。

Apple iPod 30GB ホワイト [MA002J/A]
アップルコンピュータ (2005/10/20)
おすすめ度の平均: 4.21
4 ビデオ早送り方法
4 ビデオはおまけ
4 iPodでも、PSPでも再生できる映像ファイルが便利

いやぜんぜんたいしたことではないんだけど、発見したので書きます。

FirefoxでCtrl+sして検索したときに、ウィンドウの下に検索バーが出てきます。これを今までは毎回マウスで×ボタンを押して閉じてたのですが、そのバーにフォーカスがあるときにEscを押すと閉まわれます。

発見したときにはちょと嬉しかった…。ただそれだけですけど…。

Greasemonkeyのスクリプトを作ってみたいなと思っていて、ちょうどいい題材があったので作ってみた。

作ったのは、なおやさんのRFC: 続・Hatena ID Auto-Discovery の仕様というエントリで出ていたlinkタグで表現されている「はてなID」を取得して、画面右上に表示するというユーザスクリプト。

hatenaid_autodiscovery.user.js

とりあえずデフォルトでは「http://d.hatena.ne.jp/*」に限っています。といいつつこれって今必要じゃなくね?というつっこみはごもっとも。このタグが埋め込まれたサイトはまだないんじゃないかと&仕様が変わることあり(笑)

とりあえず作ってみたいベースで作ってみました。

検索

広告

OpenID対応しています OpenIDについて
Powered by Movable Type 4.22-ja