mirror of
https://github.com/GoogleChrome/chrome-extensions-samples.git
synced 2026-03-26 13:19:49 +07:00
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:
13
api-samples/history/historyOverride/README.md
Normal file
13
api-samples/history/historyOverride/README.md
Normal 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.
|
||||
43
api-samples/history/historyOverride/history.html
Normal file
43
api-samples/history/historyOverride/history.html
Normal 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>
|
||||
BIN
api-samples/history/historyOverride/history128.png
Normal file
BIN
api-samples/history/historyOverride/history128.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
BIN
api-samples/history/historyOverride/history16.png
Normal file
BIN
api-samples/history/historyOverride/history16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 276 B |
BIN
api-samples/history/historyOverride/history32.png
Normal file
BIN
api-samples/history/historyOverride/history32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 360 B |
BIN
api-samples/history/historyOverride/history48.png
Normal file
BIN
api-samples/history/historyOverride/history48.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 458 B |
85
api-samples/history/historyOverride/logic.js
Normal file
85
api-samples/history/historyOverride/logic.js
Normal 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);
|
||||
16
api-samples/history/historyOverride/manifest.json
Normal file
16
api-samples/history/historyOverride/manifest.json
Normal 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"
|
||||
}
|
||||
}
|
||||
88
api-samples/history/historyOverride/style.css
Normal file
88
api-samples/history/historyOverride/style.css
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user