From 1a831ef31e6d60af258ea5ba66f76913eacdb5e2 Mon Sep 17 00:00:00 2001 From: Maksim Sukharev Date: Fri, 15 Nov 2024 23:09:09 +0100 Subject: [PATCH 1/2] fix(NcRichContenteditable): do not break adjacent mentions - when injecting HTML template, newlines, tabs and consecutive whitespaces should be stripped - when parsing innerHTML (reverse process), collapsing of whitespacing also affecting two adjacent HTML templates - parsed ids without whitespace will be joined and won't be rendered next time Signed-off-by: Maksim Sukharev --- src/mixins/richEditor/index.js | 8 +++---- tests/unit/mixins/richEditor.spec.js | 31 ++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/mixins/richEditor/index.js b/src/mixins/richEditor/index.js index 4dfe65fb1c..4f2dfe7b4b 100644 --- a/src/mixins/richEditor/index.js +++ b/src/mixins/richEditor/index.js @@ -73,8 +73,6 @@ export default { */ parseContent(content) { let text = content - // Consecutive spaces in HTML tags should collapse - text = text.replace(/>\s+<') // Replace break lines with new lines text = text.replace(/
/gmi, '\n') // Replace some html special characters @@ -115,8 +113,10 @@ export default { : `@"${value}"` } - // Return template and make sure we strip of new lines and tabs - return this.renderComponentHtml(data, NcMentionBubble).replace(/[\n\t]/gmi, '') + // Return template and make sure we strip off new lines, tabs and consecutive whitespaces + return this.renderComponentHtml(data, NcMentionBubble) + .replace(/[\n\t]/gmi, '') + .replace(/>\s+<') }, /** diff --git a/tests/unit/mixins/richEditor.spec.js b/tests/unit/mixins/richEditor.spec.js index 34f65f25e1..327cb6554a 100644 --- a/tests/unit/mixins/richEditor.spec.js +++ b/tests/unit/mixins/richEditor.spec.js @@ -60,10 +60,37 @@ describe('richEditor.js', () => { }, }, }) - const input = 'hello @jdoe' + const input = 'hello @jdoe!\nhow are you?' const output = editor.vm.renderContent(input) - expect(output).toMatch(/^hello !
how are you\?$/) + expect(output).not.toMatch(/[\n\t]/gmi) + expect(output).not.toMatch(/>\s+ { + const editor = shallowMount(TestEditor, { + propsData: { + userData: { + jdoe: { + id: 'jdoe', + label: 'J. Doe', + source: 'users', + icon: 'icon-user', + }, + 'guest/47e0a7cf': { + id: 'guest/47e0a7cf', + label: 'J. Guest', + source: 'emails', + icon: 'icon-user', + }, + }, + }, + }) + const input = 'hello @jdoe @"guest/47e0a7cf"! how are you?' + const output = editor.vm.renderContent(input) + + expect(output).toMatch(/^hello ! how are you\?$/) }) it('keep mentions with special characters', () => { From f62f92161fd242d9de2b1dc4b513976645cba7aa Mon Sep 17 00:00:00 2001 From: Maksim Sukharev Date: Tue, 19 Nov 2024 17:09:42 +0100 Subject: [PATCH 2/2] fix(test): ensure parsed content after rendering matches the original - sanitized strings are skipped Signed-off-by: Maksim Sukharev --- tests/unit/mixins/richEditor.spec.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/unit/mixins/richEditor.spec.js b/tests/unit/mixins/richEditor.spec.js index 327cb6554a..c17fc78895 100644 --- a/tests/unit/mixins/richEditor.spec.js +++ b/tests/unit/mixins/richEditor.spec.js @@ -29,6 +29,9 @@ describe('richEditor.js', () => { const output = editor.vm.renderContent(input) expect(output).toEqual('hard
break') + + const parsedOutput = editor.vm.parseContent(output) + expect(parsedOutput).toEqual(input) }) it('no duplicated ampersand (from Linkify)', () => { @@ -37,6 +40,9 @@ describe('richEditor.js', () => { const output = editor.vm.renderContent(input) expect(output).toEqual('hello &') + + const parsedOutput = editor.vm.parseContent(output) + expect(parsedOutput).toEqual(input) }) it('keeps mentions without user data', () => { @@ -45,6 +51,9 @@ describe('richEditor.js', () => { const output = editor.vm.renderContent(input) expect(output).toEqual('hello @foobar') + + const parsedOutput = editor.vm.parseContent(output) + expect(parsedOutput).toEqual(input) }) it('keeps mentions with user data', () => { @@ -66,6 +75,9 @@ describe('richEditor.js', () => { expect(output).toMatch(/^hello !
how are you\?$/) expect(output).not.toMatch(/[\n\t]/gmi) expect(output).not.toMatch(/>\s+ { @@ -91,6 +103,9 @@ describe('richEditor.js', () => { const output = editor.vm.renderContent(input) expect(output).toMatch(/^hello ! how are you\?$/) + + const parsedOutput = editor.vm.parseContent(output) + expect(parsedOutput).toEqual(input) }) it('keep mentions with special characters', () => { @@ -119,6 +134,9 @@ describe('richEditor.js', () => { for (const i in inputs) { const output = editor.vm.renderContent(inputs[i]) expect(output).toEqual(outputs[i]) + + const parsedOutput = editor.vm.parseContent(output) + expect(parsedOutput).toEqual(inputs[i]) } }) })