## UserUtils
Library with various utilities for userscripts - register listeners for when CSS selectors exist, intercept events, modify the DOM more easily and more.
Contains builtin TypeScript definitions.
## Table of Contents:
- [Installation](#installation)
- [Features](#features)
- [onSelector()](#onselector) - call a listener once a selector is found in the DOM
- [autoPlural()](#autoplural) - automatically pluralize a string
- [clamp()](#clamp) - clamp a number between a min and max value
- [pauseFor()](#pausefor) - pause the execution of a function for a given amount of time
- [debounce()](#debounce) - call a function only once, after a given amount of time
- [getUnsafeWindow()](#getunsafewindow) - get the unsafeWindow object or fall back to the regular window object
- [insertAfter()](#insertafter) - insert an element as a sibling after another element
- [addParent()](#addparent) - add a parent element around another element
- [addGlobalStyle()](#addglobalstyle) - add a global style to the page
- [preloadImages()](#preloadimages) - preload images into the browser cache for faster loading later on
- [fetchAdvanced()](#fetchadvanced) - wrapper around the fetch API with a timeout option
- [openInNewTab()](#openinnewtab) - open a link in a new tab
- [interceptEvent()](#interceptevent) - conditionally intercepts events registered by `addEventListener()` on any given EventTarget object
- [interceptWindowEvent()](#interceptwindowevent) - conditionally intercepts events registered by `addEventListener()` on the window object
- [License](#license)
## Installation:
- If you are using a bundler like webpack, you can install this package using npm:
```
npm i @sv443-network/userutils
```
Then, import it in your script as usual:
```ts
import { addGlobalStyle } from "@sv443-network/userutils";
// or
import * as userUtils from "@sv443-network/userutils";
```
Shameless plug: I also have a [webpack-based template for userscripts in TypeScript](https://github.com/Sv443/Userscript.ts) that you can use to get started quickly.
- If you are not using a bundler, you can include the latest release from GreasyFork by adding this directive to the userscript header:
```
// @require https://greasyfork.org/scripts/TODO
```
If you like using this library, please consider [supporting development](https://github.com/sponsors/Sv443)
## Features:
### onSelector()
\- UNFINISHED -
Registers a listener to be called whenever the element(s) behind a selector is/are found in the DOM.
In order to use this function, the MutationObservers have to be initialized with `initOnSelector()` first.
Example:
```ts
// TODO
```
### autoPlural()
Usage: `autoPlural(str: string, num: number | Array | NodeList): string`
Automatically pluralizes a string if the given number is not 1.
If an array or NodeList is passed, the length of it will be used.
Example:
```ts
autoPlural("apple", 0); // "apples"
autoPlural("apple", 1); // "apple"
autoPlural("apple", 2); // "apples"
autoPlural("apple", [1]); // "apple"
autoPlural("apple", [1, 2]); // "apples"
```
### clamp()
Usage: `clamp(num: number, min: number, max: number): number`
Clamps a number between a min and max value.
Example:
```ts
clamp(5, 0, 10); // 5
clamp(-1, 0, 10); // 0
clamp(Infinity, 0, 10); // 10
```
### pauseFor()
Usage: `pauseFor(ms: number): Promise`
Pauses async execution for a given amount of time.
Example:
```ts
async function run() {
console.log("Hello");
await pauseFor(3000); // waits for 3 seconds
console.log("World");
}
```
### debounce()
Usage: `debounce(func: Function, timeout?: number): Function`
Debounces a function, meaning that it will only be called once after a given amount of time.
This is very useful for functions that are called repeatedly, like event listeners, to remove extraneous calls.
The timeout will default to 300ms if left undefined.
Example:
```ts
window.addEventListener("resize", debounce((event) => {
console.log("Window was resized:", event);
}, 500)); // 500ms timeout
```
### getUnsafeWindow()
Usage: `getUnsafeWindow(): Window`
Returns the unsafeWindow object or falls back to the regular window object if the `@grant unsafeWindow` is not given.
Userscripts are sandboxed and do not have access to the regular window object, so this function is useful for websites that reject some events that were dispatched by the userscript.
Example:
```ts
const mouseEvent = new MouseEvent("click", {
view: getUnsafeWindow(),
});
document.body.dispatchEvent(mouseEvent);
```
### insertAfter()
Usage: `insertAfter(beforeElement: HTMLElement, afterElement: HTMLElement): HTMLElement`
Inserts the element passed as `afterElement` as a sibling after the passed `beforeElement`.
The `afterElement` will be returned.
Example:
```ts
const beforeElement = document.querySelector("#before");
const afterElement = document.createElement("div");
afterElement.innerText = "After";
insertAfter(beforeElement, afterElement);
```
### addParent()
Usage: `addParent(element: HTMLElement, newParent: HTMLElement): HTMLElement`
Adds a parent element around the passed `element` and returns the new parent.
Previously registered event listeners should be kept intact.
Example:
```ts
const element = document.querySelector("#element");
const newParent = document.createElement("a");
newParent.href = "https://example.org/";
addParent(element, newParent);
```
### addGlobalStyle()
Usage: `addGlobalStyle(css: string): void`
Adds a global style to the page in form of a `