そこに仁義はあるのか(仮)

略してそこ仁!

はじめてのGoogle Chrome拡張(とVue.js)

社内サイトのちょっと手の届かないところを触りたくてGoogle Chrome拡張をはじめて作ってみたので、備忘メモ。
ツール自体はかなりサクッと作れました。はじめてのChrome拡張とはじめてのVue.jsだったけど、雑務しつつも2時間くらいで完成できました。
Selectボックスの中の要素を取ってきて、インクリメンタルサーチして、選択したらその値をSelectボックスに設定するという、それだけのツール。

構成ファイル

作ったファイルとフォルダ構成はこんな感じ。
manifest.jsonで読み込むJSファイル(vue.jsmain.js)を指定しています。

.
├── README.md
└── src
    ├── js
    │   ├── main.js
    │   └── vue.js
    └── manifest.json
{
  "manifest_version": 2,
  "name": "tool name",
  "version": "0.0.1",
  "run_at": "document_end",
  "content_scripts": [
    {
      "matches": [
        "https://example.com/roles/*",
        "https://example.com/users/*"
      ],
      "js": [
        "js/vue.js",
        "js/main.js"
      ]
    }
  ],
  "permissions": [
    "activeTab"
  ]
}

Vue.jsはcurlコマンドで格納。これでVue.jsが使える。

$ curl https://cdn.jsdelivr.net/npm/vue/dist/vue.js -o src/js/vue.js

めっちゃ雑なコード。かなりサクッと動かせてよかった。あと、わざわざ別でhtmlファイルを作らなくても画面にフォームなどをお手軽に挿入できて、Chrome拡張のためのVue.jsかと錯覚した。
画面が動的に読み込まれるので、最初に8秒待ったりしている。
拡張を挿入する画面側がjQueryでchangeイベントからHTTPリクエスト投げたりしているんだけど、Elementのvalue変えただけではchangeイベントが発火してくれなかったのでdispatchEvent(new Event("change"));で無理矢理発火させたりしてる。
拡張を更新して試さないとエラー出ないとか辛い…。コンパイルしたい…。

(function () {
    'use strict';
    setTimeout(
        function () {
            var comboboxList = document.querySelectorAll(".combobox")
            var index = 0;

            comboboxList.forEach(
                function (combobox) {
                    combobox.insertAdjacentHTML(
                        "beforebegin",
                        `
                        <style>
                        .selecting-item:hover {
                            background: #e0dfff;
                        }
                        </style>

                        <div id="vue-app-${index}">
                            Policy Filter
                            <input type="text" v-model="policyName">
                            <ul style="list-style-type: none;">
                                <li v-for="item, index in policyList" v-if="policyName && item.text.indexOf(policyName) > -1" 
                                :value="item.value" @click="selectPolicy(item, ${index})" class="selecting-item">
                                    {{ item.text }}
                                </li>
                            </ul>
                        </div>
                        `
                    );

                    var box_options = combobox.options;

                    let vue = new Vue({
                        el: "#vue-app-" + index,
                        data: {
                            policyList: box_options,
                            policyName: ""
                        },
                        methods: {
                            selectPolicy: function (item, index) {
                                combobox.value = item.value;
                                combobox.dispatchEvent(new Event("change"));
                            }
                        }
                    });

                    index++;
                }
            )
        }, 8000)
})();

読み込み方法

公開はしたくなかったので、ローカルのフォルダを読み込ませて動かしました。

1. Google Chromeの「設定」から「拡張機能」をクリック
2. 画面左上の「パッケージ化されていない拡張機能を読み込む」をクリック
3. 「src」フォルダを指定