たまに18歳未満の人や心臓の弱い人にはお勧めできない情報が含まれることもあるかもしれない、甘くなくて酸っぱくてしょっぱいチラシの裏。RSSによる簡単な更新情報を利用したりすると、ハッピーになるかも知れませんしそうでないかも知れません。
の動向はもえじら組ブログで。
宣伝。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。
以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能!
タブのバインディングやスタイル指定のためのコードの削減のせいで、Firefoxのタブの拡張性は深刻なまでに低下した。ツリー型タブも情報化タブも動かなくなったし、Alice0775氏のスクリプトなども被害を被っているし、他にも被害を受けている拡張機能はあるんじゃないかと思う。
拡張機能がたくさんあるから云々ということを売り文句にしておきながら、このように拡張機能作者をいじめることにしかならないような変更を軽々しく入れてくる連中には、本当に腹が立つ。この詐欺的行為にあまりに腹が立ったので、自分でバグを立ててみた。
バグの報告文に書いたけど、この問題の要点は「拡張するためのあそびが全くなくなってしまった」という一言に尽きる。現行のFirefoxでは、スタイル指定のために用意された匿名要素のボックスや、そもそも今のFirefoxでは使われていないけれども今後実装されるかもしれない何らかの機能のために用意されていた(と僕は思っているけど確証はない)プレースホルダーがあって、それらの中に色々な要素を追加することができた。そのお陰で、タブの中にサムネイルを出したり、タブのロック状態などをアイコンで表示したりということが可能になっていた。ところが前述のバグで提出されたパッチによって、現在Firefoxの標準的な機能で使われている物以外の「あそび」は一掃されてしまった。
今の構造でも、バインディングを使えば要素を追加することはできるけれども、複数のアドオンでそれぞれ別々のバインディングを提供すればそれらは確実に衝突する。例えば、今までは情報化タブとツリー型タブを(それだけでなく、他のいろんなタブ系拡張機能を)好みに応じて組み合わせて使えていたのに、これからは、そのうちどれか一つしか使えなくなる、「組み合わせて使う自由」が失われるということだ。これでは、Firefox 1.5以前の暗黒時代に逆戻りだ。拡張性が高いことにFirefoxの価値を見出している者にとっては、こういう愚行は決して容認できるものではない。
でも英語力に自信がないしBugzillaの流儀にも詳しくないので、invalidとかworksformeとかそういう処理をされて、結局何も変わらないままFirefox 3正式リリースまでこの問題は解決されないまま放置されてしまいそうな気がする。誰か援護射撃してくれると嬉しいんだけれど……
ツリー型タブでずっと前から発生条件が分からなくて困ってた「一つもタブが選択されていない状態」になってしまうバグの原因がやっと分かったので、速攻で修正した。
この問題は、以下の条件がすべて揃った時に発生していた。
この時、内部的にどういう処理が行われていたかというと、以下のような感じだ。
この「TabCloseイベント」というのがFirefox 2以降で使えるAPIなんだけれども、問題は7のステップで起こっていた。7のステップで「次に選択するべきタブ」を決定するためのキーとして「現在開いているタブの総数」を使っているのだけれども、その値は1のステップの間に取得しているため、1から7までの間のどこかでタブの数が増減した場合、タブの選択状態が狂ってしまうのである。7のステップで「現在のタブまたはそれよりあとのタブ」が選択される場合、ここでは4のステップでタブの数が減少しているため、「次に選択するタブの番号」が「すでに削除されたタブ」のインデックスを指し示すことになり、selectedTabの値がundefinedとなりNull Pointer Errorが発生してしまう。……というのが事の真相だった。
ツリー型タブの側でselectedTabのセッタを上書きし、もし存在しないタブが選択されそうになった時は強制的に最後のタブを選択するようにしたところ、「一つもタブが選択されていない状態」は発生しなくなった。以下はそのためのコード。
// var b = gBrowser
var getter = b.__lookupGetter__('selectedTab');
var setter = b.__lookupSetter__('selectedTab');
eval('setter = '+setter.toSource().replace(
'{',
'{ if (!val) val = this.mTabContainer.lastChild;'
));
b.__defineGetter__('selectedTab', getter);
b.__defineSetter__('selectedTab', setter);
この部分ではなく、removeTabメソッドを上書きするという手もあるんだけど、ここはいろんなアドオンが上書きしたがるためコンフリクトの原因になると思ったので、「標準的な動作と変わってしまう」ことは仕方がないと割り切って、ほとんど誰も触らないであろうselectedTabの方を上書きするようにした。ちなみに、ゲッタとセッタ両方を定義し直しているのは、片方だけを再定義するともう片方が未定義になってしまうから。
表題の件に流れを戻すと、「タブを閉じる」という操作をイベントとして捕捉できるようにしたのなら、そのイベントをトリガーにして他のタブを連動して操作するという機能も当然登場してくるわけで、そういうことを考慮せずに「はいはいイベント発行すりゃいいんだろdispatchEvent っと!」と適当に設計してしまうとこういうトラブルが起こるので、APIを作る時にはもうちょっと慎重になった方がいいよね、という教訓を得たという話なのでした。
方針が明らかになったことを受けて、さらにいくつかのアドオンを追加で応募した。以下はその時に書いた紹介文。
今回追加エントリーした連中の方が一応僕にとっては「本命」なんだけど、これも箸にも棒にもかからなかったら泣けるね……
Mozilla Labsのアドオンコンテストに殴り込みをかけようとして不発に終わった件について、フォーラムに書いた質問に、Personasの作者でもあるクリス氏から回答があった。だいたい以下のような感じ?
Mozilla Labsで行われているアドオンコンテストに乾坤一擲のエントリーを!!と思って人の手も借りながら超気合い入れて説明文を書いてツリー型タブあたりを投稿しようと思って送信ボタンを押したら説明文が最初の1/4くらいでゴッソリ切られてしまって激しく脱力した 字数制限があるなら最初から言ってくれよと……
しょうがないからヤケクソで小物を連投してみた。以下、実際に投稿した説明文。
あー……もしかしてinstall.rdfに書いた「homepageURL」のページに詳しい説明を書いとけということだったんだろうか?
元々はね。手持ちの弾を全部出し尽くして、説明もし尽くして、エントリーそれ自体に全力尽くすつもりだったんですよ。今までこういうコンテストからはずっと逃げてきてたから。実力を冷静に判断される機会をずっと避けてきてたから。
拡張機能について言えば、唯一参加したもじら組の拡張機能コンテストは参加者少なすぎてまともな体裁だったとは言えなかったようだし、こないだのMozilla 24のSOI Asia主催のコンテストは審査員だったから参加はハナからできなかったし。前回のコンテストの時はまだ英語の読み書きに今よりずっと抵抗が強かったこともあって参加しなかったけど、それは今から振り返ってみたらただの言い訳だったのかもしれない。CSSについてだって、2chのカスイケスレに晒すのが関の山で、ホントにハイレベルな連中が集まってたCSS Zen Gardenにはついぞ一歩も踏み入れられなかった。絵のことなんて言わずもがな。
僕のことを褒めてくれる人とかはいるけど、でもそれって客観的に見てどうなんだ、技能とか発想とか作り込みとか、ちゃんと冷静に比べたらどのくらいなんだ、ってことを評価される機会に今までちゃんと向き合ったことがなかった。だから、天狗になって「僕チンはすごいんだぞ! 日本で拡張機能作ってた人間の中では最古参の一人なんだぞ! タブブラウザ拡張では世界中から注目されたんだぞ!」なんて勘違いも甚だしい大言壮語の自慢話を、酒に酔った勢いでグチグチと垂れ流したりするわけですよ。
そんな自分にけじめを付ける機会にしたかったんです。いい結果が出たのなら、それを自信として、歪んだ自尊心なんかこれ以上膨らまさないようにしよう。応募作の中で最終的に箸にも棒にもかからないような物でしかなかったという結果が出たのなら、あるいは、何とも言えない微妙な結果だったのなら、自分の程度という物をきちんと自覚して、分をわきまえるようにしよう。
という風に物凄く強い思い入れがあってエントリーを考えていただけに、説明文の字数オーバーでアウトというのはなんとも言えずもにょってしまうのです。
……とまあ、こんな極東の島国で少数民族の使う言葉で愚痴っていたところで疑問が向こうに伝わる訳はないので、フォーラムで質問してみた。……他にまだ一件もコンテスト関係の書き込みがないから、空気の読みようがなくてガクガクブルブルだ。
需要がどれだけあるか分からんけど、ツリー型タブをTab Mix Plusと同時に使えるようにしてみた。といっても左右にタブバーを表示した場合限定で、それ以外の場合については全然まったく動作確認を行っていないので要注意。とりあえず多段タブの設定になってる時はそれを自動的にキャンセルするようにはしてあるけど、TMPの設定次第ではグッチャグチャになる可能性もある。
TMPによって改変された後のDOMツリーは旧TBEを思わせる混沌とした有り様で、解析するのにえらく骨が折れた……
途中まで作ってた奴をもう少し作り込んで、正式版としました。
表示するサムネイルはローカルに保存しています。前後のページのサムネイルを表示する方法には色々やり方がありそうなんだけど、とりあえず一番作るのが楽そうな方法(記憶領域を無駄遣いする代わりに、確実に動作して、トラブルも起こりにくい)を選びました。
ちなみに最初はキャッシュと同様にサムネイルを一つ一つ画像ファイルとして保存するように作ってたんだけど、サムネイルが溜まってきた時に要らないやつを削除する処理について、効率的にやれる方法を思いつけなかったので、思い切ってMozStorage(SQLite)に手を出してみました。画像はdata: URL形式の文字列としてプロファイル内のbfthumbnail.sqliteに格納されます。SQLのことはよくわからんのでFirefox内のコード等を見ながら見よう見まねで書いてみたんですが、一応動いてるみたいなので大丈夫なのかな、と。
戻る・進むボタンにおけるツールチップを見てサクッと作ってみた。
まだ色々未実装だけどとりあえずソースだけ公開しときます。
公開した後から言うのもナンだけど、横長のタブバーでツリー表示にはやっぱり無理があるよねぇ……横長の時は多段タブバー、縦長の時はツリー、というのが最強のような気がする。縦長で多数列とか横長でツリーとか、逆の組み合わせは正直言って使いにくいことこの上ない。設定UIからは削って隠し機能止まりにしといた方がよかったかも。「できる」というのと「するべき」というのとは別問題だ、ということを痛感した。
View Source in Tab。その名の通り、ソースの表示をタブで行うようにするだけという物。ツリー型タブの機能として加えようとしてて、よく考えたらこれツリー関係の機能関係なくね? と思ったので別途リリースすることにした。
作り始める前に「そういえばそんな名前のアドオンがすでにあったような気がするんだが……」と思って「View Source in Tab」で検索してみたけど見あたらなかったのでそれなりに作り込んでさあそろそろ公開するか、と思ったところでふと「Open Source in Tab」で検索してみたらあっさり見つかったし
まあそれでもせっかく作っちゃったから公開しておく。一応、Open Source in TabやView Source Choiceに比べて以下の点でView Source in Tabの方が高機能ではあります。
でも徹底的に探したわけではないので、これで後から「実はすでにView Source in Tabという名前のアドオンがあるんだが」という風に気がついたら、もうどうしようもない。→ありました
25日追記。無難なところで「Source Viewer Tab(ソース表示タブ)」に改名しておきました……