たまに18歳未満の人や心臓の弱い人にはお勧めできない情報が含まれることもあるかもしれない、甘くなくて酸っぱくてしょっぱいチラシの裏。RSSによる簡単な更新情報を利用したりすると、ハッピーになるかも知れませんしそうでないかも知れません。
の動向はもえじら組ブログで。
宣伝。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。
以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能!
マシンはLet's note CF-W7。Ubuntu 8.10→9.04の時もいくつかトラブルが起こっていたけれども、今回もやっぱりトラブルがついてきた。
アップグレード後。
なんで無線LANが使えないのか分からなくて、池添さんや小野寺さんに色々助けて貰いました。自分で面倒見きれないくせに使うなって話ですよね。ごめんなさい。
こたせんせがHTML5の話をされると聞いて、全然追いかけてないからそろそろ情報仕入れとかなきゃなーと思って、お説教を聴きに行って参りました。
どちらかというとAPIの面に期待してたので、そっちは話さないよと冒頭でバッサリ切られちゃってとても残念でした……
聞いた中で「ほう」と思ったのはこの辺。
質問タイムがなかったけど、あったら訊いてみたかったこと。
会場に入って後ろで立って話聞いてたんだけど、前に立ってる人がしきりに「ふんふん」「うんうん」と頷いて、熱心にメモを取っているのを見て、ちょっとなごんだ。
Firefoxでは、タブがセッション情報も伴って復元された時に、SSTabRestoring
とSSTabRestored
という2つのイベントが発行される。イベントのoriginalTarget
はいずれも復元されたタブの要素で、SSTabRestoring
はセッション復元処理が走ったけれどもタブの読み込みは完了していない段階、SSTabRestored
はタブの読み込みが完了した段階で発行される。
これらのイベントが発行される場面は、3つある。
この3つの場合を、特に1とそれ以外とを判別したい、その方法を考えてみたよ、というのがこのエントリの主題です。
例えばツリー型タブでは、タブの親子関係が変更された時のインデントの変更やツリーの折りたたみ時にアニメーション効果を適用している。しかしながら、Firefoxのセッション復元時に複数のタブのツリー構造を一気に変更する場合には、いちいちアニメーションしてたら重くてしょうがない。なので、この時だけはアニメーション効果を適用しないようにしたいと僕は思った。
しかしながら、前述のSSTabRestoring
とSSTabRestored
からは、そのイベントが発行されたのが上記の3つの場面のうちいずれなのかが分からない。どの場面でイベントが発行されたのかを判別するには、他の情報も参照する必要がある。
実は1の場合については、セッションが復元される時にObserverServiceに登録したオブザーバに対してsessionstore-windows-restored
というメッセージが通知される。なので、これを監視すればいいんじゃないか?と、最初のうちは考えてた。
でも、話はそう単純には済まなかった。実際にイベントを監視してみると、セッション復元時には以下のような順番でイベントが発行されていることが分かった。
SSTabRestoring
イベントが発行される。sessionstore-windows-restored
が通知される。SSTabRestoring
イベントが順番に発行される。SSTabRestored
イベントが読み込みの終わった物から発行される。3と4はこの通りにならないこともあって、あるタブのSSTabRestoring
が発行されてすぐに読み込みが完了したタブについては、次のタブのSSTabRestoring
が発行される前にSSTabRestored
が発行される場合もある。
一番致命的なのは、複数タブのセッション復元が始まったことは通知されるのに、全部のタブのセッション復元が終わったことは通知されないという点だ。
sessionstore-windows-restored
が通知されたらその後に発行されたSSTabRestoring
は全部ウィンドウ単位のセッション復元の一部なんだな、と判断してしまうと、例えば10個のタブを開いたウィンドウのセッションを復元した後、1つタブを開いて、閉じて、開き直した時、そのタブまで「ウィンドウ単位のセッション復元の一部」と誤爆してしまう。SSTabRestored
が発行されるまでの間にSSTabRestoring
が発行されたタブ」がウィンドウ単位のセッション復元なんだな、と判断してしまうと、後続のタブのSSTabRestoring
よりも前にSSTabRestored
が発行された時に、セッション復元が終わってないのに終わったと見なされてしまう。という具合で、「ウィンドウ単位でのセッション復元の終わり」がいつなのかが分からないと、誤爆しまくりで全然役に立たない。
また、重ねて困ったことに、sessionstore-windows-restored
の通知はsubjectがnull
なので、どのウィンドウでセッション復元が開始されたのかすらオブザーバ側からは分からない。別のウィンドウでセッション復元がはじまった時に来た通知を見て「これからこのウィンドウで開き直されるタブは全部、ウィンドウ単位のセッション復元の一部なんだな」と判断してしまってはいけない。
dump()
をコードの中に埋め込んで調べたところ、nsSessionStore.js内の各処理とイベントは、以下のような順番で起こっているらしいということが分かった。
SSTabRestoring
が発火sessionstore-windows-restored
が通知されるSSTabRestoring
が発火×タブの個数分SSTabRestored
が発火×タブの個数分SSTabRestored
が発火したら、すべてのタブの復元が完了このうちnsSessionStore::restoreHistoryPrecursor()やnsSessionStore::restoreHistory()やnsSessionStore::restoreDocument_proxy()は、タブを1つ復元するだけの時にも使われてる。
よくコードをよく読むと、nsSessionStore::restoreHistoryPrecursor()の中で「復元するタブの数だけ新しくタブを開く」「それらのタブのtab.linkedBrowser.parentNode.__SS_data._tabStillLoading
をtrue
にセットする」という処理が行われて、その後でsessionstore-windows-restored
がオブザーバに通知されていた。(このtab.linkedBrowser.parentNode.__SS_data._tabStillLoading
は、タブの復元が完了した段階でundefined
になる。)
ということは、sessionstore-windows-restored
が通知された時にウィンドウ内の全部のタブを調べて、tab.linkedBrowser.parentNode.__SS_data._tabStillLoading
がtrue
であるタブが2つ以上ある(復元待ちのタブが複数ある)なら、そのウィンドウでこれからウィンドウ単位のセッション復元が行われようとしている、と考えてよいわけだ。
で、SSTabRestored
が発行される度に復元待ちのタブの数を確認して、復元待ちのタブの数が0になったら、ウィンドウ単位でのセッション復元が終わったと判断できる。
厳密には、「ウィンドウ単位でのセッションの復元中に別途タブを1個だけ復元した」という場合にもそのタブが「ウィンドウ単位のセッション復元の一環で復元された」と見なされてしまうので、この方法にも穴はある。たくさんのタブのツリー構造を一気に変更した時にアニメーションでクソ重くなるのを避けたい、という僕の目的ではこれで必要十分なので、これ以上は追求してない。
以上をコンパクトにまとめると、こんな感じになる。
var ObserverService = Cc['@mozilla.org/observer-service;1']
.getService(Ci.nsIObserverService);
var observer = {
restoringWindow : false,
getRestoringTabsCount : function() {
return Array.slice(gBrowser.mTabContainer.childNodes)
.filter(function(aTab) {
var owner = aTab.linkedBrowser;
var data = owner.parentNode.__SS_data;
return data && data._tabStillLoading;
}).length;
},
observe : function(aSubject, aTopic, aData) {
if (aTopic == 'sessionstore-windows-restored')
this.restoringWindow = this.getRestoringTabsCount() > 1;
},
handleEvent : function(aEvent) {
switch (aEvent.type) {
case 'load':
window.removeEventListener('load', this, false);
window.addEventListener('unload', this, false);
gBrowser.addEventListener('SSTabRestoring', this, false);
gBrowser.addEventListener('SSTabRestored', this, false);
return;
case 'unload':
ObserverService.removebserver(this, 'sessionstore-windows-restored');
window.removeEventListener('unload', this, false);
gBrowser.removeEventListener('SSTabRestoring', this, false);
gBrowser.removeEventListener('SSTabRestored', this, false);
return;
case 'SSTabRestoring':
this.onTabRestoring(aEvent);
return;
case 'SSTabRestored':
this.onTabRestored(aEvent);
return;
}
},
onTabRestoring : function(aEvent) {
var tab = aEvent.originalTarget;
if (this.restoringWindow) {
// ウィンドウ単位でのセッション復元時の処理
}
else {
// タブが個別に開き直された時の処理
}
},
onTabRestored : function(aEvent) {
if (this.restoringWindow)
this.restoringWindow = this.getRestoringTabsCount() > 0;
}
};
window.addEventListener('load', observer, false);
ObserverService.addObserver(observer, 'sessionstore-windows-restored', false);
セッションストアAPIを使ってタブにいろんな情報を紐付けて、その情報に基づいてあれこれしたい人には、役に立つんじゃないでしょうか。(でもそんな変なことやってる人はほとんどいないんだろうなー)
I would like to see a shortcut assigned to show/hide the tab bar with the next update. That would be very useful since I reckon, since I have to click every time I want to show/hide it, which every time I want to read some thing on the web, which is way too frequent.
次のアップデートで、タブバーの表示・非表示の切り替えのためのキーボードショートカットを追加して欲しいです。私が思うにそれはきっととても便利でしょう。Webで何かを読もうと思う度に、タブバーの表示・非表示を切り替えるために今は(タブバーを?)その都度クリックしていますが、この操作が頻繁すぎて面倒です。
I'm very sorry, currently I have no idea to add new shortcut to show/hide tab bar. Instead, if you press "Ctrl" key for a while, collapsed tab bar will be expanded while you press the key. I hope it helps you.
If you like, you can call internal methods to show/hide tab bar from keyboard shortcuts defined by keyconfig or KeySnail. For example:
// toggle mode shown <=> hidden (shown <=> shrunken)
TreeStyleTabBrowserAutoHide.toggleMode();
// set to "shown"
TreeStyleTabService.setTreePref('tabbar.autoHide.mode',
TreeStyleTabBrowserAutoHide.prototype.kMODE_DISABLED);
// set to "hidden"
TreeStyleTabService.setTreePref('tabbar.autoHide.mode',
TreeStyleTabBrowserAutoHide.prototype.kMODE_HIDE);
// set to "shrunken"
TreeStyleTabService.setTreePref('tabbar.autoHide.mode',
TreeStyleTabBrowserAutoHide.prototype.kMODE_SHRINK);
Note: These examples work on Tree Style Tab 0.8.2009100101 or later.
すみません、今の所タブバーの表示・非表示を切り替えるショートカットを加える予定はないです。その代わり、Ctrlキーを長押しすると、非表示になっていたタブバーがCtrlキーを押している間表示されるという機能があります。これが助けになることを願っています。
お好みで、タブバーの表示・非表示を切り替える内部的な機能をkeyconfigやKeySnailで定義されたショートカットから呼ぶこともできます。例は上記の通りです(ツリー型タブ0.8.2009100101以降で動作します)。
In Tree Style Tab extension, would it be possible to make the background (dark gray blank area) display an image? Maybe with a userstyle or script...
ツリー型タブで、タブの背景(暗いグレーの空白の領域)に画像を表示できませんか? ユーザースタイルシートかスクリプトを使えばできると思うんですが……
On Firefox 3.6, you'll be able to make the background color of the tabbar transparent, like following CSS in the userChrome.css:
tabbrowser[treestyletab-style][treestyletab-mode]
.tabs-stack,
tabbrowser[treestyletab-style][treestyletab-mode]
.tabbrowser-tabs,
tabbrowser[treestyletab-style][treestyletab-tabbar-position]
.tabbrowser-tabs {
background: transparent !important;
}
On Firefox 4:
:root[treestyletab-style][treestyletab-tabbar-position]
#appcontent,
:root[treestyletab-style][treestyletab-tabbar-position]
tabbrowser,
:root[treestyletab-style][treestyletab-tabbar-position]
.tabbrowser-strip {
background: transparent !important;
}
Another way, you can get transparent tab bar with a secret preference "extensions.treestyletab.tabbar.style.aero". Go to "about:config" and turn it to "true".
上記のようなCSSをuserChrome.cssに書くと、タブバーの背景色を透明にできます。1つ目はFirefox 3.6用、2つ目はFirefox 4用の指定です。
また別の方法として、隠し設定「extensions.treestyletab.tabbar.style.aero」でもタブバーを透明にできます。「about:config」を開いて、この設定の値を「true」に変更して下さい。
XUL/Migemo 0.12.xで、機能を他のアドオンとかから呼び出すためのAPIを刷新してみたよ。
古いAPI(はてなブックマーク拡張とかが使ってくれてるやつ)は僕自身が色々よく分からないまま作った物だったために、引数を文字列で渡さないといけないとか戻り値も正規表現オブジェクトではなく文字列だとか、色々と使い勝手が悪かったと思う。メインウィンドウ以外では呼び出す時にいちいちXPConnect使わないといかんし。
新しいAPIは、それに比べたらものっそシンプルになった。XPConnect使わなくてもmigemo.getRegExp('hoge')
とか書くだけで使えるし、戻り値もすぐに使える正規表現オブジェクトが返ってくるし。互換性を保つために旧APIはそのまま残してあるので、旧APIを使ってるアドオンが動かなくなるということはないけど、今後は使うなら新APIの方を使うのがお勧めです。
で、このAPIはWebページ内のスクリプトでもCPUの使用率を取得できるようにするAPIを提供する例のアドオンの技術の応用なので、Webページ内のスクリプトからもXUL/Migemoの機能を利用できてしまいます。
ただしスクリプトの実行権限の関係で、上記のmigemo.getRegExp('hoge')
のような、正規表現オブジェクトを直に受け取る機能は使えません。代わりにJavaScript/Migemo互換の、正規表現のソース文字列を返すAPI migemo.query('hoge')
などを使う必要があります。
XUL/Migemo 0.12.2以降が入ってる環境でこのページを表示してれば、以下のデモを試せるはず。
ページ内検索系のメソッドもあるんだけど、多分使いでがなさそうなので解説は用意してないです。
すでに上でもリンクしてるけど、エンジンごとページ内に埋め込めるJavaScript/Migemoという実装もあるから、XUL/Migemoを入れてるFirefoxユーザでないと使えないこのAPIってなんか意味あんの?と言われそう。深くはツッコまないでください。
以下、補足事項。
当初このエントリでは、「Webページ上のスクリプトからもmigemo.getRegExp('hoge')
のようにして正規表現を取得して利用できる」という風な書き方をしてたけど、これは大間違いだった。戻り値の正規表現オブジェクトが生成された実行コンテキストがUniversalXPConnect特権のある場所なのに対して、呼び出し元は特権のない普通のWebページ上であるため、それぞれの権限が違うので本来ならその正規表現の各メソッドは実行できないのが正しい。
ただ、Gecko 1.9.1(Firefox 3.5)以前のバージョンにはバグがあって、上記のようなセキュリティのチェックが働かないために、戻り値の正規表現の各メソッドを呼べてしまう状態になっていた。
このバグはGecko 1.9.2(Firefox 3.6)以降ではすでに修正済みで、実際、Trunk等で戻り値の正規表現オブジェクトのメソッドを呼ぼうとすると、その場で処理が中断されて Error: RegExp.prototype.toString called on incompatible ChromeObjectWrapper というエラーがエラーコンソール上に出力される。
ということで、JavaScript/Migemo互換のAPIとして正規表現オブジェクトのソース文字列だけを返すような機能を0.12.2で新たに加えた。文字列や数値などのプリミティブ値に対してはセキュリティのチェックが行われないようなので、こっちはGecko 1.9.2以降でもWeb上で使える。
Tab Progress BarのプログレスバーがFirefox 3.7のモックアップ風なのを見て「羨ましい!」と思ったのでInformational Tabのデフォルトスタイルをそのように変えてみた。一応、設定で今まで通り(ラベルの下に表示)にも戻せる。
で、やるならとことんやってみっか!と一念発起して、モックアップにあるような光るプログレスバーを再現しようと頑張ってみた。
伸びるバーの部分は背景画像で、ぽわーんと光った感じは-moz-box-shadowを使ってるので、Firefox 3.5じゃないと期待通りには見えない。
匿名云々の話になるとどうしても感情的になってしまう。そこに「ネットはバーチャル」「ネットは現実と切り離して好き勝手暴れまくるための掃き溜め」みたいな話が入ってくるとなおのこと。
匿名であることを全面的に非難するとか、実名を明らかにすることを強要するとか、そういう考えは無い。自分も匿名でつぶやくことはあるし。
何に対して激しくアレルギー反応を示してるかって、やっぱり、匿名で安全圏から石投げてくる奴らにイラつかされてきた……という印象があるから、そういうのに対して過敏になってるんだろう。「実名晒すとか馬鹿かよwww俺はネットは便所の落描きにしか使ってないしwwww承認はオフラインで十分得られてるしwwwwお前みたいなウスノロはネットというただの便所にしがみついておこぼれにあずかってろよwwwwホレホレ悔しかったらリア充になってみろよwwwwまあ無理だけどなwwww」みたいに言われてるように感じる。
僕が実名をWebで出し始めたのは、Mozilla用の拡張機能のライセンス文に本名を書く必要があるものと思い込んでいたためだった。実際の所、世に溢れるコードを見てみると必ずしも本名でなくても構わないような感じだ、というのはずいぶん後になってから知った。ともかく、まあ、本名を晒し始めたという事実があったわけです。当時僕は何歳だっけ。記録に残ってる一番古いバージョンが2001年9月のリリースだから、ええと、大学1年で19歳の時か。
でも、名前を晒すということは実質的には何の変化ももたらさなかった。
そもそも、大学3年になるまでアルバイトというものをしたことが無く、やってた部活も交流試合があるようなものではなかったので、自分は「リアルの世界」ではほとんど全く社会との繋がりがない、価値のない存在だったと言っていいと思う。学祭の垂れ幕作りだとかそういう所でしか世の主流の人々から存在を意識されることがない、いてもいなくてもどうでもいいような人だった。
そんな僕が他人からとそれなりの価値を認められたのは、漫研の中であり、イラストを公開するために作ったこのサイト(当時はまださくらのレンタルサーバではなくISPの無料スペースだったんだけど)であり、そこでの活動であり、つまり僕にとっては「社会との繋がり」はリアル世界よりもむしろWebが起点になっていた。
なので、アルファベット4文字の「Piro」であろうが漢字4文字の「下田洋志」であろうが、その文字列にはWeb上での僕を識別するためのidentifier以上の意味はなかったわけです。実質的には。Webにあった僕の活動の足跡を粗探ししても、出てくる物はたかが知れてたし。
その後、Mozillaの拡張機能を作っていたことが縁でもじら組のMozilla Partyに呼んでいただけて、その打ち上げの席でグッデイに紹介してもらえて、就職して、クリアコードに籍を移して、「Piroがおるから」という理由で会社にMozilla関係の仕事が舞い込んできたりして、という感じで今に至ってる。
で、この現状が「実名を出してたからこそこうなった」「完全匿名でやってたらこうはいかなかった」という話の例になるのかというと、それが僕には分からない。会社で普通に「ぴろたん」と呼ばれてる事を考えると、実名公開してなくてもこうなってたんじゃないの? と思えてくる。
ただ、活動の最初から今に至るまで一貫して同じ名前でいたからこそこうなったのだろう、という事は言えると思ってる。誉められた事も誉められなかった事も、僕がやってきた事は全部この名前に紐付けられていて、だからこそそれらは「実績」として評価することができるのだろう。identify不能な完全匿名で(毎回別の名前で、とか、「名無しさん」でだけ書き込む、とか)活動していたら、何をしてもそれらはひとまとまりの「実績」として見ることはできなかったのだろう。
そういえば僕は、トロフィーとか盾とか貰ったことがないんすよね。そのくせ、誰かに誉めて欲しがっていた。トロフィーという、「お前のそれは称賛に値するのだ」という目に見える評価がずっと欲しかった。欲しかったけど、手に入れられるはずのない物だ。同人だのCSSだのWeb標準だのMozillaだのという非主流のものを、しかもその世界の中心でガッツリやるんじゃなくて周辺に留まってちまちまやってるだけでは、絶対にそんなもん貰えない。誰もそんなものくれない。中心に飛び込む勇気だとか、マイナー分野じゃなくメジャー分野に転向する勇気だとか、そういうのがなければもう絶対に手に入らない。
でも、そんなマイナー分野の周辺でゴソゴソしてただけの僕でも、今自分の名前でググると何かしら出てくる。作った物への評価、していた事への評価が見つかる。それが今の僕にとってはトロフィー代わりになってるのかもしれない。
人に誉められて悦になりたい、トロフィーを眺めたり人に見せびらかしたりしてニタニタしたい、にもかかわらずその象徴たる「トロフィー」のような物理的な証を絶対にもらえそうにないという人は、ひとつの名前で活動するといいのかもしれない。検索すればそこにトロフィーがあるし、そういう形で人に見せびらかすこともできるのだから。
そういうわけで僕は「実名推進」ではなく「顕名推進」の立場を取らせていただいております次第です。
伝説の黒歴史ドキッ! 丸ごとウェブ!! ブラウザだらけの討論大会 ~Chatでユーザのポロリもあるよ~をプロデュースした哀さんは最近演劇に凝っておられるようなのですが、その哀さんがプロの劇団で客演するそうで、見に来るようにというサクラ電波を受信しました。
演劇というと、高校時代に漫研の隣が演劇部で、演劇部の友人からかなりカオスな世界であると聞かされていた(いかにワケの分からないことをするかを競うとかなんとか……)ため、苦手意識があったんですよね。でも食わず嫌いみたいなんですよねよく考えたら。
という感じでミュージカルとオペラは見たことあるけど普通の舞台演劇は意外にも未体験だったようです。なので、いい機会かと思って行ってみることにしました。
哀さん曰く、演じるために5回ほどDVD見て毎回泣いたそうなので、(高校の頃に聞いたカオスな情報とは異なって)普通にお話として楽しめるものなのだと推測しています。以下IRCのログより抜粋。
21:30 (i_Phone) ケータイが無いころの長野県高校三年生が 21:30 (i_Phone) 大雪で学校に閉じ込められて 21:31 (i_Phone) 自分の未来も見えなくて 21:31 (Piro) 一人また一人と消えていく「ケッ、俺は殺人鬼なんかと一緒にいられねえぜ! 部屋に帰らせてもらうぜ!」 21:31 (i_Phone) とりあえず学校の出し物のお芝居、頑張ってやろうよ 21:31 (i_Phone) ちげえw
ということで、このエントリを見た人で7日がヒマな人は一緒に見に行ってみませんか。という宣伝なのでした。
ちなみにその翌日の11月8日はFirefox Developers Conferenceが開催される予定です。僕もなんか話すと思うのでよかったら見に来て下さい。