[PR]ޔԑg\
̔ԑg

電気分解部 Diary



陽極日記

2006 年 11 月の log

2006.11.2 Thu

Firefox でタブをユニーク化

要するに,Firefox でタブを複数開いているときに同じページを開いていることもあるので,そういう重複しているタブは 1 つだけを残して他は全部閉じてしまおうというもの. 既にそういうことを実現するコードはどっかにありそうだが,探すのが面倒だったし,タブ周りの処理の勉強のためにも自分で書いた. 車輪のなんちゃら万歳.

var hogera = {
    _duplicatedTabs : [],

    _getTabUrl : function(aTab){
        return gBrowser.getBrowserForTab(aTab).contentWindow.location.href;
    },

    _checkTabs : function(aTab, aUrl){
        if(aUrl == this._getTabUrl(aTab)){
            this._duplicatedTabs.push(aTab);
        }
        if(aTab.nextSibling){
            this._checkTabs(aTab.nextSibling, aUrl);
        }
    },
        
    _closeDuplicatedTabs : function(){
        for(var i = 0; i < this._duplicatedTabs.length; i++){
            gBrowser.removeTab(this._duplicatedTabs[i]);
        }
        this._duplicatedTabs = [];
    },

    uniq : function(aTab){
        var currentTab = aTab || gBrowser.mTabs[0];
        if(!currentTab) return;

        var nextTab = currentTab.nextSibling;
        if(!nextTab) return;

        this._checkTabs(nextTab, this._getTabUrl(currentTab));
        this._closeDuplicatedTabs();
        if(currentTab.nextSibling){
            this.uniq(currentTab.nextSibling);
        }
    }
};

hogera.uniq();

総当たり的に各タブの URL を順々に調べていくという,非常に単純かつ原始的なアルゴリズムをまず思い浮かべたのでそれを実装したもの. 右クリック系の拡張から呼び出すとか,使い方はいろいろ. タブを閉じるときに例外を投げることがあるかもしれないけど,まあ.

2006.11.3 Fri

お肉好き好き

mozilla.dev.mdc で MDC statistics graph のリリースが 告知されていた のだが,吹いた. 日本語にすれば,「先月 29 日に MDC 支援プロジェクトでほげほげ」という感じで始まるのだが,ここで気づいておくべきだった. 最後まで読み進めると,「10 月 29 日にリリースしたわけだが,この日は日本語で肉の日って言うんだぜ」的な文が. おいおい,ちゃっかりしっかり肉の日リリースかよ,と. しかしこんなことを急に書かれても普通の外国人連中にはなんのこっちゃって感じだろうな. 肉の日の説明だけして,肉の日リリースの説明は書かないところがまたいいのだが.

2006.11.4 Sat

Firefox でタブをソート

今度は Firefox のタブをそのタイトル順で整列するものを書いた. やはり既にそういうことを実現するコードはどっかにありそうだが,探すのが面倒だったし,タブ周りの処理の勉強のためにも自分で書いた. 車輪のなんちゃら万歳.

var piyo = {
    _titleIndexTable : [],

    _getTabTitle : function(aTab){
        return gBrowser.getBrowserForTab(aTab).contentWindow.document.title;
    },

    _getSortTable : function(){
        var sortTable = new Array(this._titleIndexTable.length);
        for(var i = 0; i < this._titleIndexTable.length; i++){
            sortTable[this._titleIndexTable[i].index] = i;
        }
        return sortTable;
    },

    sort : function(){
        var tabs = gBrowser.mTabs;

        for(var i = 0; i < tabs.length; i++){
            this._titleIndexTable.push({title : this._getTabTitle(tabs[i]), index : i});
        }

        function sortFn(aObjA, aObjB){  // 大文字・小文字を無視した A to Z なソート
            var titleA = aObjA.title.toUpperCase();
            var titleB = aObjB.title.toUpperCase();
            return((titleA > titleB) - (titleA < titleB));
        }
        this._titleIndexTable.sort(sortFn);  // タブのタイトルでソートしてみる

        var from = 0;
        var to = 0;
        var sortTable = this._getSortTable();  // 各タブがどこに移動すべきかの一覧表を取得

        for(var lockedCount = 0; lockedCount < tabs.length;){  // 全タブが固定されるまで
            to = sortTable[from];
            if(to < 0){
                from++;
                continue;
            }

              // タブの交換
            if(from != to){  // 同一のタブは交換しない
                  // tabs[from] と tabs[to] を交換
                gBrowser.moveTabTo(tabs[from], to);
                if(from < to){
                    gBrowser.moveTabTo(tabs[to - 1], from);
                }
                else{
                    gBrowser.moveTabTo(tabs[to + 1], from);
                }
            }
              // 一覧表更新
            sortTable[from] = sortTable[to];
            sortTable[to] = -1;  // 移動完了のタブは位置を固定

            lockedCount++;  // 固定されたタブの数を更新
        }
    }
};

