2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Chrome拡張機能の実践:データ保存と活用

Posted at

以前の記事で、Chrome拡張機能自体の作成についてを実践することができたので、続いてもう一歩踏み込んだところとして、chrome.storage.local/sync.set/get を用いた「データの保存」「(保存した)データの使用」について実践してみます

TL;DR

chrome.storage.local.set , chrome.storage.local.get の実践
実践を通じて自分でわかったこと

完成形

GitHubレポジトリに配置しました

要件定義

「データを保存」「(保存した)データの使用」が必要になるプロダクトを作る必要がある
そのため、以前から面倒だと思っていた点として、たまにやっていた「アンケートの個人情報入力」(ブラウザの機能だといまいち)について半自動化する、をついでにやってしまおうと考える
何かしらのページに対する「入力フォームに入力する個人情報の保存」(→options.htmlを使う)、「保存した情報を入力フォームに(半)自動入力」する拡張機能を最終形とする
セキュリティ面が不安である+自分のPCでしか使わないものであるため、chrome.storage.sync (Googleアカウントを用いて異なるデバイス間でデータを同期、別デバイスでも使用できるようになる)でなく、 chrome.storage.local (PC自体にデータを保存する、5MBまで)を用いる

設計

manifest.json

だいたい前のものと同じなので使いまわしです
ただし、今回はどのページでも動いてほしいので、 "content_scripts""matches"["http://*/*", "https://*/*"] とかにしておきます
また今回は(設定用に)オプションページが要るので、"options_page": "options.html" を設定、また chrome.storage を使うので "permissions": ["storage"] もつけておきます

options.html

特に工夫も何もなく、 input タグで入力欄を作っていくだけになります

入力欄一例
<div class="form">姓(漢字): <input type="text" class="inputForm narrowForm" id="lastNameJPKanji" value="">   名(漢字): <input type="text" class="inputForm narrowForm" id="firstNameJPKanji" value=""></div>

「念のため」を考えて、使うと使わないとに関わらず、名前(フル・姓・名/漢字・ひらがな・カタカナ)、電話番号(固定・携帯/ハイフン無し・ハイフンあり)など、さらに英語表記の場合など色々用意しました
後から考えればハイフンとか空白とかで区切るときは、出力時に split とか使えばいいだろ、とか、こんな沢山入力項目いらんだろ(実際、後のoptions.jsやcontents.jsまで含めて、作るの面倒だった)とかありましたが、まあ実践ということでいいか、と流します

挙動(保存・読み出し・クリア)の発火のために、ボタンも作ってだいたい完成です
(配置若干乱れてる箇所がありますが、自分用である+今回の主題ではないということで目をつぶります)

ボタン押した時の挙動は、options.htmlで動くための挙動ということでoptions.jsに書いていきます

options.js

ここで、まずデータの保存である chrome.storage.local.set の実践になります

