2015年6月6日
writing-mode: vertical-lr;
や、writing-mode: vertical-rl;
でエディタを縦書きにした際にIMMのIMEも縦書きに対応させようというバグです。
IMMでは縦書きはAPIレベルではサポートされていないのですが、composition fontに@で始まる縦書き用のフォント名を指定した場合に、IMEが縦書きをサポートしているなら、縦書きのUIや操作形態に切り替えるという暗黙のルールがあります。ですので、最初は単純にcomposition fontを取得し、その頭に@を付けたり外したりして再設定することでIMMモードで動いているIMEのUIも切り替える予定でした。しかし、色々とIMEごとに問題があり、様々なprefを追加することで、最悪の場合はユーザ自身で自分の利用しているIME用に設定を変更する必要があります。
intl.imm.composition_font
-
通常、Geckoはcomposition fontを取得し、それを横書き用、@を付けて縦書き用とします。しかし、特定のフォントを指定しておかないとUIが崩れる環境では、この設定にフォント名を設定しておけば、常にそのフォントを利用するようになります。
縦書き時には自動的に@を追加して利用されますので、@で始まらない、横書き用のフォントを指定しておいてください。また、そのフォントが縦書きに対応していることも確認しておいてください。
intl.imm.composition_font.japanist_2003
-
通常、デフォルトのcomposition fontはSystem
です。しかし、Japanist 2003に対して@System
を設定すると、候補ウインドウのレイアウトが壊れるバグがあります。これを回避するために、Japanist 2003専用のcomposition fontを指定するprefを用意しています。
このprefのデフォルト値はMS PGothic
です。
intl.imm.vertical_writing.always_assume_not_supported
-
Geckoは、現在アクティブなIMEが縦書きに対応しているかどうか、IMEのプロパティを取得して検査します。しかし、Google Chromeのように、未確定文字列の表示にだけ縦書き対応しているものの、候補ウインドウ位置の配置が縦書きに対応していないようなケースも考えられます。
もし、あなたの利用しているIMEが縦書きに対応していない場合、このprefをtrue
に変更しておけば、Geckoは常に、そのIMEが縦書きに対応していないものと仮定して、未確定文字列と候補ウインドウが重ならないように、候補ウインドウ位置を調整します。
intl.imm.japanese.assume_active_tip_name_as
-
Windowsは、アクティブなIMEがTSFに対応しているTIPの場合にTSFに対応していないアプリ上では、CUASという仕組みを用いて、アプリから見ると複数のTIPが一つの同じIMEに見えるようなトリックを使っています。
例えば、Windows 8以降では、Google日本語入力はTIPとしてインストールされていますので、IMMモードで動作しているGeckoからは、アクティブなIMEの名前やプロパティが取得できないため、縦書き非対応のIMEとして処理することができません。
もし、Windows 8以降でGoogle日本語入力のみを利用している場合、この設定値をGoogle 日本語入力 IMM32 モジュール
としておくと、TIPがアクティブな間は、常にそのIMEをGoogle日本語入力だと仮定して動作するようになります(ちなみに、Firefox 40以降、TSFモードが標準で有効になるため、Google日本語入力のユーザは、自分でTSFモードを無効化しない限りはこの設定を行う必要はありません)。
現在、縦書きのサポートがいつからリリース版で標準で有効になるかは不明ですが、縦書きがサポートされた場合、TSFモードを無効にしない方が無難です。また、縦書きのエディタを使うことがある場合は、Google日本語入力以外の縦書きに対応したTIP(MS-IMEやATOK等)を利用することをお勧めします。
ATOK X3に対応した際のregressionで、Facebookのコメント入力欄が空の場合に、IMEで未確定文字列を入力するとクラッシュするというバグです。
Facebookのコメント入力欄はcontenteditable
で作成されていて、placeholder
のような入力時に自動的に消える文字は、通常のテキストノードです。
このため、未確定文字列を挿入しようとした際に、このテキストノードがFacebookにより削除され、内部ではselection changeが発生します。selection changeが発生するとGTKアプリでは、gtk_im_context_reset()
を呼び出すことになっていますが、iBusは、preedit_start
シグナルの送信中にgtk_im_context_reset()
が呼び出されても未確定文字列を削除しない、バグっぽい動作を行います。しかし、Gecko内部では空文字列ですでに確定していますので、NS_COMPOSITION_START
が発生していない状態でNS_COMPOSITION_CHANGE
イベントが発生し、あり得ない状況としてGeckoはMOZ_CRASH()
を呼び出して安全にクラッシュしていました。
どちらにせよ、preedit_start
シグナルの送信中に未確定文字列がキャンセルされるのはユーザの意図する状況とは言えませんので、preedit_start
シグナルの送信中にselection changeが発生してもひとまず無視するように修正しました。ただし、IMEを混乱させないように、未確定文字列の開始位置はselection changeが発生した段階で補正するようにはしています。
Web開発者の方は、compsoitionstart
イベントの発生時に、選択位置や、コンテンツの内容を書き換えるのはやめてください。おそらく、様々な問題が潜んでいると思います。
mochitest-browser
の、browser_tabopen_reflows.js
が、選択範囲変更時のreflowを不要なものと判断し、テスト失敗としていたというバグです。
現在、IMEContentObserver
はエディタ内で選択範囲が変更された場合、それをIMEに通知しています。その際に、IMEやプラットフォームによっては、新しい選択範囲や、選択範囲の位置を取得しようとします。この際に、ContentEventHandler
は保留されているreflowを全て先に処理しようとします。このため、日本語環境で実行するとこのテストはかなりの環境で失敗するようになっていました。
このテストが選択範囲を変更した際に発生するかもしれないreflowは無視するように修正しています。
<input>
要素等のwidth
、height
、overflow
等、再レイアウトが必要なCSSプロパティが変更された場合、Geckoは、テキストエディタのフレームを再生成します。この際に、IMEには一度、フォーカスを失い、その直後にまた、フォーカスを得たという通知を行っていました。
フォーカスを失うという通知は、IMEやプラットフォームによっては編集中の未確定文字列を強制確定してしまうため、これらの通知は行うべきではないと言えます。そこで、今回の修正では、エディタのフレームが再生成された際に、これらの通知を出していたIMEContentObserver
を再生成せずに部分的に再度初期化するようにしました。この再度の初期化に成功した場合、そのまま通知無しで処理を終えます。もし、再初期化に失敗するような、まだ分かっていない状況が発生した場合は従来通り、IMEにフォーカス移動の通知が行われます。
Facebookでメッセージを作成する際に、宛先をIMEを利用して入力しようとすると、入力結果が重複していき変になる上、WindowsでTSFモードだとTIP内部でクラッシュすることもあるというバグです。
メジャーなサイトなのに、今までバグ報告が無かったのが不思議ですが、新しいregressionではありません。
Geckoは、<input>
要素等のテキストエディタのwidth
プロパティ等、再レイアウトが必要になった場合、そのエディタのフレームを一度破棄してしまいます。その際に、エディタの内容と選択範囲は一度nsTextEditorState
に保存され、nsEditor
は破棄こそされないものの、一度、そのメンバが一部、クリアされます。その後、フレームが再生成されると、nsTextEditorState
が値と選択範囲を復元後にnsEditor
を再度初期化し、nsEditor
が選択範囲等を実際にDOMに反映させます。
この際に未確定文字列は、value
値の一部になってしまっていますし、IMEの未確定文字列の範囲の情報は破棄されてしまっていたため、nsEditor
は再初期化された後は、元の未確定文字列を消すことができず、新しいキャレット位置に未確定文字列を新たに挿入するという挙動になってしまっていました。
そこで今回、nsEditor
が再初期化される際に、未確定文字列を確定済みの文字としてではなく、未確定文字列として復元するようにしました。
まず、最新の未確定文字列の状態や文節情報は幸い、TextComposition
クラスが保存しています。そこで、nsEditor
は破棄される際にTextComposition
へのポインタをクリアせず、再初期化された際に再利用することにしました。
nsEditor
が再初期化されている際には、保存していた未確定文字列を含むテキストノードは、フレーム破棄時に同じ内容で再生成されているため、今までと同様に捨てるようにしましたが、未確定文字列のスタート位置は初期化せず、そのまま保存しておくようにしました。
次に、選択範囲が初期化される際に、TextComposition
から得られる情報と、未確定文字列のスタート位置の情報を基に、文節ごとのIME用の選択範囲を復元し、見た目を元に戻すようにしました。ただし、これは、非アクティブウインドウで発生した場合、次にフォーカスが得られるまで、実行されません。レアケースですし、一部プラットフォームでしか発生しない問題ですが、現在のGeckoの仕様上、どうしようもありません。
そして、次にNS_COMPOSITION_CHANGE
イベントをnsEditor
が受け取った際には、未確定文字列だったはずの場所を新しい未確定文字列で置換するようにしました。なんとこの部分(nsEditor::InsertTextImpl()
とnsEditor::InsertTextIntoTextNodeImpl()
は、メンバ変数を使ったトリックで、未確定文字列がある場合に引数を無視することで動いていたため、その呼び出し元から修正する必要があるという、Netscape時代からの隠れたバグの修正になってしまいました。
最後に、TSFモードでは、未確定文字列が期待通りにTIPから送信されないことが多々あったので、フレームの再生成中には一切、TSFに通知を送らないようにし、情報を提供できる準備が整ってから通知を出すように修正して対応しています(ただし、一部のケースで高速に入力すると未だにこのバグは再生しますが、レアケースにはなっています)。
Bug 1162818のデバッグ中に見つけたバグです。<input>
要素等のテキストエディタのフレームが再生成された際にnsEditor
が再初期化される際に、大量のwarningがターミナル上に出力されていました。
WARNING: NS_ENSURE_TRUE(aSelection->RangeCount()) failed: file a:\mozilla\mc-e\src\editor\libeditor\nsEditor.cpp, line 3664
WARNING: NS_ENSURE_SUCCESS(rv, rv) failed with result 0x80004005: file a:\mozilla\mc-e\src\editor\libeditor\nsEditor.cpp, line 3643
WARNING: NS_ENSURE_SUCCESS(res, res) failed with result 0x80004005: file a:\mozilla\mc-e\src\editor\libeditor\nsTextEditRules.cpp, line 437
初回の初期化時には、nsEditor
の通常の選択範囲を管理しているSelection
はひとつの選択範囲を持っています。しかし、何故か再初期化の段階ではこれが無く、空の状態になっています。
選択範囲が存在していない場合、nsTextEditRules::Init()
の最後の方でエディタの末尾にキャレットを置くことで選択範囲を必ず存在させるという処理がありましたが、その前に、nsTextEditRules::CreateBogusNodeIfNeeded()
でbogus nodeが必要だった場合に生成しようとします。しかし、そのエディタ内に編集可能なテキストノードを見つけてしまうと、キャレット位置をセットせずに処理を終了してしまいますが、編集処理後に自動的に走るpost processingでは、選択範囲が存在していることが前提のメソッドが先に呼ばれてしまい、上記のwarningが発生し、なんと初期化処理を途中で投げ出してしまっていました。
今回の修正では、問題のpost processingが開始された際に、選択範囲がもし無かった場合、一旦、エディタの末尾にキャレットをセットすることで選択範囲を生成し、初期化処理が完遂されるようにしています。
editor/
配下のソースコードは、Netscape時代からそのまま無修正の箇所が多く、現在のコーディングルールとかけ離れていたり、いい加減なエラーハンドリングがやたらとあったりと、初歩的な問題が多いのですが、そのひとつに、行の末尾に空白がある行がやたらと存在しているという問題があります。
今回の修正では、秀丸の機能を利用して、全ファイルの行末にある無駄な空白を削除しておきました。
Linux版のFirefoxでは、Altキーでメニューバーを表示し、続いて、文字入力のキーを押すことで、それに対応したメニューを開くことができます。しかし、検索バー等のエディタでサジェスト用のポップアップが既に開かれている状態で、なおかつIMEがオンになっている際にこの操作を行うとクラッシュするというバグです。
原因は、Altキーを押した際に疑似フォーカスがメニューバーに移動していないため、IMEの無効化が行われず、IMEが意図せずフォーカス済みのエディタを無視して動作してしまったために、Gecko内部での状態管理に矛盾が生じていたことにありました。
何故か、既にポップアップが開かれていると、メニューバーがアクティブになった際に、メニューバーのキーイベントリスナに主導権が渡されず、その結果、IMEStateManager
がIMEを無効化するタイミングを失っていました。
今回の修正では、メニューバーをアクティブにする前に、存在している全てのポップアップをまずは閉じるようにしました。これにより、UI上もユーザの混乱は無くなりますし、キーイベントの奪い合いも発生しなくなります。
ただし、この修正によって、存在しないとは思うのですが、ポップアップ上にメニューバーを設置しているアドオンはキーボードでそのメニューバーを開くことができなくなっています(しようとすると、そのポップアップ自体が閉じられてしまうため)。もし万が一そういうUIを持ったアドオンでこの問題を確認された方が居ましたら、bugzillaの方へ報告し、私にご一報ください。その場合、アクティブにしようとしてるメニューバーの親がポップアップかどうかを調査し、それより下位(見た目では上)にあるポップアップしか閉じないようにコードを追加します。
ContentEventHandler
が、NS_QUERY_CARET_RECT
を処理する際に発見したキャレットの親となるフレームはnsTextFrame
であるという前提で実装されていました。しかし、エディタの内容が空の場合等にはそうではないことが分かりました。
今回の修正で、問い合わせのあったオフセットのノードがテキストノードでは無かった場合に、そのノードの子がテキストノードではないかどうかを確認した上で、それでも見つからなかった場合のみ、その非テキストノードのプライマリフレームに頼るようにしました。また、問題の間違ったassertionは無用なテスト失敗の原因になりますので、削除してあります。
Windows x64版でe10sが有効かつ、IMMモード(現在、Nightlyでもe10sモードの場合はIMMモードが標準)の場合、TabParent
がNS_QUERY_TEXT_RECT
をハンドリング中にクラッシュする、というバグです。ちなみに、crash reportを見てみると、Macでも希に発生している模様です。
散々デバッグした結果、その原因は、TabParent
がキャッシュしている未確定文字列の各文字の矩形にアクセスする際のチェックにありました。もともと、おかしな値であるUINT32_MAX
がオフセットとして指定されている場合限定のバグなのですが、取得する文字数がゼロではない場合、そのオフセット(UINT32_MAX
)と長さを足すことで、uint32_t
からオーバーフローし、小さな値になります。その結果、オフセットは、キャッシュしてる文字の矩形の最初のオフセット以上かつ、キャッシュしてる最後の文字の矩形のオフセット以下という判定にパスしてしまいます。C++に詳しくないので、なぜこれがx64ビルドでのみ発生しているのかその原因は分かりませんが、ありえないオフセットが来た場合のチェックが甘いことがクラッシュの原因でした。
TabParent
は元々、Android版のFirefoxを開発時に段階的に実装され、e10s対応でさらにコンテンツのキャッシュが増え、コードがかなり見づらい状態に陥っていましたので、上記の原因はコードを読んでいるだけでは発見できませんでした。そこで、検証をより簡単にするために、リファクタリングを行うことにしました。
現在のTabParent
は、PuppetWidget
がIMEへの通知を受け取る度に、様々な情報を更新していくスタイルです。しかし、非同期でこれが行われているため、TabParent
からすると、一部の情報のみが更新されているタイミングで、IMEからコンテンツの問い合わせが来るかもしれません。その場合、TSFではよくあるのですが、想定外の問い合わせ結果を返してしまうとTSFやTIP内部でクラッシュしてしまうことがあります。これを解決するには、PuppetWidget
側で必要な情報を揃えてからTabParent
側で一括でキャッシュを更新してしまう必要があります。
これらを踏まえて新しいデザインを考えた結果、PuppetWidget
とTabParent
双方で同じクラスをデータの保存のために利用し、IMEに対して何らかの変更通知を出す際に、PuppetWidget
側で必要な情報を揃えてから、通知に添えて新しいコンテンツの情報を送信するようにしました。
この新しいクラスは、mozilla::ContentCache
で、メンバ変数は全てprivate
で、直接それらにアクセスすることも今はできません。その代わりにこのクラスがWidgetQueryContentEvent
を直接ハンドリングしますし、PuppetWidget
の代わりにコンテンツの情報を必要に応じて自動的に取得するようにしています(例えばテキストが変更された場合は、選択範囲や、テキストの矩形も変化している可能性が高いので自動的に取得します)。
また、デバッグを容易にするため、ログも取れるようになっています。NSPR_LOG_MODULES=ContentCacheWidgets:5
で動作ログと、キャッシュの情報が取得できますので、デバッグの際にはご利用ください。
選択範囲の開始位置や終了位置の文字の矩形もキャッシュするようにしたり、キャレットの問い合わせ位置に実際にキャレットが無かった場合は、文字の矩形のキャッシュが無いか調査し、もしあれば、そこから推測してキャレットの矩形を返すようにもなっていますので、いくつかのケースで動作が改善しているかもしれません。
TSFの動作ログを取ろうとすると、nsTextStore::Initialize()
のログで、sCreateNativeCaretForATOK=
の後ろが常に壊れた値が記録されていたバグです。イージーミスでした。printf()
形式の入力の検査はコンパイラにやって欲しいですね……
2015年6月19日
IMEがキャレットの矩形を問い合わせて来た場合、GeckoのContentEventHandler
は現在のキャレット位置を問い合わせてこられた場合にはキャレットの矩形をそのまま返しますが、別の位置のキャレットの矩形をリクエストされた場合、その位置にキャレットがある場合の矩形を推測して返します。
この推測するケースでキャレットの矩形を計算するコードに縦書きの対応が入っていなかったので、それを修正しました。
e10sモードでは、IMEが同期的にコンテンツの情報を取得することができないので、TabParent
内のContentCache
が必要されるであろう文字の矩形を予めキャッシュしています。このような手法でIMEのハンドリングを実装しているため、様々なケースに対応できるように矩形のキャッシュを無理の無い範囲で増やしていかなくてはいけません。
このバグでは、IMEが選択範囲全体を含む矩形をリクエストしてきた場合に、それを返すことができるように修正しています。
このバグ自体は私の修正ではないのですが、このバグを修正してテストを書いてみると、nsITextInputProcessor
にバグがあってテストがパスしないということで、その修正だけを行いました。
nsITextInputProcessor
はbeginInputTransaction()
が呼び出された際にその引数のDOM windowに対応するnsIWidget
のインスタンスからTextEventDispatcher
を取得し、リンクします。
その後、そのnsITextInputProcessor
が別のDOM windowと共にbeginInputTransaction()
が呼び出された際に、それまでのTextEventDispatcher
から新しいものに切り替えますが、リンクが解除されたTextEventDispatcher
にその旨を通知していませんでした。そのため、すでにリンクしていないTextEventDispatcher
がIMEへの通知を既に別のものとリンクしているnsITextInputProcessor
に通知し、デバッグビルドではそのバグを検知してクラッシュしていました。
今回の修正では、TextEventDispatcher
にEndInputTransaction()
を追加し、nsITextInputProcessor
は内部で明示的にリンクを解除するようになりました。JavascriptからnsITextInputProcessor
を利用する場合には、これまでと変わらずbeginInputTransaction()
のみの呼び出ししか必要ありません。これは、endInputTransaction()
を設けてしまうと、これを呼び出し忘れたアドオン等によって他のアドオン等からの入力が再起動するまで阻害されてしまうことを防ぐためです。
GTKというかLinuxのIMEには、縦書きという概念そのものが存在していませんでした。そこで、抜本的な解決策として、誠さんがGTK側に仕様を追加するように依頼して、既に修正されました。
しかし、GTK3のみでの修正になりますし、現在のFirefox/GeckoはあくまでもGTK2がターゲットです。また、各IMEがきちんと縦書きモードをハンドリングできるようになるまで時間がかかるでしょう。そこで、Gecko側でもなんらかの対応が必要になります。
この修正では、変換のために選択された文節、もしくはそれが無い場合は、未確定文字列全体にIMEの候補ウインドウが重ならないように文節全体を縦断する大きなキャレットが存在しているかのように、それをGTKに通知するようにしました。
この修正により、候補ウインドウの文字の大きさが変化したりすることを懸念していましたが、幸い、テストした範囲ではそのような挙動の変換エンジンはありませんでしたのでこのハックを入れています。もし、UIの文字の大きさがおかしい場合を発見したらバグ報告をお願いします。
IMEContentObserver
はフォーカスを持ったエディタの内容の変化を監視し、IMEが必要としている場合はそれをnsIWidget
経由で通知します。また、自身の生成時と破棄時にはIMEにフォーカスを得たことと失ったことを通知します。
これまで前者はDOMイベントの発火が安全では無い場合のみ、安全になるのを待って非同期で生成し、後者は同期で通知を行っていました。しかし、リフローの最中はDOMイベントの発火が安全ではないにも関わらず、前者でも通知が行われるということが分かりましたし、後者は言うに及ばずです。
もし、リフロー中にIMEになんらかの通知を出すと、その通知に反応して同期的にコンテンツの内容を取得しにくる可能性があります(というかそういうIMEがほとんどです)。また、e10sモードでは、ContentCache
がそれを必ず行っています。
リフロー中にコンテンツの情報を取得しようとした場合、ContentEventHandler
はそんな状況を想定していないので、そのままペンディングとなっているリフローを全て完了させようとnsIPresShell
に指示を出しますが、既にリフロー中だと、nsIPresShell
はこれを無視します。このため、まだリフローが終了しないコンテンツにアクセスして、処理が失敗するケースが存在していました。
このバグの修正では、フォーカスを失う場合以外の通知を全て非同期で通知することを可能にして、非同期で実行された際にもリフロー中かどうかを確認し、リフロー中であった場合には再び、IMEContentObserver
に通知を再予約します(IMEContentObserver
はリフローが終了すると自動的に貯まっている通知を行うことを試みます)。
残念ながらblur
の通知のみ非同期にできなかったのは、別のエディタにフォーカスが移動した際に、新しいエディタからのfocus
通知との順番を保証することができなかったことと、blur
通知からコンテンツを問い合わせてくるケースが通常は存在しない点にあります。
e10sモードではTabParent
がIMEから受け取ったイベントを子プロセスに送信し、その結果を受けとるまでにはタイムラグがあります。そのため、未確定文字列の変更直後にIMEがコンテンツを確認しにきた場合、必ず、TabParent
側のContentCache
には古い情報がキャッシュされていることになります。
しかし、このようなシステムを想定して設計されているTSFでも肝心のTIPで対応が完璧なものはありませんし、CocoaのAPIに至っては、そのようなアプリを想定すらしていませんので、またしてもハックが必要な局面です。
今回の修正では、文字の矩形を問い合わせに来た場合、普通は最初の文字の矩形のみが重要ですので、その矩形がキャッシュにある場合、2文字目以降の矩形の情報をキャッシュしていなくても、分かる範囲で矩形を結合してIMEに返すようにしました。
Mac OS X Yosemiteの日本語入力のアプリは、長らく標準で使われていたことえりから別物になっています。この新しいIMEは何故か時折、最初の文字の矩形を取得しに来ます。
そこで、TabParent
のContentCache
がこれをキャッシュしておくように修正しました。
今のところ実害を発見していないバグですが、nsTextStore
はイベントの発火後に、そのハンドリングが終了したという通知が来ているか確認せずにTSFに様々な通知を返しているため、e10sの動作によっては、TSFやTIPがコンテンツの内容を問い合わせて来ても、想定していない結果が返されて、挙動がおかしくなったり、そもそも動作しなくなったりする可能性があります。
この修正では、イベントの発火後から、通知が来るまでの間を魔の時間帯と考え、コンテンツから変更完了通知が来るまではTSFへの通知を延期するようにしています。ただし、二つ以上のイベントが投げられた状態で、一つ目のイベントへの通知のみが返ってきた場合のようなケースには今回の修正でも不十分です。
他のバグを修正中に、何故かnsContentUtils::SendKeyEvent()
の最初の引数がnsCOMPtr<nsIWidget>
になっていることに気付きました。このため、例えばnsRefPtr<DerivedClass>
を持っているクラスからの呼び出し時には面倒で無駄なコストが発生します。
そこで、生のポインタをそのまま受け取るように修正しています。
Geckoは昔から、未確定文字列がある場合に<input>
要素や<textarea>
要素のvalue
属性値を変更しても、IMEは未確定文字列を持ったままで動作がおかしくなるようになっていました。
このバグが長年修正されなかったのは、まず、標準仕様でどうするべきか策定すべきではないかという話がありました。しかし、これは実装側の事情でどうにかしろという話になりました。IE11やGoogle Chromeでは未確定文字列は確定されます(後者はどうにも挙動が怪しいですが)。
もう一つの理由は、LinuxのiBusのように確定のリクエストが非同期で実行される場合にどうすれば良いのかという点がありました。しかし、これはTextComposition
がコンテンツ上での同期的強制確定を保証できている時点で既に問題ではなくなっていました。
今回、IMEまわりの修正を盛大に行っているため、Androidでは一部のサイトでのサジェスト機能がうまく機能しなくなるというregressionが発生してしまっていましたが、その原因の特定やバックアウトが困難なため、今回、この機能の修正に踏み切りました。
今回の修正により、以下のような例では、value
属性が変更された場合に、Geckoではtext
(Gecko独自イベント)、compositionend
、input
イベントが発生するようになっています。また、その最中にvalue
属性値を取得して処理する際にも期待通りに動作するように、内部では若干、ハッキーな手法をとって、セットした値がそのまま取得されるようになっています。これは、maxlength
等を無視することを意味していることに注意してください。
var textarea = document.getElementsByTagName("textarea")[0];
function handler(aEvent)
{
textarea.value += ", " + aEvent.type;
}
textarea.addEventListener("text", handler);
textarea.addEventListener("compositionupdate", handler);
textarea.addEventListener("compositionend", handler);
textarea.addEventListener("input", handler);
// 未確定文字列("あいうえお")がある状態で
textarea.value += ", " + "setting value";
この結果、textarea
の内容は、あいうえお, setting value, text, compositionend, input
となります。IE 11ではtext
とcompositionend
は発火しません(前者はともかく、後者はバグですが……)。
Bug-org 1130937の修正時のミスです。WidgetCompositionEvent::TargetClauseLength()
や、WidgetCompositionEvent::TargetClauseOffset()
を利用すべき時に、WidgetCompositionEvent::mRanges
の、TextRangeArray::TargetClauseLength()
やTextRangeArray::TargetClauseOffset()
を利用していたため、WidgetCompositionEvent
側で実装されている、選択された文節が無い場合の回避処理が行われていませんでした。
今回の修正では、TextRangeArray
のこれらのメソッドはWidgetCompositionEvent
以外が利用する必要はないので、friend
宣言を利用しつつ、これらのメソッドをprivate
メンバーに変更しています。
TabChild
は自身でPuppetWidget
のインスタンスを生成し、保持し続けますが、その間、ずっとnsCOMPtr<nsIWidget> mWidget;
として保持しています。そのため、ぱっと見、mWidget
がPuppetWidget
以外の可能性があるかのように見えますし、実際にPuppetWidget
固有のメソッドにアクセスする場合にはstatic_cast
を利用していて、コードがスッキリしていませんでした。
この修正で、nsRefPtr<PuppetWidget> mPuppetWidget;
に保存するようにしたので、簡単・確実なコードになっています。
Windows上でe10sをデバッグしようとすると、デバッグビルドの実行時にプロンプトにもprintf()
等での出力が出力されませんし、MOZ_LOG()
で出力したログも、ファイルは生成されるものの一行も生成されないというバグです。
まだ修正されていませんが、原因は子プロセスのサンドボックス化のためらしく、デバッグ時には環境変数でMOZ_DISABLE_CONTENT_SANDBOX=1
とすれば解決するとのことです(実際、それで解決します)。
ちなみに、LinuxやMacでは問題ありません。
例のVideo DownloadHelperをインストールしていると、Firefoxの動作が遅く、軽くハングアップするという問題ですが、bugzillaに報告したところ、アドオンの作者の方が作業を開始してくれました。これにテスタとして協力してくれているやっさんさんにも感謝です。
At this point, we know we fixed an important cause of slowdowns (CPOW) since version 5.3.1. My plan is to release 5.4.0 with this fix, auto-detection (gallery and screen capture) and icon animation off by default. We'll see if users continue to complain about VDH slowing down the browser.
I'll post here when 5.4.0 is ready (this should happen in a few days).
Many thanks for your help Yassan.
原因の一つは、CPOWを利用していることによってFirefoxのメインスレッドが待ち状態になっていることが多いことのようですが、これはまもなく公開予定の5.4.0で修正されるそうです。
しかし、やっさんさんの検証では他にもバグがあるらしく、相変わらず動作が遅くなることがあるとのことで、やりとりが今でも続いています。
Amazon.co.jpを複数のタブで開いていると、FirefoxのCPU使用率が100%になってしまうというバグです。いつもながらAliceさんからの報告です。
原因等はまったく分かっていませんが、CSSを適用しなかったら再現しなくなるとのこと。profilingできる人は協力をお願いします。
こちらのバグは世界中のAmazonのサイトでの問題のようです。
Amazon, shortly after the page has loaded, calls createElement(OBJECT) a dozen of times to load resources. We handle that just like iframes and show the spinner. Amazon does that only in Firefox... in Chrome it just doesn't do that.
Amazon checks for |document.documentElement.style.MozAppearance| and if that exists uses <object> elements to preload .js, .css, .gif, etc. files. So they basically visually f up every page load to preload resources possibly needed for further navigation.
FTR, this isn't something we changed. I can reproduce this issue with Firefox back to 2012-01-01 builds. Amazon is preloading resources using <object> tags ~2.5s after the page has finished loading and that causes our throbber to go wild. They use different tags in Chrome and IE.
とのことで、Firefoxの場合にのみ、何故か処理が遅くなる<object>
要素を利用して様々なものを先読みしているので遅くなっているようです。Amazonのサイト側の問題ということで、こちらはAmazonにコンタクトを取っている模様です。