@sv443-network/userutils 0.5.1 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @sv443-network/userutils
2
2
 
3
+ ## 0.5.3
4
+
5
+ ### Patch Changes
6
+
7
+ - f97dae6: change bundling process
8
+
9
+ ## 0.5.2
10
+
11
+ ### Patch Changes
12
+
13
+ - 18d4a10: make npm bundle smaller
14
+
3
15
  ## 0.5.1
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  <div style="text-align: center;" align="center">
2
2
 
3
3
  ## UserUtils
4
- Library with various utilities for userscripts - register listeners for when CSS selectors exist, intercept events, modify the DOM more easily and more.
4
+ Zero-dependency library with various utilities for userscripts - register listeners for when CSS selectors exist, intercept events, modify the DOM more easily and more.
5
5
  Contains builtin TypeScript declarations. Webpack compatible and supports ESM and CJS.
6
6
  If you like using this library, please consider [supporting the development ❤️](https://github.com/sponsors/Sv443)
7
7
 
package/dist/index.js CHANGED
@@ -1,28 +1,28 @@
1
1
  'use strict';
2
2
 
3
- var h=Object.defineProperty,y=Object.defineProperties;var g=Object.getOwnPropertyDescriptors;var p=Object.getOwnPropertySymbols;var w=Object.prototype.hasOwnProperty,v=Object.prototype.propertyIsEnumerable;var f=(n,e,t)=>e in n?h(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t,m=(n,e)=>{for(var t in e||(e={}))w.call(e,t)&&f(n,t,e[t]);if(p)for(var t of p(e))v.call(e,t)&&f(n,t,e[t]);return n},b=(n,e)=>y(n,g(e));var x=(n,e,t)=>new Promise((r,o)=>{var i=s=>{try{a(t.next(s));}catch(l){o(l);}},u=s=>{try{a(t.throw(s));}catch(l){o(l);}},a=s=>s.done?r(s.value):Promise.resolve(s.value).then(i,u);a((t=t.apply(n,e)).next());});function A(n,e,t){return Math.max(Math.min(n,t),e)}function N(n,e,t,r,o){return Number(e)===0&&Number(r)===0?n*(o/t):(n-e)*((o-r)/(t-e))+r}function d(...n){let e,t;if(typeof n[0]=="number"&&typeof n[1]=="number")[e,t]=n;else if(typeof n[0]=="number"&&typeof n[1]!="number")e=0,t=n[0];else throw new TypeError(`Wrong parameter(s) provided - expected: "number" and "number|undefined", got: "${typeof n[0]}" and "${typeof n[1]}"`);if(e=Number(e),t=Number(t),isNaN(e)||isNaN(t))throw new TypeError(`Parameters "min" and "max" can't be NaN`);if(e>t)throw new TypeError(`Parameter "min" can't be bigger than "max"`);return Math.floor(Math.random()*(t-e+1))+e}function H(n){return T(n)[0]}function T(n){if(n.length===0)return [void 0,void 0];let e=d(n.length-1);return [n[e],e]}function I(n){let[e,t]=T(n);if(t!==void 0)return n.splice(t,1),e}function C(n){let e=[...n];if(n.length===0)return n;for(let t=e.length-1;t>0;t--){let r=Math.floor(d(0,1e4)/1e4*(t+1));[e[t],e[r]]=[e[r],e[t]];}return e}function L(){try{return unsafeWindow}catch(n){return window}}function j(n,e){var t;return (t=n.parentNode)==null||t.insertBefore(e,n.nextSibling),e}function R(n,e){let t=n.parentNode;if(!t)throw new Error("Element doesn't have a parent node");return t.replaceChild(e,n),e.appendChild(n),e}function F(n){let e=document.createElement("style");e.innerHTML=n,document.head.appendChild(e);}function W(n,e=!1){let t=n.map(r=>new Promise((o,i)=>{let u=new Image;u.src=r,u.addEventListener("load",()=>o(u)),u.addEventListener("error",a=>e&&i(a));}));return Promise.allSettled(t)}function $(n){let e=document.createElement("a");Object.assign(e,{className:"userutils-open-in-new-tab",target:"_blank",rel:"noopener noreferrer",href:n}),e.style.display="none",document.body.appendChild(e),e.click(),setTimeout(e.remove,50);}function M(n,e,t){typeof Error.stackTraceLimit=="number"&&Error.stackTraceLimit<1e3&&(Error.stackTraceLimit=1e3),function(r){element.__proto__.addEventListener=function(...o){if(!(o[0]===e&&t()))return r.apply(this,o)};}(n.__proto__.addEventListener);}function q(n,e){return M(L(),n,e)}function G(n,e=1){let t=new(window.AudioContext||window.webkitAudioContext),r={mediaElement:n,amplify:o=>{r.gain.gain.value=o;},getAmpLevel:()=>r.gain.gain.value,context:t,source:t.createMediaElementSource(n),gain:t.createGain()};return r.source.connect(r.gain),r.gain.connect(t.destination),r.amplify(e),r}function B(n,e){return (Array.isArray(e)||e instanceof NodeList)&&(e=e.length),`${n}${e===1?"":"s"}`}function U(n){return new Promise(e=>{setTimeout(e,n);})}function D(n,e=300){let t;return function(...r){clearTimeout(t),t=setTimeout(()=>n.apply(this,r),e);}}function J(t){return x(this,arguments,function*(n,e={}){let{timeout:r=1e4}=e,o=new AbortController,i=setTimeout(()=>o.abort(),r),u=yield fetch(n,b(m({},e),{signal:o.signal}));return clearTimeout(i),u})}var c=new Map;function V(n,e){let t=[];c.has(n)&&(t=c.get(n)),t.push(e),c.set(n,t),E(n,t);}function X(n){return c.delete(n)}function E(n,e){let t=[];if(e.forEach((r,o)=>{try{let i=r.all?document.querySelectorAll(n):document.querySelector(n);(i!==null&&i instanceof NodeList&&i.length>0||i!==null)&&(r.listener(i),r.continuous||t.push(o));}catch(i){console.error(`Couldn't call listener for selector '${n}'`,i);}}),t.length>0){let r=e.filter((o,i)=>!t.includes(i));r.length===0?c.delete(n):c.set(n,r);}}function Y(n={}){new MutationObserver(()=>{for(let[t,r]of c.entries())E(t,r);}).observe(document.body,m({subtree:!0,childList:!0},n));}function Z(){return c}
3
+ var h=Object.defineProperty,y=Object.defineProperties;var g=Object.getOwnPropertyDescriptors;var p=Object.getOwnPropertySymbols;var w=Object.prototype.hasOwnProperty,v=Object.prototype.propertyIsEnumerable;var f=(t,e,n)=>e in t?h(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,c=(t,e)=>{for(var n in e||(e={}))w.call(e,n)&&f(t,n,e[n]);if(p)for(var n of p(e))v.call(e,n)&&f(t,n,e[n]);return t},b=(t,e)=>y(t,g(e));var T=(t,e,n)=>new Promise((r,o)=>{var i=s=>{try{a(n.next(s));}catch(m){o(m);}},u=s=>{try{a(n.throw(s));}catch(m){o(m);}},a=s=>s.done?r(s.value):Promise.resolve(s.value).then(i,u);a((n=n.apply(t,e)).next());});function S(t,e,n){return Math.max(Math.min(t,n),e)}function A(t,e,n,r,o){return Number(e)===0&&Number(r)===0?t*(o/n):(t-e)*((o-r)/(n-e))+r}function d(...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 H(t){return x(t)[0]}function x(t){if(t.length===0)return [void 0,void 0];let e=d(t.length-1);return [t[e],e]}function I(t){let[e,n]=x(t);if(n!==void 0)return t.splice(n,1),e}function P(t){let e=[...t];if(t.length===0)return t;for(let n=e.length-1;n>0;n--){let r=Math.floor(d(0,1e4)/1e4*(n+1));[e[n],e[r]]=[e[r],e[n]];}return e}function O(){try{return unsafeWindow}catch(t){return window}}function j(t,e){var n;return (n=t.parentNode)==null||n.insertBefore(e,t.nextSibling),e}function R(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 F(t){let e=document.createElement("style");e.innerHTML=t,document.head.appendChild(e);}function W(t,e=!1){let n=t.map(r=>new Promise((o,i)=>{let u=new Image;u.src=r,u.addEventListener("load",()=>o(u)),u.addEventListener("error",a=>e&&i(a));}));return Promise.allSettled(n)}function $(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 L(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 B(t,e){return L(O(),t,e)}function q(t,e=1){let n=new(window.AudioContext||window.webkitAudioContext),r={mediaElement:t,amplify:o=>{r.gain.gain.value=o;},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 z(t,e){return (Array.isArray(e)||e instanceof NodeList)&&(e=e.length),`${t}${e===1?"":"s"}`}function U(t){return new Promise(e=>{setTimeout(e,t);})}function D(t,e=300){let n;return function(...r){clearTimeout(n),n=setTimeout(()=>t.apply(this,r),e);}}function J(n){return T(this,arguments,function*(t,e={}){let{timeout:r=1e4}=e,o=new AbortController,i=setTimeout(()=>o.abort(),r),u=yield fetch(t,b(c({},e),{signal:o.signal}));return clearTimeout(i),u})}var l=new Map;function V(t,e){let n=[];l.has(t)&&(n=l.get(t)),n.push(e),l.set(t,n),E(t,n);}function X(t){return l.delete(t)}function E(t,e){let n=[];if(e.forEach((r,o)=>{try{let i=r.all?document.querySelectorAll(t):document.querySelector(t);(i!==null&&i instanceof NodeList&&i.length>0||i!==null)&&(r.listener(i),r.continuous||n.push(o));}catch(i){console.error(`Couldn't call listener for selector '${t}'`,i);}}),n.length>0){let r=e.filter((o,i)=>!n.includes(i));r.length===0?l.delete(t):l.set(t,r);}}function Y(t={}){new MutationObserver(()=>{for(let[n,r]of l.entries())E(n,r);}).observe(document.body,c({subtree:!0,childList:!0},t));}function Z(){return l}
4
4
 
5
5
  exports.addGlobalStyle = F;
6
6
  exports.addParent = R;
7
- exports.amplifyMedia = G;
8
- exports.autoPlural = B;
9
- exports.clamp = A;
7
+ exports.amplifyMedia = q;
8
+ exports.autoPlural = z;
9
+ exports.clamp = S;
10
10
  exports.debounce = D;
11
11
  exports.fetchAdvanced = J;
12
12
  exports.getSelectorMap = Z;
13
- exports.getUnsafeWindow = L;
13
+ exports.getUnsafeWindow = O;
14
14
  exports.initOnSelector = Y;
15
15
  exports.insertAfter = j;
16
- exports.interceptEvent = M;
17
- exports.interceptWindowEvent = q;
18
- exports.mapRange = N;
16
+ exports.interceptEvent = L;
17
+ exports.interceptWindowEvent = B;
18
+ exports.mapRange = A;
19
19
  exports.onSelector = V;
20
20
  exports.openInNewTab = $;
21
21
  exports.pauseFor = U;
22
22
  exports.preloadImages = W;
23
23
  exports.randRange = d;
24
24
  exports.randomItem = H;
25
- exports.randomItemIndex = T;
26
- exports.randomizeArray = C;
25
+ exports.randomItemIndex = x;
26
+ exports.randomizeArray = P;
27
27
  exports.removeOnSelector = X;
28
28
  exports.takeRandomItem = I;
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- var h=Object.defineProperty,y=Object.defineProperties;var g=Object.getOwnPropertyDescriptors;var p=Object.getOwnPropertySymbols;var w=Object.prototype.hasOwnProperty,v=Object.prototype.propertyIsEnumerable;var f=(n,e,t)=>e in n?h(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t,m=(n,e)=>{for(var t in e||(e={}))w.call(e,t)&&f(n,t,e[t]);if(p)for(var t of p(e))v.call(e,t)&&f(n,t,e[t]);return n},b=(n,e)=>y(n,g(e));var x=(n,e,t)=>new Promise((r,o)=>{var i=s=>{try{a(t.next(s));}catch(l){o(l);}},u=s=>{try{a(t.throw(s));}catch(l){o(l);}},a=s=>s.done?r(s.value):Promise.resolve(s.value).then(i,u);a((t=t.apply(n,e)).next());});function A(n,e,t){return Math.max(Math.min(n,t),e)}function N(n,e,t,r,o){return Number(e)===0&&Number(r)===0?n*(o/t):(n-e)*((o-r)/(t-e))+r}function d(...n){let e,t;if(typeof n[0]=="number"&&typeof n[1]=="number")[e,t]=n;else if(typeof n[0]=="number"&&typeof n[1]!="number")e=0,t=n[0];else throw new TypeError(`Wrong parameter(s) provided - expected: "number" and "number|undefined", got: "${typeof n[0]}" and "${typeof n[1]}"`);if(e=Number(e),t=Number(t),isNaN(e)||isNaN(t))throw new TypeError(`Parameters "min" and "max" can't be NaN`);if(e>t)throw new TypeError(`Parameter "min" can't be bigger than "max"`);return Math.floor(Math.random()*(t-e+1))+e}function H(n){return T(n)[0]}function T(n){if(n.length===0)return [void 0,void 0];let e=d(n.length-1);return [n[e],e]}function I(n){let[e,t]=T(n);if(t!==void 0)return n.splice(t,1),e}function C(n){let e=[...n];if(n.length===0)return n;for(let t=e.length-1;t>0;t--){let r=Math.floor(d(0,1e4)/1e4*(t+1));[e[t],e[r]]=[e[r],e[t]];}return e}function L(){try{return unsafeWindow}catch(n){return window}}function j(n,e){var t;return (t=n.parentNode)==null||t.insertBefore(e,n.nextSibling),e}function R(n,e){let t=n.parentNode;if(!t)throw new Error("Element doesn't have a parent node");return t.replaceChild(e,n),e.appendChild(n),e}function F(n){let e=document.createElement("style");e.innerHTML=n,document.head.appendChild(e);}function W(n,e=!1){let t=n.map(r=>new Promise((o,i)=>{let u=new Image;u.src=r,u.addEventListener("load",()=>o(u)),u.addEventListener("error",a=>e&&i(a));}));return Promise.allSettled(t)}function $(n){let e=document.createElement("a");Object.assign(e,{className:"userutils-open-in-new-tab",target:"_blank",rel:"noopener noreferrer",href:n}),e.style.display="none",document.body.appendChild(e),e.click(),setTimeout(e.remove,50);}function M(n,e,t){typeof Error.stackTraceLimit=="number"&&Error.stackTraceLimit<1e3&&(Error.stackTraceLimit=1e3),function(r){element.__proto__.addEventListener=function(...o){if(!(o[0]===e&&t()))return r.apply(this,o)};}(n.__proto__.addEventListener);}function q(n,e){return M(L(),n,e)}function G(n,e=1){let t=new(window.AudioContext||window.webkitAudioContext),r={mediaElement:n,amplify:o=>{r.gain.gain.value=o;},getAmpLevel:()=>r.gain.gain.value,context:t,source:t.createMediaElementSource(n),gain:t.createGain()};return r.source.connect(r.gain),r.gain.connect(t.destination),r.amplify(e),r}function B(n,e){return (Array.isArray(e)||e instanceof NodeList)&&(e=e.length),`${n}${e===1?"":"s"}`}function U(n){return new Promise(e=>{setTimeout(e,n);})}function D(n,e=300){let t;return function(...r){clearTimeout(t),t=setTimeout(()=>n.apply(this,r),e);}}function J(t){return x(this,arguments,function*(n,e={}){let{timeout:r=1e4}=e,o=new AbortController,i=setTimeout(()=>o.abort(),r),u=yield fetch(n,b(m({},e),{signal:o.signal}));return clearTimeout(i),u})}var c=new Map;function V(n,e){let t=[];c.has(n)&&(t=c.get(n)),t.push(e),c.set(n,t),E(n,t);}function X(n){return c.delete(n)}function E(n,e){let t=[];if(e.forEach((r,o)=>{try{let i=r.all?document.querySelectorAll(n):document.querySelector(n);(i!==null&&i instanceof NodeList&&i.length>0||i!==null)&&(r.listener(i),r.continuous||t.push(o));}catch(i){console.error(`Couldn't call listener for selector '${n}'`,i);}}),t.length>0){let r=e.filter((o,i)=>!t.includes(i));r.length===0?c.delete(n):c.set(n,r);}}function Y(n={}){new MutationObserver(()=>{for(let[t,r]of c.entries())E(t,r);}).observe(document.body,m({subtree:!0,childList:!0},n));}function Z(){return c}
1
+ var h=Object.defineProperty,y=Object.defineProperties;var g=Object.getOwnPropertyDescriptors;var p=Object.getOwnPropertySymbols;var w=Object.prototype.hasOwnProperty,v=Object.prototype.propertyIsEnumerable;var f=(t,e,n)=>e in t?h(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,c=(t,e)=>{for(var n in e||(e={}))w.call(e,n)&&f(t,n,e[n]);if(p)for(var n of p(e))v.call(e,n)&&f(t,n,e[n]);return t},b=(t,e)=>y(t,g(e));var T=(t,e,n)=>new Promise((r,o)=>{var i=s=>{try{a(n.next(s));}catch(m){o(m);}},u=s=>{try{a(n.throw(s));}catch(m){o(m);}},a=s=>s.done?r(s.value):Promise.resolve(s.value).then(i,u);a((n=n.apply(t,e)).next());});function S(t,e,n){return Math.max(Math.min(t,n),e)}function A(t,e,n,r,o){return Number(e)===0&&Number(r)===0?t*(o/n):(t-e)*((o-r)/(n-e))+r}function d(...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 H(t){return x(t)[0]}function x(t){if(t.length===0)return [void 0,void 0];let e=d(t.length-1);return [t[e],e]}function I(t){let[e,n]=x(t);if(n!==void 0)return t.splice(n,1),e}function P(t){let e=[...t];if(t.length===0)return t;for(let n=e.length-1;n>0;n--){let r=Math.floor(d(0,1e4)/1e4*(n+1));[e[n],e[r]]=[e[r],e[n]];}return e}function O(){try{return unsafeWindow}catch(t){return window}}function j(t,e){var n;return (n=t.parentNode)==null||n.insertBefore(e,t.nextSibling),e}function R(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 F(t){let e=document.createElement("style");e.innerHTML=t,document.head.appendChild(e);}function W(t,e=!1){let n=t.map(r=>new Promise((o,i)=>{let u=new Image;u.src=r,u.addEventListener("load",()=>o(u)),u.addEventListener("error",a=>e&&i(a));}));return Promise.allSettled(n)}function $(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 L(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 B(t,e){return L(O(),t,e)}function q(t,e=1){let n=new(window.AudioContext||window.webkitAudioContext),r={mediaElement:t,amplify:o=>{r.gain.gain.value=o;},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 z(t,e){return (Array.isArray(e)||e instanceof NodeList)&&(e=e.length),`${t}${e===1?"":"s"}`}function U(t){return new Promise(e=>{setTimeout(e,t);})}function D(t,e=300){let n;return function(...r){clearTimeout(n),n=setTimeout(()=>t.apply(this,r),e);}}function J(n){return T(this,arguments,function*(t,e={}){let{timeout:r=1e4}=e,o=new AbortController,i=setTimeout(()=>o.abort(),r),u=yield fetch(t,b(c({},e),{signal:o.signal}));return clearTimeout(i),u})}var l=new Map;function V(t,e){let n=[];l.has(t)&&(n=l.get(t)),n.push(e),l.set(t,n),E(t,n);}function X(t){return l.delete(t)}function E(t,e){let n=[];if(e.forEach((r,o)=>{try{let i=r.all?document.querySelectorAll(t):document.querySelector(t);(i!==null&&i instanceof NodeList&&i.length>0||i!==null)&&(r.listener(i),r.continuous||n.push(o));}catch(i){console.error(`Couldn't call listener for selector '${t}'`,i);}}),n.length>0){let r=e.filter((o,i)=>!n.includes(i));r.length===0?l.delete(t):l.set(t,r);}}function Y(t={}){new MutationObserver(()=>{for(let[n,r]of l.entries())E(n,r);}).observe(document.body,c({subtree:!0,childList:!0},t));}function Z(){return l}
2
2
 
3
- export { F as addGlobalStyle, R as addParent, G as amplifyMedia, B as autoPlural, A as clamp, D as debounce, J as fetchAdvanced, Z as getSelectorMap, L as getUnsafeWindow, Y as initOnSelector, j as insertAfter, M as interceptEvent, q as interceptWindowEvent, N as mapRange, V as onSelector, $ as openInNewTab, U as pauseFor, W as preloadImages, d as randRange, H as randomItem, T as randomItemIndex, C as randomizeArray, X as removeOnSelector, I as takeRandomItem };
3
+ export { F as addGlobalStyle, R as addParent, q as amplifyMedia, z as autoPlural, S as clamp, D as debounce, J as fetchAdvanced, Z as getSelectorMap, O as getUnsafeWindow, Y as initOnSelector, j as insertAfter, L as interceptEvent, B as interceptWindowEvent, A as mapRange, V as onSelector, $ as openInNewTab, U as pauseFor, W as preloadImages, d as randRange, H as randomItem, x as randomItemIndex, P as randomizeArray, X as removeOnSelector, I 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,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>(eventObject: TEvtObj, eventName: Parameters<TEvtObj["addEventListener"]>[0], predicate: () => 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(eventName: keyof WindowEventMap, predicate: () => 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,5 @@
1
+ export * from "./array";
2
+ export * from "./dom";
3
+ export * from "./math";
4
+ export * from "./misc";
5
+ export * from "./onSelector";
@@ -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,19 @@
1
+ export type FetchAdvancedOpts = RequestInit & Partial<{
2
+ /** Timeout in milliseconds after which the fetch call will be canceled with an AbortController signal */
3
+ timeout: number;
4
+ }>;
5
+ /**
6
+ * Automatically appends an `s` to the passed `word`, if `num` is not equal to 1
7
+ * @param word A word in singular form, to auto-convert to plural
8
+ * @param num If this is an array or NodeList, the amount of items is used
9
+ */
10
+ export declare function autoPlural(word: string, num: number | unknown[] | NodeList): string;
11
+ /** Pauses async execution for the specified time in ms */
12
+ export declare function pauseFor(time: number): Promise<unknown>;
13
+ /**
14
+ * Calls the passed `func` after the specified `timeout` in ms.
15
+ * Any subsequent calls to this function will reset the timer and discard previous calls.
16
+ */
17
+ export declare function debounce<TFunc extends (...args: TArgs[]) => void, TArgs = any>(func: TFunc, timeout?: number): (...args: TArgs[]) => void;
18
+ /** Calls the fetch API with special options like a timeout */
19
+ export declare function fetchAdvanced(url: string, options?: FetchAdvancedOpts): Promise<Response>;
@@ -0,0 +1,39 @@
1
+ export type OnSelectorOpts<TElem extends Element = HTMLElement> = SelectorOptsOne<TElem> | SelectorOptsAll<TElem>;
2
+ type SelectorOptsOne<TElem extends Element> = SelectorOptsBase & {
3
+ /** Whether to use `querySelectorAll()` instead - default is false */
4
+ all?: false;
5
+ /** Gets called whenever the selector was found in the DOM */
6
+ listener: (element: TElem) => void;
7
+ };
8
+ type SelectorOptsAll<TElem extends Element> = SelectorOptsBase & {
9
+ /** Whether to use `querySelectorAll()` instead - default is false */
10
+ all: true;
11
+ /** Gets called whenever the selector was found in the DOM */
12
+ listener: (elements: NodeListOf<TElem>) => void;
13
+ };
14
+ type SelectorOptsBase = {
15
+ /** Whether to call the listener continuously instead of once - default is false */
16
+ continuous?: boolean;
17
+ };
18
+ /**
19
+ * Calls the `listener` as soon as the `selector` exists in the DOM.
20
+ * Listeners are deleted when they are called once, unless `options.continuous` is set.
21
+ * Multiple listeners with the same selector may be registered.
22
+ * @param selector The selector to listen for
23
+ * @param options Used for switching to `querySelectorAll()` and for calling the listener continuously
24
+ * @template TElem The type of element that the listener will return as its argument (defaults to the generic HTMLElement)
25
+ */
26
+ export declare function onSelector<TElem extends Element = HTMLElement>(selector: string, options: OnSelectorOpts<TElem>): void;
27
+ /**
28
+ * Removes all listeners registered in `onSelector()` that have the given selector
29
+ * @returns Returns true when all listeners with the associated selector were found and removed, false otherwise
30
+ */
31
+ export declare function removeOnSelector(selector: string): boolean;
32
+ /**
33
+ * Initializes a MutationObserver that checks for all registered selectors whenever an element is added to or removed from the `<body>`
34
+ * @param options For fine-tuning what triggers the MutationObserver's checking function - `subtree` and `childList` are set to true by default
35
+ */
36
+ export declare function initOnSelector(options?: MutationObserverInit): void;
37
+ /** Returns all currently registered selectors, as a map of selector strings to their associated options */
38
+ export declare function getSelectorMap(): Map<string, OnSelectorOpts<HTMLElement>[]>;
39
+ export {};
package/package.json CHANGED
@@ -1,15 +1,17 @@
1
1
  {
2
2
  "name": "@sv443-network/userutils",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
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-common": "tsup lib/index.ts --format cjs,esm,iife --dts --clean --treeshake",
11
- "build": "npm run build-common -- --minify",
12
- "dev": "npm run build-common -- --sourcemap --watch",
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-iife": "tsup lib/index.ts --format cjs,esm,iife --clean --treeshake --minify",
13
+ "build": "npm run build-common -- --minify && npm run build-types",
14
+ "dev": "npm run build-common -- --sourcemap --watch --onSuccess \"npm run build-types\"",
13
15
  "publish-package": "npm run build && changeset publish"
14
16
  },
15
17
  "repository": {
@@ -39,9 +41,13 @@
39
41
  "tsup": "^7.2.0",
40
42
  "typescript": "^5.1.6"
41
43
  },
42
- "browserslist": [
43
- "last 1 version",
44
- "> 1%",
45
- "not dead"
44
+ "files": [
45
+ "/dist/index.js",
46
+ "/dist/index.mjs",
47
+ "/dist/lib/**.*",
48
+ "/package.json",
49
+ "/README.md",
50
+ "/CHANGELOG.md",
51
+ "/LICENSE.txt"
46
52
  ]
47
53
  }
@@ -1,75 +0,0 @@
1
- ## UserUtils
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 declarations. Webpack compatible and supports ESM and CJS.
4
- Licensed under the [MIT license.](https://github.com/Sv443-Network/UserUtils/blob/main/LICENSE.txt)
5
-
6
- If you like using this library, please consider [supporting the development ❤️](https://github.com/sponsors/Sv443)
7
-
8
- <br>
9
-
10
- ### Full documentation [on GitHub](https://github.com/Sv443-Network/UserUtils#readme)
11
-
12
- <br>
13
-
14
- ## Features:
15
- - DOM:
16
- - [onSelector()](https://github.com/Sv443-Network/UserUtils#onselector) - call a listener once a selector is found in the DOM
17
- - [initOnSelector()](https://github.com/Sv443-Network/UserUtils#initonselector) - needs to be called once to be able to use `onSelector()`
18
- - [getSelectorMap()](https://github.com/Sv443-Network/UserUtils#getselectormap) - returns all currently registered selectors, listeners and options
19
- - [getUnsafeWindow()](https://github.com/Sv443-Network/UserUtils#getunsafewindow) - get the unsafeWindow object or fall back to the regular window object
20
- - [insertAfter()](https://github.com/Sv443-Network/UserUtils#insertafter) - insert an element as a sibling after another element
21
- - [addParent()](https://github.com/Sv443-Network/UserUtils#addparent) - add a parent element around another element
22
- - [addGlobalStyle()](https://github.com/Sv443-Network/UserUtils#addglobalstyle) - add a global style to the page
23
- - [preloadImages()](https://github.com/Sv443-Network/UserUtils#preloadimages) - preload images into the browser cache for faster loading later on
24
- - [openInNewTab()](https://github.com/Sv443-Network/UserUtils#openinnewtab) - open a link in a new tab
25
- - [interceptEvent()](https://github.com/Sv443-Network/UserUtils#interceptevent) - conditionally intercepts events registered by `addEventListener()` on any given EventTarget object
26
- - [interceptWindowEvent()](https://github.com/Sv443-Network/UserUtils#interceptwindowevent) - conditionally intercepts events registered by `addEventListener()` on the window object
27
- - [amplifyMedia()](https://github.com/Sv443-Network/UserUtils#amplifymedia) - amplify an audio or video element's volume past the maximum of 100%
28
- - Math:
29
- - [clamp()](https://github.com/Sv443-Network/UserUtils#clamp) - constrain a number between a min and max value
30
- - [mapRange()](https://github.com/Sv443-Network/UserUtils#maprange) - map a number from one range to the same spot in another range
31
- - [randRange()](https://github.com/Sv443-Network/UserUtils#randrange) - generate a random number between a min and max boundary
32
- - Misc:
33
- - [autoPlural()](https://github.com/Sv443-Network/UserUtils#autoplural) - automatically pluralize a string
34
- - [pauseFor()](https://github.com/Sv443-Network/UserUtils#pausefor) - pause the execution of a function for a given amount of time
35
- - [debounce()](https://github.com/Sv443-Network/UserUtils#debounce) - call a function only once, after a given amount of time
36
- - [fetchAdvanced()](https://github.com/Sv443-Network/UserUtils#fetchadvanced) - wrapper around the fetch API with a timeout option
37
- - Arrays:
38
- - [randomItem()](https://github.com/Sv443-Network/UserUtils#randomitem) - returns a random item from an array
39
- - [randomItemIndex()](https://github.com/Sv443-Network/UserUtils#randomitemindex) - returns a tuple of a random item and its index from an array
40
- - [takeRandomItem()](https://github.com/Sv443-Network/UserUtils#takerandomitem) - returns a random item from an array and mutates it to remove the item
41
- - [randomizeArray()](https://github.com/Sv443-Network/UserUtils#randomizearray) - returns a copy of the array with its items in a random order
42
-
43
- <br><br>
44
-
45
- ## Installation:
46
- - If you are using a bundler like webpack, you can install this package using npm:
47
- ```
48
- npm i @sv443-network/userutils
49
- ```
50
-
51
- Then, import it in your script as usual:
52
- ```ts
53
- import { addGlobalStyle } from "@sv443-network/userutils";
54
- // or
55
- import * as userUtils from "@sv443-network/userutils";
56
- ```
57
-
58
- Shameless plug: I also have a [webpack-based template for userscripts in TypeScript](https://github.com/Sv443/Userscript.ts) that you can use to get started quickly.
59
-
60
- <br>
61
-
62
- - If you are not using a bundler, you can include the latest release from GreasyFork by adding this directive to the userscript header:
63
- ```
64
- // @require https://greasyfork.org/scripts/472956-userutils/code/UserUtils.js
65
- ```
66
-
67
- Then, access the functions on the global variable `UserUtils`:
68
- ```ts
69
- UserUtils.addGlobalStyle("body { background-color: red; }");
70
-
71
- // or using object destructuring:
72
-
73
- const { clamp } = UserUtils;
74
- console.log(clamp(1, 5, 10); // 5
75
- ```
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 };
package/dist/index.d.ts 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 };
@@ -1,33 +0,0 @@
1
- (function (exports) {
2
- 'use strict';
3
-
4
- var h=Object.defineProperty,y=Object.defineProperties;var g=Object.getOwnPropertyDescriptors;var p=Object.getOwnPropertySymbols;var w=Object.prototype.hasOwnProperty,v=Object.prototype.propertyIsEnumerable;var f=(n,e,t)=>e in n?h(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t,m=(n,e)=>{for(var t in e||(e={}))w.call(e,t)&&f(n,t,e[t]);if(p)for(var t of p(e))v.call(e,t)&&f(n,t,e[t]);return n},b=(n,e)=>y(n,g(e));var x=(n,e,t)=>new Promise((r,o)=>{var i=s=>{try{a(t.next(s));}catch(l){o(l);}},u=s=>{try{a(t.throw(s));}catch(l){o(l);}},a=s=>s.done?r(s.value):Promise.resolve(s.value).then(i,u);a((t=t.apply(n,e)).next());});function A(n,e,t){return Math.max(Math.min(n,t),e)}function N(n,e,t,r,o){return Number(e)===0&&Number(r)===0?n*(o/t):(n-e)*((o-r)/(t-e))+r}function d(...n){let e,t;if(typeof n[0]=="number"&&typeof n[1]=="number")[e,t]=n;else if(typeof n[0]=="number"&&typeof n[1]!="number")e=0,t=n[0];else throw new TypeError(`Wrong parameter(s) provided - expected: "number" and "number|undefined", got: "${typeof n[0]}" and "${typeof n[1]}"`);if(e=Number(e),t=Number(t),isNaN(e)||isNaN(t))throw new TypeError(`Parameters "min" and "max" can't be NaN`);if(e>t)throw new TypeError(`Parameter "min" can't be bigger than "max"`);return Math.floor(Math.random()*(t-e+1))+e}function H(n){return T(n)[0]}function T(n){if(n.length===0)return [void 0,void 0];let e=d(n.length-1);return [n[e],e]}function I(n){let[e,t]=T(n);if(t!==void 0)return n.splice(t,1),e}function C(n){let e=[...n];if(n.length===0)return n;for(let t=e.length-1;t>0;t--){let r=Math.floor(d(0,1e4)/1e4*(t+1));[e[t],e[r]]=[e[r],e[t]];}return e}function L(){try{return unsafeWindow}catch(n){return window}}function j(n,e){var t;return (t=n.parentNode)==null||t.insertBefore(e,n.nextSibling),e}function R(n,e){let t=n.parentNode;if(!t)throw new Error("Element doesn't have a parent node");return t.replaceChild(e,n),e.appendChild(n),e}function F(n){let e=document.createElement("style");e.innerHTML=n,document.head.appendChild(e);}function W(n,e=!1){let t=n.map(r=>new Promise((o,i)=>{let u=new Image;u.src=r,u.addEventListener("load",()=>o(u)),u.addEventListener("error",a=>e&&i(a));}));return Promise.allSettled(t)}function $(n){let e=document.createElement("a");Object.assign(e,{className:"userutils-open-in-new-tab",target:"_blank",rel:"noopener noreferrer",href:n}),e.style.display="none",document.body.appendChild(e),e.click(),setTimeout(e.remove,50);}function M(n,e,t){typeof Error.stackTraceLimit=="number"&&Error.stackTraceLimit<1e3&&(Error.stackTraceLimit=1e3),function(r){element.__proto__.addEventListener=function(...o){if(!(o[0]===e&&t()))return r.apply(this,o)};}(n.__proto__.addEventListener);}function q(n,e){return M(L(),n,e)}function G(n,e=1){let t=new(window.AudioContext||window.webkitAudioContext),r={mediaElement:n,amplify:o=>{r.gain.gain.value=o;},getAmpLevel:()=>r.gain.gain.value,context:t,source:t.createMediaElementSource(n),gain:t.createGain()};return r.source.connect(r.gain),r.gain.connect(t.destination),r.amplify(e),r}function B(n,e){return (Array.isArray(e)||e instanceof NodeList)&&(e=e.length),`${n}${e===1?"":"s"}`}function U(n){return new Promise(e=>{setTimeout(e,n);})}function D(n,e=300){let t;return function(...r){clearTimeout(t),t=setTimeout(()=>n.apply(this,r),e);}}function J(t){return x(this,arguments,function*(n,e={}){let{timeout:r=1e4}=e,o=new AbortController,i=setTimeout(()=>o.abort(),r),u=yield fetch(n,b(m({},e),{signal:o.signal}));return clearTimeout(i),u})}var c=new Map;function V(n,e){let t=[];c.has(n)&&(t=c.get(n)),t.push(e),c.set(n,t),E(n,t);}function X(n){return c.delete(n)}function E(n,e){let t=[];if(e.forEach((r,o)=>{try{let i=r.all?document.querySelectorAll(n):document.querySelector(n);(i!==null&&i instanceof NodeList&&i.length>0||i!==null)&&(r.listener(i),r.continuous||t.push(o));}catch(i){console.error(`Couldn't call listener for selector '${n}'`,i);}}),t.length>0){let r=e.filter((o,i)=>!t.includes(i));r.length===0?c.delete(n):c.set(n,r);}}function Y(n={}){new MutationObserver(()=>{for(let[t,r]of c.entries())E(t,r);}).observe(document.body,m({subtree:!0,childList:!0},n));}function Z(){return c}
5
-
6
- exports.addGlobalStyle = F;
7
- exports.addParent = R;
8
- exports.amplifyMedia = G;
9
- exports.autoPlural = B;
10
- exports.clamp = A;
11
- exports.debounce = D;
12
- exports.fetchAdvanced = J;
13
- exports.getSelectorMap = Z;
14
- exports.getUnsafeWindow = L;
15
- exports.initOnSelector = Y;
16
- exports.insertAfter = j;
17
- exports.interceptEvent = M;
18
- exports.interceptWindowEvent = q;
19
- exports.mapRange = N;
20
- exports.onSelector = V;
21
- exports.openInNewTab = $;
22
- exports.pauseFor = U;
23
- exports.preloadImages = W;
24
- exports.randRange = d;
25
- exports.randomItem = H;
26
- exports.randomItemIndex = T;
27
- exports.randomizeArray = C;
28
- exports.removeOnSelector = X;
29
- exports.takeRandomItem = I;
30
-
31
- return exports;
32
-
33
- })({});