2021-04-29

VueやVuexのデータを操作するChrome拡張の作り方

Vueコンポーネントの属性値(propsやcomputedなど)やVuexのstoreを操作するChrome拡張の作り方の備忘録

概要

  1. ContentScriptで対象のページにスクリプトをインジェクト
  2. インジェクトしたスクリプトでVueインスタンスを取り出す
  3. 取り出したVueインスタンスをCustomEvent経由でContentScriptに渡したり、ContentScript側からCustomEvent経由で操作する

実装例

manifest.json

{
  "manifest_version": 3,
  "name": "Store Sample",
  "version": "1.0",
  "description": "",
  "content_scripts": [
    {
      "matches": [
        "https://*/*"
      ],
      "js": ["main.js"],
      "css": [],
      "run_at": "document_end"
    }
  ],
  "web_accessible_resources": [
    {
      "resources": ["inject.js"],
      "matches": ["https://*/*"],
      "extension_ids": []
    }
  ]
}

main.js

window.onload = () => {
  document.addEventListener('yourCustomEvent', function (e) {
    console.log('received', JSON.parse(e.detail));
  });

  const script = document.createElement('script');
  script.setAttribute('type', 'text/javascript');
  script.setAttribute('src', chrome.runtime.getURL('inject.js'));
  (document.head||document.documentElement).appendChild(script);
  script.remove();
};

inject.js

const $vue = document.getElementById('__nuxt').__vue__;
document.dispatchEvent(new CustomEvent('yourCustomEvent', {detail: JSON.stringify($vue.$store.state)}));

解説

以下はNuxt/Vuexの例ですが、DOMの __vue__ プロパティでvueオブジェクトを取り出せます

const $vue = document.getElementById('__nuxt').__vue__;

Vuexを使っている場合はこの中にstoreが入っていて $vue.$store.state で取得できます。

ContentScriptとページ側ではJSの実行環境が違うようで、ContentScript側ではこのオブジェクトを取得できないため ページ側で取得するようにscriptタグを動的に埋め込んでいます。

書き換え操作したい場合はインジェクトしたスクリプトで __vue__ の操作を行い 読み込み操作したい場合はCustomEvent経由でContentScript側に送って操作することになります。

CustomEventを使う場合はオブジェクトそのままではContentScriptに送れなかったのでJSON文字列にして送ってます。

書き換える場合はインジェクトしたJSでCustomEventをlistenしてContentScript側でイベントを送ることで任意のタイミングで書き換えることができます。

document.addEventListener('ActionEvent', function (e) {
  $vue.$store.state.about = 'hogehoge';
});

ちなみにVuexのstore以外も、コンポーネントのDOMに __vue__ プロパティが生えているので、それを使ってコンポーネントの属性を取得・操作ができます。

このエントリーをはてなブックマークに追加