この日記はMozillaのプロダクトへの貢献者としての私の成果を中心に、気になったバグやWeb界隈の話題について書いていますが、 断り書きがある場合を除き、いかなる団体のオフィシャルな見解ではありません。あくまでも個人的なものです。 Mozilla Foundation、Mozilla Corporation、及び関連企業の公式情報ではないことに注意してください。

現在、XHTML 1.0 (もどき)から、HTML5なコンテンツに修正中です。古い日記は修正が完了していませんので表示が崩れます。 順次、修正していく予定ですのでしばらくお待ちください。

もずはっく日記(2010年9月)

2010年9月3日

2010年9月4日

Bug-org 590819 Click event isn't fired when mouse button down on border of <input> and mouse button up on padding box of it 初回投稿日時: 2010年09月04日11時44分05秒
最終更新日時: 2010年09月04日11時46分23秒
カテゴリ: Javascript Mozilla Core バグ修正
固定リンク: id=2010090400
SNS: (list)

<input><textarea>border上でマウスのボタンを押し、そのままマウスカーソルを動かしてborderより内側でボタンを離した場合に、クリックイベントが発生しない、というバグです。

もともと、Bug-org 552707の修正中にまったく関係無い自動テストがMacでのみ、通らなくなってしまう、ということから偶然発見したバグです。Macでのみ、たまたま生成されたmousedownイベントがborder上で発生していたため、新しいロジックでは問題が出ていたのでした。

Geckoの<input><textarea>は、単にinline-blockを生成していて、これがborderを生成します。そして、その内部に匿名のdiv要素を作り、これをエディタのルート要素とし、エディタの内容をこのdiv要素の下に匿名のテキストノードとしてぶら下げていきます。

clickイベントは同じ要素上でmousedownイベントと、mouseupイベントの両方が発生した場合に生成されるイベントですが、これが、input要素で発生した後、匿名div要素で発生した、と判断され、clickイベントが生成されていませんでした。

今回の修正により、mouseup時の要素が匿名の要素だった場合、その匿名サブツリーの親とも比較して判断するようになっています。

Bug-org 593377 bug 535922 killed all tests in dom/tests/browser 初回投稿日時: 2010年09月04日16時31分03秒
カテゴリ: Mozilla Core バグ修正
固定リンク: id=2010090401
SNS: (list)

モバイルチームがbrowserの自動テストをそれ以外のプロダクトでは無効化する際にMakefileの修正をミスしてしまい、ディレクトリ単位でテストが走らなくなったまま3ヶ月も経過してしまっていたというバグです。

幸い二つしかテストがないディレクトリでしたが、うち一つはregressionを検出できず、今では正常にパスしなくなっています。

モバイルチームは仕事が雑すぎて困ります。

2010年9月8日

また捕まえられた 初回投稿日時: 2010年09月08日21時42分00秒
カテゴリ: 雑談
固定リンク: id=2010090800
SNS: (list)

うーむ。keyhell以来、キーボード周りの処理でなんかあると毎回、捕まえられてるような気が。

Bug-org 593620 Starting autoscroll and releasing middle button over a linked image causes link activatio 初回投稿日時: 2010年09月08日22時53分36秒
カテゴリ: Mozilla Core バグ修正
固定リンク: id=2010090801
SNS: (list)

中、もしくは右ボタンを離しただけでクリックイベントが発生するため、オートスクロールをリンク上で止めたらそのリンクが開かれてしまう、というバグです。

理由はあまりに恥ずかしいので気になる人はパッチを見てください。テスト対策で急ぎで作るもんじゃないですね。反省。

P.S. Aliceさん、blocking2.0を?にしておいてもらえると、regressionや新機能の国際化バグはだいたい、betaN+になると思います、そうなればレビューが終われば迅速にチェックインできるのであらかじめ申請しておいてもらえると助かります(フラグを'?'にして、その理由をdriversに向けて、簡単にコメントで説明しておけばOKです)。

2010年9月12日

Bug-org 587243 Textbox of tab group lost focus immediately by keypress Eenter(Conversion Enter Commit) while IME composition 初回投稿日時: 2010年09月12日12時53分20秒
最終更新日時: 2010年09月12日13時09分53秒
カテゴリ: Mozilla Core バグ修正
固定リンク: id=2010091200
SNS: (list)

IMEで確定する時のEnterキーや、キャンセル時のESCキーの入力でtab group名を入れるエディタからフォーカスが失われてしまう、というバグです。

今回のtab candyはjQueryとHTMLで実装されているようで、このjQueryがバグの原因でした。

Geckoの流儀ではキーの入力処理は基本的にkeypressイベントを活用します。しかし、jQueryはおそらくクロスブラウザな動作を実現するためにESCキーのような文字を入力しないキーではkeypressイベントを発生させていません。このため、代わりにkeyupイベントが利用されていたことが直接の原因です。

