diff --git a/packages/quill/src/core/editor.ts b/packages/quill/src/core/editor.ts
index a19485840d..b6391a7cd4 100644
--- a/packages/quill/src/core/editor.ts
+++ b/packages/quill/src/core/editor.ts
@@ -370,7 +370,8 @@ function convertHTML(
return blot.html(index, length);
}
if (blot instanceof TextBlot) {
- return escapeText(blot.value().slice(index, index + length));
+ const escapedText = escapeText(blot.value().slice(index, index + length));
+ return escapedText.replaceAll(' ', ' ');
}
if (blot instanceof ParentBlot) {
// TODO fix API
diff --git a/packages/quill/src/modules/clipboard.ts b/packages/quill/src/modules/clipboard.ts
index e4c3f755b5..ea3df80403 100644
--- a/packages/quill/src/modules/clipboard.ts
+++ b/packages/quill/src/modules/clipboard.ts
@@ -624,9 +624,12 @@ function matchTable(
return delta;
}
+const NBSP = '\u00a0';
+const SPACE_EXCLUDE_NBSP = `[^\\S${NBSP}]`;
+
function matchText(node: HTMLElement, delta: Delta, scroll: ScrollBlot) {
// @ts-expect-error
- let text = node.data;
+ let text = node.data as string;
// Word represents empty line with
123 123 123
').getHTML( + 0, + 11, + ), + ).toEqual('123 123 123'); + + expect(createEditor(new Delta().insert('1 2\n')).getHTML(0, 5)).toEqual( + '1 2', + ); + + expect( + createEditor( + new Delta().insert(' 123', { bold: true }).insert('\n'), + ).getHTML(0, 5), + ).toEqual(' 123'); + }); + test('mixed list', () => { const editor = createEditor( ` diff --git a/packages/quill/test/unit/modules/clipboard.spec.ts b/packages/quill/test/unit/modules/clipboard.spec.ts index 0ba7c159ed..69142690a2 100644 --- a/packages/quill/test/unit/modules/clipboard.spec.ts +++ b/packages/quill/test/unit/modules/clipboard.spec.ts @@ -244,6 +244,12 @@ describe('Clipboard', () => { expect(delta).toEqual(new Delta().insert('0\n1 2 3 4\n5 6 7 8')); }); + test('multiple whitespaces', () => { + const html = '0 1 2
'; const delta = createClipboard().convert({ html }); @@ -256,19 +262,23 @@ describe('Clipboard', () => { const html = '0 1 2'; const delta = createClipboard().convert({ html }); expect(delta).toEqual( - new Delta() - .insert('0\u00a0') - .insert('1', { bold: true }) - .insert('\u00a02'), + new Delta().insert('0 ').insert('1', { bold: true }).insert(' 2'), ); }); test('consecutive intentional whitespace', () => { const html = ' 1 '; const delta = createClipboard().convert({ html }); - expect(delta).toEqual( - new Delta().insert('\u00a0\u00a01\u00a0\u00a0', { bold: true }), - ); + expect(delta).toEqual(new Delta().insert(' 1 ', { bold: true })); + }); + + test('intentional whitespace at line start/end', () => { + expect( + createClipboard().convert({ html: '0
2
' }), + ).toEqual(new Delta().insert('0 \n 2')); + expect( + createClipboard().convert({ html: '0
2
' }), + ).toEqual(new Delta().insert('0 \n 2')); }); test('newlines between inline elements', () => { diff --git a/packages/quill/tsconfig.json b/packages/quill/tsconfig.json index ad105b7c1e..062af2c011 100644 --- a/packages/quill/tsconfig.json +++ b/packages/quill/tsconfig.json @@ -7,7 +7,7 @@ "compilerOptions": { "outDir": "./dist", "allowSyntheticDefaultImports": true, - "target": "ES2020", + "target": "ES2021", "sourceMap": true, "resolveJsonModule": true, "declaration": false, diff --git a/tsconfig.json b/tsconfig.json index 87860003ec..146b141a1f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,7 +7,7 @@ }, "compilerOptions": { "allowSyntheticDefaultImports": true, - "target": "ES2020", + "target": "ES2021", "sourceMap": true, "declaration": true, "module": "ES2020",