Bug-org 806996 CreateTextStateManager not called when editor is reframed during focus
初回投稿日時: 2012年11月14日13時58分50秒
カテゴリ: Mozilla Core Mozilla19 TSF バグ修正
SNS:
Tweet (list)
Bug-org 805306の修正によるregressionで、<input type="text">
や、<textarea>
といった要素が、フォーカスを持っている際に、nsTextStateManager
はその匿名div要素を監視して、選択位置の変更や、テキストの変化をIMEに通知していますが、一部リフローが原因でリフレームが発生した場合に、監視している匿名div要素がエディタから削除され、新たに別の匿名div要素が使われるようになっても、古い方を監視し続けていた、というバグです。
Android版で、Google Instantがうまく動かず、未確定文字列が複製され続けるという形で症状は出ていたようです(私の端末ではIMEの違いのせいか、再現しませんでしたが)。
nsEditor
からnsIMEStateManager
にフォーカスが変わったと擬似的に通知していたのですが、nsTextStateManager
はまだ、古い匿名div要素で監視が成功していると判断していたのがこのバグの直接的な原因でした。ただ、nsIMEStateManager
とnsTextStateManager
の設計の悪さがこのバグを招いているので、この機会に再設計を行っています。
まず、エディタからは、実際に起きたことをそのまま伝えるように、nsIMEStateManager::OnChangeFocus()
ではなく、nsIMEStateManager::UpdateIMEState()
を利用するようにしました。
nsIMEStateManager::UpdateIMEState()
はIMEの状態に変化がない場合には、何もしていなかったので、変化がない場合でも、nsTextStateManager
が監視している匿名div要素が既にドキュメント内にない場合には作り直すように修正しています。
また、このままではIMEへのフォーカス移動通知が非常に壊れやすい設計であることも問題なので、これを確実に通知できるように、nsTextStateManager
は編集可能な要素がフォーカスを持つ場合には常に存在するように修正し、nsTextStateManager
のコンストラクタで、nsIWidget::OnIMEFocusChange(true)
を呼び出し、nsTextStateManager::Destroy()
で、nsIWidget::OnIMEFocusChange(false)
を呼び出すようにし、確実に1:1の呼び出し回数で、ミス無く処理できるように改善しています。
また、IMEのテスト中にのみ、IMEにフォーカス移動を通知する直前にその内容をカスタムDOMイベントで、そのドキュメントに通知するようにし、自動テストでカバーしています。
この修正により、nsTextStateManager
の動作が非常に分かりやすい物になったと思います。