diff --git a/packages/roosterjs-content-model-dom/lib/modelApi/editing/mergeModel.ts b/packages/roosterjs-content-model-dom/lib/modelApi/editing/mergeModel.ts index 94ed4f65319..df6639be10f 100644 --- a/packages/roosterjs-content-model-dom/lib/modelApi/editing/mergeModel.ts +++ b/packages/roosterjs-content-model-dom/lib/modelApi/editing/mergeModel.ts @@ -377,9 +377,9 @@ function applyDefaultFormat( }); if (segment.link) { - segment.link.format = mergeSegmentFormat( + segment.link.format = mergeLinkFormat( applyDefaultFormatOption, - getSegmentFormatInLinkFormat(format), + format, segment.link.format ); } @@ -400,16 +400,13 @@ function mergeBlockFormat(applyDefaultFormatOption: string, block: ReadonlyConte } /** - * Hyperlink format type definition only contains textColor, backgroundColor and underline. + * Hyperlink format type definition only contains backgroundColor and underline. * So create a minimum object with the styles supported in Hyperlink to be used in merge. */ function getSegmentFormatInLinkFormat( targetFormat: ContentModelSegmentFormat ): ContentModelSegmentFormat { const result: ContentModelHyperLinkFormat = {}; - if (targetFormat.textColor) { - result.textColor = targetFormat.textColor; - } if (targetFormat.backgroundColor) { result.backgroundColor = targetFormat.backgroundColor; } @@ -420,6 +417,28 @@ function getSegmentFormatInLinkFormat( return result; } +function mergeLinkFormat( + applyDefaultFormatOption: 'mergeAll' | 'keepSourceEmphasisFormat', + targetFormat: ContentModelSegmentFormat, + sourceFormat: ContentModelHyperLinkFormat +) { + return applyDefaultFormatOption == 'mergeAll' + ? { ...getSegmentFormatInLinkFormat(targetFormat), ...sourceFormat } + : { + // Hyperlink segment format contains other attributes such as LinkFormat + // so we have to retain them + ...getFormatWithoutSegmentFormat(sourceFormat), + // Link format only have Text color, background color, Underline, but only + // text color + background color should be merged from the target + ...getSegmentFormatInLinkFormat(targetFormat), + // Get the semantic format of the source + ...getSemanticFormat(sourceFormat), + // The text color of the hyperlink should not be merged and + // we should always retain the source text color + ...getHyperlinkTextColor(sourceFormat), + }; +} + function mergeSegmentFormat( applyDefaultFormatOption: 'mergeAll' | 'keepSourceEmphasisFormat', targetFormat: ContentModelSegmentFormat, @@ -465,3 +484,11 @@ function getFormatWithoutSegmentFormat( KeysOfSegmentFormat.forEach(key => delete resultFormat[key]); return resultFormat; } +function getHyperlinkTextColor(sourceFormat: ContentModelHyperLinkFormat) { + const result: ContentModelHyperLinkFormat = {}; + if (sourceFormat.textColor) { + result.textColor = sourceFormat.textColor; + } + + return result; +} diff --git a/packages/roosterjs-content-model-dom/test/modelApi/editing/mergeModelTest.ts b/packages/roosterjs-content-model-dom/test/modelApi/editing/mergeModelTest.ts index b22a2988f7b..72c4023c39e 100644 --- a/packages/roosterjs-content-model-dom/test/modelApi/editing/mergeModelTest.ts +++ b/packages/roosterjs-content-model-dom/test/modelApi/editing/mergeModelTest.ts @@ -3737,7 +3737,7 @@ describe('mergeModel', () => { anchorClass: 'bolt-link', borderRadius: '2px', textAlign: 'start', - textColor: '#000000', + textColor: 'var(--communication-foreground,rgba(0, 90, 158, 1))', underline: true, }, dataset: {},