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

Bug: Unexepected behavior when using append() on ListNode #6793

Open
basile-savouret opened this issue Nov 5, 2024 · 1 comment
Open

Bug: Unexepected behavior when using append() on ListNode #6793

basile-savouret opened this issue Nov 5, 2024 · 1 comment

Comments

@basile-savouret
Copy link

basile-savouret commented Nov 5, 2024

I have copied the column layout and image nodes from the playground in my project and I implemented a backspace handler for the column layout, to be able to remove it. My solution is to append all the children of the layout item into his ancestor and then remove it.
Here is the backspace handler i wrote:

const $onDelete = (isBackspace: boolean) => {
      const selection = $getSelection();
      if (
        $isRangeSelection(selection)
      ) {
        const container = $findMatchingParent(
          selection.anchor.getNode(),
          $isLayoutContainerNode,
        );
        const { layoutItemNode, previousSibling } = getLayoutItemInParentsAndFindPreviousSibling(selection.anchor.getNode())
        const previousContainer = layoutItemNode?.getPreviousSibling() ?? container?.getPreviousSibling()
        if (previousContainer && $isElementNode(previousContainer)) {

          if (layoutItemNode && !previousSibling && selection.anchor.offset === 0 && isBackspace) {
            previousContainer.append(...layoutItemNode.getChildren())
            layoutItemNode.remove(false)
            return false
          }

          if (layoutItemNode && layoutItemNode.getChildren().length === 1) {
            const firstChild = layoutItemNode.getFirstChild()
            if ($isParagraphNode(firstChild) && firstChild.isEmpty()) {
              previousContainer.append(...layoutItemNode.getChildren())
              layoutItemNode.remove(false)
            }
          }

        }

      }

      return false
    };

It works fine on every node:

Enregistrement.de.l.ecran.2024-11-05.085945.mp4

But it fails when the ancestor is a ListNode.

The editor stop working and i get those errors Expected node root to have a parent, updateEditor: selection has been lost because the previously selected nodes have been removed and selection wasn't moved to another node. Ensure selection changes after removing/replacing a selected node

When i disable the remove of the layout item and just keep the append of the children i notice the different behavior of the ListNode compared to the others:

Append on a quote node:

Enregistrement.de.l.ecran.2024-11-05.101942.mp4

The children are moved into the node like i expect them to be.
The selection follows them.

Append on a list node:

Enregistrement.de.l.ecran.2024-11-05.102025.mp4

The children are duplicated into the node and the image is lost. The selection stays in the original children.

I believe this is what triggers my bug as when i try to remove the layout item the children are still in and the selection is lost afterwards.

Lexical version: 0.19.0

@basile-savouret
Copy link
Author

basile-savouret commented Nov 5, 2024

After looking into the source code it seems like this behavior is comming from this line of code:

const textNode = $createTextNode(currentNode.getTextContent());

else if ($isElementNode(currentNode)) {
          const textNode = $createTextNode(currentNode.getTextContent());
          listItemNode.append(textNode);
}

where it creates a new textNode and only paste the text content inside it ignoring the image that is kept as a decorator.

I can try to resolve this and make a pull request but I don't have enough context and there might be a reason for this special behaviour on ListNode that i don't know of.

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

No branches or pull requests

1 participant