100 lines
3.1 KiB
JavaScript
100 lines
3.1 KiB
JavaScript
(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);
|
|
})();
|