Bug-org 1037346 Unexpected assertion in nsTextStore at running toolkit/content/tests/chrome/test_dialogfocus.xul
初回投稿日時: 2014年07月24日06時04分39秒
カテゴリ: Mozilla Core Mozilla33 TSF Windows バグ修正
SNS:
Tweet (list)
TSFモードを有効にして、全テストを走らせてみると、toolkit/content/tests/chrome/test_dialogfocus.xul
を実行中に、nsTextStore
がassertionを吐き、オレンジになるというバグです。
問題のテストはダイアログを開き、初期フォーカスが想定通りの要素になっているのかを検査していました。しかし、このテストの奇妙なところは、window
でfocus
イベントをcapture
フェイズで捕まえ、そのターゲットを調べ、さらに、そのままダイアログを閉じてしまう、という、現実ではちょっとあり得ないものでした。
IMEStateManager
のログで調べてみたところ、ダイアログの<input>
要素にフォーカスが移動した時点で、IMEStateManager
が、IMEの状態を有効にしにいくのですが、この際に、まだ、フォーカスを持っている要素をグローバル変数に格納していませんでした。そして、そのまま、IMEStateManager::UpdateIMEState()
が呼び出され、あり得ないフォーカス状態を元にIMEContentObserver
が作られ、nsTextStore
がフォーカスを取得した処理を行っていました。その後、IMEStateManager::UpdateIMEState()
が終了し、元のフォーカスの移動時の処理に戻ってきた後、<input>
要素のエディタがフォーカスイベントを受け取った際に、本来なら存在しない、IMEContentObserver
を正しい情報と共に再生成し、nsTextStore
が再び、フォーカスを取得したという通知を受け取って、assertionを吐いていた、という状態でした。
問題は何故、予期しないタイミングでIMEStateManager::UpdateIMEState()
が呼び出されていたか、ということなのですが、要素が期待するIMEの状態を、nsIContent::GetDesiredIMEState()
で取得しにいくと、その段階で、<input>
要素がエディタをようやく作成し、エディタの初期化処理が、IMEStateManager::UpdateIMEState()
を呼び出していたため、このような変なスタックになっていたわけです(エディタを後から作るのは、<input>
要素が大量にあるサイトでも、初期化のパフォーマンスが低下しないようにするために、初めて必要になった時、例えば、フォーカスを受け取った時にエディタを生成するようになっています)。
IMEStateManager::UpdateIMEState()
が呼び出された時点で、グローバル変数が期待通りの状態になっていれば大丈夫かと思いましたが、他のテストがやたらとオレンジになってしまうのでこのアプローチは断念し、ちょっとダサいですが、nsIContent::GetDesiredIMEState()
を呼んでいる最中は、IMEStateManager::UpdateIMEState()
が呼び出されても何もしない、という形で修正しています。