您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
MetaFilter: label domains in post links. No mystery meat here!
// ==UserScript== // @name MeFi Domain Labels // @namespace https://github.com/klipspringr/mefi-userscripts // @version 2025-08-29-a // @description MetaFilter: label domains in post links. No mystery meat here! // @author Klipspringer // @supportURL https://github.com/klipspringr/mefi-userscripts // @license MIT // @match *://*.metafilter.com/* // @grant GM_getValue // @grant GM_setValue // @grant GM_registerMenuCommand // ==/UserScript== ;(async () => { "use strict" const HOSTNAME_EXCLUDE = /^(?:bestof|faq)\./ const PATHNAME_INCLUDE = /^\/(?:$|\d+\/|archived.mefi|comments\.mefi|home\/|popular\.mefi|tags\/)/ const PATHNAME_EXCLUDE = /rss$/ if ( HOSTNAME_EXCLUDE.test(window.location.hostname) || !PATHNAME_INCLUDE.test(window.location.pathname) || PATHNAME_EXCLUDE.test(window.location.pathname) ) return const KEY_DOMAINS_HIGHLIGHT = "domains-highlight" const INTERNAL_LABEL_TEXT = "MeFi" const LABEL_CLASS = "mfdl-label" const HIGHLIGHT_CLASS = "mfdl-highlight" const LABEL_CSS = ` a > span.${LABEL_CLASS} { background-color: rgba(0, 0, 0, 0.15); border-radius: 5px; color:rgba(255, 255, 255, 0.8); font-size: 80%; font-style: normal; font-weight: normal; margin-left: 4px; padding: 1px 5px 2px 5px; user-select: none; transition: color 100ms; white-space: nowrap; } a > span.${LABEL_CLASS}.${HIGHLIGHT_CLASS} { background-color: rgba(255, 0, 0, 0.4); color:rgb(255, 255, 255); } a:hover > span.${LABEL_CLASS} { color: rgb(255, 255, 255); }` // common patterns for multi-level TLDs like .co.uk, .com.au, etc. const COMPLEX_TLDS = /\.(co|com|net|org|gov|edu|ac|mil)\.[a-z]{2}$/i const getDomain = (href) => { if (!href) return let hostname try { hostname = new URL(href).hostname } catch { return } const parts = hostname.split(".") if (COMPLEX_TLDS.test(hostname)) { return parts.slice(-3).join(".") } else { return parts.slice(-2).join(".") } } const getHighlightDomains = async () => { const value = await GM_getValue(KEY_DOMAINS_HIGHLIGHT, "") if (typeof value !== "string") return [] return value.split(",").map((d) => d.trim().toLowerCase()) } const handleEditHighlightDomains = async () => { const existing = await GM_getValue(KEY_DOMAINS_HIGHLIGHT, "") const edited = prompt( "Domains to highlight in red (comma-separated list):", String(existing) ) await GM_setValue(KEY_DOMAINS_HIGHLIGHT, edited || "") addDomainLabels() } const addDomainLabels = async () => { // remove any existing labels document .querySelectorAll(`a > span.${LABEL_CLASS}`) .forEach((e) => e.remove()) const highlightDomains = await getHighlightDomains() document .querySelectorAll( "#posts div.copy:not(.recently) a:not(.smallcopy *), " + "#popposts div.copy a:not(.smallcopy *)" ) .forEach((a) => { const domain = getDomain(a.getAttribute("href")) if (!domain) return const tag = document.createElement("span") tag.classList.add(LABEL_CLASS) if (highlightDomains.includes(domain)) tag.classList.add(HIGHLIGHT_CLASS) tag.textContent = domain === "metafilter.com" ? INTERNAL_LABEL_TEXT : domain a.insertAdjacentElement("beforeend", tag) // remove any stray period after the domain label const nextSibling = a.nextSibling if (nextSibling && nextSibling.nodeType === Node.TEXT_NODE) { const text = nextSibling.textContent if (/^\s*\./.test(text)) { nextSibling.textContent = text.replace(/^\s*\./, "") } } }) } GM_registerMenuCommand( "Edit highlighted domains", handleEditHighlightDomains ) const styleElement = document.createElement("style") styleElement.textContent = LABEL_CSS document.body.insertAdjacentElement("beforeend", styleElement) const start = performance.now() addDomainLabels() console.log( "mefi-domain-labels", Math.round(performance.now() - start) + "ms" ) })()