1function submitHandler(event) { 2 event.preventDefault(); 3 const container = event.target.parentNode; 4 const form = container.querySelector(".newsletter-form"); 5 const formInputEmail = container.querySelector(".newsletter-form-input[name='email']"); 6 const formInputFirstName = container.querySelector(".newsletter-form-input[name='firstName']"); 7 const success = container.querySelector(".newsletter-success"); 8 const errorContainer = container.querySelector(".newsletter-error"); 9 const errorMessage = container.querySelector(".newsletter-error-message"); 10 const submitButton = container.querySelector(".newsletter-form-button"); 11 const loadingButton = container.querySelector(".newsletter-loading-button"); 12 13 const rateLimit = () => { 14 errorContainer.style.display = "flex"; 15 errorMessage.innerText = "Too many signups, please try again in a little while"; 16 submitButton.style.display = "none"; 17 formInputEmail.style.display = "none"; 18 formInputFirstName.style.display = "none"; 19 } 20 21 // Compare current time with time of previous sign up 22 const time = new Date(); 23 const timestamp = time.valueOf(); 24 const previousTimestamp = localStorage.getItem("loops-form-timestamp"); 25 26 // If last sign up was less than a minute ago 27 // display error 28 if (previousTimestamp && Number(previousTimestamp) + 60000 > timestamp) { 29 rateLimit(); 30 return; 31 } 32 localStorage.setItem("loops-form-timestamp", timestamp); 33 34 submitButton.style.display = "none"; 35 loadingButton.style.display = "flex"; 36 37 const formBody = new URLSearchParams(); 38 formBody.append("userGroup", "www-subscribe"); 39 formBody.append("email", formInputEmail.value); 40 formBody.append("firstName", formInputFirstName.value); 41 formBody.append("mailingLists", "cm1k52a2f00e20lk37tiq72af, cm1k52li200ux0ll995ok870g, cm1kf5p5n01ox0llae7u0c3rp"); 42 43 fetch(event.target.action, { 44 method: "POST", 45 body: formBody.toString(), 46 headers: { 47 "Content-Type": "application/x-www-form-urlencoded", 48 }, 49 }) 50 .then((res) => [res.ok, res.json(), res]) 51 .then(([ok, dataPromise, res]) => { 52 if (ok) { 53 // If response successful 54 // display success 55 success.style.display = "flex"; 56 form.reset(); 57 } else { 58 // If response unsuccessful 59 // display error message or response status 60 dataPromise.then(data => { 61 errorContainer.style.display = "flex"; 62 errorMessage.innerText = data.message 63 ? data.message 64 : res.statusText; 65 }); 66 } 67 }) 68 .catch(error => { 69 // check for cloudflare error 70 if (error.message === "Failed to fetch") { 71 rateLimit(); 72 return; 73 } 74 // If error caught 75 // display error message if available 76 errorContainer.style.display = "flex"; 77 if (error.message) errorMessage.innerText = error.message; 78 localStorage.setItem("loops-form-timestamp", ''); 79 }) 80 .finally(() => { 81 formInputEmail.style.display = "none"; 82 formInputFirstName.style.display = "none"; 83 loadingButton.style.display = "none"; 84 }); 85 } 86 87 const formContainers = document.getElementsByClassName( 88 "newsletter-form-container" 89 ); 90 91 for (let i = 0; i < formContainers.length; i++) { 92 const formContainer = formContainers[i] 93 const handlersAdded = formContainer.classList.contains('newsletter-handlers-added') 94 if (handlersAdded) continue; 95 formContainer 96 .querySelector(".newsletter-form") 97 .addEventListener("submit", submitHandler); 98 formContainer.classList.add("newsletter-handlers-added"); 99 }
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.