From 21781189916647ce92eeafecc6e4a2cd56d21ece Mon Sep 17 00:00:00 2001 From: Glenn Allen Date: Mon, 11 Nov 2024 19:05:32 +1100 Subject: [PATCH] feat: add Node `linebreakReplacement` support and enable on hardBreak nodes (#5821) * Support the Node linebreakReplacement property Support the [linebreakReplacement](https://prosemirror.net/docs/ref/#model.NodeSpec.linebreakReplacement) property on Nodes, allowing a node to be used wherever a newline character is, when converting between blocks that don't support the linebreak node, but have their whitespace set to "pre". This is useful, for example, when converting between code blocks & normal paragraphs. Code blocks don't support the linebreak node, but do allow newline characters ('\n'). Marking the `hardBreak` node as the `linebreakReplacement` will mean the newline characters within codeBlock nodes will be converted to `hardBreak` nodes in the paragraph. * Make hardBreak the default linebreakReplacement node When converting between codeBlocks and normal paragraphs, the hardBreak node should be used in place of newline '\n' characters. --- .changeset/shy-pigs-exercise.md | 6 ++++++ packages/core/src/Node.ts | 19 +++++++++++++++++++ .../helpers/getSchemaByResolvedExtensions.ts | 1 + .../extension-hard-break/src/hard-break.ts | 2 ++ 4 files changed, 28 insertions(+) create mode 100644 .changeset/shy-pigs-exercise.md diff --git a/.changeset/shy-pigs-exercise.md b/.changeset/shy-pigs-exercise.md new file mode 100644 index 000000000..16e4d26ff --- /dev/null +++ b/.changeset/shy-pigs-exercise.md @@ -0,0 +1,6 @@ +--- +"@tiptap/core": patch +"@tiptap/extension-hard-break": patch +--- + +Add Node `linebreakReplacement` support and enable on hard-break nodes diff --git a/packages/core/src/Node.ts b/packages/core/src/Node.ts index 19d01ca81..567e0eef7 100644 --- a/packages/core/src/Node.ts +++ b/packages/core/src/Node.ts @@ -595,6 +595,25 @@ declare module '@tiptap/core' { editor?: Editor }) => NodeSpec['whitespace']) + /** + * Allows a **single** node to be set as linebreak equivalent (e.g. hardBreak). + * When converting between block types that have whitespace set to "pre" + * and don't support the linebreak node (e.g. codeBlock) and other block types + * that do support the linebreak node (e.g. paragraphs) - this node will be used + * as the linebreak instead of stripping the newline. + * + * See [linebreakReplacement](https://prosemirror.net/docs/ref/#model.NodeSpec.linebreakReplacement). + */ + linebreakReplacement?: + | NodeSpec['linebreakReplacement'] + | ((this: { + name: string + options: Options + storage: Storage + parent: ParentConfig>['linebreakReplacement'] + editor?: Editor + }) => NodeSpec['linebreakReplacement']) + /** * When enabled, enables both * [`definingAsContext`](https://prosemirror.net/docs/ref/#model.NodeSpec.definingAsContext) and diff --git a/packages/core/src/helpers/getSchemaByResolvedExtensions.ts b/packages/core/src/helpers/getSchemaByResolvedExtensions.ts index 25b856140..602298172 100644 --- a/packages/core/src/helpers/getSchemaByResolvedExtensions.ts +++ b/packages/core/src/helpers/getSchemaByResolvedExtensions.ts @@ -78,6 +78,7 @@ export function getSchemaByResolvedExtensions(extensions: Extensions, editor?: E ), code: callOrReturn(getExtensionField(extension, 'code', context)), whitespace: callOrReturn(getExtensionField(extension, 'whitespace', context)), + linebreakReplacement: callOrReturn(getExtensionField(extension, 'linebreakReplacement', context)), defining: callOrReturn( getExtensionField(extension, 'defining', context), ), diff --git a/packages/extension-hard-break/src/hard-break.ts b/packages/extension-hard-break/src/hard-break.ts index 6461faf5b..ed5b9a68b 100644 --- a/packages/extension-hard-break/src/hard-break.ts +++ b/packages/extension-hard-break/src/hard-break.ts @@ -48,6 +48,8 @@ export const HardBreak = Node.create({ selectable: false, + linebreakReplacement: true, + parseHTML() { return [ { tag: 'br' },