diff --git a/.changeset/chatty-pianos-learn.md b/.changeset/chatty-pianos-learn.md new file mode 100644 index 000000000..201b5076c --- /dev/null +++ b/.changeset/chatty-pianos-learn.md @@ -0,0 +1,5 @@ +--- +"@tiptap/core": patch +--- + +preserve existing node attributes when running setNode diff --git a/docs/api/utilities.md b/docs/api/utilities.md deleted file mode 100644 index d4d982882..000000000 --- a/docs/api/utilities.md +++ /dev/null @@ -1,11 +0,0 @@ -# Editor API Utility Overview - -Welcome to the Editor API Utility section. Here, you'll discover essential tools to enhance your Tiptap experience: - -- **Render JSON as HTML**: Learn to convert JSON content to HTML, even without an editor instance, simplifying content management. - -- **Tiptap for PHP**: Explore PHP integration for Tiptap, enabling seamless content transformation and modification. - -- **Suggestions**: Enhance your editor with suggestions like mentions and emojis, tailored to your needs. - -Explore subpages for in-depth guidance and examples. diff --git a/packages/core/src/commands/setNode.ts b/packages/core/src/commands/setNode.ts index b48e1a376..d3828d05f 100644 --- a/packages/core/src/commands/setNode.ts +++ b/packages/core/src/commands/setNode.ts @@ -21,6 +21,13 @@ declare module '@tiptap/core' { export const setNode: RawCommands['setNode'] = (typeOrName, attributes = {}) => ({ state, dispatch, chain }) => { const type = getNodeType(typeOrName, state.schema) + let attributesToCopy: Record | undefined + + if (state.selection.$anchor.sameParent(state.selection.$head)) { + // only copy attributes if the selection is pointing to a node of the same type + attributesToCopy = state.selection.$anchor.parent.attrs + } + // TODO: use a fallback like insertContent? if (!type.isTextblock) { console.warn('[tiptap warn]: Currently "setNode()" only supports text block nodes.') @@ -32,7 +39,7 @@ export const setNode: RawCommands['setNode'] = (typeOrName, attributes = {}) => chain() // try to convert node to default node if needed .command(({ commands }) => { - const canSetBlock = setBlockType(type, attributes)(state) + const canSetBlock = setBlockType(type, { ...attributesToCopy, ...attributes })(state) if (canSetBlock) { return true @@ -41,7 +48,7 @@ export const setNode: RawCommands['setNode'] = (typeOrName, attributes = {}) => return commands.clearNodes() }) .command(({ state: updatedState }) => { - return setBlockType(type, attributes)(updatedState, dispatch) + return setBlockType(type, { ...attributesToCopy, ...attributes })(updatedState, dispatch) }) .run() )