TSFは、IMEによるコンテンツの変更をTSFに通知してはいけないという仕様になっているのを、nsTextStore
内でフラグを用いて管理していましたが、未確定文字列の変更等によって発生するDOMイベントからエディタのコンテンツが変更されたことか、IMEの操作による変更なのかの見分けがつかないという問題がありました。
Bug-org 960866の修正により、mozilla::TextComposition
に問い合わせれば、エディタがWidgetTextEvent
を処理中かどうか、つまり、IMEの未確定文字の変更、もしくは確定での変更が発生したのか、他の要因でエディタの内容が変更されたのかを、nsTextStateManager
で判断できるようになりましたので、これを利用し、TSFでは、エディタがWidgetTextEvent
を処理中に発生した変更は無視することができるようになりました。
ただし、nsTextStore
側にはまだ対応をきちんと入れていないため、未確定文字列の変更等の最中にJSから加えられた変更は、まだ、TSFには通知されません。
content/events
配下のファイルは全て、dom/events
に移動されましたが、ファイルの内容はそのままの移動でした。このフォルダ配下のファイルはほとんどが古くから存在しているものなので、ns
プレフィックス付きのクラス・ファイル名を利用しているため、ヘッダファイル内では、引数の型の定義が名前空間の付与で長くなりがちで、ソースコードの80桁制限のため、読みづらいところが多いのが問題になっていました。そこで、これらのファイル内のクラスを全て、mozilla::dom
か、mozilla
名前空間に移動させ、モダンなクラス名に変更することにしました。
このバグでは、nsDOM*Event
という名前で定義されていたクラスを全て、mozilla::dom::*Event
という名前に変更しています。
この際に、Event.h
のEvent
クラス等、あまりに一般的すぎる名前になるため、ヘッダファイルの方は、あえてすべてエクスポートし、mozilla/dom/*Event.h
でインクルードするように修正しています。
文字にするとこれだけですが、30クラスぐらいあった上に、一番ベースのコンクリートクラスである、nsDOMEvent
のmozilla::dom::Event
化には苦労させられました……
GeckoのIMEまわりのコードを見たことある人は分かると思いますが、現在のGeckoでは、widget
側で様々なルールに則ってイベントを発行しなければエディタが正確にハンドリングできない上、DOMイベントの発生順序等にもプラットフォーム毎にバグが混入する可能性があります。そこで、これを簡素化し、プラットフォーム間の違いが発生しにくいように再設計することにしました。
このバグではまず、リファクタリングを行いやすい様に、WidgetTextEvent
の保持する文節情報をnsTArray
の派生クラスで処理しやすくし、また、Netscape時代から続く、WidgetTextEvent
の未確定文字列の文節情報をnsDOMTextEvent
でコピーする、という無駄で分かり難い設計を改善することをゴールにしました。
この修正により、WidgetTextEvent
は、新たに定義された、TextRangeArray
クラスのインスタンスを必要な場合にのみヒープに確保して、それへの参照を保持するようになりました。このため、スタックに文節情報を保存し、メモリの断片化を抑えるという手法が使えなくなりましたが、TextRangeArray
は、nsAutoTArray<TextRange, 10>
の派生クラスで、9文節とキャレットの情報、または10文節の情報を、再アロケーション無しで取り扱えるため、今回の修正による新たなメモリ断片化は起きづらいのでは無いかと思います。
またこのクラスは動的にアロケーションし、参照カウンタで管理するようになっています。このため、nsDOMTextEvent
内でコピーを作成する必要が無くなり、その結果、nsDOMTextEvent
、その固有のインターフェースであるnsIPrivateTextEvent
、文節の情報をXPCOMとして表現するnsIPrivateTextRange
、これを配列として表現するnsIPrivateTextRangeList
、そしてこれらのコンクリートクラスである、nsPrivateTextRange
とnsPrivateTextRange
を削除することができました。
そして、TextRangeArray
は、TextComposition
がnsEditor
の代わりに保存するようになりしました。これにより、文節情報にはエディタ外からでも簡単に参照可能になっています。これにより、nsEditor
と、IMETextTxn
クラスの関係を今までよりも疎遠にすることに成功しています。
言葉では非常に伝わりにくいですが、興味のある方はパッチを参照してみてください。かなり、エディタやイベント周りのコードがシンプルになったことが分かると思います。