かすみん日記

暇なときに何か喋ります

【Chrome拡張機能】特定のURLの時だけpopup表示の代わりにonClickedイベントを発生させる

実現したいこと

ツールバー拡張機能アイコンをクリックしたとき、特定のURLのときだけポップアップを表示し、それ以外のURLではポップアップを表示する代わりにaction.onClicked.addListenerを設定したい。

環境

内容

以下の例では、ツールバー拡張機能アイコンをクリックしたとき、開いている(activeな)タブのURLがhttps://www.google.com/〜のときはpopup.htmlを表示し、それ以外のURLのときはポップアップは表示せず、その代わりに新規タブでhttps://www.google.comを開くような拡張機能を作ります。

用意するファイルは以下の3つ:

  • manifest.json
  • popup.html
  • background.js

それぞれの中身は以下の通りです。

manifest.json:

{
  "name": "てすと",
  "description": "てすとです。",
  "version": "1.0",
  "manifest_version": 3,
  "permissions": ["activeTab", "tabs"],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_popup": "popup.html"
  }
}

マニフェストバージョンが3なのと、permissionstabsも必要なことに注意してください。
(失敗談:permissionstabsを指定していないと、tab.urlでURLが取得できなかった)

あと、backgroundがこの書き方だと、そのままではfirefoxに流用できないっぽいです(参考)。

popup.html:

<p>今期の覇権はU149</p>

ポッポアップの表示の確認だけなので、中身はなんでもいいです。好きな俳句を書いてください。

background.js:

chrome.tabs.onActivated.addListener( function(activeInfo){
  chrome.tabs.get(activeInfo.tabId, function(tab){
    setAction(tab.url);
  });
});

chrome.tabs.onUpdated.addListener((tabId, change, tab) => {
  if (tab.active && change.url) {
    setAction(change.url);
  }
});

function setAction(url) {
  // console.log(url);
  const pattern = /^https:\/\/www.google.com/;
  if (pattern.test(url)) {
    chrome.action.setPopup({ popup: "./popup.html"})
    chrome.action.onClicked.removeListener(openGoogle);
  } else {
    chrome.action.setPopup({ popup: "" });
    chrome.action.onClicked.addListener(openGoogle);
  }
}

function openGoogle(tab) {
  const newURL = 'https://www.google.com';
  chrome.tabs.create({ url: newURL });
}

ここにガッツリ処理を書いていますね。ざっくり解説します。

tabs.onActivatedは、アクティブなタブを切り替えたときに発生するイベントです。 tabs.onUpdatedの方は、タブの情報に変更があったとき(画面遷移やリロードなど)に発生するイベントです。 これらのイベントが発生したときに、アクティブなタブのurlを取得して、それを引数として関数setActionを呼んでいます。

setActionでは、アクティブなタブのURLがGoogleかどうかを見分けて、ツールバー拡張機能アイコンをクリックしたときの処理を付け替えています。 アクティブなタブのURLがGoogleのとき(if文のtrueの処理)、ポップアップに./popup.htmlを設定しています。 これはmanifestのdefault_popupに指定したものと同じです。 またこのとき、クリックイベントのリスナーopenGoogleを削除しています。

アクティブなタブのURLがGoogleでないとき(if文のfalseの処理)は、上記の逆の処理を行なっています。 action.setPopup({ popup: "" })でポップアップのhtmlを空白で上書き(削除)しています。 そうすることで、拡張機能のアイコンをクリックしても、ポップアップは表示されなくなります。 また、action.onClicked.addListener(openGoogle)にて、アイコンをクリックしたときに関数openGoogleが呼ばれるようにリスナーを設定しています。 関数openGoogleは、URLがhttps://www.google.comの新しいタブを作成(してアクティブに)する処理となっています。

説明は以上です。 あとは適当に応用していただければと思います。

参考

developer.mozilla.org

developer.mozilla.org

developer.mozilla.org

stackoverflow.com

stackoverflow.com

github.com