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

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

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

2013年12月19日

Bug-org 912858 Implement KeyboardEvent.key for printable keys (except dead key handling) 初回投稿日時: 2013年12月19日14時42分00秒
最終更新日時: 2013年12月19日14時42分26秒
カテゴリ: Android Events Gonk GTK Mac Mozilla Core Mozilla29 Windows バグ修正
固定リンク: id=2013121901
SNS: (list)

今まで、D3E仕様に不明瞭なところがあったので、KeyboardEvent.keyの、プリンタブルキーの値はMozPrintableKey値を暫定的に設定していましたが、仕様が概ね固まったので、デッドキー以外に関しては最新仕様にあわせたものに修正されました。現行仕様は以下のようになっています。

文字列が入力される時
入力される文字列
モディファイアキーにより、文字列が入力されない、もしくは制御文字の場合
OSが参考に提供する文字列が変わる場合(Macのcommandキー押下時)
その提供された文字列(多くの場合、QWERTY配列のアルファベット)
AltGrキー、もしくはMacのoptionキーが押されている場合
AltGrキーを押さなかった場合に入力される文字列
それ以外のモディファイアキーが押されている場合
Shiftキーを除いたモディファイアキーが押されていない場合に入力される文字列

また、Geckoでは、Windowsのカナロックは無視します。Macでは、ことえりのかな入力時や、ハングル・中国語IMEではキーボードレイアウトを変更しますが、IME依存の動作でWebアプリにとって互換性テストの負担が大きすぎるので、その時のASCII Capableキーボードレイアウトを利用します。

プラットフォームを問わず、プリンタブルキーが文字を入力しない場合、例えば、テンキーのカンマキー(セパレーターキー)が、ブラジルのポルトガル語レイアウト以外では文字入力にならない場合、空文字列になります。

なお、今回の修正では、QtとOS/2は修正していません。これらのプラットフォームは今後、複雑な修正は行わない予定です。貢献者がパッチを提出してきてくれた場合にはレビューは行いますが。

Bug-org 930374 Event.defaultPrevented shouldn't become true if preventDefault() was called by our internal handler for default action 初回投稿日時: 2013年12月19日14時55分33秒
カテゴリ: Events Mozilla Core Mozilla28 バグ修正
固定リンク: id=2013121902
SNS: (list)

Geckoや、Firefox等のXULアプリは、DOMイベントをハンドリングすることで、イベントのデフォルトアクションを実装しています。前者で、イベントのディスパッチが完全に終了した後以外にハンドリングした場合には、他の要素がデフォルトアクションを二重実行してしまわないように、Event.preventDefault()が呼び出されています。これが原因で、イベントを保存しておいて、イベントのディスパッチが終了した後にEvent.defaultPreventedの値を確認すると、WebアプリがEvent.preventDefault()を呼び出したわけでもないのに、trueになっている、という奇妙な状態になっていました。

今回の修正で、Event.preventDefault()が、content権限のJavascriptから呼ばれた場合にのみ、mozilla::EventFlags::mDefaultPreventedByContenttrueにし、content権限のJavascriptがEvent.defaultPreventedの値を確認した場合には、mozilla::EventFlags::mDefaultPreventedByContenttrueでなければ、trueに見えないようになっています。

つまり、chrome権限で動作している(はず)のアドオンから見ると、動作は一切変わっていませんので、互換性に問題が出ないように配慮しています。

また、Event.defaultPreventedが提案されるまで、独自に実装していたEvent.getPreventDefault()は、そもそもWebコンテンツでは利用されるべきではありませんし、これを未だに利用しているWebアプリがこの修正により不具合が出たしてもメンテされる可能性が低いので、互換性維持の観点から、元の動作のままにしてあります。

Bug-org 948839 Drag and Drop broken 初回投稿日時: 2013年12月19日15時06分17秒
カテゴリ: Events Firefox Mozilla Core Mozilla28 Mozilla29 バグ修正
固定リンク: id=2013121903
SNS: (list)

ファイルやURLを<input>要素等にドロップしても、タブがそれを読み込んでしまって、ドロップした要素固有の処理にならない、というバグです。

Bug-org 930374の修正時に、ドラッグイベントが利用していたmozilla::EventFlags::mDefaultPreventedByContentフラグの設定条件を私もレビュアのSmaugも共に誤解していたため、これをそのまま流用したことが原因です。

ドラッグイベントでは、これを、どのコンテキストでEvent.preventDefault()が呼び出されたのか、ではなく、contentとchrome、どちの要素上にある時に呼び出されたのか、を記録していました。

今回の修正で、WidgetDragEvent::mDefaultPreventedOnContentを新たに作り、こちらに元通りの条件でtrueをセットするようにしています。

Bug-org 946044 Pressing the Windows "Application" key inserts a U+0010 'DATA LINK ESCAPE' hexbox into text editor 初回投稿日時: 2013年12月19日15時18分17秒
カテゴリ: Events Mac Mozilla Core Mozilla28 バグ修正
固定リンク: id=2013121904
SNS: (list)

MacにPC用のキーボードを接続し、コンテキストメニューを開く、アプリケーションキーを押すと、制御文字である、U+0010が入力され、それがエディタにそのまま表示されてしまうというバグです。

