ueberdosis / tiptap

The headless rich text editor framework for web artisans.
https://tiptap.dev
MIT License
27.33k stars 2.27k forks source link

[PRO]: Unique-ID Regenerates If Node Has No Content #5577

Open rosenbauerwillbacker opened 2 months ago

rosenbauerwillbacker commented 2 months ago

Affected Packages

@tiptap-pro/extension-unique-id, @tiptap-react

Version(s)

2.10.11

Description of the Bug

When you have nodes with no content, the unique-id is regenerated.

Example 1: Headings

Editor options:

Heading.configure({
  levels: [1, 2, 3, 4, 5],
}),
UniqueID.configure({
  types: ['heading']
}),

Parse and render HTML content:

const content = '<title-node></title-node><h1 data-id="a70661d9-cd0d-4119-941f-a16b6f788397"></h1><h1 data-id="0e6d8ef0-4961-49cf-9461-c0f339579325"></h1>'

editor.commands.setContent(content)
console.log(editor.getHTML());

The console.log statement returns:

<h1 data-id="a70661d9-cd0d-4119-941f-a16b6f788397">
</h1><h1 data-id="e6443c31-c5d0-40f3-98a7-d4e2a5699fc6"></h1>

As you can see the second heading doesn't preserve it's id, but regenerates a new one.

Example 2: Custom extension

Test Extension (simply renders the id):

import { Node } from '@tiptap/core';
import { NodeViewWrapper, ReactNodeViewRenderer } from '@tiptap/react';

const Component = ({ node }: any) => (
  <NodeViewWrapper as="span">
    {node.attrs.id}
  </NodeViewWrapper>
)

const Test = Node.create({
  name: 'test',
  inline: false,
  group: 'block',
  atom: true,

  renderHTML({ HTMLAttributes }) {
    return ['test', HTMLAttributes];
  },

  parseHTML() {
    return [
      {
        tag: 'test',
      },
    ];
  },

  addNodeView() {
    return ReactNodeViewRenderer(Component);
  },
})

export default Test;

Setting the content:

const content = '<test data-id="a70661d9-cd0d-4119-941f-a16b6f788397"></test ><test data-id="0e6d8ef0-4961-49cf-9461-c0f339579325"></test >'
editor.commands.setContent(content)

Rendered content: image

Again the second id is not preserved.

Important note: This bug only occurs when the content of the node is empty and only then to the following node. So we have headings with content everything works as intended. This is particularly painful when building a custom node that doesn't have any content.

Browser Used

Chrome

Code Example (Preferred)

No response

Expected Behavior

The ids should be preserved and not regenerate.

Additional Context (Optional)

No response

Dependency Updates

rosenbauerwillbacker commented 2 months ago

I tried to fix the package code myself. However, I found out that the code is obfuscated. Thus, I am at your mercy of resolving this issue.

Thank you in advance for your support!!

nperez0111 commented 2 months ago

Reading through the code it looks like this was intentional though I cannot understand why. Would need @bdbch to shed light on it