dataset一例
function dataSet () {
    chrome.storage.local.set(
  {
    "ProfilesJP": {
        "FullName": {
            "Kanji": document.getElementById("fullNameJPKanji").value,
            "Hiragana": document.getElementById("fullNameJPHira").value,
            "Katakana": document.getElementById("fullNameJPKana").value
        },
        "LastName": {
            "Kanji": document.getElementById("lastNameJPKanji").value,
            "Hiragana": document.getElementById("lastNameJPHira").value,
            "Katakana": document.getElementById("lastNameJPKana").value
        },
...
    });
}

基本的にはこんな漢字で、JSON型データ(オブジェクト)の各キーを定め、そのキーに対し : で区切って保存するデータ(今回はinputタグの入力フォーム内に書いたものなので、 getElementById で入力フォームを指定し .value で中身を指定する)を当てはめる形になります
この関数を「Save」ボタンを押した時に働かせたいので、「Save」ボタンに addEventListener clickdataSet が発火するように設定しておきます

続いて、保存したデータの読み出しのために chrome.storage.local.get の実践です
ここでは、保存したデータを読み出して各入力フォームに表示する(データの確認のため)挙動を作ることで学んでいきます

savedDataLoad一例
function savedDataLoad (){
    chrome.storage.local.get("ProfilesJP", function (value) {
        document.getElementById("fullNameJPKanji").value = value.ProfilesJP.FullName.Kanji;
        document.getElementById("fullNameJPHira").value = value.ProfilesJP.FullName.Hiragana;
        document.getElementById("fullNameJPKana").value = value.ProfilesJP.FullName.Katakana;

        document.getElementById("lastNameJPKanji").value = value.ProfilesJP.LastName.Kanji;
        document.getElementById("lastNameJPHira").value = value.ProfilesJP.LastName.Hiragana;
        document.getElementById("lastNameJPKana").value = value.ProfilesJP.LastName.Katakana;
...
    });
}

データロードを行なう chrome.storage.local.get 自体は上記のように、第一引数に読み込みたいデータのキー(上記だと "ProfilesJP" )を設定することになります(多分 set した時の一番上のキーのどれか?)
第二引数に function (value) (あるいは (value) => とアロー関数でも良さそう)を設定して、この関数の中でデータが使用できることになります
データ自体の読み出しとしては、 value (第二引数の関数の引数として設定したもの)からピリオドで区切り、保存したデータのキーを書いていくことでデータを指定できますが、この際 value の直後に来るものとして、 chrome.storage.local.get 自体の第一引数に指定したキーを入れないとちゃんと指定できません

読み込めなかった例
document.getElementById("fullNameJPKanji").value = value.FullName.Kanji;
読み込めた正答例
document.getElementById("fullNameJPKanji").value = value.ProfilesJP.FullName.Kanji;

ここで value だけで最初のキーの代わりのようになると誤解して、 value.FullName.Kanji のように書いたところ「そんなデータないぞ」とエラー出されて少し詰まりました

この関数についても、対応する「Load」ボタンを押した時に働かせたいので、 addEventListener clicksavedDataLoad が発火するように設定しておきます

上記のコードについて、一部のみ設定して、単体テストと結合テストの中間のようなことを実行します

AutoInput_Input.gif

ちゃんと入力したデータを保存した後、入力内容を消去してから読み出すと、入力内容が復活しているので動作確認完了です
すべてのデータに対して同じように設定し、options.jsを完成させます
(時折id名やキー名を間違える凡ミスをちょくちょくやらかし、名付けのてきとーさを後悔)

contents.js

ちゃんと挙動ができたということで、今度は適用先のページで動かすためのcontents.jsを用意しておきます
やること自体はoptinos.jsで行なったデータ読み込みと同じなので、先に作成した savedDataLoad と同じように設定するだけです
実際のページを確認して入力フォームのclass名やname名(今回の適用先と考えているページのフォームにはidが設定されてなかった)で指定し、そこに value.~ を設定していきます

このとき、発火については対象ページのみにしておきたいこと、各ページでフォームの形式やclass名などが統一されていないであろうこと(A社のアンケートフォームとB社のアンケートフォームで入力フォームの数や形式が全然違うなんてザラなので)を考えて、URLで入力フォームを判別し、その際に適した入力が行なわれるように、URLの中身で異なる入力用関数が動くようにします(今回は1つだけ)
また、場合によっては「やっぱ手で入力したい」となるであろうことも考えて「自動」で働くように、入力用関数の最初に window.confirm で自動入力するかどうかを選べるようにします

実際に挙動を確かめた結果がこのような形
AutoInput_demonstration.gif

「自動入力しますか?」にOKと応えることで、入力対象の情報が入っていることが確認できました

学び

  • chrome.storage.local.set( ) の中身にJSON型で記述することで、データを保存できる
  • chrome.storage.local.get("キー名", function (value) { }); の中身に value.キー名 と書くことで、データの読み出しができる
    • value.キー名 について、最初のキー名は一番上のキー名(chrome.storage.local.getの第一引数に入れたもの)でなければならない
  • window.confirm の実践

実用

目的の一つとして、対象アンケートフォームへの入力(半)自動化もあったので、早速使用してみたところ、しっかりフォームが埋められ、回答速度がだいぶ早くなりました
ただ、同じ会社のアンケートフォームの中でも、質問内容によってはフォームの数やname名が異なり適切に埋められないことも何度か
完全にするには事前にフォーム数を見るとか、フォームの手前に書いてある記述名とかで判別する必要がありそうです(今回は要件的にそこまでしなくていいのでやらない)

実用に向く拡張機能が作れるようになったことで、自分の作業も効率化できそうになってきました
似たような機能持つChrome拡張はすでにあると思いますが、学習も目的の一つなので車輪の再発明おおいに結構!
自分用に最適化できるようカスタマイズしていけそうです

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?