Skip to content

Proof of concept wrapper library for MutationObserver Web API, suitable to be used in userscripts.

License

Notifications You must be signed in to change notification settings

Ragnarokkr/tokan.js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tokan.js

Tokan ("特観", "とくかん") is a Japanese compound word where "特" (toku) means "special" and "観" (kan) relates to "view" or "observation." This term aptly reflects the purpose of the Tokan library, which serves as a specialized tool for observing changes in the Document Object Model (DOM) of web applications.

Tokan is a library designed to simplify and enhance the functionality of the native MutationObserver API. The native API, while powerful, can be complex and cumbersome to use, especially for developers who need to track various types of changes in the DOM. Tokan addresses these challenges by providing a more user-friendly interface that abstracts away some of the complexities associated with the native API.

Key Features:

  • Simplified Syntax: The library offers a more intuitive syntax for setting up observers, reducing boilerplate code and making it easier to implement.
  • Batch Processing: It can batch multiple mutations together, allowing for more efficient handling of changes and reducing the number of callback executions.
  • Custom Callbacks: Users can define custom callback functions that can be triggered based on specific types of mutations, providing greater control over how changes are handled.

Example Usage

Setting Up an Observer

const tokan = new Tokan("#myElement");

const filterCallback: TokanMutationFilterCallback = (node) =>
  node.nodeName === "A";

const observerAttrsId = tokan.watch(Tokan.MutationKinds.Attr, {
  oldValue: true,
  subtree: true,
  filters: ["id", "class", "disabled"],
});

const observerNodesID = tokan.watch(Tokan.MutationKinds.Nodes, {
  subtree: true,
  filters: [filterCallback],
});

tokan.on(Tokan.MutationEvents.Added, (node) => {
  console.log("Node added:", node);
});

tokan.on(Tokan.MutationEvents.AttrChanged, (node, data) => {
  console.log("Attribute changed:", node, data);
});

tokan.start();

Stopping an Observer

tokan.stop();
tokan.unwatch();

Listening for Multiple Events

tokan.on(Tokan.MutationEvents.Removed, (node) => {
  console.log("Node removed:", node);
});

tokan.on(Tokan.MutationEvents.CharDataChanged, (node, data) => {
  console.log("Character data changed:", node, data);
});

tokan.start();

Types

TokanMutationFilterCallback

  • Type: (node: Node) => boolean
  • Description: A callback function that determines whether a node should be considered for mutation observation. It receives a Node as input and returns a boolean indicating whether the node should be included.
  • Usage Example:
    const filterCallback: TokanMutationFilterCallback = (node) =>
      node.nodeName === "DIV";

TokanMutationFilter

  • Type: string | TokanMutationFilterCallback
  • Description: A filter that can be either a string or a TokanMutationFilterCallback. If a string is provided, it might represent an attribute name. If a callback is provided, it uses the TokanMutationFilterCallback returned result.
  • Usage Example:
    const filter: TokanMutationFilter = "div.my-class";
    const filterCallback: TokanMutationFilterCallback = (node) =>
      node.textContent.includes("var");

TokanMutationKindOptions

  • Type: interface
  • Properties:
    • oldValue (optional): boolean - Indicates whether the previous value of the node should be recorded.
    • subtree (optional): boolean - Indicates whether the observer should monitor the entire subtree of the target node.
    • filters (optional): TokanMutationFilter[] - An array of filters to apply to nodes being observed.
  • Usage Example:
    const options: TokanMutationKindOptions = {
      oldValue: true,
      subtree: true,
      filters: ["id", "class", (node) => node.nodeName === "PICTURE"],
    };

TokanEventCallback

  • Type: (nodeList: Node, data?: unknown) => void
  • Description: A callback function that is triggered when a mutation event occurs. It receives the affected node list and optional data related to the mutation.
  • Usage Example:
    const eventCallback: TokanEventCallback = (nodeList, data) => {
      console.log("Mutation detected:", nodeList, data);
    };

TokanObserverDescriptor

  • Type: interface
  • Properties:
    • id: number - A unique identifier for the observer instance.
    • instance: MutationObserver - The actual MutationObserver instance.
    • config: MutationObserverInit - Configuration options for the MutationObserver.
    • filters: Set<TokanMutationFilterCallback> - A set of filter callbacks applied to nodes.
    • started: boolean - Indicates whether the observer has been started.
  • Usage Example:
    const observerDescriptor: TokanObserverDescriptor = {
      id: 1,
      instance: new MutationObserver(eventCallback),
      config: { attributes: true },
      filters: new Set([filterCallback]),
      started: false,
    };

Constants

TokanMutationKinds

  • Type: object
  • Description: An object containing constants representing different types of mutations that can be observed.
  • Constants:
    • Attr: "attributes" - Represents changes to the attributes of elements.
    • CharData: "characterData" - Represents changes to the text content of nodes.
    • Nodes: "nodes" - Represents additions or removals of child nodes.
  • Usage Example:
    const mutationKind = TokanMutationKinds.Attr;
    console.log(mutationKind); // Output: "attributes"

