はじめに
タイトルがわかりにくいですが、ここで書いている WebUIというのは、Chrome(Chromium)の WebUIのことであり、普段からChromeを通して使っているものです。chrome://から始まる特別な表記のURLをアドレス欄に入力してアクセスします。chrome://about を見ると一覧があります。この部分に使われている Chromeの UIのことをWebUIと呼んでおり、HTML/CSS/Javascript で作られています。
Chromeチームの人がWebUIを開発する開発者向けにドキュメントを整備しています
WebUI
私は普段 Javascriptを書かないので、Javascriptのちょっとしたことを調べたりするのにコードを書くというよりも毎回Webを検索したりしています。
最近は(Webの検索もしますが)代わりにchromium のWebUIのコードを検索する事が増えました。
WebUIのコードを見たり検索したりするのは少し考えてみるとWebUIというのが
- いつでもアクセスできるところにある
- 古いコードとモダンな実装が混在している
- ドキュメントがあるのでコードを読む気になる
というのが理由なんじゃないかなぁと思っています。
最初の理由のいつでもアクセスできる、というのは大きいと思います。
どのOSを使っている時でも手元にchromeがインストールされていることが多いですし。
常に手元に情報源があると参照回数は増えます。なにか思い出せない事があるときにWebの検索の前にまずmanコマンドで調べろ!という話を思い出します。私なんかは(物理キーボードをLinuxに繋ぐ機会も最近はなくなりましたが)Linuxを触っていてキーボード配列を少し変えたいときはいつも、man xmodmapとしてCapsについての段落を検索してCtrlとSwapする、みたいなお決まりの作業をするのですが、手順をWebの検索に頼るのではなく手元ですぐに出せるのは非常に便利です(manは最高)。Javascriptのコードや動作例をWebUIで短時間で確認できたことが結構な回数あって、このことからmanの例と少し似ているなぁと思いました。
次の理由の古いコードについてはchromiumは開発の歴史も長く、継続的に改善する中で一部モダンなやり方で実装されますが、全体的には昔のコードがメンテナンスされている、という状況によります。WebUIという枠組みをなんとなく把握しておいて時代を感じるコードやモダンなコード例を同時に辿れる状態がすぐ手元にあるのが好きです。
Promissのresolve/rejectの動作例とかは、xxxPromiseのような関数名で呼びだして、以下のように処理するコードが主流だったりします。
export function webUIResponse(id, isSuccess, response) {
const resolver = chromeSendResolverMap[id];
assert(resolver);
delete chromeSendResolverMap[id];
if (isSuccess) {
resolver.resolve(response)
} else {
resolver.reject(response)
}
}
最後のドキュメントが用意されている部分については冒頭に書いたwebui_explainer.md
の他にwebui_in_chrome.md
があります。
このドキュメントに書かれているWebUIの例としては以下の3つです。
- chrome://hello_world
- chrome://donuts
- chrome://history
それぞれ
- chrome://hello_world が C++/Javascriptをどのようにセットアップするかという前提部分の説明で
webui_in_chrome.md
のメイン部分で、 - chrome://donuts は
webui_explainer.md
のメインの部分です - chrome://history は実際のサンプルとして引用している
という感じです。冒頭にも書きましたがこのドキュメントは主にchromium開発者向けに書かれているのであまり頑張って読むものではないです。私は一通り目を通してあとは chrome://history
を chrome devtools で調べた、みたいな感じでした。
内容も開発者向けの注意点といった感じです。セキュリティに問題がないようにCallJavascriptFunctionを直接使わせず、きちんとAllowJavascriptを使わせる、みたいな内容です。書き方もMojo、Pre-Mojo(イベントベースとresolve/rejectパターン)の両方について記述されています。
WebUIに親しみを覚えたのは、はやりこのドキュメントのおかげです。Javascript関連でWeb検索よりも色々なコードを読むようになれた気がします。
Mojoというのはブラウザとレンダラー間のプロセス間通信(IPC)のために、Ninja/GNの上に構築されてた仕様でmojomというIDLが用意されており仕組みとして面白いと思います。
さて、chrome:// (WebUI)のjavascriptが参照するもので chrome://resources/js/cr.js
というのがあります。いろんなWebUIから参照される共通の(グローバルな)処理を集めた小さなファイルでいつも参照します。
この cr.js
の webUIListenerCallback
という関数にブレークポイントを貼って挙動を見るというのが最初は簡単でした。例えば、chrome://history だと foreign-sessions-changed
というイベントがブラウザプロセスからレンダラプロセスに送られてきます。foreign-sessions-changed
だと、複数端末でブラウザを同期している時のスマホや別のマシンでタブを開く/閉じるなどを行うと発火されるイベントになっています。こういうのを入り口にして、色々仕組みを覗いていくと色々と発見があって楽しいと思います。このあたりに興味がある人は是非試してみてください。
最後に
つれづれと書いていて最後に気がついたのですがWebの検索が減ったというのはChatGPTを使っているからなのでした。最近、Webの検索が超めんどくさくなったからだと思います。検索が面倒、というのは今だと当たり前なのでした。