PluginProbe
404 Solution / 4.3.3
404 Solution v4.3.3
4.3.5 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 4.2.0 4.1.19 4.1.18 4.1.17 4.1.16 4.1.15 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.1.7 4.1.6 4.1.5 4.1.4 4.1.3 trunk 2.30.0 All 109 releases
404-solution / includes / html / setupWizardScript.html

setupWizardScript.html in 404 Solution 4.3.3, at includes/html/setupWizardScript.html

137 lines 4.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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