PageSourceSearch

https://hospicenews.com/wp-content/plugins/wp-force-images-download/wpfid-ajax.js?ver=2.6

js hospicenews.com collected 2026-09-24 19:51:14 UTC 10,542 bytes, 268 lines download raw bytes

1/**
2 * WP-Force Images Download — AJAX Download & Size Picker
3 *
4 * Intercepts form submissions to provide seamless in-page downloads
5 * without opening a new browser tab. Falls back to normal form POST
6 * if JavaScript is unavailable or the AJAX request fails.
7 *
8 * @package WPFID
9 * @since   2.0
10 * @version 2.6
11 */
12
13/* =========================================================================
14 * EMAIL GATE HANDLER
15 * Global function — called from inline onsubmit on the email gate form.
16 * Step 1: Save email via AJAX (PHP sets the HMAC cookie in the response).
17 * Step 2: Trigger file download via the same AJAX download endpoint.
18 * ======================================================================= */
19function wpfidHandleEmailGate( event, form, gateId ) {
20	event.preventDefault();
21
22	var emailInput = form.querySelector( 'input[name="wpfid_email"]' );
23	var email      = emailInput ? emailInput.value.trim() : '';
24
25	if ( ! email || ! /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test( email ) ) {
26		if ( emailInput ) { emailInput.style.borderColor = '#e53e3e'; }
27		return false;
28	}
29
30	var submitBtn = form.querySelector( '[type="submit"]' );
31	if ( submitBtn ) {
32		submitBtn.disabled      = true;
33		submitBtn.style.opacity = '0.7';
34	}
35
36	var ajaxUrl      = ( typeof wpfid_ajax !== 'undefined' ) ? wpfid_ajax.ajax_url : '/wp-admin/admin-ajax.php';
37	var emailNonce   = form.querySelector( '[name="_wpfid_email_nonce"]' );
38	var picUrlInput  = form.querySelector( '[name="wpfid_pic_url"]' );
39	var newNameInput = form.querySelector( '[name="new_name"]' );
40	var postIdInput  = form.querySelector( '[name="wpfid_post_id"]' );
41	var picNonce     = form.querySelector( 'input[name="pic_url_nonce"]' );
42	var newNonce     = form.querySelector( 'input[name="new_name_nonce"]' );
43
44	/* Step 1: Save e-mail.
45	 * credentials:'same-origin' ensures the Set-Cookie from the PHP response
46	 * (the HMAC token) is stored so Step 2's request can send it. */
47	var saveBody = new FormData();
48	saveBody.append( 'action',             'wpfid_save_email' );
49	saveBody.append( 'wpfid_email',        email );
50	saveBody.append( '_wpfid_email_nonce', emailNonce  ? emailNonce.value  : '' );
51	saveBody.append( 'wpfid_post_id',      postIdInput ? postIdInput.value : '' );
52
53	fetch( ajaxUrl, { method: 'POST', body: saveBody, credentials: 'same-origin' } )
54		.then( function ( res ) {
55			if ( ! res.ok ) { throw new Error( 'Email save failed: ' + res.status ); }
56			return res.json();
57		} )
58		.then( function ( json ) {
59			if ( ! json || ! json.success ) {
60				throw new Error( json && json.data && json.data.message ? json.data.message : 'Email save rejected' );
61			}
62
63			/* Step 2: Download — cookie from Step 1 is now in the browser. */
64			var dlBody = new FormData();
65			dlBody.append( 'action',         'wpfid_ajax_download' );
66			dlBody.append( 'wpfid_pic_url',  picUrlInput  ? picUrlInput.value  : '' );
67			dlBody.append( 'new_name',       newNameInput ? newNameInput.value : '' );
68			dlBody.append( 'wpfid_post_id',  postIdInput  ? postIdInput.value  : '' );
69			dlBody.append( 'pic_url_nonce',  picNonce     ? picNonce.value     : '' );
70			dlBody.append( 'new_name_nonce', newNonce     ? newNonce.value     : '' );
71
72			return fetch( ajaxUrl, { method: 'POST', body: dlBody, credentials: 'same-origin' } );
73		} )
74		.then( function ( response ) {
75			if ( ! response.ok ) { throw new Error( 'Download failed: ' + response.status ); }
76
77			/* Guard: if server returned an HTML error page instead of binary data */
78			var ct = response.headers.get( 'Content-Type' ) || '';
79			if ( ct.indexOf( 'text/html' ) !== -1 ) {
80				throw new Error( 'Server returned an error page instead of a file.' );
81			}
82
83			/* Extract filename from Content-Disposition header */
84			var filename    = 'download';
85			var disposition = response.headers.get( 'Content-Disposition' );
86			if ( disposition ) {
87				var utf8Match = disposition.match( /filename\*=UTF-8''(.+)/i );
88				if ( utf8Match ) {
89					filename = decodeURIComponent( utf8Match[1].split( ';' )[0].trim() );
90				} else {
91					var match = disposition.match( /filename[^;=\n]*=["']?([^"';\n]*)["']?/ );
92					if ( match && match[1] ) { filename = decodeURIComponent( match[1] ); }
93				}
94			} else {
95				var rawUrl = picUrlInput ? picUrlInput.value : '';
96				if ( rawUrl ) { filename = rawUrl.split( '/' ).pop().split( '?' )[0] || 'download'; }
97			}
98
99			return response.blob().then( function ( blob ) {
100				return { blob: blob, filename: filename };
101			} );
102		} )
103		.then( function ( data ) {
104			var objUrl = window.URL.createObjectURL( data.blob );
105			var anchor = document.createElement( 'a' );
106			anchor.href          = objUrl;
107			anchor.download      = data.filename;
108			anchor.style.display = 'none';
109			document.body.appendChild( anchor );
110			anchor.click();
111			document.body.removeChild( anchor );
112			window.URL.revokeObjectURL( objUrl );
113
114			var gate = document.getElementById( gateId );
115			if ( gate ) {
116				var successMsg = ( typeof wpfid_ajax !== 'undefined' && wpfid_ajax.success_text )
117					? wpfid_ajax.success_text
118					: 'Thank you! Your download has started.';
119				gate.innerHTML = '<p style="color:#2f855a;margin:10px 0;font-size:0.9em;display:flex;align-items:center;gap:6px;">'
120					+ '<span class="dashicons dashicons-yes-alt"></span> ' + successMsg + '</p>';
121			}
122		} )
123		.catch( function ( err ) {
124			console.warn( 'WPFID email gate error:', err );
125			if ( submitBtn ) { submitBtn.disabled = false; submitBtn.style.opacity = '1'; }
126
127			var errEl = form.querySelector( '.wpfid-gate-error' );
128			if ( ! errEl ) {
129				errEl = document.createElement( 'p' );
130				errEl.className    = 'wpfid-gate-error';
131				errEl.style.cssText = 'color:#c53030;font-size:0.85em;margin:6px 0 0;';
132				form.appendChild( errEl );
133			}
134			errEl.textContent = ( typeof wpfid_ajax !== 'undefined' && wpfid_ajax.error_text )
135				? wpfid_ajax.error_text
136				: 'Download failed. Please try again.';
137		} );
138
139	return false;
140}
141
142/* =========================================================================
143 * MAIN DOWNLOAD IIFE
144 * Size picker update + AJAX form intercept for the standard download button.
145 * ======================================================================= */
146(function () {
147	'use strict';
148
149	document.addEventListener( 'DOMContentLoaded', function () {
150
151		/* -------------------------------------------------------
152		 * 1. Size Picker — update hidden URL field on change
153		 * ----------------------------------------------------- */
154		document.querySelectorAll( '.wpfid-size-picker' ).forEach( function ( select ) {
155			select.addEventListener( 'change', function () {
156				var form = this.closest( 'form' );
157				if ( ! form ) { return; }
158				var urlInput = form.querySelector( 'input[name="wpfid_pic_url"]' );
159				if ( urlInput ) {
160					urlInput.value = this.value;
161				}
162			} );
163		} );
164
165		/* -------------------------------------------------------
166		 * 2. AJAX Download — intercept .wpfid-download-form submit
167		 * ----------------------------------------------------- */
168		if ( typeof wpfid_ajax === 'undefined' || ! wpfid_ajax.enabled ) {
169			return; /* AJAX disabled — forms submit normally */
170		}
171
172		document.querySelectorAll( '.wpfid-download-form' ).forEach( function ( form ) {
173
174			/* Named function so we can removeEventListener in the catch fallback.
175			 * (arguments.callee is illegal in strict mode.) */
176			function handleWpfidSubmit( e ) {
177				e.preventDefault();
178
179				var formData = new FormData( form );
180				formData.set( 'action', 'wpfid_ajax_download' );
181
182				var button    = form.querySelector( '.wpfid_button, [type="submit"]' );
183				var titleSpan = button ? button.querySelector( '.wpfid_title' ) : null;
184				var origText  = '';
185
186				if ( button ) {
187					button.disabled      = true;
188					button.style.opacity = '0.7';
189					if ( titleSpan ) {
190						origText          = titleSpan.textContent;
191						titleSpan.textContent = wpfid_ajax.downloading_text || 'Downloading…';
192					}
193				}
194
195				fetch( wpfid_ajax.ajax_url, {
196					method      : 'POST',
197					body        : formData,
198					credentials : 'same-origin',
199				} )
200				.then( function ( response ) {
201					if ( ! response.ok ) { throw new Error( 'HTTP ' + response.status ); }
202
203					/* Guard: catch wp_die() HTML error pages */
204					var ct = response.headers.get( 'Content-Type' ) || '';
205					if ( ct.indexOf( 'text/html' ) !== -1 ) {
206						throw new Error( 'Server returned an error page.' );
207					}
208
209					/* Extract filename from Content-Disposition header */
210					var filename    = 'download';
211					var disposition = response.headers.get( 'Content-Disposition' );
212					if ( disposition ) {
213						var utf8Match = disposition.match( /filename\*=UTF-8''(.+)/i );
214						if ( utf8Match ) {
215							filename = decodeURIComponent( utf8Match[1].split( ';' )[0].trim() );
216						} else {
217							var match = disposition.match( /filename[^;=\n]*=["']?([^"';
217\n]*)["']?/ );
218							if ( match && match[1] ) { filename = decodeURIComponent( match[1] ); }
219						}
220					}
221
222					return response.blob().then( function ( blob ) {
223						return { blob: blob, filename: filename };
224					} );
225				} )
226				.then( function ( data ) {
227					var url    = window.URL.createObjectURL( data.blob );
228					var anchor = document.createElement( 'a' );
229					anchor.href          = url;
230					anchor.download      = data.filename;
231					anchor.style.display = 'none';
232					document.body.appendChild( anchor );
233					anchor.click();
234					document.body.removeChild( anchor );
235					window.URL.revokeObjectURL( url );
236
237					/* Update download count display (if visible on page) */
238					var container = form.closest( '.wpfid-wrapper' ) || form.parentElement;
239					var countEl   = container ? container.querySelector( '.wpfid-download-count' ) : null;
240					if ( countEl ) {
241						var num = ( parseInt( countEl.getAttribute( 'data-count' ), 10 ) || 0 ) + 1;
242						countEl.setAttribute( 'data-count', num );
243						countEl.textContent = num + ( 1 === num ? ' download' : ' downloads' );
244					}
245				} )
246				.catch( function () {
247					/* Fallback: remove interceptor and submit normally (opens in new tab) */
248					form.removeEventListener( 'submit', handleWpfidSubmit );
249					form.setAttribute( 'target', '_blank' );
250					form.setAttribute( 'rel', 'noopener noreferrer' );
251					form.submit();
252				} )
253				.finally( function () {
254					if ( button ) {
255						button.disabled      = false;
256						button.style.opacity = '1';
257						if ( titleSpan && origText ) {
258							titleSpan.textContent = origText;
259						}
260					}
261				} );
262			}
263
264			form.addEventListener( 'submit', handleWpfidSubmit );
265		} );
266	} );
267
268}());

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.