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

NotFoundError: Failed to execute 'removeChild' on 'Node' #920

Closed
parisk opened this issue Aug 25, 2017 · 6 comments
Closed

NotFoundError: Failed to execute 'removeChild' on 'Node' #920

parisk opened this issue Aug 25, 2017 · 6 comments
Assignees
Labels
type/bug Something is misbehaving
Milestone

Comments

@parisk
Copy link
Contributor

parisk commented Aug 25, 2017

We also ran into this issue on SourceLair, at the same time with #919 (same user).

Seems like rowContainer can be detached from term.element at some points 🤔.

https://github.com/sourcelair/xterm.js/blob/6e9d60d76d6cfb3d279f9e58499ba62ca6af479c/src/Renderer.ts#L129-L131

Details

@parisk parisk added the type/bug Something is misbehaving label Aug 25, 2017
@Tyriar
Copy link
Member

Tyriar commented Aug 25, 2017

It's removed and added again at the end of refresh so a partial layout isn't attempted. All the DOM manipulations are done while it's detached. This is meant to be the only point that it's detached though.

@parisk
Copy link
Contributor Author

parisk commented Aug 25, 2017

https://github.com/sourcelair/xterm.js/blob/6e9d60d76d6cfb3d279f9e58499ba62ca6af479c/src/Renderer.ts#L319-L321

So based on the lines below, it seems that the issue is:

  1. Refresh happens, but at the end of it, there is no parent, so the element is not put back
  2. Another refresh happens, but now while a parent element exists (for some reason), the rowContainer has not been put back into its place

Maybe we should perform a check for rowContainer as well, before removing or appending it.

@Tyriar
Copy link
Member

Tyriar commented Aug 25, 2017

After a closer look, I notice parent != Terminal.parent (at least i the sense is can be unset).

parent gets set if the terminal is attached to the DOM (ie. Terminal.element has a parentNode) and > 50% of the viewport is getting refreshed. I don't think a check for rowContainer would change the outcome, or it would hide the underlying bug.

Perhaps something in another class is messing with the DOM in an unexpected way?

@parisk parisk mentioned this issue Sep 4, 2017
22 tasks
@Tyriar Tyriar self-assigned this Sep 4, 2017
@Tyriar Tyriar added this to the 3.0.0 milestone Sep 4, 2017
@JoshuaKGoldberg
Copy link
Contributor

JoshuaKGoldberg commented May 28, 2020

Hey @Tyriar, the situation of another class messing with the DOM actually reproduces reliably now with hot module reloading in React applications. Here's a demo: https://codesandbox.io/s/xtermjs-dom-renderer-disposal-jsd75

useEffect(() => {
  if (!divRef.current) {
    return;
  }

  const terminal = new Terminal({
    rendererType: "dom"
  });

  terminal.open(divRef.current);
  terminal.write(`It has begun! ${Math.random()}`);

  return () => {
    // To cause this line to crash, modify some code in CodeSandbox.
    // That'll cause a hot module reload (HMR), which removes the
    // terminal's element *before* this disposal function is run.
    terminal.dispose();
  };
}, [divRef]);

I'd be happy to send a PR that, say, changes the DOM renderer's dispose() to only removeChild the intended elements if they're children of _screenElement?

@Tyriar
Copy link
Member

Tyriar commented Jun 3, 2020

@JoshuaKGoldberg yes please send a PR 🙂

@Tyriar
Copy link
Member

Tyriar commented Jun 3, 2020

👉 #2960

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/bug Something is misbehaving
Projects
None yet
Development

No branches or pull requests

3 participants