From 7cc5a1b84a94fd4473b48b312cd43a95e6cfcc25 Mon Sep 17 00:00:00 2001 From: Jiuqing Song Date: Mon, 13 May 2024 11:39:04 -0700 Subject: [PATCH 01/15] Readonly types (3rd try --- .../lib/command/paste/mergePasteContent.ts | 4 +- .../lib/modelApi/editing/cloneModel.ts | 3 +- .../modelApi/editing/getSegmentTextFormat.ts | 3 +- .../contentModel/block/ContentModelBlock.ts | 35 ++- .../block/ContentModelBlockBase.ts | 48 +++- .../contentModel/block/ContentModelDivider.ts | 33 ++- .../block/ContentModelParagraph.ts | 53 +++- .../contentModel/block/ContentModelTable.ts | 41 +++- .../block/ContentModelTableRow.ts | 46 +++- .../blockGroup/ContentModelBlockGroup.ts | 26 +- .../blockGroup/ContentModelBlockGroupBase.ts | 29 ++- .../blockGroup/ContentModelDocument.ts | 37 ++- .../blockGroup/ContentModelFormatContainer.ts | 43 +++- .../blockGroup/ContentModelGeneralBlock.ts | 50 +++- .../blockGroup/ContentModelListItem.ts | 48 +++- .../blockGroup/ContentModelTableCell.ts | 53 +++- .../lib/contentModel/common/MutableMark.ts | 29 +++ .../lib/contentModel/common/MutableType.ts | 98 ++++++++ .../lib/contentModel/common/ReadonlyMark.ts | 29 +++ .../lib/contentModel/common/Selectable.ts | 15 +- .../decorator/ContentModelCode.ts | 25 +- .../decorator/ContentModelDecorator.ts | 14 +- .../decorator/ContentModelLink.ts | 30 ++- .../decorator/ContentModelListLevel.ts | 44 +++- .../ContentModelParagraphDecorator.ts | 39 ++- .../contentModel/entity/ContentModelEntity.ts | 62 ++++- .../format/ContentModelBlockFormat.ts | 17 +- .../format/ContentModelCodeFormat.ts | 14 +- .../format/ContentModelDividerFormat.ts | 19 +- .../format/ContentModelEntityFormat.ts | 15 +- .../format/ContentModelFormatBase.ts | 4 +- .../ContentModelFormatContainerFormat.ts | 26 +- .../format/ContentModelHyperLinkFormat.ts | 17 +- .../format/ContentModelImageFormat.ts | 23 +- .../format/ContentModelListItemFormat.ts | 17 +- .../format/ContentModelListItemLevelFormat.ts | 17 +- .../format/ContentModelSegmentFormat.ts | 17 +- .../format/ContentModelTableCellFormat.ts | 23 +- .../format/ContentModelTableFormat.ts | 23 +- .../format/ContentModelWithDataset.ts | 18 +- .../format/ContentModelWithFormat.ts | 10 + .../format/metadata/DatasetFormat.ts | 5 + .../contentModel/segment/ContentModelBr.ts | 10 +- .../segment/ContentModelGeneralSegment.ts | 30 ++- .../contentModel/segment/ContentModelImage.ts | 37 ++- .../segment/ContentModelSegment.ts | 29 ++- .../segment/ContentModelSegmentBase.ts | 59 ++++- .../segment/ContentModelSelectionMarker.ts | 11 +- .../contentModel/segment/ContentModelText.ts | 21 +- .../lib/index.ts | 232 ++++++++++++++---- 50 files changed, 1379 insertions(+), 252 deletions(-) create mode 100644 packages/roosterjs-content-model-types/lib/contentModel/common/MutableMark.ts create mode 100644 packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts create mode 100644 packages/roosterjs-content-model-types/lib/contentModel/common/ReadonlyMark.ts diff --git a/packages/roosterjs-content-model-core/lib/command/paste/mergePasteContent.ts b/packages/roosterjs-content-model-core/lib/command/paste/mergePasteContent.ts index 9cd3302ad4b..b8125a6097c 100644 --- a/packages/roosterjs-content-model-core/lib/command/paste/mergePasteContent.ts +++ b/packages/roosterjs-content-model-core/lib/command/paste/mergePasteContent.ts @@ -12,12 +12,12 @@ import type { ClipboardData, CloneModelOptions, ContentModelDocument, - ContentModelSegmentFormat, + ContentModelSegmentFormatCommon, IEditor, MergeModelOption, } from 'roosterjs-content-model-types'; -const EmptySegmentFormat: Required = { +const EmptySegmentFormat: Required = { backgroundColor: '', fontFamily: '', fontSize: '', diff --git a/packages/roosterjs-content-model-dom/lib/modelApi/editing/cloneModel.ts b/packages/roosterjs-content-model-dom/lib/modelApi/editing/cloneModel.ts index 2bf5dc15344..95ee0cee0ed 100644 --- a/packages/roosterjs-content-model-dom/lib/modelApi/editing/cloneModel.ts +++ b/packages/roosterjs-content-model-dom/lib/modelApi/editing/cloneModel.ts @@ -265,12 +265,13 @@ function cloneListItem( item: ContentModelListItem, options: CloneModelOptions ): ContentModelListItem { - const { formatHolder, levels } = item; + const { formatHolder, levels, cachedElement } = item; return Object.assign( { formatHolder: cloneSelectionMarker(formatHolder), levels: levels.map(cloneListLevel), + cachedElement: handleCachedElement(cachedElement, 'cache', options), }, cloneBlockBase(item), cloneBlockGroupBase(item, options) diff --git a/packages/roosterjs-content-model-dom/lib/modelApi/editing/getSegmentTextFormat.ts b/packages/roosterjs-content-model-dom/lib/modelApi/editing/getSegmentTextFormat.ts index c8928b96cf9..cd91dbbde22 100644 --- a/packages/roosterjs-content-model-dom/lib/modelApi/editing/getSegmentTextFormat.ts +++ b/packages/roosterjs-content-model-dom/lib/modelApi/editing/getSegmentTextFormat.ts @@ -22,9 +22,10 @@ export function getSegmentTextFormat(segment: ContentModelSegment): ContentModel } const removeUndefinedValues = (format: ContentModelSegmentFormat): ContentModelSegmentFormat => { - const textFormat: Record = {}; + const textFormat: Record = {}; Object.keys(format).filter(key => { const value = format[key as keyof ContentModelSegmentFormat]; + if (value !== undefined) { textFormat[key] = value; } diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlock.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlock.ts index 59179bdd73c..c4256a3bc06 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlock.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlock.ts @@ -1,10 +1,19 @@ -import type { ContentModelDivider } from './ContentModelDivider'; -import type { ContentModelEntity } from '../entity/ContentModelEntity'; -import type { ContentModelFormatContainer } from '../blockGroup/ContentModelFormatContainer'; -import type { ContentModelGeneralBlock } from '../blockGroup/ContentModelGeneralBlock'; -import type { ContentModelListItem } from '../blockGroup/ContentModelListItem'; -import type { ContentModelParagraph } from './ContentModelParagraph'; -import type { ContentModelTable } from './ContentModelTable'; +import type { ContentModelDivider, ReadonlyContentModelDivider } from './ContentModelDivider'; +import type { ContentModelEntity, ReadonlyContentModelEntity } from '../entity/ContentModelEntity'; +import type { + ContentModelFormatContainer, + ReadonlyContentModelFormatContainer, +} from '../blockGroup/ContentModelFormatContainer'; +import type { + ContentModelGeneralBlock, + ReadonlyContentModelGeneralBlock, +} from '../blockGroup/ContentModelGeneralBlock'; +import type { + ContentModelListItem, + ReadonlyContentModelListItem, +} from '../blockGroup/ContentModelListItem'; +import type { ContentModelParagraph, ReadonlyContentModelParagraph } from './ContentModelParagraph'; +import type { ContentModelTable, ReadonlyContentModelTable } from './ContentModelTable'; /** * A union type of Content Model Block @@ -17,3 +26,15 @@ export type ContentModelBlock = | ContentModelParagraph | ContentModelEntity | ContentModelDivider; + +/** + * A union type of Content Model Block (Readonly) + */ +export type ReadonlyContentModelBlock = + | ReadonlyContentModelFormatContainer + | ReadonlyContentModelListItem + | ReadonlyContentModelGeneralBlock + | ReadonlyContentModelTable + | ReadonlyContentModelParagraph + | ReadonlyContentModelEntity + | ReadonlyContentModelDivider; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlockBase.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlockBase.ts index 8e05b45151f..6d0a4f3e532 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlockBase.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlockBase.ts @@ -1,16 +1,48 @@ -import type { ContentModelBlockFormat } from '../format/ContentModelBlockFormat'; +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { ContentModelBlockWithCache } from '../common/ContentModelBlockWithCache'; +import type { MutableMark } from '../common/MutableMark'; +import type { + ContentModelBlockFormat, + ReadonlyContentModelBlockFormat, +} from '../format/ContentModelBlockFormat'; import type { ContentModelBlockType } from './BlockType'; -import type { ContentModelWithFormat } from '../format/ContentModelWithFormat'; +import type { + ContentModelWithFormat, + ReadonlyContentModelWithFormat, +} from '../format/ContentModelWithFormat'; /** - * Base type of a block + * Common part of base type of a block */ -export interface ContentModelBlockBase< - T extends ContentModelBlockType, - TFormat extends ContentModelBlockFormat = ContentModelBlockFormat -> extends ContentModelWithFormat { +export interface ContentModelBlockBaseCommon { /** * Type of this block */ - blockType: T; + readonly blockType: T; } + +/** + * Base type of a block + */ +export interface ContentModelBlockBase< + T extends ContentModelBlockType, + TFormat extends ContentModelBlockFormat = ContentModelBlockFormat, + TCacheElement extends HTMLElement = HTMLElement +> + extends MutableMark, + ContentModelBlockBaseCommon, + ContentModelWithFormat, + ContentModelBlockWithCache {} + +/** + * Base type of a block (Readonly) + */ +export interface ReadonlyContentModelBlockBase< + T extends ContentModelBlockType, + TFormat extends ReadonlyContentModelBlockFormat = ReadonlyContentModelBlockFormat, + TCacheElement extends HTMLElement = HTMLElement +> + extends ReadonlyMark, + ContentModelBlockBaseCommon, + ReadonlyContentModelWithFormat, + ContentModelBlockWithCache {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelDivider.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelDivider.ts index 23fe4386273..1bf01b5f435 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelDivider.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelDivider.ts @@ -1,15 +1,14 @@ -import type { ContentModelBlockBase } from './ContentModelBlockBase'; -import type { ContentModelBlockWithCache } from '../common/ContentModelBlockWithCache'; -import type { ContentModelDividerFormat } from '../format/ContentModelDividerFormat'; -import type { Selectable } from '../common/Selectable'; +import type { ContentModelBlockBase, ReadonlyContentModelBlockBase } from './ContentModelBlockBase'; +import type { + ContentModelDividerFormat, + ReadonlyContentModelDividerFormat, +} from '../format/ContentModelDividerFormat'; +import type { ReadonlySelectable, Selectable } from '../common/Selectable'; /** - * Content Model of horizontal divider + * Common part of Content Model of horizontal divider */ -export interface ContentModelDivider - extends Selectable, - ContentModelBlockWithCache, - ContentModelBlockBase<'Divider', ContentModelDividerFormat> { +export interface ContentModelDividerCommon { /** * Tag name of this element, either HR or DIV */ @@ -20,3 +19,19 @@ export interface ContentModelDivider */ size?: string; } + +/** + * Content Model of horizontal divider + */ +export interface ContentModelDivider + extends Selectable, + ContentModelDividerCommon, + ContentModelBlockBase<'Divider', ContentModelDividerFormat> {} + +/** + * Content Model of horizontal divider (Readonly) + */ +export interface ReadonlyContentModelDivider + extends ReadonlySelectable, + ReadonlyContentModelBlockBase<'Divider', ReadonlyContentModelDividerFormat>, + Readonly {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelParagraph.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelParagraph.ts index cb47999a4a4..4deb7725e7d 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelParagraph.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelParagraph.ts @@ -1,14 +1,33 @@ -import type { ContentModelBlockBase } from './ContentModelBlockBase'; -import type { ContentModelBlockWithCache } from '../common/ContentModelBlockWithCache'; -import type { ContentModelParagraphDecorator } from '../decorator/ContentModelParagraphDecorator'; -import type { ContentModelSegment } from '../segment/ContentModelSegment'; -import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; +import type { ContentModelBlockBase, ReadonlyContentModelBlockBase } from './ContentModelBlockBase'; +import type { + ContentModelParagraphDecorator, + ReadonlyContentModelParagraphDecorator, +} from '../decorator/ContentModelParagraphDecorator'; +import type { + ContentModelSegment, + ReadonlyContentModelSegment, +} from '../segment/ContentModelSegment'; +import type { + ContentModelSegmentFormat, + ReadonlyContentModelSegmentFormat, +} from '../format/ContentModelSegmentFormat'; + +/** + * Common part of Content Model of Paragraph + */ +export interface ContentModelParagraphCommon { + /** + * Whether this block was created from a block HTML element or just some simple segment between other block elements. + * True means it doesn't have a related block element, false means it was from a block element + */ + isImplicit?: boolean; +} /** * Content Model of Paragraph */ export interface ContentModelParagraph - extends ContentModelBlockWithCache, + extends ContentModelParagraphCommon, ContentModelBlockBase<'Paragraph'> { /** * Segments within this paragraph @@ -24,10 +43,26 @@ export interface ContentModelParagraph * Decorator info for this paragraph, used by heading and P tags */ decorator?: ContentModelParagraphDecorator; +} + +/** + * Content Model of Paragraph (Readonly) + */ +export interface ReadonlyContentModelParagraph + extends ReadonlyContentModelBlockBase<'Paragraph'>, + Readonly { + /** + * Segments within this paragraph + */ + readonly segments: ReadonlyArray; /** - * Whether this block was created from a block HTML element or just some simple segment between other block elements. - * True means it doesn't have a related block element, false means it was from a block element + * Segment format on this paragraph. This is mostly used for default format */ - isImplicit?: boolean; + readonly segmentFormat?: ReadonlyContentModelSegmentFormat; + + /** + * Decorator info for this paragraph, used by heading and P tags + */ + readonly decorator?: ReadonlyContentModelParagraphDecorator; } diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTable.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTable.ts index c9c70ebe6c4..db8ecebcd24 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTable.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTable.ts @@ -1,17 +1,21 @@ -import type { ContentModelBlockBase } from './ContentModelBlockBase'; -import type { ContentModelBlockWithCache } from '../common/ContentModelBlockWithCache'; -import type { ContentModelTableFormat } from '../format/ContentModelTableFormat'; -import type { ContentModelTableRow } from './ContentModelTableRow'; -import type { ContentModelWithDataset } from '../format/ContentModelWithDataset'; +import type { ContentModelBlockBase, ReadonlyContentModelBlockBase } from './ContentModelBlockBase'; +import type { + ContentModelTableFormat, + ReadonlyContentModelTableFormat, +} from '../format/ContentModelTableFormat'; +import type { ContentModelTableRow, ReadonlyContentModelTableRow } from './ContentModelTableRow'; +import type { + ContentModelWithDataset, + ReadonlyContentModelWithDataset, +} from '../format/ContentModelWithDataset'; import type { TableMetadataFormat } from '../format/metadata/TableMetadataFormat'; /** * Content Model of Table */ export interface ContentModelTable - extends ContentModelBlockBase<'Table', ContentModelTableFormat>, - ContentModelWithDataset, - ContentModelBlockWithCache { + extends ContentModelBlockBase<'Table', ContentModelTableFormat, HTMLTableElement>, + ContentModelWithDataset { /** * Widths of each column */ @@ -22,3 +26,24 @@ export interface ContentModelTable */ rows: ContentModelTableRow[]; } + +/** + * Content Model of Table (Readonly) + */ +export interface ReadonlyContentModelTable + extends ReadonlyContentModelBlockBase< + 'Table', + ReadonlyContentModelTableFormat, + HTMLTableElement + >, + ReadonlyContentModelWithDataset { + /** + * Widths of each column + */ + readonly widths: ReadonlyArray; + + /** + * Cells of this table + */ + readonly rows: ReadonlyArray; +} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTableRow.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTableRow.ts index 7a5327feb01..39443c5ad9d 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTableRow.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTableRow.ts @@ -1,21 +1,53 @@ -import type { ContentModelBlockFormat } from '../format/ContentModelBlockFormat'; +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark } from '../common/MutableMark'; +import type { + ContentModelBlockFormat, + ReadonlyContentModelBlockFormat, +} from '../format/ContentModelBlockFormat'; import type { ContentModelBlockWithCache } from '../common/ContentModelBlockWithCache'; -import type { ContentModelTableCell } from '../blockGroup/ContentModelTableCell'; -import type { ContentModelWithFormat } from '../format/ContentModelWithFormat'; +import type { + ContentModelTableCell, + ReadonlyContentModelTableCell, +} from '../blockGroup/ContentModelTableCell'; +import type { + ContentModelWithFormat, + ReadonlyContentModelWithFormat, +} from '../format/ContentModelWithFormat'; /** - * Content Model of Table + * Common part of Content Model of Table */ -export interface ContentModelTableRow - extends ContentModelBlockWithCache, - ContentModelWithFormat { +export interface ContentModelTableRowCommon { /** * Heights of each row */ height: number; +} +/** + * Content Model of Table + */ +export interface ContentModelTableRow + extends MutableMark, + ContentModelTableRowCommon, + ContentModelBlockWithCache, + ContentModelWithFormat { /** * Cells of this table */ cells: ContentModelTableCell[]; } + +/** + * Content Model of Table (Readonly) + */ +export interface ReadonlyContentModelTableRow + extends ReadonlyMark, + ContentModelBlockWithCache, + ReadonlyContentModelWithFormat, + Readonly { + /** + * Cells of this table + */ + readonly cells: ReadonlyArray; +} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroup.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroup.ts index 9462d998e10..aa908291f8e 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroup.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroup.ts @@ -1,8 +1,14 @@ -import type { ContentModelDocument } from './ContentModelDocument'; -import type { ContentModelFormatContainer } from './ContentModelFormatContainer'; -import type { ContentModelGeneralBlock } from './ContentModelGeneralBlock'; -import type { ContentModelListItem } from './ContentModelListItem'; -import type { ContentModelTableCell } from './ContentModelTableCell'; +import type { ContentModelDocument, ReadonlyContentModelDocument } from './ContentModelDocument'; +import type { + ContentModelFormatContainer, + ReadonlyContentModelFormatContainer, +} from './ContentModelFormatContainer'; +import type { + ContentModelGeneralBlock, + ReadonlyContentModelGeneralBlock, +} from './ContentModelGeneralBlock'; +import type { ContentModelListItem, ReadonlyContentModelListItem } from './ContentModelListItem'; +import type { ContentModelTableCell, ReadonlyContentModelTableCell } from './ContentModelTableCell'; /** * The union type of Content Model Block Group @@ -13,3 +19,13 @@ export type ContentModelBlockGroup = | ContentModelListItem | ContentModelTableCell | ContentModelGeneralBlock; + +/** + * The union type of Content Model Block Group (Readonly) + */ +export type ReadonlyContentModelBlockGroup = + | ReadonlyContentModelDocument + | ReadonlyContentModelFormatContainer + | ReadonlyContentModelListItem + | ReadonlyContentModelTableCell + | ReadonlyContentModelGeneralBlock; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroupBase.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroupBase.ts index 648f9b1bd70..f401cf27bd6 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroupBase.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroupBase.ts @@ -1,17 +1,38 @@ -import type { ContentModelBlock } from '../block/ContentModelBlock'; +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark } from '../common/MutableMark'; +import type { ContentModelBlock, ReadonlyContentModelBlock } from '../block/ContentModelBlock'; import type { ContentModelBlockGroupType } from './BlockGroupType'; /** - * Base type of Content Model Block Group + * Common part of base type of Content Model Block Group */ -export interface ContentModelBlockGroupBase { +export interface ContentModelBlockGroupBaseCommon { /** * Type of this block group */ - blockGroupType: T; + readonly blockGroupType: T; +} +/** + * Base type of Content Model Block Group + */ +export interface ContentModelBlockGroupBase + extends MutableMark, + ContentModelBlockGroupBaseCommon { /** * Blocks under this group */ blocks: ContentModelBlock[]; } + +/** + * Base type of Content Model Block Group (Readonly) + */ +export interface ReadonlyContentModelBlockGroupBase + extends ReadonlyMark, + ContentModelBlockGroupBaseCommon { + /** + * Blocks under this group + */ + readonly blocks: ReadonlyArray; +} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelDocument.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelDocument.ts index 7f1eac6188c..63b888b13ac 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelDocument.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelDocument.ts @@ -1,15 +1,38 @@ -import type { ContentModelBlockGroupBase } from './ContentModelBlockGroupBase'; -import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; -import type { ContentModelWithFormat } from '../format/ContentModelWithFormat'; +import type { + ContentModelBlockGroupBase, + ReadonlyContentModelBlockGroupBase, +} from './ContentModelBlockGroupBase'; +import type { + ContentModelSegmentFormat, + ReadonlyContentModelSegmentFormat, +} from '../format/ContentModelSegmentFormat'; +import type { + ContentModelWithFormat, + ReadonlyContentModelWithFormat, +} from '../format/ContentModelWithFormat'; /** - * Content Model document entry point + * Common part of Content Model document entry point */ -export interface ContentModelDocument - extends ContentModelBlockGroupBase<'Document'>, - Partial> { +export interface ContentModelDocumentCommon { /** * Whether the selection in model (if any) is a revert selection (end is before start) */ hasRevertedRangeSelection?: boolean; } + +/** + * Content Model document entry point + */ +export interface ContentModelDocument + extends ContentModelDocumentCommon, + ContentModelBlockGroupBase<'Document'>, + Partial> {} + +/** + * Content Model document entry point (Readonly) + */ +export interface ReadonlyContentModelDocument + extends ReadonlyContentModelBlockGroupBase<'Document'>, + Partial>, + Readonly {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelFormatContainer.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelFormatContainer.ts index 5abe704bdea..eeb0393043a 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelFormatContainer.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelFormatContainer.ts @@ -1,15 +1,20 @@ -import type { ContentModelBlockBase } from '../block/ContentModelBlockBase'; -import type { ContentModelBlockGroupBase } from './ContentModelBlockGroupBase'; -import type { ContentModelBlockWithCache } from '../common/ContentModelBlockWithCache'; -import type { ContentModelFormatContainerFormat } from '../format/ContentModelFormatContainerFormat'; +import type { + ContentModelBlockBase, + ReadonlyContentModelBlockBase, +} from '../block/ContentModelBlockBase'; +import type { + ContentModelBlockGroupBase, + ReadonlyContentModelBlockGroupBase, +} from './ContentModelBlockGroupBase'; +import type { + ContentModelFormatContainerFormat, + ReadonlyContentModelFormatContainerFormat, +} from '../format/ContentModelFormatContainerFormat'; /** - * Content Model of Format Container + * Common part of Content Model of Format Container */ -export interface ContentModelFormatContainer - extends ContentModelBlockWithCache, - ContentModelBlockGroupBase<'FormatContainer'>, - ContentModelBlockBase<'BlockGroup', ContentModelFormatContainerFormat> { +export interface ContentModelFormatContainerCommon { /** * Tag name of this container */ @@ -21,3 +26,23 @@ export interface ContentModelFormatContainer */ zeroFontSize?: boolean; } + +/** + * Content Model of Format Container + */ +export interface ContentModelFormatContainer + extends ContentModelFormatContainerCommon, + ContentModelBlockGroupBase<'FormatContainer'>, + ContentModelBlockBase<'BlockGroup', ContentModelFormatContainerFormat, HTMLElement> {} + +/** + * Content Model of Format Container (Readonly) + */ +export interface ReadonlyContentModelFormatContainer + extends ReadonlyContentModelBlockGroupBase<'FormatContainer'>, + ReadonlyContentModelBlockBase< + 'BlockGroup', + ReadonlyContentModelFormatContainerFormat, + HTMLElement + >, + Readonly {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelGeneralBlock.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelGeneralBlock.ts index ff3899baa4f..1f39af631d8 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelGeneralBlock.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelGeneralBlock.ts @@ -1,18 +1,48 @@ -import type { ContentModelBlockBase } from '../block/ContentModelBlockBase'; -import type { ContentModelBlockFormat } from '../format/ContentModelBlockFormat'; -import type { ContentModelBlockGroupBase } from './ContentModelBlockGroupBase'; -import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; -import type { Selectable } from '../common/Selectable'; +import type { + ContentModelBlockBase, + ReadonlyContentModelBlockBase, +} from '../block/ContentModelBlockBase'; +import type { + ContentModelBlockFormat, + ReadonlyContentModelBlockFormat, +} from '../format/ContentModelBlockFormat'; +import type { + ContentModelBlockGroupBase, + ReadonlyContentModelBlockGroupBase, +} from './ContentModelBlockGroupBase'; +import type { + ContentModelSegmentFormat, + ReadonlyContentModelSegmentFormat, +} from '../format/ContentModelSegmentFormat'; +import type { ReadonlySelectable, Selectable } from '../common/Selectable'; /** - * Content Model for general Block element + * Common part of Content Model for general Block element */ -export interface ContentModelGeneralBlock - extends Selectable, - ContentModelBlockGroupBase<'General'>, - ContentModelBlockBase<'BlockGroup', ContentModelBlockFormat & ContentModelSegmentFormat> { +export interface ContentModelGeneralBlockCommon { /** * A reference to original HTML node that this model was created from */ element: HTMLElement; } + +/** + * Content Model for general Block element + */ +export interface ContentModelGeneralBlock + extends Selectable, + ContentModelGeneralBlockCommon, + ContentModelBlockGroupBase<'General'>, + ContentModelBlockBase<'BlockGroup', ContentModelBlockFormat & ContentModelSegmentFormat> {} + +/** + * Content Model for general Block element (Readonly) + */ +export interface ReadonlyContentModelGeneralBlock + extends ReadonlySelectable, + ReadonlyContentModelBlockGroupBase<'General'>, + ReadonlyContentModelBlockBase< + 'BlockGroup', + ReadonlyContentModelBlockFormat & ReadonlyContentModelSegmentFormat + >, + Readonly {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts index a7b7eabd5ff..5f29ec1cc57 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts @@ -1,15 +1,30 @@ -import type { ContentModelBlockBase } from '../block/ContentModelBlockBase'; -import type { ContentModelBlockGroupBase } from './ContentModelBlockGroupBase'; -import type { ContentModelListItemFormat } from '../format/ContentModelListItemFormat'; -import type { ContentModelListLevel } from '../decorator/ContentModelListLevel'; -import type { ContentModelSelectionMarker } from '../segment/ContentModelSelectionMarker'; +import type { + ContentModelBlockBase, + ReadonlyContentModelBlockBase, +} from '../block/ContentModelBlockBase'; +import type { + ContentModelBlockGroupBase, + ReadonlyContentModelBlockGroupBase, +} from './ContentModelBlockGroupBase'; +import type { + ContentModelListItemFormat, + ReadonlyContentModelListItemFormat, +} from '../format/ContentModelListItemFormat'; +import type { + ContentModelListLevel, + ReadonlyContentModelListLevel, +} from '../decorator/ContentModelListLevel'; +import type { + ContentModelSelectionMarker, + ReadonlyContentModelSelectionMarker, +} from '../segment/ContentModelSelectionMarker'; /** * Content Model of List Item */ export interface ContentModelListItem extends ContentModelBlockGroupBase<'ListItem'>, - ContentModelBlockBase<'BlockGroup', ContentModelListItemFormat> { + ContentModelBlockBase<'BlockGroup', ContentModelListItemFormat, HTMLLIElement> { /** * Type of this list, either ordered or unordered */ @@ -20,3 +35,24 @@ export interface ContentModelListItem */ formatHolder: ContentModelSelectionMarker; } + +/** + * Content Model of List Item (Readonly) + */ +export interface ReadonlyContentModelListItem + extends ReadonlyContentModelBlockGroupBase<'ListItem'>, + ReadonlyContentModelBlockBase< + 'BlockGroup', + ReadonlyContentModelListItemFormat, + HTMLLIElement + > { + /** + * Type of this list, either ordered or unordered + */ + readonly levels: ReadonlyArray; + + /** + * A dummy segment to hold format of this list item + */ + readonly formatHolder: ReadonlyContentModelSelectionMarker; +} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelTableCell.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelTableCell.ts index 4e51590c48b..d231cee39ea 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelTableCell.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelTableCell.ts @@ -1,20 +1,27 @@ import type { TableCellMetadataFormat } from '../format/metadata/TableCellMetadataFormat'; -import type { ContentModelBlockGroupBase } from './ContentModelBlockGroupBase'; +import type { + ContentModelBlockGroupBase, + ReadonlyContentModelBlockGroupBase, +} from './ContentModelBlockGroupBase'; import type { ContentModelBlockWithCache } from '../common/ContentModelBlockWithCache'; -import type { ContentModelTableCellFormat } from '../format/ContentModelTableCellFormat'; -import type { ContentModelWithDataset } from '../format/ContentModelWithDataset'; -import type { ContentModelWithFormat } from '../format/ContentModelWithFormat'; -import type { Selectable } from '../common/Selectable'; +import type { + ContentModelTableCellFormat, + ReadonlyContentModelTableCellFormat, +} from '../format/ContentModelTableCellFormat'; +import type { + ContentModelWithDataset, + ReadonlyContentModelWithDataset, +} from '../format/ContentModelWithDataset'; +import type { + ContentModelWithFormat, + ReadonlyContentModelWithFormat, +} from '../format/ContentModelWithFormat'; +import type { ReadonlySelectable, Selectable } from '../common/Selectable'; /** - * Content Model of Table Cell + * Common part of Content Model of Table Cell */ -export interface ContentModelTableCell - extends Selectable, - ContentModelBlockGroupBase<'TableCell'>, - ContentModelWithFormat, - ContentModelWithDataset, - ContentModelBlockWithCache { +export interface ContentModelTableCellCommon { /** * Whether this cell is spanned from left cell */ @@ -30,3 +37,25 @@ export interface ContentModelTableCell */ isHeader?: boolean; } + +/** + * Content Model of Table Cell + */ +export interface ContentModelTableCell + extends Selectable, + ContentModelTableCellCommon, + ContentModelBlockGroupBase<'TableCell'>, + ContentModelWithFormat, + ContentModelWithDataset, + ContentModelBlockWithCache {} + +/** + * Content Model of Table Cell (Readonly) + */ +export interface ReadonlyContentModelTableCell + extends ReadonlySelectable, + ReadonlyContentModelBlockGroupBase<'TableCell'>, + ReadonlyContentModelWithFormat, + ReadonlyContentModelWithDataset, + ContentModelBlockWithCache, + Readonly {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/common/MutableMark.ts b/packages/roosterjs-content-model-types/lib/contentModel/common/MutableMark.ts new file mode 100644 index 00000000000..ae5b46d684a --- /dev/null +++ b/packages/roosterjs-content-model-types/lib/contentModel/common/MutableMark.ts @@ -0,0 +1,29 @@ +/** + * A tag type to mark a content model type as mutable. + * + * This is generally a workaround to https://github.com/microsoft/TypeScript/issues/13347 + * + * In order to know if a block has been changed, we want to mark all blocks, blocks groups, segments and their members as readonly, + * When we want to change a block/segment/block group, we need to call a function to convert it to mutable. Inside this function + * we can make some change to the object (e.g. remove cached element if any) so later we know this object is changed. + * So that we expect there is a build time error if we assign a readonly object to a function that accepts mutable object only. + * However this does not happen today. + * + * To workaround it, we manually add a hidden member (dummy) to all mutable types, and add another member with readonly array type to + * readonly types. When we assign readonly object to mutable one, compiler will fail to build since the two arrays are not matching. + * So that we can know where to fix from build time. And since the dummy value is optional, it won't break existing creator code. + * + * @example + * let readonly: ReadonlyMark = {}; + * let mutable: MutableMark = {}; + * + * readonly = mutable; // OK + * mutable = readonly; // Error: Type 'ReadonlyMark' is not assignable to type 'MutableMark'. + */ +export type MutableMark = { + /** + * The mutable marker to mark an object as mutable. When assign readonly object to a mutable type, compile will fail to build + * due to this member does not exist from source type. + */ + readonly dummy?: never[]; +}; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts b/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts new file mode 100644 index 00000000000..cbe8a351149 --- /dev/null +++ b/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts @@ -0,0 +1,98 @@ +import type { ContentModelBr, ReadonlyContentModelBr } from '../segment/ContentModelBr'; +import type { ContentModelCode, ReadonlyContentModelCode } from '../decorator/ContentModelCode'; +import type { + ContentModelDivider, + ReadonlyContentModelDivider, +} from '../block/ContentModelDivider'; +import type { + ContentModelDocument, + ReadonlyContentModelDocument, +} from '../blockGroup/ContentModelDocument'; +import type { ContentModelEntity, ReadonlyContentModelEntity } from '../entity/ContentModelEntity'; +import type { + ContentModelFormatContainer, + ReadonlyContentModelFormatContainer, +} from '../blockGroup/ContentModelFormatContainer'; +import type { + ContentModelGeneralBlock, + ReadonlyContentModelGeneralBlock, +} from '../blockGroup/ContentModelGeneralBlock'; +import type { + ContentModelGeneralSegment, + ReadonlyContentModelGeneralSegment, +} from '../segment/ContentModelGeneralSegment'; +import type { ContentModelImage, ReadonlyContentModelImage } from '../segment/ContentModelImage'; +import type { ContentModelLink, ReadonlyContentModelLink } from '../decorator/ContentModelLink'; +import type { + ContentModelListItem, + ReadonlyContentModelListItem, +} from '../blockGroup/ContentModelListItem'; +import type { + ContentModelListLevel, + ReadonlyContentModelListLevel, +} from '../decorator/ContentModelListLevel'; +import type { + ContentModelParagraph, + ReadonlyContentModelParagraph, +} from '../block/ContentModelParagraph'; +import type { + ContentModelParagraphDecorator, + ReadonlyContentModelParagraphDecorator, +} from '../decorator/ContentModelParagraphDecorator'; +import type { + ContentModelSelectionMarker, + ReadonlyContentModelSelectionMarker, +} from '../segment/ContentModelSelectionMarker'; +import type { ContentModelTable, ReadonlyContentModelTable } from '../block/ContentModelTable'; +import type { + ContentModelTableCell, + ReadonlyContentModelTableCell, +} from '../blockGroup/ContentModelTableCell'; +import type { + ContentModelTableRow, + ReadonlyContentModelTableRow, +} from '../block/ContentModelTableRow'; +import type { ContentModelText, ReadonlyContentModelText } from '../segment/ContentModelText'; + +/** + * Get mutable type from its related readonly type + */ +export type MutableType = T extends ReadonlyContentModelGeneralSegment + ? ContentModelGeneralSegment + : T extends ReadonlyContentModelSelectionMarker + ? ContentModelSelectionMarker + : T extends ReadonlyContentModelImage + ? ContentModelImage + : T extends ReadonlyContentModelEntity + ? ContentModelEntity + : T extends ReadonlyContentModelText + ? ContentModelText + : T extends ReadonlyContentModelBr + ? ContentModelBr + : T extends ReadonlyContentModelParagraph + ? ContentModelParagraph + : T extends ReadonlyContentModelTable + ? ContentModelTable + : T extends ReadonlyContentModelTableRow + ? ContentModelTableRow + : T extends ReadonlyContentModelTableCell + ? ContentModelTableCell + : T extends ReadonlyContentModelFormatContainer + ? ContentModelFormatContainer + : T extends ReadonlyContentModelListItem + ? ContentModelListItem + : T extends ReadonlyContentModelListLevel + ? ContentModelListLevel + : T extends ReadonlyContentModelDivider + ? ContentModelDivider + : T extends ReadonlyContentModelDocument + ? ContentModelDocument + : T extends ReadonlyContentModelGeneralBlock + ? ContentModelGeneralBlock + : T extends ReadonlyContentModelParagraphDecorator + ? ContentModelParagraphDecorator + : T extends ReadonlyContentModelLink + ? ContentModelLink + : T extends ReadonlyContentModelCode + ? ContentModelCode + : never; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/common/ReadonlyMark.ts b/packages/roosterjs-content-model-types/lib/contentModel/common/ReadonlyMark.ts new file mode 100644 index 00000000000..e4568edf284 --- /dev/null +++ b/packages/roosterjs-content-model-types/lib/contentModel/common/ReadonlyMark.ts @@ -0,0 +1,29 @@ +/** + * A tag type to mark a content model type as readonly. + * + * This is generally a workaround to https://github.com/microsoft/TypeScript/issues/13347 + * + * In order to know if a block has been changed, we want to mark all blocks, blocks groups, segments and their members as readonly, + * When we want to change a block/segment/block group, we need to call a function to convert it to mutable. Inside this function + * we can make some change to the object (e.g. remove cached element if any) so later we know this object is changed. + * So that we expect there is a build time error if we assign a readonly object to a function that accepts mutable object only. + * However this does not happen today. + * + * To workaround it, we manually add a hidden member (dummy) to all mutable types, and add another member with readonly array type to + * readonly types. When we assign readonly object to mutable one, compiler will fail to build since the two arrays are not matching. + * So that we can know where to fix from build time. And since the dummy value is optional, it won't break existing creator code. + * + * @example + * let readonly: ReadonlyMark = {}; + * let mutable: MutableMark = {}; + * + * readonly = mutable; // OK + * mutable = readonly; // Error: Type 'ReadonlyMark' is not assignable to type 'MutableMark'. + */ +export type ReadonlyMark = { + /** + * The mutable marker to mark an object as mutable. When assign readonly object to a mutable type, compile will fail to build + * due to this member does not exist from source type. + */ + readonly dummy?: ReadonlyArray; +}; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/common/Selectable.ts b/packages/roosterjs-content-model-types/lib/contentModel/common/Selectable.ts index 2e28a98e1e2..4ceef92d5e8 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/common/Selectable.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/common/Selectable.ts @@ -1,9 +1,22 @@ +import type { MutableMark } from './MutableMark'; +import type { ReadonlyMark } from './ReadonlyMark'; + /** * Represents a selectable Content Model object */ -export interface Selectable { +export interface Selectable extends MutableMark { /** * Whether this model object is selected */ isSelected?: boolean; } + +/** + * Represents a selectable Content Model object (Readonly) + */ +export interface ReadonlySelectable extends ReadonlyMark { + /** + * Whether this model object is selected + */ + readonly isSelected?: boolean; +} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelCode.ts b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelCode.ts index b124d0e61b5..77406c02033 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelCode.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelCode.ts @@ -1,9 +1,28 @@ -import type { ContentModelCodeFormat } from '../format/ContentModelCodeFormat'; -import type { ContentModelWithFormat } from '../format/ContentModelWithFormat'; +import type { MutableMark } from '../common/MutableMark'; +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { + ContentModelCodeFormat, + ReadonlyContentModelCodeFormat, +} from '../format/ContentModelCodeFormat'; +import type { + ContentModelWithFormat, + ReadonlyContentModelWithFormat, +} from '../format/ContentModelWithFormat'; /** * Represent code info of Content Model. * ContentModelCode is a decorator but not a standalone model type, instead it need to be put inside a ContentModelSegment * since code is also a kind of segment, with some extra information */ -export interface ContentModelCode extends ContentModelWithFormat {} +export interface ContentModelCode + extends MutableMark, + ContentModelWithFormat {} + +/** + * Represent code info of Content Model. (Readonly) + * ContentModelCode is a decorator but not a standalone model type, instead it need to be put inside a ContentModelSegment + * since code is also a kind of segment, with some extra information + */ +export interface ReadonlyContentModelCode + extends ReadonlyMark, + ReadonlyContentModelWithFormat {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelDecorator.ts b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelDecorator.ts index b8fe53b3f2d..44e2a394627 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelDecorator.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelDecorator.ts @@ -1,8 +1,16 @@ -import type { ContentModelCode } from './ContentModelCode'; -import type { ContentModelLink } from './ContentModelLink'; -import type { ContentModelListLevel } from './ContentModelListLevel'; +import type { ContentModelCode, ReadonlyContentModelCode } from './ContentModelCode'; +import type { ContentModelLink, ReadonlyContentModelLink } from './ContentModelLink'; +import type { ContentModelListLevel, ReadonlyContentModelListLevel } from './ContentModelListLevel'; /** * Union type for segment decorators */ export type ContentModelDecorator = ContentModelLink | ContentModelCode | ContentModelListLevel; + +/** + * Union type for segment decorators (Readonly) + */ +export type ReadonlyContentModelDecorator = + | ReadonlyContentModelLink + | ReadonlyContentModelCode + | ReadonlyContentModelListLevel; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelLink.ts b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelLink.ts index c0622fba7ef..441fdf4d846 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelLink.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelLink.ts @@ -1,6 +1,17 @@ -import type { ContentModelHyperLinkFormat } from '../format/ContentModelHyperLinkFormat'; -import type { ContentModelWithDataset } from '../format/ContentModelWithDataset'; -import type { ContentModelWithFormat } from '../format/ContentModelWithFormat'; +import type { MutableMark } from '../common/MutableMark'; +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { + ContentModelHyperLinkFormat, + ReadonlyContentModelHyperLinkFormat, +} from '../format/ContentModelHyperLinkFormat'; +import type { + ContentModelWithDataset, + ReadonlyContentModelWithDataset, +} from '../format/ContentModelWithDataset'; +import type { + ContentModelWithFormat, + ReadonlyContentModelWithFormat, +} from '../format/ContentModelWithFormat'; /** * Represent link info of Content Model. @@ -8,5 +19,16 @@ import type { ContentModelWithFormat } from '../format/ContentModelWithFormat'; * since link is also a kind of segment, with some extra information */ export interface ContentModelLink - extends ContentModelWithFormat, + extends MutableMark, + ContentModelWithFormat, ContentModelWithDataset {} + +/** + * Represent link info of Content Model (Readonly). + * ContentModelLink is not a standalone model type, instead it need to be put inside a ContentModelSegment + * since link is also a kind of segment, with some extra information + */ +export interface ReadonlyContentModelLink + extends ReadonlyMark, + ReadonlyContentModelWithFormat, + ReadonlyContentModelWithDataset {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelListLevel.ts b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelListLevel.ts index 206d541701e..16a91a1e23d 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelListLevel.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelListLevel.ts @@ -1,16 +1,46 @@ -import type { ContentModelListItemLevelFormat } from '../format/ContentModelListItemLevelFormat'; -import type { ContentModelWithDataset } from '../format/ContentModelWithDataset'; -import type { ContentModelWithFormat } from '../format/ContentModelWithFormat'; +import type { ContentModelBlockWithCache } from '../common/ContentModelBlockWithCache'; +import type { MutableMark } from '../common/MutableMark'; +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { + ContentModelListItemLevelFormat, + ReadonlyContentModelListItemLevelFormat, +} from '../format/ContentModelListItemLevelFormat'; +import type { + ContentModelWithDataset, + ReadonlyContentModelWithDataset, +} from '../format/ContentModelWithDataset'; +import type { + ContentModelWithFormat, + ReadonlyContentModelWithFormat, +} from '../format/ContentModelWithFormat'; import type { ListMetadataFormat } from '../format/metadata/ListMetadataFormat'; /** - * Content Model of List Level + * Common part of Content Model of List Level */ -export interface ContentModelListLevel - extends ContentModelWithFormat, - ContentModelWithDataset { +export interface ContentModelListLevelCommon { /** * Type of a list, order (OL) or unordered (UL) */ listType: 'OL' | 'UL'; } + +/** + * Content Model of List Level + */ +export interface ContentModelListLevel + extends MutableMark, + ContentModelBlockWithCache, + ContentModelListLevelCommon, + ContentModelWithFormat, + ContentModelWithDataset {} + +/** + * Content Model of List Level (Readonly) + */ +export interface ReadonlyContentModelListLevel + extends ReadonlyMark, + ContentModelBlockWithCache, + ReadonlyContentModelWithFormat, + ReadonlyContentModelWithDataset, + Readonly {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelParagraphDecorator.ts b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelParagraphDecorator.ts index b3c154b6ff1..21794a2280c 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelParagraphDecorator.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelParagraphDecorator.ts @@ -1,15 +1,40 @@ -import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; -import type { ContentModelWithFormat } from '../format/ContentModelWithFormat'; +import type { MutableMark } from '../common/MutableMark'; +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { + ContentModelSegmentFormat, + ReadonlyContentModelSegmentFormat, +} from '../format/ContentModelSegmentFormat'; +import type { + ContentModelWithFormat, + ReadonlyContentModelWithFormat, +} from '../format/ContentModelWithFormat'; /** - * Represent decorator for a paragraph in Content Model - * A decorator of paragraph can represent a heading, or a P tag that act likes a paragraph but with some extra format info - * since heading is also a kind of paragraph, with some extra information + * Common part of decorator for a paragraph in Content Model */ -export interface ContentModelParagraphDecorator - extends ContentModelWithFormat { +export interface ContentModelParagraphDecoratorCommon { /** * Tag name of this paragraph */ tagName: string; } + +/** + * Represent decorator for a paragraph in Content Model + * A decorator of paragraph can represent a heading, or a P tag that act likes a paragraph but with some extra format info + * since heading is also a kind of paragraph, with some extra information + */ +export interface ContentModelParagraphDecorator + extends MutableMark, + ContentModelParagraphDecoratorCommon, + ContentModelWithFormat {} + +/** + * Represent decorator for a paragraph in Content Model (Readonly) + * A decorator of paragraph can represent a heading, or a P tag that act likes a paragraph but with some extra format info + * since heading is also a kind of paragraph, with some extra information + */ +export interface ReadonlyContentModelParagraphDecorator + extends ReadonlyMark, + ReadonlyContentModelWithFormat, + Readonly {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/entity/ContentModelEntity.ts b/packages/roosterjs-content-model-types/lib/contentModel/entity/ContentModelEntity.ts index 897a572920e..5a9889a5175 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/entity/ContentModelEntity.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/entity/ContentModelEntity.ts @@ -1,22 +1,66 @@ -import type { ContentModelBlockBase } from '../block/ContentModelBlockBase'; -import type { ContentModelBlockFormat } from '../format/ContentModelBlockFormat'; -import type { ContentModelEntityFormat } from '../format/ContentModelEntityFormat'; -import type { ContentModelSegmentBase } from '../segment/ContentModelSegmentBase'; -import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark } from '../common/MutableMark'; +import type { + ContentModelBlockBase, + ReadonlyContentModelBlockBase, +} from '../block/ContentModelBlockBase'; +import type { + ContentModelBlockFormat, + ReadonlyContentModelBlockFormat, +} from '../format/ContentModelBlockFormat'; +import type { + ContentModelEntityFormat, + ReadonlyContentModelEntityFormat, +} from '../format/ContentModelEntityFormat'; +import type { + ContentModelSegmentBase, + ReadonlyContentModelSegmentBase, +} from '../segment/ContentModelSegmentBase'; +import type { + ContentModelSegmentFormat, + ReadonlyContentModelSegmentFormat, +} from '../format/ContentModelSegmentFormat'; /** - * Content Model of Entity + * Common part of Content Model of Entity */ -export interface ContentModelEntity - extends ContentModelBlockBase<'Entity', ContentModelBlockFormat & ContentModelSegmentFormat>, - ContentModelSegmentBase<'Entity', ContentModelBlockFormat & ContentModelSegmentFormat> { +export interface ContentModelEntityCommon { /** * The wrapper DOM node of this entity which holds the info CSS classes of this entity */ wrapper: HTMLElement; +} +/** + * Content Model of Entity + */ +export interface ContentModelEntity + extends MutableMark, + ContentModelEntityCommon, + ContentModelBlockBase<'Entity', ContentModelBlockFormat & ContentModelSegmentFormat>, + ContentModelSegmentBase<'Entity', ContentModelBlockFormat & ContentModelSegmentFormat> { /** * Format of this entity */ entityFormat: ContentModelEntityFormat; } + +/** + * Content Model of Entity (Readonly) + */ +export interface ReadonlyContentModelEntity + extends ReadonlyMark, + Readonly, + ReadonlyContentModelBlockBase< + 'Entity', + ReadonlyContentModelBlockFormat & ReadonlyContentModelSegmentFormat + >, + ReadonlyContentModelSegmentBase< + 'Entity', + ReadonlyContentModelBlockFormat & ReadonlyContentModelSegmentFormat + > { + /** + * Format of this entity + */ + readonly entityFormat: ReadonlyContentModelEntityFormat; +} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelBlockFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelBlockFormat.ts index d09450d161f..60dddcc6bf9 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelBlockFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelBlockFormat.ts @@ -1,3 +1,5 @@ +import type { MutableMark } from '../common/MutableMark'; +import type { ReadonlyMark } from '../common/ReadonlyMark'; import type { BackgroundColorFormat } from './formatParts/BackgroundColorFormat'; import type { BorderFormat } from './formatParts/BorderFormat'; import type { DirectionFormat } from './formatParts/DirectionFormat'; @@ -10,9 +12,9 @@ import type { TextIndentFormat } from './formatParts/TextIndentFormat'; import type { WhiteSpaceFormat } from './formatParts/WhiteSpaceFormat'; /** - * The format object for a paragraph in Content Model + * Common part of format object for a paragraph in Content Model */ -export type ContentModelBlockFormat = BackgroundColorFormat & +export type ContentModelBlockFormatCommon = BackgroundColorFormat & DirectionFormat & TextAlignFormat & HtmlAlignFormat & @@ -22,3 +24,14 @@ export type ContentModelBlockFormat = BackgroundColorFormat & WhiteSpaceFormat & BorderFormat & TextIndentFormat; + +/** + * The format object for a paragraph in Content Model + */ +export type ContentModelBlockFormat = MutableMark & ContentModelBlockFormatCommon; + +/** + * The format object for a paragraph in Content Model (Readonly) + */ +export type ReadonlyContentModelBlockFormat = ReadonlyMark & + Readonly; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelCodeFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelCodeFormat.ts index e674a4f7552..739bf3e3ee5 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelCodeFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelCodeFormat.ts @@ -1,7 +1,19 @@ +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark } from '../common/MutableMark'; import type { DisplayFormat } from './formatParts/DisplayFormat'; import type { FontFamilyFormat } from './formatParts/FontFamilyFormat'; +/** + * Common part of format object for a code element in Content Model + */ +export type ContentModelCodeFormatCommon = FontFamilyFormat & DisplayFormat; + /** * The format object for a code element in Content Model */ -export type ContentModelCodeFormat = FontFamilyFormat & DisplayFormat; +export type ContentModelCodeFormat = MutableMark & ContentModelCodeFormatCommon; + +/** + * The format object for a code element in Content Model (Readonly) + */ +export type ReadonlyContentModelCodeFormat = ReadonlyMark & Readonly; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelDividerFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelDividerFormat.ts index bec64102174..d803cba7601 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelDividerFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelDividerFormat.ts @@ -1,8 +1,23 @@ -import type { ContentModelBlockFormat } from './ContentModelBlockFormat'; +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark } from '../common/MutableMark'; +import type { ContentModelBlockFormatCommon } from './ContentModelBlockFormat'; import type { DisplayFormat } from './formatParts/DisplayFormat'; import type { SizeFormat } from './formatParts/SizeFormat'; +/** + * Common part of format object for a divider in Content Model + */ +export type ContentModelDividerFormatCommon = DisplayFormat & + SizeFormat & + ContentModelBlockFormatCommon; + /** * The format object for a divider in Content Model */ -export type ContentModelDividerFormat = ContentModelBlockFormat & DisplayFormat & SizeFormat; +export type ContentModelDividerFormat = MutableMark & ContentModelDividerFormatCommon; + +/** + * The format object for a divider in Content Model (Readonly) + */ +export type ReadonlyContentModelDividerFormat = ReadonlyMark & + Readonly; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelEntityFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelEntityFormat.ts index 0570d49228d..1c474999fba 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelEntityFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelEntityFormat.ts @@ -1,7 +1,20 @@ +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark } from '../common/MutableMark'; import type { IdFormat } from './formatParts/IdFormat'; import type { EntityInfoFormat } from './formatParts/EntityInfoFormat'; +/** + * Common part of format object for an entity in Content Model + */ +export type ContentModelEntityFormatCommon = EntityInfoFormat & IdFormat; + /** * The format object for an entity in Content Model */ -export type ContentModelEntityFormat = EntityInfoFormat & IdFormat; +export type ContentModelEntityFormat = MutableMark & ContentModelEntityFormatCommon; + +/** + * The format object for an entity in Content Model (Readonly) + */ +export type ReadonlyContentModelEntityFormat = ReadonlyMark & + Readonly; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelFormatBase.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelFormatBase.ts index b0cce2e2ecd..313fb57025e 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelFormatBase.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelFormatBase.ts @@ -4,12 +4,14 @@ * So that we can use a single level copy ({...object}) to easily clone a format object */ export type ContentModelFormatBase< - V extends string | number | boolean | undefined | null = + V extends string | number | boolean | undefined | null | never[] | ReadonlyArray = | string | number | boolean | undefined | null + | never[] + | ReadonlyArray > = { [key: string]: V; }; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelFormatContainerFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelFormatContainerFormat.ts index e5dfb905fc5..a85ef5e2804 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelFormatContainerFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelFormatContainerFormat.ts @@ -1,12 +1,26 @@ -import type { ContentModelBlockFormat } from './ContentModelBlockFormat'; -import type { ContentModelSegmentFormat } from './ContentModelSegmentFormat'; +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark } from '../common/MutableMark'; +import type { ContentModelBlockFormatCommon } from './ContentModelBlockFormat'; +import type { ContentModelSegmentFormatCommon } from './ContentModelSegmentFormat'; import type { DisplayFormat } from './formatParts/DisplayFormat'; import type { SizeFormat } from './formatParts/SizeFormat'; +/** + * Common part of type for FormatContainer + */ +export type ContentModelFormatContainerFormatCommon = SizeFormat & + DisplayFormat & + ContentModelSegmentFormatCommon & + ContentModelBlockFormatCommon; + /** * Type for FormatContainer */ -export type ContentModelFormatContainerFormat = ContentModelBlockFormat & - ContentModelSegmentFormat & - SizeFormat & - DisplayFormat; +export type ContentModelFormatContainerFormat = MutableMark & + ContentModelFormatContainerFormatCommon; + +/** + * Type for FormatContainer (Readonly) + */ +export type ReadonlyContentModelFormatContainerFormat = ReadonlyMark & + Readonly; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelHyperLinkFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelHyperLinkFormat.ts index 129cc55d84f..282a7af1408 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelHyperLinkFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelHyperLinkFormat.ts @@ -1,3 +1,5 @@ +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark } from '../common/MutableMark'; import type { BackgroundColorFormat } from './formatParts/BackgroundColorFormat'; import type { BorderFormat } from './formatParts/BorderFormat'; import type { DisplayFormat } from './formatParts/DisplayFormat'; @@ -10,9 +12,9 @@ import type { TextColorFormat } from './formatParts/TextColorFormat'; import type { UnderlineFormat } from './formatParts/UnderlineFormat'; /** - * The format object for a hyperlink in Content Model + * Common part of format object for a hyperlink in Content Model */ -export type ContentModelHyperLinkFormat = LinkFormat & +export type ContentModelHyperLinkFormatCommon = LinkFormat & TextColorFormat & BackgroundColorFormat & UnderlineFormat & @@ -22,3 +24,14 @@ export type ContentModelHyperLinkFormat = LinkFormat & BorderFormat & SizeFormat & TextAlignFormat; + +/** + * The format object for a hyperlink in Content Model + */ +export type ContentModelHyperLinkFormat = MutableMark & ContentModelHyperLinkFormatCommon; + +/** + * The format object for a hyperlink in Content Model (Readonly) + */ +export type ReadonlyContentModelHyperLinkFormat = ReadonlyMark & + Readonly; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelImageFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelImageFormat.ts index 6f9ba413a85..ee96be64bb5 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelImageFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelImageFormat.ts @@ -1,6 +1,8 @@ +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark } from '../common/MutableMark'; import type { BorderFormat } from './formatParts/BorderFormat'; import type { BoxShadowFormat } from './formatParts/BoxShadowFormat'; -import type { ContentModelSegmentFormat } from './ContentModelSegmentFormat'; +import type { ContentModelSegmentFormatCommon } from './ContentModelSegmentFormat'; import type { DisplayFormat } from './formatParts/DisplayFormat'; import type { FloatFormat } from './formatParts/FloatFormat'; import type { IdFormat } from './formatParts/IdFormat'; @@ -10,10 +12,9 @@ import type { SizeFormat } from './formatParts/SizeFormat'; import type { VerticalAlignFormat } from './formatParts/VerticalAlignFormat'; /** - * The format object for an image in Content Model + * Common part of format object for an image in Content Model */ -export type ContentModelImageFormat = ContentModelSegmentFormat & - IdFormat & +export type ContentModelImageFormatCommon = IdFormat & SizeFormat & MarginFormat & PaddingFormat & @@ -21,4 +22,16 @@ export type ContentModelImageFormat = ContentModelSegmentFormat & BoxShadowFormat & DisplayFormat & FloatFormat & - VerticalAlignFormat; + VerticalAlignFormat & + ContentModelSegmentFormatCommon; + +/** + * The format object for an image in Content Model + */ +export type ContentModelImageFormat = MutableMark & ContentModelImageFormatCommon; + +/** + * The format object for an image in Content Model (Readonly) + */ +export type ReadonlyContentModelImageFormat = ReadonlyMark & + Readonly; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelListItemFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelListItemFormat.ts index f2d7b550b62..69903df63b5 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelListItemFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelListItemFormat.ts @@ -1,3 +1,5 @@ +import type { MutableMark } from '../common/MutableMark'; +import type { ReadonlyMark } from '../common/ReadonlyMark'; import type { BackgroundColorFormat } from './formatParts/BackgroundColorFormat'; import type { DirectionFormat } from './formatParts/DirectionFormat'; import type { LineHeightFormat } from './formatParts/LineHeightFormat'; @@ -8,9 +10,9 @@ import type { TextAlignFormat } from './formatParts/TextAlignFormat'; import type { TextIndentFormat } from './formatParts/TextIndentFormat'; /** - * The format object for a list item in Content Model + * Common part of format object for a list item in Content Model */ -export type ContentModelListItemFormat = DirectionFormat & +export type ContentModelListItemFormatCommon = DirectionFormat & LineHeightFormat & MarginFormat & PaddingFormat & @@ -18,3 +20,14 @@ export type ContentModelListItemFormat = DirectionFormat & ListStyleFormat & TextIndentFormat & BackgroundColorFormat; + +/** + * The format object for a list item in Content Model + */ +export type ContentModelListItemFormat = MutableMark & ContentModelListItemFormatCommon; + +/** + * The format object for a list item in Content Model (Readonly) + */ +export type ReadonlyContentModelListItemFormat = ReadonlyMark & + Readonly; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelListItemLevelFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelListItemLevelFormat.ts index c0ea2bf60b6..98c559a1583 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelListItemLevelFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelListItemLevelFormat.ts @@ -1,3 +1,5 @@ +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark } from '../common/MutableMark'; import type { DirectionFormat } from './formatParts/DirectionFormat'; import type { ListStyleFormat } from './formatParts/ListStyleFormat'; import type { ListThreadFormat } from './formatParts/ListThreadFormat'; @@ -6,11 +8,22 @@ import type { PaddingFormat } from './formatParts/PaddingFormat'; import type { TextAlignFormat } from './formatParts/TextAlignFormat'; /** - * The format object for a list level in Content Model + * Common part of format object for a list level in Content Model */ -export type ContentModelListItemLevelFormat = ListThreadFormat & +export type ContentModelListItemLevelFormatCommon = ListThreadFormat & DirectionFormat & TextAlignFormat & MarginFormat & PaddingFormat & ListStyleFormat; + +/** + * The format object for a list level in Content Model + */ +export type ContentModelListItemLevelFormat = MutableMark & ContentModelListItemLevelFormatCommon; + +/** + * The format object for a list level in Content Model (Readonly) + */ +export type ReadonlyContentModelListItemLevelFormat = ReadonlyMark & + Readonly; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelSegmentFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelSegmentFormat.ts index d8552973cef..789de2d021d 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelSegmentFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelSegmentFormat.ts @@ -1,3 +1,5 @@ +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark } from '../common/MutableMark'; import type { BackgroundColorFormat } from './formatParts/BackgroundColorFormat'; import type { BoldFormat } from './formatParts/BoldFormat'; import type { FontFamilyFormat } from './formatParts/FontFamilyFormat'; @@ -11,9 +13,9 @@ import type { TextColorFormat } from './formatParts/TextColorFormat'; import type { UnderlineFormat } from './formatParts/UnderlineFormat'; /** - * The format object for a segment in Content Model + * Common part of format object for a segment in Content Model */ -export type ContentModelSegmentFormat = TextColorFormat & +export type ContentModelSegmentFormatCommon = TextColorFormat & BackgroundColorFormat & LetterSpacingFormat & FontSizeFormat & @@ -24,3 +26,14 @@ export type ContentModelSegmentFormat = TextColorFormat & StrikeFormat & SuperOrSubScriptFormat & LineHeightFormat; + +/** + * The format object for a segment in Content Model + */ +export type ContentModelSegmentFormat = MutableMark & ContentModelSegmentFormatCommon; + +/** + * The format object for a segment in Content Model (Readonly) + */ +export type ReadonlyContentModelSegmentFormat = ReadonlyMark & + Readonly; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelTableCellFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelTableCellFormat.ts index 651535c95f0..592606bdee2 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelTableCellFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelTableCellFormat.ts @@ -1,16 +1,29 @@ +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark } from '../common/MutableMark'; import type { BorderBoxFormat } from './formatParts/BorderBoxFormat'; -import type { ContentModelBlockFormat } from './ContentModelBlockFormat'; +import type { ContentModelBlockFormatCommon } from './ContentModelBlockFormat'; import type { SizeFormat } from './formatParts/SizeFormat'; import type { TextColorFormat } from './formatParts/TextColorFormat'; import type { VerticalAlignFormat } from './formatParts/VerticalAlignFormat'; import type { WordBreakFormat } from '../format/formatParts/WordBreakFormat'; /** - * Format of table cell + * Common part of format of table cell */ -export type ContentModelTableCellFormat = ContentModelBlockFormat & - BorderBoxFormat & +export type ContentModelTableCellFormatCommon = BorderBoxFormat & VerticalAlignFormat & WordBreakFormat & TextColorFormat & - SizeFormat; + SizeFormat & + ContentModelBlockFormatCommon; + +/** + * Format of table cell + */ +export type ContentModelTableCellFormat = MutableMark & ContentModelTableCellFormatCommon; + +/** + * Format of table cell (Readonly) + */ +export type ReadonlyContentModelTableCellFormat = ReadonlyMark & + Readonly; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelTableFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelTableFormat.ts index 7d84b3fe376..b5e3f11a48c 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelTableFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelTableFormat.ts @@ -1,6 +1,8 @@ +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark } from '../common/MutableMark'; import type { BorderBoxFormat } from './formatParts/BorderBoxFormat'; import type { BorderFormat } from './formatParts/BorderFormat'; -import type { ContentModelBlockFormat } from './ContentModelBlockFormat'; +import type { ContentModelBlockFormatCommon } from './ContentModelBlockFormat'; import type { DisplayFormat } from './formatParts/DisplayFormat'; import type { IdFormat } from './formatParts/IdFormat'; import type { MarginFormat } from './formatParts/MarginFormat'; @@ -9,14 +11,25 @@ import type { TableLayoutFormat } from './formatParts/TableLayoutFormat'; import type { SizeFormat } from './formatParts/SizeFormat'; /** - * Format of Table + * Common part of format of Table */ -export type ContentModelTableFormat = ContentModelBlockFormat & - IdFormat & +export type ContentModelTableFormatCommon = IdFormat & BorderFormat & BorderBoxFormat & SpacingFormat & MarginFormat & DisplayFormat & TableLayoutFormat & - SizeFormat; + SizeFormat & + ContentModelBlockFormatCommon; + +/** + * Format of Table + */ +export type ContentModelTableFormat = MutableMark & ContentModelTableFormatCommon; + +/** + * Format of Table (Readonly) + */ +export type ReadonlyContentModelTableFormat = ReadonlyMark & + Readonly; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithDataset.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithDataset.ts index 0fe8f417c78..255cb1553f2 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithDataset.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithDataset.ts @@ -1,11 +1,23 @@ -import type { DatasetFormat } from './metadata/DatasetFormat'; +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark } from '../common/MutableMark'; +import type { DatasetFormat, ReadonlyDatasetFormat } from './metadata/DatasetFormat'; /** * Represents base format of an element that supports dataset and/or metadata */ -export interface ContentModelWithDataset { +export type ContentModelWithDataset = MutableMark & { /** * dataset of this element */ dataset: DatasetFormat; -} +}; + +/** + * Represents base format of an element that supports dataset and/or metadata (Readonly) + */ +export type ReadonlyContentModelWithDataset = ReadonlyMark & { + /** + * dataset of this element + */ + readonly dataset: ReadonlyDatasetFormat; +}; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithFormat.ts index 53f52e67522..cfbe0d6b821 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithFormat.ts @@ -9,3 +9,13 @@ export interface ContentModelWithFormat { */ format: T; } + +/** + * Represent a content model with format (Readonly) + */ +export interface ReadonlyContentModelWithFormat { + /** + * Format of this model + */ + readonly format: Readonly; +} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/metadata/DatasetFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/metadata/DatasetFormat.ts index e71cadf3c37..11625671ba6 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/metadata/DatasetFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/metadata/DatasetFormat.ts @@ -2,3 +2,8 @@ * Represents dataset format of Content Model */ export type DatasetFormat = Record; + +/** + * Represents dataset format of Content Model (Readonly) + */ +export type ReadonlyDatasetFormat = Readonly>; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelBr.ts b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelBr.ts index d8bf1b04871..e414626c817 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelBr.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelBr.ts @@ -1,6 +1,14 @@ -import type { ContentModelSegmentBase } from './ContentModelSegmentBase'; +import type { + ContentModelSegmentBase, + ReadonlyContentModelSegmentBase, +} from './ContentModelSegmentBase'; /** * Content Model of BR */ export interface ContentModelBr extends ContentModelSegmentBase<'Br'> {} + +/** + * Content Model of BR (Readonly) + */ +export interface ReadonlyContentModelBr extends ReadonlyContentModelSegmentBase<'Br'> {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelGeneralSegment.ts b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelGeneralSegment.ts index bbd0741c7ac..e3287e700a9 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelGeneralSegment.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelGeneralSegment.ts @@ -1,7 +1,19 @@ -import type { ContentModelBlockFormat } from '../format/ContentModelBlockFormat'; -import type { ContentModelGeneralBlock } from '../blockGroup/ContentModelGeneralBlock'; -import type { ContentModelSegmentBase } from './ContentModelSegmentBase'; -import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; +import type { + ContentModelBlockFormat, + ReadonlyContentModelBlockFormat, +} from '../format/ContentModelBlockFormat'; +import type { + ContentModelGeneralBlock, + ReadonlyContentModelGeneralBlock, +} from '../blockGroup/ContentModelGeneralBlock'; +import type { + ContentModelSegmentBase, + ReadonlyContentModelSegmentBase, +} from './ContentModelSegmentBase'; +import type { + ContentModelSegmentFormat, + ReadonlyContentModelSegmentFormat, +} from '../format/ContentModelSegmentFormat'; /** * Content Model of general Segment @@ -9,3 +21,13 @@ import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFor export interface ContentModelGeneralSegment extends ContentModelGeneralBlock, ContentModelSegmentBase<'General', ContentModelBlockFormat & ContentModelSegmentFormat> {} + +/** + * Content Model of general Segment (Readonly) + */ +export interface ReadonlyContentModelGeneralSegment + extends ReadonlyContentModelGeneralBlock, + ReadonlyContentModelSegmentBase< + 'General', + ReadonlyContentModelBlockFormat & ReadonlyContentModelSegmentFormat + > {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelImage.ts b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelImage.ts index 8b457ce4f0c..f349d9e481e 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelImage.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelImage.ts @@ -1,14 +1,21 @@ -import type { ContentModelImageFormat } from '../format/ContentModelImageFormat'; -import type { ContentModelSegmentBase } from './ContentModelSegmentBase'; -import type { ContentModelWithDataset } from '../format/ContentModelWithDataset'; +import type { + ContentModelImageFormat, + ReadonlyContentModelImageFormat, +} from '../format/ContentModelImageFormat'; +import type { + ContentModelSegmentBase, + ReadonlyContentModelSegmentBase, +} from './ContentModelSegmentBase'; +import type { + ContentModelWithDataset, + ReadonlyContentModelWithDataset, +} from '../format/ContentModelWithDataset'; import type { ImageMetadataFormat } from '../format/metadata/ImageMetadataFormat'; /** - * Content Model of IMG + * Common part of Content Model of IMG */ -export interface ContentModelImage - extends ContentModelSegmentBase<'Image', ContentModelImageFormat>, - ContentModelWithDataset { +export interface ContentModelImageCommon { /** * Image source of this IMG element */ @@ -29,3 +36,19 @@ export interface ContentModelImage */ isSelectedAsImageSelection?: boolean; } + +/** + * Content Model of IMG + */ +export interface ContentModelImage + extends ContentModelImageCommon, + ContentModelSegmentBase<'Image', ContentModelImageFormat>, + ContentModelWithDataset {} + +/** + * Content Model of IMG (Readonly) + */ +export interface ReadonlyContentModelImage + extends ReadonlyContentModelSegmentBase<'Image', ReadonlyContentModelImageFormat>, + ReadonlyContentModelWithDataset, + Readonly {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegment.ts b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegment.ts index 77fd2c68cad..687fb511796 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegment.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegment.ts @@ -1,9 +1,15 @@ -import type { ContentModelBr } from './ContentModelBr'; -import type { ContentModelEntity } from '../entity/ContentModelEntity'; -import type { ContentModelGeneralSegment } from './ContentModelGeneralSegment'; -import type { ContentModelImage } from './ContentModelImage'; -import type { ContentModelSelectionMarker } from './ContentModelSelectionMarker'; -import type { ContentModelText } from './ContentModelText'; +import type { ContentModelBr, ReadonlyContentModelBr } from './ContentModelBr'; +import type { ContentModelEntity, ReadonlyContentModelEntity } from '../entity/ContentModelEntity'; +import type { + ContentModelGeneralSegment, + ReadonlyContentModelGeneralSegment, +} from './ContentModelGeneralSegment'; +import type { ContentModelImage, ReadonlyContentModelImage } from './ContentModelImage'; +import type { + ContentModelSelectionMarker, + ReadonlyContentModelSelectionMarker, +} from './ContentModelSelectionMarker'; +import type { ContentModelText, ReadonlyContentModelText } from './ContentModelText'; /** * Union type of Content Model Segment @@ -15,3 +21,14 @@ export type ContentModelSegment = | ContentModelGeneralSegment | ContentModelEntity | ContentModelImage; + +/** + * Union type of Content Model Segment (Readonly) + */ +export type ReadonlyContentModelSegment = + | ReadonlyContentModelSelectionMarker + | ReadonlyContentModelText + | ReadonlyContentModelBr + | ReadonlyContentModelGeneralSegment + | ReadonlyContentModelEntity + | ReadonlyContentModelImage; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegmentBase.ts b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegmentBase.ts index 22df2695372..23687afb195 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegmentBase.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegmentBase.ts @@ -1,9 +1,27 @@ -import type { ContentModelCode } from '../decorator/ContentModelCode'; -import type { ContentModelLink } from '../decorator/ContentModelLink'; -import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; +import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark } from '../common/MutableMark'; +import type { ContentModelCode, ReadonlyContentModelCode } from '../decorator/ContentModelCode'; +import type { ContentModelLink, ReadonlyContentModelLink } from '../decorator/ContentModelLink'; +import type { + ContentModelSegmentFormat, + ReadonlyContentModelSegmentFormat, +} from '../format/ContentModelSegmentFormat'; import type { ContentModelSegmentType } from './SegmentType'; -import type { ContentModelWithFormat } from '../format/ContentModelWithFormat'; -import type { Selectable } from '../common/Selectable'; +import type { + ContentModelWithFormat, + ReadonlyContentModelWithFormat, +} from '../format/ContentModelWithFormat'; +import type { ReadonlySelectable, Selectable } from '../common/Selectable'; + +/** + * Common part of base type of Content Model Segment + */ +export interface ContentModelSegmentBaseCommon { + /** + * Type of this segment + */ + readonly segmentType: T; +} /** * Base type of Content Model Segment @@ -11,19 +29,40 @@ import type { Selectable } from '../common/Selectable'; export interface ContentModelSegmentBase< T extends ContentModelSegmentType, TFormat extends ContentModelSegmentFormat = ContentModelSegmentFormat -> extends Selectable, ContentModelWithFormat { +> + extends MutableMark, + Selectable, + ContentModelWithFormat, + ContentModelSegmentBaseCommon { /** - * Type of this segment + * Hyperlink info */ - segmentType: T; + link?: ContentModelLink; + /** + * Code info + */ + code?: ContentModelCode; +} + +/** + * Base type of Content Model Segment (Readonly) + */ +export interface ReadonlyContentModelSegmentBase< + T extends ContentModelSegmentType, + TFormat extends ReadonlyContentModelSegmentFormat = ReadonlyContentModelSegmentFormat +> + extends ReadonlyMark, + ReadonlySelectable, + ReadonlyContentModelWithFormat, + Readonly> { /** * Hyperlink info */ - link?: ContentModelLink; + readonly link?: ReadonlyContentModelLink; /** * Code info */ - code?: ContentModelCode; + readonly code?: ReadonlyContentModelCode; } diff --git a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSelectionMarker.ts b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSelectionMarker.ts index e99db906635..2e1f9b400eb 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSelectionMarker.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSelectionMarker.ts @@ -1,6 +1,15 @@ -import type { ContentModelSegmentBase } from './ContentModelSegmentBase'; +import type { + ContentModelSegmentBase, + ReadonlyContentModelSegmentBase, +} from './ContentModelSegmentBase'; /** * Content Model of Selection Marker */ export interface ContentModelSelectionMarker extends ContentModelSegmentBase<'SelectionMarker'> {} + +/** + * Content Model of Selection Marker (Readonly) + */ +export interface ReadonlyContentModelSelectionMarker + extends ReadonlyContentModelSegmentBase<'SelectionMarker'> {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelText.ts b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelText.ts index 5cd7c79f19b..7cee676ad6c 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelText.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelText.ts @@ -1,11 +1,26 @@ -import type { ContentModelSegmentBase } from './ContentModelSegmentBase'; +import type { + ContentModelSegmentBase, + ReadonlyContentModelSegmentBase, +} from './ContentModelSegmentBase'; /** - * Content Model for Text + * Common port of Content Model for Text */ -export interface ContentModelText extends ContentModelSegmentBase<'Text'> { +export interface ContentModelTextCommon { /** * Text content of this segment */ text: string; } + +/** + * Content Model for Text + */ +export interface ContentModelText extends ContentModelTextCommon, ContentModelSegmentBase<'Text'> {} + +/** + * Content Model for Text (Readonly) + */ +export interface ReadonlyContentModelText + extends ReadonlyContentModelSegmentBase<'Text'>, + Readonly {} diff --git a/packages/roosterjs-content-model-types/lib/index.ts b/packages/roosterjs-content-model-types/lib/index.ts index a6b748c4c68..4f4dd6d1abb 100644 --- a/packages/roosterjs-content-model-types/lib/index.ts +++ b/packages/roosterjs-content-model-types/lib/index.ts @@ -1,19 +1,73 @@ -export { ContentModelSegmentFormat } from './contentModel/format/ContentModelSegmentFormat'; -export { ContentModelWithFormat } from './contentModel/format/ContentModelWithFormat'; -export { ContentModelTableFormat } from './contentModel/format/ContentModelTableFormat'; -export { ContentModelWithDataset } from './contentModel/format/ContentModelWithDataset'; -export { ContentModelBlockFormat } from './contentModel/format/ContentModelBlockFormat'; -export { ContentModelTableCellFormat } from './contentModel/format/ContentModelTableCellFormat'; -export { ContentModelListItemFormat } from './contentModel/format/ContentModelListItemFormat'; -export { ContentModelListItemLevelFormat } from './contentModel/format/ContentModelListItemLevelFormat'; -export { ContentModelHyperLinkFormat } from './contentModel/format/ContentModelHyperLinkFormat'; -export { ContentModelCodeFormat } from './contentModel/format/ContentModelCodeFormat'; -export { ContentModelFormatContainerFormat } from './contentModel/format/ContentModelFormatContainerFormat'; -export { ContentModelDividerFormat } from './contentModel/format/ContentModelDividerFormat'; +export { + ContentModelSegmentFormat, + ContentModelSegmentFormatCommon, + ReadonlyContentModelSegmentFormat, +} from './contentModel/format/ContentModelSegmentFormat'; +export { + ContentModelWithFormat, + ReadonlyContentModelWithFormat, +} from './contentModel/format/ContentModelWithFormat'; +export { + ContentModelTableFormat, + ContentModelTableFormatCommon, + ReadonlyContentModelTableFormat, +} from './contentModel/format/ContentModelTableFormat'; +export { + ContentModelWithDataset, + ReadonlyContentModelWithDataset, +} from './contentModel/format/ContentModelWithDataset'; +export { + ContentModelBlockFormat, + ContentModelBlockFormatCommon, + ReadonlyContentModelBlockFormat, +} from './contentModel/format/ContentModelBlockFormat'; +export { + ContentModelTableCellFormat, + ContentModelTableCellFormatCommon, + ReadonlyContentModelTableCellFormat, +} from './contentModel/format/ContentModelTableCellFormat'; +export { + ContentModelListItemFormat, + ContentModelListItemFormatCommon, + ReadonlyContentModelListItemFormat, +} from './contentModel/format/ContentModelListItemFormat'; +export { + ContentModelListItemLevelFormat, + ContentModelListItemLevelFormatCommon, + ReadonlyContentModelListItemLevelFormat, +} from './contentModel/format/ContentModelListItemLevelFormat'; +export { + ContentModelHyperLinkFormat, + ContentModelHyperLinkFormatCommon, + ReadonlyContentModelHyperLinkFormat, +} from './contentModel/format/ContentModelHyperLinkFormat'; +export { + ContentModelCodeFormat, + ContentModelCodeFormatCommon, + ReadonlyContentModelCodeFormat, +} from './contentModel/format/ContentModelCodeFormat'; +export { + ContentModelFormatContainerFormat, + ContentModelFormatContainerFormatCommon, + ReadonlyContentModelFormatContainerFormat, +} from './contentModel/format/ContentModelFormatContainerFormat'; +export { + ContentModelDividerFormat, + ContentModelDividerFormatCommon, + ReadonlyContentModelDividerFormat, +} from './contentModel/format/ContentModelDividerFormat'; export { ContentModelFormatBase } from './contentModel/format/ContentModelFormatBase'; export { ContentModelFormatMap } from './contentModel/format/ContentModelFormatMap'; -export { ContentModelImageFormat } from './contentModel/format/ContentModelImageFormat'; -export { ContentModelEntityFormat } from './contentModel/format/ContentModelEntityFormat'; +export { + ContentModelImageFormat, + ContentModelImageFormatCommon, + ReadonlyContentModelImageFormat, +} from './contentModel/format/ContentModelImageFormat'; +export { + ContentModelEntityFormat, + ContentModelEntityFormatCommon, + ReadonlyContentModelEntityFormat, +} from './contentModel/format/ContentModelEntityFormat'; export { FormatHandlerTypeMap, FormatKey } from './contentModel/format/FormatHandlerTypeMap'; export { BackgroundColorFormat } from './contentModel/format/formatParts/BackgroundColorFormat'; @@ -50,7 +104,7 @@ export { ListStyleFormat } from './contentModel/format/formatParts/ListStyleForm export { FloatFormat } from './contentModel/format/formatParts/FloatFormat'; export { EntityInfoFormat } from './contentModel/format/formatParts/EntityInfoFormat'; -export { DatasetFormat } from './contentModel/format/metadata/DatasetFormat'; +export { DatasetFormat, ReadonlyDatasetFormat } from './contentModel/format/metadata/DatasetFormat'; export { TableMetadataFormat } from './contentModel/format/metadata/TableMetadataFormat'; export { ListMetadataFormat } from './contentModel/format/metadata/ListMetadataFormat'; export { @@ -89,39 +143,133 @@ export { DeleteResult } from './enum/DeleteResult'; export { InsertEntityPosition } from './enum/InsertEntityPosition'; export { ExportContentMode } from './enum/ExportContentMode'; -export { ContentModelBlock } from './contentModel/block/ContentModelBlock'; -export { ContentModelParagraph } from './contentModel/block/ContentModelParagraph'; -export { ContentModelTable } from './contentModel/block/ContentModelTable'; -export { ContentModelDivider } from './contentModel/block/ContentModelDivider'; -export { ContentModelBlockBase } from './contentModel/block/ContentModelBlockBase'; +export { + ContentModelBlock, + ReadonlyContentModelBlock, +} from './contentModel/block/ContentModelBlock'; +export { + ContentModelParagraph, + ContentModelParagraphCommon, + ReadonlyContentModelParagraph, +} from './contentModel/block/ContentModelParagraph'; +export { + ContentModelTable, + ReadonlyContentModelTable, +} from './contentModel/block/ContentModelTable'; +export { + ContentModelDivider, + ContentModelDividerCommon, + ReadonlyContentModelDivider, +} from './contentModel/block/ContentModelDivider'; +export { + ContentModelBlockBase, + ContentModelBlockBaseCommon, + ReadonlyContentModelBlockBase, +} from './contentModel/block/ContentModelBlockBase'; export { ContentModelBlockWithCache } from './contentModel/common/ContentModelBlockWithCache'; -export { ContentModelTableRow } from './contentModel/block/ContentModelTableRow'; +export { + ContentModelTableRow, + ContentModelTableRowCommon, + ReadonlyContentModelTableRow, +} from './contentModel/block/ContentModelTableRow'; -export { ContentModelEntity } from './contentModel/entity/ContentModelEntity'; +export { + ContentModelEntity, + ContentModelEntityCommon, + ReadonlyContentModelEntity, +} from './contentModel/entity/ContentModelEntity'; + +export { + ContentModelDocument, + ContentModelDocumentCommon, + ReadonlyContentModelDocument, +} from './contentModel/blockGroup/ContentModelDocument'; +export { + ContentModelBlockGroupBase, + ContentModelBlockGroupBaseCommon, + ReadonlyContentModelBlockGroupBase, +} from './contentModel/blockGroup/ContentModelBlockGroupBase'; +export { + ContentModelFormatContainer, + ContentModelFormatContainerCommon, + ReadonlyContentModelFormatContainer, +} from './contentModel/blockGroup/ContentModelFormatContainer'; +export { + ContentModelGeneralBlock, + ContentModelGeneralBlockCommon, + ReadonlyContentModelGeneralBlock, +} from './contentModel/blockGroup/ContentModelGeneralBlock'; +export { + ContentModelListItem, + ReadonlyContentModelListItem, +} from './contentModel/blockGroup/ContentModelListItem'; +export { + ContentModelTableCell, + ContentModelTableCellCommon, + ReadonlyContentModelTableCell, +} from './contentModel/blockGroup/ContentModelTableCell'; +export { + ContentModelBlockGroup, + ReadonlyContentModelBlockGroup, +} from './contentModel/blockGroup/ContentModelBlockGroup'; -export { ContentModelDocument } from './contentModel/blockGroup/ContentModelDocument'; -export { ContentModelBlockGroupBase } from './contentModel/blockGroup/ContentModelBlockGroupBase'; -export { ContentModelFormatContainer } from './contentModel/blockGroup/ContentModelFormatContainer'; -export { ContentModelGeneralBlock } from './contentModel/blockGroup/ContentModelGeneralBlock'; -export { ContentModelListItem } from './contentModel/blockGroup/ContentModelListItem'; -export { ContentModelTableCell } from './contentModel/blockGroup/ContentModelTableCell'; -export { ContentModelBlockGroup } from './contentModel/blockGroup/ContentModelBlockGroup'; +export { ContentModelBr, ReadonlyContentModelBr } from './contentModel/segment/ContentModelBr'; +export { + ContentModelGeneralSegment, + ReadonlyContentModelGeneralSegment, +} from './contentModel/segment/ContentModelGeneralSegment'; +export { + ContentModelImage, + ContentModelImageCommon, + ReadonlyContentModelImage, +} from './contentModel/segment/ContentModelImage'; +export { + ContentModelText, + ContentModelTextCommon, + ReadonlyContentModelText, +} from './contentModel/segment/ContentModelText'; +export { + ContentModelSelectionMarker, + ReadonlyContentModelSelectionMarker, +} from './contentModel/segment/ContentModelSelectionMarker'; +export { + ContentModelSegmentBase, + ContentModelSegmentBaseCommon, + ReadonlyContentModelSegmentBase, +} from './contentModel/segment/ContentModelSegmentBase'; +export { + ContentModelSegment, + ReadonlyContentModelSegment, +} from './contentModel/segment/ContentModelSegment'; -export { ContentModelBr } from './contentModel/segment/ContentModelBr'; -export { ContentModelGeneralSegment } from './contentModel/segment/ContentModelGeneralSegment'; -export { ContentModelImage } from './contentModel/segment/ContentModelImage'; -export { ContentModelText } from './contentModel/segment/ContentModelText'; -export { ContentModelSelectionMarker } from './contentModel/segment/ContentModelSelectionMarker'; -export { ContentModelSegmentBase } from './contentModel/segment/ContentModelSegmentBase'; -export { ContentModelSegment } from './contentModel/segment/ContentModelSegment'; +export { + ContentModelCode, + ReadonlyContentModelCode, +} from './contentModel/decorator/ContentModelCode'; +export { + ContentModelLink, + ReadonlyContentModelLink, +} from './contentModel/decorator/ContentModelLink'; +export { + ContentModelParagraphDecorator, + ContentModelParagraphDecoratorCommon, + ReadonlyContentModelParagraphDecorator, +} from './contentModel/decorator/ContentModelParagraphDecorator'; +export { + ContentModelDecorator, + ReadonlyContentModelDecorator, +} from './contentModel/decorator/ContentModelDecorator'; +export { + ContentModelListLevel, + ContentModelListLevelCommon, + ReadonlyContentModelListLevel, +} from './contentModel/decorator/ContentModelListLevel'; -export { ContentModelCode } from './contentModel/decorator/ContentModelCode'; -export { ContentModelLink } from './contentModel/decorator/ContentModelLink'; -export { ContentModelParagraphDecorator } from './contentModel/decorator/ContentModelParagraphDecorator'; -export { ContentModelDecorator } from './contentModel/decorator/ContentModelDecorator'; -export { ContentModelListLevel } from './contentModel/decorator/ContentModelListLevel'; +export { Selectable, ReadonlySelectable } from './contentModel/common/Selectable'; +export { ReadonlyMark } from './contentModel/common/ReadonlyMark'; +export { MutableMark } from './contentModel/common/MutableMark'; +export { MutableType } from './contentModel/common/MutableType'; -export { Selectable } from './contentModel/common/Selectable'; export { DOMSelection, SelectionType, From 3ff07793285c320434b1e0702660b4a8fee6a9e7 Mon Sep 17 00:00:00 2001 From: jiuqingsong Date: Tue, 14 May 2024 08:35:54 -0700 Subject: [PATCH 02/15] Improve --- .../block/ContentModelBlockBase.ts | 7 +- .../contentModel/block/ContentModelDivider.ts | 7 +- .../block/ContentModelParagraph.ts | 7 +- .../contentModel/block/ContentModelTable.ts | 11 +-- .../block/ContentModelTableRow.ts | 7 +- .../blockGroup/ContentModelDocument.ts | 7 +- .../blockGroup/ContentModelFormatContainer.ts | 11 +-- .../blockGroup/ContentModelGeneralBlock.ts | 12 +--- .../blockGroup/ContentModelListItem.ts | 11 +-- .../blockGroup/ContentModelTableCell.ts | 7 +- .../decorator/ContentModelCode.ts | 7 +- .../decorator/ContentModelLink.ts | 7 +- .../decorator/ContentModelListLevel.ts | 7 +- .../ContentModelParagraphDecorator.ts | 7 +- .../contentModel/entity/ContentModelEntity.ts | 21 ++---- .../format/ContentModelBlockFormat.ts | 17 +---- .../format/ContentModelCodeFormat.ts | 14 +--- .../format/ContentModelDividerFormat.ts | 19 +---- .../format/ContentModelEntityFormat.ts | 15 +--- .../format/ContentModelFormatBase.ts | 4 +- .../ContentModelFormatContainerFormat.ts | 26 ++----- .../format/ContentModelHyperLinkFormat.ts | 17 +---- .../format/ContentModelImageFormat.ts | 23 ++---- .../format/ContentModelListItemFormat.ts | 17 +---- .../format/ContentModelListItemLevelFormat.ts | 17 +---- .../format/ContentModelSegmentFormat.ts | 17 +---- .../format/ContentModelTableCellFormat.ts | 23 ++---- .../format/ContentModelTableFormat.ts | 23 ++---- .../format/ContentModelWithDataset.ts | 6 +- .../segment/ContentModelGeneralSegment.ts | 12 +--- .../contentModel/segment/ContentModelImage.ts | 7 +- .../segment/ContentModelSegmentBase.ts | 7 +- .../lib/index.ts | 72 ++++--------------- 33 files changed, 92 insertions(+), 380 deletions(-) diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlockBase.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlockBase.ts index 6d0a4f3e532..6ccf329e98c 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlockBase.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlockBase.ts @@ -1,10 +1,7 @@ import type { ReadonlyMark } from '../common/ReadonlyMark'; import type { ContentModelBlockWithCache } from '../common/ContentModelBlockWithCache'; import type { MutableMark } from '../common/MutableMark'; -import type { - ContentModelBlockFormat, - ReadonlyContentModelBlockFormat, -} from '../format/ContentModelBlockFormat'; +import type { ContentModelBlockFormat } from '../format/ContentModelBlockFormat'; import type { ContentModelBlockType } from './BlockType'; import type { ContentModelWithFormat, @@ -39,7 +36,7 @@ export interface ContentModelBlockBase< */ export interface ReadonlyContentModelBlockBase< T extends ContentModelBlockType, - TFormat extends ReadonlyContentModelBlockFormat = ReadonlyContentModelBlockFormat, + TFormat extends ContentModelBlockFormat = ContentModelBlockFormat, TCacheElement extends HTMLElement = HTMLElement > extends ReadonlyMark, diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelDivider.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelDivider.ts index 1bf01b5f435..c38c9d15734 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelDivider.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelDivider.ts @@ -1,8 +1,5 @@ import type { ContentModelBlockBase, ReadonlyContentModelBlockBase } from './ContentModelBlockBase'; -import type { - ContentModelDividerFormat, - ReadonlyContentModelDividerFormat, -} from '../format/ContentModelDividerFormat'; +import type { ContentModelDividerFormat } from '../format/ContentModelDividerFormat'; import type { ReadonlySelectable, Selectable } from '../common/Selectable'; /** @@ -33,5 +30,5 @@ export interface ContentModelDivider */ export interface ReadonlyContentModelDivider extends ReadonlySelectable, - ReadonlyContentModelBlockBase<'Divider', ReadonlyContentModelDividerFormat>, + ReadonlyContentModelBlockBase<'Divider', ContentModelDividerFormat>, Readonly {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelParagraph.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelParagraph.ts index 4deb7725e7d..987c7033a3b 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelParagraph.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelParagraph.ts @@ -7,10 +7,7 @@ import type { ContentModelSegment, ReadonlyContentModelSegment, } from '../segment/ContentModelSegment'; -import type { - ContentModelSegmentFormat, - ReadonlyContentModelSegmentFormat, -} from '../format/ContentModelSegmentFormat'; +import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; /** * Common part of Content Model of Paragraph @@ -59,7 +56,7 @@ export interface ReadonlyContentModelParagraph /** * Segment format on this paragraph. This is mostly used for default format */ - readonly segmentFormat?: ReadonlyContentModelSegmentFormat; + readonly segmentFormat?: ContentModelSegmentFormat; /** * Decorator info for this paragraph, used by heading and P tags diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTable.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTable.ts index db8ecebcd24..b13dfeb8975 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTable.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTable.ts @@ -1,8 +1,5 @@ import type { ContentModelBlockBase, ReadonlyContentModelBlockBase } from './ContentModelBlockBase'; -import type { - ContentModelTableFormat, - ReadonlyContentModelTableFormat, -} from '../format/ContentModelTableFormat'; +import type { ContentModelTableFormat } from '../format/ContentModelTableFormat'; import type { ContentModelTableRow, ReadonlyContentModelTableRow } from './ContentModelTableRow'; import type { ContentModelWithDataset, @@ -31,11 +28,7 @@ export interface ContentModelTable * Content Model of Table (Readonly) */ export interface ReadonlyContentModelTable - extends ReadonlyContentModelBlockBase< - 'Table', - ReadonlyContentModelTableFormat, - HTMLTableElement - >, + extends ReadonlyContentModelBlockBase<'Table', ContentModelTableFormat, HTMLTableElement>, ReadonlyContentModelWithDataset { /** * Widths of each column diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTableRow.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTableRow.ts index 39443c5ad9d..449ae86076d 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTableRow.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTableRow.ts @@ -1,9 +1,6 @@ import type { ReadonlyMark } from '../common/ReadonlyMark'; import type { MutableMark } from '../common/MutableMark'; -import type { - ContentModelBlockFormat, - ReadonlyContentModelBlockFormat, -} from '../format/ContentModelBlockFormat'; +import type { ContentModelBlockFormat } from '../format/ContentModelBlockFormat'; import type { ContentModelBlockWithCache } from '../common/ContentModelBlockWithCache'; import type { ContentModelTableCell, @@ -44,7 +41,7 @@ export interface ContentModelTableRow export interface ReadonlyContentModelTableRow extends ReadonlyMark, ContentModelBlockWithCache, - ReadonlyContentModelWithFormat, + ReadonlyContentModelWithFormat, Readonly { /** * Cells of this table diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelDocument.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelDocument.ts index 63b888b13ac..3dc7175dc62 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelDocument.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelDocument.ts @@ -2,10 +2,7 @@ import type { ContentModelBlockGroupBase, ReadonlyContentModelBlockGroupBase, } from './ContentModelBlockGroupBase'; -import type { - ContentModelSegmentFormat, - ReadonlyContentModelSegmentFormat, -} from '../format/ContentModelSegmentFormat'; +import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; import type { ContentModelWithFormat, ReadonlyContentModelWithFormat, @@ -34,5 +31,5 @@ export interface ContentModelDocument */ export interface ReadonlyContentModelDocument extends ReadonlyContentModelBlockGroupBase<'Document'>, - Partial>, + Partial>, Readonly {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelFormatContainer.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelFormatContainer.ts index eeb0393043a..c8573111673 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelFormatContainer.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelFormatContainer.ts @@ -6,10 +6,7 @@ import type { ContentModelBlockGroupBase, ReadonlyContentModelBlockGroupBase, } from './ContentModelBlockGroupBase'; -import type { - ContentModelFormatContainerFormat, - ReadonlyContentModelFormatContainerFormat, -} from '../format/ContentModelFormatContainerFormat'; +import type { ContentModelFormatContainerFormat } from '../format/ContentModelFormatContainerFormat'; /** * Common part of Content Model of Format Container @@ -40,9 +37,5 @@ export interface ContentModelFormatContainer */ export interface ReadonlyContentModelFormatContainer extends ReadonlyContentModelBlockGroupBase<'FormatContainer'>, - ReadonlyContentModelBlockBase< - 'BlockGroup', - ReadonlyContentModelFormatContainerFormat, - HTMLElement - >, + ReadonlyContentModelBlockBase<'BlockGroup', ContentModelFormatContainerFormat, HTMLElement>, Readonly {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelGeneralBlock.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelGeneralBlock.ts index 1f39af631d8..caefb55a56d 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelGeneralBlock.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelGeneralBlock.ts @@ -2,18 +2,12 @@ import type { ContentModelBlockBase, ReadonlyContentModelBlockBase, } from '../block/ContentModelBlockBase'; -import type { - ContentModelBlockFormat, - ReadonlyContentModelBlockFormat, -} from '../format/ContentModelBlockFormat'; +import type { ContentModelBlockFormat } from '../format/ContentModelBlockFormat'; import type { ContentModelBlockGroupBase, ReadonlyContentModelBlockGroupBase, } from './ContentModelBlockGroupBase'; -import type { - ContentModelSegmentFormat, - ReadonlyContentModelSegmentFormat, -} from '../format/ContentModelSegmentFormat'; +import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; import type { ReadonlySelectable, Selectable } from '../common/Selectable'; /** @@ -43,6 +37,6 @@ export interface ReadonlyContentModelGeneralBlock ReadonlyContentModelBlockGroupBase<'General'>, ReadonlyContentModelBlockBase< 'BlockGroup', - ReadonlyContentModelBlockFormat & ReadonlyContentModelSegmentFormat + ContentModelBlockFormat & ContentModelSegmentFormat >, Readonly {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts index 5f29ec1cc57..a801f9d41e4 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts @@ -6,10 +6,7 @@ import type { ContentModelBlockGroupBase, ReadonlyContentModelBlockGroupBase, } from './ContentModelBlockGroupBase'; -import type { - ContentModelListItemFormat, - ReadonlyContentModelListItemFormat, -} from '../format/ContentModelListItemFormat'; +import type { ContentModelListItemFormat } from '../format/ContentModelListItemFormat'; import type { ContentModelListLevel, ReadonlyContentModelListLevel, @@ -41,11 +38,7 @@ export interface ContentModelListItem */ export interface ReadonlyContentModelListItem extends ReadonlyContentModelBlockGroupBase<'ListItem'>, - ReadonlyContentModelBlockBase< - 'BlockGroup', - ReadonlyContentModelListItemFormat, - HTMLLIElement - > { + ReadonlyContentModelBlockBase<'BlockGroup', ContentModelListItemFormat, HTMLLIElement> { /** * Type of this list, either ordered or unordered */ diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelTableCell.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelTableCell.ts index d231cee39ea..0f8674a5861 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelTableCell.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelTableCell.ts @@ -4,10 +4,7 @@ import type { ReadonlyContentModelBlockGroupBase, } from './ContentModelBlockGroupBase'; import type { ContentModelBlockWithCache } from '../common/ContentModelBlockWithCache'; -import type { - ContentModelTableCellFormat, - ReadonlyContentModelTableCellFormat, -} from '../format/ContentModelTableCellFormat'; +import type { ContentModelTableCellFormat } from '../format/ContentModelTableCellFormat'; import type { ContentModelWithDataset, ReadonlyContentModelWithDataset, @@ -55,7 +52,7 @@ export interface ContentModelTableCell export interface ReadonlyContentModelTableCell extends ReadonlySelectable, ReadonlyContentModelBlockGroupBase<'TableCell'>, - ReadonlyContentModelWithFormat, + ReadonlyContentModelWithFormat, ReadonlyContentModelWithDataset, ContentModelBlockWithCache, Readonly {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelCode.ts b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelCode.ts index 77406c02033..353cdc61fee 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelCode.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelCode.ts @@ -1,9 +1,6 @@ import type { MutableMark } from '../common/MutableMark'; import type { ReadonlyMark } from '../common/ReadonlyMark'; -import type { - ContentModelCodeFormat, - ReadonlyContentModelCodeFormat, -} from '../format/ContentModelCodeFormat'; +import type { ContentModelCodeFormat } from '../format/ContentModelCodeFormat'; import type { ContentModelWithFormat, ReadonlyContentModelWithFormat, @@ -25,4 +22,4 @@ export interface ContentModelCode */ export interface ReadonlyContentModelCode extends ReadonlyMark, - ReadonlyContentModelWithFormat {} + ReadonlyContentModelWithFormat {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelLink.ts b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelLink.ts index 441fdf4d846..18856a29424 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelLink.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelLink.ts @@ -1,9 +1,6 @@ import type { MutableMark } from '../common/MutableMark'; import type { ReadonlyMark } from '../common/ReadonlyMark'; -import type { - ContentModelHyperLinkFormat, - ReadonlyContentModelHyperLinkFormat, -} from '../format/ContentModelHyperLinkFormat'; +import type { ContentModelHyperLinkFormat } from '../format/ContentModelHyperLinkFormat'; import type { ContentModelWithDataset, ReadonlyContentModelWithDataset, @@ -30,5 +27,5 @@ export interface ContentModelLink */ export interface ReadonlyContentModelLink extends ReadonlyMark, - ReadonlyContentModelWithFormat, + ReadonlyContentModelWithFormat, ReadonlyContentModelWithDataset {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelListLevel.ts b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelListLevel.ts index 16a91a1e23d..ccb346e9845 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelListLevel.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelListLevel.ts @@ -1,10 +1,7 @@ import type { ContentModelBlockWithCache } from '../common/ContentModelBlockWithCache'; import type { MutableMark } from '../common/MutableMark'; import type { ReadonlyMark } from '../common/ReadonlyMark'; -import type { - ContentModelListItemLevelFormat, - ReadonlyContentModelListItemLevelFormat, -} from '../format/ContentModelListItemLevelFormat'; +import type { ContentModelListItemLevelFormat } from '../format/ContentModelListItemLevelFormat'; import type { ContentModelWithDataset, ReadonlyContentModelWithDataset, @@ -41,6 +38,6 @@ export interface ContentModelListLevel export interface ReadonlyContentModelListLevel extends ReadonlyMark, ContentModelBlockWithCache, - ReadonlyContentModelWithFormat, + ReadonlyContentModelWithFormat, ReadonlyContentModelWithDataset, Readonly {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelParagraphDecorator.ts b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelParagraphDecorator.ts index 21794a2280c..b838b7f01bc 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelParagraphDecorator.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelParagraphDecorator.ts @@ -1,9 +1,6 @@ import type { MutableMark } from '../common/MutableMark'; import type { ReadonlyMark } from '../common/ReadonlyMark'; -import type { - ContentModelSegmentFormat, - ReadonlyContentModelSegmentFormat, -} from '../format/ContentModelSegmentFormat'; +import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; import type { ContentModelWithFormat, ReadonlyContentModelWithFormat, @@ -36,5 +33,5 @@ export interface ContentModelParagraphDecorator */ export interface ReadonlyContentModelParagraphDecorator extends ReadonlyMark, - ReadonlyContentModelWithFormat, + ReadonlyContentModelWithFormat, Readonly {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/entity/ContentModelEntity.ts b/packages/roosterjs-content-model-types/lib/contentModel/entity/ContentModelEntity.ts index 5a9889a5175..a44731bc54f 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/entity/ContentModelEntity.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/entity/ContentModelEntity.ts @@ -4,22 +4,13 @@ import type { ContentModelBlockBase, ReadonlyContentModelBlockBase, } from '../block/ContentModelBlockBase'; -import type { - ContentModelBlockFormat, - ReadonlyContentModelBlockFormat, -} from '../format/ContentModelBlockFormat'; -import type { - ContentModelEntityFormat, - ReadonlyContentModelEntityFormat, -} from '../format/ContentModelEntityFormat'; +import type { ContentModelBlockFormat } from '../format/ContentModelBlockFormat'; +import type { ContentModelEntityFormat } from '../format/ContentModelEntityFormat'; import type { ContentModelSegmentBase, ReadonlyContentModelSegmentBase, } from '../segment/ContentModelSegmentBase'; -import type { - ContentModelSegmentFormat, - ReadonlyContentModelSegmentFormat, -} from '../format/ContentModelSegmentFormat'; +import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; /** * Common part of Content Model of Entity @@ -53,14 +44,14 @@ export interface ReadonlyContentModelEntity Readonly, ReadonlyContentModelBlockBase< 'Entity', - ReadonlyContentModelBlockFormat & ReadonlyContentModelSegmentFormat + ContentModelBlockFormat & ContentModelSegmentFormat >, ReadonlyContentModelSegmentBase< 'Entity', - ReadonlyContentModelBlockFormat & ReadonlyContentModelSegmentFormat + ContentModelBlockFormat & ContentModelSegmentFormat > { /** * Format of this entity */ - readonly entityFormat: ReadonlyContentModelEntityFormat; + readonly entityFormat: Readonly; } diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelBlockFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelBlockFormat.ts index 60dddcc6bf9..d09450d161f 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelBlockFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelBlockFormat.ts @@ -1,5 +1,3 @@ -import type { MutableMark } from '../common/MutableMark'; -import type { ReadonlyMark } from '../common/ReadonlyMark'; import type { BackgroundColorFormat } from './formatParts/BackgroundColorFormat'; import type { BorderFormat } from './formatParts/BorderFormat'; import type { DirectionFormat } from './formatParts/DirectionFormat'; @@ -12,9 +10,9 @@ import type { TextIndentFormat } from './formatParts/TextIndentFormat'; import type { WhiteSpaceFormat } from './formatParts/WhiteSpaceFormat'; /** - * Common part of format object for a paragraph in Content Model + * The format object for a paragraph in Content Model */ -export type ContentModelBlockFormatCommon = BackgroundColorFormat & +export type ContentModelBlockFormat = BackgroundColorFormat & DirectionFormat & TextAlignFormat & HtmlAlignFormat & @@ -24,14 +22,3 @@ export type ContentModelBlockFormatCommon = BackgroundColorFormat & WhiteSpaceFormat & BorderFormat & TextIndentFormat; - -/** - * The format object for a paragraph in Content Model - */ -export type ContentModelBlockFormat = MutableMark & ContentModelBlockFormatCommon; - -/** - * The format object for a paragraph in Content Model (Readonly) - */ -export type ReadonlyContentModelBlockFormat = ReadonlyMark & - Readonly; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelCodeFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelCodeFormat.ts index 739bf3e3ee5..e674a4f7552 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelCodeFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelCodeFormat.ts @@ -1,19 +1,7 @@ -import type { ReadonlyMark } from '../common/ReadonlyMark'; -import type { MutableMark } from '../common/MutableMark'; import type { DisplayFormat } from './formatParts/DisplayFormat'; import type { FontFamilyFormat } from './formatParts/FontFamilyFormat'; -/** - * Common part of format object for a code element in Content Model - */ -export type ContentModelCodeFormatCommon = FontFamilyFormat & DisplayFormat; - /** * The format object for a code element in Content Model */ -export type ContentModelCodeFormat = MutableMark & ContentModelCodeFormatCommon; - -/** - * The format object for a code element in Content Model (Readonly) - */ -export type ReadonlyContentModelCodeFormat = ReadonlyMark & Readonly; +export type ContentModelCodeFormat = FontFamilyFormat & DisplayFormat; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelDividerFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelDividerFormat.ts index d803cba7601..bec64102174 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelDividerFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelDividerFormat.ts @@ -1,23 +1,8 @@ -import type { ReadonlyMark } from '../common/ReadonlyMark'; -import type { MutableMark } from '../common/MutableMark'; -import type { ContentModelBlockFormatCommon } from './ContentModelBlockFormat'; +import type { ContentModelBlockFormat } from './ContentModelBlockFormat'; import type { DisplayFormat } from './formatParts/DisplayFormat'; import type { SizeFormat } from './formatParts/SizeFormat'; -/** - * Common part of format object for a divider in Content Model - */ -export type ContentModelDividerFormatCommon = DisplayFormat & - SizeFormat & - ContentModelBlockFormatCommon; - /** * The format object for a divider in Content Model */ -export type ContentModelDividerFormat = MutableMark & ContentModelDividerFormatCommon; - -/** - * The format object for a divider in Content Model (Readonly) - */ -export type ReadonlyContentModelDividerFormat = ReadonlyMark & - Readonly; +export type ContentModelDividerFormat = ContentModelBlockFormat & DisplayFormat & SizeFormat; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelEntityFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelEntityFormat.ts index 1c474999fba..0570d49228d 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelEntityFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelEntityFormat.ts @@ -1,20 +1,7 @@ -import type { ReadonlyMark } from '../common/ReadonlyMark'; -import type { MutableMark } from '../common/MutableMark'; import type { IdFormat } from './formatParts/IdFormat'; import type { EntityInfoFormat } from './formatParts/EntityInfoFormat'; -/** - * Common part of format object for an entity in Content Model - */ -export type ContentModelEntityFormatCommon = EntityInfoFormat & IdFormat; - /** * The format object for an entity in Content Model */ -export type ContentModelEntityFormat = MutableMark & ContentModelEntityFormatCommon; - -/** - * The format object for an entity in Content Model (Readonly) - */ -export type ReadonlyContentModelEntityFormat = ReadonlyMark & - Readonly; +export type ContentModelEntityFormat = EntityInfoFormat & IdFormat; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelFormatBase.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelFormatBase.ts index 313fb57025e..b0cce2e2ecd 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelFormatBase.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelFormatBase.ts @@ -4,14 +4,12 @@ * So that we can use a single level copy ({...object}) to easily clone a format object */ export type ContentModelFormatBase< - V extends string | number | boolean | undefined | null | never[] | ReadonlyArray = + V extends string | number | boolean | undefined | null = | string | number | boolean | undefined | null - | never[] - | ReadonlyArray > = { [key: string]: V; }; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelFormatContainerFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelFormatContainerFormat.ts index a85ef5e2804..e5dfb905fc5 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelFormatContainerFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelFormatContainerFormat.ts @@ -1,26 +1,12 @@ -import type { ReadonlyMark } from '../common/ReadonlyMark'; -import type { MutableMark } from '../common/MutableMark'; -import type { ContentModelBlockFormatCommon } from './ContentModelBlockFormat'; -import type { ContentModelSegmentFormatCommon } from './ContentModelSegmentFormat'; +import type { ContentModelBlockFormat } from './ContentModelBlockFormat'; +import type { ContentModelSegmentFormat } from './ContentModelSegmentFormat'; import type { DisplayFormat } from './formatParts/DisplayFormat'; import type { SizeFormat } from './formatParts/SizeFormat'; -/** - * Common part of type for FormatContainer - */ -export type ContentModelFormatContainerFormatCommon = SizeFormat & - DisplayFormat & - ContentModelSegmentFormatCommon & - ContentModelBlockFormatCommon; - /** * Type for FormatContainer */ -export type ContentModelFormatContainerFormat = MutableMark & - ContentModelFormatContainerFormatCommon; - -/** - * Type for FormatContainer (Readonly) - */ -export type ReadonlyContentModelFormatContainerFormat = ReadonlyMark & - Readonly; +export type ContentModelFormatContainerFormat = ContentModelBlockFormat & + ContentModelSegmentFormat & + SizeFormat & + DisplayFormat; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelHyperLinkFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelHyperLinkFormat.ts index 282a7af1408..129cc55d84f 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelHyperLinkFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelHyperLinkFormat.ts @@ -1,5 +1,3 @@ -import type { ReadonlyMark } from '../common/ReadonlyMark'; -import type { MutableMark } from '../common/MutableMark'; import type { BackgroundColorFormat } from './formatParts/BackgroundColorFormat'; import type { BorderFormat } from './formatParts/BorderFormat'; import type { DisplayFormat } from './formatParts/DisplayFormat'; @@ -12,9 +10,9 @@ import type { TextColorFormat } from './formatParts/TextColorFormat'; import type { UnderlineFormat } from './formatParts/UnderlineFormat'; /** - * Common part of format object for a hyperlink in Content Model + * The format object for a hyperlink in Content Model */ -export type ContentModelHyperLinkFormatCommon = LinkFormat & +export type ContentModelHyperLinkFormat = LinkFormat & TextColorFormat & BackgroundColorFormat & UnderlineFormat & @@ -24,14 +22,3 @@ export type ContentModelHyperLinkFormatCommon = LinkFormat & BorderFormat & SizeFormat & TextAlignFormat; - -/** - * The format object for a hyperlink in Content Model - */ -export type ContentModelHyperLinkFormat = MutableMark & ContentModelHyperLinkFormatCommon; - -/** - * The format object for a hyperlink in Content Model (Readonly) - */ -export type ReadonlyContentModelHyperLinkFormat = ReadonlyMark & - Readonly; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelImageFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelImageFormat.ts index ee96be64bb5..6f9ba413a85 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelImageFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelImageFormat.ts @@ -1,8 +1,6 @@ -import type { ReadonlyMark } from '../common/ReadonlyMark'; -import type { MutableMark } from '../common/MutableMark'; import type { BorderFormat } from './formatParts/BorderFormat'; import type { BoxShadowFormat } from './formatParts/BoxShadowFormat'; -import type { ContentModelSegmentFormatCommon } from './ContentModelSegmentFormat'; +import type { ContentModelSegmentFormat } from './ContentModelSegmentFormat'; import type { DisplayFormat } from './formatParts/DisplayFormat'; import type { FloatFormat } from './formatParts/FloatFormat'; import type { IdFormat } from './formatParts/IdFormat'; @@ -12,9 +10,10 @@ import type { SizeFormat } from './formatParts/SizeFormat'; import type { VerticalAlignFormat } from './formatParts/VerticalAlignFormat'; /** - * Common part of format object for an image in Content Model + * The format object for an image in Content Model */ -export type ContentModelImageFormatCommon = IdFormat & +export type ContentModelImageFormat = ContentModelSegmentFormat & + IdFormat & SizeFormat & MarginFormat & PaddingFormat & @@ -22,16 +21,4 @@ export type ContentModelImageFormatCommon = IdFormat & BoxShadowFormat & DisplayFormat & FloatFormat & - VerticalAlignFormat & - ContentModelSegmentFormatCommon; - -/** - * The format object for an image in Content Model - */ -export type ContentModelImageFormat = MutableMark & ContentModelImageFormatCommon; - -/** - * The format object for an image in Content Model (Readonly) - */ -export type ReadonlyContentModelImageFormat = ReadonlyMark & - Readonly; + VerticalAlignFormat; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelListItemFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelListItemFormat.ts index 69903df63b5..f2d7b550b62 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelListItemFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelListItemFormat.ts @@ -1,5 +1,3 @@ -import type { MutableMark } from '../common/MutableMark'; -import type { ReadonlyMark } from '../common/ReadonlyMark'; import type { BackgroundColorFormat } from './formatParts/BackgroundColorFormat'; import type { DirectionFormat } from './formatParts/DirectionFormat'; import type { LineHeightFormat } from './formatParts/LineHeightFormat'; @@ -10,9 +8,9 @@ import type { TextAlignFormat } from './formatParts/TextAlignFormat'; import type { TextIndentFormat } from './formatParts/TextIndentFormat'; /** - * Common part of format object for a list item in Content Model + * The format object for a list item in Content Model */ -export type ContentModelListItemFormatCommon = DirectionFormat & +export type ContentModelListItemFormat = DirectionFormat & LineHeightFormat & MarginFormat & PaddingFormat & @@ -20,14 +18,3 @@ export type ContentModelListItemFormatCommon = DirectionFormat & ListStyleFormat & TextIndentFormat & BackgroundColorFormat; - -/** - * The format object for a list item in Content Model - */ -export type ContentModelListItemFormat = MutableMark & ContentModelListItemFormatCommon; - -/** - * The format object for a list item in Content Model (Readonly) - */ -export type ReadonlyContentModelListItemFormat = ReadonlyMark & - Readonly; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelListItemLevelFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelListItemLevelFormat.ts index 98c559a1583..c0ea2bf60b6 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelListItemLevelFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelListItemLevelFormat.ts @@ -1,5 +1,3 @@ -import type { ReadonlyMark } from '../common/ReadonlyMark'; -import type { MutableMark } from '../common/MutableMark'; import type { DirectionFormat } from './formatParts/DirectionFormat'; import type { ListStyleFormat } from './formatParts/ListStyleFormat'; import type { ListThreadFormat } from './formatParts/ListThreadFormat'; @@ -8,22 +6,11 @@ import type { PaddingFormat } from './formatParts/PaddingFormat'; import type { TextAlignFormat } from './formatParts/TextAlignFormat'; /** - * Common part of format object for a list level in Content Model + * The format object for a list level in Content Model */ -export type ContentModelListItemLevelFormatCommon = ListThreadFormat & +export type ContentModelListItemLevelFormat = ListThreadFormat & DirectionFormat & TextAlignFormat & MarginFormat & PaddingFormat & ListStyleFormat; - -/** - * The format object for a list level in Content Model - */ -export type ContentModelListItemLevelFormat = MutableMark & ContentModelListItemLevelFormatCommon; - -/** - * The format object for a list level in Content Model (Readonly) - */ -export type ReadonlyContentModelListItemLevelFormat = ReadonlyMark & - Readonly; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelSegmentFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelSegmentFormat.ts index 789de2d021d..d8552973cef 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelSegmentFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelSegmentFormat.ts @@ -1,5 +1,3 @@ -import type { ReadonlyMark } from '../common/ReadonlyMark'; -import type { MutableMark } from '../common/MutableMark'; import type { BackgroundColorFormat } from './formatParts/BackgroundColorFormat'; import type { BoldFormat } from './formatParts/BoldFormat'; import type { FontFamilyFormat } from './formatParts/FontFamilyFormat'; @@ -13,9 +11,9 @@ import type { TextColorFormat } from './formatParts/TextColorFormat'; import type { UnderlineFormat } from './formatParts/UnderlineFormat'; /** - * Common part of format object for a segment in Content Model + * The format object for a segment in Content Model */ -export type ContentModelSegmentFormatCommon = TextColorFormat & +export type ContentModelSegmentFormat = TextColorFormat & BackgroundColorFormat & LetterSpacingFormat & FontSizeFormat & @@ -26,14 +24,3 @@ export type ContentModelSegmentFormatCommon = TextColorFormat & StrikeFormat & SuperOrSubScriptFormat & LineHeightFormat; - -/** - * The format object for a segment in Content Model - */ -export type ContentModelSegmentFormat = MutableMark & ContentModelSegmentFormatCommon; - -/** - * The format object for a segment in Content Model (Readonly) - */ -export type ReadonlyContentModelSegmentFormat = ReadonlyMark & - Readonly; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelTableCellFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelTableCellFormat.ts index 592606bdee2..651535c95f0 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelTableCellFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelTableCellFormat.ts @@ -1,29 +1,16 @@ -import type { ReadonlyMark } from '../common/ReadonlyMark'; -import type { MutableMark } from '../common/MutableMark'; import type { BorderBoxFormat } from './formatParts/BorderBoxFormat'; -import type { ContentModelBlockFormatCommon } from './ContentModelBlockFormat'; +import type { ContentModelBlockFormat } from './ContentModelBlockFormat'; import type { SizeFormat } from './formatParts/SizeFormat'; import type { TextColorFormat } from './formatParts/TextColorFormat'; import type { VerticalAlignFormat } from './formatParts/VerticalAlignFormat'; import type { WordBreakFormat } from '../format/formatParts/WordBreakFormat'; /** - * Common part of format of table cell + * Format of table cell */ -export type ContentModelTableCellFormatCommon = BorderBoxFormat & +export type ContentModelTableCellFormat = ContentModelBlockFormat & + BorderBoxFormat & VerticalAlignFormat & WordBreakFormat & TextColorFormat & - SizeFormat & - ContentModelBlockFormatCommon; - -/** - * Format of table cell - */ -export type ContentModelTableCellFormat = MutableMark & ContentModelTableCellFormatCommon; - -/** - * Format of table cell (Readonly) - */ -export type ReadonlyContentModelTableCellFormat = ReadonlyMark & - Readonly; + SizeFormat; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelTableFormat.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelTableFormat.ts index b5e3f11a48c..7d84b3fe376 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelTableFormat.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelTableFormat.ts @@ -1,8 +1,6 @@ -import type { ReadonlyMark } from '../common/ReadonlyMark'; -import type { MutableMark } from '../common/MutableMark'; import type { BorderBoxFormat } from './formatParts/BorderBoxFormat'; import type { BorderFormat } from './formatParts/BorderFormat'; -import type { ContentModelBlockFormatCommon } from './ContentModelBlockFormat'; +import type { ContentModelBlockFormat } from './ContentModelBlockFormat'; import type { DisplayFormat } from './formatParts/DisplayFormat'; import type { IdFormat } from './formatParts/IdFormat'; import type { MarginFormat } from './formatParts/MarginFormat'; @@ -11,25 +9,14 @@ import type { TableLayoutFormat } from './formatParts/TableLayoutFormat'; import type { SizeFormat } from './formatParts/SizeFormat'; /** - * Common part of format of Table + * Format of Table */ -export type ContentModelTableFormatCommon = IdFormat & +export type ContentModelTableFormat = ContentModelBlockFormat & + IdFormat & BorderFormat & BorderBoxFormat & SpacingFormat & MarginFormat & DisplayFormat & TableLayoutFormat & - SizeFormat & - ContentModelBlockFormatCommon; - -/** - * Format of Table - */ -export type ContentModelTableFormat = MutableMark & ContentModelTableFormatCommon; - -/** - * Format of Table (Readonly) - */ -export type ReadonlyContentModelTableFormat = ReadonlyMark & - Readonly; + SizeFormat; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithDataset.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithDataset.ts index 255cb1553f2..f79e379ee04 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithDataset.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithDataset.ts @@ -1,11 +1,9 @@ -import type { ReadonlyMark } from '../common/ReadonlyMark'; -import type { MutableMark } from '../common/MutableMark'; import type { DatasetFormat, ReadonlyDatasetFormat } from './metadata/DatasetFormat'; /** * Represents base format of an element that supports dataset and/or metadata */ -export type ContentModelWithDataset = MutableMark & { +export type ContentModelWithDataset = { /** * dataset of this element */ @@ -15,7 +13,7 @@ export type ContentModelWithDataset = MutableMark & { /** * Represents base format of an element that supports dataset and/or metadata (Readonly) */ -export type ReadonlyContentModelWithDataset = ReadonlyMark & { +export type ReadonlyContentModelWithDataset = { /** * dataset of this element */ diff --git a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelGeneralSegment.ts b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelGeneralSegment.ts index e3287e700a9..cca9d00d8e0 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelGeneralSegment.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelGeneralSegment.ts @@ -1,7 +1,4 @@ -import type { - ContentModelBlockFormat, - ReadonlyContentModelBlockFormat, -} from '../format/ContentModelBlockFormat'; +import type { ContentModelBlockFormat } from '../format/ContentModelBlockFormat'; import type { ContentModelGeneralBlock, ReadonlyContentModelGeneralBlock, @@ -10,10 +7,7 @@ import type { ContentModelSegmentBase, ReadonlyContentModelSegmentBase, } from './ContentModelSegmentBase'; -import type { - ContentModelSegmentFormat, - ReadonlyContentModelSegmentFormat, -} from '../format/ContentModelSegmentFormat'; +import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; /** * Content Model of general Segment @@ -29,5 +23,5 @@ export interface ReadonlyContentModelGeneralSegment extends ReadonlyContentModelGeneralBlock, ReadonlyContentModelSegmentBase< 'General', - ReadonlyContentModelBlockFormat & ReadonlyContentModelSegmentFormat + ContentModelBlockFormat & ContentModelSegmentFormat > {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelImage.ts b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelImage.ts index f349d9e481e..9b7e531d728 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelImage.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelImage.ts @@ -1,7 +1,4 @@ -import type { - ContentModelImageFormat, - ReadonlyContentModelImageFormat, -} from '../format/ContentModelImageFormat'; +import type { ContentModelImageFormat } from '../format/ContentModelImageFormat'; import type { ContentModelSegmentBase, ReadonlyContentModelSegmentBase, @@ -49,6 +46,6 @@ export interface ContentModelImage * Content Model of IMG (Readonly) */ export interface ReadonlyContentModelImage - extends ReadonlyContentModelSegmentBase<'Image', ReadonlyContentModelImageFormat>, + extends ReadonlyContentModelSegmentBase<'Image', ContentModelImageFormat>, ReadonlyContentModelWithDataset, Readonly {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegmentBase.ts b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegmentBase.ts index 23687afb195..4c6f2636a25 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegmentBase.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegmentBase.ts @@ -2,10 +2,7 @@ import type { ReadonlyMark } from '../common/ReadonlyMark'; import type { MutableMark } from '../common/MutableMark'; import type { ContentModelCode, ReadonlyContentModelCode } from '../decorator/ContentModelCode'; import type { ContentModelLink, ReadonlyContentModelLink } from '../decorator/ContentModelLink'; -import type { - ContentModelSegmentFormat, - ReadonlyContentModelSegmentFormat, -} from '../format/ContentModelSegmentFormat'; +import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; import type { ContentModelSegmentType } from './SegmentType'; import type { ContentModelWithFormat, @@ -50,7 +47,7 @@ export interface ContentModelSegmentBase< */ export interface ReadonlyContentModelSegmentBase< T extends ContentModelSegmentType, - TFormat extends ReadonlyContentModelSegmentFormat = ReadonlyContentModelSegmentFormat + TFormat extends ContentModelSegmentFormat = ContentModelSegmentFormat > extends ReadonlyMark, ReadonlySelectable, diff --git a/packages/roosterjs-content-model-types/lib/index.ts b/packages/roosterjs-content-model-types/lib/index.ts index 4f4dd6d1abb..16ea23b8d07 100644 --- a/packages/roosterjs-content-model-types/lib/index.ts +++ b/packages/roosterjs-content-model-types/lib/index.ts @@ -1,73 +1,25 @@ -export { - ContentModelSegmentFormat, - ContentModelSegmentFormatCommon, - ReadonlyContentModelSegmentFormat, -} from './contentModel/format/ContentModelSegmentFormat'; +export { ContentModelSegmentFormat } from './contentModel/format/ContentModelSegmentFormat'; export { ContentModelWithFormat, ReadonlyContentModelWithFormat, } from './contentModel/format/ContentModelWithFormat'; -export { - ContentModelTableFormat, - ContentModelTableFormatCommon, - ReadonlyContentModelTableFormat, -} from './contentModel/format/ContentModelTableFormat'; +export { ContentModelTableFormat } from './contentModel/format/ContentModelTableFormat'; export { ContentModelWithDataset, ReadonlyContentModelWithDataset, } from './contentModel/format/ContentModelWithDataset'; -export { - ContentModelBlockFormat, - ContentModelBlockFormatCommon, - ReadonlyContentModelBlockFormat, -} from './contentModel/format/ContentModelBlockFormat'; -export { - ContentModelTableCellFormat, - ContentModelTableCellFormatCommon, - ReadonlyContentModelTableCellFormat, -} from './contentModel/format/ContentModelTableCellFormat'; -export { - ContentModelListItemFormat, - ContentModelListItemFormatCommon, - ReadonlyContentModelListItemFormat, -} from './contentModel/format/ContentModelListItemFormat'; -export { - ContentModelListItemLevelFormat, - ContentModelListItemLevelFormatCommon, - ReadonlyContentModelListItemLevelFormat, -} from './contentModel/format/ContentModelListItemLevelFormat'; -export { - ContentModelHyperLinkFormat, - ContentModelHyperLinkFormatCommon, - ReadonlyContentModelHyperLinkFormat, -} from './contentModel/format/ContentModelHyperLinkFormat'; -export { - ContentModelCodeFormat, - ContentModelCodeFormatCommon, - ReadonlyContentModelCodeFormat, -} from './contentModel/format/ContentModelCodeFormat'; -export { - ContentModelFormatContainerFormat, - ContentModelFormatContainerFormatCommon, - ReadonlyContentModelFormatContainerFormat, -} from './contentModel/format/ContentModelFormatContainerFormat'; -export { - ContentModelDividerFormat, - ContentModelDividerFormatCommon, - ReadonlyContentModelDividerFormat, -} from './contentModel/format/ContentModelDividerFormat'; +export { ContentModelBlockFormat } from './contentModel/format/ContentModelBlockFormat'; +export { ContentModelTableCellFormat } from './contentModel/format/ContentModelTableCellFormat'; +export { ContentModelListItemFormat } from './contentModel/format/ContentModelListItemFormat'; +export { ContentModelListItemLevelFormat } from './contentModel/format/ContentModelListItemLevelFormat'; +export { ContentModelHyperLinkFormat } from './contentModel/format/ContentModelHyperLinkFormat'; +export { ContentModelCodeFormat } from './contentModel/format/ContentModelCodeFormat'; +export { ContentModelFormatContainerFormat } from './contentModel/format/ContentModelFormatContainerFormat'; +export { ContentModelDividerFormat } from './contentModel/format/ContentModelDividerFormat'; export { ContentModelFormatBase } from './contentModel/format/ContentModelFormatBase'; export { ContentModelFormatMap } from './contentModel/format/ContentModelFormatMap'; -export { - ContentModelImageFormat, - ContentModelImageFormatCommon, - ReadonlyContentModelImageFormat, -} from './contentModel/format/ContentModelImageFormat'; -export { - ContentModelEntityFormat, - ContentModelEntityFormatCommon, - ReadonlyContentModelEntityFormat, -} from './contentModel/format/ContentModelEntityFormat'; +export { ContentModelImageFormat } from './contentModel/format/ContentModelImageFormat'; +export { ContentModelEntityFormat } from './contentModel/format/ContentModelEntityFormat'; export { FormatHandlerTypeMap, FormatKey } from './contentModel/format/FormatHandlerTypeMap'; export { BackgroundColorFormat } from './contentModel/format/formatParts/BackgroundColorFormat'; From 950a4ae6913c5a3426517a5badb471541f8b7af9 Mon Sep 17 00:00:00 2001 From: jiuqingsong Date: Tue, 14 May 2024 08:47:34 -0700 Subject: [PATCH 03/15] fix build --- .../lib/command/paste/mergePasteContent.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/roosterjs-content-model-core/lib/command/paste/mergePasteContent.ts b/packages/roosterjs-content-model-core/lib/command/paste/mergePasteContent.ts index b8125a6097c..9cd3302ad4b 100644 --- a/packages/roosterjs-content-model-core/lib/command/paste/mergePasteContent.ts +++ b/packages/roosterjs-content-model-core/lib/command/paste/mergePasteContent.ts @@ -12,12 +12,12 @@ import type { ClipboardData, CloneModelOptions, ContentModelDocument, - ContentModelSegmentFormatCommon, + ContentModelSegmentFormat, IEditor, MergeModelOption, } from 'roosterjs-content-model-types'; -const EmptySegmentFormat: Required = { +const EmptySegmentFormat: Required = { backgroundColor: '', fontFamily: '', fontSize: '', From 2574fe2dbde60cd56bf4b39412647086ec46e93f Mon Sep 17 00:00:00 2001 From: Jiuqing Song Date: Tue, 14 May 2024 13:31:37 -0700 Subject: [PATCH 04/15] Improve --- .../roosterjs-content-model-dom/lib/index.ts | 1 + .../lib/modelApi/common/mutate.ts | 99 +++++++++++++++++++ .../blockGroup/ContentModelBlockGroup.ts | 30 +++++- .../blockGroup/ContentModelBlockGroupBase.ts | 33 +++++-- .../blockGroup/ContentModelDocument.ts | 15 ++- .../blockGroup/ContentModelFormatContainer.ts | 19 +++- .../blockGroup/ContentModelGeneralBlock.ts | 14 ++- .../blockGroup/ContentModelListItem.ts | 22 ++++- .../blockGroup/ContentModelTableCell.ts | 24 +++-- .../lib/contentModel/common/MutableType.ts | 24 ++--- .../format/ContentModelWithDataset.ts | 6 +- .../segment/ContentModelGeneralSegment.ts | 8 ++ .../lib/index.ts | 8 ++ 13 files changed, 261 insertions(+), 42 deletions(-) create mode 100644 packages/roosterjs-content-model-dom/lib/modelApi/common/mutate.ts diff --git a/packages/roosterjs-content-model-dom/lib/index.ts b/packages/roosterjs-content-model-dom/lib/index.ts index d2f8789135a..d871e3d46f2 100644 --- a/packages/roosterjs-content-model-dom/lib/index.ts +++ b/packages/roosterjs-content-model-dom/lib/index.ts @@ -55,6 +55,7 @@ export { createDivider } from './modelApi/creators/createDivider'; export { createListLevel } from './modelApi/creators/createListLevel'; export { createEmptyModel } from './modelApi/creators/createEmptyModel'; +export { mutateBlock, mutateSegments, mutateSegment } from './modelApi/common/mutate'; export { addBlock } from './modelApi/common/addBlock'; export { addCode } from './modelApi/common/addDecorators'; export { addLink } from './modelApi/common/addDecorators'; diff --git a/packages/roosterjs-content-model-dom/lib/modelApi/common/mutate.ts b/packages/roosterjs-content-model-dom/lib/modelApi/common/mutate.ts new file mode 100644 index 00000000000..699bb3e7616 --- /dev/null +++ b/packages/roosterjs-content-model-dom/lib/modelApi/common/mutate.ts @@ -0,0 +1,99 @@ +import type { + ContentModelParagraph, + ContentModelSegment, + MutableType, + ReadonlyContentModelBlock, + ReadonlyContentModelBlockGroup, + ReadonlyContentModelListItem, + ReadonlyContentModelParagraph, + ReadonlyContentModelSegment, + ReadonlyContentModelTable, +} from 'roosterjs-content-model-types'; + +/** + * Convert a readonly block to mutable block, clear cached element if exist + * @param block The block to convert from + * @returns The same block object of its related mutable type + */ +export function mutateBlock( + block: T +): MutableType { + if (block.cachedElement) { + delete block.cachedElement; + } + + if (isTable(block)) { + block.rows.forEach(row => { + delete row.cachedElement; + }); + } else if (isListItem(block)) { + block.levels.forEach(level => delete level.cachedElement); + } + + const result = (block as unknown) as MutableType; + + return result; +} + +/** + * Convert segments of a readonly paragraph to be mutable. + * Segments that are not belong to the given paragraph will be skipped + * @param paragraph The readonly paragraph to convert from + * @param segments The segments to convert from + */ +export function mutateSegments( + paragraph: ReadonlyContentModelParagraph, + segments: ReadonlyContentModelSegment[] +): [ContentModelParagraph, ContentModelSegment[], number[]] { + const mutablePara = mutateBlock(paragraph); + const result: [ContentModelParagraph, ContentModelSegment[], number[]] = [mutablePara, [], []]; + + if (segments) { + segments.forEach(segment => { + const index = paragraph.segments.indexOf(segment); + + if (index >= 0) { + result[1].push(mutablePara.segments[index]); + result[2].push(index); + } + }); + } + + return result; +} + +/** + * Convert a readonly segment to be mutable, together with its owner paragraph + * If the segment does not belong to the given paragraph, return null for the segment + * @param paragraph The readonly paragraph to convert from + * @param segment The segment to convert from + */ +export function mutateSegment( + paragraph: ReadonlyContentModelParagraph, + segment: T, + callback?: (segment: MutableType, paragraph: ContentModelParagraph, index: number) => void +): [ContentModelParagraph, MutableType | null, number] { + const [mutablePara, mutableSegments, indexes] = mutateSegments(paragraph, [segment]); + const mutableSegment = + (mutableSegments[0] as ReadonlyContentModelSegment) == segment + ? (mutableSegments[0] as MutableType) + : null; + + if (callback && mutableSegment) { + callback(mutableSegments[0] as MutableType, mutablePara, indexes[0]); + } + + return [mutablePara, mutableSegment, indexes[0] ?? -1]; +} + +function isTable( + obj: ReadonlyContentModelBlockGroup | ReadonlyContentModelBlock +): obj is ReadonlyContentModelTable { + return (obj as ReadonlyContentModelTable).blockType == 'Table'; +} + +function isListItem( + obj: ReadonlyContentModelBlockGroup | ReadonlyContentModelBlock +): obj is ReadonlyContentModelListItem { + return (obj as ReadonlyContentModelListItem).blockGroupType == 'ListItem'; +} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroup.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroup.ts index aa908291f8e..9be2dd2b791 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroup.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroup.ts @@ -1,14 +1,28 @@ -import type { ContentModelDocument, ReadonlyContentModelDocument } from './ContentModelDocument'; +import type { + ContentModelDocument, + MutableContentModelDocument, + ReadonlyContentModelDocument, +} from './ContentModelDocument'; import type { ContentModelFormatContainer, + MutableContentModelFormatContainer, ReadonlyContentModelFormatContainer, } from './ContentModelFormatContainer'; import type { ContentModelGeneralBlock, + MutableContentModelGeneralBlock, ReadonlyContentModelGeneralBlock, } from './ContentModelGeneralBlock'; -import type { ContentModelListItem, ReadonlyContentModelListItem } from './ContentModelListItem'; -import type { ContentModelTableCell, ReadonlyContentModelTableCell } from './ContentModelTableCell'; +import type { + ContentModelListItem, + MutableContentModelListItem, + ReadonlyContentModelListItem, +} from './ContentModelListItem'; +import type { + ContentModelTableCell, + MutableContentModelTableCell, + ReadonlyContentModelTableCell, +} from './ContentModelTableCell'; /** * The union type of Content Model Block Group @@ -29,3 +43,13 @@ export type ReadonlyContentModelBlockGroup = | ReadonlyContentModelListItem | ReadonlyContentModelTableCell | ReadonlyContentModelGeneralBlock; + +/** + * The union type of Content Model Block Group (Single level mutable) + */ +export type MutableContentModelBlockGroup = + | MutableContentModelDocument + | MutableContentModelFormatContainer + | MutableContentModelListItem + | MutableContentModelTableCell + | MutableContentModelGeneralBlock; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroupBase.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroupBase.ts index f401cf27bd6..61e72267938 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroupBase.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroupBase.ts @@ -1,3 +1,4 @@ +import type { ContentModelBlockWithCache } from '../common/ContentModelBlockWithCache'; import type { ReadonlyMark } from '../common/ReadonlyMark'; import type { MutableMark } from '../common/MutableMark'; import type { ContentModelBlock, ReadonlyContentModelBlock } from '../block/ContentModelBlock'; @@ -6,7 +7,10 @@ import type { ContentModelBlockGroupType } from './BlockGroupType'; /** * Common part of base type of Content Model Block Group */ -export interface ContentModelBlockGroupBaseCommon { +export interface ContentModelBlockGroupBaseCommon< + T extends ContentModelBlockGroupType, + TElement extends HTMLElement = HTMLElement +> extends ContentModelBlockWithCache { /** * Type of this block group */ @@ -16,9 +20,10 @@ export interface ContentModelBlockGroupBaseCommon - extends MutableMark, - ContentModelBlockGroupBaseCommon { +export interface ContentModelBlockGroupBase< + T extends ContentModelBlockGroupType, + TElement extends HTMLElement = HTMLElement +> extends MutableMark, ContentModelBlockGroupBaseCommon { /** * Blocks under this group */ @@ -28,11 +33,25 @@ export interface ContentModelBlockGroupBase - extends ReadonlyMark, - ContentModelBlockGroupBaseCommon { +export interface ReadonlyContentModelBlockGroupBase< + T extends ContentModelBlockGroupType, + TElement extends HTMLElement = HTMLElement +> extends ReadonlyMark, ContentModelBlockGroupBaseCommon { /** * Blocks under this group */ readonly blocks: ReadonlyArray; } + +/** + * Base type of Content Model Block Group (Readonly) + */ +export interface MutableContentModelBlockGroupBase< + T extends ContentModelBlockGroupType, + TElement extends HTMLElement = HTMLElement +> extends MutableMark, ContentModelBlockGroupBaseCommon { + /** + * Blocks under this group + */ + blocks: ReadonlyContentModelBlock[]; +} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelDocument.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelDocument.ts index 3dc7175dc62..2571557eacb 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelDocument.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelDocument.ts @@ -1,5 +1,6 @@ import type { ContentModelBlockGroupBase, + MutableContentModelBlockGroupBase, ReadonlyContentModelBlockGroupBase, } from './ContentModelBlockGroupBase'; import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; @@ -30,6 +31,14 @@ export interface ContentModelDocument * Content Model document entry point (Readonly) */ export interface ReadonlyContentModelDocument - extends ReadonlyContentModelBlockGroupBase<'Document'>, - Partial>, - Readonly {} + extends Readonly, + ReadonlyContentModelBlockGroupBase<'Document'>, + Partial> {} + +/** + * Content Model document entry point (Single level mutable) + */ +export interface MutableContentModelDocument + extends ContentModelDocumentCommon, + MutableContentModelBlockGroupBase<'Document'>, + Partial> {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelFormatContainer.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelFormatContainer.ts index c8573111673..445075ec6f9 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelFormatContainer.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelFormatContainer.ts @@ -4,6 +4,7 @@ import type { } from '../block/ContentModelBlockBase'; import type { ContentModelBlockGroupBase, + MutableContentModelBlockGroupBase, ReadonlyContentModelBlockGroupBase, } from './ContentModelBlockGroupBase'; import type { ContentModelFormatContainerFormat } from '../format/ContentModelFormatContainerFormat'; @@ -36,6 +37,18 @@ export interface ContentModelFormatContainer * Content Model of Format Container (Readonly) */ export interface ReadonlyContentModelFormatContainer - extends ReadonlyContentModelBlockGroupBase<'FormatContainer'>, - ReadonlyContentModelBlockBase<'BlockGroup', ContentModelFormatContainerFormat, HTMLElement>, - Readonly {} + extends Readonly, + ReadonlyContentModelBlockGroupBase<'FormatContainer'>, + ReadonlyContentModelBlockBase< + 'BlockGroup', + ContentModelFormatContainerFormat, + HTMLElement + > {} + +/** + * Content Model of Format Container (Single level mutable) + */ +export interface MutableContentModelFormatContainer + extends ContentModelFormatContainerCommon, + MutableContentModelBlockGroupBase<'FormatContainer'>, + ContentModelBlockBase<'BlockGroup', ContentModelFormatContainerFormat, HTMLElement> {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelGeneralBlock.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelGeneralBlock.ts index caefb55a56d..c05051a6f99 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelGeneralBlock.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelGeneralBlock.ts @@ -5,6 +5,7 @@ import type { import type { ContentModelBlockFormat } from '../format/ContentModelBlockFormat'; import type { ContentModelBlockGroupBase, + MutableContentModelBlockGroupBase, ReadonlyContentModelBlockGroupBase, } from './ContentModelBlockGroupBase'; import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; @@ -34,9 +35,18 @@ export interface ContentModelGeneralBlock */ export interface ReadonlyContentModelGeneralBlock extends ReadonlySelectable, + Readonly, ReadonlyContentModelBlockGroupBase<'General'>, ReadonlyContentModelBlockBase< 'BlockGroup', ContentModelBlockFormat & ContentModelSegmentFormat - >, - Readonly {} + > {} + +/** + * Content Model for general Block element (Single level mutable) + */ +export interface MutableContentModelGeneralBlock + extends Selectable, + ContentModelGeneralBlockCommon, + MutableContentModelBlockGroupBase<'General'>, + ContentModelBlockBase<'BlockGroup', ContentModelBlockFormat & ContentModelSegmentFormat> {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts index a801f9d41e4..05b3ce10720 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts @@ -4,6 +4,7 @@ import type { } from '../block/ContentModelBlockBase'; import type { ContentModelBlockGroupBase, + MutableContentModelBlockGroupBase, ReadonlyContentModelBlockGroupBase, } from './ContentModelBlockGroupBase'; import type { ContentModelListItemFormat } from '../format/ContentModelListItemFormat'; @@ -20,7 +21,7 @@ import type { * Content Model of List Item */ export interface ContentModelListItem - extends ContentModelBlockGroupBase<'ListItem'>, + extends ContentModelBlockGroupBase<'ListItem', HTMLLIElement>, ContentModelBlockBase<'BlockGroup', ContentModelListItemFormat, HTMLLIElement> { /** * Type of this list, either ordered or unordered @@ -37,7 +38,7 @@ export interface ContentModelListItem * Content Model of List Item (Readonly) */ export interface ReadonlyContentModelListItem - extends ReadonlyContentModelBlockGroupBase<'ListItem'>, + extends ReadonlyContentModelBlockGroupBase<'ListItem', HTMLLIElement>, ReadonlyContentModelBlockBase<'BlockGroup', ContentModelListItemFormat, HTMLLIElement> { /** * Type of this list, either ordered or unordered @@ -49,3 +50,20 @@ export interface ReadonlyContentModelListItem */ readonly formatHolder: ReadonlyContentModelSelectionMarker; } + +/** + * Content Model of List Item (Single level mutable) + */ +export interface MutableContentModelListItem + extends MutableContentModelBlockGroupBase<'ListItem', HTMLLIElement>, + ContentModelBlockBase<'BlockGroup', ContentModelListItemFormat, HTMLLIElement> { + /** + * Type of this list, either ordered or unordered + */ + readonly levels: ReadonlyArray; + + /** + * A dummy segment to hold format of this list item + */ + readonly formatHolder: ReadonlyContentModelSelectionMarker; +} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelTableCell.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelTableCell.ts index 0f8674a5861..2dfa3eb467a 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelTableCell.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelTableCell.ts @@ -1,9 +1,9 @@ import type { TableCellMetadataFormat } from '../format/metadata/TableCellMetadataFormat'; import type { ContentModelBlockGroupBase, + MutableContentModelBlockGroupBase, ReadonlyContentModelBlockGroupBase, } from './ContentModelBlockGroupBase'; -import type { ContentModelBlockWithCache } from '../common/ContentModelBlockWithCache'; import type { ContentModelTableCellFormat } from '../format/ContentModelTableCellFormat'; import type { ContentModelWithDataset, @@ -41,18 +41,26 @@ export interface ContentModelTableCellCommon { export interface ContentModelTableCell extends Selectable, ContentModelTableCellCommon, - ContentModelBlockGroupBase<'TableCell'>, + ContentModelBlockGroupBase<'TableCell', HTMLTableCellElement>, ContentModelWithFormat, - ContentModelWithDataset, - ContentModelBlockWithCache {} + ContentModelWithDataset {} /** * Content Model of Table Cell (Readonly) */ export interface ReadonlyContentModelTableCell extends ReadonlySelectable, - ReadonlyContentModelBlockGroupBase<'TableCell'>, + Readonly, + ReadonlyContentModelBlockGroupBase<'TableCell', HTMLTableCellElement>, ReadonlyContentModelWithFormat, - ReadonlyContentModelWithDataset, - ContentModelBlockWithCache, - Readonly {} + ReadonlyContentModelWithDataset {} + +/** + * Content Model of Table Cell (Single level mutable) + */ +export interface MutableContentModelTableCell + extends Selectable, + ContentModelTableCellCommon, + MutableContentModelBlockGroupBase<'TableCell', HTMLTableCellElement>, + ContentModelWithFormat, + ContentModelWithDataset {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts b/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts index cbe8a351149..658d96d44fb 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts @@ -5,26 +5,26 @@ import type { ReadonlyContentModelDivider, } from '../block/ContentModelDivider'; import type { - ContentModelDocument, + MutableContentModelDocument, ReadonlyContentModelDocument, } from '../blockGroup/ContentModelDocument'; import type { ContentModelEntity, ReadonlyContentModelEntity } from '../entity/ContentModelEntity'; import type { - ContentModelFormatContainer, + MutableContentModelFormatContainer, ReadonlyContentModelFormatContainer, } from '../blockGroup/ContentModelFormatContainer'; import type { - ContentModelGeneralBlock, + MutableContentModelGeneralBlock, ReadonlyContentModelGeneralBlock, } from '../blockGroup/ContentModelGeneralBlock'; import type { - ContentModelGeneralSegment, + MutableContentModelGeneralSegment, ReadonlyContentModelGeneralSegment, } from '../segment/ContentModelGeneralSegment'; import type { ContentModelImage, ReadonlyContentModelImage } from '../segment/ContentModelImage'; import type { ContentModelLink, ReadonlyContentModelLink } from '../decorator/ContentModelLink'; import type { - ContentModelListItem, + MutableContentModelListItem, ReadonlyContentModelListItem, } from '../blockGroup/ContentModelListItem'; import type { @@ -45,7 +45,7 @@ import type { } from '../segment/ContentModelSelectionMarker'; import type { ContentModelTable, ReadonlyContentModelTable } from '../block/ContentModelTable'; import type { - ContentModelTableCell, + MutableContentModelTableCell, ReadonlyContentModelTableCell, } from '../blockGroup/ContentModelTableCell'; import type { @@ -58,7 +58,7 @@ import type { ContentModelText, ReadonlyContentModelText } from '../segment/Cont * Get mutable type from its related readonly type */ export type MutableType = T extends ReadonlyContentModelGeneralSegment - ? ContentModelGeneralSegment + ? MutableContentModelGeneralSegment : T extends ReadonlyContentModelSelectionMarker ? ContentModelSelectionMarker : T extends ReadonlyContentModelImage @@ -76,19 +76,19 @@ export type MutableType = T extends ReadonlyContentModelGeneralSegment : T extends ReadonlyContentModelTableRow ? ContentModelTableRow : T extends ReadonlyContentModelTableCell - ? ContentModelTableCell + ? MutableContentModelTableCell : T extends ReadonlyContentModelFormatContainer - ? ContentModelFormatContainer + ? MutableContentModelFormatContainer : T extends ReadonlyContentModelListItem - ? ContentModelListItem + ? MutableContentModelListItem : T extends ReadonlyContentModelListLevel ? ContentModelListLevel : T extends ReadonlyContentModelDivider ? ContentModelDivider : T extends ReadonlyContentModelDocument - ? ContentModelDocument + ? MutableContentModelDocument : T extends ReadonlyContentModelGeneralBlock - ? ContentModelGeneralBlock + ? MutableContentModelGeneralBlock : T extends ReadonlyContentModelParagraphDecorator ? ContentModelParagraphDecorator : T extends ReadonlyContentModelLink diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithDataset.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithDataset.ts index f79e379ee04..7de91cc8062 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithDataset.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithDataset.ts @@ -1,9 +1,11 @@ +import type { MutableMark } from '../common/MutableMark'; +import type { ReadonlyMark } from '../common/ReadonlyMark'; import type { DatasetFormat, ReadonlyDatasetFormat } from './metadata/DatasetFormat'; /** * Represents base format of an element that supports dataset and/or metadata */ -export type ContentModelWithDataset = { +export type ContentModelWithDataset = MutableMark & { /** * dataset of this element */ @@ -13,7 +15,7 @@ export type ContentModelWithDataset = { /** * Represents base format of an element that supports dataset and/or metadata (Readonly) */ -export type ReadonlyContentModelWithDataset = { +export type ReadonlyContentModelWithDataset = ReadonlyMark & { /** * dataset of this element */ diff --git a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelGeneralSegment.ts b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelGeneralSegment.ts index cca9d00d8e0..078776b69c2 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelGeneralSegment.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelGeneralSegment.ts @@ -1,6 +1,7 @@ import type { ContentModelBlockFormat } from '../format/ContentModelBlockFormat'; import type { ContentModelGeneralBlock, + MutableContentModelGeneralBlock, ReadonlyContentModelGeneralBlock, } from '../blockGroup/ContentModelGeneralBlock'; import type { @@ -25,3 +26,10 @@ export interface ReadonlyContentModelGeneralSegment 'General', ContentModelBlockFormat & ContentModelSegmentFormat > {} + +/** + * Content Model of general Segment (Single level mutable) + */ +export interface MutableContentModelGeneralSegment + extends MutableContentModelGeneralBlock, + ContentModelSegmentBase<'General', ContentModelBlockFormat & ContentModelSegmentFormat> {} diff --git a/packages/roosterjs-content-model-types/lib/index.ts b/packages/roosterjs-content-model-types/lib/index.ts index 16ea23b8d07..541e22bb21c 100644 --- a/packages/roosterjs-content-model-types/lib/index.ts +++ b/packages/roosterjs-content-model-types/lib/index.ts @@ -135,40 +135,48 @@ export { ContentModelDocument, ContentModelDocumentCommon, ReadonlyContentModelDocument, + MutableContentModelDocument, } from './contentModel/blockGroup/ContentModelDocument'; export { ContentModelBlockGroupBase, ContentModelBlockGroupBaseCommon, ReadonlyContentModelBlockGroupBase, + MutableContentModelBlockGroupBase, } from './contentModel/blockGroup/ContentModelBlockGroupBase'; export { ContentModelFormatContainer, ContentModelFormatContainerCommon, ReadonlyContentModelFormatContainer, + MutableContentModelFormatContainer, } from './contentModel/blockGroup/ContentModelFormatContainer'; export { ContentModelGeneralBlock, ContentModelGeneralBlockCommon, ReadonlyContentModelGeneralBlock, + MutableContentModelGeneralBlock, } from './contentModel/blockGroup/ContentModelGeneralBlock'; export { ContentModelListItem, ReadonlyContentModelListItem, + MutableContentModelListItem, } from './contentModel/blockGroup/ContentModelListItem'; export { ContentModelTableCell, ContentModelTableCellCommon, ReadonlyContentModelTableCell, + MutableContentModelTableCell, } from './contentModel/blockGroup/ContentModelTableCell'; export { ContentModelBlockGroup, ReadonlyContentModelBlockGroup, + MutableContentModelBlockGroup, } from './contentModel/blockGroup/ContentModelBlockGroup'; export { ContentModelBr, ReadonlyContentModelBr } from './contentModel/segment/ContentModelBr'; export { ContentModelGeneralSegment, ReadonlyContentModelGeneralSegment, + MutableContentModelGeneralSegment, } from './contentModel/segment/ContentModelGeneralSegment'; export { ContentModelImage, From 47b21f39c584aa93c9b8ff96078334357809ba23 Mon Sep 17 00:00:00 2001 From: Jiuqing Song Date: Tue, 14 May 2024 13:41:44 -0700 Subject: [PATCH 05/15] improve --- .../lib/contentModel/blockGroup/ContentModelListItem.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts index 05b3ce10720..2d965f98157 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts @@ -65,5 +65,5 @@ export interface MutableContentModelListItem /** * A dummy segment to hold format of this list item */ - readonly formatHolder: ReadonlyContentModelSelectionMarker; + formatHolder: ContentModelSelectionMarker; } From bd6b0cbf0c95f770c5837dec4f56310458718d49 Mon Sep 17 00:00:00 2001 From: Jiuqing Song Date: Tue, 14 May 2024 13:49:57 -0700 Subject: [PATCH 06/15] Improve --- .../contentModel/block/ContentModelBlock.ts | 4 +- .../lib/contentModel/common/MutableType.ts | 4 +- .../contentModel/entity/ContentModelEntity.ts | 47 +++---------------- .../segment/ContentModelSegment.ts | 4 +- .../lib/index.ts | 6 +-- 5 files changed, 13 insertions(+), 52 deletions(-) diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlock.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlock.ts index c4256a3bc06..2422de45cd5 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlock.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlock.ts @@ -1,5 +1,5 @@ import type { ContentModelDivider, ReadonlyContentModelDivider } from './ContentModelDivider'; -import type { ContentModelEntity, ReadonlyContentModelEntity } from '../entity/ContentModelEntity'; +import type { ContentModelEntity } from '../entity/ContentModelEntity'; import type { ContentModelFormatContainer, ReadonlyContentModelFormatContainer, @@ -36,5 +36,5 @@ export type ReadonlyContentModelBlock = | ReadonlyContentModelGeneralBlock | ReadonlyContentModelTable | ReadonlyContentModelParagraph - | ReadonlyContentModelEntity + | ContentModelEntity | ReadonlyContentModelDivider; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts b/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts index 658d96d44fb..5e1f46c34c9 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts @@ -8,7 +8,7 @@ import type { MutableContentModelDocument, ReadonlyContentModelDocument, } from '../blockGroup/ContentModelDocument'; -import type { ContentModelEntity, ReadonlyContentModelEntity } from '../entity/ContentModelEntity'; +import type { ContentModelEntity } from '../entity/ContentModelEntity'; import type { MutableContentModelFormatContainer, ReadonlyContentModelFormatContainer, @@ -63,7 +63,7 @@ export type MutableType = T extends ReadonlyContentModelGeneralSegment ? ContentModelSelectionMarker : T extends ReadonlyContentModelImage ? ContentModelImage - : T extends ReadonlyContentModelEntity + : T extends ContentModelEntity ? ContentModelEntity : T extends ReadonlyContentModelText ? ContentModelText diff --git a/packages/roosterjs-content-model-types/lib/contentModel/entity/ContentModelEntity.ts b/packages/roosterjs-content-model-types/lib/contentModel/entity/ContentModelEntity.ts index a44731bc54f..897a572920e 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/entity/ContentModelEntity.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/entity/ContentModelEntity.ts @@ -1,57 +1,22 @@ -import type { ReadonlyMark } from '../common/ReadonlyMark'; -import type { MutableMark } from '../common/MutableMark'; -import type { - ContentModelBlockBase, - ReadonlyContentModelBlockBase, -} from '../block/ContentModelBlockBase'; +import type { ContentModelBlockBase } from '../block/ContentModelBlockBase'; import type { ContentModelBlockFormat } from '../format/ContentModelBlockFormat'; import type { ContentModelEntityFormat } from '../format/ContentModelEntityFormat'; -import type { - ContentModelSegmentBase, - ReadonlyContentModelSegmentBase, -} from '../segment/ContentModelSegmentBase'; +import type { ContentModelSegmentBase } from '../segment/ContentModelSegmentBase'; import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; -/** - * Common part of Content Model of Entity - */ -export interface ContentModelEntityCommon { - /** - * The wrapper DOM node of this entity which holds the info CSS classes of this entity - */ - wrapper: HTMLElement; -} - /** * Content Model of Entity */ export interface ContentModelEntity - extends MutableMark, - ContentModelEntityCommon, - ContentModelBlockBase<'Entity', ContentModelBlockFormat & ContentModelSegmentFormat>, + extends ContentModelBlockBase<'Entity', ContentModelBlockFormat & ContentModelSegmentFormat>, ContentModelSegmentBase<'Entity', ContentModelBlockFormat & ContentModelSegmentFormat> { /** - * Format of this entity + * The wrapper DOM node of this entity which holds the info CSS classes of this entity */ - entityFormat: ContentModelEntityFormat; -} + wrapper: HTMLElement; -/** - * Content Model of Entity (Readonly) - */ -export interface ReadonlyContentModelEntity - extends ReadonlyMark, - Readonly, - ReadonlyContentModelBlockBase< - 'Entity', - ContentModelBlockFormat & ContentModelSegmentFormat - >, - ReadonlyContentModelSegmentBase< - 'Entity', - ContentModelBlockFormat & ContentModelSegmentFormat - > { /** * Format of this entity */ - readonly entityFormat: Readonly; + entityFormat: ContentModelEntityFormat; } diff --git a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegment.ts b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegment.ts index 687fb511796..7fec3926408 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegment.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegment.ts @@ -1,5 +1,5 @@ import type { ContentModelBr, ReadonlyContentModelBr } from './ContentModelBr'; -import type { ContentModelEntity, ReadonlyContentModelEntity } from '../entity/ContentModelEntity'; +import type { ContentModelEntity } from '../entity/ContentModelEntity'; import type { ContentModelGeneralSegment, ReadonlyContentModelGeneralSegment, @@ -30,5 +30,5 @@ export type ReadonlyContentModelSegment = | ReadonlyContentModelText | ReadonlyContentModelBr | ReadonlyContentModelGeneralSegment - | ReadonlyContentModelEntity + | ContentModelEntity | ReadonlyContentModelImage; diff --git a/packages/roosterjs-content-model-types/lib/index.ts b/packages/roosterjs-content-model-types/lib/index.ts index 541e22bb21c..975f5b4dd7e 100644 --- a/packages/roosterjs-content-model-types/lib/index.ts +++ b/packages/roosterjs-content-model-types/lib/index.ts @@ -125,11 +125,7 @@ export { ReadonlyContentModelTableRow, } from './contentModel/block/ContentModelTableRow'; -export { - ContentModelEntity, - ContentModelEntityCommon, - ReadonlyContentModelEntity, -} from './contentModel/entity/ContentModelEntity'; +export { ContentModelEntity } from './contentModel/entity/ContentModelEntity'; export { ContentModelDocument, From cf3ea785bd172f65529fc05a784d0494b18345d7 Mon Sep 17 00:00:00 2001 From: Jiuqing Song Date: Tue, 14 May 2024 14:25:20 -0700 Subject: [PATCH 07/15] Add shallow mutable type --- .../block/ContentModelBlockBase.ts | 16 +++- .../block/ContentModelTableRow.ts | 3 +- .../blockGroup/ContentModelBlockGroup.ts | 24 +++--- .../blockGroup/ContentModelBlockGroupBase.ts | 9 +- .../blockGroup/ContentModelDocument.ts | 8 +- .../blockGroup/ContentModelFormatContainer.ts | 15 ++-- .../blockGroup/ContentModelGeneralBlock.ts | 22 +++-- .../blockGroup/ContentModelListItem.ts | 15 ++-- .../blockGroup/ContentModelTableCell.ts | 19 ++-- .../lib/contentModel/common/MutableMark.ts | 86 ++++++++++++++----- .../lib/contentModel/common/MutableType.ts | 24 +++--- .../lib/contentModel/common/ReadonlyMark.ts | 29 ------- .../lib/contentModel/common/Selectable.ts | 13 ++- .../decorator/ContentModelCode.ts | 3 +- .../decorator/ContentModelLink.ts | 3 +- .../decorator/ContentModelListLevel.ts | 3 +- .../ContentModelParagraphDecorator.ts | 3 +- .../format/ContentModelWithDataset.ts | 13 ++- .../segment/ContentModelGeneralSegment.ts | 14 +-- .../segment/ContentModelSegmentBase.ts | 31 ++++++- .../lib/index.ts | 28 +++--- 21 files changed, 239 insertions(+), 142 deletions(-) delete mode 100644 packages/roosterjs-content-model-types/lib/contentModel/common/ReadonlyMark.ts diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlockBase.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlockBase.ts index 6ccf329e98c..7fef63cb17a 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlockBase.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlockBase.ts @@ -1,6 +1,5 @@ -import type { ReadonlyMark } from '../common/ReadonlyMark'; import type { ContentModelBlockWithCache } from '../common/ContentModelBlockWithCache'; -import type { MutableMark } from '../common/MutableMark'; +import type { MutableMark, ReadonlyMark, ShallowMutableMark } from '../common/MutableMark'; import type { ContentModelBlockFormat } from '../format/ContentModelBlockFormat'; import type { ContentModelBlockType } from './BlockType'; import type { @@ -43,3 +42,16 @@ export interface ReadonlyContentModelBlockBase< ContentModelBlockBaseCommon, ReadonlyContentModelWithFormat, ContentModelBlockWithCache {} + +/** + * Base type of a block (Shallow mutable) + */ +export interface ShallowMutableContentModelBlockBase< + T extends ContentModelBlockType, + TFormat extends ContentModelBlockFormat = ContentModelBlockFormat, + TCacheElement extends HTMLElement = HTMLElement +> + extends ShallowMutableMark, + ContentModelBlockBaseCommon, + ContentModelWithFormat, + ContentModelBlockWithCache {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTableRow.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTableRow.ts index 449ae86076d..309808338fd 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTableRow.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTableRow.ts @@ -1,5 +1,4 @@ -import type { ReadonlyMark } from '../common/ReadonlyMark'; -import type { MutableMark } from '../common/MutableMark'; +import type { MutableMark, ReadonlyMark } from '../common/MutableMark'; import type { ContentModelBlockFormat } from '../format/ContentModelBlockFormat'; import type { ContentModelBlockWithCache } from '../common/ContentModelBlockWithCache'; import type { diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroup.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroup.ts index 9be2dd2b791..d526e962738 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroup.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroup.ts @@ -1,27 +1,27 @@ import type { ContentModelDocument, - MutableContentModelDocument, ReadonlyContentModelDocument, + ShallowMutableContentModelDocument, } from './ContentModelDocument'; import type { ContentModelFormatContainer, - MutableContentModelFormatContainer, ReadonlyContentModelFormatContainer, + ShallowMutableContentModelFormatContainer, } from './ContentModelFormatContainer'; import type { ContentModelGeneralBlock, - MutableContentModelGeneralBlock, ReadonlyContentModelGeneralBlock, + ShallowMutableContentModelGeneralBlock, } from './ContentModelGeneralBlock'; import type { ContentModelListItem, - MutableContentModelListItem, ReadonlyContentModelListItem, + ShallowMutableContentModelListItem, } from './ContentModelListItem'; import type { ContentModelTableCell, - MutableContentModelTableCell, ReadonlyContentModelTableCell, + ShallowMutableContentModelTableCell, } from './ContentModelTableCell'; /** @@ -45,11 +45,11 @@ export type ReadonlyContentModelBlockGroup = | ReadonlyContentModelGeneralBlock; /** - * The union type of Content Model Block Group (Single level mutable) + * The union type of Content Model Block Group (Shallow mutable) */ -export type MutableContentModelBlockGroup = - | MutableContentModelDocument - | MutableContentModelFormatContainer - | MutableContentModelListItem - | MutableContentModelTableCell - | MutableContentModelGeneralBlock; +export type ShallowMutableContentModelBlockGroup = + | ShallowMutableContentModelDocument + | ShallowMutableContentModelFormatContainer + | ShallowMutableContentModelListItem + | ShallowMutableContentModelTableCell + | ShallowMutableContentModelGeneralBlock; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroupBase.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroupBase.ts index 61e72267938..3235a5e4acb 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroupBase.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelBlockGroupBase.ts @@ -1,6 +1,5 @@ import type { ContentModelBlockWithCache } from '../common/ContentModelBlockWithCache'; -import type { ReadonlyMark } from '../common/ReadonlyMark'; -import type { MutableMark } from '../common/MutableMark'; +import type { MutableMark, ReadonlyMark, ShallowMutableMark } from '../common/MutableMark'; import type { ContentModelBlock, ReadonlyContentModelBlock } from '../block/ContentModelBlock'; import type { ContentModelBlockGroupType } from './BlockGroupType'; @@ -44,12 +43,12 @@ export interface ReadonlyContentModelBlockGroupBase< } /** - * Base type of Content Model Block Group (Readonly) + * Base type of Content Model Block Group (Shallow mutable) */ -export interface MutableContentModelBlockGroupBase< +export interface ShallowMutableContentModelBlockGroupBase< T extends ContentModelBlockGroupType, TElement extends HTMLElement = HTMLElement -> extends MutableMark, ContentModelBlockGroupBaseCommon { +> extends ShallowMutableMark, ContentModelBlockGroupBaseCommon { /** * Blocks under this group */ diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelDocument.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelDocument.ts index 2571557eacb..0584de310d6 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelDocument.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelDocument.ts @@ -1,7 +1,7 @@ import type { ContentModelBlockGroupBase, - MutableContentModelBlockGroupBase, ReadonlyContentModelBlockGroupBase, + ShallowMutableContentModelBlockGroupBase, } from './ContentModelBlockGroupBase'; import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; import type { @@ -36,9 +36,9 @@ export interface ReadonlyContentModelDocument Partial> {} /** - * Content Model document entry point (Single level mutable) + * Content Model document entry point (Shallow mutable) */ -export interface MutableContentModelDocument +export interface ShallowMutableContentModelDocument extends ContentModelDocumentCommon, - MutableContentModelBlockGroupBase<'Document'>, + ShallowMutableContentModelBlockGroupBase<'Document'>, Partial> {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelFormatContainer.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelFormatContainer.ts index 445075ec6f9..8ebcc01c06e 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelFormatContainer.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelFormatContainer.ts @@ -1,11 +1,12 @@ import type { ContentModelBlockBase, ReadonlyContentModelBlockBase, + ShallowMutableContentModelBlockBase, } from '../block/ContentModelBlockBase'; import type { ContentModelBlockGroupBase, - MutableContentModelBlockGroupBase, ReadonlyContentModelBlockGroupBase, + ShallowMutableContentModelBlockGroupBase, } from './ContentModelBlockGroupBase'; import type { ContentModelFormatContainerFormat } from '../format/ContentModelFormatContainerFormat'; @@ -46,9 +47,13 @@ export interface ReadonlyContentModelFormatContainer > {} /** - * Content Model of Format Container (Single level mutable) + * Content Model of Format Container (Shallow mutable) */ -export interface MutableContentModelFormatContainer +export interface ShallowMutableContentModelFormatContainer extends ContentModelFormatContainerCommon, - MutableContentModelBlockGroupBase<'FormatContainer'>, - ContentModelBlockBase<'BlockGroup', ContentModelFormatContainerFormat, HTMLElement> {} + ShallowMutableContentModelBlockGroupBase<'FormatContainer'>, + ShallowMutableContentModelBlockBase< + 'BlockGroup', + ContentModelFormatContainerFormat, + HTMLElement + > {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelGeneralBlock.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelGeneralBlock.ts index c05051a6f99..e6f577dc99b 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelGeneralBlock.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelGeneralBlock.ts @@ -1,15 +1,20 @@ import type { ContentModelBlockBase, ReadonlyContentModelBlockBase, + ShallowMutableContentModelBlockBase, } from '../block/ContentModelBlockBase'; import type { ContentModelBlockFormat } from '../format/ContentModelBlockFormat'; import type { ContentModelBlockGroupBase, - MutableContentModelBlockGroupBase, + ShallowMutableContentModelBlockGroupBase, ReadonlyContentModelBlockGroupBase, } from './ContentModelBlockGroupBase'; import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; -import type { ReadonlySelectable, Selectable } from '../common/Selectable'; +import type { + ReadonlySelectable, + Selectable, + ShallowMutableSelectable, +} from '../common/Selectable'; /** * Common part of Content Model for general Block element @@ -43,10 +48,13 @@ export interface ReadonlyContentModelGeneralBlock > {} /** - * Content Model for general Block element (Single level mutable) + * Content Model for general Block element (Shallow mutable) */ -export interface MutableContentModelGeneralBlock - extends Selectable, +export interface ShallowMutableContentModelGeneralBlock + extends ShallowMutableSelectable, ContentModelGeneralBlockCommon, - MutableContentModelBlockGroupBase<'General'>, - ContentModelBlockBase<'BlockGroup', ContentModelBlockFormat & ContentModelSegmentFormat> {} + ShallowMutableContentModelBlockGroupBase<'General'>, + ShallowMutableContentModelBlockBase< + 'BlockGroup', + ContentModelBlockFormat & ContentModelSegmentFormat + > {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts index 2d965f98157..c4f8b2fbb76 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts @@ -1,11 +1,12 @@ import type { ContentModelBlockBase, ReadonlyContentModelBlockBase, + ShallowMutableContentModelBlockBase, } from '../block/ContentModelBlockBase'; import type { ContentModelBlockGroupBase, - MutableContentModelBlockGroupBase, ReadonlyContentModelBlockGroupBase, + ShallowMutableContentModelBlockGroupBase, } from './ContentModelBlockGroupBase'; import type { ContentModelListItemFormat } from '../format/ContentModelListItemFormat'; import type { @@ -52,11 +53,15 @@ export interface ReadonlyContentModelListItem } /** - * Content Model of List Item (Single level mutable) + * Content Model of List Item (Shallow mutable) */ -export interface MutableContentModelListItem - extends MutableContentModelBlockGroupBase<'ListItem', HTMLLIElement>, - ContentModelBlockBase<'BlockGroup', ContentModelListItemFormat, HTMLLIElement> { +export interface ShallowMutableContentModelListItem + extends ShallowMutableContentModelBlockGroupBase<'ListItem', HTMLLIElement>, + ShallowMutableContentModelBlockBase< + 'BlockGroup', + ContentModelListItemFormat, + HTMLLIElement + > { /** * Type of this list, either ordered or unordered */ diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelTableCell.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelTableCell.ts index 2dfa3eb467a..03749696b78 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelTableCell.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelTableCell.ts @@ -1,19 +1,24 @@ import type { TableCellMetadataFormat } from '../format/metadata/TableCellMetadataFormat'; import type { ContentModelBlockGroupBase, - MutableContentModelBlockGroupBase, ReadonlyContentModelBlockGroupBase, + ShallowMutableContentModelBlockGroupBase, } from './ContentModelBlockGroupBase'; import type { ContentModelTableCellFormat } from '../format/ContentModelTableCellFormat'; import type { ContentModelWithDataset, ReadonlyContentModelWithDataset, + ShallowMutableContentModelWithDataset, } from '../format/ContentModelWithDataset'; import type { ContentModelWithFormat, ReadonlyContentModelWithFormat, } from '../format/ContentModelWithFormat'; -import type { ReadonlySelectable, Selectable } from '../common/Selectable'; +import type { + ReadonlySelectable, + Selectable, + ShallowMutableSelectable, +} from '../common/Selectable'; /** * Common part of Content Model of Table Cell @@ -56,11 +61,11 @@ export interface ReadonlyContentModelTableCell ReadonlyContentModelWithDataset {} /** - * Content Model of Table Cell (Single level mutable) + * Content Model of Table Cell (Shallow mutable) */ -export interface MutableContentModelTableCell - extends Selectable, +export interface ShallowMutableContentModelTableCell + extends ShallowMutableSelectable, ContentModelTableCellCommon, - MutableContentModelBlockGroupBase<'TableCell', HTMLTableCellElement>, + ShallowMutableContentModelBlockGroupBase<'TableCell', HTMLTableCellElement>, ContentModelWithFormat, - ContentModelWithDataset {} + ShallowMutableContentModelWithDataset {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/common/MutableMark.ts b/packages/roosterjs-content-model-types/lib/contentModel/common/MutableMark.ts index ae5b46d684a..9912a147c44 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/common/MutableMark.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/common/MutableMark.ts @@ -1,29 +1,73 @@ +// We are using a tag type to mark a content model type as mutable. + +// This is generally a workaround to https://github.com/microsoft/TypeScript/issues/13347 + +// In order to know if a block has been changed, we want to mark all blocks, blocks groups, segments and their members as readonly, +// When we want to change a block/segment/block group, we need to call a function to convert it to mutable. Inside this function +// we can make some change to the object (e.g. remove cached element if any) so later we know this object is changed. +// So that we expect there is a build time error if we assign a readonly object to a function that accepts mutable object only. +// However this does not happen today. + +// To workaround it, we manually add a hidden member (dummy) to all mutable types, and add another member with readonly array type to +// readonly types. When we assign readonly object to mutable one, compiler will fail to build since the two arrays are not matching. +// So that we can know where to fix from build time. And since the dummy value is optional, it won't break existing creator code. + +// @example +// let readonly: ReadonlyMark = {}; +// let mutable: MutableMark = {}; + +// readonly = mutable; // OK +// mutable = readonly; // Error: Type 'ReadonlyMark' is not assignable to type 'MutableMark'. + /** - * A tag type to mark a content model type as mutable. - * - * This is generally a workaround to https://github.com/microsoft/TypeScript/issues/13347 - * - * In order to know if a block has been changed, we want to mark all blocks, blocks groups, segments and their members as readonly, - * When we want to change a block/segment/block group, we need to call a function to convert it to mutable. Inside this function - * we can make some change to the object (e.g. remove cached element if any) so later we know this object is changed. - * So that we expect there is a build time error if we assign a readonly object to a function that accepts mutable object only. - * However this does not happen today. - * - * To workaround it, we manually add a hidden member (dummy) to all mutable types, and add another member with readonly array type to - * readonly types. When we assign readonly object to mutable one, compiler will fail to build since the two arrays are not matching. - * So that we can know where to fix from build time. And since the dummy value is optional, it won't break existing creator code. - * - * @example - * let readonly: ReadonlyMark = {}; - * let mutable: MutableMark = {}; - * - * readonly = mutable; // OK - * mutable = readonly; // Error: Type 'ReadonlyMark' is not assignable to type 'MutableMark'. + * Mark an object as mutable */ export type MutableMark = { /** * The mutable marker to mark an object as mutable. When assign readonly object to a mutable type, compile will fail to build * due to this member does not exist from source type. */ - readonly dummy?: never[]; + readonly dummy1?: never[]; + + /** + * The mutable marker to mark an object as mutable. When assign readonly object to a mutable type, compile will fail to build + * due to this member does not exist from source type. + */ + readonly dummy2?: never[]; +}; + +/** + * Mark an object as single level mutable (child models are still readonly) + */ +export type ShallowMutableMark = { + /** + * The mutable marker to mark an object as mutable. When assign readonly object to a mutable type, compile will fail to build + * due to this member does not exist from source type. + */ + readonly dummy1?: never[]; + + /** + * The mutable marker to mark an object as mutable. When assign readonly object to a mutable type, compile will fail to build + * due to this member does not exist from source type. + * This is used for preventing assigning ShallowMutableMark to MutableMark + */ + readonly dummy2?: ReadonlyArray; +}; + +/** + * Mark an object as readonly + */ +export type ReadonlyMark = { + /** + * The mutable marker to mark an object as mutable. When assign readonly object to a mutable type, compile will fail to build + * due to this member does not exist from source type. + * This is used for preventing assigning ReadonlyMark to ShallowMutableMark or MutableMark + */ + readonly dummy1?: ReadonlyArray; + + /** + * The mutable marker to mark an object as mutable. When assign readonly object to a mutable type, compile will fail to build + * due to this member does not exist from source type. + */ + readonly dummy2?: ReadonlyArray; }; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts b/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts index 5e1f46c34c9..b8b0d695314 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts @@ -5,26 +5,26 @@ import type { ReadonlyContentModelDivider, } from '../block/ContentModelDivider'; import type { - MutableContentModelDocument, + ShallowMutableContentModelDocument, ReadonlyContentModelDocument, } from '../blockGroup/ContentModelDocument'; import type { ContentModelEntity } from '../entity/ContentModelEntity'; import type { - MutableContentModelFormatContainer, + ShallowMutableContentModelFormatContainer, ReadonlyContentModelFormatContainer, } from '../blockGroup/ContentModelFormatContainer'; import type { - MutableContentModelGeneralBlock, + ShallowMutableContentModelGeneralBlock, ReadonlyContentModelGeneralBlock, } from '../blockGroup/ContentModelGeneralBlock'; import type { - MutableContentModelGeneralSegment, + ShallowMutableContentModelGeneralSegment, ReadonlyContentModelGeneralSegment, } from '../segment/ContentModelGeneralSegment'; import type { ContentModelImage, ReadonlyContentModelImage } from '../segment/ContentModelImage'; import type { ContentModelLink, ReadonlyContentModelLink } from '../decorator/ContentModelLink'; import type { - MutableContentModelListItem, + ShallowMutableContentModelListItem, ReadonlyContentModelListItem, } from '../blockGroup/ContentModelListItem'; import type { @@ -45,7 +45,7 @@ import type { } from '../segment/ContentModelSelectionMarker'; import type { ContentModelTable, ReadonlyContentModelTable } from '../block/ContentModelTable'; import type { - MutableContentModelTableCell, + ShallowMutableContentModelTableCell, ReadonlyContentModelTableCell, } from '../blockGroup/ContentModelTableCell'; import type { @@ -58,7 +58,7 @@ import type { ContentModelText, ReadonlyContentModelText } from '../segment/Cont * Get mutable type from its related readonly type */ export type MutableType = T extends ReadonlyContentModelGeneralSegment - ? MutableContentModelGeneralSegment + ? ShallowMutableContentModelGeneralSegment : T extends ReadonlyContentModelSelectionMarker ? ContentModelSelectionMarker : T extends ReadonlyContentModelImage @@ -76,19 +76,19 @@ export type MutableType = T extends ReadonlyContentModelGeneralSegment : T extends ReadonlyContentModelTableRow ? ContentModelTableRow : T extends ReadonlyContentModelTableCell - ? MutableContentModelTableCell + ? ShallowMutableContentModelTableCell : T extends ReadonlyContentModelFormatContainer - ? MutableContentModelFormatContainer + ? ShallowMutableContentModelFormatContainer : T extends ReadonlyContentModelListItem - ? MutableContentModelListItem + ? ShallowMutableContentModelListItem : T extends ReadonlyContentModelListLevel ? ContentModelListLevel : T extends ReadonlyContentModelDivider ? ContentModelDivider : T extends ReadonlyContentModelDocument - ? MutableContentModelDocument + ? ShallowMutableContentModelDocument : T extends ReadonlyContentModelGeneralBlock - ? MutableContentModelGeneralBlock + ? ShallowMutableContentModelGeneralBlock : T extends ReadonlyContentModelParagraphDecorator ? ContentModelParagraphDecorator : T extends ReadonlyContentModelLink diff --git a/packages/roosterjs-content-model-types/lib/contentModel/common/ReadonlyMark.ts b/packages/roosterjs-content-model-types/lib/contentModel/common/ReadonlyMark.ts deleted file mode 100644 index e4568edf284..00000000000 --- a/packages/roosterjs-content-model-types/lib/contentModel/common/ReadonlyMark.ts +++ /dev/null @@ -1,29 +0,0 @@ -/** - * A tag type to mark a content model type as readonly. - * - * This is generally a workaround to https://github.com/microsoft/TypeScript/issues/13347 - * - * In order to know if a block has been changed, we want to mark all blocks, blocks groups, segments and their members as readonly, - * When we want to change a block/segment/block group, we need to call a function to convert it to mutable. Inside this function - * we can make some change to the object (e.g. remove cached element if any) so later we know this object is changed. - * So that we expect there is a build time error if we assign a readonly object to a function that accepts mutable object only. - * However this does not happen today. - * - * To workaround it, we manually add a hidden member (dummy) to all mutable types, and add another member with readonly array type to - * readonly types. When we assign readonly object to mutable one, compiler will fail to build since the two arrays are not matching. - * So that we can know where to fix from build time. And since the dummy value is optional, it won't break existing creator code. - * - * @example - * let readonly: ReadonlyMark = {}; - * let mutable: MutableMark = {}; - * - * readonly = mutable; // OK - * mutable = readonly; // Error: Type 'ReadonlyMark' is not assignable to type 'MutableMark'. - */ -export type ReadonlyMark = { - /** - * The mutable marker to mark an object as mutable. When assign readonly object to a mutable type, compile will fail to build - * due to this member does not exist from source type. - */ - readonly dummy?: ReadonlyArray; -}; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/common/Selectable.ts b/packages/roosterjs-content-model-types/lib/contentModel/common/Selectable.ts index 4ceef92d5e8..1b498d79f2b 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/common/Selectable.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/common/Selectable.ts @@ -1,5 +1,4 @@ -import type { MutableMark } from './MutableMark'; -import type { ReadonlyMark } from './ReadonlyMark'; +import type { MutableMark, ReadonlyMark, ShallowMutableMark } from '../common/MutableMark'; /** * Represents a selectable Content Model object @@ -20,3 +19,13 @@ export interface ReadonlySelectable extends ReadonlyMark { */ readonly isSelected?: boolean; } + +/** + * Represents a selectable Content Model object (Shallow mutable) + */ +export interface ShallowMutableSelectable extends ShallowMutableMark { + /** + * Whether this model object is selected + */ + readonly isSelected?: boolean; +} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelCode.ts b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelCode.ts index 353cdc61fee..d6823d9b496 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelCode.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelCode.ts @@ -1,5 +1,4 @@ -import type { MutableMark } from '../common/MutableMark'; -import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark, ReadonlyMark } from '../common/MutableMark'; import type { ContentModelCodeFormat } from '../format/ContentModelCodeFormat'; import type { ContentModelWithFormat, diff --git a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelLink.ts b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelLink.ts index 18856a29424..4aa98459542 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelLink.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelLink.ts @@ -1,5 +1,4 @@ -import type { MutableMark } from '../common/MutableMark'; -import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark, ReadonlyMark } from '../common/MutableMark'; import type { ContentModelHyperLinkFormat } from '../format/ContentModelHyperLinkFormat'; import type { ContentModelWithDataset, diff --git a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelListLevel.ts b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelListLevel.ts index ccb346e9845..585b0dce4ca 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelListLevel.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelListLevel.ts @@ -1,6 +1,5 @@ import type { ContentModelBlockWithCache } from '../common/ContentModelBlockWithCache'; -import type { MutableMark } from '../common/MutableMark'; -import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark, ReadonlyMark } from '../common/MutableMark'; import type { ContentModelListItemLevelFormat } from '../format/ContentModelListItemLevelFormat'; import type { ContentModelWithDataset, diff --git a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelParagraphDecorator.ts b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelParagraphDecorator.ts index b838b7f01bc..7eeebcc19b4 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelParagraphDecorator.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/decorator/ContentModelParagraphDecorator.ts @@ -1,5 +1,4 @@ -import type { MutableMark } from '../common/MutableMark'; -import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark, ReadonlyMark } from '../common/MutableMark'; import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; import type { ContentModelWithFormat, diff --git a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithDataset.ts b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithDataset.ts index 7de91cc8062..902f4dd2d5e 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithDataset.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/format/ContentModelWithDataset.ts @@ -1,5 +1,4 @@ -import type { MutableMark } from '../common/MutableMark'; -import type { ReadonlyMark } from '../common/ReadonlyMark'; +import type { MutableMark, ReadonlyMark, ShallowMutableMark } from '../common/MutableMark'; import type { DatasetFormat, ReadonlyDatasetFormat } from './metadata/DatasetFormat'; /** @@ -21,3 +20,13 @@ export type ReadonlyContentModelWithDataset = ReadonlyMark & { */ readonly dataset: ReadonlyDatasetFormat; }; + +/** + * Represents base format of an element that supports dataset and/or metadata (Readonly) + */ +export type ShallowMutableContentModelWithDataset = ShallowMutableMark & { + /** + * dataset of this element + */ + dataset: DatasetFormat; +}; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelGeneralSegment.ts b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelGeneralSegment.ts index 078776b69c2..3bfded832e0 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelGeneralSegment.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelGeneralSegment.ts @@ -1,12 +1,13 @@ import type { ContentModelBlockFormat } from '../format/ContentModelBlockFormat'; import type { ContentModelGeneralBlock, - MutableContentModelGeneralBlock, ReadonlyContentModelGeneralBlock, + ShallowMutableContentModelGeneralBlock, } from '../blockGroup/ContentModelGeneralBlock'; import type { ContentModelSegmentBase, ReadonlyContentModelSegmentBase, + ShallowMutableContentModelSegmentBase, } from './ContentModelSegmentBase'; import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; @@ -28,8 +29,11 @@ export interface ReadonlyContentModelGeneralSegment > {} /** - * Content Model of general Segment (Single level mutable) + * Content Model of general Segment (Shallow mutable) */ -export interface MutableContentModelGeneralSegment - extends MutableContentModelGeneralBlock, - ContentModelSegmentBase<'General', ContentModelBlockFormat & ContentModelSegmentFormat> {} +export interface ShallowMutableContentModelGeneralSegment + extends ShallowMutableContentModelGeneralBlock, + ShallowMutableContentModelSegmentBase< + 'General', + ContentModelBlockFormat & ContentModelSegmentFormat + > {} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegmentBase.ts b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegmentBase.ts index 4c6f2636a25..d8bea3bf4c1 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegmentBase.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegmentBase.ts @@ -1,5 +1,4 @@ -import type { ReadonlyMark } from '../common/ReadonlyMark'; -import type { MutableMark } from '../common/MutableMark'; +import type { MutableMark, ReadonlyMark, ShallowMutableMark } from '../common/MutableMark'; import type { ContentModelCode, ReadonlyContentModelCode } from '../decorator/ContentModelCode'; import type { ContentModelLink, ReadonlyContentModelLink } from '../decorator/ContentModelLink'; import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; @@ -8,7 +7,11 @@ import type { ContentModelWithFormat, ReadonlyContentModelWithFormat, } from '../format/ContentModelWithFormat'; -import type { ReadonlySelectable, Selectable } from '../common/Selectable'; +import type { + ReadonlySelectable, + Selectable, + ShallowMutableSelectable, +} from '../common/Selectable'; /** * Common part of base type of Content Model Segment @@ -63,3 +66,25 @@ export interface ReadonlyContentModelSegmentBase< */ readonly code?: ReadonlyContentModelCode; } + +/** + * Base type of Content Model Segment (Shallow mutable) + */ +export interface ShallowMutableContentModelSegmentBase< + T extends ContentModelSegmentType, + TFormat extends ContentModelSegmentFormat = ContentModelSegmentFormat +> + extends ShallowMutableMark, + ShallowMutableSelectable, + ContentModelWithFormat, + ContentModelSegmentBaseCommon { + /** + * Hyperlink info + */ + readonly link?: ReadonlyContentModelLink; + + /** + * Code info + */ + readonly code?: ReadonlyContentModelCode; +} diff --git a/packages/roosterjs-content-model-types/lib/index.ts b/packages/roosterjs-content-model-types/lib/index.ts index 975f5b4dd7e..5510fe6d6f7 100644 --- a/packages/roosterjs-content-model-types/lib/index.ts +++ b/packages/roosterjs-content-model-types/lib/index.ts @@ -7,6 +7,7 @@ export { ContentModelTableFormat } from './contentModel/format/ContentModelTable export { ContentModelWithDataset, ReadonlyContentModelWithDataset, + ShallowMutableContentModelWithDataset, } from './contentModel/format/ContentModelWithDataset'; export { ContentModelBlockFormat } from './contentModel/format/ContentModelBlockFormat'; export { ContentModelTableCellFormat } from './contentModel/format/ContentModelTableCellFormat'; @@ -117,6 +118,7 @@ export { ContentModelBlockBase, ContentModelBlockBaseCommon, ReadonlyContentModelBlockBase, + ShallowMutableContentModelBlockBase, } from './contentModel/block/ContentModelBlockBase'; export { ContentModelBlockWithCache } from './contentModel/common/ContentModelBlockWithCache'; export { @@ -131,48 +133,48 @@ export { ContentModelDocument, ContentModelDocumentCommon, ReadonlyContentModelDocument, - MutableContentModelDocument, + ShallowMutableContentModelDocument, } from './contentModel/blockGroup/ContentModelDocument'; export { ContentModelBlockGroupBase, ContentModelBlockGroupBaseCommon, ReadonlyContentModelBlockGroupBase, - MutableContentModelBlockGroupBase, + ShallowMutableContentModelBlockGroupBase, } from './contentModel/blockGroup/ContentModelBlockGroupBase'; export { ContentModelFormatContainer, ContentModelFormatContainerCommon, ReadonlyContentModelFormatContainer, - MutableContentModelFormatContainer, + ShallowMutableContentModelFormatContainer, } from './contentModel/blockGroup/ContentModelFormatContainer'; export { ContentModelGeneralBlock, ContentModelGeneralBlockCommon, ReadonlyContentModelGeneralBlock, - MutableContentModelGeneralBlock, + ShallowMutableContentModelGeneralBlock, } from './contentModel/blockGroup/ContentModelGeneralBlock'; export { ContentModelListItem, ReadonlyContentModelListItem, - MutableContentModelListItem, + ShallowMutableContentModelListItem, } from './contentModel/blockGroup/ContentModelListItem'; export { ContentModelTableCell, ContentModelTableCellCommon, ReadonlyContentModelTableCell, - MutableContentModelTableCell, + ShallowMutableContentModelTableCell, } from './contentModel/blockGroup/ContentModelTableCell'; export { ContentModelBlockGroup, ReadonlyContentModelBlockGroup, - MutableContentModelBlockGroup, + ShallowMutableContentModelBlockGroup, } from './contentModel/blockGroup/ContentModelBlockGroup'; export { ContentModelBr, ReadonlyContentModelBr } from './contentModel/segment/ContentModelBr'; export { ContentModelGeneralSegment, ReadonlyContentModelGeneralSegment, - MutableContentModelGeneralSegment, + ShallowMutableContentModelGeneralSegment, } from './contentModel/segment/ContentModelGeneralSegment'; export { ContentModelImage, @@ -192,6 +194,7 @@ export { ContentModelSegmentBase, ContentModelSegmentBaseCommon, ReadonlyContentModelSegmentBase, + ShallowMutableContentModelSegmentBase, } from './contentModel/segment/ContentModelSegmentBase'; export { ContentModelSegment, @@ -221,9 +224,12 @@ export { ReadonlyContentModelListLevel, } from './contentModel/decorator/ContentModelListLevel'; -export { Selectable, ReadonlySelectable } from './contentModel/common/Selectable'; -export { ReadonlyMark } from './contentModel/common/ReadonlyMark'; -export { MutableMark } from './contentModel/common/MutableMark'; +export { + Selectable, + ReadonlySelectable, + ShallowMutableSelectable, +} from './contentModel/common/Selectable'; +export { MutableMark, ShallowMutableMark, ReadonlyMark } from './contentModel/common/MutableMark'; export { MutableType } from './contentModel/common/MutableType'; export { From e14e506833fd578726641fa76829522142bb2c99 Mon Sep 17 00:00:00 2001 From: Jiuqing Song Date: Tue, 14 May 2024 14:29:26 -0700 Subject: [PATCH 08/15] improve --- .../lib/contentModel/common/Selectable.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/roosterjs-content-model-types/lib/contentModel/common/Selectable.ts b/packages/roosterjs-content-model-types/lib/contentModel/common/Selectable.ts index 1b498d79f2b..d9aa25b08e8 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/common/Selectable.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/common/Selectable.ts @@ -27,5 +27,5 @@ export interface ShallowMutableSelectable extends ShallowMutableMark { /** * Whether this model object is selected */ - readonly isSelected?: boolean; + isSelected?: boolean; } From 9a2d449f770c620502d087615280ec69811805cd Mon Sep 17 00:00:00 2001 From: Jiuqing Song Date: Tue, 14 May 2024 14:36:17 -0700 Subject: [PATCH 09/15] Improve --- .../lib/contentModel/blockGroup/ContentModelListItem.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts index c4f8b2fbb76..42029807129 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/blockGroup/ContentModelListItem.ts @@ -65,7 +65,7 @@ export interface ShallowMutableContentModelListItem /** * Type of this list, either ordered or unordered */ - readonly levels: ReadonlyArray; + levels: ContentModelListLevel[]; /** * A dummy segment to hold format of this list item From 719f5ed183a65f1f1f22495cf22ac694f9317466 Mon Sep 17 00:00:00 2001 From: Jiuqing Song Date: Tue, 14 May 2024 15:07:36 -0700 Subject: [PATCH 10/15] improve --- .../lib/contentModel/segment/ContentModelSegmentBase.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegmentBase.ts b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegmentBase.ts index d8bea3bf4c1..5f169c3eac7 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegmentBase.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegmentBase.ts @@ -81,10 +81,10 @@ export interface ShallowMutableContentModelSegmentBase< /** * Hyperlink info */ - readonly link?: ReadonlyContentModelLink; + link?: ContentModelLink; /** * Code info */ - readonly code?: ReadonlyContentModelCode; + code?: ContentModelCode; } From caf7ef1d0d0f3b72ac88130130f061b49499bc8c Mon Sep 17 00:00:00 2001 From: Jiuqing Song Date: Wed, 15 May 2024 16:39:02 -0700 Subject: [PATCH 11/15] improve --- .../contentModel/block/ContentModelBlock.ts | 21 ++++++++++++- .../contentModel/block/ContentModelTable.ts | 30 +++++++++++++++++-- .../block/ContentModelTableRow.ts | 20 +++++++++++-- .../lib/contentModel/common/MutableType.ts | 7 +++-- .../lib/index.ts | 3 ++ 5 files changed, 73 insertions(+), 8 deletions(-) diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlock.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlock.ts index 2422de45cd5..3ae77cedd1c 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlock.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlock.ts @@ -3,17 +3,24 @@ import type { ContentModelEntity } from '../entity/ContentModelEntity'; import type { ContentModelFormatContainer, ReadonlyContentModelFormatContainer, + ShallowMutableContentModelFormatContainer, } from '../blockGroup/ContentModelFormatContainer'; import type { ContentModelGeneralBlock, ReadonlyContentModelGeneralBlock, + ShallowMutableContentModelGeneralBlock, } from '../blockGroup/ContentModelGeneralBlock'; import type { ContentModelListItem, ReadonlyContentModelListItem, + ShallowMutableContentModelListItem, } from '../blockGroup/ContentModelListItem'; import type { ContentModelParagraph, ReadonlyContentModelParagraph } from './ContentModelParagraph'; -import type { ContentModelTable, ReadonlyContentModelTable } from './ContentModelTable'; +import type { + ContentModelTable, + ReadonlyContentModelTable, + ShallowMutableContentModelTable, +} from './ContentModelTable'; /** * A union type of Content Model Block @@ -38,3 +45,15 @@ export type ReadonlyContentModelBlock = | ReadonlyContentModelParagraph | ContentModelEntity | ReadonlyContentModelDivider; + +/** + * A union type of Content Model Block (Shallow mutable) + */ +export type ShallowMutableContentModelBlock = + | ShallowMutableContentModelFormatContainer + | ShallowMutableContentModelListItem + | ShallowMutableContentModelGeneralBlock + | ShallowMutableContentModelTable + | ContentModelParagraph + | ContentModelEntity + | ContentModelDivider; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTable.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTable.ts index b13dfeb8975..741fd7f8abc 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTable.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTable.ts @@ -1,9 +1,18 @@ -import type { ContentModelBlockBase, ReadonlyContentModelBlockBase } from './ContentModelBlockBase'; +import type { + ContentModelBlockBase, + ReadonlyContentModelBlockBase, + ShallowMutableContentModelBlockBase, +} from './ContentModelBlockBase'; import type { ContentModelTableFormat } from '../format/ContentModelTableFormat'; -import type { ContentModelTableRow, ReadonlyContentModelTableRow } from './ContentModelTableRow'; +import type { + ContentModelTableRow, + ReadonlyContentModelTableRow, + ShallowMutableContentModelTableRow, +} from './ContentModelTableRow'; import type { ContentModelWithDataset, ReadonlyContentModelWithDataset, + ShallowMutableContentModelWithDataset, } from '../format/ContentModelWithDataset'; import type { TableMetadataFormat } from '../format/metadata/TableMetadataFormat'; @@ -40,3 +49,20 @@ export interface ReadonlyContentModelTable */ readonly rows: ReadonlyArray; } + +/** + * Content Model of Table (Shallow mutable) + */ +export interface ShallowMutableContentModelTable + extends ShallowMutableContentModelBlockBase<'Table', ContentModelTableFormat, HTMLTableElement>, + ShallowMutableContentModelWithDataset { + /** + * Widths of each column + */ + widths: number[]; + + /** + * Cells of this table + */ + rows: ShallowMutableContentModelTableRow[]; +} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTableRow.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTableRow.ts index 309808338fd..3dd881f7309 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTableRow.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelTableRow.ts @@ -1,4 +1,4 @@ -import type { MutableMark, ReadonlyMark } from '../common/MutableMark'; +import type { MutableMark, ReadonlyMark, ShallowMutableMark } from '../common/MutableMark'; import type { ContentModelBlockFormat } from '../format/ContentModelBlockFormat'; import type { ContentModelBlockWithCache } from '../common/ContentModelBlockWithCache'; import type { @@ -39,11 +39,25 @@ export interface ContentModelTableRow */ export interface ReadonlyContentModelTableRow extends ReadonlyMark, + Readonly, ContentModelBlockWithCache, - ReadonlyContentModelWithFormat, - Readonly { + ReadonlyContentModelWithFormat { /** * Cells of this table */ readonly cells: ReadonlyArray; } + +/** + * Content Model of Table (Readonly) + */ +export interface ShallowMutableContentModelTableRow + extends ShallowMutableMark, + ContentModelTableRowCommon, + ContentModelBlockWithCache, + ContentModelWithFormat { + /** + * Cells of this table + */ + cells: ReadonlyContentModelTableCell[]; +} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts b/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts index b8b0d695314..72477a13d4a 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts @@ -43,7 +43,10 @@ import type { ContentModelSelectionMarker, ReadonlyContentModelSelectionMarker, } from '../segment/ContentModelSelectionMarker'; -import type { ContentModelTable, ReadonlyContentModelTable } from '../block/ContentModelTable'; +import type { + ReadonlyContentModelTable, + ShallowMutableContentModelTable, +} from '../block/ContentModelTable'; import type { ShallowMutableContentModelTableCell, ReadonlyContentModelTableCell, @@ -72,7 +75,7 @@ export type MutableType = T extends ReadonlyContentModelGeneralSegment : T extends ReadonlyContentModelParagraph ? ContentModelParagraph : T extends ReadonlyContentModelTable - ? ContentModelTable + ? ShallowMutableContentModelTable : T extends ReadonlyContentModelTableRow ? ContentModelTableRow : T extends ReadonlyContentModelTableCell diff --git a/packages/roosterjs-content-model-types/lib/index.ts b/packages/roosterjs-content-model-types/lib/index.ts index 5510fe6d6f7..242af3ef074 100644 --- a/packages/roosterjs-content-model-types/lib/index.ts +++ b/packages/roosterjs-content-model-types/lib/index.ts @@ -99,6 +99,7 @@ export { ExportContentMode } from './enum/ExportContentMode'; export { ContentModelBlock, ReadonlyContentModelBlock, + ShallowMutableContentModelBlock, } from './contentModel/block/ContentModelBlock'; export { ContentModelParagraph, @@ -108,6 +109,7 @@ export { export { ContentModelTable, ReadonlyContentModelTable, + ShallowMutableContentModelTable, } from './contentModel/block/ContentModelTable'; export { ContentModelDivider, @@ -125,6 +127,7 @@ export { ContentModelTableRow, ContentModelTableRowCommon, ReadonlyContentModelTableRow, + ShallowMutableContentModelTableRow, } from './contentModel/block/ContentModelTableRow'; export { ContentModelEntity } from './contentModel/entity/ContentModelEntity'; From 0230a26f2b27c824e2cfdbddbc906b5818d0eb18 Mon Sep 17 00:00:00 2001 From: Jiuqing Song Date: Thu, 16 May 2024 10:32:03 -0700 Subject: [PATCH 12/15] add test --- .../test/modelApi/common/mutateTest.ts | 235 ++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 packages/roosterjs-content-model-dom/test/modelApi/common/mutateTest.ts diff --git a/packages/roosterjs-content-model-dom/test/modelApi/common/mutateTest.ts b/packages/roosterjs-content-model-dom/test/modelApi/common/mutateTest.ts new file mode 100644 index 00000000000..d4b31594cc9 --- /dev/null +++ b/packages/roosterjs-content-model-dom/test/modelApi/common/mutateTest.ts @@ -0,0 +1,235 @@ +import { createContentModelDocument } from '../../../lib/modelApi/creators/createContentModelDocument'; +import { createListItem } from '../../../lib/modelApi/creators/createListItem'; +import { createListLevel } from '../../../lib/modelApi/creators/createListLevel'; +import { createParagraph } from '../../../lib/modelApi/creators/createParagraph'; +import { createTable } from '../../../lib/modelApi/creators/createTable'; +import { createTableCell } from '../../../lib/modelApi/creators/createTableCell'; +import { createText } from '../../../lib/modelApi/creators/createText'; +import { mutateBlock, mutateSegment, mutateSegments } from '../../../lib/modelApi/common/mutate'; + +const mockedCache = 'CACHE' as any; + +describe('mutate', () => { + it('mutate a block without cache', () => { + const block = {} as any; + + const mutatedBlock = mutateBlock(block); + + expect(mutatedBlock).toBe(block); + expect(mutatedBlock).toEqual({} as any); + }); + + it('mutate a block with cache', () => { + const block = {} as any; + + block.cachedElement = mockedCache; + + const mutatedBlock = mutateBlock(block); + + expect(mutatedBlock).toBe(block); + expect(mutatedBlock).toEqual({} as any); + }); + + it('mutate a block group with cache', () => { + const doc = createContentModelDocument(); + const para = createParagraph(); + + doc.cachedElement = mockedCache; + para.cachedElement = mockedCache; + + doc.blocks.push(para); + + const mutatedBlock = mutateBlock(doc); + + expect(mutatedBlock).toBe(doc); + expect(mutatedBlock).toEqual({ + blockGroupType: 'Document', + blocks: [ + { + blockType: 'Paragraph', + segments: [], + format: {}, + cachedElement: mockedCache, + }, + ], + } as any); + }); + + it('mutate a table', () => { + const table = createTable(1); + const cell = createTableCell(); + const para = createParagraph(); + + table.cachedElement = mockedCache; + table.rows[0].cachedElement = mockedCache; + cell.cachedElement = mockedCache; + para.cachedElement = mockedCache; + + cell.blocks.push(para); + table.rows[0].cells.push(cell); + + const mutatedBlock = mutateBlock(table); + + expect(mutatedBlock).toBe(table); + expect(mutatedBlock).toEqual({ + blockType: 'Table', + rows: [ + { + cells: [ + { + blockGroupType: 'TableCell', + blocks: [ + { + blockType: 'Paragraph', + segments: [], + format: {}, + cachedElement: mockedCache, + }, + ], + format: {}, + spanLeft: false, + spanAbove: false, + isHeader: false, + dataset: {}, + cachedElement: mockedCache, + }, + ], + height: 0, + format: {}, + }, + ], + format: {}, + widths: [], + dataset: {}, + } as any); + }); + + it('mutate a list', () => { + const level = createListLevel('OL'); + const list = createListItem([level]); + const para = createParagraph(); + + level.cachedElement = mockedCache; + list.cachedElement = mockedCache; + para.cachedElement = mockedCache; + + list.blocks.push(para); + + const mutatedBlock = mutateBlock(list); + + expect(mutatedBlock).toBe(list); + expect(mutatedBlock).toEqual({ + blockType: 'BlockGroup', + format: {}, + blockGroupType: 'ListItem', + blocks: [ + { + blockType: 'Paragraph', + segments: [], + format: {}, + cachedElement: mockedCache, + }, + ], + levels: [{ listType: 'OL', format: {}, dataset: {} }], + formatHolder: { + segmentType: 'SelectionMarker', + isSelected: false, + format: {}, + }, + } as any); + }); +}); + +describe('mutateSegments', () => { + it('empty paragraph', () => { + const para = createParagraph(); + + para.cachedElement = mockedCache; + + const result = mutateSegments(para, []); + + expect(result).toEqual([para, [], []]); + expect(result[0].cachedElement).toBeUndefined(); + }); + + it('Paragraph with correct segments', () => { + const para = createParagraph(); + + para.cachedElement = mockedCache; + + const text1 = createText('test1'); + const text2 = createText('test2'); + const text3 = createText('test3'); + const text4 = createText('test4'); + + para.segments.push(text1, text2, text3, text4); + + const result = mutateSegments(para, [text2, text4]); + + expect(result).toEqual([para, [text2, text4], [1, 3]]); + expect(result[0].cachedElement).toBeUndefined(); + }); + + it('Paragraph with incorrect segments', () => { + const para = createParagraph(); + + para.cachedElement = mockedCache; + + const text1 = createText('test1'); + const text2 = createText('test2'); + const text3 = createText('test3'); + const text4 = createText('test4'); + + para.segments.push(text1, text2, text3); + + const result = mutateSegments(para, [text2, text4]); + + expect(result).toEqual([para, [text2], [1]]); + expect(result[0].cachedElement).toBeUndefined(); + }); +}); + +describe('mutateSegment', () => { + let callbackSpy: jasmine.Spy; + + beforeEach(() => { + callbackSpy = jasmine.createSpy('callback'); + }); + + it('Paragraph with correct segment', () => { + const para = createParagraph(); + + para.cachedElement = mockedCache; + + const text1 = createText('test1'); + const text2 = createText('test2'); + const text3 = createText('test3'); + + para.segments.push(text1, text2, text3); + + const result = mutateSegment(para, text2, callbackSpy); + + expect(result).toEqual([para, text2, 1]); + expect(result[0].cachedElement).toBeUndefined(); + expect(callbackSpy).toHaveBeenCalledTimes(1); + expect(callbackSpy).toHaveBeenCalledWith(text2, para, 1); + }); + + it('Paragraph with incorrect segment', () => { + const para = createParagraph(); + + para.cachedElement = mockedCache; + + const text1 = createText('test1'); + const text2 = createText('test2'); + const text3 = createText('test3'); + + para.segments.push(text1, text3); + + const result = mutateSegment(para, text2, callbackSpy); + + expect(result).toEqual([para, null, -1]); + expect(result[0].cachedElement).toBeUndefined(); + expect(callbackSpy).toHaveBeenCalledTimes(0); + }); +}); From 6dbd78ba60145449bf919400a7b701cd63dc83c5 Mon Sep 17 00:00:00 2001 From: Jiuqing Song Date: Fri, 17 May 2024 12:03:43 -0700 Subject: [PATCH 13/15] improve --- .../lib/contentModel/block/ContentModelParagraph.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelParagraph.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelParagraph.ts index 987c7033a3b..4db9b6ba111 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelParagraph.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelParagraph.ts @@ -56,7 +56,7 @@ export interface ReadonlyContentModelParagraph /** * Segment format on this paragraph. This is mostly used for default format */ - readonly segmentFormat?: ContentModelSegmentFormat; + readonly segmentFormat?: Readonly; /** * Decorator info for this paragraph, used by heading and P tags From b4ab1346a3b37a27bcf30650fc471ccd2b2c3a2b Mon Sep 17 00:00:00 2001 From: Jiuqing Song Date: Mon, 20 May 2024 11:37:53 -0700 Subject: [PATCH 14/15] improve --- .../contentModel/block/ContentModelBlock.ts | 8 +++++-- .../block/ContentModelParagraph.ts | 23 +++++++++++++++++++ .../segment/ContentModelSegment.ts | 12 ++++++++++ .../lib/index.ts | 2 ++ 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlock.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlock.ts index 3ae77cedd1c..7ec515f4e77 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlock.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelBlock.ts @@ -15,7 +15,11 @@ import type { ReadonlyContentModelListItem, ShallowMutableContentModelListItem, } from '../blockGroup/ContentModelListItem'; -import type { ContentModelParagraph, ReadonlyContentModelParagraph } from './ContentModelParagraph'; +import type { + ContentModelParagraph, + ReadonlyContentModelParagraph, + ShallowMutableContentModelParagraph, +} from './ContentModelParagraph'; import type { ContentModelTable, ReadonlyContentModelTable, @@ -54,6 +58,6 @@ export type ShallowMutableContentModelBlock = | ShallowMutableContentModelListItem | ShallowMutableContentModelGeneralBlock | ShallowMutableContentModelTable - | ContentModelParagraph + | ShallowMutableContentModelParagraph | ContentModelEntity | ContentModelDivider; diff --git a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelParagraph.ts b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelParagraph.ts index 4db9b6ba111..94a46391352 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelParagraph.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/block/ContentModelParagraph.ts @@ -6,6 +6,7 @@ import type { import type { ContentModelSegment, ReadonlyContentModelSegment, + ShallowMutableContentModelSegment, } from '../segment/ContentModelSegment'; import type { ContentModelSegmentFormat } from '../format/ContentModelSegmentFormat'; @@ -63,3 +64,25 @@ export interface ReadonlyContentModelParagraph */ readonly decorator?: ReadonlyContentModelParagraphDecorator; } + +/** + * Content Model of Paragraph (Shallow mutable) + */ +export interface ShallowMutableContentModelParagraph + extends ContentModelParagraphCommon, + ContentModelBlockBase<'Paragraph'> { + /** + * Segments within this paragraph + */ + segments: ShallowMutableContentModelSegment[]; + + /** + * Segment format on this paragraph. This is mostly used for default format + */ + segmentFormat?: ContentModelSegmentFormat; + + /** + * Decorator info for this paragraph, used by heading and P tags + */ + decorator?: ContentModelParagraphDecorator; +} diff --git a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegment.ts b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegment.ts index 7fec3926408..4989fddc1c4 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegment.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/segment/ContentModelSegment.ts @@ -3,6 +3,7 @@ import type { ContentModelEntity } from '../entity/ContentModelEntity'; import type { ContentModelGeneralSegment, ReadonlyContentModelGeneralSegment, + ShallowMutableContentModelGeneralSegment, } from './ContentModelGeneralSegment'; import type { ContentModelImage, ReadonlyContentModelImage } from './ContentModelImage'; import type { @@ -32,3 +33,14 @@ export type ReadonlyContentModelSegment = | ReadonlyContentModelGeneralSegment | ContentModelEntity | ReadonlyContentModelImage; + +/** + * Union type of Content Model Segment (Shallow mutable) + */ +export type ShallowMutableContentModelSegment = + | ContentModelSelectionMarker + | ContentModelText + | ContentModelBr + | ShallowMutableContentModelGeneralSegment + | ContentModelEntity + | ContentModelImage; diff --git a/packages/roosterjs-content-model-types/lib/index.ts b/packages/roosterjs-content-model-types/lib/index.ts index 242af3ef074..9f696e2c23b 100644 --- a/packages/roosterjs-content-model-types/lib/index.ts +++ b/packages/roosterjs-content-model-types/lib/index.ts @@ -105,6 +105,7 @@ export { ContentModelParagraph, ContentModelParagraphCommon, ReadonlyContentModelParagraph, + ShallowMutableContentModelParagraph, } from './contentModel/block/ContentModelParagraph'; export { ContentModelTable, @@ -202,6 +203,7 @@ export { export { ContentModelSegment, ReadonlyContentModelSegment, + ShallowMutableContentModelSegment, } from './contentModel/segment/ContentModelSegment'; export { From 06cfab1ad316f3041cc53f7c59d2bf29f2faa96e Mon Sep 17 00:00:00 2001 From: Jiuqing Song Date: Mon, 20 May 2024 13:20:01 -0700 Subject: [PATCH 15/15] improve --- .../lib/modelApi/common/mutate.ts | 20 +++++++++++++------ .../lib/contentModel/common/MutableType.ts | 4 ++-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/packages/roosterjs-content-model-dom/lib/modelApi/common/mutate.ts b/packages/roosterjs-content-model-dom/lib/modelApi/common/mutate.ts index 699bb3e7616..e2ce4bc59f3 100644 --- a/packages/roosterjs-content-model-dom/lib/modelApi/common/mutate.ts +++ b/packages/roosterjs-content-model-dom/lib/modelApi/common/mutate.ts @@ -1,6 +1,4 @@ import type { - ContentModelParagraph, - ContentModelSegment, MutableType, ReadonlyContentModelBlock, ReadonlyContentModelBlockGroup, @@ -8,6 +6,8 @@ import type { ReadonlyContentModelParagraph, ReadonlyContentModelSegment, ReadonlyContentModelTable, + ShallowMutableContentModelParagraph, + ShallowMutableContentModelSegment, } from 'roosterjs-content-model-types'; /** @@ -44,9 +44,13 @@ export function mutateBlock { @@ -71,8 +75,12 @@ export function mutateSegments( export function mutateSegment( paragraph: ReadonlyContentModelParagraph, segment: T, - callback?: (segment: MutableType, paragraph: ContentModelParagraph, index: number) => void -): [ContentModelParagraph, MutableType | null, number] { + callback?: ( + segment: MutableType, + paragraph: ShallowMutableContentModelParagraph, + index: number + ) => void +): [ShallowMutableContentModelParagraph, MutableType | null, number] { const [mutablePara, mutableSegments, indexes] = mutateSegments(paragraph, [segment]); const mutableSegment = (mutableSegments[0] as ReadonlyContentModelSegment) == segment diff --git a/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts b/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts index 72477a13d4a..ecc921b98e6 100644 --- a/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts +++ b/packages/roosterjs-content-model-types/lib/contentModel/common/MutableType.ts @@ -32,8 +32,8 @@ import type { ReadonlyContentModelListLevel, } from '../decorator/ContentModelListLevel'; import type { - ContentModelParagraph, ReadonlyContentModelParagraph, + ShallowMutableContentModelParagraph, } from '../block/ContentModelParagraph'; import type { ContentModelParagraphDecorator, @@ -73,7 +73,7 @@ export type MutableType = T extends ReadonlyContentModelGeneralSegment : T extends ReadonlyContentModelBr ? ContentModelBr : T extends ReadonlyContentModelParagraph - ? ContentModelParagraph + ? ShallowMutableContentModelParagraph : T extends ReadonlyContentModelTable ? ShallowMutableContentModelTable : T extends ReadonlyContentModelTableRow