@sv443-network/userutils 8.3.1 → 8.3.3
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 +12 -0
- package/README.md +83 -24
- package/dist/index.cjs +1521 -0
- package/dist/index.global.js +1 -1
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -5,9 +5,19 @@
|
|
|
5
5
|
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 more.
|
|
6
6
|
|
|
7
7
|
Contains builtin TypeScript declarations. Supports ESM and CJS imports via a bundler and global declaration via `@require`
|
|
8
|
+
|
|
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.
|
|
8
10
|
If you like using this library, please consider [supporting the development ❤️](https://github.com/sponsors/Sv443)
|
|
9
11
|
|
|
10
12
|
<br>
|
|
13
|
+
|
|
14
|
+
[](https://bundlephobia.com/package/@sv443-network/userutils)
|
|
15
|
+
[](https://bundlephobia.com/package/@sv443-network/userutils)
|
|
16
|
+
[](https://bundlephobia.com/package/@sv443-network/userutils)
|
|
17
|
+
|
|
18
|
+
[](https://github.com/Sv443-Network/UserUtils/stargazers)
|
|
19
|
+
[](https://dc.sv443.net/)
|
|
20
|
+
|
|
11
21
|
<sup>
|
|
12
22
|
View the documentation of previous major releases:
|
|
13
23
|
</sup>
|
|
@@ -86,12 +96,16 @@ View the documentation of previous major releases:
|
|
|
86
96
|
## Installation:
|
|
87
97
|
Shameless plug: I made a [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.
|
|
88
98
|
|
|
89
|
-
- If you are using a bundler (like webpack, rollup, vite, etc.), you can install this package
|
|
99
|
+
- If you are using a bundler (like webpack, rollup, vite, etc.), you can install this package in one of the following ways:
|
|
90
100
|
```
|
|
91
101
|
npm i @sv443-network/userutils
|
|
102
|
+
pnpm i @sv443-network/userutils
|
|
103
|
+
yarn add @sv443-network/userutils
|
|
104
|
+
npx jsr install @sv443-network/userutils
|
|
105
|
+
deno add jsr:@sv443-network/userutils
|
|
92
106
|
```
|
|
93
|
-
|
|
94
|
-
|
|
107
|
+
Then import it in your script as usual:
|
|
108
|
+
|
|
95
109
|
```ts
|
|
96
110
|
import { addGlobalStyle } from "@sv443-network/userutils";
|
|
97
111
|
|
|
@@ -102,16 +116,26 @@ Shameless plug: I made a [template for userscripts in TypeScript](https://github
|
|
|
102
116
|
|
|
103
117
|
<br>
|
|
104
118
|
|
|
105
|
-
- If you are not using a bundler
|
|
119
|
+
- If you are not using a bundler, want to reduce the size of your userscript, 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:
|
|
120
|
+
|
|
121
|
+
Versioned (recommended):
|
|
106
122
|
```
|
|
107
|
-
// @require https://
|
|
123
|
+
// @require https://cdn.jsdelivr.net/npm/@sv443-network/userutils@INSERT_VERSION/dist/index.global.js
|
|
124
|
+
// @require https://unpkg.com/@sv443-network/userutils@INSERT_VERSION/dist/index.global.js
|
|
108
125
|
```
|
|
126
|
+
Non-versioned (not recommended because auto-updating):
|
|
109
127
|
```
|
|
128
|
+
// @require https://update.greasyfork.org/scripts/472956/UserUtils.js
|
|
110
129
|
// @require https://openuserjs.org/src/libs/Sv443/UserUtils.js
|
|
111
130
|
```
|
|
112
|
-
(in order for your userscript not to break on a major library update, instead use the versioned URL at the top of the [GreasyFork page](https://greasyfork.org/scripts/472956-userutils))
|
|
113
131
|
|
|
114
|
-
|
|
132
|
+
> [!NOTE]
|
|
133
|
+
> 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)
|
|
134
|
+
|
|
135
|
+
<br>
|
|
136
|
+
|
|
137
|
+
- Then, access the functions on the global variable `UserUtils`:
|
|
138
|
+
|
|
115
139
|
```ts
|
|
116
140
|
UserUtils.addGlobalStyle("body { background-color: red; }");
|
|
117
141
|
|
|
@@ -120,10 +144,27 @@ Shameless plug: I made a [template for userscripts in TypeScript](https://github
|
|
|
120
144
|
const { clamp } = UserUtils;
|
|
121
145
|
console.log(clamp(1, 5, 10)); // 5
|
|
122
146
|
```
|
|
123
|
-
|
|
147
|
+
|
|
148
|
+
<br>
|
|
149
|
+
|
|
150
|
+
- 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 a `.d.ts` file somewhere in the directory (or a subdirectory) defined in your `tsconfig.json`'s `baseUrl` option or `include` array:
|
|
151
|
+
|
|
124
152
|
```ts
|
|
153
|
+
declare const UserUtils: typeof import("@sv443-network/userutils");
|
|
154
|
+
|
|
125
155
|
declare global {
|
|
126
|
-
|
|
156
|
+
interface Window {
|
|
157
|
+
UserUtils: typeof UserUtils;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
<br>
|
|
163
|
+
|
|
164
|
+
- If you're using a linter like ESLint, it might complain about the global variable `UserUtils` not being defined. To fix this, add the following to your ESLint configuration file:
|
|
165
|
+
```json
|
|
166
|
+
"globals": {
|
|
167
|
+
"UserUtils": "readonly"
|
|
127
168
|
}
|
|
128
169
|
```
|
|
129
170
|
|
|
@@ -137,8 +178,11 @@ Each feature has example code that can be expanded by clicking on the text "Exam
|
|
|
137
178
|
The usages and examples are written in TypeScript and use ESM import syntax, but the library can also be used in plain JavaScript after removing the type annotations (and changing the imports if you are using CommonJS or the global declaration).
|
|
138
179
|
If the usage section contains multiple usages of the function, each occurrence represents an overload and you can choose which one you want to use.
|
|
139
180
|
|
|
140
|
-
Some features require the `@run-at` or `@grant` directives to be tweaked in the userscript header or have other requirements.
|
|
141
|
-
|
|
181
|
+
Some features require the `@run-at` or `@grant` directives to be tweaked in the userscript header or have other specific requirements and limitations.
|
|
182
|
+
Those will be listed in a section marked by a warning emoji (⚠️) each.
|
|
183
|
+
|
|
184
|
+
If you need help with something, please [create a new discussion](https://github.com/Sv443-Network/UserUtils/discussions) or [join my Discord server.](https://dc.sv443.net/)
|
|
185
|
+
For submitting bug reports or feature requests, please use the [GitHub issue tracker.](https://github.com/Sv443-Network/UserUtils/issues)
|
|
142
186
|
|
|
143
187
|
<br><br>
|
|
144
188
|
|
|
@@ -2167,8 +2211,8 @@ tr.addLanguage("de", {
|
|
|
2167
2211
|
// the language is set to "en"
|
|
2168
2212
|
tr.setLanguage("en");
|
|
2169
2213
|
|
|
2170
|
-
console.log(tr("welcome_name", "John")); // "Welcome"
|
|
2171
|
-
//
|
|
2214
|
+
console.log(tr("welcome_name", "John")); // "Welcome, John"
|
|
2215
|
+
// no need to call tr.setLanguage():
|
|
2172
2216
|
console.log(tr.forLang("de", "welcome_name", "John")); // "Willkommen, John"
|
|
2173
2217
|
```
|
|
2174
2218
|
</details>
|
|
@@ -2181,9 +2225,9 @@ Usage:
|
|
|
2181
2225
|
tr.addLanguage(language: string, translations: Record<string, string>): void
|
|
2182
2226
|
```
|
|
2183
2227
|
|
|
2184
|
-
Adds a language and its associated translations to the translation function.
|
|
2185
|
-
The passed language can be any unique identifier, though I recommend sticking to the [ISO 639-1
|
|
2186
|
-
The passed translations should be
|
|
2228
|
+
Adds or overwrites a language and its associated translations to the translation function.
|
|
2229
|
+
The passed language can be any unique identifier, though I highly recommend sticking to a standard like [BCP 47 / RFC 5646](https://www.rfc-editor.org/rfc/rfc5646.txt) (which is used by the [`Intl` namespace](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl) and methods like [`Number.toLocaleString()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString)), or [ISO 639-1.](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)
|
|
2230
|
+
The passed translations should be a flat object (no nested objects are allowed for now), where the key is the translation key used in `tr()` and the value is the translation itself.
|
|
2187
2231
|
If `tr.addLanguage()` is called multiple times with the same language, the previous translations of that language will be overwritten.
|
|
2188
2232
|
|
|
2189
2233
|
The translation values may contain placeholders in the format `%n`, where `n` is the number of the value starting at 1.
|
|
@@ -2213,10 +2257,13 @@ tr.addLanguage("en", {
|
|
|
2213
2257
|
// can be used for different locales too:
|
|
2214
2258
|
|
|
2215
2259
|
tr.addLanguage("en-US", {
|
|
2216
|
-
"fries": "
|
|
2260
|
+
"fries": "fries",
|
|
2261
|
+
"color": "color",
|
|
2217
2262
|
});
|
|
2263
|
+
|
|
2218
2264
|
tr.addLanguage("en-GB", {
|
|
2219
2265
|
"fries": "chips",
|
|
2266
|
+
"color": "colour",
|
|
2220
2267
|
});
|
|
2221
2268
|
|
|
2222
2269
|
|
|
@@ -2226,15 +2273,18 @@ const translation_de = {
|
|
|
2226
2273
|
"greeting": "Guten Tag!",
|
|
2227
2274
|
"foo": "Foo",
|
|
2228
2275
|
};
|
|
2276
|
+
|
|
2229
2277
|
tr.addLanguage("de-DE", translation_de);
|
|
2278
|
+
|
|
2230
2279
|
tr.addLanguage("de-CH", {
|
|
2280
|
+
// overwrite the "greeting" but keep other keys as they are:
|
|
2231
2281
|
...translation_de,
|
|
2232
|
-
// overwrite the "greeting" but keep other keys as they are
|
|
2233
2282
|
"greeting": "Grüezi!",
|
|
2234
2283
|
});
|
|
2284
|
+
|
|
2235
2285
|
tr.addLanguage("de-AT", {
|
|
2286
|
+
// overwrite "greeting" again but keep other keys as they are:
|
|
2236
2287
|
...translation_de,
|
|
2237
|
-
// overwrite "greeting" again but keep other keys as they are
|
|
2238
2288
|
"greeting": "Grüß Gott!",
|
|
2239
2289
|
});
|
|
2240
2290
|
|
|
@@ -2247,17 +2297,23 @@ tr.addLanguage("en", {
|
|
|
2247
2297
|
"cart_items_added-n": "Added %1 items to the cart",
|
|
2248
2298
|
});
|
|
2249
2299
|
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2300
|
+
type Numberish = number | Array<unknown> | NodeList | { length: number } | { size: number };
|
|
2301
|
+
|
|
2302
|
+
/** Returns the translation key with a custom pluralization identifier added to it for the given number of items (or size of Array/NodeList or anything else with a `length` or `size` property) */
|
|
2303
|
+
function pl(key: string, num: Numberish): string {
|
|
2304
|
+
if(typeof num !== "number") {
|
|
2305
|
+
if("length" in num)
|
|
2306
|
+
num = num.length;
|
|
2307
|
+
else if("size" in num)
|
|
2308
|
+
num = num.size;
|
|
2309
|
+
}
|
|
2254
2310
|
|
|
2255
2311
|
if(num === 0)
|
|
2256
2312
|
return `${key}-0`;
|
|
2257
2313
|
else if(num === 1)
|
|
2258
2314
|
return `${key}-1`;
|
|
2259
2315
|
else
|
|
2260
|
-
return `${key}-n`;
|
|
2316
|
+
return `${key}-n`; // will also be the fallback for non-numeric values
|
|
2261
2317
|
};
|
|
2262
2318
|
|
|
2263
2319
|
const items = [];
|
|
@@ -2268,6 +2324,9 @@ console.log(tr(pl("cart_items_added", items), items.length)); // "Added 1 item t
|
|
|
2268
2324
|
|
|
2269
2325
|
items.push("bar");
|
|
2270
2326
|
console.log(tr(pl("cart_items_added", items), items.length)); // "Added 2 items to the cart"
|
|
2327
|
+
|
|
2328
|
+
// you will need to catch cases like this manually or in your own implementation of `pl()`:
|
|
2329
|
+
console.log(tr(pl("cart_items_added", NaN), NaN)); // "Added NaN items to the cart"
|
|
2271
2330
|
```
|
|
2272
2331
|
</details>
|
|
2273
2332
|
|