historyOverride sample for mv3 (#945)

* Add historyOverride sample

* Remove action

* Add README.md

* Remove IIFE

* Update style

* Fix double click
This commit is contained in:
Xuezhou Dai
2023-07-07 22:35:03 +08:00
committed by GitHub
parent 0af7b5132d
commit b4a018418d
9 changed files with 245 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
# chrome.history - History Override
A sample that demonstrates how to override the default history page.
## Overview
Once this extension is installed, `chrome://history` will be overridden by the extension's custom page.
## Running this extension
1. Clone this repository.
2. Load this directory in Chrome as an [unpacked extension](https://developer.chrome.com/docs/extensions/mv3/getstarted/development-basics/#load-unpacked).
3. Open `chrome://history` and you will find the custom history page.

View File

@@ -0,0 +1,43 @@
<html>
<head>
<title>History</title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<div id="searchbar">
<h1>
Custom History Page
<br />
<small>Only show the history within one week.</small>
</h1>
<input
id="searchInput"
type="text"
name="search"
placeholder="Search History"
/>
<input type="submit" id="searchSubmit" value="Search" />
<input type="submit" id="deleteSelected" value="Remove Selected" />
<input type="submit" id="removeAll" value="Remove All" />
</div>
<div id="historyDiv"></div>
<template id="historyTemplate">
<div class="history">
<div class="image-wrapper"></div>
<div class="page-meta">
<div class="page-detail">
<p class="page-title"></p>
<a class="page-link" target="_blank"></a>
</div>
<div class="page-visit-time"></div>
</div>
<div class="actions">
<input type="checkbox" class="removeCheck" />
<button class="removeButton">remove</button>
</div>
</div>
</template>
<script src="logic.js"></script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 458 B

View File

@@ -0,0 +1,85 @@
const kMillisecondsPerWeek = 1000 * 60 * 60 * 24 * 7;
const kOneWeekAgo = new Date().getTime() - kMillisecondsPerWeek;
const historyDiv = document.getElementById('historyDiv');
function faviconURL(u) {
const url = new URL(chrome.runtime.getURL('/_favicon/'));
url.searchParams.set('pageUrl', u);
url.searchParams.set('size', '24');
return url.toString();
}
function constructHistory(historyItems) {
const template = document.getElementById('historyTemplate');
for (let item of historyItems) {
const clone = document.importNode(template.content, true);
const pageLinkEl = clone.querySelector('.page-link');
const pageTitleEl = clone.querySelector('.page-title');
const pageVisitTimeEl = clone.querySelector('.page-visit-time');
const imageWrapperEl = clone.querySelector('.image-wrapper');
const checkbox = clone.querySelector('.removeCheck, input');
checkbox.setAttribute('value', item.url);
const favicon = document.createElement('img');
pageLinkEl.href = item.url;
favicon.src = faviconURL(item.url);
pageLinkEl.textContent = item.url;
imageWrapperEl.prepend(favicon);
pageVisitTimeEl.textContent = new Date(item.lastVisitTime).toLocaleString();
if (!item.title) {
pageTitleEl.style.display = 'none';
}
pageTitleEl.innerText = item.title;
clone
.querySelector('.removeButton, button')
.addEventListener('click', async function () {
await chrome.history.deleteUrl({ url: item.url });
location.reload();
});
clone
.querySelector('.history')
.addEventListener('click', async function (event) {
// fix double click
if (event.target.className === 'removeCheck') {
return;
}
checkbox.checked = !checkbox.checked;
});
historyDiv.appendChild(clone);
}
}
document.getElementById('searchSubmit').onclick = async function () {
historyDiv.innerHTML = ' ';
const searchQuery = document.getElementById('searchInput').value;
const historyItems = await chrome.history.search({
text: searchQuery,
startTime: kOneWeekAgo
});
constructHistory(historyItems);
};
document.getElementById('deleteSelected').onclick = async function () {
const checkboxes = document.getElementsByTagName('input');
for (let checkbox of checkboxes) {
if (checkbox.checked == true) {
await chrome.history.deleteUrl({ url: checkbox.value });
}
}
location.reload();
};
document.getElementById('removeAll').onclick = async function () {
await chrome.history.deleteAll();
location.reload();
};
chrome.history
.search({
text: '',
startTime: kOneWeekAgo,
maxResults: 99
})
.then(constructHistory);

View File

@@ -0,0 +1,16 @@
{
"manifest_version": 3,
"name": "History Override",
"description": "Overrides the History Page",
"version": "1.0",
"chrome_url_overrides": {
"history": "history.html"
},
"permissions": ["history", "favicon"],
"icons": {
"16": "history16.png",
"32": "history32.png",
"48": "history48.png",
"128": "history128.png"
}
}

View File

@@ -0,0 +1,88 @@
small {
font-size: 12px;
font-weight: normal;
}
#historyDiv {
margin-top: 10px;
display: flex;
flex-direction: column;
gap: 10px;
max-width: 1000px;
}
.history {
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.2);
border-radius: 10px;
display: flex;
height: 60px;
padding: 10px;
cursor: pointer;
}
.image-wrapper {
width: 24px;
height: 100%;
margin-right: 10px;
flex-grow: 0;
flex-shrink: 0;
}
.image-wrapper img {
width: 100%;
}
.page-meta {
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
max-width: calc(100% - 180px);
}
.page-title {
font-weight: bold;
font-size: 0.8rem;
}
.page-detail {
display: flex;
flex-direction: column;
align-items: start;
}
.page-link,
.page-title {
overflow: hidden;
white-space: nowrap;
max-width: 100%;
display: inline-block;
text-overflow: ellipsis;
margin: 0;
}
.page-link {
font-size: 0.8rem;
color: #8c8c8c;
}
.page-link:hover {
color: #000;
}
.page-visit-time {
font-size: 0.8rem;
color: #a5a5a5;
}
.actions {
flex-grow: 0;
flex-shrink: 0;
display: flex;
flex-grow: 1;
flex-shrink: 0;
flex-direction: column;
justify-content: space-between;
align-items: end;
gap: 5px;
}