Skip to content

Commit

Permalink
Fix pasting HTML with newlines
Browse files Browse the repository at this point in the history
At the moment, if you paste the following HTML, the newline between the
`<span>` elements is incorrectly discarded.

```html
<span>foo</span>
<span>bar</span>
```

This will currently insert `foobar` into Quill, when we'd expect
`foo bar`, since newlines should [treated as spaces][1] between inline
elements (such as `<span>`).

This change updates the `matchText()` clipboard matcher to check if the
text node is between inline elements or not before early-returning.

[1]: https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace
  • Loading branch information
alecgibson committed Jun 2, 2023
1 parent b3d1532 commit 3289aee
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
15 changes: 14 additions & 1 deletion modules/clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,15 @@ function isLine(node: Element) {
].includes(node.tagName.toLowerCase());
}

function isBetweenInlineElements(node) {
return (
node.previousSibling &&
node.nextSibling &&
!isLine(node.previousSibling) &&
!isLine(node.nextSibling)
);
}

const preNodes = new WeakMap();
function isPre(node: Node) {
if (node == null) return false;
Expand Down Expand Up @@ -562,7 +571,11 @@ function matchText(node, delta) {
return delta.insert(text.trim());
}
if (!isPre(node)) {
if (text.trim().length === 0 && text.includes('\n')) {
if (
text.trim().length === 0 &&
text.includes('\n') &&
!isBetweenInlineElements(node)
) {
return delta;
}
const replacer = (collapse, match) => {
Expand Down
24 changes: 24 additions & 0 deletions test/unit/modules/clipboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,30 @@ describe('Clipboard', function () {
);
});

it('newlines between inline elements', function () {
const html = '<span>foo</span>\n<span>bar</span>';
const delta = this.clipboard.convert({ html });
expect(delta).toEqual(new Delta().insert('foo bar'));
});

it('multiple newlines between inline elements', function () {
const html = '<span>foo</span>\n\n\n\n<span>bar</span>';
const delta = this.clipboard.convert({ html });
expect(delta).toEqual(new Delta().insert('foo bar'));
});

it('newlines between block elements', function () {
const html = '<p>foo</p>\n<p>bar</p>';
const delta = this.clipboard.convert({ html });
expect(delta).toEqual(new Delta().insert('foo\nbar'));
});

it('multiple newlines between block elements', function () {
const html = '<p>foo</p>\n\n\n\n<p>bar</p>';
const delta = this.clipboard.convert({ html });
expect(delta).toEqual(new Delta().insert('foo\nbar'));
});

it('break', function () {
const html =
'<div>0<br>1</div><div>2<br></div><div>3</div><div><br>4</div><div><br></div><div>5</div>';
Expand Down

0 comments on commit 3289aee

Please sign in to comment.