Skip to content

Commit

Permalink
historyOverride sample for mv3 (GoogleChrome#945)
Browse files Browse the repository at this point in the history
* Add historyOverride sample

* Remove action

* Add README.md

* Remove IIFE

* Update style

* Fix double click
  • Loading branch information
daidr authored Jul 7, 2023
1 parent 0af7b51 commit b4a0184
Show file tree
Hide file tree
Showing 9 changed files with 245 additions and 0 deletions.
13 changes: 13 additions & 0 deletions api-samples/history/historyOverride/README.md
Original file line number Diff line number Diff line change
@@ -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 changes: 43 additions & 0 deletions api-samples/history/historyOverride/history.html
Original file line number Diff line number Diff line change
@@ -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>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added api-samples/history/historyOverride/history16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added api-samples/history/historyOverride/history32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added api-samples/history/historyOverride/history48.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
85 changes: 85 additions & 0 deletions api-samples/history/historyOverride/logic.js
Original file line number Diff line number Diff line change
@@ -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 changes: 16 additions & 0 deletions api-samples/history/historyOverride/manifest.json
Original file line number Diff line number Diff line change
@@ -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 changes: 88 additions & 0 deletions api-samples/history/historyOverride/style.css
Original file line number Diff line number Diff line change
@@ -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;
}

0 comments on commit b4a0184

Please sign in to comment.