Google Chromeの拡張を作ってみたい チュートリアル

スポンサーリンク
スポンサーリンク

Chromeの拡張

やってみたいことがあるので、Chromeの拡張の作り方を調べる。

スポンサーリンク

チュートリアルやる

Extensions / Get started  |  Chrome for Developers
All the basics to get started with Chrome extensions

チュートリアルがあったので、チュートリアルをやる。ここの背景色を変えるやつみたいだけど、せっかくなのでこのブログのを変えたい。

スポンサーリンク

manifest.json

{
  "name": "Getting Started Example",
  "version": "1.0",
  "description": "Build an Extension!",
  "manifest_version": 2
}

これだけでもう拡張として認識されるみたい。

なった。

スポンサーリンク

background.js

落としてきて、同じフォルダに入れる。あと、manifestのdescription以下に

"background": {
    "scripts": ["background.js"],
    "persistent": false
  },

追記することでbackground.jsを使いますよーという意味になるみたい。persistantは知らん。background.jsの中身は

'use strict';

chrome.runtime.onInstalled.addListener(function() {
  chrome.storage.sync.set({color: '#3aa757'}, function() {
    console.log("The color is green.");
  });
});

なんですが、はっきり言ってさっぱり意味が分からん。うーんと’use strict’;がコードを厳格に書かなきゃいけないみたいなモードの文言みたい。chrome.runtime.onInstalled.addListenerが拡張がインストールされた時とかに走るみたいなやつ。chrome.storage.sync.setがchrome内にデータを保存するやつで、syncが同期可能な感じで保存、ここではcolorというキーに、#3aa757という値を保存してる。そのコールバック…コールバックもよく分かってないけど、成功・失敗時にconsole.logに表示する。

ここの、chrome.storageはchromeで用意されてるAPIで、使うにはmanifest.jsonにpermissionを追加する必要がある。なので、descriptionの下に

"permissions": ["storage"],

を追記する。拡張機能を再読込すると、バックグラウンドページのリンクがついて、クリックするとコンソールが開く。

スポンサーリンク

UserInterface (popup.html, etc)

popup.html

https://dalomo.net/blog/files/popup.html

これを落としまして。htmlうまく貼れない。styleタグ内がcssってやつでボタン作ってる。button idをchangeColorとする。scriptがよく分かんない。ボタン押した時?html開いた時?どっちで実行されんだろ。popup.jsも作ってない。どこにあるんだこれ。とりあえず先に進むとして、popup.htmlを使うためにも、manifest.jsonに追記する必要がある。

"page_action": {
    "default_popup": "popup.html"
  },

こうか。page_actionってのがメニューんとこにあるアイコンをどうのこうのするやつみたい。

icon

アイコンの指定もここでできてimgを落としてきて同じフォルダに置き、

,
      "default_icon": {
        "16": "images/get_started16.png",
        "32": "images/get_started32.png",
        "48": "images/get_started48.png",
        "128": "images/get_started128.png"
      }

また追記。拡張機能管理ページ、アクセス許可の警告、およびファビコン用にも

"icons": {
    "16": "images/get_started16.png",
    "32": "images/get_started32.png",
    "48": "images/get_started48.png",
    "128": "images/get_started128.png"
  },

と追記。

アイコンついた。

declarativeContent

指定urlによってアイコンの状態を変化させるためにbackground.jsのさっきのリスナ内に

chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
    chrome.declarativeContent.onPageChanged.addRules([{
      conditions: [new chrome.declarativeContent.PageStateMatcher({
        pageUrl: {hostEquals: 'developer.chrome.com'},
      })
      ],
          actions: [new chrome.declarativeContent.ShowPageAction()]
    }]);
  });

こう。ううう、何だこれは…。chrome.declarativeContent

to take actions depending on the content of a page, without requiring permission to read the page’s content.

ページのコンテンツを読み取る許可を必要とせずに、ページのコンテンツに応じてアクションを実行します。

うん。で、onPageChangedっていうぐらいだから、ページを遷移した時に自分で設定したルールとマッチするか、みたいな感じだろか。そいでそのルールの編集がremoveRulesaddRulesかな。

chrome.events  |  API  |  Chrome for Developers

ここの

Event objects may support rules. These event objects don’t call a callback function when events happen but test whether any registered rule has at least one fulfilled condition and execute the actions associated with this rule. Event objects supporting the declarative API have three relevant methods: events.Event.addRules, events.Event.removeRules, and events.Event.getRules.

イベントオブジェクトはルールをサポートする場合があります。これらのイベントオブジェクトは、イベントが発生したときにコールバック関数を呼び出しませんが、登録されたルールに少なくとも1つの条件を満たす条件があるかどうかをテストし、このルールに関連付けられたアクションを実行します。宣言型APIをサポートするイベントオブジェクトには、events.Event.addRules、 events.Event.removeRules、およびevents.Event.getRulesの 3つの関連メソッドがあり ます。

うん。そのルールの書き方が

var rule = {
    conditions: [ /* my conditions */ ],
    actions: [ /* my actions */ ]
};

が基本形で、最低でもconditionsとactionsが必要。

chrome.events  |  API  |  Chrome for Developers
  • conditions
    • List of conditions that can trigger the actions.
  • actions
    • List of actions that are triggered if one of the conditions is fulfilled.

ここではconditionsにchrome.declarativeContent.PageStateMatcherを使って、pageUrl(UrlFilterページのトップレベルURLの 条件が満たされている場合に一致)のhostEquals(URLのホスト名が指定された文字列と等しい場合に一致)でdeveloper.chrome.comを指定してる。このURLをdalomo.netに変えりゃいいんだな。まぁ後にしよ。で、actionsにchrome.declarativeContent.ShowPageActionでメニューバーのアイコンに色付いて使えるようになるし、アクティブタブへのアクセスが許可される。分かりづらいよぅ。慣れてないからなのかなぁ…。

