Files
ausboss-ComfyUI-AusBoss/js/shared/show_text.mjs
T
ausboss 3f715a4af8 Ship the crush-list build-out: 7 new node files, replace button, video and LoRA polish
- 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.
2026-08-27 13:30:35 -05:00

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 };
}