1class DetailsModal extends HTMLElement { 2 constructor() { 3 super(); 4 this.detailsContainer = this.querySelector('details'); 5 this.summaryToggle = this.querySelector('summary'); 6 7 this.detailsContainer.addEventListener( 8 'keyup', 9 (event) => event.code.toUpperCase() === 'ESCAPE' && this.close() 10 ); 11 this.summaryToggle.addEventListener( 12 'click', 13 this.onSummaryClick.bind(this) 14 ); 15 this.querySelector('button[type="button"]').addEventListener( 16 'click', 17 this.close.bind(this) 18 ); 19 20 this.summaryToggle.setAttribute('role', 'button'); 21 } 22 23 isOpen() { 24 return this.detailsContainer.hasAttribute('open'); 25 } 26 27 onSummaryClick(event) { 28 event.preventDefault(); 29 const details = event.target.closest('details'); 30 details.hasAttribute('open') && !details.classList.contains('details-closing') 31 ? this.close() 32 : this.open(event); 33 } 34 35 onBodyClick(event) { 36 if (!this.contains(event.target) || event.target.classList.contains('modal-overlay')) this.close(false); 37 } 38 39 open(event) { 40 clearTimeout(this.closeTimeout); 41 this.detailsContainer.classList.remove('details-closing'); 42 this.onBodyClickEvent = 43 this.onBodyClickEvent || this.onBodyClick.bind(this); 44 event.target.closest('details').setAttribute('open', true); 45 document.body.addEventListener('click', this.onBodyClickEvent); 46 document.body.classList.add('overflow-hidden'); 47 48 trapFocus( 49 this.detailsContainer.querySelector('[tabindex="-1"]'), 50 this.detailsContainer.querySelector('input:not([type="hidden"])') 51 ); 52 } 53 54 close(focusToggle = true) { 55 removeTrapFocus(focusToggle ? this.summaryToggle : null); 56 this.detailsContainer.classList.add('details-closing'); 57 clearTimeout(this.closeTimeout); 58 this.closeTimeout = setTimeout(() => { 59 this.detailsContainer.classList.remove('details-closing'); 60 this.detailsContainer.removeAttribute('open'); 61 }, 200); 62 document.body.removeEventListener('click', this.onBodyClickEvent); 63 document.body.classList.remove('overflow-hidden'); 64 } 65} 66 67customElements.define('details-modal', DetailsModal);
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.