piyo.sort();

という感じなのだが,やはりなんとなく思いついた感じ. タブのタイトルとインデックスのペアからなる配列をタイトルについてソートし,その結果から各タブをどこに移動すべきかを割り出し,それに従ってちまちまと並び替えていく感じ. ちょっと効率が悪そう.

使用上の注意として,Tab Mix Plus(Tab Mix 系全般か?)には gBrowser.moveTabTo の独自のラッパがあるようなので,そういう拡張を使っている場合はそのラッパを使うべき. つまり moveTabToTMmoveTabTo に置き換えるとよろし. 他のタブ系拡張ではどうなってるかは知らない. 今回はその辺のことは本質的ではないので,条件分岐ということにはしなかった. また,SpiderMonkey な JavaScript の sort メソッドはいわゆる不安定なソートらしいので,同じタブがいくつかあるときにソート前後でそれらの順番が変わることがあるので,それも注意.

Firefox 2 からアンインストールしてもいい 3 個の拡張機能

Firefox 2 にインストールする3個の拡張機能募集 - えむもじら ということだけど,やはり拡張を 25 個も入れてるわけであって,それを 3 つに絞ることなんて俺には不可能なんでしゅよ. どんなに頑張っても無理. まずタブブラウジングの絶対的かつ基本的な補助として Tab Mix Plus がある. で,サイドバーでいろいろとほげほげしながら巡回するのだけど,これのファンダメンタルなところで All-in-One Sidebar と Sage と bbs2chreader と Foxage2ch が 1 つのセットになっている. 不可分. あと,主に翻訳をするときに使う Content Holder も欠かせない. 最低でもこの 6 つは必須. これを 3 つに絞ることは不可能. 必須ではないにしてもプライオリティがかなり高いコンテキストメニュー系の拡張がいくつかある.

というわけで,別になくてもそんなに支障はない 3 個の拡張機能ということでピックアップすることにする. これなら楽チン.

自分で作ったものが含まれているのがまた.

そして関連するヤツ.

2006.11.6 Mon

れっつ・ベイズ分類

ベイズ分類 その2 - Torisugari の日記 のブツで遊びたいなぁと. とりあえずそこで配布されているパッチを当てて,ac_add_options --enable-extensions=default,bayesiantest を指定しつつ Firefox をビルドした. すると bayesiantest が使える環境ができる. いやはや,久々に trunk をビルドした. 実は Firefox をビルドせずともブツを作れそうだが,自前のビルドを用意したかった衝動のついでみたいなものなので.

あとは適当に学習を繰り返し,テストする. この手順について取説はないので,idl ファイルやその他のソースとにらめっこしつつ,しばし試行錯誤を. ソースがドキュメント状態につき.

const bayesianTestService = Components.classes["@mozilla.org/extensions/bayesiantest/gr;1"]
        .getService(Components.interfaces.mozIBayesianTestService);

var db = Components.classes["@mozilla.org/file/local;1"]
        .createInstance(Components.interfaces.nsILocalFile);
db.initWithPath("f:\\bayes.sqlite");

var tester = bayesianTestService.createTester(db);

とりあえずこれでテスト環境を作る. 途中で指定している sqlite ファイルのパスは適当. ファイルが存在しなければ勝手に作られる模様.

