Initial commit
This commit is contained in:
commit
4ae6b27809
4 changed files with 137 additions and 0 deletions
13
background.js
Normal file
13
background.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
browser.action.onClicked.addListener((tab) => {
|
||||
// Inject the CSS for the hover highlight
|
||||
browser.scripting.insertCSS({
|
||||
target: { tabId: tab.id },
|
||||
files: ["content.css"]
|
||||
});
|
||||
|
||||
// Inject the JavaScript for the element picker
|
||||
browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
files: ["content.js"]
|
||||
});
|
||||
});
|
||||
6
content.css
Normal file
6
content.css
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
.pep-hover-highlight {
|
||||
outline: 3px dashed #0088ff !important;
|
||||
outline-offset: -3px !important;
|
||||
cursor: crosshair !important;
|
||||
background-color: rgba(0, 136, 255, 0.1) !important;
|
||||
}
|
||||
100
content.js
Normal file
100
content.js
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
(function() {
|
||||
if (window.pepActive) return;
|
||||
window.pepActive = true;
|
||||
|
||||
let currentHovered = null;
|
||||
|
||||
function handleMouseOver(e) {
|
||||
e.stopPropagation();
|
||||
if (currentHovered) {
|
||||
currentHovered.classList.remove('pep-hover-highlight');
|
||||
}
|
||||
currentHovered = e.target;
|
||||
currentHovered.classList.add('pep-hover-highlight');
|
||||
}
|
||||
|
||||
function handleMouseOut(e) {
|
||||
e.stopPropagation();
|
||||
if (currentHovered) {
|
||||
currentHovered.classList.remove('pep-hover-highlight');
|
||||
currentHovered = null;
|
||||
}
|
||||
}
|
||||
|
||||
function handleClick(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
// Turn off picker mode
|
||||
document.removeEventListener('mouseover', handleMouseOver, true);
|
||||
document.removeEventListener('mouseout', handleMouseOut, true);
|
||||
document.removeEventListener('click', handleClick, true);
|
||||
window.pepActive = false;
|
||||
|
||||
if (currentHovered) {
|
||||
currentHovered.classList.remove('pep-hover-highlight');
|
||||
printElement(currentHovered);
|
||||
}
|
||||
}
|
||||
|
||||
function printElement(el) {
|
||||
el.classList.add('pep-print-target');
|
||||
|
||||
// Walk up the DOM tree to tag all ancestors of the target
|
||||
let current = el.parentElement;
|
||||
const ancestors = [];
|
||||
while (current && current !== document.body && current !== document.documentElement) {
|
||||
current.classList.add('pep-print-ancestor');
|
||||
ancestors.push(current);
|
||||
current = current.parentElement;
|
||||
}
|
||||
|
||||
// Inject CSS that hides siblings of the target and siblings of its ancestors
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
@media print {
|
||||
/* Hide all siblings of the body, ancestors, and target */
|
||||
body > *:not(.pep-print-ancestor):not(.pep-print-target),
|
||||
.pep-print-ancestor > *:not(.pep-print-ancestor):not(.pep-print-target) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Strip formatting from ancestors to prevent them from pushing the target around */
|
||||
.pep-print-ancestor {
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
border: none !important;
|
||||
background: transparent !important;
|
||||
box-shadow: none !important;
|
||||
position: static !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
/* Reset body constraints */
|
||||
body {
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
min-height: 100vh !important;
|
||||
}
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
// Short delay to ensure browser applies the print CSS before opening dialog
|
||||
setTimeout(() => {
|
||||
window.print();
|
||||
|
||||
// Clean up the temporary styles and classes after the print dialog closes
|
||||
setTimeout(() => {
|
||||
el.classList.remove('pep-print-target');
|
||||
ancestors.forEach(a => a.classList.remove('pep-print-ancestor'));
|
||||
style.remove();
|
||||
}, 1000);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// Activate event listeners in the capture phase to override default page behaviors
|
||||
document.addEventListener('mouseover', handleMouseOver, true);
|
||||
document.addEventListener('mouseout', handleMouseOut, true);
|
||||
document.addEventListener('click', handleClick, true);
|
||||
})();
|
||||
18
manifest.json
Normal file
18
manifest.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Print Element Picker",
|
||||
"version": "1.0",
|
||||
"description": "Interactively pick an element on the page and print only that element.",
|
||||
"permissions": ["activeTab", "scripting"],
|
||||
"action": {
|
||||
"default_title": "Pick element to print"
|
||||
},
|
||||
"background": {
|
||||
"scripts": ["background.js"]
|
||||
},
|
||||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
"id": "print-picker@yourdomain.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue