PageSourceSearch

https://basecamp.com/assets/js/modules/newsletter.js?v=1.5.6

js basecamp.com collected 2026-09-24 06:36:48 UTC 2,275 bytes, 99 lines download raw bytes

1function ready() {
2
3  document.querySelectorAll('.newsletter').forEach(function(newsletter) {
4
5    const newsletterForm = newsletter.querySelector('form');
6    const newsletterInput = newsletterForm && newsletterForm.querySelector('input[type="email"]');
7    const newsletterButton = newsletterForm && newsletterForm.querySelector('button');
8
9    if(!newsletterForm || !newsletterInput || !newsletterButton) return;
10
11    newsletterForm.addEventListener('submit', function(e) {
12
13      e.preventDefault();
14
15      newsletterInput.value = newsletterInput.value.trim();
16
17      if(newsletterInput.value) {
18
19        const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(newsletterInput.value);
20
21        if(isValid) {
22
23          fetch(newsletterForm.action, {
24
25            body: new FormData(newsletterForm),
26            method: newsletterForm.method,
27            mode: 'no-cors'
28
29          }).then(() => {
30
31            newsletterForm.reset();
32
33            newsletter.classList.add('newsletter--success');
34
35          }).catch(() => {
36
37            handoff();
38
39          }).finally(() => {
40
41            newsletterButton.disabled = false;
42
43          });
44
45          newsletterButton.disabled = true;
46
47        } else {
48
49          newsletter.classList.add('newsletter--error');
50
51        }
52
53      }
54
55    });
56
57    function handoff() {
58
59      const action = newsletterForm.getAttribute('action');
60      const target = newsletterForm.getAttribute('target');
61
62      newsletterForm.action = action.replace('/subscribe/post-json', '/subscribe/post').replace(/&c=\?$/, '');
63      const popup = window.open('', 'newsletter');
64
65      if(popup) popup.opener = null;
66
67      newsletterForm.target = popup ? 'newsletter' : '_self';
68
69      newsletterForm.submit();
70
71      newsletterForm.setAttribute('action', action);
72
73      if(target) {
74
75        newsletterForm.setAttribute('target', target);
76
77      } else {
78
79        newsletterForm.removeAttribute('target');
80
81      }
82
83    }
84
85    function removeError() {
86
87      newsletter.classList.remove('newsletter--error', 'newsletter--success');
88
89    }
90
91    newsletterInput.addEventListener('click', removeError);
92    newsletterInput.addEventListener('focus', removeError);
93    newsletterInput.addEventListener('input', removeError);
94
95  });
96
97}
98
99export { ready };

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.