tester.train("test", "ほげほげ文字列だよー", true);

とかすると,学習できる. このメソッドの引数については idl ファイルを見ればいいのだが,おそらく第 1 引数には適当な URI 文字列,第 2 引数には学習対象の文字列,第 3 引数にはポジティブか否か(例えばスパム判定ならスパムか否か)を指す真偽値を指定する模様. こんな感じでいろいろな文章を truefalse に分けつつガスガスと学習. ある程度学習を済ませたら,テストをする.

tester.test("ふがふが");

これが返す数値が判定結果であり,1 に近いほど true を指定して学習したものに近い傾向であるということだと思う.

他にもいくつかプロパティがあるようだが,最低限の遊び方としては今示したヤツで十分だと思う. ただしすべてテケトーにやっていることなので,変なところや解釈を誤っている部分もあるかもしれないので注意.

今回の bayes.sqlite ファイルを sqlitereader で読み込んでニヤニヤするのがよい.

2006.11.7 Tue

ToggleStyle プチハック

朝顔日記 - Firefox 拡張機能 ToggleStyle 1.0 リリース ということで,誰か、タブブラウザ対応に書き直してください。ということなので,改造.

<?xml version="1.0" encoding="UTF-8"?>
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript">
function setStyleDisabled(disabled, isFromCheckbox){
    getMarkupDocumentViewer().authorStyleDisabled = disabled;
    if(!isFromCheckbox) TS.setCheckState();
}

var TS = {
    toggle : function(){
        var isChecked = document.getElementById("styletoggle").checked;
        setStyleDisabled(isChecked, true);
    },

    setCheckState : function(){
        if(!document.getElementById("styletoggle")) return;
        document.getElementById("styletoggle").checked = !getMarkupDocumentViewer().authorStyleDisabled;
    }
};

var appcontent = document.getElementById("appcontent");
appcontent.addEventListener("select", TS.setCheckState, false);
</script>
  <toolbarpalette id="BrowserToolbarPalette">
    <toolbaritem id="StyleToggle-Checkbox">
      <checkbox onclick="TS.toggle();" id="styletoggle" label="CSS" checked="true"/>
    </toolbaritem>
  </toolbarpalette>
</overlay>

という感じなのだけど,イベントリスナを追加してるところは,こうすることでタブを切り替えたことを検知できるようになる模様. ただ 1 回切り替えると 2 回イベントが発動する. 他に,View -> Page Style から切り替えたときにそれがチェックボックスに反映される仕様にした. 全体的におざなりな感じだけどどうか.

2006.11.8 Wed

オープンソースマガジン立ち読み

level 氏と Piro 氏が Firefox 2 について書いたということなので,早速立ち読みしてきた. 特に気になったのは後半の Piro 氏の書いたところ. それはカスタマイズの領域を越えたハックではないかと. あと,クリアユードというように誤植されてた気がするけど気にしない. ユのように見えるコなんだ,これは.

2006.11.10 Fri

Binary R-18

Binary Hacks なる本が話題みたいだけど,その辺からふたなりを連想してしまったのでメモ. 実際は 萌える Binary Hacks の「ふたりはプリキュア」から「ふたなりプリキュア」を連想し,ふたなりとバイナリの関係に気づいたのだが. 言葉の響きだけではなく,binary の意味を考えるとなんとなくふたなりと共通点があるというか,むしろ合致していると言える. ほら,そういう方向で話を進めてきたら 0 と 1 が何かの比喩に思えてきた. というわけで,これからはバイナリ云々という議論を見るたびにそれをふたなりに脳内変換し,ニヤニヤすることにする. 将来的に萌え系のバイナリハック本がマジで出るとしたら,それにはふたなりキャラを使うべきだ. 同人誌とかで出ないかな. 読まないけど.

いつかこの項を見て俺は何を考えていたんだと思うことになりそうで早くも鬱.

はらたいらさんには 3000 点か全部かのほぼ 2 択状態のようだ

今回の件で確信した. 慣用句だよな.

2006.11.11 Sat

