1/** 2 * @file 3 * Progress bar. 4 */ 5 6(function ($, Drupal) { 7 /** 8 * Theme function for the progress bar. 9 * 10 * @param {string} id 11 * The id for the progress bar. 12 * 13 * @return {string} 14 * The HTML for the progress bar. 15 */ 16 Drupal.theme.progressBar = function (id) { 17 return ( 18 `<div id="${id}" class="progress" aria-live="polite">` + 19 '<div class="progress__label"> </div>' + 20 '<div class="progress__track"><div class="progress__bar"></div></div>' + 21 '<div class="progress__percentage"></div>' + 22 '<div class="progress__description"> </div>' + 23 '</div>' 24 ); 25 }; 26 27 /** 28 * A progressbar object. Initialized with the given id. Must be inserted into 29 * the DOM afterwards through progressBar.element. 30 * 31 * Method is the function which will perform the HTTP request to get the 32 * progress bar state. Either "GET" or "POST". 33 * 34 * @example 35 * pb = new Drupal.ProgressBar('myProgressBar'); 36 * some_element.appendChild(pb.element); 37 * 38 * @constructor 39 * 40 * @param {string} id 41 * The id for the progressbar. 42 * @param {function} updateCallback 43 * Callback to run on update. 44 * @param {string} method 45 * HTTP method to use. 46 * @param {function} errorCallback 47 * Callback to call on error. 48 */ 49 Drupal.ProgressBar = function (id, updateCallback, method, errorCallback) { 50 this.id = id; 51 this.method = method || 'GET'; 52 this.updateCallback = updateCallback; 53 this.errorCallback = errorCallback; 54 55 // The WAI-ARIA setting aria-live="polite" will announce changes after 56 // users 57 // have completed their current activity and not interrupt the screen 58 // reader. 59 this.element = $(Drupal.theme('progressBar', id)); 60 }; 61 62 $.extend( 63 Drupal.ProgressBar.prototype, 64 /** @lends Drupal.ProgressBar# */ { 65 /** 66 * Set the percentage and status message for the progressbar. 67 * 68 * @param {number} percentage 69 * The progress percentage. 70 * @param {string} message 71 * The message to show the user. 72 * @param {string} label 73 * The text for the progressbar label. 74 */ 75 setProgress(percentage, message, label) { 76 if (percentage >= 0 && percentage <= 100) { 77 $(this.element) 78 .find('div.progress__bar') 79 .css('width', `${percentage}%`); 80 $(this.element) 81 .find('div.progress__percentage') 82 .html(`${percentage}%`); 83 } 84 $('div.progress__description', this.element).html(message); 85 $('div.progress__label', this.element).html(label); 86 if (this.updateCallback) { 87 this.updateCallback(percentage, message, this); 88 } 89 }, 90 91 /** 92 * Start monitoring progress via Ajax. 93 * 94 * @param {string} uri 95 * The URI to use for monitoring. 96 * @param {number} delay 97 * The delay for calling the monitoring URI. 98 */ 99 startMonitoring(uri, delay) { 100 this.delay = delay; 101 this.uri = uri; 102 this.sendPing(); 103 }, 104 105 /** 106 * Stop monitoring progress via Ajax. 107 */ 108 stopMonitoring() { 109 clearTimeout(this.timer); 110 // This allows monitoring to be stopped from within the callback. 111 this.uri = null; 112 }, 113 114 /** 115 * Request progress data from server. 116 */ 117 sendPing() { 118 if (this.timer) { 119 clearTimeout(this.timer); 120 } 121 if (this.uri) { 122 const pb = this; 123 // When doing a post request, you need non-null data. Otherwise a 124 // HTTP 411 or HTTP 406 (with Apache mod_security) error may result. 125 let uri = this.uri; 126 if (uri.indexOf('?') === -1) { 127 uri += '?'; 128 } else { 129 uri += '&'; 130 } 131 uri += '_format=json'; 132 $.ajax({ 133 type: this.method, 134 url: uri, 135 data: '', 136 dataType: 'json', 137 success(progress) { 138 // Display errors. 139 if (progress.status === 0) { 140 pb.displayError(progress.data); 141 return; 142 } 143 // Update display. 144 pb.setProgress( 145 progress.percentage, 146 progress.message, 147 progress.label, 148 ); 149 // Schedule next timer.
150 pb.timer = setTimeout(() => { 151 pb.sendPing(); 152 }, pb.delay); 153 }, 154 error(xmlhttp) { 155 const e = new Drupal.AjaxError(xmlhttp, pb.uri); 156 pb.displayError(`<pre>${e.message}</pre>`); 157 }, 158 }); 159 } 160 }, 161 162 /** 163 * Display errors on the page. 164 * 165 * @param {string} string 166 * The error message to show the user. 167 */ 168 displayError(string) { 169 const error = $('<div class="messages messages--error"></div>').html( 170 string, 171 ); 172 $(this.element).before(error).hide(); 173 174 if (this.errorCallback) { 175 this.errorCallback(this); 176 } 177 }, 178 }, 179 ); 180})(jQuery, Drupal);
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.