TokanMutationEvents

  • Type: object
  • Description: An object containing constants representing different mutation events that can be triggered.
  • Constants:
    • Added: "added" - Triggered when nodes are added.
    • AttrChanged: "attributeChanged" - Triggered when attributes of elements change.
    • CharDataChanged: "characterDataChanged" - Triggered when the text content of nodes changes.
    • Removed: "removed" - Triggered when nodes are removed.
  • Usage Example:
    const mutationEvent = TokanMutationEvents.CharDataChanged;
    console.log(mutationEvent); // Output: "characterDataChanged"

Class: Tokan

Static Properties

Tokan.MutationKinds

Constant Type Value Description
Attr string "attributes" Represents changes to the attributes of elements.
CharData string "characterData" Represents changes to the text content of nodes.
Nodes string "nodes" Represents additions or removals of child nodes.

Tokan.MutationEvents

Constant Type Value Description
Added string "added" Triggered when nodes are added.
AttrChanged string "attributeChanged" Triggered when attributes of elements change.
CharDataChanged string "characterDataChanged" Triggered when the text content of nodes changes.
Removed string "removed" Triggered when nodes are removed.

Constructor

Method Parameters Description
constructor target: string | Node Initializes a new instance of the Tokan class with a target node or a CSS selector string.

Methods

Method Parameters Returns Description
observerRouter mutationList: MutationRecord[], observer: MutationObserver void Routes mutation records to the appropriate listeners based on the mutation type and filters.
watch mutationKind: TokanMutationKind, options?: TokanMutationKindOptions number | undefined Sets up a new observer for a specific type of mutation.
unwatch id?: number boolean Stops and removes an observer or all observers.
on event: TokanMutationEvent, callback: TokanEventCallback Tokan Adds an event listener for a specific mutation event.
start id?: number void Starts observing with a specific observer or all observers.
stop id?: number void Stops observing with a specific observer or all observers.

Constructor

constructor(target: string | Node)

  • Description: Initializes a new instance of the Tokan class with a target node or a CSS selector string.
  • Parameters:
    • target: string | Node - The target node or a CSS selector string to observe.
  • Usage Example:
    const tokan = new Tokan("#myElement");
    const tokanNode = new Tokan(document.getElementById("myElement"));

Private Properties

target: Node

  • Description: The target node being observed.

observerId: number

  • Description: A unique identifier for observer instances.

observers: Set<TokanObserverDescriptor>

  • Description: A set of observer descriptors.

listeners: { [key in TokanMutationEvent]: TokanEventCallback[] }

  • Description: An object mapping mutation events to their respective event callbacks.

Methods

observerRouter(mutationList: MutationRecord[], observer: MutationObserver): void

  • Description: Routes mutation records to the appropriate listeners based on the mutation type and filters.
  • Parameters:
    • mutationList: MutationRecord[] - A list of mutation records.
    • observer: MutationObserver - The observer instance that generated the mutation records.
  • Usage Example: (Internal method, not directly called by users)

watch(mutationKind: TokanMutationKind, options?: TokanMutationKindOptions): number | undefined

  • Description: Sets up a new observer for a specific type of mutation.
  • Parameters:
    • mutationKind: TokanMutationKind - The type of mutation to observe.
    • options (optional): TokanMutationKindOptions - Configuration options for the observer.
  • Returns: number | undefined - The ID of the new observer or undefined if an error occurs.
  • Usage Example:
    const observerId = tokan.watch(Tokan.MutationKinds.Attr, {
      oldValue: true,
      subtree: true,
      filters: ['input[type="text"]', filterCallback],
    });

unwatch(id?: number): boolean

  • Description: Stops and removes an observer or all observers.
  • Parameters:
    • id (optional): number - The ID of the observer to remove. If not provided, all observers are removed.
  • Returns: boolean - Indicates whether the operation was successful.
  • Usage Example:
    tokan.unwatch(observerId);
    tokan.unwatch(); // Removes all observers

on(event: TokanMutationEvent, callback: TokanEventCallback): Tokan

  • Description: Adds an event listener for a specific mutation event.
  • Parameters:
    • event: TokanMutationEvent - The type of mutation event to listen for.
    • callback: TokanEventCallback - The callback function to execute when the event occurs.
  • Returns: Tokan - The current Tokan instance for method chaining.
  • Usage Example:
    tokan.on(Tokan.MutationEvents.Added, (node) => {
      console.log("Node added:", node);
    });

start(id?: number): void

  • Description: Starts observing with a specific observer or all observers.
  • Parameters:
    • id (optional): number - The ID of the observer to start. If not provided, all observers are started.
  • Usage Example:
    tokan.start(observerId);
    tokan.start(); // Starts all observers

stop(id?: number): void

  • Description: Stops observing with a specific observer or all observers.
  • Parameters:
    • id (optional): number - The ID of the observer to stop. If not provided, all observers are stopped.
  • Usage Example:
    tokan.stop(observerId);
    tokan.stop(); // Stops all observers

About

Proof of concept wrapper library for MutationObserver Web API, suitable to be used in userscripts.

Topics

Resources

License

Stars

Watchers

Forks