LoginSignup
7
9

More than 1 year has passed since last update.

逆引きChrome extension開発メモ

Last updated at Posted at 2020-10-08

Chrome extensionの基本的な概念

Chrome拡張の開発方法まとめ その1:概念編
Chrome Extension の作り方 (その1: 3つの世界)
Chrome Extension の作り方 (その2: Contents Script)
Chrome Extension の作り方 (その3: Browser Action / Page Action)
Chrome Extension の作り方 (その4: Event Page / Background Page)
Chrome Extension の作り方 (最終話: メッセージパッシング)

Chrome extensionにおける基本的なことは上記のページでかなり勉強できる.お世話になりました.

現在開いているタブの情報を取得する

ここで現在開いているタブとは,現在選択しているウィンドウで開いているタブのことを示す.

permissions
["tabs","activeTab"]

chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
  active_url = tabs[0].url;
});

<解説>
chrome.tabs.query(object queryInfo, function callback)を使う.
active:trueで実行したウィンドウ内でのアクティブなタブを指定し,currentWindow:trueで現在選択しているウィンドウを指定する.
queryのcallbackはarray of Tabsであり,今取得しようとしているタブの情報はtabs[0]に格納されている.
URL以外にも以下のような情報も含まれている.

  • id
    タブのID.browser session内で固有の値を持つので,sendMessageなどでメッセージパッシングを行う際にこれを指定することにより,任意のタブへメッセージを送ることができるようになる.
  • windowId
    そのタブを含むウィンドウのID.
  • title
    タイトル.
  • pendingUrl

The URL the tab is navigating to, before it has committed. This property is only present if the extension's manifest includes the "tabs" permission and there is a pending navigation.
https://developer.chrome.com/extensions/tabs#property-Tab-pendingUrl

参考:https://developer.chrome.com/extensions/tabs#type-Tab

タブのURLを取得できない


chrome.tabs.onCreated.addListener(function (tab) {
  alert(tab.url);//sometimes ""
  alert(tab.pendingUrl);
  if(tab.pendingUrl.match(/.*.pdf$/)){
    //URLが.pdfで終わるような場合にのみ実行する
  };
}

<解説>
TabからURLを取得できない場合は,タブを開いたばかりだとtab.urlを取得できないことがある(確定?)ので,pendingUrlを確認してみるとよい.

選択しているテキストを取得

<解説>

contents.js
winodw.getSelection().toString()

contents.jsではこのように簡単に取得できる.一方,ContextMenusでは以下のような方法でも取得できる.

permissions
["contextMenus"]
background.js
chrome.contextMenus.create({
  title: "selectiontext>:%s",
  type: "normal",
  contexts: ["selection"],
  onclick: function (info) {
    alert(info.selectionText)
  },
});

titleにある%sは選択中のテキストに置き換わる.
infoに含まれる他の情報など詳細はchrome.contextMenusを参照されたい.
余談だが,PDF上の選択したテキストはwindow.getSelection().toString()で拾うのは難しい.
私は諦めてonclickinfoから拾う実装にした.

タブを開く


chrome.tabs.create({
  url: "http://www.google.co.jp/search?hl=ja&source=hp&q=how_to_create_tabs",
  active: false,
});

<解説>
chrome.tabs.create(object createProperties, function callback)を使う.
ここではactive:falseとしてタブを開いた際に現在開いているタブの選択状態が変わらないように指定した.createPropertiesにはwindowIdなども指定できる(デフォルトは現在のウィンドウ).

タブを消す


chrome.tabs.getSelected(null, function (tab) {
  chrome.tabs.remove((tabIds = tab.id));
});

<解説>
chrome.tabs.remove(integer or array of integer tabIds, function callback)を使用する.
現在選択しているタブのTab Objectsをchrome.tabs.remove((tabIds))により選択したIDを持つタブを削除する.tabIdsにはIDのリストを渡すこともできる.
参考:https://developer.chrome.com/extensions/tabs#method-remove

popupのウィンドウを消す

popup.js
window.close();

<解説>
cssでdisplay:none;を指定しても完全には消えずに小さなウィンドウが残ってしまうのでclose()してしまえばよい.ただし,sendMessagebackgroundにメッセージを送っていた場合は,sendResponse()から返ってくる前に消してしまうと正常に処理を終えられなくなることに注意したい.
あくまですべての処理を終えてから消すこと.

background.jsにメッセージを送る

contents.js
chrome.runtime.sendMessage({ message: "from_contents" }, function (res) {
  alert("Hello "+res);
});
background.js
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
  if (request.message == "from_contents") {
   sendResponse("World!")
  }
});

<解説>
background.jsにメッセージを送るにはchrome.runtime.sendMessage(string extensionId, any message, object options, function responseCallback)を用いる.
chrome.tabs.sendMessage(integer tabId, any message, object options, function responseCallback)tabIdを指定できないので使用できない.
つまり,background.jsに向けたメッセージはすべてchrome.runtime.sendMessage()を用いる.

contents.jsからpopup.jsにメッセージを送る

contents.js
chrome.runtime.sendMessage({ message: "from_contents" }, function (res) {
  alert("Hello "+res);
});
popup.js
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
  if (request.message == "from_contents") {
   sendResponse("World!")
}
});

<解説>
popup.jsはアイコンをクリックしたウィンドウ上に現れるので,一見するとそのタブのIDを持っていそうだが,実際は持っていない.
そのため,chrome.runtime.sendMessage()を用いる.この辺の使い分けを理解するのに私は時間がかかった...

sendResponse()で複数の値を渡したい

popup.js
chrome.runtime.sendMessage({ message: "test" }, function (resjson) {
  var obj = JSON.parse(resjson);
  alert(obj.count);
  alert(obj.result);
});
background.js
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
  if (request.message == "test") {
    var result=true;
    var count=42;
    sendResponse('{"result":result,"count":count}');
  }
});

<解説>
sendResponse()の引数はJSON objectであるので,JSONの形に成形すれば複数引数の値を渡すことができる.
公式ドキュメントにはしっかり記載されているが,外部解説サイトではsendResponse(result)のように一つの変数の値しか渡していない例が多かったので,ここで強調して紹介しておきたい.

終わりに

chromeにデータを保存できるchrome.storageや,Options Pageはまだ使用したことがないので勉強次第追記する.

jsやhtml周りを勉強する必要はありますが,Chrome拡張機能は思った以上に簡単に作れます.
はじめに紹介した分かりやすい解説記事や公式サンプルを参考に作ってみてはいかがでしょうか.

7
9
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
7
9