ueberdosis / tiptap

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

[Bug]: setContent breaks mentions when provided as html #4893

Open stefanholzapfel opened 4 months ago

stefanholzapfel commented 4 months ago

Which packages did you experience the bug in?

core, extension-mention

What Tiptap version are you using?

2.2.3

What’s the bug you are facing?

I remember in earlier versions it was working perfectly fine to re-add a mention tag that was previously extracted from the editor as plain html like e.g.:

editor.commands.setContent('<p><span class="mention" data-id="4221" data-mention="" data-label="Stefan Holzapfel" contenteditable="false">@Stefan Holzapfel</span></p>')

In version 2.2 that behavior doesn't work anymore, something parses the mention and transforms it to that:

<p><span data-decoration-id="id_3447837711" class="suggestion">@Stefan Hol</span>zapfel</p>

Anyone has an explanation what happens here? Especially the cropping and re-attaching of a part of the string after the closing tag is weird.

I have defined the renderHtml in the Mention.configuration like this:

return [
            "span",
            {
                class: 'mention',
                'data-id': id,
                'data-mention': '',
                'data-label': label
            },
            `@${label}`
        ]

This is the complete initialization of the editor:

        editor = new Editor({
            element: this.shadowRoot.querySelector('#container'),
            parseOptions: {
                preserveWhitespace: true
            },
            onBlur: () => {
                this.closeMentionList();
            },
            autofocus: false,
            extensions: [
              StarterKit.configure({
                  blockquote: false,
                  bulletList: false,
                  codeBlock: false,
                  hardBreak: false,
                  heading: false,
                  horizontalRule: false,
                  listItem: false,
                  orderedList: false,
                  code: false
              }),
              Highlight,
              Typography,
              Placeholder.configure({
                  placeholder: this.placeholder
              }),
              Mention.configure({
                renderHTML: ({ options, node }) => {
                    return [
                      "span",
                      {
                          class: 'mention',
                          'data-id': id,
                          'data-mention': '',
                          'data-label': label
                      },
                      `@${label}`
                  ]
                },
                suggestion: {
                    allowSpaces: true,
                    items: query => {
                        return this.mentionData;
                    },
                    render: () => {
                        return {
                            onStart: props => {
                                // ...
                            },
                            onKeyDown: props => {
                                // ...
                            },
                            onUpdate: props => {
                                // ...
                            },
                            onExit: () => {
                                this.closeMentionList();
                            },
                        };
                    }
                }
            })
        ]
        });

What browser are you using?

Chrome

Code example

No response

What did you expect to happen?

The html to get imported witouth any transformations on setContent.

Anything to add? (optional)

No response

Did you update your dependencies?

Are you sponsoring us?

bdbch commented 4 months ago

Does this work with insertContent? I checked if the setContent logic was changed somehow but can't really see any significant change. Could you try the latest 2.2.3 and tell me if that still happens as we had a similar issue with parsing links?

stefanholzapfel commented 4 months ago

@bdbch sry i forgot to add the patch version, fixed that - I'm already on 2.2.3. Also downgraded to 2.1, same problem.

And yes the behavior is the same for insertContent. Tested in Chrome and Firefox.

Might the data-mention attribute with an empty string ('data-mention': '') be a problem? Found no way to add it as boolean attribute.

bdbch commented 4 months ago

Mh that's weird, the issue looked a lot like the issue we had with links where the link parsing lead to wrong positions and links having either links that were wrapped to long or to short.

Not sure why this happens right now - I created a test in #4895 regarding this with a more simplified variant of the mention implementation and there it works fine while mentioning @John Doe.

stefanholzapfel commented 4 months ago

What I also recognized is that in older versions you could use the default implementation of the mention template, it would automatically add the data-mention & data-label attributes when you provide id an label props in the command.

This no longer works, that's why I created my own template in renderHTML. Maybe that's the breaker?

vasyaqwe commented 4 months ago

stuck on a very similar issue, I think they might be the same thing. I have used the renderHTML() function, made it a button: renderHTML({ node }) { return ["button",@${node.attrs.label}] },

When editor mounts and has content value as this example string: <p><button>@test</button> </p>

it replaces the button tag with the same span with class="suggestion". Sometimes it just removes the button tag, and leaves out @test

just confirmed, it happens on the latest 2.2.3

nperez0111 commented 2 weeks ago

Should be resolved with v2.5.0-beta.5 Can you try it out & let us know?