NotFoundError: Node.removeChild: O nó a ser removido não é um filho deste nó

Desenvolvi um componente de tema:

Ele substitui o BBCode por SVG. Isso funciona também na pré-visualização do editor.

Meu problema é que, em alguns casos, recebo um erro ao digitar um caractere no editor:

NotFoundError: Node.removeChild: O nó a ser removido não é filho deste nó

Tenho quase certeza de que isso está relacionado ao fato de eu ter removido alguns elementos, pois se não remover nada, o erro não ocorre.

EDIT: O erro não ocorre quando faço a remoção, mas quando digito o primeiro caractere no editor após a remoção.

Minha pergunta é: remover elementos não é permitido?

Se for permitido: vocês têm alguma ideia do motivo desse erro?

Sei que isso é meio vago. Posso fornecer mais detalhes se necessário.

O rastreamento da pilha pode ser visto aqui:

EDIT 2: Não são apenas os elementos que eu removo. Às vezes, removo apenas os nós de texto.

Consigo reproduzir isso com este componente de tema simples:

<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. Crie um novo tópico
  2. Comece a digitar. O erro aparece no console de desenvolvimento ao digitar o segundo caractere.

A prévia do compositor usa o Ember para renderizar o conteúdo cooked. Parece que o erro está vindo do mecanismo de renderização do Ember, que provavelmente está confuso porque o DOM está sendo alterado por algo mais.

Para evitar o problema, sugiro que você não remove() nenhum nó e, em vez disso, os oculte usando display:none; ou algo similar.

Obrigado. Essa é uma solução alternativa que tenho considerado, mas gostaria que você confirmasse se isso é um bug ou não.

A prévia do compositor é uma combinação incomum de renderização do Ember e funções personalizadas ‘decorateCooked’. Parece que isso é uma peculiaridade dessa implementação. No momento, não temos planos de alterar a forma como funciona, especialmente porque a solução alternativa é simples e prática.

@j.jaffeux Notei que você passa essa função cleanUp para api.cleanupStream ao usar o WidgetGlue.

Estou recebendo o erro no OP ao tentar escrever no composer depois que meu widget é anexado. Vale notar que o div data-wrap original desaparece completamente depois que eu o destino com WidgetGlue.appendTo()

EDIT: Resolvido. Criei um nó <div> sacrificial para o Widget consumir, para que eu possa deixar o div [wrap=dice] ativo.

  // 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);