Skip to content

Commit 2e7d36e

Browse files
committed
Merge branch 'master' into u/jisong/listcache
2 parents e80df74 + c4aa81a commit 2e7d36e

File tree

26 files changed

+759
-217
lines changed

26 files changed

+759
-217
lines changed

demo/scripts/controlsV2/sidePane/editorOptions/EditorOptionsPlugin.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,7 @@ const initialState: OptionState = {
6464
customReplacements: emojiReplacements,
6565
disableSideResize: false,
6666
experimentalFeatures: new Set<ExperimentalFeature>([
67-
'PersistCache',
6867
'HandleEnterKey',
69-
'CustomCopyCut',
7068
'CloneIndependentRoot',
7169
'CacheList',
7270
]),

demo/scripts/controlsV2/sidePane/editorOptions/ExperimentalFeatures.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ export class ExperimentalFeatures extends React.Component<DefaultFormatProps, {}
1111
render() {
1212
return (
1313
<>
14-
{this.renderFeature('PersistCache')}
1514
{this.renderFeature('HandleEnterKey')}
16-
{this.renderFeature('CustomCopyCut')}
15+
{this.renderFeature('KeepSelectionMarkerWhenEnteringTextNode')}
1716
{this.renderFeature('CloneIndependentRoot')}
1817
{this.renderFeature('CacheList')}
1918
</>

packages/roosterjs-content-model-api/lib/publicApi/table/insertTable.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,27 @@ import {
99
normalizeTable,
1010
setSelection,
1111
} from 'roosterjs-content-model-dom';
12-
import type { IEditor, TableMetadataFormat } from 'roosterjs-content-model-types';
12+
import type {
13+
ContentModelTableFormat,
14+
IEditor,
15+
TableMetadataFormat,
16+
} from 'roosterjs-content-model-types';
1317

1418
/**
1519
* Insert table into editor at current selection
1620
* @param editor The editor instance
1721
* @param columns Number of columns in table, it also controls the default table cell width:
1822
* if columns &lt;= 4, width = 120px; if columns &lt;= 6, width = 100px; else width = 70px
1923
* @param rows Number of rows in table
20-
* @param format (Optional) The table format. If not passed, the default format will be applied:
21-
* background color: #FFF; border color: #ABABAB
24+
* @param tableMetadataFormat (Optional) The table format that are stored as metadata. If not passed, the default format will be applied: background color: #FFF; border color: #ABABAB
25+
* @param format (Optional) The table format used for style attributes
2226
*/
2327
export function insertTable(
2428
editor: IEditor,
2529
columns: number,
2630
rows: number,
27-
format?: Partial<TableMetadataFormat>
31+
tableMetadataFormat?: Partial<TableMetadataFormat>,
32+
format?: ContentModelTableFormat
2833
) {
2934
editor.focus();
3035

@@ -35,14 +40,17 @@ export function insertTable(
3540
if (insertPosition) {
3641
const doc = createContentModelDocument();
3742
const table = createTableStructure(doc, columns, rows);
43+
if (format) {
44+
table.format = { ...format };
45+
}
3846

3947
normalizeTable(table, editor.getPendingFormat() || insertPosition.marker.format);
4048

4149
adjustTableIndentation(insertPosition, table);
4250

4351
// Assign default vertical align
44-
format = format || { verticalAlign: 'top' };
45-
applyTableFormat(table, format);
52+
tableMetadataFormat = tableMetadataFormat || { verticalAlign: 'top' };
53+
applyTableFormat(table, tableMetadataFormat);
4654
mergeModel(model, doc, context, {
4755
insertPosition,
4856
mergeFormat: 'mergeAll',

packages/roosterjs-content-model-api/test/modelApi/block/splitSelectedParagraphByBrTest.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,11 +468,13 @@ describe('splitSelectedParagraphByBr', () => {
468468
blockType: 'Paragraph',
469469
segments: [text3_1],
470470
format: {},
471+
cachedElement: mockedCache,
471472
},
472473
{
473474
blockType: 'Paragraph',
474475
segments: [text4_1],
475476
format: {},
477+
cachedElement: mockedCache,
476478
},
477479
{
478480
blockType: 'Paragraph',

packages/roosterjs-content-model-api/test/publicApi/table/insertTableTest.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,5 +261,70 @@ describe('insertTable', () => {
261261
],
262262
});
263263
});
264+
265+
it('should insert table with format', () => {
266+
// Arrange
267+
const model: ContentModelDocument = {
268+
blockGroupType: 'Document',
269+
blocks: [
270+
{
271+
blockType: 'Paragraph',
272+
segments: [
273+
{
274+
segmentType: 'SelectionMarker',
275+
isSelected: true,
276+
format: {},
277+
},
278+
],
279+
format: {},
280+
},
281+
],
282+
};
283+
284+
let resultModel: ContentModelDocument | null = null;
285+
286+
formatContentModelSpy.and.callFake((callback: any) => {
287+
const result = callback(model, {
288+
newEntities: [],
289+
deletedEntities: [],
290+
newImages: [],
291+
});
292+
resultModel = model;
293+
return result;
294+
});
295+
296+
// Act
297+
insertTable(editor, 3, 3, undefined, {
298+
marginBottom: '1px',
299+
});
300+
301+
// Assert
302+
expect(resultModel!).toEqual({
303+
blockGroupType: 'Document',
304+
blocks: [
305+
{
306+
blockType: 'Table',
307+
rows: jasmine.any(Array),
308+
format: {
309+
borderCollapse: true,
310+
useBorderBox: true,
311+
marginBottom: '1px',
312+
},
313+
widths: jasmine.any(Array),
314+
dataset: jasmine.any(Object),
315+
},
316+
{
317+
blockType: 'Paragraph',
318+
segments: [
319+
{
320+
segmentType: 'Br',
321+
format: {},
322+
},
323+
],
324+
format: {},
325+
},
326+
],
327+
});
328+
});
264329
});
265330
});

packages/roosterjs-content-model-core/test/coreApi/createEditorContext/createEditorContextTest.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ describe('createEditorContext', () => {
5151
experimentalFeatures: [],
5252
paragraphMap: mockedParagraphMap,
5353
editorViewWidth: 800,
54+
allowCacheListItem: false,
5455
});
5556
});
5657

@@ -103,6 +104,7 @@ describe('createEditorContext', () => {
103104
experimentalFeatures: [],
104105
paragraphMap: mockedParagraphMap,
105106
editorViewWidth: 800,
107+
allowCacheListItem: false,
106108
});
107109
});
108110

