1/** 2 * Email-Gated Discount Tab â front-end behaviour. 3 * Opens the tab, submits the e-mail to the server (which validates + stores), 4 * then reveals the returned code. The code is never in the page source. 5 */ 6(function () { 7 'use strict'; 8 9 function init() { 10 var wrap = document.getElementById('egdTab'); 11 if (!wrap || typeof EGD === 'undefined') return; 12 13 var handle = wrap.querySelector('.egd-handle'); 14 var panel = wrap.querySelector('.egd-panel'); 15 var closeBtn = wrap.querySelector('.egd-close'); 16 var form = wrap.querySelector('.egd-form'); 17 var emailIn = wrap.querySelector('.egd-email'); 18 var consent = wrap.querySelector('.egd-consent-cb'); 19 var submit = wrap.querySelector('.egd-submit'); 20 var errorEl = wrap.querySelector('.egd-error'); 21 var formState = wrap.querySelector('.egd-state-form'); 22 var codeState = wrap.querySelector('.egd-state-code'); 23 var codeEl = wrap.querySelector('.egd-code'); 24 var copyBtn = wrap.querySelector('.egd-copy'); 25 26 function open() { 27 wrap.classList.add('is-open'); 28 panel.hidden = false; 29 handle.setAttribute('aria-expanded', 'true'); 30 if (formState && !formState.hidden && emailIn) { 31 setTimeout(function () { emailIn.focus(); }, 250); 32 } 33 } 34 function close() { 35 wrap.classList.remove('is-open'); 36 handle.setAttribute('aria-expanded', 'false'); 37 setTimeout(function () { 38 if (!wrap.classList.contains('is-open')) panel.hidden = true; 39 }, 300); 40 } 41 42 handle.addEventListener('click', function () { 43 wrap.classList.contains('is-open') ? close() : open(); 44 }); 45 if (closeBtn) closeBtn.addEventListener('click', close); 46 document.addEventListener('keydown', function (e) { 47 if (e.key === 'Escape' && wrap.classList.contains('is-open')) close(); 48 }); 49 document.addEventListener('click', function (e) { 50 if (!wrap.contains(e.target) && wrap.classList.contains('is-open')) close(); 51 }); 52 53 function showError(msg) { 54 if (!errorEl) return; 55 errorEl.textContent = msg; 56 errorEl.hidden = false; 57 } 58 function clearError() { 59 if (errorEl) { errorEl.hidden = true; errorEl.textContent = ''; } 60 } 61 62 function validEmail(v) { 63 return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v); 64 } 65 66 if (form) { 67 form.addEventListener('submit', function (e) { 68 e.preventDefault(); 69 clearError(); 70 var email = (emailIn.value || '').trim(); 71 if (!validEmail(email)) { 72 showError(EGD.i18n.invalid); 73 emailIn.focus(); 74 return; 75 } 76 submit.disabled = true; 77 var label = submit.textContent; 78 submit.textContent = EGD.i18n.sending; 79 80 var body = new URLSearchParams(); 81 body.set('action', 'egd_reveal'); 82 body.set('nonce', EGD.nonce); 83 body.set('email', email); 84 body.set('consent', consent && consent.checked ? '1' : '0'); 85 86 fetch(EGD.ajaxUrl, { 87 method: 'POST', 88 credentials: 'same-origin', 89 headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, 90 body: body.toString() 91 }) 92 .then(function (r) { return r.json(); }) 93 .then(function (res) { 94 submit.disabled = false; 95 submit.textContent = label; 96 if (res && res.success && res.data && res.data.code) { 97 codeEl.textContent = res.data.code; 98 formState.hidden = true; 99 codeState.hidden = false; 100 } else { 101 showError((res && res.data && res.data.message) ? res.data.message : EGD.i18n.error); 102 } 103 }) 104 .catch(function () { 105 submit.disabled = false;
106 submit.textContent = label; 107 showError(EGD.i18n.error); 108 }); 109 }); 110 } 111 112 if (copyBtn) { 113 copyBtn.addEventListener('click', function () { 114 var code = codeEl.textContent || ''; 115 var orig = copyBtn.getAttribute('data-copy') || copyBtn.textContent; 116 var done = function () { 117 copyBtn.textContent = copyBtn.getAttribute('data-copied') || 'Copied!'; 118 copyBtn.classList.add('is-copied'); 119 setTimeout(function () { 120 copyBtn.textContent = orig; 121 copyBtn.classList.remove('is-copied'); 122 }, 2000); 123 }; 124 if (navigator.clipboard && navigator.clipboard.writeText) { 125 navigator.clipboard.writeText(code).then(done).catch(fallback); 126 } else { 127 fallback(); 128 } 129 function fallback() { 130 var ta = document.createElement('textarea'); 131 ta.value = code; ta.setAttribute('readonly', ''); 132 ta.style.position = 'absolute'; ta.style.left = '-9999px'; 133 document.body.appendChild(ta); ta.select(); 134 try { document.execCommand('copy'); done(); } catch (e) {} 135 document.body.removeChild(ta); 136 } 137 }); 138 } 139 } 140 141 if (document.readyState === 'loading') { 142 document.addEventListener('DOMContentLoaded', init); 143 } else { 144 init(); 145 } 146})();
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.