1class Dialog { 2 constructor(dialogElement) { 3 this.dialog = dialogElement; 4 this.isClosing = false; 5 6 this.backdropClose = this.dialog.dataset.backdropClose !== "False"; 7 this.escapeClose = this.dialog.dataset.escapeClose !== "False"; 8 9 this.initializeEventListeners(); 10 } 11 12 initializeEventListeners() { 13 const closeButtons = this.dialog.querySelectorAll("[data-dialog-close]"); 14 closeButtons.forEach((closeButton) => { 15 closeButton.addEventListener("click", (e) => { 16 e.preventDefault(); 17 this.close(); 18 }); 19 }); 20 21 if (this.backdropClose) { 22 this.dialog.addEventListener("click", (e) => { 23 if (e.target === this.dialog) { 24 this.close(); 25 } 26 }); 27 } 28 29 if (this.escapeClose) { 30 this.dialog.addEventListener("keydown", (e) => { 31 if (e.key === "Escape") { 32 e.preventDefault(); 33 this.close(); 34 } 35 }); 36 } 37 38 this.dialog.addEventListener("close", () => { 39 this.handleDialogClose(); 40 }); 41 } 42 43 open() { 44 if (this.dialog.open || this.isClosing) return; 45 46 this.dialog.showModal(); 47 this.focusFirstElement(); 48 49 this.dialog.dispatchEvent( 50 new CustomEvent("dialog:opened", { 51 bubbles: true, 52 detail: { dialog: this.dialog }, 53 }) 54 ); 55 } 56 57 close() { 58 if (!this.dialog.open || this.isClosing) return; 59 60 this.isClosing = true; 61 this.dialog.close(); 62 } 63 64 handleDialogClose() { 65 this.isClosing = false; 66 67 this.dialog.dispatchEvent( 68 new CustomEvent("dialog:closed", { 69 bubbles: true, 70 detail: { dialog: this.dialog }, 71 }) 72 ); 73 } 74 75 focusFirstElement() { 76 const focusableElements = this.dialog.querySelectorAll("input, select, textarea"); 77 78 if (focusableElements.length > 0) { 79 focusableElements[0].focus(); 80 } 81 } 82 83 static getInstance(dialogElement) { 84 if (!dialogElement._dialogInstance) { 85 dialogElement._dialogInstance = new Dialog(dialogElement); 86 } 87 return dialogElement._dialogInstance; 88 } 89 90 static open(dialogId) { 91 const dialog = document.getElementById(dialogId); 92 if (dialog) { 93 const instance = Dialog.getInstance(dialog); 94 instance.open(); 95 } 96 } 97 98 static close(dialogId) { 99 const dialog = document.getElementById(dialogId); 100 if (dialog) { 101 const instance = Dialog.getInstance(dialog); 102 instance.close(); 103 } 104 } 105} 106 107document.addEventListener("DOMContentLoaded", () => { 108 const dialogs = document.querySelectorAll(".shared-dialog"); 109
110 dialogs.forEach((dialog) => { 111 Dialog.getInstance(dialog); 112 }); 113 114 document.addEventListener("click", (e) => { 115 const trigger = e.target.closest("[data-dialog-open]"); 116 if (trigger) { 117 e.preventDefault(); 118 const dialogId = trigger.dataset.dialogOpen; 119 Dialog.open(dialogId); 120 } 121 }); 122}); 123 124window.Dialog = Dialog;
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.