|
| 1 | +/* global ClipboardJS */ |
| 2 | + |
| 3 | +"use strict"; |
| 4 | + |
| 5 | +(function () { |
| 6 | + const CONTAINER_CLASS_NAME = "code-block-with-actions"; |
| 7 | + const ACTIONS_CONTAINER_CLASS_NAME = "code-block-actions"; |
| 8 | + const COPY_BUTTON_CLASS_NAME = "code-block-copy-button"; |
| 9 | + const COPY_BUTTON_COPIED_CLASS_NAME = `${COPY_BUTTON_CLASS_NAME}--copied`; |
| 10 | + const COPY_BUTTON_ICON_CLASS_NAME = `${COPY_BUTTON_CLASS_NAME}__icon`; |
| 11 | + const COPY_BUTTON_COPY_ICON_CLASS_NAME = `${COPY_BUTTON_ICON_CLASS_NAME}--copy`; |
| 12 | + const COPY_BUTTON_COPIED_ICON_CLASS_NAME = `${COPY_BUTTON_ICON_CLASS_NAME}--copied`; |
| 13 | + const ARIA_LABEL = "Copy code to clipboard"; |
| 14 | + const ARIA_LABEL_COPIED = "Copied"; |
| 15 | + |
| 16 | + function init(codeBlock) { |
| 17 | + const container = codeBlock.parentNode; |
| 18 | + container.classList.add(CONTAINER_CLASS_NAME); |
| 19 | + |
| 20 | + const actionsContainer = Object.assign(document.createElement("div"), { |
| 21 | + className: ACTIONS_CONTAINER_CLASS_NAME, |
| 22 | + }); |
| 23 | + const copyButton = Object.assign(document.createElement("button"), { |
| 24 | + className: COPY_BUTTON_CLASS_NAME, |
| 25 | + type: "button", |
| 26 | + innerHTML: |
| 27 | + `<svg class="${COPY_BUTTON_ICON_CLASS_NAME} ${COPY_BUTTON_COPY_ICON_CLASS_NAME}" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg>` + |
| 28 | + `<svg class="${COPY_BUTTON_ICON_CLASS_NAME} ${COPY_BUTTON_COPIED_ICON_CLASS_NAME}" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg>`, |
| 29 | + }); |
| 30 | + copyButton.setAttribute("aria-label", ARIA_LABEL); |
| 31 | + |
| 32 | + new ClipboardJS(copyButton, { target: () => codeBlock }).on( |
| 33 | + "success", |
| 34 | + (event) => { |
| 35 | + event.clearSelection(); |
| 36 | + copyButton.classList.add(COPY_BUTTON_COPIED_CLASS_NAME); |
| 37 | + copyButton.setAttribute("aria-label", ARIA_LABEL_COPIED); |
| 38 | + copyButton.disabled = true; |
| 39 | + |
| 40 | + setTimeout(() => { |
| 41 | + copyButton.classList.remove(COPY_BUTTON_COPIED_CLASS_NAME); |
| 42 | + copyButton.setAttribute("aria-label", ARIA_LABEL); |
| 43 | + copyButton.disabled = false; |
| 44 | + }, 2000); |
| 45 | + } |
| 46 | + ); |
| 47 | + |
| 48 | + actionsContainer.appendChild(copyButton); |
| 49 | + container.appendChild(actionsContainer); |
| 50 | + } |
| 51 | + |
| 52 | + window.addEventListener("load", () => { |
| 53 | + for (const codeBlock of document.querySelectorAll("pre > code.hljs")) { |
| 54 | + init(codeBlock); |
| 55 | + } |
| 56 | + }); |
| 57 | +})(); |
0 commit comments