100 lines
2.8 KiB
JavaScript
100 lines
2.8 KiB
JavaScript
// ==UserScript==
|
|
// @name Link URL Tooltip
|
|
// @namespace https://github.com/kalekber/libnovel-v2
|
|
// @version 1.0.0
|
|
// @description Show the destination URL near the cursor when hovering over any link
|
|
// @author kalekber
|
|
// @match *://*/*
|
|
// @run-at document-idle
|
|
// @grant none
|
|
// ==/UserScript==
|
|
|
|
(function () {
|
|
'use strict';
|
|
|
|
// --- Inject styles ---
|
|
const style = document.createElement('style');
|
|
style.textContent = `
|
|
#lnk-tooltip {
|
|
position: fixed;
|
|
display: none;
|
|
background-color: #333;
|
|
color: #fff;
|
|
padding: 5px 10px;
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
font-family: monospace;
|
|
pointer-events: none;
|
|
z-index: 2147483647;
|
|
white-space: nowrap;
|
|
max-width: 600px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
box-shadow: 0 2px 6px rgba(0,0,0,0.4);
|
|
}
|
|
`;
|
|
document.head.appendChild(style);
|
|
|
|
// --- Inject tooltip element ---
|
|
const tooltip = document.createElement('div');
|
|
tooltip.id = 'lnk-tooltip';
|
|
document.body.appendChild(tooltip);
|
|
|
|
// --- Helpers ---
|
|
function getAnchor(target) {
|
|
// Walk up the DOM to find the nearest <a href="...">
|
|
// (handles clicks on nested elements like <a><span>text</span></a>)
|
|
return target.closest('a[href]');
|
|
}
|
|
|
|
function show(anchor, clientX, clientY) {
|
|
tooltip.textContent = anchor.href;
|
|
tooltip.style.display = 'block';
|
|
position(clientX, clientY);
|
|
}
|
|
|
|
function hide() {
|
|
tooltip.style.display = 'none';
|
|
}
|
|
|
|
function position(clientX, clientY) {
|
|
const offset = 12;
|
|
const tw = tooltip.offsetWidth;
|
|
const th = tooltip.offsetHeight;
|
|
const vw = window.innerWidth;
|
|
const vh = window.innerHeight;
|
|
|
|
let x = clientX + offset;
|
|
let y = clientY + offset;
|
|
|
|
// Flip horizontally if it would overflow the right edge
|
|
if (x + tw > vw - 4) {
|
|
x = clientX - tw - offset;
|
|
}
|
|
// Flip vertically if it would overflow the bottom edge
|
|
if (y + th > vh - 4) {
|
|
y = clientY - th - offset;
|
|
}
|
|
|
|
tooltip.style.left = Math.max(0, x) + 'px';
|
|
tooltip.style.top = Math.max(0, y) + 'px';
|
|
}
|
|
|
|
// --- Event delegation on document ---
|
|
document.addEventListener('mouseover', (e) => {
|
|
const anchor = getAnchor(e.target);
|
|
if (anchor) show(anchor, e.clientX, e.clientY);
|
|
});
|
|
|
|
document.addEventListener('mousemove', (e) => {
|
|
if (tooltip.style.display === 'block') {
|
|
position(e.clientX, e.clientY);
|
|
}
|
|
});
|
|
|
|
document.addEventListener('mouseout', (e) => {
|
|
const anchor = getAnchor(e.target);
|
|
if (anchor) hide();
|
|
});
|
|
})();
|