Fast_deploy / ComfyUI-MiniMaxH3-Context-Loop /web /h3_legacy_widget_width_fix.js
dzmdd's picture
Upload folder using huggingface_hub (part 3)
8fb6433 verified
Raw History Blame Contribute Delete
6.2 kB
import {app} from "/scripts/app.js";
import {
createLegacyWidgetWidthController,
graphNodes,
} from "./h3_legacy_widget_width_fix_core.mjs?v=0.6.2";
const SETTING_ID = "MiniMaxH3ContexLoop.legacyWidgetWidthFix";
const LEGACY_FIX_NODE = "LegacyWidgetWidthFix";
const REPAIR_BUTTON = "Repair widget widths now";
const HOST_LIFECYCLE_PATCH = "__h3_lwwf_host_lifecycle";
const LEGACY_LIFECYCLE_PATCH = "__h3_lwwf_legacy_lifecycle";
const LEGACY_DISPLAY_PREFIX = "MiniMax H3 Contex Loop";
const CURRENT_DISPLAY_PREFIX = "MiniMax H3 Context Loop";
const H3_NODE_TYPES = new Set([
"MiniMaxH3LoopTrim",
"MiniMaxH3ContexLoopSeamProbe",
"MiniMaxH3ChainPlan",
"MiniMaxH3ChainPlanModern",
"MiniMaxH3ChainCheckpointManager",
"MiniMaxH3ChainScenePromptEditor",
"MiniMaxH3ChainRunManager",
"MiniMaxH3ReferenceVideoPrepare",
"MiniMaxH3ScheduledPictureReference",
"MiniMaxH3ScheduledVideoReference",
"MiniMaxH3ScheduledAudioReference",
"MiniMaxH3ScheduledReferenceToVideo",
"MiniMaxH3TaggedPictureReference",
"MiniMaxH3TaggedVideoReference",
"MiniMaxH3TaggedMotionReference",
"MiniMaxH3LazyMotionAVLoader",
"MiniMaxH3TaggedMotionReferencePath",
"MiniMaxH3LazyMotionScenePreview",
"MiniMaxH3TaggedAudioReference",
"MiniMaxH3TaggedReferenceToVideo",
"MiniMaxH3ChainExternalVideo",
"MiniMaxH3ChainLoopStart",
"MiniMaxH3ChainCurrent",
"MiniMaxH3ChainContext",
"MiniMaxH3ChainSegmentSave",
"MiniMaxH3ChainReview",
"MiniMaxH3ChainLoopEnd",
"MiniMaxH3ChainManifestLoad",
"MiniMaxH3ChainExportPNG",
"MiniMaxH3ChainLatentVideoAdapter",
"MiniMaxH3ChainAssemble",
]);
function nodeType(node) {
return node?.comfyClass ?? node?.constructor?.comfyClass ?? node?.type ?? null;
}
function isH3Host(node) {
return H3_NODE_TYPES.has(nodeType(node));
}
function correctLegacyNodeTitle(node) {
if (!isH3Host(node) || typeof node?.title !== "string"
|| !node.title.includes(LEGACY_DISPLAY_PREFIX)) return false;
node.title = node.title.replaceAll(
LEGACY_DISPLAY_PREFIX, CURRENT_DISPLAY_PREFIX);
return true;
}
function correctLegacyGraphTitles(graph) {
for (const node of graphNodes(graph)) correctLegacyNodeTitle(node);
}
function schedule(callback) {
if (typeof globalThis.requestAnimationFrame === "function") {
globalThis.requestAnimationFrame(callback);
} else {
globalThis.setTimeout?.(callback, 0);
}
}
function askStandaloneFixToRepair() {
schedule(() => {
for (const node of graphNodes(app.graph)) {
if (nodeType(node) !== LEGACY_FIX_NODE) continue;
const button = node.widgets?.find((widget) =>
widget.name === REPAIR_BUTTON);
button?.callback?.();
}
});
}
const controller = createLegacyWidgetWidthController({
getGraph: () => app.graph,
requestFrame: schedule,
onRelinquish: askStandaloneFixToRepair,
});
function patchHostLifecycle(nodeTypeDefinition) {
const prototype = nodeTypeDefinition?.prototype;
if (!prototype || prototype[HOST_LIFECYCLE_PATCH]) return;
Object.defineProperty(prototype, HOST_LIFECYCLE_PATCH, {value: true});
const originalAdded = prototype.onAdded;
prototype.onAdded = function h3WidthFixHostAdded(...args) {
const result = originalAdded?.apply(this, args);
controller.addHost(this);
return result;
};
const originalRemoved = prototype.onRemoved;
prototype.onRemoved = function h3WidthFixHostRemoved(...args) {
try {
return originalRemoved?.apply(this, args);
} finally {
controller.removeHost(this);
}
};
}
function patchStandaloneRemoval(nodeTypeDefinition) {
const prototype = nodeTypeDefinition?.prototype;
if (!prototype || prototype[LEGACY_LIFECYCLE_PATCH]) return;
Object.defineProperty(prototype, LEGACY_LIFECYCLE_PATCH, {value: true});
const originalRemoved = prototype.onRemoved;
prototype.onRemoved = function h3WidthFixStandaloneRemoved(...args) {
try {
return originalRemoved?.apply(this, args);
} finally {
controller.scheduleRepairAll();
}
};
}
function settingEnabled() {
return app.ui?.settings?.getSettingValue?.(SETTING_ID) !== false;
}
app.registerExtension({
name: "MiniMaxH3ContexLoop.LegacyWidgetWidthFix",
init() {
controller.installHooks(globalThis.LGraphNode?.prototype);
app.ui?.settings?.addSetting?.({
id: SETTING_ID,
category: ["MiniMax H3 Context Loop", "Compatibility", "Widget widths"],
name: "Repair legacy widget widths while H3 nodes are present",
tooltip: "Works around ComfyUI frontend issue #12443 across the whole canvas. Disable only if your frontend has fixed the LiteGraph widget-width regression.",
type: "boolean",
defaultValue: true,
onChange(value) {
controller.setAllowed(value !== false);
},
});
controller.setAllowed(settingEnabled());
},
beforeRegisterNodeDef(nodeTypeDefinition, nodeData) {
controller.installHooks(globalThis.LGraphNode?.prototype);
if (H3_NODE_TYPES.has(nodeData?.name)) {
patchHostLifecycle(nodeTypeDefinition);
} else if (nodeData?.name === LEGACY_FIX_NODE) {
patchStandaloneRemoval(nodeTypeDefinition);
}
},
nodeCreated(node) {
controller.installHooks(globalThis.LGraphNode?.prototype);
correctLegacyNodeTitle(node);
if (isH3Host(node)) controller.addHost(node);
controller.nodeCreated(node);
},
afterConfigureGraph() {
correctLegacyGraphTitles(app.graph);
controller.syncHosts(graphNodes(app.graph), isH3Host);
controller.scheduleRepairAll();
},
setup() {
controller.installHooks(globalThis.LGraphNode?.prototype);
controller.setAllowed(settingEnabled());
correctLegacyGraphTitles(app.graph);
controller.syncHosts(graphNodes(app.graph), isH3Host);
controller.scheduleRepairAll();
},
});