@@ -152,6 +154,7 @@ describe('createEditorContext', () => {
152154
experimentalFeatures: [],
153155
paragraphMap: mockedParagraphMap,
154156
editorViewWidth: 800,
157+
allowCacheListItem: false,
155158
});
156159
});
157160

@@ -204,6 +207,7 @@ describe('createEditorContext', () => {
204207
experimentalFeatures: [],
205208
paragraphMap: mockedParagraphMap,
206209
editorViewWidth: 800,
210+
allowCacheListItem: false,
207211
});
208212
});
209213
});
@@ -262,6 +266,7 @@ describe('createEditorContext - checkZoomScale', () => {
262266
experimentalFeatures: [],
263267
paragraphMap: mockedParagraphMap,
264268
editorViewWidth: 800,
269+
allowCacheListItem: false,
265270
});
266271
});
267272
});
@@ -320,6 +325,7 @@ describe('createEditorContext - checkRootDir', () => {
320325
experimentalFeatures: [],
321326
paragraphMap: mockedParagraphMap,
322327
editorViewWidth: 800,
328+
allowCacheListItem: false,
323329
});
324330
});
325331

@@ -341,6 +347,7 @@ describe('createEditorContext - checkRootDir', () => {
341347
experimentalFeatures: [],
342348
paragraphMap: mockedParagraphMap,
343349
editorViewWidth: 800,
350+
allowCacheListItem: false,
344351
});
345352
});
346353
});

packages/roosterjs-content-model-dom/lib/domToModel/domToContentModel.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { createContentModelDocument } from '../modelApi/creators/createContentModelDocument';
22
import { normalizeContentModel } from '../modelApi/common/normalizeContentModel';
3-
import type { ContentModelDocumentWithPersistedCache } from '../modelApi/selection/iterateSelections';
43
import type { ContentModelDocument, DomToModelContext } from 'roosterjs-content-model-types';
54

