--- title: ウェブページを変更する slug: Mozilla/Add-ons/WebExtensions/Modify_a_web_page tags: - WebExtensions translation_of: Mozilla/Add-ons/WebExtensions/Modify_a_web_page ---
拡張機能の一般的な事例の1つはウェブページを変更することです。例えば、ページのスタイルを変更、特定の DOM ノードを隠す、別の DOM ノードをページに挿入する、といいでしょう。
WebExtensions API での実現方法は2つあります:
どちらの方法のスクリプトもコンテンツスクリプトと呼ばれ、拡張機能を構成する他のスクリプトとは異なります:
この記事ではスクリプトを読み込むそれぞれの方法について説明します。
まず始めに、"modify-page" という新しいディレクトリーを作成します。このディレクトリーで "manifest.json" というファイルを作成し、以下のように記述します。
{ "manifest_version": 2, "name": "modify-page", "version": "1.0", "content_scripts": [ { "matches": ["https://developer.mozilla.org/*"], "js": ["page-eater.js"] } ] }
content_scripts
キーは URL パターンと一致するページにスクリプトを読み込む方法です。この場合、content_scripts
は https://developer.mozilla.org/ 以下のすべてのページで "page-eater.js" というスクリプトをロードするようにブラウザーに指示します。
content_scripts
の "js"
プロパティ は配列なので、マッチしているページに複数のスクリプトを挿入できます。これを行うと、ページによってロードされるいくつかのスクリプトと同じように、ページは同じスコープを共有し、配列にリストされている順序でロードされます。
content_scripts
キーでは "css"
プロパティで CSS スタイルシートを挿入することもできます。
次に、"page-eater.js" というファイルを "modify-page" ディレクトリー内に作り、以下のように記述します。
document.body.textContent = ""; var header = document.createElement('h1'); header.textContent = "This page has been eaten"; document.body.appendChild(header);
拡張機能をインストール して https://developer.mozilla.org/ を訪れてみましょう。
{{EmbedYouTube("lxf2Tkg6U1M")}}
このビデオでは addons.mozilla.org で動作するコンテンツスクリプトを示していますが、現在このサイトではコンテンツスクリプトはブロックされています。
ユーザーがあなたに質問してきたとき、まだページを処理している場合どうしたらいいですか? この例を更新して、ユーザーがコンテキストメニュー項目をクリックしたときにコンテンツスクリプトを挿入しましょう。
始めに、"manifest.json" を以下のように更新してください。
{ "manifest_version": 2, "name": "modify-page", "version": "1.0", "permissions": [ "activeTab", "contextMenus" ], "background": { "scripts": ["background.js"] } }
これは content_scripts
キーを削除し、新たに 2 つのキーを追加しました。
permissions
: スクリプトをページに挿入するには、変更するページへの権限が必要です。activeTab
パーミッションは現在アクティブなタブへの一時的な権限を取得する方法です。コンテキストメニューに項目を追加するには contextMenus
パーミッションも必要となります。background
: "バックグラウンドスクリプト" という "background.js" を永続的に読み込み、ここでコンテキストメニューを設定し、コンテンツスクリプトを挿入します。このファイルを作りましょう。"background.js" というファイルを "modify-page" ディレクトリー内に作り以下のように記述します。
browser.contextMenus.create({ id: "eat-page", title: "Eat this page" }); browser.contextMenus.onClicked.addListener(function(info, tab) { if (info.menuItemId == "eat-page") { browser.tabs.executeScript({ file: "page-eater.js" }); } });
このスクリプトでは context menu item を作成し、特定の id とタイトルを指定します。(コンテキストメニューに表示するテキスト) 次に、イベントリスナーを設定して、ユーザーがコンテキストメニュー項目をクリックしたときに、それが eat-page
項目であるかどうかをチェックします。それが正しければ、tabs.executeScript()
API を利用して、"page-eater.js" を挿入します。この API はオプションでタブ ID を引数として取ります、よってタブ ID は省略されています。つまり、スクリプトは現在アクティブなタブに挿入されています。
この時点で拡張機能は以下のようになっています。
modify-page/
background.js
manifest.json
page-eater.js
拡張機能を再読み込みして、ページを開きます (任意のページ) コンテキストメニューを有効化し、"Eat this page" を選択します。
{{EmbedYouTube("zX4Bcv8VctA")}}
このビデオでは addons.mozilla.org で動作するコンテンツスクリプトを示していますが、現在このサイトではコンテンツスクリプトはブロックされています。
コンテンツスクリプトとバックグラウンドスクリプトはお互いの状態に直接アクセスすることはできません。しかし、メッセージを送ることによる対話をすることができます。一方のエンドはメッセージリスナーを設定し、もう一方のエンドはメッセージを送信します。 次の表は、各側面に関連する API をまとめたものです。
コンテンツスクリプト内 | バックグラウンドスクリプト内 | |
---|---|---|
メッセージ送信 | browser.runtime.sendMessage() |
browser.tabs.sendMessage() |
メッセージ受信 | browser.runtime.onMessage |
browser.runtime.onMessage |
このワンオフメッセージを送る通信メソッドに加えて、メッセージ交換するコネクションベースの方法も使えます。これらのオプションを選択するアドバイスは、ワンオフメッセージとコネクションベースのメッセージのいずれかを選択するを見てください。
例を更新して、バックグラウンドスクリプトからメッセージを送信する方法を示します。
始めに "background.js" を編集して、次のようにします。
browser.contextMenus.create({ id: "eat-page", title: "Eat this page" }); function messageTab(tabs) { browser.tabs.sendMessage(tabs[0].id, { replacement: "Message from the extension!" }); } function onExecuted(result) { var querying = browser.tabs.query({ active: true, currentWindow: true }); querying.then(messageTab); } browser.contextMenus.onClicked.addListener(function(info, tab) { if (info.menuItemId == "eat-page") { let executing = browser.tabs.executeScript({ file: "page-eater.js" }); executing.then(onExecuted); } });
次に、"page-eater.js" を挿入し、tabs.query()
を使用し、現在アクティブなタブを取得し、tabs.sendMessage()
を使用し、そのタブにロードされたコンテンツスクリプトにメッセージを送信します。 メッセージにはペイロード {replacement: "Message from the extension!"}
があります。
次に "page-eater.js" を次のように更新します。
function eatPageReceiver(request, sender, sendResponse) { document.body.textContent = ""; var header = document.createElement('h1'); header.textContent = request.replacement; document.body.appendChild(header); } browser.runtime.onMessage.addListener(eatPageReceiver);
今すぐページを処理する代わりに、コンテンツスクリプトは runtime.onMessage
を使ってメッセージを取得します。 メッセージが到着すると、コンテンツスクリプトは前と同じコードを実行しますが、置換テキストは request.replacement
から取得されます。
tabs.executeScript()
は非同期関数であり、リスナーが "page-eater.js" に追加された後にのみメッセージを送信するために、"page-eater.js" を実行した後に呼び出される onExecuted
を使用します。
Ctrl+Shift+J (Mac では Cmd+Shift+J) を押します。もしくは web-ext run --bc
で Browser Console を開きバックグラウンドスクリプトの console.log
を見ます。または、 Add-on Debugger を使用して、ブレークポイントを設定することもできます。 現在、web-ext から 直接 Add-on Debugger を起動する 方法はありません。
コンテンツスクリプトからバックグラウンドページにメッセージを戻したい場合は、 runtime.sendMessage()
の代わりに tabs.sendMessage()
を使用します。
例:
browser.runtime.sendMessage({ title: "from page-eater.js" });
content_scripts
manifest キーpermissions
manifest キーtabs.executeScript()
tabs.insertCSS()
tabs.sendMessage()
runtime.sendMessage()
runtime.onMessage
content_scripts
を使用した例:
tabs.executeScript()
を使用した例: