Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changing the text direction breaks the editor #5628

Open
azvoncov-smartling opened this issue Apr 4, 2024 · 2 comments
Open

Changing the text direction breaks the editor #5628

azvoncov-smartling opened this issue Apr 4, 2024 · 2 comments
Labels

Comments

@azvoncov-smartling
Copy link

Description
The bug is reproduced in Chromium; when changing the direction of the text, the browser wraps the elements in an extra div, which breaks the editor

I didn't find the specification, but it looks like all inline blocks are up to the nearest contenteditable="false"

That is, if you use inline-void elements and change the direction of the text -> the editor breaks

Recording

output.mov

Sandbox
https://www.slatejs.org/examples/mentions

Steps
To reproduce the behavior:

  1. Go to https://www.slatejs.org/examples/mentions
  2. Click on the text after mentioned user (inline-void element)
  3. Сall context menu -> Writing Direction -> Right to Left
  4. See extra div and errors in the console

Expectation
Ideal option: when changing the direction of the text, the dir attribute is set to the entire editor
Ok option: intercept this event and restore the previous state of DOM

Environment

  • Slate Version: any
  • Operating System: MacOS/Windows
  • Browser: Chrome
  • TypeScript Version: any

Context
In lexical this problem is solved (try Insert -> Image -> Sample) https://playground.lexical.dev/

@azvoncov-smartling
Copy link
Author

Also, if you apply a change of direction to the selected text close to the Void Element - Chrome removes the span nodes and after any changes (Ctrl+z for example) the editor crashes

output1.mov

@azvoncov-smartling
Copy link
Author

azvoncov-smartling commented Apr 4, 2024

btw, I have a raw version of the hook that fixes this problem, you can also save a new direction locally and change it in the editor if desired

const config = { attributes: true, childList: true, subtree: true };

function isElementNode(node: Node | null): node is Element {
    return !!node && node.nodeType === Node.ELEMENT_NODE;
}

export function useChangingDirection(editor: SlateEditor) {
    useLayoutEffect(() => {
        const textbox = ReactEditor.toDOMNode(editor, editor);

        const callback: MutationCallback = (mutationsList) => {
            const changedDirection = mutationsList.some(mutation => {
                const { type, attributeName, target } = mutation;

                if (type === "attributes" && target.nodeName === "DIV") {
                    if (attributeName === "style"
                        && isElementNode(target)
                    ) {
                        const styleAttribute = target.getAttribute("style");

                        return styleAttribute && styleAttribute.includes("direction");
                    }

                    return attributeName === "dir";
                }

                return false;
            });

            if (changedDirection) {
                const childListMutations = mutationsList
                    .filter(mutation => mutation.type === "childList")
                    .reverse();

                childListMutations.forEach(currentMutation => {
                    currentMutation.addedNodes.forEach(node => {
                        node.parentNode?.removeChild(node);
                    });

                    currentMutation.removedNodes.forEach(node => {
                        currentMutation.target.insertBefore(node, currentMutation.nextSibling);
                    });
                });
            }
        };

        const observer = new MutationObserver(callback);
        observer.observe(textbox, config);

        return () => observer.disconnect();
    }, [editor]);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant