PageSourceSearch

https://typeheist.co/subscribe.js

js typeheist.co collected 2026-10-04 01:50:53 UTC 3,760 bytes, 99 lines download raw bytes

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.