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

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

もずはっく日記(2014年9月)

2014年9月25日

Bug-org 1066594 [TSF]Microsoft IME 2010 remove typed text by converting character
初回投稿日時: 2014年09月25日01時11分44秒
カテゴリ: Mozilla Core Mozilla35 TSF Windows バグ修正
SNS: (list)

MS-IMEで、変換中に新たに文字を追加入力すると、変換している部分が確定され、追加の文字が未確定文字列として挿入されます。しかし、MS-IMEは非常にトリッキーにこれを実現しています。まず最初に、未確定文字列に新しい文字を追加し、変換済みの文節のみを部分的に確定します。そして、新しい文字だけ未確定のまま、その状態が継続します。この複雑な動作がGeckoではうまく処理できていなかったのをBug-org 1057192で修正したのですが、その修正が中途半端で、未確定文字列の後ろに確定済みの文字が既にある場合は、追加入力した一文字が、キャレット直後の一文字を上書きしてしまう、というバグが残ってしまっていました。

部分確定を行う際に、まず、最新のコンテンツと選択範囲を保存しておき、未確定部分を一旦、コンテンツから取り除き、通常通りに確定。その後でコンテンツと選択範囲を復元し、compositionstartを生成する、という前回の修正の仕方にこのバグの原因がありました。

nsTextStoreは、TSFのドキュメントロックを実現するために、コンテンツや選択範囲変更のリクエストを即座にエディタに反映させるのではなく、キャッシュしておいたコンテンツと選択範囲を、TSFからのリクエストに応じて変更しつつ、それに必要な後でエディタに反映される際に必要なDOMイベントをpending actionとして、配列に保存し、ロック解除時にDOMイベントを連続して発火するという方法をとっています。

このため、上記の処理の流れでは、pending actionからcompositionstartイベントを生成する際には、復元したはずの、新しい未確定文字列をエディタ側に送っていないのに、未確定文字列が存在しているはずの、その部分を選択するようにエディタにイベントを発火し、その部分を上書きする形で未確定文字列を生成しようとしていました。これが、新しい未確定文字列と同数の確定済みの文字が上書きされてしまう原因です。

新しい未確定文字列はcompositionstartイベントの後に続くtextイベントで自動的に送信・挿入されるので、compositionstartイベントの発火時には、選択範囲を変更して上書きするのではなく、部分確定後のキャレット位置にそのまま、未確定文字列が挿入されるように修正しました。

今回の一件で、キャッシュをトリッキーにいじっても、それがpending actionの解消時に結果として反映されるわけではないという、当たり前の教訓が得られました。

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

bug-org 1066594を含むエントリ