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

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

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

2015年6月6日

Bug-org 1162818 [IME] Typing a name in Japanese in facebook message compose produces junk (or crashes)
初回投稿日時: 2015年06月06日14時01分03秒
最終更新日時: 2015年06月06日14時01分31秒
カテゴリ: Mozilla Core Mozilla41 バグ修正
SNS: (list)

Facebookでメッセージを作成する際に、宛先をIMEを利用して入力しようとすると、入力結果が重複していき変になる上、WindowsでTSFモードだとTIP内部でクラッシュすることもあるというバグです。

メジャーなサイトなのに、今までバグ報告が無かったのが不思議ですが、新しいregressionではありません。

Geckoは、<input>要素等のテキストエディタのwidthプロパティ等、再レイアウトが必要になった場合、そのエディタのフレームを一度破棄してしまいます。その際に、エディタの内容と選択範囲は一度nsTextEditorStateに保存され、nsEditorは破棄こそされないものの、一度、そのメンバが一部、クリアされます。その後、フレームが再生成されると、nsTextEditorStateが値と選択範囲を復元後にnsEditorを再度初期化し、nsEditorが選択範囲等を実際にDOMに反映させます。

この際に未確定文字列は、value値の一部になってしまっていますし、IMEの未確定文字列の範囲の情報は破棄されてしまっていたため、nsEditorは再初期化された後は、元の未確定文字列を消すことができず、新しいキャレット位置に未確定文字列を新たに挿入するという挙動になってしまっていました。

そこで今回、nsEditorが再初期化される際に、未確定文字列を確定済みの文字としてではなく、未確定文字列として復元するようにしました。

まず、最新の未確定文字列の状態や文節情報は幸い、TextCompositionクラスが保存しています。そこで、nsEditorは破棄される際にTextCompositionへのポインタをクリアせず、再初期化された際に再利用することにしました。

nsEditorが再初期化されている際には、保存していた未確定文字列を含むテキストノードは、フレーム破棄時に同じ内容で再生成されているため、今までと同様に捨てるようにしましたが、未確定文字列のスタート位置は初期化せず、そのまま保存しておくようにしました。

次に、選択範囲が初期化される際に、TextCompositionから得られる情報と、未確定文字列のスタート位置の情報を基に、文節ごとのIME用の選択範囲を復元し、見た目を元に戻すようにしました。ただし、これは、非アクティブウインドウで発生した場合、次にフォーカスが得られるまで、実行されません。レアケースですし、一部プラットフォームでしか発生しない問題ですが、現在のGeckoの仕様上、どうしようもありません。

そして、次にNS_COMPOSITION_CHANGEイベントをnsEditorが受け取った際には、未確定文字列だったはずの場所を新しい未確定文字列で置換するようにしました。なんとこの部分(nsEditor::InsertTextImpl()nsEditor::InsertTextIntoTextNodeImpl()は、メンバ変数を使ったトリックで、未確定文字列がある場合に引数を無視することで動いていたため、その呼び出し元から修正する必要があるという、Netscape時代からの隠れたバグの修正になってしまいました。

最後に、TSFモードでは、未確定文字列が期待通りにTIPから送信されないことが多々あったので、フレームの再生成中には一切、TSFに通知を送らないようにし、情報を提供できる準備が整ってから通知を出すように修正して対応しています(ただし、一部のケースで高速に入力すると未だにこのバグは再生しますが、レアケースにはなっています)。

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

bug-org 1162818を含むエントリ

このエントリへのリンク元

このエントリを参照しているURIはありません。