Browse Source

ref: update comments & types

Sven 1 year ago
parent
commit
f672c60747
3 changed files with 38 additions and 24 deletions
  1. 1 0
      lib/index.ts
  2. 4 0
      lib/types.ts
  3. 33 24
      lib/utils.ts

+ 1 - 0
lib/index.ts

@@ -1,2 +1,3 @@
 export * from "./utils";
 export * from "./onSelector";
+export type * from "./types";

+ 4 - 0
lib/types.ts

@@ -6,3 +6,7 @@ export type SelectorExistsOpts = {
   /** Whether to call the listener continuously instead of once */
   continuous?: boolean;
 };
+
+export type FetchAdvancedOpts = RequestInit & Partial<{
+  timeout: number;
+}>;

+ 33 - 24
lib/utils.ts

@@ -1,7 +1,9 @@
+import type { FetchAdvancedOpts } from "./types";
+
 /**
  * Automatically appends an `s` to the passed `word`, if `num` is not equal to 1
  * @param word A word in singular form, to auto-convert to plural
- * @param num If this is an array, the amount of items is used
+ * @param num If this is an array or NodeList, the amount of items is used
  */
 export function autoPlural(word: string, num: number | unknown[] | NodeList) {
   if(Array.isArray(num) || num instanceof NodeList)
@@ -34,7 +36,7 @@ export function debounce<TFunc extends (...args: TArgs[]) => void, TArgs = any>(
 }
 
 /**
- * Returns `unsafeWindow` if it is available (if `@grant unsafeWindow` is set), otherwise falls back to the regular `window`
+ * Returns `unsafeWindow` if the `@grant unsafeWindow` is given, otherwise falls back to the regular `window`
  */
 export function getUnsafeWindow() {
   try {
@@ -47,15 +49,18 @@ export function getUnsafeWindow() {
 }
 
 /**
- * Inserts `afterNode` as a sibling just after the provided `beforeNode`
- * @returns Returns the `afterNode`
+ * Inserts `afterElement` as a sibling just after the provided `beforeElement`
+ * @returns Returns the `afterElement`
  */
-export function insertAfter(beforeNode: HTMLElement, afterNode: HTMLElement) {
-  beforeNode.parentNode?.insertBefore(afterNode, beforeNode.nextSibling);
-  return afterNode;
+export function insertAfter(beforeElement: HTMLElement, afterElement: HTMLElement) {
+  beforeElement.parentNode?.insertBefore(afterElement, beforeElement.nextSibling);
+  return afterElement;
 }
 
-/** Adds a parent container around the provided element - returns the new parent node */
+/**
+ * Adds a parent container around the provided element
+ * @returns Returns the new parent element
+ */
 export function addParent(element: HTMLElement, newParent: HTMLElement) {
   const oldParent = element.parentNode;
 
@@ -69,8 +74,8 @@ export function addParent(element: HTMLElement, newParent: HTMLElement) {
 }
 
 /**
- * Adds global CSS style through a `<style>` element in the document's `<head>`  
- * This needs to be run after the `DOMContentLoaded` event has fired on the document object.
+ * Adds global CSS style in the form of a `<style>` element in the document's `<head>`  
+ * This needs to be run after the `DOMContentLoaded` event has fired on the document object (or instantly if `@run-at document-end` is used).
  * @param style CSS string
  */
 export function addGlobalStyle(style: string) {
@@ -79,24 +84,24 @@ export function addGlobalStyle(style: string) {
   document.head.appendChild(styleElem);
 }
 
-/** Preloads an array of image URLs so they can be loaded instantly from the browser cache later on */
+/**
+ * Preloads an array of image URLs so they can be loaded instantly from the browser cache later on
+ * @param rejects If set to `true`, the returned PromiseSettledResults will contain rejections for any of the images that failed to load
+ * @returns Returns an array of `PromiseSettledResult` - each resolved result will contain the loaded image element, while each rejected result will contain an `ErrorEvent`
+ */
 export function preloadImages(srcUrls: string[], rejects = false) {
   const promises = srcUrls.map(src => new Promise((res, rej) => {
     const image = new Image();
     image.src = src;
     image.addEventListener("load", () => res(image));
-    image.addEventListener("error", () => rejects && rej(`Failed to preload image with URL '${src}'`));
+    image.addEventListener("error", (evt) => rejects && rej(evt));
   }));
 
   return Promise.allSettled(promises);
 }
 
-type FetchOpts = RequestInit & Partial<{
-  timeout: number;
-}>;
-
-/** Calls the fetch API with special options */
-export async function fetchAdvanced(url: string, options: FetchOpts = {}) {
+/** Calls the fetch API with special options like a timeout */
+export async function fetchAdvanced(url: string, options: FetchAdvancedOpts = {}) {
   const { timeout = 10000 } = options;
 
   const controller = new AbortController();
@@ -112,8 +117,10 @@ export async function fetchAdvanced(url: string, options: FetchOpts = {}) {
 }
 
 /**
- * Creates an invisible anchor with _blank target and clicks it.  
- * This has to be run in relatively quick succession to a user interaction event, else the browser rejects it.
+ * Creates an invisible anchor with a `_blank` target and clicks it.  
+ * 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.  
+ *   
+ * This function has to be run in relatively quick succession in response to a user interaction event, else the browser might reject it.
  */
 export function openInNewTab(href: string) {
   const openElem = document.createElement("a");
@@ -128,11 +135,12 @@ export function openInNewTab(href: string) {
   document.body.appendChild(openElem);
   openElem.click();
   // timeout just to be safe
-  setTimeout(openElem.remove, 100);
+  setTimeout(openElem.remove, 50);
 }
 
 /**
- * Intercepts the specified event on the passed object and prevents it from being called if the called `predicate` function returns `true`
+ * Intercepts the specified event on the passed object and prevents it from being called if the called `predicate` function returns a truthy value.  
+ * Calling this function will set the `stackTraceLimit` to 1000 to ensure the stack trace is preserved.
  */
 export function interceptEvent<TEvtObj extends EventTarget>(eventObject: TEvtObj, eventName: Parameters<TEvtObj["addEventListener"]>[0], predicate: () => boolean) {  
   // default is between 10 and 100 on conventional browsers so this should hopefully be more than enough
@@ -155,8 +163,9 @@ export function interceptEvent<TEvtObj extends EventTarget>(eventObject: TEvtObj
 }
 
 /**
- * Intercepts the specified event on the window object and prevents it from being called if the called `predicate` function returns `true`
+ * Intercepts the specified event on the window object and prevents it from being called if the called `predicate` function returns a truthy value.  
+ * Calling this function will set the `stackTraceLimit` to 1000 to ensure the stack trace is preserved.
  */
 export function interceptWindowEvent(eventName: keyof WindowEventMap, predicate: () => boolean) {  
-  interceptEvent(getUnsafeWindow(), eventName, predicate);
+  return interceptEvent(getUnsafeWindow(), eventName, predicate);
 }