From a93a952b1a16d71ecf661d3b3400cdc4dfa9f151 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 (cherry picked from commit 1a831ef31e6d60af258ea5ba66f76913eacdb5e2) 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 a623acca31..4381e84684 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 a7249a12d8..106787e623 100644 --- a/tests/unit/mixins/richEditor.spec.js +++ b/tests/unit/mixins/richEditor.spec.js @@ -63,10 +63,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, { + props: { + 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 74be2f3083d095be24a0390a9799cb02b8902dda 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 (cherry picked from commit f62f92161fd242d9de2b1dc4b513976645cba7aa) 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 106787e623..a60def1873 100644 --- a/tests/unit/mixins/richEditor.spec.js +++ b/tests/unit/mixins/richEditor.spec.js @@ -32,6 +32,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)', () => { @@ -40,6 +43,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', () => { @@ -48,6 +54,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', () => { @@ -69,6 +78,9 @@ describe('richEditor.js', () => { expect(output).toMatch(/^hello !
how are you\?$/) expect(output).not.toMatch(/[\n\t]/gmi) expect(output).not.toMatch(/>\s+ { @@ -94,6 +106,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', () => { @@ -122,6 +137,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]) } }) })