近況報告たまに18歳未満の人や心臓の弱い人にはお勧めできない情報が含まれることもあるかもしれない、甘くなくて酸っぱくてしょっぱいチラシの裏。RSSによる簡単な更新情報を利用したりすると、ハッピーになるかも知れませんしそうでないかも知れません。動向はもえじら組ブログで。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。2014Firefoxのマルチプロセス設計への移行がいよいよ目前に迫っている。Rebootedでも詳しく解説してたんだけど、ブラウザのUIを動かすプロセスとコンテンツ領域のプロセスを分けるというのはFirefoxではかなりの大ごとだった。一時は「こんなん無理!」っつって計画が凍結されてたほどだったと記憶してる。e10s移行が困難だった理由は、多分、Firefoxというアプリケーションそのものの設計にあったのだと思う。FirefoxというWebブラウザは、「GeckoというHTML・XMLレンダリングエンジンの上で動作するJavaScript製のローカルWebアプリケーション」といった感じの設計になっている。コンテンツ領域内の操作のためのコードとUI部分の操作のためのコードが非常に似通っていて、シームレスに連携しやすかった、否、「連携しやすすぎた」と言える。あまりにシームレスに連携できたせいで、ブラウザのUIに関わるコードとコンテンツ領域内の操作に関わるコードが渾然一体の密結合になってしまい、それが「UI部分とコンテンツ領域内との間はテキストメッセージだけを非同期に通信しあう」というe10sベースの設計への移行を阻んでいた、という事なのではないか......と僕は思っている。いう理由があったのかは知らないけど、最近のバージョンのFirefoxではe10sベースの設計への本格的な以降のための準備が着々と進められている。上記のような密結合だった部分が「UI領域専用」「コンテンツ領域専用」「両方で共通」といった感じに分離されてきているし、同期処理前提だった部分が非同期処理前提に改められている。セッション保存の仕組み(ページ内のテキストボックスへの入力内容を保存する所とか)、リンクのクリック操作のハンドリング、その他多数の部分が大幅に書き直されている。アドオンから見た時のAPI的な互換性は可能な限り残すようにしてあるようで、その努力の様子が非常に興味深い。アドオン側での対応をどう進めるかなんだけど、実際にいくつかのアドオンをe10s対応に改修してみて、アドオンの性質によって典型的なパターンがあるようだという事が分かった。browserのcontentWindowやcontentDocumentに一切触れず、コンテンツ領域内からBubblingしてくるイベントも捕捉しないタイプのアドオンは、何も考えなくてもそのままe10sで動く。アドオンの実装を、「UI領域からコンテンツ領域へ、処理スタートの指示のメッセージを送る」「コンテンツ領域で指示のメッセージを受け取って、実際の処理を行う」という2段階に分け、実装の一部をコンテンツ領域側に読み込ませるコードの中に移動する必要がある。マルチプルタブハンドラの場合、「選択したタブをファイルとして保存する」機能について、ページをファイルとして保存する処理をコンテンツ領域側に移動し、UI領域からのメッセージをトリガーとして実行するためのコードを追加した。アドオンの実装を、コンテンツ領域側に読み込ませるコードの中に移動して、そこで処理を完結させるようにする必要がある。コンテンツ領域側にコードを読み込ませて、コンテンツ領域内で発生したイベントをUI領域に通知してやる必要がある。ツリー型タブの場合、タブバーを自動で隠す機能において、コンテンツ領域上でのマウスの移動を検知するために、マウスのボタン操作や移動で発生したイベントをUI領域に通知するコードを追加した。生のイベントオブジェクトやDOMノードは渡せなくなるので、文字列として渡せる情報だけでもきちんと動くようにする工夫が要る。これが一番厄介なパターン。書けたけれども、こういう事ができなくなる。UI領域とコンテンツ領域の境界をまたぐ時に非同期処理を挟まないといけないので、処理を「UI領域からコンテンツ領域へ、リンクを収集する指示のメッセージを送る」「コンテンツ領域で指示のメッセージを受け取って、リンクを収集し、UI領域へ結果を報告するメッセージを送る」「UI領域で報告のメッセージを受け取って、次の処理を行う」という3つの段階に分けなくてはならない。マルチプルタブハンドラの場合、「選択したタブの情報をクリップボードにコピーする」という機能のために、タブ(で開いているページ)の情報からクリップボードにコピーするための文字列を得る処理をコンテンツ領域側に移動した上で、UI領域からコンテンツ領域へ・コンテンツ領域からUI領域への橋渡しを行うためのコードを追加し、前後の処理をPromiseで繋ぐようにした。上記の5パターンの最初の方の物ほど実装が容易で、後の方の物ほど実装が面倒になる(その上、メッセージの往復を待たないといけないのでオーバーヘッドも大きくなる)。深い意味もなく後の方のパターンで実装していた機能は、どうにかして前の方のパターンで実装できないか検討した方がいい(Firefox本体の設計変更も、おそらくそういう風に進められたのではないかと思う)。実際に、情報化タブではWebページのサムネイル画像を取得する処理について、元々はUI領域で「サムネイルが必要だ」となったタイミングでその都度同期処理していたのだけれども、まずサムネイル取得の処理はコンテンツ領域に移し、処理が走るタイミングについて、コンテンツ領域側で発生したイベントをトリガーとしてサムネイル画像をUI領域側にpushで送りつけるように改めた。これは上のリストで言うと、5番目のパターンから4番目のパターンに設計変更した、ということになる。それでもどうしても5番目のパターンで実装しないといけないケースというのはあって、前後の処理とどうやって繋ぐか(同期処理だった物をどう非同期化するか)というのが問題になる。Promise互換APIを使うようになった)。ツリー型タブでも、コンテンツ領域内にプラグイン(Flashなど)で描画されている領域があるかどうかを調べるための処理で、このパターンが残っている。Promiseを使うコードはUI領域側のブリッジにまとめてあり、こんな感じになってる。}},checkPluginAreaExistenceメソッドは、その実行を示すユニークなidを伴ってコンテンツ領域に指示のメッセージを送ると同時に、新たに生成したPromiseのリゾルバ関数を、idと対応付けて保持する。メソッドの戻り値はPromiseとする。コンテンツ領域側では、指示のメッセージを受け取って処理を行い、結果のメッセージをid付きでUI領域に送り返す。送り返されてきたメッセージをUI領域側で捕捉したら、idに基づいて、保持していたリゾルバ関数の中から対応する物を見付け、送り返されてきたメッセージに含まれていた情報を渡す形で実行する。いう風にする事で、checkPluginAreaExistenceメソッドをthenableなメソッドとして他の処理の中に無理なく組み込める(次のコールバックには、コンテンツ領域側での処理で得られた結果が渡る)ようになってる。境界を2回以上またぐ処理を実装する時は、多少の差異はあれどだいたいこんな感じになるんじゃないだろうか。必要かどうかで言うと、このパターンでPromiseは必須ではなくて、Promiseのリゾルバ関数を保持・実行する代わりに、単にcheckPluginAreaExistenceメソッドでコールバック関数を受け取って、それを保持・実行するようにしてもいいんだけど。非同期の処理同士を何度も書き連ねる時のコールバック地獄は見たくない(今はそういう連携をする必要がないとしても、今後いつ必要になるとも限らない)ので、僕は自分で書く非同期処理は、インターフェースとしては基本的にPromiseを使う方向で統一するように考えてる。2012ツリー型タブ、情報化タブの今日付でのリリース分から、tabFx2Compatibleという自作のライブラリ(?)を使わないようにした。当初はマルチプルタブハンドラでも使ってたけど、ツリー型タブ・情報化タブに先駆けて一足先に使わないようにしていた。今回残りの2つでも利用をやめたことで、TBEやり直し組のアドオンからはこのライブラリが全く姿を消したことになる。作ったのが2008年の2月からだから、丸4年くらいは使ってたのか。3での仕様変更に追従するために仕方なく作った物だった。2ではタブの中に任意の要素(サムネイル描画用のcanvasだったりカウンタ表示用のlabelだったり)をXBLのコンテナ要素を使って動的に追加できていた。3になる時、具体的には2007年の12月頃に、高速化のためにそういう冗長性を排除する変更が行われてしまって、JavaScriptで動的にタブの内容を追加するということが原理上不可能になってしまった。正確には、方法はあった。Firefox本体がタブに適用していたXBLによるバインディングを独自のバインディングで置き換えて、それを使ってタブの内容を変更するというやり方だ。XBLのバインディングは同時に1個だけしか適用できないという制限がある。複数のアドオンが同じ事をやろうとしたら、結局どれか1つのアドオンしかまともに動かないという事になってしまう。他の人の作る物との互換性という話に限らず、リッチでファットなAll-in-One型のアドオンであったTBEを捨てて各機能ごとに個別のアドオンに開発し直す道を選んでいた僕にとっては、自分の手がける物同士の互換性を維持するためにも、これは致命的な問題だった。3向けに復活させるという物だった。風向きが変わったのは2010年9月の事だった。3.7のモックアップで示された視覚的なデザインを実現するために、タブのバインディングに再び冗長性が付与された。4から反映されている。2以前のタブのバインディングの構造の、両方を併せ持つ状態に変更した。3.0から3.6までの間のバージョンに対応するためには欠かすことができなかった。ツリー型タブ等のアドオンの対応バージョン範囲の下限がこの範囲に重なっている間は、このライブラリは絶対に使う必要があったので、いくらTMPやVimperator等とバインディングの衝突の危険性があったとしても、構成ファイル群から外すことができなかった。3.6のサポートを打ち切って、それと同時にtabFx2Compatibleも廃止することにした。4以降の既定のDOMツリー構造に合わせて変更する作業は、それなりの手間を要したけれども、これでカビの生えた過去から決別できるのなら安い物だと思った。選択肢の1つとして、tabFx2Compatibleを今後も使い続ける(Firefoxのタブのバインディングの構造が変わったら、その度にtabFx2Compatibleを更新していく)というやり方もあった。今この瞬間にかける労力を最小化する事を選ぶのなら、そういう選択もあり得たと思う。3から3.6までの暗黒期を乗り越えるためだけに用意された物だったのだから、用済みになったのなら、思い切って捨てた方が今後のためになると思った。いう切り替えをできる時にやっておかないと、またTBEみたいな事になってしまう恐れがある。TBEでは、タブの移動等といった基本的な機能すらFirefox本体に備わっていなかった頃から開発していたため、TBE自身で独自の「タブを移動する」などのAPIを実装していた。1.5とともに時代に取り残され死んでしまった。そんな愚はもう繰り返してはいけない。それにつけても、あの辺(Firefoxのタブまわり)の開発をやってる人達の意向に振り回されっぱなしだった4年間だったなー......と思うと、なんか感慨深い。menuこのへんのパッチが投入されて、gBrowser.pinTab()とgBrowser.unpinTab()というメソッドが実装された。pinTab()にタブを渡すとそのタブが他のタブの左側に寄せられて、unpinTab()に(pinnedな)タブを渡すと元に戻る。ぶっちゃけアレですね、Chromeの似たような機能のパクリですね。この時、タブはスクロールボタン(左向き三角のボタン)よりもさらに左に表示されるようになるんだけど、これは一体どうやって実現されてるのか。実は、CSSで非常にトリッキーなことをしている。pinTab()に渡されたタブはpinnedという属性の値にvalueが設定されるんだけど、この時、.tabbrowser-tab[pinned="true"]なタブはposition:fixedに設定されて、通常の描画フローから切り離される。その上で、スクロールボックスの左にすべてのpinnedなタブの幅の合計と同じだけのマージンを設けて、pinnedなタブ1つ1つにはネガティブマージンを設定してそれらしい位置に表示する......という感じ。moveTab()の中とかでタブの状態を見て処理を分けていて、pinnedなタブはpinnedじゃないタブの中には移動できないし、その逆も然り。原稿のコードに対する最小限の変更でそれらしい挙動を実現するようにしている。思いつくな、こんなの。既存のアドオンは影響を受けないはずなんだけど、タブ周りで凝ったことをしてる奴は、下手したら全滅しそうな気がする。いうかツリー型タブなんかはお話にならないのが目に見えてる。pinnedなタブのレイアウトの処理。pinnedになった時、自動的にツリーから解放するとか。最初は単に、pinnedなタブのレイアウト処理の所のX軸とY軸を入れ換えるだけにしてみたんだけど、それだと縦置きタブバーの場合は無駄な領域がメチャメチャ増えるだけだという事が分かったから、「タブが小さくなる」という所を優先して、24×24固定サイズでアイコンを並べられるだけ並べる(1行に収まらなければ改行する)という風にした。見た目は......あんまり良くないね。縦置きしたタブバーとpinnedなタブの相性はすこぶる悪い。結局全部ツリー型タブの方で作り直すのに近い状態になってしまった気がする。挙動としてはそれなりに違和感のない状態に落ち着いた。これからまた実装に仕様変更が入らないことを祈るばかりだ。実装の仕方自体が変わってしまうなら、今回のこの作業はまるっきり無駄になってしまうから。Tabのデフォルトスタイルをそのように変えてみた。一応、設定で今まで通り(ラベルの下に表示)にも戻せる。やるならとことんやってみっか!と一念発起して、モックアップにあるような光るプログレスバーを再現しようと頑張ってみた。3.5じゃないと期待通りには見えない。(ページ全体のスクリーンショットのサムネイルは、ページを判別するのには実際の所便利ではない。そのページのほとんどがテキストである場合は。)とあったので、試しに情報化タブのサムネイル表示機能について、ページの端から一定のピクセル数の部分を切り出してサムネイルにするモードを加えてみた。理屈の上では、各Webサイトはページの左上にブランドロゴのようなものを置いている場合が多いから、この方が視認性が高まる、って事らしいんだけど......単純に慣れの問題なのか、あんまり視認性が上がったような気がしない。したらサムネイルがそもそも小さすぎるからなのかもしれない(32×32程度のサムネイルだったら、全体の縮小だろうが一部の縮小だろうが大して変わらない)。本当のところを言えば、端から固定で何ピクセルなんていう取り方じゃなくて、人の視覚を引き付ける特徴的な要素がある部分を切り取る形にできれば、それが最良なんだろうけど(そうしないと、例えばこのページだったら左上を切り取ると真っ黒なサムネイルになるけど、全体を引いて見た印象はブルー、というちぐはぐなことになる)......そんな事僕の頭じゃできませんわ。2009「次のエントリで書く」なんて予告じみたことを書いてはみたものの、どうも話がまとまらない。思ったことを箇条書きで書くだけにする。現実的に言って、1つのアドオンであらゆる人のニーズを満たすことは不可能だと思うし、そういう方向での努力はしない方がいいとも思う。何でもかんでも......と際限なく詰め込んでいくと、どこかで破綻すると思う。機能の詰め込みは、ある時点までは効率がいいんだけど、ある時点を超えてしまうと、デメリットの方が大きくなってくる。「Piro拡張化」なんて言われるようになる。作る側の心理として、どうして機能を増やしたくなるのか。他の人はどうか知らないけど、僕はこんな感じだった。デバッグより、新機能を実装する方が楽しい。モチベーションが高まる。大きいことはよいことだ。「こんな小さな物をたくさん作りました」よりも「こんなデカい物をたった一人で作りました」の方がなんかすごそう。多くの人のニーズを満たせば、より多くの称賛を得られる。それまでに作った部分を土台や部品として使えるので、新しい別個のアドオンにするのに比べてはるかに楽に「すぐ動く物」ができる。共有できる部分が多ければ、それだけ「無駄が無い」と言える。同じことをするコードが複数のアドオンにあるのは、無駄なことで、気持ち悪いと感じる。複数の機能を有機的に連携させて、「100%ぴったり、思い通り」の挙動を実現できる。そんな感じの理由でどんどん機能を加えていく。ある時点までは、それでうまく回る。応援してくれる人とか感謝してくれる人とか、モチベーションを高めてくれる声も寄せられる。なんかの閾値を超えたところで、あらゆる物事が下り坂に転じる。目が行き届かない所が出てくる。自分が使う物は目が届くけど、使ってない機能には目が届かない。自分の環境では問題ないのに他の環境では問題が起こる、というケースが頻発するようになる。機能同士が複雑に絡み合っているので、原因の特定がどんどん困難になる。ある機能との整合性を常に考えないといけないため、新しい機能を加えにくくなってくる。新しい機能を加えることに物凄くエネルギーを使わないといけなくなる。作り込めば作り込む程、前提とする環境への依存が強くなる。前提がちょっと変わるともう全然動かなくなる。素晴らしい!」と称賛されていたのに、だんだんそれがなくなってくる。「定番だよね」「むしろ当たり前だよね」と言われるようになってくる。使う側から見たら「あって当たり前」という感覚だから、感動なんてしない。最初の時点で「とりあえず入れとけ」みたいな感じで勧められるから、それが無い時の不便さも、それを導入することで起こる変化にも、気がつかない。本当だったら使わなくてもいいはずの人まで、「なんかみんな使ってるみたいだし、入れとくか」という感じで使うようになる。アドオンは薬のようなもので、導入するのは薬効と副作用のトレードオフ。しても必要な薬効があるから副作用を我慢して使う、というのが本来そうあるべき使い方なのに、薬効をそもそも知らないまま流されて服用して、副作用に苦しむことになる。「バグが多い」「不具合ばっかり」「他のアドオンと衝突しまくる」などのデメリットばかりがとりあげられるようになってくる。定番なんだからできて当然なんじゃないの?」みたいな、お客様気分の声が増えてくる。やる気を削がれてくる。そんなわけで、精神的な負荷と時間的なコストがどんどん大きくなっていって、タブブラウザ拡張は破綻した。1.5のサポート完全終了と共に、過去の遺物となった。2デフォルトの状態で我慢できるわけもなくて。Plusに乗り換えるというのも考えられなかった。感情的な理由もあった。後から来て追い抜いていった(と同時に、良い評価もかっさらっていった)相手に自分が依存するのは屈辱だと思った。TMPも「Piro拡張化」の行き着く果てまで来ているように思えた。ここから先は下り坂だと思った。いうわけで、過去の自分の失敗を徹底的に反省して、ゼロからやり直すことにした。全部詰め込むのはやめる。1つ1つのアドオンを可能な限り単機能に保つようにする。多少効率が悪くても、重複する部分があっても、個別のアドオンに分ける。重複する部分がデカくなるようだったら、ライブラリにする。ライブラリはファイル単位で上書きできるようにする。ファイルの中を見て必要な箇所を切り貼りして......という風なことはミスの元になるから、やらない。複数の異なるバージョンの同じライブラリが同時に入っていても、問題なく動くようにする。いう考えで作ったライブラリをリポジトリにまとめてある。関係ない機能を含めない。コンセプトが合わない機能は、簡単に実装できそうであったとしても、加えない。これはユーザにもメリットがある。多機能で「とにかく便利」なんてコンセプトだと、ユーザは入れてみるまで薬効と副作用の比較ができない。入れた後も、どれが薬効でどれが副作用なのか分からない。単機能なら、薬効と副作用を比較しやすい。「この機能はいらないから、入れない」という判断ができる。「よく分からんけどとりあえず入れてみる」という選択を防ぐ圧力が生じる。多機能にするよりユーザ数は多分減る。薬効が必要なくて副作用しか得られない人にまで、使ってもらいたくない。主要な機能を、他のアドオン(自分が作る物も含めて)から使いやすいように「API」として公開する。いっても、物自体は変わらない。作る時の心構えを変える。自分だけが使うものだから......と思っていると、メンバ変数とかをがんがん使った、実装するのが楽な、結合が密な設計にしてしまいがち。結合が密だと、100%全ての情報の流れを理解している人間でなければメソッドを使えない。理解できなさそうなら、それは駄目な設計。結合をなるべく疎にする。密な結合にしないといけない時は、せめて、情報が双方向に流れないようにする。通行に処理を追いかけるだけで理解できるようにする。インターフェースを公開して、ドキュメントも作る。公開してしまっている物だから、安易に変更できないというプレッシャーがかかる。APIの互換性を維持する力が働く。機能同士の連携は、必ず公開APIを経由して行う。APIでできないことはしない。必要なら新しいAPIを考える。やっつけ仕事ではなく、ちゃんとした設計で。TBEでやってたような、ガチガチの作り込みはしない。泥臭くてカッコ悪くても、フレキシブルな対応が可能なやり方を取る。XBLでスッキリ書くより、DOMでゴリゴリ書く。Firefox自体が持つ構造を壊さない。要素構造を自分好みにすっかり作り替えてしまえば、自分は楽になる。他のアドオン作者も困る。要素構造を変えると他のアドオンと衝突しやすくなる。XBLの使用はできるだけ避ける。既存のバインディングの「置き換え」は「最後の手段」「禁じ手」と考える。「まだバインディングが行われていない部分への追加」だったら、使ってもいい。してもXBLじゃなきゃ実現できない、という部分だけに限って使う。それ以外でXBLを使うのは、極論すれば「珍しい技術を使ってる自分」に酔っぱらってる自己満足な行為でしかない、と考える。メソッドを丸ごと置き換える、という事はできる限り避ける。やるのなら、eval()による部分的な書き換えで対処する。やりたいことの大半は、元のメソッドの最初か最後に処理を追加するだけ。メソッドを丸ごと全部別物に置き換えてしまう必要は本来無い。見通しは悪くなるけど、他のアドオンとの競合は起こりにくくなる。これによる開発効率・メンテナンス効率の低下は、個々のアドオンを単機能に・シンプルに保つという前提によって相殺する。他のアドオンでできることはしない。自分一人で抱え込まない。他の人がやってることをわざわざ自分でやり直そうなんてことはしない。組み合わせて使うことを積極的に推奨する。自分自身も、他のアドオンと組み合わせて使う。組み合わせて使って問題が起こりにくい設計にしないといけない、という圧力が自然とかかる。いう考えに基づいて作ったのが、マルチプルタブハンドラ、情報化タブ、ツリー型タブ、ソース表示タブという4つのアドオンだ。上に書いたことを完全に守れてるとは言えない部分もあるけど、昔に比べれば遙かにマシになってると思う。作る側としても、使う側としても、僕は今の方がずっと楽だ。「多機能に」「1つだけで様々なニーズに応えられるように」という方向に頑張ると、縛りがどんどんきつくなってくる。1つのアドオンだけでできることを増やしていこうとすると、妙な話だけど、他のアドオンに頼れなくなっていく。作り込むほどに、そのアドオンを入れた結果が素のFirefoxとかけ離れてしまうから、他のアドオンとの互換性がどんどん失われていく。1つのアドオンだけでしなきゃいけない事がイモヅル式にどんどん増えてくる。ユーザの視点から見ると、「多機能なアドオン1つだけの世界で完結した使い勝手を享受する」か、「いろんなアドオンを組み合わせて使う」かの、どっちかを選ばないといけないということでもある。Plusと上記のタブ系アドオンの組み合わせは推奨していない。一応TMPで動くようにはした、けれども、継続的に追っかけ続けるモチベーションが無い。僕はTMPユーザではなく、TMPと組み合わせて壊れるようであっても僕自身は全く困らないから。TMPユーザでない他のアドオンの作者の中には、同じように感じてる人もいるんじゃないかと思う。アドオンで、部分的には、痒い所に手が届くような感覚がある。それを補うための他のアドオンと組み合わせて使うことは、残念ながらできない。」「単機能のアドオンをたくさん入れていて、それぞれはそれなりに便利。連携が取れてなくて、痒い所に手が届かない。」そのどっちかを選ばないといけない。一人あるいは少数の作者の頑張りだけに期待しなきゃいけない、期待して待ってなきゃいけない。多機能長大路線を歩むという事は、ユーザにそれを強いるという事だと思う。僕はそれが嫌になった。多機能な物を「作る」だけなら、誰にでもできるんだと思う。当時の僕にもうなる程の時間があった(大学生で、レベルもそんなに高くなかったから楽に単位を取れて、その分自由に時間を使えた)から、できてたんだと思う。大きな問題は「作った」の後にあると思う。多機能長大路線ではそれは難しいと、僕は思った。3.1からは、ウィンドウをまたいでタブを移動できるようになる。アドオンの作者はこれに合わせて修正を行わないといけない場合がある。この機能を実現するために新しく用意された「表示されている2つのフレームの内容を破壊せずに入れ換える」APIは、他の目的でも利用することができる。2008そんなわけで(?)、TBE3に含まれる4つともアップデートした。3.1向けに、最後のタブのクローズボックスを強制的に表示させるオプションを加えた。本体の方でまた隠し設定がどうとか色々変わりそうな気もするけど、とりあえず現時点での仕様に合わせておく。不要になったら機能自体削除の可能性もある。ソース表示タブは、機能は変わってないんだけど、動的に書き換えてるメソッド類がMinefieldでだいぶ変わってるようだったので、その修正が主。Editorとの競合を解消したり、ツリー型タブと組み合わせた時の地味なトラブルを直したり、といった程度。2007タブをバカスカ開く人のために、いろんなアドオンが開発されている。僕が存在を認識している物を、分類して列挙してみた。素のFirefoxでは、タブが多くなると画面外に隠れるタブが出てきてしまい、タブを探したりタブを切り替えたりといった操作が非常に面倒になる。大量のタブをいかにして管理するか、という観点から考えられるアプローチはこんな感じだろうか。一つのウィンドウの中で開くタブの数を少なくする。ウィンドウを「タブのグループ」と見なして、ウィンドウ単位でタブのグループを使い分ける。Showcase:すべてのウィンドウを横断してタブのサムネイル一覧を表示する。→タブカタログ:すべてのウィンドウを横断してタブのサムネイル一覧を表示する。タブのサムネイルはウィンドウごとにグループ化して表示する。一度に大量のタブを一覧できるようにする。一つ一つのタブを小さく表示する。→about:configでbrowser.tabs.tabMinWidthの値を変更。→FishEyeTabs:ポインタが近づくとタブをリアルタイムに拡大して表示する。→FaviconizeTab:タブをアイコンだけの状態に畳めるようにする。一つ一つのタブの大きさは変えない。タブバーを複数行で表示する。Kitタブバーを画面横に移動し、タブを縦に並べる。Kit→ツリー型タブタブ以外の手段で一覧する。ポップアップメニューで見る。→タブバー端の「すべてのタブ」ボタン。Sidebar:サムネイル表示。Tree:ツリー表示。サムネイル一覧で見る。Showcase→タブカタログまた、素のFirefoxでは、すべてのタブが同じように表示されるので、タブ同士の見分けが付きにくい。沢山のタブの中からいかにして操作したいタブを素早く見つけるか、タブを見分けるか、という観点からだとこうなるだろうか。サムネイルで見分ける。Sidebar:タブの代わりに使えるサムネイル付きのボックスをサイドバーの中に表示する。→情報化タブ:タブの中に小さなサムネイルを表示する。Showcase:すべてのタブをサムネイルで一覧する。→Ctrl-Tab:すべてのタブをサムネイルで一覧する。→タブカタログ:すべてのタブをサムネイルで一覧する。Tabs:それぞれのタブにランダムに色を付ける。→ChromaTabs:それぞれのタブに、開いているページの背景色を反映させる。Tabs:開いてから時間が経ったタブの色をだんだん変える。色でグループ分けする。Kit:タブを色分け表示し、リンクから開かれたタブなどについて元のタブと同じ色を付けて、タブ同士の関連性を明示する。形、シルエットでグループ分けする。Groups:タブのセットを丸ごと切り替える、より上位のレベルのタブをFirefoxに加える。→Separe:任意の位置にセパレータ用の特殊なタブを置いて、関連するタブ同士を仕切って表示する。tabs:Separeと同様のセパレータを表示し、同時に、開かれたタブを自動的にドメイン単位でグループ化する。→ツリー型タブ:タブを上か下に表示する場合、リンクから開かれたタブなどについてグループを形成し、グループ同士の間にスペースを空けて表示する。ツリーでグループ分けする。Tree:タブの親子関係をサイドバー内でツリーとして表示する。ツリーの折り畳みが可能。Kit:タブバーをウィンドウの左または右で縦に並べて、ツリー状にインデント表示し、タブ同士の親子関係を明示する。→ツリー型タブ:タブバーをウィンドウの左または右で縦に並べて、ツリー状にインデント表示し、タブ同士の親子関係を明示する。ツリーの折り畳みが可能。「これが抜けてるぞ」というのがあったら指摘をよろしく。僕自身は、以前はTBEで「複数行表示」且つ「グループを色分け」という使い方をしてたけど、TBEにツリー表示機能を加えてからは「ウィンドウ横でツリー表示」で「シルエット(インデント)でグループを判別」という使い方に変わった。同じ色のタブの「グループ」が途中で改行されると混乱の元だし、そもそも色を判別しにくい環境だと、色での判別自体が困難になる(僕自身は特に色弱とか色盲とかの症状はないと思うけど)。それに比べて、タブのインデントのようにシルエットでのグループの明示は、色の再現性が悪い環境でも影響を受けないし、視認速度の点でも圧倒的に上回ってると思う。縦一列にシーケンシャルにタブが並んでいるから、複数行表示のような二次元の配置に比べれば視線の移動は少なく済みそうな気もする。いう事情があったのでツリー型タブではタブの複数行表示機能はオミットしたし、そもそもタブバーを画面の左右以外に置くという設定も設けるつもりは元々なかった(汎用性を高く作ってたら、たまたまできちゃった、という感じだ)。勘違いしちゃいけないというか固定観念に囚われちゃいけない部分だと思うんだけど。ここまで「タブ」という言葉を軸にして書いてみたけど、実際の所は別に「タブ」が重要なわけではない。あるWebページを一つの画面に表示しきれないから、現在表示されていない分のWebページへアクセスするための「目印」、「手がかり」だけを見えるいちに表示させておく。その概念を現実に僕らが目に触れる物に当てはめた時に、書類を綴じたファイルの中のあちこちを行ったり来たり、あるいは机の引き出しの中を行ったり来たりするために使っている「タブ」が、一番誰にでも分かるしっくり来るメタファだった、ただそれだけのことなんじゃないかと思う。Separeのような「セパレータ」の導入やタブの色分け、タブにサムネイルを......というのは、「タブ」という現実のメタファに則って発想された、「多数のタブをより効率よく管理するための工夫」と言えると思う。それに対して、ツリー表示とかサムネイル一覧とかは、そういう「現実世界のメタファのタブ」の制約を超えて別の次元に飛び出している、「沢山のWebページ」というものをタブよりもより的確に視覚的に表現する試みと言えるんじゃないだろうか。Vistaのウィンドウ切り替えのアレは、見た目は派手だけど、前述のような「沢山のものをより効率よく一覧する」「沢山のものの中から目的のものを見つけ出す」という観点からの工夫には欠けていて、だから実用性はイマイチなんじゃないか?)。「タブ」というメタファに依拠すると、そのUIの使い方を誰でもすんなりと理解できるようになるけれども、しかし同時に「タブ」という現実の存在が持つ色々な制約に発想が囚われてしまう。その制約から離れればツリーとか全サムネイル一覧とか、あるいは検索ベースの一覧のような物も生まれ出てくるけれども、今度は逆に、それが何を意味しているのかというメンタルモデルを構築する手がかりがないために、使い方が分からず戸惑ってしまうリスクが増える。2007タブブラウザ拡張3を公開しました。......といっても実際にタブブラウザ拡張のバージョン3を作ったわけではなくて、情報化タブ、マルチプルタブハンドラ、ツリー型タブ、ソース表示タブを以前訳したマルチアイテムパッケージの作り方のまんまで一つにパッケージングしただけですハイ。「TBE3」をインスコすると上記4つのアドオンがアドオンマネージャに普通に並びます。要望等はあると思うけど、僕にとってはこれだけ揃ってたら「TBE3」と名前を付けてもべつにいっかなーと思えている、僕にとっての「タブブラウザ拡張」の「他では替えが効かないもの」はこういう事かな、という感じです。僕自身はこれに加えて以下のアドオンを組み合わせて、旧TBEで使ってた操作感をなるべく再現して使ってる。Button:閉じたタブを一覧からすぐに開き直せるように。Options:タブバー上でのダブルクリックで新規タブ、タブバー上での中クリックで閉じたタブを復元、という操作をするため。それ以外の機能は使ってない。Remover:127.0.0.1とかlocalhostとかからのリファラ送信をカットするために。Removerで代用可能)、JavaScript・Cookie・Refreshによる自動リロード・プラグイン・画像表示それぞれのタブごとの有効無効の設定、それらの情報をブックマークに保存する、といった機能か。2リリースの時から数えれば1年近く)できずにいたので、ついにここまで来たかぁ、と感無量です。TBE3に含まれている4つのアドオンはどれも一応最近のMinefieldで動作確認はしてるので、次のFirefoxメジャーアップデートの時には今回よりはすんなり移行できるんじゃないかなと思ってる。UIまわりが(特にタブが)色々変わる可能性はあるようなので安心はできないけど。