Skip to content

Commit

Permalink
fix(extension-list): fix a bug that causes incorrect indent when chan…
Browse files Browse the repository at this point in the history
…ging list type (remirror#1296)
  • Loading branch information
ocavue authored Oct 8, 2021
1 parent 748e057 commit b9422f9
Show file tree
Hide file tree
Showing 17 changed files with 682 additions and 376 deletions.
5 changes: 5 additions & 0 deletions .changeset/lemon-bottles-perform.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@remirror/extension-list': patch
---

Fix a bug that causes incorrect indent when changing list type.
3 changes: 3 additions & 0 deletions docs/extensions/list-extension.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ title: 'ListExtension'

import Basic from '../../website/extension-examples/extension-list/basic';
import Collapsible from '../../website/extension-examples/extension-list/collapsible';
import Toggleable from '../../website/extension-examples/extension-list/toggleable';

# `ListExtension`

Expand Down Expand Up @@ -34,6 +35,8 @@ The extension is provided by the `@remirror/extension-list` package. There are t

<Collapsible />

<Toggleable />

## API

- [ListExtension](../api/extension-list)
155 changes: 122 additions & 33 deletions packages/remirror__extension-list/__tests__/list-commands.spec.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,10 @@
import { renderEditor } from 'jest-remirror';
import {
BulletListExtension,
ListItemExtension,
OrderedListExtension,
TaskListExtension,
toggleList,
} from 'remirror/extensions';
import { toggleList } from 'remirror/extensions';

import { calculateItemRange } from '../src/list-commands';
import { setupListEditor } from './list-setup';

describe('toggleList', () => {
const editor = renderEditor([
new ListItemExtension(),
new BulletListExtension(),
new OrderedListExtension(),
new TaskListExtension(),
]);
const {
nodes: { doc, paragraph: p, taskList, bulletList: ul, listItem: li, orderedList: ol },
attributeNodes: { taskListItem },
} = editor;

const checked = taskListItem({ checked: true });
const unchecked = taskListItem({ checked: false });
const { editor, doc, p, ul, ol, li, taskList, checked, unchecked } = setupListEditor();

it('toggles paragraph to bullet list', () => {
const from = doc(p('make <cursor>list'));
Expand Down Expand Up @@ -355,18 +339,7 @@ describe('toggleList', () => {
});

describe('toggleCheckboxChecked', () => {
const editor = renderEditor([
new ListItemExtension(),
new BulletListExtension(),
new OrderedListExtension(),
new TaskListExtension(),
]);
const {
nodes: { doc, paragraph: p, taskList },
attributeNodes: { taskListItem },
} = editor;
const checked = taskListItem({ checked: true });
const unchecked = taskListItem({ checked: false });
const { editor, doc, p, taskList, checked, unchecked } = setupListEditor();

it('toggles checkbox checked when the cursor is at the end of a task list item', () => {
const from = doc(
Expand Down Expand Up @@ -476,3 +449,119 @@ describe('toggleCheckboxChecked', () => {
expect(editor.view.state.doc).toEqualProsemirrorNode(uncheckedDoc);
});
});

describe('calculateItemRange', () => {
const { editor, doc, p, ul, ol, li, taskList, checked, unchecked } = setupListEditor();

it('returns correct range when the selection is empty', () => {
editor.add(
doc(
ul(
li(p('A<cursor>')), //
li(p('B')), //
li(p('C')), //
),
),
);
const range = calculateItemRange(editor.state.selection)!;
expect(range.depth).toEqual(1);
expect(range.parent.type.name).toEqual('bulletList');
expect(range.startIndex).toEqual(0);
expect(range.endIndex).toEqual(1);
expect(editor.doc.resolve(range.start).node().type.name).toEqual('bulletList');
expect(editor.doc.resolve(range.end).node().type.name).toEqual('bulletList');
});

it('returns correct range when the selection is not empty', () => {
editor.add(
doc(
taskList(
unchecked(p('A')), //
checked(p('B<start>')), //
checked(p('C<end>')), //
),
),
);
const range = calculateItemRange(editor.state.selection)!;
expect(range.depth).toEqual(1);
expect(range.parent.type.name).toEqual('taskList');
expect(range.startIndex).toEqual(1);
expect(range.endIndex).toEqual(3);
expect(editor.doc.resolve(range.start).node().type.name).toEqual('taskList');
expect(editor.doc.resolve(range.end).node().type.name).toEqual('taskList');
});

it('returns correct range when the selection is in a deep list', () => {
editor.add(
doc(
ul(
li(p('A')),
li(
p('B'),
ol(
li(p('a')), //
li(p('<start>b')),
li(p('c')),
li(p('d<end>')),
),
),
li(p('C')),
),
),
);
const range = calculateItemRange(editor.state.selection)!;
expect(range.depth).toEqual(3);
expect(range.parent.type.name).toEqual('orderedList');
expect(range.startIndex).toEqual(1);
expect(range.endIndex).toEqual(4);
expect(editor.doc.resolve(range.start).node().type.name).toEqual('orderedList');
expect(editor.doc.resolve(range.end).node().type.name).toEqual('orderedList');

const slice = editor.doc.slice(range.start, range.end);
expect(slice.openStart).toEqual(0);
expect(slice.openEnd).toEqual(0);
expect(slice.content.childCount).toEqual(3);
});

it('returns correct range when the selection across different levels', () => {
editor.add(
doc(
ul(
li(p('A')),
li(
p('B<start>'),
ol(
li(p('a')), //
li(p('b')),
li(p('c')),
li(p('d<end>')),
),
),
li(p('C')),
),
),
);
const range = calculateItemRange(editor.state.selection)!;
expect(range.depth).toEqual(1);
expect(range.parent.type.name).toEqual('bulletList');
expect(range.startIndex).toEqual(1);
expect(range.endIndex).toEqual(2);
expect(editor.doc.resolve(range.start).node().type.name).toEqual('bulletList');
expect(editor.doc.resolve(range.end).node().type.name).toEqual('bulletList');
});

it('returns nothing when the selection is not in a list', () => {
editor.add(
doc(
ul(
li(p('A')), //
li(p('B')), //
li(p('C')), //
),
p('<cursor>'),
),
);
const range = calculateItemRange(editor.state.selection);
expect(range).toBeUndefined();
});
});
Loading

0 comments on commit b9422f9

Please sign in to comment.