您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Library with various utilities for userscripts - register listeners for when CSS selectors exist, intercept events, modify the DOM more easily and more
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/472956/1245169/UserUtils.js
// ==UserScript== // @name UserUtils // @description Library with various utilities for userscripts - register listeners for when CSS selectors exist, intercept events, modify the DOM more easily and more // @namespace https://github.com/Sv443-Network/UserUtils // @version 0.5.3 // @license MIT // @author Sv443 // @copyright Sv443 (https://github.com/Sv443) // @supportURL https://github.com/Sv443-Network/UserUtils/issues // @homepageURL https://github.com/Sv443-Network/UserUtils#readme // ==/UserScript== var UserUtils = (function (exports) { var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // lib/math.ts function clamp(value, min, max) { return Math.max(Math.min(value, max), min); } function mapRange(value, range_1_min, range_1_max, range_2_min, range_2_max) { if (Number(range_1_min) === 0 && Number(range_2_min) === 0) return value * (range_2_max / range_1_max); return (value - range_1_min) * ((range_2_max - range_2_min) / (range_1_max - range_1_min)) + range_2_min; } function randRange(...args) { let min, max; if (typeof args[0] === "number" && typeof args[1] === "number") { [min, max] = args; } else if (typeof args[0] === "number" && typeof args[1] !== "number") { min = 0; max = args[0]; } else throw new TypeError(`Wrong parameter(s) provided - expected: "number" and "number|undefined", got: "${typeof args[0]}" and "${typeof args[1]}"`); min = Number(min); max = Number(max); if (isNaN(min) || isNaN(max)) throw new TypeError(`Parameters "min" and "max" can't be NaN`); if (min > max) throw new TypeError(`Parameter "min" can't be bigger than "max"`); return Math.floor(Math.random() * (max - min + 1)) + min; } // lib/array.ts function randomItem(array) { return randomItemIndex(array)[0]; } function randomItemIndex(array) { if (array.length === 0) return [void 0, void 0]; const idx = randRange(array.length - 1); return [array[idx], idx]; } function takeRandomItem(arr) { const [itm, idx] = randomItemIndex(arr); if (idx === void 0) return void 0; arr.splice(idx, 1); return itm; } function randomizeArray(array) { const retArray = [...array]; if (array.length === 0) return array; for (let i = retArray.length - 1; i > 0; i--) { const j = Math.floor(randRange(0, 1e4) / 1e4 * (i + 1)); [retArray[i], retArray[j]] = [retArray[j], retArray[i]]; } return retArray; } // lib/dom.ts function getUnsafeWindow() { try { return unsafeWindow; } catch (e) { return window; } } function insertAfter(beforeElement, afterElement) { var _a; (_a = beforeElement.parentNode) == null ? void 0 : _a.insertBefore(afterElement, beforeElement.nextSibling); return afterElement; } function addParent(element2, newParent) { const oldParent = element2.parentNode; if (!oldParent) throw new Error("Element doesn't have a parent node"); oldParent.replaceChild(newParent, element2); newParent.appendChild(element2); return newParent; } function addGlobalStyle(style) { const styleElem = document.createElement("style"); styleElem.innerHTML = style; document.head.appendChild(styleElem); } function preloadImages(srcUrls, rejects = false) { const promises = srcUrls.map((src) => new Promise((res, rej) => { const image = new Image(); image.src = src; image.addEventListener("load", () => res(image)); image.addEventListener("error", (evt) => rejects && rej(evt)); })); return Promise.allSettled(promises); } function openInNewTab(href) { const openElem = document.createElement("a"); Object.assign(openElem, { className: "userutils-open-in-new-tab", target: "_blank", rel: "noopener noreferrer", href }); openElem.style.display = "none"; document.body.appendChild(openElem); openElem.click(); setTimeout(openElem.remove, 50); } function interceptEvent(eventObject, eventName, predicate) { if (typeof Error.stackTraceLimit === "number" && Error.stackTraceLimit < 1e3) { Error.stackTraceLimit = 1e3; } (function(original) { element.__proto__.addEventListener = function(...args) { if (args[0] === eventName && predicate()) return; else return original.apply(this, args); }; })(eventObject.__proto__.addEventListener); } function interceptWindowEvent(eventName, predicate) { return interceptEvent(getUnsafeWindow(), eventName, predicate); } function amplifyMedia(mediaElement, multiplier = 1) { const context = new (window.AudioContext || window.webkitAudioContext)(); const result = { mediaElement, amplify: (multiplier2) => { result.gain.gain.value = multiplier2; }, getAmpLevel: () => result.gain.gain.value, context, source: context.createMediaElementSource(mediaElement), gain: context.createGain() }; result.source.connect(result.gain); result.gain.connect(context.destination); result.amplify(multiplier); return result; } // lib/misc.ts function autoPlural(word, num) { if (Array.isArray(num) || num instanceof NodeList) num = num.length; return `${word}${num === 1 ? "" : "s"}`; } function pauseFor(time) { return new Promise((res) => { setTimeout(() => res(), time); }); } function debounce(func, timeout = 300) { let timer; return function(...args) { clearTimeout(timer); timer = setTimeout(() => func.apply(this, args), timeout); }; } function fetchAdvanced(_0) { return __async(this, arguments, function* (url, options = {}) { const { timeout = 1e4 } = options; const controller = new AbortController(); const id = setTimeout(() => controller.abort(), timeout); const res = yield fetch(url, __spreadProps(__spreadValues({}, options), { signal: controller.signal })); clearTimeout(id); return res; }); } // lib/onSelector.ts var selectorMap = /* @__PURE__ */ new Map(); function onSelector(selector, options) { let selectorMapItems = []; if (selectorMap.has(selector)) selectorMapItems = selectorMap.get(selector); selectorMapItems.push(options); selectorMap.set(selector, selectorMapItems); checkSelectorExists(selector, selectorMapItems); } function removeOnSelector(selector) { return selectorMap.delete(selector); } function checkSelectorExists(selector, options) { const deleteIndices = []; options.forEach((option, i) => { try { const elements = option.all ? document.querySelectorAll(selector) : document.querySelector(selector); if (elements !== null && elements instanceof NodeList && elements.length > 0 || elements !== null) { option.listener(elements); if (!option.continuous) deleteIndices.push(i); } } catch (err) { console.error(`Couldn't call listener for selector '${selector}'`, err); } }); if (deleteIndices.length > 0) { const newOptsArray = options.filter((_, i) => !deleteIndices.includes(i)); if (newOptsArray.length === 0) selectorMap.delete(selector); else { selectorMap.set(selector, newOptsArray); } } } function initOnSelector(options = {}) { const observer = new MutationObserver(() => { for (const [selector, options2] of selectorMap.entries()) checkSelectorExists(selector, options2); }); observer.observe(document.body, __spreadValues({ subtree: true, childList: true }, options)); } function getSelectorMap() { return selectorMap; } exports.addGlobalStyle = addGlobalStyle; exports.addParent = addParent; exports.amplifyMedia = amplifyMedia; exports.autoPlural = autoPlural; exports.clamp = clamp; exports.debounce = debounce; exports.fetchAdvanced = fetchAdvanced; exports.getSelectorMap = getSelectorMap; exports.getUnsafeWindow = getUnsafeWindow; exports.initOnSelector = initOnSelector; exports.insertAfter = insertAfter; exports.interceptEvent = interceptEvent; exports.interceptWindowEvent = interceptWindowEvent; exports.mapRange = mapRange; exports.onSelector = onSelector; exports.openInNewTab = openInNewTab; exports.pauseFor = pauseFor; exports.preloadImages = preloadImages; exports.randRange = randRange; exports.randomItem = randomItem; exports.randomItemIndex = randomItemIndex; exports.randomizeArray = randomizeArray; exports.removeOnSelector = removeOnSelector; exports.takeRandomItem = takeRandomItem; return exports; })({});