@sv443-network/userutils 0.1.1 → 0.1.4

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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # @sv443-network/userutils
2
2
 
3
+ ## 0.1.4
4
+
5
+ ### Patch Changes
6
+
7
+ - a1e8dec: please just work thanks
8
+
9
+ ## 0.1.3
10
+
11
+ ### Patch Changes
12
+
13
+ - 9673cad: more testing
14
+
15
+ ## 0.1.2
16
+
17
+ ### Patch Changes
18
+
19
+ - 6eafb79: test publish workflow lol
20
+
3
21
  ## 0.1.1
4
22
 
5
23
  ### Patch Changes
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ## UserUtils
2
2
  Library with various utilities for userscripts - register listeners for when CSS selectors exist, intercept events, modify the DOM more easily and more.
3
- Contains builtin TypeScript definitions.
3
+ Contains builtin TypeScript declarations.
4
4
 
5
5
  <br>
6
6
 
package/dist/index.d.mts CHANGED
@@ -62,12 +62,14 @@ declare function fetchAdvanced(url: string, options?: FetchAdvancedOpts): Promis
62
62
  declare function openInNewTab(href: string): void;
63
63
  /**
64
64
  * Intercepts the specified event on the passed object and prevents it from being called if the called `predicate` function returns a truthy value.
65
- * Calling this function will set the `stackTraceLimit` to 1000 to ensure the stack trace is preserved.
65
+ * This function should be called as soon as possible (I recommend using `@run-at document-start`), as it will only intercept events that are added after this function is called.
66
+ * Calling this function will set the `Error.stackTraceLimit` to 1000 to ensure the stack trace is preserved.
66
67
  */
67
68
  declare function interceptEvent<TEvtObj extends EventTarget>(eventObject: TEvtObj, eventName: Parameters<TEvtObj["addEventListener"]>[0], predicate: () => boolean): void;
68
69
  /**
69
70
  * Intercepts the specified event on the window object and prevents it from being called if the called `predicate` function returns a truthy value.
70
- * Calling this function will set the `stackTraceLimit` to 1000 to ensure the stack trace is preserved.
71
+ * This function should be called as soon as possible (I recommend using `@run-at document-start`), as it will only intercept events that are added after this function is called.
72
+ * Calling this function will set the `Error.stackTraceLimit` to 1000 to ensure the stack trace is preserved.
71
73
  */
72
74
  declare function interceptWindowEvent(eventName: keyof WindowEventMap, predicate: () => boolean): void;
73
75
 
package/dist/index.d.ts CHANGED
@@ -62,12 +62,14 @@ declare function fetchAdvanced(url: string, options?: FetchAdvancedOpts): Promis
62
62
  declare function openInNewTab(href: string): void;
63
63
  /**
64
64
  * Intercepts the specified event on the passed object and prevents it from being called if the called `predicate` function returns a truthy value.
65
- * Calling this function will set the `stackTraceLimit` to 1000 to ensure the stack trace is preserved.
65
+ * This function should be called as soon as possible (I recommend using `@run-at document-start`), as it will only intercept events that are added after this function is called.
66
+ * Calling this function will set the `Error.stackTraceLimit` to 1000 to ensure the stack trace is preserved.
66
67
  */
67
68
  declare function interceptEvent<TEvtObj extends EventTarget>(eventObject: TEvtObj, eventName: Parameters<TEvtObj["addEventListener"]>[0], predicate: () => boolean): void;
68
69
  /**
69
70
  * Intercepts the specified event on the window object and prevents it from being called if the called `predicate` function returns a truthy value.
70
- * Calling this function will set the `stackTraceLimit` to 1000 to ensure the stack trace is preserved.
71
+ * This function should be called as soon as possible (I recommend using `@run-at document-start`), as it will only intercept events that are added after this function is called.
72
+ * Calling this function will set the `Error.stackTraceLimit` to 1000 to ensure the stack trace is preserved.
71
73
  */
72
74
  declare function interceptWindowEvent(eventName: keyof WindowEventMap, predicate: () => boolean): void;
73
75
 
package/dist/index.js CHANGED
@@ -1,162 +1,19 @@
1
1
  'use strict';
2
2
 
