NotFoundError: Node.removeChild: Il nodo da rimuovere non è un figlio di questo nodo

I’ve developed a theme component:

It replaces BBCode with SVG. This works also in the editor preview.

My problem is that in some cases I get an error when I type a character in the editor:

NotFoundError: Node.removeChild: The node to be removed is not a child of this node

I’m pretty sure that this is related to that I have removed some elements, because if I don’t remove anything, I don’t get the error.

EDIT: I doesn’t happen when I do the removal, but when I type the first character in the editor after the removal.

My question is if removing elements is not allowed?

If it is; Do you have any idea why I’m getting this error?

I realize this is kind of vague. I may be able to provide more details if necessary.

The stack trace can be seen here:

1 Mi Piace

EDIT 2: It’s not just elements that I remove. I sometimes remove only text nodes.

1 Mi Piace

I can reproduce this with this simple theme component:

<script type="text/discourse-plugin" version="0.8">

  api.decorateCooked($elem => {
    if ($elem.get(0).className == 'd-editor-preview') {
      const $paragraphs = $elem.children('p');
      $.each($paragraphs, (paragraphIndex, paragraph) => {
        paragraph.remove();
      });
    }
  });

</script>
  1. Create a new topic
  2. Start typing. The error appears in the dev console for the second character that is typed.
2 Mi Piace

The composer preview uses ember to render the cooked content. It looks like that error is coming from the ember rendering engine, which is probably confused by the DOM being changed by something else.

To avoid the issue, I suggest that you don’t remove() any nodes, and instead hide them using display:none; or something similar.

3 Mi Piace

Thanks. That’s a workaround I’ve been thinking of, but I would appreciate if you could confirm that this is a bug or not.

The composer preview is an unusual combination of ember rendering and custom ‘decorateCooked’ functions. It looks like this is a quirk of that implementation. We don’t have any plans to change the way it works at the moment, especially since the workaround is nice and simple.

4 Mi Piace

@j.jaffeux Ho notato che hai passato questa funzione cleanUp a api.cleanupStream quando hai usato WidgetGlue.

Sto riscontrando l’errore nell’OP quando provo a scrivere nel composer dopo che il mio widget si è attaccato. In particolare, il div data-wrap originale è completamente scomparso dopo averlo selezionato con WidgetGlue.appendTo()

EDIT: Risolto. Ho creato un nodo <div> sacrificale da far consumare al Widget, in modo da poter lasciare il div [wrap=dice] attivo.

  // elem: <div class="d-wrap" data-wrap="dice">

  //- const glue = new WidgetGlue("dice-result", register, attrs);
  elem.innerHTML = "";
  //- glue.appendTo(elem);
  const sacrificial = document.createElement("div");
  elem.appendChild(sacrificial);
  attachDiceWidget(sacrificial, attrs);
2 Mi Piace