feat(contextMenu): add extension API for context menu items

Introduces a new extension API that allows extensions to provide context menu items directly, without monkey-patching. This provides a clean, type-safe way for extensions to add menu items.

**New API methods:**
- `getCanvasMenuItems(canvas)`: Add items to canvas right-click menus
- `getNodeMenuItems(node)`: Add items to node right-click menus

**Implementation:**
- Added TypeScript interfaces in `src/types/comfy.ts`
- Added collection methods in `ComfyApp` class
- Comprehensive test coverage for the new API
This commit is contained in:
Johnpaul
2025-10-09 01:33:29 +01:00
parent 338cbd4eed
commit 5b37fc59e7
4 changed files with 438 additions and 2 deletions

View File

@@ -7,6 +7,7 @@ import { shallowRef } from 'vue'
import { useCanvasPositionConversion } from '@/composables/element/useCanvasPositionConversion'
import { registerProxyWidgets } from '@/core/graph/subgraph/proxyWidget'
import { st, t } from '@/i18n'
import type { IContextMenuValue } from '@/lib/litegraph/src/interfaces'
import {
LGraph,
LGraphCanvas,
@@ -1667,6 +1668,56 @@ export class ComfyApp {
useExtensionService().registerExtension(extension)
}
/**
* Collects context menu items from all extensions for canvas menus
* @param canvas The canvas instance
* @returns Array of context menu items from all extensions
*/
collectCanvasMenuItems(canvas: LGraphCanvas): IContextMenuValue[] {
const items: IContextMenuValue[] = []
for (const ext of this.extensions) {
if (ext.getCanvasMenuItems) {
try {
const extItems = ext.getCanvasMenuItems(canvas)
items.push(...extItems)
} catch (error) {
console.error(
`[Context Menu] Extension "${ext.name}" failed to provide canvas menu items:`,
error
)
}
}
}
return items
}
/**
* Collects context menu items from all extensions for node menus
* @param node The node being right-clicked
* @returns Array of context menu items from all extensions
*/
collectNodeMenuItems(node: LGraphNode): IContextMenuValue[] {
const items: IContextMenuValue[] = []
for (const ext of this.extensions) {
if (ext.getNodeMenuItems) {
try {
const extItems = ext.getNodeMenuItems(node)
items.push(...extItems)
} catch (error) {
console.error(
`[Context Menu] Extension "${ext.name}" failed to provide node menu items:`,
error
)
}
}
}
return items
}
/**
* Refresh combo list on whole nodes
*/