您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
small utilities that I'm tired of digging from old scripts to put in new ones.
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/468394/1228139/Itsnotlupus%27%20Tiny%20Utilities.js
// ==UserScript== // @name Itsnotlupus' Tiny Utilities // @namespace Itsnotlupus Industries // @version 1.12 // @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, 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, e=document, f=v.sup?()=>$(v,e):v) => new Promise((r,_,d = observeDOM(() => (_=f()) && d() | r(_), e)) => 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))); /** remember and shortcut what a (pure) function returns */ const memoize = (f,mkKey=args=>args[0]+'',cache=new Map()) => (...args) => ((key=mkKey(args)) => (cache.has(key) || cache.set(key, f(...args)), cache.get(key)))(); /** requestAnimationFrame wrapper that allows a callback to request another run without referencing itself * Use as: * rAF((time, next) => { * // cool animation code goes here. * next(); // run again next frame * }); */ const rAF = (f, n=t=>f(t,r), r=_=>requestAnimationFrame(n)) => r(); /** define a few event listeners in one shot - call the returned function to remove them. */ const events = (o, t=window, opts, f=op=>Object.keys(o).forEach(e=>t[op](e,o[e],opts))) => (f("addEventListener"), () => f("removeEventListener")); /** 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 })); /** Some sites break the `console` API. This attempts to restore a working console object. */ const fixConsole = (i = crel('iframe', { style:'display:none'}), _ = document.body.append(i)) => unsafeWindow.console = i.contentWindow.console;