You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
5.1 KiB
183 lines
5.1 KiB
/** |
|
* @file |
|
* Progress bar. |
|
*/ |
|
|
|
(function ($, Drupal) { |
|
/** |
|
* Theme function for the progress bar. |
|
* |
|
* @param {string} id |
|
* The id for the progress bar. |
|
* |
|
* @return {string} |
|
* The HTML for the progress bar. |
|
*/ |
|
Drupal.theme.progressBar = function (id) { |
|
const escapedId = Drupal.checkPlain(id); |
|
return ( |
|
`<div id="${escapedId}" class="progress" aria-live="polite">` + |
|
'<div class="progress__label"> </div>' + |
|
'<div class="progress__track"><div class="progress__bar"></div></div>' + |
|
'<div class="progress__percentage"></div>' + |
|
'<div class="progress__description"> </div>' + |
|
'</div>' |
|
); |
|
}; |
|
|
|
/** |
|
* A progressbar object. Initialized with the given id. Must be inserted into |
|
* the DOM afterwards through progressBar.element. |
|
* |
|
* Method is the function which will perform the HTTP request to get the |
|
* progress bar state. Either "GET" or "POST". |
|
* |
|
* @example |
|
* pb = new Drupal.ProgressBar('myProgressBar'); |
|
* some_element.appendChild(pb.element); |
|
* |
|
* @constructor |
|
* |
|
* @param {string} id |
|
* The id for the progressbar. |
|
* @param {function} updateCallback |
|
* Callback to run on update. |
|
* @param {string} method |
|
* HTTP method to use. |
|
* @param {function} errorCallback |
|
* Callback to call on error. |
|
*/ |
|
Drupal.ProgressBar = function (id, updateCallback, method, errorCallback) { |
|
this.id = id; |
|
this.method = method || 'GET'; |
|
this.updateCallback = updateCallback; |
|
this.errorCallback = errorCallback; |
|
|
|
// The WAI-ARIA setting aria-live="polite" will announce changes after |
|
// users |
|
// have completed their current activity and not interrupt the screen |
|
// reader. |
|
this.element = $(Drupal.theme('progressBar', id)); |
|
}; |
|
|
|
$.extend( |
|
Drupal.ProgressBar.prototype, |
|
/** @lends Drupal.ProgressBar# */ { |
|
/** |
|
* Set the percentage and status message for the progressbar. |
|
* |
|
* @param {number} percentage |
|
* The progress percentage. |
|
* @param {string} message |
|
* The message to show the user. |
|
* @param {string} label |
|
* The text for the progressbar label. |
|
*/ |
|
setProgress(percentage, message, label) { |
|
if (percentage >= 0 && percentage <= 100) { |
|
$(this.element) |
|
.find('div.progress__bar') |
|
.each(function () { |
|
this.style.width = `${percentage}%`; |
|
}); |
|
$(this.element) |
|
.find('div.progress__percentage') |
|
.html(`${percentage}%`); |
|
} |
|
$('div.progress__description', this.element).html(message); |
|
$('div.progress__label', this.element).html(label); |
|
if (this.updateCallback) { |
|
this.updateCallback(percentage, message, this); |
|
} |
|
}, |
|
|
|
/** |
|
* Start monitoring progress via Ajax. |
|
* |
|
* @param {string} uri |
|
* The URI to use for monitoring. |
|
* @param {number} delay |
|
* The delay for calling the monitoring URI. |
|
*/ |
|
startMonitoring(uri, delay) { |
|
this.delay = delay; |
|
this.uri = uri; |
|
this.sendPing(); |
|
}, |
|
|
|
/** |
|
* Stop monitoring progress via Ajax. |
|
*/ |
|
stopMonitoring() { |
|
clearTimeout(this.timer); |
|
// This allows monitoring to be stopped from within the callback. |
|
this.uri = null; |
|
}, |
|
|
|
/** |
|
* Request progress data from server. |
|
*/ |
|
sendPing() { |
|
if (this.timer) { |
|
clearTimeout(this.timer); |
|
} |
|
if (this.uri) { |
|
const pb = this; |
|
// When doing a post request, you need non-null data. Otherwise a |
|
// HTTP 411 or HTTP 406 (with Apache mod_security) error may result. |
|
let uri = this.uri; |
|
if (!uri.includes('?')) { |
|
uri += '?'; |
|
} else { |
|
uri += '&'; |
|
} |
|
uri += '_format=json'; |
|
$.ajax({ |
|
type: this.method, |
|
url: uri, |
|
data: '', |
|
dataType: 'json', |
|
success(progress) { |
|
// Display errors. |
|
if (progress.status === 0) { |
|
pb.displayError(progress.data); |
|
return; |
|
} |
|
// Update display. |
|
pb.setProgress( |
|
progress.percentage, |
|
progress.message, |
|
progress.label, |
|
); |
|
// Schedule next timer. |
|
pb.timer = setTimeout(() => { |
|
pb.sendPing(); |
|
}, pb.delay); |
|
}, |
|
error(xmlhttp) { |
|
const e = new Drupal.AjaxError(xmlhttp, pb.uri); |
|
pb.displayError(`<pre>${e.message}</pre>`); |
|
}, |
|
}); |
|
} |
|
}, |
|
|
|
/** |
|
* Display errors on the page. |
|
* |
|
* @param {string} string |
|
* The error message to show the user. |
|
*/ |
|
displayError(string) { |
|
const error = $('<div class="messages messages--error"></div>').html( |
|
string, |
|
); |
|
$(this.element).before(error).hide(); |
|
|
|
if (this.errorCallback) { |
|
this.errorCallback(this); |
|
} |
|
}, |
|
}, |
|
); |
|
})(jQuery, Drupal);
|
|
|