Skip to content

Commit 4717e6b

Browse files
authored
Move graduated feature to a separate type (#3205)
* Move graduated feature to a separate type * improve * fix build
1 parent 7d501f4 commit 4717e6b

File tree

9 files changed

+66
-129
lines changed

9 files changed

+66
-129
lines changed

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,7 @@ const initialState: OptionState = {
6363
},
6464
customReplacements: emojiReplacements,
6565
disableSideResize: false,
66-
experimentalFeatures: new Set<ExperimentalFeature>([
67-
'PersistCache',
68-
'HandleEnterKey',
69-
'CustomCopyCut',
70-
'CloneIndependentRoot',
71-
]),
66+
experimentalFeatures: new Set<ExperimentalFeature>(['HandleEnterKey', 'CloneIndependentRoot']),
7267
};
7368

7469
export class EditorOptionsPlugin extends SidePanePluginImpl<OptionsPane, OptionPaneProps> {

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
</>
1918
);

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-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/test/modelApi/selection/iterateSelectionsTest.ts

Lines changed: 41 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -250,17 +250,12 @@ describe('iterateSelections', () => {
250250
iterateSelections(group, callback);
251251

252252
expect(callback).toHaveBeenCalledTimes(3);
253-
expect(callback).toHaveBeenCalledWith(
254-
[group],
255-
{
256-
table: table,
257-
colIndex: 0,
258-
rowIndex: 0,
259-
isWholeTableSelected: false,
260-
},
261-
undefined,
262-
undefined
263-
);
253+
expect(callback).toHaveBeenCalledWith([group], {
254+
table: table,
255+
colIndex: 0,
256+
rowIndex: 0,
257+
isWholeTableSelected: false,
258+
});
264259
expect(callback).toHaveBeenCalledWith(
265260
[cell1, group],
266261
{
@@ -311,17 +306,12 @@ describe('iterateSelections', () => {
311306
});
312307

313308
expect(callback).toHaveBeenCalledTimes(1);
314-
expect(callback).toHaveBeenCalledWith(
315-
[group],
316-
{
317-
table: table,
318-
colIndex: 0,
319-
rowIndex: 0,
320-
isWholeTableSelected: false,
321-
},
322-
undefined,
323-
undefined
324-
);
309+
expect(callback).toHaveBeenCalledWith([group], {
310+
table: table,
311+
colIndex: 0,
312+
rowIndex: 0,
313+
isWholeTableSelected: false,
314+
});
325315
});
326316

327317
it('Group with table selection and ignore selected table content', () => {
@@ -350,17 +340,12 @@ describe('iterateSelections', () => {
350340
});
351341

352342
expect(callback).toHaveBeenCalledTimes(3);
353-
expect(callback).toHaveBeenCalledWith(
354-
[group],
355-
{
356-
table: table,
357-
colIndex: 0,
358-
rowIndex: 0,
359-
isWholeTableSelected: false,
360-
},
361-
undefined,
362-
undefined
363-
);
343+
expect(callback).toHaveBeenCalledWith([group], {
344+
table: table,
345+
colIndex: 0,
346+
rowIndex: 0,
347+
isWholeTableSelected: false,
348+
});
364349
expect(callback).toHaveBeenCalledWith(
365350
[cell1, group],
366351
{
@@ -410,7 +395,7 @@ describe('iterateSelections', () => {
410395
iterateSelections(group, callback, { contentUnderSelectedTableCell: 'ignoreForTable' });
411396

412397
expect(callback).toHaveBeenCalledTimes(1);
413-
expect(callback).toHaveBeenCalledWith([group], undefined, table, undefined);
398+
expect(callback).toHaveBeenCalledWith([group], undefined, table);
414399
});
415400

416401
it('Select from the end of paragraph', () => {
@@ -857,16 +842,16 @@ describe('iterateSelections', () => {
857842
iterateSelections(group, callback3, { contentUnderSelectedGeneralElement: 'both' });
858843

859844
expect(callback).toHaveBeenCalledTimes(1);
860-
expect(callback).toHaveBeenCalledWith([group], undefined, generalDiv, undefined);
845+
expect(callback).toHaveBeenCalledWith([group], undefined, generalDiv);
861846

862847
expect(callback1).toHaveBeenCalledTimes(1);
863-
expect(callback1).toHaveBeenCalledWith([group], undefined, generalDiv, undefined);
848+
expect(callback1).toHaveBeenCalledWith([group], undefined, generalDiv);
864849

865850
expect(callback2).toHaveBeenCalledTimes(1);
866-
expect(callback2).toHaveBeenCalledWith([group], undefined, generalDiv, undefined);
851+
expect(callback2).toHaveBeenCalledWith([group], undefined, generalDiv);
867852

868853
expect(callback3).toHaveBeenCalledTimes(1);
869-
expect(callback3).toHaveBeenCalledWith([group], undefined, generalDiv, undefined);
854+
expect(callback3).toHaveBeenCalledWith([group], undefined, generalDiv);
870855
});
871856

872857
it('Get Selection from model that contains selected general block', () => {
@@ -907,14 +892,14 @@ describe('iterateSelections', () => {
907892
]);
908893

909894
expect(callback2).toHaveBeenCalledTimes(1);
910-
expect(callback2).toHaveBeenCalledWith([group], undefined, generalDiv, undefined);
895+
expect(callback2).toHaveBeenCalledWith([group], undefined, generalDiv);
911896

912897
expect(callback3).toHaveBeenCalledTimes(2);
913898
expect(callback3).toHaveBeenCalledWith([generalDiv, group], undefined, para2, [
914899
text1,
915900
text2,
916901
]);
917-
expect(callback3).toHaveBeenCalledWith([group], undefined, generalDiv, undefined);
902+
expect(callback3).toHaveBeenCalledWith([group], undefined, generalDiv);
918903
});
919904

920905
it('Divider selection', () => {
@@ -927,7 +912,7 @@ describe('iterateSelections', () => {
927912
iterateSelections(group, callback);
928913

929914
expect(callback).toHaveBeenCalledTimes(1);
930-
expect(callback).toHaveBeenCalledWith([group], undefined, divider, undefined);
915+
expect(callback).toHaveBeenCalledWith([group], undefined, divider);
931916
});
932917

933918
it('Return true from first selection', () => {
@@ -983,7 +968,7 @@ describe('iterateSelections', () => {
983968

984969
expect(newCallback).toHaveBeenCalledTimes(2);
985970
expect(newCallback).toHaveBeenCalledWith([group], undefined, para1, [text1]);
986-
expect(newCallback).toHaveBeenCalledWith([group], undefined, divider, undefined);
971+
expect(newCallback).toHaveBeenCalledWith([group], undefined, divider);
987972
});
988973

989974
it('Return true from first selection in nested block group', () => {
@@ -1043,7 +1028,7 @@ describe('iterateSelections', () => {
10431028
});
10441029

10451030
expect(newCallback).toHaveBeenCalledTimes(1);
1046-
expect(newCallback).toHaveBeenCalledWith([group], undefined, table, undefined);
1031+
expect(newCallback).toHaveBeenCalledWith([group], undefined, table);
10471032
});
10481033

10491034
it('Return true from table cell selection', () => {
@@ -1075,28 +1060,18 @@ describe('iterateSelections', () => {
10751060
iterateSelections(group, newCallback);
10761061

10771062
expect(newCallback).toHaveBeenCalledTimes(2);
1078-
expect(newCallback).toHaveBeenCalledWith(
1079-
[group],
1080-
{
1081-
table: table,
1082-
rowIndex: 0,
1083-
colIndex: 0,
1084-
isWholeTableSelected: true,
1085-
},
1086-
undefined,
1087-
undefined
1088-
);
1089-
expect(newCallback).toHaveBeenCalledWith(
1090-
[group],
1091-
{
1092-
table: table,
1093-
rowIndex: 0,
1094-
colIndex: 1,
1095-
isWholeTableSelected: true,
1096-
},
1097-
undefined,
1098-
undefined
1099-
);
1063+
expect(newCallback).toHaveBeenCalledWith([group], {
1064+
table: table,
1065+
rowIndex: 0,
1066+
colIndex: 0,
1067+
isWholeTableSelected: true,
1068+
});
1069+
expect(newCallback).toHaveBeenCalledWith([group], {
1070+
table: table,
1071+
rowIndex: 0,
1072+
colIndex: 1,
1073+
isWholeTableSelected: true,
1074+
});
11001075
});
11011076

11021077
it('includeListFormatHolder=anySegment', () => {
@@ -1218,6 +1193,6 @@ describe('iterateSelections', () => {
12181193
iterateSelections(doc, callback, { includeListFormatHolder: 'never' });
12191194

12201195
expect(callback).toHaveBeenCalledTimes(1);
1221-
expect(callback).toHaveBeenCalledWith([doc], undefined, entity, undefined);
1196+
expect(callback).toHaveBeenCalledWith([doc], undefined, entity);
12221197
});
12231198
});

packages/roosterjs-content-model-types/lib/editor/ExperimentalFeature.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
/**
2-
* Predefined experiment features
3-
* By default these features are not enabled. To enable them, pass the feature name into EditorOptions.experimentalFeatures
4-
* when create editor
2+
* Predefined experiment features (Graduated, only keep them for backward compatibility)
53
*/
6-
export type ExperimentalFeature =
4+
export type GraduatedExperimentalFeature =
75
/**
86
* @deprecated When this feature is enabled, we will persist a content model in memory as long as we can,
97
* and use cached element when write back if it is not changed.
@@ -14,17 +12,28 @@ export type ExperimentalFeature =
1412
* Workaround for the Legacy Image Edit
1513
*/
1614
| 'LegacyImageSelection'
17-
/**
18-
* @deprecated Please use the shouldHandleEnterKey option of the EditPlugin Options
19-
* Use Content Model handle ENTER key
20-
*/
21-
| 'HandleEnterKey'
15+
2216
/**
2317
* @deprecated
2418
* Prevent default browser behavior for copy/cut event,
2519
* and set the clipboard data with custom implementation.
2620
*/
27-
| 'CustomCopyCut'
21+
| 'CustomCopyCut';
22+
23+
/**
24+
* Predefined experiment features
25+
* By default these features are not enabled. To enable them, pass the feature name into EditorOptions.experimentalFeatures
26+
* when create editor
27+
*/
28+
export type ExperimentalFeature =
29+
| GraduatedExperimentalFeature
30+
31+
/**
32+
* @deprecated Please use the shouldHandleEnterKey option of the EditPlugin Options
33+
* Use Content Model handle ENTER key
34+
*/
35+
| 'HandleEnterKey'
36+
2837
/**
2938
* For CJK keyboard input on mobile, if the user toggles bold/italic/underline on an empty div,
3039
* the pending format will be applied on the selection marker. When typing text, the selection moves to the text node and the

packages/roosterjs-content-model-types/lib/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ export {
333333
export { DarkColorHandler, Colors, ColorTransformFunction } from './context/DarkColorHandler';
334334

335335
export { IEditor } from './editor/IEditor';
336-
export { ExperimentalFeature } from './editor/ExperimentalFeature';
336+
export { ExperimentalFeature, GraduatedExperimentalFeature } from './editor/ExperimentalFeature';
337337
export {
338338
EditorOptions,
339339
ColorOptions,

0 commit comments

Comments
 (0)