- New nodes: Image Resize plus the Utility group (Text, Integer, Float, Show Text, Math Expression, Select Every Nth, Split Batch, Merge Batches, Free Memory) - the dependency-free gaps that let shared workflows drop heavy packs. - Replace with AusBoss nodes (prototype): preview-then-confirm graph rewrite swapping known third-party nodes for pack equivalents, with a tested translation map, per-node opt-out, and refuse-with-reason for nodes the pack cannot stand in for. - Load Video: single-frame FRAME picker, an honest "what will load" label from the probed source rate, drop-a-video-to-restore. Save Video: format-aware widgets and a file_path output. Stitch Inpaint gained a blend_mask output, Select Frame negative from-the-end indexing, Image Size a batch count - all appended, saved workflows load unchanged. - LoRA Loader: drag-to-reorder rows, hover thumbnails on rows, file size and date in the info card. - Appearance: flagship scheme deepened to slate-teal; the retired bright-teal pair upgrades automatically via LEGACY_SCHEME_PAIRS. Optional queue-completion chime, off by default. - Image Resize invariant: pixels are only invented on an explicit width+height pad request - scale-derived modes resolve divisible_by snaps with a sub-half-step resize, never bars. - Docs refreshed for six stale pages, stale text and metadata fixed across the pack, the panel-height rule codified in AGENTS.md and the brand skill, and ausboss_node_tour.json added - a model-free example exercising 17 node types in one graph. Validated: scripts/validate_nodes.py (24 files), 300 JS tests, all Python suites under the ComfyUI embedded interpreter.
36 lines
1.5 KiB
JavaScript
36 lines
1.5 KiB
JavaScript
// Decision logic for the Show Text panel. No DOM and no ComfyUI imports in
|
|
// here, so it stays testable under node:test.
|
|
|
|
// The executed message's `text` entry arrives however the run shaped it: our
|
|
// backend sends ["one string"], list-producing graphs deliver nested arrays,
|
|
// and a replayed history can hand the same payload back again. Flatten it to
|
|
// one displayable string. null means "nothing arrived", so the caller keeps
|
|
// its placeholder — distinct from "", which is a real (empty) result.
|
|
export function textFromExecuted(message) {
|
|
const value = message?.text;
|
|
if (value === undefined || value === null) return null;
|
|
const parts = [];
|
|
const walk = (entry) => {
|
|
if (entry === undefined || entry === null) return;
|
|
if (Array.isArray(entry)) {
|
|
for (const item of entry) walk(item);
|
|
return;
|
|
}
|
|
parts.push(typeof entry === "string" ? entry : String(entry));
|
|
};
|
|
walk(value);
|
|
if (!parts.length) return null;
|
|
return parts.join("\n");
|
|
}
|
|
|
|
// The panel is a viewport, not a document: a runaway string (a JSON dump, a
|
|
// caption model gone feral) must not build a multi-megabyte DOM node. The
|
|
// full string still flows through the node's STRING output untouched.
|
|
export const DISPLAY_LIMIT = 10000;
|
|
|
|
export function displayText(text, limit = DISPLAY_LIMIT) {
|
|
if (typeof text !== "string") return { text: "", truncated: false };
|
|
if (text.length <= limit) return { text, truncated: false };
|
|
return { text: text.slice(0, limit), truncated: true };
|
|
}
|