"use strict";
(function(namespace){
const fossil = namespace;
fossil.fetch = function f(uri,opt){
const F = fossil;
if(!f.onload){
f.onload = (r)=>console.debug('fossil.fetch() XHR response:',r);
}
if(!f.onerror){
f.onerror = function(e){
console.error("fossil.fetch() XHR error:",e);
if(e instanceof Error) F.error('Exception:',e);
else F.error("Unknown error in handling of XHR request.");
};
}
if(!f.parseResponseHeaders){
f.parseResponseHeaders = function(h){
const rc = {};
if(!h) return rc;
const ar = h.trim().split(/[\r\n]+/);
ar.forEach(function(line) {
const parts = line.split(': ');
const header = parts.shift();
const value = parts.join(': ');
rc[header.toLowerCase()] = value;
});
return rc;
};
}
if('/'===uri[0]) uri = uri.substr(1);
if(!opt) opt = {};
else if('function'===typeof opt) opt={onload:opt};
if(!opt.onload) opt.onload = f.onload;
if(!opt.onerror) opt.onerror = f.onerror;
if(!opt.beforesend) opt.beforesend = f.beforesend;
if(!opt.aftersend) opt.aftersend = f.aftersend;
let payload = opt.payload, jsonResponse = false;
if(undefined!==payload){
opt.method = 'POST';
if(!(payload instanceof FormData)
&& !(payload instanceof Document)
&& !(payload instanceof Blob)
&& !(payload instanceof File)
&& !(payload instanceof ArrayBuffer)
&& ('object'===typeof payload
|| payload instanceof Array)){
payload = JSON.stringify(payload);
opt.contentType = 'application/json';
}
}
const url=[f.urlTransform(uri,opt.urlParams)],
x=new XMLHttpRequest();
if('json'===opt.responseType){
jsonResponse = true;
x.responseType = 'text';
}else{
x.responseType = opt.responseType||'text';
}
x.ontimeout = function(){
try{opt.aftersend()}catch(e){}
opt.onerror(new Error("XHR timeout of "+x.timeout+"ms expired."));
};
x.onreadystatechange = function(){
if(XMLHttpRequest.DONE !== x.readyState) return;
try{opt.aftersend()}catch(e){}
if(false && 0===x.status){
return;
}
if(200!==x.status){
let err;
try{
const j = JSON.parse(x.response);
if(j.error) err = new Error(j.error);
}catch(ex){}
opt.onerror(err || new Error("HTTP response status "+x.status+"."));
return;
}
const orh = opt.responseHeaders;
let head;
if(true===orh){
head = f.parseResponseHeaders(x.getAllResponseHeaders());
}else if('string'===typeof orh){
head = x.getResponseHeader(orh);
}else if(orh instanceof Array){
head = {};
orh.forEach((s)=>{
if('string' === typeof s) head[s.toLowerCase()] = x.getResponseHeader(s);
});
}
try{
const args = [(jsonResponse && x.response)
? JSON.parse(x.response) : x.response];
if(head) args.push(head);
opt.onload.apply(opt, args);
}catch(e){
opt.onerror(e);
}
};
try{opt.beforesend()}
catch(e){
opt.onerror(e);
return;
}
x.open(opt.method||'GET', url.join(''), true);
if('POST'===opt.method && 'string'===typeof opt.contentType){
x.setRequestHeader('Content-Type',opt.contentType);
}
x.timeout = +opt.timeout || f.timeout;
if(undefined!==payload) x.send(payload);
else x.send();
return this;
};
fossil.fetch.urlTransform = (u,p)=>fossil.repoUrl(u,p);
fossil.fetch.beforesend = function(){};
fossil.fetch.aftersend = function(){};
fossil.fetch.timeout = 15000;
})(window.fossil);