2016年1月19日
先日、TweetDeckでFirefoxから日本語が入力できなくなっているという話を聞きました。実際に試してみると、IMEで一文字入力する度に、未確定文字列が強制的に確定されてしまいます。
Army of Awesome上ではかなりこの件で悲鳴を上げている方が多く、また、検索結果から原因を誤解してFirefoxが悪いんだと悪評を広めてくれている人を多々見かけましたので、何が原因で、どういう状況なのかをまとめておきます。
私は今回の原因はTweetDeckの開発者のテスト不足が原因だと思っています。ちなみに、Firefox側のアップデートで発生した訳でも、OSのアップデート等で発生した訳でもなく、TweetDeck側のメンテナンス作業の結果、発生しているregressionです。
何が起きているのかというと、実際のコードを確かめられた訳ではありませんが、スタックトレースやFirefox 41以降で発生するということから、以下のようなJavascriptのコードが実行され、その結果、Firefoxでのみ未確定文字列が強制的に確定されるという状況に陥っていることが分かりました。
var textarea = document.getElementsByTagName("textarea")[0];
textarea.addEventListener("input",
function (event) {
textarea.value = textarea.value;
});
実際のテストケースで動作を確認できますが、非常に無意味な処理です。実際にはセットしている値は変数等に格納されているのでしょうが、複雑なWebアプリだから発生しているイージーミスのように見えます。
では、このケース、どのように動作すべきだと思いますか? 実は、未定義なのです。 WHATWGに昔、加藤誠さんが未確定文字列がある場合に値がセットされた場合、未確定文字列をどうすべきかとポストしたのですが、それに対するHixieの返事は、
Well the value should definitely get set, per spec. Whether the IME should reset state is a UI issue, so the spec doesn't address that.
I've specced what should happen to the cursor and selection, though only as a "should". I haven't specced what should happen with IME since, as mentioned above, it seems like this is just a UI issue that doesn't affect interop (you can't detect the IME state unlike the selection state, for example).
というものでした。IMEの動作についてどうあるべきかはUIの問題であり、それは(少なくとも)HTML5では定義しないということです。
Firefox 41でのBug-org 549674の修正まで、Geckoは未確定文字列があるままに値を設定されると、未確定文字列の表示が壊れるものの、IMEは未確定文字列を持ち続けるという状態の齟齬があり、これがいくつかのWebアプリで問題になっていました。この修正時に、<input>
や<textarea>
の値がセットされた際には、常に未確定文字列を強制的に確定するようにしましたが、それが今回、あだとなってしまったわけです。
実際には他のブラウザはセットされた値によって、実際に値が変化する場合のみ、未確定文字列を強制確定していました。この違いが、今、Firefoxでのみこの問題が起きている理由です。
今回の件は非常に発生タイミングも悪く、Firefox 44でのGecko側での修正にはスケジュール的に難色が示されています。
また、今回の問題を引き起こしたTweetDeck側にもいくつかの方法でコンタクトを試みていますが、今のところ、修正はされていないようです。
- TweetDeckに対するEvangelismバグ
- Bug-org 1240170: Japanese IME won't join a consonant and a vowel on TweetDeck's Tweet field
- Gecko側の動作を他のブラウザと同じ様に修正するバグ
- Bug-org 1240336 At setting either <textarea>.value or <input>.value, we shouldn't commit composition if the value won't be changed
TweetDeckの開発者と思われる方からコンタクトがあり、修正方法を提案しておきました。その後、今日明日中に修正できたらいいな、という旨のツイートをされていました。
TweetDeck側で無事、修正されました。まだ再現する人はリロードしてみてください。
2016年1月24日
FirefoxでTwitterの動作が遅い方はコンテンツ全体をなめる処理を行うアドオンを入れていませんか?
初回投稿日時: 2016年01月24日00時39分19秒
最終更新日時: 2016年01月25日17時08分53秒
カテゴリ: Add-onトラブル Firefox
固定リンク: id=2016012400
SNS:
(list)
FirefoxでTwitterの動作が遅いという方の話をよく聞きますが、直接話を伺ったところ、ほぼ全員がコンテンツ全体をなめる処理を行うアドオンを入れていることが分かっています。代表的なのは、
これら二つのアドオンです。
SkypeクリックコールアドオンはSkypeのアップデートの際に、毎回、アドオンのインストールを拒否しない限りインストールされてしまう行儀の悪いアドオンです。必要ではないのにインストールしてしまった場合、これを無効化するかアンインストールしてください。
Adblock Plusの場合、Adblock Plusのtwitter.comをホワイトリストに追加し、Twitterのサイト全体を動作対象から外してください。
Firefoxにブックマークを追加できなくなっている場合、IE Tab +をインストールされていませんか?
初回投稿日時: 2016年01月24日00時50分08秒
最終更新日時: 2016年01月25日17時09分46秒
カテゴリ: Add-onトラブル Firefox
固定リンク: id=2016012401
SNS:
(list)
Firefoxでブックマークを登録できなくなっているというトラブルにあっている方を時々見かけます。そのような方に確認をとったところ、大体、IE Tab +がインストールされていますが、このアドオンの互換性が既に失われているために発生している問題であることが多いです。
残念ながら、このアドオン自体の開発は終了しているようで、修正版がリリースされる気配はありません。また、他のIE Tab系アドオンも何らかのトラブルを抱えつつ、同様に開発が終了しているようで、修正版はリリースされていません。ですので、他のブラウザでFirefoxで開いているページを表示したい場合、Open Withというアドオンを利用するしかないと思います(IE View系もだいたい、トラブルを抱えたまま、開発終了している模様です)。また、IE Tab +は無効化、またはアンインストールしてください。
それから、お一方しか困っている方を見かけていませんが、Old Add Bookmark Behaviorが原因でブックマークが追加できなくなっているケースもありました。もし、IE Tab +をインストールされていないのでしたら、こちらのアドオンも確認してください(削除するか無効化するしかありません)。
Firefoxで、Twitterで使われている短縮URL等をクリックした時にリンク先を開けない場合、True Key Add-onをインストールしていませんか?
初回投稿日時: 2016年01月24日00時57分20秒
最終更新日時: 2016年01月25日17時07分41秒
カテゴリ: Add-onトラブル Firefox
固定リンク: id=2016012402
SNS:
(list)
Twitterでは短縮URLサービスが多用されていますが、これらの全部、もしくは一部のリンクをクリックしても期待通りにリンク先を開けないという方が時々いらっしゃいます。そのうち、完全に原因を特定できたのは、True Key Add-onというアドオンでした。
このアドオンはセーフモードで起動しようとしたときにも強制的に有効化されているようで、問題の切り分けを難解にしてくれている行儀の悪いアドオンです。これを無効化しても強制的に有効化されるようなので、このアドオン、もしくはTrue Keyというアプリ自体をアンインストールするしか解決方法は無いと思います。
また、このアドオンをインストールされていない方で、この症状に悩まされている方は、このアドオンと同じ様に、セキュリティソフトか何かによって、リダイレクトを妨害されていると考えられますので、セキュリティソフトを一時的に無効化する等して検証してみてください。
Firefoxが高頻度でランダムにクラッシュするという方、Rapport (ラポート)というセキュリティソフトをインストールしていませんか?
初回投稿日時: 2016年01月24日01時06分40秒
最終更新日時: 2016年01月30日10時23分24秒
カテゴリ: Add-onトラブル Firefox
固定リンク: id=2016012403
SNS:
(list)
いわゆるFirefoxのアドオンではないのですが、一部銀行ではネットバンキングのユーザに対して、Rapport(ラポート)というセキュリティソフトのインストールを勧めています。しかし、このソフトは自動更新を行わないのか、古いバージョンがインストールされているままだと、これがインストールされていると、Firefoxがクラッシュするようです。
この場合、Rapportのサイトのダウンロードのリンク先から最新版をダウンロードし、再インストールを行って下さい。最新版を入れてもクラッシュするとのことですので、Rapport側でバグ修正されるまで、アンインストールするしか無いようです。
Rapport側で修正が入って、アップデートが配信され始めたらしく、クラッシュリポート数が激減してきました。
まだクラッシュする方はRapportをアップデートしてください。
2016年1月30日
e10sモードかつ、TSFモードの場合、MS-IMEをWindows 7で使っていると、時々候補ウインドウが画面の左上に表示されるというバグです。
原因は、Windows 7に標準で搭載されているMS-IMEのバグで、ITextStoreACP::GetTextExt()
でTS_E_NOLAYOUT
を返すと、即座に候補ウインドウを画面左上に表示してしまうというものでした。Windows 8以降に搭載されているMS-IMEのサジェストウインドウ位置がおかしかったバグと同じです。
MS-IMEのサジェストウインドウはWindows 8以降で実装されたものなので、以前の修正でハックを入れるのをWindows 8以降に限定していましたが、副作用の少ないハックですので、OSのバージョン制限を取り払って、MS-IMEなら常にこのハックが動作するように修正しました。
マウスホイールで最初にスクロールした時に使用したのが、Synapticsのタッチパッドか、外付けのマウスかで、スクロールスピードが変わってしまうというバグです。特に、Synapticsのタッチパッドで最初にスクロールすると、外付けマウスでのスクロール速度がWindowsのデフォルト設定で1/3になってしまうので、かなり遅く、不快に感じるバグでした。
Windowsの設定でマウスのスクロールスピードを修正すると、意図した速度で動くことから、システム設定のキャッシュに問題があることが分かりました。そして、MouseScrollHandler
のログをとってみたところ、Windowsのデフォルト設定でデルタ値120あたり、3行スクロールするようになっていても、Synapticsのタッチパッドを使用した場合には、::SystemParametersInfo(SPI_GETWHEELSCROLLLINES)
が常に1、つまり、デルタ値120あたり、1行スクロールする設定になっていると返すことが分かりました。
おそらく、これはSynapticsのタッチパッドのユーティリティがSystemParametersInfo
APIをフックしているものと思われます。なぜなら、WM_SETTINGCHANGE
メッセージが来ないまま、このAPIで返される値が変わってしまうためです。
また、幸い、自宅にAlpsのタッチパッドを積んだ珍しいノートPCもあるので、確認したところ、Synapticsとは違うものの、本来の設定値を無視した値が返ってくることが分かりました。もっともこちらはシステム設定がデフォルトのままだと気になるほどの差ではありませんが。
Elantechのタッチパッドを搭載したノートPCは持っていなかったのでTwitterで協力者を募ったところ、Kuroさんがテストしてくれて、Elantechでは問題無いことが分かりました。
そこで、スマートな解決方法が思いつかないので、Synapticsのタッチパッドか、Alpsのタッチパッドがインストールされている場合、システム設定のキャッシュを信頼せず、ホイールのメッセージが来る度にキャッシュを更新するように修正しました。
ちなみに、どれぐらいのユーザに影響があるのか気になったので、タッチパッドのシェアを検索してみましたが、特にそういった統計は見当たりませんでした。しかし、Synapticsの日本代理店(?)のPALTECK社のサイトによると、
シナプティクスは、ヒューマン・インターフェイス技術をミッションとして掲げ、1986年に米国San Joseに設立されました。製品開発は全て自社内で行い、出願中を含めて90以上の技術特許を所有し、主力のTouchPad製品ではノートPCを中心に全世界の70%以上、入力デバイス製品全般では全世界で50%以上のシェアを獲得しています。 また、成長が著しい各種モバイル機器の入力デバイスとしても数多くの採用実績を獲得しており、名実共にヒューマン・インターフェイス技術のエキスパートとして入力デバイスのワールドリーダーです。
とのことです。
Bug-org 1208944の修正により、windowlessなFlash Playerであっても、Windowsでは未確定文字列がインラインで表示されるように修正されていますが、ATOK 2016でテストしてみると、候補ウインドウが画面の左上に表示されるというバグです。
Bug-org 789706で、TSFのTIPとなったATOKの大半のバージョンでは、ATOKは未確定文字列の表示位置を決めるのに、なぜかネイティブのキャレット位置を参照するという不思議な挙動になっていることが分かっていました。そこで、今回の修正でも、プラグイン経由で::ImmSetCandidateWindow()
を呼び出す際に、その位置から上方に20pxの高さのキャレットを生成して配置するようにすると解決しました(非表示ですので見えるわけではありません)。
何故、20pxにしたかというと、下方向に候補ウインドウが開けない場合、キャレットの上端から上方向に候補ウインドウが開かれるのですが、20pxぐらいの高さがあれば大抵のケースでは問題にならないだろうという理由からです。マジックナンバーですのでこれ以上の理由はありません。
Windowsでは、5ボタンのマウスに専用のユーティリティが付属していない場合、第四ボタンを押すと、WM_XBUTTONDOWN
とWM_XBUTTONUP
メッセージがXBUTTON1
のイベントとして発生します。これを::DefWindowProc()
に渡すと、Windowsはブラウザの「戻る」を促すWM_APPCOMMAND
メッセージを生成します。
同様に、第五ボタンを押すと、WM_XBUTTONDOWN
とWM_XBUTTONUP
メッセージがXBUTTON2
のイベントとして発生し、これを::DefWindowProc()
に渡すと、Windowsはブラウザの「進む」を促すWM_APPCOMMAND
メッセージを生成します。
MicrosoftやLogicoolのマウス等、ユーティリティが付属している場合はこれらのボタンを無効化することで、これらのボタンの利用をやめる(誤操作での意図しないページ移動を防ぐ)ことができますが、そうではない、Windows標準のドライバだけで動作する安価なマウスではこれを防ぐ方法がありません(ひょっとするとレジストリをいじるとできるのかもしれませんが)。
このバグは、そのような無効化機能をFirefox自体に実装してprefsで無効化できるようにしておいて欲しいというものです。
今回の修正で、mousebutton.4th.enabled
とmousebutton.5th.enabled
というprefを新設し、これらがfalse
に設定されていた場合、WM_XBUTTONDOWN
やWM_XBUTTONUP
メッセージを::DefWindowProc()
に渡さないようにして、WM_APPCOMMAND
の生成を妨害するようにしています。
繁体中国語(台湾・香港)用に以前はあった、MS New ChangJieと、MS New QuickというTIPが、Windows 10でもレジストリを先にいじっておくと、言語の追加で選択可能になるそうなのですが、これをNightlyで使ってみると、NightlyのプロセスがCPUリソースを食い続け、半分フリーズしたような状態になるというバグです。
Bug-org 1234422の修正で、ITextStoreACP::GetTextExt()
がTS_E_NOLAYOUT
を返した後、再度、ITextStoreACP::GetTextExt()
が再度呼び出され、TS_E_NOLAYOUT
以外を返すまで、ITextStoreACPSink::OnLayoutChange()
を::PostMessageW()
を利用して繰り返し、確実にTIPが必要な文字の矩形を得られるようにしました。
しかし、上記のTIPはTS_E_NOLAYOUT
を返した後、完全に安全になってからITextStoreACPSink::OnLayoutChange()
を呼び出しても、再度、ITextStoreACP::GetTextExt()
を呼び出さず、あきらめてしまっていました。このため、::PostMessageW()
で何度もリトライが行われ続けていたので、操作していない間はずっとCPUリソースを食い続けるという状況になっていました。
今回の修正で、::PostMessageW()
からITextStoreACPSink::OnLayoutChange()
を呼び出した後にはそれ以上リトライしないようにしました。
今回、問題になったこれらのTIPではe10sでしかTS_E_NOLAYOUT
を返すことがなかったため、e10sが最初に有効になる予定のFirefox 45での修正になっていますが、問題のBug-org 1234422の修正はFirefox 44にも入っていますので、ひょっとすると、今、このバグが原因でCPUリソースを食い続けるTIPがあるかもしれません。そのような症状に会っている方は修正を行いますので、バグを報告するか、私の方まで直接ご連絡ください。
ハングル用のMS-IMEは、TSFモードではCompositionEvent
がおかしな発火のされ方になるというバグです。具体的には二文字目を入力開始すると一文字目が確定されるのですが、その間に、compositionstart
とcompositionend
がワンセットで発火されます。
ハングル用のMS-IMEは日本語とも中国語とも全然違う動作を行うTIPで、二文字目の入力が行われた時に一文字目の未確定文字列処理を確定しないまま、二文字目の範囲を新たな未確定文字列の範囲として指示して来ます。この時に未確定文字列の先頭のオフセットが変更になってしまうので、DOMイベント的には、一度、compositionを終了し、新しいcompositionを開始するしかありません。
そのため、二文字目の入力が開始された時にTSFTextStore
は一文字目の編集を終了し、強制確定させてから、新たな未確定文字列の編集処理を開始するのですが、その直後にTIPから一文字目の確定処理が通知されます。この際に、キューに入れるcompositionend
が実際に文字列を変更していない場合、すでにキューに入れているcompositionstart
から削除してしまうことで修正に成功しました。
TSF-awareなアプリを書かれる方は、他言語のTIPとはあまりに動作が異なっている、ハングルのTIPでのテストは十分に行った方が良いです。
TweetDeckでIMEを利用すると、一文字入力ごとに強制的に確定されてしまい、まともに日本語等の入力ができないというバグです。
詳細は以前のエントリに書きましたが、TweetDeckがメンテナンスを行った際に、Web標準仕様では動作を(意図的に)定義していないコードを入れたため、FirefoxのみがEdge、IE、Chrome、Safariと動作がたまたま違うケースにハマってしまっていたというTweetDeckのバグです。
いくつかの方法でTweetDeck側にコンタクトを試みましたが、最終的にうまくいったのは、The TweetDeck Blogに記事をポストしているアカウントに@付きツイートを投げたところ、関係者がそれを見つけてくれたことでした。
既に上記の記事で書いてある通り、TweetDeck側で修正が行われています。もし、まだ再現する方が居たら、Ctrl+F5か、Ctrl+Shift+R (MacではCommand+Shift+R)でキャッシュを無視した再読み込みを行えば修正されたバージョンが読み込まれます(ちなみにこの機能をスーパーリロードと言います)。
TweetDeckのバグを引き起こしたFirefoxのみ動作が違うケースを他のブラウザと同じ動作に修正し、二度と同じ問題が起きないようにしようというバグです。
修正内容は、要約の通りのことで単純ですので説明は省きます。問題自体は以前のエントリを参照してください。
Windowsでは、マウスホイールのスクロール量のシステム設定が変更されていない場合、ルートのドキュメントのページ全体のスクロール時にのみ、スクロール量を倍にするシステムスクロールオーバーライドという機能があります。e10sモードが無効の時と、e10sモードが有効でも、APZが有効な場合には問題無く動いてるのですが、e10sモードが有効でAPZが無効の場合、スクロール量が本来の速度に戻ってしまい、遅く感じるというバグです。
e10sモードが有効で、APZが無効な場合のみ、オーバライドは子プロセスからnsIWidget::OverrideSystemMouseScrollSpeed()
が呼び出されているのがその違いなのですが、親プロセスではnsWindow::OverrideSystemMouseScrollSpeed()
が呼び出されるのに対し、子プロセスではPuppetWidget::OverrideSystemMouseScrollSpeed()
が実装されていないのでnsBaseWidget::OverrideSystemMouseScrollSpeed()
が呼び出され、Windows固有のこの機能がうまく動いていなかったわけです。
このメソッドはwheel
イベントが発生する度に呼び出されますので、単純にPuppetWidget::OverrideSystemMouseScrollSpeed()
からプロセス間通信を行って、親プロセスのnsWindow::OverrideSystemMouseScrollSpeed()
を呼び出していては負荷が大きくなりすぎます。
そこで、今回の修正では、WidgetWheelEvent
に設定の確認とオーバーライド済みのデルタ値を返すメソッドを実装し、親プロセスでなくては問い合わせることができない、システム設定がデフォルト設定かどうかをWidgetWheelEvent
の発火時に先に確認し、デフォルト設定でなければWidgetWheelEvent::mAllowToOverrideSystemScrollSpeed
をfalse
に、デフォルト設定ならtrue
にするようにし、全ての判断材料をWidgetWheelEvent
に持たせておくようにしました。
APZはこのこのコードをコピペで重複して持っているので、APZ対応に関しては独立したパッチにまとめていますので、参考にしてみてください。
e10sモードで、TSFモードでWebコンテンツに入力していると、子プロセスがビジーな場合、入力中の未確定文字列が強制的に確定され、再度入力しなければいけなくなるというバグです。
強制確定は、フォーカスのあるエディタ内のテキストが、TIPの未確定文字列変更以外で変更された場合(Javascriptでの変更を元々は想定)、TSFやTIPが混乱してFirefoxを再起動するまで日本語入力ができなくなるのを避けるためにTSFTextStore
が予防策として行っています。
e10sモードで子プロセスがビジー状態になっている場合、未確定文字列の入力中にその未確定文字列の入力が始まる前に直接キーボードで入力した内容まで、TIPが意図していなかったテキストの変更として通知されてしまいます。そのため、上記の予防策がユーザの正常な入力を妨害してしまっていました。
今回の修正では、TextChangeDataBase
に、mIncludingChangesDuringComposition
とmIncludingChangesWithoutComposition
を追加しました。前者は、IMEへの通知を待っているテキスト変更のデータが、IME以外による変更が未確定文字列が存在している時に起こったかを記録し、後者は、IME以外による変更が未確定文字列が存在しない時に起こったかを記録しています。ここで重要なポイントは、その時点の未確定文字列の編集が開始される前の未確定文字列の編集中に発生した変更は、未確定文字列が存在していない時に起きた変更として扱うようにしていることです。つまり、現在の未確定文字列の編集が始まる前の変更は全て、未確定文字列が無かった時の変更として記録・通知されます。
これにより、TSFTextStore
は、現在の未確定文字列の編集が始まって以降にTIP以外が原因でテキストに変更があった場合にのみ未確定文字列を強制確定するようにしました(つまり、元々の意図通りに動作するように修正しました)。
ただし、勘の良い方は気付かれたと思いますが、この状態が発生すると、TSFTextStore
はTIPからの問い合わせに正しく応答できなくなるパターンが存在します。例えば、空のエディタに「あいう」という文字列を入力、確定し、次に「え」と入力したとします。もし、子プロセスがビジー状態で、「え」を入力した時点で、まだ、先の入力処理を終えてなかったとします。すると、「え」の開始時にTSFTextStore
はオフセット0の位置に入力を開始したと誤解してしまいます。そして、前の文字の入力完了の通知が来ると、例えば未確定文字列の1文字目の内容をTIPが取得しようとしても、確定済みの先の確定文字列の1文字目が返されることになります。
このため、候補ウインドウの位置がおかしくなったりする諸々の新しいバグが発生することになりますが、今時のPCであれば、極端に様々な処理がバックグラウンドで走りまくっているサイトを開いていなければそうそう問題にはならないと思います。
この辺の問題に対する抜本的な解決は今年のQ2以降での修正を予定していますが、もちろん、パッチを書いてくれる人が居ればレビューしますので気軽にレビューのリクエストを私に投げて下さい。
どうしてもこのバグが発生してしまう環境であったり、そのような「重い」Webサービスを利用する場合は、about:config
から、intl.tsf.enable
をfalse
に変更してFirefoxを再起動し、TSFモード自体を無効化してください。
発生すると非常に不快なバグですので、この修正により、候補ウインドウ等がおかしな表示位置になることがありますが、それよりは入力を継続できる方がマシだと判断し、Firefox 46へupliftを行いました。
e10sモードを無効にしている状態で、TSFで未確定文字列が存在している時に、Javascriptからエディタの内容が変更され、その未確定文字列が強制確定されると、TIPは実際には確定しておらず、「見えない」未確定文字列が存在し、それへの入力が続いているというバグです。
e10sモードを無効にしている状態で強制確定が発生すると、TSFTextStore
はドキュメントをロックしたまま、TIPに未確定文字列を強制確定するように指示します。
しかし、TIPは自身がドキュメントを既にロックしているにも関わらず、同期的にドキュメントを再度ロックしようとし、これにもちろん失敗します。そのため、TIPは強制確定処理を中断し、未確定文字列をそのまま保持しますが、Gecko内部ではWebアプリに同期的に強制確定が行われたかのように偽装し、非同期で来るはずの強制確定結果を待ちます。
今回の修正ではこれを解決するために、ドキュメントロック中に強制確定のリクエストがTSFTextStore
に来た場合、ただちにTIPに強制確定を指示せずに、ドキュメントがアンロックされた時にそれを遅らせるようにしました。
空の<input>
要素でスペルチェッカを有効にし、未確定文字列を入力、それをキャンセルすると、<input>
要素の右端にキャレットが表示されてしまうというバグで、何故か、WindowsではIMMモードでは再現が確認されているものの、TSFモードでは再現が確認できない不思議なバグです。
デバッグビルドで走らせてみると、エディタとスペルチェッカで、警告をいくつか吐いていました。その内容から、編集直後にスペルチェッカがスペルチェックを行おうとして失敗したあと、空のエディタに必要な匿名の<br>
要素の生成が行われてないことが分かりました。
直接、エラーを返しているのは、編集前にキャレットがあったノードと、現在の選択範囲を比較するRange::Compare()
でした。IMEの未確定文字列は削除されてエディタは空になっているので、その編集前にキャレットがあったノードというのは既にドキュメントから削除されています。ですので、比較に失敗するのは自明なわけです。
その直前の処理を見ると、エディタの変更理由が削除だった場合は比較を行わずにその処理を終了していました。とすると、ここにIMEの未確定文字列の変更の場合でも、未確定文字列が空になった場合には削除と同じ扱いで処理してもらわなくてはいけないことが分かります。しかし、そのメソッドでは未確定文字列がどうなったのかは分かりません。そこで代わりに、比較対象のノードがドキュメントから削除されている場合には、通常の削除処理と同じように処理するように修正しました。