1import { Controller } from "@hotwired/stimulus" 2 3// Accordion for the inline chapter editors: only one chapter is editable at a time. 4// 5// - Opening one chapter's edit form collapses any other still open (driven by 6// turbo:frame-render bubbling from each chapter frame). 7// - Clicking anywhere outside the open editor closes it. That click is swallowed (capture 8// phase, preventDefault + stopPropagation), so a click landing on a link in the softened 9// area only dismisses the editor â it doesn't follow the link. 10// 11// Closing reverts a frame to its display by pointing its src at its showUrl â the same thing 12// its Cancel link does. 13export default class extends Controller { 14 static targets = ["frame"] 15 16 connect() { 17 document.addEventListener("click", this.dismiss, true) 18 } 19 20 disconnect() { 21 document.removeEventListener("click", this.dismiss, true) 22 } 23 24 collapseOthers({ target }) { 25 const opened = target.closest("[data-accordion-target='frame']") 26 if (!opened || !this.editing(opened)) return 27 28 this.frameTargets.forEach((frame) => { 29 if (frame !== opened && this.editing(frame)) this.close(frame) 30 }) 31 } 32 33 dismiss = (event) => { 34 const open = this.frameTargets.find((frame) => this.editing(frame)) 35 if (!open || open.contains(event.target)) return 36 37 event.preventDefault() 38 event.stopPropagation() 39 this.close(open) 40 } 41 42 close(frame) { 43 frame.src = frame.dataset.showUrl 44 } 45 46 editing(frame) { 47 return frame.querySelector(".focus-editor") !== null 48 } 49}
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.