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

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

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

2014年8月14日

Bug-org 1050703 [TSF] Cursor doesn't move when input an Enter with IME in Contenteditable = true field
初回投稿日時: 2014年08月14日11時56分13秒
最終更新日時: 2014年08月14日11時56分59秒
カテゴリ: Mozilla Core Mozilla34 TSF Windows バグ修正
SNS: (list)

TSFモードで、HTMLエディタの行頭に文字を入力しようとすると、前の行末に入力される、というバグです。

contenteditableな要素等、HTMLエディタ上でEnterキーを押すと、<p>要素が閉じられ、新たに、<p>要素が生成されます。つまり、

<p>一行目</p>
<p></p>

という感じになります。ただし、空の要素に通常のフォントサイズの行高を持たせるため、実際には<br>要素が挿入されています。

<p>一行目</p>
<p><br></p>

TIPにテキストやキャレット位置を返す場合、このHTMLの内容を、プレーンテキストとして扱って、その内容やオフセットを利用しているのですが、この、変換時に、全ての要素の末尾に<br>要素が存在しているのを期待していたのが原因でした。

例えば、

<p>一行目</p>
<p>二行目</p>

という場合、生成されるプレーンテキストは、"一行目\r\n二行目"ではなく、"一行目二行目"となっていました。このため、HTMLエディタ上での一行目末尾と、二行目行頭は同一のオフセットとなり、selection setイベントを利用して、キャレット位置を指定すると、一行目の末尾が優先されていました。

根本的なバグの修正方法は、<p>要素の末尾に改行文字を挿入して扱うということになりますが、ちょっとパッチを書いただけではうまくいきませんでした。また、成功しても副作用の恐れがあり、現在対応中のバグの数から、もう新しいバグを処理する余裕がありませんでしたので、nsTextStore側で回避することにしました。

nsTextStoreは常に、compositionstartイベントを送信する前に、selection setイベントを利用して、キャレット位置をTIPの指示通りの位置に移動させています。しかし、設定すべき位置が元々の位置と同じであれば、そもそもこれを行う必要がありませんので、そのように変更しました。これにより、行頭にキャレットがある場合、キャレット位置が行末に再設定されることを抑制しています。

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

bug-org 1050703を含むエントリ