GeckoのキーイベントとIMEのイベントの関係は次のようになっています。

アクション発生するイベント
最初の一文字のキー入力
  1. keydown
    (※ただし、gtkでSCIMのようなキーのイベントをまるごと横取りしてしまうようなIMEではこれと、次のkeypressイベントは発生しない)
  2. keypress
  3. compositionstart
  4. text
途中のキー入力
  1. text
最後のキー入力
  1. text
  2. compositionend
  3. keyup

そう、未確定文字列を確定、もしくはキャンセルさせた場合、keyupイベントは発生しているのですが、これはすでにOS側で消費されているはずのキー入力なのにもう一度アクションを起こしてしまうから変な動きになっていたのです。

対策として、EnterキーとESCキーで未確定文字列が発生することは無いことを利用してkeydownでフォーカスまわりの処理を行うようにし、またそのイベントをそこで消費してしまうようにしました。ただし、ラベルの保存等はkeydownイベントではテキストの入力がまだ終わっていない可能性が高いので引き続きkeyupイベントハンドラに残したままにしています。

テスト用URI

data:text/html,<script type="text/javascript">
  function printEvent(e) {
    var p = document.getElementById('p');
    p.innerHTML = e.type + "<br>" + p.innerHTML;
  }
</script>
<body onload="document.addEventListener('compositionstart',
                function (e) { printEvent(e); }, false);
              document.addEventListener('compositionend',
                function (e) { printEvent(e); }, false);
              document.addEventListener('text',
                function (e) { printEvent(e); }, false);">
  <input onkeypress="printEvent(event);"
         onkeydown="printEvent(event);"
         onkeyup="printEvent(event);">
  <p id="p"></p>
</body>

2010年9月17日

Bug-org 143390 Arrow keys stuck when Chinese ChangJie and Japanese IME's are used 初回投稿日時: 2010年09月17日19時39分32秒
カテゴリ: Mozilla Core バグ修正
固定リンク: id=2010091700
SNS: (list)

かなり古いバグですが、WinXPで台湾のIME、ChangJieを利用中に、カーソルキーを押してもキャレットが移動しない、というバグです。

ChangJieでは一つ文字を確定しても、その後に来る文字を提案したりします。このとき、内部的にはまだ変換途中なのですが、この状態でChangJieはカーソルキー等のキー入力があっても、自身ではなにも処理せず(変換作業も打ち切らず)、キー入力メッセージをそのままアプリケーションに渡していました。

Geckoはこのような状況は想定していなかったので、今回の修正では、キャレットを移動させるキーと、フォーカスを移動させるタブキーのメッセージが、変換中に来た場合、現在の変換をキャンセルして普段通りにキー入力を処理するように修正しています。

日本語のIMEではこのような状態になるパターンを見つけることができませんでしたので副作用はないと思いますが、もしあったらバグ報告をお願いします。

2010年9月18日

MacでのIMEまわりのバグ修正はOSの設計の問題との戦い 初回投稿日時: 2010年09月18日13時12分47秒
カテゴリ: 雑談
固定リンク: id=2010091800
SNS: (list)

本当にどうなってんだというぐらいに、MacのAPIやイベントモデルは最悪きわまりないですね。Cocoaのキー入力、テキスト入力を書いたことある人なら誰しもが賛同してくれるんではないかと思いますが。

キー入力の方はkeyDownperformKeyEquivalentという二つのイベント的なメソッドが用意されていて、一筋縄ではハンドリングできません。幸いにもJoshが_wantsKeyDownForEventという隠しメソッドの存在を発見し、これによりkeyDownだけで概ねほとんどのキーイベントをハンドリングできるようになり、かなりのバグが消えましたが。普通に考えればperformKeyEquivalentが何故存在しているのかさっぱり分かりません。また、keyDownの戻り値がvoidなのも変です。普通、イベントを処理した後にそのイベントを消費するのかどうするのか選択できるものですから。

さらに奇妙なのがinterpretKeyEventsです。keyDownでこのメソッドを呼ぶと、IMEにキーイベントが渡されます。ですが、なんとこれも戻り値がvoidで、アプリケーションからはそのキーイベントがIMEに消費されたのかどうか、一筋縄では判断できません。この問題の解決はFx4以降での課題となっています(ATOKの確定アンドゥがGeckoで機能しないのはこの問題)。

