diff --git a/AF_Enhanced_HTML_Note.py b/AF_Enhanced_HTML_Note.py index e0e70cf..2a967a0 100644 --- a/AF_Enhanced_HTML_Note.py +++ b/AF_Enhanced_HTML_Note.py @@ -1,13 +1,6 @@ # ****** ComfyUI-AF - Enhanced HTML-NOTE ****** # -# Creator: Alex Furer - Co-Creator(s): Claude AI -# -# Praise, comment, bugs, improvements: https://github.com/alFrame/ComfyUI_AF_FindNodeByID -# -# LICENSE: MIT License -## ****** ComfyUI-AF - Enhanced HTML-NOTE ****** -# -# Creator: Alex Furer - Co-Creator(s): Claude AI +# Creator: Alex Furer - Co-Creator(s): Claude AI & DeepSeek # # Praise, comment, bugs, improvements: https://github.com/alFrame/ComfyUI_AF_FindNodeByID # @@ -25,7 +18,7 @@ # v0.0.04 # - Fixed node selection and resizing by removing OUTPUT_NODE and using proper widget approach # - Double clicking is now used to edit the html -# - Mouse interaction is now persistent to ComfyUI behaviour. Except middle mouse button for panning. +# - Mouse interaction is now persistent to ComfyUI behavior. Except middle mouse button for panning. # v0.0.03 # - Fixed node resizing issues on save/reload # - Improved selection and edit mode behavior to match ComfyUI core notes @@ -52,7 +45,7 @@ class AF_Enhanced_HTML_Note: "default": """

đŸŸĸ Positive Prompts

Your positive prompts go here...

