basyura's blog

あしたになったらほんきだす。

cVim : manifest v3 対応

夏休みで北海道に来た。一つの宿に連泊してのんびりしている。

困る

作者の 1995eaton はどこに行ってもうたんや。 2018 年あたりで活動が止まり、たまに動いたと思ったら 2022 年を最後にまた止まった。

僕のブラウジングにおいて無くてはならないものとなった chromium-vim は chrome 拡張の manifest v2 なので、 v3 に対応しないと動かなくなる。

同様に無くてはならないものとなっているブラウザの vivaldi はカスタマイズ性を重視している。v2 も並行サポートしたりしないかと期待したけど最大 2025/06 までのよう。

cVim は MIT license でソースコードもあるから必要な人が Fork して直せばいいだけではある。 念の為、Issue や Pull Request を確認したけど特に無い (どちらも 2022 で止まっているので、使う側も諦めているぽい)。自分が困る前にやるしかない。

対応

manifest.json はルールにそって変える程度。

  • manifest_version を 2 から 3 に変更。
  • background スクリプトの指定を scripts から service_worker に変更。
  • content_security_policy の書式を変更。
  • browser_action を action に変更。

各種 API の変更。動かしてエラーが出るところを随時見直していく。

  • storage
  • XMLHttpRequest → fetch
  • tabs → scripting
  • extension → runtime
  • などなど

設定の読み込み

最初に service worker で取得した設定を保持しているはずが、cmdline_frame.html 経由でページを開くと消える。アドレスバーから開いた場合は設定がある。意味不明でずっとハマっていたが、取れていない場合は storage から取得し直すように対応を入れた。

heart beat

ようやく動くようになったと思って喜んでいたら一定期間後に動かなくなる。ページを開きっぱなしにしていたら、何もしていないのに動かなくなる。

v3 からの仕様で一定期間後?に切断されてしまうようだ。onDisconnect が実行されることは console.log で確認できた。

messenger.js

var port = chrome.runtime.connect({ name: "main" });
port.onDisconnect.addListener(function () {

本来は storage を使ってどうのこうのとか、接続し直してどうのこうのするのが正しいようだけどめんどくさいので定期的にメッセージを送信するように修正。

setInterval(() => {
  keep_count ++
  console.log("keep alive : ", keep_count)
  ECHO("keepalive", {});
}, 20000)

service worker に通信を投げるのも無駄だなと思って記事を読んでいたら、公式に非推奨だけど?回避方法がばっちり書いてあった。

こちらも定期実行で setInterval を使って 20s ごとに storage の api を叩いてるだけ。

let heartbeatInterval;
async function runHeartbeat() {
  await chrome.storage.local.set({ 'last-heartbeat': new Date().getTime() });
}
async function startHeartbeat() {
  runHeartbeat().then(() => {
    heartbeatInterval = setInterval(() => {
      console.log("heart beat")
      runHeartbeat()
    }, 20 * 1000);
  });
}
startHeartbeat()

公式の方法に従う。

eval

元々の cVim には無いのだけど、自分でコマンド (js) を定義して実行できる機能を追加していた。設定画面にあるテキストを読み込んで eval することで実現していた。これが v3 ではできなくなった。

動的に外部コードを読み込むのは難しそう。会社端末には会社用コマンドを追加して常用しているので困る。他の人に公開するわけでは無いので、ローカル編集用 js を置いて各端末で編集すればいいかと思っている。

動いた

自分のスキル的に動作サポートされるギリギリまでかかるかと思ったけど案外うまく行った。動いた。とはいえ、なんとなく調べ始めてから途中で何回か諦めたりして 3 ヶ月弱かかった。

また一つ便利になったというわけではないが、v2 のサポートが切れてもブラウジング効率が下がることは無さそうだ。

コードが大きいので、自分にとって不要な機能は削っていくかな。