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

略してそこ仁!

Chrome拡張でユーザーからの入力値を利用する

Chrome拡張作りにハマっています。
syobochim.hatenablog.com

Chrome拡張でユーザーからのInputを利用したくなりました。そこで調べたらオプションページを作って入力させられるとのことでした。
オプションページはmanifest.jsonoptions_uiのプロパティを設定して作っていきます。
"open_in_tab": falseで、オプションページをタブではなくポップアップで作成できる。調べてみると、ポップアップが推奨っぽい。
設定した値はストレージに保存したかったので、permissionsstorageも追加しました。

{
...
  "permissions": [
    "activeTab",
    "storage"
  ],
  "options_ui": {
    "page": "option/options.html",
    "open_in_tab": false
  }
}

最初はoptionsページもVue.jsで作ろうと思っていましたが、Chrome拡張のセキュリティポリシーでInline JavaScriptが利用できないらしく、v-model@clickなどを書いていたら警告が出てしまいました。
Content Security Policy (CSP) - Google Chrome

Vue.jsを利用する場合はこういうリポジトリもあったけど、なんとなくbuildしたくなかったので、結果としてプレーンなJavaScriptでファイルを作成することにしました。
GitHub - Kocal/vue-web-extension: 🛠️ A boilerplate for quickly starting a web extension with Vue, webpack 4, ESLint and more!

optionページはこんな感じ。認証情報をユーザーの入力から取得する。
Chrome拡張のセキュリティポリシーによって、scriptはファイルとして外出ししなければならない。

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>Resources List - Options</title>
</head>

<body>
    api key : <input type="text" id="api_key"><br />
    secret key : <input type="text" id="secret_key"><br />
    <button id="save">Save</button>
    <div id="status"></div>
    <script src="options.js"></script>
</body>
</html>

options.jsの中はこんな感じ。Inilne JavaScriptが使えないからHTMLタグの方にonclickを設定することもできず、addEventListenerを利用している。
データの保存はlocalとsyncがある。どちらが安全なのかは今後調べる予定。

function save_options() {
    chrome.storage.sync.set({
        api_key: document.getElementById('api_key').value,
        secret_key: document.getElementById('secret_key').value
    }, function () {
        var status = document.getElementById('status');
        status.textContent = 'Saved.';
        setTimeout(function () {
            status.textContent = '';
        }, 750);
    })
}

function restore_options() {
    chrome.storage.sync.get({
        api_key: 'input here',
        secret_key: 'input here'

    }, function (items) {
        document.getElementById('api_key').value = items.api_key;
        document.getElementById('secret_key').value = items.secret_key;
    });
}

document.addEventListener('DOMContentLoaded', restore_options);
document.getElementById('save').addEventListener('click', save_options);

設定した値は、メインの方のJavaScriptにてこのように利用可能。設定値を別のプロパティに詰め替えてfunctionの外で利用しようと思っていたけれど、なぜかundefinedになってしまったので制限されているのかな。
なので、メインの方の処理はこのfunctionの中に移動した。

    chrome.storage.sync.get(["api_key", "secret_key"], function (input) {
        input.api_key;
        input.secret_key;
    });