1class AjaxQueue { 2 3 constructor() { 4 5 this.queue = [] 6 this.stopped = false 7 this.currentRequest = null 8 9 } 10 11 stop() { 12 this.stopped = true; 13 } 14 15 run() { 16 this.stopped = false; 17 this.startNextRequest(); 18 } 19 20 clear() { 21 this.queue = []; 22 this.currentRequest = null; 23 } 24 25 /** 26 * @param {object} request AJAX request options 27 * @param {object} options General options for method 28 */ 29 call(request, overrideOptions={}) { 30 31 const self = this 32 33 const options = { 34 xhr: false, 35 forceNextRequest: false, 36 disableQueue: false, 37 defaultErrorHandling: true, 38 errorNotificationPrefix: 'Error: ' 39 } 40 41 Object.keys(overrideOptions).forEach((optionKey) => { 42 options[optionKey] = overrideOptions[optionKey] 43 }) 44 45 // console.log(request); 46 // Is the dev providing additional error handling? 47 var additionalCompleteHandling = false 48 if (request.complete) { 49 additionalCompleteHandling = request.complete 50 } 51 52 //When the task is complete, it needs to tell the AjaxQueue so we can run the next task 53 const requestComplete = (response) => { 54 this.requestComplete() 55 56 if (additionalCompleteHandling) { 57 additionalCompleteHandling(response) 58 } 59 }; 60 61 // Ensure key properties are set 62 if (!request.method) request.method = 'POST' 63 if (!request.complete) request.complete = () => {} 64 if (!request.headers) request.headers = {} 65 // if (!request.headers.accept) request.headers.accept = 'application/json' 66 if (!request.onAjaxStart) request.onAjaxStart = () => {} 67 68 if (options.defaultErrorHandling) { 69 let error = () => ''; 70 71 if (request.error) { 72 // Include the request's error handling in the default error handling 73 error = request.error 74 } 75 76 request.error = (response) => { 77 self.defaultErrorHandling(response, options) 78 error(response); 79 } 80 } 81 82 if (options.xhr) { 83 request.xhr = function () { 84 var xhr = new XMLHttpRequest(); 85 xhr.onreadystatechange = function () { 86 if (xhr.readyState == 2) { 87 // if (xhr.status == 200) { 88 // xhr.responseType = "blob"; 89 // } else { 90 // xhr.responseType = "text"; 91 // } 92 xhr.responseType = "text"; 93 } 94 }; 95 return xhr; 96 } 97 98 request.cache = false; 99 request.contentType = false;
100 request.processData = false; 101 } 102 103 if (options.disableQueue) { 104 105 var request = new AjaxTask(request, options, () => {}); 106 request.perform() 107 108 } else { 109 var request = new AjaxTask(request, options, requestComplete); 110 111 if (options.forceNextRequest) { 112 // Add this request to the top of the pile 113 this.queue.unshift(request) 114 } else { 115 this.queue.push(request) 116 } 117 118 this.startNextRequest(); 119 } 120 } 121 122 requestComplete() { 123 this.currentRequest = null; 124 this.startNextRequest(); 125 } 126 127 startNextRequest() { 128 //If the queue is stopped or a request is in progress, do nothing. 129 if (this.stopped || this.currentRequest) { 130 return false; 131 } 132 133 var request = this.queue.shift(); 134 if (request) { 135 this.currentRequest = request; 136 137 if (request.request.start) { 138 request.request.start() 139 } 140 141 request.perform(); 142 } 143 } 144 145 defaultErrorHandling(response, options) { 146 // Handle unauthenticated response 147 if (response.status == 401) { 148 window.location.href = '/login' 149 return; 150 } 151 if (response.status == 419) { 152 window.location.href = '/login' 153 return; 154 } 155 156 if (response.status == 404) { 157 handleAppMessage({ message: `Resource not found.` }) 158 return; 159 } 160 161 if (response.responseJSON) { 162 if (response.responseJSON.errors) { 163 let errors = [] 164 165 Object.keys(response.responseJSON.errors).forEach((name) => { 166 errors.push(`<li>${response.responseJSON.errors[name]}</li>`) 167 }) 168 169 handleAppMessage({ message: `<p><strong>Please handle the below validation errors:</strong></p><ul>` + errors.join('') + '</ul>' }) 170 171 } 172 173 if (response.responseJSON.error) { 174 handleAppMessage({ message: `${options.errorNotificationPrefix}${response.responseJSON.error}` }) 175 } 176 177 if (response.responseJSON.message) { 178 handleAppMessage({ message: `${options.errorNotificationPrefix}${response.responseJSON.message}` }) 179 } 180 } 181 182 if (!response.responseJSON && response.status != 200) { 183 handleAppMessage({ message: 'Unexpected server error.' }) 184 } 185 } 186} 187 188class AjaxTask { 189 190 constructor(request, options, requestComplete) { 191 this.request = request 192 193 194 this.request.complete = function(XMLHttpRequest, textStatus) { 195 //Let the AjaxQueue know to run the next task. 196 requestComplete(); 197 }; 198 199 } 200 201 perform() { 202 this.request.onAjaxStart() 203 $.ajax(this.request) 204 } 205} 206 207const ajaxRequest = new AjaxQueue()
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.