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

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

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

2013年7月29日

Bug-org 501496 preventDefault on keydown does not cancel following keypress
初回投稿日時: 2013年07月29日20時14分50秒
カテゴリ: Events Google Chrome IE Mac Mozilla Core Mozilla25 Safari Windows バグ修正
SNS: (list)

Geckoでは、keydownイベントのpreventDefault()を呼び出しても、続いて、keypressイベントが発生する、というバグです。

Gecko 24までは、keydownイベントが消費された場合、defaultPreventedtrueに設定して、keypressイベントを発火していました。

しかし、IE、Safari、Chromeではこの場合、keypressイベント自体が発火されません。

D3Eの仕様では、keydownイベントのデフォルトアクションに、keypressイベントが含まれていますので、Gecko以外のブラウザの動作が正しいことが明白です。

このため、今回の修正を行うことにしました。これにより、Webサイトや、Webアプリが影響を受けることはほとんどないと思います。なぜなら、他のブラウザの動作に合わせた修正だからです。

これに対して、FirefoxやThunderbirdのキー処理、アドオンのキー処理は、Geckoのこれまでの動作を前提に書かれている可能性がありますが、その場合、regressionが発生する可能性があります。

この修正により、regressionが発生する条件は、

  1. keypressイベントがdefaultPrevented属性値を確認していない(常に動作する)
  2. Webコンテンツも含め、keydownイベントがpreventDefault()を呼んでいる

というものになります。つまり、他の部分の処理に関係無く、強引に処理が行われる、keypressイベントハンドラがなければ、regressionは発生しません。

regressionが出た場合、その対処方法は、keypressイベントハンドラでkeyCode値を検査していたものはkeydownイベントハンドラで処理するようにする。

それ以外の、charCodeを見ているものに関しては、keydownイベントハンドラに移動できませんので、そのまま、動作しない形が好ましいと私は思います。なぜなら、他のイベントハンドラが、デフォルトアクションをキャンセルしているのですから、アドオンも含めたブラウザのデフォルトアクションは実行されるべきではありません。

ちなみに、Gecko内で、defaultPreventedを無視するのは、セキュリティに関わる部分です。例えば、開いたパネルやメニューが閉じることができなくなると問題ですので、このあたりは他の処理結果を無視して、強引に動作するようになっています。

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

bug-org 501496を含むエントリ