カテゴリー
JavaScript

Chrome Extensionを作ってみた

Chrome Extensionを作る機会があったので、書きとめておきます。

まずはプロジェクトフォルダを作成し、manifest.jsonというJSONファイルを作成します。このファイルはフォルダのrootに置く必要があります。なお、このJSONファイル内のコメントはChrome Web Storeにアップロードする前に削除する必要があります。

このJSONファイルの必須Keyは”manifest_version”、”name”、”version”の三つです。

その他の色々なアクション、JacvaScriptファイルやアイコン画像の在りか(path)についてもここに記述します。

“background” 内の”service_worker”はTabに表示されるWeb pageとは関係なく実行されるJavaScriptを記述し、”content_scripts”はTabに表示されるWeb pageを操作するためのJavaScriptを記述します。”run_at”はこのscriptが実行されるタイミングを指定します。”document_start”, “document_end”, “document_idle”の三つから選択します。

manifestの仕様

// manifest.json
{
    "manifest_version" : 3,
    "name" : "Save The Word",
    "version" : "1.0",
    "description" : "A word saving app",

    // background works separate from the web page loaded in the tab
    "background" : {
        "service_worker" : "scripts/background.js"
    },

  // content_scripts works to interact and manipulate the web page loaded in the tab
    "content_scripts" : [
        {
            "js" : ["scripts/content.js"],
            "run_at" : "document_idle",
            "matches" : [
                "<all_urls>"
            ]
        }
    ]
}
// scripts/content.js

console.log("hello");

chrome://extensions/にアクセスし、Developer modeをオン、Load unpackedからプロジェクトフォルダを読み込むと、https://から始まるあらゆるサイトを読み込む時に、ブラウザのコンソールに”hello”がプリントされると、content.jsが上手く読み込まれていることが確認出来ます。

Web page内のテキストを右クリックすると、chromeのcontext menuにextensionが表示され、そのテキストを使って何かをするためのコードは以下。

var menus = {
    "Save" : "Save",
    "Copy" : "Copy"
};

chrome.runtime.onInstalled.addListener( () => {
    for(let key of Object.keys(menus)) {
        chrome.contextMenus.create({
            id: key,
            title: key,
            type: "normal",
            contexts: ["selection"]
        });
    }
});

chrome.contextMenus.onClicked.addListener( (item, tab) => {
    const text = item.selectionText;
    console.log(text);
});

selectionTextの周囲の文章もゲットしたい場合は、DOMを操作できるcontent_scriptへメッセージを送りたいため、以下のようにします。ちなみに、content_scriptからbackgroundへ送る場合はchrome.runtime APIを使いますが、backgroundからcontent_scriptへ送る場合はchrome.tab APIを使ってtabを指定する必要があります。公式document

// in background.js
chrome.contextMenus.onClicked.addListener(function(item, tab){
    const text = item.selectionText;
    chrome.tabs.sendMessage(tab.id, { greeting: text });
});

// in content.js
chrome.runtime.onMessage.addListener( (request, sender, sendResponse) => {
    console.log("selected word: ", request.greeting);
    console.log("selected context: ", window.getSelection().anchorNode.data);
});

service_workerのコンソールの表示はこちらをクリック