NotFoundError: Node.removeChild: Le nœud à supprimer n'est pas un enfant de ce nœud

J’ai développé un composant de thème :

Il remplace le BBCode par du SVG. Cela fonctionne également dans l’aperçu de l’éditeur.

Mon problème est que, dans certains cas, je reçois une erreur lorsque je tape un caractère dans l’éditeur :

NotFoundError: Node.removeChild: Le nœud à supprimer n'est pas un enfant de ce nœud

Je suis presque certain que cela est lié au fait que j’ai supprimé certains éléments, car si je ne supprime rien, je ne rencontre pas l’erreur.

MODIFICATION : L’erreur ne se produit pas lors de la suppression, mais lorsque je tape le premier caractère dans l’éditeur après la suppression.

Ma question est donc : la suppression d’éléments n’est-elle pas autorisée ?

Si elle l’est, avez-vous une idée de pourquoi je rencontre cette erreur ?

Je réalise que c’est un peu vague. Je pourrai fournir plus de détails si nécessaire.

La trace de la pile est visible ici :

1 « J'aime »

EDIT 2 : Ce ne sont pas seulement des éléments que je supprime. Parfois, je supprime uniquement des nœuds de texte.

1 « J'aime »

Je peux reproduire ce problème avec ce simple composant de thème :

<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. Créez un nouveau sujet
  2. Commencez à taper. L’erreur apparaît dans la console de développement pour le deuxième caractère saisi.
2 « J'aime »

L’aperçu du compositeur utilise Ember pour rendre le contenu « cuit ». Il semble que cette erreur provienne du moteur de rendu Ember, qui est probablement perturbé par des modifications du DOM effectuées par un autre élément.

Pour éviter ce problème, je vous suggère de ne pas supprimer (remove()) de nœuds, mais plutôt de les masquer en utilisant display:none; ou une méthode similaire.

3 « J'aime »

Merci. C’est une solution de contournement à laquelle je pensais, mais j’apprécierais que vous confirmiez s’il s’agit bien d’un bug ou non.

L’aperçu du compositeur est une combinaison inhabituelle du rendu Ember et de fonctions personnalisées ‘decorateCooked’. Il semble qu’il s’agisse d’une particularité de cette implémentation. Nous n’avons aucun projet de modifier son fonctionnement pour le moment, d’autant plus que la solution de contournement est simple et élégante.

4 « J'aime »

@j.jaffeux Je remarque que vous passez cette fonction cleanUp à api.cleanupStream lorsque vous utilisez WidgetGlue.

Je rencontre l’erreur mentionnée dans l’ouverture de sujet lorsque j’essaie d’écrire dans le compositeur après que mon widget se soit attaché. Notamment, le div data-wrap original a complètement disparu après que je l’ai ciblé avec WidgetGlue.appendTo()

EDIT : Résolu. J’ai créé un nœud <div> sacrificiel pour que le Widget le consomme, afin de pouvoir laisser le div [wrap=dice] en vie.

  // 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 « J'aime »