Search code examples
javascriptphplaravelckeditor

CKeditor remove extra whitespace at beginning - trim


I am trying to remove the extra whitespaces at the beginning and end of a text generated by ckeditor but not the whtiespaces between the text itself.

I am ending up with many space at beginning and then the actual text.

so I am trying to write a trim function for ckeditor generated text, the traditional trim() not working as the text includes <p></p> &nbsp; and sometimes <br> so I couldn't just write a regex.

Example of the generated text

<p><br><br><br><br><br><br><br><br><br><br><br>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p><br><br><br><br><br><br>here text begins</p><p><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>another line</p><p><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>third line </p><p><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><strong>fourth line</strong></p><p><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><span class="text-huge"><strong>sdsdsdsdsd</strong></span></p><h2><span class="text-huge"><i><strong><u>sdsdsdsdsdsdsd</u></strong></i></span><br><br><br><br><br><br><span class="text-huge"><i><strong><u>csdsdsdsdsdsds</u></strong></i></span><br><br><br><br><br><br><br><br><br>&nbsp;</h2>

I want to remove every tags until the here text begins but this text might vary might be anything,

any suggestions?


Solution

  • okay, I have managed to sort this issue with a workaround, the idea is:

    1- parse the total string we got from the ckeditor content.getData() to an HTMLCollection,

    2- loop over the html tags and delete any tag that does NOT have words by checking the property textContent, as soon as the tag has words exit the loop.

    3- loop inside the tag that has words in it and convert the string to array of words by splitting str.split(' ') and loop over the array and remove each <br> or &nbsp; until you reach anything other than these tag and entity then exit the loop.

    4- you need to go through this process from the beginning of the (total text you got from ckeditor) and from the end.

            trimedCkEditorText() {
                let contentStr = this.content.getData();
                // Remove Extra whitespaces at the begining of the text
                contentStr = this.trimedCkEditorTextAt(contentStr, true);
    
                // Remove Extra whitespaces at the end of the text
                contentStr = this.trimedCkEditorTextAt(contentStr, false);
    
                return contentStr;
            },
            trimedCkEditorTextAt(contentStr, startOfText) {
                const parser = new DOMParser();
                const doc = parser.parseFromString(contentStr, "text/html")
    
                // Check first child 
                while(doc.body.children.length) {
                    const index = startOfText ? 0 : doc.body.children.length - 1; 
                    const child = doc.body.children[index];
                    
                    if(child.textContent.replace(/\s/g, '').length) {
                        // Remove <br> tags
                        while(child.children.length) {
                            const index = startOfText ? 0 : child.children.length - 1; 
                            const grandechild = child.children[index];
                            if(grandechild.localName === 'br') grandechild.remove();
                            else break;
                        }
    
                        // Remove &nbsp;
                        const childTextArray = child.innerHTML.split(' ');
                        while(childTextArray.length) {
                            const index = startOfText ? 0 : childTextArray.length - 1; 
                            if(childTextArray[index] === '&nbsp;') childTextArray.splice(index, 1);
                            else break;
                        }
                        child.innerHTML = childTextArray.join(' ');
                        break;
                    } else {
                        child.remove();
                    }
                }
    
                return doc.body.innerHTML;
            }