Files
outline/shared/editor/nodes/HardBreak.ts
T
Tom Moor f329b56d0e fix: Hard break serialization for commonMark (#12603)
* fix: Hard break serialization for commonMark

* tests
2026-06-06 07:24:16 -04:00

69 lines
1.8 KiB
TypeScript

import type { NodeSpec, NodeType } from "prosemirror-model";
import type { Command } from "prosemirror-state";
import { isInTable } from "prosemirror-tables";
import type { MarkdownSerializerState } from "../lib/markdown/serializer";
import { isInCode } from "../queries/isInCode";
import { isNodeActive } from "../queries/isNodeActive";
import breakRule from "../rules/breaks";
import Node from "./Node";
export default class HardBreak extends Node {
get name() {
return "br";
}
get schema(): NodeSpec {
return {
inline: true,
group: "inline",
selectable: false,
parseDOM: [{ tag: "br" }],
toDOM: () => ["br"],
leafText: () => "\n",
};
}
get rulePlugins() {
return [breakRule];
}
commands({ type }: { type: NodeType }) {
return (): Command => (state, dispatch) => {
dispatch?.(state.tr.replaceSelectionWith(type.create()).scrollIntoView());
return true;
};
}
keys({ type }: { type: NodeType }): Record<string, Command> {
return {
"Shift-Enter": (state, dispatch) => {
const isParagraphActive = isNodeActive(state.schema.nodes.paragraph)(
state
);
if (
(!isInTable(state) && !isParagraphActive) ||
isInCode(state, { onlyBlock: true })
) {
return false;
}
dispatch?.(
state.tr.replaceSelectionWith(type.create()).scrollIntoView()
);
return true;
},
};
}
toMarkdown(state: MarkdownSerializerState) {
// Two trailing spaces is a CommonMark hard break that survives a
// copy/export round-trip, unlike a bare newline.
state.write(
state.inTable ? "<br>" : state.options.commonMark ? " \n" : "\\n"
);
}
parseMarkdown() {
return { node: "br" };
}
}