たまに18歳未満の人や心臓の弱い人にはお勧めできない情報が含まれることもあるかもしれない、甘くなくて酸っぱくてしょっぱいチラシの裏。RSSによる簡単な更新情報を利用したりすると、ハッピーになるかも知れませんしそうでないかも知れません。
の動向はもえじら組ブログで。
宣伝。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。 以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能!
という報告を受けて調べてみて、解決策が見えなくて頭を抱えてる。
原因はFirefox 3以降でタブの拡張性が深刻なまでに低下したことに起因している。現在、Firefox 3でタブの中に独自の要素(ツリー型タブの「ツリーの開閉状態を示すアイコン」「折り畳まれたタブの数を表示するラベル」など)を追加しようとすると、バインディングを上書きしてやらないといけない。でも複数のアドオンでバインディングを上書き上書きとやってると、最後にバインディングを適用した誰かの物だけが生き残って、他のアドオンが追加したバインディングは全滅してしまう。今回の問題も、ツリー型タブがFirefox自身の提供するバインディングを上書きした後から、Vimperatorがさらにバインディングを上書きしているために、タブの要素構造がツリー型タブが想定する構造から変化して、初期化に失敗するようになってしまっている。
ツリー型タブ、マルチプルタブハンドラ、情報化タブの3つを開発するにあたっては、この問題に対処するために、以下のような方針をとることにした。
これを実現するために作ったのがこちらのライブラリ。3つのファイルで構成されてる。
3つを同じ所に置いてXULファイルだけをオーバーレイで読み込ませると、バインディングを上書きする。他のアドオンで同じライブラリが読み込まれてる時は、最新の物が使われる。
これをVimperatorの作者の人にも使ってもらえればいいんだけど……誰にコンタクトすればいいか分からないし、そもそも向こうにはわざわざこれを使う動機がない。Vimperatorユーザは基本的にVimperatorのカスタマイズですべてを解決する傾向にあるようだから、他のアドオンとの互換性が低くても問題にならないだろうし。
ていうか僕自身Vimperator使ってないから、わざわざ上記のような交渉をしようというモチベーションがない。というわけで、上に名前が出てる3つのアドオンのどれかとVimperatorとを共存させたいVimperatorユーザの人は、自分で作者にコンタクト取ってください。(丸投げ)
Tree Style Tab 0.7.2009040901公開した。アニメーション効果の実装の他に、細かいバグ修正も色々。
あと、実際どんな感じかというのをわかりやすく示せるかなと思って、デモ動画も作ってみた。CamStudioもNiVEも使うの久しぶり(っていうかVistaにしてからは初)だから、やり方思い出すのに苦労したよ……
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/M9dUfyoHz3E&hl=ja&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/M9dUfyoHz3E&hl=ja&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>
ヌルヌル動いてるのは倍速再生してるわけではなく、これで等倍速です(一応)。タブの影はbox-shadowで描画してるので、Firefox 3.0.xだと影無しになります。
しかしYouTubeはアップロードが簡単になってるわ画質が上がってるわで、いつの間にかすんげーパワーアップしてますね。Stage6とかあった頃とは隔世の感があります。
以下余談。
実装の最後の段階になって困った点として、画面外にタブが開かれた時にそこまで自動スクロールしてくれないという問題が起こってた。スクロールしても、新しく開かれたタブの一個前のタブの位置にスクロールしちゃったりして。上の動画で言うと、0:57あたりで画面下の方でサブツリーを展開した時に、子タブが画面内におさまるように自動でスクロールしてるけど、これがちゃんと動かなくなってた。
なんでこんな問題が起こってたかというと、「そのタブが画面外にあるのかどうかを判定する」「そのタブの位置までスクロールする」といった処理が全部「タブの座標」を基準にしてたせいで、アニメーション開始時点やアニメーション中の中途半端な座標を元に処理を行ってしまい、もうシッチャカメッチャカになってた、という……
上記の処理を行う時に、アニメーション中の座標とアニメーション終了後の座標とのズレをきちんと考慮して計算してやればいいってだけの話なんだけど、普通に考えるとこれがめんどくさい。それぞれのタブがちょっとずつズレて表示されてるわけだから、座標を調べたいタブだけじゃなくてそれより前(上)にあるタブ全部について、そのタブはアニメーション中か?とか、そのタブは非表示か?とかを判別しながらオフセット値を調べないといけないわけで……いちいちそんな計算するのはめんどくさすぎる。メンテナンスし辛そうだし、コードの量が多くなりそうだし、真面目に書く気しないです(大学生の頃だったらやってたかもだけどね……時間は有り余ってたから)。
で、代わりに以下のようなやり方を思いついた。
コードにするとこんな感じ。
getYOffsetOfTab : function(aTab)
{
return document.evaluate(
'sum((self::* | preceding-sibling::*[not(@tab-collapsed="true")])'+
'/attribute::tab-y-offset)',
aTab,
null,
XPathResult.NUMBER_TYPE,
null
).numberValue;
},
sum()
は、渡されたノードセットの値を数値として合計したものを返すXPathの関数。受け取る結果の型をXPathResult.NUMBER_TYPE
と指定すれば、計算結果の数値を直接得られる。XPathはうまく使えばこんな風に、処理対象のノードの絞り込みだけじゃなくその後の処理(ここでは計算)まで一発で済ませられるので面白い。
トゥイーンの話を受けてごろたんがさらに発展的な話を書いてくれた。で、「ほうほう、こういうのをeasingと言うのか……」と自分の無知っぷり&何も知らんくせに偉そうなことを語る厚顔さに恥じ入りながら先のエントリを少し手直しした。
で、JSTweener という Tweener (as3 のモーショントィーンライブラリ) 互換のライブラリを使うと、標準で様々な easing 関数が利用できたり、タイマーが一つなので、数百, 数千オブジェクトをモーションさせるときにはだいぶ高速になる。
というのを読んで、確かに先のエントリに書いた物はいっこいっこのタブごとにタイマー走らせるから効率悪いよなあ、と思い、1個のタイマーだけで複数のアニメーションを走らせるための簡単なライブラリを作ってみた。ツリー型タブの開発版にも早速組み込んでる。
window['piro.sakura.ne.jp'].animationManager.addTask(
)
にアニメーション用の関数その他の引数を渡してやると、それを共通のタイマーで処理する、というごく単純なもの。window['piro.sakura.ne.jp'].animationManager.removeTask(
)
で関数の登録を解除してやる。クロージャ使って書くこと前提の不親切なAPIですんません……
以前、ツリーの折りたたみでアニメーションするようにしてみた事があった。
この界隈には、GUI要素のアニメーションは嫌いで片っ端から無効にしてて、Web上でもアニメーション効果が使われてると「ウザッ」と思う、というタイプの人が多そうだと思う。でも、アニメーション効果ってのはインターフェースの見た目を考える上で結構バカにできない。
現状のように一気にすべての子タブが出たり消えたりすると、「最初の状態」と「最後の状態」の差が大きすぎて、今自分がどのタブを見ているのか見失ってしまう事がある。でもアニメーションで少しずつ折りたたんだり少しずつ展開したりする事で、「最初の状態」と「最後の状態」の間を段階的に変化させてやると、それほど戸惑わなくて済むようになる。こういう、2つの状態の間を埋めるアニメーションのことを一般にトゥイーンと呼ぶ。使い所を間違えなければ、アニメーションするインターフェースは人にやさしいものとなる。
問題は、再描画が頻繁にかかるのでPCの性能次第では激重になってしまうということ。以前試した時も、自分の環境でとんでもなく重い結果になってしまったので、導入を諦めてた。
で、今日ふと思い立ってもう一度試してみたところ、VistaのAeroが快適に動くような環境ではさすがに快適に動作してくれることが分かった。上記のような小難しい理屈を抜きにしてもヌルヌル動きまくりなのが単純にスゲー面白い。今回はかつて諦めた時のようなフレーム数固定(何回描画したら終わり、というやり方)ではなくフレームレート可変(何秒以内にできる限りの回数だけ描画する、というやり方)で処理するように実装してみたので、貧弱な環境でもそれほど重くはならないと思うんだけど……一応会社のマシンとかで試してみて、問題なさそうなら次版でデフォルト有効にしてみようと思う。
ここでは折りたたみのトゥイーンについてだけ書いてるけど、今回最初に取り組んでたのは元々はインデント幅の変更部分のトゥイーンだった。インデント幅の調整くらいだったらそれほど負荷は高くないだろう、という考えでやり始めたんだけど、最終的には折りたたみまで含めてアニメーション化しても結構気持ちよく動いてくれたということで、上のような話になっている。
面白い副作用として、インデント幅の調整と「折り畳まれたタブを元の状態に戻す」処理とが同時に走ると、まるで画面の左上からその位置にタブが落ちてきて填り込むようなエフェクトになる事に気がついた。どこにタブが増えたかを見失いにくくなる、という効果があるんじゃないかと思う。また、Vista+Aeroだと割となんでもアニメーションするので、その中に結構馴染んでる気もする。
追記。Let's note W7のUbuntuだと、Shiretokoだとわりかしヌルヌル、Firefox 3.0.xだとフレーム落ちで単純にアニメーションしてないように見えるだけという感じ。ドスパラのWindows XPマシンでも同じような感じだった。コマ落ちした場合でも最低1回は再描画があるので、ワンテンポ遅れる感じはあるんだけど、アニメーションしてる間反応がなくなるという風なことはないので、とりあえず次版から有効にしようと思う。(無効にする設定はもちろん付ける)
こんなメールが@google.comなアドレスから来たわけですが。(以下、適当訳は僕による物)
We are working on developing extensions for Chrome and are interested in exploring an opportunity to bring Tree Style Tab to Chrome. The initial design documents may be found here:
今私達はChrome用の拡張機能の開発のために働いており、Tree Style TabをChromeに移植する可能性について関心を持っています。最初の設計書は以下にあります:
http://dev.chromium.org/developers/design-documents/extensions
Further information on the API's that are up for consideration may also specifically be found here:
検討中のAPIについてのさらなる情報はこちら:
http://dev.chromium.org/developers/design-documents/extensions/apis As things further develop, the site will be updated and more information will become available."
将来的に、このサイトは更新され、より多くの情報が利用可能になる予定です。
で、この後にアンケートの案内が続く。アンケートはAPIの案に挙がってる物の中でどれが欲しいかというもので、自由回答欄もあったので、こう答えておいた。
Tree Style Tab totally restructures Firefox's tab bar. If I try to import it to Chrome, I'll need high flexibility not only Greasemonkey-like, but userChrome.js-like to control Chrome's UI from script.
Tree Style TabはFirefoxのタブバーを全体的に再構築します。もしChrome用に移植するなら、Greasemonkey風のものだけでなくuserChrome.js的な、ChromeのUIをスクリプトから制御する高い柔軟性が必要です。
どんなアドオンなのか中身を見ないでとりあえずAMOのおすすめリストから適当に選んでコンタクトしてきてんじゃないか?という気もする(速度重視の設計思想のChromeには、ツリー型タブを移植可能にするような高いカスタマイズ性はそぐわないと思う)。とはいえ、アドオン作者の積極的な取り込みのために動いてるとは、Google本気だな。
とりあえず僕個人に関しては、
という感じなので、僕がChromeにツリー型タブを移植するか?というと、可能になったとしてもやらないんじゃないかって気がする。リポジトリは公開してるから、やりたい人はどうぞお好きにってことで……
popInが入っているとテキストリンクが動かない、ことの理由はどうも以下の2点によるみたい。
stopPropagation()
しているため、テキストリンクにイベントが渡されなくなっている。stopPropagation()
されない状態にしてテキストリンク側でイベントを拾って処理を行おうとしても、イベント発生時とテキストリンクが処理を行う時とでDOMツリーの構造が微妙に変わっていて、正常に動かない。何か有効な対策が無いか考えてる。
ところでpopInは内部的にjQueryを使ってるようなんだけど、その旨の表記を僕には見つけられなかった。jQueryはMITライセンスとGPLのデュアルライセンスで、MITを選択した場合でもThe above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
(著作権表示とMITライセンスの許諾表示をソフトウェアの全コピーかもしくは重要な箇所で示す必要がある)ということなので、下手したらMITライセンスの違反ということになるような気が…… (一応フィードバックフォームから送ってはみた)
テキストリンクをThunderbirdにもインストールできるようにしたのにAMOのサイト上ではFirefox専用のままになってしまう件についてボヤいたところ、くでんさんに「Bugzillaで言えばいいじゃない」的な指摘を受けたので、確かにその通りだと思って、念のため新しくバグ報告する前に「target」あたりのキーワードで検索してみたら、Adding new compatible application fails when it's the first oneというバグが出てきて、でもFIXEDになってて「おっかしーなー」と思いながら最初に添付されてたスクリーンショットを見てみたら「Add New Application」と書かれたボタンがあって「なんじゃこりゃあああああこんなん見たこと無いぞおおおお?!」と思って、バグ報告しようとした時に「対象アプリケーション」の英語版表記を知りたくて英語ロケールに切り替えた状態になってたままで開発者用ページのトップに移動したら「新しいUIを試してみよう」みたいな今まで見たことない告知が一番上に表示されてて、そこから辿っていったら今テスト中らしい新UIにアクセスできて(新UIはまだ日本語じゃ利用できないようで、日本語に切り替えてアクセスしようとしたら見れなかった)、それを使うと手動で対象アプリケーションを追加できた。
あと、今までは一度アップロードしたバージョンは、ファイルを削除することはできてもその「バージョン」自体を無かったことにはできなかったんだけど、新UIの方ではそういうファイルが無い状態になったバージョンを「削除」する機能も加わってた。やっときたか……ていうかなんで今までできなかったんだ?
テキストリンク バージョン3.1以降で、Thunderbirdでも利用できるようにした。
プレーンテキスト形式のメールでは、Thunderbird自体のURI自動認識の処理を置き換える形で動作する。 Thunderbird本体のURIの認識部分は結構いいかげんなので、地の文とURIが連続してるとたまに酷い事になる。テキストリンク導入後は、Thunderbird自身による抽出結果を一旦全部白紙に戻して、もう一度URIの認識を自力で行うようになる。
同じような事をするアドオンが他にもありそう(っていうかFirefoxではLinkificationがそうだ)だけど、自分では見つけられなかったので……
ところで、AMOの方にもアップロードしたんだけど、過去にFirefox専用として登録したアドオンは後からThunderbirdにも対応した後も、Firefox専用アドオンとして扱われてしまって、Thunderbird Add-onsの方からは辿る事ができないようだ。これってどうにかならんのだろうか。
Tree Style Tabで選択可能な組み込みのスタイル指定の一つとして、Mac OS X上のデフォルトテーマ風の物を、cho45さんのStylish用スタイル定義を参考にして作ってみた。 スクリーンショットはVista上での物だけど、OS X上でも確認はしてるのでご安心を。
Firefox 3以前の環境ではcho45さんのスタイル定義ほぼそのまんまを適用するようになってて、その場合はタブの高さが26ピクセル固定になってしまうのでタブの中に何か追加する系のアドオン(具体的にはInformational Tab)との相性が非常に悪い。
で、それをなんとかする方法として、Firefox 3.5以降ではborder-imageが使えるということを思い出したので、その実験というか練習も兼ねて使ってみる事にした。
普通に考えると、tab要素自体に-moz-border-imageを指定すればそれでおしまいという事になるんだけど……ツリー型タブの場合はドロップ位置のマーカーを表示するためにborderを多用してるので、-moz-border-imageをtabに指定すると都合が悪い(普通のborderと同時に指定した場合、-moz-border-imageの方が優先されるようだ)。かといって、内側や外側にもう一つタブ全体を囲うXUL要素を増やそうとすると、他のスタイル指定と激しく競合して見た目がグチャグチャになるし……
で、色々試行錯誤して、Firefox 3以前でタブの右・左・中央のそれぞれに異なる背景画像を表示するために使っていたボックスを流用して解決する方法を思いついた。
この拡大図で言うと、9個に分けられた各領域を普通だったら一つのボックスのborder-imageでカバーするところを、今回は1~3・4~6・7~9の3つのボックスに分けている。-webkit-border-imageや-moz-border-imageの例として紹介されているコードでは4つの辺の幅を同じにしてる例が多いけど、実は4つの辺はそれぞれバラバラに幅を指定できる。なので、
url("共通の画像") 10 10 10 10 / 10px 0 10px 10px
で右の辺の幅を0に。url("共通の画像") 10 10 10 10 / 10px 0 10px 0
で左右の辺の幅を0に。url("共通の画像") 10 10 10 10 / 10px 10px 10px 0
で左の辺の幅を0に。という風にしてやる事で、1枚の画像で3つのボックスそれぞれに異なる部分を切り出して適用するような効果を得られる。
また、このままだとタブの高さがborder-imageの幅の分だけ高くなってしまう(border-imageの上辺+タブのラベルの高さ+border-imageの下辺=タブの高さ)ので、タブのラベルやアイコンなどに対して上下にネガティブマージンを設定して、強制的にタブの高さを小さくするようにしてみた。上の図は切り出し位置を示すためにわざと高さを広げた状態だけど、ネガティブマージンを効かせれば、冒頭のスクリーンショットのようなスリムなタブになる。
ツリー型タブに似たアドオン2つを新たに知った。
VertTabbarは、タブバーをウィンドウの右または左に移動して縦列タブにするアドオン。Vertigoはずいぶん昔に更新が止まってるようなので、その代替と言えるだろうか。カスタマイズ機能も色々あるみたい。
タブグループマネージャーは、名前から見ても機能的にもTabGroupsの後継っぽい。でも多分中身は全然別物なんだろう。今見てないグループのタブ全部をメモリから追い出して省メモリにする機能とか、検索バーからの検索結果を自動的にグループにする(セカンドサーチとも連携できるらしい)とか、色々高機能だ。