From 903719192366b0545b318c05651444e287c9818f Mon Sep 17 00:00:00 2001 From: "Julia Roldi (from Dev Box)" Date: Tue, 21 Jan 2025 19:45:42 -0300 Subject: [PATCH 1/2] fixes --- .../lib/edit/inputSteps/handleEnterOnList.ts | 23 +- .../edit/inputSteps/handleEnterOnListTest.ts | 894 ++++++++++++++++++ 2 files changed, 903 insertions(+), 14 deletions(-) diff --git a/packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnList.ts b/packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnList.ts index 2cae41ef692..00660bbc1c3 100644 --- a/packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnList.ts +++ b/packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnList.ts @@ -67,14 +67,14 @@ export const handleEnterOnList: DeleteSelectionStep = context => { }); if (listItem.levels.length == 0) { - const index = findIndex( + const nextBlockIndex = findIndex( listParent.blocks, - nextBlock.levels.length, - listIndex + nextBlock.levels.length ); + nextBlock.levels[ nextBlock.levels.length - 1 - ].format.startNumberOverride = index; + ].format.startNumberOverride = nextBlockIndex; } } } @@ -148,24 +148,19 @@ const createNewListLevel = (listItem: ReadonlyContentModelListItem) => { }); }; -const findIndex = ( - blocks: readonly ReadonlyContentModelBlock[], - levelLength: number, - index: number -) => { +const findIndex = (blocks: readonly ReadonlyContentModelBlock[], levelLength: number) => { let counter = 1; - for (let i = index; i > -1; i--) { + for (let i = 0; i > -1; i++) { const listItem = blocks[i]; + if ( isBlockGroupOfType(listItem, 'ListItem') && listItem.levels.length === levelLength ) { counter++; } else if ( - !( - isBlockGroupOfType(listItem, 'ListItem') && - listItem.levels.length == 0 - ) + isBlockGroupOfType(listItem, 'ListItem') && + listItem.levels.length == 0 ) { return counter; } diff --git a/packages/roosterjs-content-model-plugins/test/edit/inputSteps/handleEnterOnListTest.ts b/packages/roosterjs-content-model-plugins/test/edit/inputSteps/handleEnterOnListTest.ts index 75d7b96a537..2a3b4c9bda1 100644 --- a/packages/roosterjs-content-model-plugins/test/edit/inputSteps/handleEnterOnListTest.ts +++ b/packages/roosterjs-content-model-plugins/test/edit/inputSteps/handleEnterOnListTest.ts @@ -3198,4 +3198,898 @@ describe('handleEnterOnList - keyboardEnter', () => { }; runTest(model, false, expectedModel, false, 1); }); + + it('Should maintain list chain when split the list ', () => { + const model: ContentModelDocument = { + blockGroupType: 'Document', + blocks: [ + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + startNumberOverride: 1, + listStyleType: 'decimal', + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'one', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + listStyleType: 'decimal', + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'two', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + listStyleType: 'decimal', + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + isSelected: true, + segmentType: 'SelectionMarker', + format: {}, + }, + { + segmentType: 'Br', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + listStyleType: 'decimal', + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'three', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + listStyleType: 'decimal', + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'four', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + ], + format: {}, + }; + const expectedModel: ContentModelDocument = { + blockGroupType: 'Document', + blocks: [ + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + startNumberOverride: 1, + listStyleType: 'decimal', + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'one', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + listStyleType: 'decimal', + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'two', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + { + segments: [ + { + isSelected: true, + segmentType: 'SelectionMarker', + format: {}, + }, + { + segmentType: 'Br', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + listStyleType: 'decimal', + startNumberOverride: 3, + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'three', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + listStyleType: 'decimal', + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'four', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + ], + format: {}, + }; + runTest(model, false, expectedModel, false, 1); + }); + + it('Should maintain list chain when split the list two times', () => { + const model: ContentModelDocument = { + blockGroupType: 'Document', + blocks: [ + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + startNumberOverride: 1, + listStyleType: 'decimal', + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'one', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + listStyleType: 'decimal', + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'two', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + { + segments: [ + { + segmentType: 'Br', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + listStyleType: 'decimal', + startNumberOverride: 3, + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'three', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + listStyleType: 'decimal', + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'four', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + listStyleType: 'decimal', + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'five', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + listStyleType: 'decimal', + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + isSelected: true, + segmentType: 'SelectionMarker', + format: {}, + }, + { + segmentType: 'Br', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + listStyleType: 'decimal', + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'six', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + ], + format: {}, + }; + const expectedModel: ContentModelDocument = { + blockGroupType: 'Document', + blocks: [ + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + startNumberOverride: 1, + listStyleType: 'decimal', + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'one', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + listStyleType: 'decimal', + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'two', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + { + segments: [ + { + segmentType: 'Br', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + listStyleType: 'decimal', + startNumberOverride: 3, + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'three', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + listStyleType: 'decimal', + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'four', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + listStyleType: 'decimal', + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'five', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + { + segments: [ + { + isSelected: true, + segmentType: 'SelectionMarker', + format: {}, + }, + { + segmentType: 'Br', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + { + formatHolder: { + isSelected: false, + segmentType: 'SelectionMarker', + format: {}, + }, + levels: [ + { + listType: 'OL', + format: { + listStyleType: 'decimal', + startNumberOverride: 6, + }, + dataset: { + editingInfo: + '{"applyListStyleFromLevel":false,"orderedStyleType":1}', + }, + }, + ], + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + segments: [ + { + text: 'six', + segmentType: 'Text', + format: {}, + }, + ], + segmentFormat: {}, + blockType: 'Paragraph', + format: {}, + }, + ], + }, + ], + format: {}, + }; + runTest(model, false, expectedModel, false, 1); + }); }); From 5d5981af2c42f66bc62bd932064555b4a39cfdbd Mon Sep 17 00:00:00 2001 From: "Julia Roldi (from Dev Box)" Date: Wed, 22 Jan 2025 12:36:44 -0300 Subject: [PATCH 2/2] fix --- .../lib/edit/inputSteps/handleEnterOnList.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnList.ts b/packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnList.ts index 00660bbc1c3..d50d91b0616 100644 --- a/packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnList.ts +++ b/packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnList.ts @@ -150,7 +150,7 @@ const createNewListLevel = (listItem: ReadonlyContentModelListItem) => { const findIndex = (blocks: readonly ReadonlyContentModelBlock[], levelLength: number) => { let counter = 1; - for (let i = 0; i > -1; i++) { + for (let i = 0; i < blocks.length; i++) { const listItem = blocks[i]; if (