2024/08/29

特定URLだけをChromeの履歴から自動で消去する拡張機能作った

RSSリーダーのfeedly.comで閲覧すると、このような感じにズラッと履歴を占有してしまうので何とかしたい…と思って入れていたのがHistory Blacklistという拡張機能。
ですが残念なことにManifest V3に対応しておらず、代わりの拡張機能も見つからずで困り果てたので、ChatGPTさんに作って貰いました。
作りは最小限しかなくアイコンさえもないので、ちゃんと作ってストアに提出する気もないのですが、とりあえず作った記念でアップ。



・追記:設定オプションを表示するpopup.html,popup.jsが抜けていましたので追加…ChatGPTさん…。
ダウンロード履歴の消去オプションも追加。
・追記2:ダウンロード中に指定時間が来てしまうとダウンロードがキャンセルされる問題。→ダウンロード中は消去しない仕様にしました。

この下の続きもChatGPTさんが著者ですw


今回は、指定したURLに関連するブラウザの履歴を自動的に削除するカスタムChrome拡張機能の設定と使い方をご紹介します。この拡張機能は、消去間隔を1分から1440分までの範囲でユーザーが設定できるように設計されています。

拡張機能のインストール方法

まず、以下の手順に従って、Chrome拡張機能をローカルでインストールします。

  1. ファイルの準備:

    以下のファイルを作成し、任意のフォルダに保存します。

    • manifest.json
    • background.js
    • options.html
    • options.js
    • popup.html
    • popup.js
  2. 拡張機能管理ページにアクセス:

    Chromeを開き、アドレスバーに chrome://extensions/ と入力してアクセスします。右上の「デベロッパーモード」をオンにします。

  3. パッケージ化されていない拡張機能を読み込む:

    「パッケージ化されていない拡張機能を読み込む」をクリックし、保存したフォルダを選択します。

コード例

ここでは、各ファイルのコード例を紹介します。

manifest.json

{
"manifest_version": 3,
"name": "URL and Download History Cleaner",
"version": "1.1",
"permissions": [
"history",
"storage",
"alarms",
"downloads"
],
"background": {
"service_worker": "background.js"
},
"options_page": "options.html",
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"action": {
"default_icon": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"default_popup": "popup.html"
}
}

background.js

// 初期化およびオプション変更時にアラームを設定
chrome.runtime.onInstalled.addListener(() => {
setAlarm();
});

chrome.runtime.onStartup.addListener(() => {
setAlarm(); // ブラウザ起動時にアラームを再設定
});

chrome.runtime.onMessage.addListener((message) => {
if (message.action === "updateAlarm") {
setAlarm();
}
});

function setAlarm() {
chrome.storage.sync.get('interval', function (result) {
const interval = result.interval || 1; // デフォルトで1分
chrome.alarms.clearAll(() => {
chrome.alarms.create('deleteHistoryAlarm', { periodInMinutes: interval });
});
});
}

chrome.alarms.onAlarm.addListener(function(alarm) {
if (alarm.name === 'deleteHistoryAlarm') {
deleteCustomUrlsHistory();
deleteDownloadHistory(); // ダウンロード履歴も削除
}
});

// ユーザーが登録したURLに基づいて履歴を削除する関数
function deleteCustomUrlsHistory() {
chrome.storage.sync.get(['urls'], function (result) {
const urls = result.urls || [];
urls.forEach(function (url) {
chrome.history.search({ text: url, maxResults: 100 }, function(results) {
results.forEach(function(item) {
chrome.history.deleteUrl({ url: item.url });
});
});
});
});
}

// ダウンロード履歴を削除する関数
function deleteDownloadHistory() {
chrome.storage.sync.get('clearDownloads', function (result) {
if (result.clearDownloads) {
// ダウンロード中のアイテムがないか確認
chrome.downloads.search({ state: "in_progress" }, function (items) {
if (items.length === 0) {
// ダウンロード中のアイテムがない場合に履歴を削除
chrome.downloads.erase({}, function() {
console.log('Download history deleted.');
});
} else {
console.log('Downloads in progress. Skipping deletion.');
}
});
}
});
}

