@sv443-network/userutils 0.5.2 → 1.0.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 +17 -0
- package/README.md +270 -59
- package/dist/index.js +25 -24
- package/dist/index.mjs +2 -2
- package/dist/lib/array.d.ts +11 -0
- package/dist/lib/config.d.ts +83 -0
- package/dist/lib/dom.d.ts +69 -0
- package/dist/lib/index.d.ts +6 -0
- package/dist/lib/math.d.ts +11 -0
- package/dist/lib/misc.d.ts +20 -0
- package/dist/lib/onSelector.d.ts +40 -0
- package/package.json +15 -11
- package/dist/index.d.mts +0 -155
- package/dist/index.d.ts +0 -155
package/dist/index.js
CHANGED
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var v=Object.defineProperty,x=Object.defineProperties;var w=Object.getOwnPropertyDescriptors;var h=Object.getOwnPropertySymbols;var M=Object.prototype.hasOwnProperty,O=Object.prototype.propertyIsEnumerable;var p=(t,e,n)=>e in t?v(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,f=(t,e)=>{for(var n in e||(e={}))M.call(e,n)&&p(t,n,e[n]);if(h)for(var n of h(e))O.call(e,n)&&p(t,n,e[n]);return t},b=(t,e)=>x(t,w(e));var m=(t,e,n)=>(p(t,typeof e!="symbol"?e+"":e,n),n);var l=(t,e,n)=>new Promise((r,i)=>{var o=s=>{try{u(n.next(s));}catch(c){i(c);}},a=s=>{try{u(n.throw(s));}catch(c){i(c);}},u=s=>s.done?r(s.value):Promise.resolve(s.value).then(o,a);u((n=n.apply(t,e)).next());});function D(t,e,n){return Math.max(Math.min(t,n),e)}function L(t,e,n,r,i){return Number(e)===0&&Number(r)===0?t*(i/n):(t-e)*((i-r)/(n-e))+r}function g(...t){let e,n;if(typeof t[0]=="number"&&typeof t[1]=="number")[e,n]=t;else if(typeof t[0]=="number"&&typeof t[1]!="number")e=0,n=t[0];else throw new TypeError(`Wrong parameter(s) provided - expected: "number" and "number|undefined", got: "${typeof t[0]}" and "${typeof t[1]}"`);if(e=Number(e),n=Number(n),isNaN(e)||isNaN(n))throw new TypeError(`Parameters "min" and "max" can't be NaN`);if(e>n)throw new TypeError(`Parameter "min" can't be bigger than "max"`);return Math.floor(Math.random()*(n-e+1))+e}function V(t){return T(t)[0]}function T(t){if(t.length===0)return [void 0,void 0];let e=g(t.length-1);return [t[e],e]}function $(t){let[e,n]=T(t);if(n!==void 0)return t.splice(n,1),e}function k(t){let e=[...t];if(t.length===0)return t;for(let n=e.length-1;n>0;n--){let r=Math.floor(g(0,1e4)/1e4*(n+1));[e[n],e[r]]=[e[r],e[n]];}return e}var y=class{constructor(e){m(this,"id");m(this,"formatVersion");m(this,"defaultConfig");m(this,"cachedConfig");m(this,"migrations");this.id=e.id,this.formatVersion=e.formatVersion,this.defaultConfig=e.defaultConfig,this.cachedConfig=e.defaultConfig,this.migrations=e.migrations;}loadData(){return l(this,null,function*(){try{let e=yield GM.getValue(`_uucfg-${this.id}`,this.defaultConfig),n=Number(yield GM.getValue(`_uucfgver-${this.id}`));if(typeof e!="string")return yield this.saveDefaultData(),this.defaultConfig;isNaN(n)&&(yield GM.setValue(`_uucfgver-${this.id}`,n=this.formatVersion));let r=JSON.parse(e);return n<this.formatVersion&&this.migrations&&(r=yield this.runMigrations(r,n)),this.cachedConfig=typeof r=="object"?r:void 0}catch(e){return yield this.saveDefaultData(),this.defaultConfig}})}getData(){return this.deepCopy(this.cachedConfig)}setData(e){return this.cachedConfig=e,new Promise(n=>l(this,null,function*(){yield Promise.allSettled([GM.setValue(`_uucfg-${this.id}`,JSON.stringify(e)),GM.setValue(`_uucfgver-${this.id}`,this.formatVersion)]),n();}))}saveDefaultData(){return l(this,null,function*(){return this.cachedConfig=this.defaultConfig,new Promise(e=>l(this,null,function*(){yield Promise.allSettled([GM.setValue(`_uucfg-${this.id}`,JSON.stringify(this.defaultConfig)),GM.setValue(`_uucfgver-${this.id}`,this.formatVersion)]),e();}))})}deleteConfig(){return l(this,null,function*(){yield Promise.allSettled([GM.deleteValue(`_uucfg-${this.id}`),GM.deleteValue(`_uucfgver-${this.id}`)]);})}runMigrations(e,n){return l(this,null,function*(){if(!this.migrations)return e;let r=e,i=Object.entries(this.migrations).sort(([a],[u])=>Number(a)-Number(u)),o=n;for(let[a,u]of i){let s=Number(a);if(n<this.formatVersion&&n<s)try{let c=u(r);r=c instanceof Promise?yield c:c,o=n=s;}catch(c){console.error(`Error while running migration function for format version ${a}:`,c);}}return yield Promise.allSettled([GM.setValue(`_uucfg-${this.id}`,JSON.stringify(r)),GM.setValue(`_uucfgver-${this.id}`,o)]),r})}deepCopy(e){return JSON.parse(JSON.stringify(e))}};function S(){try{return unsafeWindow}catch(t){return window}}function R(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 j(t){let e=document.createElement("style");e.innerHTML=t,document.head.appendChild(e);}function F(t,e=!1){let n=t.map(r=>new Promise((i,o)=>{let a=new Image;a.src=r,a.addEventListener("load",()=>i(a)),a.addEventListener("error",u=>e&&o(u));}));return Promise.allSettled(n)}function J(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 N(t,e,n){typeof Error.stackTraceLimit=="number"&&Error.stackTraceLimit<1e3&&(Error.stackTraceLimit=1e3),function(r){t.__proto__.addEventListener=function(...i){var a,u;let o=typeof i[1]=="function"?i[1]:(u=(a=i[1])==null?void 0:a.handleEvent)!=null?u:()=>{};i[1]=function(...s){if(!(i[0]===e&&n(Array.isArray(s)?s[0]:s)))return o.apply(this,s)},r.apply(this,i);};}(t.__proto__.addEventListener);}function W(t,e){return N(S(),t,e)}function B(t,e=1){let n=new(window.AudioContext||window.webkitAudioContext),r={mediaElement:t,amplify:i=>{r.gain.gain.value=i;},getAmpLevel:()=>r.gain.gain.value,context:n,source:n.createMediaElementSource(t),gain:n.createGain()};return r.source.connect(r.gain),r.gain.connect(n.destination),r.amplify(e),r}function K(t,e){return (Array.isArray(e)||e instanceof NodeList)&&(e=e.length),`${t}${e===1?"":"s"}`}function z(t){return new Promise(e=>{setTimeout(()=>e(),t);})}function U(t,e=300){let n;return function(...r){clearTimeout(n),n=setTimeout(()=>t.apply(this,r),e);}}function Q(n){return l(this,arguments,function*(t,e={}){let{timeout:r=1e4}=e,i=new AbortController,o=setTimeout(()=>i.abort(),r),a=yield fetch(t,b(f({},e),{signal:i.signal}));return clearTimeout(o),a})}var d=new Map;function Z(t,e){let n=[];d.has(t)&&(n=d.get(t)),n.push(e),d.set(t,n),E(t,n);}function ee(t){return d.delete(t)}function E(t,e){let n=[];if(e.forEach((r,i)=>{try{let o=r.all?document.querySelectorAll(t):document.querySelector(t);(o!==null&&o instanceof NodeList&&o.length>0||o!==null)&&(r.listener(o),r.continuous||n.push(i));}catch(o){console.error(`Couldn't call listener for selector '${t}'`,o);}}),n.length>0){let r=e.filter((i,o)=>!n.includes(o));r.length===0?d.delete(t):d.set(t,r);}}function te(t={}){new MutationObserver(()=>{for(let[n,r]of d.entries())E(n,r);}).observe(document.body,f({subtree:!0,childList:!0},t));}function ne(){return d}
|
|
4
4
|
|
|
5
|
-
exports.
|
|
6
|
-
exports.
|
|
7
|
-
exports.
|
|
8
|
-
exports.
|
|
9
|
-
exports.
|
|
10
|
-
exports.
|
|
11
|
-
exports.
|
|
12
|
-
exports.
|
|
13
|
-
exports.
|
|
14
|
-
exports.
|
|
15
|
-
exports.
|
|
16
|
-
exports.
|
|
17
|
-
exports.
|
|
18
|
-
exports.
|
|
19
|
-
exports.
|
|
20
|
-
exports.
|
|
21
|
-
exports.
|
|
22
|
-
exports.
|
|
23
|
-
exports.
|
|
24
|
-
exports.
|
|
5
|
+
exports.ConfigManager = y;
|
|
6
|
+
exports.addGlobalStyle = j;
|
|
7
|
+
exports.addParent = _;
|
|
8
|
+
exports.amplifyMedia = B;
|
|
9
|
+
exports.autoPlural = K;
|
|
10
|
+
exports.clamp = D;
|
|
11
|
+
exports.debounce = U;
|
|
12
|
+
exports.fetchAdvanced = Q;
|
|
13
|
+
exports.getSelectorMap = ne;
|
|
14
|
+
exports.getUnsafeWindow = S;
|
|
15
|
+
exports.initOnSelector = te;
|
|
16
|
+
exports.insertAfter = R;
|
|
17
|
+
exports.interceptEvent = N;
|
|
18
|
+
exports.interceptWindowEvent = W;
|
|
19
|
+
exports.mapRange = L;
|
|
20
|
+
exports.onSelector = Z;
|
|
21
|
+
exports.openInNewTab = J;
|
|
22
|
+
exports.pauseFor = z;
|
|
23
|
+
exports.preloadImages = F;
|
|
24
|
+
exports.randRange = g;
|
|
25
|
+
exports.randomItem = V;
|
|
25
26
|
exports.randomItemIndex = T;
|
|
26
|
-
exports.randomizeArray =
|
|
27
|
-
exports.removeOnSelector =
|
|
28
|
-
exports.takeRandomItem =
|
|
27
|
+
exports.randomizeArray = k;
|
|
28
|
+
exports.removeOnSelector = ee;
|
|
29
|
+
exports.takeRandomItem = $;
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
1
|
+
var v=Object.defineProperty,x=Object.defineProperties;var w=Object.getOwnPropertyDescriptors;var h=Object.getOwnPropertySymbols;var M=Object.prototype.hasOwnProperty,O=Object.prototype.propertyIsEnumerable;var p=(t,e,n)=>e in t?v(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,f=(t,e)=>{for(var n in e||(e={}))M.call(e,n)&&p(t,n,e[n]);if(h)for(var n of h(e))O.call(e,n)&&p(t,n,e[n]);return t},b=(t,e)=>x(t,w(e));var m=(t,e,n)=>(p(t,typeof e!="symbol"?e+"":e,n),n);var l=(t,e,n)=>new Promise((r,i)=>{var o=s=>{try{u(n.next(s));}catch(c){i(c);}},a=s=>{try{u(n.throw(s));}catch(c){i(c);}},u=s=>s.done?r(s.value):Promise.resolve(s.value).then(o,a);u((n=n.apply(t,e)).next());});function D(t,e,n){return Math.max(Math.min(t,n),e)}function L(t,e,n,r,i){return Number(e)===0&&Number(r)===0?t*(i/n):(t-e)*((i-r)/(n-e))+r}function g(...t){let e,n;if(typeof t[0]=="number"&&typeof t[1]=="number")[e,n]=t;else if(typeof t[0]=="number"&&typeof t[1]!="number")e=0,n=t[0];else throw new TypeError(`Wrong parameter(s) provided - expected: "number" and "number|undefined", got: "${typeof t[0]}" and "${typeof t[1]}"`);if(e=Number(e),n=Number(n),isNaN(e)||isNaN(n))throw new TypeError(`Parameters "min" and "max" can't be NaN`);if(e>n)throw new TypeError(`Parameter "min" can't be bigger than "max"`);return Math.floor(Math.random()*(n-e+1))+e}function V(t){return T(t)[0]}function T(t){if(t.length===0)return [void 0,void 0];let e=g(t.length-1);return [t[e],e]}function $(t){let[e,n]=T(t);if(n!==void 0)return t.splice(n,1),e}function k(t){let e=[...t];if(t.length===0)return t;for(let n=e.length-1;n>0;n--){let r=Math.floor(g(0,1e4)/1e4*(n+1));[e[n],e[r]]=[e[r],e[n]];}return e}var y=class{constructor(e){m(this,"id");m(this,"formatVersion");m(this,"defaultConfig");m(this,"cachedConfig");m(this,"migrations");this.id=e.id,this.formatVersion=e.formatVersion,this.defaultConfig=e.defaultConfig,this.cachedConfig=e.defaultConfig,this.migrations=e.migrations;}loadData(){return l(this,null,function*(){try{let e=yield GM.getValue(`_uucfg-${this.id}`,this.defaultConfig),n=Number(yield GM.getValue(`_uucfgver-${this.id}`));if(typeof e!="string")return yield this.saveDefaultData(),this.defaultConfig;isNaN(n)&&(yield GM.setValue(`_uucfgver-${this.id}`,n=this.formatVersion));let r=JSON.parse(e);return n<this.formatVersion&&this.migrations&&(r=yield this.runMigrations(r,n)),this.cachedConfig=typeof r=="object"?r:void 0}catch(e){return yield this.saveDefaultData(),this.defaultConfig}})}getData(){return this.deepCopy(this.cachedConfig)}setData(e){return this.cachedConfig=e,new Promise(n=>l(this,null,function*(){yield Promise.allSettled([GM.setValue(`_uucfg-${this.id}`,JSON.stringify(e)),GM.setValue(`_uucfgver-${this.id}`,this.formatVersion)]),n();}))}saveDefaultData(){return l(this,null,function*(){return this.cachedConfig=this.defaultConfig,new Promise(e=>l(this,null,function*(){yield Promise.allSettled([GM.setValue(`_uucfg-${this.id}`,JSON.stringify(this.defaultConfig)),GM.setValue(`_uucfgver-${this.id}`,this.formatVersion)]),e();}))})}deleteConfig(){return l(this,null,function*(){yield Promise.allSettled([GM.deleteValue(`_uucfg-${this.id}`),GM.deleteValue(`_uucfgver-${this.id}`)]);})}runMigrations(e,n){return l(this,null,function*(){if(!this.migrations)return e;let r=e,i=Object.entries(this.migrations).sort(([a],[u])=>Number(a)-Number(u)),o=n;for(let[a,u]of i){let s=Number(a);if(n<this.formatVersion&&n<s)try{let c=u(r);r=c instanceof Promise?yield c:c,o=n=s;}catch(c){console.error(`Error while running migration function for format version ${a}:`,c);}}return yield Promise.allSettled([GM.setValue(`_uucfg-${this.id}`,JSON.stringify(r)),GM.setValue(`_uucfgver-${this.id}`,o)]),r})}deepCopy(e){return JSON.parse(JSON.stringify(e))}};function S(){try{return unsafeWindow}catch(t){return window}}function R(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 j(t){let e=document.createElement("style");e.innerHTML=t,document.head.appendChild(e);}function F(t,e=!1){let n=t.map(r=>new Promise((i,o)=>{let a=new Image;a.src=r,a.addEventListener("load",()=>i(a)),a.addEventListener("error",u=>e&&o(u));}));return Promise.allSettled(n)}function J(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 N(t,e,n){typeof Error.stackTraceLimit=="number"&&Error.stackTraceLimit<1e3&&(Error.stackTraceLimit=1e3),function(r){t.__proto__.addEventListener=function(...i){var a,u;let o=typeof i[1]=="function"?i[1]:(u=(a=i[1])==null?void 0:a.handleEvent)!=null?u:()=>{};i[1]=function(...s){if(!(i[0]===e&&n(Array.isArray(s)?s[0]:s)))return o.apply(this,s)},r.apply(this,i);};}(t.__proto__.addEventListener);}function W(t,e){return N(S(),t,e)}function B(t,e=1){let n=new(window.AudioContext||window.webkitAudioContext),r={mediaElement:t,amplify:i=>{r.gain.gain.value=i;},getAmpLevel:()=>r.gain.gain.value,context:n,source:n.createMediaElementSource(t),gain:n.createGain()};return r.source.connect(r.gain),r.gain.connect(n.destination),r.amplify(e),r}function K(t,e){return (Array.isArray(e)||e instanceof NodeList)&&(e=e.length),`${t}${e===1?"":"s"}`}function z(t){return new Promise(e=>{setTimeout(()=>e(),t);})}function U(t,e=300){let n;return function(...r){clearTimeout(n),n=setTimeout(()=>t.apply(this,r),e);}}function Q(n){return l(this,arguments,function*(t,e={}){let{timeout:r=1e4}=e,i=new AbortController,o=setTimeout(()=>i.abort(),r),a=yield fetch(t,b(f({},e),{signal:i.signal}));return clearTimeout(o),a})}var d=new Map;function Z(t,e){let n=[];d.has(t)&&(n=d.get(t)),n.push(e),d.set(t,n),E(t,n);}function ee(t){return d.delete(t)}function E(t,e){let n=[];if(e.forEach((r,i)=>{try{let o=r.all?document.querySelectorAll(t):document.querySelector(t);(o!==null&&o instanceof NodeList&&o.length>0||o!==null)&&(r.listener(o),r.continuous||n.push(i));}catch(o){console.error(`Couldn't call listener for selector '${t}'`,o);}}),n.length>0){let r=e.filter((i,o)=>!n.includes(o));r.length===0?d.delete(t):d.set(t,r);}}function te(t={}){new MutationObserver(()=>{for(let[n,r]of d.entries())E(n,r);}).observe(document.body,f({subtree:!0,childList:!0},t));}function ne(){return d}
|
|
2
2
|
|
|
3
|
-
export {
|
|
3
|
+
export { y as ConfigManager, j as addGlobalStyle, _ as addParent, B as amplifyMedia, K as autoPlural, D as clamp, U as debounce, Q as fetchAdvanced, ne as getSelectorMap, S as getUnsafeWindow, te as initOnSelector, R as insertAfter, N as interceptEvent, W as interceptWindowEvent, L as mapRange, Z as onSelector, J as openInNewTab, z as pauseFor, F as preloadImages, g as randRange, V as randomItem, T as randomItemIndex, k as randomizeArray, ee as removeOnSelector, $ as takeRandomItem };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Returns a random item from the passed array */
|
|
2
|
+
export declare function randomItem<T = unknown>(array: T[]): T | undefined;
|
|
3
|
+
/**
|
|
4
|
+
* Returns a tuple of a random item and its index from the passed array
|
|
5
|
+
* Returns `[undefined, undefined]` if the passed array is empty
|
|
6
|
+
*/
|
|
7
|
+
export declare function randomItemIndex<T = unknown>(array: T[]): [item?: T, index?: number];
|
|
8
|
+
/** Returns a random item from the passed array and mutates the array to remove the item */
|
|
9
|
+
export declare function takeRandomItem<T = unknown>(arr: T[]): T | undefined;
|
|
10
|
+
/** Returns a copy of the array with its items in a random order */
|
|
11
|
+
export declare function randomizeArray<T = unknown>(array: T[]): T[];
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/** Function that takes the data in the old format and returns the data in the new format. Also supports an asynchronous migration. */
|
|
2
|
+
type MigrationFunc = <TOldData = any>(oldData: TOldData) => any | Promise<any>;
|
|
3
|
+
/** Dictionary of format version numbers and the function that migrates to them from the previous whole integer */
|
|
4
|
+
type MigrationsDict = Record<number, MigrationFunc>;
|
|
5
|
+
/** Options for the ConfigManager instance */
|
|
6
|
+
export interface ConfigManagerOptions<TData> {
|
|
7
|
+
/** A unique internal ID for this configuration - choose wisely as changing it is not supported yet. */
|
|
8
|
+
id: string;
|
|
9
|
+
/**
|
|
10
|
+
* The default config data object to use if no data is saved in persistent storage yet.
|
|
11
|
+
* Until the data is loaded from persistent storage with `loadData()`, this will be the data returned by `getData()`
|
|
12
|
+
*
|
|
13
|
+
* ⚠️ This has to be an object that can be serialized to JSON, so no functions or circular references are allowed, they will cause unexpected behavior.
|
|
14
|
+
*/
|
|
15
|
+
defaultConfig: TData;
|
|
16
|
+
/**
|
|
17
|
+
* An incremental, whole integer version number of the current format of config data.
|
|
18
|
+
* If the format of the data is changed, this number should be incremented, in which case all necessary functions of the migrations dictionary will be run consecutively.
|
|
19
|
+
*
|
|
20
|
+
* ⚠️ Never decrement this number and optimally don't skip any numbers either!
|
|
21
|
+
*/
|
|
22
|
+
formatVersion: number;
|
|
23
|
+
/**
|
|
24
|
+
* A dictionary of functions that can be used to migrate data from older versions of the configuration to newer ones.
|
|
25
|
+
* The keys of the dictionary should be the format version that the functions can migrate to, from the previous whole integer value.
|
|
26
|
+
* The values should be functions that take the data in the old format and return the data in the new format.
|
|
27
|
+
* The functions will be run in order from the oldest to the newest version.
|
|
28
|
+
* If the current format version is not in the dictionary, no migrations will be run.
|
|
29
|
+
*/
|
|
30
|
+
migrations?: MigrationsDict;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Manages a user configuration that is cached in memory and persistently saved across sessions.
|
|
34
|
+
* Supports migrating data from older versions of the configuration to newer ones and populating the cache with default data if no persistent data is found.
|
|
35
|
+
*
|
|
36
|
+
* ⚠️ Requires the directives `@grant GM.getValue` and `@grant GM.setValue`
|
|
37
|
+
* ⚠️ Make sure to call `loadData()` at least once after creating an instance, or the returned data will be the same as `options.defaultConfig`
|
|
38
|
+
*
|
|
39
|
+
* @template TData The type of the data that is saved in persistent storage (will be automatically inferred from `config.defaultConfig`) - this should also be the type of the data format associated with the current `options.formatVersion`
|
|
40
|
+
*/
|
|
41
|
+
export declare class ConfigManager<TData = any> {
|
|
42
|
+
readonly id: string;
|
|
43
|
+
readonly formatVersion: number;
|
|
44
|
+
readonly defaultConfig: TData;
|
|
45
|
+
private cachedConfig;
|
|
46
|
+
private migrations?;
|
|
47
|
+
/**
|
|
48
|
+
* Creates an instance of ConfigManager to manage a user configuration that is cached in memory and persistently saved across sessions.
|
|
49
|
+
* Supports migrating data from older versions of the configuration to newer ones and populating the cache with default data if no persistent data is found.
|
|
50
|
+
*
|
|
51
|
+
* ⚠️ Requires the directives `@grant GM.getValue` and `@grant GM.setValue`
|
|
52
|
+
* ⚠️ Make sure to call `loadData()` at least once after creating an instance, or the returned data will be the same as `options.defaultConfig`
|
|
53
|
+
*
|
|
54
|
+
* @template TData The type of the data that is saved in persistent storage (will be automatically inferred from `config.defaultConfig`) - this should also be the type of the data format associated with the current `options.formatVersion`
|
|
55
|
+
* @param options The options for this ConfigManager instance
|
|
56
|
+
*/
|
|
57
|
+
constructor(options: ConfigManagerOptions<TData>);
|
|
58
|
+
/**
|
|
59
|
+
* Loads the data saved in persistent storage into the in-memory cache and also returns it.
|
|
60
|
+
* Automatically populates persistent storage with default data if it doesn't contain any data yet.
|
|
61
|
+
* Also runs all necessary migration functions if the data format has changed since the last time the data was saved.
|
|
62
|
+
*/
|
|
63
|
+
loadData(): Promise<TData>;
|
|
64
|
+
/** Returns a copy of the data from the in-memory cache. Use `loadData()` to get fresh data from persistent storage (usually not necessary since the cache should always exactly reflect persistent storage). */
|
|
65
|
+
getData(): TData;
|
|
66
|
+
/** Saves the data synchronously to the in-memory cache and asynchronously to the persistent storage */
|
|
67
|
+
setData(data: TData): Promise<void>;
|
|
68
|
+
/** Saves the default configuration data passed in the constructor synchronously to the in-memory cache and asynchronously to persistent storage */
|
|
69
|
+
saveDefaultData(): Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* Call this method to clear all persistently stored data associated with this ConfigManager instance.
|
|
72
|
+
* The in-memory cache will be left untouched, so you may still access the data with `getData()`.
|
|
73
|
+
* Calling `loadData()` or `setData()` after this method was called will recreate persistent storage with the cached or default data.
|
|
74
|
+
*
|
|
75
|
+
* ⚠️ This requires the additional directive `@grant GM.deleteValue`
|
|
76
|
+
*/
|
|
77
|
+
deleteConfig(): Promise<void>;
|
|
78
|
+
/** Runs all necessary migration functions consecutively - may be overwritten in a subclass */
|
|
79
|
+
protected runMigrations(oldData: any, oldFmtVer: number): Promise<TData>;
|
|
80
|
+
/** Copies a JSON-compatible object and loses its internal references */
|
|
81
|
+
private deepCopy;
|
|
82
|
+
}
|
|
83
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns `unsafeWindow` if the `@grant unsafeWindow` is given, otherwise falls back to the regular `window`
|
|
3
|
+
*/
|
|
4
|
+
export declare function getUnsafeWindow(): Window;
|
|
5
|
+
/**
|
|
6
|
+
* Inserts `afterElement` as a sibling just after the provided `beforeElement`
|
|
7
|
+
* @returns Returns the `afterElement`
|
|
8
|
+
*/
|
|
9
|
+
export declare function insertAfter(beforeElement: HTMLElement, afterElement: HTMLElement): HTMLElement;
|
|
10
|
+
/**
|
|
11
|
+
* Adds a parent container around the provided element
|
|
12
|
+
* @returns Returns the new parent element
|
|
13
|
+
*/
|
|
14
|
+
export declare function addParent(element: HTMLElement, newParent: HTMLElement): HTMLElement;
|
|
15
|
+
/**
|
|
16
|
+
* Adds global CSS style in the form of a `<style>` element in the document's `<head>`
|
|
17
|
+
* This needs to be run after the `DOMContentLoaded` event has fired on the document object (or instantly if `@run-at document-end` is used).
|
|
18
|
+
* @param style CSS string
|
|
19
|
+
*/
|
|
20
|
+
export declare function addGlobalStyle(style: string): void;
|
|
21
|
+
/**
|
|
22
|
+
* Preloads an array of image URLs so they can be loaded instantly from the browser cache later on
|
|
23
|
+
* @param rejects If set to `true`, the returned PromiseSettledResults will contain rejections for any of the images that failed to load
|
|
24
|
+
* @returns Returns an array of `PromiseSettledResult` - each resolved result will contain the loaded image element, while each rejected result will contain an `ErrorEvent`
|
|
25
|
+
*/
|
|
26
|
+
export declare function preloadImages(srcUrls: string[], rejects?: boolean): Promise<PromiseSettledResult<unknown>[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Creates an invisible anchor with a `_blank` target and clicks it.
|
|
29
|
+
* 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.
|
|
30
|
+
*
|
|
31
|
+
* This function has to be run in response to a user interaction event, else the browser might reject it.
|
|
32
|
+
*/
|
|
33
|
+
export declare function openInNewTab(href: string): void;
|
|
34
|
+
/**
|
|
35
|
+
* Intercepts the specified event on the passed object and prevents it from being called if the called `predicate` function returns a truthy value.
|
|
36
|
+
* 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.
|
|
37
|
+
* Calling this function will set the `Error.stackTraceLimit` to 1000 to ensure the stack trace is preserved.
|
|
38
|
+
*/
|
|
39
|
+
export declare function interceptEvent<TEvtObj extends EventTarget, TPredicateEvt extends Event>(eventObject: TEvtObj, eventName: Parameters<TEvtObj["addEventListener"]>[0], predicate: (event: TPredicateEvt) => boolean): void;
|
|
40
|
+
/**
|
|
41
|
+
* Intercepts the specified event on the window object and prevents it from being called if the called `predicate` function returns a truthy value.
|
|
42
|
+
* 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.
|
|
43
|
+
* Calling this function will set the `Error.stackTraceLimit` to 1000 to ensure the stack trace is preserved.
|
|
44
|
+
*/
|
|
45
|
+
export declare function interceptWindowEvent<TEvtKey extends keyof WindowEventMap>(eventName: TEvtKey, predicate: (event: WindowEventMap[TEvtKey]) => boolean): void;
|
|
46
|
+
/**
|
|
47
|
+
* Amplifies the gain of the passed media element's audio by the specified multiplier.
|
|
48
|
+
* This function supports any media element like `<audio>` or `<video>`
|
|
49
|
+
*
|
|
50
|
+
* This function has to be run in response to a user interaction event, else the browser will reject it because of the strict autoplay policy.
|
|
51
|
+
*
|
|
52
|
+
* @returns Returns an object with the following properties:
|
|
53
|
+
* | Property | Description |
|
|
54
|
+
* | :-- | :-- |
|
|
55
|
+
* | `mediaElement` | The passed media element |
|
|
56
|
+
* | `amplify()` | A function to change the amplification level |
|
|
57
|
+
* | `getAmpLevel()` | A function to return the current amplification level |
|
|
58
|
+
* | `context` | The AudioContext instance |
|
|
59
|
+
* | `source` | The MediaElementSourceNode instance |
|
|
60
|
+
* | `gain` | The GainNode instance |
|
|
61
|
+
*/
|
|
62
|
+
export declare function amplifyMedia<TElem extends HTMLMediaElement>(mediaElement: TElem, multiplier?: number): {
|
|
63
|
+
mediaElement: TElem;
|
|
64
|
+
amplify: (multiplier: number) => void;
|
|
65
|
+
getAmpLevel: () => number;
|
|
66
|
+
context: AudioContext;
|
|
67
|
+
source: MediaElementAudioSourceNode;
|
|
68
|
+
gain: GainNode;
|
|
69
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Ensures the passed `value` always stays between `min` and `max` */
|
|
2
|
+
export declare function clamp(value: number, min: number, max: number): number;
|
|
3
|
+
/**
|
|
4
|
+
* Transforms the value parameter from the numerical range `range_1_min-range_1_max` to the numerical range `range_2_min-range_2_max`
|
|
5
|
+
* For example, you can map the value 2 in the range of 0-5 to the range of 0-10 and you'd get a 4 as a result.
|
|
6
|
+
*/
|
|
7
|
+
export declare function mapRange(value: number, range_1_min: number, range_1_max: number, range_2_min: number, range_2_max: number): number;
|
|
8
|
+
/** Returns a random number between `min` and `max` (inclusive) */
|
|
9
|
+
export declare function randRange(min: number, max: number): number;
|
|
10
|
+
/** Returns a random number between 0 and `max` (inclusive) */
|
|
11
|
+
export declare function randRange(max: number): number;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Automatically appends an `s` to the passed `word`, if `num` is not equal to 1
|
|
3
|
+
* @param word A word in singular form, to auto-convert to plural
|
|
4
|
+
* @param num If this is an array or NodeList, the amount of items is used
|
|
5
|
+
*/
|
|
6
|
+
export declare function autoPlural(word: string, num: number | unknown[] | NodeList): string;
|
|
7
|
+
/** Pauses async execution for the specified time in ms */
|
|
8
|
+
export declare function pauseFor(time: number): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* Calls the passed `func` after the specified `timeout` in ms (defaults to 300).
|
|
11
|
+
* Any subsequent calls to this function will reset the timer and discard previous calls.
|
|
12
|
+
*/
|
|
13
|
+
export declare function debounce<TFunc extends (...args: TArgs[]) => void, TArgs = any>(func: TFunc, timeout?: number): (...args: TArgs[]) => void;
|
|
14
|
+
/** Options for the `fetchAdvanced()` function */
|
|
15
|
+
export type FetchAdvancedOpts = RequestInit & Partial<{
|
|
16
|
+
/** Timeout in milliseconds after which the fetch call will be canceled with an AbortController signal */
|
|
17
|
+
timeout: number;
|
|
18
|
+
}>;
|
|
19
|
+
/** Calls the fetch API with special options like a timeout */
|
|
20
|
+
export declare function fetchAdvanced(url: string, options?: FetchAdvancedOpts): Promise<Response>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** Options for the `onSelector()` function */
|
|
2
|
+
export type OnSelectorOpts<TElem extends Element = HTMLElement> = SelectorOptsOne<TElem> | SelectorOptsAll<TElem>;
|
|
3
|
+
type SelectorOptsOne<TElem extends Element> = SelectorOptsBase & {
|
|
4
|
+
/** Whether to use `querySelectorAll()` instead - default is false */
|
|
5
|
+
all?: false;
|
|
6
|
+
/** Gets called whenever the selector was found in the DOM */
|
|
7
|
+
listener: (element: TElem) => void;
|
|
8
|
+
};
|
|
9
|
+
type SelectorOptsAll<TElem extends Element> = SelectorOptsBase & {
|
|
10
|
+
/** Whether to use `querySelectorAll()` instead - default is false */
|
|
11
|
+
all: true;
|
|
12
|
+
/** Gets called whenever the selector was found in the DOM */
|
|
13
|
+
listener: (elements: NodeListOf<TElem>) => void;
|
|
14
|
+
};
|
|
15
|
+
type SelectorOptsBase = {
|
|
16
|
+
/** Whether to call the listener continuously instead of once - default is false */
|
|
17
|
+
continuous?: boolean;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Calls the `listener` as soon as the `selector` exists in the DOM.
|
|
21
|
+
* Listeners are deleted when they are called once, unless `options.continuous` is set.
|
|
22
|
+
* Multiple listeners with the same selector may be registered.
|
|
23
|
+
* @param selector The selector to listen for
|
|
24
|
+
* @param options Used for switching to `querySelectorAll()` and for calling the listener continuously
|
|
25
|
+
* @template TElem The type of element that the listener will return as its argument (defaults to the generic HTMLElement)
|
|
26
|
+
*/
|
|
27
|
+
export declare function onSelector<TElem extends Element = HTMLElement>(selector: string, options: OnSelectorOpts<TElem>): void;
|
|
28
|
+
/**
|
|
29
|
+
* Removes all listeners registered in `onSelector()` that have the given selector
|
|
30
|
+
* @returns Returns true when all listeners with the associated selector were found and removed, false otherwise
|
|
31
|
+
*/
|
|
32
|
+
export declare function removeOnSelector(selector: string): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Initializes a MutationObserver that checks for all registered selectors whenever an element is added to or removed from the `<body>`
|
|
35
|
+
* @param options For fine-tuning what triggers the MutationObserver's checking function - `subtree` and `childList` are set to true by default
|
|
36
|
+
*/
|
|
37
|
+
export declare function initOnSelector(options?: MutationObserverInit): void;
|
|
38
|
+
/** Returns all currently registered selectors, as a map of selector strings to their associated options */
|
|
39
|
+
export declare function getSelectorMap(): Map<string, OnSelectorOpts<HTMLElement>[]>;
|
|
40
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sv443-network/userutils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.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",
|
|
7
|
-
"types": "dist/index.d.ts",
|
|
7
|
+
"types": "dist/lib/index.d.ts",
|
|
8
8
|
"scripts": {
|
|
9
|
-
"lint": "tsc && eslint .",
|
|
10
|
-
"build-
|
|
11
|
-
"build-
|
|
12
|
-
"build": "
|
|
13
|
-
"
|
|
14
|
-
"
|
|
9
|
+
"lint": "tsc --noEmit && eslint .",
|
|
10
|
+
"build-types": "tsc --emitDeclarationOnly --declaration --outDir dist",
|
|
11
|
+
"build-common": "tsup lib/index.ts --format cjs,esm --clean --treeshake",
|
|
12
|
+
"build-global": "tsup lib/index.ts --format cjs,esm,iife --treeshake --onSuccess \"npm run post-build-global\"",
|
|
13
|
+
"build": "npm run build-common -- --minify && npm run build-types",
|
|
14
|
+
"post-build-global": "npm run node-ts -- ./tools/post-build-global.mts",
|
|
15
|
+
"dev": "npm run build-common -- --sourcemap --watch --onSuccess \"npm run build-types\"",
|
|
16
|
+
"publish-package": "npm run build && changeset publish",
|
|
17
|
+
"node-ts": "node --no-warnings=ExperimentalWarning --enable-source-maps --loader ts-node/esm"
|
|
15
18
|
},
|
|
16
19
|
"repository": {
|
|
17
20
|
"type": "git",
|
|
@@ -29,13 +32,15 @@
|
|
|
29
32
|
"bugs": {
|
|
30
33
|
"url": "https://github.com/Sv443-Network/UserUtils/issues"
|
|
31
34
|
},
|
|
32
|
-
"homepage": "https://github.com/Sv443-Network/UserUtils
|
|
35
|
+
"homepage": "https://github.com/Sv443-Network/UserUtils",
|
|
33
36
|
"devDependencies": {
|
|
34
37
|
"@changesets/cli": "^2.26.2",
|
|
35
38
|
"@types/greasemonkey": "^4.0.4",
|
|
39
|
+
"@types/node": "^20.5.9",
|
|
36
40
|
"@typescript-eslint/eslint-plugin": "^6.2.1",
|
|
37
41
|
"@typescript-eslint/parser": "^6.2.1",
|
|
38
42
|
"eslint": "^8.46.0",
|
|
43
|
+
"ts-node": "^10.9.1",
|
|
39
44
|
"tslib": "^2.6.1",
|
|
40
45
|
"tsup": "^7.2.0",
|
|
41
46
|
"typescript": "^5.1.6"
|
|
@@ -43,8 +48,7 @@
|
|
|
43
48
|
"files": [
|
|
44
49
|
"/dist/index.js",
|
|
45
50
|
"/dist/index.mjs",
|
|
46
|
-
"/dist/
|
|
47
|
-
"/dist/index.d.mts",
|
|
51
|
+
"/dist/lib/**.*",
|
|
48
52
|
"/package.json",
|
|
49
53
|
"/README.md",
|
|
50
54
|
"/CHANGELOG.md",
|
package/dist/index.d.mts
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
/** Returns a random item from the passed array */
|
|
2
|
-
declare function randomItem<T = unknown>(array: T[]): T | undefined;
|
|
3
|
-
/**
|
|
4
|
-
* Returns a tuple of a random item and its index from the passed array
|
|
5
|
-
* Returns `[undefined, undefined]` if the passed array is empty
|
|
6
|
-
*/
|
|
7
|
-
declare function randomItemIndex<T = unknown>(array: T[]): [item?: T, index?: number];
|
|
8
|
-
/** Returns a random item from the passed array and mutates the array to remove the item */
|
|
9
|
-
declare function takeRandomItem<T = unknown>(arr: T[]): T | undefined;
|
|
10
|
-
/** Returns a copy of the array with its items in a random order */
|
|
11
|
-
declare function randomizeArray<T = unknown>(array: T[]): T[];
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Returns `unsafeWindow` if the `@grant unsafeWindow` is given, otherwise falls back to the regular `window`
|
|
15
|
-
*/
|
|
16
|
-
declare function getUnsafeWindow(): Window;
|
|
17
|
-
/**
|
|
18
|
-
* Inserts `afterElement` as a sibling just after the provided `beforeElement`
|
|
19
|
-
* @returns Returns the `afterElement`
|
|
20
|
-
*/
|
|
21
|
-
declare function insertAfter(beforeElement: HTMLElement, afterElement: HTMLElement): HTMLElement;
|
|
22
|
-
/**
|
|
23
|
-
* Adds a parent container around the provided element
|
|
24
|
-
* @returns Returns the new parent element
|
|
25
|
-
*/
|
|
26
|
-
declare function addParent(element: HTMLElement, newParent: HTMLElement): HTMLElement;
|
|
27
|
-
/**
|
|
28
|
-
* Adds global CSS style in the form of a `<style>` element in the document's `<head>`
|
|
29
|
-
* This needs to be run after the `DOMContentLoaded` event has fired on the document object (or instantly if `@run-at document-end` is used).
|
|
30
|
-
* @param style CSS string
|
|
31
|
-
*/
|
|
32
|
-
declare function addGlobalStyle(style: string): void;
|
|
33
|
-
/**
|
|
34
|
-
* Preloads an array of image URLs so they can be loaded instantly from the browser cache later on
|
|
35
|
-
* @param rejects If set to `true`, the returned PromiseSettledResults will contain rejections for any of the images that failed to load
|
|
36
|
-
* @returns Returns an array of `PromiseSettledResult` - each resolved result will contain the loaded image element, while each rejected result will contain an `ErrorEvent`
|
|
37
|
-
*/
|
|
38
|
-
declare function preloadImages(srcUrls: string[], rejects?: boolean): Promise<PromiseSettledResult<unknown>[]>;
|
|
39
|
-
/**
|
|
40
|
-
* Creates an invisible anchor with a `_blank` target and clicks it.
|
|
41
|
-
* 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.
|
|
42
|
-
*
|
|
43
|
-
* This function has to be run in response to a user interaction event, else the browser might reject it.
|
|
44
|
-
*/
|
|
45
|
-
declare function openInNewTab(href: string): void;
|
|
46
|
-
/**
|
|
47
|
-
* Intercepts the specified event on the passed object and prevents it from being called if the called `predicate` function returns a truthy value.
|
|
48
|
-
* 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.
|
|
49
|
-
* Calling this function will set the `Error.stackTraceLimit` to 1000 to ensure the stack trace is preserved.
|
|
50
|
-
*/
|
|
51
|
-
declare function interceptEvent<TEvtObj extends EventTarget>(eventObject: TEvtObj, eventName: Parameters<TEvtObj["addEventListener"]>[0], predicate: () => boolean): void;
|
|
52
|
-
/**
|
|
53
|
-
* Intercepts the specified event on the window object and prevents it from being called if the called `predicate` function returns a truthy value.
|
|
54
|
-
* 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.
|
|
55
|
-
* Calling this function will set the `Error.stackTraceLimit` to 1000 to ensure the stack trace is preserved.
|
|
56
|
-
*/
|
|
57
|
-
declare function interceptWindowEvent(eventName: keyof WindowEventMap, predicate: () => boolean): void;
|
|
58
|
-
/**
|
|
59
|
-
* Amplifies the gain of the passed media element's audio by the specified multiplier.
|
|
60
|
-
* This function supports any media element like `<audio>` or `<video>`
|
|
61
|
-
*
|
|
62
|
-
* This function has to be run in response to a user interaction event, else the browser will reject it because of the strict autoplay policy.
|
|
63
|
-
*
|
|
64
|
-
* @returns Returns an object with the following properties:
|
|
65
|
-
* | Property | Description |
|
|
66
|
-
* | :-- | :-- |
|
|
67
|
-
* | `mediaElement` | The passed media element |
|
|
68
|
-
* | `amplify()` | A function to change the amplification level |
|
|
69
|
-
* | `getAmpLevel()` | A function to return the current amplification level |
|
|
70
|
-
* | `context` | The AudioContext instance |
|
|
71
|
-
* | `source` | The MediaElementSourceNode instance |
|
|
72
|
-
* | `gain` | The GainNode instance |
|
|
73
|
-
*/
|
|
74
|
-
declare function amplifyMedia<TElem extends HTMLMediaElement>(mediaElement: TElem, multiplier?: number): {
|
|
75
|
-
mediaElement: TElem;
|
|
76
|
-
amplify: (multiplier: number) => void;
|
|
77
|
-
getAmpLevel: () => number;
|
|
78
|
-
context: AudioContext;
|
|
79
|
-
source: MediaElementAudioSourceNode;
|
|
80
|
-
gain: GainNode;
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
/** Ensures the passed `value` always stays between `min` and `max` */
|
|
84
|
-
declare function clamp(value: number, min: number, max: number): number;
|
|
85
|
-
/**
|
|
86
|
-
* Transforms the value parameter from the numerical range `range_1_min-range_1_max` to the numerical range `range_2_min-range_2_max`
|
|
87
|
-
* For example, you can map the value 2 in the range of 0-5 to the range of 0-10 and you'd get a 4 as a result.
|
|
88
|
-
*/
|
|
89
|
-
declare function mapRange(value: number, range_1_min: number, range_1_max: number, range_2_min: number, range_2_max: number): number;
|
|
90
|
-
/** Returns a random number between `min` and `max` (inclusive) */
|
|
91
|
-
declare function randRange(min: number, max: number): number;
|
|
92
|
-
/** Returns a random number between 0 and `max` (inclusive) */
|
|
93
|
-
declare function randRange(max: number): number;
|
|
94
|
-
|
|
95
|
-
type OnSelectorOpts<TElem extends Element = HTMLElement> = SelectorOptsOne<TElem> | SelectorOptsAll<TElem>;
|
|
96
|
-
type SelectorOptsOne<TElem extends Element> = SelectorOptsBase & {
|
|
97
|
-
/** Whether to use `querySelectorAll()` instead - default is false */
|
|
98
|
-
all?: false;
|
|
99
|
-
/** Gets called whenever the selector was found in the DOM */
|
|
100
|
-
listener: (element: TElem) => void;
|
|
101
|
-
};
|
|
102
|
-
type SelectorOptsAll<TElem extends Element> = SelectorOptsBase & {
|
|
103
|
-
/** Whether to use `querySelectorAll()` instead - default is false */
|
|
104
|
-
all: true;
|
|
105
|
-
/** Gets called whenever the selector was found in the DOM */
|
|
106
|
-
listener: (elements: NodeListOf<TElem>) => void;
|
|
107
|
-
};
|
|
108
|
-
type SelectorOptsBase = {
|
|
109
|
-
/** Whether to call the listener continuously instead of once - default is false */
|
|
110
|
-
continuous?: boolean;
|
|
111
|
-
};
|
|
112
|
-
type FetchAdvancedOpts = RequestInit & Partial<{
|
|
113
|
-
/** Timeout in milliseconds after which the fetch call will be canceled with an AbortController signal */
|
|
114
|
-
timeout: number;
|
|
115
|
-
}>;
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Automatically appends an `s` to the passed `word`, if `num` is not equal to 1
|
|
119
|
-
* @param word A word in singular form, to auto-convert to plural
|
|
120
|
-
* @param num If this is an array or NodeList, the amount of items is used
|
|
121
|
-
*/
|
|
122
|
-
declare function autoPlural(word: string, num: number | unknown[] | NodeList): string;
|
|
123
|
-
/** Pauses async execution for the specified time in ms */
|
|
124
|
-
declare function pauseFor(time: number): Promise<unknown>;
|
|
125
|
-
/**
|
|
126
|
-
* Calls the passed `func` after the specified `timeout` in ms.
|
|
127
|
-
* Any subsequent calls to this function will reset the timer and discard previous calls.
|
|
128
|
-
*/
|
|
129
|
-
declare function debounce<TFunc extends (...args: TArgs[]) => void, TArgs = any>(func: TFunc, timeout?: number): (...args: TArgs[]) => void;
|
|
130
|
-
/** Calls the fetch API with special options like a timeout */
|
|
131
|
-
declare function fetchAdvanced(url: string, options?: FetchAdvancedOpts): Promise<Response>;
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Calls the `listener` as soon as the `selector` exists in the DOM.
|
|
135
|
-
* Listeners are deleted when they are called once, unless `options.continuous` is set.
|
|
136
|
-
* Multiple listeners with the same selector may be registered.
|
|
137
|
-
* @param selector The selector to listen for
|
|
138
|
-
* @param options Used for switching to `querySelectorAll()` and for calling the listener continuously
|
|
139
|
-
* @template TElem The type of element that the listener will return as its argument (defaults to the generic HTMLElement)
|
|
140
|
-
*/
|
|
141
|
-
declare function onSelector<TElem extends Element = HTMLElement>(selector: string, options: OnSelectorOpts<TElem>): void;
|
|
142
|
-
/**
|
|
143
|
-
* Removes all listeners registered in `onSelector()` that have the given selector
|
|
144
|
-
* @returns Returns true when all listeners with the associated selector were found and removed, false otherwise
|
|
145
|
-
*/
|
|
146
|
-
declare function removeOnSelector(selector: string): boolean;
|
|
147
|
-
/**
|
|
148
|
-
* Initializes a MutationObserver that checks for all registered selectors whenever an element is added to or removed from the `<body>`
|
|
149
|
-
* @param options For fine-tuning what triggers the MutationObserver's checking function - `subtree` and `childList` are set to true by default
|
|
150
|
-
*/
|
|
151
|
-
declare function initOnSelector(options?: MutationObserverInit): void;
|
|
152
|
-
/** Returns all currently registered selectors, as a map of selector strings to their associated options */
|
|
153
|
-
declare function getSelectorMap(): Map<string, OnSelectorOpts[]>;
|
|
154
|
-
|
|
155
|
-
export { FetchAdvancedOpts, OnSelectorOpts, addGlobalStyle, addParent, amplifyMedia, autoPlural, clamp, debounce, fetchAdvanced, getSelectorMap, getUnsafeWindow, initOnSelector, insertAfter, interceptEvent, interceptWindowEvent, mapRange, onSelector, openInNewTab, pauseFor, preloadImages, randRange, randomItem, randomItemIndex, randomizeArray, removeOnSelector, takeRandomItem };
|