UNPKG

agahi

Version:

Client-side engine that renders Markdown files as a docs site in the browser—no build step.

103 lines (81 loc) 3.66 kB
(function () { 'use strict'; function styleInject(css, ref) { if ( ref === void 0 ) ref = {}; var insertAt = ref.insertAt; if (typeof document === 'undefined') { return; } var head = document.head || document.getElementsByTagName('head')[0]; var style = document.createElement('style'); style.type = 'text/css'; if (insertAt === 'top') { if (head.firstChild) { head.insertBefore(style, head.firstChild); } else { head.appendChild(style); } } else { head.appendChild(style); } if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } } var css_248z = ".copy-code {\n position: absolute;\n top: 0.5rem;\n right: 0.5rem;\n padding: 0.25rem 0.5rem;\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--text-color);\n background-color: var(--background-hover);\n border: 1px solid var(--border-color);\n border-radius: 0.25rem;\n cursor: pointer;\n opacity: 0;\n transition: all 0.2s ease;\n z-index: 1;\n}\n\n/* Show on hover (desktop) */\n\n@media (hover: hover) {\n pre:hover .copy-code {\n opacity: 1;\n }\n}\n\n/* Always show on mobile */\n\n@media (hover: none) and (pointer: coarse) {\n .copy-code {\n opacity: 1;\n }\n}\n\n.copy-code:active,\n.copy-code:focus {\n outline: none;\n color: #fff;\n}\n\n.copy-code:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n"; styleInject(css_248z); /** * copy-code Plugin * This plugin adds a "Copy Code" button to code blocks in the article. * When clicked, it copies the code to the clipboard and shows a confirmation message. * It uses MutationObserver to detect dynamically added code blocks. */ document.addEventListener('agahi:ready', () => { const article = document.getElementById('md'); if (!article) { throw new Error( 'Article element with id="md" not found. Copy code plugin cannot initialize.', ); } /** * Adds a "Copy" button to a given code block and attaches the copy logic. * @param {HTMLElement} codeBlock - The <code> element to which the button should be added. */ const addCopyButton = (codeBlock) => { const pre = codeBlock.parentElement; // Ensure the parent is a <pre> tag and that a copy button doesn't already exist. if (!pre || pre.tagName !== 'PRE' || pre.querySelector('.copy-code')) { return; } const copyButton = document.createElement('button'); copyButton.className = 'copy-code'; copyButton.textContent = 'Copy'; copyButton.onclick = () => { navigator.clipboard .writeText(codeBlock.textContent) .then(() => { copyButton.textContent = 'Copied!'; setTimeout(() => (copyButton.textContent = 'Copy'), 1500); }) .catch((err) => { console.error('Failed to copy using navigator.clipboard:', err); }); }; pre.appendChild(copyButton); }; article.querySelectorAll('pre > code').forEach(addCopyButton); const observer = new MutationObserver((mutations) => { for (const { addedNodes } of mutations) { for (const node of addedNodes) { if (node.nodeType !== 1) continue; const codes = node.tagName === 'CODE' && node.parentElement?.tagName === 'PRE' ? [node] : node.querySelectorAll?.('pre > code') || []; codes.forEach(addCopyButton); } } }); observer.observe(article, { childList: true, subtree: true }); }); })();