Skip to content

Commit

Permalink
Convert newlines between inline elements to a space
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 authored and luin committed Jan 31, 2024
1 parent 7aa6189 commit f777637
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# [Unreleased]

- **Clipboard** Convert newlines between inline elements to a space.

# 2.0.0-beta.2

- Fix IME not working correctly in Safari.
Expand Down
15 changes: 14 additions & 1 deletion packages/quill/src/modules/clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,15 @@ function isLine(node: Element) {
].includes(node.tagName.toLowerCase());
}

function isBetweenInlineElements(node: HTMLElement) {
return (
node.previousElementSibling &&
node.nextElementSibling &&
!isLine(node.previousElementSibling) &&
!isLine(node.nextElementSibling)
);
}

const preNodes = new WeakMap();
function isPre(node: Node | null) {
if (node == null) return false;
Expand Down Expand Up @@ -573,7 +582,11 @@ function matchText(node: HTMLElement, delta: 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: unknown, match: string) => {
Expand Down
24 changes: 24 additions & 0 deletions packages/quill/test/unit/modules/clipboard.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,30 @@ describe('Clipboard', () => {
);
});

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

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

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

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

test('break', () => {
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 f777637

Please sign in to comment.