3
- var __defProp = Object.defineProperty;
4
- var __defProps = Object.defineProperties;
5
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
9
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10
- var __spreadValues = (a, b) => {
11
- for (var prop in b || (b = {}))
12
- if (__hasOwnProp.call(b, prop))
13
- __defNormalProp(a, prop, b[prop]);
14
- if (__getOwnPropSymbols)
15
- for (var prop of __getOwnPropSymbols(b)) {
16
- if (__propIsEnum.call(b, prop))
17
- __defNormalProp(a, prop, b[prop]);
18
- }
19
- return a;
20
- };
21
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
22
- var __async = (__this, __arguments, generator) => {
23
- return new Promise((resolve, reject) => {
24
- var fulfilled = (value) => {
25
- try {
26
- step(generator.next(value));
27
- } catch (e) {
28
- reject(e);
29
- }
30
- };
31
- var rejected = (value) => {
32
- try {
33
- step(generator.throw(value));
34
- } catch (e) {
35
- reject(e);
36
- }
37
- };
38
- var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
39
- step((generator = generator.apply(__this, __arguments)).next());
40
- });
41
- };
3
+ var E=Object.defineProperty,T=Object.defineProperties;var x=Object.getOwnPropertyDescriptors;var l=Object.getOwnPropertySymbols;var v=Object.prototype.hasOwnProperty,b=Object.prototype.propertyIsEnumerable;var p=(t,e,n)=>e in t?E(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)&&p(t,n,e[n]);if(l)for(var n of l(e))b.call(e,n)&&p(t,n,e[n]);return t},m=(t,e)=>T(t,x(e));var f=(t,e,n)=>new Promise((o,r)=>{var a=s=>{try{c(n.next(s));}catch(d){r(d);}},i=s=>{try{c(n.throw(s));}catch(d){r(d);}},c=s=>s.done?o(s.value):Promise.resolve(s.value).then(a,i);c((n=n.apply(t,e)).next());});function h(t,e){return (Array.isArray(e)||e instanceof NodeList)&&(e=e.length),`${t}${e===1?"":"s"}`}function O(t,e,n){return Math.max(Math.min(t,n),e)}function w(t){return new Promise(e=>{setTimeout(e,t);})}function A(t,e=300){let n;return function(...o){clearTimeout(n),n=setTimeout(()=>t.apply(this,o),e);}}function y(){try{return unsafeWindow}catch(t){return window}}function M(t,e){var n;return (n=t.parentNode)==null||n.insertBefore(e,t.nextSibling),e}function _(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 k(t){let e=document.createElement("style");e.innerHTML=t,document.head.appendChild(e);}function S(t,e=!1){let n=t.map(o=>new Promise((r,a)=>{let i=new Image;i.src=o,i.addEventListener("load",()=>r(i)),i.addEventListener("error",c=>e&&a(c));}));return Promise.allSettled(n)}function H(n){return f(this,arguments,function*(t,e={}){let{timeout:o=1e4}=e,r=new AbortController,a=setTimeout(()=>r.abort(),o),i=yield fetch(t,m(u({},e),{signal:r.signal}));return clearTimeout(a),i})}function N(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 g(t,e,n){typeof Error.stackTraceLimit=="number"&&Error.stackTraceLimit<1e3&&(Error.stackTraceLimit=1e3),function(o){element.__proto__.addEventListener=function(...r){if(!(r[0]===e&&n()))return o.apply(this,r)};}(t.__proto__.addEventListener);}function j(t,e){return g(y(),t,e)}function F(t,e){}function W(t){}
42
4
 
43
- // lib/utils.ts
44
- function autoPlural(word, num) {
45
- if (Array.isArray(num) || num instanceof NodeList)
46
- num = num.length;
47
- return `${word}${num === 1 ? "" : "s"}`;
48
- }
49
- function clamp(value, min, max) {
50
- return Math.max(Math.min(value, max), min);
51
- }
52
- function pauseFor(time) {
53
- return new Promise((res) => {
54
- setTimeout(res, time);
55
- });
56
- }
57
- function debounce(func, timeout = 300) {
58
- let timer;
59
- return function(...args) {
60
- clearTimeout(timer);
61
- timer = setTimeout(() => func.apply(this, args), timeout);
62
- };
63
- }
64
- function getUnsafeWindow() {
65
- try {
66
- return unsafeWindow;
67
- } catch (e) {
68
- return window;
69
- }
70
- }
71
- function insertAfter(beforeElement, afterElement) {
72
- var _a;
73
- (_a = beforeElement.parentNode) == null ? void 0 : _a.insertBefore(afterElement, beforeElement.nextSibling);
74
- return afterElement;
75
- }
76
- function addParent(element2, newParent) {
77
- const oldParent = element2.parentNode;
78
- if (!oldParent)
79
- throw new Error("Element doesn't have a parent node");
80
- oldParent.replaceChild(newParent, element2);
81
- newParent.appendChild(element2);
82
- return newParent;
83
- }
84
- function addGlobalStyle(style) {
85
- const styleElem = document.createElement("style");
86
- styleElem.innerHTML = style;
87
- document.head.appendChild(styleElem);
88
- }
89
- function preloadImages(srcUrls, rejects = false) {
90
- const promises = srcUrls.map((src) => new Promise((res, rej) => {
91
- const image = new Image();
92
- image.src = src;
93
- image.addEventListener("load", () => res(image));
94
- image.addEventListener("error", (evt) => rejects && rej(evt));
95
- }));
96
- return Promise.allSettled(promises);
97
- }
98
- function fetchAdvanced(_0) {
99
- return __async(this, arguments, function* (url, options = {}) {
100
- const { timeout = 1e4 } = options;
101
- const controller = new AbortController();
102
- const id = setTimeout(() => controller.abort(), timeout);
103
- const res = yield fetch(url, __spreadProps(__spreadValues({}, options), {
104
- signal: controller.signal
105
- }));
106
- clearTimeout(id);
107
- return res;
108
- });
109
- }
110
- function openInNewTab(href) {
111
- const openElem = document.createElement("a");
112
- Object.assign(openElem, {
113
- className: "userutils-open-in-new-tab",
114
- target: "_blank",
115
- rel: "noopener noreferrer",
116
- href
117
- });
118
- openElem.style.display = "none";
119
- document.body.appendChild(openElem);
120
- openElem.click();
121
- setTimeout(openElem.remove, 50);
122
- }
123
- function interceptEvent(eventObject, eventName, predicate) {
124
- if (Error.stackTraceLimit < 1e3) {
125
- Error.stackTraceLimit = 1e3;
126
- }
127
- (function(original) {
128
- element.__proto__.addEventListener = function(...args) {
129
- if (args[0] === eventName && predicate())
130
- return;
131
- else
132
- return original.apply(this, args);
133
- };
134
- })(eventObject.__proto__.addEventListener);
135
- }
136
- function interceptWindowEvent(eventName, predicate) {
137
- return interceptEvent(getUnsafeWindow(), eventName, predicate);
138
- }
139
-
140
- // lib/onSelector.ts
141
- function onSelector(options, listener) {
142
- }
143
- function removeOnSelector(selector) {
144
- }
145
-
146
- exports.addGlobalStyle = addGlobalStyle;
147
- exports.addParent = addParent;
148
- exports.autoPlural = autoPlural;
149
- exports.clamp = clamp;
150
- exports.debounce = debounce;
151
- exports.fetchAdvanced = fetchAdvanced;
152
- exports.getUnsafeWindow = getUnsafeWindow;
153
- exports.insertAfter = insertAfter;
154
- exports.interceptEvent = interceptEvent;
155
- exports.interceptWindowEvent = interceptWindowEvent;
156
- exports.onSelector = onSelector;
157
- exports.openInNewTab = openInNewTab;
158
- exports.pauseFor = pauseFor;
159
- exports.preloadImages = preloadImages;
160
- exports.removeOnSelector = removeOnSelector;
161
- //# sourceMappingURL=out.js.map
162
- //# sourceMappingURL=index.js.map
5
+ exports.addGlobalStyle = k;
6
+ exports.addParent = _;
7
+ exports.autoPlural = h;
8
+ exports.clamp = O;
9
+ exports.debounce = A;
10
+ exports.fetchAdvanced = H;
11
+ exports.getUnsafeWindow = y;
12
+ exports.insertAfter = M;
13
+ exports.interceptEvent = g;
14
+ exports.interceptWindowEvent = j;
15
+ exports.onSelector = F;
16
+ exports.openInNewTab = N;
17
+ exports.pauseFor = w;
18
+ exports.preloadImages = S;
19
+ exports.removeOnSelector = W;
package/dist/index.mjs CHANGED
@@ -1,146 +1,3 @@
1
- var __defProp = Object.defineProperty;
2
- var __defProps = Object.defineProperties;
3
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
- var __spreadValues = (a, b) => {
9
- for (var prop in b || (b = {}))
10
- if (__hasOwnProp.call(b, prop))
11
- __defNormalProp(a, prop, b[prop]);
12
- if (__getOwnPropSymbols)
13
- for (var prop of __getOwnPropSymbols(b)) {
14
- if (__propIsEnum.call(b, prop))
15
- __defNormalProp(a, prop, b[prop]);
16
- }
17
- return a;
18
- };
19
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
- var __async = (__this, __arguments, generator) => {
21
- return new Promise((resolve, reject) => {
22
- var fulfilled = (value) => {
23
- try {
24
- step(generator.next(value));
25
- } catch (e) {
26
- reject(e);
27
- }
28
- };
29
- var rejected = (value) => {
30
- try {
31
- step(generator.throw(value));
32
- } catch (e) {
33
- reject(e);
34
- }
35
- };
36
- var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
37
- step((generator = generator.apply(__this, __arguments)).next());
38
- });
39
- };
1
+ var E=Object.defineProperty,T=Object.defineProperties;var x=Object.getOwnPropertyDescriptors;var l=Object.getOwnPropertySymbols;var v=Object.prototype.hasOwnProperty,b=Object.prototype.propertyIsEnumerable;var p=(t,e,n)=>e in t?E(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)&&p(t,n,e[n]);if(l)for(var n of l(e))b.call(e,n)&&p(t,n,e[n]);return t},m=(t,e)=>T(t,x(e));var f=(t,e,n)=>new Promise((o,r)=>{var a=s=>{try{c(n.next(s));}catch(d){r(d);}},i=s=>{try{c(n.throw(s));}catch(d){r(d);}},c=s=>s.done?o(s.value):Promise.resolve(s.value).then(a,i);c((n=n.apply(t,e)).next());});function h(t,e){return (Array.isArray(e)||e instanceof NodeList)&&(e=e.length),`${t}${e===1?"":"s"}`}function O(t,e,n){return Math.max(Math.min(t,n),e)}function w(t){return new Promise(e=>{setTimeout(e,t);})}function A(t,e=300){let n;return function(...o){clearTimeout(n),n=setTimeout(()=>t.apply(this,o),e);}}function y(){try{return unsafeWindow}catch(t){return window}}function M(t,e){var n;return (n=t.parentNode)==null||n.insertBefore(e,t.nextSibling),e}function _(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 k(t){let e=document.createElement("style");e.innerHTML=t,document.head.appendChild(e);}function S(t,e=!1){let n=t.map(o=>new Promise((r,a)=>{let i=new Image;i.src=o,i.addEventListener("load",()=>r(i)),i.addEventListener("error",c=>e&&a(c));}));return Promise.allSettled(n)}function H(n){return f(this,arguments,function*(t,e={}){let{timeout:o=1e4}=e,r=new AbortController,a=setTimeout(()=>r.abort(),o),i=yield fetch(t,m(u({},e),{signal:r.signal}));return clearTimeout(a),i})}function N(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 g(t,e,n){typeof Error.stackTraceLimit=="number"&&Error.stackTraceLimit<1e3&&(Error.stackTraceLimit=1e3),function(o){element.__proto__.addEventListener=function(...r){if(!(r[0]===e&&n()))return o.apply(this,r)};}(t.__proto__.addEventListener);}function j(t,e){return g(y(),t,e)}function F(t,e){}function W(t){}
40
2
 
41
- // lib/utils.ts
42
- function autoPlural(word, num) {
43
- if (Array.isArray(num) || num instanceof NodeList)
44
- num = num.length;
45
- return `${word}${num === 1 ? "" : "s"}`;
46
- }
47
- function clamp(value, min, max) {
48
- return Math.max(Math.min(value, max), min);
49
- }
50
- function pauseFor(time) {
51
- return new Promise((res) => {
52
- setTimeout(res, time);
53
- });
54
- }
55
- function debounce(func, timeout = 300) {
56
- let timer;
57
- return function(...args) {
58
- clearTimeout(timer);
59
- timer = setTimeout(() => func.apply(this, args), timeout);
60
- };
61
- }
62
- function getUnsafeWindow() {
63
- try {
64
- return unsafeWindow;
65
- } catch (e) {
66
- return window;
67
- }
68
- }
69
- function insertAfter(beforeElement, afterElement) {
70
- var _a;
71
- (_a = beforeElement.parentNode) == null ? void 0 : _a.insertBefore(afterElement, beforeElement.nextSibling);
72
- return afterElement;
73
- }
74
- function addParent(element2, newParent) {
75
- const oldParent = element2.parentNode;
76
- if (!oldParent)
77
- throw new Error("Element doesn't have a parent node");
78
- oldParent.replaceChild(newParent, element2);
79
- newParent.appendChild(element2);
80
- return newParent;
81
- }
82
- function addGlobalStyle(style) {
83
- const styleElem = document.createElement("style");
84
- styleElem.innerHTML = style;
85
- document.head.appendChild(styleElem);
86
- }
87
- function preloadImages(srcUrls, rejects = false) {
88
- const promises = srcUrls.map((src) => new Promise((res, rej) => {
89
- const image = new Image();
90
- image.src = src;
91
- image.addEventListener("load", () => res(image));
92
- image.addEventListener("error", (evt) => rejects && rej(evt));
93
- }));
94
- return Promise.allSettled(promises);
95
- }
96
- function fetchAdvanced(_0) {
97
- return __async(this, arguments, function* (url, options = {}) {
98
- const { timeout = 1e4 } = options;
99
- const controller = new AbortController();
100
- const id = setTimeout(() => controller.abort(), timeout);
101
- const res = yield fetch(url, __spreadProps(__spreadValues({}, options), {
102
- signal: controller.signal
103
- }));
104
- clearTimeout(id);
105
- return res;
106
- });
107
- }
108
- function openInNewTab(href) {
109
- const openElem = document.createElement("a");
110
- Object.assign(openElem, {
111
- className: "userutils-open-in-new-tab",
112
- target: "_blank",
113
- rel: "noopener noreferrer",
114
- href
115
- });
116
- openElem.style.display = "none";
117
- document.body.appendChild(openElem);
118
- openElem.click();
119
- setTimeout(openElem.remove, 50);
120
- }
121
- function interceptEvent(eventObject, eventName, predicate) {
122
- if (Error.stackTraceLimit < 1e3) {
123
- Error.stackTraceLimit = 1e3;
124
- }
125
- (function(original) {
126
- element.__proto__.addEventListener = function(...args) {
127
- if (args[0] === eventName && predicate())
128
- return;
129
- else
130
- return original.apply(this, args);
131
- };
132
- })(eventObject.__proto__.addEventListener);
133
- }
134
- function interceptWindowEvent(eventName, predicate) {
135
- return interceptEvent(getUnsafeWindow(), eventName, predicate);
136
- }
137
-
138
- // lib/onSelector.ts
139
- function onSelector(options, listener) {
140
- }
141
- function removeOnSelector(selector) {
142
- }
143
-
144
- export { addGlobalStyle, addParent, autoPlural, clamp, debounce, fetchAdvanced, getUnsafeWindow, insertAfter, interceptEvent, interceptWindowEvent, onSelector, openInNewTab, pauseFor, preloadImages, removeOnSelector };
145
- //# sourceMappingURL=out.js.map
146
- //# sourceMappingURL=index.mjs.map
3
+ export { k as addGlobalStyle, _ as addParent, h as autoPlural, O as clamp, A as debounce, H as fetchAdvanced, y as getUnsafeWindow, M as insertAfter, g as interceptEvent, j as interceptWindowEvent, F as onSelector, N as openInNewTab, w as pauseFor, S as preloadImages, W as removeOnSelector };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sv443-network/userutils",
3
- "version": "0.1.1",
3
+ "version": "0.1.4",
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",
@@ -9,7 +9,8 @@
9
9
  "lint": "tsc && eslint .",
10
10
  "prepare-build": "tsup lib/index.ts --format cjs,esm --dts --clean --treeshake",
11
11
  "build": "npm run prepare-build -- --minify",
12
- "build-dev": "npm run prepare-build -- --sourcemap --watch"
12
+ "build-dev": "npm run prepare-build -- --sourcemap --watch",
13
+ "publish-package": "npm run build && changeset publish"
13
14
  },
14
15
  "repository": {
15
16
  "type": "git",
@@ -43,4 +44,4 @@
43
44
  "> 1%",
44
45
  "not dead"
45
46
  ]
46
- }
47
+ }
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../lib/utils.ts","../lib/onSelector.ts"],"names":["element"],"mappings":"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","sourcesContent":["import type { FetchAdvancedOpts } from \"./types\";\n\n/**\n * Automatically appends an `s` to the passed `word`, if `num` is not equal to 1\n * @param word A word in singular form, to auto-convert to plural\n * @param num If this is an array or NodeList, the amount of items is used\n */\nexport function autoPlural(word: string, num: number | unknown[] | NodeList) {\n if(Array.isArray(num) || num instanceof NodeList)\n num = num.length;\n return `${word}${num === 1 ? \"\" : \"s\"}`;\n}\n\n/** Ensures the passed `value` always stays between `min` and `max` */\nexport function clamp(value: number, min: number, max: number) {\n return Math.max(Math.min(value, max), min);\n}\n\n/** Pauses async execution for the specified time in ms */\nexport function pauseFor(time: number) {\n return new Promise((res) => {\n setTimeout(res, time);\n });\n}\n\n/**\n * Calls the passed `func` after the specified `timeout` in ms. \n * Any subsequent calls to this function will reset the timer and discard previous calls.\n */\nexport function debounce<TFunc extends (...args: TArgs[]) => void, TArgs = any>(func: TFunc, timeout = 300) { // eslint-disable-line @typescript-eslint/no-explicit-any\n let timer: number | undefined;\n return function(...args: TArgs[]) {\n clearTimeout(timer);\n timer = setTimeout(() => func.apply(this, args), timeout) as unknown as number;\n };\n}\n\n/**\n * Returns `unsafeWindow` if the `@grant unsafeWindow` is given, otherwise falls back to the regular `window`\n */\nexport function getUnsafeWindow() {\n try {\n // throws ReferenceError if the \"@grant unsafeWindow\" isn't present\n return unsafeWindow;\n }\n catch(e) {\n return window;\n }\n}\n\n/**\n * Inserts `afterElement` as a sibling just after the provided `beforeElement`\n * @returns Returns the `afterElement`\n */\nexport function insertAfter(beforeElement: HTMLElement, afterElement: HTMLElement) {\n beforeElement.parentNode?.insertBefore(afterElement, beforeElement.nextSibling);\n return afterElement;\n}\n\n/**\n * Adds a parent container around the provided element\n * @returns Returns the new parent element\n */\nexport function addParent(element: HTMLElement, newParent: HTMLElement) {\n const oldParent = element.parentNode;\n\n if(!oldParent)\n throw new Error(\"Element doesn't have a parent node\");\n\n oldParent.replaceChild(newParent, element);\n newParent.appendChild(element);\n\n return newParent;\n}\n\n/**\n * Adds global CSS style in the form of a `<style>` element in the document's `<head>` \n * This needs to be run after the `DOMContentLoaded` event has fired on the document object (or instantly if `@run-at document-end` is used).\n * @param style CSS string\n */\nexport function addGlobalStyle(style: string) {\n const styleElem = document.createElement(\"style\");\n styleElem.innerHTML = style;\n document.head.appendChild(styleElem);\n}\n\n/**\n * Preloads an array of image URLs so they can be loaded instantly from the browser cache later on\n * @param rejects If set to `true`, the returned PromiseSettledResults will contain rejections for any of the images that failed to load\n * @returns Returns an array of `PromiseSettledResult` - each resolved result will contain the loaded image element, while each rejected result will contain an `ErrorEvent`\n */\nexport function preloadImages(srcUrls: string[], rejects = false) {\n const promises = srcUrls.map(src => new Promise((res, rej) => {\n const image = new Image();\n image.src = src;\n image.addEventListener(\"load\", () => res(image));\n image.addEventListener(\"error\", (evt) => rejects && rej(evt));\n }));\n\n return Promise.allSettled(promises);\n}\n\n/** Calls the fetch API with special options like a timeout */\nexport async function fetchAdvanced(url: string, options: FetchAdvancedOpts = {}) {\n const { timeout = 10000 } = options;\n\n const controller = new AbortController();\n const id = setTimeout(() => controller.abort(), timeout);\n\n const res = await fetch(url, {\n ...options,\n signal: controller.signal,\n });\n\n clearTimeout(id);\n return res;\n}\n\n/**\n * Creates an invisible anchor with a `_blank` target and clicks it. \n * Contrary to `window.open()`, this has a lesser chance to get blocked by the browser's popup blocker and doesn't open the URL as a new window. \n * \n * This function has to be run in relatively quick succession in response to a user interaction event, else the browser might reject it.\n */\nexport function openInNewTab(href: string) {\n const openElem = document.createElement(\"a\");\n Object.assign(openElem, {\n className: \"userutils-open-in-new-tab\",\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n href,\n });\n openElem.style.display = \"none\";\n\n document.body.appendChild(openElem);\n openElem.click();\n // timeout just to be safe\n setTimeout(openElem.remove, 50);\n}\n\n/**\n * Intercepts the specified event on the passed object and prevents it from being called if the called `predicate` function returns a truthy value. \n * Calling this function will set the `stackTraceLimit` to 1000 to ensure the stack trace is preserved.\n */\nexport function interceptEvent<TEvtObj extends EventTarget>(eventObject: TEvtObj, eventName: Parameters<TEvtObj[\"addEventListener\"]>[0], predicate: () => boolean) { \n // default is between 10 and 100 on conventional browsers so this should hopefully be more than enough\n // @ts-ignore\n if(Error.stackTraceLimit < 1000) {\n // @ts-ignore\n Error.stackTraceLimit = 1000;\n }\n\n (function(original: typeof eventObject.addEventListener) {\n // @ts-ignore\n element.__proto__.addEventListener = function(...args: Parameters<typeof eventObject.addEventListener>) {\n if(args[0] === eventName && predicate())\n return;\n else\n return original.apply(this, args);\n };\n // @ts-ignore\n })(eventObject.__proto__.addEventListener);\n}\n\n/**\n * Intercepts the specified event on the window object and prevents it from being called if the called `predicate` function returns a truthy value. \n * Calling this function will set the `stackTraceLimit` to 1000 to ensure the stack trace is preserved.\n */\nexport function interceptWindowEvent(eventName: keyof WindowEventMap, predicate: () => boolean) { \n return interceptEvent(getUnsafeWindow(), eventName, predicate);\n}\n","import { SelectorExistsOpts } from \"./types\";\n\n/**\n * Calls the `listener` as soon as the `selector` exists in the DOM. \n * Listeners are deleted when they are called once, unless `options.continuous` is set. \n * Multiple listeners with the same selector may be registered.\n * @template TElem The type of element that this selector will return - FIXME: listener inferring doesn't work when this generic is given\n */\nexport function onSelector<TElem = HTMLElement, TOpts extends SelectorExistsOpts = SelectorExistsOpts>(\n options: TOpts,\n listener: (element: TOpts[\"all\"] extends true ? (TElem extends HTMLElement ? NodeListOf<TElem> : TElem) : TElem) => void,\n) {\n // TODO:\n void [options, listener];\n}\n\n/** Removes all listeners registered in `onSelector()` with a matching selector property */\nexport function removeOnSelector(selector: string) {\n // TODO:\n void [selector];\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../lib/utils.ts","../lib/onSelector.ts"],"names":["element"],"mappings":"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","sourcesContent":["import type { FetchAdvancedOpts } from \"./types\";\n\n/**\n * Automatically appends an `s` to the passed `word`, if `num` is not equal to 1\n * @param word A word in singular form, to auto-convert to plural\n * @param num If this is an array or NodeList, the amount of items is used\n */\nexport function autoPlural(word: string, num: number | unknown[] | NodeList) {\n if(Array.isArray(num) || num instanceof NodeList)\n num = num.length;\n return `${word}${num === 1 ? \"\" : \"s\"}`;\n}\n\n/** Ensures the passed `value` always stays between `min` and `max` */\nexport function clamp(value: number, min: number, max: number) {\n return Math.max(Math.min(value, max), min);\n}\n\n/** Pauses async execution for the specified time in ms */\nexport function pauseFor(time: number) {\n return new Promise((res) => {\n setTimeout(res, time);\n });\n}\n\n/**\n * Calls the passed `func` after the specified `timeout` in ms. \n * Any subsequent calls to this function will reset the timer and discard previous calls.\n */\nexport function debounce<TFunc extends (...args: TArgs[]) => void, TArgs = any>(func: TFunc, timeout = 300) { // eslint-disable-line @typescript-eslint/no-explicit-any\n let timer: number | undefined;\n return function(...args: TArgs[]) {\n clearTimeout(timer);\n timer = setTimeout(() => func.apply(this, args), timeout) as unknown as number;\n };\n}\n\n/**\n * Returns `unsafeWindow` if the `@grant unsafeWindow` is given, otherwise falls back to the regular `window`\n */\nexport function getUnsafeWindow() {\n try {\n // throws ReferenceError if the \"@grant unsafeWindow\" isn't present\n return unsafeWindow;\n }\n catch(e) {\n return window;\n }\n}\n\n/**\n * Inserts `afterElement` as a sibling just after the provided `beforeElement`\n * @returns Returns the `afterElement`\n */\nexport function insertAfter(beforeElement: HTMLElement, afterElement: HTMLElement) {\n beforeElement.parentNode?.insertBefore(afterElement, beforeElement.nextSibling);\n return afterElement;\n}\n\n/**\n * Adds a parent container around the provided element\n * @returns Returns the new parent element\n */\nexport function addParent(element: HTMLElement, newParent: HTMLElement) {\n const oldParent = element.parentNode;\n\n if(!oldParent)\n throw new Error(\"Element doesn't have a parent node\");\n\n oldParent.replaceChild(newParent, element);\n newParent.appendChild(element);\n\n return newParent;\n}\n\n/**\n * Adds global CSS style in the form of a `<style>` element in the document's `<head>` \n * This needs to be run after the `DOMContentLoaded` event has fired on the document object (or instantly if `@run-at document-end` is used).\n * @param style CSS string\n */\nexport function addGlobalStyle(style: string) {\n const styleElem = document.createElement(\"style\");\n styleElem.innerHTML = style;\n document.head.appendChild(styleElem);\n}\n\n/**\n * Preloads an array of image URLs so they can be loaded instantly from the browser cache later on\n * @param rejects If set to `true`, the returned PromiseSettledResults will contain rejections for any of the images that failed to load\n * @returns Returns an array of `PromiseSettledResult` - each resolved result will contain the loaded image element, while each rejected result will contain an `ErrorEvent`\n */\nexport function preloadImages(srcUrls: string[], rejects = false) {\n const promises = srcUrls.map(src => new Promise((res, rej) => {\n const image = new Image();\n image.src = src;\n image.addEventListener(\"load\", () => res(image));\n image.addEventListener(\"error\", (evt) => rejects && rej(evt));\n }));\n\n return Promise.allSettled(promises);\n}\n\n/** Calls the fetch API with special options like a timeout */\nexport async function fetchAdvanced(url: string, options: FetchAdvancedOpts = {}) {\n const { timeout = 10000 } = options;\n\n const controller = new AbortController();\n const id = setTimeout(() => controller.abort(), timeout);\n\n const res = await fetch(url, {\n ...options,\n signal: controller.signal,\n });\n\n clearTimeout(id);\n return res;\n}\n\n/**\n * Creates an invisible anchor with a `_blank` target and clicks it. \n * Contrary to `window.open()`, this has a lesser chance to get blocked by the browser's popup blocker and doesn't open the URL as a new window. \n * \n * This function has to be run in relatively quick succession in response to a user interaction event, else the browser might reject it.\n */\nexport function openInNewTab(href: string) {\n const openElem = document.createElement(\"a\");\n Object.assign(openElem, {\n className: \"userutils-open-in-new-tab\",\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n href,\n });\n openElem.style.display = \"none\";\n\n document.body.appendChild(openElem);\n openElem.click();\n // timeout just to be safe\n setTimeout(openElem.remove, 50);\n}\n\n/**\n * Intercepts the specified event on the passed object and prevents it from being called if the called `predicate` function returns a truthy value. \n * Calling this function will set the `stackTraceLimit` to 1000 to ensure the stack trace is preserved.\n */\nexport function interceptEvent<TEvtObj extends EventTarget>(eventObject: TEvtObj, eventName: Parameters<TEvtObj[\"addEventListener\"]>[0], predicate: () => boolean) { \n // default is between 10 and 100 on conventional browsers so this should hopefully be more than enough\n // @ts-ignore\n if(Error.stackTraceLimit < 1000) {\n // @ts-ignore\n Error.stackTraceLimit = 1000;\n }\n\n (function(original: typeof eventObject.addEventListener) {\n // @ts-ignore\n element.__proto__.addEventListener = function(...args: Parameters<typeof eventObject.addEventListener>) {\n if(args[0] === eventName && predicate())\n return;\n else\n return original.apply(this, args);\n };\n // @ts-ignore\n })(eventObject.__proto__.addEventListener);\n}\n\n/**\n * Intercepts the specified event on the window object and prevents it from being called if the called `predicate` function returns a truthy value. \n * Calling this function will set the `stackTraceLimit` to 1000 to ensure the stack trace is preserved.\n */\nexport function interceptWindowEvent(eventName: keyof WindowEventMap, predicate: () => boolean) { \n return interceptEvent(getUnsafeWindow(), eventName, predicate);\n}\n","import { SelectorExistsOpts } from \"./types\";\n\n/**\n * Calls the `listener` as soon as the `selector` exists in the DOM. \n * Listeners are deleted when they are called once, unless `options.continuous` is set. \n * Multiple listeners with the same selector may be registered.\n * @template TElem The type of element that this selector will return - FIXME: listener inferring doesn't work when this generic is given\n */\nexport function onSelector<TElem = HTMLElement, TOpts extends SelectorExistsOpts = SelectorExistsOpts>(\n options: TOpts,\n listener: (element: TOpts[\"all\"] extends true ? (TElem extends HTMLElement ? NodeListOf<TElem> : TElem) : TElem) => void,\n) {\n // TODO:\n void [options, listener];\n}\n\n/** Removes all listeners registered in `onSelector()` with a matching selector property */\nexport function removeOnSelector(selector: string) {\n // TODO:\n void [selector];\n}\n"]}