@sv443-network/userutils 0.2.0 → 0.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 +6 -0
- package/README.md +64 -11
- package/dist/index.d.mts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +6 -5
- package/dist/index.mjs +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ Contains builtin TypeScript declarations.
|
|
|
9
9
|
- [Features](#features)
|
|
10
10
|
- [onSelector()](#onselector) - call a listener once a selector is found in the DOM
|
|
11
11
|
- [initOnSelector()](#initonselector) - needs to be called once to be able to use `onSelector()`
|
|
12
|
+
- [getSelectorMap()](#getselectormap) - returns all currently registered selectors, listeners and options
|
|
12
13
|
- [autoPlural()](#autoplural) - automatically pluralize a string
|
|
13
14
|
- [clamp()](#clamp) - clamp a number between a min and max value
|
|
14
15
|
- [pauseFor()](#pausefor) - pause the execution of a function for a given amount of time
|
|
@@ -69,7 +70,7 @@ If the selector already exists, the listener will be called immediately.
|
|
|
69
70
|
|
|
70
71
|
If `all` is set to `true`, querySelectorAll() will be used instead and the listener will return a NodeList of matching elements.
|
|
71
72
|
This will also include elements that were already found in a previous listener call.
|
|
72
|
-
If set to `false` (default), querySelector() will be used and only the first element will be returned.
|
|
73
|
+
If set to `false` (default), querySelector() will be used and only the first matching element will be returned.
|
|
73
74
|
|
|
74
75
|
If `continuous` is set to `true`, the listener will not be deregistered after it was called once (defaults to false).
|
|
75
76
|
|
|
@@ -86,18 +87,18 @@ Calling onSelector() before `DOMContentLoaded` is fired will not throw an error,
|
|
|
86
87
|
document.addEventListener("DOMContentLoaded", initOnSelector);
|
|
87
88
|
|
|
88
89
|
// Continuously checks if `div` elements are added to the DOM, then returns all of them (even previously detected ones) in a NodeList
|
|
89
|
-
onSelector("div", {
|
|
90
|
-
listener: (
|
|
91
|
-
console.log("Elements found:",
|
|
90
|
+
onSelector<HTMLDivElement>("div", {
|
|
91
|
+
listener: (elements) => {
|
|
92
|
+
console.log("Elements found:", elements); // type = NodeListOf<HTMLDivElement>
|
|
92
93
|
},
|
|
93
94
|
all: true,
|
|
94
95
|
continuous: true,
|
|
95
96
|
});
|
|
96
97
|
|
|
97
98
|
// Checks if an input element with a value attribute of "5" is added to the DOM, then returns it and deregisters the listener
|
|
98
|
-
onSelector("input[value=\"5\"]", {
|
|
99
|
+
onSelector<HTMLInputElement>("input[value=\"5\"]", {
|
|
99
100
|
listener: (element) => {
|
|
100
|
-
console.log("Element found:", element);
|
|
101
|
+
console.log("Element found:", element); // type = HTMLInputElement
|
|
101
102
|
},
|
|
102
103
|
});
|
|
103
104
|
```
|
|
@@ -109,7 +110,7 @@ onSelector("input[value=\"5\"]", {
|
|
|
109
110
|
### initOnSelector()
|
|
110
111
|
Usage:
|
|
111
112
|
```ts
|
|
112
|
-
initOnSelector(options
|
|
113
|
+
initOnSelector(options?: {
|
|
113
114
|
attributes?: boolean,
|
|
114
115
|
characterData?: boolean,
|
|
115
116
|
}): void
|
|
@@ -140,6 +141,46 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
|
140
141
|
|
|
141
142
|
<br>
|
|
142
143
|
|
|
144
|
+
### getSelectorMap()
|
|
145
|
+
Usage: `getSelectorMap(): Map<string, OnSelectorOptions[]>`
|
|
146
|
+
|
|
147
|
+
Returns a Map of all currently registered selectors and their options, including listener function.
|
|
148
|
+
Since multiple listeners can be registered for the same selector, the value of the Map is an array of `OnSelectorOptions` objects.
|
|
149
|
+
|
|
150
|
+
<details><summary><b>Example - click to view</b></summary>
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
document.addEventListener("DOMContentLoaded", initOnSelector);
|
|
154
|
+
|
|
155
|
+
onSelector<HTMLDivElement>("div", {
|
|
156
|
+
listener: (elements) => void 0,
|
|
157
|
+
all: true,
|
|
158
|
+
continuous: true,
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
onSelector<HTMLDivElement>("div", {
|
|
162
|
+
listener: (elements) => void 0,
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const selectorMap = getSelectorMap();
|
|
166
|
+
// Map(1) {
|
|
167
|
+
// "div" => [
|
|
168
|
+
// {
|
|
169
|
+
// listener: (elements) => void 0,
|
|
170
|
+
// all: true,
|
|
171
|
+
// continuous: true,
|
|
172
|
+
// },
|
|
173
|
+
// {
|
|
174
|
+
// listener: (elements) => void 0,
|
|
175
|
+
// },
|
|
176
|
+
// ]
|
|
177
|
+
// }
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
</details>
|
|
181
|
+
|
|
182
|
+
<br>
|
|
183
|
+
|
|
143
184
|
### autoPlural()
|
|
144
185
|
Usage: `autoPlural(str: string, num: number | Array | NodeList): string`
|
|
145
186
|
|
|
@@ -155,6 +196,9 @@ autoPlural("apple", 2); // "apples"
|
|
|
155
196
|
|
|
156
197
|
autoPlural("apple", [1]); // "apple"
|
|
157
198
|
autoPlural("apple", [1, 2]); // "apples"
|
|
199
|
+
|
|
200
|
+
const items = [1, 2, 3, 4, "foo", "bar"];
|
|
201
|
+
console.log(`Found ${items.length} ${autoPlural("item", items)}`); // "Found 6 items"
|
|
158
202
|
```
|
|
159
203
|
|
|
160
204
|
</details>
|
|
@@ -171,6 +215,7 @@ Clamps a number between a min and max value.
|
|
|
171
215
|
```ts
|
|
172
216
|
clamp(5, 0, 10); // 5
|
|
173
217
|
clamp(-1, 0, 10); // 0
|
|
218
|
+
clamp(7, 0, 10); // 7
|
|
174
219
|
clamp(Infinity, 0, 10); // 10
|
|
175
220
|
```
|
|
176
221
|
|
|
@@ -225,8 +270,13 @@ Userscripts are sandboxed and do not have access to the regular window object, s
|
|
|
225
270
|
<details><summary><b>Example - click to view</b></summary>
|
|
226
271
|
|
|
227
272
|
```ts
|
|
228
|
-
|
|
273
|
+
// trick the site into thinking the mouse was moved:
|
|
274
|
+
const mouseEvent = new MouseEvent("mousemove", {
|
|
229
275
|
view: getUnsafeWindow(),
|
|
276
|
+
screenY: 69,
|
|
277
|
+
screenX: 420,
|
|
278
|
+
movementX: 10,
|
|
279
|
+
movementY: 0,
|
|
230
280
|
});
|
|
231
281
|
document.body.dispatchEvent(mouseEvent);
|
|
232
282
|
```
|
|
@@ -246,6 +296,7 @@ The passed `afterElement` will be returned.
|
|
|
246
296
|
<details><summary><b>Example - click to view</b></summary>
|
|
247
297
|
|
|
248
298
|
```ts
|
|
299
|
+
// insert a <div> as a sibling next to an element
|
|
249
300
|
const beforeElement = document.querySelector("#before");
|
|
250
301
|
const afterElement = document.createElement("div");
|
|
251
302
|
afterElement.innerText = "After";
|
|
@@ -267,6 +318,7 @@ Previously registered event listeners are kept intact.
|
|
|
267
318
|
<details><summary><b>Example - click to view</b></summary>
|
|
268
319
|
|
|
269
320
|
```ts
|
|
321
|
+
// add an <a> around an element
|
|
270
322
|
const element = document.querySelector("#element");
|
|
271
323
|
const newParent = document.createElement("a");
|
|
272
324
|
newParent.href = "https://example.org/";
|
|
@@ -340,6 +392,7 @@ The timeout will default to 10 seconds if left undefined.
|
|
|
340
392
|
```ts
|
|
341
393
|
fetchAdvanced("https://api.example.org/data", {
|
|
342
394
|
timeout: 5000,
|
|
395
|
+
// also accepts any other fetch options like headers:
|
|
343
396
|
headers: {
|
|
344
397
|
"Accept": "application/json",
|
|
345
398
|
},
|
|
@@ -364,7 +417,7 @@ This function has to be run in relatively quick succession in response to a user
|
|
|
364
417
|
<details><summary><b>Example - click to view</b></summary>
|
|
365
418
|
|
|
366
419
|
```ts
|
|
367
|
-
document.querySelector("#button").addEventListener("click", () => {
|
|
420
|
+
document.querySelector("#my-button").addEventListener("click", () => {
|
|
368
421
|
openInNewTab("https://example.org/");
|
|
369
422
|
});
|
|
370
423
|
```
|
|
@@ -377,7 +430,7 @@ document.querySelector("#button").addEventListener("click", () => {
|
|
|
377
430
|
Usage: `interceptEvent(eventObject: EventTarget, eventName: string, predicate: () => boolean): void`
|
|
378
431
|
|
|
379
432
|
Intercepts all events dispatched on the `eventObject` and prevents the listeners from being called as long as the predicate function returns a truthy value.
|
|
380
|
-
Calling this function will set the `Error.stackTraceLimit` to 1000 to ensure the stack trace is preserved.
|
|
433
|
+
Calling this function will set the `Error.stackTraceLimit` to 1000 (if it's not already higher) to ensure the stack trace is preserved.
|
|
381
434
|
|
|
382
435
|
⚠️ This function should be called as soon as possible (I recommend using `@run-at document-start`), as it will only intercept events that are *attached* after this function is called.
|
|
383
436
|
|
|
@@ -385,7 +438,7 @@ Calling this function will set the `Error.stackTraceLimit` to 1000 to ensure the
|
|
|
385
438
|
|
|
386
439
|
```ts
|
|
387
440
|
interceptEvent(document.body, "click", () => {
|
|
388
|
-
return true; // prevent all click events on the body
|
|
441
|
+
return true; // prevent all click events on the body element
|
|
389
442
|
});
|
|
390
443
|
```
|
|
391
444
|
|
package/dist/index.d.mts
CHANGED
|
@@ -98,12 +98,17 @@ declare function interceptWindowEvent(eventName: keyof WindowEventMap, predicate
|
|
|
98
98
|
* @template TElem The type of element that the listener will return as its argument (defaults to the generic HTMLElement)
|
|
99
99
|
*/
|
|
100
100
|
declare function onSelector<TElem extends Element = HTMLElement>(selector: string, options: OnSelectorOpts<TElem>): void;
|
|
101
|
-
/**
|
|
101
|
+
/**
|
|
102
|
+
* Removes all listeners registered in `onSelector()` that have the given selector
|
|
103
|
+
* @returns Returns true when all listeners with the associated selector were found and removed, false otherwise
|
|
104
|
+
*/
|
|
102
105
|
declare function removeOnSelector(selector: string): boolean;
|
|
103
106
|
/**
|
|
104
107
|
* Initializes a MutationObserver that checks for all registered selectors whenever an element is added to or removed from the `<body>`
|
|
105
108
|
* @param opts For fine-tuning when the MutationObserver checks for the selectors
|
|
106
109
|
*/
|
|
107
110
|
declare function initOnSelector(opts?: InitOnSelectorOpts): void;
|
|
111
|
+
/** Returns all currently registered selectors, as a map of selector strings to their associated options */
|
|
112
|
+
declare function getSelectorMap(): Map<string, OnSelectorOpts[]>;
|
|
108
113
|
|
|
109
|
-
export { FetchAdvancedOpts, InitOnSelectorOpts, OnSelectorOpts, addGlobalStyle, addParent, autoPlural, clamp, debounce, fetchAdvanced, getUnsafeWindow, initOnSelector, insertAfter, interceptEvent, interceptWindowEvent, onSelector, openInNewTab, pauseFor, preloadImages, removeOnSelector };
|
|
114
|
+
export { FetchAdvancedOpts, InitOnSelectorOpts, OnSelectorOpts, addGlobalStyle, addParent, autoPlural, clamp, debounce, fetchAdvanced, getSelectorMap, getUnsafeWindow, initOnSelector, insertAfter, interceptEvent, interceptWindowEvent, onSelector, openInNewTab, pauseFor, preloadImages, removeOnSelector };
|
package/dist/index.d.ts
CHANGED
|
@@ -98,12 +98,17 @@ declare function interceptWindowEvent(eventName: keyof WindowEventMap, predicate
|
|
|
98
98
|
* @template TElem The type of element that the listener will return as its argument (defaults to the generic HTMLElement)
|
|
99
99
|
*/
|
|
100
100
|
declare function onSelector<TElem extends Element = HTMLElement>(selector: string, options: OnSelectorOpts<TElem>): void;
|
|
101
|
-
/**
|
|
101
|
+
/**
|
|
102
|
+
* Removes all listeners registered in `onSelector()` that have the given selector
|
|
103
|
+
* @returns Returns true when all listeners with the associated selector were found and removed, false otherwise
|
|
104
|
+
*/
|
|
102
105
|
declare function removeOnSelector(selector: string): boolean;
|
|
103
106
|
/**
|
|
104
107
|
* Initializes a MutationObserver that checks for all registered selectors whenever an element is added to or removed from the `<body>`
|
|
105
108
|
* @param opts For fine-tuning when the MutationObserver checks for the selectors
|
|
106
109
|
*/
|
|
107
110
|
declare function initOnSelector(opts?: InitOnSelectorOpts): void;
|
|
111
|
+
/** Returns all currently registered selectors, as a map of selector strings to their associated options */
|
|
112
|
+
declare function getSelectorMap(): Map<string, OnSelectorOpts[]>;
|
|
108
113
|
|
|
109
|
-
export { FetchAdvancedOpts, InitOnSelectorOpts, OnSelectorOpts, addGlobalStyle, addParent, autoPlural, clamp, debounce, fetchAdvanced, getUnsafeWindow, initOnSelector, insertAfter, interceptEvent, interceptWindowEvent, onSelector, openInNewTab, pauseFor, preloadImages, removeOnSelector };
|
|
114
|
+
export { FetchAdvancedOpts, InitOnSelectorOpts, OnSelectorOpts, addGlobalStyle, addParent, autoPlural, clamp, debounce, fetchAdvanced, getSelectorMap, getUnsafeWindow, initOnSelector, insertAfter, interceptEvent, interceptWindowEvent, onSelector, openInNewTab, pauseFor, preloadImages, removeOnSelector };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var b=Object.defineProperty,
|
|
3
|
+
var b=Object.defineProperty,y=Object.defineProperties;var g=Object.getOwnPropertyDescriptors;var m=Object.getOwnPropertySymbols;var v=Object.prototype.hasOwnProperty,x=Object.prototype.propertyIsEnumerable;var f=(t,e,n)=>e in t?b(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,u=(t,e)=>{for(var n in e||(e={}))v.call(e,n)&&f(t,n,e[n]);if(m)for(var n of m(e))x.call(e,n)&&f(t,n,e[n]);return t},d=(t,e)=>y(t,g(e));var E=(t,e,n)=>new Promise((r,o)=>{var s=a=>{try{l(n.next(a));}catch(p){o(p);}},i=a=>{try{l(n.throw(a));}catch(p){o(p);}},l=a=>a.done?r(a.value):Promise.resolve(a.value).then(s,i);l((n=n.apply(t,e)).next());});function w(t,e){return (Array.isArray(e)||e instanceof NodeList)&&(e=e.length),`${t}${e===1?"":"s"}`}function M(t,e,n){return Math.max(Math.min(t,n),e)}function S(t){return new Promise(e=>{setTimeout(e,t);})}function A(t,e=300){let n;return function(...r){clearTimeout(n),n=setTimeout(()=>t.apply(this,r),e);}}function h(){try{return unsafeWindow}catch(t){return window}}function _(t,e){var n;return (n=t.parentNode)==null||n.insertBefore(e,t.nextSibling),e}function k(t,e){let n=t.parentNode;if(!n)throw new Error("Element doesn't have a parent node");return n.replaceChild(e,t),e.appendChild(t),e}function H(t){let e=document.createElement("style");e.innerHTML=t,document.head.appendChild(e);}function I(t,e=!1){let n=t.map(r=>new Promise((o,s)=>{let i=new Image;i.src=r,i.addEventListener("load",()=>o(i)),i.addEventListener("error",l=>e&&s(l));}));return Promise.allSettled(n)}function j(n){return E(this,arguments,function*(t,e={}){let{timeout:r=1e4}=e,o=new AbortController,s=setTimeout(()=>o.abort(),r),i=yield fetch(t,d(u({},e),{signal:o.signal}));return clearTimeout(s),i})}function C(t){let e=document.createElement("a");Object.assign(e,{className:"userutils-open-in-new-tab",target:"_blank",rel:"noopener noreferrer",href:t}),e.style.display="none",document.body.appendChild(e),e.click(),setTimeout(e.remove,50);}function O(t,e,n){typeof Error.stackTraceLimit=="number"&&Error.stackTraceLimit<1e3&&(Error.stackTraceLimit=1e3),function(r){element.__proto__.addEventListener=function(...o){if(!(o[0]===e&&n()))return r.apply(this,o)};}(t.__proto__.addEventListener);}function N(t,e){return O(h(),t,e)}var c=new Map;function W(t,e){let n=[];c.has(t)&&(n=c.get(t)),n.push(e),c.set(t,n),T(t,n);}function $(t){return c.delete(t)}function T(t,e){let n=[];if(e.forEach((r,o)=>{try{let s=r.all?document.querySelectorAll(t):document.querySelector(t);s&&(r.listener(s),r.continuous||n.push(o));}catch(s){console.error(`Couldn't call listener for selector '${t}'`,s);}}),n.length>0){let r=e.filter((o,s)=>!n.includes(s));r.length===0?c.delete(t):c.set(t,r);}}function q(t={}){new MutationObserver(()=>{for(let[n,r]of c.entries())T(n,r);}).observe(document.body,d(u({},t),{childList:!0}));}function B(){return c}
|
|
4
4
|
|
|
5
5
|
exports.addGlobalStyle = H;
|
|
6
6
|
exports.addParent = k;
|
|
@@ -8,13 +8,14 @@ exports.autoPlural = w;
|
|
|
8
8
|
exports.clamp = M;
|
|
9
9
|
exports.debounce = A;
|
|
10
10
|
exports.fetchAdvanced = j;
|
|
11
|
+
exports.getSelectorMap = B;
|
|
11
12
|
exports.getUnsafeWindow = h;
|
|
12
|
-
exports.initOnSelector =
|
|
13
|
+
exports.initOnSelector = q;
|
|
13
14
|
exports.insertAfter = _;
|
|
14
15
|
exports.interceptEvent = O;
|
|
15
|
-
exports.interceptWindowEvent =
|
|
16
|
+
exports.interceptWindowEvent = N;
|
|
16
17
|
exports.onSelector = W;
|
|
17
|
-
exports.openInNewTab =
|
|
18
|
+
exports.openInNewTab = C;
|
|
18
19
|
exports.pauseFor = S;
|
|
19
20
|
exports.preloadImages = I;
|
|
20
|
-
exports.removeOnSelector =
|
|
21
|
+
exports.removeOnSelector = $;
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var b=Object.defineProperty,
|
|
1
|
+
var b=Object.defineProperty,y=Object.defineProperties;var g=Object.getOwnPropertyDescriptors;var m=Object.getOwnPropertySymbols;var v=Object.prototype.hasOwnProperty,x=Object.prototype.propertyIsEnumerable;var f=(t,e,n)=>e in t?b(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,u=(t,e)=>{for(var n in e||(e={}))v.call(e,n)&&f(t,n,e[n]);if(m)for(var n of m(e))x.call(e,n)&&f(t,n,e[n]);return t},d=(t,e)=>y(t,g(e));var E=(t,e,n)=>new Promise((r,o)=>{var s=a=>{try{l(n.next(a));}catch(p){o(p);}},i=a=>{try{l(n.throw(a));}catch(p){o(p);}},l=a=>a.done?r(a.value):Promise.resolve(a.value).then(s,i);l((n=n.apply(t,e)).next());});function w(t,e){return (Array.isArray(e)||e instanceof NodeList)&&(e=e.length),`${t}${e===1?"":"s"}`}function M(t,e,n){return Math.max(Math.min(t,n),e)}function S(t){return new Promise(e=>{setTimeout(e,t);})}function A(t,e=300){let n;return function(...r){clearTimeout(n),n=setTimeout(()=>t.apply(this,r),e);}}function h(){try{return unsafeWindow}catch(t){return window}}function _(t,e){var n;return (n=t.parentNode)==null||n.insertBefore(e,t.nextSibling),e}function k(t,e){let n=t.parentNode;if(!n)throw new Error("Element doesn't have a parent node");return n.replaceChild(e,t),e.appendChild(t),e}function H(t){let e=document.createElement("style");e.innerHTML=t,document.head.appendChild(e);}function I(t,e=!1){let n=t.map(r=>new Promise((o,s)=>{let i=new Image;i.src=r,i.addEventListener("load",()=>o(i)),i.addEventListener("error",l=>e&&s(l));}));return Promise.allSettled(n)}function j(n){return E(this,arguments,function*(t,e={}){let{timeout:r=1e4}=e,o=new AbortController,s=setTimeout(()=>o.abort(),r),i=yield fetch(t,d(u({},e),{signal:o.signal}));return clearTimeout(s),i})}function C(t){let e=document.createElement("a");Object.assign(e,{className:"userutils-open-in-new-tab",target:"_blank",rel:"noopener noreferrer",href:t}),e.style.display="none",document.body.appendChild(e),e.click(),setTimeout(e.remove,50);}function O(t,e,n){typeof Error.stackTraceLimit=="number"&&Error.stackTraceLimit<1e3&&(Error.stackTraceLimit=1e3),function(r){element.__proto__.addEventListener=function(...o){if(!(o[0]===e&&n()))return r.apply(this,o)};}(t.__proto__.addEventListener);}function N(t,e){return O(h(),t,e)}var c=new Map;function W(t,e){let n=[];c.has(t)&&(n=c.get(t)),n.push(e),c.set(t,n),T(t,n);}function $(t){return c.delete(t)}function T(t,e){let n=[];if(e.forEach((r,o)=>{try{let s=r.all?document.querySelectorAll(t):document.querySelector(t);s&&(r.listener(s),r.continuous||n.push(o));}catch(s){console.error(`Couldn't call listener for selector '${t}'`,s);}}),n.length>0){let r=e.filter((o,s)=>!n.includes(s));r.length===0?c.delete(t):c.set(t,r);}}function q(t={}){new MutationObserver(()=>{for(let[n,r]of c.entries())T(n,r);}).observe(document.body,d(u({},t),{childList:!0}));}function B(){return c}
|
|
2
2
|
|
|
3
|
-
export { H as addGlobalStyle, k as addParent, w as autoPlural, M as clamp, A as debounce, j as fetchAdvanced, h as getUnsafeWindow,
|
|
3
|
+
export { H as addGlobalStyle, k as addParent, w as autoPlural, M as clamp, A as debounce, j as fetchAdvanced, B as getSelectorMap, h as getUnsafeWindow, q as initOnSelector, _ as insertAfter, O as interceptEvent, N as interceptWindowEvent, W as onSelector, C as openInNewTab, S as pauseFor, I as preloadImages, $ as removeOnSelector };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sv443-network/userutils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Library with various utilities for userscripts - register listeners for when CSS selectors exist, intercept events, modify the DOM more easily and more ",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|