PDF Viewer にて開いているPDFファイルを Mendeley へアップロードするChrome拡張機能を作りたかったのですが,調べた限りではタイトル通りの理由で難しいと思われたため断念しました.別の方法で開発中です.
調査した内容を備忘録を兼ねて共有します.
chrome.scripting.executeScript() が実行されない
PDF viewer で開いたページのHTMLソースにて <div id="viewer" class="pdfViewer">
というタグがあったので,これを利用して「拡張機能のアイコンをクリックしたら,現在開いているページが PDF viewer かどうかを判別できる機能」をまずは実装しようとしました.
chrome-extensions-samples や公式ドキュメントを参考に,以下のコードを記述しました.
src
├── manifest.json
└── background.js
{
(中略)
"manifest_version": 3,
"action": {},
"permissions": [
"activeTab",
"scripting"
],
"background": {
"service_worker": "background.js"
}
}
function isViewer() {
var divViewerElement = document.getElementById('viewer');
if (divViewerElement == null){
console.log("It's not viewer.");
return;
}
var isPdfViewer = divViewerElement.classList.contains('pdfViewer');
if (isPdfViewer) {
// open pdfviewer
console.log("It's pdf viewer.");
} else {
// not open pdfviewer
console.log("It's not pdf viewer.");
}
}
chrome.action.onClicked.addListener((tab) => {
console.log(tab.url);
console.log(tab.id);
chrome.scripting.executeScript({
target: { tabId: tab.id },
function: isViewer
});
});
これらのコードを拡張機能としてChromeへ追加し,右上に現れたアイコンをクリックしたところ,通常のページ (http://*/, https://*/) を開いた状態では想定通りコンソールに It's not viewer. と表示されました.
しかし,PDF Viewer によってページを開いた状態 (chrome-extension://*/) にてアイコンをクリックしたところ,コンソールに何も出力されないという問題が発生しました.
後のデバッグによりchrome.action.onClicked.addListener()
の発火自体は行われているのが判明したので,原因はchrome.scripting.executeScript()
にあると考えられます.
ServiceWorker のデバッグ
先述のコード (background.js) における console.log(tab.url)
とconsole.log(tab.id)
の実行結果は,Chromeの開発ツールに存在するコンソールからは出力されません.
一方現在 (2021年7月時点) のChrome拡張では,background.js は ServiceWorker の内部にて実行されているそうです.
なので,こちらの回答を参考にServiceWorkerのデバッグによるconsole.logの出力を試みたところ,通常のサイトを開いた状態と PDF Viewer を開いた状態で以下のように出力に差がありました.
Console: {"lineNumber":20,"message":"https://developer.chrome.com/docs/extensions/reference/tabs/#type-Tab","message_level":1,"sourceIdentifier":3,"sourceURL":"chrome-extension://ejopbekoomobchmbbmdjkpandfobpchl/background.js"}
Console: {"lineNumber":21,"message":"2431","message_level":1,"sourceIdentifier":3,"sourceURL":"chrome-extension://ejopbekoomobchmbbmdjkpandfobpchl/background.js"
Console: {"lineNumber":20,"message":"chrome-extension://oemmndcbldboiebfnladdacbdfmadadm/http://www.shikisensha.com/books2009.pdf","message_level":1,"sourceIdentifier":3,"sourceURL":"chrome-extension://ejopbekoomobchmbbmdjkpandfobpchl/background.js"}
Console: {"lineNumber":21,"message":"2039","message_level":1,"sourceIdentifier":3,"sourceURL":"chrome-extension://ejopbekoomobchmbbmdjkpandfobpchl/background.js"}
Console: {"lineNumber":0,"message":"Uncaught (in promise) Error: Cannot access a chrome-extension:// URL of different extension","message_level":3,"sourceIdentifier":1,"sourceURL":"chrome-extension://ejopbekoomobchmbbmdjkpandfobpchl/background.js"
2つの console.log
が実行されていることから,やはり chrome.action.onClicked.addListener()
の発火に問題はなさそうです.
原因は chrome.scripting.executeScript()
実行時のパーミッションにあると思われ,PDF Viewer を開いた状態での出力には "Uncaught (in promise) Error: Cannot access a chrome-extension:// URL of different extension"
とはっきり書かれていました.
試したこと① Extensions on chrome:// URLs の設定変更
こちらの回答によると, Chromeの設定ページ (chrome://*/) に対しては,Chromeの設定変更によってアクセスを許可できるそうです.
Extensions on chrome:// URLs
Enables running extensions on chrome:// URLs, where extensions explicitly request this permission. – Mac, Windows, Linux, Chrome OS, Android
セキュリティ的にはあまり良くないそうですが,試しに上記の設定を Enabled に変更して再度 ServiceWorker のデバッグを試みてみました.
# 拡張機能が chrome:// へアクセスできるようchromeの設定を変更
Console: {"lineNumber":20,"message":"chrome-extension://oemmndcbldboiebfnladdacbdfmadadm/http://www.shikisensha.com/nanok.pdf","message_level":1,"sourceIdentifier":3,"sourceURL":"chrome-extension://ejopbekoomobchmbbmdjkpandfobpchl/background.js"}
Console: {"lineNumber":21,"message":"229","message_level":1,"sourceIdentifier":3,"sourceURL":"chrome-extension://ejopbekoomobchmbbmdjkpandfobpchl/background.js"}
Console: {"lineNumber":0,"message":"Uncaught (in promise) Error: Cannot access contents of url \"chrome-extension://oemmndcbldboiebfnladdacbdfmadadm/http://www.shikisensha.com/nanok.pdf\". Extension manifest must request permission to access this host.","message_level":3,"sourceIdentifier":1,"sourceURL":"chrome-extension://ejopbekoomobchmbbmdjkpandfobpchl/background.js"}
すると Extension manifest must request permission to access this host.
と出力されたので,今度は manifest.json の内容を変更してみました.
試したこと② manifest.json の permission を変更
Manifest V3 の記法 を参考に,以下のように manifest.json を追記してみました.
{
(中略)
"permissions": [
"activeTab",
"scripting"
],
"host_permissions":[
"chrome-extension://*/",
"*://*/*/"
],
(中略)
}
しかし上記のように manifest.json を設定すると,Chromeに拡張機能を読み込ませる時点で以下のようなエラーが発生してしまいました.
manifest.json の "chrome-extension://*/"
の部分を "chrome://*/"
に変更した場合は,Chromeに拡張機能を読み込ませるのはできるのですが,ServiceWorker のデバッグを試したところ①と同様の出力結果となり,問題は解決しませんでした.
結論
以上のことから,chrome.scripting.executeScript による,異なった拡張機能 (chrome-extension://*/) へのアクセスは(多分)できないと思われます.
もし他に何か知っている方がいましたら,教えて頂けると幸いです.
補足 (2021/07/08)
スペルミス (編集前: chrome-extentions:// -> 編集後: chrome-extension://) を直したうえで再度デバッグしましたが,出力結果は変わりませんでした.
開発環境
Chrome 91.0