65
/**
@@ -19,11 +18,6 @@ export function domToContentModel(
1918
model.hasRevertedRangeSelection = true;
2019
}
2120

22-
// When allowed, persist cached element and do not clear it if not changed
23-
if (context.domIndexer && context.allowCacheElement) {
24-
(model as ContentModelDocumentWithPersistedCache).persistCache = true;
25-
}
26-
2721
context.elementProcessors.child(model, root, context);
2822

2923
normalizeContentModel(model);

packages/roosterjs-content-model-dom/lib/modelApi/selection/iterateSelections.ts

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import type {
22
ContentModelBlockGroup,
3-
ContentModelBlockWithCache,
4-
ContentModelDocument,
53
IterateSelectionsCallback,
64
IterateSelectionsOption,
75
ReadonlyContentModelBlockGroup,
@@ -10,17 +8,6 @@ import type {
108
ReadonlyTableSelectionContext,
119
} from 'roosterjs-content-model-types';
1210

13-
/**
14-
* @internal
15-
* This is a temporary type to pass the information of whether element cache should be persisted when possible
16-
*/
17-
export interface ContentModelDocumentWithPersistedCache extends ContentModelDocument {
18-
/**
19-
* When set to
20-
*/
21-
persistCache?: boolean;
22-
}
23-
2411
/**
2512
* Iterate all selected elements in a given model
2613
* @param group The given Content Model to iterate selection from
@@ -50,26 +37,7 @@ export function iterateSelections(
5037
callback: ReadonlyIterateSelectionsCallback | IterateSelectionsCallback,
5138
option?: IterateSelectionsOption
5239
): void {
53-
const persistCache =
54-
group.blockGroupType == 'Document'
55-
? (group as ContentModelDocumentWithPersistedCache).persistCache
56-
: false;
57-
const internalCallback: ReadonlyIterateSelectionsCallback = persistCache
58-
? (callback as ReadonlyIterateSelectionsCallback)
59-
: (path, tableContext, block, segments) => {
60-
if (!!(block as ContentModelBlockWithCache)?.cachedElement) {
61-
delete (block as ContentModelBlockWithCache).cachedElement;
62-
}
63-
64-
return (callback as ReadonlyIterateSelectionsCallback)(
65-
path,
66-
tableContext,
67-
block,
68-
segments
69-
);
70-
};
71-
72-
internalIterateSelections([group], internalCallback, option);
40+
internalIterateSelections([group], callback as ReadonlyIterateSelectionsCallback, option);
7341
}
7442

7543
function internalIterateSelections(

packages/roosterjs-content-model-dom/lib/modelToDom/contentModelToDom.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { isNodeOfType } from '../domUtils/isNodeOfType';
22
import { toArray } from '../domUtils/toArray';
3-
import type { ContentModelDocumentWithPersistedCache } from '../modelApi/selection/iterateSelections';
43
import type {
54
ContentModelDocument,
65
DOMSelection,
@@ -32,10 +31,6 @@ export function contentModelToDom(
3231
range.isReverted = true;
3332
}
3433

35-
if (context.domIndexer && context.allowCacheElement) {
36-
(model as ContentModelDocumentWithPersistedCache).persistCache = true;
37-
}
38-
3934
root.normalize();
4035

4136
return range;

packages/roosterjs-content-model-dom/lib/modelToDom/handlers/handleList.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,25 @@ export const handleList: ContentModelBlockHandler<ContentModelListItem> = (
6565
levelRefNode,
6666
context.rewriteFromModel
6767
);
68-
nodeStack.push({ node: newList, refNode: newList.firstChild, ...level });
68+
nodeStack.push({
69+
node: newList,
70+
refNode: newList.firstChild,
71+
listType: level.listType,
72+
format: { ...level.format },
73+
dataset: { ...level.dataset },
74+
});
6975
} else {
7076
newList = doc.createElement(level.listType == 'OL' ? 'ol' : 'ul');
7177
isNewlyCreated = true;
7278

7379
lastParent.insertBefore(newList, levelRefNode);
74-
nodeStack.push({ node: newList, refNode: null, ...level });
80+
nodeStack.push({
81+
node: newList,
82+
refNode: null,
83+
listType: level.listType,
84+
format: { ...level.format },
85+
dataset: { ...level.dataset },
86+
});
7587

7688
if (context.allowCacheListItem) {
7789
level.cachedElement = newList;

0 commit comments

Comments
 (0)