@sv443-network/userutils 9.0.3 → 9.1.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 +21 -0
- package/README-summary.md +28 -16
- package/README.md +15 -7
- package/dist/index.cjs +40 -19
- package/dist/index.global.js +41 -20
- package/dist/index.js +40 -20
- package/dist/lib/misc.d.ts +22 -7
- package/dist/lib/types.d.ts +8 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @sv443-network/userutils
|
|
2
2
|
|
|
3
|
+
## 9.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- eb20132: Added the type `ListWithLength` to represent an array or object with a numeric `length`, `count` or `size` property.
|
|
8
|
+
- eb20132: Added `autoPlural()` support for generic objects with a numeric `length`, `count` or `size` property.
|
|
9
|
+
- c9b13d8: Added `signal: AbortSignal` and `rejectOnAbort: boolean` params to `pauseFor()` to allow for cutting the pause short
|
|
10
|
+
- c66324b: Support for words with `-y`/`-ies` extension in `autoPlural()`
|
|
11
|
+
- c9b13d8: Added `getListLength()` function to resolve a value of the new `ListWithLength` type
|
|
12
|
+
- c13e890: `autoPlural()` now defaults `pluralType` to `"auto"` and `num` to 2 if `pluralType` is invalid or `num` resolves to NaN
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- 3f86215: Fixed fetchAdvanced error "'abort' called on an object that does not implement interface AbortController"
|
|
17
|
+
|
|
18
|
+
## 9.0.4
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- 858c948: Fix broken percent transform (`tr.transforms.percent`)
|
|
23
|
+
|
|
3
24
|
## 9.0.3
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
package/README-summary.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
## UserUtils
|
|
2
|
-
|
|
2
|
+
General purpose DOM/GreaseMonkey library that allows you to register listeners for when CSS selectors exist, intercept events, create persistent & synchronous data stores, modify the DOM more easily and much more.
|
|
3
3
|
Contains builtin TypeScript declarations. Supports ESM and CJS imports via a bundler and global declaration via `@require`
|
|
4
|
-
The library
|
|
4
|
+
The library works in any DOM environment with or without the [GreaseMonkey API](https://wiki.greasespot.net/Greasemonkey_Manual:API), but some features will be unavailable or limited.
|
|
5
5
|
|
|
6
6
|
You may want to check out my [template for userscripts in TypeScript](https://github.com/Sv443/Userscript.ts) that you can use to get started quickly. It also includes this library by default.
|
|
7
7
|
|
|
@@ -66,22 +66,27 @@ View the documentation of previous major releases:
|
|
|
66
66
|
- [`decompress()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#decompress) - decompress a previously compressed string
|
|
67
67
|
- [`computeHash()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#computehash) - compute the hash / checksum of a string or ArrayBuffer
|
|
68
68
|
- [`randomId()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#randomid) - generate a random ID of a given length and radix
|
|
69
|
+
- [`consumeGen()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#consumegen) - consumes a ValueGen and returns the value
|
|
70
|
+
- [`consumeStringGen()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#consumestringgen) - consumes a StringGen and returns the string
|
|
71
|
+
- [`getListLength()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#getlistlength) - get the length of any object with a numeric `length`, `count` or `size` property
|
|
69
72
|
- **Arrays:**
|
|
70
73
|
- [`randomItem()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#randomitem) - returns a random item from an array
|
|
71
74
|
- [`randomItemIndex()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#randomitemindex) - returns a tuple of a random item and its index from an array
|
|
72
75
|
- [`takeRandomItem()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#takerandomitem) - returns a random item from an array and mutates it to remove the item
|
|
73
76
|
- [`randomizeArray()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#randomizearray) - returns a copy of the array with its items in a random order
|
|
74
77
|
- **Translation:**
|
|
75
|
-
- [`tr()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#
|
|
76
|
-
- [`tr.
|
|
77
|
-
- [`tr.
|
|
78
|
-
- [`tr.
|
|
79
|
-
- [`tr.
|
|
80
|
-
- [`tr.
|
|
81
|
-
- [`tr.
|
|
82
|
-
- [`tr.
|
|
83
|
-
- [`tr.addTransform()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#traddtransform) -
|
|
84
|
-
- [`tr.deleteTransform()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#trdeletetransform) -
|
|
78
|
+
- [`tr.for()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#trfor) - translates a key for the specified language
|
|
79
|
+
- [`tr.use()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#truse) - creates a translation function for the specified language
|
|
80
|
+
- [`tr.hasKey()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#trhaskey) - checks if a key exists in the given language
|
|
81
|
+
- [`tr.addTranslations()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#traddtranslations) - add a flat or recursive translation object for a language
|
|
82
|
+
- [`tr.getTranslations()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#trgettranslations) - returns the translation object for a language
|
|
83
|
+
- [`tr.deleteTranslations()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#trdeletetranslations) - delete the translation object for a language
|
|
84
|
+
- [`tr.setFallbackLanguage()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#trsetfallbacklanguage) - set the fallback language used when a key is not found in the given language
|
|
85
|
+
- [`tr.getFallbackLanguage()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#trgetfallbacklanguage) - returns the fallback language
|
|
86
|
+
- [`tr.addTransform()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#traddtransform) - adds a transform function to the translation system for custom argument insertion and much more
|
|
87
|
+
- [`tr.deleteTransform()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#trdeletetransform) - removes a transform function
|
|
88
|
+
- [`tr.transforms`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#trtransforms) - predefined transform functions for quickly adding custom argument insertion
|
|
89
|
+
- [`TrKeys`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#trkeys) - generic type that extracts all keys from a flat or recursive translation object into a union
|
|
85
90
|
- **Colors:**
|
|
86
91
|
- [`hexToRgb()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#hextorgb) - convert a hex color string to an RGB or RGBA value tuple
|
|
87
92
|
- [`rgbToHex()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#rgbtohex) - convert RGB or RGBA values to a hex color string
|
|
@@ -95,6 +100,7 @@ View the documentation of previous major releases:
|
|
|
95
100
|
- [`Prettify`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#prettify) - expands a complex type into a more readable format while keeping functionality the same
|
|
96
101
|
- [`ValueGen`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#valuegen) - a "generator" value that allows for super flexible value typing and declaration
|
|
97
102
|
- [`StringGen`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#stringgen) - a "generator" string that allows for super flexible string typing and declaration, including enhanced support for unions
|
|
103
|
+
- [`ListWithLength`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#listwithlength) - represents an array or object with a numeric `length`, `count` or `size` property
|
|
98
104
|
|
|
99
105
|
<br><br>
|
|
100
106
|
|
|
@@ -138,9 +144,15 @@ Shameless plug: I made a [template for userscripts in TypeScript](https://github
|
|
|
138
144
|
// @require https://update.greasyfork.org/scripts/472956/UserUtils.js
|
|
139
145
|
// @require https://openuserjs.org/src/libs/Sv443/UserUtils.js
|
|
140
146
|
```
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
147
|
+
|
|
148
|
+
- If you are using this library in a generic DOM environment without access to the GreaseMonkey API, either download the latest release from the [releases page](https://github.com/Sv443-Network/UserUtils/releases) to include in your project or add one of the following tags to the <head>:
|
|
149
|
+
```html
|
|
150
|
+
<script src="https://cdn.jsdelivr.net/npm/@sv443-network/userutils@INSERT_VERSION/dist/index.global.js"></script>
|
|
151
|
+
<script src="https://unpkg.com/@sv443-network/userutils@INSERT_VERSION/dist/index.global.js"></script>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
> **Note:**
|
|
155
|
+
> In order for your userscript not to break on a major library update, use one the versioned URLs above after replacing `INSERT_VERSION` with the desired version (e.g. `8.3.2`) or the versioned URL that's shown [at the top of the GreasyFork page.](https://greasyfork.org/scripts/472956-userutils)
|
|
144
156
|
|
|
145
157
|
<br>
|
|
146
158
|
|
|
@@ -156,7 +168,7 @@ Shameless plug: I made a [template for userscripts in TypeScript](https://github
|
|
|
156
168
|
|
|
157
169
|
<br>
|
|
158
170
|
|
|
159
|
-
- If you're using TypeScript and it complains about the missing global variable `UserUtils`, install the library using the package manager of your choice and add the following inside
|
|
171
|
+
- If you're using TypeScript and it complains about the missing global variable `UserUtils`, install the library using the package manager of your choice and add the following inside any `.ts` file that is included in the final build:
|
|
160
172
|
```ts
|
|
161
173
|
declare const UserUtils: typeof import("@sv443-network/userutils");
|
|
162
174
|
|
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- #region Description -->
|
|
4
4
|
## UserUtils
|
|
5
|
-
|
|
5
|
+
General purpose DOM/GreaseMonkey library that allows you to register listeners for when CSS selectors exist, intercept events, create persistent & synchronous data stores, modify the DOM more easily and much more.
|
|
6
6
|
Contains builtin TypeScript declarations. Supports ESM and CJS imports via a bundler and global declaration via `@require`
|
|
7
|
-
The library
|
|
7
|
+
The library works in any DOM environment with or without the [GreaseMonkey API](https://wiki.greasespot.net/Greasemonkey_Manual:API), but some features will be unavailable or limited.
|
|
8
8
|
|
|
9
9
|
You may want to check out my [template for userscripts in TypeScript](https://github.com/Sv443/Userscript.ts) that you can use to get started quickly. It also includes this library by default.
|
|
10
10
|
If you like using this library, please consider [supporting the development ❤️](https://github.com/sponsors/Sv443)
|
|
@@ -71,6 +71,7 @@ View the documentation of previous major releases:
|
|
|
71
71
|
- [`randomId()`](./docs.md#randomid) - generate a random ID of a given length and radix
|
|
72
72
|
- [`consumeGen()`](./docs.md#consumegen) - consumes a ValueGen and returns the value
|
|
73
73
|
- [`consumeStringGen()`](./docs.md#consumestringgen) - consumes a StringGen and returns the string
|
|
74
|
+
- [`getListLength()`](./docs.md#getlistlength) - get the length of any object with a numeric `length`, `count` or `size` property
|
|
74
75
|
- [**Arrays:**](./docs.md#arrays)
|
|
75
76
|
- [`randomItem()`](./docs.md#randomitem) - returns a random item from an array
|
|
76
77
|
- [`randomItemIndex()`](./docs.md#randomitemindex) - returns a tuple of a random item and its index from an array
|
|
@@ -102,6 +103,7 @@ View the documentation of previous major releases:
|
|
|
102
103
|
- [`Prettify`](./docs.md#prettify) - expands a complex type into a more readable format while keeping functionality the same
|
|
103
104
|
- [`ValueGen`](./docs.md#valuegen) - a "generator" value that allows for super flexible value typing and declaration
|
|
104
105
|
- [`StringGen`](./docs.md#stringgen) - a "generator" string that allows for super flexible string typing and declaration, including enhanced support for unions
|
|
106
|
+
- [`ListWithLength`](./docs.md#listwithlength) - represents an array or object with a numeric `length`, `count` or `size` property
|
|
105
107
|
|
|
106
108
|
<br><br>
|
|
107
109
|
|
|
@@ -132,21 +134,27 @@ Shameless plug: I made a [template for userscripts in TypeScript](https://github
|
|
|
132
134
|
|
|
133
135
|
<br>
|
|
134
136
|
|
|
135
|
-
- If you are not using a bundler, want to reduce the size of your
|
|
137
|
+
- If you are not using a bundler, want to reduce the size of your script, or declared the package as external in your bundler, you can include the latest release by adding one of these directives to the userscript header, depending on your preferred CDN:
|
|
136
138
|
|
|
137
139
|
Versioned (recommended):
|
|
138
140
|
```
|
|
139
141
|
// @require https://cdn.jsdelivr.net/npm/@sv443-network/userutils@INSERT_VERSION/dist/index.global.js
|
|
140
142
|
// @require https://unpkg.com/@sv443-network/userutils@INSERT_VERSION/dist/index.global.js
|
|
141
143
|
```
|
|
142
|
-
Non-versioned (not recommended because auto-
|
|
144
|
+
Non-versioned (not recommended because it auto-updates):
|
|
143
145
|
```
|
|
144
146
|
// @require https://update.greasyfork.org/scripts/472956/UserUtils.js
|
|
145
147
|
// @require https://openuserjs.org/src/libs/Sv443/UserUtils.js
|
|
146
148
|
```
|
|
147
|
-
|
|
149
|
+
|
|
150
|
+
- If you are using this library in a generic DOM environment without access to the GreaseMonkey API, either download the latest release from the [releases page](https://github.com/Sv443-Network/UserUtils/releases) to include in your project or add one of the following tags to the <head>:
|
|
151
|
+
```html
|
|
152
|
+
<script src="https://cdn.jsdelivr.net/npm/@sv443-network/userutils@INSERT_VERSION/dist/index.global.js"></script>
|
|
153
|
+
<script src="https://unpkg.com/@sv443-network/userutils@INSERT_VERSION/dist/index.global.js"></script>
|
|
154
|
+
```
|
|
155
|
+
|
|
148
156
|
> [!NOTE]
|
|
149
|
-
> In order for your
|
|
157
|
+
> In order for your script not to break on a major library update, use one the versioned URLs above after replacing `INSERT_VERSION` with the desired version (e.g. `8.3.2`) or the versioned URL that's shown [at the top of the GreasyFork page.](https://greasyfork.org/scripts/472956-userutils)
|
|
150
158
|
|
|
151
159
|
<br>
|
|
152
160
|
|
|
@@ -163,7 +171,7 @@ Shameless plug: I made a [template for userscripts in TypeScript](https://github
|
|
|
163
171
|
|
|
164
172
|
<br>
|
|
165
173
|
|
|
166
|
-
- If you're using TypeScript and it complains about the missing global variable `UserUtils`, install the library using the package manager of your choice and add the following inside
|
|
174
|
+
- If you're using TypeScript and it complains about the missing global variable `UserUtils`, install the library using the package manager of your choice and add the following inside any `.ts` file that is included in the final build:
|
|
167
175
|
|
|
168
176
|
```ts
|
|
169
177
|
declare const UserUtils: typeof import("@sv443-network/userutils");
|
package/dist/index.cjs
CHANGED
|
@@ -1331,10 +1331,23 @@ var Dialog = class _Dialog extends NanoEmitter {
|
|
|
1331
1331
|
};
|
|
1332
1332
|
|
|
1333
1333
|
// lib/misc.ts
|
|
1334
|
-
function autoPlural(
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1334
|
+
function autoPlural(term, num, pluralType = "auto") {
|
|
1335
|
+
let n = num;
|
|
1336
|
+
if (typeof n !== "number")
|
|
1337
|
+
n = getListLength(n, false);
|
|
1338
|
+
if (!["-s", "-ies"].includes(pluralType))
|
|
1339
|
+
pluralType = "auto";
|
|
1340
|
+
if (isNaN(n))
|
|
1341
|
+
n = 2;
|
|
1342
|
+
const pType = pluralType === "auto" ? String(term).endsWith("y") ? "-ies" : "-s" : pluralType;
|
|
1343
|
+
switch (pType) {
|
|
1344
|
+
case "-s":
|
|
1345
|
+
return `${term}${n === 1 ? "" : "s"}`;
|
|
1346
|
+
case "-ies":
|
|
1347
|
+
return `${String(term).slice(0, -1)}${n === 1 ? "y" : "ies"}`;
|
|
1348
|
+
default:
|
|
1349
|
+
return String(term);
|
|
1350
|
+
}
|
|
1338
1351
|
}
|
|
1339
1352
|
function insertValues(input, ...values) {
|
|
1340
1353
|
return input.replace(/%\d/gm, (match) => {
|
|
@@ -1343,29 +1356,33 @@ function insertValues(input, ...values) {
|
|
|
1343
1356
|
return (_b = (_a = values[argIndex]) != null ? _a : match) == null ? undefined : _b.toString();
|
|
1344
1357
|
});
|
|
1345
1358
|
}
|
|
1346
|
-
function pauseFor(time) {
|
|
1347
|
-
return new Promise((res) => {
|
|
1348
|
-
setTimeout(() => res(), time);
|
|
1359
|
+
function pauseFor(time, signal, rejectOnAbort = false) {
|
|
1360
|
+
return new Promise((res, rej) => {
|
|
1361
|
+
const timeout = setTimeout(() => res(), time);
|
|
1362
|
+
signal == null ? undefined : signal.addEventListener("abort", () => {
|
|
1363
|
+
clearTimeout(timeout);
|
|
1364
|
+
rejectOnAbort ? rej(new Error("The pause was aborted")) : res();
|
|
1365
|
+
});
|
|
1349
1366
|
});
|
|
1350
1367
|
}
|
|
1351
1368
|
function fetchAdvanced(_0) {
|
|
1352
1369
|
return __async(this, arguments, function* (input, options = {}) {
|
|
1353
|
-
var _a;
|
|
1354
1370
|
const { timeout = 1e4 } = options;
|
|
1355
|
-
const
|
|
1356
|
-
|
|
1357
|
-
|
|
1371
|
+
const ctl = new AbortController();
|
|
1372
|
+
const _a = options, { signal } = _a, restOpts = __objRest(_a, ["signal"]);
|
|
1373
|
+
signal == null ? undefined : signal.addEventListener("abort", () => ctl.abort());
|
|
1374
|
+
let sigOpts = {}, id = undefined;
|
|
1358
1375
|
if (timeout >= 0) {
|
|
1359
|
-
id = setTimeout(() => abort(), timeout);
|
|
1360
|
-
|
|
1376
|
+
id = setTimeout(() => ctl.abort(), timeout);
|
|
1377
|
+
sigOpts = { signal: ctl.signal };
|
|
1361
1378
|
}
|
|
1362
1379
|
try {
|
|
1363
|
-
const res = yield fetch(input, __spreadValues(__spreadValues({},
|
|
1364
|
-
id && clearTimeout(id);
|
|
1380
|
+
const res = yield fetch(input, __spreadValues(__spreadValues({}, restOpts), sigOpts));
|
|
1381
|
+
typeof id !== "undefined" && clearTimeout(id);
|
|
1365
1382
|
return res;
|
|
1366
1383
|
} catch (err) {
|
|
1367
|
-
id && clearTimeout(id);
|
|
1368
|
-
throw err;
|
|
1384
|
+
typeof id !== "undefined" && clearTimeout(id);
|
|
1385
|
+
throw new Error("Error while calling fetch", { cause: err });
|
|
1369
1386
|
}
|
|
1370
1387
|
});
|
|
1371
1388
|
}
|
|
@@ -1381,6 +1398,9 @@ function consumeStringGen(strGen) {
|
|
|
1381
1398
|
);
|
|
1382
1399
|
});
|
|
1383
1400
|
}
|
|
1401
|
+
function getListLength(obj, zeroOnInvalid = true) {
|
|
1402
|
+
return "length" in obj ? obj.length : "size" in obj ? obj.size : "count" in obj ? obj.count : zeroOnInvalid ? 0 : NaN;
|
|
1403
|
+
}
|
|
1384
1404
|
|
|
1385
1405
|
// lib/SelectorObserver.ts
|
|
1386
1406
|
var domLoaded = false;
|
|
@@ -1692,11 +1712,11 @@ var templateLiteralTransform = [
|
|
|
1692
1712
|
}
|
|
1693
1713
|
];
|
|
1694
1714
|
var percentTransform = [
|
|
1695
|
-
|
|
1715
|
+
/%(\d+)/gm,
|
|
1696
1716
|
({ matches, trArgs, trValue }) => {
|
|
1697
1717
|
let str = String(trValue);
|
|
1698
1718
|
for (const match of matches) {
|
|
1699
|
-
const repl = match[1] !== undefined ? trArgs[
|
|
1719
|
+
const repl = match[1] !== undefined ? trArgs == null ? undefined : trArgs[Number(match[1]) - 1] : undefined;
|
|
1700
1720
|
if (typeof repl !== "undefined")
|
|
1701
1721
|
str = str.replace(match[0], String(repl));
|
|
1702
1722
|
}
|
|
@@ -1741,6 +1761,7 @@ exports.defaultDialogCss = defaultDialogCss;
|
|
|
1741
1761
|
exports.defaultStrings = defaultStrings;
|
|
1742
1762
|
exports.digitCount = digitCount;
|
|
1743
1763
|
exports.fetchAdvanced = fetchAdvanced;
|
|
1764
|
+
exports.getListLength = getListLength;
|
|
1744
1765
|
exports.getSiblingsFrame = getSiblingsFrame;
|
|
1745
1766
|
exports.getUnsafeWindow = getUnsafeWindow;
|
|
1746
1767
|
exports.hexToRgb = hexToRgb;
|
package/dist/index.global.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// ==UserLibrary==
|
|
9
9
|
// @name UserUtils
|
|
10
10
|
// @description Lightweight library with various utilities for userscripts - register listeners for when CSS selectors exist, intercept events, create persistent & synchronous data stores, modify the DOM more easily and much more
|
|
11
|
-
// @version 9.0
|
|
11
|
+
// @version 9.1.0
|
|
12
12
|
// @license MIT
|
|
13
13
|
// @copyright Sv443 (https://github.com/Sv443)
|
|
14
14
|
|
|
@@ -1369,10 +1369,23 @@ Has: ${checksum}`);
|
|
|
1369
1369
|
};
|
|
1370
1370
|
|
|
1371
1371
|
// lib/misc.ts
|
|
1372
|
-
function autoPlural(
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1372
|
+
function autoPlural(term, num, pluralType = "auto") {
|
|
1373
|
+
let n = num;
|
|
1374
|
+
if (typeof n !== "number")
|
|
1375
|
+
n = getListLength(n, false);
|
|
1376
|
+
if (!["-s", "-ies"].includes(pluralType))
|
|
1377
|
+
pluralType = "auto";
|
|
1378
|
+
if (isNaN(n))
|
|
1379
|
+
n = 2;
|
|
1380
|
+
const pType = pluralType === "auto" ? String(term).endsWith("y") ? "-ies" : "-s" : pluralType;
|
|
1381
|
+
switch (pType) {
|
|
1382
|
+
case "-s":
|
|
1383
|
+
return `${term}${n === 1 ? "" : "s"}`;
|
|
1384
|
+
case "-ies":
|
|
1385
|
+
return `${String(term).slice(0, -1)}${n === 1 ? "y" : "ies"}`;
|
|
1386
|
+
default:
|
|
1387
|
+
return String(term);
|
|
1388
|
+
}
|
|
1376
1389
|
}
|
|
1377
1390
|
function insertValues(input, ...values) {
|
|
1378
1391
|
return input.replace(/%\d/gm, (match) => {
|
|
@@ -1381,29 +1394,33 @@ Has: ${checksum}`);
|
|
|
1381
1394
|
return (_b = (_a = values[argIndex]) != null ? _a : match) == null ? undefined : _b.toString();
|
|
1382
1395
|
});
|
|
1383
1396
|
}
|
|
1384
|
-
function pauseFor(time) {
|
|
1385
|
-
return new Promise((res) => {
|
|
1386
|
-
setTimeout(() => res(), time);
|
|
1397
|
+
function pauseFor(time, signal, rejectOnAbort = false) {
|
|
1398
|
+
return new Promise((res, rej) => {
|
|
1399
|
+
const timeout = setTimeout(() => res(), time);
|
|
1400
|
+
signal == null ? undefined : signal.addEventListener("abort", () => {
|
|
1401
|
+
clearTimeout(timeout);
|
|
1402
|
+
rejectOnAbort ? rej(new Error("The pause was aborted")) : res();
|
|
1403
|
+
});
|
|
1387
1404
|
});
|
|
1388
1405
|
}
|
|
1389
1406
|
function fetchAdvanced(_0) {
|
|
1390
1407
|
return __async(this, arguments, function* (input, options = {}) {
|
|
1391
|
-
var _a;
|
|
1392
1408
|
const { timeout = 1e4 } = options;
|
|
1393
|
-
const
|
|
1394
|
-
|
|
1395
|
-
|
|
1409
|
+
const ctl = new AbortController();
|
|
1410
|
+
const _a = options, { signal } = _a, restOpts = __objRest(_a, ["signal"]);
|
|
1411
|
+
signal == null ? undefined : signal.addEventListener("abort", () => ctl.abort());
|
|
1412
|
+
let sigOpts = {}, id = undefined;
|
|
1396
1413
|
if (timeout >= 0) {
|
|
1397
|
-
id = setTimeout(() => abort(), timeout);
|
|
1398
|
-
|
|
1414
|
+
id = setTimeout(() => ctl.abort(), timeout);
|
|
1415
|
+
sigOpts = { signal: ctl.signal };
|
|
1399
1416
|
}
|
|
1400
1417
|
try {
|
|
1401
|
-
const res = yield fetch(input, __spreadValues(__spreadValues({},
|
|
1402
|
-
id && clearTimeout(id);
|
|
1418
|
+
const res = yield fetch(input, __spreadValues(__spreadValues({}, restOpts), sigOpts));
|
|
1419
|
+
typeof id !== "undefined" && clearTimeout(id);
|
|
1403
1420
|
return res;
|
|
1404
1421
|
} catch (err) {
|
|
1405
|
-
id && clearTimeout(id);
|
|
1406
|
-
throw err;
|
|
1422
|
+
typeof id !== "undefined" && clearTimeout(id);
|
|
1423
|
+
throw new Error("Error while calling fetch", { cause: err });
|
|
1407
1424
|
}
|
|
1408
1425
|
});
|
|
1409
1426
|
}
|
|
@@ -1419,6 +1436,9 @@ Has: ${checksum}`);
|
|
|
1419
1436
|
);
|
|
1420
1437
|
});
|
|
1421
1438
|
}
|
|
1439
|
+
function getListLength(obj, zeroOnInvalid = true) {
|
|
1440
|
+
return "length" in obj ? obj.length : "size" in obj ? obj.size : "count" in obj ? obj.count : zeroOnInvalid ? 0 : NaN;
|
|
1441
|
+
}
|
|
1422
1442
|
|
|
1423
1443
|
// lib/SelectorObserver.ts
|
|
1424
1444
|
var domLoaded = false;
|
|
@@ -1730,11 +1750,11 @@ Has: ${checksum}`);
|
|
|
1730
1750
|
}
|
|
1731
1751
|
];
|
|
1732
1752
|
var percentTransform = [
|
|
1733
|
-
|
|
1753
|
+
/%(\d+)/gm,
|
|
1734
1754
|
({ matches, trArgs, trValue }) => {
|
|
1735
1755
|
let str = String(trValue);
|
|
1736
1756
|
for (const match of matches) {
|
|
1737
|
-
const repl = match[1] !== undefined ? trArgs[
|
|
1757
|
+
const repl = match[1] !== undefined ? trArgs == null ? undefined : trArgs[Number(match[1]) - 1] : undefined;
|
|
1738
1758
|
if (typeof repl !== "undefined")
|
|
1739
1759
|
str = str.replace(match[0], String(repl));
|
|
1740
1760
|
}
|
|
@@ -1779,6 +1799,7 @@ Has: ${checksum}`);
|
|
|
1779
1799
|
exports.defaultStrings = defaultStrings;
|
|
1780
1800
|
exports.digitCount = digitCount;
|
|
1781
1801
|
exports.fetchAdvanced = fetchAdvanced;
|
|
1802
|
+
exports.getListLength = getListLength;
|
|
1782
1803
|
exports.getSiblingsFrame = getSiblingsFrame;
|
|
1783
1804
|
exports.getUnsafeWindow = getUnsafeWindow;
|
|
1784
1805
|
exports.hexToRgb = hexToRgb;
|
package/dist/index.js
CHANGED
|
@@ -1329,10 +1329,23 @@ var Dialog = class _Dialog extends NanoEmitter {
|
|
|
1329
1329
|
};
|
|
1330
1330
|
|
|
1331
1331
|
// lib/misc.ts
|
|
1332
|
-
function autoPlural(
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1332
|
+
function autoPlural(term, num, pluralType = "auto") {
|
|
1333
|
+
let n = num;
|
|
1334
|
+
if (typeof n !== "number")
|
|
1335
|
+
n = getListLength(n, false);
|
|
1336
|
+
if (!["-s", "-ies"].includes(pluralType))
|
|
1337
|
+
pluralType = "auto";
|
|
1338
|
+
if (isNaN(n))
|
|
1339
|
+
n = 2;
|
|
1340
|
+
const pType = pluralType === "auto" ? String(term).endsWith("y") ? "-ies" : "-s" : pluralType;
|
|
1341
|
+
switch (pType) {
|
|
1342
|
+
case "-s":
|
|
1343
|
+
return `${term}${n === 1 ? "" : "s"}`;
|
|
1344
|
+
case "-ies":
|
|
1345
|
+
return `${String(term).slice(0, -1)}${n === 1 ? "y" : "ies"}`;
|
|
1346
|
+
default:
|
|
1347
|
+
return String(term);
|
|
1348
|
+
}
|
|
1336
1349
|
}
|
|
1337
1350
|
function insertValues(input, ...values) {
|
|
1338
1351
|
return input.replace(/%\d/gm, (match) => {
|
|
@@ -1341,29 +1354,33 @@ function insertValues(input, ...values) {
|
|
|
1341
1354
|
return (_b = (_a = values[argIndex]) != null ? _a : match) == null ? undefined : _b.toString();
|
|
1342
1355
|
});
|
|
1343
1356
|
}
|
|
1344
|
-
function pauseFor(time) {
|
|
1345
|
-
return new Promise((res) => {
|
|
1346
|
-
setTimeout(() => res(), time);
|
|
1357
|
+
function pauseFor(time, signal, rejectOnAbort = false) {
|
|
1358
|
+
return new Promise((res, rej) => {
|
|
1359
|
+
const timeout = setTimeout(() => res(), time);
|
|
1360
|
+
signal == null ? undefined : signal.addEventListener("abort", () => {
|
|
1361
|
+
clearTimeout(timeout);
|
|
1362
|
+
rejectOnAbort ? rej(new Error("The pause was aborted")) : res();
|
|
1363
|
+
});
|
|
1347
1364
|
});
|
|
1348
1365
|
}
|
|
1349
1366
|
function fetchAdvanced(_0) {
|
|
1350
1367
|
return __async(this, arguments, function* (input, options = {}) {
|
|
1351
|
-
var _a;
|
|
1352
1368
|
const { timeout = 1e4 } = options;
|
|
1353
|
-
const
|
|
1354
|
-
|
|
1355
|
-
|
|
1369
|
+
const ctl = new AbortController();
|
|
1370
|
+
const _a = options, { signal } = _a, restOpts = __objRest(_a, ["signal"]);
|
|
1371
|
+
signal == null ? undefined : signal.addEventListener("abort", () => ctl.abort());
|
|
1372
|
+
let sigOpts = {}, id = undefined;
|
|
1356
1373
|
if (timeout >= 0) {
|
|
1357
|
-
id = setTimeout(() => abort(), timeout);
|
|
1358
|
-
|
|
1374
|
+
id = setTimeout(() => ctl.abort(), timeout);
|
|
1375
|
+
sigOpts = { signal: ctl.signal };
|
|
1359
1376
|
}
|
|
1360
1377
|
try {
|
|
1361
|
-
const res = yield fetch(input, __spreadValues(__spreadValues({},
|
|
1362
|
-
id && clearTimeout(id);
|
|
1378
|
+
const res = yield fetch(input, __spreadValues(__spreadValues({}, restOpts), sigOpts));
|
|
1379
|
+
typeof id !== "undefined" && clearTimeout(id);
|
|
1363
1380
|
return res;
|
|
1364
1381
|
} catch (err) {
|
|
1365
|
-
id && clearTimeout(id);
|
|
1366
|
-
throw err;
|
|
1382
|
+
typeof id !== "undefined" && clearTimeout(id);
|
|
1383
|
+
throw new Error("Error while calling fetch", { cause: err });
|
|
1367
1384
|
}
|
|
1368
1385
|
});
|
|
1369
1386
|
}
|
|
@@ -1379,6 +1396,9 @@ function consumeStringGen(strGen) {
|
|
|
1379
1396
|
);
|
|
1380
1397
|
});
|
|
1381
1398
|
}
|
|
1399
|
+
function getListLength(obj, zeroOnInvalid = true) {
|
|
1400
|
+
return "length" in obj ? obj.length : "size" in obj ? obj.size : "count" in obj ? obj.count : zeroOnInvalid ? 0 : NaN;
|
|
1401
|
+
}
|
|
1382
1402
|
|
|
1383
1403
|
// lib/SelectorObserver.ts
|
|
1384
1404
|
var domLoaded = false;
|
|
@@ -1690,11 +1710,11 @@ var templateLiteralTransform = [
|
|
|
1690
1710
|
}
|
|
1691
1711
|
];
|
|
1692
1712
|
var percentTransform = [
|
|
1693
|
-
|
|
1713
|
+
/%(\d+)/gm,
|
|
1694
1714
|
({ matches, trArgs, trValue }) => {
|
|
1695
1715
|
let str = String(trValue);
|
|
1696
1716
|
for (const match of matches) {
|
|
1697
|
-
const repl = match[1] !== undefined ? trArgs[
|
|
1717
|
+
const repl = match[1] !== undefined ? trArgs == null ? undefined : trArgs[Number(match[1]) - 1] : undefined;
|
|
1698
1718
|
if (typeof repl !== "undefined")
|
|
1699
1719
|
str = str.replace(match[0], String(repl));
|
|
1700
1720
|
}
|
|
@@ -1718,4 +1738,4 @@ var tr = {
|
|
|
1718
1738
|
}
|
|
1719
1739
|
};
|
|
1720
1740
|
|
|
1721
|
-
export { DataStore, DataStoreSerializer, Debouncer, Dialog, NanoEmitter, SelectorObserver, addGlobalStyle, addParent, autoPlural, clamp, compress, computeHash, consumeGen, consumeStringGen, currentDialogId, darkenColor, debounce, decompress, defaultDialogCss, defaultStrings, digitCount, fetchAdvanced, getSiblingsFrame, getUnsafeWindow, hexToRgb, insertValues, interceptEvent, interceptWindowEvent, isScrollable, lightenColor, mapRange, observeElementProp, openDialogs, openInNewTab, pauseFor, preloadImages, randRange, randomId, randomItem, randomItemIndex, randomizeArray, rgbToHex, setInnerHtmlUnsafe, takeRandomItem, tr };
|
|
1741
|
+
export { DataStore, DataStoreSerializer, Debouncer, Dialog, NanoEmitter, SelectorObserver, addGlobalStyle, addParent, autoPlural, clamp, compress, computeHash, consumeGen, consumeStringGen, currentDialogId, darkenColor, debounce, decompress, defaultDialogCss, defaultStrings, digitCount, fetchAdvanced, getListLength, getSiblingsFrame, getUnsafeWindow, hexToRgb, insertValues, interceptEvent, interceptWindowEvent, isScrollable, lightenColor, mapRange, observeElementProp, openDialogs, openInNewTab, pauseFor, preloadImages, randRange, randomId, randomItem, randomItemIndex, randomizeArray, rgbToHex, setInnerHtmlUnsafe, takeRandomItem, tr };
|
package/dist/lib/misc.d.ts
CHANGED
|
@@ -2,13 +2,18 @@
|
|
|
2
2
|
* @module lib/misc
|
|
3
3
|
* This module contains miscellaneous functions that don't fit in another category - [see the documentation for more info](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#misc)
|
|
4
4
|
*/
|
|
5
|
-
import type { Prettify, Stringifiable } from "./types.js";
|
|
5
|
+
import type { ListWithLength, Prettify, Stringifiable } from "./types.js";
|
|
6
|
+
/** Which plural form to use when auto-pluralizing */
|
|
7
|
+
export type PluralType = "auto" | "-s" | "-ies";
|
|
6
8
|
/**
|
|
7
|
-
* Automatically
|
|
8
|
-
*
|
|
9
|
-
* @
|
|
9
|
+
* Automatically pluralizes the given string by adding an `-s` or `-ies` to the passed {@linkcode term}, if {@linkcode num} is not equal to 1.
|
|
10
|
+
* By default, words ending in `-y` will have it replaced with `-ies`, and all other words will simply have `-s` appended.
|
|
11
|
+
* {@linkcode pluralType} will default to `auto` if invalid and {@linkcode num} is set to 2 if it resolves to `NaN`.
|
|
12
|
+
* @param term The term, written in singular form, to auto-convert to plural form
|
|
13
|
+
* @param num A number, or list-like value that has either a `length`, `count` or `size` property, like an array, Map or NodeList - does not support iterables, they need to be converted to an array first
|
|
14
|
+
* @param pluralType Which plural form to use when auto-pluralizing. Defaults to `"auto"`, which removes the last char and uses `-ies` for words ending in `y` and simply appends `-s` for all other words
|
|
10
15
|
*/
|
|
11
|
-
export declare function autoPlural(
|
|
16
|
+
export declare function autoPlural(term: Stringifiable, num: number | ListWithLength, pluralType?: PluralType): string;
|
|
12
17
|
/**
|
|
13
18
|
* Inserts the passed values into a string at the respective placeholders.
|
|
14
19
|
* The placeholder format is `%n`, where `n` is the 1-indexed argument number.
|
|
@@ -16,8 +21,12 @@ export declare function autoPlural(word: Stringifiable, num: number | unknown[]
|
|
|
16
21
|
* @param values The values to insert, in order, starting at `%1`
|
|
17
22
|
*/
|
|
18
23
|
export declare function insertValues(input: string, ...values: Stringifiable[]): string;
|
|
19
|
-
/**
|
|
20
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Pauses async execution for the specified time in ms.
|
|
26
|
+
* If an `AbortSignal` is passed, the pause will be aborted when the signal is triggered.
|
|
27
|
+
* By default, this will resolve the promise, but you can set {@linkcode rejectOnAbort} to true to reject it instead.
|
|
28
|
+
*/
|
|
29
|
+
export declare function pauseFor(time: number, signal?: AbortSignal, rejectOnAbort?: boolean): Promise<void>;
|
|
21
30
|
/** Options for the `fetchAdvanced()` function */
|
|
22
31
|
export type FetchAdvancedOpts = Prettify<Partial<{
|
|
23
32
|
/** Timeout in milliseconds after which the fetch call will be canceled with an AbortController signal */
|
|
@@ -46,3 +55,9 @@ export type StringGen = ValueGen<Stringifiable>;
|
|
|
46
55
|
* @template TStrUnion The union of strings that the StringGen should yield - this allows for finer type control compared to {@linkcode consumeGen()}
|
|
47
56
|
*/
|
|
48
57
|
export declare function consumeStringGen<TStrUnion extends string>(strGen: StringGen): Promise<TStrUnion>;
|
|
58
|
+
/**
|
|
59
|
+
* Returns the length of the given list-like object (anything with a numeric `length`, `size` or `count` property, like an array, Map or NodeList).
|
|
60
|
+
* If the object doesn't have any of these properties, it will return 0 by default.
|
|
61
|
+
* Set {@linkcode zeroOnInvalid} to false to return NaN instead of 0 if the object doesn't have any of the properties.
|
|
62
|
+
*/
|
|
63
|
+
export declare function getListLength(obj: ListWithLength, zeroOnInvalid?: boolean): number;
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -28,3 +28,11 @@ export type NonEmptyString<TString extends string> = TString extends "" ? never
|
|
|
28
28
|
export type Prettify<T> = {
|
|
29
29
|
[K in keyof T]: T[K];
|
|
30
30
|
} & {};
|
|
31
|
+
/** Any value that is list-like, i.e. has a numeric length, count or size property */
|
|
32
|
+
export type ListWithLength = {
|
|
33
|
+
length: number;
|
|
34
|
+
} | {
|
|
35
|
+
count: number;
|
|
36
|
+
} | {
|
|
37
|
+
size: number;
|
|
38
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sv443-network/userutils",
|
|
3
3
|
"libName": "UserUtils",
|
|
4
|
-
"version": "9.0
|
|
4
|
+
"version": "9.1.0",
|
|
5
5
|
"description": "Lightweight library with various utilities for userscripts - register listeners for when CSS selectors exist, intercept events, create persistent & synchronous data stores, modify the DOM more easily and much more",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|