Files
arcum42-ComfyUI_SageUtils/ref_docs/frontend/javascript_examples.md
T

4.8 KiB

JavaScript Annotated Examples

Summary

A growing collection of fragments of example code for ComfyUI custom nodes JavaScript development.

Right Click Menus

Background Menu

The main background menu (right-click on the canvas) is generated by a call to LGraph.getCanvasMenuOptions. One way to add your own menu options is to hijack this call:

/* in setup() */
const original_getCanvasMenuOptions = LGraphCanvas.prototype.getCanvasMenuOptions;
LGraphCanvas.prototype.getCanvasMenuOptions = function () {
    // get the basic options 
    const options = original_getCanvasMenuOptions.apply(this, arguments);
    options.push(null); // inserts a divider
    options.push({
        content: "The text for the menu",
        callback: async () => {
            // do whatever
        }
    })
    return options;
}

Node Menu

When you right click on a node, the menu is similarly generated by node.getExtraMenuOptions. But instead of returning an options object, this one gets it passed in…

/* in beforeRegisterNodeDef() */
if (nodeType?.comfyClass=="MyNodeClass") { 
    const original_getExtraMenuOptions = nodeType.prototype.getExtraMenuOptions;
    nodeType.prototype.getExtraMenuOptions = function(_, options) {
        original_getExtraMenuOptions?.apply(this, arguments);
        options.push({
            content: "Do something fun",
            callback: async () => {
                // fun thing
            }
        })
    }   
}

Submenus

If you want a submenu, provide a callback which uses LiteGraph.ContextMenu to create it:

function make_submenu(value, options, e, menu, node) {
    const submenu = new LiteGraph.ContextMenu(
        ["option 1", "option 2", "option 3"],
        { 
            event: e, 
            callback: function (v) { 
                // do something with v (=="option x")
            }, 
            parentMenu: menu, 
            node:node
        }
    )
}

/* ... */
options.push(
    {
        content: "Menu with options",
        has_submenu: true,
        callback: make_submenu,
    }
)

Capture UI Events

This works just like you'd expect - find the UI element in the DOM and add an eventListener. setup() is a good place to do this, since the page has fully loaded. For instance, to detect a click on the 'Queue' button:

function queue_button_pressed() { console.log("Queue button was pressed!") }
document.getElementById("queue-button").addEventListener("click", queue_button_pressed);

Detect When a Workflow Starts

This is one of many api events:

import { api } from "../../scripts/api.js";
/* in setup() */
function on_execution_start() { 
    /* do whatever */
}
api.addEventListener("execution_start", on_execution_start);

Detect an Interrupted Workflow

A simple example of hijacking the api:

import { api } from "../../scripts/api.js";
/* in setup() */
const original_api_interrupt = api.interrupt;
api.interrupt = function () {
    /* Do something before the original method is called */
    original_api_interrupt.apply(this, arguments);
    /* Or after */
}

Catch Clicks on Your Node

node has a mouseDown method you can hijack. This time we're careful to pass on any return value.

async nodeCreated(node) {
    if (node?.comfyClass === "My Node Name") {
        const original_onMouseDown = node.onMouseDown;
        node.onMouseDown = function( e, pos, canvas ) {
            alert("ouch!");
            return original_onMouseDown?.apply(this, arguments);
        }        
    }
}

Key Concepts

Method Hijacking

Many of these examples use a common pattern of "hijacking" existing methods:

  1. Save a reference to the original method
  2. Replace the method with your own implementation
  3. Call the original method from within your implementation
  4. Add your custom logic before or after the original call

Event Handling

ComfyUI provides several event systems:

  • DOM Events: Standard browser events on UI elements
  • API Events: Custom events fired by the ComfyUI API
  • Node Events: Events specific to node interactions
  • Graph Events: Events related to workflow changes

Common Patterns

  • Menu Extension: Adding custom options to context menus
  • Event Interception: Capturing and responding to user actions
  • UI Enhancement: Adding functionality to existing interface elements
  • Workflow Monitoring: Tracking workflow execution state

Usage Notes

  • These examples assume you're working within the ComfyUI extension system
  • Most hijacking should be done in the setup() method after the page loads
  • Always preserve the original method's behavior unless you specifically need to change it
  • Be careful with event listeners to avoid memory leaks
  • Test thoroughly as hijacking can affect other extensions