"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);