1
0
Эх сурвалжийг харах

docs: lots of readme improvements

Sv443 1 жил өмнө
parent
commit
9cceb210dc
1 өөрчлөгдсөн 163 нэмэгдсэн , 31 устгасан
  1. 163 31
      README.md

+ 163 - 31
README.md

@@ -8,6 +8,7 @@ Contains builtin TypeScript declarations.
 - [Installation](#installation)
 - [Features](#features)
   - [onSelector()](#onselector) - call a listener once a selector is found in the DOM
+  - [initOnSelector()](#initonselector) - needs to be called once to be able to use `onSelector()`
   - [autoPlural()](#autoplural) - automatically pluralize a string
   - [clamp()](#clamp) - clamp a number between a min and max value
   - [pauseFor()](#pausefor) - pause the execution of a function for a given amount of time
@@ -54,16 +55,89 @@ If you like using this library, please consider [supporting development](https:/
 ## Features:
 
 ### onSelector()
-\- UNFINISHED -  
+Usage:  
+```ts
+onSelector<TElement = HTMLElement>(selector: string, options: {
+  listener: (elements: TElement | NodeListOf<TElement>) => void,
+  all?: boolean,
+  continuous?: boolean,
+}): void
+```
   
 Registers a listener to be called whenever the element(s) behind a selector is/are found in the DOM.  
-In order to use this function, the MutationObservers have to be initialized with `initOnSelector()` first.  
+If the selector already exists, the listener will be called immediately.  
+  
+If `all` is set to `true`, querySelectorAll() will be used instead and the listener will return a NodeList of matching elements.  
+This will also include elements that were already found in a previous listener call.  
+If set to `false` (default), querySelector() will be used and only the first element will be returned.  
+  
+If `continuous` is set to `true`, the listener will not be deregistered after it was called once (defaults to false).  
   
-Example:
+When using TypeScript, the generic `TElement` can be used to specify the type of the element(s) that the listener will return.  
+  
+⚠️ In order to use this function, [`initOnSelector()`](#initonselector) has to be called as soon as possible.  
+This initialization function has to be called after `DOMContentLoaded` is fired (or immediately if `@run-at document-end` is set).  
+  
+Calling onSelector() before `DOMContentLoaded` is fired will not throw an error, but it also won't trigger listeners until the DOM is accessible.
+  
+<details><summary><b>Example - click to view</b></summary>
+
 ```ts
-// TODO
+document.addEventListener("DOMContentLoaded", initOnSelector);
+
+// Continuously checks if `div` elements are added to the DOM, then returns all of them (even previously detected ones) in a NodeList
+onSelector("div", {
+  listener: (element) => {
+    console.log("Elements found:", element);
+  },
+  all: true,
+  continuous: true,
+});
+
+// Checks if an input element with a value attribute of "5" is added to the DOM, then returns it and deregisters the listener
+onSelector("input[value=\"5\"]", {
+  listener: (element) => {
+    console.log("Element found:", element);
+  },
+});
 ```
 
+</details>
+
+<br>
+
+### initOnSelector()
+Usage:  
+```ts
+initOnSelector(options: {
+  attributes?: boolean,
+  characterData?: boolean,
+}): void
+```
+
+Initializes the MutationObserver that is used by [`onSelector()`](#onselector) to check for the registered selectors whenever a DOM change occurs on the `<body>`  
+By default, this only checks if elements are added or removed (at any depth).  
+  
+Set `attributes` to `true` to also check for attribute changes on every single descendant of the `<body>` (defaults to false).  
+Set `characterData` to `true` to also check for character data changes on every single descendant of the `<body>` (defaults to false).  
+  
+⚠️ Using these extra options can have a performance impact on larger sites or sites with a constantly changing DOM.  
+  
+⚠️ This function needs to be run after the DOM has loaded (when using `@run-at document-end` or after `DOMContentLoaded` has fired).  
+  
+<details><summary><b>Example - click to view</b></summary>
+
+```ts
+document.addEventListener("DOMContentLoaded", () => {
+  initOnSelector({
+    attributes: true,
+    characterData: true,
+  });
+});
+```
+
+</details>
+
 <br>
 
 ### autoPlural()
@@ -72,7 +146,8 @@ Usage: `autoPlural(str: string, num: number | Array | NodeList): string`
 Automatically pluralizes a string if the given number is not 1.  
 If an array or NodeList is passed, the length of it will be used.  
   
-Example:
+<details><summary><b>Example - click to view</b></summary>
+
 ```ts
 autoPlural("apple", 0); // "apples"
 autoPlural("apple", 1); // "apple"
@@ -82,6 +157,8 @@ autoPlural("apple", [1]);    // "apple"
 autoPlural("apple", [1, 2]); // "apples"
 ```
 
+</details>
+
 <br>
 
 ### clamp()
@@ -89,13 +166,16 @@ Usage: `clamp(num: number, min: number, max: number): number`
   
 Clamps a number between a min and max value.  
   
-Example:
+<details><summary><b>Example - click to view</b></summary>
+
 ```ts
 clamp(5, 0, 10);        // 5
 clamp(-1, 0, 10);       // 0
 clamp(Infinity, 0, 10); // 10
 ```
 
+</details>
+
 <br>
 
 ### pauseFor()
@@ -103,7 +183,8 @@ Usage: `pauseFor(ms: number): Promise<void>`
   
 Pauses async execution for a given amount of time.  
   
-Example:
+<details><summary><b>Example - click to view</b></summary>
+
 ```ts
 async function run() {
   console.log("Hello");
@@ -112,6 +193,8 @@ async function run() {
 }
 ```
 
+</details>
+
 <br>
 
 ### debounce()
@@ -121,13 +204,16 @@ Debounces a function, meaning that it will only be called once after a given amo
 This is very useful for functions that are called repeatedly, like event listeners, to remove extraneous calls.  
 The timeout will default to 300ms if left undefined.  
   
-Example:
+<details><summary><b>Example - click to view</b></summary>
+
 ```ts
 window.addEventListener("resize", debounce((event) => {
   console.log("Window was resized:", event);
 }, 500)); // 500ms timeout
 ```
 
+</details>
+
 <br>
 
 ### getUnsafeWindow()
@@ -136,7 +222,8 @@ Usage: `getUnsafeWindow(): Window`
 Returns the unsafeWindow object or falls back to the regular window object if the `@grant unsafeWindow` is not given.  
 Userscripts are sandboxed and do not have access to the regular window object, so this function is useful for websites that reject some events that were dispatched by the userscript.  
   
-Example:
+<details><summary><b>Example - click to view</b></summary>
+
 ```ts
 const mouseEvent = new MouseEvent("click", {
   view: getUnsafeWindow(),
@@ -144,15 +231,20 @@ const mouseEvent = new MouseEvent("click", {
 document.body.dispatchEvent(mouseEvent);
 ```
 
+</details>
+
 <br>
 
 ### insertAfter()
 Usage: `insertAfter(beforeElement: HTMLElement, afterElement: HTMLElement): HTMLElement`  
   
 Inserts the element passed as `afterElement` as a sibling after the passed `beforeElement`.  
-The `afterElement` will be returned.  
+The passed `afterElement` will be returned.  
+  
+⚠️ This function needs to be run after the DOM has loaded (when using `@run-at document-end` or after `DOMContentLoaded` has fired).  
   
-Example:
+<details><summary><b>Example - click to view</b></summary>
+
 ```ts
 const beforeElement = document.querySelector("#before");
 const afterElement = document.createElement("div");
@@ -160,15 +252,20 @@ afterElement.innerText = "After";
 insertAfter(beforeElement, afterElement);
 ```
 
+</details>
+
 <br>
 
 ### addParent()
 Usage: `addParent(element: HTMLElement, newParent: HTMLElement): HTMLElement`  
   
 Adds a parent element around the passed `element` and returns the new parent.  
-Previously registered event listeners should be kept intact.  
+Previously registered event listeners are kept intact.  
   
-Example:
+⚠️ This function needs to be run after the DOM has loaded (when using `@run-at document-end` or after `DOMContentLoaded` has fired).  
+  
+<details><summary><b>Example - click to view</b></summary>
+
 ```ts
 const element = document.querySelector("#element");
 const newParent = document.createElement("a");
@@ -176,15 +273,18 @@ newParent.href = "https://example.org/";
 addParent(element, newParent);
 ```
 
+</details>
+
 <br>
 
 ### addGlobalStyle()
 Usage: `addGlobalStyle(css: string): void`  
   
 Adds a global style to the page in form of a `<style>` element that's inserted into the `<head>`.  
-This function needs to be run after the DOM has loaded (when using `@run-at document-end` or after `DOMContentLoaded` has fired).  
+⚠️ This function needs to be run after the DOM has loaded (when using `@run-at document-end` or after `DOMContentLoaded` has fired).  
   
-Example:
+<details><summary><b>Example - click to view</b></summary>
+
 ```ts
 document.addEventListener("DOMContentLoaded", () => {
   addGlobalStyle(`
@@ -195,43 +295,61 @@ document.addEventListener("DOMContentLoaded", () => {
 });
 ```
 
+</details>
+
 <br>
 
 ### preloadImages()
-Usage: `preloadImages(...urls: string[]): Promise<void>`  
+Usage: `preloadImages(urls: string[], rejects?: boolean): Promise<void>`  
   
 Preloads images into browser cache by creating an invisible `<img>` element for each URL passed.  
 The images will be loaded in parallel and the returned Promise will only resolve once all images have been loaded.  
-The resulting PromiseSettledResult array will contain the image elements if resolved, or an ErrorEvent if rejected.  
+The resulting PromiseSettledResult array will contain the image elements if resolved, or an ErrorEvent if rejected, but only if `rejects` is set to true.  
   
-Example:
+<details><summary><b>Example - click to view</b></summary>
+
 ```ts
-preloadImages(
+preloadImages([
   "https://example.org/image1.png",
   "https://example.org/image2.png",
   "https://example.org/image3.png",
-).then((results) => {
-  console.log("Images preloaded. Results:", results);
-});
+], true)
+  .then((results) => {
+    console.log("Images preloaded. Results:", results);
+  });
 ```
 
+</details>
+
 <br>
 
 ### fetchAdvanced()
-Usage: `fetchAdvanced(url: string, options?: FetchAdvancedOptions): Promise<Response>`  
+Usage:  
+```ts
+fetchAdvanced(url: string, options?: {
+  timeout?: number,
+  // any other options from fetch() except for signal
+}): Promise<Response>
+```
   
 A wrapper around the native `fetch()` function that adds options like a timeout property.  
 The timeout will default to 10 seconds if left undefined.  
   
-Example:
+<details><summary><b>Example - click to view</b></summary>
+
 ```ts
-fetchAdvanced("https://example.org/", {
+fetchAdvanced("https://api.example.org/data", {
   timeout: 5000,
-}).then((response) => {
-  console.log("Response:", response);
+  headers: {
+    "Accept": "application/json",
+  },
+}).then(async (response) => {
+  console.log("Data:", await response.json());
 });
 ```
 
+</details>
+
 <br>
 
 ### openInNewTab()
@@ -241,29 +359,38 @@ 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.  
   
-Example:
+⚠️ This function needs to be run after the DOM has loaded (when using `@run-at document-end` or after `DOMContentLoaded` has fired).  
+  
+<details><summary><b>Example - click to view</b></summary>
+
 ```ts
 document.querySelector("#button").addEventListener("click", () => {
   openInNewTab("https://example.org/");
 });
 ```
 
+</details>
+
 <br>
 
 ### interceptEvent()
 Usage: `interceptEvent(eventObject: EventTarget, eventName: string, predicate: () => boolean): void`  
   
 Intercepts all events dispatched on the `eventObject` and prevents the listeners from being called as long as the predicate function returns a truthy value.  
-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.  
 Calling this function will set the `Error.stackTraceLimit` to 1000 to ensure the stack trace is preserved.  
   
-Example:
+⚠️ This function should be called as soon as possible (I recommend using `@run-at document-start`), as it will only intercept events that are *attached* after this function is called.  
+  
+<details><summary><b>Example - click to view</b></summary>
+
 ```ts
 interceptEvent(document.body, "click", () => {
   return true; // prevent all click events on the body
 });
 ```
 
+</details>
+
 <br>
 
 ### interceptWindowEvent()
@@ -272,13 +399,18 @@ Usage: `interceptWindowEvent(eventName: string, predicate: () => boolean): void`
 Intercepts all events dispatched on the `window` object and prevents the listeners from being called as long as the predicate function returns a truthy value.  
 This is essentially the same as [`interceptEvent()`](#interceptevent), but automatically uses the `unsafeWindow` (or falls back to regular `window`).  
   
-Example:
+⚠️ This function should be called as soon as possible (I recommend using `@run-at document-start`), as it will only intercept events that are *attached* after this function is called.  
+  
+<details><summary><b>Example - click to view</b></summary>
+
 ```ts
 interceptWindowEvent("beforeunload", () => {
   return true; // prevent the pesky "Are you sure you want to leave this page?" popup
 });
 ```
 
+</details>
+
 
 <br><br>