| 1 |
<script> |
| 2 |
(function() { |
| 3 |
var overlay = document.getElementById('abj404-setup-wizard'); |
| 4 |
var closeBtn = document.getElementById('abj404-setup-close'); |
| 5 |
var skipBtn = document.getElementById('abj404-setup-skip'); |
| 6 |
var saveBtn = document.querySelector('.abj404-setup-primary'); |
| 7 |
var form = document.querySelector('#abj404-setup-wizard form'); |
| 8 |
|
| 9 |
// Bug #9 fix: Null check for nonce element |
| 10 |
var nonceEl = document.getElementById('abj404_setup_wizard_nonce'); |
| 11 |
var nonce = nonceEl ? nonceEl.value : ''; |
| 12 |
|
| 13 |
// Bug #26 fix: Track dismiss state to prevent multiple calls |
| 14 |
var isDismissing = false; |
| 15 |
var isSubmitting = false; |
| 16 |
|
| 17 |
function dismissWizard() { |
| 18 |
// Bug #26 fix: Prevent multiple rapid dismissals |
| 19 |
if (isDismissing) { |
| 20 |
return; |
| 21 |
} |
| 22 |
isDismissing = true; |
| 23 |
|
| 24 |
// Disable buttons to prevent further clicks |
| 25 |
if (closeBtn) closeBtn.disabled = true; |
| 26 |
if (skipBtn) skipBtn.disabled = true; |
| 27 |
|
| 28 |
// Remove modal immediately |
| 29 |
if (overlay) { |
| 30 |
overlay.remove(); |
| 31 |
} |
| 32 |
|
| 33 |
// Bug #9 fix: Don't send AJAX if no nonce |
| 34 |
if (!nonce) { |
| 35 |
showToast({missing_nonce_message}); |
| 36 |
return; |
| 37 |
} |
| 38 |
|
| 39 |
// Fire AJAX to mark as complete with error handling |
| 40 |
var xhr = new XMLHttpRequest(); |
| 41 |
xhr.open('POST', ajaxurl, true); |
| 42 |
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); |
| 43 |
xhr.onload = function() { |
| 44 |
if (xhr.status !== 200) { |
| 45 |
showToast({dismissal_failed_message}); |
| 46 |
return; |
| 47 |
} |
| 48 |
try { |
| 49 |
var response = JSON.parse(xhr.responseText); |
| 50 |
if (!response.success) { |
| 51 |
var msg = response.data && response.data.message ? response.data.message : ''; |
| 52 |
showToast({dismissal_prefix} + msg + {dismissal_suffix}); |
| 53 |
} |
| 54 |
} catch (e) { |
| 55 |
showToast({dismissal_failed_message}); |
| 56 |
} |
| 57 |
}; |
| 58 |
xhr.onerror = function() { |
| 59 |
showToast({network_error_message}); |
| 60 |
}; |
| 61 |
xhr.send('action=abj404_dismiss_setup_wizard&nonce=' + encodeURIComponent(nonce)); |
| 62 |
} |
| 63 |
|
| 64 |
function showToast(message) { |
| 65 |
// Remove any existing toast |
| 66 |
var existingToast = document.querySelector('.abj404-toast'); |
| 67 |
if (existingToast) { |
| 68 |
existingToast.remove(); |
| 69 |
} |
| 70 |
|
| 71 |
// Create toast element using DOM methods |
| 72 |
var toast = document.createElement('div'); |
| 73 |
toast.className = 'abj404-toast'; |
| 74 |
toast.setAttribute('role', 'alert'); |
| 75 |
|
| 76 |
var closeBtn = document.createElement('button'); |
| 77 |
closeBtn.className = 'abj404-toast-close'; |
| 78 |
closeBtn.setAttribute('aria-label', {close_label}); |
| 79 |
closeBtn.textContent = '\u00D7'; |
| 80 |
closeBtn.onclick = function() { toast.remove(); }; |
| 81 |
|
| 82 |
var textNode = document.createTextNode(message); |
| 83 |
|
| 84 |
toast.appendChild(closeBtn); |
| 85 |
toast.appendChild(textNode); |
| 86 |
document.body.appendChild(toast); |
| 87 |
|
| 88 |
// Auto-remove after 10 seconds |
| 89 |
setTimeout(function() { |
| 90 |
if (toast && toast.parentNode) { |
| 91 |
toast.remove(); |
| 92 |
} |
| 93 |
}, 10000); |
| 94 |
} |
| 95 |
|
| 96 |
function showSavingOverlay() { |
| 97 |
// Bug #26 fix: Prevent multiple submissions |
| 98 |
if (isSubmitting) { |
| 99 |
return false; |
| 100 |
} |
| 101 |
isSubmitting = true; |
| 102 |
|
| 103 |
// Disable buttons |
| 104 |
if (saveBtn) saveBtn.disabled = true; |
| 105 |
if (skipBtn) skipBtn.disabled = true; |
| 106 |
if (closeBtn) closeBtn.disabled = true; |
| 107 |
|
| 108 |
// Bug #19 fix: Use DOM methods instead of innerHTML |
| 109 |
var loadingOverlay = document.createElement('div'); |
| 110 |
loadingOverlay.className = 'abj404-setup-loading'; |
| 111 |
|
| 112 |
var spinner = document.createElement('div'); |
| 113 |
spinner.className = 'abj404-setup-spinner'; |
| 114 |
loadingOverlay.appendChild(spinner); |
| 115 |
|
| 116 |
var loadingText = document.createElement('span'); |
| 117 |
loadingText.textContent = {saving_label}; |
| 118 |
loadingOverlay.appendChild(loadingText); |
| 119 |
|
| 120 |
var modal = overlay ? overlay.querySelector('.abj404-setup-modal') : null; |
| 121 |
if (modal) { |
| 122 |
modal.appendChild(loadingOverlay); |
| 123 |
} |
| 124 |
} |
| 125 |
|
| 126 |
if (closeBtn) { |
| 127 |
closeBtn.addEventListener('click', dismissWizard); |
| 128 |
} |
| 129 |
if (skipBtn) { |
| 130 |
skipBtn.addEventListener('click', dismissWizard); |
| 131 |
} |
| 132 |
if (form) { |
| 133 |
form.addEventListener('submit', showSavingOverlay); |
| 134 |
} |
| 135 |
})(); |
| 136 |
</script> |
| 137 |
|