diff --git a/AF_Enhanced_HTML_Note.py b/AF_Enhanced_HTML_Note.py
index 2a967a0..bf9ce79 100644
--- a/AF_Enhanced_HTML_Note.py
+++ b/AF_Enhanced_HTML_Note.py
@@ -6,7 +6,7 @@
#
# LICENSE: MIT License
#
-# v0.0.04
+# v0.0.05
#
# Description:
# A ComfyUI Note node with html capabilities. Create notes, UI's and ReadMe's directly inside the workflow, using html.
@@ -15,6 +15,8 @@
# Read Me on Github
#
# Changelog:
+# v0.0.05
+# - Made edit mode less intrusive and keep ComfyUI canvas navigation (panning, zooming [space bar] and [H] now work to pan around the canvas)
# 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
diff --git a/__init__.py b/__init__.py
index db8319d..d72aa34 100644
--- a/__init__.py
+++ b/__init__.py
@@ -7,4 +7,19 @@ from .AF_Enhanced_HTML_Note import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPIN
# Tell ComfyUI about our web files
WEB_DIRECTORY = "./web"
-__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS', 'WEB_DIRECTORY']
\ No newline at end of file
+__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS', 'WEB_DIRECTORY']
+__version__ = "0.0.05"
+__author__ = "Alex Furer"
+
+print("* * * * * * * * * * * * * * * * * * * * * * * * * *")
+print(r"""
+ ___ ____ _____ ___ __ ______ _ __ __
+ / _ | / __/ ____ / ___/__ __ _ / _/_ __/ / / / _/ / |/ /__ ___/ /__ ___
+ / __ |/ _/ /___/ / /__/ _ \/ ' \/ _/ // / /_/ // / / / _ Y _ / -_|_-<
+/_/ |_/_/ \___/\___/_/_/_/_/ \_, /\____/___/ /_/|_/\___|_,_/\__/___/
+ /___/
+
+ 📋 AF - Enhanced HTML Note Loaded !
+
+""")
+print("* * * * * * * * * * * * * * * * * * * * * * * * * *")
\ No newline at end of file
diff --git a/web/AF_Enhanced_HTML_Note.js b/web/AF_Enhanced_HTML_Note.js
index 7baef9d..1cc51ce 100644
--- a/web/AF_Enhanced_HTML_Note.js
+++ b/web/AF_Enhanced_HTML_Note.js
@@ -5,247 +5,263 @@ import { app } from "../../scripts/app.js";
// Define inline CSS styles
const AF_HTML_NOTE_STYLES = `
.af-html-note-container {
- width: 100%;
- height: 100%;
- min-height: 100px;
- background: var(--comfy-menu-bg, #2a2a2a);
- border: 1px solid var(--border-color, #555);
- padding: 8px; /* Reduced padding */
- box-sizing: border-box;
- 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;
- }
+ width: 100%;
+ height: 100%;
+ min-height: 100px;
+ background: var(--comfy-menu-bg, #2a2a2a);
+ border: 1px solid var(--border-color, #555);
+ padding: 8px;
+ box-sizing: border-box;
+ overflow: 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;
+ position: relative;
+ }
- .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-content {
+ width: 100%;
+ height: 100%;
+ overflow-y: auto;
+ flex: 1;
+ /* NO pointer-events here - let ComfyUI handle interactions */
+ }
- .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;
- }
+ .af-html-note-editor {
+ width: 100%;
+ height: 100%;
+ background: var(--comfy-menu-bg, #2a2a2a);
+ border: 1px solid var(--border-color, #555);
+ padding: 8px;
+ 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;
+ 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;
- }
+ /* Floating edit button */
+ .af-floating-edit-btn {
+ position: absolute;
+ top: 4px;
+ right: 4px;
+ background: rgba(0, 0, 0, 0.8);
+ border: 1px solid var(--border-color, #555);
+ color: var(--input-text, #ffffff);
+ border-radius: 3px;
+ width: 22px;
+ height: 22px;
+ cursor: pointer;
+ z-index: 1000;
+ font-size: 11px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ opacity: 0.7;
+ transition: opacity 0.2s ease;
+ }
- body.af-ctrl-active .af-html-note-content a {
- /* Links become clickable when Ctrl is held */
- pointer-events: auto;
- cursor: pointer;
- }
+ .af-floating-edit-btn:hover {
+ opacity: 1;
+ background: rgba(0, 0, 0, 0.9);
+ border-color: #777;
+ }
- body.af-ctrl-active .af-html-note-content a:hover {
- color: #79c0ff;
- text-decoration: underline;
- }
+ /* Enable link interactions only when Ctrl is held */
+ .af-html-note-content a {
+ color: #58a6ff;
+ text-decoration: none;
+ /* Links are never directly clickable - only via Ctrl */
+ pointer-events: none;
+ cursor: default;
+ }
- .af-html-note-editor {
- width: 100%;
- height: 100%;
- background: var(--comfy-menu-bg, #2a2a2a);
- border: 1px solid var(--border-color, #555);
- padding: 16px;
- 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;
- }
+ body.af-ctrl-active .af-html-note-content a {
+ /* Only become clickable when Ctrl is held globally */
+ pointer-events: auto;
+ cursor: pointer;
+ }
- .af-html-note-container.edit-mode .af-html-note-content {
- display: none;
- }
+ body.af-ctrl-active .af-html-note-content a:hover {
+ color: #79c0ff;
+ text-decoration: underline;
+ }
- .af-html-note-container.edit-mode .af-html-note-editor {
- display: block;
- }
+ .af-html-note-container.edit-mode .af-html-note-content {
+ display: none;
+ }
- /* 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;
- margin-bottom: 12px;
- font-weight: 600;
- }
+ .af-html-note-container.edit-mode .af-html-note-editor {
+ display: block;
+ }
- .af-html-note-content h1 { font-size: 1.5em; }
- .af-html-note-content h2 { font-size: 1.3em; }
- .af-html-note-content h3 { font-size: 1.1em; }
+ /* Hide edit button in edit mode */
+ .af-html-note-container.edit-mode .af-floating-edit-btn {
+ display: none;
+ }
- .af-html-note-content .af-section {
- padding: 8px 16px;
- margin: 8px 0;
- border-radius: 6px;
- border-left: 4px solid;
- }
+ /* Rest of your CSS remains 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;
+ margin-bottom: 12px;
+ font-weight: 600;
+ }
- .af-html-note-content .af-section.af-positive {
- background: rgba(144, 238, 144, 0.1);
- border-left-color: #90EE90;
- }
+ .af-html-note-content h1 { font-size: 1.5em; }
+ .af-html-note-content h2 { font-size: 1.3em; }
+ .af-html-note-content h3 { font-size: 1.1em; }
- .af-html-note-content .af-section.af-negative {
- background: rgba(255, 107, 107, 0.1);
- border-left-color: #FF6B6B;
- }
+ .af-html-note-content .af-section {
+ padding: 8px 16px;
+ margin: 8px 0;
+ border-radius: 6px;
+ border-left: 4px solid;
+ }
- .af-html-note-content .af-section.af-neutral {
- background: rgba(224, 224, 224, 0.1);
- border-left-color: #E0E0E0;
- }
+ .af-html-note-content .af-section.af-positive {
+ background: rgba(144, 238, 144, 0.1);
+ border-left-color: #90EE90;
+ }
- .af-html-note-content .af-section.af-info {
- background: rgba(135, 206, 235, 0.1);
- border-left-color: #87CEEB;
- }
+ .af-html-note-content .af-section.af-negative {
+ background: rgba(255, 107, 107, 0.1);
+ border-left-color: #FF6B6B;
+ }
- .af-html-note-content .af-section.af-warning {
- background: rgba(255, 128, 0, 0.1);
- border-left-color: #FFD700;
- }
+ .af-html-note-content .af-section.af-neutral {
+ background: rgba(224, 224, 224, 0.1);
+ border-left-color: #E0E0E0;
+ }
- .af-html-note-content .af-section.af-yellow {
- background: rgba(255, 128, 0, 0.1);
- border-left-color: #FFD700;
- }
+ .af-html-note-content .af-section.af-info {
+ background: rgba(135, 206, 235, 0.1);
+ border-left-color: #87CEEB;
+ }
- .af-html-note-content .af-section.af-blue {
- background: rgba(102, 105, 255, 0.1);
- border-left-color: #000099;
- }
+ .af-html-note-content .af-section.af-warning {
+ background: rgba(255, 128, 0, 0.1);
+ border-left-color: #FFD700;
+ }
- .af-html-note-content .af-section.af-custom {
- background: rgba(186, 85, 211, 0.1);
- border-left-color: #BA55D3;
- }
+ .af-html-note-content .af-section.af-yellow {
+ background: rgba(255, 128, 0, 0.1);
+ border-left-color: #FFD700;
+ }
- .af-html-note-content .af-spacer-top { height: 2px; margin: 4px 0; }
- .af-html-note-content .af-spacer-mini { height: 4px; margin: 4px 0; }
- .af-html-note-content .af-spacer-small { height: 8px; margin: 4px 0; }
- .af-html-note-content .af-spacer { height: 16px; margin: 8px 0; }
- .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 .af-section.af-blue {
+ background: rgba(102, 105, 255, 0.1);
+ border-left-color: #000099;
+ }
- .af-html-note-content code {
- background: rgba(0,0,0,0.3);
- padding: 2px 6px;
- border-radius: 4px;
- font-family: 'Monaco', 'Consolas', 'Courier New', monospace;
- font-size: 0.9em;
- color: #f0f6fc;
- }
+ .af-html-note-content .af-section.af-custom {
+ background: rgba(186, 85, 211, 0.1);
+ border-left-color: #BA55D3;
+ }
- .af-html-note-content pre {
- background: rgba(0,0,0,0.4);
- border: 1px solid #444;
- border-radius: 6px;
- padding: 12px;
- margin: 16px 0;
- overflow-x: auto;
- }
+ .af-html-note-content .af-spacer-top { height: 2px; margin: 4px 0; }
+ .af-html-note-content .af-spacer-mini { height: 4px; margin: 4px 0; }
+ .af-html-note-content .af-spacer-small { height: 8px; margin: 4px 0; }
+ .af-html-note-content .af-spacer { height: 16px; margin: 8px 0; }
+ .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 pre code {
- background: transparent;
- padding: 0;
- }
+ .af-html-note-content code {
+ background: rgba(0,0,0,0.3);
+ padding: 2px 6px;
+ border-radius: 4px;
+ font-family: 'Monaco', 'Consolas', 'Courier New', monospace;
+ font-size: 0.9em;
+ color: #f0f6fc;
+ }
- .af-html-note-content ul, .af-html-note-content ol {
- padding-left: 20px;
- margin: 12px 0;
- }
+ .af-html-note-content pre {
+ background: rgba(0,0,0,0.4);
+ border: 1px solid #444;
+ border-radius: 6px;
+ padding: 12px;
+ margin: 16px 0;
+ overflow-x: auto;
+ }
- .af-html-note-content li { margin: 4px 0; }
- .af-html-note-content p { margin: 8px 0; }
+ .af-html-note-content pre code {
+ background: transparent;
+ padding: 0;
+ }
- .af-html-note-content table {
- border-collapse: collapse;
- width: 100%;
- margin: 16px 0;
- }
+ .af-html-note-content ul, .af-html-note-content ol {
+ padding-left: 20px;
+ margin: 12px 0;
+ }
- .af-html-note-content th, .af-html-note-content td {
- border: 1px solid var(--border-color, #555);
- padding: 8px 12px;
- text-align: left;
- }
+ .af-html-note-content li { margin: 4px 0; }
+ .af-html-note-content p { margin: 8px 0; }
- .af-html-note-content th {
- background: rgba(255,255,255,0.1);
- font-weight: 600;
- }
+ .af-html-note-content table {
+ border-collapse: collapse;
+ width: 100%;
+ margin: 16px 0;
+ }
- .af-html-note-content hr {
- border: none;
- border-top: 1px solid var(--border-color, #555);
- margin: 16px 0;
- opacity: 0.6;
- }
+ .af-html-note-content th, .af-html-note-content td {
+ border: 1px solid var(--border-color, #555);
+ padding: 8px 12px;
+ text-align: left;
+ }
- .af-html-note-container::-webkit-scrollbar { width: 8px; }
- .af-html-note-container::-webkit-scrollbar-track { background: rgba(0,0,0,0.1); }
- .af-html-note-container::-webkit-scrollbar-thumb {
- background: var(--border-color, #555);
- border-radius: 4px;
- }
- .af-html-note-container::-webkit-scrollbar-thumb:hover { background: #777; }
+ .af-html-note-content th {
+ background: rgba(255,255,255,0.1);
+ font-weight: 600;
+ }
- .af-html-note-editor::-webkit-scrollbar { width: 8px; }
- .af-html-note-editor::-webkit-scrollbar-track { background: rgba(0,0,0,0.1); }
- .af-html-note-editor::-webkit-scrollbar-thumb {
- background: var(--border-color, #555);
- border-radius: 4px;
- }
- .af-html-note-editor::-webkit-scrollbar-thumb:hover { background: #777; }
+ .af-html-note-content hr {
+ border: none;
+ border-top: 1px solid var(--border-color, #555);
+ margin: 16px 0;
+ opacity: 0.6;
+ }
- /* ****** MY OWN STYLES ****** */
- .af-column-half-left {
- box-sizing: border-box;
- float: left;
- width: 49%;
- margin-right: 1% !important;
- }
- .af-column-half-right {
- box-sizing: border-box;
- float: left;
- width: 49%;
- margin-left: 1% !important;
- }
- .row:after {
- content: "";
- display: table;
- clear: both;
+ .af-html-note-container::-webkit-scrollbar { width: 8px; }
+ .af-html-note-container::-webkit-scrollbar-track { background: rgba(0,0,0,0.1); }
+ .af-html-note-container::-webkit-scrollbar-thumb {
+ background: var(--border-color, #555);
+ border-radius: 4px;
+ }
+ .af-html-note-container::-webkit-scrollbar-thumb:hover { background: #777; }
+
+ .af-html-note-editor::-webkit-scrollbar { width: 8px; }
+ .af-html-note-editor::-webkit-scrollbar-track { background: rgba(0,0,0,0.1); }
+ .af-html-note-editor::-webkit-scrollbar-thumb {
+ background: var(--border-color, #555);
+ border-radius: 4px;
+ }
+ .af-html-note-editor::-webkit-scrollbar-thumb:hover { background: #777; }
+
+ /* ****** MY OWN STYLES ****** */
+ .af-column-half-left {
+ box-sizing: border-box;
+ float: left;
+ width: 49%;
+ margin-right: 1% !important;
+ }
+ .af-column-half-right {
+ box-sizing: border-box;
+ float: left;
+ width: 49%;
+ margin-left: 1% !important;
+ }
+ .row:after {
+ content: "";
+ display: table;
+ clear: both;
+ }
`;
// Inject styles
@@ -309,11 +325,26 @@ app.registerExtension({
this.editorElement.className = "af-html-note-editor";
this.editorElement.value = content;
- // Append both elements to container
+ // Create floating edit button
+ this.editButton = document.createElement("div");
+ this.editButton.className = "af-floating-edit-btn";
+ this.editButton.innerHTML = "✏️";
+ this.editButton.title = "Edit HTML";
+
+ // Append all elements to container
this.containerElement.appendChild(this.contentElement);
this.containerElement.appendChild(this.editorElement);
+ this.containerElement.appendChild(this.editButton);
- // Add double-click to edit - works anytime (no Ctrl required)
+ // Edit button click handler
+ this.editButton.addEventListener('click', (e) => {
+ if (!this.isEditMode) {
+ this.enterEditMode();
+ e.stopPropagation();
+ }
+ });
+
+ // Add back double-click editing (user-friendly alternative)
this.contentElement.addEventListener('dblclick', (e) => {
if (!this.isEditMode) {
this.enterEditMode();
@@ -330,8 +361,6 @@ app.registerExtension({
this.exitEditMode();
e.preventDefault();
e.stopPropagation();
- } else {
- e.stopPropagation();
}
});
@@ -389,7 +418,7 @@ app.registerExtension({
// Remove any existing handlers
link.onclick = null;
- // Add new handler that requires Ctrl key
+ // Add clean, simple handler
link.addEventListener('click', (e) => {
// Only handle links when Ctrl is active
if (!document.body.classList.contains('af-ctrl-active')) {
@@ -398,14 +427,15 @@ app.registerExtension({
return false;
}
- // Handle external links
- if (link.href && !link.href.includes('#') && !link.href.startsWith('javascript:')) {
+ // Ctrl is held - handle external links only
+ if (link.href &&
+ !link.href.startsWith('javascript:') &&
+ !(link.href.startsWith('#') || link.href === '#')) {
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
+ // Stop propagation to ComfyUI
e.stopPropagation();
return false;
});