PageSourceSearch

https://sureholdings.com/blog/wp-content/plugins/download-monitor/assets/js/dlm-xhr.js?ver=5.1.14

js sureholdings.com collected 2026-10-03 22:38:14 UTC 26,465 bytes, 712 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" style="display:inline-block; vertical-align: middle; margin-left:15px;">';
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 + ' 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		} );
471
472		for ( const [ key, value ] of Object.entries( headers ) ) {
473			params.append( `responseHeaders[${ key }]`, value );
474		}
475
476		try {
477			navigator.sendBeacon(
478				dlmXHR.ajaxUrl,
479				new Blob( [ params.toString() ], { type: 'application/x-www-form-urlencoded;charset=UTF-8' } ),
480			);
481		} catch ( e ) {
482			try {
483				fetch( dlmXHR.ajaxUrl, { method: 'POST', body: params, keepalive: true } );
484			} catch ( _ ) {}
485		}
486
487		if ( ! redirect_path ) {
488			return;
489		}
490
491		if ( isAppleSafari ) {
492			window.location.href( redirect_path );
493			return;
494		}
495
496		const tgt = target || '_self';
497		const downloadTab = window.open( redirect_path, tgt, 'noopener' );
498		if ( no_access && downloadTab ) {
499			downloadTab.location.href = redirect_path;
500		}
501	}
502
503	dlmNoAccessModal( headers ) {
504		const instance = this;
505		let download = 'empty-download',
506			version = 'empty-version',
507			restriction = 'empty-restriction',
508			text = '';
509
510		/**
511		 * Old headers, will be removed in a future release. DLM Amazon S3 adds these headers.
512		 */
513		if ( 'undefined' !== typeof headers[ 'dlm-download-id' ] ) {
514			download = headers[ 'dlm-download-id' ];
515		}
516		if ( 'undefined' !== typeof headers[ 'dlm-version-id' ] ) {
517			version = headers[ 'dlm-version-id' ];
518		}
519		if ( 'undefined' !== typeof headers[ 'dlm-no-access-modal-text' ] ) {
520			text = headers[ 'dlm-no-access-modal-text' ];
521		}
522		if ( 'undefined' !== typeof headers[ 'dlm-no-access-restriction' ] ) {
523			restriction = headers[ 'dlm-no-access-restriction' ];
524		}
525		// End of old headers.
526
527		/**
528		 * New headers.
529		 */
530		if ( 'undefined' !== typeof headers[ 'x-dlm-download-id' ] ) {
531			download = headers[ 'x-dlm-download-id' ];
532		}
533		if ( 'undefined' !== typeof headers[ 'x-dlm-version-id' ] ) {
534			version = headers[ 'x-dlm-version-id' ];
535		}
536		if ( 'undefined' !== typeof headers[ 'x-dlm-no-access-modal-text' ] ) {
537			text = headers[ 'x-dlm-no-access-modal-text' ];
538		}
539		if ( 'undefined' !== typeof headers[ 'x-dlm-no-access-restriction' ] ) {
540			restriction = headers[ 'x-dlm-no-access-restriction' ];
541		}
542		// End of new headers.
543
544		const data = {
545			download_id: download,
546			version_id: version,
547			modal_text: text,
548			restriction,
549			action: 'no_access_dlm_xhr_download',
550			nonce: headers[ 'x-dlm-nonce' ],
551		};
552
553		jQuery( document ).trigger( 'dlm-xhr-modal-data', [ data, headers ] );
554		document.dispatchEvent(
555			new CustomEvent( 'dlm-xhr-modal-data', { detail: { data, headers } } ),
556		);
557
558		jQuery.post( dlmXHR.ajaxUrl, data, function( response ) {
559			jQuery( '#dlm-no-access-modal' ).remove();
560			//document.body.insertAdjacentHTML('beforeend', response);
561			const tempDiv = document.createElement( 'div' );
562			tempDiv.innerHTML = response;
563			// Extract and execute scripts from the response using a regular expression
564			const scriptRegex = /<script\b[^>]*>([\s\S]*?)<\/script>/gm;
565			// Remove script tags from tempDiv.innerHTML
566			tempDiv.innerHTML = tempDiv.innerHTML.replace( scriptRegex, '' );
567			let match;
568			while ( ( match = scriptRegex.exec( response ) ) !== null ) {
569				const scriptTag = match[ 0 ];
570				const scriptContent = match[ 1 ];
571				const newScript = document.createElement( 'script' );
572				// Check if the script has a src attribute
573				const srcMatch = scriptTag.match( /src=["']([^"']+)["']/ );
574				if ( srcMatch ) {
575					newScript.src = srcMatch[ 1 ];
576				} else {
577					newScript.textContent = scriptContent;
578				}
579				// Append the new script to the modal if exists
580				const modal = tempDiv.querySelector( '#dlm-no-access-modal' );
581				if ( modal ) {
582					modal.appendChild( newScript );
583				} else {
584					document.body.appendChild( newScript );
585				}
586			}
587			// Append the parsed HTML elements to the body
588			while ( tempDiv.firstChild ) {
589				document.body.appendChild( tempDiv.firstChild );
590			}
591
592			//jQuery('body').append(response);
593			jQuery( document ).trigger( data.action, [ response, data ] );
594
595			document.dispatchEvent(
596				new CustomEvent( data.action, { detail: [ response, data ] } ),
597			);
598		} );
599	}
600
601	dlmExternalDownload( headers, button, buttonObj, file_name, href ) {
602		const request = new XMLHttpRequest(),
603			  buttonTarget = buttonObj.attr( 'target' );
604		let buttonClass = buttonObj.attr( 'class' ),
605			_OBJECT_URL,
606			uri = '';
607
608		if ( 'undefined' !== typeof headers[ 'dlm-external-download' ] ) {
609			uri = headers[ 'dlm-external-download' ];
610		}
611		if ( 'undefined' !== typeof headers[ 'x-dlm-external-download' ] ) {
612			uri = headers[ 'x-dlm-external-download' ];
613		}
614		buttonClass = ( 'undefined' !== typeof buttonClass && '' !== buttonClass ) ? buttonClass.replace( 'dlm-download-started', '' ).replace( 'dlm-download-completed', '' ) : '';
615
616		buttonObj.addClass( 'dlm-download-started' );
617		button.setAttribute( 'href', '#' );
618		button.removeAttribute( 'download' );
619		button.setAttribute( 'disabled', 'disabled' );
620
621		// Trigger the `dlm_download_triggered` action
622		jQuery( document ).trigger( 'dlm_download_triggered', [ this, button, buttonObj, _OBJECT_URL, request ] );
623
624		request.responseType = 'blob';
625		request.onreadystatechange = function() {
626			const {
627				status,
628				readyState,
629				statusText,
630			} = request;
631
632			if ( 403 === status ) {
633				dlmXHRinstance.dlmLogDownload( headers, 'failed', false );
634				request.abort();
635				buttonObj.find( '.dlm-xhr-error' ).remove();
636				buttonObj.append( '<span class="dlm-xhr-error">Acces Denied to file.</span>' );
637				return;
638			}
639			if ( status == 200 && readyState == 4 ) {
640				const blob = request.response;
641
642				_OBJECT_URL = URL.createObjectURL( blob );
643				// Remove event listener
644				button.removeEventListener( 'click', dlmXHRinstance.handleDownloadClick );
645				// Set the download attribute of the a.download-complete to the file name
646				button.setAttribute( 'download', `${ file_name }` );
647				// Set the href of the a.download-complete to the object URL
648				button.setAttribute( 'href', _OBJECT_URL );
649				// Trigger click on a.download-complete
650				button.click();
651				buttonObj.removeClass().addClass( buttonClass + ' dlm-download-complete' );
652
653				dlmXHRinstance.attachButtonEvent();
654
655				// Append the paragraph to the download-contaner
656				// Trigger the `dlm_download_complete` action
657				jQuery( document ).trigger( 'dlm_download_complete', [ this, button, buttonObj, _OBJECT_URL ] );
658				dlmXHRinstance.dlmLogDownload( headers, 'completed', false );
659
660				// Recommended : Revoke the object URL after some time to free up resources
661				window.URL.revokeObjectURL( _OBJECT_URL );
662				button.removeAttribute( 'download' );
663				button.setAttribute( 'href', href );
664				// There is no way to find out whether user finished downloading
665				buttonObj.find( '.dlm-xhr-loading-gif' ).remove();
666				setTimeout( function() {
667					buttonObj.removeClass().addClass( buttonClass ).find( 'span.dlm-xhr-progress' ).remove();
668				}, 1000 );
669			}
670		};
671
672		if ( dlmXHRProgress ) {
673			request.addEventListener( 'progress', function( e ) {
674				let total = e.total;
675
676				if ( 'undefined' === typeof e.total || e.total === 'undefined' ) {
677					total = request.getResponseHeader( 'X-DLM-Filesize' );
678				}
679				let percent_complete = ( e.loaded / total ) * 100;
680				// Force perfect complete to have 2 digits
681				percent_complete = percent_complete.toFixed();
682				let $class = 'dlm-download-started';
683				buttonObj.find( 'span.dlm-xhr-progress' ).remove();
684				// Comment below lines for the new XHR loader so that we know where to rever
685				$class = $class + ' download-' + Math.ceil( percent_complete / 10 ) * 10;
686
687				if ( Infinity != percent_complete ) {
688					buttonObj.append( '<span class="dlm-xhr-progress">&nbsp;' + percent_complete + '%</span>' );
689				}
690
691				// Show spinner
692				buttonObj.removeClass().addClass( buttonClass + ' ' + $class );
693				// Trigger the `dlm_download_progress` action
694				jQuery( document ).trigger( 'dlm_download_progress', [ this, button, buttonObj, _OBJECT_URL, e, percent_complete ] );
695			} );
696		}
697
698		request.onerror = function() {
699			button.removeAttribute( 'download' );
700			button.setAttribute( 'href', href );
701			buttonObj.removeClass().addClass( buttonClass + ' .dlm-no-xhr-download' ).find( 'span.dlm-xhr-progress' ).remove();
702			buttonObj.find( '.dlm-xhr-error' ).remove();
703			buttonObj.append( '<span class="dlm-xhr-error">' + dlmXHRtranslations.error + '</span>' );
704			console.log( '** An error occurred during the transaction' );
705		};
706
707		request.open( 'GET', uri, true );
708		request.setRequestHeader( 'Cache-Control', 'no-store, no-cache, no-transform, max-age=0' );
709		request.setRequestHeader( 'dlm-xhr-request', 'dlm_XMLHttpRequest' );
710		request.send();
711	}
712}

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.