Skip to content

Commit

Permalink
Ignore whitespace between pasted empty paragraphs
Browse files Browse the repository at this point in the history
At the moment, when pasting HTML containing empty paragraphs with
whitespace between them, the whitespace is incorrectly rendered.

For example:

```html
<p></p> <p></p>
```

will result in a Delta containing `' \n'`

This happens because the clipboard's `isLine()` function assumes that
any element without children is an embed (which isn't true for things
like empty paragraphs).

This change updates the `isLine()` check to check the node against the
registry, and see if we have a matching `EmbedBlot` there.
  • Loading branch information
alecgibson committed Jun 2, 2023
1 parent b3d1532 commit 9414493
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 9 deletions.
20 changes: 11 additions & 9 deletions modules/clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,10 @@ function deltaEndsWith(delta: Delta, text: string) {
return endText.slice(-1 * text.length) === text;
}

function isLine(node: Element) {
if (node.childNodes.length === 0) return false; // Exclude embed blocks
function isLine(node: Element, scroll: ScrollBlot) {
if (node.nodeType !== Node.ELEMENT_NODE) return false;
const match: any = scroll.query(node);
if (match && match.prototype instanceof EmbedBlot) return false;
return [
'address',
'article',
Expand Down Expand Up @@ -494,14 +496,14 @@ function matchList(node: Node, delta: Delta) {
function matchNewline(node: Node, delta: Delta, scroll: ScrollBlot) {
if (!deltaEndsWith(delta, '\n')) {
// @ts-expect-error
if (isLine(node)) {
if (isLine(node, scroll)) {
return delta.insert('\n');
}
if (delta.length() > 0 && node.nextSibling) {
let { nextSibling } = node;
while (nextSibling != null) {
// @ts-expect-error
if (isLine(nextSibling)) {
if (isLine(nextSibling, scroll)) {
return delta.insert('\n');
}
const match = scroll.query(nextSibling);
Expand Down Expand Up @@ -555,7 +557,7 @@ function matchTable(node, delta) {
return applyFormat(delta, 'table', row);
}

function matchText(node, delta) {
function matchText(node, delta, scroll) {
let text = node.data;
// Word represents empty line with <o:p>&nbsp;</o:p>
if (node.parentNode.tagName === 'O:P') {
Expand All @@ -572,14 +574,14 @@ function matchText(node, delta) {
text = text.replace(/\r\n/g, ' ').replace(/\n/g, ' ');
text = text.replace(/\s\s+/g, replacer.bind(replacer, true)); // collapse whitespace
if (
(node.previousSibling == null && isLine(node.parentNode)) ||
(node.previousSibling != null && isLine(node.previousSibling))
(node.previousSibling == null && isLine(node.parentNode, scroll)) ||
(node.previousSibling != null && isLine(node.previousSibling, scroll))
) {
text = text.replace(/^\s+/, replacer.bind(replacer, false));
}
if (
(node.nextSibling == null && isLine(node.parentNode)) ||
(node.nextSibling != null && isLine(node.nextSibling))
(node.nextSibling == null && isLine(node.parentNode, scroll)) ||
(node.nextSibling != null && isLine(node.nextSibling, scroll))
) {
text = text.replace(/\s+$/, replacer.bind(replacer, false));
}
Expand Down
12 changes: 12 additions & 0 deletions test/unit/modules/clipboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,18 @@ describe('Clipboard', function () {
);
});

it('space between empty paragraphs', function () {
const html = '<p></p> <p></p>';
const delta = this.clipboard.convert({ html });
expect(delta).toEqual(new Delta().insert('\n'));
});

it('newline between empty paragraphs', function () {
const html = '<p></p>\n<p></p>';
const delta = this.clipboard.convert({ html });
expect(delta).toEqual(new Delta().insert('\n'));
});

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 9414493

Please sign in to comment.