Преглед на файлове

docs: SelectorObserver base

Sven преди 1 година
родител
ревизия
60041d6c5b
променени са 2 файла, в които са добавени 37 реда и са изтрити 125 реда
  1. 31 119
      README.md
  2. 6 6
      lib/SelectorObserver.ts

+ 31 - 119
README.md

@@ -15,9 +15,7 @@ If you like using this library, please consider [supporting the development ❤
 - [**License**](#license)
 - [**Features**](#features)
   - [**DOM:**](#dom)
-    - [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()`
-    - [getSelectorMap()](#getselectormap) - returns all currently registered selectors, listeners and options
+    - [SelectorObserver](#selectorobserver) - class that manages listeners that are called when selectors are found in the DOM
     - [getUnsafeWindow()](#getunsafewindow) - get the unsafeWindow object or fall back to the regular window object
     - [insertAfter()](#insertafter) - insert an element as a sibling after another element
     - [addParent()](#addparent) - add a parent element around another element
@@ -33,7 +31,7 @@ If you like using this library, please consider [supporting the development ❤
     - [mapRange()](#maprange) - map a number from one range to the same spot in another range
     - [randRange()](#randrange) - generate a random number between a min and max boundary
   - [**Misc:**](#misc)
-    - [ConfigManager()](#configmanager) - class that manages persistent userscript configurations, including data migration
+    - [ConfigManager](#configmanager) - class that manages persistent userscript configurations, including data migration
     - [autoPlural()](#autoplural) - automatically pluralize a string
     - [pauseFor()](#pausefor) - pause the execution of a function for a given amount of time
     - [debounce()](#debounce) - call a function only once, after a given amount of time
@@ -112,141 +110,55 @@ See the [license file](./LICENSE.txt) for details.
 
 ## DOM:
 
-<!-- TODO: write docs for SelectorObserver class -->
-### onSelector()
+### SelectorObserver
 Usage:  
 ```ts
-onSelector<TElement = HTMLElement>(selector: string, options: {
-  listener: (elements: TElement | NodeListOf<TElement>) => void,
-  all?: boolean,
-  continuous?: boolean,
-}): void
+new SelectorObserver(baseElement: Element, options?: MutationObserverInit)
 ```
+
+A class that manages listeners that are called when selectors are found in the DOM.  
+<!-- TODO: -->
+
+<br>
+
+### Methods:
+`addListener(selector: string, options: SelectorListenerOptions): void`  
+Adds a listener for the given selector.  
+<!-- TODO: -->
   
-Registers a listener to be called whenever the element(s) behind a selector is/are found in the DOM.  
-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 matching element will be returned.  
-  
-If `continuous` is set to `true`, the listener will not be deregistered after it was called once (defaults to false).  
+`disable(): void`  
+<!-- TODO: -->
   
-When using TypeScript, the generic `TElement` can be used to specify the type of the element(s) that the listener will return.  
-It will default to `HTMLElement` if left undefined.  
+`enable(): void`  
+<!-- TODO: -->
   
-⚠️ 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).  
+`clearListeners(): void`  
+<!-- TODO: -->
   
-Calling onSelector() before `DOMContentLoaded` is fired will not throw an error, but it also won't trigger listeners until the DOM is accessible.
+`removeAllListeners(selector: string): boolean`  
+<!-- TODO: -->
   
-<details><summary><b>Example - click to view</b></summary>
-
-```ts
-import { initOnSelector, onSelector } from "@sv443-network/userutils";
-
-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<HTMLDivElement>("div", {
-  listener: (elements) => {
-    console.log("Elements found:", elements); // type = NodeListOf<HTMLDivElement>
-  },
-  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<HTMLInputElement>("input[value=\"5\"]", {
-  listener: (element) => {
-    console.log("Element found:", element); // type = HTMLInputElement
-  },
-});
-```
-
-</details>
-
-<br>
-
-### initOnSelector()
-Usage:  
-```ts
-initOnSelector(options?: MutationObserverInit): void
-```
+`removeListener(selector: string, options: SelectorListenerOptions): boolean`  
+<!-- TODO: -->
   
-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).  
-
-⚠️ This function needs to be run after the DOM has loaded (when using `@run-at document-end` or after `DOMContentLoaded` has fired).  
+`getAllListeners(): Map<string, SelectorListenerOptions[]>`  
+<!-- TODO: -->
   
-The options object is passed directly to the MutationObserver.observe() method.  
-Note that `options.subtree` and `options.childList` will be set to true by default.  
-You may see all options [here](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe#options), but these are the important ones:  
-> Set `options.attributes` to `true` to also check for attribute changes on every single descendant of the `<body>` (defaults to false).  
-> Set `options.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.
+`getListeners(selector: string): SelectorListenerOptions[] | undefined`  
+<!-- TODO: -->
   
-<details><summary><b>Example - click to view</b></summary>
-
-```ts
-import { initOnSelector } from "@sv443-network/userutils";
-
-document.addEventListener("DOMContentLoaded", () => {
-  initOnSelector({
-    attributes: true,
-    characterData: true,
-  });
-});
-```
-
-</details>
 
 <br>
 
-### getSelectorMap()
-Usage:  
-```ts
-getSelectorMap(): Map<string, OnSelectorOptions[]>
-```
-  
-Returns a Map of all currently registered selectors and their options, including listener function.  
-Since multiple listeners can be registered for the same selector, the value of the Map is an array of `OnSelectorOptions` objects.  
-  
 <details><summary><b>Example - click to view</b></summary>
 
 ```ts
-import { initOnSelector, onSelector, getSelectorMap } from "@sv443-network/userutils";
-
-document.addEventListener("DOMContentLoaded", initOnSelector);
-
-onSelector<HTMLDivElement>("div", {
-  listener: (elements) => void 0,
-  all: true,
-  continuous: true,
-});
-
-onSelector<HTMLDivElement>("div", {
-  listener: (elements) => void 0,
-});
-
-const selectorMap = getSelectorMap();
-// Map(1) {
-//   "div" => [
-//     {
-//       listener: (elements) => void 0,
-//       all: true,
-//       continuous: true,
-//     },
-//     {
-//       listener: (elements) => void 0,
-//     },
-//   ]
-// }
+import { SelectorObserver } from "@sv443-network/userutils";
 ```
 
 </details>
 
+
 <br>
 
 ### getUnsafeWindow()
@@ -689,7 +601,7 @@ randRange(10);     // 7
 
 ## Misc:
 
-### ConfigManager()
+### ConfigManager
 Usage:  
 ```ts
 new ConfigManager(options: ConfigManagerOptions)

+ 6 - 6
lib/SelectorObserver.ts

@@ -1,5 +1,5 @@
 /** Options for the `onSelector()` method of {@linkcode SelectorObserver} */
-export type OnSelectorOptions<TElem extends Element = HTMLElement> = SelectorOptionsOne<TElem> | SelectorOptionsAll<TElem>;
+export type SelectorListenerOptions<TElem extends Element = HTMLElement> = SelectorOptionsOne<TElem> | SelectorOptionsAll<TElem>;
 
 type SelectorOptionsOne<TElem extends Element> = SelectorOptionsCommon & {
   /** Whether to use `querySelectorAll()` instead - default is false */
@@ -28,7 +28,7 @@ export class SelectorObserver {
   private baseElement: Element;
   private observer: MutationObserver;
   private observerOptions: MutationObserverInit;
-  private listenerMap = new Map<string, OnSelectorOptions[]>();
+  private listenerMap = new Map<string, SelectorListenerOptions[]>();
 
   /**
    * Creates a new SelectorObserver that will observe the children of the given base element for changes (only creation and deletion of elements by default)
@@ -91,14 +91,14 @@ export class SelectorObserver {
    * @param [options.continuous] Whether to call the listener continuously instead of just once - default is false
    * @param [options.debounce] Whether to debounce the listener to reduce calls to `querySelector` or `querySelectorAll` - set undefined or <=0 to disable (default)
    */
-  public addListener<TElem extends Element = HTMLElement>(selector: string, options: OnSelectorOptions<TElem>) {
+  public addListener<TElem extends Element = HTMLElement>(selector: string, options: SelectorListenerOptions<TElem>) {
     options = { all: false, continuous: false, debounce: 0, ...options };
     if(options.debounce && options.debounce > 0)
       options.listener = this.debounce(options.listener as ((arg: NodeListOf<Element> | Element) => void), options.debounce);
     if(this.listenerMap.has(selector))
-      this.listenerMap.get(selector)!.push(options as OnSelectorOptions<Element>);
+      this.listenerMap.get(selector)!.push(options as SelectorListenerOptions<Element>);
     else
-      this.listenerMap.set(selector, [options as OnSelectorOptions<Element>]);
+      this.listenerMap.set(selector, [options as SelectorListenerOptions<Element>]);
   }
 
   /** Disables the observation of the child elements */
@@ -138,7 +138,7 @@ export class SelectorObserver {
    * Removes a single listener for the given {@linkcode selector} and {@linkcode options} that has been registered with {@linkcode addListener()}
    * @returns Returns true when the listener was found and removed, false otherwise
    */
-  public removeListener(selector: string, options: OnSelectorOptions) {
+  public removeListener(selector: string, options: SelectorListenerOptions) {
     const listeners = this.listenerMap.get(selector);
     if(!listeners)
       return false;