From 51f8fc7fe264a334c627a18f6939c9383857f4b7 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 22 Nov 2025 03:37:18 +0000 Subject: [PATCH] Fix widget callback context bug and update credits CRITICAL FIX: Widget callback context error in MimicPC/web-based ComfyUI BUG: TypeError: can't access property "step", this.options is undefined - ROOT CAUSE: Width/height widget callbacks used .bind(this) to bind to node - When calling originalWidthCallback.apply(this, arguments), passed NODE as context - Original callback expected WIDGET as context (needs this.options.step) - CRASH: Can't access this.options because node doesn't have options property THE FIX (RegionalPrompting.js:362-393): - REMOVED .bind(this) from widget callbacks - Captured node reference in closure: const node = this - Changed originalCallback.apply(this, arguments) to originalCallback.call(this, value) - Now callback executes with WIDGET as context (default when not bound) - Node properties accessed via closure: node.properties["width"] WHY THIS MATTERS: - MimicPC and browser-based ComfyUI instances couldn't load workflows at all - Error occurred during workflow loading when configuring widgets - Desktop ComfyUI might have different widget implementation (hence not caught earlier) - This is a fundamental JavaScript context issue - widgets expect widget context CREDITS UPDATE: - Added GitHub link to Davemane42: https://github.com/Davemane42 - Maintains original author credit while making it easier to find their work Documented complete technical details in CONTEXT.md. --- CONTEXT.md | 6 ++++++ README.md | 2 +- js/RegionalPrompting.js | 18 ++++++++++-------- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/CONTEXT.md b/CONTEXT.md index 5bac66c..1b19911 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -97,6 +97,12 @@ for prompt in prompts: - **Symptom:** Canvas widget completely invisible, no drawing interface shown - **Fix:** Added `WEB_DIRECTORY = os.path.join(os.path.dirname(__file__), "js")` export - **Impact:** JavaScript extensions weren't being loaded, canvas completely broken +- 🐛 **Widget Callback Context Bug:** Fixed `TypeError: can't access property "step", this.options is undefined` + - **Cause:** Width/height widget callbacks used `.bind(this)` which bound to node, then called original callback with node as context + - **Symptom:** Loading workflows crashed with "can't access property step" error (original callback expected widget as `this`) + - **Fix:** Removed `.bind(this)`, captured node reference in closure, call original callback with widget context using `.call(this, value)` + - **Impact:** Workflows wouldn't load at all in web-based ComfyUI instances (MimicPC, browser-based) + - **Location:** RegionalPrompting.js:364-393 - 🎨 **Node Naming:** Removed "EASY!" terminology and made names model-agnostic - **Before:** "Regional Prompter (Flux/Chroma - Easy!)" ← Model-specific and gimmicky - **After:** "Regional Prompter (Mask-Based)" ← Describes technique, not specific models diff --git a/README.md b/README.md index f312c26..c355d9c 100644 --- a/README.md +++ b/README.md @@ -450,7 +450,7 @@ TL;DR: Use it however you want, but don't blame us if it breaks! 😄 **Current Maintainer:** EnragedAntelope **Repository:** [github.com/EnragedAntelope/ComfyUI_RegionalConditioning](https://github.com/EnragedAntelope/ComfyUI_RegionalConditioning) -**Original Author:** Davemane42#0042 +**Original Author:** [Davemane42](https://github.com/Davemane42) **Original Concept:** Visual regional conditioning interface for ComfyUI **Modernization & Enhancement (2025):** diff --git a/js/RegionalPrompting.js b/js/RegionalPrompting.js index f49e3ae..cb09a47 100644 --- a/js/RegionalPrompting.js +++ b/js/RegionalPrompting.js @@ -361,34 +361,36 @@ app.registerExtension({ if (widthWidget) { const originalWidthCallback = widthWidget.callback; + const node = this; // Capture node reference for closure widthWidget.callback = function(value) { // Update canvas property to match - this.properties["width"] = value; + node.properties["width"] = value; // Force canvas redraw if (app.graph) { app.graph.setDirtyCanvas(true, true); } - // Call original callback if it exists + // Call original callback if it exists (with widget as context) if (originalWidthCallback) { - originalWidthCallback.apply(this, arguments); + originalWidthCallback.call(this, value); } - }.bind(this); + }; } if (heightWidget) { const originalHeightCallback = heightWidget.callback; + const node = this; // Capture node reference for closure heightWidget.callback = function(value) { // Update canvas property to match - this.properties["height"] = value; + node.properties["height"] = value; // Force canvas redraw if (app.graph) { app.graph.setDirtyCanvas(true, true); } - // Call original callback if it exists + // Call original callback if it exists (with widget as context) if (originalHeightCallback) { - originalHeightCallback.apply(this, arguments); + originalHeightCallback.call(this, value); } - }.bind(this); + }; } return r;