Bug-org 1053048 Accessing selectionStart or selectionEnd from nsISelectionListener::NotifySelectionChanged() may cause cancelling the edit action
初回投稿日時: 2014年08月26日11時45分49秒
最終更新日時: 2014年08月26日11時48分36秒
カテゴリ: Firefox OS Mozilla Core Mozilla34 TSF バグ修正
SNS:
Tweet (list)
<input>
要素や、<textarea>
要素に対して、アドオン等がnsISelectionListener
利用して、キャレット位置の変化を監視し、NotifySelectionChanged()
が呼び出された時に、selectionStart
や、selectionEnd
の値を取得しようとしている場合、これらの要素のkeydown
イベントで、要素のレイアウトを変更すると、編集した内容がキャンセルされる、というバグです。
日本で必要としている、Firefox OSのキーボードAPIの修正が投入されないので、該当のバグを読んでみると、このバグが原因で、一部のテストがオレンジになっていることが分かりました。そこで、急遽、調査して修正することにしました。ちなみに、TSFには、キャンセル前のテキストの変更通知が行われた後、キャンセルされていたので、TIPを混乱させる原因になっていそうです。実害は未確認ですが。
nsEditor
は、編集作業を行っている間、表示がばたついてパフォーマンスが落ちないように、選択範囲・キャレット位置の変更通知や、画面の再描画を抑制し、編集が終わってから一気に行う様になっています。それが終わると、締めに、nsIEditorObserver::EditAction()
または、nsIEditorObserver::CancelEditAction()
を呼び出しています。
一方、<input>
要素や、<textarea>
要素は初めてフォーカスを持った時にnsPlaintextEditor
を生成し、編集を管理させ、レイアウトの変更で、フレームが再構築される場合には一旦、エディタを破棄し、フレームが再生成された後にエディタを再度作成し、そのvalue
値を編集対象としています。
この、value
値の保存タイミングと、値に変化があったかどうかを保持しているフラグの更新タイミングが問題でした。前者は、エディタを破棄する直前にvalue
値を内部で保持している変数にエディタの最新情報を設定していたのですが、後者のフラグは、nsIEditorObserver::EditAction()
が呼び出された時に、初めて更新されていました。このため、エディタを破棄する際には、新しいvalue
値をすでに取得しているものの、変更されたことはまだ記録していないので、デフォルトのvalue
値を取得しにいき、編集前のvalue
値でエディタが再生成され、編集がキャンセルされてしまっていました。
今回の修正で、要素を管理している側では、エディタを破棄する前に、まだ、nsIEditorObserver::EditAction()
が呼び出されていなかった場合には、先に呼び出すように変更し、何があっても、期待通りの順序で処理が行われるように修正しています。