popup.js

おぉ、さっき作ったpopup.htmlで呼ばれる外部スクリプトのpopup.jsだ。

'use strict';

let changeColor = document.getElementById('changeColor');
chrome.storage.sync.get('color', function(data) {
  changeColor.style.backgroundColor = data.color;
  changeColor.setAttribute('value', data.color);
});

えーっと、letは変数のスコープがブロック内になるやつ。そこにgetElementById(‘changeColor’)でエレメントを取得。changeColorが設定されてるタグはButtonなのでそれが取得される。chrome.storage.sync.getでこの前保存したキーのcolorを使って値を取り出す。そのコールバックで、取得した値を引数として、buttonであるchangeColorのstyle.backgroundColorを値で設定して、setAttributeでvalue属性に値を設定する。でいいのかな。data.colorっていう書き方でなんで値が引っ張れるのか分からん。style.colorっていうのがあって、それの戻り値がそれっぽい感じだったけど、ここのdataってstyleなのか?どうなの?Javascriptはそういうもんなのかもしれない。ここまで終わってpopup.htmlは

たんと追加されてた。うーんと、これstyleとvalueって何が違うんだろ。試しにstyleの方を消してみたら色が付かなかった。でもvalue消しても色付いたままだった。なんだろな。

スポンサーリンク

LayerLogic

ようやく背景色変えるところだ。popup.jsに

changeColor.onclick = function(element) {
  let color = element.target.value;
  chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    chrome.tabs.executeScript(
        tabs[0].id,
        {code: 'document.body.style.backgroundColor = "' + color + '";'});
  });
};

を追加。buttonであるchangeColorの.onclickで、クリックした際にプログラムが走る。だけど、ここのelementが分からない。見た感じchangeColorが入ってるっぽいんだけど、そういうもんとして捉えるしかないんだろうか。代入する文が見当たらないからなんでこのまま使えてるのか困惑してしまう…。こちら

  • イベント発生時の情報をイベントオブジェクトとして引数に受け取ることができる。これはJavaScript側で自動的に、イベントハンドラに指定したコールバック関数へ渡してくれるもの。
  • イベントハンドラとして設定したコールバック関数の引数にイベントオブジェクト「e」を設定しています。「e」はイベント発生時の情報を持つオブジェクトなので「e.target.id」のように情報を得ることが可能。

このあたりなのかな。だからelement.target.valueでさっき属性を追加したvalueの値を引っ張れるんだと思う。んで、chrome.tabs.queryでqueryInfoをactive(タブがウィンドウでアクティブかどうか。)かつ、currentWindow(タブが現在のウィンドウにあるかどうか。)なやつを指定して、コールバックに(ここのtabsも分からん)、chrome.tabs.executeScriptを設定する。プログラムによってContent Scriptsにプログラムを挿入するみたいです。引数は、tabs[0].idで現在のタブを指定して、codeを挿入してる。「document.body.style.backgroundColor =  color;」っていうコードを作って挿入して実行してる。疲れた。あ、manifestに

"activeTab"

を追記。background.jsのサイトをdalomo.netに変更して実行してみると

なった!

スポンサーリンク

options.html

緑じゃないオプションを追加するためのページみたいなのを作る。とりあえずファイルを落としてきまして同じフォルダに置いて、manifestに

"options_page": "options.html",

と追記。そんでoptions.jsを作る。

let page = document.getElementById('buttonDiv');
const kButtonColors = ['#3aa757', '#e8453c', '#f9bb2d', '#4688f1'];
function constructOptions(kButtonColors) {
  for (let item of kButtonColors) {
    let button = document.createElement('button');
    button.style.backgroundColor = item;
    button.addEventListener('click', function () {
      chrome.storage.sync.set({ color: item }, function () {
        console.log('color is ' + item);
      })
    });
    page.appendChild(button);
  }
}
constructOptions(kButtonColors);

getElementById(‘buttonDiv’)でdivタグのとこを取得。constは定数で色コードの配列を作る。constructOptions関数は、その定数の引数として、定数の配列のアイテム数分createElementでボタンを作ってく。style.backgroundColorでボタンの色に定数の色を設定し、addEventListenerでボタンクリック時の処理を書いてく。storage.sync.setでcolorキーに定数の色をセットするから、色が変わるのか。page.appendChildでbuttonDivの直下末尾にbuttonを追記して完了。

結果こういうソースになる。なるほどにゃん。

スポンサーリンク

愚痴

日本語の情報とか見るとさー、manifestとcontent.jsだけでできるとか書いてあるからさー、それでいいのかと思ってたら、チュートリアルだとこんな感じになるのね。どっちがいいのかは俺にはわかんないけど、チュートリアルは俺には敷居が高いな…。やりたいことはあるんだけど、できる気がしなくなってきたな。

スポンサーリンク

参考

Chrome拡張の開発方法まとめ その1:概念編 - Qiita
Chrome拡張の開発に必要な知識とかの覚書です。この記事では開発の前に知っておくべきChrome拡張の全容について解説していきます。「実際に開発しながら学ぶ」形式の解説記事は多く見られるのです…
【JavasScript】use strictとは - Qiita
*もくじ*1 概要2 使い方3 注意点4 参考URL1 概要JavaScript(以下、JS)内でuse strictを宣言すると、コードがstrict(厳格)モードで実行されるようにな…
letとvarの違い - Qiita
一言で言うと、変数のスコープがブロックスコープか関数スコープかの違いです。letを使った場合、ブロックレベルで変数のスコープが定義されるため、以下の例のように1,2,1と表示されます。funct…

コメント

タイトルとURLをコピーしました