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

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

もずはっく日記(2013年3月)

2013年3月27日

Bug-org 790516 [TSF] Should dispatch DOM events when document is unlocked
初回投稿日時: 2013年03月27日19時21分07秒
カテゴリ: Mozilla Core Mozilla22 TSF Windows バグ修正
SNS: (list)

TSFのドキュメントロックが、仕様通りに動かないのでデザインを大幅に見直しました。

TSFは、TIP (IME)がアプリにアクセスを行う際に、ITextStoreACP::RequestLock()を呼び出し、アプリ自身や、他の何らかのテキストサービスが、そのコンテンツを変更できないようにロックを行ってから処理を開始します。

ITextStoreACPの実装側(GeckoではnsTextStore)は、ロックを受け入れることができるなら、ITextStoreACP::RequestLock()内でITextStoreACPSink::OnLockGranted()を呼び出します。TIPは、この、OnLockGranted()が呼び出されている間が、ロックが実際に実行されている、という状況になりますので、アプリ側から見ると、OnLockGranted()を呼び出している最中に、文字列を変更するメソッドが呼ばれたり、キャレット位置を変更するメソッドが呼ばれたり、コンテンツの内容を調べるメソッドが呼ばれたり、コンテンツ中の特定の文字の画面座標を調べるメソッドが呼ばれたりします。

従来のnsTextStoreは、各種メソッドがTSFから呼び出された時に、逐一、DOMイベントを発行して、エディタの内容に反映し、最新のコンテンツの情報を調べて返す、という実装でした。つまり、OnLockGranted()の最中に、DOMイベントが発生するため、そのイベントハンドラから、エディタの内容や、フォーカスの移動といった、何らかの変更が可能で、実際にはロックができていない状態でした。このため、実際にそのような状況が発生すると、TIPが混乱してしまうということがありました。

今回の修正で、nsTextStoreは以下のように修正されました。

まず、未確定文字列の変更等、ドキュメントの変更に関するアクションが呼ばれた場合、アクションという形で記録だけを行い、OnLockGranted()から処理が戻ってきてから、ため込んだアクションから、DOMイベントを一気に発行するようになりました。

そして、最新のコンテンツの情報は、アクションがペンディング状態になっている時には取得できませんので、ロック後、最初に、最新のコンテンツ情報や、選択位置の情報をキャッシュし、各アクションが記録される際に、このキャッシュしたコンテンツのみを更新して、TSFにはこの情報をもとに応答する、という形をとっています。

また、コンテンツの任意の文字の位置情報だけはどうしようもありませんので、レイアウトがまだ完了していない、というエラーを発行するようにし、記録されたアクションを全て実行した直後に、TSFに対して、レイアウトの計算が終了した旨を伝えるようにしています。

今回の修正により、まず、コンテンツの情報は、一回のロックにつき、一回しか取得しにいかなくなりましたので、CPUパワーの必要な、クエリイベントを利用を大幅に削減しました。これにより、軽快に動作するようになっています。

また、選択位置の変更と、文字列の変更の合間でクエリが行われた場合に対応するための中途半端な、コンテンツ情報のキャッシュコードをごっそりと削除することができました。

そして余分なtextイベントを発行して、未確定文字列がちらついてしまうのを阻止するために、最後に発行したtextイベントを記録し、比較するコードの削除もできました。

これにより、かなり、壊れにくい、安定した、読みやすいコードに生まれ変わったと言えます。

ただし、この修正が入った今でも、RequestLock()中にDOMイベントが発生することになりますので、そのハンドラにより、何らかの変更が行われた場合に、TSFにそれを通知する手段がありません。これはまた、別のバグで対応予定ですが、XP側に相当量の変更が必要なので、今年中に取りかかれるかすら、見通しが立っていません。

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

bug-org 790516を含むエントリ