Skip to content

Commit

Permalink
馃悰 Fix inserting newlines into formatted text
Browse files Browse the repository at this point in the history
Consider a document with a single piece of bold text. As a `Delta`, this
would be represented as:

```js
const doc = new Delta().insert('a', {bold: true})
```

Now consider the following `Delta` being applied:

```js
const delta = new Delta().insert('\n1')
```

The above `Delta` will:

  - prepend the document with a newline
  - follow that newline with an **unformatted** string

Indeed, using `doc.compose(delta)` yields:

```js
const result = new Delta()
  .insert('\n1')
  .insert('a', {bold: true})
```

However, the same result is not reached when using the Quill
`editor.applyDelta()`, which instead results in bold formatting being
incorrectly applied to our unformatted string:

```js
const badResult = new Delta()
  .insert('\n')
  .insert('1a', {bold: true})
```

This happens because Quill does an insert of the whole insertion, but
doesn't handle the line splitting.

This change fixes this issue by splitting ops on newlines, and handling
them separately, which applies the correct formatting.
  • Loading branch information
alecgibson authored and luin committed Jun 15, 2023
1 parent c8dec17 commit 792052b
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
20 changes: 19 additions & 1 deletion core/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ class Editor {
this.scroll.batchStart();
const normalizedDelta = normalizeDelta(delta);
const deleteDelta = new Delta();
normalizedDelta.reduce((index, op) => {
const normalizedOps = splitOpLines(normalizedDelta.ops.slice());
normalizedOps.reduce((index, op) => {
const length = Op.length(op);
let attributes = op.attributes || {};

Check failure on line 38 in core/editor.ts

View workflow job for this annotation

GitHub Actions / unit / test (mac-safari-latest)

Property 'attributes' does not exist on type 'never'.

Check failure on line 38 in core/editor.ts

View workflow job for this annotation

GitHub Actions / unit / test (windows-chrome-latest)

Property 'attributes' does not exist on type 'never'.

Check failure on line 38 in core/editor.ts

View workflow job for this annotation

GitHub Actions / unit / test (windows-edge-latest)

Property 'attributes' does not exist on type 'never'.

Check failure on line 38 in core/editor.ts

View workflow job for this annotation

GitHub Actions / unit / test (ios-latest)

Property 'attributes' does not exist on type 'never'.

Check failure on line 38 in core/editor.ts

View workflow job for this annotation

GitHub Actions / unit / test (mac-chrome-latest)

Property 'attributes' does not exist on type 'never'.

Check failure on line 38 in core/editor.ts

View workflow job for this annotation

GitHub Actions / unit / test (windows-firefox-latest)

Property 'attributes' does not exist on type 'never'.

Check failure on line 38 in core/editor.ts

View workflow job for this annotation

GitHub Actions / unit / test (mac-firefox-latest)

Property 'attributes' does not exist on type 'never'.

Check failure on line 38 in core/editor.ts

View workflow job for this annotation

GitHub Actions / e2e / test

Property 'attributes' does not exist on type 'never'.
let isImplicitNewlinePrepended = false;
Expand Down Expand Up @@ -428,4 +429,21 @@ function shiftRange({ index, length }: Range, amount: number) {
return new Range(index + amount, length);
}

function splitOpLines(ops) {
const split = [];
ops.forEach(op => {
if (typeof op.insert === 'string') {
const lines = op.insert.split('\n');
lines.forEach((line, index) => {
if (index) split.push({ insert: '\n', attributes: op.attributes });
if (line) split.push({ insert: line, attributes: op.attributes });
});
} else {
split.push(op);
}
});

return split;
}

export default Editor;
8 changes: 8 additions & 0 deletions test/unit/core/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,14 @@ describe('Editor', function () {
editor.applyDelta(new Delta().delete(4).retain(1).delete(2));
expect(editor.scroll.domNode.innerHTML).toEqual('<p>2</p>');
});

it('prepending bold with a newline and unformatted text', function () {
const editor = this.initialize(Editor, '<p><strong>a</strong></p>');
editor.applyDelta(new Delta().insert('\n1'));
expect(this.container).toEqualHTML(
'<p><br></p><p>1<strong>a</strong></p>',
);
});
});

describe('getFormat()', function () {
Expand Down

0 comments on commit 792052b

Please sign in to comment.