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

HTML Element not found for Floating Menu in Svelte Lifecycle #2241

Closed
1 of 2 tasks
TorstenDittmann opened this issue Dec 6, 2021 · 6 comments
Closed
1 of 2 tasks
Labels
Type: Bug The issue or pullrequest is related to a bug

Comments

@TorstenDittmann
Copy link

What’s the bug you are facing?

When using the FloatingMenu or BubbleMenu Plugin with Svelte - an error message is thrown when Svelte is trying to cleanup on the Component destroy lifecycle.

Uncaught (in promise) TypeError: Cannot read properties of null (reading 'removeChild')

How can we reproduce the bug on our side?

Use Svelte with following dependencies:

  • @tiptap/core": "*"
  • @tiptap/extension-floating-menu": "*"
  • @tiptap/starter-kit": "*"

Create a component that is using tiptap with the starter kit and the floating menu (same fails with the bubble menu plugin).

Display the component in another svelte component and destroy the component containing tiptap. (This will also happen with any kind of client side router in use).

Can you provide a CodeSandbox?

https://replit.com/@TorstenDittman1/Svelte-TipTap-Floating-Menu

What did you expect to happen?

No error message.

Anything to add? (optional)

This line causes it to fail => https://github.com/ueberdosis/tiptap/blob/main/packages/extension-floating-menu/src/floating-menu-plugin.ts#L71

Not sure why exactly the element is removed in the first place? 🤔

Did you update your dependencies?

  • Yes, I’ve updated my dependencies to use the latest version of all packages.

Are you sponsoring us?

  • Yes, I’m a sponsor. 💖
@TorstenDittmann TorstenDittmann added the Type: Bug The issue or pullrequest is related to a bug label Dec 6, 2021
@TorstenDittmann
Copy link
Author

TorstenDittmann commented Dec 6, 2021

https://svelte.dev/repl/0d826c0d67c54d8693aeaa1b77ea09ef?version=3.44.2

As it looks like, this bug might be a Svelte bug in the first place 🤔

Edit: I have create a PR that fixes this on svelte itself sveltejs/svelte#6996

@philippkuehn
Copy link
Contributor

I think you should also bind the menu element:

<script>
  import { onMount, onDestroy } from "svelte";
  import { Editor } from "@tiptap/core";
  import FloatingMenu from "@tiptap/extension-floating-menu";
  import StarterKit from "@tiptap/starter-kit";

  let element;
  let editor;
  let menu;

  onMount(() => {
    element = element;
    editor = new Editor({
      element: element,
      extensions: [
        StarterKit,
        FloatingMenu.configure({
          element: menu,
        })
      ],
      content: "<p>Hello World! 🌍️ </p>",
      onTransaction: () => {
        // force re-render so `editor.isActive` works as expected
        editor = editor;
      }
    });
  });

  onDestroy(() => {
    if (editor) {
      editor.destroy();
    }
  });
</script>

<div bind:this={element} />
<div bind:this={menu} class="menu">
  Floating Menu!
</div>

@TorstenDittmann
Copy link
Author

This will still fail 😉

@philippkuehn
Copy link
Contributor

Oh you are right. I swear I didn't see that error earlier when I tried it. But not sure what we can do here 🤔

@TorstenDittmann
Copy link
Author

Me neither, this is an error on svelte's end and regarding to the issue (sveltejs/svelte#6037) and the comment a maintainer has made on my PR (sveltejs/svelte#6996 (comment)) I am not sure when/if this will be fixed anytime soon.

I'll try later today and look for a solution on the plugin 👍🏻

@TorstenDittmann
Copy link
Author

TorstenDittmann commented Dec 7, 2021

@philippkuehn unconventional workaround, but it works - since the bug in svelte relies on the parent node. Since the element was on root and removed it run into an error.

So by simply wrapping the element used for the floating menu in a div, solves the problem 👍🏻

<script>
  import { onMount, onDestroy } from "svelte";
  import { Editor } from "@tiptap/core";
  import FloatingMenu from "@tiptap/extension-floating-menu";
  import StarterKit from "@tiptap/starter-kit";

  let element;
  let editor;
  let menu;

  onMount(() => {
    element = element;
    editor = new Editor({
      element: element,
      extensions: [
        StarterKit,
        FloatingMenu.configure({
          element: menu,
        })
      ],
      content: "<p>Hello World! 🌍️ </p>",
      onTransaction: () => {
        // force re-render so `editor.isActive` works as expected
        editor = editor;
      }
    });
  });

  onDestroy(() => {
    if (editor) {
      editor.destroy();
    }
  });
</script>

<div bind:this={element} />
<div>
  <div bind:this={menu}>
    Floating Menu!
  </div>
</div>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug The issue or pullrequest is related to a bug
Projects
None yet
Development

No branches or pull requests

2 participants