// ==UserScript== // @name GM_fetch // @namespace https://scrapbox.io // @version 0.1.7 // @downloadURL https://scrapbox.io/api/code/takker/GM_fetch/scrapbox.user.js // @updateURL https://scrapbox.io/api/code/takker/GM_fetch/scrapbox.user.js // @description An implementation of the fetch API which leverages `GM_xmlhttpRequest` // @author takker // @homepage https://scrapbox.io/takker/GM_fetch // @match https://scrapbox.io/* // @connect * // @grant GM_xmlhttpRequest // @license MIT // @copyright Copyright (c) 2023 takker // ==/UserScript== var u=i=>new Headers(i.replace(/\r?\n[\t ]+/g," ").split(/\r\n|\r|\n/).flatMap(n=>{let[r,t]=n.split(":").map(e=>e.trim());return r?[[r,t]]:[]})),l=(i,n)=>new Promise((r,t)=>{let e=new Request(i,n),s=Object.fromEntries(e.headers.entries());if(n?.referrer&&(s.Referer=n.referrer),e.signal?.aborted){t(new DOMException("Aborted","AbortError"));return}let{abort:a}=GM_xmlhttpRequest({method:e.method,url:e.url,headers:s,...n?.body?{data:n.body}:{},anonymous:e.credentials==="omit",responseType:"stream",onerror:()=>{t(new TypeError("Network request failed"))},ontimeout:()=>{t(new TypeError("Network request timeout"))},onabort:()=>{t(new DOMException("Aborted","AbortError"))},onreadystatechange:o=>{switch(o.readyState){case 2:{let d=new Response(o.response,{status:o.status,statusText:o.statusText,headers:u(o.responseHeaders)});Object.defineProperty(d,"url",{value:o.finalUrl}),r(d);break}case 4:e.signal?.removeEventListener?.("abort",a);break;default:break}}});e.signal?.addEventListener?.("abort",a)});unsafeWindow.GM_fetch=l;