UserUtils

Library with various utilities for userscripts - register listeners for when CSS selectors exist, intercept events, modify the DOM more easily and more

Od 04.09.2023.. Pogledajte najnovija verzija.

Ovu skriptu ne treba izravno instalirati. To je biblioteka za druge skripte koje se uključuju u meta direktivu // @require https://update.greasyforks.org/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;

})({});
长期地址
遇到问题?请前往 GitHub 提 Issues。