713 lines
26 KiB
JavaScript
713 lines
26 KiB
JavaScript
/* eslint-disable camelcase */
|
|
/* eslint-disable no-undef */
|
|
jQuery( function( $ ) {
|
|
// Let's initiate the XHR.
|
|
new DLM_XHR_Download();
|
|
} );
|
|
|
|
class DLM_XHR_Download {
|
|
responsHeaders = {};
|
|
|
|
constructor() {
|
|
// dlmXHRinstance defined in inline script
|
|
dlmXHRinstance = this;
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
dlmXHRinstance.attachButtonEvent();
|
|
}
|
|
|
|
// Function to attach events for the download buttons
|
|
attachButtonEvent() {
|
|
// Stop propagation on child elements
|
|
jQuery( 'html,body' ).on( 'click', '.dlm-no-access-modal-window > div', function( e ) {
|
|
e.stopPropagation();
|
|
} );
|
|
// Close modal on these clicks
|
|
jQuery( 'html, body' ).on( 'click', '.dlm-no-access-modal-overlay, .dlm-no-access-modal-close, .dlm-no-access-modal-window', function( e ) {
|
|
e.stopPropagation();
|
|
jQuery( '#dlm-no-access-modal' ).remove();
|
|
} );
|
|
// Close modal on ESC key press
|
|
jQuery( document ).on( 'keydown', function( e ) {
|
|
if ( e.key === 'Escape' ) {
|
|
jQuery( '#dlm-no-access-modal' ).remove();
|
|
}
|
|
} );
|
|
|
|
jQuery( 'html, body' ).on( 'click', 'a', function( e ) {
|
|
let url = jQuery( this ).attr( 'href' );
|
|
// Let's see if we need to do XHR download on this link.
|
|
let noXHR = false;
|
|
if ( jQuery( this ).hasClass( 'dlm-no-xhr-download' ) ) {
|
|
noXHR = true;
|
|
}
|
|
|
|
if ( 'undefined' !== typeof dlmNonXHRGlobalLinks && dlmNonXHRGlobalLinks.length > 0 ) {
|
|
if ( 'undefined' !== typeof url ) {
|
|
dlmNonXHRGlobalLinks.forEach( ( element ) => {
|
|
if ( url.indexOf( element ) >= 0 ) {
|
|
noXHR = true;
|
|
}
|
|
} );
|
|
}
|
|
}
|
|
|
|
if ( noXHR ) { // No XHR so return;
|
|
jQuery( '#dlm-no-access-modal' ).remove(); // Close the modal also in case we opened it before.
|
|
return;
|
|
}
|
|
|
|
if ( typeof url === 'string' ) {
|
|
try {
|
|
url = new URL( url, window.location.origin ).href;
|
|
} catch ( e ) {}
|
|
}
|
|
|
|
jQuery( document ).trigger( 'dlm-xhr-download-button-click', [ url, this, dlmXHRGlobalLinks ] );
|
|
if ( 'undefined' !== typeof url && url.indexOf( dlmXHRGlobalLinks ) >= 0 ) {
|
|
const redirect_link = jQuery( this ).data( 'redirect' ),
|
|
target = jQuery( this ).attr( 'target' );
|
|
// Check if the link has a target attribute, and if it does, we need to open it in a new window.
|
|
if ( 'undefined' !== typeof redirect_link && true === redirect_link && '_blank' === target ) {
|
|
// If we need to redirect/open in a new tab, then we do not need to do XHR, so return.
|
|
return;
|
|
}
|
|
dlmXHRinstance.handleDownloadClick( this, e );
|
|
}
|
|
} );
|
|
}
|
|
|
|
handleDownloadClick( obj, e ) {
|
|
e.stopPropagation();
|
|
const href = obj.getAttribute( 'href' );
|
|
|
|
const triggerObject = {
|
|
button: obj,
|
|
href,
|
|
buttonObj: jQuery( obj ),
|
|
};
|
|
|
|
// Show the progress bar after complete download also
|
|
if ( triggerObject.href.indexOf( 'blob:http' ) !== -1 ) {
|
|
/*triggerObject.buttonObj.addClass('download-100');
|
|
setTimeout(function () {
|
|
triggerObject.buttonObj.removeClass('download-100');
|
|
}, 1500);*/
|
|
|
|
return;
|
|
}
|
|
|
|
if ( '#' === triggerObject.href ) {
|
|
return;
|
|
}
|
|
|
|
e.preventDefault();
|
|
dlmXHRinstance.retrieveBlob( triggerObject );
|
|
}
|
|
|
|
retrieveBlob( triggerObject ) {
|
|
const instance = this;
|
|
const {
|
|
button,
|
|
href,
|
|
buttonObj,
|
|
} = triggerObject;
|
|
|
|
// This will hold the file as a local object URL
|
|
let _OBJECT_URL;
|
|
const request = new XMLHttpRequest();
|
|
const $setCookie = dlmXHR.prevent_duplicates,
|
|
buttonTarget = buttonObj.attr( 'target' );
|
|
let buttonClass = buttonObj.attr( 'class' );
|
|
buttonClass = ( 'undefined' !== typeof buttonClass && '' !== buttonClass ) ? buttonClass.replace( 'dlm-download-started', '' ).replace( 'dlm-download-completed', '' ) : '';
|
|
|
|
buttonObj.addClass( 'dlm-download-started' );
|
|
button.setAttribute( 'href', '#' );
|
|
button.removeAttribute( 'download' );
|
|
button.setAttribute( 'disabled', 'disabled' );
|
|
if ( dlmXHRProgress ) {
|
|
const loading_gif = '<img src="' + dlmXHRgif + '" class="dlm-xhr-loading-gif" style="display:inline-block; vertical-align: middle; margin-left:15px;">';
|
|
button.innerHTML += loading_gif;
|
|
}
|
|
|
|
// Trigger the `dlm_download_triggered` action
|
|
jQuery( document ).trigger( 'dlm_download_triggered', [ this, button, buttonObj, _OBJECT_URL, request ] );
|
|
let check_headers = false;
|
|
request.responseType = 'blob';
|
|
request.onreadystatechange = function() {
|
|
const {
|
|
status,
|
|
readyState,
|
|
statusText,
|
|
} = request;
|
|
const headers = request
|
|
.getAllResponseHeaders()
|
|
.split( '\r\n' )
|
|
.reduce( ( result, current ) => {
|
|
const [ name, value ] = current.split( ': ' );
|
|
result[ name ] = value;
|
|
return result;
|
|
}, {} );
|
|
|
|
if ( Object.keys( headers ).length > 1 ) {
|
|
check_headers = true;
|
|
// Set the response headers to the instance so that we can use it later.
|
|
instance.responseHeaders = headers;
|
|
}
|
|
|
|
let file_name = 'download';
|
|
let dlmFilenameHeader = false,
|
|
dlmNoWaypoints = false,
|
|
dlmRedirectHeader = false,
|
|
dlmExternalDownloadHeader = false,
|
|
dlmNoAccessHeader = null,
|
|
dlmNoAccessModalHeader = false,
|
|
dlmErrorHeader = false,
|
|
dlmDownloadIdHeader = false,
|
|
dlmDownloadVersionHeader = false,
|
|
dlmNoAccessModalTextHeader = false;
|
|
|
|
/**
|
|
* Old headers check
|
|
*/
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-file-name' ] ) {
|
|
dlmFilenameHeader = instance.responseHeaders[ 'dlm-file-name' ];
|
|
}
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-no-waypoints' ] ) {
|
|
dlmNoWaypoints = true;
|
|
}
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-redirect' ] ) {
|
|
dlmRedirectHeader = instance.responseHeaders[ 'dlm-redirect' ];
|
|
}
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-external-download' ] ) {
|
|
dlmExternalDownloadHeader = true;
|
|
}
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-no-access' ] ) {
|
|
dlmNoAccessHeader = instance.responseHeaders[ 'dlm-no-access' ];
|
|
}
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-no-access-modal' ] ) {
|
|
dlmNoAccessModalHeader = instance.responseHeaders[ 'dlm-no-access-modal' ];
|
|
}
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-error' ] ) {
|
|
dlmErrorHeader = instance.responseHeaders[ 'dlm-error' ];
|
|
}
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-download-id' ] ) {
|
|
dlmDownloadIdHeader = instance.responseHeaders[ 'dlm-download-id' ];
|
|
}
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-version-id' ] ) {
|
|
dlmDownloadVersionHeader = instance.responseHeaders[ 'dlm-version-id' ];
|
|
}
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'dlm-no-access-modal-text' ] ) {
|
|
dlmNoAccessModalTextHeader = instance.responseHeaders[ 'dlm-no-access-modal-text' ];
|
|
}
|
|
// End old headers check
|
|
|
|
/**
|
|
* New headers check
|
|
*/
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-file-name' ] ) {
|
|
dlmFilenameHeader = instance.responseHeaders[ 'x-dlm-file-name' ];
|
|
}
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-no-waypoints' ] ) {
|
|
dlmNoWaypoints = true;
|
|
}
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-redirect' ] ) {
|
|
dlmRedirectHeader = instance.responseHeaders[ 'x-dlm-redirect' ];
|
|
}
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-external-download' ] ) {
|
|
dlmExternalDownloadHeader = true;
|
|
}
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-no-access' ] ) {
|
|
dlmNoAccessHeader = instance.responseHeaders[ 'x-dlm-no-access' ];
|
|
}
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-no-access-modal' ] ) {
|
|
dlmNoAccessModalHeader = instance.responseHeaders[ 'x-dlm-no-access-modal' ];
|
|
}
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-error' ] ) {
|
|
dlmErrorHeader = instance.responseHeaders[ 'x-dlm-error' ];
|
|
}
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-download-id' ] ) {
|
|
dlmDownloadIdHeader = instance.responseHeaders[ 'x-dlm-download-id' ];
|
|
}
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-version-id' ] ) {
|
|
dlmDownloadVersionHeader = instance.responseHeaders[ 'x-dlm-version-id' ];
|
|
}
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-no-access-modal-text' ] ) {
|
|
dlmNoAccessModalTextHeader = instance.responseHeaders[ 'x-dlm-no-access-modal-text' ];
|
|
}
|
|
|
|
// End new headers check
|
|
|
|
if ( dlmFilenameHeader ) {
|
|
file_name = dlmFilenameHeader.replace( /\"/g, '' ).replace( ';', '' );
|
|
file_name = decodeURI( file_name );
|
|
} else if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'content-disposition' ] ) {
|
|
file_name = instance.responseHeaders[ 'content-disposition' ].split( /(?:filename\*=UTF-8'')|(?:filename=)/ )[ 1 ];
|
|
file_name = file_name.replace( /\"/g, '' ).replace( ';', '' );
|
|
// We use this method because we urlencoded it on the server so that characters like chinese or persian are not broken
|
|
file_name = decodeURI( file_name );
|
|
}
|
|
|
|
// Error translations
|
|
if ( dlmErrorHeader ) {
|
|
//var obj = { key: undefined };
|
|
if ( dlmErrorHeader in dlmXHRtranslations ) {
|
|
dlmErrorHeader = dlmXHRtranslations[ dlmErrorHeader ];
|
|
} else {
|
|
dlmErrorHeader = dlmXHRtranslations.error;
|
|
}
|
|
}
|
|
|
|
// Let's check for DLM request headers
|
|
if ( request.readyState === 2 ) {
|
|
// Add other checks for responseHeaders that can be taken care of from extensions.
|
|
if ( check_headers && 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-force-abort' ] && '' !== instance.responseHeaders[ 'x-dlm-force-abort' ] ) {
|
|
button.removeAttribute( 'download' );
|
|
button.setAttribute( 'href', href );
|
|
buttonObj.removeClass().addClass( buttonClass ).find( 'span.dlm-xhr-progress' ).remove();
|
|
buttonObj.find( '.dlm-xhr-loading-gif' ).remove();
|
|
request.abort();
|
|
jQuery( '#dlm-no-access-modal' ).remove();
|
|
return;
|
|
}
|
|
|
|
// If the dlm-no-waypoints header is set we need to redirect.
|
|
if ( dlmNoWaypoints ) {
|
|
request.abort();
|
|
if ( dlmRedirectHeader ) {
|
|
window.location.href = dlmRedirectHeader;
|
|
return;
|
|
}
|
|
window.location.href = href;
|
|
return;
|
|
}
|
|
|
|
// If it's an external link we need to redirect.
|
|
if ( dlmExternalDownloadHeader ) {
|
|
request.abort();
|
|
dlmXHRinstance.dlmExternalDownload( instance.responseHeaders, button, buttonObj, file_name, href );
|
|
return;
|
|
}
|
|
|
|
// If there are no specific DLM headers then we need to abort and redirect.
|
|
const responseDLM = Object.keys( instance.responseHeaders ).filter( ( element ) => {
|
|
return element.indexOf( 'dlm-' ) !== -1;
|
|
} ).length;
|
|
|
|
if ( 0 === responseDLM ) {
|
|
request.abort();
|
|
window.location.href = href;
|
|
return;
|
|
}
|
|
|
|
if ( dlmNoAccessHeader && 'true' === dlmNoAccessHeader ) {
|
|
if ( dlmNoAccessModalHeader && 0 != dlmNoAccessModalHeader ) {
|
|
dlmXHRinstance.dlmNoAccessModal( instance.responseHeaders );
|
|
button.removeAttribute( 'download' );
|
|
button.setAttribute( 'href', href );
|
|
buttonObj.removeClass().addClass( buttonClass ).find( 'span.dlm-xhr-progress' ).remove();
|
|
buttonObj.find( '.dlm-xhr-loading-gif' ).remove();
|
|
request.abort();
|
|
return;
|
|
}
|
|
}
|
|
|
|
// If there is a dlm-error headers means we have an error. Display the error and abort.
|
|
if ( dlmErrorHeader && '' !== dlmErrorHeader && null !== dlmErrorHeader ) {
|
|
dlmXHRinstance.dlmLogDownload( instance.responseHeaders, 'failed', false );
|
|
button.removeAttribute( 'download' );
|
|
button.setAttribute( 'href', href );
|
|
buttonObj.removeClass().addClass( buttonClass ).find( 'span.dlm-xhr-progress' ).remove();
|
|
buttonObj.find( '.dlm-xhr-loading-gif' ).remove();
|
|
request.abort();
|
|
|
|
if ( dlmNoAccessModalHeader && 0 != dlmNoAccessModalHeader ) {
|
|
dlmXHRinstance.dlmNoAccessModal( instance.responseHeaders );
|
|
} else {
|
|
buttonObj.find( '.dlm-xhr-error' ).remove();
|
|
buttonObj.append( '<span class="dlm-xhr-error">' + dlmErrorHeader + '</span>' );
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// If we have a x-dlm-redirect header means this is a redirect. Let's do that.
|
|
if ( dlmRedirectHeader && '' !== dlmRedirectHeader && null !== dlmRedirectHeader ) {
|
|
dlmXHRinstance.dlmLogDownload( instance.responseHeaders, 'redirected', false, dlmRedirectHeader, dlmNoAccessHeader, buttonTarget );
|
|
button.removeAttribute( 'download' );
|
|
button.setAttribute( 'href', href );
|
|
buttonObj.removeClass().addClass( buttonClass ).find( 'span.dlm-xhr-progress' ).remove();
|
|
buttonObj.find( '.dlm-xhr-loading-gif' ).remove();
|
|
request.abort();
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( status == 404 && readyState == 2 ) {
|
|
const p = document.createElement( 'p' );
|
|
p.innerHTML = statusText;
|
|
button.parentNode.appendChild( p );
|
|
}
|
|
|
|
if ( status == 401 && readyState == 2 ) {
|
|
window.location.href = statusText;
|
|
return;
|
|
}
|
|
|
|
if ( status == 403 && readyState == 2 ) {
|
|
const p = document.createElement( 'p' );
|
|
p.innerHTML = statusText;
|
|
button.parentNode.appendChild( p );
|
|
}
|
|
|
|
if ( status == 200 && readyState == 4 ) {
|
|
const blob = request.response;
|
|
_OBJECT_URL = URL.createObjectURL( blob );
|
|
// Remove event listener
|
|
button.removeEventListener( 'click', dlmXHRinstance.handleDownloadClick );
|
|
// Set the download attribute of the a.download-complete to the file name
|
|
button.setAttribute( 'download', `${ file_name }` );
|
|
// Set the href of the a.download-complete to the object URL
|
|
button.setAttribute( 'href', _OBJECT_URL );
|
|
// Trigger click on a.download-complete
|
|
button.click();
|
|
buttonObj.removeClass().addClass( buttonClass + ' dlm-download-complete' );
|
|
|
|
dlmXHRinstance.attachButtonEvent();
|
|
|
|
// Append the paragraph to the download-contaner
|
|
// Trigger the `dlm_download_complete` action
|
|
jQuery( document ).trigger( 'dlm_download_complete', [ this, button, buttonObj, _OBJECT_URL ] );
|
|
dlmXHRinstance.dlmLogDownload( instance.responseHeaders, 'completed', $setCookie );
|
|
// Recommended : Revoke the object URL after some time to free up resources
|
|
window.URL.revokeObjectURL( _OBJECT_URL );
|
|
button.removeAttribute( 'download' );
|
|
button.setAttribute( 'href', href );
|
|
buttonObj.find( '.dlm-xhr-loading-gif' ).remove();
|
|
// There is no way to find out whether user finished downloading
|
|
setTimeout( function() {
|
|
buttonObj.removeClass().addClass( buttonClass ).find( 'span.dlm-xhr-progress' ).remove();
|
|
}, 4000 );
|
|
}
|
|
};
|
|
|
|
if ( dlmXHRProgress ) {
|
|
request.addEventListener( 'progress', function( e ) {
|
|
let total = e.total;
|
|
// Set the total file size from the custom response header
|
|
if ( 'undefined' === typeof e.total || e.total === 'undefined' || 0 === e.total ) {
|
|
if ( 'undefined' !== typeof instance.responseHeaders[ 'x-dlm-filesize' ] ) {
|
|
total = instance.responseHeaders[ 'x-dlm-filesize' ];
|
|
}
|
|
}
|
|
let percent_complete = ( e.loaded / total ) * 100;
|
|
// Force perfect complete to have 2 digits
|
|
percent_complete = percent_complete.toFixed();
|
|
let $class = 'dlm-download-started';
|
|
buttonObj.find( 'span.dlm-xhr-progress' ).remove();
|
|
// Comment below lines for the new XHR loader so that we know where to rever
|
|
$class = $class + ' download-' + Math.ceil( percent_complete / 10 ) * 10;
|
|
|
|
if ( Infinity != percent_complete ) {
|
|
buttonObj.append( '<span class="dlm-xhr-progress"> ' + percent_complete + '%</span>' );
|
|
}
|
|
|
|
// Show spinner
|
|
buttonObj.removeClass().addClass( buttonClass + ' ' + $class );
|
|
// Trigger the `dlm_download_progress` action
|
|
jQuery( document ).trigger( 'dlm_download_progress', [ this, button, buttonObj, _OBJECT_URL, e, percent_complete ] );
|
|
} );
|
|
}
|
|
|
|
request.onerror = function() {
|
|
button.removeAttribute( 'download' );
|
|
button.setAttribute( 'href', href );
|
|
buttonObj.removeClass().addClass( buttonClass + ' dlm-no-xhr-download' ).find( 'span.dlm-xhr-progress' ).remove();
|
|
buttonObj.find( '.dlm-xhr-error' ).remove();
|
|
buttonObj.append( '<span class="dlm-xhr-error">' + dlmXHRtranslations.error + '</span>' );
|
|
console.log( '** An error occurred during the transaction' );
|
|
};
|
|
|
|
request.open( 'GET', href, true );
|
|
request.setRequestHeader( 'Cache-Control', 'no-store, no-cache, no-transform, max-age=0' );
|
|
request.setRequestHeader( 'dlm-xhr-request', 'dlm_XMLHttpRequest' );
|
|
request.send();
|
|
}
|
|
|
|
dlmLogDownload( headers, status, cookie, redirect_path = null, no_access = null, target = '_self' ) {
|
|
const currentURL = window.location.href;
|
|
const download_id = headers[ 'x-dlm-download-id' ] ?? headers[ 'dlm-download-id' ];
|
|
const version_id = headers[ 'x-dlm-version-id' ] ?? headers[ 'dlm-version-id' ];
|
|
|
|
const ua = navigator.userAgent || '';
|
|
const isSafari = /^((?!chrome|android|crios|fxios|edgios).)*safari/i.test( ua );
|
|
const isAppleSafari = isSafari && ! /CriOS|FxiOS|EdgiOS/i.test( ua );
|
|
// Early redirect — skip logging if no_access = true
|
|
if ( no_access && redirect_path ) {
|
|
if ( isAppleSafari ) {
|
|
window.location.href = redirect_path;
|
|
} else {
|
|
const tgt = target || '_self';
|
|
const downloadTab = window.open( redirect_path, tgt, 'noopener' );
|
|
if ( downloadTab ) {
|
|
downloadTab.location.href = redirect_path;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
const params = new URLSearchParams( {
|
|
action: 'log_dlm_xhr_download',
|
|
download_id,
|
|
version_id,
|
|
status,
|
|
cookie,
|
|
currentURL,
|
|
nonce: headers[ 'x-dlm-nonce' ],
|
|
} );
|
|
|
|
for ( const [ key, value ] of Object.entries( headers ) ) {
|
|
params.append( `responseHeaders[${ key }]`, value );
|
|
}
|
|
|
|
try {
|
|
navigator.sendBeacon(
|
|
dlmXHR.ajaxUrl,
|
|
new Blob( [ params.toString() ], { type: 'application/x-www-form-urlencoded;charset=UTF-8' } ),
|
|
);
|
|
} catch ( e ) {
|
|
try {
|
|
fetch( dlmXHR.ajaxUrl, { method: 'POST', body: params, keepalive: true } );
|
|
} catch ( _ ) {}
|
|
}
|
|
|
|
if ( ! redirect_path ) {
|
|
return;
|
|
}
|
|
|
|
if ( isAppleSafari ) {
|
|
window.location.href( redirect_path );
|
|
return;
|
|
}
|
|
|
|
const tgt = target || '_self';
|
|
const downloadTab = window.open( redirect_path, tgt, 'noopener' );
|
|
if ( no_access && downloadTab ) {
|
|
downloadTab.location.href = redirect_path;
|
|
}
|
|
}
|
|
|
|
dlmNoAccessModal( headers ) {
|
|
const instance = this;
|
|
let download = 'empty-download',
|
|
version = 'empty-version',
|
|
restriction = 'empty-restriction',
|
|
text = '';
|
|
|
|
/**
|
|
* Old headers, will be removed in a future release. DLM Amazon S3 adds these headers.
|
|
*/
|
|
if ( 'undefined' !== typeof headers[ 'dlm-download-id' ] ) {
|
|
download = headers[ 'dlm-download-id' ];
|
|
}
|
|
if ( 'undefined' !== typeof headers[ 'dlm-version-id' ] ) {
|
|
version = headers[ 'dlm-version-id' ];
|
|
}
|
|
if ( 'undefined' !== typeof headers[ 'dlm-no-access-modal-text' ] ) {
|
|
text = headers[ 'dlm-no-access-modal-text' ];
|
|
}
|
|
if ( 'undefined' !== typeof headers[ 'dlm-no-access-restriction' ] ) {
|
|
restriction = headers[ 'dlm-no-access-restriction' ];
|
|
}
|
|
// End of old headers.
|
|
|
|
/**
|
|
* New headers.
|
|
*/
|
|
if ( 'undefined' !== typeof headers[ 'x-dlm-download-id' ] ) {
|
|
download = headers[ 'x-dlm-download-id' ];
|
|
}
|
|
if ( 'undefined' !== typeof headers[ 'x-dlm-version-id' ] ) {
|
|
version = headers[ 'x-dlm-version-id' ];
|
|
}
|
|
if ( 'undefined' !== typeof headers[ 'x-dlm-no-access-modal-text' ] ) {
|
|
text = headers[ 'x-dlm-no-access-modal-text' ];
|
|
}
|
|
if ( 'undefined' !== typeof headers[ 'x-dlm-no-access-restriction' ] ) {
|
|
restriction = headers[ 'x-dlm-no-access-restriction' ];
|
|
}
|
|
// End of new headers.
|
|
|
|
const data = {
|
|
download_id: download,
|
|
version_id: version,
|
|
modal_text: text,
|
|
restriction,
|
|
action: 'no_access_dlm_xhr_download',
|
|
nonce: headers[ 'x-dlm-nonce' ],
|
|
};
|
|
|
|
jQuery( document ).trigger( 'dlm-xhr-modal-data', [ data, headers ] );
|
|
document.dispatchEvent(
|
|
new CustomEvent( 'dlm-xhr-modal-data', { detail: { data, headers } } ),
|
|
);
|
|
|
|
jQuery.post( dlmXHR.ajaxUrl, data, function( response ) {
|
|
jQuery( '#dlm-no-access-modal' ).remove();
|
|
//document.body.insertAdjacentHTML('beforeend', response);
|
|
const tempDiv = document.createElement( 'div' );
|
|
tempDiv.innerHTML = response;
|
|
// Extract and execute scripts from the response using a regular expression
|
|
const scriptRegex = /<script\b[^>]*>([\s\S]*?)<\/script>/gm;
|
|
// Remove script tags from tempDiv.innerHTML
|
|
tempDiv.innerHTML = tempDiv.innerHTML.replace( scriptRegex, '' );
|
|
let match;
|
|
while ( ( match = scriptRegex.exec( response ) ) !== null ) {
|
|
const scriptTag = match[ 0 ];
|
|
const scriptContent = match[ 1 ];
|
|
const newScript = document.createElement( 'script' );
|
|
// Check if the script has a src attribute
|
|
const srcMatch = scriptTag.match( /src=["']([^"']+)["']/ );
|
|
if ( srcMatch ) {
|
|
newScript.src = srcMatch[ 1 ];
|
|
} else {
|
|
newScript.textContent = scriptContent;
|
|
}
|
|
// Append the new script to the modal if exists
|
|
const modal = tempDiv.querySelector( '#dlm-no-access-modal' );
|
|
if ( modal ) {
|
|
modal.appendChild( newScript );
|
|
} else {
|
|
document.body.appendChild( newScript );
|
|
}
|
|
}
|
|
// Append the parsed HTML elements to the body
|
|
while ( tempDiv.firstChild ) {
|
|
document.body.appendChild( tempDiv.firstChild );
|
|
}
|
|
|
|
//jQuery('body').append(response);
|
|
jQuery( document ).trigger( data.action, [ response, data ] );
|
|
|
|
document.dispatchEvent(
|
|
new CustomEvent( data.action, { detail: [ response, data ] } ),
|
|
);
|
|
} );
|
|
}
|
|
|
|
dlmExternalDownload( headers, button, buttonObj, file_name, href ) {
|
|
const request = new XMLHttpRequest(),
|
|
buttonTarget = buttonObj.attr( 'target' );
|
|
let buttonClass = buttonObj.attr( 'class' ),
|
|
_OBJECT_URL,
|
|
uri = '';
|
|
|
|
if ( 'undefined' !== typeof headers[ 'dlm-external-download' ] ) {
|
|
uri = headers[ 'dlm-external-download' ];
|
|
}
|
|
if ( 'undefined' !== typeof headers[ 'x-dlm-external-download' ] ) {
|
|
uri = headers[ 'x-dlm-external-download' ];
|
|
}
|
|
buttonClass = ( 'undefined' !== typeof buttonClass && '' !== buttonClass ) ? buttonClass.replace( 'dlm-download-started', '' ).replace( 'dlm-download-completed', '' ) : '';
|
|
|
|
buttonObj.addClass( 'dlm-download-started' );
|
|
button.setAttribute( 'href', '#' );
|
|
button.removeAttribute( 'download' );
|
|
button.setAttribute( 'disabled', 'disabled' );
|
|
|
|
// Trigger the `dlm_download_triggered` action
|
|
jQuery( document ).trigger( 'dlm_download_triggered', [ this, button, buttonObj, _OBJECT_URL, request ] );
|
|
|
|
request.responseType = 'blob';
|
|
request.onreadystatechange = function() {
|
|
const {
|
|
status,
|
|
readyState,
|
|
statusText,
|
|
} = request;
|
|
|
|
if ( 403 === status ) {
|
|
dlmXHRinstance.dlmLogDownload( headers, 'failed', false );
|
|
request.abort();
|
|
buttonObj.find( '.dlm-xhr-error' ).remove();
|
|
buttonObj.append( '<span class="dlm-xhr-error">Acces Denied to file.</span>' );
|
|
return;
|
|
}
|
|
if ( status == 200 && readyState == 4 ) {
|
|
const blob = request.response;
|
|
|
|
_OBJECT_URL = URL.createObjectURL( blob );
|
|
// Remove event listener
|
|
button.removeEventListener( 'click', dlmXHRinstance.handleDownloadClick );
|
|
// Set the download attribute of the a.download-complete to the file name
|
|
button.setAttribute( 'download', `${ file_name }` );
|
|
// Set the href of the a.download-complete to the object URL
|
|
button.setAttribute( 'href', _OBJECT_URL );
|
|
// Trigger click on a.download-complete
|
|
button.click();
|
|
buttonObj.removeClass().addClass( buttonClass + ' dlm-download-complete' );
|
|
|
|
dlmXHRinstance.attachButtonEvent();
|
|
|
|
// Append the paragraph to the download-contaner
|
|
// Trigger the `dlm_download_complete` action
|
|
jQuery( document ).trigger( 'dlm_download_complete', [ this, button, buttonObj, _OBJECT_URL ] );
|
|
dlmXHRinstance.dlmLogDownload( headers, 'completed', false );
|
|
|
|
// Recommended : Revoke the object URL after some time to free up resources
|
|
window.URL.revokeObjectURL( _OBJECT_URL );
|
|
button.removeAttribute( 'download' );
|
|
button.setAttribute( 'href', href );
|
|
// There is no way to find out whether user finished downloading
|
|
buttonObj.find( '.dlm-xhr-loading-gif' ).remove();
|
|
setTimeout( function() {
|
|
buttonObj.removeClass().addClass( buttonClass ).find( 'span.dlm-xhr-progress' ).remove();
|
|
}, 1000 );
|
|
}
|
|
};
|
|
|
|
if ( dlmXHRProgress ) {
|
|
request.addEventListener( 'progress', function( e ) {
|
|
let total = e.total;
|
|
|
|
if ( 'undefined' === typeof e.total || e.total === 'undefined' ) {
|
|
total = request.getResponseHeader( 'X-DLM-Filesize' );
|
|
}
|
|
let percent_complete = ( e.loaded / total ) * 100;
|
|
// Force perfect complete to have 2 digits
|
|
percent_complete = percent_complete.toFixed();
|
|
let $class = 'dlm-download-started';
|
|
buttonObj.find( 'span.dlm-xhr-progress' ).remove();
|
|
// Comment below lines for the new XHR loader so that we know where to rever
|
|
$class = $class + ' download-' + Math.ceil( percent_complete / 10 ) * 10;
|
|
|
|
if ( Infinity != percent_complete ) {
|
|
buttonObj.append( '<span class="dlm-xhr-progress"> ' + percent_complete + '%</span>' );
|
|
}
|
|
|
|
// Show spinner
|
|
buttonObj.removeClass().addClass( buttonClass + ' ' + $class );
|
|
// Trigger the `dlm_download_progress` action
|
|
jQuery( document ).trigger( 'dlm_download_progress', [ this, button, buttonObj, _OBJECT_URL, e, percent_complete ] );
|
|
} );
|
|
}
|
|
|
|
request.onerror = function() {
|
|
button.removeAttribute( 'download' );
|
|
button.setAttribute( 'href', href );
|
|
buttonObj.removeClass().addClass( buttonClass + ' .dlm-no-xhr-download' ).find( 'span.dlm-xhr-progress' ).remove();
|
|
buttonObj.find( '.dlm-xhr-error' ).remove();
|
|
buttonObj.append( '<span class="dlm-xhr-error">' + dlmXHRtranslations.error + '</span>' );
|
|
console.log( '** An error occurred during the transaction' );
|
|
};
|
|
|
|
request.open( 'GET', uri, true );
|
|
request.setRequestHeader( 'Cache-Control', 'no-store, no-cache, no-transform, max-age=0' );
|
|
request.setRequestHeader( 'dlm-xhr-request', 'dlm_XMLHttpRequest' );
|
|
request.send();
|
|
}
|
|
}
|