11import {
22 createText ,
3+ getObjectKeys ,
34 iterateSelections ,
45 mutateBlock ,
56 mutateSegment ,
89} from 'roosterjs-content-model-dom' ;
910import type {
1011 ContentModelBlockFormat ,
12+ ContentModelFormatBase ,
1113 ContentModelSegmentFormat ,
1214 IEditor ,
1315} from 'roosterjs-content-model-types' ;
@@ -47,7 +49,10 @@ export function applyPendingFormat(
4749
4850 // For space, there can be   (space) or   ( ), we treat them as the same
4951 if ( subStr == data || ( data == ANSI_SPACE && subStr == NON_BREAK_SPACE ) ) {
50- if ( segmentFormat ) {
52+ if (
53+ segmentFormat &&
54+ ! isSubFormatIncluded ( previousSegment . format , segmentFormat )
55+ ) {
5156 mutateSegment ( block , previousSegment , previousSegment => {
5257 previousSegment . text = text . substring (
5358 0 ,
@@ -69,15 +74,19 @@ export function applyPendingFormat(
6974 block . segments . splice ( index , 0 , newText ) ;
7075 setParagraphNotImplicit ( block ) ;
7176 } ) ;
77+
78+ isChanged = true ;
7279 }
7380
74- if ( paragraphFormat ) {
81+ if (
82+ paragraphFormat &&
83+ ! isSubFormatIncluded ( block . format , paragraphFormat )
84+ ) {
7585 const mutableParagraph = mutateBlock ( block ) ;
7686
7787 Object . assign ( mutableParagraph . format , paragraphFormat ) ;
88+ isChanged = true ;
7889 }
79-
80- isChanged = true ;
8190 }
8291 }
8392 }
@@ -96,3 +105,16 @@ export function applyPendingFormat(
96105 }
97106 ) ;
98107}
108+
109+ function isSubFormatIncluded < T extends ContentModelFormatBase > ( containerFormat : T , subFormat : T ) {
110+ const keys = getObjectKeys ( subFormat ) ;
111+ let result = true ;
112+
113+ keys . forEach ( key => {
114+ if ( containerFormat [ key ] !== subFormat [ key ] ) {
115+ result = false ;
116+ }
117+ } ) ;
118+
119+ return result ;
120+ }
0 commit comments