109 lines
4.4 KiB
JavaScript
109 lines
4.4 KiB
JavaScript
|
// ==UserScript==
|
||
|
// @name Hacker News URL Highlighter with Preview
|
||
|
// @namespace https://news.ycombinator.com/
|
||
|
// @version 1.3
|
||
|
// @description Highlights URLs in comments on Hacker News, lists them in a panel, and provides export functionality. Hover previews only in comments.
|
||
|
// @author MorganGeek
|
||
|
// @match https://news.ycombinator.com/item?id=*
|
||
|
// @grant GM_xmlhttpRequest
|
||
|
// @grant GM_setClipboard
|
||
|
// @connect *
|
||
|
// @run-at document-end
|
||
|
// ==/UserScript==
|
||
|
|
||
|
(function () {
|
||
|
'use strict';
|
||
|
|
||
|
// Create a floating panel for displaying URLs
|
||
|
const panel = document.createElement('div');
|
||
|
panel.id = 'url-panel';
|
||
|
panel.style.position = 'fixed';
|
||
|
panel.style.top = '10px';
|
||
|
panel.style.right = '10px';
|
||
|
panel.style.backgroundColor = '#fff';
|
||
|
panel.style.border = '1px solid #ccc';
|
||
|
panel.style.borderRadius = '5px';
|
||
|
panel.style.padding = '10px';
|
||
|
panel.style.boxShadow = '0px 0px 10px rgba(0,0,0,0.2)';
|
||
|
panel.style.maxHeight = '80vh';
|
||
|
panel.style.overflowY = 'auto';
|
||
|
panel.style.zIndex = 1000;
|
||
|
panel.innerHTML = '<h4>URLs</h4><ul id="url-list" style="margin: 0; padding: 0; list-style: none;"></ul><button id="copy-urls" style="margin-top: 10px; display: block; width: 100%;">Copy URLs</button>';
|
||
|
document.body.appendChild(panel);
|
||
|
|
||
|
// Tooltip for previews
|
||
|
const tooltip = document.createElement('div');
|
||
|
tooltip.id = 'url-tooltip';
|
||
|
tooltip.style.position = 'absolute';
|
||
|
tooltip.style.backgroundColor = '#fff';
|
||
|
tooltip.style.border = '1px solid #ccc';
|
||
|
tooltip.style.borderRadius = '5px';
|
||
|
tooltip.style.padding = '5px';
|
||
|
tooltip.style.boxShadow = '0px 0px 10px rgba(0,0,0,0.2)';
|
||
|
tooltip.style.maxWidth = '300px';
|
||
|
tooltip.style.display = 'none';
|
||
|
tooltip.style.zIndex = 1001;
|
||
|
document.body.appendChild(tooltip);
|
||
|
|
||
|
const urlSet = new Set();
|
||
|
|
||
|
// Extract URLs from comments and highlight them
|
||
|
const comments = document.querySelectorAll('.commtext');
|
||
|
comments.forEach(comment => {
|
||
|
const links = comment.querySelectorAll('a[href]');
|
||
|
links.forEach(link => {
|
||
|
const url = link.href;
|
||
|
if (!urlSet.has(url)) {
|
||
|
urlSet.add(url);
|
||
|
link.style.backgroundColor = '#ffff99'; // Highlight the link
|
||
|
|
||
|
// Add the URL to the floating panel
|
||
|
const listItem = document.createElement('li');
|
||
|
listItem.textContent = url;
|
||
|
listItem.style.marginBottom = '5px';
|
||
|
listItem.style.wordWrap = 'break-word';
|
||
|
listItem.style.cursor = 'pointer';
|
||
|
listItem.dataset.url = url;
|
||
|
document.getElementById('url-list').appendChild(listItem);
|
||
|
}
|
||
|
|
||
|
// Add hover preview functionality to comment links
|
||
|
link.addEventListener('mouseover', () => {
|
||
|
GM_xmlhttpRequest({
|
||
|
method: 'GET',
|
||
|
url: url,
|
||
|
onload: response => {
|
||
|
tooltip.innerHTML = '';
|
||
|
const parser = new DOMParser();
|
||
|
const doc = parser.parseFromString(response.responseText, 'text/html');
|
||
|
const title = doc.querySelector('title') ? doc.querySelector('title').innerText : 'No Title';
|
||
|
const description = doc.querySelector('meta[name="description"]') ? doc.querySelector('meta[name="description"]').content : 'No Description';
|
||
|
|
||
|
tooltip.innerHTML = `<strong>${title}</strong><p>${description}</p>`;
|
||
|
tooltip.style.display = 'block';
|
||
|
},
|
||
|
onerror: () => {
|
||
|
tooltip.innerHTML = '<strong>Preview unavailable</strong>';
|
||
|
tooltip.style.display = 'block';
|
||
|
}
|
||
|
});
|
||
|
|
||
|
const rect = link.getBoundingClientRect();
|
||
|
tooltip.style.top = `${rect.bottom + window.scrollY + 5}px`;
|
||
|
tooltip.style.left = `${rect.left + window.scrollX}px`;
|
||
|
});
|
||
|
|
||
|
link.addEventListener('mouseout', () => {
|
||
|
tooltip.style.display = 'none';
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
// Handle the Copy URLs button
|
||
|
document.getElementById('copy-urls').addEventListener('click', () => {
|
||
|
const urlArray = Array.from(urlSet);
|
||
|
GM_setClipboard(urlArray.join('\n'), 'text');
|
||
|
alert('URLs copied to clipboard!');
|
||
|
});
|
||
|
})();
|