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

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

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

2021年9月9日

Geckoのエディタのリファクタリング
初回投稿日時: 2021年09月09日21時46分39秒
最終更新日時: 2021年09月23日08時50分13秒
カテゴリ: Editor Firefox
SNS: (list)

なんとなく気まぐれで久しぶりに書いてみようかなと。

今はGeckoのeditor moduleのオーナーとしてゴリゴリとやっていますが、振り返るとエディタをどうこうしないと、みたいな感じでオーナーになったわけではなく、当時のマネージャに「IME周りのハンドリングをもっと向上するには最終的なアウトプットであるエディタの理解も必要」とか、「エディタはこの10年ぐらい(当時)、誰も積極的にメンテナンスしてないので他の場所のバグに重点を置くけど面倒見る人が必要」みたいにだまして説得して就任した記憶があります。

最初に着手したのはたぶん、主要クラスのリネーム。それまでのグローバルなnamespaceにnsというprefixでクラスを置いておくのが、当時、既に他のコンポーネント(例えばDOM)が既にmozilla::domというnamespaceに移行していたりで、放置しておくとヘッダファイルの記述が面倒だな、という後ろ向きなモチベーションから入っていった気がします。まあ、実際に修正してスッキリはしたんですが。

次に取り組んだのは脱XPCOM。Geckoのエディタは当時、mozilla::EditorBase(旧名:nsEditor)、mozilla::TextEditor(旧名:nsTextEditor<input><textarea>用のエディタ)、mozilla::HTMLEditor(旧名:nsHTMLEditordesignModecontenteditable用のエディタ)を、最初にnsIEditorインターフェースを実装するエディタとしてEditorBaseを得、その上でさらに目的に合致するものとしてnsIPlaintextEditornsIHTMLEditorのインターフェースを持つ、TextEditorHTMLEditorを得てメソッドを呼び出したりしていました。COM周りをやったことある人なら分かると思いますが、デザイン的には綺麗なものの、とにかくQIと、その仮想クラスで定義されているvirtualメソッドの呼び出しが遅いというのがMozilla内でも当時問題になっていました。前者は64bitを超える容量の比較が連続するので当然ですし、後者はもうhot pathでは無視できないコストだというのがC++を書かれている方にはうなずいて頂けるかと。なのでこれらを解消するために各エディタユーザにはconcreate classに直接アクセスするようにしたり、各エディタが複数のルールで動作できるように作られていたediting rulesという概念を削除して、とにかく基本的に安全かつシンプルな構成にしていきました。

そんな感じでリファクタリングを楽しんでいる時に舞い込んできたのがbeforeinputイベントの案件でした。それ以前から懸案としては上がっていたのですが、どうにかしないといけない、ということで実装を始めると予想通りその道のりは長く、想像以上のものになりました(少なくとも最初に問いかけられてから実際にshipするまで5年弱かかっています)。

まずbeforeinputイベントの実装にあたって問題だったのは、エディタの各クラスが内部からpublicなメソッドを呼び出しているため、一回のユーザのオペレーションや、JSからのAPIの呼び出しがエディタモジュール内ではハッキリしないということでした。そこで、publicなメソッドを制限しこれらをActionと(勝手に)命名し、そこから呼び出されていたpublicメソッドで行われていたことをSubActionと(やはり勝手に)命名し、どこから始まって、どこで終わるのかを明確にする作業を複数のbugで行い、さらに、publicメソッドでスタック上に一時情報を保存するようにし、管理の簡略化や省メモリ化を実現しました

これらにより、beforeinputイベントの実装への下準備が全て整うと思っていました。でも、そうではなかったのが現実の厳しさでした。

最後発でbeforeinputイベントを実装しているはずなのに……に続く

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

関連するかもしれないエントリを発見できませんでしたが、無いとは限りません。