interpretKeyEventsに戻り値がないという致命的欠陥を除けば、IMEに処理が渡る前にアプリケーションがキーイベントに介入できるという点は、それができないWindowsや、事実上できないGTK2に比べると良い面もあります。ただ、IMEの処理とアプリケーションの処理がバッティングした場合、普通はIMEが勝つべきなので(アプリケーションが勝つと、IMEのその機能を利用できませんが、逆の場合はIMEをオフにすれば利用できる)、結局あまり使いどころがないメリットです。

また、他のOSからは信じられない設計のひとつに、IMEとキーボードレイアウトが同列に扱われている、という独特の発想があります。他のOSでは、キーボードレイアウトの選択と、その選択したキーボードレイアウトでのIMEのオン、オフという二つの概念があります。ところがMacではキーボードレイアウトとIMEの各入力モード(たとえばひらがな、カタカナ等)のスイッチがダイレクトに行えてしまいます。また、現在のキーボードレイアウトが他のOSで言うIMEオンの状態の場合、IMEオフにあたるキーボードレイアウトは発見できるのですが、その逆に関しては最後に選択されていたIMEオンにあたるキーボードレイアウトを探すことはできません(記憶しておくしかない)。APIの不備、とも考えることができますが、どちらにしろ、そのIMEで対になる状態のキーボードレイアウトを非表示にされているともうどうしようもありません(たとえばATOKをインストールして、英数入力にはことえりのものを残し、ATOKはひらがなとカタカナを残し、他を全て非表示にしてしまった場合)。

さらに、キーボードレイアウトとIMEとを同列に扱うということはIMEそれぞれがキーボードレイアウトも管理しなくてはいけないことを意味します。もしDvorakのレイアウトでIMEを利用したい、と思っても原理的に難しいのです。たとえば、Dvorakを選択し、次にことえりのひらがなを選択するとキーボードレイアウトはJIS配列に戻ります。Macにおいてはこれが正しい流儀と言えます。ことえりのやり方とは対照的にATOKは直前に利用されたASCII互換のキーボードレイアウトをそのまま利用してあたかも引き継いでいるかのように振る舞いますが、スペイン語のキーボードレイアウトなんかでテストしてみるとあっさり破綻します。当たり前ですが。

これ以外にもIMEのAPIがフォーカスがあるコンテキストでしか動作しないとか、正気を疑う設計が多いです。Appleのこの辺の設計はアプリケーションのために設計したというよりも、自社アプリにとって必要最低限のものだけ用意しておけば良いという発想なのではないかと勘ぐってしまいます。

2010年9月22日

Bug-org 597389 If plug-ins disable non-Roman keyboard layout and they don't recover the state, Gecko doesn't recover it 初回投稿日時: 2010年09月22日01時51分22秒
カテゴリ: Mozilla Core バグ修正
固定リンク: id=2010092200
SNS: (list)

Geckoのバグではないんですが、修正しました。

Flash Playerが10.1.x.xになってから、FlashのコンテンツをMacでクリックすると、何故かパスワードフィールドにフォーカスがある時と同じようにキーボードレイアウトがASCII互換のものに制限されるようになりました。そのままGeckoにフォーカスを戻すと、Flashは正しくこの制限を解除するのですが、Flash内のリンクをクリックしてそのFlashがunloadされた場合、この制限を解除してくれません。このため制限がかかったままになっている、というバグです。

Geckoはパスワードフィールドで同じ制限をかけているので元に戻す機能は元々あります。そのため、一度パスワードフィールド(もしくはime-mode: disabled;なエディタ)にフォーカスを合わせて、その後フォーカスを移動させると制限が解除されます。

10.4以前のMacではなんと、この制限が現在かかっているかどうかを確認するAPIが無かったので、APIの不要な呼び出しを削減するために自分たちが制限を行ったかどうかを記憶しておき、行った場合にのみフォーカス移動時に解除するようにしていたため、このような動作になっていました。

今回の修正で、フォーカス移動のたびにこのAPIを無条件に呼び出すようになりました。ひょっとするとフォーカス移動時のパフォーマンスが低下している可能性がありますが、それ以上の問題だったのでひとまずこれで良いかと思います。

ちなみにtrunkでは10.5以降で追加された新API群で動いているので問題ありませんでした。Fx3.6の1.9.2 branchと、Fx3.5の1.9.1 branch(Seamonkeyでしばらく存命の予定)でのみ修正を行っています。

2010年9月26日

京都・嵐山 初回投稿日時: 2010年09月26日00時14分52秒
カテゴリ: 旅行
固定リンク: id=2010092600
SNS: (list)

京都・嵐山へ珍しく電車で行ってきました。

写真撮れませんでしたが、行きに乗った京福電気鉄道の車内にはうじゅを使ったポスターが。萌えおこしかと思ったんですが、実際には太秦の街中では中々見ることがなかったんですが。

他の写真はphpGraphyをインストールして公開しました

2010年9月28日