できること
- ブラウザ上のタブのリネームを行う
- 画面更新をしてもタブを閉じない限り、リネームは保持される
- ブラウザ上に公開されているものでなく自作です
- 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]]
});
}
});
}