ボクココ

個人開発に関するテックブログ

ContentEditable での IME による動作違い

ども、@kimihom です。

f:id:cevid_cpp:20210403143104j:plain

以前書いた ContentEditable の記事がよく読まれている。この辛いけど得られる HTML 拡張パワーに魅力を感じた方が多いことだろう。

www.bokukoko.info

そのパワーが得られた結果得られるエディタが以下である。

www.youtube.com

さて、今回はまた この ContentEditable で陥った困難について記しておく。

IME の違い

Windows Chrome, Mac Chrome 共に ContentEditable が正しく動いていた。テストが通ったと自負していたのである。

しかしある日、利用者から「Windows Chrome で正しく動作しない」との報告をいただいた。先方の利用環境を確認して Windows、Chrome の各バージョンはそれぞれ問題なし。シークレットウィンドウで Chrome拡張を入れてない環境でも問題が起きた。

問題の詳細を見ると、全角で # を打った変換の挙動が意図していないものだった。これはもしかして・・ IME!?

IME、ご存知の方も多いと思うが、ひらがなを漢字などに変換するツールである。Windows だとデフォルトで Microsoft IME が搭載されている。

さて、Microsoft IME に不満を持っている方のために、Google が出している Google IME というのが存在する。これらの違いによって、ContentEditable 側のイベントに違いが発生する という問題を発見した。

それが keyup 時のイベントだ。

Windows における Microsoft IME と Google IME の違い

まず、そもそも Mac と Windows で keyup イベントで得られる値が変わってくる。keyup を監視して、そこで全角 # を入力した際、以下のようなイベントが発生する。

Mac Chrome

  • evt.key: #
  • evt.keyCode: 51

Windows Chrome Microsoft IME

  • evt.key: Process
  • evt.keyCode: 229

そして、問題となった Windows Google IME だとどうなったか。なんと 上記2つが全く同じタイミングで出力されていたのであった。。

確かに 現在の Microsoft IME の "evt.key: Process" はおかしいとは思っている。とはいえ、 Google IME 側で "evt.key: #" も追加するってのはいかがなものか・・。今回この IME による差分に大きく頭を悩まされた。keyup イベントが 2回発生するという以外、JavaScript 側で IME の違いを分別することができなかった。

一時的な対応

今回、この IME による差分を認識する必要があったのは、IME によって blur() の挙動が Windows Google IME と Windows Microsoft IME で違いがあったためだった。

イベントが同時に2回呼ばれるか、1回だけか。これで 環境の差分をできる限り減らす実装が必要となる。

ContentEditable....

こんな検証の難しいようなチャレンジができる。OS や ブラウザの違いだけでも大変なのに、IME による動作も変わってくるなんて思わなかった。

それでも得られる 上記動画のようなメモ帳の拡張。Slack などの登場で もはや当たり前になりつつある中、どこまでエンジニアが頑張れるか。

共に頑張ろう、フロントエンドエンジニア!