fix(canvas): 文本节点 - 恢复正文点击选中和编辑面板

Refs #429
This commit is contained in:
ddCat
2026-09-07 22:35:45 +08:00
parent 5206e7f20f
commit d543d62592
3 changed files with 31 additions and 3 deletions

View File

@@ -329,12 +329,11 @@ function TextContent({ node, theme, isEditingContent, textareaRef, mentionRefere
<div
className="thin-scrollbar block h-full w-full select-text overflow-y-auto break-words bg-transparent px-4 pb-4 font-mono [&_a]:underline [&_blockquote]:my-2 [&_blockquote]:border-l-2 [&_blockquote]:pl-3 [&_blockquote]:opacity-70 [&_code]:rounded [&_code]:bg-black/6 [&_code]:px-1 dark:[&_code]:bg-white/8 [&_h1]:my-2 [&_h1]:text-[1.55em] [&_h1]:font-semibold [&_h2]:my-2 [&_h2]:text-[1.3em] [&_h2]:font-semibold [&_h3]:my-1.5 [&_h3]:text-[1.12em] [&_h3]:font-semibold [&_hr]:my-3 [&_li]:my-0.5 [&_ol]:my-2 [&_ol]:list-decimal [&_ol]:pl-5 [&_p]:my-1 [&_pre]:my-2 [&_pre]:overflow-x-auto [&_pre]:rounded-md [&_pre]:bg-black/90 [&_pre]:p-2 [&_pre]:text-white [&_ul]:my-2 [&_ul]:list-disc [&_ul]:pl-5"
style={textStyle}
onMouseDown={(event) => event.stopPropagation()}
onWheel={(event) => event.stopPropagation()}
dangerouslySetInnerHTML={{ __html: richTextHTML }}
/>
) : (
<div className="thin-scrollbar block h-full w-full select-text overflow-y-auto whitespace-pre-wrap break-words bg-transparent px-4 pb-4 pt-0 font-mono" style={textStyle} onMouseDown={(event) => event.stopPropagation()} onWheel={(event) => event.stopPropagation()}>
<div className="thin-scrollbar block h-full w-full select-text overflow-y-auto whitespace-pre-wrap break-words bg-transparent px-4 pb-4 pt-0 font-mono" style={textStyle} onWheel={(event) => event.stopPropagation()}>
{node.metadata?.content || <span style={{ color: theme.node.placeholder }}>双击编辑文字</span>}
</div>
)}

View File

@@ -1036,7 +1036,9 @@ function InfiniteCanvasPage() {
setDrawingNodeId(node.id);
} else if (node.type === CanvasNodeType.Script) {
setDialogNodeId(null);
} else if (node.type === CanvasNodeType.Text || node.type === CanvasNodeType.Frame) {
} else if (node.type === CanvasNodeType.Text) {
setDialogNodeId(node.id);
} else if (node.type === CanvasNodeType.Frame) {
setDialogNodeId((current) => (current === node.id ? current : null));
} else if (node.type === PORTRAIT_CLEARANCE_NODE_TYPE) {
setDialogNodeId(null);

View File

@@ -0,0 +1,27 @@
import { readFileSync } from "node:fs";
import { describe, expect, test } from "bun:test";
const source = readFileSync(new URL("../src/components/canvas/canvas-node-content.tsx", import.meta.url), "utf8");
const textContent = source.slice(source.indexOf("function TextContent("), source.indexOf("function ", source.indexOf("function TextContent(") + 1));
describe("text node selection (#429)", () => {
test("opens the text generation panel on a node click", () => {
const project = readFileSync(new URL("../src/pages/canvas/project.tsx", import.meta.url), "utf8");
const clickHandler = project.slice(project.indexOf("const handleSelectedNodeClick ="), project.indexOf("const handleNodeBringToFront ="));
expect(clickHandler).toMatch(/node.type === CanvasNodeType.Text\)\s*\{\s*setDialogNodeId\(node.id\)/);
});
test("allows plain and rich text previews to reach node selection", () => {
const preview = textContent.split(") : richTextHTML ? (")[1];
expect(preview).toBeDefined();
expect(preview).not.toContain("onMouseDown");
expect(preview).not.toContain("onPointerDown");
expect(preview?.match(/onWheel=/g)).toHaveLength(2);
});
test("keeps editing gestures isolated from canvas dragging", () => {
const editor = textContent.split(") : richTextHTML ? (")[0];
expect(editor).toContain("onMouseDown={(event) => event.stopPropagation()}");
expect(editor).toContain("onPointerDown={(event) => event.stopPropagation()}");
});
});