PageSourceSearch

https://theeasymaster.com/wp-content/themes/easymaster-theme-main/assets/newsletter.js?ver=1790097300

js theeasymaster.com collected 2026-09-24 14:54:17 UTC 4,143 bytes, 146 lines download raw bytes

1/**
2 * Newsletter forms.
3 *
4 * Binds by class rather than by a list of IDs, so a form added anywhere works
5 * without anyone remembering to come back here -- which is how the sidebar
6 * widget ended up submitting as a plain POST and reloading the page.
7 *
8 * Every outcome is said out loud: the old handler wrote a message on success
9 * and, on failure, un-hid an empty paragraph, so a mistyped address produced
10 * a blank space and no reason.
11 */
12( function () {
13	'use strict';
14
15	function config() {
16		var data = window.EasyMasterData || {};
17
18		return {
19			ajaxUrl: data.ajaxUrl || '',
20			nonce: data.nonce || ''
21		};
22	}
23
24	function setUp( form ) {
25		var message = form.querySelector( '.em-newsletter-msg' );
26		var input = form.querySelector( 'input[name="email"]' );
27		var button = form.querySelector( 'button[type="submit"]' );
28		var trap = form.querySelector( 'input[name="em_website"]' );
29		var source = form.querySelector( 'input[name="source"]' );
30		var busy = false;
31
32		if ( ! message || ! input ) {
33			return;
34		}
35
36		var label = button ? button.textContent : '';
37
38		function say( text, kind ) {
39			message.textContent = text;
40			message.hidden = false;
41			message.classList.remove( 'is-error', 'is-success' );
42			message.classList.add( kind === 'error' ? 'is-error' : 'is-success' );
43		}
44
45		function setBusy( state ) {
46			busy = state;
47			form.classList.toggle( 'is-busy', state );
48
49			if ( button ) {
50				button.disabled = state;
51				button.textContent = state ? 'Subscribing…' : label;
52			}
53		}
54
55		form.addEventListener( 'submit', function ( event ) {
56			event.preventDefault();
57
58			if ( busy ) {
59				return;
60			}
61
62			var email = input.value.trim();
63			var settings = config();
64
65			if ( ! email ) {
66				say( 'Enter your email address first.', 'error' );
67				input.focus();
68				return;
69			}
70
71			// The browser's own check, before spending a request on it.
72			if ( input.checkValidity && ! input.checkValidity() ) {
73				say( 'That does not look like an email address.', 'error' );
74				input.focus();
75				return;
76			}
77
78			if ( ! settings.ajaxUrl ) {
79				say( 'The form is not available right now. Please try again later.', 'error' );
80				return;
81			}
82
83			var body = new URLSearchParams();
84			body.append( 'action', 'em_newsletter_subscribe' );
85			body.append( 'nonce', settings.nonce );
86			body.append( 'email', email );
87			body.append( 'em_website', trap ? trap.value : '' );
88			body.append( 'source', source ? source.value : '' );
89
90			setBusy( true );
91
92			fetch( settings.ajaxUrl, {
93				method: 'POST',
94				credentials: 'same-origin',
95				headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
96				body: body.toString()
97			} )
98				.then( function ( response ) {
99					// A rejection is still JSON; a nonce failure is the bare
100					// string "-1", which JSON.parse would throw on.
101					return response.text().then( function ( text ) {
102						try {
103							return { status: response.status, payload: JSON.parse( text ) };
104						} catch ( e ) {
105							return { status: response.status, payload: null };
106						}
107					} );
108				} )
109				.then( function ( result ) {
110					var payload = result.payload;
111
112					if ( payload && payload.success ) {
113						say( ( payload.data && payload.data.message ) || 'Subscribed!', 'success' );
114						input.value = '';
115						return;
116					}
117
118					if ( payload && payload.data && payload.data.message ) {
119						say( payload.data.message, 'error' );
120						return;
121					}
122
123					say( 'That did not go through. Please reload the page and try again.', 'error' );
124				} )
125				.catch( function () {
126					say( 'Could not reach the server. Check your connection and try again.', 'error' );
127				} )
128				.then( function () {
129					setBusy( false );
130				} );
131		} );
132
133		// Clear a refusal as soon as the reader starts fixing it.
134		input.addEventListener( 'input', function () {
135			if ( message.classList.contains( 'is-error' ) ) {
136				message.hidden = true;
137				message.textContent = '';
138				message.classList.remove( 'is-error' );
139			}
140		} );
141	}
142
143	document.addEventListener( 'DOMContentLoaded', function () {
144		Array.prototype.forEach.call( document.querySelectorAll( '.em-newsletter-form' ), setUp );
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.