mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-29 08:58:53 -03:00
fix(nodes): preserve autocomplete widget values across workflow restore
This commit is contained in:
@@ -139,7 +139,7 @@ const onWheel = (event: WheelEvent) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle external value changes (e.g., from "send lora to workflow")
|
// Handle external value changes (e.g., from "send lora to workflow")
|
||||||
const onExternalValueChange = (event: CustomEvent<{ value: string }>) => {
|
const onExternalValueChange = () => {
|
||||||
updateHasTextState()
|
updateHasTextState()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ const JSON_DISPLAY_WIDGET_MIN_WIDTH = 300
|
|||||||
const JSON_DISPLAY_WIDGET_MIN_HEIGHT = 200
|
const JSON_DISPLAY_WIDGET_MIN_HEIGHT = 200
|
||||||
const AUTOCOMPLETE_TEXT_WIDGET_MIN_HEIGHT = 60
|
const AUTOCOMPLETE_TEXT_WIDGET_MIN_HEIGHT = 60
|
||||||
const AUTOCOMPLETE_TEXT_WIDGET_MAX_HEIGHT = 100
|
const AUTOCOMPLETE_TEXT_WIDGET_MAX_HEIGHT = 100
|
||||||
|
const AUTOCOMPLETE_METADATA_VERSION = 1
|
||||||
|
const LORA_MANAGER_WIDGET_IDS_PROPERTY = '__lm_widget_ids'
|
||||||
|
|
||||||
// @ts-ignore - ComfyUI external module
|
// @ts-ignore - ComfyUI external module
|
||||||
import { app } from '../../../scripts/app.js'
|
import { app } from '../../../scripts/app.js'
|
||||||
@@ -373,6 +375,136 @@ function createJsonDisplayWidget(node) {
|
|||||||
// Store nodeData options per widget type for autocomplete widgets
|
// Store nodeData options per widget type for autocomplete widgets
|
||||||
const widgetInputOptions: Map<string, { placeholder?: string }> = new Map()
|
const widgetInputOptions: Map<string, { placeholder?: string }> = new Map()
|
||||||
|
|
||||||
|
function getSerializableWidgetNames(node: any): string[] {
|
||||||
|
return (node.widgets || [])
|
||||||
|
.filter((widget: any) => widget && widget.serialize !== false)
|
||||||
|
.map((widget: any) => widget.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
function createAutocompleteMetadataValue(textWidgetName = 'text') {
|
||||||
|
return {
|
||||||
|
version: AUTOCOMPLETE_METADATA_VERSION,
|
||||||
|
textWidgetName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function shouldBypassAutocompleteWidgetMigration(
|
||||||
|
node: any,
|
||||||
|
widgetValues: unknown[]
|
||||||
|
): boolean {
|
||||||
|
const inputDefs = node?.constructor?.nodeData?.inputs
|
||||||
|
if (!inputDefs || !Array.isArray(widgetValues)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const widgetNames = new Set((node.widgets || []).map((widget: any) => widget?.name))
|
||||||
|
const hasAutocompleteMetadataWidget = Array.from(widgetNames).some((name) =>
|
||||||
|
typeof name === 'string' && name.startsWith('__lm_autocomplete_meta_')
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!hasAutocompleteMetadataWidget) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const originalWidgetsInputs = Object.values(inputDefs).filter((input: any) =>
|
||||||
|
widgetNames.has(input.name) || input.forceInput
|
||||||
|
)
|
||||||
|
|
||||||
|
const widgetIndexHasForceInput = originalWidgetsInputs.flatMap((input: any) =>
|
||||||
|
input.control_after_generate
|
||||||
|
? [!!input.forceInput, false]
|
||||||
|
: [!!input.forceInput]
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
widgetIndexHasForceInput.some(Boolean) &&
|
||||||
|
widgetIndexHasForceInput.length === widgetValues.length
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function remapWidgetValuesByName(
|
||||||
|
widgetValues: unknown[],
|
||||||
|
savedWidgetNames: string[],
|
||||||
|
currentWidgetNames: string[]
|
||||||
|
): unknown[] {
|
||||||
|
const valueByName = new Map<string, unknown>()
|
||||||
|
savedWidgetNames.forEach((name, index) => {
|
||||||
|
if (index < widgetValues.length) {
|
||||||
|
valueByName.set(name, widgetValues[index])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const remappedValues: unknown[] = []
|
||||||
|
for (const name of currentWidgetNames) {
|
||||||
|
if (valueByName.has(name)) {
|
||||||
|
remappedValues.push(valueByName.get(name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return remappedValues
|
||||||
|
}
|
||||||
|
|
||||||
|
function injectDefaultAutocompleteMetadataValues(
|
||||||
|
widgetValues: unknown[],
|
||||||
|
currentWidgetNames: string[]
|
||||||
|
): unknown[] {
|
||||||
|
const repairedValues: unknown[] = []
|
||||||
|
let legacyValueIndex = 0
|
||||||
|
|
||||||
|
for (const widgetName of currentWidgetNames) {
|
||||||
|
if (widgetName.startsWith('__lm_autocomplete_meta_')) {
|
||||||
|
const textWidgetName = widgetName.replace('__lm_autocomplete_meta_', '') || 'text'
|
||||||
|
repairedValues.push(createAutocompleteMetadataValue(textWidgetName))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (legacyValueIndex < widgetValues.length) {
|
||||||
|
repairedValues.push(widgetValues[legacyValueIndex])
|
||||||
|
legacyValueIndex++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return repairedValues
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeAutocompleteWidgetValues(node: any, info: any) {
|
||||||
|
if (!info || !Array.isArray(info.widgets_values)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentWidgetNames = getSerializableWidgetNames(node)
|
||||||
|
if (currentWidgetNames.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const savedWidgetNames = info.properties?.[LORA_MANAGER_WIDGET_IDS_PROPERTY]
|
||||||
|
|
||||||
|
if (Array.isArray(savedWidgetNames) && savedWidgetNames.length > 0) {
|
||||||
|
const remappedValues = remapWidgetValuesByName(
|
||||||
|
info.widgets_values,
|
||||||
|
savedWidgetNames,
|
||||||
|
currentWidgetNames
|
||||||
|
)
|
||||||
|
info.widgets_values = remappedValues
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const metadataWidgetCount = currentWidgetNames.filter((name) =>
|
||||||
|
name.startsWith('__lm_autocomplete_meta_')
|
||||||
|
).length
|
||||||
|
|
||||||
|
if (
|
||||||
|
metadataWidgetCount > 0 &&
|
||||||
|
info.widgets_values.length === currentWidgetNames.length - metadataWidgetCount
|
||||||
|
) {
|
||||||
|
const repairedValues = injectDefaultAutocompleteMetadataValues(
|
||||||
|
info.widgets_values,
|
||||||
|
currentWidgetNames
|
||||||
|
)
|
||||||
|
info.widgets_values = repairedValues
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Listen for Vue DOM mode setting changes and dispatch custom event
|
// Listen for Vue DOM mode setting changes and dispatch custom event
|
||||||
const initVueDomModeListener = () => {
|
const initVueDomModeListener = () => {
|
||||||
if (app.ui?.settings?.addEventListener) {
|
if (app.ui?.settings?.addEventListener) {
|
||||||
@@ -429,9 +561,10 @@ function createAutocompleteTextWidgetFactory(
|
|||||||
;(container as any).__widgetInputEl = widgetElementRef
|
;(container as any).__widgetInputEl = widgetElementRef
|
||||||
|
|
||||||
const metadataWidget = node.addWidget('text', metadataWidgetName, {
|
const metadataWidget = node.addWidget('text', metadataWidgetName, {
|
||||||
version: 1,
|
version: AUTOCOMPLETE_METADATA_VERSION,
|
||||||
textWidgetName: widgetName
|
textWidgetName: widgetName
|
||||||
})
|
})
|
||||||
|
metadataWidget.value = createAutocompleteMetadataValue(widgetName)
|
||||||
metadataWidget.type = 'LORA_MANAGER_AUTOCOMPLETE_METADATA'
|
metadataWidget.type = 'LORA_MANAGER_AUTOCOMPLETE_METADATA'
|
||||||
metadataWidget.hidden = true
|
metadataWidget.hidden = true
|
||||||
metadataWidget.computeSize = () => [0, -4]
|
metadataWidget.computeSize = () => [0, -4]
|
||||||
@@ -569,15 +702,38 @@ app.registerExtension({
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
async beforeRegisterNodeDef(nodeType, nodeData) {
|
async beforeRegisterNodeDef(nodeType, nodeData) {
|
||||||
const comfyClass = nodeType.comfyClass
|
const comfyClass = nodeType.comfyClass
|
||||||
|
const inputs = { ...nodeData.input?.required, ...nodeData.input?.optional }
|
||||||
|
let hasAutocompleteWidget = false
|
||||||
|
|
||||||
// Extract and store input options for autocomplete widgets
|
// Extract and store input options for autocomplete widgets
|
||||||
const inputs = { ...nodeData.input?.required, ...nodeData.input?.optional }
|
|
||||||
for (const [inputName, inputDef] of Object.entries(inputs)) {
|
for (const [inputName, inputDef] of Object.entries(inputs)) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (Array.isArray(inputDef) && typeof inputDef[0] === 'string' && inputDef[0].startsWith('AUTOCOMPLETE_TEXT_')) {
|
if (Array.isArray(inputDef) && typeof inputDef[0] === 'string' && inputDef[0].startsWith('AUTOCOMPLETE_TEXT_')) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const options = inputDef[1] || {}
|
const options = inputDef[1] || {}
|
||||||
widgetInputOptions.set(`${nodeData.name}:${inputName}`, options)
|
widgetInputOptions.set(`${nodeData.name}:${inputName}`, options)
|
||||||
|
hasAutocompleteWidget = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasAutocompleteWidget) {
|
||||||
|
const originalOnSerialize = nodeType.prototype.onSerialize
|
||||||
|
const originalConfigure = nodeType.prototype.configure
|
||||||
|
|
||||||
|
nodeType.prototype.onSerialize = function (serialized: any) {
|
||||||
|
originalOnSerialize?.apply(this, arguments)
|
||||||
|
|
||||||
|
serialized.properties = serialized.properties || {}
|
||||||
|
const widgetIds = getSerializableWidgetNames(this)
|
||||||
|
serialized.properties[LORA_MANAGER_WIDGET_IDS_PROPERTY] = widgetIds
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeType.prototype.configure = function (info: any) {
|
||||||
|
normalizeAutocompleteWidgetValues(this, info)
|
||||||
|
if (shouldBypassAutocompleteWidgetMigration(this, info?.widgets_values ?? [])) {
|
||||||
|
info.widgets_values = [...(info.widgets_values ?? []), null]
|
||||||
|
}
|
||||||
|
return originalConfigure?.apply(this, arguments)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2118,14 +2118,14 @@ to { transform: rotate(360deg);
|
|||||||
padding: 20px 0;
|
padding: 20px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.autocomplete-text-widget[data-v-918e2bc5] {
|
.autocomplete-text-widget[data-v-76ce0f19] {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
.input-wrapper[data-v-918e2bc5] {
|
.input-wrapper[data-v-76ce0f19] {
|
||||||
position: relative;
|
position: relative;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -2133,7 +2133,7 @@ to { transform: rotate(360deg);
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Canvas mode styles (default) - matches built-in comfy-multiline-input */
|
/* Canvas mode styles (default) - matches built-in comfy-multiline-input */
|
||||||
.text-input[data-v-918e2bc5] {
|
.text-input[data-v-76ce0f19] {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: var(--comfy-input-bg, #222);
|
background-color: var(--comfy-input-bg, #222);
|
||||||
@@ -2150,7 +2150,7 @@ to { transform: rotate(360deg);
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Vue DOM mode styles - matches built-in p-textarea in Vue DOM mode */
|
/* Vue DOM mode styles - matches built-in p-textarea in Vue DOM mode */
|
||||||
.text-input.vue-dom-mode[data-v-918e2bc5] {
|
.text-input.vue-dom-mode[data-v-76ce0f19] {
|
||||||
background-color: var(--color-charcoal-400, #313235);
|
background-color: var(--color-charcoal-400, #313235);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
padding: 8px 12px 30px 12px; /* Reserve bottom space for clear button */
|
padding: 8px 12px 30px 12px; /* Reserve bottom space for clear button */
|
||||||
@@ -2159,12 +2159,12 @@ to { transform: rotate(360deg);
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
}
|
}
|
||||||
.text-input[data-v-918e2bc5]:focus {
|
.text-input[data-v-76ce0f19]:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear button styles */
|
/* Clear button styles */
|
||||||
.clear-button[data-v-918e2bc5] {
|
.clear-button[data-v-76ce0f19] {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 6px;
|
right: 6px;
|
||||||
bottom: 6px; /* Changed from top to bottom */
|
bottom: 6px; /* Changed from top to bottom */
|
||||||
@@ -2187,31 +2187,31 @@ to { transform: rotate(360deg);
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Show clear button when hovering over input wrapper */
|
/* Show clear button when hovering over input wrapper */
|
||||||
.input-wrapper:hover .clear-button[data-v-918e2bc5] {
|
.input-wrapper:hover .clear-button[data-v-76ce0f19] {
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
.clear-button[data-v-918e2bc5]:hover {
|
.clear-button[data-v-76ce0f19]:hover {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
background: rgba(255, 100, 100, 0.8);
|
background: rgba(255, 100, 100, 0.8);
|
||||||
}
|
}
|
||||||
.clear-button svg[data-v-918e2bc5] {
|
.clear-button svg[data-v-76ce0f19] {
|
||||||
width: 12px;
|
width: 12px;
|
||||||
height: 12px;
|
height: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Vue DOM mode adjustments for clear button */
|
/* Vue DOM mode adjustments for clear button */
|
||||||
.text-input.vue-dom-mode ~ .clear-button[data-v-918e2bc5] {
|
.text-input.vue-dom-mode ~ .clear-button[data-v-76ce0f19] {
|
||||||
right: 8px;
|
right: 8px;
|
||||||
bottom: 10px; /* Changed from top to bottom, adjusted for Vue DOM padding */
|
bottom: 10px; /* Changed from top to bottom, adjusted for Vue DOM padding */
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
background: rgba(107, 114, 128, 0.6);
|
background: rgba(107, 114, 128, 0.6);
|
||||||
}
|
}
|
||||||
.text-input.vue-dom-mode ~ .clear-button[data-v-918e2bc5]:hover {
|
.text-input.vue-dom-mode ~ .clear-button[data-v-76ce0f19]:hover {
|
||||||
background: oklch(62% 0.18 25);
|
background: oklch(62% 0.18 25);
|
||||||
}
|
}
|
||||||
.text-input.vue-dom-mode ~ .clear-button svg[data-v-918e2bc5] {
|
.text-input.vue-dom-mode ~ .clear-button svg[data-v-76ce0f19] {
|
||||||
width: 14px;
|
width: 14px;
|
||||||
height: 14px;
|
height: 14px;
|
||||||
}`));
|
}`));
|
||||||
@@ -14748,7 +14748,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|||||||
app2.canvas.processMouseWheel(event);
|
app2.canvas.processMouseWheel(event);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const onExternalValueChange = (event) => {
|
const onExternalValueChange = () => {
|
||||||
updateHasTextState();
|
updateHasTextState();
|
||||||
};
|
};
|
||||||
const setupWidgetOnSetValue = () => {
|
const setupWidgetOnSetValue = () => {
|
||||||
@@ -14847,7 +14847,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const AutocompleteTextWidget = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-918e2bc5"]]);
|
const AutocompleteTextWidget = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-76ce0f19"]]);
|
||||||
const LORA_PROVIDER_NODE_TYPES$1 = [
|
const LORA_PROVIDER_NODE_TYPES$1 = [
|
||||||
"Lora Stacker (LoraManager)",
|
"Lora Stacker (LoraManager)",
|
||||||
"Lora Randomizer (LoraManager)",
|
"Lora Randomizer (LoraManager)",
|
||||||
@@ -15127,6 +15127,8 @@ const JSON_DISPLAY_WIDGET_MIN_WIDTH = 300;
|
|||||||
const JSON_DISPLAY_WIDGET_MIN_HEIGHT = 200;
|
const JSON_DISPLAY_WIDGET_MIN_HEIGHT = 200;
|
||||||
const AUTOCOMPLETE_TEXT_WIDGET_MIN_HEIGHT = 60;
|
const AUTOCOMPLETE_TEXT_WIDGET_MIN_HEIGHT = 60;
|
||||||
const AUTOCOMPLETE_TEXT_WIDGET_MAX_HEIGHT = 100;
|
const AUTOCOMPLETE_TEXT_WIDGET_MAX_HEIGHT = 100;
|
||||||
|
const AUTOCOMPLETE_METADATA_VERSION = 1;
|
||||||
|
const LORA_MANAGER_WIDGET_IDS_PROPERTY = "__lm_widget_ids";
|
||||||
function forwardMiddleMouseToCanvas(container) {
|
function forwardMiddleMouseToCanvas(container) {
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
container.addEventListener("pointerdown", (event) => {
|
container.addEventListener("pointerdown", (event) => {
|
||||||
@@ -15397,6 +15399,97 @@ function createJsonDisplayWidget(node) {
|
|||||||
return { widget };
|
return { widget };
|
||||||
}
|
}
|
||||||
const widgetInputOptions = /* @__PURE__ */ new Map();
|
const widgetInputOptions = /* @__PURE__ */ new Map();
|
||||||
|
function getSerializableWidgetNames(node) {
|
||||||
|
return (node.widgets || []).filter((widget) => widget && widget.serialize !== false).map((widget) => widget.name);
|
||||||
|
}
|
||||||
|
function createAutocompleteMetadataValue(textWidgetName = "text") {
|
||||||
|
return {
|
||||||
|
version: AUTOCOMPLETE_METADATA_VERSION,
|
||||||
|
textWidgetName
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function shouldBypassAutocompleteWidgetMigration(node, widgetValues) {
|
||||||
|
var _a2, _b;
|
||||||
|
const inputDefs = (_b = (_a2 = node == null ? void 0 : node.constructor) == null ? void 0 : _a2.nodeData) == null ? void 0 : _b.inputs;
|
||||||
|
if (!inputDefs || !Array.isArray(widgetValues)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const widgetNames = new Set((node.widgets || []).map((widget) => widget == null ? void 0 : widget.name));
|
||||||
|
const hasAutocompleteMetadataWidget = Array.from(widgetNames).some(
|
||||||
|
(name) => typeof name === "string" && name.startsWith("__lm_autocomplete_meta_")
|
||||||
|
);
|
||||||
|
if (!hasAutocompleteMetadataWidget) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const originalWidgetsInputs = Object.values(inputDefs).filter(
|
||||||
|
(input) => widgetNames.has(input.name) || input.forceInput
|
||||||
|
);
|
||||||
|
const widgetIndexHasForceInput = originalWidgetsInputs.flatMap(
|
||||||
|
(input) => input.control_after_generate ? [!!input.forceInput, false] : [!!input.forceInput]
|
||||||
|
);
|
||||||
|
return widgetIndexHasForceInput.some(Boolean) && widgetIndexHasForceInput.length === widgetValues.length;
|
||||||
|
}
|
||||||
|
function remapWidgetValuesByName(widgetValues, savedWidgetNames, currentWidgetNames) {
|
||||||
|
const valueByName = /* @__PURE__ */ new Map();
|
||||||
|
savedWidgetNames.forEach((name, index) => {
|
||||||
|
if (index < widgetValues.length) {
|
||||||
|
valueByName.set(name, widgetValues[index]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const remappedValues = [];
|
||||||
|
for (const name of currentWidgetNames) {
|
||||||
|
if (valueByName.has(name)) {
|
||||||
|
remappedValues.push(valueByName.get(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return remappedValues;
|
||||||
|
}
|
||||||
|
function injectDefaultAutocompleteMetadataValues(widgetValues, currentWidgetNames) {
|
||||||
|
const repairedValues = [];
|
||||||
|
let legacyValueIndex = 0;
|
||||||
|
for (const widgetName of currentWidgetNames) {
|
||||||
|
if (widgetName.startsWith("__lm_autocomplete_meta_")) {
|
||||||
|
const textWidgetName = widgetName.replace("__lm_autocomplete_meta_", "") || "text";
|
||||||
|
repairedValues.push(createAutocompleteMetadataValue(textWidgetName));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (legacyValueIndex < widgetValues.length) {
|
||||||
|
repairedValues.push(widgetValues[legacyValueIndex]);
|
||||||
|
legacyValueIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return repairedValues;
|
||||||
|
}
|
||||||
|
function normalizeAutocompleteWidgetValues(node, info) {
|
||||||
|
var _a2;
|
||||||
|
if (!info || !Array.isArray(info.widgets_values)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const currentWidgetNames = getSerializableWidgetNames(node);
|
||||||
|
if (currentWidgetNames.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const savedWidgetNames = (_a2 = info.properties) == null ? void 0 : _a2[LORA_MANAGER_WIDGET_IDS_PROPERTY];
|
||||||
|
if (Array.isArray(savedWidgetNames) && savedWidgetNames.length > 0) {
|
||||||
|
const remappedValues = remapWidgetValuesByName(
|
||||||
|
info.widgets_values,
|
||||||
|
savedWidgetNames,
|
||||||
|
currentWidgetNames
|
||||||
|
);
|
||||||
|
info.widgets_values = remappedValues;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const metadataWidgetCount = currentWidgetNames.filter(
|
||||||
|
(name) => name.startsWith("__lm_autocomplete_meta_")
|
||||||
|
).length;
|
||||||
|
if (metadataWidgetCount > 0 && info.widgets_values.length === currentWidgetNames.length - metadataWidgetCount) {
|
||||||
|
const repairedValues = injectDefaultAutocompleteMetadataValues(
|
||||||
|
info.widgets_values,
|
||||||
|
currentWidgetNames
|
||||||
|
);
|
||||||
|
info.widgets_values = repairedValues;
|
||||||
|
}
|
||||||
|
}
|
||||||
const initVueDomModeListener = () => {
|
const initVueDomModeListener = () => {
|
||||||
var _a2, _b;
|
var _a2, _b;
|
||||||
if ((_b = (_a2 = app$1.ui) == null ? void 0 : _a2.settings) == null ? void 0 : _b.addEventListener) {
|
if ((_b = (_a2 = app$1.ui) == null ? void 0 : _a2.settings) == null ? void 0 : _b.addEventListener) {
|
||||||
@@ -15436,9 +15529,10 @@ function createAutocompleteTextWidgetFactory(node, widgetName, modelType, inputO
|
|||||||
const widgetElementRef = { inputEl: void 0 };
|
const widgetElementRef = { inputEl: void 0 };
|
||||||
container.__widgetInputEl = widgetElementRef;
|
container.__widgetInputEl = widgetElementRef;
|
||||||
const metadataWidget = node.addWidget("text", metadataWidgetName, {
|
const metadataWidget = node.addWidget("text", metadataWidgetName, {
|
||||||
version: 1,
|
version: AUTOCOMPLETE_METADATA_VERSION,
|
||||||
textWidgetName: widgetName
|
textWidgetName: widgetName
|
||||||
});
|
});
|
||||||
|
metadataWidget.value = createAutocompleteMetadataValue(widgetName);
|
||||||
metadataWidget.type = "LORA_MANAGER_AUTOCOMPLETE_METADATA";
|
metadataWidget.type = "LORA_MANAGER_AUTOCOMPLETE_METADATA";
|
||||||
metadataWidget.hidden = true;
|
metadataWidget.hidden = true;
|
||||||
metadataWidget.computeSize = () => [0, -4];
|
metadataWidget.computeSize = () => [0, -4];
|
||||||
@@ -15562,12 +15656,31 @@ app$1.registerExtension({
|
|||||||
var _a2, _b;
|
var _a2, _b;
|
||||||
const comfyClass = nodeType.comfyClass;
|
const comfyClass = nodeType.comfyClass;
|
||||||
const inputs = { ...(_a2 = nodeData.input) == null ? void 0 : _a2.required, ...(_b = nodeData.input) == null ? void 0 : _b.optional };
|
const inputs = { ...(_a2 = nodeData.input) == null ? void 0 : _a2.required, ...(_b = nodeData.input) == null ? void 0 : _b.optional };
|
||||||
|
let hasAutocompleteWidget = false;
|
||||||
for (const [inputName, inputDef] of Object.entries(inputs)) {
|
for (const [inputName, inputDef] of Object.entries(inputs)) {
|
||||||
if (Array.isArray(inputDef) && typeof inputDef[0] === "string" && inputDef[0].startsWith("AUTOCOMPLETE_TEXT_")) {
|
if (Array.isArray(inputDef) && typeof inputDef[0] === "string" && inputDef[0].startsWith("AUTOCOMPLETE_TEXT_")) {
|
||||||
const options = inputDef[1] || {};
|
const options = inputDef[1] || {};
|
||||||
widgetInputOptions.set(`${nodeData.name}:${inputName}`, options);
|
widgetInputOptions.set(`${nodeData.name}:${inputName}`, options);
|
||||||
|
hasAutocompleteWidget = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (hasAutocompleteWidget) {
|
||||||
|
const originalOnSerialize = nodeType.prototype.onSerialize;
|
||||||
|
const originalConfigure = nodeType.prototype.configure;
|
||||||
|
nodeType.prototype.onSerialize = function(serialized) {
|
||||||
|
originalOnSerialize == null ? void 0 : originalOnSerialize.apply(this, arguments);
|
||||||
|
serialized.properties = serialized.properties || {};
|
||||||
|
const widgetIds = getSerializableWidgetNames(this);
|
||||||
|
serialized.properties[LORA_MANAGER_WIDGET_IDS_PROPERTY] = widgetIds;
|
||||||
|
};
|
||||||
|
nodeType.prototype.configure = function(info) {
|
||||||
|
normalizeAutocompleteWidgetValues(this, info);
|
||||||
|
if (shouldBypassAutocompleteWidgetMigration(this, (info == null ? void 0 : info.widgets_values) ?? [])) {
|
||||||
|
info.widgets_values = [...info.widgets_values ?? [], null];
|
||||||
|
}
|
||||||
|
return originalConfigure == null ? void 0 : originalConfigure.apply(this, arguments);
|
||||||
|
};
|
||||||
|
}
|
||||||
if (LORA_PROVIDER_NODE_TYPES$1.includes(comfyClass)) {
|
if (LORA_PROVIDER_NODE_TYPES$1.includes(comfyClass)) {
|
||||||
const originalOnNodeCreated = nodeType.prototype.onNodeCreated;
|
const originalOnNodeCreated = nodeType.prototype.onNodeCreated;
|
||||||
nodeType.prototype.onNodeCreated = function() {
|
nodeType.prototype.onNodeCreated = function() {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user