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

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

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

2015年10月31日

Bug-org 1208043 [TSF] MS-IME for Korean inserts composition string to the end of previous textnode when you type text at start of <p>
初回投稿日時: 2015年10月31日10時37分20秒
カテゴリ: IME Mozilla Core Mozilla42 Mozilla43 Mozilla44 TSF Windows バグ修正
SNS: (list)

contenteditableEnterキーを押した時の動作には2種類あって、<div contenteditable>foo</div>というエディタ上では<br>要素が挿入し、キャレットのその後ろに移動させますが、<div contenteditable><p>foo</p></div>というエディタで(<p>要素内にキャレットがある時に)は新しい<p>要素を生成して、その内部にキャレットを移動させます。このバグは後者の場合に、Enterキーを押した直後、つまり空の<p>要素でハングル文字を入力しようとすると、ひとつ前の<p>要素の最後に入力されてしまうというバグです。

まずそもそも何故このようなことが発生しているのかというと、ハングル用のMS-IMEは非常に特殊な挙動で未確定文字列の入力開始を通知してきている点にありました。普通のTIPは、ITfContextOwnerCompositionSink::OnStartComposition()を呼び出して、明示的に未確定文字列の編集が始まったことをアプリに通知してから、文字の入力や、選択範囲の設定を行います。それに対してハングル用のMS-IMEは、先にITextStoreACP::InsertTextAtSelection()を呼び出し、最後にITfContextOwnerCompositionSink::OnStartComposition()をその時に期待される選択範囲と共に呼び出します。

このような順序のため、TSFTextStoreは、まずテキストの挿入が未確定文字列の編集無しに行われ、その後、別の範囲をターゲットに未確定文字列の編集が開始されたと考えていました。ですので実際に、最初の編集に対してcompositionstartcompositionupdatecompositionendを送信した後、compositionstartが再度送信されるという動作になってしまっていました。

そして、何故、挿入位置がずれてたかというと、現在、GeckoがDOMツリーからIME APIに対して渡すコンテンツの内容は<br>要素のみを改行文字に変更したプレーンテキストになっています(ContentEventHandlerで生成)。このため、<p>foo</p><p></p>というDOMツリーでは、空の<p>要素内にキャレットがある場合のオフセットと、最初の<p>要素の末尾(つまり、fooテキストノードの末尾)のオフセットが同じになってしまいます。未確定文字列が指定された範囲で変換が開始されるこのケースでは選択範囲を再設定しなくてはいけませんが、選択範囲をContentEventHandlerを利用して設定した場合、常に、後者の位置が優先されてしまうため、このようなバグの発生につながっていました。

今回の修正では、未確定文字列の編集が開始される際に、直前に行われてキューに入っている内容を確認し、直前の内容がITfContextOwnerCompositionSink::OnStartComposition()の指定してきた範囲に直接文字を挿入していた場合、compositionstartcompositionupdatecompositionendをキューから取り除き、新たにcompositionstartcompositionupdateをあるべき形でキューに入れ直すことでContentEventHandler側のオフセットの矛盾問題に触れないように修正しました。

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

bug-org 1208043を含むエントリ