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:
Tweet (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に通知を送らないようにし、情報を提供できる準備が整ってから通知を出すように修正して対応しています(ただし、一部のケースで高速に入力すると未だにこのバグは再生しますが、レアケースにはなっています)。