PageSourceSearch

https://www.alfredstreet.org/wp-content/plugins/download-monitor/assets/js/dlm-xhr.js?ver=5.2.9

js alfredstreet.org collected 2026-09-24 09:53:16 UTC 26,444 bytes, 713 lines download raw bytes

1/* eslint-disable camelcase */
2/* eslint-disable no-undef */
3jQuery( function( $ ) {
4	// Let's initiate the XHR.
5	new DLM_XHR_Download();
6} );
7
8class DLM_XHR_Download {
9	responsHeaders = {};
10
11	constructor() {
12		// dlmXHRinstance defined in inline script
13		dlmXHRinstance = this;
14		this.init();
15	}
16
17	init() {
18		dlmXHRinstance.attachButtonEvent();
19	}
20
21	// Function to attach events for the download buttons
22	attachButtonEvent() {
23		// Stop propagation on child elements
24		jQuery( 'html,body' ).on( 'click', '.dlm-no-access-modal-window > div', function( e ) {
25			e.stopPropagation();
26		} );
27		// Close modal on these clicks
28		jQuery( 'html, body' ).on( 'click', '.dlm-no-access-modal-overlay, .dlm-no-access-modal-close, .dlm-no-access-modal-window', function( e ) {
29			e.stopPropagation();
30			jQuery( '#dlm-no-access-modal' ).remove();
31		} );
32		// Close modal on ESC key press
33		jQuery( document ).on( 'keydown', function( e ) {
34			if ( e.key === 'Escape' ) {
35				jQuery( '#dlm-no-access-modal' ).remove();
36			}
37		} );
38
39		jQuery( 'html, body' ).on( 'click', 'a', function( e ) {
40			let url = jQuery( this ).attr( 'href' );
41			// Let's see if we need to do XHR download on this link.
42			let noXHR = false;
43			if ( jQuery( this ).hasClass( 'dlm-no-xhr-download' ) ) {
44				noXHR = true;
45			}
46
47			if ( 'undefined' !== typeof dlmNonXHRGlobalLinks && dlmNonXHRGlobalLinks.length > 0 ) {
48				if ( 'undefined' !== typeof url ) {
49					dlmNonXHRGlobalLinks.forEach( ( element ) => {
50						if ( url.indexOf( element ) >= 0 ) {
51							noXHR = true;
52						}
53					} );
54				}
55			}
56
57			if ( noXHR ) { // No XHR so return;
58				jQuery( '#dlm-no-access-modal' ).remove(); // Close the modal also in case we opened it before.
59				return;
60			}
61
62			if ( typeof url === 'string' ) {
63				try {
64					url = new URL( url, window.location.origin ).href;
65				} catch ( e ) {}
66			}
67
68			jQuery( document ).trigger( 'dlm-xhr-download-button-click', [ url, this, dlmXHRGlobalLinks ] );
69			if ( 'undefined' !== typeof url && url.indexOf( dlmXHRGlobalLinks ) >= 0 ) {
70				const redirect_link = jQuery( this ).data( 'redirect' ),
71					  target = jQuery( this ).attr( 'target' );
72				// Check if the link has a target attribute, and if it does, we need to open it in a new window.
73				if ( 'undefined' !== typeof redirect_link && true === redirect_link && '_blank' === target ) {
74					// If we need to redirect/open in a new tab, then we do not need to do XHR, so return.
75					return;
76				}
77				dlmXHRinstance.handleDownloadClick( this, e );
78			}
79		} );
80	}
81
82	handleDownloadClick( obj, e ) {
83		e.stopPropagation();
84		const href = obj.getAttribute( 'href' );
85
86		const triggerObject = {
87			button: obj,
88			href,
89			buttonObj: jQuery( obj ),
90		};
91
92		// Show the progress bar after complete download also
93		if ( triggerObject.href.indexOf( 'blob:http' ) !== -1 ) {
94			/*triggerObject.buttonObj.addClass('download-100');
95			 setTimeout(function () {
96			 triggerObject.buttonObj.removeClass('download-100');
97			 }, 1500);*/
98
99			return;
100		}
101
102		if ( '#' === triggerObject.href ) {
103			return;
104		}
105
106		e.preventDefault();
107		dlmXHRinstance.retrieveBlob( triggerObject );
108	}
109
110	retrieveBlob( triggerObject ) {
111		const instance = this;
112		const {
113			button,
114			href,
115			buttonObj,
116		} = triggerObject;
117
118		// This will hold the file as a local object URL
119		let _OBJECT_URL;
120		const request = new XMLHttpRequest();
121		const $setCookie = dlmXHR.prevent_duplicates,
122			  buttonTarget = buttonObj.attr( 'target' );
123		let buttonClass = buttonObj.attr( 'class' );
124		buttonClass = ( 'undefined' !== typeof buttonClass && '' !== buttonClass ) ? buttonClass.replace( 'dlm-download-started', '' ).replace( 'dlm-download-completed', '' ) : '';
125
126		buttonObj.addClass( 'dlm-download-started' );
127		button.setAttribute( 'href', '#' );
128		button.removeAttribute( 'download' );
129		button.setAttribute( 'disabled', 'disabled' );
130		if ( dlmXHRProgress ) {
131			const loading_gif = '<img src="' + dlmXHRgif + '" class="dlm-xhr-loading-gif">';
132			button.innerHTML += loading_gif;
133		}
134
135		// Trigger the `dlm_download_triggered` action
136		jQuery( document ).trigger( 'dlm_download_triggered', [ this, button, buttonObj, _OBJECT_URL, request ] );
137		let check_headers = false;
138		request.responseType = 'blob';
139		request.onreadystatechange = function() {
140			const {
141				status,
142				readyState,
143				statusText,
144			} = request;
145			const headers = request
146				.getAllResponseHeaders()
147				.split( '\r\n' )
148				.reduce( ( result, current ) => {
149					const [ name, value ] = current.split( ': ' );
150					result[ name ] = value;
151					return result;
152				}, {} );
153
154			if ( Object.keys( headers ).length > 1 ) {
155				check_headers = true;
156				// Set the response headers to the instance so that we can use it later.
157				instance.responseHeaders = headers;
158			}
159
160			let file_name = 'download';
161			let dlmFilenameHeader = false,
162				dlmNoWaypoints = false,
163				dlmRedirectHeader = false,
164				dlmExternalDownloadHeader = false,
165				dlmNoAccessHeader = null,
166				dlmNoAccessModalHeader = false,
167				dlmErrorHeader = false,
168				dlmDownloadIdHeader = false,
169				dlmDownloadVersionHeader = false,
170				dlmNoAccessModalTextHeader = false;
171
172			/**
173			 * Old headers check
174			 */
175			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-file-name' ] ) {
176				dlmFilenameHeader = instance.responseHeaders[ 'dlm-file-name' ];
177			}
178			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-no-waypoints' ] ) {
179				dlmNoWaypoints = true;
180			}
181			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-redirect' ] ) {
182				dlmRedirectHeader = instance.responseHeaders[ 'dlm-redirect' ];
183			}
184			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-external-download' ] ) {
185				dlmExternalDownloadHeader = true;
186			}
187			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-no-access' ] ) {
188				dlmNoAccessHeader = instance.responseHeaders[ 'dlm-no-access' ];
189			}
190			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-no-access-modal' ] ) {
191				dlmNoAccessModalHeader = instance.responseHeaders[ 'dlm-no-access-modal' ];
192			}
193			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-error' ] ) {
194				dlmErrorHeader = instance.responseHeaders[ 'dlm-error' ];
195			}
196			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-download-id' ] ) {
197				dlmDownloadIdHeader = instance.responseHeaders[ 'dlm-download-id' ];
198			}
199			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-version-id' ] ) {
200				dlmDownloadVersionHeader = instance.responseHeaders[ 'dlm-version-id' ];
201			}
202			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-no-access-modal-text' ] ) {
203				dlmNoAccessModalTextHeader = instance.responseHeaders[ 'dlm-no-access-modal-text' ];
204			}
205			// End old headers check
206
207			/**
208			 * New headers check
209			 */
210			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-file-name' ] ) {
211				dlmFilenameHeader = instance.responseHeaders[ 'x-dlm-file-name' ];
212			}
213			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-no-waypoints' ] ) {
214				dlmNoWaypoints = true;
215			}
216			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-redirect' ] ) {
217				dlmRedirectHeader = instance.responseHeaders[ 'x-dlm-redirect' ];
218			}
219			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-external-download' ] ) {
220				dlmExternalDownloadHeader = true;
221			}
222			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-no-access' ] ) {
223				dlmNoAccessHeader = instance.responseHeaders[ 'x-dlm-no-access' ];
224			}
225			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-no-access-modal' ] ) {
226				dlmNoAccessModalHeader = instance.responseHeaders[ 'x-dlm-no-access-modal' ];
227			}
228			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-error' ] ) {
229				dlmErrorHeader = instance.responseHeaders[ 'x-dlm-error' ];
230			}
231			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-download-id' ] ) {
232				dlmDownloadIdHeader = instance.responseHeaders[ 'x-dlm-download-id' ];
233			}
234			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-version-id' ] ) {
235				dlmDownloadVersionHeader = instance.responseHeaders[ 'x-dlm-version-id' ];
236			}
237			if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-no-access-modal-text' ] ) {
238				dlmNoAccessModalTextHeader = instance.responseHeaders[ 'x-dlm-no-access-modal-text' ];
239			}
240
241			// End new headers check
242
243			if ( dlmFilenameHeader ) {
244				file_name = dlmFilenameHeader.replace( /\"/g, '' ).replace( ';', '' );
245				file_name = decodeURI( file_name );
246			} else if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'content-disposition' ] ) {
247				file_name = instance.responseHeaders[ 'content-disposition' ].split( /(?:filename\*=UTF-8'')|(?:filename=)/ )[ 1 ];
248				file_name = file_name.replace( /\"/g, '' ).replace( ';', '' );
249				// We use this method because we urlencoded it on the server so that characters like chinese or persian are not broken
250				file_name = decodeURI( file_name );
251			}
252
253			// Error translations
254			if ( dlmErrorHeader ) {
255				//var obj = { key: undefined };
256				if ( dlmErrorHeader in dlmXHRtranslations ) {
257					dlmErrorHeader = dlmXHRtranslations[ dlmErrorHeader ];
258				} else {
259					dlmErrorHeader = dlmXHRtranslations.error;
260				}
261			}
262
263			// Let's check for DLM request headers
264			if ( request.readyState === 2 ) {
265				// Add other checks for responseHeaders that can be taken care of from extensions.
266				if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-force-abort' ] && '' !== instance.responseHeaders[ 'x-dlm-force-abort' ] ) {
267					button.removeAttribute( 'download' );
268					button.setAttribute( 'href', href );
269					buttonObj.removeClass().addClass( buttonClass ).find( 'span.dlm-xhr-progress' ).remove();
270					buttonObj.find( '.dlm-xhr-loading-gif' ).remove();
271					request.abort();
272					jQuery( '#dlm-no-access-modal' ).remove();
273					return;
274				}
275
276				// If the dlm-no-waypoints header is set we need to redirect.
277				if ( dlmNoWaypoints ) {
278					request.abort();
279					if ( dlmRedirectHeader ) {
280						window.location.href = dlmRedirectHeader;
281						return;
282					}
283					window.location.href = href;
284					return;
285				}
286
287				// If it's an external link we need to redirect.
288				if ( dlmExternalDownloadHeader ) {
289					request.abort();
290					dlmXHRinstance.dlmExternalDownload( instance.responseHeaders, button, buttonObj, file_name, href );
291					return;
292				}
293
294				// If there are no specific DLM headers then we need to abort and redirect.
295				const responseDLM = Object.keys( instance.responseHeaders ).filter( ( element ) => {
296					return element.indexOf( 'dlm-' ) !== -1;
297				} ).length;
298
299				if ( 0 === responseDLM ) {
300					request.abort();
301					window.location.href = href;
302					return;
303				}
304
305				if ( dlmNoAccessHeader && 'true' === dlmNoAccessHeader ) {
306					if ( dlmNoAccessModalHeader && 0 != dlmNoAccessModalHeader ) {
307						dlmXHRinstance.dlmNoAccessModal( instance.responseHeaders );
308						button.removeAttribute( 'download' );
309						button.setAttribute( 'href', href );
310						buttonObj.removeClass().addClass( buttonClass ).find( 'span.dlm-xhr-progress' ).remove();
311						buttonObj.find( '.dlm-xhr-loading-gif' ).remove();
312						request.abort();
313						return;
314					}
315				}
316
317				// If there is a dlm-error headers means we have an error. Display the error and abort.
318				if ( dlmErrorHeader && '' !== dlmErrorHeader && null !== dlmErrorHeader ) {
319					dlmXHRinstance.dlmLogDownload( instance.responseHeaders, 'failed', false );
320					button.removeAttribute( 'download' );
321					button.setAttribute( 'href', href );
322					buttonObj.removeClass().addClass( buttonClass ).find( 'span.dlm-xhr-progress' ).remove();
323					buttonObj.find( '.dlm-xhr-loading-gif' ).remove();
324					request.abort();
325
326					if ( dlmNoAccessModalHeader && 0 != dlmNoAccessModalHeader ) {
327						dlmXHRinstance.dlmNoAccessModal( instance.responseHeaders );
328					} else {
329						buttonObj.find( '.dlm-xhr-error' ).remove();
330						buttonObj.append( '<span class="dlm-xhr-error">' + dlmErrorHeader + '</span>' );
331					}
332
333					return;
334				}
335
336				// If we have a x-dlm-redirect header means this is a redirect. Let's do that.
337				if ( dlmRedirectHeader && '' !== dlmRedirectHeader && null !== dlmRedirectHeader ) {
338					dlmXHRinstance.dlmLogDownload( instance.responseHeaders, 'redirected', false, dlmRedirectHeader, dlmNoAccessHeader, buttonTarget );
339					button.removeAttribute( 'download' );
340					button.setAttribute( 'href', href );
341					buttonObj.removeClass().addClass( buttonClass ).find( 'span.dlm-xhr-progress' ).remove();
342					buttonObj.find( '.dlm-xhr-loading-gif' ).remove();
343					request.abort();
344
345					return;
346				}
347			}
348
349			if ( status == 404 && readyState == 2 ) {
350				const p = document.createElement( 'p' );
351				p.innerHTML = statusText;
352				button.parentNode.appendChild( p );
353			}
354
355			if ( status == 401 && readyState == 2 ) {
356				window.location.href = statusText;
357				return;
358			}
359
360			if ( status == 403 && readyState == 2 ) {
361				const p = document.createElement( 'p' );
362				p.innerHTML = statusText;
363				button.parentNode.appendChild( p );
364			}
365
366			if ( status == 200 && readyState == 4 ) {
367				const blob = request.response;
368				_OBJECT_URL = URL.createObjectURL( blob );
369				// Remove event listener
370				button.removeEventListener( 'click', dlmXHRinstance.handleDownloadClick );
371				// Set the download attribute of the a.download-complete to the file name
372				button.setAttribute( 'download', `${ file_name }` );
373				// Set the href of the a.download-complete to the object URL
374				button.setAttribute( 'href', _OBJECT_URL );
375				// Trigger click on a.download-complete
376				button.click();
377				buttonObj.removeClass().addClass( buttonClass + ' dlm-download-complete' );
378
379				dlmXHRinstance.attachButtonEvent();
380
381				// Append the paragraph to the download-contaner
382				// Trigger the `dlm_download_complete` action
383				jQuery( document ).trigger( 'dlm_download_complete', [ this, button, buttonObj, _OBJECT_URL ] );
384				dlmXHRinstance.dlmLogDownload( instance.responseHeaders, 'completed', $setCookie );
385				// Recommended : Revoke the object URL after some time to free up resources
386				window.URL.revokeObjectURL( _OBJECT_URL );
387				button.removeAttribute( 'download' );
388				button.setAttribute( 'href', href );
389				buttonObj.find( '.dlm-xhr-loading-gif' ).remove();
390				// There is no way to find out whether user finished downloading
391				setTimeout( function() {
392					buttonObj.removeClass().addClass( buttonClass ).find( 'span.dlm-xhr-progress' ).remove();
393				}, 4000 );
394			}
395		};
396
397		if ( dlmXHRProgress ) {
398			request.addEventListener( 'progress', function( e ) {
399				let total = e.total;
400				// Set the total file size from the custom response header
401				if ( 'undefined' === typeof e.total || e.total === 'undefined' || 0 === e.total ) {
402					if ( 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-filesize' ] ) {
403						total = instance.responseHeaders[ 'x-dlm-filesize' ];
404					}
405				}
406				let percent_complete = ( e.loaded / total ) * 100;
407				// Force perfect complete to have 2 digits
408				percent_complete = percent_complete.toFixed();
409				let $class = 'dlm-download-started';
410				buttonObj.find( 'span.dlm-xhr-progress' ).remove();
411				// Comment below lines for the new XHR loader so that we know 
411where to rever
412				$class = $class + ' dlm-download-' + Math.ceil( percent_complete / 10 ) * 10;
413
414				if ( Infinity != percent_complete ) {
415					buttonObj.append( '<span class="dlm-xhr-progress">&nbsp;' + percent_complete + '%</span>' );
416				}
417
418				// Show spinner
419				buttonObj.removeClass().addClass( buttonClass + ' ' + $class );
420				// Trigger the `dlm_download_progress` action
421				jQuery( document ).trigger( 'dlm_download_progress', [ this, button, buttonObj, _OBJECT_URL, e, percent_complete ] );
422			} );
423		}
424
425		request.onerror = function() {
426			button.removeAttribute( 'download' );
427			button.setAttribute( 'href', href );
428			buttonObj.removeClass().addClass( buttonClass + ' dlm-no-xhr-download' ).find( 'span.dlm-xhr-progress' ).remove();
429			buttonObj.find( '.dlm-xhr-error' ).remove();
430			buttonObj.append( '<span class="dlm-xhr-error">' + dlmXHRtranslations.error + '</span>' );
431			console.log( '** An error occurred during the transaction' );
432		};
433
434		request.open( 'GET', href, true );
435		request.setRequestHeader( 'Cache-Control', 'no-store, no-cache, no-transform, max-age=0' );
436		request.setRequestHeader( 'dlm-xhr-request', 'dlm_XMLHttpRequest' );
437		request.send();
438	}
439
440	dlmLogDownload( headers, status, cookie, redirect_path = null, no_access = null, target = '_self' ) {
441		const currentURL = window.location.href;
442		const download_id = headers[ 'x-dlm-download-id' ] ?? headers[ 'dlm-download-id' ];
443		const version_id = headers[ 'x-dlm-version-id' ] ?? headers[ 'dlm-version-id' ];
444
445		const ua = navigator.userAgent || '';
446		const isSafari = /^((?!chrome|android|crios|fxios|edgios).)*safari/i.test( ua );
447		const isAppleSafari = isSafari && ! /CriOS|FxiOS|EdgiOS/i.test( ua );
448		// Early redirect — skip logging if no_access = true
449		if ( no_access && redirect_path ) {
450			if ( isAppleSafari ) {
451				window.location.href = redirect_path;
452			} else {
453				const tgt = target || '_self';
454				const downloadTab = window.open( redirect_path, tgt, 'noopener' );
455				if ( downloadTab ) {
456					downloadTab.location.href = redirect_path;
457				}
458			}
459			return;
460		}
461
462		const params = new URLSearchParams( {
463			action: 'log_dlm_xhr_download',
464			download_id,
465			version_id,
466			status,
467			cookie,
468			currentURL,
469			nonce: headers[ 'x-dlm-nonce' ],
470			log_token: headers[ 'x-dlm-log-token' ],
471		} );
472
473		for ( const [ key, value ] of Object.entries( headers ) ) {
474			params.append( `responseHeaders[${ key }]`, value );
475		}
476
477		try {
478			navigator.sendBeacon(
479				dlmXHR.ajaxUrl,
480				new Blob( [ params.toString() ], { type: 'application/x-www-form-urlencoded;charset=UTF-8' } ),
481			);
482		} catch ( e ) {
483			try {
484				fetch( dlmXHR.ajaxUrl, { method: 'POST', body: params, keepalive: true } );
485			} catch ( _ ) {}
486		}
487
488		if ( ! redirect_path ) {
489			return;
490		}
491
492		if ( isAppleSafari ) {
493			window.location.href = redirect_path;
494			return;
495		}
496
497		const tgt = target || '_self';
498		const downloadTab = window.open( redirect_path, tgt, 'noopener' );
499		if ( no_access && downloadTab ) {
500			downloadTab.location.href = redirect_path;
501		}
502	}
503
504	dlmNoAccessModal( headers ) {
505		const instance = this;
506		let download = 'empty-download',
507			version = 'empty-version',
508			restriction = 'empty-restriction',
509			text = '';
510
511		/**
512		 * Old headers, will be removed in a future release. DLM Amazon S3 adds these headers.
513		 */
514		if ( 'undefined' !== typeof headers[ 'dlm-download-id' ] ) {
515			download = headers[ 'dlm-download-id' ];
516		}
517		if ( 'undefined' !== typeof headers[ 'dlm-version-id' ] ) {
518			version = headers[ 'dlm-version-id' ];
519		}
520		if ( 'undefined' !== typeof headers[ 'dlm-no-access-modal-text' ] ) {
521			text = headers[ 'dlm-no-access-modal-text' ];
522		}
523		if ( 'undefined' !== typeof headers[ 'dlm-no-access-restriction' ] ) {
524			restriction = headers[ 'dlm-no-access-restriction' ];
525		}
526		// End of old headers.
527
528		/**
529		 * New headers.
530		 */
531		if ( 'undefined' !== typeof headers[ 'x-dlm-download-id' ] ) {
532			download = headers[ 'x-dlm-download-id' ];
533		}
534		if ( 'undefined' !== typeof headers[ 'x-dlm-version-id' ] ) {
535			version = headers[ 'x-dlm-version-id' ];
536		}
537		if ( 'undefined' !== typeof headers[ 'x-dlm-no-access-modal-text' ] ) {
538			text = headers[ 'x-dlm-no-access-modal-text' ];
539		}
540		if ( 'undefined' !== typeof headers[ 'x-dlm-no-access-restriction' ] ) {
541			restriction = headers[ 'x-dlm-no-access-restriction' ];
542		}
543		// End of new headers.
544
545		const data = {
546			download_id: download,
547			version_id: version,
548			modal_text: text,
549			restriction,
550			action: 'no_access_dlm_xhr_download',
551			nonce: headers[ 'x-dlm-nonce' ],
552		};
553
554		jQuery( document ).trigger( 'dlm-xhr-modal-data', [ data, headers ] );
555		document.dispatchEvent(
556			new CustomEvent( 'dlm-xhr-modal-data', { detail: { data, headers } } ),
557		);
558
559		jQuery.post( dlmXHR.ajaxUrl, data, function( response ) {
560			jQuery( '#dlm-no-access-modal' ).remove();
561			//document.body.insertAdjacentHTML('beforeend', response);
562			const tempDiv = document.createElement( 'div' );
563			tempDiv.innerHTML = response;
564			// Extract and execute scripts from the response using a regular expression
565			const scriptRegex = /<script\b[^>]*>([\s\S]*?)<\/script>/gm;
566			// Remove script tags from tempDiv.innerHTML
567			tempDiv.innerHTML = tempDiv.innerHTML.replace( scriptRegex, '' );
568			let match;
569			while ( ( match = scriptRegex.exec( response ) ) !== null ) {
570				const scriptTag = match[ 0 ];
571				const scriptContent = match[ 1 ];
572				const newScript = document.createElement( 'script' );
573				// Check if the script has a src attribute
574				const srcMatch = scriptTag.match( /src=["']([^"']+)["']/ );
575				if ( srcMatch ) {
576					newScript.src = srcMatch[ 1 ];
577				} else {
578					newScript.textContent = scriptContent;
579				}
580				// Append the new script to the modal if exists
581				const modal = tempDiv.querySelector( '#dlm-no-access-modal' );
582				if ( modal ) {
583					modal.appendChild( newScript );
584				} else {
585					document.body.appendChild( newScript );
586				}
587			}
588			// Append the parsed HTML elements to the body
589			while ( tempDiv.firstChild ) {
590				document.body.appendChild( tempDiv.firstChild );
591			}
592
593			//jQuery('body').append(response);
594			jQuery( document ).trigger( data.action, [ response, data ] );
595
596			document.dispatchEvent(
597				new CustomEvent( data.action, { detail: [ response, data ] } ),
598			);
599		} );
600	}
601
602	dlmExternalDownload( headers, button, buttonObj, file_name, href ) {
603		const request = new XMLHttpRequest(),
604			  buttonTarget = buttonObj.attr( 'target' );
605		let buttonClass = buttonObj.attr( 'class' ),
606			_OBJECT_URL,
607			uri = '';
608
609		if ( 'undefined' !== typeof headers[ 'dlm-external-download' ] ) {
610			uri = headers[ 'dlm-external-download' ];
611		}
612		if ( 'undefined' !== typeof headers[ 'x-dlm-external-download' ] ) {
613			uri = headers[ 'x-dlm-external-download' ];
614		}
615		buttonClass = ( 'undefined' !== typeof buttonClass && '' !== buttonClass ) ? buttonClass.replace( 'dlm-download-started', '' ).replace( 'dlm-download-completed', '' ) : '';
616
617		buttonObj.addClass( 'dlm-download-started' );
618		button.setAttribute( 'href', '#' );
619		button.removeAttribute( 'download' );
620		button.setAttribute( 'disabled', 'disabled' );
621
622		// Trigger the `dlm_download_triggered` action
623		jQuery( document ).trigger( 'dlm_download_triggered', [ this, button, buttonObj, _OBJECT_URL, request ] );
624
625		request.responseType = 'blob';
626		request.onreadystatechange = function() {
627			const {
628				status,
629				readyState,
630				statusText,
631			} = request;
632
633			if ( 403 === status ) {
634				dlmXHRinstance.dlmLogDownload( headers, 'failed', false );
635				request.abort();
636				buttonObj.find( '.dlm-xhr-error' ).remove();
637				buttonObj.append( '<span class="dlm-xhr-error">Acces Denied to file.</span>' );
638				return;
639			}
640			if ( status == 200 && readyState == 4 ) {
641				const blob = request.response;
642
643				_OBJECT_URL = URL.createObjectURL( blob );
644				// Remove event listener
645				button.removeEventListener( 'click', dlmXHRinstance.handleDownloadClick );
646				// Set the download attribute of the a.download-complete to the file name
647				button.setAttribute( 'download', `${ file_name }` );
648				// Set the href of the a.download-complete to the object URL
649				button.setAttribute( 'href', _OBJECT_URL );
650				// Trigger click on a.download-complete
651				button.click();
652				buttonObj.removeClass().addClass( buttonClass + ' dlm-download-complete' );
653
654				dlmXHRinstance.attachButtonEvent();
655
656				// Append the paragraph to the download-contaner
657				// Trigger the `dlm_download_complete` action
658				jQuery( document ).trigger( 'dlm_download_complete', [ this, button, buttonObj, _OBJECT_URL ] );
659				dlmXHRinstance.dlmLogDownload( headers, 'completed', false );
660
661				// Recommended : Revoke the object URL after some time to free up resources
662				window.URL.revokeObjectURL( _OBJECT_URL );
663				button.removeAttribute( 'download' );
664				button.setAttribute( 'href', href );
665				// There is no way to find out whether user finished downloading
666				buttonObj.find( '.dlm-xhr-loading-gif' ).remove();
667				setTimeout( function() {
668					buttonObj.removeClass().addClass( buttonClass ).find( 'span.dlm-xhr-progress' ).remove();
669				}, 1000 );
670			}
671		};
672
673		if ( dlmXHRProgress ) {
674			request.addEventListener( 'progress', function( e ) {
675				let total = e.total;
676
677				if ( 'undefined' === typeof e.total || e.total === 'undefined' ) {
678					total = request.getResponseHeader( 'X-DLM-Filesize' );
679				}
680				let percent_complete = ( e.loaded / total ) * 100;
681				// Force perfect complete to have 2 digits
682				percent_complete = percent_complete.toFixed();
683				let $class = 'dlm-download-started';
684				buttonObj.find( 'span.dlm-xhr-progress' ).remove();
685				// Comment below lines for the new XHR loader so that we know where to rever
686				$class = $class + ' dlm-download-' + Math.ceil( percent_complete / 10 ) * 10;
687
688				if ( Infinity != percent_complete ) {
689					buttonObj.append( '<span class="dlm-xhr-progress">&nbsp;' + percent_complete + '%</span>' );
690				}
691
692				// Show spinner
693				buttonObj.removeClass().addClass( buttonClass + ' ' + $class );
694				// Trigger the `dlm_download_progress` action
695				jQuery( document ).trigger( 'dlm_download_progress', [ this, button, buttonObj, _OBJECT_URL, e, percent_complete ] );
696			} );
697		}
698
699		request.onerror = function() {
700			button.removeAttribute( 'download' );
701			button.setAttribute( 'href', href );
702			buttonObj.removeClass().addClass( buttonClass + ' .dlm-no-xhr-download' ).find( 'span.dlm-xhr-progress' ).remove();
703			buttonObj.find( '.dlm-xhr-error' ).remove();
704			buttonObj.append( '<span class="dlm-xhr-error">' + dlmXHRtranslations.error + '</span>' );
705			console.log( '** An error occurred during the transaction' );
706		};
707
708		request.open( 'GET', uri, true );
709		request.setRequestHeader( 'Cache-Control', 'no-store, no-cache, no-transform, max-age=0' );
710		request.setRequestHeader( 'dlm-xhr-request', 'dlm_XMLHttpRequest' );
711		request.send();
712	}
713}

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.