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

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

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

2015年6月19日

Bug-org 1172466 IMEContentObserver shouldn't notify IME during reflow
初回投稿日時: 2015年06月19日17時47分20秒
カテゴリ: e10s IME Mozilla Core Mozilla41 バグ修正
SNS: (list)

IMEContentObserverはフォーカスを持ったエディタの内容の変化を監視し、IMEが必要としている場合はそれをnsIWidget経由で通知します。また、自身の生成時と破棄時にはIMEにフォーカスを得たことと失ったことを通知します。

これまで前者はDOMイベントの発火が安全では無い場合のみ、安全になるのを待って非同期で生成し、後者は同期で通知を行っていました。しかし、リフローの最中はDOMイベントの発火が安全ではないにも関わらず、前者でも通知が行われるということが分かりましたし、後者は言うに及ばずです。

もし、リフロー中にIMEになんらかの通知を出すと、その通知に反応して同期的にコンテンツの内容を取得しにくる可能性があります(というかそういうIMEがほとんどです)。また、e10sモードでは、ContentCacheがそれを必ず行っています。

リフロー中にコンテンツの情報を取得しようとした場合、ContentEventHandlerはそんな状況を想定していないので、そのままペンディングとなっているリフローを全て完了させようとnsIPresShellに指示を出しますが、既にリフロー中だと、nsIPresShellはこれを無視します。このため、まだリフローが終了しないコンテンツにアクセスして、処理が失敗するケースが存在していました。

このバグの修正では、フォーカスを失う場合以外の通知を全て非同期で通知することを可能にして、非同期で実行された際にもリフロー中かどうかを確認し、リフロー中であった場合には再び、IMEContentObserverに通知を再予約します(IMEContentObserverはリフローが終了すると自動的に貯まっている通知を行うことを試みます)。

残念ながらblurの通知のみ非同期にできなかったのは、別のエディタにフォーカスが移動した際に、新しいエディタからのfocus通知との順番を保証することができなかったことと、blur通知からコンテンツを問い合わせてくるケースが通常は存在しない点にあります。

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

bug-org 1172466を含むエントリ