@sv443-network/userutils 0.4.1 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @sv443-network/userutils
2
2
 
3
+ ## 0.5.1
4
+
5
+ ### Patch Changes
6
+
7
+ - aa8efbd: fix documentation
8
+
9
+ ## 0.5.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 54e7905: Features:
14
+
15
+ - add function `amplifyMedia()` to boost the volume of a MediaElement past its default maximum
16
+ - allow all `MutationObserver.observe()` options to be passed to `initOnSelector()`
17
+
18
+ Fixes:
19
+
20
+ - fix `onSelector()` not triggering correctly
21
+
3
22
  ## 0.4.1
4
23
 
5
24
  ### Patch Changes
@@ -11,12 +30,12 @@
11
30
  ### Minor Changes
12
31
 
13
32
  - 231a79c: Refactored code and documentation and added new functions:
14
- - mapRange() to map a number from one range to the same spot in another range
15
- - randRange() to generate a random number between a min and max boundary
16
- - randomItem() to return a random item from an array
17
- - randomItemIndex() to return a tuple of a random item and its index from an array
18
- - takeRandomItem() to return a random item from an array and mutate it to remove the item
19
- - randomizeArray() to return a copy of the array with its items in a random order
33
+ - `mapRange()` to map a number from one range to the same spot in another range
34
+ - `randRange()` to generate a random number between a min and max boundary
35
+ - `randomItem()` to return a random item from an array
36
+ - `randomItemIndex()` to return a tuple of a random item and its index from an array
37
+ - `takeRandomItem()` to return a random item from an array and mutate it to remove the item
38
+ - `randomizeArray()` to return a copy of the array with its items in a random order
20
39
 
21
40
  ### Patch Changes
22
41
 
@@ -26,13 +45,13 @@
26
45
 
27
46
  ### Minor Changes
28
47
 
29
- - 07ec443: add getSelectorMap() to return all currently registered selectors
48
+ - 07ec443: add `getSelectorMap()` to return all currently registered selectors
30
49
 
31
50
  ## 0.2.0
32
51
 
33
52
  ### Minor Changes
34
53
 
35
- - 0cf2254: add onSelector() to call a listener once a selector is found in the DOM
54
+ - 0cf2254: add `onSelector()` to call a listener once a selector is found in the DOM
36
55
 
37
56
  ## 0.1.1
38
57
 
