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

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

もずはっく日記(2015年4月)

2015年4月17日

Bug-org 1151186 Japanese IME input is not working Google spreadsheet
初回投稿日時: 2015年04月17日10時57分55秒
カテゴリ: Mozilla Core Mozilla40 TSF バグ修正
SNS: (list)

Googleスプレッドシートで日本語入力中に、一度、他のアプリをアクティブにして、再びFirefoxにフォーカスを戻すと、TSFと、IMMを問わず、しかし、症状が異なるバグり方で、正常に日本語入力ができなくなるというバグです。

調査してみると、すぐに、IMEの状態管理に問題があることが分かりました。最初にスプレッドシートを開くと、どのセルも編集モードになっていなくても、IMEをオンにできてしまいます。また、スプレッドシートを表示している状態で設定タブを開き、スプレッドシートのタブに戻ってくると、セルの編集を開始しても、IMEが無効になったままでした。

そこで、IMEStateManagerのログ等からGoogleスプレッドシートの挙動を調べて見ると、まず、ドキュメントがフォーカスを得た時に、contenteditableな要素にフォーカスを移動させている事が分かりました。ただ、問題は、ドキュメントのfocusイベントハンドラ内で、フォーカスを移動させていたことにあります。このため、ドキュメントがフォーカスを得たことで、IMEを無効化しようとしますが、それを行う前に、エディタがフォーカスを得ることで、IMEを先に有効化してしまいます。そしてその後で、ドキュメントのフォーカス処理に戻って、IMEの無効化が完成します。

まず、最初のパッチでは、ドキュメントのフォーカス処理の最中に、別の要素にフォーカスが移動していたら、IMEの状態管理は(既に行われているはずなので)行わないように修正しました。

しかし、これだけではうまく動作しませんでした。さらに調査してみると、Googleスプレッドシートは、フォーカスの移動をブラウザに任せておらず、ドキュメントがフォーカスを得るときに、自身でフォーカスを行ったん別の要素に設定し、その後、元のフォーカスを持っていた要素にフォーカスを設定するということを行っていました。

ドキュメントにひとつしか存在しないnsHTMLEditorは、入力イベントが来る度に、自分自身が管理すべき要素がフォーカスを持っているのかどうかを検査します。しかし、Googleスプレッドシートの自前フォーカス管理によって、この検査で「フォーカスを持っていない」と判断し、一部のCompositionEventを捨て、フォーカス移動によって発生している強制確定のリクエストを無視してしまっていました。

以前より、CompositionEventは、TextCompositionクラスが、compositionstartからcompositionendまで、必ず同じ要素上で発火するようにしています。そこで、これを利用して、nsHTMLEditorCompositionEventのターゲットが自分自身が管理しなくてはいけない要素のうちの一つであれば、フォーカスを持っていなくても処理を行う様に修正しました。

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

bug-org 1151186を含むエントリ