diff --git a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-body/po-rich-text-body.component.spec.ts b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-body/po-rich-text-body.component.spec.ts index 1241d01519..22618f372d 100644 --- a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-body/po-rich-text-body.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-body/po-rich-text-body.component.spec.ts @@ -1170,4 +1170,36 @@ describe('PoRichTextBodyComponent:', () => { expect(nativeElement.querySelector('.po-rich-text-body')).toBeTruthy(); }); }); + + it('sanitizeHtmlContent: should sanitize HTML content and extract text content', () => { + const htmlContent = '
Hello world!
'; + const sanitizedContent = component['sanitizeHtmlContent'](htmlContent); + expect(sanitizedContent).toBe('Hello world!'); + }); + + it('extractTextContent: should extract text content from a node', () => { + const htmlContent = '
Hello world!
'; + const parser = new DOMParser(); + const doc = parser.parseFromString(htmlContent, 'text/html'); + const textContent = component['extractTextContent'](doc.body); + expect(textContent).toBe('Hello world!'); + }); + + it('sanitizeHtmlContent: should handle nested HTML elements correctly', () => { + const htmlContent = '
Hello
beautiful world
!
'; + const sanitizedContent = component['sanitizeHtmlContent'](htmlContent); + expect(sanitizedContent).toBe('Hello beautiful world!'); + }); + + it('sanitizeHtmlContent: should return empty string for empty HTML content', () => { + const htmlContent = ''; + const sanitizedContent = component['sanitizeHtmlContent'](htmlContent); + expect(sanitizedContent).toBe(''); + }); + + it('sanitizeHtmlContent: should return text content for text nodes only', () => { + const htmlContent = 'Just plain text'; + const sanitizedContent = component['sanitizeHtmlContent'](htmlContent); + expect(sanitizedContent).toBe('Just plain text'); + }); }); diff --git a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-body/po-rich-text-body.component.ts b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-body/po-rich-text-body.component.ts index bc43db0b62..b92535173d 100644 --- a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-body/po-rich-text-body.component.ts +++ b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-body/po-rich-text-body.component.ts @@ -341,7 +341,7 @@ export class PoRichTextBodyComponent implements OnInit, OnDestroy { } private updateModel() { - this.modelValue = this.bodyElement.nativeElement.innerHTML; + this.modelValue = this.sanitizeHtmlContent(this.bodyElement.nativeElement.innerHTML); this.value.emit(this.modelValue); } @@ -371,4 +371,22 @@ export class PoRichTextBodyComponent implements OnInit, OnDestroy { return isLink; } + + private sanitizeHtmlContent(htmlContent: string): string { + const parser = new DOMParser(); + const doc = parser.parseFromString(htmlContent, 'text/html'); + return this.extractTextContent(doc.body); + } + + private extractTextContent(node: Node): string { + let textContent = ''; + node.childNodes.forEach(childNode => { + if (childNode.nodeType === Node.TEXT_NODE) { + textContent += childNode.textContent; + } else if (childNode.nodeType === Node.ELEMENT_NODE) { + textContent += this.extractTextContent(childNode); + } + }); + return textContent; + } }