@@ -0,0 +1,75 @@
1
+ ## UserUtils
2
+ Library with various utilities for userscripts - register listeners for when CSS selectors exist, intercept events, modify the DOM more easily and more.
3
+ Contains builtin TypeScript declarations. Webpack compatible and supports ESM and CJS.
4
+ Licensed under the [MIT license.](https://github.com/Sv443-Network/UserUtils/blob/main/LICENSE.txt)
5
+
6
+ If you like using this library, please consider [supporting the development ❤️](https://github.com/sponsors/Sv443)
7
+
8
+ <br>
9
+
10
+ ### Full documentation [on GitHub](https://github.com/Sv443-Network/UserUtils#readme)
11
+
12
+ <br>
13
+
14
+ ## Features:
15
+ - DOM:
16
+ - [onSelector()](https://github.com/Sv443-Network/UserUtils#onselector) - call a listener once a selector is found in the DOM
17
+ - [initOnSelector()](https://github.com/Sv443-Network/UserUtils#initonselector) - needs to be called once to be able to use `onSelector()`
18
+ - [getSelectorMap()](https://github.com/Sv443-Network/UserUtils#getselectormap) - returns all currently registered selectors, listeners and options
19
+ - [getUnsafeWindow()](https://github.com/Sv443-Network/UserUtils#getunsafewindow) - get the unsafeWindow object or fall back to the regular window object
20
+ - [insertAfter()](https://github.com/Sv443-Network/UserUtils#insertafter) - insert an element as a sibling after another element
21
+ - [addParent()](https://github.com/Sv443-Network/UserUtils#addparent) - add a parent element around another element
22
+ - [addGlobalStyle()](https://github.com/Sv443-Network/UserUtils#addglobalstyle) - add a global style to the page
23
+ - [preloadImages()](https://github.com/Sv443-Network/UserUtils#preloadimages) - preload images into the browser cache for faster loading later on
24
+ - [openInNewTab()](https://github.com/Sv443-Network/UserUtils#openinnewtab) - open a link in a new tab
25
+ - [interceptEvent()](https://github.com/Sv443-Network/UserUtils#interceptevent) - conditionally intercepts events registered by `addEventListener()` on any given EventTarget object
26
+ - [interceptWindowEvent()](https://github.com/Sv443-Network/UserUtils#interceptwindowevent) - conditionally intercepts events registered by `addEventListener()` on the window object
27
+ - [amplifyMedia()](https://github.com/Sv443-Network/UserUtils#amplifymedia) - amplify an audio or video element's volume past the maximum of 100%
28
+ - Math:
29
+ - [clamp()](https://github.com/Sv443-Network/UserUtils#clamp) - constrain a number between a min and max value
30
+ - [mapRange()](https://github.com/Sv443-Network/UserUtils#maprange) - map a number from one range to the same spot in another range
31
+ - [randRange()](https://github.com/Sv443-Network/UserUtils#randrange) - generate a random number between a min and max boundary
32
+ - Misc:
33
+ - [autoPlural()](https://github.com/Sv443-Network/UserUtils#autoplural) - automatically pluralize a string
34
+ - [pauseFor()](https://github.com/Sv443-Network/UserUtils#pausefor) - pause the execution of a function for a given amount of time
35
+ - [debounce()](https://github.com/Sv443-Network/UserUtils#debounce) - call a function only once, after a given amount of time
36
+ - [fetchAdvanced()](https://github.com/Sv443-Network/UserUtils#fetchadvanced) - wrapper around the fetch API with a timeout option
37
+ - Arrays:
38
+ - [randomItem()](https://github.com/Sv443-Network/UserUtils#randomitem) - returns a random item from an array
39
+ - [randomItemIndex()](https://github.com/Sv443-Network/UserUtils#randomitemindex) - returns a tuple of a random item and its index from an array
40
+ - [takeRandomItem()](https://github.com/Sv443-Network/UserUtils#takerandomitem) - returns a random item from an array and mutates it to remove the item
41
+ - [randomizeArray()](https://github.com/Sv443-Network/UserUtils#randomizearray) - returns a copy of the array with its items in a random order
42
+
43
+ <br><br>
44
+
45
+ ## Installation:
46
+ - If you are using a bundler like webpack, you can install this package using npm:
47
+ ```
48
+ npm i @sv443-network/userutils
49
+ ```
50
+
51
+ Then, import it in your script as usual:
52
+ ```ts
53
+ import { addGlobalStyle } from "@sv443-network/userutils";
54
+ // or
55
+ import * as userUtils from "@sv443-network/userutils";
56
+ ```
57
+
58
+ 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.
59
+
60
+ <br>
61
+
62
+ - If you are not using a bundler, you can include the latest release from GreasyFork by adding this directive to the userscript header:
63
+ ```
64
+ // @require https://greasyfork.org/scripts/472956-userutils/code/UserUtils.js
65
+ ```
66
+
67
+ Then, access the functions on the global variable `UserUtils`:
68
+ ```ts
69
+ UserUtils.addGlobalStyle("body { background-color: red; }");
70
+
71
+ // or using object destructuring:
72
+
73
+ const { clamp } = UserUtils;
74
+ console.log(clamp(1, 5, 10); // 5
75
+ ```
package/README.md CHANGED
@@ -2,14 +2,17 @@
2
2
 
3
3
  ## UserUtils
4
4
  Library with various utilities for userscripts - register listeners for when CSS selectors exist, intercept events, modify the DOM more easily and more.
5
- Contains builtin TypeScript declarations. Webpack compatible and supports ESM and CJS.
5
+ Contains builtin TypeScript declarations. Webpack compatible and supports ESM and CJS.
6
+ If you like using this library, please consider [supporting the development ❤️](https://github.com/sponsors/Sv443)
6
7
 
7
8
  </div>
8
9
  <br>
9
10
 
10
11
  ## Table of Contents:
11
- - [Installation](#installation)
12
- - [Features](#features)
12
+ - [**Installation**](#installation)
13
+ - [**Preamble**](#preamble)
14
+ - [**License**](#license)
15
+ - [**Features**](#features)
13
16
  - [DOM:](#dom)
14
17
  - [onSelector()](#onselector) - call a listener once a selector is found in the DOM
15
18
  - [initOnSelector()](#initonselector) - needs to be called once to be able to use `onSelector()`
@@ -22,8 +25,9 @@ Contains builtin TypeScript declarations. Webpack compatible and supports ESM an
22
25
  - [openInNewTab()](#openinnewtab) - open a link in a new tab
23
26
  - [interceptEvent()](#interceptevent) - conditionally intercepts events registered by `addEventListener()` on any given EventTarget object
24
27
  - [interceptWindowEvent()](#interceptwindowevent) - conditionally intercepts events registered by `addEventListener()` on the window object
28
+ - [amplifyMedia()](#amplifymedia) - amplify an audio or video element's volume past the maximum of 100%
25
29
  - [Math:](#math)
26
- - [clamp()](#clamp) - clamp a number between a min and max value
30
+ - [clamp()](#clamp) - constrain a number between a min and max value
27
31
  - [mapRange()](#maprange) - map a number from one range to the same spot in another range
28
32
  - [randRange()](#randrange) - generate a random number between a min and max boundary
29
33
  - [Misc:](#misc)
@@ -36,7 +40,6 @@ Contains builtin TypeScript declarations. Webpack compatible and supports ESM an
36
40
  - [randomItemIndex()](#randomitemindex) - returns a tuple of a random item and its index from an array
37
41
  - [takeRandomItem()](#takerandomitem) - returns a random item from an array and mutates it to remove the item
38
42
  - [randomizeArray()](#randomizearray) - returns a copy of the array with its items in a random order
39
- - [License](#license)
40
43
 
41
44
  <br><br>
42
45
 
@@ -57,17 +60,42 @@ Contains builtin TypeScript declarations. Webpack compatible and supports ESM an
57
60
 
58
61
  - If you are not using a bundler, you can include the latest release from GreasyFork by adding this directive to the userscript header:
59
62
  ```
60
- // @require https://greasyfork.org/scripts/TODO
63
+ // @require https://greasyfork.org/scripts/472956-userutils/code/UserUtils.js
61
64
  ```
62
65
 
63
- <br>
66
+ Then, access the functions on the global variable `UserUtils`:
67
+ ```ts
68
+ UserUtils.addGlobalStyle("body { background-color: red; }");
64
69
 
65
- If you like using this library, please consider [supporting development](https://github.com/sponsors/Sv443)
70
+ // or using object destructuring:
71
+
72
+ const { clamp } = UserUtils;
73
+ console.log(clamp(1, 5, 10); // 5
74
+ ```
75
+
76
+ <br><br>
77
+
78
+ ## Preamble:
79
+ This library is written in TypeScript and contains builtin TypeScript declarations.
80
+ The usages and examples in this readme are written in TypeScript, but the library can also be used in plain JavaScript.
81
+
82
+ Some functions require the `@run-at` or `@grant` directives to be tweaked in the userscript header or have other requirements.
83
+ Their documentation will contain a section marked by a warning emoji (⚠️) that will go into more detail.
84
+
85
+ If the usage contains multiple definitions of the function, each line represents an overload and you can choose which one you want to use.
86
+
87
+ <br><br>
88
+
89
+ ## License:
90
+ This library is licensed under the MIT License.
91
+ See the [license file](./LICENSE.txt) for details.
66
92
 
67
93
  <br><br>
68
94
 
69
95
  ## Features:
70
96
 
97
+ <br>
98
+
71
99
  ## DOM:
72
100
 
73
101
  ### onSelector()
@@ -125,22 +153,22 @@ onSelector<HTMLInputElement>("input[value=\"5\"]", {
125
153
  ### initOnSelector()
126
154
  Usage:
127
155
  ```ts
128
- initOnSelector(options?: {
129
- attributes?: boolean,
130
- characterData?: boolean,
131
- }): void
156
+ initOnSelector(options?: MutationObserverInit): void
132
157
  ```
133
158
 
134
159
  Initializes the MutationObserver that is used by [`onSelector()`](#onselector) to check for the registered selectors whenever a DOM change occurs on the `<body>`
135
160
  By default, this only checks if elements are added or removed (at any depth).
136
-
137
- Set `attributes` to `true` to also check for attribute changes on every single descendant of the `<body>` (defaults to false).
138
- Set `characterData` to `true` to also check for character data changes on every single descendant of the `<body>` (defaults to false).
139
-
140
- ⚠️ Using these extra options can have a performance impact on larger sites or sites with a constantly changing DOM.
141
-
161
+
142
162
  ⚠️ This function needs to be run after the DOM has loaded (when using `@run-at document-end` or after `DOMContentLoaded` has fired).
143
163
 
164
+ The options object is passed directly to the MutationObserver.observe() method.
165
+ Note that `options.subtree` and `options.childList` will be set to true by default.
166
+ You may see all options [here](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe#options), but these are the important ones:
167
+ > Set `options.attributes` to `true` to also check for attribute changes on every single descendant of the `<body>` (defaults to false).
168
+ > Set `options.characterData` to `true` to also check for character data changes on every single descendant of the `<body>` (defaults to false).
169
+ >
170
+ > ⚠️ Using these extra options can have a performance impact on larger sites or sites with a constantly changing DOM.
171
+
144
172
  <details><summary><b>Example - click to view</b></summary>
145
173
 
146
174
  ```ts
@@ -315,7 +343,7 @@ Usage: `openInNewTab(url: string): void`
315
343
 
316
344
  Creates an invisible anchor with a `_blank` target and clicks it.
317
345
  Contrary to `window.open()`, this has a lesser chance to get blocked by the browser's popup blocker and doesn't open the URL as a new window.
318
- This function has to be run in relatively quick succession in response to a user interaction event, else the browser might reject it.
346
+ This function has to be run in response to a user interaction event, else the browser might reject it.
319
347
 
320
348
  ⚠️ This function needs to be run after the DOM has loaded (when using `@run-at document-end` or after `DOMContentLoaded` has fired).
321
349
 
@@ -369,6 +397,52 @@ interceptWindowEvent("beforeunload", () => {
369
397
 
370
398
  </details>
371
399
 
400
+ <br>
401
+
402
+ ### amplifyMedia()
403
+ Usage: `amplifyMedia(mediaElement: HTMLMediaElement, multiplier?: number): AmplifyMediaResult`
404
+
405
+ Amplifies the gain of a media element (like `<audio>` or `<video>`) by a given multiplier (defaults to 1.0).
406
+ This is how you can increase the volume of a media element beyond the default maximum volume of 1.0 or 100%.
407
+ Make sure to limit the multiplier to a reasonable value ([clamp()](#clamp) is good for this), as it may cause clipping or bleeding eardrums.
408
+
409
+ ⚠️ This function has to be run in response to a user interaction event, else the browser will reject it because of the strict autoplay policy.
410
+
411
+ Returns an object with the following properties:
412
+ | Property | Description |
413
+ | :-- | :-- |
414
+ | `mediaElement` | The passed media element |
415
+ | `amplify()` | A function to change the amplification level |
416
+ | `getAmpLevel()` | A function to return the current amplification level |
417
+ | `context` | The AudioContext instance |
418
+ | `source` | The MediaElementSourceNode instance |
419
+ | `gain` | The GainNode instance |
420
+
421
+ <details><summary><b>Example - click to view</b></summary>
422
+
423
+ ```ts
424
+ const audio = document.querySelector<HTMLAudioElement>("audio");
425
+ const button = document.querySelector<HTMLButtonElement>("button");
426
+
427
+ // amplifyMedia needs to be called in response to a user interaction event:
428
+ button.addEventListener("click", () => {
429
+ const { amplify, getAmpLevel } = amplifyMedia(audio);
430
+
431
+ const setGain = (value: number) => {
432
+ // constrain the value to between 0 and 5
433
+ amplify(clamp(value, 0, 5));
434
+ console.log("Gain set to", getAmpLevel());
435
+ }
436
+
437
+ setGain(2); // set gain to 2x
438
+ setGain(3.5); // set gain to 3.5x
439
+
440
+ console.log(getAmpLevel()); // 3.5
441
+ });
442
+ ```
443
+
444
+ </details>
445
+
372
446
  <br><br>
373
447
 
374
448
  ## Math:
@@ -599,14 +673,7 @@ randomizeArray([1, 2, 3, 4, 5, 6]); // [3, 1, 5, 2, 4, 6]
599
673
 
600
674
  <br>
601
675
 
602
-
603
- <br><br>
604
-
605
- ## License:
606
- This library is licensed under the MIT License.
607
- See the [license file](./LICENSE.txt) for details.
608
-
609
- <br><br>
676
+ <br><br><br><br>
610
677
 
611
678
  <div style="text-align: center;" align="center">
612
679
 
package/dist/index.d.mts CHANGED
@@ -40,7 +40,7 @@ declare function preloadImages(srcUrls: string[], rejects?: boolean): Promise<Pr
40
40
  * Creates an invisible anchor with a `_blank` target and clicks it.
41
41
  * Contrary to `window.open()`, this has a lesser chance to get blocked by the browser's popup blocker and doesn't open the URL as a new window.
42
42
  *
43
- * This function has to be run in relatively quick succession in response to a user interaction event, else the browser might reject it.
43
+ * This function has to be run in response to a user interaction event, else the browser might reject it.
44
44
  */
45
45
  declare function openInNewTab(href: string): void;
46
46
  /**
@@ -55,6 +55,30 @@ declare function interceptEvent<TEvtObj extends EventTarget>(eventObject: TEvtOb
55
55
  * Calling this function will set the `Error.stackTraceLimit` to 1000 to ensure the stack trace is preserved.
56
56
  */
57
57
  declare function interceptWindowEvent(eventName: keyof WindowEventMap, predicate: () => boolean): void;
58
+ /**
59
+ * Amplifies the gain of the passed media element's audio by the specified multiplier.
60
+ * This function supports any media element like `<audio>` or `<video>`
61
+ *
62
+ * This function has to be run in response to a user interaction event, else the browser will reject it because of the strict autoplay policy.
63
+ *
64
+ * @returns Returns an object with the following properties:
65
+ * | Property | Description |
66
+ * | :-- | :-- |
67
+ * | `mediaElement` | The passed media element |
68
+ * | `amplify()` | A function to change the amplification level |
69
+ * | `getAmpLevel()` | A function to return the current amplification level |
70
+ * | `context` | The AudioContext instance |
71
+ * | `source` | The MediaElementSourceNode instance |
72
+ * | `gain` | The GainNode instance |
73
+ */
74
+ declare function amplifyMedia<TElem extends HTMLMediaElement>(mediaElement: TElem, multiplier?: number): {
75
+ mediaElement: TElem;
76
+ amplify: (multiplier: number) => void;
77
+ getAmpLevel: () => number;
78
+ context: AudioContext;
79
+ source: MediaElementAudioSourceNode;
80
+ gain: GainNode;
81
+ };
58
82
 
59
83
  /** Ensures the passed `value` always stays between `min` and `max` */
60
84
  declare function clamp(value: number, min: number, max: number): number;
@@ -68,12 +92,6 @@ declare function randRange(min: number, max: number): number;
68
92
  /** Returns a random number between 0 and `max` (inclusive) */
69
93
  declare function randRange(max: number): number;
70
94
 
71
- type InitOnSelectorOpts = {
72
- /** Set to true if mutations to any element's attributes are to also trigger the onSelector check (warning: this might draw a lot of performance on larger sites) */
73
- attributes?: boolean;
74
- /** Set to true if mutations to any element's character data are to also trigger the onSelector check (warning: this might draw a lot of performance on larger sites) */
75
- characterData?: boolean;
76
- };
77
95
  type OnSelectorOpts<TElem extends Element = HTMLElement> = SelectorOptsOne<TElem> | SelectorOptsAll<TElem>;
78
96
  type SelectorOptsOne<TElem extends Element> = SelectorOptsBase & {
79
97
  /** Whether to use `querySelectorAll()` instead - default is false */
@@ -128,10 +146,10 @@ declare function onSelector<TElem extends Element = HTMLElement>(selector: strin
128
146
  declare function removeOnSelector(selector: string): boolean;
129
147
  /**
130
148
  * Initializes a MutationObserver that checks for all registered selectors whenever an element is added to or removed from the `<body>`
131
- * @param opts For fine-tuning when the MutationObserver checks for the selectors
149
+ * @param options For fine-tuning what triggers the MutationObserver's checking function - `subtree` and `childList` are set to true by default
132
150
  */
133
- declare function initOnSelector(opts?: InitOnSelectorOpts): void;
151
+ declare function initOnSelector(options?: MutationObserverInit): void;
134
152
  /** Returns all currently registered selectors, as a map of selector strings to their associated options */
135
153
  declare function getSelectorMap(): Map<string, OnSelectorOpts[]>;
136
154
 
137
- export { FetchAdvancedOpts, InitOnSelectorOpts, OnSelectorOpts, addGlobalStyle, addParent, autoPlural, clamp, debounce, fetchAdvanced, getSelectorMap, getUnsafeWindow, initOnSelector, insertAfter, interceptEvent, interceptWindowEvent, mapRange, onSelector, openInNewTab, pauseFor, preloadImages, randRange, randomItem, randomItemIndex, randomizeArray, removeOnSelector, takeRandomItem };
155
+ export { FetchAdvancedOpts, OnSelectorOpts, addGlobalStyle, addParent, amplifyMedia, autoPlural, clamp, debounce, fetchAdvanced, getSelectorMap, getUnsafeWindow, initOnSelector, insertAfter, interceptEvent, interceptWindowEvent, mapRange, onSelector, openInNewTab, pauseFor, preloadImages, randRange, randomItem, randomItemIndex, randomizeArray, removeOnSelector, takeRandomItem };
package/dist/index.d.ts CHANGED
@@ -40,7 +40,7 @@ declare function preloadImages(srcUrls: string[], rejects?: boolean): Promise<Pr
40
40
  * Creates an invisible anchor with a `_blank` target and clicks it.
41
41
  * Contrary to `window.open()`, this has a lesser chance to get blocked by the browser's popup blocker and doesn't open the URL as a new window.
42
42
  *
43
- * This function has to be run in relatively quick succession in response to a user interaction event, else the browser might reject it.
43
+ * This function has to be run in response to a user interaction event, else the browser might reject it.
44
44
  */
45
45
  declare function openInNewTab(href: string): void;
46
46
  /**
@@ -55,6 +55,30 @@ declare function interceptEvent<TEvtObj extends EventTarget>(eventObject: TEvtOb
55
55
  * Calling this function will set the `Error.stackTraceLimit` to 1000 to ensure the stack trace is preserved.
56
56
  */
57
57
  declare function interceptWindowEvent(eventName: keyof WindowEventMap, predicate: () => boolean): void;
58
+ /**
59
+ * Amplifies the gain of the passed media element's audio by the specified multiplier.
60
+ * This function supports any media element like `<audio>` or `<video>`
61
+ *
62
+ * This function has to be run in response to a user interaction event, else the browser will reject it because of the strict autoplay policy.
63
+ *
64
+ * @returns Returns an object with the following properties:
65
+ * | Property | Description |
66
+ * | :-- | :-- |
67
+ * | `mediaElement` | The passed media element |
68
+ * | `amplify()` | A function to change the amplification level |
69
+ * | `getAmpLevel()` | A function to return the current amplification level |
70
+ * | `context` | The AudioContext instance |
71
+ * | `source` | The MediaElementSourceNode instance |
72
+ * | `gain` | The GainNode instance |
73
+ */
74
+ declare function amplifyMedia<TElem extends HTMLMediaElement>(mediaElement: TElem, multiplier?: number): {
75
+ mediaElement: TElem;
76
+ amplify: (multiplier: number) => void;
77
+ getAmpLevel: () => number;
78
+ context: AudioContext;
79
+ source: MediaElementAudioSourceNode;
80
+ gain: GainNode;
81
+ };
58
82
 
59
83
  /** Ensures the passed `value` always stays between `min` and `max` */
60
84
  declare function clamp(value: number, min: number, max: number): number;
@@ -68,12 +92,6 @@ declare function randRange(min: number, max: number): number;
68
92
  /** Returns a random number between 0 and `max` (inclusive) */
69
93
  declare function randRange(max: number): number;
70
94
 
71
- type InitOnSelectorOpts = {
72
- /** Set to true if mutations to any element's attributes are to also trigger the onSelector check (warning: this might draw a lot of performance on larger sites) */
73
- attributes?: boolean;
74
- /** Set to true if mutations to any element's character data are to also trigger the onSelector check (warning: this might draw a lot of performance on larger sites) */
75
- characterData?: boolean;
76
- };
77
95
  type OnSelectorOpts<TElem extends Element = HTMLElement> = SelectorOptsOne<TElem> | SelectorOptsAll<TElem>;
78
96
  type SelectorOptsOne<TElem extends Element> = SelectorOptsBase & {
79
97
  /** Whether to use `querySelectorAll()` instead - default is false */
@@ -128,10 +146,10 @@ declare function onSelector<TElem extends Element = HTMLElement>(selector: strin
128
146
  declare function removeOnSelector(selector: string): boolean;
129
147
  /**
130
148
  * Initializes a MutationObserver that checks for all registered selectors whenever an element is added to or removed from the `<body>`
131
- * @param opts For fine-tuning when the MutationObserver checks for the selectors
149
+ * @param options For fine-tuning what triggers the MutationObserver's checking function - `subtree` and `childList` are set to true by default
132
150
  */
133
- declare function initOnSelector(opts?: InitOnSelectorOpts): void;
151
+ declare function initOnSelector(options?: MutationObserverInit): void;
134
152
  /** Returns all currently registered selectors, as a map of selector strings to their associated options */
135
153
  declare function getSelectorMap(): Map<string, OnSelectorOpts[]>;
136
154
 
137
- export { FetchAdvancedOpts, InitOnSelectorOpts, OnSelectorOpts, addGlobalStyle, addParent, autoPlural, clamp, debounce, fetchAdvanced, getSelectorMap, getUnsafeWindow, initOnSelector, insertAfter, interceptEvent, interceptWindowEvent, mapRange, onSelector, openInNewTab, pauseFor, preloadImages, randRange, randomItem, randomItemIndex, randomizeArray, removeOnSelector, takeRandomItem };
155
+ export { FetchAdvancedOpts, OnSelectorOpts, addGlobalStyle, addParent, amplifyMedia, autoPlural, clamp, debounce, fetchAdvanced, getSelectorMap, getUnsafeWindow, initOnSelector, insertAfter, interceptEvent, interceptWindowEvent, mapRange, onSelector, openInNewTab, pauseFor, preloadImages, randRange, randomItem, randomItemIndex, randomizeArray, removeOnSelector, takeRandomItem };
@@ -0,0 +1,33 @@
1
+ (function (exports) {
2
+ 'use strict';
3
+
4
+ var h=Object.defineProperty,y=Object.defineProperties;var g=Object.getOwnPropertyDescriptors;var p=Object.getOwnPropertySymbols;var w=Object.prototype.hasOwnProperty,v=Object.prototype.propertyIsEnumerable;var f=(n,e,t)=>e in n?h(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t,m=(n,e)=>{for(var t in e||(e={}))w.call(e,t)&&f(n,t,e[t]);if(p)for(var t of p(e))v.call(e,t)&&f(n,t,e[t]);return n},b=(n,e)=>y(n,g(e));var x=(n,e,t)=>new Promise((r,o)=>{var i=s=>{try{a(t.next(s));}catch(l){o(l);}},u=s=>{try{a(t.throw(s));}catch(l){o(l);}},a=s=>s.done?r(s.value):Promise.resolve(s.value).then(i,u);a((t=t.apply(n,e)).next());});function A(n,e,t){return Math.max(Math.min(n,t),e)}function N(n,e,t,r,o){return Number(e)===0&&Number(r)===0?n*(o/t):(n-e)*((o-r)/(t-e))+r}function d(...n){let e,t;if(typeof n[0]=="number"&&typeof n[1]=="number")[e,t]=n;else if(typeof n[0]=="number"&&typeof n[1]!="number")e=0,t=n[0];else throw new TypeError(`Wrong parameter(s) provided - expected: "number" and "number|undefined", got: "${typeof n[0]}" and "${typeof n[1]}"`);if(e=Number(e),t=Number(t),isNaN(e)||isNaN(t))throw new TypeError(`Parameters "min" and "max" can't be NaN`);if(e>t)throw new TypeError(`Parameter "min" can't be bigger than "max"`);return Math.floor(Math.random()*(t-e+1))+e}function H(n){return T(n)[0]}function T(n){if(n.length===0)return [void 0,void 0];let e=d(n.length-1);return [n[e],e]}function I(n){let[e,t]=T(n);if(t!==void 0)return n.splice(t,1),e}function C(n){let e=[...n];if(n.length===0)return n;for(let t=e.length-1;t>0;t--){let r=Math.floor(d(0,1e4)/1e4*(t+1));[e[t],e[r]]=[e[r],e[t]];}return e}function L(){try{return unsafeWindow}catch(n){return window}}function j(n,e){var t;return (t=n.parentNode)==null||t.insertBefore(e,n.nextSibling),e}function R(n,e){let t=n.parentNode;if(!t)throw new Error("Element doesn't have a parent node");return t.replaceChild(e,n),e.appendChild(n),e}function F(n){let e=document.createElement("style");e.innerHTML=n,document.head.appendChild(e);}function W(n,e=!1){let t=n.map(r=>new Promise((o,i)=>{let u=new Image;u.src=r,u.addEventListener("load",()=>o(u)),u.addEventListener("error",a=>e&&i(a));}));return Promise.allSettled(t)}function $(n){let e=document.createElement("a");Object.assign(e,{className:"userutils-open-in-new-tab",target:"_blank",rel:"noopener noreferrer",href:n}),e.style.display="none",document.body.appendChild(e),e.click(),setTimeout(e.remove,50);}function M(n,e,t){typeof Error.stackTraceLimit=="number"&&Error.stackTraceLimit<1e3&&(Error.stackTraceLimit=1e3),function(r){element.__proto__.addEventListener=function(...o){if(!(o[0]===e&&t()))return r.apply(this,o)};}(n.__proto__.addEventListener);}function q(n,e){return M(L(),n,e)}function G(n,e=1){let t=new(window.AudioContext||window.webkitAudioContext),r={mediaElement:n,amplify:o=>{r.gain.gain.value=o;},getAmpLevel:()=>r.gain.gain.value,context:t,source:t.createMediaElementSource(n),gain:t.createGain()};return r.source.connect(r.gain),r.gain.connect(t.destination),r.amplify(e),r}function B(n,e){return (Array.isArray(e)||e instanceof NodeList)&&(e=e.length),`${n}${e===1?"":"s"}`}function U(n){return new Promise(e=>{setTimeout(e,n);})}function D(n,e=300){let t;return function(...r){clearTimeout(t),t=setTimeout(()=>n.apply(this,r),e);}}function J(t){return x(this,arguments,function*(n,e={}){let{timeout:r=1e4}=e,o=new AbortController,i=setTimeout(()=>o.abort(),r),u=yield fetch(n,b(m({},e),{signal:o.signal}));return clearTimeout(i),u})}var c=new Map;function V(n,e){let t=[];c.has(n)&&(t=c.get(n)),t.push(e),c.set(n,t),E(n,t);}function X(n){return c.delete(n)}function E(n,e){let t=[];if(e.forEach((r,o)=>{try{let i=r.all?document.querySelectorAll(n):document.querySelector(n);(i!==null&&i instanceof NodeList&&i.length>0||i!==null)&&(r.listener(i),r.continuous||t.push(o));}catch(i){console.error(`Couldn't call listener for selector '${n}'`,i);}}),t.length>0){let r=e.filter((o,i)=>!t.includes(i));r.length===0?c.delete(n):c.set(n,r);}}function Y(n={}){new MutationObserver(()=>{for(let[t,r]of c.entries())E(t,r);}).observe(document.body,m({subtree:!0,childList:!0},n));}function Z(){return c}
5
+
6
+ exports.addGlobalStyle = F;
7
+ exports.addParent = R;
8
+ exports.amplifyMedia = G;
9
+ exports.autoPlural = B;
10
+ exports.clamp = A;
11
+ exports.debounce = D;
12
+ exports.fetchAdvanced = J;
13
+ exports.getSelectorMap = Z;
14
+ exports.getUnsafeWindow = L;
15
+ exports.initOnSelector = Y;
16
+ exports.insertAfter = j;
17
+ exports.interceptEvent = M;
18
+ exports.interceptWindowEvent = q;
19
+ exports.mapRange = N;
20
+ exports.onSelector = V;
21
+ exports.openInNewTab = $;
22
+ exports.pauseFor = U;
23
+ exports.preloadImages = W;
24
+ exports.randRange = d;
25
+ exports.randomItem = H;
26
+ exports.randomItemIndex = T;
27
+ exports.randomizeArray = C;
28
+ exports.removeOnSelector = X;
29
+ exports.takeRandomItem = I;
30
+
31
+ return exports;
32
+
33
+ })({});
package/dist/index.js CHANGED
@@ -1,27 +1,28 @@
1
1
  'use strict';
2
2
 
3
- var h=Object.defineProperty,y=Object.defineProperties;var w=Object.getOwnPropertyDescriptors;var f=Object.getOwnPropertySymbols;var g=Object.prototype.hasOwnProperty,v=Object.prototype.propertyIsEnumerable;var b=(t,e,n)=>e in t?h(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,a=(t,e)=>{for(var n in e||(e={}))g.call(e,n)&&b(t,n,e[n]);if(f)for(var n of f(e))v.call(e,n)&&b(t,n,e[n]);return t},d=(t,e)=>y(t,w(e));var T=(t,e,n)=>new Promise((r,o)=>{var i=c=>{try{m(n.next(c));}catch(l){o(l);}},u=c=>{try{m(n.throw(c));}catch(l){o(l);}},m=c=>c.done?r(c.value):Promise.resolve(c.value).then(i,u);m((n=n.apply(t,e)).next());});function S(t,e,n){return Math.max(Math.min(t,n),e)}function N(t,e,n,r,o){return Number(e)===0&&Number(r)===0?t*(o/n):(t-e)*((o-r)/(n-e))+r}function p(...t){let e,n;if(typeof t[0]=="number"&&typeof t[1]=="number")[e,n]=t;else if(typeof t[0]=="number"&&typeof t[1]!="number")e=0,n=t[0];else throw new TypeError(`Wrong parameter(s) provided - expected: "number" and "number|undefined", got: "${typeof t[0]}" and "${typeof t[1]}"`);if(e=Number(e),n=Number(n),isNaN(e)||isNaN(n))throw new TypeError(`Parameters "min" and "max" can't be NaN`);if(e>n)throw new TypeError(`Parameter "min" can't be bigger than "max"`);return Math.floor(Math.random()*(n-e+1))+e}function I(t){return x(t)[0]}function x(t){if(t.length===0)return [void 0,void 0];let e=p(t.length-1);return [t[e],e]}function H(t){let[e,n]=x(t);if(n!==void 0)return t.splice(n,1),e}function P(t){let e=[...t];if(t.length===0)return t;for(let n=e.length-1;n>0;n--){let r=Math.floor(p(0,1e4)/1e4*(n+1));[e[n],e[r]]=[e[r],e[n]];}return e}function O(){try{return unsafeWindow}catch(t){return window}}function C(t,e){var n;return (n=t.parentNode)==null||n.insertBefore(e,t.nextSibling),e}function R(t,e){let n=t.parentNode;if(!n)throw new Error("Element doesn't have a parent node");return n.replaceChild(e,t),e.appendChild(t),e}function F(t){let e=document.createElement("style");e.innerHTML=t,document.head.appendChild(e);}function W(t,e=!1){let n=t.map(r=>new Promise((o,i)=>{let u=new Image;u.src=r,u.addEventListener("load",()=>o(u)),u.addEventListener("error",m=>e&&i(m));}));return Promise.allSettled(n)}function $(t){let e=document.createElement("a");Object.assign(e,{className:"userutils-open-in-new-tab",target:"_blank",rel:"noopener noreferrer",href:t}),e.style.display="none",document.body.appendChild(e),e.click(),setTimeout(e.remove,50);}function L(t,e,n){typeof Error.stackTraceLimit=="number"&&Error.stackTraceLimit<1e3&&(Error.stackTraceLimit=1e3),function(r){element.__proto__.addEventListener=function(...o){if(!(o[0]===e&&n()))return r.apply(this,o)};}(t.__proto__.addEventListener);}function q(t,e){return L(O(),t,e)}function B(t,e){return (Array.isArray(e)||e instanceof NodeList)&&(e=e.length),`${t}${e===1?"":"s"}`}function G(t){return new Promise(e=>{setTimeout(e,t);})}function U(t,e=300){let n;return function(...r){clearTimeout(n),n=setTimeout(()=>t.apply(this,r),e);}}function D(n){return T(this,arguments,function*(t,e={}){let{timeout:r=1e4}=e,o=new AbortController,i=setTimeout(()=>o.abort(),r),u=yield fetch(t,d(a({},e),{signal:o.signal}));return clearTimeout(i),u})}var s=new Map;function Q(t,e){let n=[];s.has(t)&&(n=s.get(t)),n.push(e),s.set(t,n),E(t,n);}function V(t){return s.delete(t)}function E(t,e){let n=[];if(e.forEach((r,o)=>{try{let i=r.all?document.querySelectorAll(t):document.querySelector(t);i&&(r.listener(i),r.continuous||n.push(o));}catch(i){console.error(`Couldn't call listener for selector '${t}'`,i);}}),n.length>0){let r=e.filter((o,i)=>!n.includes(i));r.length===0?s.delete(t):s.set(t,r);}}function X(t={}){new MutationObserver(()=>{for(let[n,r]of s.entries())E(n,r);}).observe(document.body,d(a({},t),{childList:!0}));}function Y(){return s}
3
+ var h=Object.defineProperty,y=Object.defineProperties;var g=Object.getOwnPropertyDescriptors;var p=Object.getOwnPropertySymbols;var w=Object.prototype.hasOwnProperty,v=Object.prototype.propertyIsEnumerable;var f=(n,e,t)=>e in n?h(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t,m=(n,e)=>{for(var t in e||(e={}))w.call(e,t)&&f(n,t,e[t]);if(p)for(var t of p(e))v.call(e,t)&&f(n,t,e[t]);return n},b=(n,e)=>y(n,g(e));var x=(n,e,t)=>new Promise((r,o)=>{var i=s=>{try{a(t.next(s));}catch(l){o(l);}},u=s=>{try{a(t.throw(s));}catch(l){o(l);}},a=s=>s.done?r(s.value):Promise.resolve(s.value).then(i,u);a((t=t.apply(n,e)).next());});function A(n,e,t){return Math.max(Math.min(n,t),e)}function N(n,e,t,r,o){return Number(e)===0&&Number(r)===0?n*(o/t):(n-e)*((o-r)/(t-e))+r}function d(...n){let e,t;if(typeof n[0]=="number"&&typeof n[1]=="number")[e,t]=n;else if(typeof n[0]=="number"&&typeof n[1]!="number")e=0,t=n[0];else throw new TypeError(`Wrong parameter(s) provided - expected: "number" and "number|undefined", got: "${typeof n[0]}" and "${typeof n[1]}"`);if(e=Number(e),t=Number(t),isNaN(e)||isNaN(t))throw new TypeError(`Parameters "min" and "max" can't be NaN`);if(e>t)throw new TypeError(`Parameter "min" can't be bigger than "max"`);return Math.floor(Math.random()*(t-e+1))+e}function H(n){return T(n)[0]}function T(n){if(n.length===0)return [void 0,void 0];let e=d(n.length-1);return [n[e],e]}function I(n){let[e,t]=T(n);if(t!==void 0)return n.splice(t,1),e}function C(n){let e=[...n];if(n.length===0)return n;for(let t=e.length-1;t>0;t--){let r=Math.floor(d(0,1e4)/1e4*(t+1));[e[t],e[r]]=[e[r],e[t]];}return e}function L(){try{return unsafeWindow}catch(n){return window}}function j(n,e){var t;return (t=n.parentNode)==null||t.insertBefore(e,n.nextSibling),e}function R(n,e){let t=n.parentNode;if(!t)throw new Error("Element doesn't have a parent node");return t.replaceChild(e,n),e.appendChild(n),e}function F(n){let e=document.createElement("style");e.innerHTML=n,document.head.appendChild(e);}function W(n,e=!1){let t=n.map(r=>new Promise((o,i)=>{let u=new Image;u.src=r,u.addEventListener("load",()=>o(u)),u.addEventListener("error",a=>e&&i(a));}));return Promise.allSettled(t)}function $(n){let e=document.createElement("a");Object.assign(e,{className:"userutils-open-in-new-tab",target:"_blank",rel:"noopener noreferrer",href:n}),e.style.display="none",document.body.appendChild(e),e.click(),setTimeout(e.remove,50);}function M(n,e,t){typeof Error.stackTraceLimit=="number"&&Error.stackTraceLimit<1e3&&(Error.stackTraceLimit=1e3),function(r){element.__proto__.addEventListener=function(...o){if(!(o[0]===e&&t()))return r.apply(this,o)};}(n.__proto__.addEventListener);}function q(n,e){return M(L(),n,e)}function G(n,e=1){let t=new(window.AudioContext||window.webkitAudioContext),r={mediaElement:n,amplify:o=>{r.gain.gain.value=o;},getAmpLevel:()=>r.gain.gain.value,context:t,source:t.createMediaElementSource(n),gain:t.createGain()};return r.source.connect(r.gain),r.gain.connect(t.destination),r.amplify(e),r}function B(n,e){return (Array.isArray(e)||e instanceof NodeList)&&(e=e.length),`${n}${e===1?"":"s"}`}function U(n){return new Promise(e=>{setTimeout(e,n);})}function D(n,e=300){let t;return function(...r){clearTimeout(t),t=setTimeout(()=>n.apply(this,r),e);}}function J(t){return x(this,arguments,function*(n,e={}){let{timeout:r=1e4}=e,o=new AbortController,i=setTimeout(()=>o.abort(),r),u=yield fetch(n,b(m({},e),{signal:o.signal}));return clearTimeout(i),u})}var c=new Map;function V(n,e){let t=[];c.has(n)&&(t=c.get(n)),t.push(e),c.set(n,t),E(n,t);}function X(n){return c.delete(n)}function E(n,e){let t=[];if(e.forEach((r,o)=>{try{let i=r.all?document.querySelectorAll(n):document.querySelector(n);(i!==null&&i instanceof NodeList&&i.length>0||i!==null)&&(r.listener(i),r.continuous||t.push(o));}catch(i){console.error(`Couldn't call listener for selector '${n}'`,i);}}),t.length>0){let r=e.filter((o,i)=>!t.includes(i));r.length===0?c.delete(n):c.set(n,r);}}function Y(n={}){new MutationObserver(()=>{for(let[t,r]of c.entries())E(t,r);}).observe(document.body,m({subtree:!0,childList:!0},n));}function Z(){return c}
4
4
 
5
5
  exports.addGlobalStyle = F;
6
6
  exports.addParent = R;
7
+ exports.amplifyMedia = G;
7
8
  exports.autoPlural = B;
8
- exports.clamp = S;
9
- exports.debounce = U;
10
- exports.fetchAdvanced = D;
11
- exports.getSelectorMap = Y;
12
- exports.getUnsafeWindow = O;
13
- exports.initOnSelector = X;
14
- exports.insertAfter = C;
15
- exports.interceptEvent = L;
9
+ exports.clamp = A;
10
+ exports.debounce = D;
11
+ exports.fetchAdvanced = J;
12
+ exports.getSelectorMap = Z;
13
+ exports.getUnsafeWindow = L;
14
+ exports.initOnSelector = Y;
15
+ exports.insertAfter = j;
16
+ exports.interceptEvent = M;
16
17
  exports.interceptWindowEvent = q;
17
18
  exports.mapRange = N;
18
- exports.onSelector = Q;
19
+ exports.onSelector = V;
19
20
  exports.openInNewTab = $;
20
- exports.pauseFor = G;
21
+ exports.pauseFor = U;
21
22
  exports.preloadImages = W;
22
- exports.randRange = p;
23
- exports.randomItem = I;
24
- exports.randomItemIndex = x;
25
- exports.randomizeArray = P;
26
- exports.removeOnSelector = V;
27
- exports.takeRandomItem = H;
23
+ exports.randRange = d;
24
+ exports.randomItem = H;
25
+ exports.randomItemIndex = T;
26
+ exports.randomizeArray = C;
27
+ exports.removeOnSelector = X;
28
+ exports.takeRandomItem = I;
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- var h=Object.defineProperty,y=Object.defineProperties;var w=Object.getOwnPropertyDescriptors;var f=Object.getOwnPropertySymbols;var g=Object.prototype.hasOwnProperty,v=Object.prototype.propertyIsEnumerable;var b=(t,e,n)=>e in t?h(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,a=(t,e)=>{for(var n in e||(e={}))g.call(e,n)&&b(t,n,e[n]);if(f)for(var n of f(e))v.call(e,n)&&b(t,n,e[n]);return t},d=(t,e)=>y(t,w(e));var T=(t,e,n)=>new Promise((r,o)=>{var i=c=>{try{m(n.next(c));}catch(l){o(l);}},u=c=>{try{m(n.throw(c));}catch(l){o(l);}},m=c=>c.done?r(c.value):Promise.resolve(c.value).then(i,u);m((n=n.apply(t,e)).next());});function S(t,e,n){return Math.max(Math.min(t,n),e)}function N(t,e,n,r,o){return Number(e)===0&&Number(r)===0?t*(o/n):(t-e)*((o-r)/(n-e))+r}function p(...t){let e,n;if(typeof t[0]=="number"&&typeof t[1]=="number")[e,n]=t;else if(typeof t[0]=="number"&&typeof t[1]!="number")e=0,n=t[0];else throw new TypeError(`Wrong parameter(s) provided - expected: "number" and "number|undefined", got: "${typeof t[0]}" and "${typeof t[1]}"`);if(e=Number(e),n=Number(n),isNaN(e)||isNaN(n))throw new TypeError(`Parameters "min" and "max" can't be NaN`);if(e>n)throw new TypeError(`Parameter "min" can't be bigger than "max"`);return Math.floor(Math.random()*(n-e+1))+e}function I(t){return x(t)[0]}function x(t){if(t.length===0)return [void 0,void 0];let e=p(t.length-1);return [t[e],e]}function H(t){let[e,n]=x(t);if(n!==void 0)return t.splice(n,1),e}function P(t){let e=[...t];if(t.length===0)return t;for(let n=e.length-1;n>0;n--){let r=Math.floor(p(0,1e4)/1e4*(n+1));[e[n],e[r]]=[e[r],e[n]];}return e}function O(){try{return unsafeWindow}catch(t){return window}}function C(t,e){var n;return (n=t.parentNode)==null||n.insertBefore(e,t.nextSibling),e}function R(t,e){let n=t.parentNode;if(!n)throw new Error("Element doesn't have a parent node");return n.replaceChild(e,t),e.appendChild(t),e}function F(t){let e=document.createElement("style");e.innerHTML=t,document.head.appendChild(e);}function W(t,e=!1){let n=t.map(r=>new Promise((o,i)=>{let u=new Image;u.src=r,u.addEventListener("load",()=>o(u)),u.addEventListener("error",m=>e&&i(m));}));return Promise.allSettled(n)}function $(t){let e=document.createElement("a");Object.assign(e,{className:"userutils-open-in-new-tab",target:"_blank",rel:"noopener noreferrer",href:t}),e.style.display="none",document.body.appendChild(e),e.click(),setTimeout(e.remove,50);}function L(t,e,n){typeof Error.stackTraceLimit=="number"&&Error.stackTraceLimit<1e3&&(Error.stackTraceLimit=1e3),function(r){element.__proto__.addEventListener=function(...o){if(!(o[0]===e&&n()))return r.apply(this,o)};}(t.__proto__.addEventListener);}function q(t,e){return L(O(),t,e)}function B(t,e){return (Array.isArray(e)||e instanceof NodeList)&&(e=e.length),`${t}${e===1?"":"s"}`}function G(t){return new Promise(e=>{setTimeout(e,t);})}function U(t,e=300){let n;return function(...r){clearTimeout(n),n=setTimeout(()=>t.apply(this,r),e);}}function D(n){return T(this,arguments,function*(t,e={}){let{timeout:r=1e4}=e,o=new AbortController,i=setTimeout(()=>o.abort(),r),u=yield fetch(t,d(a({},e),{signal:o.signal}));return clearTimeout(i),u})}var s=new Map;function Q(t,e){let n=[];s.has(t)&&(n=s.get(t)),n.push(e),s.set(t,n),E(t,n);}function V(t){return s.delete(t)}function E(t,e){let n=[];if(e.forEach((r,o)=>{try{let i=r.all?document.querySelectorAll(t):document.querySelector(t);i&&(r.listener(i),r.continuous||n.push(o));}catch(i){console.error(`Couldn't call listener for selector '${t}'`,i);}}),n.length>0){let r=e.filter((o,i)=>!n.includes(i));r.length===0?s.delete(t):s.set(t,r);}}function X(t={}){new MutationObserver(()=>{for(let[n,r]of s.entries())E(n,r);}).observe(document.body,d(a({},t),{childList:!0}));}function Y(){return s}
1
+ var h=Object.defineProperty,y=Object.defineProperties;var g=Object.getOwnPropertyDescriptors;var p=Object.getOwnPropertySymbols;var w=Object.prototype.hasOwnProperty,v=Object.prototype.propertyIsEnumerable;var f=(n,e,t)=>e in n?h(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t,m=(n,e)=>{for(var t in e||(e={}))w.call(e,t)&&f(n,t,e[t]);if(p)for(var t of p(e))v.call(e,t)&&f(n,t,e[t]);return n},b=(n,e)=>y(n,g(e));var x=(n,e,t)=>new Promise((r,o)=>{var i=s=>{try{a(t.next(s));}catch(l){o(l);}},u=s=>{try{a(t.throw(s));}catch(l){o(l);}},a=s=>s.done?r(s.value):Promise.resolve(s.value).then(i,u);a((t=t.apply(n,e)).next());});function A(n,e,t){return Math.max(Math.min(n,t),e)}function N(n,e,t,r,o){return Number(e)===0&&Number(r)===0?n*(o/t):(n-e)*((o-r)/(t-e))+r}function d(...n){let e,t;if(typeof n[0]=="number"&&typeof n[1]=="number")[e,t]=n;else if(typeof n[0]=="number"&&typeof n[1]!="number")e=0,t=n[0];else throw new TypeError(`Wrong parameter(s) provided - expected: "number" and "number|undefined", got: "${typeof n[0]}" and "${typeof n[1]}"`);if(e=Number(e),t=Number(t),isNaN(e)||isNaN(t))throw new TypeError(`Parameters "min" and "max" can't be NaN`);if(e>t)throw new TypeError(`Parameter "min" can't be bigger than "max"`);return Math.floor(Math.random()*(t-e+1))+e}function H(n){return T(n)[0]}function T(n){if(n.length===0)return [void 0,void 0];let e=d(n.length-1);return [n[e],e]}function I(n){let[e,t]=T(n);if(t!==void 0)return n.splice(t,1),e}function C(n){let e=[...n];if(n.length===0)return n;for(let t=e.length-1;t>0;t--){let r=Math.floor(d(0,1e4)/1e4*(t+1));[e[t],e[r]]=[e[r],e[t]];}return e}function L(){try{return unsafeWindow}catch(n){return window}}function j(n,e){var t;return (t=n.parentNode)==null||t.insertBefore(e,n.nextSibling),e}function R(n,e){let t=n.parentNode;if(!t)throw new Error("Element doesn't have a parent node");return t.replaceChild(e,n),e.appendChild(n),e}function F(n){let e=document.createElement("style");e.innerHTML=n,document.head.appendChild(e);}function W(n,e=!1){let t=n.map(r=>new Promise((o,i)=>{let u=new Image;u.src=r,u.addEventListener("load",()=>o(u)),u.addEventListener("error",a=>e&&i(a));}));return Promise.allSettled(t)}function $(n){let e=document.createElement("a");Object.assign(e,{className:"userutils-open-in-new-tab",target:"_blank",rel:"noopener noreferrer",href:n}),e.style.display="none",document.body.appendChild(e),e.click(),setTimeout(e.remove,50);}function M(n,e,t){typeof Error.stackTraceLimit=="number"&&Error.stackTraceLimit<1e3&&(Error.stackTraceLimit=1e3),function(r){element.__proto__.addEventListener=function(...o){if(!(o[0]===e&&t()))return r.apply(this,o)};}(n.__proto__.addEventListener);}function q(n,e){return M(L(),n,e)}function G(n,e=1){let t=new(window.AudioContext||window.webkitAudioContext),r={mediaElement:n,amplify:o=>{r.gain.gain.value=o;},getAmpLevel:()=>r.gain.gain.value,context:t,source:t.createMediaElementSource(n),gain:t.createGain()};return r.source.connect(r.gain),r.gain.connect(t.destination),r.amplify(e),r}function B(n,e){return (Array.isArray(e)||e instanceof NodeList)&&(e=e.length),`${n}${e===1?"":"s"}`}function U(n){return new Promise(e=>{setTimeout(e,n);})}function D(n,e=300){let t;return function(...r){clearTimeout(t),t=setTimeout(()=>n.apply(this,r),e);}}function J(t){return x(this,arguments,function*(n,e={}){let{timeout:r=1e4}=e,o=new AbortController,i=setTimeout(()=>o.abort(),r),u=yield fetch(n,b(m({},e),{signal:o.signal}));return clearTimeout(i),u})}var c=new Map;function V(n,e){let t=[];c.has(n)&&(t=c.get(n)),t.push(e),c.set(n,t),E(n,t);}function X(n){return c.delete(n)}function E(n,e){let t=[];if(e.forEach((r,o)=>{try{let i=r.all?document.querySelectorAll(n):document.querySelector(n);(i!==null&&i instanceof NodeList&&i.length>0||i!==null)&&(r.listener(i),r.continuous||t.push(o));}catch(i){console.error(`Couldn't call listener for selector '${n}'`,i);}}),t.length>0){let r=e.filter((o,i)=>!t.includes(i));r.length===0?c.delete(n):c.set(n,r);}}function Y(n={}){new MutationObserver(()=>{for(let[t,r]of c.entries())E(t,r);}).observe(document.body,m({subtree:!0,childList:!0},n));}function Z(){return c}
2
2
 
3
- export { F as addGlobalStyle, R as addParent, B as autoPlural, S as clamp, U as debounce, D as fetchAdvanced, Y as getSelectorMap, O as getUnsafeWindow, X as initOnSelector, C as insertAfter, L as interceptEvent, q as interceptWindowEvent, N as mapRange, Q as onSelector, $ as openInNewTab, G as pauseFor, W as preloadImages, p as randRange, I as randomItem, x as randomItemIndex, P as randomizeArray, V as removeOnSelector, H as takeRandomItem };
3
+ export { F as addGlobalStyle, R as addParent, G as amplifyMedia, B as autoPlural, A as clamp, D as debounce, J as fetchAdvanced, Z as getSelectorMap, L as getUnsafeWindow, Y as initOnSelector, j as insertAfter, M as interceptEvent, q as interceptWindowEvent, N as mapRange, V as onSelector, $ as openInNewTab, U as pauseFor, W as preloadImages, d as randRange, H as randomItem, T as randomItemIndex, C as randomizeArray, X as removeOnSelector, I as takeRandomItem };
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@sv443-network/userutils",
3
- "version": "0.4.1",
3
+ "version": "0.5.1",
4
4
  "description": "Library with various utilities for userscripts - register listeners for when CSS selectors exist, intercept events, modify the DOM more easily and more ",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",
8
8
  "scripts": {
9
9
  "lint": "tsc && eslint .",
10
- "build-common": "tsup lib/index.ts --format cjs,esm --dts --clean --treeshake",
10
+ "build-common": "tsup lib/index.ts --format cjs,esm,iife --dts --clean --treeshake",
11
11
  "build": "npm run build-common -- --minify",
12
12
  "dev": "npm run build-common -- --sourcemap --watch",
13
13
  "publish-package": "npm run build && changeset publish"