From bf721e6e307a8efd6351f32be79f0ed3fb3e427f Mon Sep 17 00:00:00 2001
From: luin
Date: Wed, 3 Feb 2021 00:54:23 +0800
Subject: [PATCH] Cut across lines shouldn't affect the formatting of the line
above
To test:
1. Open http://localhost:9000/standalone/full/
2. Create two lines:
```
Hea|der
Normal |paragraph
```
3. Cut text between two |.
Expected:
The first line is a header.
Actually:
The first line is a normal paragraph.
---
modules/clipboard.js | 3 ++-
modules/keyboard.js | 30 +++++++++++++++++-------------
test/unit/modules/clipboard.js | 27 +++++++++++++++++++++++++++
3 files changed, 46 insertions(+), 14 deletions(-)
diff --git a/modules/clipboard.js b/modules/clipboard.js
index f8d409fe62..6045fa31c5 100644
--- a/modules/clipboard.js
+++ b/modules/clipboard.js
@@ -19,6 +19,7 @@ import { ColorStyle } from '../formats/color';
import { DirectionAttribute, DirectionStyle } from '../formats/direction';
import { FontStyle } from '../formats/font';
import { SizeStyle } from '../formats/size';
+import { deleteRange } from './keyboard';
const debug = logger('quill:clipboard');
@@ -135,7 +136,7 @@ class Clipboard extends Module {
e.clipboardData.setData('text/plain', text);
e.clipboardData.setData('text/html', html);
if (isCut) {
- this.quill.deleteText(range, Quill.sources.USER);
+ deleteRange({ range, quill: this.quill });
}
}
diff --git a/modules/keyboard.js b/modules/keyboard.js
index 1a4bd004ee..d3d4d6e55e 100644
--- a/modules/keyboard.js
+++ b/modules/keyboard.js
@@ -244,18 +244,7 @@ class Keyboard extends Module {
}
handleDeleteRange(range) {
- const lines = this.quill.getLines(range);
- let formats = {};
- if (lines.length > 1) {
- const firstFormats = lines[0].formats();
- const lastFormats = lines[lines.length - 1].formats();
- formats = AttributeMap.diff(lastFormats, firstFormats) || {};
- }
- this.quill.deleteText(range, Quill.sources.USER);
- if (Object.keys(formats).length > 0) {
- this.quill.formatLine(range.index, 1, formats, Quill.sources.USER);
- }
- this.quill.setSelection(range.index, Quill.sources.SILENT);
+ deleteRange({ range, quill: this.quill });
this.quill.focus();
}
@@ -709,6 +698,21 @@ function normalize(binding) {
return binding;
}
+function deleteRange({ quill, range }) {
+ const lines = quill.getLines(range);
+ let formats = {};
+ if (lines.length > 1) {
+ const firstFormats = lines[0].formats();
+ const lastFormats = lines[lines.length - 1].formats();
+ formats = AttributeMap.diff(lastFormats, firstFormats) || {};
+ }
+ quill.deleteText(range, Quill.sources.USER);
+ if (Object.keys(formats).length > 0) {
+ quill.formatLine(range.index, 1, formats, Quill.sources.USER);
+ }
+ quill.setSelection(range.index, Quill.sources.SILENT);
+}
+
function tableSide(table, row, cell, offset) {
if (row.prev == null && row.next == null) {
if (cell.prev == null && cell.next == null) {
@@ -725,4 +729,4 @@ function tableSide(table, row, cell, offset) {
return null;
}
-export { Keyboard as default, SHORTKEY, normalize };
+export { Keyboard as default, SHORTKEY, normalize, deleteRange };
diff --git a/test/unit/modules/clipboard.js b/test/unit/modules/clipboard.js
index d542fc9fcd..b7b804c605 100644
--- a/test/unit/modules/clipboard.js
+++ b/test/unit/modules/clipboard.js
@@ -58,6 +58,33 @@ describe('Clipboard', function() {
});
});
+ describe('cut', () => {
+ beforeEach(function() {
+ this.clipboardData = {};
+ this.clipboardEvent = {
+ clipboardData: {
+ setData: (type, data) => {
+ this.clipboardData[type] = data;
+ },
+ },
+ preventDefault: () => {},
+ };
+ });
+
+ it('keeps formats of first line', function(done) {
+ this.quill.clipboard.onCaptureCopy(this.clipboardEvent, true);
+ setTimeout(() => {
+ expect(this.quill.root).toEqualHTML('0178
');
+ expect(this.quill.getSelection()).toEqual(new Range(2));
+ expect(this.clipboardData['text/plain']).toEqual('23\n56');
+ expect(this.clipboardData['text/html']).toEqual(
+ '23
56
', + ); + done(); + }, 2); + }); + }); + it('dangerouslyPasteHTML(html)', function() { this.quill.clipboard.dangerouslyPasteHTML('abcd'); expect(this.quill.root).toEqualHTML(