manifest v3 で画像をブロックする拡張機能を自作してみる

Chrome や Edge の拡張機能で今後採用される Manifest v3 では webRequest が廃止され、declarativeNetRequest に置き換わるとの事。
そこで、Manifest v3 で declarativeNetRequest を使って画像をブロックする簡単な拡張を作ってみました。
用意するファイルは「manifest.json」と「rules.json」の2つ。rules.json のファイル名は任意です。

manifest.json


{
"name": "Block Image Request",
"version": "1.0.0",
"manifest_version": 3,
"declarative_net_request": {
  "rule_resources": [{
    "id": "ruleset_1",
    "enabled": true,
    "path": "rules.json"
  }]
},
"permissions": ["declarativeNetRequest"]
}

manifest_version を「3」にし、permissions に declarativeNetRequest を加え、ルールを記述するファイルをここでは rules.json にしています。

rules.json


[
{
  "id": 1,
  "priority": 1,
  "action": {
    "type": "block"
  },
  "condition": {
    "resourceTypes": ["image"]
  }
},
{
  "id": 2,
  "priority": 2,
  "action": {
    "type": "allowAllRequests"
  },
  "condition": {
    "urlFilter": "yaraneba.com",
    "resourceTypes": ["main_frame"]
  }
}
]

id1では image のブロックルールを定義し、id2はホワイトリストとして作用させています。
id2の allowAllRequest を allow にして、resourceTypes を image にしても動作しそうですが、その場合、サードパーティの画像は許可されずにブロックされる様です。

逆に、ファーストパーティやサードパーティのみを許可・ブロックしたい場合は、"domainType": "firstParty"または"thirtParty"として定義する事が出来ます。
ここでは image を対象にしていますが、resourceType に script 等を指定してブロックする事も出来ます。

有効/無効を切り替える

ブロックを一時的に解除したい時等の為に有効/無効を切り替えるボタンが有ると便利です。
単純に切り替えるだけなら permissions に読み書きの権限を与える事無く declarativeNetRequest API を使って作れます。

有効/無効ボタン用に新たに popup.html と popup.js ファイルを用意します。
オプションページでも良いですが、今回はアクセスが簡単なポップアップページで作って行きます。

manifest.json

manifest.json にポップアップページの記述を追加。


"action": {
  "default_popup": "popup.html",
  "default_title": "declarativeNetRequest extension"
},

途中に追加した場合は最後にカンマが必要です。

popup.html

popup.html ファイルを作り有効/無効を切り替えるボタンの作成をします。


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>declarativeNetRequest Option</title>
<style>
body{width: 250px}
</style>
</head>
<body>
<button type="button" id="on">有効にする</button>
<button type="button" id="off">無効にする</button>
<script src="popup.js"></script>
</body>
</html>

有効にするボタンと無効にするボタンを置いただけのコードです。
CSS は好みの問題なので割愛。body の幅だけ指定しています。

最後に読み込む popup.js ファイルのパスを指定しています。この場合は同じ階層にファイルを置いた場合です。

popup.js

declarativeNetRequest API を使って ruleset の有効/無効を切り替えるコードを記述します。


document.addEventListener('DOMContentLoaded', () => {
  document.getElementById('on').addEventListener('click', () => {
    chrome.declarativeNetRequest.updateEnabledRulesets({
      enableRulesetIds: ["ruleset_1"]
    });
  });
  document.getElementById('off').addEventListener('click', () => {
    chrome.declarativeNetRequest.updateEnabledRulesets({
      disableRulesetIds: ["ruleset_1"]
    });
  });
});

それぞれ popup.html の id="on" と "off" のボタンが押された時に "ruleset_1" の有効と無効が切り替わり、ブラウザを閉じても状態は保持されます。

因みにバッジ表示をするコードは


chrome.declarativeNetRequest.setExtensionActionOptions({
  displayActionCountAsBadgeText: true
});

無効にするには


chrome.declarativeNetRequest.setExtensionActionOptions({
  displayActionCountAsBadgeText: false
});

ruleset の有効/無効の状態はバッジ表示の有無で確認する事も出来ます。

storage を利用してdeclarativeNetRequest をショートカットキーで切り替える方法も参考に。

拡張機能として読み込ませる

Microsoft Edge の場合、拡張機能の管理ページを開き、「開発者モード」にチェックを入れて、上記作成した2つのファイルをフォルダに入れ、展開して読み込みから選択します。
構文エラーが出る時は何行目に問題が有るかも教えてくれるので修正して再度アップします。
Manifest v3 では、background の scripts 等の構文が入っているだけでインストールが弾かれます。

Edge はバージョン 87 の正式版でも読み込む事が出来ました。ただ、正式版でローカルの拡張を入れると警告がうるさいので dev 版等で利用する方が良いかもしれません。