/** * Return an endpoint URL that has a protocol, domain and path */ function normalizedEndpoint(endpoint) { let matches = endpoint.match(/^(https?:\/\/)?([^\/]+)(\/.*)?$/i); if (!matches) throw Error("Invalid endpoint URL"); let protocol = matches[1] || "https://"; let domain = matches[2]; let path = matches[3] || "/api/v4"; return `${protocol}${domain}${path}`; } /** * Return the endpoint as it should be shown to the user */ function humanReadableEndpoint(endpoint) { let matches = endpoint.match(/^(https?:\/\/.+)\/api\/v4$/i); if (!matches) throw Error("Invalid endpoint URL"); return matches[1]; } /** * Shorthand for document.getElementById */ function byId(id, nullOk=false) { const el = document.getElementById(id); if (!el && !nullOk) { console.error(`No element #${id}`); } return el; } /** * Wrap a function so that it receives `this` as first argument */ function thisToArg(f) { return function(...rest) { return f(this, ...rest); } }