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

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

もずはっく日記(2018年12月)

2018年12月11日

Bug-org 1479964 Tracking event.keyCode issue due to the implementation of window.event
初回投稿日時: 2018年12月11日23時53分08秒
カテゴリ: Events KeyboardEvent Mozilla Core Mozilla65 バグ修正
SNS: (list)

多くのデキの悪いサイトがGeckoで動かない原因のひとつに、イベントリスナにeventという引数を渡していないのに、event.preventDefault()等と書き、実質的にwindow.eventを参照しているというケースが多々あったそうです。これに対する互換性としてwindow.eventはWHATWGによって標準仕様に取り込まれることになったので、Geckoでもサポートするようにした模様です。

ところが、いざ実際にこれを実装し、有効化してみると、多くのサイトがwindow.eventをIEと同じkeypressイベントが来るかどうかを判定するfeature detectionとしてこれを参照していました。当然、これらに関連性は皆無なので、そのように書かれていると動きません。まさにそのようなアプリのコードはfeature detectionの悪い例です。

そこで急遽、keypressイベントのみ、KeyboardEvent.keyCodeKeyboardEvent.charCodeの値をどちらか非ゼロの値をもう一方にセットしなくてはいけなくなりました。

Geckoでは、keypressイベントのKeyboardEvent.keyCodeの値をまずは先行するkeydownイベントと同じものと仮セットします。次に、KeyboardEvent.charCodeをそのキー入力、もしくは、そのキー入力からCtrlAlt、またはCommandの状態を取り除いた際に入力される文字のUnicodeコードポイントにセットします。最後に、KeyboardEvent.charCode値が非ゼロ場合、KeyboardEvent.keyCodeをゼロにしていました。

しかし、他のブラウザでは最後の段階でKeyboardEvent.keyCodeKeyboardEvent.charCodeの値をセットし、逆に、KeyboardEvent.charCodeの値がゼロの場合(Enterキーの場合)にKeyboardEvent.keyCodeの値をKeyboardEvent.charCodeにセットしていました。

幸いにもnon-printableキーのkeypressイベントの発火を止める修正が進行中だったので、少ないリスクでこの修正を行うことができました。

それにしても、本当に、論理的に考えずにトライアンドエラーだけで実装しちゃう人が多いんですね。一見関連性のあるもの同士を対にしていたために壊れるサイトが多かったことに非常に驚かされました。

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

bug-org 1479964を含むエントリ