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

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

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

2014年11月21日

Bug-org 1047588 Intermittent 456727-2.html,test_bug611182.html | application crashed [@ mozilla::IMEContentObserver::Init(nsIWidget*, nsPresContext*, nsIContent*)] after "Assertion failure: mEditor (Failed to get editor), at dom/events/IMEContentObserver.cpp:127" 初回投稿日時: 2014年11月21日16時17分44秒
最終更新日時: 2014年11月21日16時18分14秒
カテゴリ: Mozilla Core Mozilla35 Mozilla36 バグ修正
固定リンク: id=2014112100
リンク元: 0件
SNS: (list)

Bug-org 496360の修正によるregressionというか、その修正自体のバグです。Bug-org 496360の修正で、IMEContentObserverは、エディタの編集アクション一回につき、一回だけ通知を発行することで、パフォーマンスを向上させていますが、このためには当然、フォーカスを持ったエディタの取得が必要になります。デバッグビルドでは、エディタの取得に意図せず失敗した場合に、クラッシュするようにしていましたので、これにより、レアケースのバグが自動テストであぶり出された形になります。

ちなみに、リリースビルドではパフォーマンスが従来通り悪いまま、クラッシュせずに動作するようになっていたので、実際のユーザがこれによってデータロス等を経験はしている可能性はあまりないと思います(このレアケースにはまった時に、膨大な量のテキストを貼り付けるとしばらくの間ハングアップするので、その間に強制終了するとなんらかのデータロスが発生している可能性はありますが)。

とにかく発生頻度が低く、1日中テストしてても、2回ぐらいしか再現しないので、原因の特定にすごい日数かかりましたが、結局、どのようにしてその状況に陥るのかは最後まで分からずじまいでした。とりあえず、判明したのは、designModeonに設定した時、なぜか、エディタがフォーカスを取得した時点で、documentは編集可能と状態更新済みなのに、nsDocShellに編集可能になったことの通知とnsHTMLEditorへのポインタの受け渡しが終わっていない、という状況が発生しうるということでした。

これにより、IMEStateManager::GetRootEditableNode()は編集可能と期待通りの結果を返すのに対し、nsContentUtils::GetHTMLEditor()はまだnsDocShellnsHTMLEditorが登録されていないので、nullptrを返してしまうことが分かりました。

今回の修正では、問題のコードが呼び出される時は、必ずnsEditorEventListener::Focus()がスタックに含まれているので、この時経由する全てのメソッドにエディタへのポインタを引数で渡し、IMEContentObserver::Init()が確実にエディタへのポインタを利用できるようにしています。

比較的安全な修正かつ、このオレンジの頻度が比較的高いということで、Auroraでも修正されています。

Bug-org 1083067 Make nsGtkIMModule simpler 初回投稿日時: 2014年11月21日16時24分39秒
カテゴリ: GTK Mozilla Core Mozilla36 バグ修正
固定リンク: id=2014112101
リンク元: 0件
SNS: (list)

Bug-org 1077345の修正時にnsGtkIMModuleの修正が大きくなってしまうので、事前の整理を行った方がレビューがスムーズになるために行ったリファクタリングです。

また、Bug-org 1083098の修正に対するフォローアップもかねて、意味合いが変化したメソッドのリネームや、論理的に正しい動作への微修正等も行っています。

Bug-org 1094000 Caret position becomes out of message body text box 初回投稿日時: 2014年11月21日16時38分16秒
カテゴリ: Mozilla Core Mozilla36 バグ修正
固定リンク: id=2014112102
リンク元: 0件
SNS: (list)

min-heightが指定されていないcontenteditableな要素の内容を、Backspaceキーで全て削除すると、プレースホルダー用(高さ確保用)の<br>要素の自動挿入が行われず、height: 0;になってしまい、キャレットが変な位置に表示されるというバグです。

全てを選択した状態からDeleteキーやBackspaceキーで削除した場合や、Deleteキーで削除した場合には問題がありませんでしたが、Backspaceキーで削除した場合のみ、このバグが発生していました。なぜこんなことになっていたかというと、選択範囲無しでBackspaceキーが押された場合のみ、専用のパスで削除処理を行っていたため、このような変な条件付きのバグになってしまっていました。

Backspaceキーで削除した場合にも立てておかないといけないフラグを立てるようにし、正常に動作しているケースと同様にnsHTMLEditRules::InsertBRIfNeeded()が後処理で確実に呼び出されるように修正しています。

なお、他のブラウザの動作と比較した場合、未編集のcontenteditableな要素も<br>要素を自動的に挿入するべきなようなので、そちらはBug-org 1098151にバグを登録し、エディタのモジュールオーナーのEhsanの判断を待っているところです。

Bug-org 1097238 Non-ASCII input with GTK_IM_MODULE=xim broken after bug 1083067 初回投稿日時: 2014年11月21日16時52分57秒
カテゴリ: GTK Mozilla Core Mozilla36 バグ修正
固定リンク: id=2014112103
リンク元: 0件
SNS: (list)

