fix: restore Load3D widget rendering

This commit is contained in:
DrJKL
2026-06-30 14:25:12 -07:00
parent 66bad3b522
commit 4dac3ccb22
4 changed files with 75 additions and 1 deletions

View File

@@ -4,7 +4,15 @@ import { setActivePinia } from 'pinia'
import { beforeEach, describe, expect, it } from 'vitest'
import { LGraph, LGraphNode } from '@/lib/litegraph/src/litegraph'
import type { INumericWidget } from '@/lib/litegraph/src/types/widgets'
import type {
IBaseWidget,
INumericWidget
} from '@/lib/litegraph/src/types/widgets'
import { BaseWidget } from '@/lib/litegraph/src/widgets/BaseWidget'
import type {
DrawWidgetOptions,
WidgetEventOptions
} from '@/lib/litegraph/src/widgets/BaseWidget'
import { NumberWidget } from '@/lib/litegraph/src/widgets/NumberWidget'
import { useWidgetValueStore } from '@/stores/widgetValueStore'
import { toNodeId } from '@/types/nodeId'
@@ -27,6 +35,28 @@ function createTestWidget(
)
}
class MutableTypeWidget extends BaseWidget<IBaseWidget<number, string>> {
drawWidget(
_ctx: CanvasRenderingContext2D,
_options: DrawWidgetOptions
): void {}
onClick(_options: WidgetEventOptions): void {}
}
function createMutableTypeWidget(node: LGraphNode): MutableTypeWidget {
return new MutableTypeWidget(
{
type: 'number',
name: 'typeChangedWidget',
value: 42,
options: { min: 0, max: 100 },
y: 0
},
node
)
}
describe('BaseWidget store integration', () => {
let graph: LGraph
let node: LGraphNode
@@ -175,6 +205,31 @@ describe('BaseWidget store integration', () => {
store.getWidget(widgetId(graph.id, toNodeId(1), 'valuesWidget'))?.value
).toBe(77)
})
it('registers the live widget type', () => {
const widget = createMutableTypeWidget(node)
widget.type = 'number-custom'
widget.setNodeId(toNodeId(1))
expect(
store.getWidget(widgetId(graph.id, toNodeId(1), 'typeChangedWidget'))
?.type
).toBe('number-custom')
})
it('stores explicit isDOMWidget false over component presence', () => {
const widget = createTestWidget(node, { name: 'flaggedDomWidget' })
Object.assign(widget, { component: {}, isDOMWidget: false })
widget.setNodeId(toNodeId(1))
expect(
store.getWidgetRenderState(
widgetId(graph.id, toNodeId(1), 'flaggedDomWidget')
)?.isDOMWidget
).toBe(false)
})
})
describe('DOM widget value registration', () => {

View File

@@ -47,6 +47,9 @@ export interface WidgetEventOptions {
}
function isDOMBackedWidget(widget: IBaseWidget): boolean {
if ('isDOMWidget' in widget && typeof widget.isDOMWidget === 'boolean') {
return widget.isDOMWidget
}
return (
('element' in widget && !!widget.element) ||
('component' in widget && !!widget.component)
@@ -158,6 +161,7 @@ export abstract class BaseWidget<TWidget extends IBaseWidget = IBaseWidget>
const id = widgetId(graphId, nodeId, this.name)
this._state = store.registerWidget(id, {
...this._state,
type: this.type,
value: this.value
})
store.registerWidgetRenderState(id, {

View File

@@ -12,6 +12,8 @@ import {
hasWidgetError,
isWidgetVisible
} from '@/renderer/extensions/vueNodes/composables/useProcessedWidgets'
import WidgetDOM from '@/renderer/extensions/vueNodes/widgets/components/WidgetDOM.vue'
import WidgetLegacy from '@/renderer/extensions/vueNodes/widgets/components/WidgetLegacy.vue'
import { useExecutionErrorStore } from '@/stores/executionErrorStore'
import { useWidgetValueStore } from '@/stores/widgetValueStore'
import {
@@ -445,6 +447,16 @@ describe('computeProcessedWidgets', () => {
}
})
})
it('treats explicit isDOMWidget false as authoritative', () => {
const widget = createMockWidget({ name: 'custom', type: 'unknown' })
Object.assign(widget, { component: {}, isDOMWidget: false })
const result = processWidgets({ widgets: [widget] })
expect(result[0].vueComponent).toBe(WidgetLegacy)
expect(result[0].vueComponent).not.toBe(WidgetDOM)
})
})
describe('createWidgetUpdateHandler (via computeProcessedWidgets)', () => {

View File

@@ -150,6 +150,9 @@ function normalizeWidgetValue(value: unknown): WidgetValue {
}
function isDOMBackedWidget(widget: IBaseWidget): boolean {
if ('isDOMWidget' in widget && typeof widget.isDOMWidget === 'boolean') {
return widget.isDOMWidget
}
return (
('element' in widget && !!widget.element) ||
('component' in widget && !!widget.component)