From ad6e53d3293fa4c3fb2849037479439b0ffc6055 Mon Sep 17 00:00:00 2001 From: Jiuqing Song Date: Fri, 8 Sep 2023 14:30:23 -0700 Subject: [PATCH] Content Model: Fix line space when reduce font size --- .../lib/publicApi/segment/changeFontSize.ts | 10 ++-- .../lib/publicApi/segment/setFontSize.ts | 30 +++++++++-- .../publicApi/segment/changeFontSizeTest.ts | 43 +++++++++++++++ .../test/publicApi/segment/setFontSizeTest.ts | 52 +++++++++++++++++++ 4 files changed, 128 insertions(+), 7 deletions(-) diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/changeFontSize.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/changeFontSize.ts index 0832f626851..10868f8b4b8 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/changeFontSize.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/changeFontSize.ts @@ -1,7 +1,8 @@ -import { ContentModelSegmentFormat } from 'roosterjs-content-model-types'; +import { ContentModelParagraph, ContentModelSegmentFormat } from 'roosterjs-content-model-types'; import { formatSegmentWithContentModel } from '../utils/formatSegmentWithContentModel'; import { IContentModelEditor } from '../../publicTypes/IContentModelEditor'; import { parseValueWithUnit } from 'roosterjs-content-model-dom'; +import { setFontSizeInternal } from './setFontSize'; /** * Default font size sequence, in pt. Suggest editor UI use this sequence as your font size list, @@ -24,15 +25,16 @@ export default function changeFontSize( formatSegmentWithContentModel( editor, 'changeFontSize', - format => changeFontSizeInternal(format, change), + (format, _, __, paragraph) => changeFontSizeInternal(change, format, paragraph), undefined /* segmentHasStyleCallback*/, true /*includingFormatHandler*/ ); } function changeFontSizeInternal( + change: 'increase' | 'decrease', format: ContentModelSegmentFormat, - change: 'increase' | 'decrease' + paragraph: ContentModelParagraph | null ) { if (format.fontSize) { let sizeInPt = parseValueWithUnit(format.fontSize, undefined /*element*/, 'pt'); @@ -40,7 +42,7 @@ function changeFontSizeInternal( if (sizeInPt > 0) { const newSize = getNewFontSize(sizeInPt, change == 'increase' ? 1 : -1, FONT_SIZES); - format.fontSize = newSize + 'pt'; + setFontSizeInternal(newSize + 'pt', format, paragraph); } } } diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setFontSize.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setFontSize.ts index 87fe60c764f..c718710e088 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setFontSize.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setFontSize.ts @@ -1,3 +1,4 @@ +import { ContentModelParagraph, ContentModelSegmentFormat } from 'roosterjs-content-model-types'; import { formatSegmentWithContentModel } from '../utils/formatSegmentWithContentModel'; import { IContentModelEditor } from '../../publicTypes/IContentModelEditor'; @@ -10,10 +11,33 @@ export default function setFontSize(editor: IContentModelEditor, fontSize: strin formatSegmentWithContentModel( editor, 'setFontSize', - format => { - format.fontSize = fontSize; - }, + (format, _, __, paragraph) => setFontSizeInternal(fontSize, format, paragraph), undefined /* segmentHasStyleCallback*/, true /*includingFormatHandler*/ ); } + +/** + * @internal + * Internal set font function shared by setFontSize and changeFontSize + */ +export function setFontSizeInternal( + fontSize: string, + format: ContentModelSegmentFormat, + paragraph: ContentModelParagraph | null +) { + format.fontSize = fontSize; + + // Since we have set font size to segment, it can be smaller than the one in paragraph format, so delete font size from paragraph + if (paragraph?.segmentFormat?.fontSize) { + const size = paragraph.segmentFormat.fontSize; + + paragraph.segments.forEach(segment => { + if (!segment.format.fontSize) { + segment.format.fontSize = size; + } + }); + + delete paragraph.segmentFormat.fontSize; + } +} diff --git a/packages-content-model/roosterjs-content-model-editor/test/publicApi/segment/changeFontSizeTest.ts b/packages-content-model/roosterjs-content-model-editor/test/publicApi/segment/changeFontSizeTest.ts index d1aa4f7b317..c50faa49a45 100644 --- a/packages-content-model/roosterjs-content-model-editor/test/publicApi/segment/changeFontSizeTest.ts +++ b/packages-content-model/roosterjs-content-model-editor/test/publicApi/segment/changeFontSizeTest.ts @@ -378,4 +378,47 @@ describe('changeFontSize', () => { { onNodeCreated: undefined } ); }); + + it('Paragraph has font size', () => { + runTest( + { + blockGroupType: 'Document', + blocks: [ + { + blockType: 'Paragraph', + format: {}, + segmentFormat: { fontSize: '20pt' }, + segments: [ + { + segmentType: 'Text', + text: 'test', + format: { fontSize: '10pt' }, + isSelected: true, + }, + ], + }, + ], + }, + { + blockGroupType: 'Document', + blocks: [ + { + blockType: 'Paragraph', + format: {}, + segmentFormat: {}, + segments: [ + { + segmentType: 'Text', + text: 'test', + format: { fontSize: '11pt' }, + isSelected: true, + }, + ], + }, + ], + }, + 1, + 'increase' + ); + }); }); diff --git a/packages-content-model/roosterjs-content-model-editor/test/publicApi/segment/setFontSizeTest.ts b/packages-content-model/roosterjs-content-model-editor/test/publicApi/segment/setFontSizeTest.ts index 09db567a658..78ee1274cb3 100644 --- a/packages-content-model/roosterjs-content-model-editor/test/publicApi/segment/setFontSizeTest.ts +++ b/packages-content-model/roosterjs-content-model-editor/test/publicApi/segment/setFontSizeTest.ts @@ -318,4 +318,56 @@ describe('setFontSize', () => { 1 ); }); + + it('With font size in paragraph', () => { + runTest( + { + blockGroupType: 'Document', + blocks: [ + { + blockType: 'Paragraph', + format: {}, + segmentFormat: { fontSize: '8pt', fontFamily: 'Arial' }, + segments: [ + { + segmentType: 'Text', + text: 'test', + format: {}, + isSelected: true, + }, + { + segmentType: 'Text', + text: 'test', + format: {}, + }, + ], + }, + ], + }, + { + blockGroupType: 'Document', + blocks: [ + { + blockType: 'Paragraph', + format: {}, + segmentFormat: { fontFamily: 'Arial' }, + segments: [ + { + segmentType: 'Text', + text: 'test', + format: { fontSize: '10pt' }, + isSelected: true, + }, + { + segmentType: 'Text', + text: 'test', + format: { fontSize: '8pt' }, + }, + ], + }, + ], + }, + 1 + ); + }); });