From e803a369f66935f349d71db37fa82abb32ad2c3c Mon Sep 17 00:00:00 2001 From: Bianca Pereira de Almeida Date: Tue, 11 Jun 2024 01:06:05 -0300 Subject: [PATCH] =?UTF-8?q?fix(rich-text-body):=20realiza=20sanitiza=C3=A7?= =?UTF-8?q?=C3=A3o=20do=20texto=20colado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit O componente po-rich-text ao receber um texto colado, não sanitiza o css do mesmo, gravando informações desnecessárias na model. Realiza a sanitização da model, para que receba apenas o valor, deixando a estilização a cargo do usuário, através das ferramentas disponibilizadas no componente. Fixes #1872 --- .../po-rich-text-body.component.spec.ts | 32 +++++++++++++++++++ .../po-rich-text-body.component.ts | 20 +++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) 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; + } }