[chrome拡張機能]TabRenamer

できること

  • ブラウザ上のタブのリネームを行う
  • 画面更新をしてもタブを閉じない限り、リネームは保持される
  • ブラウザ上に公開されているものでなく自作です
  • Ctrl + Qでリネームの小窓を表示し、Enterでリネームを確定させる

manifest.json

{
    "manifest_version": 3
    , "version": "0.1.0"
    , "name": "TabRenamer"
    , "description": "ブラウザのタブをCtrl+Qでリネームします"
    , "background": {
        "service_worker": "background.js"
        , "type": "module"
    }
    , "action": {
        "default_title": "Tab Namer"
        , "default_popup": "popup.html"
    }
    , "permissions": [
        "scripting"
        , "tabs"
        , "storage"
    ]
    , "host_permissions": [
        "http://*/"
        , "https://*/"
    ]
}

popup.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="popup.js" defer></script>
</head>
  <body>
    <label>タブ名</label>
    <input type="text" id="tab-name-text" value="" autofocus/>
    <input type="button" id="rename-button" value="rename" />
  </body>
</html>

 popup.css


(() => {

    const button = document.querySelector("#rename-button");
    const text = document.querySelector('#tab-name-text');
    // イベント:変更ボタン押下時
    button.addEventListener("click", async () => {
        await renameTab();
    });
    // イベント:Enter押下時
    text.addEventListener("keydown", async (e) => {
        if (e.key === 'Enter') {
            await renameTab();
        }
    })

    /**
     * リネーム処理
     */
    async function renameTab() {
        const newTabName = text.value.trim();
        if (!newTabName) {
            return;
        }
        const tab = await getCurrentTab();
        await setMemory(tab.id, newTabName);
        // コンテンツへ処理を依頼
        chrome.scripting.executeScript(
        {
            target: { tabId: tab.id }
            , func: (tabName) => { document.title = tabName; }
            , args: [newTabName]
        });
    }

    /**
     * ローカルストレージにデータを保存する
     */
    async function setMemory(key, value) {
        let renamedTabs = await getMemory();
        renamedTabs ??= {};
        renamedTabs[key] = value;
        await chrome.storage.local.set({ renamedTabs });
        // console.log(`save: tabId:${key}, name:${value}`);
    }

    /**
     * ローカルストレージからデータを取得する
     */
    async function getMemory() {
        // get()は{key:value}で取得されるため、valueのみ返却する
        return (await chrome.storage.local.get('renamedTabs'))?.renamedTabs;
    }

    /**
     * 現在のタブを取得する
     */
    async function getCurrentTab() {
        let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
        // console.log("アクティブなタブID:", tab.id, "タイトル:", tab.title, "URL:", tab.url);
        return tab;
    }
})();

background.js

/**
 * ページ表示イベント
 */
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
    // ページ表示が完了したら
    if (changeInfo.status === 'complete') {
        renameTab(tab);
    }
});

/**
 * ユーザーがそのタブをリネーム済みであれば
 * 画面更新されるたびに、リネームする
 */
async function renameTab(tab) {
    chrome.storage.local.get('renamedTabs', (value) => {
        const renamedTabs = value?.renamedTabs;
        if (renamedTabs && tab.id in renamedTabs) {
            // コンテンツへ処理を依頼
            chrome.scripting.executeScript(
            {
                target: { tabId: tab.id }
                , func: (tabName) => { document.title = tabName; }
                , args: [renamedTabs[tab.id]]
            });
        }
    });
}