Skip to content

Highlights Manager

This Extension allows you to save highlights made by a user on a page, save them to state in extension background script and display them in a Popup window.

  • Directoryhighlights-manager-extension
    • manifest.json
    • content.js
    • popup.html
    • popup.js
    • background.js
{
"manifest_version": 3,
"name": "Highlights Manager",
"version": "1.0",
"background": {
"service_worker": "background.js"
},
"action": {
"default_popup": "popup.html"
},
"content_scripts": [
{
"js": ["content.js"]
}
]
}
let lastSelection = '';
document.addEventListener('mouseup', () => {
const selection = window.getSelection().toString().trim();
if (selection && selection !== lastSelection) {
lastSelection = selection;
browser.runtime.sendMessage({ type: 'saveSelection', text: selection });
showNotification('Saved to Highlights Manager');
}
});
function showNotification(message) {
// Avoid stacking: remove existing
const existing = document.getElementById('highlights-ext-notification');
if (existing) existing.remove();
const div = document.createElement('span');
div.id = 'highlights-ext-notification';
div.textContent = message;
Object.assign(div.style, {
position: 'fixed',
bottom: '20px',
right: '20px',
background: 'rgba(0,0,0,0.8)',
color: 'white',
padding: '8px 12px',
borderRadius: '6px',
fontSize: '14px',
zIndex: '999999',
fontFamily: 'sans-serif',
display: 'inline-block',
});
document.body.appendChild(div);
setTimeout(() => {
div.remove();
}, 3000);
}
<!DOCTYPE html>
<html>
<head>
<title>Highlights Manager</title>
<style>
body { font-family: sans-serif; padding: 10px; }
header {
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
#list { margin-top: 10px; }
.entry {
padding: 4px;
border-bottom: 1px solid #ddd;
display: flex;
justify-content: space-between;
align-items: center;
}
button { margin-left: 4px; }
</style>
</head>
<body>
<header>
<h3>Highlights Manager</h3>
<button id="clearBtn">Clear All</button>
</header>
<div id="list"></div>
<script src="popup.js"></script>
</body>
</html>
const list = document.getElementById('list');
function render(items) {
list.innerHTML = '';
if (items.length === 0) {
list.innerHTML = '<p><i>No entries yet</i></p>';
return;
}
items.forEach((text, index) => {
const div = document.createElement('div');
div.className = 'entry';
const span = document.createElement('span');
span.textContent = text;
const deleteBtn = document.createElement('button');
deleteBtn.textContent = 'X';
deleteBtn.onclick = () => {
browser.runtime.sendMessage({ type: 'deleteEntry', index });
};
div.appendChild(span);
div.appendChild(deleteBtn);
list.appendChild(div);
});
}
browser.runtime.onMessage.addListener((messageData, sender) => {
if (messageData.type === 'receiveHighlights' && messageData.to === 'popup' && sender.name === 'background') {
render(messageData.items);
}
});
function refresh() {
browser.runtime.sendMessage({ type: 'getHighlights' });
}
document.getElementById('clearBtn').onclick = () => {
browser.runtime.sendMessage({ type: 'clearAll' });
};
// Load state on popup open
browser.browserAction.resizePopup(600, 300);
refresh();
let highlightsState = [];
function addToHighlights(text) {
highlightsState.unshift(text.trim());
if (highlightsState.length > 10) highlightsState.pop();
}
const highlightsEvents = ['getHighlights', 'saveSelection', 'clearAll', 'deleteEntry'];
browser.runtime.onMessage.addListener((msg, sender, sendResponse) => {
if (!highlightsEvents.includes(msg.type)) {
return;
}
if (msg.type === 'saveSelection' && msg.text) {
addToHighlights(msg.text);
} else if (msg.type === 'clearAll') {
highlightsState = [];
} else if (msg.type === 'deleteEntry' && msg.index > -1) {
highlightsState.splice(msg.index, 1);
}
browser.runtime.sendMessage({type: 'receiveHighlights', to: 'popup', items: highlightsState});
});
  • Listening for messages in various extension components:
    • The extension components utilize the browser.runtime.onMessage.addListener() method to listen for various events from the extension.
browser.runtime.onMessage.addListener();
  • Sending Messages to the extension components:
    • The extension components utilize the browser.runtime.sendMessage() method to send a message to the popup html (and any other extension component).
browser.runtime.sendMessage();
  • Keeping state in the background script and manipulateing it via messages from various extension components:
highlightsState = [];
  • Including the popup.js script in the popup.html file with a regular script tag:
<script src="popup.js"></script>