PageSourceSearch

https://www.danahuff.net/wp-content/plugins/wp-polls/js/wp-polls.js?ver=3.0.0

js danahuff.net collected 2026-09-25 00:38:09 UTC 6,471 bytes, 231 lines download raw bytes

1/**
2 * WP-Polls front end.
3 *
4 * Nothing here is exported. Poll markup asks for behaviour through
5 * data-poll-action / data-poll-id attributes, which are picked up by the
6 * delegated listener at the bottom of this file.
7 */
8( function() {
9	'use strict';
10
11	const l10n = window.wpPollsL10n || {};
12
13	// Matches the fade duration used before.
14	const FADE_DURATION = 400;
15
16	/**
17	 * Whether the visitor has asked for less movement.
18	 *
19	 * The fade is an inline transition, so a stylesheet media query cannot
20	 * reach it the way it reaches the spinner and the result bars -- an inline
21	 * style wins. Read here instead, and read on every call rather than once at
22	 * load, because the setting can change while the page is open.
23	 *
24	 * @return {boolean} True when motion should be skipped.
25	 */
26	function prefersReducedMotion() {
27		return (
28			typeof window.matchMedia === 'function' &&
29			window.matchMedia( '(prefers-reduced-motion: reduce)' ).matches
30		);
31	}
32
33	// The Poll Container For A Given Poll
34	function pollContainer( currentPollId ) {
35		return document.getElementById( 'polls-' + currentPollId );
36	}
37
38	// Show Or Hide The Loading Indicator
39	// The indicator is hidden by a stylesheet rule, so it needs an explicit
40	// display value rather than just clearing the inline one.
41	function setLoading( currentPollId, visible ) {
42		const loading = document.getElementById(
43			'polls-' + currentPollId + '-loading',
44		);
45		if ( loading ) {
46			loading.style.display = visible ? 'block' : 'none';
47		}
48	}
49
50	// Fade An Element To The Given Opacity
51	function fadeTo( element, opacity ) {
52		if ( ! element ) {
53			return;
54		}
55
56		// Straight to the end state when motion is unwelcome: the poll still
57		// dims, it just does not travel there.
58		element.style.transition = prefersReducedMotion()
59			? ''
60			: 'opacity ' + FADE_DURATION + 'ms';
61		element.style.opacity = opacity;
62	}
63
64	// Make Sure A Poll Is Fully Visible
65	// Only ever clears opacity, never animates towards it. Fading a poll *in*
66	// would have to start it at zero opacity, and browsers freeze animations in
67	// background tabs, which would leave the poll invisible until it is looked at.
68	function show( element ) {
69		if ( element ) {
70			element.style.transition = '';
71			element.style.opacity = '';
72		}
73	}
74
75	// When User Vote For Poll
76	function pollVote( currentPollId ) {
77		const form = document.getElementById( 'polls_form_' + currentPollId );
78		if ( ! form ) {
79			return;
80		}
81
82		const multipleField = document.getElementById(
83			'poll_multiple_ans_' + currentPollId,
84		);
85		const pollMultipleAns = multipleField
86			? parseInt( multipleField.value, 10 )
87			: 0;
88
89		const selected = [];
90		const choices = form.querySelectorAll(
91			'input[type="checkbox"], input[type="radio"], option',
92		);
93		Array.prototype.forEach.call( choices, function( choice ) {
94			// Inputs expose 'checked', options expose 'selected'.
95			if ( choice.checked || choice.selected ) {
96				selected.push( choice.value );
97			}
98		} );
99
100		if ( pollMultipleAns > 0 ) {
101			if ( selected.length === 0 ) {
102				alert( l10n.text_valid );
103			} else if ( selected.length > pollMultipleAns ) {
104				alert( l10n.text_multiple + ' ' + pollMultipleAns );
105			} else {
106				pollProcess( currentPollId, selected.join( ',' ) );
107			}
108			return;
109		}
110
111		const pollAnswerId = selected.length
112			? parseInt( selected[ selected.length - 1 ], 10 )
113			: 0;
114		if ( pollAnswerId > 0 ) {
115			pollProcess( currentPollId, pollAnswerId );
116		} else {
117			alert( l10n.text_valid );
118		}
119	}
120
121	// Send A Poll Request And Swap In The Markup That Comes Back
122	function pollRequest( currentPollId, view, extraFields ) {
123		const nonceField = document.getElementById(
124			'poll_' + currentPollId + '_nonce',
125		);
126
127		const body = new URLSearchParams();
128		body.append( 'action', 'polls' );
129		body.append( 'view', view );
130		body.append( 'poll_id', currentPollId );
131		body.append(
132			'poll_' + currentPollId + '_nonce',
133			nonceField ? nonceField.value : '',
134		);
135		if ( extraFields ) {
136			Object.keys( extraFields ).forEach( function( name ) {
137				body.append( name, extraFields[ name ] );
138			} );
139		}
140
141		fadeTo( pollContainer( currentPollId ), 0 );
142		setLoading( currentPollId, true );
143
144		fetch( l10n.ajax_url, {
145			method: 'POST',
146			credentials: 'include',
147			cache: 'no-cache',
148			body,
149		} )
150			.then( function( response ) {
151				return response.text();
152			} )
153			.then( function( data ) {
154				pollProcessSuccess( currentPollId, data );
155			} )
156			.catch( function() {
157				// Leave the poll readable rather than stuck faded out behind a spinner.
158				setLoading( currentPollId, false );
159				show( pollContainer( currentPollId ) );
160			} );
161	}
162
163	// Process Poll (User Click "Vote" Button)
164	function pollProcess( currentPollId, pollAnswerId ) {
165		const fields = {};
166		fields[ 'poll_' + currentPollId ] = pollAnswerId;
167		pollRequest( currentPollId, 'process', fields );
168	}
169
170	// Poll's Result (User Click "View Results" Link)
171	function pollResult( currentPollId ) {
172		pollRequest( currentPollId, 'result' );
173	}
174
175	// Poll's Voting Booth (User Click "Vote" Link)
176	function pollBooth( currentPollId ) {
177		pollRequest( currentPollId, 'booth' );
178	}
179
180	// Poll Process Successfully
181	function pollProcessSuccess( currentPollId, data ) {
182		const container = pollContainer( currentPollId );
183		if ( container ) {
184			const parsed = document.createElement( 'div' );
185			parsed.innerHTML = data;
186			container.replaceWith.apply(
187				container,
188				Array.prototype.slice.call( parsed.childNodes ),
189			);
190		}
191
192		setLoading( currentPollId, false );
193
194		// The old poll was faded out and has now been thrown away, so all that is
195		// left to do is make sure the markup that replaced it is visible.
196		show( pollContainer( currentPollId ) );
197	}
198
199	// On Click Events
200	document.addEventListener( 'click', function( event ) {
201		const target = event.target;
202		if ( ! target || typeof target.closest !== 'function' ) {
203			return;
204		}
205
206		const trigger = target.closest( '[data-poll-action]' );
207		if ( ! trigger ) {
208			return;
209		}
210
211		const pollId = trigger.getAttribute( 'data-poll-id' );
212
213		// The result and booth templates use anchors, so stop the browser
214		// from following the placeholder href while the request runs.
215		if ( trigger.tagName === 'A' ) {
216			event.preventDefault();
217		}
218
219		switch ( trigger.getAttribute( 'data-poll-action' ) ) {
220			case 'vote':
221				pollVote( pollId );
222				break;
223			case 'result':
224				pollResult( pollId );
225				break;
226			case 'booth':
227				pollBooth( pollId );
228				break;
229		}
230	} );
231}() );

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.