From efdb8080ae72aa595a4f3771228fd64e77bed81e Mon Sep 17 00:00:00 2001 From: filtered <176114999+webfiltered@users.noreply.github.com> Date: Tue, 22 Jul 2025 02:31:16 +1000 Subject: [PATCH] Change widget demoted event name (#1144) --- src/infrastructure/SubgraphEventMap.ts | 2 +- src/subgraph/SubgraphNode.ts | 11 ++++----- src/widgets/BaseWidget.ts | 8 ------- test/subgraph/SubgraphWidgetPromotion.test.ts | 23 +++++++++---------- 4 files changed, 17 insertions(+), 27 deletions(-) diff --git a/src/infrastructure/SubgraphEventMap.ts b/src/infrastructure/SubgraphEventMap.ts index 48c7072be..ca433295e 100644 --- a/src/infrastructure/SubgraphEventMap.ts +++ b/src/infrastructure/SubgraphEventMap.ts @@ -47,7 +47,7 @@ export interface SubgraphEventMap extends LGraphEventMap { widget: IBaseWidget subgraphNode: SubgraphNode } - "widget-unpromoted": { + "widget-demoted": { widget: IBaseWidget subgraphNode: SubgraphNode } diff --git a/src/subgraph/SubgraphNode.ts b/src/subgraph/SubgraphNode.ts index 0ba651842..826037a2b 100644 --- a/src/subgraph/SubgraphNode.ts +++ b/src/subgraph/SubgraphNode.ts @@ -187,9 +187,8 @@ export class SubgraphNode extends LGraphNode implements BaseLGraph { } #setWidget(subgraphInput: Readonly, input: INodeInputSlot, widget: Readonly) { - const concreteWidget = toConcreteWidget(widget, this) - - const promotedWidget = concreteWidget.createCopyForNode(this) + // Use the first matching widget + const promotedWidget = toConcreteWidget(widget, this).createCopyForNode(this) // Set parentSubgraphNode for all promoted widgets to track their origin promotedWidget.parentSubgraphNode = this @@ -318,14 +317,14 @@ export class SubgraphNode extends LGraphNode implements BaseLGraph { override removeWidgetByName(name: string): void { const widget = this.widgets.find(w => w.name === name) if (widget) { - this.subgraph.events.dispatch("widget-unpromoted", { widget, subgraphNode: this }) + this.subgraph.events.dispatch("widget-demoted", { widget, subgraphNode: this }) } super.removeWidgetByName(name) } override ensureWidgetRemoved(widget: IBaseWidget): void { if (this.widgets.includes(widget)) { - this.subgraph.events.dispatch("widget-unpromoted", { widget, subgraphNode: this }) + this.subgraph.events.dispatch("widget-demoted", { widget, subgraphNode: this }) } super.ensureWidgetRemoved(widget) } @@ -334,7 +333,7 @@ export class SubgraphNode extends LGraphNode implements BaseLGraph { // Clean up all promoted widgets for (const widget of this.widgets) { widget.parentSubgraphNode = undefined - this.subgraph.events.dispatch("widget-unpromoted", { widget, subgraphNode: this }) + this.subgraph.events.dispatch("widget-demoted", { widget, subgraphNode: this }) } for (const input of this.inputs) { diff --git a/src/widgets/BaseWidget.ts b/src/widgets/BaseWidget.ts index d503a3f2c..ac50ea90f 100644 --- a/src/widgets/BaseWidget.ts +++ b/src/widgets/BaseWidget.ts @@ -304,12 +304,4 @@ export abstract class BaseWidget impl cloned.value = this.value return cloned } - - /** - * Type guard to check if this widget has a DOM element. - * @returns True if the widget has a DOM element attached - */ - isDOMWidget(): this is this & { element: HTMLElement } { - return this.element instanceof HTMLElement - } } diff --git a/test/subgraph/SubgraphWidgetPromotion.test.ts b/test/subgraph/SubgraphWidgetPromotion.test.ts index 7598c8fb6..d35e71b94 100644 --- a/test/subgraph/SubgraphWidgetPromotion.test.ts +++ b/test/subgraph/SubgraphWidgetPromotion.test.ts @@ -103,7 +103,7 @@ describe("SubgraphWidgetPromotion", () => { const eventCapture = createEventCapture(subgraph.events, [ "widget-promoted", - "widget-unpromoted", + "widget-demoted", ]) const { node } = createNodeWithWidget("Test Node") @@ -119,7 +119,7 @@ describe("SubgraphWidgetPromotion", () => { eventCapture.cleanup() }) - it("should fire widget-unpromoted event when removing promoted widget", () => { + it("should fire widget-demoted event when removing promoted widget", () => { const subgraph = createTestSubgraph({ inputs: [{ name: "input", type: "number" }], }) @@ -128,16 +128,16 @@ describe("SubgraphWidgetPromotion", () => { const subgraphNode = setupPromotedWidget(subgraph, node) expect(subgraphNode.widgets).toHaveLength(1) - const eventCapture = createEventCapture(subgraph.events, ["widget-unpromoted"]) + const eventCapture = createEventCapture(subgraph.events, ["widget-demoted"]) // Remove the widget subgraphNode.removeWidgetByName("input") // Check event was fired - const unpromotedEvents = eventCapture.getEventsByType("widget-unpromoted") - expect(unpromotedEvents).toHaveLength(1) - expect(unpromotedEvents[0].detail.widget).toBeDefined() - expect(unpromotedEvents[0].detail.subgraphNode).toBe(subgraphNode) + const demotedEvents = eventCapture.getEventsByType("widget-demoted") + expect(demotedEvents).toHaveLength(1) + expect(demotedEvents[0].detail.widget).toBeDefined() + expect(demotedEvents[0].detail.subgraphNode).toBe(subgraphNode) // Widget should be removed expect(subgraphNode.widgets).toHaveLength(0) @@ -210,7 +210,7 @@ describe("SubgraphWidgetPromotion", () => { expect(promotedWidget.parentSubgraphNode).toBe(subgraphNode) - const eventCapture = createEventCapture(subgraph.events, ["widget-unpromoted"]) + const eventCapture = createEventCapture(subgraph.events, ["widget-demoted"]) // Remove the subgraph node subgraphNode.onRemoved() @@ -218,9 +218,9 @@ describe("SubgraphWidgetPromotion", () => { // parentSubgraphNode should be cleared expect(promotedWidget.parentSubgraphNode).toBeUndefined() - // Should fire unpromoted events for all widgets - const unpromotedEvents = eventCapture.getEventsByType("widget-unpromoted") - expect(unpromotedEvents).toHaveLength(1) + // Should fire demoted events for all widgets + const demotedEvents = eventCapture.getEventsByType("widget-demoted") + expect(demotedEvents).toHaveLength(1) eventCapture.cleanup() }) @@ -240,7 +240,6 @@ describe("SubgraphWidgetPromotion", () => { // DOM widget should be promoted with parentSubgraphNode expect(subgraphNode.widgets).toHaveLength(1) const promotedWidget = subgraphNode.widgets[0] - expect(promotedWidget.isDOMWidget()).toBe(true) expect(promotedWidget.parentSubgraphNode).toBe(subgraphNode) expect(promotedWidget.name).toBe("domInput") })