| function cleanupClipboardText(targetSelector) { |
| const targetElement = document.querySelector(targetSelector); |
| |
| // exclude "Generic Prompt" and "Generic Output" spans from copy |
| const excludedClasses = ["gp", "go"]; |
| |
| const clipboardText = Array.from(targetElement.childNodes) |
| .filter( |
| (node) => |
| !excludedClasses.some((className) => |
| node?.classList?.contains(className), |
| ), |
| ) |
| .map((node) => node.textContent) |
| .filter((s) => s !== ""); |
| return clipboardText.join("").trim(); |
| } |
| |
| // Sets copy text to attributes lazily using an Intersection Observer. |
| function setCopyText() { |
| // The `data-clipboard-text` attribute allows for customized content in the copy |
| // See: https://www.npmjs.com/package/clipboard#copy-text-from-attribute |
| const attr = "clipboardText"; |
| // all "copy" buttons whose target selector is a <code> element |
| const elements = document.querySelectorAll( |
| 'button[data-clipboard-target$="code"]', |
| ); |
| |
| if (elements.length === 0) { |
| return; |
| } |
| |
| const observer = new IntersectionObserver((entries) => { |
| entries.forEach((entry) => { |
| // target in the viewport that have not been patched |
| if ( |
| entry.intersectionRatio > 0 && |
| entry.target.dataset[attr] === undefined |
| ) { |
| entry.target.dataset[attr] = cleanupClipboardText( |
| entry.target.dataset.clipboardTarget, |
| ); |
| } |
| }); |
| }); |
| |
| elements.forEach((elt) => { |
| observer.observe(elt); |
| }); |
| } |
| |
| // Using the document$ observable is particularly important if you are using instant loading since |
| // it will not result in a page refresh in the browser |
| // See `How to integrate with third-party JavaScript libraries` guideline: |
| // https://squidfunk.github.io/mkdocs-material/customization/?h=javascript#additional-javascript |
| document$.subscribe(function () { |
| setCopyText(); |
| }); |
| |