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

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

もずはっく日記(2013年8月)

2013年8月31日

Bug-org 907657 Firefox24 hangs if synchronous XMLHttpRequest was sent inside onkeydown
初回投稿日時: 2013年08月31日12時40分22秒
カテゴリ: Mozilla Core Mozilla24 Mozilla25 Mozilla26 Windows バグ修正
SNS: (list)

keydownイベントハンドラで、XMLHttpRequest.send()を同期通信として使用すると、ハングアップするというバグです。ギリギリ、Betaで重大なバグが発見され、報告されました。本当に助かります。

同期通信が行われた場合、本来なら、その通信が終わってから、keydownイベントが全ての必要な要素に配信された後に、keypressイベントが発生すべきです。しかし、Geckoの現在の設計でこれを行ってしまうと、通信中はウインドウを閉じたりすることすらできなくなってしまいます。これを解決するために、Geckoではメッセージループをネストさせて、chromeには次のWM_CHARメッセージを元にkeypressイベントを発生させ、contentには、通信終了後にキューにためておいたDOMイベントを発生させる、という実にトリッキーなことをやっています。

このため、keydownイベントの送信前に、WM_CHARメッセージの有無を確認しておき、送信後にWM_CHARメッセージをGetMessageW()で取得しにいったら、既にキューからは削除されているために、GetMessageW()から処理が返ってこない、というのが原因でした。

今回の修正では、送信前にWM_CHARメッセージの有無を確認してキャッシュするのではなく、リアルタイムで、WM_CHARメッセージの有無を確認後に、GetMessageW()を使用するように変更し、ハングアップを回避しています。

しかし、実にハッキーなことをやっているため、keydownイベントでpreventDefault()を呼んでも一切、無視されていますし、その後contentに送信されてくるイベントも正確性に欠くので、Web開発者の方は、同期通信を使わないようにした方が余計なバグを生み出さずに済むので良いでしょう(そもそもレスポンスの面から、使うことは希だと思うのですが、実情は全く知りません)。

関連するかもしれないエントリ

bug-org 907657を含むエントリ