たまに18歳未満の人や心臓の弱い人にはお勧めできない情報が含まれることもあるかもしれない、甘くなくて酸っぱくてしょっぱいチラシの裏。RSSによる簡単な更新情報を利用したりすると、ハッピーになるかも知れませんしそうでないかも知れません。
の動向はもえじら組ブログで。
宣伝。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。 以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能!
XUL/Migemo [Forked Edition]の挙動がおかしいのを直そうとしてハマってしまった。検索欄に長い文字列をペーストして検索を実行しても正常に検索できないという問題。
色々条件を変えて試してみたら、どうも、検索できなくなってるんじゃなくて、リンク内の文字列のみ検索するモードに強制的に切り替えられてしまっているようだった。しかし検索モードを指定するフラグの値を変更しても全然効果が現れない。
Type Ahead Findの実装の深いところを見てみてびっくらこいた。検索バッファ(最後に検索した文字列)が空の状態で検索を始めて、且つ、accessibility.typeaheadfind.linksonlyがtrueの時は、強制的にリンク内検索モードになるように書かれてるじゃあないですか。そりゃあ、いくらやっても無駄なはずだよ……
つうかコレ書いた人何考えてんだろう? 普通のページ内検索でこの設定を参照する意図が全然わからない。これってクイック検索の時専用の設定じゃないのん? まあ、そもそもこの問題に引っかかったのは何らかの理由でaccessibility.typeaheadfind.linksonlyがtrueになってしまってた(初期状態はfalse)のが原因なので、こっちのせいといえばこっちのせいなんだけど。
とりあえず、検索を実行する前に検索文字列の最初の1文字で検索してからもう一度長い文字列で検索するようにしてみたところ、accessibility.typeaheadfind.linksonlyがtrueでも問題なく意図通りの動作をするようになってくれるところまでは確認できた。でも、これって変なやり方だよなあ。たぶんaccessibility.typeaheadfind.linksonlyをfalseに設定するのが本道なんだと思う。でもこの設定を本来の目的で使いたい人はどうすればいいんだろう? 全く訳がわからない。
Fx2でこの問題が起こることを確認したけど、Fx3ではどうなのかは未確認。そっちでも起こってるようならいよいよバグ報告してみようか(どちらかというと機能要望?)。
MozLabの一機能の単体テスト用ツールMozUnitではasync型のテストケースを書くことができる、というのは前にここでも書いたんだけど、使い勝手の悪いポイント?が一つある。それは、テストケースの中で、ある処理が終わってから次の処理に進むといったことが簡単にはできないこと。
現状の仕様では、
という書き方しかできなくて、各テストケースの中でコールバック関数を使って準備が整うのを待つという使い方はできない。一般的な意味での単体テストというのがどうある「べき」なのかは知らないけど、やりたいこととしては、
の方が便利ですよね? ね?
んでscript.aculo.usのユニットテストの機能ではwaitという機能を使って処理待ちができるそうだから、MozUnitステでscript.aculo.usを拡張機能の開発でも使えるようにせよ!という指令が須藤さんから下ったのだけれども。
なんか仕様があちこち違うから今までMozLabベースで作ってた物をこれ用にするにはscript.aculo.usのソースもガッツリ読まなきゃいけないっぽいし、どうもscript.aculo.usは複数のテストが同時に動くことを想定していなさそうな雰囲気だったので、MozReplみたいな機能を使って同時に複数人でテストするようなことは難しいっぽかった(そんな事ほんとにやるのかどうかはさておき)ので、新しいこと覚えるよりは今までの知識がそのまま使えた方が僕が楽だと思った。
ということでMozUnitのTescCaseクラスの定義をゴニョゴニョと書き換えて、JavaScript 1.7のジェネレータを応用し、テストケースの中で yield 5000;
とか書くとそこで指定時間(ここでは5000ミリ秒=5秒)待ってから次の処理に進むということができるようにしてみた。テストケースの実行結果の返り値を見て、 [object Generator]
である場合は、StopIteration例外が出るまでタイマー使って何度もnext()
を実行して、それが済んでから次に処理を進めるようにした次第です。
……ということなんだけど、yieldってこんな使い方しちゃっていいのかしらん? yield(生産)って書いてるのに何も生産しとらんし。
minmax.jsというライブラリを使うと、最小サイズ・最大サイズを設定するCSSの機能を古いIEでも使えるそうで。IE6でやっても動いた。
IE6でもXML宣言があると後方互換モードになってしまってこれらのプロパティが機能しなくなるんじゃなかったかな。だとしたらもうしばらくの間は有用かも?
なんか文章が分かりにくいと言われたんで言い訳しとくと、スクリプト発見→IE6で表示→おお確かに動いてるねぇ→説明読む→ってIE5用なのかよ!→でもIE6で動いたなぁ→ていうかそもそもIE6って本体でmax-widthとか実装してたよね→でも後方互換モードじゃ使えないんだよね、XML宣言あると後方互換モードになっちゃうんだよね→じゃあやっぱりIE6でも有用なんじゃね? という流れがあった結果としてのこのエントリなんですよと。読む人の都合とか利便とか考えてないオナニー文章の典型ですね。
Tab EffectはDirectX8以降が必須=Windowsのみ対応ということなので、環境に依存せず動く物をHTML Canvasを使って作れないかなーと思ってやってみた。
結論。こりゃとても実用にはならんわ…… 行列変換とかやったら死ぬのが目に見えてる(そもそもやり方分からんけど)ので簡単な伸縮だけのエフェクトにしてても、重すぎて重すぎて実用に耐えません。しかも時々ウィンドウの描画に失敗して真っ白になるし。何故?
タブという概念は普通の人(コンピュータの中で何が起こってるのか頭の中で想像することに長けていない人)には分かりにくくて、Tab Effectのようにそれを視覚的に表現する物はユーザビリティの向上において結構役立ちそうな気がするんだけど、ジョークとしか思われなかったりするのが切ないところですね。
追記。Takenさんにアドバイスをもらって、HTML Canvasに描画した物をtoDataURL()
で画像としてキャッシュして処理するようにしてみたところ少しだけ軽くなったので、調子に乗ってもうちょっと3Dっぽい効果を加えてみた。
軽くなったとはいえ、さすがに台形に画像を拡縮すると重すぎるんで、あくまで「それっぽいニセモノの効果」でしかないですが。
Split Browserの作り込みの話のおまけ。このエントリにはドラッグ&ドロップの実装に関する話が含まれているかもしれません。
まず基本の話として、Firefoxで(というかXULで)ドラッグ&ドロップを実装するには、ondraggesutre, ondragover, ondragenter, ondragexit, ondragdropの5つのイベントハンドラと、XPCOMの機能を使う必要がある。このあたりの話はMDCのXULチュートリアルには無いんだけど、古いXULチュートリアルには載ってるので、熟読しとくことをお勧めしたい。
XUL要素をドラッグしようとすると、draggesutreというイベントが発行される。いわゆるAjaxとかだと、ボタンを押下→マウスが動いた、という操作をそれぞれ別のイベントで拾わないといけなかったり、クリック時にマウスがブレただけでドラッグ開始と判断してしまわないように閾値を設定したり、と色々めんどくさい配慮がいるんだけど、XULではdraggestureイベントいっこ拾うだけで済むので話が早い。
ドラッグ中にボタンを放した時、つまりドロップの操作が行われた時には、dragdropというイベントが発生する。これは他のアプリケーションからのドラッグ&ドロップでも発生するので、アプリケーションの垣根を越えてのデータのやりとりもできる。やろうと思えば多分バイナリデータも渡せるんじゃないかな……やったことは無いけど。
あとの3つのイベントはおまけのようなもので、ドラッグ中にポインタが載った要素に対して、今ドラッグ中のデータをドロップできるかどうか(その要素がそのデータのドロップを受け入れられるかどうか)を示す、とかそういった用途で使うことが多い。
データの受け渡しにはXPCOMの機能を使う。詳細は旧チュートリアルの当該項目で解説されてる……ンだけど、ぶっちゃけこんなの真面目に使ったらあかん(ぉぃ)。これをラッピングして簡単に使えるようにしてくれる物として、nsDragAndDropという標準ライブラリがあって、これはFirefoxでも利用できる(っていうかFirefox内部で使われまくり)ので是非活用しましょう。旧チュートリアルのnsDragAndDropの使い方の解説と利用例は要チェックですよ。
……というのがドラッグ&ドロップの実装の基本。ここから先は、その応用。
最初のリリース前の作り込みの話の続き。最終段階、ブラウズ領域の上下左右のポップアップボタンの実装について。このエントリは、XULにおける要素の重ね合わせ表示の方法に関する話が色々含まれています。多分。
実は当初は、こんな機能を付けるつもりは無かった。Split Browserのコンセプト自体が半分冗談みたいなものだったから、そこまで深く考えてなかったし。
ただ、実際に基本的な機能が揃って形になってくると、コンテキストメニューから「ブラウザを分割」を選んでさらにサブメニューから上下左右を選択する、という操作がだんだん鬱陶しくなってきた。と同時に、これをどうにかすることができれば使い勝手の面でブレイクスルーになるのではないか、という事も漠然と思うようになってきた。その最も安直な解決策として思い付いたのが、分割可能な領域の端にポインタが近付いたら勝手にボタンを表示して、それをクリックしたらその方向にそのブラウザを分割する、というものだったワケです。
ただ、思い付いたはいいものの、どうやって実装するかでだいぶあっちに行ったりこっちに行ったりウロウロしてた。
MozLabに含まれてる単体テストツールのMozUnitの使いかたが分からない、っていうか真面目にプログラミング勉強したことないから単体テストっていうのがどういう物なのかすらわかってない。説明が全然ないし、普通に他のテスト用のツールを使い慣れた人でないと使えないとかそういう物なのだろうか?
とりあえず試しに動かしてみたけど、何が嬉しいのかいまいち分からない。隠し設定使えば普通にJSコンソールにエラーがリアルタイムで表示されるし、エラー表示だけじゃどこがいけないのか分からないとかいっても結局の所JSデバッガで一行ずつ見ていかないと分からない所だってあるし……自動制御で動かすのも、userChrome.jsとかで自分でスクリプト書いてやるのとの違いが分からない。特に、ブラウザの読み込みが完了したタイミングでのテストとか。
日曜プログラマもどきみたいなのが手を出していい物じゃあないんじゃないのか、これは。
追記。MozUnitのソースコード見てああでもないこうでもないと頭の中で検証してやっと使い方が理解できた。
動画で紹介されてるのは非同期処理の例なんだけど、これで例えばブラウザの読み込みを待ってからテストを実行するとかそういうのをやろうとすると、全然うまくいかない。
こういう場合はコールバック関数とかイベントリスナとかを使って、テストしたい状態になるのを待ってからテストしてやらなきゃいかんのだけど、その方法が全然分からなかった。MozUnitのページには、何やらオプションを指定すると非同期でない(変な日本語だ……)テストができるとか書いてあるんだけど、英語だし略語と技術的専門用語との区別がつかんしで、ちんぷんかんぷんだった。
結論から言うと、async型のテストを作る場合は「setUp」メソッドに渡されるコールバック関数を使うというのが鍵だった。このコールバック関数を実行しないと、処理が一歩も進まない。
XUL/Migemoの動作の中で一番のネックになっているのは「辞書から正規表現のパターンを生成する」処理だそうで、そのために、本家XUL/Migemoでは200KB近いキャッシュファイルまで用意されていた。plus7さんの環境では一文字のパターンに対するキャッシュを生成するのに14秒もかかった(その間Mozillaはフリーズする)とまで書いてあって、他をどんなに改善してもここが足をひっぱってるんじゃあなあ、という感じだ。
んで、少しでもこれを高速化できないかな?と思って自分の分かる範囲で考えてみた。
金曜日、Shibuya.js Development Environment Conferenceに行ってきた。 申し込み受付から3分で120の定員が埋まってしまったということで受付のお手伝いとして潜り込んできたわけですが。今回はやっぱりハテナオヤ氏が来るということで注目度が高かったんでしょうか。
男女比は圧倒的に男が多く、女性も数名来られてたけど多分ほとんどプレス。CSS Niteでは半分が女性だったらしく、JavaScriptはやっぱりモテないのかなーと改めて思った。
開始早々いきなりデジハリの人が「えー今日ははてなさんのカンファレンスということで」とかなんとかカッ飛ばしてて、「これはひどい」と思った。
今回は著名な開発者の人達の開発環境の紹介ということで、今までのテクニカルトークとはだいぶ感触が違った。第1回、第2回のぶっ飛んだ空気の方が僕は好きだなあ。まあmalaさんはいつもの調子だったけど。
JavaScript 1.7 の yield が凄すぎる件についてを見てもyieldってそもそも何なのかちいとも分かっとらんかったのでそこから調べてみた。