Make the comment link on Hacker News front page match the story link formatting (external stories only). So that you can use Snap Links to easily Right Click and drag to mass open links if you like to read Comments page for stories.
目前為
// ==UserScript==
// @name Hacker News - Match Comment Link Style to Story Link
// @author MedX
// @namespace MedX-AA
// @license MIT
// @icon https://news.ycombinator.com/favicon.ico
// @version 1.3
// @description Make the comment link on Hacker News front page match the story link formatting (external stories only). So that you can use Snap Links to easily Right Click and drag to mass open links if you like to read Comments page for stories.
// @match https://news.ycombinator.com/front*
// @match https://news.ycombinator.com/newest*
// @grant none
// ==/UserScript==
(function () {
'use strict';
// 🛡️ Prevent duplicate observers if script re-executes
if (window.hnStyleObserverActive) return;
window.hnStyleObserverActive = true;
const DEBOUNCE_MS = 300; // Wait time after Pagetual finishes inserting
let cachedStyle = null;
let debounceTimer = null;
let styleTag = null;
// 1️⃣ Read style once from the first story title
function cacheTitleStyle() {
if (cachedStyle) return;
const first = document.querySelector('.titleline > a');
if (!first) return;
const s = getComputedStyle(first);
cachedStyle = {
fontSize: s.fontSize,
fontWeight: s.fontWeight,
color: s.color,
fontFamily: s.fontFamily,
textDecoration: s.textDecoration
};
}
// 2️⃣ Inject or update a CSS rule for all comment links
function injectCommentStyleRule() {
if (!cachedStyle) cacheTitleStyle();
if (!cachedStyle) return;
const css = `
.subtext a[href^="item?id="]:is(:link, :visited) {
font-size: ${cachedStyle.fontSize};
font-weight: ${cachedStyle.fontWeight};
color: ${cachedStyle.color};
font-family: ${cachedStyle.fontFamily};
text-decoration: ${cachedStyle.textDecoration};
}
`;
if (!styleTag) {
styleTag = document.createElement('style');
styleTag.id = 'hnCommentStyle';
document.head.appendChild(styleTag);
}
styleTag.textContent = css;
}
// 3️⃣ Debounce updates to run after Pagetual is done
function scheduleStyling() {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(injectCommentStyleRule, DEBOUNCE_MS);
}
// Initial run
injectCommentStyleRule();
// 4️⃣ Watch for new content from Pagetual
const obs = new MutationObserver(muts => {
for (const m of muts) {
if (m.addedNodes.length) {
scheduleStyling();
break;
}
}
});
obs.observe(document.body, { childList: true, subtree: true });
})();