Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 74 additions & 3 deletions src/lib/litegraph/src/LGraphNode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
LGraphNode,
LiteGraph,
LGraph,
LGraphCanvas,
NodeInputSlot,
NodeOutputSlot
} from '@/lib/litegraph/src/litegraph'
Expand Down Expand Up @@ -148,15 +149,85 @@ describe('LGraphNode', () => {
expect(serialized).not.toHaveProperty('size')
})

test('keeps the recorded size while collapsed, since flags are replayed from the file', () => {
test('keeps the recorded size while collapsed, since a placeholder cannot re-derive an expanded one', () => {
const placeholder = createPlaceholder({ flags: { collapsed: false } })
placeholder.flags.collapsed = true
new LGraph().add(placeholder)
placeholder.collapse(true)
placeholder.setSize([80, 30])

const serialized = placeholder.serialize()

expect(serialized.size).toEqual([140, 60])
expect(serialized.flags).toEqual({ collapsed: false })
expect(serialized.flags).toEqual({ collapsed: true })
})

test('carries a live pin through', () => {
const placeholder = createPlaceholder()
new LGraph().add(placeholder)
placeholder.pin(true)

expect(placeholder.serialize().flags).toEqual({ pinned: true })
})

test('carries a live rename through', () => {
const placeholder = createPlaceholder({ title: 'Recorded Title' })
placeholder.title = 'renamed'

expect(placeholder.serialize().title).toEqual('renamed')
})

test('carries a live recolour through, over the recorded colours', () => {
const placeholder = createPlaceholder({
color: '#111',
bgcolor: '#222'
})
placeholder.setColorOption(LGraphCanvas.node_colors.red)

const serialized = placeholder.serialize()

expect(serialized.color).toEqual(LGraphCanvas.node_colors.red.color)
expect(serialized.bgcolor).toEqual(LGraphCanvas.node_colors.red.bgcolor)
})

test('drops the recorded colours when the live colour is cleared', () => {
const placeholder = createPlaceholder({
color: '#111',
bgcolor: '#222'
})
placeholder.setColorOption(null)

const serialized = placeholder.serialize()

expect(serialized).not.toHaveProperty('color')
expect(serialized).not.toHaveProperty('bgcolor')
})

test('round-trips an untouched placeholder that recorded decorations', () => {
const recorded = {
title: 'Recorded Title',
flags: { collapsed: true, pinned: true },
color: '#111',
bgcolor: '#222'
}
const serialized = createPlaceholder(recorded).serialize()

expect(serialized).toMatchObject(recorded)
})

test('round-trips an untouched placeholder that recorded no decorations', () => {
const serialized = createPlaceholder().serialize()

expect(serialized).not.toHaveProperty('title')
expect(serialized).not.toHaveProperty('color')
expect(serialized).not.toHaveProperty('bgcolor')
expect(serialized.flags).toEqual({})
})

test('does not invent flags when the recorded serialization has none', () => {
const placeholder = createPlaceholder()
delete (placeholder.last_serialization as Partial<ISerialisedNode>).flags

expect(placeholder.serialize()).not.toHaveProperty('flags')
})
})

Expand Down
33 changes: 25 additions & 8 deletions src/lib/litegraph/src/LGraphNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1061,22 +1061,39 @@ export class LGraphNode

// special case for when there were errors
if (this.constructor === LGraphNode && this.last_serialization) {
// Only an expanded placeholder whose file recorded a size has a live
// size worth keeping. Vue nodes mode drops the CSS width/height floors
// on collapse, so a collapsed node's size is a measurement of the
// collapsed card, and `flags` is replayed from the file — keeping both
// would pair `collapsed: false` with collapsed dimensions. With no
// recorded size there is no definition to compute a real one from, so
// keeping the live size would invent a dimension the file never had.
// A collapsed placeholder keeps the file's recorded (expanded) size:
// it has no definition to re-derive one from, and in Vue nodes mode a
// collapsed node's live size is a measurement of the collapsed card.
// With no recorded size there is nothing to fall back to either, so the
// live size would invent a dimension the file never had.
const carriesLiveSize =
this.last_serialization.size != null && !this.flags.collapsed
Comment thread
mattmillerai marked this conversation as resolved.
Outdated

return {
const result: ISerialisedNode = {
...this.last_serialization,
mode: o.mode,
pos: o.pos,
...(carriesLiveSize && { size: o.size })
}

// `flags` is required by the schema, but a hand-written file can omit it
// and an untouched placeholder has to round-trip that absence.
if (this.last_serialization.flags || Object.keys(o.flags).length)
Comment thread
mattmillerai marked this conversation as resolved.
Outdated
Comment thread
mattmillerai marked this conversation as resolved.
Outdated
result.flags = o.flags

// Mirror the normal path's title guard, and delete rather than skip the
// unset keys so a cleared decoration cannot resurrect the file's value.
if (this.title && this.title !== this.constructor.title)
result.title = this.title
else delete result.title

if (this.color) result.color = this.color
else delete result.color

if (this.bgcolor) result.bgcolor = this.bgcolor
else delete result.bgcolor
Comment thread
mattmillerai marked this conversation as resolved.
Outdated

return result
}

if (this.inputs)
Expand Down
Loading