amirhhashemi / tiptap-text-direction

Text direction extension for Tiptap
https://www.npmjs.com/package/tiptap-text-direction
MIT License
38 stars 1 forks source link

The text styles are being reset when a line break is inserted #13

Closed thisunravisara closed 6 months ago

thisunravisara commented 1 year ago

Hi there,

Upon installing this extension, the text styles are being reset when a line break is inserted by pressing the enter key, or when text is deleted without removing the entire line itself. With

The expected behavior is Without

Any insights are greatly appreciated!

amirhhashemi commented 1 year ago

Hi @thisunravisara

Thank you for reporting this.

I'm looking into it and will let you know when I found a solution.

I spent a couple of hours to find the issue but it doesn't seem to be a bug in my plugin. The default behaviour of ProseMirror is to remove all marks from the previous line when entering a new like, as you can see in their basic example. Maybe TipTap is doing something that I'm not aware of.

thisunravisara commented 1 year ago

Hi @amirhhashemi

Thanks a lot for the speedy reply!

You can find out the problem by toggling the extension on and off over here: StackBlitz Link.

Yeah, it appears that Tiptap has indeed enhanced the default behaviour of ProseMirror.

thisunravisara commented 6 months ago

Hi @amirhhashemi

Have to preserve and restore marks after updating node attributes

addProseMirrorPlugins: function( this ) {
                        return [
                            new Plugin({
                                appendTransaction: ( transactions, oldState, newState ) => {
                                    const docChanges = transactions.some( transaction => transaction.docChanged,
                                    );
                                    if ( !docChanges ) {
                                      return;
                                    }
                                    let modified = false;
                                    const tr = newState.tr;
                                    newState.doc.descendants(( node, pos ) => {
                                      if ( this.options.types.includes( node.type.name )) {
                                        if ( node.attrs.dir !== null && node.textContent.length > 0 ) {
                                          return;
                                        }
                                        const marks = tr.storedMarks || [];
                                        tr.setNodeAttribute( pos, 'dir', getTextDirection( node.textContent ));
                                        marks.forEach( mark => {
                                          tr.addStoredMark( mark );
                                        });
                                        modified = true;
                                      }
                                    });
                                    return modified ? tr : null;
                                }}),
                        ];
amirhhashemi commented 6 months ago

@thisunravisara I can't find any documentation pointing setNodeAttribute resets marks. But your solution works. Thank you.

I released 0.3.1 to fix this issue.