@sv443-network/userutils 7.2.1 → 7.3.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 +13 -0
- package/README.md +67 -1
- package/dist/index.global.js +64 -4
- package/dist/index.js +60 -4
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/translation.d.ts +4 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @sv443-network/userutils
|
|
2
2
|
|
|
3
|
+
## 7.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 7e8e147: - Added `tr.forLang()` to get the translation for a specified language code
|
|
8
|
+
- Added `tr.getTranslations()` to return the translations object for the given or currently active language
|
|
9
|
+
|
|
10
|
+
## 7.2.2
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- a171b0d: Fix color functions not being exported 🥴
|
|
15
|
+
|
|
3
16
|
## 7.2.1
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
## UserUtils
|
|
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
|
-
Contains builtin TypeScript declarations. Supports ESM and CJS imports via a bundler and
|
|
7
|
+
Contains builtin TypeScript declarations. Supports ESM and CJS imports via a bundler and global declaration via `@require`
|
|
8
8
|
If you like using this library, please consider [supporting the development ❤️](https://github.com/sponsors/Sv443)
|
|
9
9
|
|
|
10
10
|
<br>
|
|
@@ -63,9 +63,11 @@ View the documentation of previous major releases:
|
|
|
63
63
|
- [`randomizeArray()`](#randomizearray) - returns a copy of the array with its items in a random order
|
|
64
64
|
- [**Translation:**](#translation)
|
|
65
65
|
- [`tr()`](#tr) - simple translation of a string to another language
|
|
66
|
+
- [`tr.forLang()`](#trforlang) - specify a language besides the currently set one for the translation
|
|
66
67
|
- [`tr.addLanguage()`](#traddlanguage) - add a language and its translations
|
|
67
68
|
- [`tr.setLanguage()`](#trsetlanguage) - set the currently active language for translations
|
|
68
69
|
- [`tr.getLanguage()`](#trgetlanguage) - returns the currently active language
|
|
70
|
+
- [`tr.getTranslations()`](#trgettranslations) - returns the translations for the given language or the currently active one
|
|
69
71
|
- [**Colors:**](#colors)
|
|
70
72
|
- [`hexToRgb()`](#hextorgb) - convert a hex color string to an RGB number tuple
|
|
71
73
|
- [`rgbToHex()`](#rgbtohex) - convert RGB numbers to a hex color string
|
|
@@ -1960,6 +1962,39 @@ console.log(tr("welcome_name", "John")); // "Willkommen, John"
|
|
|
1960
1962
|
|
|
1961
1963
|
<br>
|
|
1962
1964
|
|
|
1965
|
+
### tr.forLang()
|
|
1966
|
+
Usage:
|
|
1967
|
+
```ts
|
|
1968
|
+
tr.forLang(language: string, key: string, ...values: Stringifiable[]): string
|
|
1969
|
+
```
|
|
1970
|
+
|
|
1971
|
+
Returns the translation of the passed key in the specified language. Otherwise behaves exactly like [`tr()`](#tr)
|
|
1972
|
+
This function does not change the currently active language set by [`tr.setLanguage()`](#trsetlanguage)
|
|
1973
|
+
|
|
1974
|
+
<details><summary><b>Example - click to view</b></summary>
|
|
1975
|
+
|
|
1976
|
+
```ts
|
|
1977
|
+
import { tr } from "@sv443-network/userutils";
|
|
1978
|
+
|
|
1979
|
+
tr.addLanguage("en", {
|
|
1980
|
+
"welcome_name": "Welcome, %1",
|
|
1981
|
+
});
|
|
1982
|
+
|
|
1983
|
+
tr.addLanguage("de", {
|
|
1984
|
+
"welcome_name": "Willkommen, %1",
|
|
1985
|
+
});
|
|
1986
|
+
|
|
1987
|
+
// the language is set to "en"
|
|
1988
|
+
tr.setLanguage("en");
|
|
1989
|
+
|
|
1990
|
+
console.log(tr("welcome_name", "John")); // "Welcome"
|
|
1991
|
+
// the language doesn't need to be changed:
|
|
1992
|
+
console.log(tr.forLang("de", "welcome_name", "John")); // "Willkommen, John"
|
|
1993
|
+
```
|
|
1994
|
+
</details>
|
|
1995
|
+
|
|
1996
|
+
<br>
|
|
1997
|
+
|
|
1963
1998
|
### tr.addLanguage()
|
|
1964
1999
|
Usage:
|
|
1965
2000
|
```ts
|
|
@@ -2080,6 +2115,37 @@ tr.getLanguage(): string | undefined
|
|
|
2080
2115
|
Returns the currently active language set by [`tr.setLanguage()`](#trsetlanguage)
|
|
2081
2116
|
If no language has been set yet, it will return undefined.
|
|
2082
2117
|
|
|
2118
|
+
<br>
|
|
2119
|
+
|
|
2120
|
+
### tr.getTranslations()
|
|
2121
|
+
Usage:
|
|
2122
|
+
```ts
|
|
2123
|
+
tr.getTranslations(language?: string): Record<string, string> | undefined
|
|
2124
|
+
```
|
|
2125
|
+
|
|
2126
|
+
Returns the translations of the specified language.
|
|
2127
|
+
If no language is specified, it will return the translations of the currently active language set by [`tr.setLanguage()`](#trsetlanguage)
|
|
2128
|
+
If no translations are found, it will return undefined.
|
|
2129
|
+
|
|
2130
|
+
<details><summary><b>Example - click to view</b></summary>
|
|
2131
|
+
|
|
2132
|
+
```ts
|
|
2133
|
+
import { tr } from "@sv443-network/userutils";
|
|
2134
|
+
|
|
2135
|
+
tr.addLanguage("en", {
|
|
2136
|
+
"welcome": "Welcome",
|
|
2137
|
+
});
|
|
2138
|
+
|
|
2139
|
+
console.log(tr.getTranslations()); // undefined
|
|
2140
|
+
tr.setLanguage("en");
|
|
2141
|
+
console.log(tr.getTranslations()); // { "welcome": "Welcome" }
|
|
2142
|
+
|
|
2143
|
+
console.log(tr.getTranslations("en")); // { "welcome": "Welcome" }
|
|
2144
|
+
|
|
2145
|
+
console.log(tr.getTranslations("de")); // undefined
|
|
2146
|
+
```
|
|
2147
|
+
</details>
|
|
2148
|
+
|
|
2083
2149
|
<br><br>
|
|
2084
2150
|
|
|
2085
2151
|
## Colors:
|
package/dist/index.global.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// ==UserLibrary==
|
|
9
9
|
// @name UserUtils
|
|
10
10
|
// @description 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
|
|
11
|
-
// @version 7.
|
|
11
|
+
// @version 7.3.0
|
|
12
12
|
// @license MIT
|
|
13
13
|
// @copyright Sv443 (https://github.com/Sv443)
|
|
14
14
|
|
|
@@ -128,6 +128,55 @@ var UserUtils = (function (exports) {
|
|
|
128
128
|
return retArray;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
// lib/colors.ts
|
|
132
|
+
function hexToRgb(hex) {
|
|
133
|
+
hex = hex.trim();
|
|
134
|
+
const bigint = parseInt(hex.startsWith("#") ? hex.slice(1) : hex, 16);
|
|
135
|
+
const r = bigint >> 16 & 255;
|
|
136
|
+
const g = bigint >> 8 & 255;
|
|
137
|
+
const b = bigint & 255;
|
|
138
|
+
return [clamp(r, 0, 255), clamp(g, 0, 255), clamp(b, 0, 255)];
|
|
139
|
+
}
|
|
140
|
+
function rgbToHex(red, green, blue, withHash = true, upperCase = false) {
|
|
141
|
+
const toHexVal = (n) => clamp(Math.round(n), 0, 255).toString(16).padStart(2, "0")[upperCase ? "toUpperCase" : "toLowerCase"]();
|
|
142
|
+
return `${withHash ? "#" : ""}${toHexVal(red)}${toHexVal(green)}${toHexVal(blue)}`;
|
|
143
|
+
}
|
|
144
|
+
function lightenColor(color, percent) {
|
|
145
|
+
return darkenColor(color, percent * -1);
|
|
146
|
+
}
|
|
147
|
+
function darkenColor(color, percent) {
|
|
148
|
+
var _a;
|
|
149
|
+
color = color.trim();
|
|
150
|
+
const darkenRgb = (r2, g2, b2, percent2) => {
|
|
151
|
+
r2 = Math.max(0, Math.min(255, r2 - r2 * percent2 / 100));
|
|
152
|
+
g2 = Math.max(0, Math.min(255, g2 - g2 * percent2 / 100));
|
|
153
|
+
b2 = Math.max(0, Math.min(255, b2 - b2 * percent2 / 100));
|
|
154
|
+
return [r2, g2, b2];
|
|
155
|
+
};
|
|
156
|
+
let r, g, b, a;
|
|
157
|
+
const isHexCol = color.match(/^#?([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/);
|
|
158
|
+
if (isHexCol)
|
|
159
|
+
[r, g, b] = hexToRgb(color);
|
|
160
|
+
else if (color.startsWith("rgb")) {
|
|
161
|
+
const rgbValues = (_a = color.match(/\d+(\.\d+)?/g)) == null ? void 0 : _a.map(Number);
|
|
162
|
+
if (rgbValues)
|
|
163
|
+
[r, g, b, a] = rgbValues;
|
|
164
|
+
else
|
|
165
|
+
throw new Error("Invalid RGB/RGBA color format");
|
|
166
|
+
} else
|
|
167
|
+
throw new Error("Unsupported color format");
|
|
168
|
+
[r, g, b] = darkenRgb(r, g, b, percent);
|
|
169
|
+
const upperCase = color.match(/[A-F]/) !== null;
|
|
170
|
+
if (isHexCol)
|
|
171
|
+
return rgbToHex(r, g, b, color.startsWith("#"), upperCase);
|
|
172
|
+
else if (color.startsWith("rgba"))
|
|
173
|
+
return `rgba(${r}, ${g}, ${b}, ${a})`;
|
|
174
|
+
else if (color.startsWith("rgb"))
|
|
175
|
+
return `rgb(${r}, ${g}, ${b})`;
|
|
176
|
+
else
|
|
177
|
+
throw new Error("Unsupported color format");
|
|
178
|
+
}
|
|
179
|
+
|
|
131
180
|
// lib/dom.ts
|
|
132
181
|
function getUnsafeWindow() {
|
|
133
182
|
try {
|
|
@@ -1343,18 +1392,22 @@ Has: ${checksum}`);
|
|
|
1343
1392
|
// lib/translation.ts
|
|
1344
1393
|
var trans = {};
|
|
1345
1394
|
var curLang;
|
|
1346
|
-
|
|
1395
|
+
var trLang = (language, key, ...args) => {
|
|
1347
1396
|
var _a;
|
|
1348
|
-
if (!
|
|
1397
|
+
if (!language)
|
|
1349
1398
|
return key;
|
|
1350
|
-
const trText = (_a = trans[
|
|
1399
|
+
const trText = (_a = trans[language]) == null ? void 0 : _a[key];
|
|
1351
1400
|
if (!trText)
|
|
1352
1401
|
return key;
|
|
1353
1402
|
if (args.length > 0 && trText.match(/%\d/)) {
|
|
1354
1403
|
return insertValues(trText, ...args);
|
|
1355
1404
|
}
|
|
1356
1405
|
return trText;
|
|
1406
|
+
};
|
|
1407
|
+
function tr(key, ...args) {
|
|
1408
|
+
return trLang(curLang, key, ...args);
|
|
1357
1409
|
}
|
|
1410
|
+
tr.forLang = trLang;
|
|
1358
1411
|
tr.addLanguage = (language, translations) => {
|
|
1359
1412
|
trans[language] = translations;
|
|
1360
1413
|
};
|
|
@@ -1364,6 +1417,9 @@ Has: ${checksum}`);
|
|
|
1364
1417
|
tr.getLanguage = () => {
|
|
1365
1418
|
return curLang;
|
|
1366
1419
|
};
|
|
1420
|
+
tr.getTranslations = (language) => {
|
|
1421
|
+
return trans[language != null ? language : curLang];
|
|
1422
|
+
};
|
|
1367
1423
|
|
|
1368
1424
|
exports.DataStore = DataStore;
|
|
1369
1425
|
exports.DataStoreSerializer = DataStoreSerializer;
|
|
@@ -1376,6 +1432,7 @@ Has: ${checksum}`);
|
|
|
1376
1432
|
exports.clamp = clamp;
|
|
1377
1433
|
exports.compress = compress;
|
|
1378
1434
|
exports.computeHash = computeHash;
|
|
1435
|
+
exports.darkenColor = darkenColor;
|
|
1379
1436
|
exports.debounce = debounce;
|
|
1380
1437
|
exports.decompress = decompress;
|
|
1381
1438
|
exports.defaultDialogCss = defaultDialogCss;
|
|
@@ -1383,10 +1440,12 @@ Has: ${checksum}`);
|
|
|
1383
1440
|
exports.fetchAdvanced = fetchAdvanced;
|
|
1384
1441
|
exports.getSiblingsFrame = getSiblingsFrame;
|
|
1385
1442
|
exports.getUnsafeWindow = getUnsafeWindow;
|
|
1443
|
+
exports.hexToRgb = hexToRgb;
|
|
1386
1444
|
exports.insertValues = insertValues;
|
|
1387
1445
|
exports.interceptEvent = interceptEvent;
|
|
1388
1446
|
exports.interceptWindowEvent = interceptWindowEvent;
|
|
1389
1447
|
exports.isScrollable = isScrollable;
|
|
1448
|
+
exports.lightenColor = lightenColor;
|
|
1390
1449
|
exports.mapRange = mapRange;
|
|
1391
1450
|
exports.observeElementProp = observeElementProp;
|
|
1392
1451
|
exports.openDialogs = openDialogs;
|
|
@@ -1398,6 +1457,7 @@ Has: ${checksum}`);
|
|
|
1398
1457
|
exports.randomItem = randomItem;
|
|
1399
1458
|
exports.randomItemIndex = randomItemIndex;
|
|
1400
1459
|
exports.randomizeArray = randomizeArray;
|
|
1460
|
+
exports.rgbToHex = rgbToHex;
|
|
1401
1461
|
exports.setInnerHtmlUnsafe = setInnerHtmlUnsafe;
|
|
1402
1462
|
exports.takeRandomItem = takeRandomItem;
|
|
1403
1463
|
exports.tr = tr;
|
package/dist/index.js
CHANGED
|
@@ -108,6 +108,55 @@ function randomizeArray(array) {
|
|
|
108
108
|
return retArray;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
// lib/colors.ts
|
|
112
|
+
function hexToRgb(hex) {
|
|
113
|
+
hex = hex.trim();
|
|
114
|
+
const bigint = parseInt(hex.startsWith("#") ? hex.slice(1) : hex, 16);
|
|
115
|
+
const r = bigint >> 16 & 255;
|
|
116
|
+
const g = bigint >> 8 & 255;
|
|
117
|
+
const b = bigint & 255;
|
|
118
|
+
return [clamp(r, 0, 255), clamp(g, 0, 255), clamp(b, 0, 255)];
|
|
119
|
+
}
|
|
120
|
+
function rgbToHex(red, green, blue, withHash = true, upperCase = false) {
|
|
121
|
+
const toHexVal = (n) => clamp(Math.round(n), 0, 255).toString(16).padStart(2, "0")[upperCase ? "toUpperCase" : "toLowerCase"]();
|
|
122
|
+
return `${withHash ? "#" : ""}${toHexVal(red)}${toHexVal(green)}${toHexVal(blue)}`;
|
|
123
|
+
}
|
|
124
|
+
function lightenColor(color, percent) {
|
|
125
|
+
return darkenColor(color, percent * -1);
|
|
126
|
+
}
|
|
127
|
+
function darkenColor(color, percent) {
|
|
128
|
+
var _a;
|
|
129
|
+
color = color.trim();
|
|
130
|
+
const darkenRgb = (r2, g2, b2, percent2) => {
|
|
131
|
+
r2 = Math.max(0, Math.min(255, r2 - r2 * percent2 / 100));
|
|
132
|
+
g2 = Math.max(0, Math.min(255, g2 - g2 * percent2 / 100));
|
|
133
|
+
b2 = Math.max(0, Math.min(255, b2 - b2 * percent2 / 100));
|
|
134
|
+
return [r2, g2, b2];
|
|
135
|
+
};
|
|
136
|
+
let r, g, b, a;
|
|
137
|
+
const isHexCol = color.match(/^#?([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/);
|
|
138
|
+
if (isHexCol)
|
|
139
|
+
[r, g, b] = hexToRgb(color);
|
|
140
|
+
else if (color.startsWith("rgb")) {
|
|
141
|
+
const rgbValues = (_a = color.match(/\d+(\.\d+)?/g)) == null ? void 0 : _a.map(Number);
|
|
142
|
+
if (rgbValues)
|
|
143
|
+
[r, g, b, a] = rgbValues;
|
|
144
|
+
else
|
|
145
|
+
throw new Error("Invalid RGB/RGBA color format");
|
|
146
|
+
} else
|
|
147
|
+
throw new Error("Unsupported color format");
|
|
148
|
+
[r, g, b] = darkenRgb(r, g, b, percent);
|
|
149
|
+
const upperCase = color.match(/[A-F]/) !== null;
|
|
150
|
+
if (isHexCol)
|
|
151
|
+
return rgbToHex(r, g, b, color.startsWith("#"), upperCase);
|
|
152
|
+
else if (color.startsWith("rgba"))
|
|
153
|
+
return `rgba(${r}, ${g}, ${b}, ${a})`;
|
|
154
|
+
else if (color.startsWith("rgb"))
|
|
155
|
+
return `rgb(${r}, ${g}, ${b})`;
|
|
156
|
+
else
|
|
157
|
+
throw new Error("Unsupported color format");
|
|
158
|
+
}
|
|
159
|
+
|
|
111
160
|
// lib/dom.ts
|
|
112
161
|
function getUnsafeWindow() {
|
|
113
162
|
try {
|
|
@@ -1303,18 +1352,22 @@ var SelectorObserver = class {
|
|
|
1303
1352
|
// lib/translation.ts
|
|
1304
1353
|
var trans = {};
|
|
1305
1354
|
var curLang;
|
|
1306
|
-
|
|
1355
|
+
var trLang = (language, key, ...args) => {
|
|
1307
1356
|
var _a;
|
|
1308
|
-
if (!
|
|
1357
|
+
if (!language)
|
|
1309
1358
|
return key;
|
|
1310
|
-
const trText = (_a = trans[
|
|
1359
|
+
const trText = (_a = trans[language]) == null ? void 0 : _a[key];
|
|
1311
1360
|
if (!trText)
|
|
1312
1361
|
return key;
|
|
1313
1362
|
if (args.length > 0 && trText.match(/%\d/)) {
|
|
1314
1363
|
return insertValues(trText, ...args);
|
|
1315
1364
|
}
|
|
1316
1365
|
return trText;
|
|
1366
|
+
};
|
|
1367
|
+
function tr(key, ...args) {
|
|
1368
|
+
return trLang(curLang, key, ...args);
|
|
1317
1369
|
}
|
|
1370
|
+
tr.forLang = trLang;
|
|
1318
1371
|
tr.addLanguage = (language, translations) => {
|
|
1319
1372
|
trans[language] = translations;
|
|
1320
1373
|
};
|
|
@@ -1324,5 +1377,8 @@ tr.setLanguage = (language) => {
|
|
|
1324
1377
|
tr.getLanguage = () => {
|
|
1325
1378
|
return curLang;
|
|
1326
1379
|
};
|
|
1380
|
+
tr.getTranslations = (language) => {
|
|
1381
|
+
return trans[language != null ? language : curLang];
|
|
1382
|
+
};
|
|
1327
1383
|
|
|
1328
|
-
export { DataStore, DataStoreSerializer, Dialog, NanoEmitter, SelectorObserver, addGlobalStyle, addParent, autoPlural, clamp, compress, computeHash, currentDialogId, debounce, decompress, defaultDialogCss, defaultStrings, fetchAdvanced, getSiblingsFrame, getUnsafeWindow, insertValues, interceptEvent, interceptWindowEvent, isScrollable, mapRange, observeElementProp, openDialogs, openInNewTab, pauseFor, preloadImages, randRange, randomId, randomItem, randomItemIndex, randomizeArray, setInnerHtmlUnsafe, takeRandomItem, tr };
|
|
1384
|
+
export { DataStore, DataStoreSerializer, Dialog, NanoEmitter, SelectorObserver, addGlobalStyle, addParent, autoPlural, clamp, compress, computeHash, currentDialogId, darkenColor, debounce, decompress, defaultDialogCss, defaultStrings, fetchAdvanced, 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/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { Stringifiable } from "./types.js";
|
|
2
2
|
/**
|
|
3
3
|
* Returns the translated text for the specified key in the current language set by {@linkcode tr.setLanguage()}
|
|
4
|
-
*
|
|
4
|
+
* Use {@linkcode tr.forLang()} to get the translation for a specific language instead of the currently set one.
|
|
5
|
+
* If the key is not found in the currently set language, the key itself is returned.
|
|
5
6
|
*
|
|
6
7
|
* ⚠️ Remember to register a language with {@linkcode tr.addLanguage()} and set it as active with {@linkcode tr.setLanguage()} before using this function, otherwise it will always return the key itself.
|
|
7
8
|
* @param key Key of the translation to return
|
|
@@ -9,8 +10,10 @@ import type { Stringifiable } from "./types.js";
|
|
|
9
10
|
*/
|
|
10
11
|
declare function tr(key: string, ...args: Stringifiable[]): string;
|
|
11
12
|
declare namespace tr {
|
|
13
|
+
var forLang: (language: string, key: string, ...args: Stringifiable[]) => string;
|
|
12
14
|
var addLanguage: (language: string, translations: Record<string, string>) => void;
|
|
13
15
|
var setLanguage: (language: string) => void;
|
|
14
16
|
var getLanguage: () => string;
|
|
17
|
+
var getTranslations: (language?: string | undefined) => Record<string, string> | undefined;
|
|
15
18
|
}
|
|
16
19
|
export { tr };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sv443-network/userutils",
|
|
3
3
|
"libName": "UserUtils",
|
|
4
|
-
"version": "7.
|
|
4
|
+
"version": "7.3.0",
|
|
5
5
|
"description": "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
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.mjs",
|