Why are document.execCommand() and contenteditable div separating my formatted text into nodes?

58 Views Asked by At

good morning to all! I have my component to which is performed in another component a document.execCommand(action) to a selected text.

The html of my component is extremely simple:

<template>
    <div contenteditable="true">
    </div>
    <div class="clone"> </div>
    
</template>

And this is the JS:

import { api, track, LightningElement } from 'lwc';

export default class appRichText extends LightningElement {
    @api textvalue;


    renderedCallback(){
        this.divRich = this.template.querySelector("div");
        this.divRich.innerHTML = this.textvalue;
        this.clone = this.template.querySelector(".clone");
        

    }

    @api
    getHTML(){
        let clonedHtml = this.divRich.cloneNode(true);
        clonedHtml.removeAttribute("contenteditable");
        let completeHTML = this.getDivContentAsString(clonedHtml);
        return completeHTML;
    }

    getDivContentAsString(divElement) {
        let contentString = "";
        function traverseNodes(node) {
            if (node.nodeType === Node.TEXT_NODE) {
              contentString += node.textContent;
            } else if (node.nodeType === Node.ELEMENT_NODE) {
                contentString += node.textContent;
                for (let childNode of node.childNodes) {
                    traverseNodes(childNode);
                }
            } 
        } 
        traverseNodes(divElement);
        return contentString;
      }

}

The problem I am having, that when doing the execCommand, the selected text of the div is divided into several nodes as I present in the following images:

Before formatting

After formatting

I have tried to go to the innerHTML and outerHTML of the div, but instead of putting all the text with the formatting tags applied, it only returns the first unformatted piece, taking the example from the images: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi posuere a erat sed sodales".

So I performed the method shown above in the JS to traverse the child nodes. With that method I only get the union of the two pieces of plain text, and I need to get the whole thing with format tags included.

When doing console logs of the nodes it is strange, because the node for the formatting (in this case ) claims to be an HTMLCollection. I tried to do divElement.children[0] but it doesn't find it and if I do the console log of divElement.children it returns it as HTMLCollection.

If I do console log of divElement, you can see that there are 3 childNodes (among them the formatted piece of text) and in children it is also there. but when doing the foreach of the childNodes it skips it. This would be the image of the information that has divElement.

The divElement console.log

So what I would be needing would be to understand how to go through those childNodes and have the whole value of that div with the tags applied. It can be achieved?

thanks in advance!

Tried to clone the nodes into another div (and a textarea) with no avail. Tried creating ranges for position but didnt worked. Tried to reach the children in several ways but couldnt do it. Of course, tried to do innerHTML to the div and that didnt worked neither.

0

There are 0 best solutions below