Copy code

This commit is contained in:
Magnus Åhall 2026-06-16 09:37:10 +02:00
parent ecf68132a1
commit b0a95c9382
3 changed files with 42 additions and 3 deletions

View file

@ -102,6 +102,11 @@
border: 1px solid #ccc;
padding: 2px 4px;
border-radius: 4px;
&.copy {
border: var(--markdown-copy-border);
background-color: var(--markdown-copy-background);
}
}
pre {
@ -111,6 +116,14 @@
border-radius: 4px;
white-space: pre-wrap;
&.copy {
border: var(--markdown-copy-border);
background-color: var(--markdown-copy-background);
code {
background-color: inherit !important;
}
}
code {
border: unset;
padding: unset;

View file

@ -15,6 +15,9 @@
--menu-item-hover-color: #f4f4f4;
--font-monospace: "Liberation Mono", monospace;
--markdown-copy-border: 1px solid #0a0;
--markdown-copy-background: #e3f4d7;
}
html {

View file

@ -94,6 +94,7 @@ export class MarkedPosition {
constructor() {// {{{
window.marked_setpos = (event) => this.setpos(event)
window.marked_changecheckbox = (event) => this.changecheckbox(event)
window.marked_copy_to_clipboard = (event) => this.copy_to_clipboard(event)
this.render()
}// }}}
setpos(event) {// {{{
@ -119,6 +120,28 @@ export class MarkedPosition {
}
})
}// }}}
async copy_to_clipboard(event) {// {{{
if (!event.shiftKey)
return
try {
// Stop text selections on the page to the mouse pointer.
// Old selections are remove as well to give a cleaner view
// of the copied text/highlighting.
event.preventDefault()
event.stopPropagation()
window.getSelection().removeAllRanges()
const text = event.target.innerText
await navigator.clipboard.writeText(text)
event.target.classList.add('copy')
setTimeout(()=>event.target.classList.remove('copy'), 250)
} catch (err) {
console.error('Failed to copy: ', err)
alert('Failed to copy: ', err)
}
}// }}}
render() {// {{{
const markedObject = this
this.marked = new Marked()
@ -165,12 +188,12 @@ export class MarkedPosition {
const code = token.text.replace(other.endingNewline, '') + '\n'
if (!langString) {
return `<pre ondblclick="marked_setpos(event)" data-offset-start="${token.position.start.offset}" data-offset-end="${token.position.end.offset}"><code>`
return `<pre ondblclick="marked_setpos(event)" onmousedown="marked_copy_to_clipboard(event)" data-offset-start="${token.position.start.offset}" data-offset-end="${token.position.end.offset}"><code>`
+ (token.escaped ? code : escapeHtmlEntities(code, true))
+ '</code></pre>\n'
}
return `<pre ondblclick="marked_setpos(event)" data-offset-start="${token.position.start.offset}" data-offset-end="${token.position.end.offset}"><code class="language-`
return `<pre ondblclick="marked_setpos(event)" onmousedown="marked_copy_to_clipboard(event)" data-offset-start="${token.position.start.offset}" data-offset-end="${token.position.end.offset}"><code class="language-`
+ escapeHtmlEntities(langString)
+ '">'
+ (token.escaped ? code : escapeHtmlEntities(code, true))
@ -260,7 +283,7 @@ export class MarkedPosition {
},
codespan(token) {
return `<code ondblclick="marked_setpos(event)" data-offset-start="${token.position.start.offset}" data-offset-end="${token.position.end.offset}">${escapeHtmlEntities(token.text, true)}</code>`
return `<code ondblclick="marked_setpos(event)" onmousedown="marked_copy_to_clipboard(event)" data-offset-start="${token.position.start.offset}" data-offset-end="${token.position.end.offset}">${escapeHtmlEntities(token.text, true)}</code>`
},
br(token) {