Bug-org 1083067の修正によるregressionです。少なくとも、iBusでデッドキーを利用しても、入力できなくなっていました。

GTKでのデッドキーでの入力は、簡単なIMEが内部的には利用されているわけですが、デッドキーが押された後に、何らかの文字のキーを入力し、デッドキーの入力が成立すると、いきなり、確定のイベントが発生していました。ところが、Bug-org 1083067の修正で、確定イベントが発生した際に、未確定文字列が無い場合、何も処理せずに終了するように修正してしまっていたため、デッドキーを利用しての入力が全て無視される形になっていました。

未確定文字列が無い場合に確定イベントが発生した場合、確定する文字列が空文字列の場合はそのまま何もしないようにしていますが、空では無い場合、compositionstartからcompositionendまで一通り発火させて、文字が入力されるように修正しています。

Bug-org 1063857 Spaces between characters are not equal for "text-align-last: justify" 初回投稿日時: 2014年11月21日17時21分29秒
最終更新日時: 2014年11月21日17時26分24秒
カテゴリ: CSS Mozilla Core Mozilla36 バグ修正
固定リンク: id=2014112104
リンク元: 0件
SNS: (list)

元々は、Bug-org 288439に2005年に登録して、大きなリファクタリングにブロックされ、そのまま放置してしまっていたバグなのですが、今回、Xidorn Quanが修正してくれたので、紹介しておきます。なお、サマリは、text-align-lastと書かれていますが、text-align: justify;の場合も修正されています。

Geckoは日本語と中国語の文章であることが明白な場合、例えば、lang="ja"が指定されている場合に、日本語か中国語、つまり、かな、カナ、漢字等はjustifiableな文字と判断し、各文字の両側にスペースを「半分ずつ」追加してレイアウトします。ただ、Firefox 3.0で設計変更されたnsTextFrameでは、justifiableな文字の判断対象から、行頭・行末の文字は除外していましたし、justifiableな文字とjustifiableではない文字との間にも半分のスペースしか追加されていないため、以下のスクリーンショットのように、追加されるスペースが大きい時に、明らかにバランスの悪い文字の配置になってしまっていました。

Gecko 35以前の日本語のjustification

見やすくするために、一文字おきに選択、非選択を行ってます。これを見ると、行頭の「自」と、行末の「、」にはスペースが追加されず、「E」の前の「、」の後ろと、「)」の後ろの「が」の前にはスペースがもう半分追加されていないとバランスが悪いのが見て取れるかと思います。

今回の修正により、期待通り、以下のように表示されるようになりました。

Gecko 36以前の日本語のjustification

これにより、行頭の「自」、行末の「、」には内側にそれぞれ半分ずつスペースが追加され、justifiableではない文字の直前、直後にある文字には一個分のスペースが追加され、均等なレイアウトになっているのが分かるかと思います。

本当は、justifiableではない文字の方にスペースを追加し、インラインボックスの幅を広げるのがCSS 3 Text Moduleの仕様では正しいのですが、それはまた別のバグでの対応、ということになっています。

2014年11月25日

Bug-org 1077345 Make compositionend event dispatchers of widget simpler 初回投稿日時: 2014年11月25日23時35分39秒
カテゴリ: Mozilla Core Mozilla36 バグ修正
固定リンク: id=2014112500
リンク元: 0件
SNS: (list)

IMEが未確定文字列を確定する際、widgetは、NS_COMPOSITION_CHANGEイベントを文節情報無しで発火し、未確定文字列から文節情報を削除した後、NS_COMPOSITION_ENDイベントを発火して、エディタがこれを受け取ると、IMEからの入力を一旦打ち切る、という形になっていました。しかし、これは冗長な上に、e10sに移行すると、NS_COMPOSITION_CHANGEイベントとNS_COMPOSITION_ENDイベントの間で、今までには走り得なかった、別の処理が割り込んでくる可能性がありました(実際に起こりうるかはしりませんが、Javascriptのタイマー等)。

今回の修正で、確定用に、NS_COMPOSITION_COMMIT_AS_ISと、NS_COMPOSITION_COMMITイベントを新設しました。前者は発火時の未確定文字列をそのまま確定、後者はWidgetCompositionEvent::mDataで任意の確定文字列を指定できるようにしています。TextCompositionがこれらを受け取ると、必要に応じて、NS_COMPOSITION_UPDATEを発火し、その後、NS_COMPOSITION_CHANGEを文節情報無しで発火し、エディタ上から文節情報を取り除き、NS_COMPOSITION_ENDでエディタのIME編集モードを終了させます。

これにより、確定時のプロセス間通信は半減しました。さらに、別プロセス上で確定される場合、そのプロセス内のTextCompositionが必要なイベントを自動的に発火するので、これまでと同じ様に、イベントが連続して発火されることになります。