Add Markdown support to the Note node (#2044)

This commit is contained in:
gremlation
2024-12-27 02:16:00 +08:00
committed by GitHub
parent 66ada54587
commit 7990491c58
5 changed files with 863 additions and 2 deletions

View File

@@ -148,6 +148,55 @@ body {
font-size: var(--comfy-textarea-font-size);
}
.comfy-markdown {
/* We assign the textarea and the Tiptap editor to the same CSS grid area to stack them on top of one another. */
display: grid;
}
.comfy-markdown > textarea {
grid-area: 1 / 1 / 2 / 2;
}
.comfy-markdown .tiptap {
grid-area: 1 / 1 / 2 / 2;
background-color: var(--comfy-input-bg);
color: var(--input-text);
overflow: hidden;
overflow-y: auto;
resize: none;
border: none;
box-sizing: border-box;
font-size: var(--comfy-textarea-font-size);
height: 100%;
padding: 0.5em;
}
.comfy-markdown.editing .tiptap {
display: none;
}
.comfy-markdown .tiptap :first-child {
margin-top: 0;
}
.comfy-markdown .tiptap :last-child {
margin-bottom: 0;
}
.comfy-markdown .tiptap blockquote {
border-left: medium solid;
margin-left: 1em;
padding-left: 0.5em;
}
.comfy-markdown .tiptap pre {
border: thin dotted;
border-radius: 0.5em;
margin: 0.5em;
padding: 0.5em;
}
.comfy-modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */

View File

@@ -23,11 +23,11 @@ app.registerExtension({
if (!this.properties) {
this.properties = { text: '' }
}
ComfyWidgets.STRING(
ComfyWidgets.MARKDOWN(
// Should we extends LGraphNode? Yesss
this,
'',
['', { default: this.properties.text, multiline: true }],
['', { default: this.properties.text }],
app
)

View File

@@ -7,6 +7,10 @@ import { InputSpec } from '@/types/apiTypes'
import { useSettingStore } from '@/stores/settingStore'
import { useToastStore } from '@/stores/toastStore'
import type { IWidget } from '@comfyorg/litegraph'
import { Editor as TiptapEditor } from '@tiptap/core'
import TiptapStarterKit from '@tiptap/starter-kit'
import { Markdown as TiptapMarkdown } from 'tiptap-markdown'
import TiptapLink from '@tiptap/extension-link'
export type ComfyWidgetConstructor = (
node: LGraphNode,
@@ -362,6 +366,85 @@ function addMultilineWidget(node, name: string, opts, app: ComfyApp) {
return { minWidth: 400, minHeight: 200, widget }
}
function addMarkdownWidget(node, name: string, opts, app: ComfyApp) {
TiptapMarkdown.configure({
html: false,
breaks: true,
transformPastedText: true
})
const editor = new TiptapEditor({
extensions: [TiptapStarterKit, TiptapMarkdown, TiptapLink],
content: opts.defaultVal,
editable: false
})
const inputEl = editor.options.element
inputEl.classList.add('comfy-markdown')
const textarea = document.createElement('textarea')
inputEl.append(textarea)
const widget = node.addDOMWidget(name, 'MARKDOWN', inputEl, {
getValue() {
return textarea.value
},
setValue(v) {
textarea.value = v
editor.commands.setContent(v)
}
})
widget.inputEl = inputEl
editor.options.element.addEventListener(
'pointerdown',
(event: PointerEvent) => {
if (event.button !== 0) {
app.canvas.processMouseDown(event)
return
}
if (event.target instanceof HTMLAnchorElement) {
return
}
inputEl.classList.add('editing')
setTimeout(() => {
textarea.focus()
}, 0)
}
)
textarea.addEventListener('blur', () => {
inputEl.classList.remove('editing')
})
textarea.addEventListener('change', () => {
editor.commands.setContent(textarea.value)
widget.callback?.(widget.value)
})
inputEl.addEventListener('keydown', (event: KeyboardEvent) => {
event.stopPropagation()
})
inputEl.addEventListener('pointerdown', (event: PointerEvent) => {
if (event.button === 1) {
app.canvas.processMouseDown(event)
}
})
inputEl.addEventListener('pointermove', (event: PointerEvent) => {
if ((event.buttons & 4) === 4) {
app.canvas.processMouseMove(event)
}
})
inputEl.addEventListener('pointerup', (event: PointerEvent) => {
if (event.button === 1) {
app.canvas.processMouseUp(event)
}
})
return { minWidth: 400, minHeight: 200, widget }
}
function isSlider(display, app) {
if (app.ui.settings.getSettingValue('Comfy.DisableSliders')) {
return 'number'
@@ -475,6 +558,18 @@ export const ComfyWidgets: Record<string, ComfyWidgetConstructor> = {
return res
},
MARKDOWN(node, inputName, inputData: InputSpec, app) {
const defaultVal = inputData[1].default || ''
let res
res = addMarkdownWidget(
node,
inputName,
{ defaultVal, ...inputData[1] },
app
)
return res
},
COMBO(node, inputName, inputData: InputSpec) {
const type = inputData[0]
let defaultValue = type[0]