45 lines
1.2 KiB
TypeScript
45 lines
1.2 KiB
TypeScript
/**
|
|
* copy-code.ts
|
|
* Adds a "Copy" button to every <pre><code> block in the article content.
|
|
*/
|
|
|
|
export function initCopyCode(): void {
|
|
const blocks = document.querySelectorAll<HTMLPreElement>(
|
|
'.entry-content pre, .post-card__content pre, .single-article pre'
|
|
);
|
|
|
|
if ( ! blocks.length ) return;
|
|
|
|
blocks.forEach( ( pre ) => {
|
|
// Avoid adding duplicate buttons.
|
|
if ( pre.querySelector( '.copy-code-btn' ) ) return;
|
|
|
|
const btn = document.createElement( 'button' );
|
|
btn.className = 'copy-code-btn';
|
|
btn.textContent = '复制';
|
|
btn.setAttribute( 'aria-label', '复制代码' );
|
|
btn.type = 'button';
|
|
|
|
btn.addEventListener( 'click', async () => {
|
|
const code = pre.querySelector( 'code' );
|
|
const text = code?.textContent ?? pre.textContent ?? '';
|
|
|
|
try {
|
|
await navigator.clipboard.writeText( text );
|
|
btn.textContent = '已复制!';
|
|
btn.classList.add( 'is-copied' );
|
|
setTimeout( () => {
|
|
btn.textContent = '复制';
|
|
btn.classList.remove( 'is-copied' );
|
|
}, 2000 );
|
|
} catch {
|
|
btn.textContent = '失败';
|
|
setTimeout( () => { btn.textContent = '复制'; }, 2000 );
|
|
}
|
|
} );
|
|
|
|
pre.style.position = 'relative';
|
|
pre.appendChild( btn );
|
|
} );
|
|
}
|