Skip to content

Commit

Permalink
Fix #2699 (#2797)
Browse files Browse the repository at this point in the history
Co-authored-by: Julia Roldi <[email protected]>
  • Loading branch information
JiuqingSong and juliaroldi authored Sep 23, 2024
1 parent 63747b9 commit f2ffdab
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ export function clearModelFormat(
blocksToClear: [ReadonlyContentModelBlockGroup[], ShallowMutableContentModelBlock][],
segmentsToClear: ShallowMutableContentModelSegment[],
tablesToClear: [ContentModelTable, boolean][]
) {
): boolean {
let pendingStructureChange = false;

iterateSelections(
model,
(path, tableContext, block, segments) => {
Expand Down Expand Up @@ -75,14 +77,14 @@ export function clearModelFormat(
blocksToClear.length == 1
) {
segmentsToClear.splice(0, segmentsToClear.length, ...adjustWordSelection(model, marker));
clearListFormat(blocksToClear[0][0]);
pendingStructureChange = clearListFormat(blocksToClear[0][0]) || pendingStructureChange;
} else if (blocksToClear.length > 1 || blocksToClear.some(x => isWholeBlockSelected(x[1]))) {
// 2. If a full block or multiple blocks are selected, clear block format
for (let i = blocksToClear.length - 1; i >= 0; i--) {
const [path, block] = blocksToClear[i];

clearBlockFormat(path, block);
clearListFormat(path);
pendingStructureChange = clearListFormat(path) || pendingStructureChange;
clearContainerFormat(path, block);
}
}
Expand All @@ -92,6 +94,8 @@ export function clearModelFormat(

// 4. Clear format for table if any
createTablesFormat(tablesToClear);

return pendingStructureChange;
}

function createTablesFormat(tablesToClear: [ContentModelTable, boolean][]) {
Expand Down Expand Up @@ -191,6 +195,10 @@ function clearListFormat(path: ReadonlyContentModelBlockGroup[]) {

if (listItem) {
mutateBlock(listItem).levels = [];

return true;
} else {
return false;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import type {
ContentModelTable,
} from 'roosterjs-content-model-types';

const MAX_TRY = 3;

/**
* Clear format of selection
* @param editor The editor to clear format from
Expand All @@ -17,17 +19,27 @@ export function clearFormat(editor: IEditor) {

editor.formatContentModel(
model => {
const blocksToClear: [ContentModelBlockGroup[], ContentModelBlock][] = [];
const segmentsToClear: ContentModelSegment[] = [];
const tablesToClear: [ContentModelTable, boolean][] = [];
let changed = false;
let needtoRun = true;
let triedTimes = 0;

while (needtoRun && triedTimes++ < MAX_TRY) {
const blocksToClear: [ContentModelBlockGroup[], ContentModelBlock][] = [];
const segmentsToClear: ContentModelSegment[] = [];
const tablesToClear: [ContentModelTable, boolean][] = [];

needtoRun = clearModelFormat(model, blocksToClear, segmentsToClear, tablesToClear);

clearModelFormat(model, blocksToClear, segmentsToClear, tablesToClear);
normalizeContentModel(model);

normalizeContentModel(model);
changed =
changed ||
blocksToClear.length > 0 ||
segmentsToClear.length > 0 ||
tablesToClear.length > 0;
}

return (
blocksToClear.length > 0 || segmentsToClear.length > 0 || tablesToClear.length > 0
);
return changed;
},
{
apiName: 'clearFormat',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,13 @@ describe('clearModelFormat', () => {
const segments: any[] = [];
const tables: any[] = [];

clearModelFormat(model, [], [], []);
const result = clearModelFormat(model, [], [], []);

expect(model).toEqual({ blockGroupType: 'Document', blocks: [] });
expect(blocks).toEqual([]);
expect(segments).toEqual([]);
expect(tables).toEqual([]);
expect(result).toBeFalse();
});

it('Model without selection', () => {
Expand All @@ -122,7 +123,7 @@ describe('clearModelFormat', () => {
para.segments.push(text);
model.blocks.push(para);

clearModelFormat(model, blocks, segments, tables);
const result = clearModelFormat(model, blocks, segments, tables);

expect(model).toEqual({
blockGroupType: 'Document',
Expand All @@ -144,6 +145,7 @@ describe('clearModelFormat', () => {
expect(blocks).toEqual([]);
expect(segments).toEqual([]);
expect(tables).toEqual([]);
expect(result).toBeFalse();
});

it('Model with text selection', () => {
Expand All @@ -161,7 +163,7 @@ describe('clearModelFormat', () => {
const segments: any[] = [];
const tables: any[] = [];

clearModelFormat(model, blocks, segments, tables);
const result = clearModelFormat(model, blocks, segments, tables);

expect(model).toEqual({
blockGroupType: 'Document',
Expand All @@ -188,6 +190,7 @@ describe('clearModelFormat', () => {
expect(blocks).toEqual([[[model], para]]);
expect(segments).toEqual([text2]);
expect(tables).toEqual([]);
expect(result).toBeFalse();
});

it('Model with link', () => {
Expand All @@ -211,7 +214,7 @@ describe('clearModelFormat', () => {
const segments: any[] = [];
const tables: any[] = [];

clearModelFormat(model, blocks, segments, tables);
const result = clearModelFormat(model, blocks, segments, tables);

expect(model).toEqual({
blockGroupType: 'Document',
Expand Down Expand Up @@ -239,6 +242,7 @@ describe('clearModelFormat', () => {
expect(blocks).toEqual([[[model], para]]);
expect(segments).toEqual([text1]);
expect(tables).toEqual([]);
expect(result).toBeFalse();
});

it('Model with code', () => {
Expand All @@ -260,7 +264,7 @@ describe('clearModelFormat', () => {
const segments: any[] = [];
const tables: any[] = [];

clearModelFormat(model, blocks, segments, tables);
const result = clearModelFormat(model, blocks, segments, tables);

expect(model).toEqual({
blockGroupType: 'Document',
Expand All @@ -282,6 +286,7 @@ describe('clearModelFormat', () => {
expect(blocks).toEqual([[[model], para]]);
expect(segments).toEqual([text1]);
expect(tables).toEqual([]);
expect(result).toBeFalse();
});

it('Model with text selection in whole paragraph', () => {
Expand All @@ -300,7 +305,7 @@ describe('clearModelFormat', () => {
const segments: any[] = [];
const tables: any[] = [];

clearModelFormat(model, blocks, segments, tables);
const result = clearModelFormat(model, blocks, segments, tables);

expect(model).toEqual({
blockGroupType: 'Document',
Expand Down Expand Up @@ -328,6 +333,7 @@ describe('clearModelFormat', () => {
expect(blocks).toEqual([[[model], para]]);
expect(segments).toEqual([text1, text2]);
expect(tables).toEqual([]);
expect(result).toBeFalse();
});

it('Model with collapsed selection', () => {
Expand All @@ -344,7 +350,7 @@ describe('clearModelFormat', () => {
const segments: any[] = [];
const tables: any[] = [];

clearModelFormat(model, blocks, segments, tables);
const result = clearModelFormat(model, blocks, segments, tables);

expect(model).toEqual({
blockGroupType: 'Document',
Expand Down Expand Up @@ -375,6 +381,7 @@ describe('clearModelFormat', () => {
expect(blocks).toEqual([[[model], para]]);
expect(segments).toEqual([marker]);
expect(tables).toEqual([]);
expect(result).toBeFalse();
});

it('Model with collapsed selection inside word', () => {
Expand All @@ -392,7 +399,7 @@ describe('clearModelFormat', () => {
const segments: any[] = [];
const tables: any[] = [];

clearModelFormat(model, blocks, segments, tables);
const result = clearModelFormat(model, blocks, segments, tables);

expect(model).toEqual({
blockGroupType: 'Document',
Expand Down Expand Up @@ -447,6 +454,7 @@ describe('clearModelFormat', () => {
text3,
]);
expect(tables).toEqual([]);
expect(result).toBeFalse();
});

it('Model with collapsed selection under list', () => {
Expand All @@ -463,7 +471,7 @@ describe('clearModelFormat', () => {
const segments: any[] = [];
const tables: any[] = [];

clearModelFormat(model, blocks, segments, tables);
const result = clearModelFormat(model, blocks, segments, tables);

expect(model).toEqual({
blockGroupType: 'Document',
Expand Down Expand Up @@ -499,6 +507,7 @@ describe('clearModelFormat', () => {
expect(blocks).toEqual([[[list, model], para]]);
expect(segments).toEqual([marker]);
expect(tables).toEqual([]);
expect(result).toBeTrue();
});

it('Model with divider selection', () => {
Expand All @@ -516,7 +525,7 @@ describe('clearModelFormat', () => {
const segments: any[] = [];
const tables: any[] = [];

clearModelFormat(model, blocks, segments, tables);
const result = clearModelFormat(model, blocks, segments, tables);

expect(model).toEqual({
blockGroupType: 'Document',
Expand All @@ -540,6 +549,7 @@ describe('clearModelFormat', () => {
expect(blocks).toEqual([[[model], divider]]);
expect(segments).toEqual([]);
expect(tables).toEqual([]);
expect(result).toBeFalse();
});

it('Model with selection under list', () => {
Expand All @@ -558,7 +568,7 @@ describe('clearModelFormat', () => {
const segments: any[] = [];
const tables: any[] = [];

clearModelFormat(model, blocks, segments, tables);
const result = clearModelFormat(model, blocks, segments, tables);

expect(model).toEqual({
blockGroupType: 'Document',
Expand Down Expand Up @@ -600,6 +610,7 @@ describe('clearModelFormat', () => {
},
]);
expect(tables).toEqual([]);
expect(result).toBeTrue();
});

it('Model with selection under list, has defaultSegmentFormat', () => {
Expand All @@ -620,7 +631,7 @@ describe('clearModelFormat', () => {
const segments: any[] = [];
const tables: any[] = [];

clearModelFormat(model, blocks, segments, tables);
const result = clearModelFormat(model, blocks, segments, tables);

expect(model).toEqual({
blockGroupType: 'Document',
Expand Down Expand Up @@ -662,6 +673,7 @@ describe('clearModelFormat', () => {
expect(blocks).toEqual([[[list, model], para]]);
expect(segments).toEqual([text]);
expect(tables).toEqual([]);
expect(result).toBeTrue();
});

it('Model with selection under quote', () => {
Expand All @@ -688,7 +700,7 @@ describe('clearModelFormat', () => {
const segments: any[] = [];
const tables: any[] = [];

clearModelFormat(model, blocks, segments, tables);
const result = clearModelFormat(model, blocks, segments, tables);

expect(model).toEqual({
blockGroupType: 'Document',
Expand Down Expand Up @@ -774,6 +786,7 @@ describe('clearModelFormat', () => {
]);
expect(segments).toEqual([text3, text4]);
expect(tables).toEqual([]);
expect(result).toBeFalse();
});

it('Model with selection under table', () => {
Expand All @@ -796,7 +809,7 @@ describe('clearModelFormat', () => {
const segments: any[] = [];
const tables: any[] = [];

clearModelFormat(model, blocks, segments, tables);
const result = clearModelFormat(model, blocks, segments, tables);

expect(model).toEqual({
blockGroupType: 'Document',
Expand Down Expand Up @@ -855,5 +868,6 @@ describe('clearModelFormat', () => {
expect(blocks).toEqual([]);
expect(segments).toEqual([]);
expect(tables).toEqual([[table, true]]);
expect(result).toBeFalse();
});
});
Loading

0 comments on commit f2ffdab

Please sign in to comment.