1import { Controller } from "@hotwired/stimulus" 2 3// Click any <img> inside the controller scope to open it full-size in a 4// modal <dialog>. Click anywhere on the dialog (or press ESC) to close. 5export default class extends Controller { 6 connect() { 7 this.onClick = this.onClick.bind(this) 8 this.element.addEventListener("click", this.onClick) 9 } 10 11 disconnect() { 12 this.element.removeEventListener("click", this.onClick) 13 this.dialog?.remove() 14 this.dialog = null 15 } 16 17 onClick(event) { 18 const img = event.target.closest("img") 19 if (!img || !this.element.contains(img)) return 20 event.preventDefault() 21 this.open(img) 22 } 23 24 open(img) { 25 const dialog = document.createElement("dialog") 26 dialog.className = "blog-lightbox" 27 28 const full = document.createElement("img") 29 full.src = img.currentSrc || img.src 30 full.alt = img.alt 31 full.className = "blog-lightbox-img" 32 dialog.appendChild(full) 33 34 dialog.addEventListener("click", () => dialog.close()) 35 dialog.addEventListener("close", () => { 36 dialog.remove() 37 if (this.dialog === dialog) this.dialog = null 38 }) 39 40 document.body.appendChild(dialog) 41 dialog.showModal() 42 this.dialog = dialog 43 } 44}
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.