Macでは、キーイベントをハンドリングする際に、controlキーが押されている場合にのみ、制御文字をASCIIアルファベットに変換する処理を行っていましたが、それ以外の場合は素通りしていました。今回、ASCII文字の範囲内にある制御文字が入力された場合には、これを無視するようにしています。CodeInput等で、それ以外の制御文字を入力することは可能なままですが、普通にはあり得ない上に、膨大な調査とコードが必要になるため、それらについては確認しないようにしています。

また、Macでは、PC用のキーボードを接続しても、Macのキーボードにないキーは普通、Aキーと同じ0が仮想キーコードとしてマッピングされ、判別がつかないのですが、アプリケーションキーは固有の数値(0x6E)にマッピングされているので、他のプラットフォームと同様に、keyCodeや、keyの値を設定するように修正しています。

ただし、他のアプリでも、このキーでコンテキストメニューを開くことはできないので、そのようには今のところは修正していません。

Bug-org 950559 IME composition window should be positioned at bottom-left of windowless plugin rather than top-left of screen 初回投稿日時: 2013年12月19日15時27分38秒
最終更新日時: 2013年12月20日13時27分51秒
カテゴリ: Flash Mozilla Core Mozilla29 plugin Windows バグ修正
固定リンク: id=2013121905
SNS: (list)

WindowsでwindowlessなFlashにIMEで未確定文字列を入力すると、画面左上に未確定文字列が表示され、視点移動が大きく、非常に見づらい動作でした。これの代表例は、ustreamのチャットの入力欄です。

今回の修正では、未確定文字列をフォーカスを持つプラグインの左下隅を、未確定文字列が表示されるComposition Windowの左上の座標として指定するようにしました。なお、プラグインがスクロールによって、ウインドウ外にある場合は、ウインドウの端に丸め込まれます。

windowlessプラグインで、IMEの未確定文字列がプラグインの左下に表示されている例

なお、ATOKのみ、未確定文字列の上に、候補ウインドウも重なるという動作になりますが、候補ウインドウ位置を明示的に指定しても動作が変わらなかったので、ATOK側のバグだと思われます。

Bug-org 951021 nsWindow of Android should set modifier state at dispatching events derived from WidgetInputEvent 初回投稿日時: 2013年12月19日15時34分53秒
最終更新日時: 2013年12月19日15時38分54秒
カテゴリ: Android Events Mozilla Core Mozilla29 バグ修正
固定リンク: id=2013121906
SNS: (list)

Android版のnsWindowがイベントを発行する際に、マウスやタッチイベントでは、一切、モディファイアの情報を設定しておらず、キーイベントでも、AltCtrlMetaShiftしか設定していないというバグです。

今回の修正により、全てのイベントで、CapsLockNumLockScrollLockも設定されるようになりました。Functionというモディファイア状態もFnに反映するように修正していますが、これがどのような場合にアクティブになっているのかは不明です。

ただし、Javascriptから擬似的に生成されている、一文字で確定した場合のキーイベントや、タッチ操作によるマウスイベントは今回の修正では変更されていません。

また、Androidの制約により、AltGrの情報も設定されていません。

より詳しい情報は、MSDNの資料を参考にしてください。

Bug-org 947115 native key event handling tests should use synthesizeNativeKey of EventUtils 初回投稿日時: 2013年12月19日15時49分43秒
カテゴリ: Mac Mozilla Core Mozilla29 Windows バグ修正
固定リンク: id=2013121907
SNS: (list)

WindowsとMacでは、ネイティブキーイベントをエミュレートして、ネイティブキーイベントのハンドリング処理が行えますが、このAPIが非常に使いにくいため、EventUtils.jsに、synthesizeNativeKey()ができたことを契機に、パラメータを読みやすいものにし、全てのテストでこのファンクションを使って、APIにアクセスするように修正しました。

これを利用することにより、chrome権限がなくても、ネイティブキーイベントのエミュレーションが手軽にできるようにもなっています。

2013年12月20日

Bug-org 950564 Complex text input panel for plugin should be positioned at bottom-left of focused plugin 初回投稿日時: 2013年12月20日13時14分32秒
最終更新日時: 2013年12月23日09時26分27秒
カテゴリ: Flash Mac Mozilla Core Mozilla29 plugin バグ修正
固定リンク: id=2013122000
SNS: (list)

Macでは、Flash等のplugin上で日本語を入力する際に、必ずIMEの未確定文字列がフローティングウインドウに表示されますが、これの位置が固定なので、位置関係によっては見づらいので、プラグインの左下に表示しよう、というバグです。

ニコニコ動画の動画プレーヤーの左下に未確定文字列が表示されているスクリーンショット

Retinaディスプレイでもテストしてもらっているので大丈夫だと思いますが、手元に実機がないので詳しいことはわかりません。最小幅は、ui.plugin.panel.min-widthで指定できるようにしておきました。これが、論理ピクセルになっていると意図通りなのですが、ひょっとすると物理ピクセルになっているかもしれません。その場合はバグ報告をお願いします。

最小幅設定が最大幅設定として動作してしまっていた、しょうもないミスがあったので、若干修正を入れました。これにより、以下のような感じに変わります。

プラグインの幅が最小幅より大きい場合
パネルの幅は、プラグインの幅と同じになっているスクリーンショット
プラグインの幅が最小幅より小さい場合
パネルの幅は、最小幅になるので、プラグインよりも長くなっているスクリーンショット