@sv443-network/userutils 4.0.0 → 4.2.0
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 +18 -0
- package/README.md +75 -11
- package/dist/index.global.js +68 -14
- package/dist/index.js +67 -13
- package/dist/index.mjs +67 -14
- package/dist/lib/SelectorObserver.d.ts +7 -2
- package/dist/lib/dom.d.ts +12 -1
- package/dist/lib/math.d.ts +1 -0
- package/dist/lib/misc.d.ts +3 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @sv443-network/userutils
|
|
2
2
|
|
|
3
|
+
## 4.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 47639f0: Added SelectorObserver options `disableOnNoListeners` and `enableOnAddListener`
|
|
8
|
+
- 4a58caa: `addGlobalStyle` now returns the created style element
|
|
9
|
+
- 5038967: `fetchAdvanced` is now a drop-in replacement and timeout can now optionally be disabled
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 17a6ad5: `randomizeArray` now returns a copy if an empty array is passed as well
|
|
14
|
+
|
|
15
|
+
## 4.1.0
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- 885323d: Added function `observeElementProp` to allow observing element property changes
|
|
20
|
+
|
|
3
21
|
## 4.0.0
|
|
4
22
|
|
|
5
23
|
### Major Changes
|
package/README.md
CHANGED
|
@@ -33,6 +33,7 @@ View the documentation of previous major releases: [3.0.0](https://github.com/Sv
|
|
|
33
33
|
- [interceptEvent()](#interceptevent) - conditionally intercepts events registered by `addEventListener()` on any given EventTarget object
|
|
34
34
|
- [interceptWindowEvent()](#interceptwindowevent) - conditionally intercepts events registered by `addEventListener()` on the window object
|
|
35
35
|
- [isScrollable()](#isscrollable) - check if an element has a horizontal or vertical scroll bar
|
|
36
|
+
- [observeElementProp()](#observeelementprop) - observe changes to an element's property that can't be observed with MutationObserver
|
|
36
37
|
- [**Math:**](#math)
|
|
37
38
|
- [clamp()](#clamp) - constrain a number between a min and max value
|
|
38
39
|
- [mapRange()](#maprange) - map a number from one range to the same spot in another range
|
|
@@ -83,7 +84,7 @@ View the documentation of previous major releases: [3.0.0](https://github.com/Sv
|
|
|
83
84
|
|
|
84
85
|
<br>
|
|
85
86
|
|
|
86
|
-
- If you are not using a bundler, you can include the latest release
|
|
87
|
+
- If you are not using a bundler, you can include the latest release by adding one of these directives to the userscript header, depending on your preferred CDN:
|
|
87
88
|
```
|
|
88
89
|
// @require https://greasyfork.org/scripts/472956-userutils/code/UserUtils.js
|
|
89
90
|
```
|
|
@@ -99,7 +100,7 @@ View the documentation of previous major releases: [3.0.0](https://github.com/Sv
|
|
|
99
100
|
// or using object destructuring:
|
|
100
101
|
|
|
101
102
|
const { clamp } = UserUtils;
|
|
102
|
-
console.log(clamp(1, 5, 10); // 5
|
|
103
|
+
console.log(clamp(1, 5, 10)); // 5
|
|
103
104
|
```
|
|
104
105
|
|
|
105
106
|
<br><br>
|
|
@@ -147,9 +148,12 @@ If a selector string is passed instead, it will be used to find the element.
|
|
|
147
148
|
If you want to observe the entire document, you can pass `document.body`
|
|
148
149
|
|
|
149
150
|
The `options` parameter is optional and will be passed to the MutationObserver that is used internally.
|
|
150
|
-
The
|
|
151
|
-
For example, if you want to trigger the listeners when certain attributes change, pass `{
|
|
151
|
+
The MutationObserver options present by default are `{ childList: true, subtree: true }` - you may see the [MutationObserver.observe() documentation](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe#options) for more information and a list of options.
|
|
152
|
+
For example, if you want to trigger the listeners when certain attributes change, pass `{ attributeFilter: ["class", "data-my-attribute"] }`
|
|
153
|
+
|
|
152
154
|
Additionally, there are the following extra options:
|
|
155
|
+
- `disableOnNoListeners` - whether to disable the SelectorObserver when there are no listeners left (defaults to false)
|
|
156
|
+
- `enableOnAddListener` - whether to enable the SelectorObserver when a new listener is added (defaults to true)
|
|
153
157
|
- `defaultDebounce` - if set to a number, this debounce will be applied to every listener that doesn't have a custom debounce set (defaults to 0)
|
|
154
158
|
|
|
155
159
|
⚠️ Make sure to call `enable()` to actually start observing. This will need to be done after the DOM has loaded (when using `@run-at document-end` or after `DOMContentLoaded` has fired) **and** as soon as the `baseElement` or `baseElementSelector` is available.
|
|
@@ -505,10 +509,11 @@ addParent(element, newParent);
|
|
|
505
509
|
### addGlobalStyle()
|
|
506
510
|
Usage:
|
|
507
511
|
```ts
|
|
508
|
-
addGlobalStyle(css: string):
|
|
512
|
+
addGlobalStyle(css: string): HTMLStyleElement
|
|
509
513
|
```
|
|
510
514
|
|
|
511
515
|
Adds a global style to the page in form of a `<style>` element that's inserted into the `<head>`.
|
|
516
|
+
Returns the style element that was just created.
|
|
512
517
|
⚠️ This function needs to be run after the DOM has loaded (when using `@run-at document-end` or after `DOMContentLoaded` has fired).
|
|
513
518
|
|
|
514
519
|
<details><summary><b>Example - click to view</b></summary>
|
|
@@ -675,6 +680,59 @@ console.log("Element has a vertical scroll bar:", vertical);
|
|
|
675
680
|
|
|
676
681
|
</details>
|
|
677
682
|
|
|
683
|
+
<br>
|
|
684
|
+
|
|
685
|
+
### observeElementProp()
|
|
686
|
+
Usage:
|
|
687
|
+
```ts
|
|
688
|
+
observeElementProp(
|
|
689
|
+
element: Element,
|
|
690
|
+
property: string,
|
|
691
|
+
callback: (oldValue: any, newValue: any) => void
|
|
692
|
+
): void
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
This function observes changes to the given property of a given element.
|
|
696
|
+
While regular HTML attributes can be observed using a MutationObserver, this is not always possible for properties that are assigned on the JS object.
|
|
697
|
+
This function shims the setter of the provided property and calls the callback function whenever it is changed through any means.
|
|
698
|
+
|
|
699
|
+
When using TypeScript, the types for `element`, `property` and the arguments for `callback` will be automatically inferred.
|
|
700
|
+
|
|
701
|
+
<details><summary><b>Example - click to view</b></summary>
|
|
702
|
+
|
|
703
|
+
```ts
|
|
704
|
+
import { observeElementProp } from "@sv443-network/userutils";
|
|
705
|
+
|
|
706
|
+
const myInput = document.querySelector("input#my-input");
|
|
707
|
+
|
|
708
|
+
let value = 0;
|
|
709
|
+
|
|
710
|
+
setInterval(() => {
|
|
711
|
+
value += 1;
|
|
712
|
+
myInput.value = String(value);
|
|
713
|
+
}, 1000);
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
const observer = new MutationObserver((mutations) => {
|
|
717
|
+
// will never be called:
|
|
718
|
+
console.log("MutationObserver mutation:", mutations);
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
// one would think this should work, but "value" is a JS object *property*, not a DOM *attribute*
|
|
722
|
+
observer.observe(myInput, {
|
|
723
|
+
attributes: true,
|
|
724
|
+
attributeFilter: ["value"],
|
|
725
|
+
});
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
observeElementProp(myInput, "value", (oldValue, newValue) => {
|
|
729
|
+
// will be called every time the value changes:
|
|
730
|
+
console.log("Value changed from", oldValue, "to", newValue);
|
|
731
|
+
});
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
</details>
|
|
735
|
+
|
|
678
736
|
<br><br>
|
|
679
737
|
|
|
680
738
|
<!-- #SECTION Math -->
|
|
@@ -769,6 +827,9 @@ randomId(length?: number, radix?: number): string
|
|
|
769
827
|
```
|
|
770
828
|
|
|
771
829
|
Generates a cryptographically strong random ID of a given length and [radix (base).](https://en.wikipedia.org/wiki/Radix)
|
|
830
|
+
Uses the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues) for generating the random numbers.
|
|
831
|
+
⚠️ This is not intended for generating encryption keys, only for generating IDs with a decent amount of entropy!
|
|
832
|
+
|
|
772
833
|
The default length is 16 and the default radix is 16 (hexadecimal).
|
|
773
834
|
You may change the radix to get digits from different numerical systems.
|
|
774
835
|
Use 2 for binary, 8 for octal, 10 for decimal, 16 for hexadecimal and 36 for alphanumeric.
|
|
@@ -1004,14 +1065,15 @@ window.addEventListener("resize", debounce((event) => {
|
|
|
1004
1065
|
### fetchAdvanced()
|
|
1005
1066
|
Usage:
|
|
1006
1067
|
```ts
|
|
1007
|
-
fetchAdvanced(
|
|
1068
|
+
fetchAdvanced(input: string | Request | URL, options?: {
|
|
1008
1069
|
timeout?: number,
|
|
1009
1070
|
// any other options from fetch() except for signal
|
|
1010
1071
|
}): Promise<Response>
|
|
1011
1072
|
```
|
|
1012
1073
|
|
|
1013
|
-
A
|
|
1014
|
-
The timeout will default to 10 seconds if left undefined.
|
|
1074
|
+
A drop-in replacement for the native `fetch()` function that adds options like a timeout property.
|
|
1075
|
+
The timeout will default to 10 seconds if left undefined. Set it to a negative number to disable the timeout.
|
|
1076
|
+
Note that the `signal` option will be overwritten if passed.
|
|
1015
1077
|
|
|
1016
1078
|
<details><summary><b>Example - click to view</b></summary>
|
|
1017
1079
|
|
|
@@ -1022,10 +1084,12 @@ fetchAdvanced("https://jokeapi.dev/joke/Any?safe-mode", {
|
|
|
1022
1084
|
timeout: 5000,
|
|
1023
1085
|
// also accepts any other fetch options like headers:
|
|
1024
1086
|
headers: {
|
|
1025
|
-
"Accept": "
|
|
1087
|
+
"Accept": "text/plain",
|
|
1026
1088
|
},
|
|
1027
1089
|
}).then(async (response) => {
|
|
1028
|
-
console.log("
|
|
1090
|
+
console.log("Fetch data:", await response.text());
|
|
1091
|
+
}).catch((err) => {
|
|
1092
|
+
console.error("Fetch error:", err);
|
|
1029
1093
|
});
|
|
1030
1094
|
```
|
|
1031
1095
|
|
|
@@ -1215,7 +1279,7 @@ randomizeArray(array: Array): Array
|
|
|
1215
1279
|
```
|
|
1216
1280
|
|
|
1217
1281
|
Returns a copy of an array with its items in a random order.
|
|
1218
|
-
If the array is empty,
|
|
1282
|
+
If the array is empty, a new, empty array will be returned.
|
|
1219
1283
|
|
|
1220
1284
|
<details><summary><b>Example - click to view</b></summary>
|
|
1221
1285
|
|
package/dist/index.global.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// ==UserLibrary==
|
|
10
10
|
// @name UserUtils
|
|
11
11
|
// @description Library with various utilities for userscripts - register listeners for when CSS selectors exist, intercept events, manage persistent user configurations, modify the DOM more easily and more
|
|
12
|
-
// @version 4.
|
|
12
|
+
// @version 4.2.0
|
|
13
13
|
// @license MIT
|
|
14
14
|
// @copyright Sv443 (https://github.com/Sv443)
|
|
15
15
|
|
|
@@ -22,8 +22,6 @@
|
|
|
22
22
|
|
|
23
23
|
var UserUtils = (function (exports) {
|
|
24
24
|
var __defProp = Object.defineProperty;
|
|
25
|
-
var __defProps = Object.defineProperties;
|
|
26
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
27
25
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
28
26
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
29
27
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
@@ -39,7 +37,18 @@ var UserUtils = (function (exports) {
|
|
|
39
37
|
}
|
|
40
38
|
return a;
|
|
41
39
|
};
|
|
42
|
-
var
|
|
40
|
+
var __objRest = (source, exclude) => {
|
|
41
|
+
var target = {};
|
|
42
|
+
for (var prop in source)
|
|
43
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
44
|
+
target[prop] = source[prop];
|
|
45
|
+
if (source != null && __getOwnPropSymbols)
|
|
46
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
47
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
48
|
+
target[prop] = source[prop];
|
|
49
|
+
}
|
|
50
|
+
return target;
|
|
51
|
+
};
|
|
43
52
|
var __publicField = (obj, key, value) => {
|
|
44
53
|
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
45
54
|
return value;
|
|
@@ -120,7 +129,7 @@ var UserUtils = (function (exports) {
|
|
|
120
129
|
function randomizeArray(array) {
|
|
121
130
|
const retArray = [...array];
|
|
122
131
|
if (array.length === 0)
|
|
123
|
-
return
|
|
132
|
+
return retArray;
|
|
124
133
|
for (let i = retArray.length - 1; i > 0; i--) {
|
|
125
134
|
const j = Math.floor(randRange(0, 1e4) / 1e4 * (i + 1));
|
|
126
135
|
[retArray[i], retArray[j]] = [retArray[j], retArray[i]];
|
|
@@ -282,6 +291,7 @@ var UserUtils = (function (exports) {
|
|
|
282
291
|
const styleElem = document.createElement("style");
|
|
283
292
|
styleElem.innerHTML = style;
|
|
284
293
|
document.head.appendChild(styleElem);
|
|
294
|
+
return styleElem;
|
|
285
295
|
}
|
|
286
296
|
function preloadImages(srcUrls, rejects = false) {
|
|
287
297
|
const promises = srcUrls.map((src) => new Promise((res, rej) => {
|
|
@@ -333,6 +343,28 @@ var UserUtils = (function (exports) {
|
|
|
333
343
|
horizontal: (overflowX === "scroll" || overflowX === "auto") && element.scrollWidth > element.clientWidth
|
|
334
344
|
};
|
|
335
345
|
}
|
|
346
|
+
function observeElementProp(element, property, callback) {
|
|
347
|
+
const elementPrototype = Object.getPrototypeOf(element);
|
|
348
|
+
if (elementPrototype.hasOwnProperty(property)) {
|
|
349
|
+
const descriptor = Object.getOwnPropertyDescriptor(elementPrototype, property);
|
|
350
|
+
Object.defineProperty(element, property, {
|
|
351
|
+
get: function() {
|
|
352
|
+
var _a;
|
|
353
|
+
return (_a = descriptor == null ? void 0 : descriptor.get) == null ? void 0 : _a.apply(this, arguments);
|
|
354
|
+
},
|
|
355
|
+
set: function() {
|
|
356
|
+
var _a;
|
|
357
|
+
const oldValue = this[property];
|
|
358
|
+
(_a = descriptor == null ? void 0 : descriptor.set) == null ? void 0 : _a.apply(this, arguments);
|
|
359
|
+
const newValue = this[property];
|
|
360
|
+
if (typeof callback === "function") {
|
|
361
|
+
callback.bind(this, oldValue, newValue);
|
|
362
|
+
}
|
|
363
|
+
return newValue;
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
}
|
|
336
368
|
|
|
337
369
|
// lib/misc.ts
|
|
338
370
|
function autoPlural(word, num) {
|
|
@@ -353,13 +385,15 @@ var UserUtils = (function (exports) {
|
|
|
353
385
|
};
|
|
354
386
|
}
|
|
355
387
|
function fetchAdvanced(_0) {
|
|
356
|
-
return __async(this, arguments, function* (
|
|
388
|
+
return __async(this, arguments, function* (input, options = {}) {
|
|
357
389
|
const { timeout = 1e4 } = options;
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
390
|
+
let signalOpts = {}, id = void 0;
|
|
391
|
+
if (timeout >= 0) {
|
|
392
|
+
const controller = new AbortController();
|
|
393
|
+
id = setTimeout(() => controller.abort(), timeout);
|
|
394
|
+
signalOpts = { signal: controller.signal };
|
|
395
|
+
}
|
|
396
|
+
const res = yield fetch(input, __spreadValues(__spreadValues({}, options), signalOpts));
|
|
363
397
|
clearTimeout(id);
|
|
364
398
|
return res;
|
|
365
399
|
});
|
|
@@ -409,14 +443,29 @@ var UserUtils = (function (exports) {
|
|
|
409
443
|
__publicField(this, "baseElement");
|
|
410
444
|
__publicField(this, "observer");
|
|
411
445
|
__publicField(this, "observerOptions");
|
|
446
|
+
__publicField(this, "customOptions");
|
|
412
447
|
__publicField(this, "listenerMap");
|
|
413
448
|
this.baseElement = baseElement;
|
|
414
449
|
this.listenerMap = /* @__PURE__ */ new Map();
|
|
415
450
|
this.observer = new MutationObserver(() => this.checkAllSelectors());
|
|
451
|
+
const _a = options, {
|
|
452
|
+
defaultDebounce,
|
|
453
|
+
disableOnNoListeners,
|
|
454
|
+
enableOnAddListener
|
|
455
|
+
} = _a, observerOptions = __objRest(_a, [
|
|
456
|
+
"defaultDebounce",
|
|
457
|
+
"disableOnNoListeners",
|
|
458
|
+
"enableOnAddListener"
|
|
459
|
+
]);
|
|
416
460
|
this.observerOptions = __spreadValues({
|
|
417
461
|
childList: true,
|
|
418
462
|
subtree: true
|
|
419
|
-
},
|
|
463
|
+
}, observerOptions);
|
|
464
|
+
this.customOptions = {
|
|
465
|
+
defaultDebounce: defaultDebounce != null ? defaultDebounce : 0,
|
|
466
|
+
disableOnNoListeners: disableOnNoListeners != null ? disableOnNoListeners : false,
|
|
467
|
+
enableOnAddListener: enableOnAddListener != null ? enableOnAddListener : true
|
|
468
|
+
};
|
|
420
469
|
}
|
|
421
470
|
checkAllSelectors() {
|
|
422
471
|
for (const [selector, listeners] of this.listenerMap.entries())
|
|
@@ -449,6 +498,8 @@ var UserUtils = (function (exports) {
|
|
|
449
498
|
}
|
|
450
499
|
if (((_a = this.listenerMap.get(selector)) == null ? void 0 : _a.length) === 0)
|
|
451
500
|
this.listenerMap.delete(selector);
|
|
501
|
+
if (this.listenerMap.size === 0 && this.customOptions.disableOnNoListeners)
|
|
502
|
+
this.disable();
|
|
452
503
|
}
|
|
453
504
|
}
|
|
454
505
|
debounce(func, time) {
|
|
@@ -469,16 +520,18 @@ var UserUtils = (function (exports) {
|
|
|
469
520
|
*/
|
|
470
521
|
addListener(selector, options) {
|
|
471
522
|
options = __spreadValues({ all: false, continuous: false, debounce: 0 }, options);
|
|
472
|
-
if (options.debounce && options.debounce > 0 || this.
|
|
523
|
+
if (options.debounce && options.debounce > 0 || this.customOptions.defaultDebounce && this.customOptions.defaultDebounce > 0) {
|
|
473
524
|
options.listener = this.debounce(
|
|
474
525
|
options.listener,
|
|
475
|
-
options.debounce || this.
|
|
526
|
+
options.debounce || this.customOptions.defaultDebounce
|
|
476
527
|
);
|
|
477
528
|
}
|
|
478
529
|
if (this.listenerMap.has(selector))
|
|
479
530
|
this.listenerMap.get(selector).push(options);
|
|
480
531
|
else
|
|
481
532
|
this.listenerMap.set(selector, [options]);
|
|
533
|
+
if (this.enabled === false && this.customOptions.enableOnAddListener)
|
|
534
|
+
this.enable();
|
|
482
535
|
this.checkSelector(selector, [options]);
|
|
483
536
|
}
|
|
484
537
|
/** Disables the observation of the child elements */
|
|
@@ -585,6 +638,7 @@ var UserUtils = (function (exports) {
|
|
|
585
638
|
exports.interceptWindowEvent = interceptWindowEvent;
|
|
586
639
|
exports.isScrollable = isScrollable;
|
|
587
640
|
exports.mapRange = mapRange;
|
|
641
|
+
exports.observeElementProp = observeElementProp;
|
|
588
642
|
exports.openInNewTab = openInNewTab;
|
|
589
643
|
exports.pauseFor = pauseFor;
|
|
590
644
|
exports.preloadImages = preloadImages;
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
|
-
var __defProps = Object.defineProperties;
|
|
5
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
6
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
@@ -18,7 +16,18 @@ var __spreadValues = (a, b) => {
|
|
|
18
16
|
}
|
|
19
17
|
return a;
|
|
20
18
|
};
|
|
21
|
-
var
|
|
19
|
+
var __objRest = (source, exclude) => {
|
|
20
|
+
var target = {};
|
|
21
|
+
for (var prop in source)
|
|
22
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
23
|
+
target[prop] = source[prop];
|
|
24
|
+
if (source != null && __getOwnPropSymbols)
|
|
25
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
26
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
27
|
+
target[prop] = source[prop];
|
|
28
|
+
}
|
|
29
|
+
return target;
|
|
30
|
+
};
|
|
22
31
|
var __publicField = (obj, key, value) => {
|
|
23
32
|
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
24
33
|
return value;
|
|
@@ -99,7 +108,7 @@ function takeRandomItem(arr) {
|
|
|
99
108
|
function randomizeArray(array) {
|
|
100
109
|
const retArray = [...array];
|
|
101
110
|
if (array.length === 0)
|
|
102
|
-
return
|
|
111
|
+
return retArray;
|
|
103
112
|
for (let i = retArray.length - 1; i > 0; i--) {
|
|
104
113
|
const j = Math.floor(randRange(0, 1e4) / 1e4 * (i + 1));
|
|
105
114
|
[retArray[i], retArray[j]] = [retArray[j], retArray[i]];
|
|
@@ -261,6 +270,7 @@ function addGlobalStyle(style) {
|
|
|
261
270
|
const styleElem = document.createElement("style");
|
|
262
271
|
styleElem.innerHTML = style;
|
|
263
272
|
document.head.appendChild(styleElem);
|
|
273
|
+
return styleElem;
|
|
264
274
|
}
|
|
265
275
|
function preloadImages(srcUrls, rejects = false) {
|
|
266
276
|
const promises = srcUrls.map((src) => new Promise((res, rej) => {
|
|
@@ -312,6 +322,28 @@ function isScrollable(element) {
|
|
|
312
322
|
horizontal: (overflowX === "scroll" || overflowX === "auto") && element.scrollWidth > element.clientWidth
|
|
313
323
|
};
|
|
314
324
|
}
|
|
325
|
+
function observeElementProp(element, property, callback) {
|
|
326
|
+
const elementPrototype = Object.getPrototypeOf(element);
|
|
327
|
+
if (elementPrototype.hasOwnProperty(property)) {
|
|
328
|
+
const descriptor = Object.getOwnPropertyDescriptor(elementPrototype, property);
|
|
329
|
+
Object.defineProperty(element, property, {
|
|
330
|
+
get: function() {
|
|
331
|
+
var _a;
|
|
332
|
+
return (_a = descriptor == null ? void 0 : descriptor.get) == null ? void 0 : _a.apply(this, arguments);
|
|
333
|
+
},
|
|
334
|
+
set: function() {
|
|
335
|
+
var _a;
|
|
336
|
+
const oldValue = this[property];
|
|
337
|
+
(_a = descriptor == null ? void 0 : descriptor.set) == null ? void 0 : _a.apply(this, arguments);
|
|
338
|
+
const newValue = this[property];
|
|
339
|
+
if (typeof callback === "function") {
|
|
340
|
+
callback.bind(this, oldValue, newValue);
|
|
341
|
+
}
|
|
342
|
+
return newValue;
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
}
|
|
315
347
|
|
|
316
348
|
// lib/misc.ts
|
|
317
349
|
function autoPlural(word, num) {
|
|
@@ -332,13 +364,15 @@ function debounce(func, timeout = 300) {
|
|
|
332
364
|
};
|
|
333
365
|
}
|
|
334
366
|
function fetchAdvanced(_0) {
|
|
335
|
-
return __async(this, arguments, function* (
|
|
367
|
+
return __async(this, arguments, function* (input, options = {}) {
|
|
336
368
|
const { timeout = 1e4 } = options;
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
369
|
+
let signalOpts = {}, id = void 0;
|
|
370
|
+
if (timeout >= 0) {
|
|
371
|
+
const controller = new AbortController();
|
|
372
|
+
id = setTimeout(() => controller.abort(), timeout);
|
|
373
|
+
signalOpts = { signal: controller.signal };
|
|
374
|
+
}
|
|
375
|
+
const res = yield fetch(input, __spreadValues(__spreadValues({}, options), signalOpts));
|
|
342
376
|
clearTimeout(id);
|
|
343
377
|
return res;
|
|
344
378
|
});
|
|
@@ -388,14 +422,29 @@ var SelectorObserver = class {
|
|
|
388
422
|
__publicField(this, "baseElement");
|
|
389
423
|
__publicField(this, "observer");
|
|
390
424
|
__publicField(this, "observerOptions");
|
|
425
|
+
__publicField(this, "customOptions");
|
|
391
426
|
__publicField(this, "listenerMap");
|
|
392
427
|
this.baseElement = baseElement;
|
|
393
428
|
this.listenerMap = /* @__PURE__ */ new Map();
|
|
394
429
|
this.observer = new MutationObserver(() => this.checkAllSelectors());
|
|
430
|
+
const _a = options, {
|
|
431
|
+
defaultDebounce,
|
|
432
|
+
disableOnNoListeners,
|
|
433
|
+
enableOnAddListener
|
|
434
|
+
} = _a, observerOptions = __objRest(_a, [
|
|
435
|
+
"defaultDebounce",
|
|
436
|
+
"disableOnNoListeners",
|
|
437
|
+
"enableOnAddListener"
|
|
438
|
+
]);
|
|
395
439
|
this.observerOptions = __spreadValues({
|
|
396
440
|
childList: true,
|
|
397
441
|
subtree: true
|
|
398
|
-
},
|
|
442
|
+
}, observerOptions);
|
|
443
|
+
this.customOptions = {
|
|
444
|
+
defaultDebounce: defaultDebounce != null ? defaultDebounce : 0,
|
|
445
|
+
disableOnNoListeners: disableOnNoListeners != null ? disableOnNoListeners : false,
|
|
446
|
+
enableOnAddListener: enableOnAddListener != null ? enableOnAddListener : true
|
|
447
|
+
};
|
|
399
448
|
}
|
|
400
449
|
checkAllSelectors() {
|
|
401
450
|
for (const [selector, listeners] of this.listenerMap.entries())
|
|
@@ -428,6 +477,8 @@ var SelectorObserver = class {
|
|
|
428
477
|
}
|
|
429
478
|
if (((_a = this.listenerMap.get(selector)) == null ? void 0 : _a.length) === 0)
|
|
430
479
|
this.listenerMap.delete(selector);
|
|
480
|
+
if (this.listenerMap.size === 0 && this.customOptions.disableOnNoListeners)
|
|
481
|
+
this.disable();
|
|
431
482
|
}
|
|
432
483
|
}
|
|
433
484
|
debounce(func, time) {
|
|
@@ -448,16 +499,18 @@ var SelectorObserver = class {
|
|
|
448
499
|
*/
|
|
449
500
|
addListener(selector, options) {
|
|
450
501
|
options = __spreadValues({ all: false, continuous: false, debounce: 0 }, options);
|
|
451
|
-
if (options.debounce && options.debounce > 0 || this.
|
|
502
|
+
if (options.debounce && options.debounce > 0 || this.customOptions.defaultDebounce && this.customOptions.defaultDebounce > 0) {
|
|
452
503
|
options.listener = this.debounce(
|
|
453
504
|
options.listener,
|
|
454
|
-
options.debounce || this.
|
|
505
|
+
options.debounce || this.customOptions.defaultDebounce
|
|
455
506
|
);
|
|
456
507
|
}
|
|
457
508
|
if (this.listenerMap.has(selector))
|
|
458
509
|
this.listenerMap.get(selector).push(options);
|
|
459
510
|
else
|
|
460
511
|
this.listenerMap.set(selector, [options]);
|
|
512
|
+
if (this.enabled === false && this.customOptions.enableOnAddListener)
|
|
513
|
+
this.enable();
|
|
461
514
|
this.checkSelector(selector, [options]);
|
|
462
515
|
}
|
|
463
516
|
/** Disables the observation of the child elements */
|
|
@@ -564,6 +617,7 @@ exports.interceptEvent = interceptEvent;
|
|
|
564
617
|
exports.interceptWindowEvent = interceptWindowEvent;
|
|
565
618
|
exports.isScrollable = isScrollable;
|
|
566
619
|
exports.mapRange = mapRange;
|
|
620
|
+
exports.observeElementProp = observeElementProp;
|
|
567
621
|
exports.openInNewTab = openInNewTab;
|
|
568
622
|
exports.pauseFor = pauseFor;
|
|
569
623
|
exports.preloadImages = preloadImages;
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
|
-
var __defProps = Object.defineProperties;
|
|
3
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
2
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
3
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
4
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
@@ -16,7 +14,18 @@ var __spreadValues = (a, b) => {
|
|
|
16
14
|
}
|
|
17
15
|
return a;
|
|
18
16
|
};
|
|
19
|
-
var
|
|
17
|
+
var __objRest = (source, exclude) => {
|
|
18
|
+
var target = {};
|
|
19
|
+
for (var prop in source)
|
|
20
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
21
|
+
target[prop] = source[prop];
|
|
22
|
+
if (source != null && __getOwnPropSymbols)
|
|
23
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
24
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
25
|
+
target[prop] = source[prop];
|
|
26
|
+
}
|
|
27
|
+
return target;
|
|
28
|
+
};
|
|
20
29
|
var __publicField = (obj, key, value) => {
|
|
21
30
|
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
22
31
|
return value;
|
|
@@ -97,7 +106,7 @@ function takeRandomItem(arr) {
|
|
|
97
106
|
function randomizeArray(array) {
|
|
98
107
|
const retArray = [...array];
|
|
99
108
|
if (array.length === 0)
|
|
100
|
-
return
|
|
109
|
+
return retArray;
|
|
101
110
|
for (let i = retArray.length - 1; i > 0; i--) {
|
|
102
111
|
const j = Math.floor(randRange(0, 1e4) / 1e4 * (i + 1));
|
|
103
112
|
[retArray[i], retArray[j]] = [retArray[j], retArray[i]];
|
|
@@ -259,6 +268,7 @@ function addGlobalStyle(style) {
|
|
|
259
268
|
const styleElem = document.createElement("style");
|
|
260
269
|
styleElem.innerHTML = style;
|
|
261
270
|
document.head.appendChild(styleElem);
|
|
271
|
+
return styleElem;
|
|
262
272
|
}
|
|
263
273
|
function preloadImages(srcUrls, rejects = false) {
|
|
264
274
|
const promises = srcUrls.map((src) => new Promise((res, rej) => {
|
|
@@ -310,6 +320,28 @@ function isScrollable(element) {
|
|
|
310
320
|
horizontal: (overflowX === "scroll" || overflowX === "auto") && element.scrollWidth > element.clientWidth
|
|
311
321
|
};
|
|
312
322
|
}
|
|
323
|
+
function observeElementProp(element, property, callback) {
|
|
324
|
+
const elementPrototype = Object.getPrototypeOf(element);
|
|
325
|
+
if (elementPrototype.hasOwnProperty(property)) {
|
|
326
|
+
const descriptor = Object.getOwnPropertyDescriptor(elementPrototype, property);
|
|
327
|
+
Object.defineProperty(element, property, {
|
|
328
|
+
get: function() {
|
|
329
|
+
var _a;
|
|
330
|
+
return (_a = descriptor == null ? void 0 : descriptor.get) == null ? void 0 : _a.apply(this, arguments);
|
|
331
|
+
},
|
|
332
|
+
set: function() {
|
|
333
|
+
var _a;
|
|
334
|
+
const oldValue = this[property];
|
|
335
|
+
(_a = descriptor == null ? void 0 : descriptor.set) == null ? void 0 : _a.apply(this, arguments);
|
|
336
|
+
const newValue = this[property];
|
|
337
|
+
if (typeof callback === "function") {
|
|
338
|
+
callback.bind(this, oldValue, newValue);
|
|
339
|
+
}
|
|
340
|
+
return newValue;
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
}
|
|
313
345
|
|
|
314
346
|
// lib/misc.ts
|
|
315
347
|
function autoPlural(word, num) {
|
|
@@ -330,13 +362,15 @@ function debounce(func, timeout = 300) {
|
|
|
330
362
|
};
|
|
331
363
|
}
|
|
332
364
|
function fetchAdvanced(_0) {
|
|
333
|
-
return __async(this, arguments, function* (
|
|
365
|
+
return __async(this, arguments, function* (input, options = {}) {
|
|
334
366
|
const { timeout = 1e4 } = options;
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
367
|
+
let signalOpts = {}, id = void 0;
|
|
368
|
+
if (timeout >= 0) {
|
|
369
|
+
const controller = new AbortController();
|
|
370
|
+
id = setTimeout(() => controller.abort(), timeout);
|
|
371
|
+
signalOpts = { signal: controller.signal };
|
|
372
|
+
}
|
|
373
|
+
const res = yield fetch(input, __spreadValues(__spreadValues({}, options), signalOpts));
|
|
340
374
|
clearTimeout(id);
|
|
341
375
|
return res;
|
|
342
376
|
});
|
|
@@ -386,14 +420,29 @@ var SelectorObserver = class {
|
|
|
386
420
|
__publicField(this, "baseElement");
|
|
387
421
|
__publicField(this, "observer");
|
|
388
422
|
__publicField(this, "observerOptions");
|
|
423
|
+
__publicField(this, "customOptions");
|
|
389
424
|
__publicField(this, "listenerMap");
|
|
390
425
|
this.baseElement = baseElement;
|
|
391
426
|
this.listenerMap = /* @__PURE__ */ new Map();
|
|
392
427
|
this.observer = new MutationObserver(() => this.checkAllSelectors());
|
|
428
|
+
const _a = options, {
|
|
429
|
+
defaultDebounce,
|
|
430
|
+
disableOnNoListeners,
|
|
431
|
+
enableOnAddListener
|
|
432
|
+
} = _a, observerOptions = __objRest(_a, [
|
|
433
|
+
"defaultDebounce",
|
|
434
|
+
"disableOnNoListeners",
|
|
435
|
+
"enableOnAddListener"
|
|
436
|
+
]);
|
|
393
437
|
this.observerOptions = __spreadValues({
|
|
394
438
|
childList: true,
|
|
395
439
|
subtree: true
|
|
396
|
-
},
|
|
440
|
+
}, observerOptions);
|
|
441
|
+
this.customOptions = {
|
|
442
|
+
defaultDebounce: defaultDebounce != null ? defaultDebounce : 0,
|
|
443
|
+
disableOnNoListeners: disableOnNoListeners != null ? disableOnNoListeners : false,
|
|
444
|
+
enableOnAddListener: enableOnAddListener != null ? enableOnAddListener : true
|
|
445
|
+
};
|
|
397
446
|
}
|
|
398
447
|
checkAllSelectors() {
|
|
399
448
|
for (const [selector, listeners] of this.listenerMap.entries())
|
|
@@ -426,6 +475,8 @@ var SelectorObserver = class {
|
|
|
426
475
|
}
|
|
427
476
|
if (((_a = this.listenerMap.get(selector)) == null ? void 0 : _a.length) === 0)
|
|
428
477
|
this.listenerMap.delete(selector);
|
|
478
|
+
if (this.listenerMap.size === 0 && this.customOptions.disableOnNoListeners)
|
|
479
|
+
this.disable();
|
|
429
480
|
}
|
|
430
481
|
}
|
|
431
482
|
debounce(func, time) {
|
|
@@ -446,16 +497,18 @@ var SelectorObserver = class {
|
|
|
446
497
|
*/
|
|
447
498
|
addListener(selector, options) {
|
|
448
499
|
options = __spreadValues({ all: false, continuous: false, debounce: 0 }, options);
|
|
449
|
-
if (options.debounce && options.debounce > 0 || this.
|
|
500
|
+
if (options.debounce && options.debounce > 0 || this.customOptions.defaultDebounce && this.customOptions.defaultDebounce > 0) {
|
|
450
501
|
options.listener = this.debounce(
|
|
451
502
|
options.listener,
|
|
452
|
-
options.debounce || this.
|
|
503
|
+
options.debounce || this.customOptions.defaultDebounce
|
|
453
504
|
);
|
|
454
505
|
}
|
|
455
506
|
if (this.listenerMap.has(selector))
|
|
456
507
|
this.listenerMap.get(selector).push(options);
|
|
457
508
|
else
|
|
458
509
|
this.listenerMap.set(selector, [options]);
|
|
510
|
+
if (this.enabled === false && this.customOptions.enableOnAddListener)
|
|
511
|
+
this.enable();
|
|
459
512
|
this.checkSelector(selector, [options]);
|
|
460
513
|
}
|
|
461
514
|
/** Disables the observation of the child elements */
|
|
@@ -545,4 +598,4 @@ tr.getLanguage = () => {
|
|
|
545
598
|
return curLang;
|
|
546
599
|
};
|
|
547
600
|
|
|
548
|
-
export { ConfigManager, SelectorObserver, addGlobalStyle, addParent, autoPlural, clamp, compress, debounce, decompress, fetchAdvanced, getUnsafeWindow, insertAfter, insertValues, interceptEvent, interceptWindowEvent, isScrollable, mapRange, openInNewTab, pauseFor, preloadImages, randRange, randomId, randomItem, randomItemIndex, randomizeArray, takeRandomItem, tr };
|
|
601
|
+
export { ConfigManager, SelectorObserver, addGlobalStyle, addParent, autoPlural, clamp, compress, debounce, decompress, fetchAdvanced, getUnsafeWindow, insertAfter, insertValues, interceptEvent, interceptWindowEvent, isScrollable, mapRange, observeElementProp, openInNewTab, pauseFor, preloadImages, randRange, randomId, randomItem, randomItemIndex, randomizeArray, takeRandomItem, tr };
|
|
@@ -18,9 +18,13 @@ type SelectorOptionsCommon = {
|
|
|
18
18
|
/** Whether to debounce the listener to reduce calls to `querySelector` or `querySelectorAll` - set undefined or <=0 to disable (default) */
|
|
19
19
|
debounce?: number;
|
|
20
20
|
};
|
|
21
|
-
export type SelectorObserverOptions =
|
|
21
|
+
export type SelectorObserverOptions = {
|
|
22
22
|
/** If set, applies this debounce in milliseconds to all listeners that don't have their own debounce set */
|
|
23
23
|
defaultDebounce?: number;
|
|
24
|
+
/** Whether to disable the observer when no listeners are present - default is true */
|
|
25
|
+
disableOnNoListeners?: boolean;
|
|
26
|
+
/** Whether to ensure the observer is enabled when a new listener is added - default is true */
|
|
27
|
+
enableOnAddListener?: boolean;
|
|
24
28
|
};
|
|
25
29
|
/** Observes the children of the given element for changes */
|
|
26
30
|
export declare class SelectorObserver {
|
|
@@ -28,13 +32,14 @@ export declare class SelectorObserver {
|
|
|
28
32
|
private baseElement;
|
|
29
33
|
private observer;
|
|
30
34
|
private observerOptions;
|
|
35
|
+
private customOptions;
|
|
31
36
|
private listenerMap;
|
|
32
37
|
/**
|
|
33
38
|
* Creates a new SelectorObserver that will observe the children of the given base element selector for changes (only creation and deletion of elements by default)
|
|
34
39
|
* @param baseElementSelector The selector of the element to observe
|
|
35
40
|
* @param options Fine-tune what triggers the MutationObserver's checking function - `subtree` and `childList` are set to true by default
|
|
36
41
|
*/
|
|
37
|
-
constructor(baseElementSelector: string, options?: SelectorObserverOptions);
|
|
42
|
+
constructor(baseElementSelector: string, options?: SelectorObserverOptions & MutationObserverInit);
|
|
38
43
|
/**
|
|
39
44
|
* Creates a new SelectorObserver that will observe the children of the given base element for changes (only creation and deletion of elements by default)
|
|
40
45
|
* @param baseElement The element to observe
|
package/dist/lib/dom.d.ts
CHANGED
|
@@ -16,8 +16,9 @@ export declare function addParent(element: Element, newParent: Element): Element
|
|
|
16
16
|
* Adds global CSS style in the form of a `<style>` element in the document's `<head>`
|
|
17
17
|
* This needs to be run after the `DOMContentLoaded` event has fired on the document object (or instantly if `@run-at document-end` is used).
|
|
18
18
|
* @param style CSS string
|
|
19
|
+
* @returns Returns the created style element
|
|
19
20
|
*/
|
|
20
|
-
export declare function addGlobalStyle(style: string):
|
|
21
|
+
export declare function addGlobalStyle(style: string): HTMLStyleElement;
|
|
21
22
|
/**
|
|
22
23
|
* Preloads an array of image URLs so they can be loaded instantly from the browser cache later on
|
|
23
24
|
* @param rejects If set to `true`, the returned PromiseSettledResults will contain rejections for any of the images that failed to load
|
|
@@ -50,3 +51,13 @@ export declare function isScrollable(element: Element): {
|
|
|
50
51
|
vertical: boolean;
|
|
51
52
|
horizontal: boolean;
|
|
52
53
|
};
|
|
54
|
+
/**
|
|
55
|
+
* Executes the callback when the passed element's property changes.
|
|
56
|
+
* Contrary to an element's attributes, properties can usually not be observed with a MutationObserver.
|
|
57
|
+
* This function shims the getter and setter of the property to invoke the callback.
|
|
58
|
+
*
|
|
59
|
+
* [Source](https://stackoverflow.com/a/61975440)
|
|
60
|
+
* @param property The name of the property to observe
|
|
61
|
+
* @param callback Callback to execute when the value is changed
|
|
62
|
+
*/
|
|
63
|
+
export declare function observeElementProp<TElem extends Element = HTMLElement, TPropKey extends keyof TElem = keyof TElem>(element: TElem, property: TPropKey, callback: (oldVal: TElem[TPropKey], newVal: TElem[TPropKey]) => void): void;
|
package/dist/lib/math.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export declare function randRange(max: number): number;
|
|
|
12
12
|
/**
|
|
13
13
|
* Generates a random ID with the specified length and radix (16 characters and hexadecimal by default)
|
|
14
14
|
* Uses [`crypto.getRandomValues()`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues) for better cryptographic randomness
|
|
15
|
+
* ⚠️ Not suitable for generating encryption keys! Use [`crypto.subtle.generateKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey) for that.
|
|
15
16
|
* @param length The length of the ID to generate (defaults to 16)
|
|
16
17
|
* @param radix The [radix](https://en.wikipedia.org/wiki/Radix) of each digit (defaults to 16 which is hexadecimal. Use 2 for binary, 10 for decimal, 36 for alphanumeric, etc.)
|
|
17
18
|
*/
|
package/dist/lib/misc.d.ts
CHANGED
|
@@ -29,12 +29,12 @@ export declare function pauseFor(time: number): Promise<void>;
|
|
|
29
29
|
*/
|
|
30
30
|
export declare function debounce<TFunc extends (...args: TArgs[]) => void, TArgs = any>(func: TFunc, timeout?: number): (...args: TArgs[]) => void;
|
|
31
31
|
/** Options for the `fetchAdvanced()` function */
|
|
32
|
-
export type FetchAdvancedOpts = RequestInit & Partial<{
|
|
32
|
+
export type FetchAdvancedOpts = Omit<RequestInit & Partial<{
|
|
33
33
|
/** Timeout in milliseconds after which the fetch call will be canceled with an AbortController signal */
|
|
34
34
|
timeout: number;
|
|
35
|
-
}>;
|
|
35
|
+
}>, "signal">;
|
|
36
36
|
/** Calls the fetch API with special options like a timeout */
|
|
37
|
-
export declare function fetchAdvanced(
|
|
37
|
+
export declare function fetchAdvanced(input: RequestInfo | URL, options?: FetchAdvancedOpts): Promise<Response>;
|
|
38
38
|
/**
|
|
39
39
|
* Inserts the passed values into a string at the respective placeholders.
|
|
40
40
|
* The placeholder format is `%n`, where `n` is the 1-indexed argument number.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sv443-network/userutils",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"description": "Library with various utilities for userscripts - register listeners for when CSS selectors exist, intercept events, manage persistent user configurations, modify the DOM more easily and more",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|