1/* 2 Email list signup. 3 4 Posts the address to /mailingList.php, which sends a confirmation link. 5 The address only joins the list once that link is opened, so the success 6 copy here says "check your email", not "you're subscribed". 7*/ 8(function () { 9 var EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/; 10 var GENERIC_ERROR = 'There was an error processing your request. Please try again.'; 11 12 function setMessage (node, text, isError) { 13 node.textContent = text; 14 node.hidden = !text; 15 node.classList.toggle('is-error', !!isError); 16 } 17 18 function initSignup (root) { 19 var form = root.querySelector('[data-signup-form]'); 20 var input = root.querySelector('[data-signup-input]'); 21 var button = root.querySelector('[data-signup-button]'); 22 var message = root.querySelector('[data-signup-message]'); 23 if (!form || !input || !message) { return; } 24 25 var submitting = false; 26 27 form.addEventListener('submit', function (event) { 28 event.preventDefault(); 29 // Sending the confirmation email takes a beat -- block re-submits until it lands. 30 if (submitting) { return; } 31 32 var email = input.value.trim(); 33 if (!EMAIL_PATTERN.test(email)) { 34 setMessage(message, 'Please enter a valid email address.', true); 35 return; 36 } 37 38 submitting = true; 39 if (button) { button.disabled = true; } 40 setMessage(message, '', false); 41 42 fetch('/mailingList.php', { 43 method: 'POST', 44 headers: { 'Content-Type': 'application/json' }, 45 body: JSON.stringify({ action: 'add', email: email }) 46 }) 47 .then(function (response) { return response.json(); }) 48 .then(function (result) { 49 result = result || {}; 50 if (result.ok === false) { 51 setMessage(message, result.message || GENERIC_ERROR, true); 52 return; 53 } 54 setMessage(message, result.message || 'Almost there! Check your email for a confirmation link.', false); 55 form.hidden = true; 56 }) 57 .catch(function () { 58 setMessage(message, GENERIC_ERROR, true); 59 }) 60 .then(function () { 61 submitting = false; 62 if (button) { button.disabled = false; } 63 }); 64 }); 65 } 66 67 document.addEventListener('DOMContentLoaded', function () { 68 var roots = document.querySelectorAll('[data-email-signup]'); 69 for (var i = 0; i < roots.length; i++) { initSignup(roots[i]); } 70 }); 71})();
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.