Updated to Drupal 8.6.4, which is PHP 7.3 friendly. Also updated HTMLaw library....
[yaffs-website] / web / core / misc / progress.es6.js
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">&nbsp;</div>' +
20       '<div class="progress__track"><div class="progress__bar"></div></div>' +
21       '<div class="progress__percentage"></div>' +
22       '<div class="progress__description">&nbsp;</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)
173           .before(error)
174           .hide();
175
176         if (this.errorCallback) {
177           this.errorCallback(this);
178         }
179       },
180     },
181   );
182 })(jQuery, Drupal);