1// Helper function to safely set dialog content 2function updateDialogContent(dialog, content) { 3 Object.entries(content).forEach(([selector, text]) => { 4 const element = dialog.querySelector(selector); 5 if (element) element.textContent = text; 6 }); 7} 8 9// Helper function to create a dialog from a template 10function createDialogFromTemplate(templateId) { 11 const template = document.querySelector(`#${templateId}`); 12 if (!template) { 13 console.error(`Dialog template with id "${templateId}" not found.`); 14 return null; 15 } 16 17 const dialog = template.content.cloneNode(true).querySelector('dialog'); 18 if (!dialog) { 19 console.error(`Dialog element not found in the template with id "${templateId}".`); 20 return null; 21 } 22 23 document.body.appendChild(dialog); 24 return dialog; 25} 26 27// Helper function to configure the dialog 28function configureDialog(button, reference) { 29 const dialog = createDialogFromTemplate(reference); 30 if (!dialog) return Promise.resolve(false); 31 32 const { 33 turboConfirmHeader, 34 turboConfirmTitle, 35 turboConfirmDescription, 36 turboConfirmNegative, 37 turboConfirmPositive, 38 turboConfirm 39 } = button.dataset; 40 41 // Set dialog content 42 updateDialogContent(dialog, { 43 '#turbo-confirm-header': turboConfirmHeader || button.textContent, 44 '#turbo-confirm-title': turboConfirmTitle || turboConfirm, 45 '#turbo-confirm-description': turboConfirmDescription || 'Please confirm your action.', 46 '#turbo-confirm-negative': turboConfirmNegative || 'Cancel', 47 '#turbo-confirm-positive': turboConfirmPositive || 'Confirm', 48 }); 49 50 // Disable scrolling on the body when the dialog is open 51 document.body.style.overflow = 'hidden'; 52 53 dialog.showModal(); 54 55 return new Promise((resolve) => { 56 dialog.addEventListener('close', () => { 57 resolve(dialog.returnValue === 'positive'); 58 dialog.remove(); 59 60 // Re-enable scrolling on the body when the dialog is closed 61 document.body.style.overflow = ''; 62 }, { once: true }); 63 }); 64} 65 66// Set Turbo confirmation method 67Turbo.config.forms.confirm = (confirmationMessage, formElement, submitter) => { 68 const templateId = submitter.dataset.turboConfirmTemplateId 69 70 if (templateId) { 71 const dialog = document.getElementById(templateId); 72 if (!dialog) { 73 console.error(`Dialog with id "${templateId}" not found.`); 74 return Promise.resolve(false); 75 } 76 dialog.showModal(); 77 document.body.style.overflow = 'hidden'; 78 return new Promise((resolve) => { 79 dialog.addEventListener('close', () => { 80 resolve(dialog.returnValue === 'positive'); 81 document.body.style.overflow = ''; 82 }, { once: true }); 83 }); 84 } else { 85 return configureDialog(submitter, 'turbo-confirm'); 86 } 87}; 88 89// Function to handle link confirmation 90window.showConfirmForLink = async function(event, link) { 91 event.preventDefault(); 92 event.stopImmediatePropagation(); 93 94 const confirmed = await configureDialog(link, 'turbo-confirm'); 95 96 if (confirmed) { 97 const target = link.getAttribute('target'); 98 if (target === '_blank') { 99 window.open(link.href, '_blank'); 100 } else { 101 window.location.href = link.href; 102 } 103 return true; 104 } 105 return false; 106};
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.