small utilities that I'm tired of digging from old scripts to put in new ones.
Från och med
Detta skript bör inte installeras direkt. Det är ett bibliotek för andra skript att inkludera med meta-direktivet // @require https://updategf.qytechs.cn/scripts/468394/1218675/Itsnotlupus%27%20Tiny%20Utilities.js
// ==UserScript==
// @name Itsnotlupus' Tiny Utilities
// @namespace Itsnotlupus Industries
// @version 1.8
// @description small utilities that I'm tired of digging from old scripts to put in new ones.
// @author Itsnotlupus
// @license MIT
// ==/UserScript==
/* jshint esversion:11 */
/* jshint -W138 */
/** DOM queries - CSS selectors and XPath */
const $ = (q,d=document)=>d.querySelector(q);
const $$ = (q,d=document)=>d.querySelectorAll(q);
const $$$ = (q,d=document,x=d.evaluate(q,d),a=[],n=x.iterateNext()) => n ? (a.push(n), $$$(q,d,x,a)) : a;
/** calls a function whenever the DOM changes */
const observeDOM = (fn, e = document.documentElement, config = { attributes: 1, childList: 1, subtree: 1 }, o = new MutationObserver(fn)) => (o.observe(e,config),()=>o.disconnect());
/** check a condition on every DOM change until true */
const untilDOM = (v, doc=document,f=v.sup?()=>$(v,doc):v) => new Promise((r,_,d = observeDOM(() => (_=f()) && d() | r(_), doc.documentElement)) => 0);
/** promisify setTimeout and setInterval */
const sleep = (w = 100) => new Promise(r=>setTimeout(r, w));
const until = (v, w=100, t) => new Promise(r => t=setInterval((s=v.sup?$(v):v()) => s && (clearInterval(t), r(s)), w));
/** slightly less painful syntax to create DOM trees */
const crel = (name, attrs, ...children) => ((e = Object.assign(document.createElement(name), attrs)) => (e.append(...children), e))();
/** same, for SVG content. */
const svg = (name, attrs={}, ...children) => ((e=document.createElementNS('http://www.w3.org/2000/svg', name), _=Object.keys(attrs).forEach(k=>e.setAttribute(k,attrs[k])),__=e.append(...children)) => e)();
/** create a shadow dom with an isolated stylesheet */
const custom = (name, css, dom, e = crel(name), ss = e.attachShadow({mode:'closed'})) => (ss.adoptedStyleSheets = [ (s = new CSSStyleSheet(), s.replaceSync(css),s) ], ss.append(...dom), e);
/** add a stylesheet */
const addStyles = css => document.head.append(crel('style', { type: 'text/css', textContent: css }));
/** stolen from https://gist.github.com/nmsdvid/8807205 */
const slowDebounce = (a,b=250,c=0)=>(...d)=>clearTimeout(c,c=setTimeout(a,b,...d));
/** microtask debounce */
const fastDebounce = (f, l, s=0) => async (...a) => (l = a, !s && (await (s=1), s = 0, f(...l)));
/** requestAnimationFrame wrapper that allows a callback to request another run without referencing itself */
const rAF = (f, n=t=>f(t,r), r=_=>requestAnimationFrame(n)) => r();
/** define a few event listeners in one shot */
const events = (o, t=window, opts) => Object.keys(o).forEach(e=>t.addEventListener(e,o[e],opts));
/** promisify a @grant-less XHR. probably useless. */
const xhr = (url, type='') => new Promise((r,e,x=Object.assign(new XMLHttpRequest(), {responseType: type,onload() { r(x.response); },onerror:e}),_=x.open('GET',url)) => x.send());
/** fetch and parse */
const fetchDOM = (url, mimeType) => fetch(url).then(r=>r.text()).then(t=>new DOMParser().parseFromString(t,mimeType));
const fetchHTML = url => fetchDOM(url, 'text/html');
const fetchJSON = url => fetch(url).then(r=>r.json());
/** Prefetch a URL */
const prefetch = url => document.head.append(crel('link', { rel: 'prefetch', href: url }));