以前の記事で、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
の実践になります
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
click
で dataSet
が発火するように設定しておきます
続いて、保存したデータの読み出しのために chrome.storage.local.get
の実践です
ここでは、保存したデータを読み出して各入力フォームに表示する(データの確認のため)挙動を作ることで学んでいきます
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
click
で savedDataLoad
が発火するように設定しておきます
上記のコードについて、一部のみ設定して、単体テストと結合テストの中間のようなことを実行します
ちゃんと入力したデータを保存した後、入力内容を消去してから読み出すと、入力内容が復活しているので動作確認完了です
すべてのデータに対して同じように設定し、options.jsを完成させます
(時折id名やキー名を間違える凡ミスをちょくちょくやらかし、名付けのてきとーさを後悔)
contents.js
ちゃんと挙動ができたということで、今度は適用先のページで動かすためのcontents.jsを用意しておきます
やること自体はoptinos.jsで行なったデータ読み込みと同じなので、先に作成した savedDataLoad
と同じように設定するだけです
実際のページを確認して入力フォームのclass名やname名(今回の適用先と考えているページのフォームにはidが設定されてなかった)で指定し、そこに value.~
を設定していきます
このとき、発火については対象ページのみにしておきたいこと、各ページでフォームの形式やclass名などが統一されていないであろうこと(A社のアンケートフォームとB社のアンケートフォームで入力フォームの数や形式が全然違うなんてザラなので)を考えて、URLで入力フォームを判別し、その際に適した入力が行なわれるように、URLの中身で異なる入力用関数が動くようにします(今回は1つだけ)
また、場合によっては「やっぱ手で入力したい」となるであろうことも考えて「半自動」で働くように、入力用関数の最初に window.confirm
で自動入力するかどうかを選べるようにします
「自動入力しますか?」にOKと応えることで、入力対象の情報が入っていることが確認できました
学び
-
chrome.storage.local.set( )
の中身にJSON型で記述することで、データを保存できる -
chrome.storage.local.get("キー名", function (value) { });
の中身にvalue.キー名
と書くことで、データの読み出しができる-
value.キー名
について、最初のキー名は一番上のキー名(chrome.storage.local.getの第一引数に入れたもの)でなければならない
-
-
window.confirm
の実践
実用
目的の一つとして、対象アンケートフォームへの入力(半)自動化もあったので、早速使用してみたところ、しっかりフォームが埋められ、回答速度がだいぶ早くなりました
ただ、同じ会社のアンケートフォームの中でも、質問内容によってはフォームの数やname名が異なり適切に埋められないことも何度か
完全にするには事前にフォーム数を見るとか、フォームの手前に書いてある記述名とかで判別する必要がありそうです(今回は要件的にそこまでしなくていいのでやらない)
実用に向く拡張機能が作れるようになったことで、自分の作業も効率化できそうになってきました
似たような機能持つChrome拡張はすでにあると思いますが、学習も目的の一つなので車輪の再発明おおいに結構!
自分用に最適化できるようカスタマイズしていけそうです