options.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Options - URL and Download History Cleaner</title>
<style>
body {
font-family: Arial, sans-serif;
padding: 10px;
}
ul {
list-style-type: none;
padding: 0;
}
li {
margin-bottom: 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
button.delete-btn {
background-color: #e74c3c;
color: white;
border: none;
padding: 5px 10px;
cursor: pointer;
}
button.delete-btn:hover {
background-color: #c0392b;
}
</style>
</head>
<body>
<h1>Manage URLs to Clean</h1>
<input type="text" id="urlInput" placeholder="Enter URL or domain (e.g., example.com)" style="width: 100%;">
<button id="addUrlButton">Add URL</button>
<ul id="urlList"></ul>

<h2>Set Cleaning Interval</h2>
<input type="number" id="intervalInput" placeholder="Enter interval in minutes" style="width: 100%;">
<br><br>
<label>
<input type="checkbox" id="downloadToggle">
Clear download history
</label>

<br><br> <!-- ボタン間のスペース追加 -->

<button id="saveButton">Save Changes</button>

<script src="options.js"></script>
</body>
</html>

options.js

document.addEventListener('DOMContentLoaded', function () {
const urlInput = document.getElementById('urlInput');
const urlList = document.getElementById('urlList');
const intervalInput = document.getElementById('intervalInput');
const downloadToggle = document.getElementById('downloadToggle');
const saveButton = document.getElementById('saveButton');

// 既存のURLリストとインターバル、ダウンロード設定を表示
chrome.storage.sync.get(['urls', 'interval', 'clearDownloads'], function (result) {
const urls = result.urls || [];
const interval = result.interval || 1;
const clearDownloads = result.clearDownloads || false;

urls.forEach(function (url) {
addUrlToList(url);
});

intervalInput.value = interval;
downloadToggle.checked = clearDownloads;
});

// URLをリストに追加
document.getElementById('addUrlButton').addEventListener('click', function () {
const url = urlInput.value.trim();
if (url) {
addUrlToList(url);
urlInput.value = '';
}
});

// 設定を保存
saveButton.addEventListener('click', function () {
const urls = [];
document.querySelectorAll('#urlList li span.url-text').forEach(function (span) {
urls.push(span.textContent);
});

const interval = parseInt(intervalInput.value, 10);
const clearDownloads = downloadToggle.checked;

// インターバルのバリデーション
if (isNaN(interval) || interval < 1 || interval > 1440) {
alert('Please enter a valid interval between 1 and 1440 minutes.');
return;
}

// 保存処理
chrome.storage.sync.set({ urls: urls, interval: interval, clearDownloads: clearDownloads });
chrome.runtime.sendMessage({ action: "updateAlarm" });
});

// リストにURLを追加
function addUrlToList(url) {
const li = document.createElement('li');
const span = document.createElement('span');
span.textContent = url;
span.className = 'url-text';
const deleteButton = document.createElement('button');
deleteButton.textContent = 'Delete';
deleteButton.className = 'delete-btn';

deleteButton.addEventListener('click', function () {
li.remove();
});

li.appendChild(span);
li.appendChild(deleteButton);
urlList.appendChild(li);
}
});

popup.js

document.addEventListener('DOMContentLoaded', function () {
const historyList = document.getElementById('history-list');

// 保存されたURLリストを取得
chrome.storage.sync.get('urls', function (result) {
const urls = result.urls || [];
let foundHistory = false; // 履歴が見つかったかどうかを追跡

if (urls.length === 0) {
const li = document.createElement('li');
li.textContent = 'No URLs saved.';
historyList.appendChild(li);
return;
}

// 各URLに対して履歴を検索
urls.forEach(function (url) {
chrome.history.search({ text: url, maxResults: 10 }, function (results) {
if (results.length > 0) {
results.forEach(function (item) {
const li = document.createElement('li');
const a = document.createElement('a');
a.href = item.url;
a.textContent = item.title || item.url;
a.target = '_blank';
li.appendChild(a);
historyList.appendChild(li);
foundHistory = true; // 履歴が見つかった
});
}

// 全ての検索が終わって、履歴がない場合にメッセージを表示
if (!foundHistory && urls.indexOf(url) === urls.length - 1) {
const li = document.createElement('li');
li.textContent = 'No history found';
historyList.appendChild(li);
}
});
});
});
});

popup.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>History</title>
<style>
body {
font-family: Arial, sans-serif;
padding: 10px;
width: 300px;
}
ul {
list-style-type: none;
padding: 0;
}
li {
margin-bottom: 10px;
}
</style>
</head>
<body>
<ul id="history-list"></ul>
<script src="popup.js"></script>
</body>
</html>

icons

各画像を他のファイルと同階層に作ったiconsという名前のフォルダに
ファイル名を小さい方から以下の名前で保存します。
icon16.png
icon48.png
icon128.png




おわりに

この拡張機能を使用することで、指定したURLに関連する履歴を自動的に削除し、ブラウジング体験をより安全かつプライバシーに配慮したものにすることができます。必要に応じて、インターバルを調整して、自分に最適な設定を見つけてください。