Compare commits

..

8 Commits

Author SHA1 Message Date
bymyself
4d19bd2f32 add browser test 2025-04-05 10:42:21 -07:00
bymyself
323db0e049 filter unserialized widgets values 2025-04-05 10:35:49 -07:00
Comfy Org PR Bot
3978613f14 1.15.11 (#3322)
Co-authored-by: webfiltered <176114999+webfiltered@users.noreply.github.com>
2025-04-05 17:56:18 +11:00
Comfy Org PR Bot
0a40e07f7e [chore] Update litegraph to 0.11.10 (#3321)
Co-authored-by: webfiltered <176114999+webfiltered@users.noreply.github.com>
2025-04-05 17:42:24 +11:00
Comfy Org PR Bot
577af51ff8 1.15.10 (#3319)
Co-authored-by: huchenlei <20929282+huchenlei@users.noreply.github.com>
2025-04-03 22:31:57 -04:00
Chenlei Hu
df7c7383e2 Only show reroute migration dialog when native reroute is not present (#3318) 2025-04-03 22:08:40 -04:00
Comfy Org PR Bot
1279f30f5a [chore] Update litegraph to 0.11.9 (#3316)
Co-authored-by: huchenlei <20929282+huchenlei@users.noreply.github.com>
2025-04-03 14:49:35 -04:00
Benjamin Lu
9ab4b549c0 Enable double clicking keybind row to edit bind (#2924) (#3315)
Co-authored-by: Benjamin Lu <templu1107@proton.me>
2025-04-03 14:04:02 -04:00
8 changed files with 89 additions and 13 deletions

View File

@@ -192,3 +192,19 @@ test.describe('Load audio widget', () => {
await expect(comfyPage.canvas).toHaveScreenshot('load_audio_widget.png')
})
})
test.describe('Unserialized widgets', () => {
test('Unserialized widgets values do not mark graph as modified', async ({
comfyPage
}) => {
// Add workflow w/ LoadImage node, which contains file upload and image preview widgets (not serialized)
await comfyPage.loadWorkflow('widgets/load_image_widget')
// Move mouse and click to trigger the `graphEqual` check in `changeTracker.ts`
await comfyPage.page.mouse.move(10, 10)
await comfyPage.page.mouse.click(10, 10)
// Expect the graph to not be modified
expect(await comfyPage.isCurrentWorkflowModified()).toBe(false)
})
})

12
package-lock.json generated
View File

@@ -1,18 +1,18 @@
{
"name": "@comfyorg/comfyui-frontend",
"version": "1.15.9",
"version": "1.15.11",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@comfyorg/comfyui-frontend",
"version": "1.15.9",
"version": "1.15.11",
"license": "GPL-3.0-only",
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
"@atlaskit/pragmatic-drag-and-drop": "^1.3.1",
"@comfyorg/comfyui-electron-types": "^0.4.31",
"@comfyorg/litegraph": "^0.11.8",
"@comfyorg/litegraph": "^0.11.10",
"@primevue/forms": "^4.2.5",
"@primevue/themes": "^4.2.5",
"@sentry/vue": "^8.48.0",
@@ -478,9 +478,9 @@
"license": "GPL-3.0-only"
},
"node_modules/@comfyorg/litegraph": {
"version": "0.11.8",
"resolved": "https://registry.npmjs.org/@comfyorg/litegraph/-/litegraph-0.11.8.tgz",
"integrity": "sha512-N2RJvLCD5m53WeJ4Ip5ZLG26LncqBisHfeKZegNOwADoaJiHoSFuJrqdLu4LFVTr9JxP7gI2dyTRW9gYI8njbg==",
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/@comfyorg/litegraph/-/litegraph-0.11.10.tgz",
"integrity": "sha512-3kMndikjaJSJ0NDQyueOKJKRI7GwThMIbdLSdPREnHiyCPpNusNev7bmzP4XvlzuLppmhH7dEwzBTWTQtQVRyA==",
"license": "MIT"
},
"node_modules/@cspotcode/source-map-support": {

View File

@@ -1,7 +1,7 @@
{
"name": "@comfyorg/comfyui-frontend",
"private": true,
"version": "1.15.9",
"version": "1.15.11",
"type": "module",
"repository": "https://github.com/Comfy-Org/ComfyUI_frontend",
"homepage": "https://comfy.org",
@@ -71,7 +71,7 @@
"@alloc/quick-lru": "^5.2.0",
"@atlaskit/pragmatic-drag-and-drop": "^1.3.1",
"@comfyorg/comfyui-electron-types": "^0.4.31",
"@comfyorg/litegraph": "^0.11.8",
"@comfyorg/litegraph": "^0.11.10",
"@primevue/forms": "^4.2.5",
"@primevue/themes": "^4.2.5",
"@sentry/vue": "^8.48.0",

View File

@@ -17,6 +17,7 @@
:pt="{
header: 'px-0'
}"
@rowDblclick="editKeybinding($event.data)"
>
<Column field="actions" header="">
<template #body="slotProps">

View File

@@ -48,7 +48,10 @@ import { ExtensionManager } from '@/types/extensionTypes'
import { ColorAdjustOptions, adjustColor } from '@/utils/colorUtil'
import { graphToPrompt } from '@/utils/executionUtil'
import { executeWidgetsCallback, isImageNode } from '@/utils/litegraphUtil'
import { findLegacyRerouteNodes } from '@/utils/migration/migrateReroute'
import {
findLegacyRerouteNodes,
noNativeReroutes
} from '@/utils/migration/migrateReroute'
import { deserialiseAndCreate } from '@/utils/vintageClipboard'
import { type ComfyApi, PromptExecutionError, api } from './api'
@@ -986,11 +989,15 @@ export class ComfyApp {
// Ideally we should not block users from loading the workflow.
graphData = validatedGraphData ?? graphData
}
// Only show the reroute migration warning if the workflow does not have native
// reroutes. Merging reroute network has great complexity, and it is not supported
// for now.
// See: https://github.com/Comfy-Org/ComfyUI_frontend/issues/3317
if (
checkForRerouteMigration &&
graphData.version === 0.4 &&
findLegacyRerouteNodes(graphData).length
findLegacyRerouteNodes(graphData).length &&
noNativeReroutes(graphData)
) {
useToastStore().add({
group: 'reroute-migration',

View File

@@ -8,6 +8,7 @@ import type { ExecutedWsMessage } from '@/schemas/apiSchema'
import type { ComfyWorkflowJSON } from '@/schemas/comfyWorkflowSchema'
import { useExecutionStore } from '@/stores/executionStore'
import { ComfyWorkflow, useWorkflowStore } from '@/stores/workflowStore'
import { filterSerializedWidgetValues } from '@/utils/litegraphUtil'
import { api } from './api'
import type { ComfyApp } from './app'
@@ -385,7 +386,10 @@ export class ChangeTracker {
if (
!_.isEqualWith(a.nodes, b.nodes, (arrA, arrB) => {
if (Array.isArray(arrA) && Array.isArray(arrB)) {
return _.isEqual(new Set(arrA), new Set(arrB))
// Filter non-serializable widget values before comparison
const filteredArrA = filterSerializedWidgetValues(arrA, app.graph)
const filteredArrB = filterSerializedWidgetValues(arrB, app.graph)
return _.isEqual(new Set(filteredArrA), new Set(filteredArrB))
}
})
) {

View File

@@ -1,8 +1,10 @@
import type { ColorOption } from '@comfyorg/litegraph'
import type { ColorOption, LGraph } from '@comfyorg/litegraph'
import { LGraphGroup, LGraphNode, isColorable } from '@comfyorg/litegraph'
import type { IComboWidget } from '@comfyorg/litegraph/dist/types/widgets'
import _ from 'lodash'
import type { ComfyNode } from '@/schemas/comfyWorkflowSchema'
type ImageNode = LGraphNode & { imgs: HTMLImageElement[] | undefined }
type VideoNode = LGraphNode & {
videoContainer: HTMLElement | undefined
@@ -70,3 +72,40 @@ export function executeWidgetsCallback(
}
}
}
/**
* Creates a copy of the nodes with non-serialized widget values removed
*/
export function filterSerializedWidgetValues(
nodes: ComfyNode[],
graph: LGraph
): ComfyNode[] {
if (!graph) return nodes
return nodes.map((node) => {
if (!node.widgets_values) return node
const graphNode = graph.getNodeById(node.id)
if (!graphNode?.widgets) return node
const filteredNode = { ...node }
const serializedValues = []
for (let i = 0; i < graphNode.widgets.length; i++) {
const widget = graphNode.widgets[i]
// Skip if widget is not serialized
if (!widget.options || widget.options.serialize !== false) {
const value = Array.isArray(node.widgets_values)
? node.widgets_values[i]
: node.widgets_values[widget.name || i.toString()]
serializedValues.push(
typeof value === 'object' && value !== null ? value.value : value
)
}
}
filteredNode.widgets_values = serializedValues
return filteredNode
})
}

View File

@@ -28,6 +28,15 @@ export function findLegacyRerouteNodes(
) as RerouteNode[]
}
/**
* Checks if the workflow has no native reroutes
*/
export function noNativeReroutes(workflow: WorkflowJSON04): boolean {
return (
!workflow.extra?.reroutes?.length && !workflow.extra?.linkExtensions?.length
)
}
/**
* Gets the center position of a node
*/