1import { Controller } from "@hotwired/stimulus" 2 3export default class extends Controller { 4 static targets = ["source"] 5 6 copy(event) { 7 const button = event.currentTarget 8 const text = this.hasSourceTarget ? this.sourceTarget.value : button.dataset.clipboardText 9 10 if (!text) return 11 12 const writeClipboard = navigator.clipboard?.writeText 13 ? navigator.clipboard.writeText(text) 14 : this.fallbackCopy(text) 15 16 Promise.resolve(writeClipboard) 17 .then(() => this.showFeedback(button)) 18 .catch(() => this.showFeedback(button)) 19 } 20 21 fallbackCopy(text) { 22 return new Promise((resolve, reject) => { 23 try { 24 const textarea = document.createElement("textarea") 25 textarea.value = text 26 textarea.setAttribute("readonly", "") 27 textarea.style.position = "absolute" 28 textarea.style.left = "-9999px" 29 document.body.appendChild(textarea) 30 textarea.select() 31 document.execCommand("copy") 32 document.body.removeChild(textarea) 33 resolve() 34 } catch (error) { 35 reject(error) 36 } 37 }) 38 } 39 40 showFeedback(button) { 41 const originalText = button.dataset.originalText || button.textContent 42 const successText = button.dataset.clipboardSuccessText || originalText 43 44 button.dataset.originalText = originalText 45 button.textContent = successText 46 button.classList.add("clipboard-button--copied") 47 48 setTimeout(() => { 49 button.textContent = button.dataset.originalText 50 button.classList.remove("clipboard-button--copied") 51 }, 2000) 52 } 53};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.