diff --git a/demo/main.tsx b/demo/main.tsx
index 0d072d9a..fdee5415 100644
--- a/demo/main.tsx
+++ b/demo/main.tsx
@@ -68,7 +68,7 @@ const editorState = EditorState.create({
schema,
doc: schema.nodes.doc.create({}, [
schema.nodes.paragraph.create({}, [
- schema.text("This", [schema.marks.em.create()]),
+ schema.text("This", [schema.marks.em.create(), schema.marks.em.create()]),
schema.text(" is the first paragraph"),
]),
schema.nodes.paragraph.create(
diff --git a/src/components/MarkView.tsx b/src/components/MarkView.tsx
new file mode 100644
index 00000000..1c1b865c
--- /dev/null
+++ b/src/components/MarkView.tsx
@@ -0,0 +1,24 @@
+import { Mark } from "prosemirror-model";
+import React, { ReactNode, forwardRef } from "react";
+
+import { OutputSpec } from "./OutputSpec.js";
+
+type Props = {
+ mark: Mark;
+ children: ReactNode;
+};
+
+export const MarkView = forwardRef(function MarkView(
+ { mark, children }: Props,
+ ref
+) {
+ const outputSpec = mark.type.spec.toDOM?.(mark, true);
+ if (!outputSpec)
+ throw new Error(`Mark spec for ${mark.type.name} is missing toDOM`);
+
+ return (
+
+ {children}
+
+ );
+});
diff --git a/src/components/NodeView.tsx b/src/components/NodeView.tsx
index de8aa116..356d4153 100644
--- a/src/components/NodeView.tsx
+++ b/src/components/NodeView.tsx
@@ -14,6 +14,7 @@ import { ChildDescriptorsContext } from "../contexts/ChildDescriptorsContext.js"
import { NodeViewContext } from "../contexts/NodeViewContext.js";
import { NodeViewDesc, ViewDesc } from "../descriptors/ViewDesc.js";
+import { MarkView } from "./MarkView.js";
import { NodeViewComponentProps } from "./NodeViewComponentProps.js";
import { OutputSpec } from "./OutputSpec.js";
import { TextNodeView } from "./TextNodeView.js";
@@ -29,10 +30,10 @@ export function NodeView({ node, pos }: Props) {
useContext(NodeViewContext);
const siblingDescriptors = useContext(ChildDescriptorsContext);
const childDescriptors: ViewDesc[] = [];
- const ref = useRef(null);
+ const domRef = useRef(null);
useLayoutEffect(() => {
- if (!ref.current) return;
+ if (!domRef.current) return;
const firstChildDesc = childDescriptors[0];
@@ -41,15 +42,15 @@ export function NodeView({ node, pos }: Props) {
node,
[],
DecorationSet.empty,
- ref.current,
+ domRef.current,
firstChildDesc?.dom.parentElement ?? null,
- ref.current,
+ domRef.current,
posToDesc,
domToDesc
);
desc.children = childDescriptors;
posToDesc.set(pos, desc);
- domToDesc.set(ref.current, desc);
+ domToDesc.set(domRef.current, desc);
siblingDescriptors.push(desc);
for (const childDesc of childDescriptors) {
@@ -57,12 +58,12 @@ export function NodeView({ node, pos }: Props) {
}
});
- const children: ReactNode[] = [];
+ const content: ReactNode[] = [];
const innerPos = pos + 1;
node.content.forEach((childNode, offset) => {
const childPos = innerPos + offset;
if (childNode.isText) {
- children.push(
+ content.push(
{(siblingDescriptors) => (
);
} else {
- children.push(
-
- );
+ content.push();
}
});
- if (!children.length) {
- children.push();
+ if (!content.length) {
+ content.push();
}
+ const children = (
+
+ {content}
+
+ );
+
const Component:
| ForwardRefExoticComponent<
NodeViewComponentProps & RefAttributes
@@ -91,9 +96,10 @@ export function NodeView({ node, pos }: Props) {
| undefined = nodeViews[node.type.name];
if (Component) {
- return (
+ return node.marks.reduce(
+ (element, mark) => {element},
-
- {children}
-
+ {children}
);
}
@@ -112,11 +116,10 @@ export function NodeView({ node, pos }: Props) {
const outputSpec: DOMOutputSpec | undefined = node.type.spec.toDOM?.(node);
if (outputSpec) {
- return (
-
-
- {children}
-
+ return node.marks.reduce(
+ (element, mark) => {element},
+
+ {children}
);
}
diff --git a/src/components/TextNodeView.tsx b/src/components/TextNodeView.tsx
index cf8cab03..b00a2aa6 100644
--- a/src/components/TextNodeView.tsx
+++ b/src/components/TextNodeView.tsx
@@ -9,7 +9,7 @@ import {
} from "../contexts/NodeViewContext.js";
import { TextViewDesc, ViewDesc } from "../descriptors/ViewDesc.js";
-import { OutputSpec } from "./OutputSpec.js";
+import { MarkView } from "./MarkView.js";
type Props = {
node: Node;
@@ -75,13 +75,10 @@ export class TextNodeView extends Component {
}
render() {
- return this.props.node.marks.reduce((children, mark) => {
- const outputSpec = mark.type.spec.toDOM?.(mark, true);
- if (!outputSpec)
- throw new Error(`Mark spec for ${mark.type.name} is missing toDOM`);
-
- return {children};
- }, <>{this.props.node.text}>);
+ return this.props.node.marks.reduce(
+ (children, mark) => {children},
+ <>{this.props.node.text}>
+ );
}
}