- Click me! + Click me!
@@ -96,85 +89,3 @@ NODE_CLASS_MAPPINGS = { NODE_DISPLAY_NAME_MAPPINGS = { "AF_Enhanced_HTML_Note": "AF - Enhanced HTML Note", } -# v0.0.04 -# -# Description: -# A ComfyUI Note node with html capabilities. Create notes, UI's and ReadMe's directly inside the workflow, using html. -# -# Usage: -# Read Me on Github -# -# Changelog: -# v0.0.04 -# - Removed width and height parameters - using standard ComfyUI resizing -# - Simplified node to be just the HTML display -# v0.0.03 -# - Fixed node resizing issues on save/reload -# - Improved selection and edit mode behavior to match ComfyUI core notes -# - Fixed middle mouse button panning over the node -# - Improved HTML indentation in default content -# v0.0.02 -# - Fixed naming consistency to HTML_Note -# - Implemented single-window toggle behavior -# v0.0.01 -# - Initial Version -# - -class AF_Enhanced_HTML_Note: - """ - AF Enhanced HTML-Note node with colored sections and rich formatting - """ - - @classmethod - def INPUT_TYPES(cls): - return { - "required": { - "html_content": ("STRING", { - "multiline": True, - "default": """
-

đŸŸĸ Positive Prompts

-

Your positive prompts go here...

- Click me! -
- -
- -
-

🔴 Negative Prompts

-

Your negative prompts go here...

-
- -
- -
-

📝 Notes

-

Additional notes and information...

- -
""", - "placeholder": "Enter your HTML content here..." - }), - } - } - - RETURN_TYPES = () - FUNCTION = "display_html" - CATEGORY = "AF - Nodes" - OUTPUT_NODE = False - - def display_html(self, html_content): - """ - Display enhanced HTML content - """ - return {"ui": {"text": html_content}, "result": (html_content,)} - -# Node mappings for ComfyUI -NODE_CLASS_MAPPINGS = { - "AF_Enhanced_HTML_Note": AF_Enhanced_HTML_Note, -} - -NODE_DISPLAY_NAME_MAPPINGS = { - "AF_Enhanced_HTML_Note": "AF - Enhanced HTML Note", -} \ No newline at end of file diff --git a/README.md b/README.md index be73018..b7a491f 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,34 @@ # AF Enhanced HTML Node - Usage Guide -A ComfyUI Note node with html capabilities. Create notes, UI's and ReadMe's directly inside the workflow, using html. +A ComfyUI Note node with HTML capabilities. Create notes, UI's and ReadMe's directly inside the workflow using rich HTML formatting. -## Basic Section Colors +## ✨ Key Features + +- **Rich HTML Support** - Full HTML formatting with colored sections, lists, tables, code blocks, and more +- **Non-Intrusive Design** - Doesn't interfere with normal ComfyUI workflow interactions +- **Easy Editing** - Double-click anywhere on the content to edit HTML +- **Smart Links** - Ctrl+click to open external links or trigger custom actions +- **Beautiful Styling** - Predefined color schemes that match ComfyUI's theme +- **No Dependencies** - All CSS is inlined for reliable performance + +## 🎮 Interaction Guide + +### Editing Content +- **Double-click** anywhere on the HTML content to enter edit mode +- **Escape key** or click outside to exit edit mode and save changes +- Changes are automatically saved when exiting edit mode + +### Using Links +- **Hold Control key + Click** on any link to activate it +- External links open in new tabs +- JavaScript actions and alerts work when Control is held + +### Node Management +- **Click and drag** the node title bar to move +- **Drag edges/corners** to resize +- **Middle mouse button** works for canvas panning (like other nodes) + +## 🎨 Basic Section Colors ```html @@ -40,11 +66,9 @@ A ComfyUI Note node with html capabilities. Create notes, UI's and ReadMe's dire

🎨 Custom

Custom styled content...

-``` -## Spacers +# 📐 Spacers -```html
@@ -56,40 +80,40 @@ A ComfyUI Note node with html capabilities. Create notes, UI's and ReadMe's dire
-``` -## Clickable Links +#🔗 Clickable Links & Actions -```html - -ComfyUI GitHub + +ComfyUI GitHub - + Click for alert - -Custom Command -``` + +Link with multiple actions -## Complete Example Template + +JavaScript link + +# 📋 Complete Example Template -```html

đŸŸĸ Positive Prompts

-

masterpiece, best quality, highly detailed

+

masterpiece, best quality, highly detailed

+ 📋 Copy Prompts

🔴 Negative Prompts

-

low quality, blurry, distorted

- nsfw, watermark, signature +

low quality, blurry, distorted

+ nsfw, watermark, signature, bad anatomy
@@ -97,41 +121,84 @@ A ComfyUI Note node with html capabilities. Create notes, UI's and ReadMe's dire

â„šī¸ Model Information

Using: SDXL 1.0

-

Steps: 25 | CFG: 7.5

- Model Page +

Steps: 25 | CFG: 7.5 | Sampler: DPM++ 2M Karras

+ Model Page +
+ +
+ +
+

âš ī¸ Important Notes

+

This workflow requires:

+
    +
  1. High VRAM (8GB+)
  2. +
  3. Latest ComfyUI version
  4. +
  5. SDXL compatible models
  6. +
-

📝 Notes

+

📝 Workflow Notes

Remember to:

-
    -
  1. Check image dimensions
  2. -
  3. Adjust sampling method
  4. -
  5. Fine-tune CFG scale
  6. -
+
-

Last updated: Today

+

Last updated: Today | Created with AF Enhanced HTML Node

-``` -## Features +đŸ› ī¸ Installation +Create folder: ComfyUI/custom_nodes/ComfyUI-AF_Enhanced_HTML_Note/ -- **No external dependencies** - All CSS is inlined to avoid loading issues -- **Colored sections** - 6 predefined color schemes (positive, negative, neutral, info, warning, custom) -- **Flexible spacers** - 4 different spacer sizes -- **Clickable links** - Support for external links and custom actions -- **Responsive design** - Works on different screen sizes -- **HTML support** - Full HTML formatting (lists, tables, code blocks, etc.) -- **Custom scrollbars** - Styled to match ComfyUI theme +Add the Python file: AF_Enhanced_HTML_Note.py -## Installation +Add the init file: __init__.py -1. Create folder: `ComfyUI/custom_nodes/ComfyUI-AF_Enhanced_HTML/` -2. Add the Python file: `AF_Enhanced_HTML.py` -3. Add the init file: `__init__.py` -4. Create `web/` subfolder -5. Add the JavaScript file: `web/AF_Enhanced_HTML.js` -6. Restart ComfyUI -7. Find the node under **AF > AF - Enhanced HTML** +Create web/ subfolder + +Add the JavaScript file: web/AF_Enhanced_HTML_Note.js + +Restart ComfyUI + +Find the node under AF - Nodes > AF - Enhanced HTML Note + +🔧 Technical Details +Node Name: AF_Enhanced_HTML_Note + +Category: AF - Nodes + +Input: HTML content (multiline string) + +Output: None (display only) + +Compatibility: ComfyUI latest version + +🐛 Troubleshooting +Node won't select/move? + +Click on the node's title bar or edges, not the HTML content area + +Links not working? + +Remember to hold the Control key while clicking links + +Can't edit content? + +Double-click directly on the HTML content (not the node borders) + +Scrollbar appears unnecessarily? + +The node has minimal padding; resize if you need more space + +📞 Support +Creator: Alex Furer + +Co-Creators: Claude AI & DeepSeek + +GitHub: https://github.com/alFrame/ComfyUI_AF_FindNodeByID + +License: MIT License \ No newline at end of file diff --git a/web/AF_Enhanced_HTML_Note.js b/web/AF_Enhanced_HTML_Note.js index ad89df1..d9eccbd 100644 --- a/web/AF_Enhanced_HTML_Note.js +++ b/web/AF_Enhanced_HTML_Note.js @@ -10,23 +10,61 @@ const AF_HTML_NOTE_STYLES = ` min-height: 100px; background: var(--comfy-menu-bg, #2a2a2a); border: 1px solid var(--border-color, #555); - padding: 16px; + padding: 8px; /* Reduced padding */ box-sizing: border-box; - overflow-y: auto; + overflow: hidden; /* Changed from auto to hidden */ cursor: default; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; line-height: 1.6; color: var(--input-text, #ffffff); + display: flex; + flex-direction: column; } .af-html-note-content { width: 100%; height: 100%; + /* Allow double-clicks for editing */ + pointer-events: auto; + overflow-y: auto; /* Move scroll to content instead of container */ + flex: 1; + } + + .af-html-note-editor { + width: 100%; + height: 100%; + background: var(--comfy-menu-bg, #2a2a2a); + border: 1px solid var(--border-color, #555); + padding: 8px; /* Reduced padding to match container */ + font-family: 'Monaco', 'Consolas', 'Courier New', monospace; + line-height: 1.4; + color: var(--input-text, #ffffff); + box-sizing: border-box; + resize: none; + outline: none; + font-size: 14px; + display: none; + pointer-events: auto; + flex: 1; + } + + /* Enable link interactions only when Ctrl is held */ + .af-html-note-content a { + color: #58a6ff; + text-decoration: none; + /* Links are not clickable by default */ pointer-events: none; } - body.af-ctrl-active .af-html-note-content { + body.af-ctrl-active .af-html-note-content a { + /* Links become clickable when Ctrl is held */ pointer-events: auto; + cursor: pointer; + } + + body.af-ctrl-active .af-html-note-content a:hover { + color: #79c0ff; + text-decoration: underline; } .af-html-note-editor { @@ -43,6 +81,7 @@ const AF_HTML_NOTE_STYLES = ` outline: none; font-size: 14px; display: none; + pointer-events: auto; } .af-html-note-container.edit-mode .af-html-note-content { @@ -53,7 +92,7 @@ const AF_HTML_NOTE_STYLES = ` display: block; } - /* HTML content styles */ + /* Rest of your CSS remains exactly the same... */ .af-html-note-content h1, .af-html-note-content h2, .af-html-note-content h3, .af-html-note-content h4, .af-html-note-content h5, .af-html-note-content h6 { margin-top: 0; @@ -107,16 +146,6 @@ const AF_HTML_NOTE_STYLES = ` .af-html-note-content .af-spacer-large { height: 32px; margin: 16px 0; } .af-html-note-content .af-spacer-xl { height: 48px; margin: 24px 0; } - .af-html-note-content a { - color: #58a6ff; - text-decoration: none; - } - - body.af-ctrl-active .af-html-note-content a:hover { - color: #79c0ff; - text-decoration: underline; - } - .af-html-note-content code { background: rgba(0,0,0,0.3); padding: 2px 6px; @@ -235,58 +264,58 @@ app.registerExtension({ return result; }; - nodeType.prototype.createHTMLNoteDisplay = function(content) { - // Create container element - this.containerElement = document.createElement("div"); - this.containerElement.className = "af-html-note-container"; - - // Create HTML content display - this.contentElement = document.createElement("div"); - this.contentElement.className = "af-html-note-content"; - this.contentElement.innerHTML = content; - - // Create editor element - this.editorElement = document.createElement("textarea"); - this.editorElement.className = "af-html-note-editor"; - this.editorElement.value = content; - - // Append both elements to container - this.containerElement.appendChild(this.contentElement); - this.containerElement.appendChild(this.editorElement); - - // Add double-click to edit - this.containerElement.addEventListener('dblclick', (e) => { - if (!this.isEditMode) { - this.enterEditMode(); - e.stopPropagation(); - } - }); + nodeType.prototype.createHTMLNoteDisplay = function(content) { + // Create container element + this.containerElement = document.createElement("div"); + this.containerElement.className = "af-html-note-container"; + + // Create HTML content display + this.contentElement = document.createElement("div"); + this.contentElement.className = "af-html-note-content"; + this.contentElement.innerHTML = content; + + // Create editor element + this.editorElement = document.createElement("textarea"); + this.editorElement.className = "af-html-note-editor"; + this.editorElement.value = content; + + // Append both elements to container + this.containerElement.appendChild(this.contentElement); + this.containerElement.appendChild(this.editorElement); + + // Add double-click to edit - works anytime (no Ctrl required) + this.contentElement.addEventListener('dblclick', (e) => { + if (!this.isEditMode) { + this.enterEditMode(); + e.stopPropagation(); + } + }); - // Handle links - this.handleLinksInHTML(); + // Handle links + this.handleLinksInHTML(); - // Handle editor events - this.editorElement.addEventListener('keydown', (e) => { - if (e.key === 'Escape') { - this.exitEditMode(); - e.preventDefault(); - e.stopPropagation(); - } else { - e.stopPropagation(); - } - }); + // Handle editor events + this.editorElement.addEventListener('keydown', (e) => { + if (e.key === 'Escape') { + this.exitEditMode(); + e.preventDefault(); + e.stopPropagation(); + } else { + e.stopPropagation(); + } + }); - this.editorElement.addEventListener('blur', () => { - setTimeout(() => { - if (this.isEditMode && document.activeElement !== this.editorElement) { - this.exitEditMode(); - } - }, 10); - }); + this.editorElement.addEventListener('blur', () => { + setTimeout(() => { + if (this.isEditMode && document.activeElement !== this.editorElement) { + this.exitEditMode(); + } + }, 10); + }); - // Add as DOM widget - this.addDOMWidget("html_note_display", "div", this.containerElement); - }; + // Add as DOM widget + this.addDOMWidget("html_note_display", "div", this.containerElement); + }; nodeType.prototype.enterEditMode = function() { if (this.isEditMode) return; @@ -322,30 +351,36 @@ app.registerExtension({ this.handleLinksInHTML(); }; - nodeType.prototype.handleLinksInHTML = function() { - if (!this.contentElement) return; - - const links = this.contentElement.querySelectorAll('a'); - links.forEach(link => { - link.onclick = (e) => { - // Only handle links when Ctrl is active - if (!document.body.classList.contains('af-ctrl-active')) { - e.preventDefault(); - e.stopPropagation(); - return false; - } - - // Handle external links - if (link.href && !link.href.includes('#') && !link.href.startsWith('javascript:')) { - e.preventDefault(); - window.open(link.href, '_blank'); - } - - e.stopPropagation(); - return false; - }; - }); - }; + nodeType.prototype.handleLinksInHTML = function() { + if (!this.contentElement) return; + + const links = this.contentElement.querySelectorAll('a'); + links.forEach(link => { + // Remove any existing handlers + link.onclick = null; + + // Add new handler that requires Ctrl key + link.addEventListener('click', (e) => { + // Only handle links when Ctrl is active + if (!document.body.classList.contains('af-ctrl-active')) { + e.preventDefault(); + e.stopPropagation(); + return false; + } + + // Handle external links + if (link.href && !link.href.includes('#') && !link.href.startsWith('javascript:')) { + e.preventDefault(); + window.open(link.href, '_blank'); + } + // For javascript: links and onclick handlers, let them execute naturally + // Don't prevent default or stop propagation for these + + e.stopPropagation(); + return false; + }); + }); + }; // Global Ctrl key handling let ctrlKeyActive = false;