您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
A userscript that adds a copy to clipboard button on hover of code snippets in HackMD
// ==UserScript== // @name HackMD Copy Code Snippet // @version 1.0.0 // @description A userscript that adds a copy to clipboard button on hover of code snippets in HackMD // @license MIT // @author Planetoid Hsu (Made with Claude) // @namespace https://github.com/planetoid // @match https://hackmd.io/* // @run-at document-idle // @grant GM_addStyle // ==/UserScript== (() => { "use strict"; let copyId = 0; const codeSelector = "pre"; const copyButton = document.createElement("button"); copyButton.className = "copy-btn"; copyButton.setAttribute("aria-label", "Copy to clipboard"); copyButton.innerHTML = "Copy"; GM_addStyle(` .code-wrap { position: relative; } .code-wrap:hover .copy-btn { display: block; } .copy-btn { display: none; position: absolute; top: 5px; right: 5px; padding: 3px 6px; background-color: #f1f1f1; border: 1px solid #ccc; border-radius: 3px; font-size: 12px; cursor: pointer; z-index: 1000; } .copy-btn:hover { background-color: #e1e1e1; } `); function addButton(codeBlock) { if (!codeBlock.classList.contains("code-wrap")) { copyId++; const code = codeBlock.querySelector("code") || codeBlock; if (code) { code.id = `hmd-csc-${copyId}`; const newButton = copyButton.cloneNode(true); newButton.addEventListener("click", () => { navigator.clipboard.writeText(code.textContent).then(() => { newButton.textContent = "Copied!"; setTimeout(() => { newButton.textContent = "Copy"; }, 2000); }); }); codeBlock.classList.add("code-wrap"); codeBlock.insertBefore(newButton, codeBlock.firstChild); } } } function init() { document.querySelectorAll(codeSelector).forEach(addButton); } window.addEventListener('load', init); const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.type === 'childList') { mutation.addedNodes.forEach((node) => { if (node.nodeType === Node.ELEMENT_NODE) { if (node.matches(codeSelector)) { addButton(node); } else { node.querySelectorAll(codeSelector).forEach(addButton); } } }); } }); }); observer.observe(document.body, { childList: true, subtree: true }); })();