bbs2chreader (BRANCH-SERVER) with Opera

bbs2chreader に BRANCH-SERVER なるブランチができたようで,スレを Firefox 上にできた鯖が吐き出すという仕組みのようだ. これによってあんなことやこんなことができるかもしれないということで,早速 b2r 経由で Opera でスレを開くということを試したのが この画像. 合成でもローカルに保存した HTML を開き直したわけでもなく,ちゃんと Opera で頑張ったもの. で,これって XULRunner 上に搭載して常駐させておけば最強じゃね? メモリ云々を気にしなければ.

2006.11.12 Sun

糞ノートクリアランス終了

数日前から糞ノートの中の邪魔なものを消そうといろいろとやりだしたら止まらなくなったのだが,ようやく終わった. 今までは C にシステム関連のブツ,D にいろんなプログラムのソースやら成果物やら,E にいろいろなアプリという感じの Windows 側と Ubuntu 側に分けていたのだが,サブマシンになっちまったわけで,使わないものがいっぱいあるので消しちゃおうと.

とりあえず E に入れていたものを全部消して,E を潰した. パーティションの構成が変わったせいで MBR に入った GRUB からはエラーで起動できなくなったので,とりあえず FIXMBR. で,C の領域を増やし,D は作業用として確保. 必要なアプリを C に入れ直し,Windows 環境はまず完成.

あとは GRUB を入れ直すのだが,とりあえず Ubuntu の FAQ に従って Super Grub Disk なるブツを使ってみた. これ経由で Ubuntu を起動し,/boot/grub/menu.lst を書き換えて $ sudo grub-install /dev/hda な感じで GRUB を入れ直した. 最近はちゃんと sudo するようにしてる. えらい. 他に /etc/fstab を直しつつ,終了. よくわからんけど,GRUB 周りの修正は全部 Super Grub Disk からできそうな感じなのか? 今回は Super Grub Disk から Ubuntu を起動できたので直接 Ubuntu で作業したけど.

というメモ.

2006.11.13 Mon

冬支度

さすがに寒さに耐えられなくなってきたのでコタツを出した. 朝晩の冷え込みやばい. 気付いたときにはもう風邪を引いていたし. 熱はあるし頭は痛いし体はだるいし.

2006.11.17 Fri

全快

ふぅ. ぶり返さないようにしないとな.

2006.11.18 Sat

次の書(ryモジュール構想

もうこうなったら Jane みたいに書き込みウィザードにステータスバー付けちゃおうぜ.

書き込み内容の行数をどこかに表示したいなと思ったのだが,やはりそういうのはステータスバーに表示するものだろうということで. 今まではウィザードのボタンが並んでいるところに後付け的にぶち込むという変則的な方法で samba 周りの表示を行っていたのだけど,そのステータスバーに samba のヤツも移しちゃえばいいんじゃね的なソリューション.

2006.11.19 Sun

samba.txt 更新

2ch 本家のメニューに載っていない,いわゆる隠し板に対応してみた.

それにしてもメニュー取得から samba.txt 生成まで一発でやりたいな.

2006.11.22 Wed

JavaScript で samba.txt を一発生成

今までは Irvine と Perl と JavaScript のコンボだったのをまるっと JavaScript(一部 XPCOM)でやってみた. 主に,Irvine でダウンロードしていたところと,その落とした一連のファイルから Perl で鯖名と板名と秒数の羅列からなる一時ファイル(さらに JavaScript で処理するヤツ)を生成していたところを JavaScript で書き直しただけだが. で,Firefox で動かしてみた. 予想どおり,処理中はフリーズ状態. ダウンロードにはかなり時間がかかり,全体の処理時間のほとんどがそれなのだが,5 分も 10 分もブラウザに固まられちゃどうしようもないな. 全部 Perl とかのほうがよさそうかも.

2006.11.24 Fri

アンテナのデザインを変えてみた

b2r の俺用スキンやはてブで使ってるデザインに合わせた感じ. やっつけだけどまあいいや. しかし,はてなアンテナのデザイン管理周りのアレでこういう作業がやりやすくなったのう.

周辺のネタ