blob: dce2abfbf7b2ccefd087888ae0f82688321738ee [file] [log] [blame]
/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// URL calls currently 'in escrow'. This controls the spinny wheel animation
let async_escrow = {}
const ASYNC_MAXWAIT = 250; // ms to wait before displaying spinner
let async_status = 'clear';
let async_cache = {}
// Escrow spinner check
async function escrow_check() {
let now = new Date();
let show_spinner = false;
for (let k in async_escrow) {
if ((now - async_escrow[k]) > ASYNC_MAXWAIT) {
show_spinner = true;
break;
}
}
// Fetch or create the spinner
let spinner = document.getElementById('spinner');
if (!spinner) {
spinner = new HTML('div', {
id: 'spinner',
class: 'spinner'
});
let spinwheel = new HTML('div', {
id: 'spinwheel',
class: 'spinwheel'
});
spinner.inject(spinwheel);
spinner.inject(new HTML('h2', {}, "Loading, please wait.."));
document.body.appendChild(spinner);
}
// Show or don't show spinner?
if (show_spinner) {
spinner.style.display = 'block';
if (async_status === 'clear') {
console.log("Waiting for JSON resource, deploying spinner");
async_status = 'waiting';
}
} else {
spinner.style.display = 'none';
if (async_status === 'waiting') {
console.log("All URLs out of escrow, dropping spinner");
async_status = 'clear';
}
}
}
async function async_snap(error) {
let msg = await error.text();
msg = msg.replace(/<.*?>/g, ""); // strip HTML tags
if (error.status === 404) {
msg += "\n\nYou may need to be logged in with additional permissions in order to view this resource.";
if (pm_config.perm_error_postface) {
msg += pm_config.perm_error_postface;
}
}
modal("An error occured", "An error code %u occured while trying to fetch %s:\n%s".format(error.status, error.url, msg), "error");
}
// Asynchronous GET call
async function GET(url, callback, state) {
console.log("Fetching JSON resource at %s".format(url));
let pkey = "GET-%s-%s".format(callback, url);
let res;
let res_json;
state = state || {};
state.url = url;
if (state && state.cached === true && async_cache[url]) {
console.log("Fetching %s from cache".format(url));
res_json = async_cache[url];
} else {
try {
console.log("putting %s in escrow...".format(url));
async_escrow[pkey] = new Date(); // Log start of request in escrow dict
const rv = await fetch(url, {
credentials: 'same-origin'
}); // Wait for resource...
// Since this is an async request, the request may have been canceled
// by the time we get a response. Only do callback if not.
if (async_escrow[pkey] !== undefined) {
res = rv;
}
} catch (e) {
delete async_escrow[pkey]; // move out of escrow if failed
console.log("The URL %s could not be fetched: %s".format(url, e));
modal("An error occured", "An error occured while trying to fetch %s:\n%s".format(url, e), "error");
}
}
if (res !== undefined || res_json !== undefined) {
// We expect a 2xx return code (usually 200 or 201), snap otherwise
if ((res_json) || (res.status >= 200 && res.status < 300)) {
console.log("Successfully fetched %s".format(url))
let js;
if (res_json) {
js = res_json;
} else {
js = await res.json();
delete async_escrow[pkey]; // move out of escrow when fetched
async_cache[url] = js;
}
if (callback) {
callback(state, js);
} else {
console.log("No callback function was registered for %s, ignoring result.".format(url));
}
} else {
console.log("URL %s returned HTTP code %u, snapping!".format(url, res.status));
delete async_escrow[pkey]; // move out of escrow when fetched
async_snap(res);
}
}
}