[Chrome拡張]　Chrome拡張メニューからページを操作する方法

Chrome拡張画面(manu.html)から「content scripts」へメッセージを送って
ページの内容を書き換える方法をご紹介します。
（なお、ManifestV3対応です）

[前回](https://qiita.com/doran/items/743f687eb413c41432e1)の続きです
[[Chrome拡張] ツールバーのアイコンをクッリクしてHTMLページを表示する方法](https://qiita.com/doran/items/743f687eb413c41432e1)

:::note info
新しく作成したchrome拡張を公開しました。
そこで使用した技術を備忘録として共有できればと思い、記事を書いています。
[こちらがそのChrome拡張の記事です。ご興味があれば](https://qiita.com/doran/items/8c3ca80de3f149dce0e0)

[こちらは別のChrome拡張の記事です。合わせてどうぞ](https://qiita.com/doran/items/6613ea2d92b330bae2c9)
:::
#### 用意するファイル
```
root/
 　├ manifest.json
 　├ menu.html
 　├ js/
 　│　 ├ background.js
 　│　 ├ menu.js
 　│　 ├ script.js
 　│　 └ jquery-3.5.1.min.js
 　└ img/
 　　  ├ icon32.png
  　　 └ icon48.png
```
#### menu.html
まずは、アイコンをクリックした際に表示させるHTMLページを用意します。
今回は、「manifest.json」と同じ階層に「menu.html」、
「js」フォルダを用意して「jquery-3.5.1.min.js」と「menu.js」を用意しました。
```html
<!DOCTYPE HTML>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <title>メッセージ送信テスト</title>
    <script src="js/jquery-3.5.1.min.js"></script>
    <script src="js/menu.js"></script>
  </head>
  <body>
    <input id="send_input" type="text">
    <button id="send_button">送信ボタン</button>
  </body>
</html>
```
#### menu.js
次に「menu.html」で行われた操作を処理する「menu.js」を「js」フォルダ以下に作成します。
やっていることは以下です。
1.「menu.html」の送信ボタンが押されます。
2.現在のウィンドウで開かれているタブを全て取得します。
3.上記2のタブに対して「menu.html」の入力フィールドで入力したメッセージを送信します。
```js
$(function(){
  //「menu.html」の送信ボタンを押したときに実行されます。
  $(document).on("click","#send_button",function(){
    var send = $("#send_input").val();

    //「currentWindow:true」現在のウィンドウにあるタブを全て取得します。
    chrome.tabs.query( {currentWindow:true}, function(tabs){  
      for(var i=0; i<tabs.length; i++){
      	//「content_scripts」へメッセージを送信します。
		//ここでは、「menu.html」の「$("#send_input")」に入力したテキストを送信しています。
        chrome.tabs.sendMessage(tabs[i].id,{"msg":send})
        .then((response)=> {
          //メッセージ送信が成功した場合、「content_scripts」側での実行結果が返されます。
          console.log(response);
        }).catch((error)=> {
          //メッセージ送信が失敗した場合に実行されます
          console.log(error);
       });
      }
    });
  });
});
```
#### manifest.json
**permissions**はcontent_scriptsへメッセージを送るだけなら不要です。
**matches**は私が書いた記事を書き換えますのでhttps\://qiita.com/doran/items/*を指定します。
```json
{
  "name": "メッセージ送信テスト",
  "version": "1.00",
  "description": "メッセージ送信テスト",
  "permissions": [],
  "background": {
    "service_worker": "js/background.js"
  },
  "action": {
    "default_icon": {
      "32": "images/icon32.png"
    }
  },
  "icons": {
    "48": "images/icon48.png"
  },
  "content_scripts": [
    {
      "matches": ["https://qiita.com/doran/items/*"],
      "js": ["js/jquery-3.5.1.min.js","js/script.js"]
    }
  ],
  "manifest_version": 3
}
```
・permissions
　　メニューを表示、メッセージ送信するだけなら不要です。
・background
　　backgroundで実行されるjsを指定します。
・action
　・default_icon
　　　　ツールバーに表示されるアイコンを指定します。
・icons
　　menu.htmlのファビコンを指定します。
・content_scripts
　・matches
　　　　content_scriptsを読み込むページのURLを指定します。
　　　　<font color="red">この指定に当てはまらないURLの場合は、content_scriptsは読み込まれせん。</font>
　・js
　　　content_scriptsのソースと、そこでで使用するjsを指定します。
#### background.js
Chromeブラウザのツールバーにあるアイコンがクリック時に「menu.html」を
新しいタブで開くためにbackgroundを用意します。
```js
chrome.action.onClicked.addListener(function(){
  chrome.tabs.create({"url": "menu.html"});
});
```
#### script.js
content_scriptsのmatchesで指定したアドレスと一致するページで実行されるJS。
ここでは投稿者のアイコンと、記事タイトルを変更します。
```js
//「menu.html」から送信されてきたメッセージを受信します。
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
    //投稿者のアイコンを書き換えます。
	$("[data-logly-image='true'] img").attr("src",$("[rel='apple-touch-icon']").attr("href"));
    //記事タイトルを「menu.html」から送信されてきたメッセージに置き換えます。
	$(".p-items_main h1").text(request.msg);

    //「menu.html」へ返信します。
    sendResponse("OK");
});
```

#### 実行結果
1. https\://qiita.com/doran/items/から続くURLの記事を2つほど開いておきます。
2. Chrome拡張を開いて、メッセージを入力して送信ボタンを押します。
![0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/1023d2af-1625-7cab-dec2-239c970a22ac.png)
3. ２つのページにメッセージが飛びます
4. 開いていた２記事の投稿者アイコンと記事タイトルが書き変わりました。

***これが。。。***
<img width="280" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/1f343749-8b57-fc0b-b0ec-b057c1fd9526.png">　　　<img width="280" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/c086472a-52b2-bd8e-eff8-87c65b097b89.png">
***こうなりました！***
<img width="280" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/78dfe03a-3483-0407-6d91-72b29162a1bf.png">　　　<img width="280" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/9ee01fba-2298-31b0-a6d2-ec601c4e5c7a.png">
おしまい。。。
#### その他のChrome拡張の実装方法
以下はこれまでに投稿したChrome拡張の記事です。用途に応じてご覧ください。
[[Chrome拡張]　ツールバーのアイコンをクリックしてHTMLページを表示する方法](https://qiita.com/doran/items/743f687eb413c41432e1)
[[Chrome拡張]　Chrome拡張メニューからページを操作する方法](https://qiita.com/doran/items/9203789b570632e2456e)
[[Chrome拡張]　Webページ(content scripts)からChrome拡張画面へメッセージを送る方法](https://qiita.com/doran/items/faf21f816b168606cfbe)
[[Chrome拡張]　Chrome拡張画面でタイマー(定期実行処理)を使用する方法](https://qiita.com/doran/items/c2c5c225691fd423b2e6)
[[Chrome拡張]　Content Scriptsでタイマー(定期実行処理)を使用する方法](https://qiita.com/doran/items/2620b2c8f2ac2c5548b6)
[[Chrome拡張]　Chrome拡張メニューからWebページを操作する方法](https://qiita.com/doran/items/8045701ba688f50d6295)
[[Chrome拡張]　Chrome拡張メニューからWebページを操作する方法(jQueryを使う)](https://qiita.com/doran/items/817432932bf77c781002)
[[Chrome拡張]　Chrome拡張メニューとWebページでやりとりする方法](https://qiita.com/doran/items/7ccf10bb310ab46478d4)
[[Chrome拡張]　Chrome拡張メニューとWebページでやりとりする方法(Content Scriptsを使う)](https://qiita.com/doran/items/e69ba19cbd2f5049bc97)
[[Chrome拡張]　Chrome拡張メニューから開いていないWebページの情報を取得する方法](https://qiita.com/doran/items/c2d3249c53b97ddeed0d)
[[Chrome拡張]　ポップアップメニューを表示する方法](https://qiita.com/doran/items/6684c939c5dc2b9d091a)
[[Chrome拡張]　ポップアップメニューからWebページを操作する方法](https://qiita.com/doran/items/c34be1c03353a02cd04f)
[[Chrome拡張]　ポップアップメニューからWebページを操作する方法(jQueryを使う)](https://qiita.com/doran/items/6b7181e369cd1be7dfc4)
[[Chrome拡張]　ポップアップメニューからWebページを操作する方法(スタイル変更)](https://qiita.com/doran/items/00ea4f88862031811ed4)
[[Chrome拡張]　ストレージ(chrome.storage.local)を利用する方法](https://qiita.com/doran/items/38a89bcaf4b89c758725)
[[Chrome拡張]　オプションページを表示する方法](https://qiita.com/doran/items/8154f96c200b73bb9e38)