// Type definitions for roosterjs (Version 9.31.0)
// Generated by dts tool from roosterjs
// Project: https://github.com/Microsoft/roosterjs

/**
 * Create a new Editor instance using the given options
 * @param contentDiv The html div element needed for creating the editor
 * @param additionalPlugins The additional user defined plugins. Currently the default plugins that are already included are
 * PastePlugin, EditPlugin, user don't need to add those.
 * @param initialModel The initial content model to show in editor. It can't be removed by undo, user need to manually remove it if needed.
 * @returns The Editor instance
 */
export function createEditor(contentDiv: HTMLDivElement, additionalPlugins?: EditorPlugin[], initialModel?: ContentModelDocument): IEditor;

/**
 * The format object for a segment in Content Model
 */
export type ContentModelSegmentFormat = TextColorFormat & BackgroundColorFormat & LetterSpacingFormat & FontSizeFormat & FontFamilyFormat & BoldFormat & ItalicFormat & UnderlineFormat & StrikeFormat & SuperOrSubScriptFormat & LineHeightFormat;

/**
 * Represent a content model with format
 */
export interface ContentModelWithFormat<T extends ContentModelFormatBase> {
    /**
     * Format of this model
     */
    format: T;
}

/**
 * Represent a content model with format (Readonly)
 */
export interface ReadonlyContentModelWithFormat<T extends ContentModelFormatBase> {
    /**
     * Format of this model
     */
    readonly format: Readonly<T>;
}

/**
 * Format of Table
 */
export type ContentModelTableFormat = ContentModelBlockFormat & IdFormat & AriaFormat & BorderFormat & BorderBoxFormat & SpacingFormat & MarginFormat & DisplayFormat & TableLayoutFormat & SizeFormat;

/**
 * Represents base format of an element that supports dataset and/or metadata
 */
export type ContentModelWithDataset<T> = MutableMark & {
    /**
     * dataset of this element
     */
    dataset: DatasetFormat;
};

/**
 * Represents base format of an element that supports dataset and/or metadata (Readonly)
 */
export type ReadonlyContentModelWithDataset<T> = ReadonlyMark & {
    /**
     * dataset of this element
     */
    readonly dataset: ReadonlyDatasetFormat;
};

/**
 * Represents base format of an element that supports dataset and/or metadata (Readonly)
 */
export type ShallowMutableContentModelWithDataset<T> = ShallowMutableMark & {
    /**
     * dataset of this element
     */
    dataset: DatasetFormat;
};

/**
 * The format object for a paragraph in Content Model
 */
export type ContentModelBlockFormat = BackgroundColorFormat & DirectionFormat & TextAlignFormat & HtmlAlignFormat & MarginFormat & PaddingFormat & LineHeightFormat & WhiteSpaceFormat & BorderFormat & TextIndentFormat & IdFormat;

/**
 * Format of table cell
 */
export type ContentModelTableCellFormat = ContentModelBlockFormat & BorderBoxFormat & VerticalAlignFormat & WordBreakFormat & TextColorFormat & SizeFormat & BoldFormat;

/**
 * The format object for a list item in Content Model
 */
export type ContentModelListItemFormat = DirectionFormat & LineHeightFormat & MarginFormat & PaddingFormat & TextAlignFormat & ListStyleFormat & TextIndentFormat & BackgroundColorFormat;

/**
 * The format object for a list level in Content Model
 */
export type ContentModelListItemLevelFormat = ListThreadFormat & DirectionFormat & TextAlignFormat & MarginFormat & PaddingFormat & ListStyleFormat;

/**
 * The format object for a hyperlink in Content Model
 */
export type ContentModelHyperLinkFormat = LinkFormat & TextColorFormat & BackgroundColorFormat & UnderlineFormat & DisplayFormat & MarginFormat & PaddingFormat & BorderFormat & SizeFormat & TextAlignFormat & UndeletableFormat;

/**
 * The format object for a code element in Content Model
 */
export type ContentModelCodeFormat = FontFamilyFormat & DisplayFormat;

/**
 * Type for FormatContainer
 */
export type ContentModelFormatContainerFormat = ContentModelBlockFormat & ContentModelSegmentFormat & SizeFormat & DisplayFormat;

/**
 * The format object for a divider in Content Model
 */
export type ContentModelDividerFormat = ContentModelBlockFormat & DisplayFormat & SizeFormat;

/**
 * Base type of content model format.
 * All content model format should only have simple value type (string, number, boolean).
 * 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 = string | number | boolean | undefined | null> = {
    [key: string]: V;
};

/**
 * A map from Content Model format name to its combined format type
 */
export interface ContentModelFormatMap {
    /**
     * Format type for block
     */
    block: ContentModelBlockFormat;
    /**
     * Format type for style based segment format
     */
    styleBasedSegment: ContentModelSegmentFormat;
    /**
     * Format type for element based segment format
     */
    elementBasedSegment: ContentModelSegmentFormat;
    /**
     * Format type for segment
     */
    segment: ContentModelSegmentFormat;
    /**
     * Format type for segment on block.
     * Block can have format that can impact segment, such as font and color.
     * But some segment format should not be read from block, like background color.
     */
    segmentOnBlock: ContentModelSegmentFormat;
    /**
     * Format type for segment on table cell.
     * This is very similar with segmentOnBlock, without 'textColor'. Because we will keep
     * text color style on table cell to indicate auto calculated segment color when set table cell shade.
     * Segments can set its own text color to override this value
     */
    segmentOnTableCell: ContentModelSegmentFormat;
    /**
     * Format type for table, except alignment related styles
     */
    table: ContentModelTableFormat;
    /**
     * Format type for tableCell
     */
    tableCell: ContentModelTableCellFormat;
    /**
     * Format type for tableRow
     */
    tableRow: ContentModelBlockFormat;
    /**
     * Format type for tableColumn
     */
    tableColumn: SizeFormat;
    /**
     * Format type for table border
     */
    tableBorder: ContentModelTableFormat;
    /**
     * Format type for tableCell border
     */
    tableCellBorder: ContentModelTableCellFormat;
    /**
     * Format type for li element
     */
    listItemElement: ContentModelListItemFormat;
    /**
     * Format type for listItem
     */
    listItemThread: ContentModelListItemLevelFormat;
    /**
     * Format type for listLevel
     */
    listLevel: ContentModelListItemLevelFormat;
    /**
     * Format type for listLevel
     */
    listLevelThread: ContentModelListItemLevelFormat;
    /**
     * Format type for image
     */
    image: ContentModelImageFormat;
    /**
     * Format type for link
     */
    link: ContentModelHyperLinkFormat;
    /**
     * Format type for segment inside link
     */
    segmentUnderLink: ContentModelHyperLinkFormat;
    /**
     * Format type for code
     */
    code: FontFamilyFormat;
    /**
     * Format type for dataset
     */
    dataset: DatasetFormat;
    /**
     * Format type for divider
     */
    divider: ContentModelDividerFormat;
    /**
     * Format type for format container
     */
    container: ContentModelFormatContainerFormat;
    /**
     * Format type for entity
     */
    entity: ContentModelEntityFormat;
    /**
     * Format type for general model
     */
    general: ContentModelSegmentFormat;
}

/**
 * The format object for an image in Content Model
 */
export type ContentModelImageFormat = ContentModelSegmentFormat & IdFormat & SizeFormat & MarginFormat & PaddingFormat & BorderFormat & BoxShadowFormat & DisplayFormat & FloatFormat & VerticalAlignFormat & ImageStateFormat;

/**
 * The format object for an entity in Content Model
 */
export type ContentModelEntityFormat = EntityInfoFormat & IdFormat;

/**
 * Represents a record of all format handlers
 */
export interface FormatHandlerTypeMap {
    /**
     * Format for AriaFormat
     */
    aria: AriaFormat;
    /**
     * Format for BackgroundColorFormat
     */
    backgroundColor: BackgroundColorFormat;
    /**
     * Format for BoldFormat
     */
    bold: BoldFormat;
    /**
     * Format for BorderFormat
     */
    border: BorderFormat;
    /**
     * Format for BorderBoxFormat
     */
    borderBox: BorderBoxFormat;
    /**
     * Format for BoxShadowFormat
     */
    boxShadow: BoxShadowFormat;
    /**
     * Format for DatasetFormat
     */
    dataset: DatasetFormat;
    /**
     * Format for DirectionFormat
     */
    direction: DirectionFormat;
    /**
     * Format for DisplayFormat
     */
    display: DisplayFormat;
    /**
     * Format for EntityInfoFormat and IdFormat
     */
    entity: EntityInfoFormat & IdFormat;
    /**
     * Format for FloatFormat
     */
    float: FloatFormat;
    /**
     * Format for FontFamilyFormat
     */
    fontFamily: FontFamilyFormat;
    /**
     * Format for FontSizeFormat
     */
    fontSize: FontSizeFormat;
    /**
     * Format for HtmlAlignFormat
     */
    htmlAlign: HtmlAlignFormat;
    /**
     * Format for IdFormat
     */
    id: IdFormat;
    /**
     * Format of ImageStateFormat
     */
    imageState: ImageStateFormat;
    /**
     * Format for ItalicFormat
     */
    italic: ItalicFormat;
    /**
     * Format for LetterSpacingFormat
     */
    letterSpacing: LetterSpacingFormat;
    /**
     * Format for LineHeightFormat
     */
    lineHeight: LineHeightFormat;
    /**
     * Format for LinkFormat
     */
    link: LinkFormat;
    /**
     * Format for ListThreadFormat (used by list item)
     */
    listItemThread: ListThreadFormat;
    /**
     * Format for ListThreadFormat (used by list level)
     */
    listLevelThread: ListThreadFormat;
    /**
     * Format for ListStyleFormat
     */
    listStyle: ListStyleFormat;
    /**
     * Format for MarginFormat
     */
    margin: MarginFormat;
    /**
     * Format for PaddingFormat
     */
    padding: PaddingFormat;
    /**
     * Format for SizeFormat
     */
    size: SizeFormat;
    /**
     * Format for StrikeFormat
     */
    strike: StrikeFormat;
    /**
     * Format for SuperOrSubScriptFormat
     */
    superOrSubScript: SuperOrSubScriptFormat;
    /**
     * Format for TableLayout
     */
    tableLayout: TableLayoutFormat;
    /**
     * Format for SpacingFormat
     */
    tableSpacing: SpacingFormat;
    /**
     * Format for TextAlignFormat
     */
    textAlign: TextAlignFormat;
    /**
     * Format for TextColorFormat
     */
    textColor: TextColorFormat;
    /**
     * Format for TextColorFormat, for Table Cell only
     */
    textColorOnTableCell: TextColorFormat;
    /**
     * Format for TextIndentFormat
     */
    textIndent: TextIndentFormat;
    /**
     * Format for Undeletable link
     */
    undeletableLink: UndeletableFormat;
    /**
     * Format for UnderlineFormat
     */
    underline: UnderlineFormat;
    /**
     * Format for VerticalAlignFormat
     */
    verticalAlign: VerticalAlignFormat;
    /**
     * Format for WhiteSpaceFormat
     */
    whiteSpace: WhiteSpaceFormat;
    /**
     * Format for WordBreakFormat
     */
    wordBreak: WordBreakFormat;
}

/**
 * Key of all format handler
 */
export type FormatKey = keyof FormatHandlerTypeMap;

/**
 * Format of background color
 */
export type AriaFormat = {
    /**
     * Aria-describedby  attribute
     */
    ariaDescribedBy?: string;
    /**
     * Title attribute
     */
    title?: string;
};

/**
 * Format of background color
 */
export type BackgroundColorFormat = {
    /**
     * Background color
     */
    backgroundColor?: string;
};

/**
 * Format of bold
 */
export type BoldFormat = {
    /**
     * Font weight of the element
     */
    fontWeight?: string;
};

/**
 * Format of font family
 */
export type FontFamilyFormat = {
    /**
     * Font family
     */
    fontFamily?: string;
};

/**
 * Format of font size
 */
export type FontSizeFormat = {
    /**
     * Font size
     */
    fontSize?: string;
};

/**
 * Format of italic
 */
export type ItalicFormat = {
    /**
     * Whether it is in italic
     */
    italic?: boolean;
};

/**
 * Format of letter spacing
 */
export type LetterSpacingFormat = {
    /**
     * letter-spacing style
     */
    letterSpacing?: string;
};

/**
 * Format of line height
 */
export type LineHeightFormat = {
    /**
     * Line height of this block
     */
    lineHeight?: string;
};

/**
 * Format of strikethrough
 */
export type StrikeFormat = {
    /**
     * Whether it has strike through
     */
    strikethrough?: boolean;
};

/**
 * Format of superscript/subscript
 */
export type SuperOrSubScriptFormat = {
    /**
     * Sequence of superscript/subscript
     * e.g. sub super sub
     */
    superOrSubScriptSequence?: string;
};

/**
 * Format of text color
 */
export type TextColorFormat = {
    /**
     * Text color
     */
    textColor?: string;
};

/**
 * Format of underline
 */
export type UnderlineFormat = {
    /**
     * Whether it has underline
     */
    underline?: boolean;
};

/**
 * Format of border box
 */
export type BorderBoxFormat = {
    /**
     * Whether use border-box for this element
     */
    useBorderBox?: boolean;
};

/**
 * Format of vertical alignment
 */
export type VerticalAlignFormat = {
    /**
     * Vertical alignment
     */
    verticalAlign?: 'top' | 'middle' | 'bottom';
};

/**
 * Format of word break
 */
export type WordBreakFormat = {
    /**
     * Word break CSS value
     */
    wordBreak?: string;
};

/**
 * Format of border
 */
export type BorderFormat = {
    /**
     * Top border in format 'width style color'
     */
    borderTop?: string;
    /**
     * Right border in format 'width style color'
     */
    borderRight?: string;
    /**
     * Bottom border in format 'width style color'
     */
    borderBottom?: string;
    /**
     * Left border in format 'width style color'
     */
    borderLeft?: string;
    /**
     * Radius to be applied in all borders corners
     */
    borderRadius?: string;
    /**
     * Radius to be applied in top left corner
     */
    borderTopLeftRadius?: string;
    /**
     * Radius to be applied in top right corner
     */
    borderTopRightRadius?: string;
    /**
     * Radius to be applied in bottom left corner
     */
    borderBottomLeftRadius?: string;
    /**
     * Radius to be applied in bottom right corner
     */
    borderBottomRightRadius?: string;
};

/**
 * Format of direction
 */
export type DirectionFormat = {
    /**
     * Text direction
     */
    direction?: 'ltr' | 'rtl';
};

/**
 * Format of HTML align attribute
 */
export type HtmlAlignFormat = {
    /**
     * Horizontal alignment, from HTML attribute "align"
     */
    htmlAlign?: 'start' | 'center' | 'end' | 'justify' | 'initial';
};

/**
 * Format of margin
 */
export type MarginFormat = {
    /**
     * Margin top value
     */
    marginTop?: string;
    /**
     * Margin right value
     */
    marginRight?: string;
    /**
     * Margin bottom value
     */
    marginBottom?: string;
    /**
     * Margin left value
     */
    marginLeft?: string;
};

/**
 * Format of padding
 */
export type PaddingFormat = {
    /**
     * Padding top value
     */
    paddingTop?: string;
    /**
     * Padding right value
     */
    paddingRight?: string;
    /**
     * Padding bottom value
     */
    paddingBottom?: string;
    /**
     * Padding left value
     */
    paddingLeft?: string;
};

/**
 * Format of text-align
 */
export type TextAlignFormat = {
    /**
     * Horizontal alignment, from CSS "text-align"
     */
    textAlign?: 'start' | 'center' | 'end' | 'justify' | 'initial';
};

/**
 * Format of text-indent
 */
export type TextIndentFormat = {
    /**
     * Text indent of a paragraph
     */
    textIndent?: string;
    /**
     * Due to the special behavior of text-indent style, we need to know if this text-indent style is already applied to any child block.
     * Then after that, we can ignore it for the block at the same level.
     */
    isTextIndentApplied?: boolean;
};

/**
 * Format of white space
 */
export type WhiteSpaceFormat = {
    /**
     * White space
     */
    whiteSpace?: string;
};

/**
 * Format of display
 */
export type DisplayFormat = {
    /**
     * Display of this element
     */
    display?: string;
};

/**
 * Format for element with Id
 */
export type IdFormat = {
    /**
     * Id of the element
     */
    id?: string;
};

/**
 * Format of spacing
 */
export type SpacingFormat = {
    /**
     * Whether borders of cells are collapsed together
     */
    borderCollapse?: boolean;
    /**
     * Whether borders of cells are separated
     */
    borderSeparate?: boolean;
};

/**
 * Format of Table Layout
 */
export type TableLayoutFormat = {
    /**
     * Whether borders of cells are collapsed together
     */
    tableLayout?: string;
};

/**
 * Format of hyper link
 */
export type LinkFormat = {
    /**
     * Name of this link
     */
    name?: string;
    /**
     * Href of the hyper link
     */
    href?: string;
    /**
     * Target of the hyper link
     */
    target?: string;
    /**
     * Id of anchor element
     */
    anchorId?: string;
    /**
     * Class attribute of anchor element
     */
    anchorClass?: string;
    /**
     * Title attribute of anchor element
     */
    anchorTitle?: string;
    /**
     * Rel attribute of anchor element
     */
    relationship?: string;
};

/**
 * Format of element size
 */
export type SizeFormat = {
    /**
     * Width of the element
     */
    width?: string;
    /**
     * Height of the element
     */
    height?: string;
    /**
     * Maximum width of the element
     */
    maxWidth?: string;
    /**
     * Maximum height of the element
     */
    maxHeight?: string;
    /**
     * Minimum width of the element
     */
    minWidth?: string;
    /**
     * Minimum height of the element
     */
    minHeight?: string;
};

/**
 * Format of box shadow
 */
export type BoxShadowFormat = {
    /**
     * Box shadow in format "offset-x  offset-y  blur-radius  spread-radius  color"
     */
    boxShadow?: string;
};

/**
 * Format of list thread id
 */
export type ListThreadFormat = {
    /**
     * When restart a new list thread, set this value to be the restart number.
     * Otherwise, leave it undefined to continue last list
     */
    startNumberOverride?: number;
    /**
     * For a list item, it should have "list-item" (default value) for display style. In those case,
     * we will leave displayForDummyItem as undefined.
     * But if there is other value than "list-item" in display style, we store it here and treat this item
     * as a dummy item. Dummy item won't have list bullet or number, and we won't add 1 for list number for such items
     */
    displayForDummyItem?: string;
};

/**
 * Format of list-style
 */
export type ListStyleFormat = {
    /**
     * list-style-position
     */
    listStylePosition?: string;
    /**
     * list-style-type
     */
    listStyleType?: string;
};

/**
 * Format of float
 */
export type FloatFormat = {
    /**
     * Float style
     */
    float?: string;
};

/**
 * Format of entity type
 */
export type EntityInfoFormat = {
    /**
     * For a readonly DOM element, we also treat it as entity, with isFakeEntity set to true
     */
    isFakeEntity?: boolean;
    /**
     * Whether the entity is readonly
     */
    isReadonly?: boolean;
    /**
     * Type of this entity
     */
    entityType?: string;
};

/**
 * Format of undeletable segments
 */
export type UndeletableFormat = {
    /**
     * When set to true, this link is not allowed to be deleted by deleteSelection API.
     * This is used to protect links that are not allowed to be deleted by user action.
     */
    undeletable?: boolean;
};

/**
 * The hidden property of an image
 */
export type ImageStateFormat = {
    /**
     * A hidden marker for the image state
     */
    imageState?: string;
};

/**
 * Represents dataset format of Content Model
 */
export type DatasetFormat = Record<string, string>;

/**
 * Represents dataset format of Content Model (Readonly)
 */
export type ReadonlyDatasetFormat = Readonly<Record<string, string>>;

/**
 * Format of table that stored as metadata
 */
export type TableMetadataFormat = {
    /**
     * Top border color for each row
     */
    topBorderColor?: string | null;
    /**
     * Bottom border color for each row
     */
    bottomBorderColor?: string | null;
    /**
     * Vertical border color for each row
     */
    verticalBorderColor?: string | null;
    /**
     * Set header row
     */
    hasHeaderRow?: boolean;
    /**
     * Header row background color for even cells
     */
    headerRowColor?: string | null;
    /**
     * Set first column
     */
    hasFirstColumn?: boolean;
    /**
     * Set banded columns
     */
    hasBandedColumns?: boolean;
    /**
     * Set banded rows
     */
    hasBandedRows?: boolean;
    /**
     * Background color for even row or even columns
     */
    bgColorEven?: string | null;
    /**
     * Background color for odd row or odd columns
     */
    bgColorOdd?: string | null;
    /**
     * Table Borders Type. Use value of constant TableBorderFormat as value
     */
    tableBorderFormat?: number;
    /**
     * Vertical alignment for each row
     */
    verticalAlign?: 'top' | 'middle' | 'bottom' | null;
};

/**
 * Format of list / list item that stored as metadata
 */
export type ListMetadataFormat = {
    /**
     * Style type for Ordered list. Use value of constant NumberingListType as value.
     */
    orderedStyleType?: number;
    /**
     * Style type for Unordered list. Use value of constant BulletListType as value.
     */
    unorderedStyleType?: number;
    /**
     * When set to true, if there is no orderedStyleType (for OL) or unorderedStyleType (for UL) specified, use the list from its level
     * For ordered list, the default list styles from levels are: 'decimal', 'lower-alpha', 'lower-roman', then loop
     * For unordered list, the default list styles from levels are: 'disc', 'circle', 'square', then loop
     */
    applyListStyleFromLevel?: boolean;
};

/**
 * Metadata for inline image resize
 */
export type ImageResizeMetadataFormat = {
    /**
     * Width after resize, in px.
     * If image is cropped, this is the width of visible part
     * If image is rotated, this is the width before rotation
     * @default clientWidth of the image
     */
    widthPx?: number;
    /**
     * Height after resize, in px.
     * If image is cropped, this is the height of visible part
     * If image is rotated, this is the height before rotation
     * @default clientHeight of the image
     */
    heightPx?: number;
};

/**
 * Metadata for inline image crop
 */
export type ImageCropMetadataFormat = {
    /**
     * Left cropped percentage. Rotation or resizing won't impact this percentage value
     * @default 0
     */
    leftPercent?: number;
    /**
     * Right cropped percentage. Rotation or resizing won't impact this percentage value
     * @default 0
     */
    rightPercent?: number;
    /**
     * Top cropped percentage. Rotation or resizing won't impact this percentage value
     * @default 0
     */
    topPercent?: number;
    /**
     * Bottom cropped percentage. Rotation or resizing won't impact this percentage value
     * @default 0
     */
    bottomPercent?: number;
};

/**
 * Metadata for inline image
 */
export type ImageMetadataFormat = ImageResizeMetadataFormat & ImageCropMetadataFormat & ImageRotateMetadataFormat & ImageFlipMetadataFormat & {
    /**
     * Original src of the image. This value will not be changed when edit image. We can always use it
     * to get the original image so that all editing operation will be on top of the original image.
     */
    readonly src?: string;
    /**
     * Natural width of the original image (specified by the src field, may not be the current edited image)
     */
    readonly naturalWidth?: number;
    /**
     * Natural height of the original image (specified by the src field, may not be the current edited image)
     */
    readonly naturalHeight?: number;
};

/**
 * Metadata for inline image rotate
 */
export type ImageRotateMetadataFormat = {
    /**
     * Rotated angle of inline image, in radian. Cropping or resizing won't impact this percentage value
     * @default 0
     */
    angleRad?: number;
};

/**
 *  Metadata for inline image flip
 */
export interface ImageFlipMetadataFormat {
    /**
     * If true, the image was flipped.
     */
    flippedVertical?: boolean;
    /**
     * If true, the image was flipped.
     */
    flippedHorizontal?: boolean;
}

/**
 * Format of table cell that stored as metadata
 */
export type TableCellMetadataFormat = {
    /**
     * Override default background color
     */
    bgColorOverride?: boolean;
    /**
     * Override default vertical align value
     */
    vAlignOverride?: boolean;
    /**
     * Override default border value
     */
    borderOverride?: boolean;
};

/**
 * Type of Block Group in Content Model
 */
export type ContentModelBlockGroupType = /**
 * Represents the document entry of Content Model
 */
'Document'
/**
 * Represents a FormatContainer
 */
 | 'FormatContainer'
/**
 * Represents a list item (LI) element
 */
 | 'ListItem'
/**
 * Represents a table cell (TD, TH) element
 */
 | 'TableCell'
/**
 * Represents a general HTML element that doesn't have a special type
 */
 | 'General';

/**
 * Type of Block in Content Model
 */
export type ContentModelBlockType = /**
 * Represent a Block Group
 */
'BlockGroup'
/**
 * Represent a Table
 */
 | 'Table'
/**
 * Represent a general paragraph (DIV, P, ...)
 */
 | 'Paragraph'
/**
 * Represent a block entity
 */
 | 'Entity'
/**
 * Represents a horizontal divider element
 */
 | 'Divider';

/**
 * Type of Segment in Content Model
 */
export type ContentModelSegmentType = /**
 * Represents a text node
 */
'Text'
/**
 * Represents a BR element
 */
 | 'Br'
/**
 * Represents an IMG element
 */
 | 'Image'
/**
 * Represents a selection marker. A selection marker is an empty segment that mark the start/end of selection
 */
 | 'SelectionMarker'
/**
 * Represents a general segment that doesn't have a special type
 */
 | 'General'
/**
 * Represents an inline entity
 */
 | 'Entity';

/**
 * Define entity lifecycle related operations
 */
export type EntityLifecycleOperation = /**
 * Notify plugins that there is a new plugin was added into editor.
 * Plugin can handle this event to entity hydration.
 * This event will be only fired once for each entity DOM node.
 * After undo, or copy/paste, since new DOM nodes were added, this event will be fired
 * for those entities represented by newly added nodes.
 */
'newEntity'
/**
 * Notify plugins that editor is generating HTML content for save.
 * Plugin should use this event to remove any temporary content, and only leave DOM nodes that
 * should be saved as HTML string.
 * This event will provide a cloned DOM tree for each entity, do NOT compare the DOM nodes with cached nodes
 * because it will always return false.
 */
 | 'replaceTemporaryContent'
/**
 * This event is triggered when an undo snapshot is taken while a custom logical root is used
 * Plugins can handle this event to include entity state to include in the snapshot
 */
 | 'snapshotEntityState'
/**
 * Notify plugins that a new entity state need to be updated to an entity.
 * This is normally happened when user undo/redo the content with an entity snapshot added by a plugin that handles entity
 */
 | 'updateEntityState'
/**
 * Notify plugins that user is clicking target to an entity
 */
 | 'click';

/**
 * Define possible operations to an entity
 */
export type EntityOperation = EntityLifecycleOperation | EntityRemovalOperation | EntityFormatOperation;

/**
 * Define entity removal related operations
 */
export type EntityRemovalOperation = /**
 * Notify plugins that user is removing an entity from its start position using DELETE key
 */
'removeFromStart'
/**
 * Notify plugins that user is remove an entity from its end position using BACKSPACE key
 */
 | 'removeFromEnd'
/**
 * Notify plugins that an entity is being overwritten.
 * This can be caused by key in, cut, paste, delete, backspace ... on a selection
 * which contains some entities.
 */
 | 'overwrite';

/**
 * DEfine entity format related operations
 */
export type EntityFormatOperation = /**
 * Tell plugins we are doing format change and an entity is inside the selection.
 * Plugin can handle this event and put root level node (must be under the entity wrapper) into
 * event.formattableRoots so editor will create content models for each root and do format to their contents
 */
'beforeFormat';

/**
 * Operations used by editTable() API
 */
export type TableOperation = TableVerticalInsertOperation | TableHorizontalInsertOperation | TableDeleteOperation | TableVerticalMergeOperation | TableHorizontalMergeOperation | TableCellMergeOperation | TableSplitOperation | TableAlignOperation | TableCellHorizontalAlignOperation | TableCellVerticalAlignOperation;

/**
 * Operations used by editTable() API for insert table cell vertically
 */
export type TableVerticalInsertOperation = /**
 * Insert a row above current row
 */
'insertAbove'
/**
 * Insert a row below current row
 */
 | 'insertBelow';

/**
 * Operations used by editTable() API for insert table cell horizontally
 */
export type TableHorizontalInsertOperation = /**
 * Insert a column on the left of current column
 */
'insertLeft'
/**
 * Insert a column on the right of current column
 */
 | 'insertRight';

/**
 * Operations used by editTable() API for delete table cells
 */
export type TableDeleteOperation = /**
 * Delete the whole table
 */
'deleteTable'
/**
 * Delete current column
 */
 | 'deleteColumn'
/**
 * Delete current row
 */
 | 'deleteRow';

/**
 * Operations used by editTable() API for merge table cells vertically
 */
export type TableVerticalMergeOperation = /**
 * Merge current row with the row above
 */
'mergeAbove'
/**
 * Merge current row with the row below
 */
 | 'mergeBelow';

/**
 * Operations used by editTable() API for merge table cells horizontally
 */
export type TableHorizontalMergeOperation = /**
 * Merge current column with the column on the left
 */
'mergeLeft'
/**
 * Merge current column with the column on the right
 */
 | 'mergeRight';

/**
 * Operations used by editTable() API for merge selected table cells
 */
export type TableCellMergeOperation = /**
 * Merge all selected cells
 */
'mergeCells';

/**
 * Operations used by editTable() API for split table cells
 */
export type TableSplitOperation = /**
 * Split current table cell horizontally
 */
'splitHorizontally'
/**
 * Split current table cell vertically
 */
 | 'splitVertically';

/**
 * Operations used by editTable() API for align table
 */
export type TableAlignOperation = /**
 * Align current table at the center
 */
'alignCenter'
/**
 * Align current table at the left
 */
 | 'alignLeft'
/**
 * Align current table at the right
 */
 | 'alignRight';

/**
 * Operations used by editTable() API for align table cell horizontally
 */
export type TableCellHorizontalAlignOperation = /**
 * Align current content table cell at the left
 */
'alignCellLeft'
/**
 * Align current content table cell at the center
 */
 | 'alignCellCenter'
/**
 * Align current content table cell at the right
 */
 | 'alignCellRight';

/**
 * Operations used by editTable() API for align table cell vertically
 */
export type TableCellVerticalAlignOperation = /**
 * Align current content table cell at the top
 */
'alignCellTop'
/**
 * Align current table cell at the middle
 */
 | 'alignCellMiddle'
/**
 * Align current table cell at the bottom
 */
 | 'alignCellBottom';

/**
 * Specify what type of content to paste
 */
export type PasteType = /**
 * Default paste behavior
 */
'normal'
/**
 * Paste only the plain text
 */
 | 'asPlainText'
/**
 * Apply the current style to pasted content
 */
 | 'mergeFormat'
/**
 * If there is a image uri in the clipboard, paste the content as image element
 */
 | 'asImage';

/**
 * All Border operations
 */
export type BorderOperations = /**
 * Apply border format to all borders
 */
'allBorders'
/**
 * Remove al borders
 */
 | 'noBorders'
/**
 * Apply border format to left borders
 */
 | 'leftBorders'
/**
 * Apply border format to right borders
 */
 | 'rightBorders'
/**
 * Apply border format to top borders
 */
 | 'topBorders'
/**
 * Apply border format to bottom borders
 */
 | 'bottomBorders'
/**
 * Apply border format to inside borders
 */
 | 'insideBorders'
/**
 * Apply border format to outside borders
 */
 | 'outsideBorders';

/**
 * Delete selection result
 */
export type DeleteResult = /**
 * Content Model could not finish deletion, need to let browser handle it
 */
'notDeleted'
/**
 * Deleted a single char, no need to let browser keep handling
 */
 | 'singleChar'
/**
 * Deleted a range, no need to let browser keep handling
 */
 | 'range'
/**
 * There is nothing to delete, no need to let browser keep handling
 */
 | 'nothingToDelete';

/**
 * Define the position of the entity to insert. It can be:
 * "focus": insert at current focus. If insert a block entity, it will be inserted under the paragraph where focus is
 * "begin": insert at beginning of content. When insert an inline entity, it will be wrapped with a paragraph.
 * "end": insert at end of content. When insert an inline entity, it will be wrapped with a paragraph.
 * "root": insert at the root level of current region
 */
export type InsertEntityPosition = 'focus' | 'begin' | 'end' | 'root';

/**
 * The mode parameter type for exportContent API
 */
export type ExportContentMode = /**
 * Export to clean HTML in light color mode with dehydrated entities
 */
'HTML'
/**
 * Export to plain text
 */
 | 'PlainText'
/**
 * Export to plain text via browser's textContent property
 */
 | 'PlainTextFast';

/**
 * A union type of Content Model Block
 */
export type ContentModelBlock = ContentModelFormatContainer | ContentModelListItem | ContentModelGeneralBlock | ContentModelTable | ContentModelParagraph | ContentModelEntity | ContentModelDivider;

/**
 * A union type of Content Model Block (Readonly)
 */
export type ReadonlyContentModelBlock = ReadonlyContentModelFormatContainer | ReadonlyContentModelListItem | ReadonlyContentModelGeneralBlock | ReadonlyContentModelTable | ReadonlyContentModelParagraph | ContentModelEntity | ReadonlyContentModelDivider;

/**
 * A union type of Content Model Block (Shallow mutable)
 */
export type ShallowMutableContentModelBlock = ShallowMutableContentModelFormatContainer | ShallowMutableContentModelListItem | ShallowMutableContentModelGeneralBlock | ShallowMutableContentModelTable | ShallowMutableContentModelParagraph | ContentModelEntity | ContentModelDivider;

/**
 * Content Model of Paragraph
 */
export interface ContentModelParagraph extends ContentModelParagraphCommon, ContentModelBlockBase<'Paragraph'> {
    /**
     * Segments within this paragraph
     */
    segments: ContentModelSegment[];
    /**
     * 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;
}

/**
 * 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 (Readonly)
 */
export interface ReadonlyContentModelParagraph extends ReadonlyContentModelBlockBase<'Paragraph'>, Readonly<ContentModelParagraphCommon> {
    /**
     * Segments within this paragraph
     */
    readonly segments: ReadonlyArray<ReadonlyContentModelSegment>;
    /**
     * Segment format on this paragraph. This is mostly used for default format
     */
    readonly segmentFormat?: Readonly<ContentModelSegmentFormat>;
    /**
     * Decorator info for this paragraph, used by heading and P tags
     */
    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;
}

/**
 * Content Model of Table
 */
export interface ContentModelTable extends ContentModelBlockBase<'Table', ContentModelTableFormat, HTMLTableElement>, ContentModelWithDataset<TableMetadataFormat> {
    /**
     * Widths of each column
     */
    widths: number[];
    /**
     * Cells of this table
     */
    rows: ContentModelTableRow[];
}

/**
 * Content Model of Table (Readonly)
 */
export interface ReadonlyContentModelTable extends ReadonlyContentModelBlockBase<'Table', ContentModelTableFormat, HTMLTableElement>, ReadonlyContentModelWithDataset<TableMetadataFormat> {
    /**
     * Widths of each column
     */
    readonly widths: ReadonlyArray<number>;
    /**
     * Cells of this table
     */
    readonly rows: ReadonlyArray<ReadonlyContentModelTableRow>;
}

/**
 * Content Model of Table (Shallow mutable)
 */
export interface ShallowMutableContentModelTable extends ShallowMutableContentModelBlockBase<'Table', ContentModelTableFormat, HTMLTableElement>, ShallowMutableContentModelWithDataset<TableMetadataFormat> {
    /**
     * Widths of each column
     */
    widths: number[];
    /**
     * Cells of this table
     */
    rows: ShallowMutableContentModelTableRow[];
}

/**
 * Content Model of horizontal divider
 */
export interface ContentModelDivider extends Selectable, ContentModelDividerCommon, ContentModelBlockBase<'Divider', ContentModelDividerFormat> {
}

/**
 * Common part of Content Model of horizontal divider
 */
export interface ContentModelDividerCommon {
    /**
     * Tag name of this element, either HR or DIV
     */
    tagName: 'hr' | 'div';
    /**
     * Size property for HR
     */
    size?: string;
}

/**
 * Content Model of horizontal divider (Readonly)
 */
export interface ReadonlyContentModelDivider extends ReadonlySelectable, ReadonlyContentModelBlockBase<'Divider', ContentModelDividerFormat>, Readonly<ContentModelDividerCommon> {
}

/**
 * Base type of a block
 */
export interface ContentModelBlockBase<T extends ContentModelBlockType, TFormat extends ContentModelBlockFormat = ContentModelBlockFormat, TCacheElement extends HTMLElement = HTMLElement> extends MutableMark, ContentModelBlockBaseCommon<T>, ContentModelWithFormat<TFormat>, ContentModelBlockWithCache<TCacheElement> {
}

/**
 * Common part of base type of a block
 */
export interface ContentModelBlockBaseCommon<T extends ContentModelBlockType> {
    /**
     * Type of this block
     */
    readonly blockType: T;
}

/**
 * Base type of a block (Readonly)
 */
export interface ReadonlyContentModelBlockBase<T extends ContentModelBlockType, TFormat extends ContentModelBlockFormat = ContentModelBlockFormat, TCacheElement extends HTMLElement = HTMLElement> extends ReadonlyMark, ContentModelBlockBaseCommon<T>, ReadonlyContentModelWithFormat<TFormat>, ContentModelBlockWithCache<TCacheElement> {
}

/**
 * Base type of a block (Shallow mutable)
 */
export interface ShallowMutableContentModelBlockBase<T extends ContentModelBlockType, TFormat extends ContentModelBlockFormat = ContentModelBlockFormat, TCacheElement extends HTMLElement = HTMLElement> extends ShallowMutableMark, ContentModelBlockBaseCommon<T>, ContentModelWithFormat<TFormat>, ContentModelBlockWithCache<TCacheElement> {
}

/**
 * Represent a Content Model block with cached element
 */
export interface ContentModelBlockWithCache<TElement extends HTMLElement = HTMLElement> {
    /**
     * Cached element for reuse
     */
    cachedElement?: TElement;
}

/**
 * Content Model of Table
 */
export interface ContentModelTableRow extends MutableMark, ContentModelTableRowCommon, ContentModelBlockWithCache<HTMLTableRowElement>, ContentModelWithFormat<ContentModelBlockFormat> {
    /**
     * Cells of this table
     */
    cells: ContentModelTableCell[];
}

/**
 * Common part of Content Model of Table
 */
export interface ContentModelTableRowCommon {
    /**
     * Heights of each row
     */
    height: number;
}

/**
 * Content Model of Table (Readonly)
 */
export interface ReadonlyContentModelTableRow extends ReadonlyMark, Readonly<ContentModelTableRowCommon>, ContentModelBlockWithCache<HTMLTableRowElement>, ReadonlyContentModelWithFormat<ContentModelBlockFormat> {
    /**
     * Cells of this table
     */
    readonly cells: ReadonlyArray<ReadonlyContentModelTableCell>;
}

/**
 * Content Model of Table (Readonly)
 */
export interface ShallowMutableContentModelTableRow extends ShallowMutableMark, ContentModelTableRowCommon, ContentModelBlockWithCache<HTMLTableRowElement>, ContentModelWithFormat<ContentModelBlockFormat> {
    /**
     * Cells of this table
     */
    cells: ReadonlyContentModelTableCell[];
}

/**
 * Content Model of Entity
 */
export interface ContentModelEntity extends ContentModelBlockBase<'Entity', ContentModelBlockFormat & ContentModelSegmentFormat>, ContentModelSegmentBase<'Entity', ContentModelBlockFormat & ContentModelSegmentFormat> {
    /**
     * The wrapper DOM node of this entity which holds the info CSS classes of this entity
     */
    wrapper: HTMLElement;
    /**
     * Format of this entity
     */
    entityFormat: ContentModelEntityFormat;
}

/**
 * Content Model document entry point
 */
export interface ContentModelDocument extends ContentModelDocumentCommon, ContentModelBlockGroupBase<'Document'>, Partial<ContentModelWithFormat<ContentModelSegmentFormat>> {
}

/**
 * Common part of Content Model document entry point
 */
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 (Readonly)
 */
export interface ReadonlyContentModelDocument extends Readonly<ContentModelDocumentCommon>, ReadonlyContentModelBlockGroupBase<'Document'>, Partial<ReadonlyContentModelWithFormat<ContentModelSegmentFormat>> {
}

/**
 * Content Model document entry point (Shallow mutable)
 */
export interface ShallowMutableContentModelDocument extends ContentModelDocumentCommon, ShallowMutableContentModelBlockGroupBase<'Document'>, Partial<ContentModelWithFormat<ContentModelSegmentFormat>> {
}

/**
 * Base type of Content Model Block Group
 */
export interface ContentModelBlockGroupBase<T extends ContentModelBlockGroupType, TElement extends HTMLElement = HTMLElement> extends MutableMark, ContentModelBlockGroupBaseCommon<T, TElement> {
    /**
     * Blocks under this group
     */
    blocks: ContentModelBlock[];
}

/**
 * Common part of base type of Content Model Block Group
 */
export interface ContentModelBlockGroupBaseCommon<T extends ContentModelBlockGroupType, TElement extends HTMLElement = HTMLElement> extends ContentModelBlockWithCache<TElement> {
    /**
     * Type of this block group
     */
    readonly blockGroupType: T;
}

/**
 * Base type of Content Model Block Group (Readonly)
 */
export interface ReadonlyContentModelBlockGroupBase<T extends ContentModelBlockGroupType, TElement extends HTMLElement = HTMLElement> extends ReadonlyMark, ContentModelBlockGroupBaseCommon<T, TElement> {
    /**
     * Blocks under this group
     */
    readonly blocks: ReadonlyArray<ReadonlyContentModelBlock>;
}

/**
 * Base type of Content Model Block Group (Shallow mutable)
 */
export interface ShallowMutableContentModelBlockGroupBase<T extends ContentModelBlockGroupType, TElement extends HTMLElement = HTMLElement> extends ShallowMutableMark, ContentModelBlockGroupBaseCommon<T, TElement> {
    /**
     * Blocks under this group
     */
    blocks: ReadonlyContentModelBlock[];
}

/**
 * Content Model of Format Container
 */
export interface ContentModelFormatContainer extends ContentModelFormatContainerCommon, ContentModelBlockGroupBase<'FormatContainer'>, ContentModelBlockBase<'BlockGroup', ContentModelFormatContainerFormat, HTMLElement> {
}

/**
 * Common part of Content Model of Format Container
 */
export interface ContentModelFormatContainerCommon {
    /**
     * Tag name of this container
     */
    tagName: Lowercase<string>;
    /**
     * Whether we can apply "font-size: 0" to this paragraph. When set to true, we will check if there is no text segment inside,
     * and apply "font-size: 0" to the container element
     */
    zeroFontSize?: boolean;
}

/**
 * Content Model of Format Container (Readonly)
 */
export interface ReadonlyContentModelFormatContainer extends Readonly<ContentModelFormatContainerCommon>, ReadonlyContentModelBlockGroupBase<'FormatContainer'>, ReadonlyContentModelBlockBase<'BlockGroup', ContentModelFormatContainerFormat, HTMLElement> {
}

/**
 * Content Model of Format Container (Shallow mutable)
 */
export interface ShallowMutableContentModelFormatContainer extends ContentModelFormatContainerCommon, ShallowMutableContentModelBlockGroupBase<'FormatContainer'>, ShallowMutableContentModelBlockBase<'BlockGroup', ContentModelFormatContainerFormat, HTMLElement> {
}

/**
 * Content Model for general Block element
 */
export interface ContentModelGeneralBlock extends Selectable, ContentModelGeneralBlockCommon, ContentModelBlockGroupBase<'General'>, ContentModelBlockBase<'BlockGroup', ContentModelBlockFormat & ContentModelSegmentFormat> {
}

/**
 * Common part of Content Model for general Block element
 */
export interface ContentModelGeneralBlockCommon {
    /**
     * A reference to original HTML node that this model was created from
     */
    element: HTMLElement;
}

/**
 * Content Model for general Block element (Readonly)
 */
export interface ReadonlyContentModelGeneralBlock extends ReadonlySelectable, Readonly<ContentModelGeneralBlockCommon>, ReadonlyContentModelBlockGroupBase<'General'>, ReadonlyContentModelBlockBase<'BlockGroup', ContentModelBlockFormat & ContentModelSegmentFormat> {
}

/**
 * Content Model for general Block element (Shallow mutable)
 */
export interface ShallowMutableContentModelGeneralBlock extends ShallowMutableSelectable, ContentModelGeneralBlockCommon, ShallowMutableContentModelBlockGroupBase<'General'>, ShallowMutableContentModelBlockBase<'BlockGroup', ContentModelBlockFormat & ContentModelSegmentFormat> {
}

/**
 * Content Model of List Item
 */
export interface ContentModelListItem extends ContentModelBlockGroupBase<'ListItem', HTMLLIElement>, ContentModelBlockBase<'BlockGroup', ContentModelListItemFormat, HTMLLIElement> {
    /**
     * Type of this list, either ordered or unordered
     */
    levels: ContentModelListLevel[];
    /**
     * A dummy segment to hold format of this list item
     */
    formatHolder: ContentModelSelectionMarker;
}

/**
 * Content Model of List Item (Readonly)
 */
export interface ReadonlyContentModelListItem extends ReadonlyContentModelBlockGroupBase<'ListItem', HTMLLIElement>, ReadonlyContentModelBlockBase<'BlockGroup', ContentModelListItemFormat, HTMLLIElement> {
    /**
     * Type of this list, either ordered or unordered
     */
    readonly levels: ReadonlyArray<ReadonlyContentModelListLevel>;
    /**
     * A dummy segment to hold format of this list item
     */
    readonly formatHolder: ReadonlyContentModelSelectionMarker;
}

/**
 * Content Model of List Item (Shallow mutable)
 */
export interface ShallowMutableContentModelListItem extends ShallowMutableContentModelBlockGroupBase<'ListItem', HTMLLIElement>, ShallowMutableContentModelBlockBase<'BlockGroup', ContentModelListItemFormat, HTMLLIElement> {
    /**
     * Type of this list, either ordered or unordered
     */
    levels: ContentModelListLevel[];
    /**
     * A dummy segment to hold format of this list item
     */
    formatHolder: ContentModelSelectionMarker;
}

/**
 * Content Model of Table Cell
 */
export interface ContentModelTableCell extends Selectable, ContentModelTableCellCommon, ContentModelBlockGroupBase<'TableCell', HTMLTableCellElement>, ContentModelWithFormat<ContentModelTableCellFormat>, ContentModelWithDataset<TableCellMetadataFormat> {
}

/**
 * Common part of Content Model of Table Cell
 */
export interface ContentModelTableCellCommon {
    /**
     * Whether this cell is spanned from left cell
     */
    spanLeft: boolean;
    /**
     * Whether this cell is spanned from above cell
     */
    spanAbove: boolean;
    /**
     * Whether this cell is a table header (TH) element
     */
    isHeader?: boolean;
}

/**
 * Content Model of Table Cell (Readonly)
 */
export interface ReadonlyContentModelTableCell extends ReadonlySelectable, Readonly<ContentModelTableCellCommon>, ReadonlyContentModelBlockGroupBase<'TableCell', HTMLTableCellElement>, ReadonlyContentModelWithFormat<ContentModelTableCellFormat>, ReadonlyContentModelWithDataset<TableCellMetadataFormat> {
}

/**
 * Content Model of Table Cell (Shallow mutable)
 */
export interface ShallowMutableContentModelTableCell extends ShallowMutableSelectable, ContentModelTableCellCommon, ShallowMutableContentModelBlockGroupBase<'TableCell', HTMLTableCellElement>, ContentModelWithFormat<ContentModelTableCellFormat>, ShallowMutableContentModelWithDataset<TableCellMetadataFormat> {
}

/**
 * The union type of Content Model Block Group
 */
export type ContentModelBlockGroup = ContentModelDocument | ContentModelFormatContainer | ContentModelListItem | ContentModelTableCell | ContentModelGeneralBlock;

/**
 * The union type of Content Model Block Group (Readonly)
 */
export type ReadonlyContentModelBlockGroup = ReadonlyContentModelDocument | ReadonlyContentModelFormatContainer | ReadonlyContentModelListItem | ReadonlyContentModelTableCell | ReadonlyContentModelGeneralBlock;

/**
 * The union type of Content Model Block Group (Shallow mutable)
 */
export type ShallowMutableContentModelBlockGroup = ShallowMutableContentModelDocument | ShallowMutableContentModelFormatContainer | ShallowMutableContentModelListItem | ShallowMutableContentModelTableCell | ShallowMutableContentModelGeneralBlock;

/**
 * Content Model of BR
 */
export interface ContentModelBr extends ContentModelSegmentBase<'Br'> {
}

/**
 * Content Model of BR (Readonly)
 */
export interface ReadonlyContentModelBr extends ReadonlyContentModelSegmentBase<'Br'> {
}

/**
 * Content Model of general Segment
 */
export interface ContentModelGeneralSegment extends ContentModelGeneralBlock, ContentModelSegmentBase<'General', ContentModelBlockFormat & ContentModelSegmentFormat> {
}

/**
 * Content Model of general Segment (Readonly)
 */
export interface ReadonlyContentModelGeneralSegment extends ReadonlyContentModelGeneralBlock, ReadonlyContentModelSegmentBase<'General', ContentModelBlockFormat & ContentModelSegmentFormat> {
}

/**
 * Content Model of general Segment (Shallow mutable)
 */
export interface ShallowMutableContentModelGeneralSegment extends ShallowMutableContentModelGeneralBlock, ShallowMutableContentModelSegmentBase<'General', ContentModelBlockFormat & ContentModelSegmentFormat> {
}

/**
 * Content Model of IMG
 */
export interface ContentModelImage extends ContentModelImageCommon, ContentModelSegmentBase<'Image', ContentModelImageFormat>, ContentModelWithDataset<ImageMetadataFormat> {
}

/**
 * Common part of Content Model of IMG
 */
export interface ContentModelImageCommon {
    /**
     * Image source of this IMG element
     */
    src: string;
    /**
     * Alt text of image
     */
    alt?: string;
    /**
     * Title text of image
     */
    title?: string;
    /**
     * Whether this image is selected as image selection (show a border around the image)
     */
    isSelectedAsImageSelection?: boolean;
}

/**
 * Content Model of IMG (Readonly)
 */
export interface ReadonlyContentModelImage extends ReadonlyContentModelSegmentBase<'Image', ContentModelImageFormat>, ReadonlyContentModelWithDataset<ImageMetadataFormat>, Readonly<ContentModelImageCommon> {
}

/**
 * Content Model for Text
 */
export interface ContentModelText extends ContentModelTextCommon, ContentModelSegmentBase<'Text'> {
}

/**
 * Common port of Content Model for Text
 */
export interface ContentModelTextCommon {
    /**
     * Text content of this segment
     */
    text: string;
}

/**
 * Content Model for Text (Readonly)
 */
export interface ReadonlyContentModelText extends ReadonlyContentModelSegmentBase<'Text'>, Readonly<ContentModelTextCommon> {
}

/**
 * Content Model of Selection Marker
 */
export interface ContentModelSelectionMarker extends ContentModelSegmentBase<'SelectionMarker'> {
}

/**
 * Content Model of Selection Marker (Readonly)
 */
export interface ReadonlyContentModelSelectionMarker extends ReadonlyContentModelSegmentBase<'SelectionMarker'> {
}

/**
 * Base type of Content Model Segment
 */
export interface ContentModelSegmentBase<T extends ContentModelSegmentType, TFormat extends ContentModelSegmentFormat = ContentModelSegmentFormat> extends MutableMark, Selectable, ContentModelWithFormat<TFormat>, ContentModelSegmentBaseCommon<T> {
    /**
     * Hyperlink info
     */
    link?: ContentModelLink;
    /**
     * Code info
     */
    code?: ContentModelCode;
}

/**
 * Common part of base type of Content Model Segment
 */
export interface ContentModelSegmentBaseCommon<T extends ContentModelSegmentType> {
    /**
     * Type of this segment
     */
    readonly segmentType: T;
}

/**
 * Base type of Content Model Segment (Readonly)
 */
export interface ReadonlyContentModelSegmentBase<T extends ContentModelSegmentType, TFormat extends ContentModelSegmentFormat = ContentModelSegmentFormat> extends ReadonlyMark, ReadonlySelectable, ReadonlyContentModelWithFormat<TFormat>, Readonly<ContentModelSegmentBaseCommon<T>> {
    /**
     * Hyperlink info
     */
    readonly link?: ReadonlyContentModelLink;
    /**
     * Code info
     */
    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<TFormat>, ContentModelSegmentBaseCommon<T> {
    /**
     * Hyperlink info
     */
    link?: ContentModelLink;
    /**
     * Code info
     */
    code?: ContentModelCode;
}

/**
 * Union type of Content Model Segment
 */
export type ContentModelSegment = ContentModelSelectionMarker | ContentModelText | ContentModelBr | ContentModelGeneralSegment | ContentModelEntity | ContentModelImage;

/**
 * Union type of Content Model Segment (Readonly)
 */
export type ReadonlyContentModelSegment = ReadonlyContentModelSelectionMarker | ReadonlyContentModelText | ReadonlyContentModelBr | ReadonlyContentModelGeneralSegment | ContentModelEntity | ReadonlyContentModelImage;

/**
 * Union type of Content Model Segment (Shallow mutable)
 */
export type ShallowMutableContentModelSegment = ContentModelSelectionMarker | ContentModelText | ContentModelBr | ShallowMutableContentModelGeneralSegment | ContentModelEntity | ContentModelImage;

/**
 * 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 MutableMark, ContentModelWithFormat<ContentModelCodeFormat> {
}

/**
 * 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<ContentModelCodeFormat> {
}

/**
 * Represent link info of Content Model.
 * 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 ContentModelLink extends MutableMark, ContentModelWithFormat<ContentModelHyperLinkFormat>, ContentModelWithDataset<null> {
}

/**
 * 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<ContentModelHyperLinkFormat>, ReadonlyContentModelWithDataset<null> {
}

/**
 * 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<ContentModelSegmentFormat> {
}

/**
 * Common part of decorator for a paragraph in Content Model
 */
export interface ContentModelParagraphDecoratorCommon {
    /**
     * Tag name of this paragraph
     */
    tagName: string;
}

/**
 * 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<ContentModelSegmentFormat>, Readonly<ContentModelParagraphDecoratorCommon> {
}

/**
 * Union type for segment decorators
 */
export type ContentModelDecorator = ContentModelLink | ContentModelCode | ContentModelListLevel;

/**
 * Union type for segment decorators (Readonly)
 */
export type ReadonlyContentModelDecorator = ReadonlyContentModelLink | ReadonlyContentModelCode | ReadonlyContentModelListLevel;

/**
 * Content Model of List Level
 */
export interface ContentModelListLevel extends MutableMark, ContentModelBlockWithCache<HTMLOListElement | HTMLUListElement>, ContentModelListLevelCommon, ContentModelWithFormat<ContentModelListItemLevelFormat>, ContentModelWithDataset<ListMetadataFormat> {
}

/**
 * Common part of Content Model of List Level
 */
export interface ContentModelListLevelCommon {
    /**
     * Type of a list, order (OL) or unordered (UL)
     */
    listType: 'OL' | 'UL';
}

/**
 * Content Model of List Level (Readonly)
 */
export interface ReadonlyContentModelListLevel extends ReadonlyMark, ContentModelBlockWithCache<HTMLOListElement | HTMLUListElement>, ReadonlyContentModelWithFormat<ContentModelListItemLevelFormat>, ReadonlyContentModelWithDataset<ListMetadataFormat>, Readonly<ContentModelListLevelCommon> {
}

/**
 * Represents a selectable Content Model object
 */
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;
}

/**
 * Represents a selectable Content Model object (Shallow mutable)
 */
export interface ShallowMutableSelectable extends ShallowMutableMark  {
    /**
     * Whether this model object is selected
     */
    isSelected?: boolean;
}

/**
 * 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 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<never>;
};

/**
 * 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<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?: ReadonlyArray<never>;
};

/**
 * Get mutable type from its related readonly type
 */
export type MutableType<T> = T extends ReadonlyContentModelGeneralSegment ? ShallowMutableContentModelGeneralSegment : T extends ReadonlyContentModelSelectionMarker ? ContentModelSelectionMarker : T extends ReadonlyContentModelImage ? ContentModelImage : T extends ContentModelEntity ? ContentModelEntity : T extends ReadonlyContentModelText ? ContentModelText : T extends ReadonlyContentModelBr ? ContentModelBr : T extends ReadonlyContentModelParagraph ? ShallowMutableContentModelParagraph : T extends ReadonlyContentModelTable ? ShallowMutableContentModelTable : T extends ReadonlyContentModelTableRow ? ContentModelTableRow : T extends ReadonlyContentModelTableCell ? ShallowMutableContentModelTableCell : T extends ReadonlyContentModelFormatContainer ? ShallowMutableContentModelFormatContainer : T extends ReadonlyContentModelListItem ? ShallowMutableContentModelListItem : T extends ReadonlyContentModelListLevel ? ContentModelListLevel : T extends ReadonlyContentModelDivider ? ContentModelDivider : T extends ReadonlyContentModelDocument ? ShallowMutableContentModelDocument : T extends ReadonlyContentModelGeneralBlock ? ShallowMutableContentModelGeneralBlock : T extends ReadonlyContentModelParagraphDecorator ? ContentModelParagraphDecorator : T extends ReadonlyContentModelLink ? ContentModelLink : T extends ReadonlyContentModelCode ? ContentModelCode : never;

/**
 * The union type of 3 selection types
 */
export type DOMSelection = RangeSelection | ImageSelection | TableSelection;

/**
 * Type of DOM selection, it can be one of the 3 below:
 * range: A regular selection that can be represented by a DOM Range object with start and end container and offset
 * table: A table selection that can be defined using the Table element and first/last row and column number. Table selection can
 * cover multiple table cells, it does not need to be continuous, but it should be a rectangle
 * image: A image selection that can be defined with an image element. Not like a regular range selection with an image, image selection
 * is created when user single click the image, then we will show a selection border rather the blue background to show the selection
 */
export type SelectionType = 'range' | 'table' | 'image';

/**
 * Base type of Selection
 */
export interface SelectionBase<T extends SelectionType> {
    /**
     * Type of this selection
     */
    type: T;
}

/**
 * image: A image selection that can be defined with an image element. Not like a regular range selection with an image, image selection
 * is created when user single click the image, then we will show a selection border rather the blue background to show the selection
 */
export interface ImageSelection extends SelectionBase<'image'> {
    /**
     * The image that this selection is representing
     */
    image: HTMLImageElement;
}

/**
 * A regular selection that can be represented by a DOM Range object with start and end container and offset
 */
export interface RangeSelection extends SelectionBase<'range'> {
    /**
     * The DOM Range of this selection
     */
    range: Range;
    /**
     * Whether the selection was from left to right (in document order) or
     * right to left (reverse of document order)
     */
    isReverted: boolean;
}

/**
 * A table selection that can be defined using the Table element and first/last row and column number. Table selection can
 * cover multiple table cells, it does not need to be continuous, but it should be a rectangle
 */
export interface TableSelection extends TableSelectionCoordinates, SelectionBase<'table'> {
    /**
     * The table that this selection is representing
     */
    table: HTMLTableElement;
}

/**
 * Represents an insert point from DOM selection
 */
export interface DOMInsertPoint {
    /**
     * The container node
     */
    node: Node;
    /**
     * The offset under container node
     */
    offset: number;
}

/**
 * Represent all related information of an insert point
 */
export interface InsertPoint {
    /**
     * The selection marker object for this insert point
     */
    marker: ContentModelSelectionMarker;
    /**
     * The paragraph that contains this insert point
     */
    paragraph: ShallowMutableContentModelParagraph;
    /**
     * Block group path of this insert point, from direct parent group to the root group
     */
    path: ReadonlyContentModelBlockGroup[];
    /**
     * Table context of this insert point
     */
    tableContext?: ReadonlyTableSelectionContext;
}

/**
 * Context object for table in a selection
 */
export interface TableSelectionContext {
    /**
     * The table that contains the selection
     */
    table: ContentModelTable;
    /**
     * Row Index of the selected table cell
     */
    rowIndex: number;
    /**
     * Column Index of the selected table cell
     */
    colIndex: number;
    /**
     * Whether the whole table is selected
     */
    isWholeTableSelected: boolean;
}

/**
 * Context object for table in a selection (Readonly)
 */
export interface ReadonlyTableSelectionContext {
    /**
     * The table that contains the selection
     */
    table: ReadonlyContentModelTable;
    /**
     * Row Index of the selected table cell
     */
    rowIndex: number;
    /**
     * Column Index of the selected table cell
     */
    colIndex: number;
    /**
     * Whether the whole table is selected
     */
    isWholeTableSelected: boolean;
}

/**
 * Coordinates of table selection
 */
export interface TableSelectionCoordinates {
    /**
     * Index of the first selected row, start from 0
     */
    firstRow: number;
    /**
     * Index of the first selected column, start from 0
     */
    firstColumn: number;
    /**
     * Index of the last selected row, start from 0
     */
    lastRow: number;
    /**
     * Index of the last selected column, start from 0
     */
    lastColumn: number;
}

/**
 * Represents a map from content model handler name to its handle type
 */
export type ContentModelHandlerMap = {
    /**
     * Content Model type for ContentModelBlock
     */
    block: ContentModelBlockHandler<ContentModelBlock>;
    /**
     * Content Model type for child models of ContentModelBlockGroup
     */
    blockGroupChildren: ContentModelHandler<ContentModelBlockGroup>;
    /**
     * Content Model type for ContentModelBr
     */
    br: ContentModelSegmentHandler<ContentModelBr>;
    /**
     * Content Model type for child models of ContentModelEntity
     */
    entityBlock: ContentModelBlockHandler<ContentModelEntity>;
    /**
     * Content Model type for child models of ContentModelEntity
     */
    entitySegment: ContentModelSegmentHandler<ContentModelEntity>;
    /**
     * Content Model type for ContentModelGeneralBlock
     */
    generalBlock: ContentModelBlockHandler<ContentModelGeneralBlock>;
    /**
     * Content Model type for ContentModelGeneralBlock
     */
    generalSegment: ContentModelSegmentHandler<ContentModelGeneralSegment>;
    /**
     * Content Model type for ContentModelHR
     */
    divider: ContentModelBlockHandler<ContentModelDivider>;
    /**
     * Content Model type for ContentModelImage
     */
    image: ContentModelSegmentHandler<ContentModelImage>;
    /**
     * Content Model type for list group of ContentModelListItem
     */
    list: ContentModelBlockHandler<ContentModelListItem>;
    /**
     * Content Model type for list item of ContentModelListItem
     */
    listItem: ContentModelBlockHandler<ContentModelListItem>;
    /**
     * Content Model type for ContentModelParagraph
     */
    paragraph: ContentModelBlockHandler<ContentModelParagraph>;
    /**
     * Content Model type for ContentModelFormatContainer
     */
    formatContainer: ContentModelBlockHandler<ContentModelFormatContainer>;
    /**
     * Content Model type for ContentModelSegment
     */
    segment: ContentModelSegmentHandler<ContentModelSegment>;
    /**
     * Content Model type for ContentModelCode
     */
    segmentDecorator: ContentModelSegmentHandler<ContentModelSegment>;
    /**
     * Content Model type for ContentModelTable
     */
    table: ContentModelBlockHandler<ContentModelTable>;
    /**
     * Content Model type for ContentModelText
     */
    text: ContentModelSegmentHandler<ContentModelText>;
};

/**
 * Default implicit format map from tag name (lower case) to segment format
 */
export type DefaultImplicitFormatMap = Record<string, Readonly<ContentModelSegmentFormat & ContentModelBlockFormat>>;

/**
 * All format appliers
 */
export type FormatAppliers = {
    [Key in FormatKey]: FormatApplier<FormatHandlerTypeMap[Key]> | null;
};

/**
 * A map from format parser category name to an array of parsers
 */
export type FormatAppliersPerCategory = ElementFormatAppliersPerCategory & {
    text: TextFormatApplier[];
};

/**
 * An optional callback that will be called when a DOM node is created
 * @param modelElement The related Content Model element
 * @param node The node created for this model element
 */
export type OnNodeCreated = (modelElement: ContentModelBlock | ContentModelBlockGroup | ContentModelSegment | ContentModelDecorator | ContentModelTableRow, node: Node) => void;

/**
 * Represents settings to customize DOM to Content Model conversion
 */
export interface ModelToDomSettings {
    /**
     * Map of Content Model handlers
     */
    modelHandlers: ContentModelHandlerMap;
    /**
     * Map of format appliers
     */
    formatAppliers: FormatAppliersPerCategory;
    /**
     * Map of metadata appliers
     */
    metadataAppliers: MetadataAppliers;
    /**
     * Default Content Model to DOM handlers before overriding.
     * This provides a way to call original handler from an overridden handler function
     */
    defaultModelHandlers: Readonly<ContentModelHandlerMap>;
    /**
     * Default format parsers before overriding.
     * This provides a way to call original format applier from an overridden applier function
     */
    defaultFormatAppliers: Readonly<FormatAppliers>;
    /**
     * An optional callback that will be called when a DOM node is created
     * @param modelElement The related Content Model element
     * @param node The node created for this model element
     */
    onNodeCreated?: OnNodeCreated;
}

/**
 * Apply format to the given HTML element
 * @param format The format object to apply
 * @param element The HTML element to apply format to
 * @param context The context object that provide related context information
 */
export type FormatApplier<TFormat extends ContentModelFormatBase> = (format: TFormat, element: HTMLElement, context: ModelToDomContext) => void;

/**
 * Function type to apply metadata value into format
 * @param metadata The metadata object to apply
 * @param format The format object to apply metadata to
 * @param context Content Model to DOM context
 */
export type ApplyMetadata<TMetadata, TFormat extends ContentModelFormatBase> = (metadata: TMetadata | null, format: TFormat, context: ModelToDomContext) => void;

/**
 * Metadata applier interface
 */
export interface MetadataApplier<TMetadata, TFormat extends ContentModelFormatBase> {
    /**
     * The metadata applier function
     */
    applierFunction: ApplyMetadata<TMetadata, TFormat>;
    /**
     * @optional Metadata definition, used for validate the metadata object
     */
    metadataDefinition?: Definition<TMetadata>;
}

/**
 * Map of metadata handlers
 */
export type MetadataAppliers = {
    /**
     * Metadata handler for list item
     */
    listItem?: MetadataApplier<ListMetadataFormat, ContentModelListItemFormat>;
    /**
     * Metadata handler for list level
     */
    listLevel?: MetadataApplier<ListMetadataFormat, ContentModelListItemLevelFormat>;
};

/**
 * Apply format to the given text node
 * @param format The format object to apply
 * @param textNode The text node to apply format to
 * @param context The context object that provide related context information
 */
export type TextFormatApplier<TFormat extends ContentModelSegmentFormat = ContentModelSegmentFormat> = (format: TFormat, textNode: Text, context: ModelToDomContext) => void;

/**
 * A map from format parser category name to an array of parsers. This is for HTMLElement only
 */
export type ElementFormatAppliersPerCategory = {
    [Key in keyof ContentModelFormatMap]: (FormatApplier<ContentModelFormatMap[Key]> | null)[];
};

/**
 * A type of Default style map, from tag name string (in upper case) to a static style object
 */
export type DefaultStyleMap = {
    [key in keyof HTMLElementDeprecatedTagNameMap]?: Readonly<Partial<CSSStyleDeclaration>>;
} & {
    [key in keyof HTMLElementTagNameMap]?: Readonly<Partial<CSSStyleDeclaration>>;
} & {
    center?: Partial<CSSStyleDeclaration>;
    strike?: Partial<CSSStyleDeclaration>;
};

/**
 * A map from element processor name to its processor type
 */
export type ElementProcessorMap = {
    [key in keyof HTMLElementDeprecatedTagNameMap]?: ElementProcessor<HTMLElementDeprecatedTagNameMap[key]>;
} & {
    [key in keyof HTMLElementTagNameMap]?: ElementProcessor<HTMLElementTagNameMap[key]>;
} & {
    /**
     * Processors for all other HTML elements
     */
    '*': ElementProcessor<HTMLElement>;
    /**
     * Processor for text node
     */
    '#text': ElementProcessor<Text>;
    /**
     * Processor for text node with selection.
     * This is an internal processor used by #text processor
     */
    textWithSelection: ElementProcessor<Text>;
    /**
     * Processor for entity
     */
    entity: ElementProcessor<HTMLElement>;
    /**
     * Common processor dispatch for all elements
     */
    element: ElementProcessor<HTMLElement>;
    /**
     * Common processor for child nodes of a given element
     */
    child: ElementProcessor<ParentNode>;
    /**
     * Workaround for typescript 4.4.4 that doesn't have element "strike" in its element type
     */
    strike?: ElementProcessor<HTMLElement>;
    /**
     * Workaround for typescript 4.4.4 that doesn't have element "center" in its element type
     */
    center?: ElementProcessor<HTMLElement>;
    /**
     * Processor for Inline Readonly Delimiters
     */
    delimiter?: ElementProcessor<Node>;
};

/**
 * All format parsers
 */
export type FormatParsers = {
    [Key in FormatKey]: FormatParser<FormatHandlerTypeMap[Key]> | null;
};

/**
 * A map from format parser category name to an array of parsers
 */
export type FormatParsersPerCategory = ElementFormatParserPerCategory & {
    text: TextFormatParser[];
};

/**
 * Represents settings to customize DOM to Content Model conversion
 */
export interface DomToModelSettings {
    /**
     * Map of element processors
     */
    elementProcessors: ElementProcessorMap;
    /**
     * Map of format parsers
     */
    formatParsers: FormatParsersPerCategory;
    /**
     * Default DOM to Content Model processors before overriding.
     * This provides a way to call original processor from an overridden processor function
     */
    defaultElementProcessors: Readonly<ElementProcessorMap>;
    /**
     * Default format parsers before overriding.
     * This provides a way to call original format parser from an overridden parser function
     */
    defaultFormatParsers: Readonly<FormatParsers>;
}

/**
 * Parse format from the given HTML element and default style
 * @param format The format object to parse into
 * @param element The HTML element to parse format from
 * @param context The context object that provide related context information
 * @param defaultStyle Default CSS style of the given HTML element
 */
export type FormatParser<TFormat extends ContentModelFormatBase> = (format: TFormat, element: HTMLElement, context: DomToModelContext, defaultStyle: Readonly<Partial<CSSStyleDeclaration>>) => void;

/**
 * Parse format from the given text node
 * @param format The format object to parse into
 * @param textNode The text node to parse format from
 * @param context The context object that provide related context information
 */
export type TextFormatParser<TFormat extends ContentModelSegmentFormat = ContentModelSegmentFormat> = (format: TFormat, textNode: Text, context: DomToModelContext) => void;

/**
 * A map from format parser category name to an array of parsers. This is for HTML Element only
 */
export type ElementFormatParserPerCategory = {
    [Key in keyof ContentModelFormatMap]: (FormatParser<ContentModelFormatMap[Key]> | null)[];
};

/**
 * Context of DOM to Model conversion, used for parse HTML element according to current context
 */
export interface DomToModelContext extends EditorContext, DomToModelSelectionContext, DomToModelFormatContext, DomToModelSettings, DomToModelDecoratorContext  {
}

/**
 * A function type to process HTML element when do DOM to Content Model conversion
 * @param group Parent content model group
 * @param element The element to process
 * @param context The context object to provide related information
 */
export type ElementProcessor<T extends Node> = (group: ContentModelBlockGroup, element: T, context: DomToModelContext) => void;

/**
 * Represents the selection information of content used by DOM to Content Model conversion
 */
export interface DomToModelSelectionContext {
    /**
     * Is current context under a selection
     */
    isInSelection?: boolean;
    /**
     * Current selection range
     */
    selection?: DOMSelection;
}

/**
 * An editor context interface used by ContentModel PAI
 */
export interface EditorContext {
    /**
     * Whether current content is in dark mode
     */
    isDarkMode?: boolean;
    /**
     * Default format of editor
     */
    defaultFormat?: ContentModelSegmentFormat;
    /**
     * Pending format if any
     */
    pendingFormat?: PendingFormat;
    /**
     * Color manager, to help manager color in dark mode
     */
    darkColorHandler?: DarkColorHandler;
    /**
     * Whether to handle delimiters in Content Model
     */
    addDelimiterForEntity?: boolean;
    /**
     * Zoom scale number
     */
    zoomScale?: number;
    /**
     * Whether the content is in Right-to-left from root level
     */
    isRootRtl?: boolean;
    /**
     * Whether put the source element into Content Model when possible.
     * When pass true, this cached element will be used to create DOM tree back when convert Content Model to DOM
     */
    allowCacheElement?: boolean;
    /**
     * @optional Indexer for content model, to help build backward relationship from DOM node to Content Model
     */
    domIndexer?: DomIndexer;
    /**
     * Root Font size in Px.
     */
    rootFontSize?: number;
    /**
     * Enabled experimental features
     */
    experimentalFeatures?: ReadonlyArray<string>;
    /**
     * A helper class that manages a mapping from paragraph marker to paragraph object.
     */
    paragraphMap?: ParagraphMap;
    /**
     * When set to true, size of table will be recalculated when converting from DOM to Content Model.
     */
    recalculateTableSize?: boolean | 'all' | 'selected' | 'none';
}

/**
 * Represents format info used by DOM to Content Model conversion
 */
export interface DomToModelFormatContext {
    /**
     * Format of current block
     */
    blockFormat: ContentModelBlockFormat;
    /**
     * Format of current segment
     */
    segmentFormat: ContentModelSegmentFormat;
    /**
     * Context of list that is currently processing
     */
    listFormat: DomToModelListFormat;
}

/**
 * Represents decorator info used by DOM to Content Model conversion
 */
export interface DomToModelDecoratorContext {
    /**
     * Context of hyper link info
     */
    link: ContentModelLink;
    /**
     * Context of code info
     */
    code: ContentModelCode;
    /**
     * Context for paragraph decorator
     */
    blockDecorator: ContentModelParagraphDecorator;
}

/**
 * Represents the context object used when do DOM to Content Model conversion and processing a List
 */
export interface DomToModelListFormat {
    /**
     * Current number of each level of current thread
     */
    threadItemCounts: number[];
    /**
     * The list that is currently processing
     */
    listParent?: ContentModelBlockGroup;
    /**
     * Current list type stack
     */
    levels: ContentModelListLevel[];
}

/**
 * Context of Model to DOM conversion, used for generate HTML DOM tree according to current context
 */
export interface ModelToDomContext extends EditorContext, ModelToDomSelectionContext, ModelToDomFormatContext, ModelToDomSettings, RewriteFromModelContext  {
}

/**
 * Represents internal data structure for a selection position, combined by block and segment node
 */
export interface ModelToDomBlockAndSegmentNode {
    /**
     * The block element of the selection. When segment is null, it represents the start position of this block element,
     * otherwise block element will be ignored and we can always retrieve position from segment node
     */
    block: Node | null;
    /**
     * Segment node of this position. When provided, it represents the position right after this node
     */
    segment: Node | null;
    /**
     * Offset number of this position. It is only used for Text node, default value is 0
     */
    offset?: number;
}

/**
 * Represents internal data structure for regular selection
 */
export interface ModelToDomRegularSelection {
    /**
     * Start position of selection
     */
    start?: ModelToDomBlockAndSegmentNode;
    /**
     * End position of selection
     */
    end?: ModelToDomBlockAndSegmentNode;
    /**
     * Current navigating position
     */
    current: ModelToDomBlockAndSegmentNode;
}

/**
 * Represents selection info used by Content Model to DOM conversion
 */
export interface ModelToDomSelectionContext {
    /**
     * Regular selection info
     */
    regularSelection: ModelToDomRegularSelection;
    /**
     * Table selection info
     */
    tableSelection?: TableSelection;
    /**
     * Image selection info
     */
    imageSelection?: ImageSelection;
}

/**
 * Represents a list stack item used by Content Model to DOM conversion
 */
export interface ModelToDomListStackItem extends Partial<ContentModelListLevel> {
    /**
     * DOM node of this list stack
     */
    node: Node;
}

/**
 * Represents context for list handling
 */
export interface ModelToDomListContext {
    /**
     * Current number of each level of current thread
     */
    threadItemCounts: number[];
    /**
     * A stack of current list element chain, start from the parent node of top level list
     */
    nodeStack: ModelToDomListStackItem[];
}

/**
 * Represents format context used by Content Model to DOM conversion
 */
export interface ModelToDomFormatContext {
    /**
     * Context for list handling
     */
    listFormat: ModelToDomListContext;
    /**
     * Existing format implicitly applied from parent element
     */
    implicitFormat: ContentModelSegmentFormat & ContentModelBlockFormat;
}

/**
 * Represents added and removed block elements during content model to dom conversion
 */
export interface RewriteFromModel {
    /**
     * Added block elements
     */
    addedBlockElements: HTMLElement[];
    /**
     * Removed block elements
     */
    removedBlockElements: HTMLElement[];
}

/**
 * Context object used by contentModelToDom to record added and removed block elements
 */
export interface RewriteFromModelContext {
    /**
     * DOM modification object
     */
    rewriteFromModel: RewriteFromModel;
}

/**
 * Type of Content Model to DOM handler
 * @param doc Target HTML Document object
 * @param parent Parent HTML node to append the new node from the given model
 * @param model The Content Model to handle
 * @param context The context object to provide related information
 */
export type ContentModelHandler<T extends ContentModelSegment | ContentModelBlockGroup | ContentModelDecorator> = (doc: Document, parent: Node, model: T, context: ModelToDomContext) => void;

/**
 * Type of Content Model to DOM handler for block
 * @param doc Target HTML Document object
 * @param parent Parent HTML node to append the new node from the given model
 * @param model The Content Model to handle
 * @param context The context object to provide related information
 * @param segmentNodes Nodes that created to represent this segment. In most cases there will be one node returned, except
 * - For segments with decorators: decorator elements will also be included
 * - For inline entity segment, the delimiter SPANs will also be included
 */
export type ContentModelSegmentHandler<T extends ContentModelSegment> = (doc: Document, parent: Node, model: T, context: ModelToDomContext, segmentNodes: Node[]) => void;

/**
 * Type of Content Model to DOM handler for block
 * @param doc Target HTML Document object
 * @param parent Parent HTML node to append the new node from the given model
 * @param model The Content Model to handle
 * @param context The context object to provide related information
 * @param refNode Reference node. This is the next node the new node to be inserted.
 * It is used when write DOM tree onto existing DOM true. If there is no reference node, pass null.
 */
export type ContentModelBlockHandler<T extends ContentModelBlock | ContentModelBlockGroup> = (doc: Document, parent: Node, model: T, context: ModelToDomContext, refNode: Node | null) => Node | null;

/**
 * Options for creating DomToModelContext
 */
export interface DomToModelOption {
    /**
     * Overrides default element processors
     */
    processorOverride?: Partial<ElementProcessorMap>;
    /**
     * Overrides default format handlers
     */
    formatParserOverride?: Partial<FormatParsers>;
    /**
     * Provide additional format parsers for each format type
     */
    additionalFormatParsers?: Partial<FormatParsersPerCategory>;
}

/**
 * Options for DOM to Content Model conversion for paste only
 */
export interface DomToModelOptionForSanitizing extends Required<DomToModelOption> {
    /**
     * Additional allowed HTML tags in lower case. Element with these tags will be preserved
     */
    readonly additionalAllowedTags: Lowercase<string>[];
    /**
     * Additional disallowed HTML tags in lower case. Elements with these tags will be dropped
     */
    readonly additionalDisallowedTags: Lowercase<string>[];
    /**
     * Additional sanitizers for CSS styles
     */
    readonly styleSanitizers: Record<string, ValueSanitizer>;
    /**
     * Additional sanitizers for CSS styles
     */
    readonly attributeSanitizers: Record<string, ValueSanitizer>;
}

/**
 * Options for creating DomToModelContext, used by formatContentModel and createContentModel API
 */
export interface DomToModelOptionForCreateModel extends DomToModelOption  {
    /**
     * When set to true, it will try to reuse cached content model if any
     */
    tryGetFromCache?: boolean;
    /**
     * Whether recalculate table size when parse table
     * 'all' or true means recalculate all tables in the model
     * 'selected' means recalculate only selected tables in the model
     * 'none' or false means do not recalculate any table in the model
     *
     * When this option is passed, "tryGetFromCache" will be ignored.
     */
    recalculateTableSize?: boolean | 'all' | 'selected' | 'none';
}

/**
 * Options for creating ModelToDomContext
 */
export interface ModelToDomOption {
    /**
     * Overrides default format appliers
     */
    formatApplierOverride?: Partial<FormatAppliers>;
    /**
     * Provide additional format appliers for each format type
     */
    additionalFormatAppliers?: Partial<FormatAppliersPerCategory>;
    /**
     * Overrides default model handlers
     */
    modelHandlerOverride?: Partial<ContentModelHandlerMap>;
    /**
     * Overrides default metadata appliers
     */
    metadataAppliers?: Partial<MetadataAppliers>;
    /**
     * When set to true, selection from content model will not be applied
     */
    ignoreSelection?: boolean;
}

/**
 * Represents an indexer object which provides methods to help build backward relationship
 * from DOM node to Content Model
 */
export interface DomIndexer {
    /**
     * Invoked when processing a segment
     * @param segmentNode The new DOM node for this segment
     * @param paragraph Parent paragraph of this segment
     * @param segments The source segments
     */
    onSegment: (segmentNode: Node, paragraph: ContentModelParagraph, segments: ContentModelSegment[]) => void;
    /**
     * Invoked when new paragraph node is created in DOM tree
     * @param paragraphElement The new DOM node for this paragraph
     */
    onParagraph: (paragraphElement: HTMLElement) => void;
    /**
     * Invoked when new table node is created in DOM tree
     * @param tableElement The new DOM node for this table
     */
    onTable: (tableElement: HTMLTableElement, tableModel: ContentModelTable) => void;
    /**
     * Invoke when new block entity is created in DOM tree
     * @param entity The related entity
     * @param parent Parent of entity. For block element, this should be the parent block group. For inline entity, this should be the parent paragraph
     */
    onBlockEntity: (entity: ContentModelEntity, group: ContentModelBlockGroup) => void;
    /**
     * Invoke when merge two continuous text nodes, we need to merge their indexes as well
     * @param targetText Target text node to merge into
     * @param sourceText Source text node to merge from
     * @example Assume we have two text nodes: Node1="Foo", Node2="Bar", after merge,
     * Node1 will become "FooBar", Node2 will be removed from DOM tree
     */
    onMergeText: (targetText: Text, sourceText: Text) => void;
    /**
     * Clear index from the given container and all its descendants
     * @param container The root container to clear index from
     */
    clearIndex: (container: Node) => void;
    /**
     * When document content or selection is changed by user, we need to use this function to update the content model
     * to reflect the latest document. This process can fail since the selected node may not have a related model data structure.
     * @param model Current cached content model
     * @param newSelection Latest selection
     * @param oldSelection @optional Original selection before this change
     * @returns True if reconcile successfully, otherwise false
     */
    reconcileSelection: (model: ContentModelDocument, newSelection: DOMSelection, oldSelection?: CacheSelection) => boolean;
    /**
     * When id is changed from DOM element, update the new ID to related content model if possible
     * @param element The element that has id changed
     * @returns True if successfully updated, otherwise false
     */
    reconcileElementId: (element: HTMLElement) => boolean;
    /**
     * When child list of editor content is changed, we can use this method to do sync the change from editor into content model.
     * This is mostly used when user start to type in an empty line. In that case browser will remove the existing BR node in the empty line if any,
     * and create a new TEXT node for the typed text. Here we use these information to remove original Br segment and create a new Text segment
     * in content model. But if we find anything that cannot be handled, return false so caller will invalidate the cached model
     * @param addedNodes Nodes added by browser during mutation
     * @param removedNodes Nodes removed by browser during mutation
     * @returns True if the changed nodes are successfully reconciled, otherwise false
     */
    reconcileChildList: (addedNodes: ArrayLike<Node>, removedNodes: ArrayLike<Node>) => boolean;
}

/**
 * A wrapper of MutationObserver to observe text change from editor
 */
export interface TextMutationObserver {
    /**
     * Start observing mutations from editor
     */
    startObserving(): void;
    /**
     * Stop observing mutations from editor
     */
    stopObserving(): void;
    /**
     * Flush all pending mutations and update cached model if need
     * @param ignoreMutations When pass true, all mutations will be ignored and do not update content model.
     * This should only be used when we already have a up-to-date content model and will set it as latest cache
     */
    flushMutations(ignoreMutations?: boolean): void;
}

/**
 * Types of definitions, used by Definition type
 */
export type DefinitionType = /**
 * Boolean type definition, represents a boolean type value
 */
'boolean'
/**
 * Number type definition, represents a number type value
 */
 | 'number'
/**
 * String type definition, represents a string type value
 */
 | 'string'
/**
 * Array type definition, represents an array with a given item type
 */
 | 'array'
/**
 * Object type definition, represents an object with the given property types
 */
 | 'object';

/**
 * A type template to get item type of an array
 */
export type ArrayItemType<T extends any[]> = T extends (infer U)[] ? U : never;

/**
 * Base interface of property definition
 */
export interface DefinitionBase<T extends DefinitionType> {
    /**
     * Type of this property
     */
    type: T;
    /**
     * Whether this property is optional
     */
    isOptional?: boolean;
    /**
     * Whether this property is allowed to be null
     */
    allowNull?: boolean;
}

/**
 * String property definition. This definition can also be used for string based enum property
 */
export interface StringDefinition extends DefinitionBase<'string'> {
    /**
     * An optional value of this property. When specified, the given property must have exactly same value of this value
     */
    value?: string;
}

/**
 * Number property definition. This definition can also be used for number based enum property
 */
export interface NumberDefinition extends DefinitionBase<'number'> {
    /**
     * An optional value of this property. When specified, the given property must have same value of this value
     */
    value?: number;
    /**
     * An optional minimum value of this property. When specified, the given property must be greater or equal to this value
     */
    minValue?: number;
    /**
     * An optional maximum value of this property. When specified, the given property must be less or equal to this value
     */
    maxValue?: number;
}

/**
 * Boolean property definition
 */
export interface BooleanDefinition extends DefinitionBase<'boolean'> {
    /**
     * An optional value of this property. When specified, the given property must have same value of this value
     */
    value?: boolean;
}

/**
 * Array property definition.
 */
export interface ArrayDefinition<T extends any[]> extends DefinitionBase<'array'> {
    /**
     * Definition of each item of this array. All items of the given array must have the same type. Otherwise, use CustomizeDefinition instead.
     */
    itemDef: Definition<ArrayItemType<T>>;
    /**
     * An optional minimum length of this array. When specified, the given array must have at least this value of items
     */
    minLength?: number;
    /**
     * An optional maximum length of this array. When specified, the given array must have at most this value of items
     */
    maxLength?: number;
}

/**
 * Object property definition type used by Object Definition
 */
export type ObjectPropertyDefinition<T extends Object> = {
    [Key in keyof T]: Definition<T[Key]>;
};

/**
 * Object property definition.
 */
export interface ObjectDefinition<T extends Object> extends DefinitionBase<'object'> {
    /**
     * A key-value map to specify the definition of each possible property of this object
     */
    propertyDef: ObjectPropertyDefinition<T>;
}

/**
 * A combination of all definition types
 */
export type Definition<T> = T extends any[] ? ArrayDefinition<T> : T extends Record<string, any> ? ObjectDefinition<T> : T extends String ? StringDefinition : T extends Number ? NumberDefinition : T extends Boolean ? BooleanDefinition : never;

/**
 * A handler object for dark color, used for variable-based dark color solution
 */
export interface DarkColorHandler {
    /**
     * Map of known colors
     */
    readonly knownColors: Record<string, Colors>;
    /**
     * Update all known colors to root container.
     * @param isDarkMode Whether container is in dark mode. When in dark mode, we add CSS color variables for all known colors.
     * When in light mode, we will remove all those CSS color variables
     */
    updateKnownColor(isDarkMode: boolean): void;
    /**
     * Register a known color, and update it to root container via CSS color variable when in dark mode
     * @param isDarkMode Whether container is in dark mode.
     * @param key The key of color, normally it is the name of color variable
     * @param colorPair A pair value of light color and dark color
     */
    updateKnownColor(isDarkMode: boolean, key: string, colorPair: Colors): void;
    /**
     * Reset known color record, clean up registered color variables.
     */
    reset(): void;
    /**
     * A util function to transform light mode color to dark mode color
     */
    getDarkColor: ColorTransformFunction;
    /**
     * Generate color key for dark mode color.
     */
    generateColorKey: ColorTransformFunction;
}

/**
 * Represents a combination of color key, light color and dark color, parsed from existing color value
 */
export interface Colors {
    /**
     * Light mode color value
     */
    lightModeColor: string;
    /**
     * Dark mode color value, if found, otherwise undefined
     */
    darkModeColor: string;
}

/**
 * A util function type to transform light mode color to dark mode color
 * Default value is to return the original light color
 * @param lightColor Source color string in light mode
 * @param baseLValue Base value of light used for dark value calculation
 * @param colorType @optional Type of color, can be text, background, or border
 * @param element @optional Source HTML element of the color
 */
export type ColorTransformFunction = (lightColor: string, baseLValue?: number, colorType?: 'text' | 'background' | 'border', element?: HTMLElement) => string;

/**
 * An interface of Editor, built on top of Content Model
 */
export interface IEditor {
    /**
     * @deprecated Use formatContentModel() instead
     */
    getContentModelCopy(mode: 'connected'): ContentModelDocument;
    /**
     * Create Content Model from DOM tree in this editor
     * @param mode What kind of Content Model we want. Currently we support the following values:
     * - disconnected: Returns a disconnected clone of Content Model from editor which you can do any change on it and it won't impact the editor content.
     * If there is any entity in editor, the returned object will contain cloned copy of entity wrapper element.
     * If editor is in dark mode, the cloned entity will be converted back to light mode.
     * - clean: Similar with disconnected, this will return a disconnected model, the difference is "clean" mode will not include any selection info.
     * This is usually used for exporting content
     */
    getContentModelCopy(mode: 'disconnected' | 'clean'): ContentModelDocument;
    /**
     * Get current running environment, such as if editor is running on Mac
     */
    getEnvironment(): EditorEnvironment;
    /**
     * Get current DOM selection.
     * This is the replacement of IEditor.getSelectionRangeEx.
     */
    getDOMSelection(): DOMSelection | null;
    /**
     * Set DOMSelection into editor content.
     * This is the replacement of IEditor.select.
     * @param selection The selection to set
     */
    setDOMSelection(selection: DOMSelection | null): void;
    /**
     * Set a new logical root (most likely due to focus change)
     * @param core The StandaloneEditorCore object
     * @param logicalRoot The new logical root (has to be child of physicalRoot or null to use physicalRoot as logical root)
     */
    setLogicalRoot(logicalRoot: HTMLDivElement | null): void;
    /**
     * The general API to do format change with Content Model
     * It will grab a Content Model for current editor content, and invoke a callback function
     * to do format change. Then according to the return value, write back the modified content model into editor.
     * If there is cached model, it will be used and updated.
     * @param formatter Formatter function, see ContentModelFormatter
     * @param options More options, see FormatContentModelOptions
     */
    formatContentModel(formatter: ContentModelFormatter, options?: FormatContentModelOptions, domToModelOption?: DomToModelOptionForCreateModel): void;
    /**
     * Get pending format of editor if any, or return null
     */
    getPendingFormat(): ContentModelSegmentFormat | null;
    /**
     * Get whether this editor is disposed
     * @returns True if editor is disposed, otherwise false
     */
    isDisposed(): boolean;
    /**
     * Get a DOM Helper object to help access DOM tree in editor
     */
    getDOMHelper(): DOMHelper;
    /**
     * Get document which contains this editor
     * @returns The HTML document which contains this editor
     */
    getDocument(): Document;
    /**
     * Focus to this editor, the selection was restored to where it was before, no unexpected scroll.
     */
    focus(): void;
    /**
     * Trigger an event to be dispatched to all plugins
     * @param eventType Type of the event
     * @param data data of the event with given type, this is the rest part of PluginEvent with the given type
     * @param broadcast indicates if the event needs to be dispatched to all plugins
     * True means to all, false means to allow exclusive handling from one plugin unless no one wants that
     * @returns the event object which is really passed into plugins. Some plugin may modify the event object so
     * the result of this function provides a chance to read the modified result
     */
    triggerEvent<T extends PluginEventType>(eventType: T, data: PluginEventData<T>, broadcast?: boolean): PluginEventFromType<T>;
    /**
     * Get undo snapshots manager
     */
    getSnapshotsManager(): SnapshotsManager;
    /**
     * Check if the editor is in dark mode
     * @returns True if the editor is in dark mode, otherwise false
     */
    isDarkMode(): boolean;
    /**
     * Set the dark mode state and transforms the content to match the new state.
     * @param isDarkMode The next status of dark mode. True if the editor should be in dark mode, false if not.
     */
    setDarkModeState(isDarkMode?: boolean): void;
    /**
     * Add a single undo snapshot to undo stack
     * @param entityState @optional State for entity if we want to add entity state for this snapshot
     */
    takeSnapshot(entityState?: EntityState): Snapshot | null;
    /**
     * Restore an undo snapshot into editor
     * @param snapshot The snapshot to restore
     */
    restoreSnapshot(snapshot: Snapshot): void;
    /**
     * Attach a DOM event to the editor content DIV
     * @param eventMap A map from event name to its handler
     */
    attachDomEvent(eventMap: Record<string, DOMEventRecord>): () => void;
    /**
     * Check if editor is in Shadow Edit mode
     */
    isInShadowEdit(): boolean;
    /**
     * Make the editor in "Shadow Edit" mode.
     * In Shadow Edit mode, all format change will finally be ignored.
     * This can be used for building a live preview feature for format button, to allow user
     * see format result without really apply it.
     * This function can be called repeated. If editor is already in shadow edit mode, we can still
     * use this function to do more shadow edit operation.
     */
    startShadowEdit(): void;
    /**
     * Leave "Shadow Edit" mode, all changes made during shadow edit will be discarded
     */
    stopShadowEdit(): void;
    /**
     * Get a darkColorHandler object for this editor.
     */
    getColorManager(): DarkColorHandler;
    /**
     * Dispose this editor, dispose all plugins and custom data
     */
    dispose(): void;
    /**
     * Check if focus is in editor now
     * @returns true if focus is in editor, otherwise false
     */
    hasFocus(): boolean;
    /**
     * @deprecated use getDOMCreator instead
     * Get a function to convert HTML string to trusted HTML string.
     * By default it will just return the input HTML directly. To override this behavior,
     * pass your own trusted HTML handler to EditorOptions.trustedHTMLHandler
     * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types
     */
    getTrustedHTMLHandler(): LegacyTrustedHTMLHandler;
    /**
     * Get a function to convert HTML string to a trust Document.
     * By default it will just convert the original HTML string into a Document object directly.
     * To override, pass your own trusted HTML handler to EditorOptions.trustedHTMLHandler
     * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types
     */
    getDOMCreator(): DOMCreator;
    /**
     * Get the scroll container of the editor
     */
    getScrollContainer(): HTMLElement;
    /**
     * Retrieves the rect of the visible viewport of the editor.
     */
    getVisibleViewport(): Rect | null;
    /**
     * Add CSS rules for editor
     * @param key A string to identify the CSS rule type. When set CSS rules with the same key again, existing rules with the same key will be replaced.
     * @param cssRule The CSS rule string, must be a valid CSS rule string, or browser may throw exception. Pass null to clear existing rules
     * @param subSelectors @optional If the rule is used for child element under editor, use this parameter to specify the child elements. Each item will be
     * combined with root selector together to build a separate rule.
     */
    setEditorStyle(key: string, cssRule: string | null, subSelectors?: 'before' | 'after' | string[]): void;
    /**
     * Announce the given data
     * @param announceData Data to announce
     */
    announce(announceData: AnnounceData): void;
    /**
     * Check if a given feature is enabled
     * @param featureName The name of feature to check
     */
    isExperimentalFeatureEnabled(featureName: ExperimentalFeature | string): boolean;
}

/**
 * Predefined experiment features
 * By default these features are not enabled. To enable them, pass the feature name into EditorOptions.experimentalFeatures
 * when create editor
 */
export type ExperimentalFeature = /**
 * When this feature is enabled, we will persist a content model in memory as long as we can,
 * and use cached element when write back if it is not changed.
 */
'PersistCache'
/**
 * @deprecated
 * Workaround for the Legacy Image Edit
 */
 | 'LegacyImageSelection'
/**
 * @deprecated Please use the shouldHandleEnterKey option of the EditPlugin Options
 * Use Content Model handle ENTER key
 */
 | 'HandleEnterKey'
/**
 *  Prevent default browser behavior for copy/cut event,
 *  and set the clipboard data with custom implementation.
 */
 | 'CustomCopyCut'
/**
 * For CJK keyboard input on mobile, if the user toggles bold/italic/underline on an empty div,
 * the pending format will be applied on the selection marker. When typing text, the selection moves to the text node and the
 * selection marker may be recreated during reconciliation, potentially losing its original formatting. This feature ensures
 * the original formatting of the selection marker is kept to match the pending format.
 */
 | 'KeepSelectionMarkerWhenEnteringTextNode';

/**
 * Options for editor
 */
export interface EditorOptions extends EditorBaseOptions, ColorOptions, ContentModelOptions, SelectionOptions, PasteOptions  {
}

/**
 * Options for colors and dark mode
 */
export interface ColorOptions {
    /**
     * A util function to transform light mode color to dark mode color
     * Default value is to return the original light color
     */
    getDarkColor?: ColorTransformFunction;
    /**
     * A util function to generate color key for dark mode color.
     * By default, the color key is generated from the light mode color. For example,
     * color "#123456" will have the key "--darkColor__123456", and
     * color "rgb(0,0,0)" will have key "--darkColor_rgb_0_0_0_".
     * Pass in this function to customize this behavior.
     * The return value must be a valid CSS variable, starts with "--"
     */
    generateColorKey?: ColorTransformFunction;
    /**
     * Existing known color pairs
     */
    knownColors?: Record<string, Colors>;
    /**
     * Whether to skip the adjust editor process when for light/dark mode
     */
    doNotAdjustEditorColor?: boolean;
    /**
     * If the editor is currently in dark mode
     */
    inDarkMode?: boolean;
}

/**
 * Options for Content Model
 */
export interface ContentModelOptions {
    /**
     * Default options used for DOM to Content Model conversion
     */
    defaultDomToModelOptions?: DomToModelOption;
    /**
     * Default options used for Content Model to DOM conversion
     */
    defaultModelToDomOptions?: ModelToDomOption;
    /**
     * Default format of editor content. This will be applied to empty content.
     * If there is already content inside editor, format of existing content will not be changed.
     * Default value is the computed style of editor content DIV
     */
    defaultSegmentFormat?: ContentModelSegmentFormat;
    /**
     * An optional callback function that will be invoked before write content model back to editor.
     * This is used for make sure model can satisfy some customized requirement
     * @param model The model to fix up
     */
    onFixUpModel?: (model: ReadonlyContentModelDocument) => void;
    /**
     * @deprecated
     */
    disableCache?: boolean;
}

/**
 * Options for selection
 */
export interface SelectionOptions {
    /**
     * Color of the border of a selectedImage. Default color: '#DB626C'
     */
    imageSelectionBorderColor?: string;
    /**
     * Background color of a selected table cell. Default color: '#C6C6C6'
     */
    tableCellSelectionBackgroundColor?: string;
}

/**
 * Options for paste
 */
export interface PasteOptions {
    /**
     * Allowed custom content type when paste besides text/plain, text/html and images
     * Only text types are supported, and do not add "text/" prefix to the type values
     */
    allowedCustomPasteType?: string[];
    /**
     * Default paste type or function that returns the paste type. By default will use the normal (as-is) paste type.
     */
    defaultPasteType?: PasteTypeOrGetter;
}

/**
 * Options for editor fundamental data structure
 */
export interface EditorBaseOptions {
    /**
     * Enabled experimental features
     */
    experimentalFeatures?: (ExperimentalFeature | string)[];
    /**
     * List of plugins.
     * The order of plugins here determines in what order each event will be dispatched.
     * Plugins not appear in this list will not be added to editor, including built-in plugins.
     * Default value is empty array.
     */
    plugins?: EditorPlugin[];
    /**
     * The scroll container to get scroll event from.
     * By default, the scroll container will be the same with editor content DIV
     */
    scrollContainer?: HTMLElement;
    /**
     * Customized trusted type handler used for sanitizing HTML string before assign to DOM tree
     * This is required when trusted-type Content-Security-Policy (CSP) is enabled.
     * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types
     */
    trustedHTMLHandler?: TrustedHTMLHandler;
    /**
     * A function map to override default core API implementation
     * Default value is null
     */
    coreApiOverride?: Partial<CoreApiMap>;
    /**
     * Initial Content Model
     */
    initialModel?: ContentModelDocument;
    /**
     * Undo snapshot. Use this parameter to provide an external storage of undo snapshots
     */
    snapshots?: Snapshots;
    /**
     * A callback to be invoked when any exception is thrown during disposing editor
     * @param plugin The plugin that causes exception
     * @param error The error object we got
     */
    disposeErrorHandler?: (plugin: EditorPlugin, error: Error) => void;
    /**
     * A callback to help get string template to announce, used for accessibility
     * @param key The key of known announce data
     * @returns A template string to announce, use placeholder such as "{0}" for variables if necessary
     */
    announcerStringGetter?: (key: KnownAnnounceStrings) => string;
    /**
     * Whether to enable paragraph map. Default value is false.
     * Paragraph map is used to save a marker for paragraphs so it can be found even content is changed from a previous marked paragraph.
     */
    enableParagraphMap?: boolean;
}

/**
 * Create Content Model from DOM tree in this editor
 * @param core The EditorCore object
 * @param option The option to customize the behavior of DOM to Content Model conversion
 * @param selectionOverride When passed a valid selection, use this selection range instead of current selection in editor.
 * When pass "none", it means we don't need a selection in content model
 */
export type CreateContentModel = (core: EditorCore, option?: DomToModelOptionForCreateModel, selectionOverride?: DOMSelection | 'none') => ContentModelDocument;

/**
 * Create a EditorContext object used by ContentModel API
 * @param core The EditorCore object
 * @param saveIndex True to allow saving index info into node using domIndexer, otherwise false
 */
export type CreateEditorContext = (core: EditorCore, saveIndex: boolean) => EditorContext;

/**
 * Get current DOM selection from editor
 * @param core The EditorCore object
 */
export type GetDOMSelection = (core: EditorCore) => DOMSelection | null;

/**
 * Set content with content model. This is the replacement of core API getSelectionRangeEx
 * @param core The EditorCore object
 * @param model The content model to set
 * @param option Additional options to customize the behavior of Content Model to DOM conversion
 * @param onNodeCreated An optional callback that will be called when a DOM node is created
 * @param isInitializing True means editor is being initialized then it will save modification nodes onto
 * lifecycleState instead of triggering events, false means other cases
 */
export type SetContentModel = (core: EditorCore, model: ContentModelDocument, option?: ModelToDomOption, onNodeCreated?: OnNodeCreated, isInitializing?: boolean) => DOMSelection | null;

/**
 * Set current DOM selection from editor. This is the replacement of core API select
 * @param core The EditorCore object
 * @param selection The selection to set
 * @param skipSelectionChangedEvent @param Pass true to skip triggering a SelectionChangedEvent
 */
export type SetDOMSelection = (core: EditorCore, selection: DOMSelection | null, skipSelectionChangedEvent?: boolean) => void;

/**
 * Set a new logical root (most likely due to focus change)
 * @param core The EditorCore object
 * @param logicalRoot The new logical root (has to be child of physicalRoot or null to use physicalRoot as logical root)
 */
export type SetLogicalRoot = (core: EditorCore, logicalRoot: HTMLDivElement | null) => void;

/**
 * The general API to do format change with Content Model
 * It will grab a Content Model for current editor content, and invoke a callback function
 * to do format change. Then according to the return value, write back the modified content model into editor.
 * If there is cached model, it will be used and updated.
 * @param core The EditorCore object
 * @param formatter Formatter function, see ContentModelFormatter
 * @param options More options, see FormatContentModelOptions
 */
export type FormatContentModel = (core: EditorCore, formatter: ContentModelFormatter, options?: FormatContentModelOptions, domToModelOptions?: DomToModelOptionForCreateModel) => void;

/**
 * The interface for the map of core API for Editor.
 * Editor can call call API from this map under EditorCore object
 */
export interface CoreApiMap {
    /**
     * Create Content Model from DOM tree in this editor
     * @param core The EditorCore object
     * @param option The option to customize the behavior of DOM to Content Model conversion
     * @param selectionOverride When passed a valid selection, use this selection range instead of current selection in editor.
     * When pass "none", it means we don't need a selection in content model
     */
    createEditorContext: CreateEditorContext;
    /**
     * Create Content Model from DOM tree in this editor
     * @param core The EditorCore object
     * @param option The option to customize the behavior of DOM to Content Model conversion
     */
    createContentModel: CreateContentModel;
    /**
     * Get current DOM selection from editor
     * @param core The EditorCore object
     */
    getDOMSelection: GetDOMSelection;
    /**
     * Set content with content model
     * @param core The EditorCore object
     * @param model The content model to set
     * @param option Additional options to customize the behavior of Content Model to DOM conversion
     * @param onNodeCreated An optional callback that will be called when a DOM node is created
     * @param isInitializing True means editor is being initialized then it will save modification nodes onto
     * lifecycleState instead of triggering events, false means other cases
     */
    setContentModel: SetContentModel;
    /**
     * Set current DOM selection from editor. This is the replacement of core API select
     * @param core The EditorCore object
     * @param selection The selection to set
     * @param skipSelectionChangedEvent @param Pass true to skip triggering a SelectionChangedEvent
     */
    setDOMSelection: SetDOMSelection;
    /**
     * Set a new logical root (most likely due to focus change)
     * @param core The StandaloneEditorCore object
     * @param logicalRoot The new logical root (has to be child of physicalRoot)
     */
    setLogicalRoot: SetLogicalRoot;
    /**
     * The general API to do format change with Content Model
     * It will grab a Content Model for current editor content, and invoke a callback function
     * to do format change. Then according to the return value, write back the modified content model into editor.
     * If there is cached model, it will be used and updated.
     * @param core The EditorCore object
     * @param formatter Formatter function, see ContentModelFormatter
     * @param options More options, see FormatContentModelOptions
     */
    formatContentModel: FormatContentModel;
    /**
     * Switch the Shadow Edit mode of editor On/Off
     * @param core The EditorCore object
     * @param isOn True to switch On, False to switch Off
     */
    switchShadowEdit: SwitchShadowEdit;
    /**
     * Retrieves the rect of the visible viewport of the editor.
     * @param core The EditorCore object
     */
    getVisibleViewport: GetVisibleViewport;
    /**
     * Focus to editor. If there is a cached selection range, use it as current selection
     * @param core The EditorCore object
     */
    focus: Focus;
    /**
     * Add an undo snapshot to current undo snapshot stack
     * @param core The EditorCore object
     * @param canUndoByBackspace True if this action can be undone when user press Backspace key (aka Auto Complete).
     * @param entityStates @optional Entity states related to this snapshot.
     * Each entity state will cause an EntityOperation event with operation = EntityOperation.UpdateEntityState
     * when undo/redo to this snapshot
     */
    addUndoSnapshot: AddUndoSnapshot;
    /**
     * Restore an undo snapshot into editor
     * @param core The editor core object
     * @param step Steps to move, can be 0, positive or negative
     */
    restoreUndoSnapshot: RestoreUndoSnapshot;
    /**
     * Attach a DOM event to the editor content DIV
     * @param core The EditorCore object
     * @param eventMap A map from event name to its handler
     */
    attachDomEvent: AttachDomEvent;
    /**
     * Trigger a plugin event
     * @param core The EditorCore object
     * @param pluginEvent The event object to trigger
     * @param broadcast Set to true to skip the shouldHandleEventExclusively check
     */
    triggerEvent: TriggerEvent;
    /**
     * Add CSS rules for editor
     * @param core The EditorCore object
     * @param key A string to identify the CSS rule type. When set CSS rules with the same key again, existing rules with the same key will be replaced.
     * @param cssRule The CSS rule string, must be a valid CSS rule string, or browser may throw exception
     * @param subSelectors @optional If the rule is used for child element under editor, use this parameter to specify the child elements. Each item will be
     * combined with root selector together to build a separate rule.
     */
    setEditorStyle: SetEditorStyle;
    /**
     * Announce the given data
     * @param core The EditorCore object
     * @param announceData Data to announce
     */
    announce: Announce;
}

/**
 * Represents the core data structure of an editor
 */
export interface EditorCore extends PluginState  {
    /**
     * The root DIV element of this editor (formerly contentDiv)
     */
    readonly physicalRoot: HTMLDivElement;
    /**
     * The content DIV element that operations should be applied to
     * By default, the logical root is the same as the physical root,
     * but if nested editors are used, the logical root changes to that of the inner editor
     */
    logicalRoot: HTMLDivElement;
    /**
     * Core API map of this editor
     */
    readonly api: CoreApiMap;
    /**
     * Original API map of this editor. Overridden core API can use API from this map to call the original version of core API.
     */
    readonly originalApi: CoreApiMap;
    /**
     * An array of editor plugins.
     */
    readonly plugins: EditorPlugin[];
    /**
     * Editor running environment
     */
    readonly environment: EditorEnvironment;
    /**
     * Dark model handler for the editor, used for variable-based solution.
     * If keep it null, editor will still use original dataset-based dark mode solution.
     */
    readonly darkColorHandler: DarkColorHandler;
    /**
     * @deprecated
     * @see DOMCreator
     * A handler to convert HTML string to a trust string.
     * By default it will just convert the original HTML string into a string directly.
     * To override, pass your own trusted HTML handler to EditorOptions.trustedHTMLHandler
     */
    readonly trustedHTMLHandler: LegacyTrustedHTMLHandler;
    /**
     * A handler to convert HTML string to a trust Document.
     * By default it will just convert the original HTML string into a Document object directly.
     * To override, pass your own trusted HTML handler to EditorOptions.trustedHTMLHandler
     */
    readonly domCreator: DOMCreator;
    /**
     * A helper class to provide DOM access APIs
     */
    readonly domHelper: DOMHelper;
    /**
     * A callback to be invoked when any exception is thrown during disposing editor
     * @param plugin The plugin that causes exception
     * @param error The error object we got
     */
    readonly disposeErrorHandler?: (plugin: EditorPlugin, error: Error) => void;
    /**
     * An optional callback function that will be invoked before write content model back to editor.
     * This is used for make sure model can satisfy some customized requirement
     * @param model The model to fix up
     */
    readonly onFixUpModel?: (model: ReadonlyContentModelDocument) => void;
    /**
     * Enabled experimental features
     */
    readonly experimentalFeatures: ReadonlyArray<string>;
}

/**
 * Switch the Shadow Edit mode of editor On/Off
 * @param core The EditorCore object
 * @param isOn True to switch On, False to switch Off
 */
export type SwitchShadowEdit = (core: EditorCore, isOn: boolean) => void;

/**
 * Trigger a plugin event
 * @param core The EditorCore object
 * @param pluginEvent The event object to trigger
 * @param broadcast Set to true to skip the shouldHandleEventExclusively check
 */
export type TriggerEvent = (core: EditorCore, pluginEvent: PluginEvent, broadcast: boolean) => void;

/**
 * Add an undo snapshot to current undo snapshot stack
 * @param core The EditorCore object
 * @param canUndoByBackspace True if this action can be undone when user press Backspace key (aka Auto Complete).
 * @param entityStates @optional Entity states related to this snapshot.
 * Each entity state will cause an EntityOperation event with operation = EntityOperation.UpdateEntityState
 * when undo/redo to this snapshot
 */
export type AddUndoSnapshot = (core: EditorCore, canUndoByBackspace: boolean, entityStates?: EntityState[]) => Snapshot | null;

/**
 * Focus to editor. If there is a cached selection range, use it as current selection
 * @param core The EditorCore object
 */
export type Focus = (core: EditorCore) => void;

/**
 * Attach a DOM event to the editor content DIV
 * @param core The EditorCore object
 * @param eventMap A map from event name to its handler
 */
export type AttachDomEvent = (core: EditorCore, eventMap: Record<string, DOMEventRecord>) => () => void;

/**
 * Restore an undo snapshot into editor
 * @param core The EditorCore object
 * @param step Steps to move, can be 0, positive or negative
 */
export type RestoreUndoSnapshot = (core: EditorCore, snapshot: Snapshot) => void;

/**
 * Retrieves the rect of the visible viewport of the editor.
 * @param core The EditorCore object
 */
export type GetVisibleViewport = (core: EditorCore) => Rect | null;

/**
 * Add CSS rules for editor
 * @param core The EditorCore object
 * @param key A string to identify the CSS rule type. When set CSS rules with the same key again, existing rules with the same key will be replaced.
 * @param cssRule The CSS rule string, must be a valid CSS rule string, or browser may throw exception. Pass null to remove existing rules
 * @param subSelectors @optional If the rule is used for child element under editor, use this parameter to specify the child elements. Each item will be
 * combined with root selector together to build a separate rule. It also accepts pseudo classes "before" and "after" to create pseudo class rule "::before"
 * and "::after" to the editor root element itself
 * @param maxRuleLength @optional Set maximum length for a single rule. This is used by test code only
 */
export type SetEditorStyle = (core: EditorCore, key: string, cssRule: string | null, subSelectors?: 'before' | 'after' | string[], maxRuleLength?: number) => void;

/**
 * Announce the given data
 * @param core The EditorCore object
 * @param announceData Data to announce
 */
export type Announce = (core: EditorCore, announceData: AnnounceData) => void;

/**
 * Core plugins for editor
 */
export interface EditorCorePlugins {
    /**
     * ContentModel cache plugin manages cached Content Model, and refresh the cache when necessary
     */
    readonly cache: PluginWithState<CachePluginState>;
    /**
     * ContentModelFormat plugins helps editor to do formatting on top of content model.
     */
    readonly format: PluginWithState<FormatPluginState>;
    /**
     * Copy and paste plugin for handling onCopy and onPaste event
     */
    readonly copyPaste: PluginWithState<CopyPastePluginState>;
    /**
     * DomEvent plugin helps handle additional DOM events such as IME composition, cut, drop.
     */
    readonly domEvent: PluginWithState<DOMEventPluginState>;
    /**
     * Selection plugin handles selection, including range selection, table selection, and image selection
     */
    readonly selection: PluginWithState<SelectionPluginState>;
    /**
     * Entity Plugin handles all operations related to an entity and generate entity specified events
     */
    readonly entity: PluginWithState<EntityPluginState>;
    /**
     * Undo plugin provides the ability to undo/redo
     */
    readonly undo: PluginWithState<UndoPluginState>;
    /**
     * Undo plugin provides the ability get context menu items and trigger ContextMenu event
     */
    readonly contextMenu: PluginWithState<ContextMenuPluginState>;
    /**
     * Lifecycle plugin handles editor initialization and disposing
     */
    readonly lifecycle: PluginWithState<LifecyclePluginState>;
}

/**
 * Interface of an editor plugin
 */
export interface EditorPlugin {
    /**
     * Get a friendly name of this plugin
     */
    getName: () => string;
    /**
     * The first method that editor will call to a plugin when editor is initializing.
     * It will pass in the editor instance, plugin should take this chance to save the
     * editor reference so that it can call to any editor method or format API later.
     * @param editor The editor object
     */
    initialize: (editor: IEditor) => void;
    /**
     * The last method that editor will call to a plugin before it is disposed.
     * Plugin can take this chance to clear the reference to editor. After this method is
     * called, plugin should not call to any editor method since it will result in error.
     */
    dispose: () => void;
    /**
     * Check if the plugin should handle the given event exclusively.
     * Handle an event exclusively means other plugin will not receive this event in
     * onPluginEvent method.
     * If two plugins will return true in willHandleEventExclusively() for the same event,
     * the final result depends on the order of the plugins are added into editor
     * @param event The event to check:
     */
    willHandleEventExclusively?: (event: PluginEvent) => boolean;
    /**
     * Core method for a plugin. Once an event happens in editor, editor will call this
     * method of each plugin to handle the event as long as the event is not handled
     * exclusively by another plugin.
     * @param event The event to handle:
     */
    onPluginEvent?: (event: PluginEvent) => void;
}

/**
 * An editor plugin which have a state object stored on editor core
 * so that editor and core api can access it
 */
export interface PluginWithState<T> extends EditorPlugin  {
    /**
     * Get plugin state object
     */
    getState(): T;
}

/**
 * An extended Editor plugin interface which supports providing context menu items
 */
export interface ContextMenuProvider<T> extends EditorPlugin  {
    /**
     * A callback to return context menu items
     * @param target Target node that triggered a ContextMenu event
     * @returns An array of context menu items, or null means no items needed
     */
    getContextMenuItems: (target: Node) => T[] | null;
}

/**
 * Plugin state for CacheEditPlugin
 */
export interface CachePluginState {
    /**
     * Cached selection
     */
    cachedSelection?: CacheSelection | undefined;
    /**
     * When reuse Content Model is allowed, we cache the Content Model object here after created
     */
    cachedModel?: ContentModelDocument;
    /**
     * A helper class that manages a mapping from paragraph marker to paragraph object.
     */
    paragraphMap?: ParagraphMap & ParagraphIndexer;
    /**
     * @optional Indexer for CachePlugin, to help build backward relationship from DOM node to Content Model
     */
    domIndexer?: DomIndexer;
    /**
     * @optional A wrapper of MutationObserver to help detect text changes in editor
     */
    textMutationObserver?: TextMutationObserver;
}

/**
 * Represents a range selection used for cache. We store the start and end insert point here instead of range itself
 * to prevent range got automatically modified by browser
 */
export interface RangeSelectionForCache extends SelectionBase<'range'> {
    /**
     * Start insert point
     */
    start: DOMInsertPoint;
    /**
     * End inset point
     */
    end: DOMInsertPoint;
    /**
     * Whether the selection was from left to right (in document order) or
     * right to left (reverse of document order)
     */
    isReverted: boolean;
}

/**
 * Represents a selection used for cache
 */
export type CacheSelection = RangeSelectionForCache | ImageSelection | TableSelection;

/**
 * Plugin state for ContentModelFormatPlugin
 */
export interface FormatPluginState {
    /**
     * Default format of this editor
     */
    defaultFormat: ContentModelSegmentFormat;
    /**
     * Pending format
     */
    pendingFormat: PendingFormat | null;
}

/**
 * Pending format holder interface
 */
export interface PendingFormat {
    /**
     * The pending format
     */
    format?: ContentModelSegmentFormat;
    /**
     * Customized format for paragraph
     */
    paragraphFormat?: ContentModelBlockFormat;
    /**
     * Insert point of pending format
     */
    insertPoint: DOMInsertPoint;
}

/**
 * The state object for CopyPastePlugin
 */
export interface CopyPastePluginState {
    /**
     * Allowed custom content type when paste besides text/plain, text/html and images
     * Only text types are supported, and do not add "text/" prefix to the type values
     */
    allowedCustomPasteType: string[];
    /**
     * A temporary DIV element used for cut/copy content
     */
    tempDiv: HTMLDivElement | null;
    /**
     * Default paste type. By default will use the normal (as-is) paste type.
     */
    defaultPasteType?: PasteTypeOrGetter;
}

/**
 * The state object for DOMEventPlugin
 */
export interface DOMEventPluginState {
    /**
     * Whether editor is in IME input sequence
     */
    isInIME: boolean;
    /**
     * Scroll container of editor
     */
    scrollContainer: HTMLElement;
    /**
     * Whether mouse up event handler is added
     */
    mouseUpEventListerAdded: boolean;
    /**
     * X-coordinate when mouse down happens
     */
    mouseDownX: number | null;
    /**
     * X-coordinate when mouse down happens
     */
    mouseDownY: number | null;
}

/**
 * The state object for LifecyclePlugin
 */
export interface LifecyclePluginState {
    /**
     * Whether editor is in dark mode
     */
    isDarkMode: boolean;
    /**
     * Cached document fragment for original content
     */
    shadowEditFragment: DocumentFragment | null;
    /**
     * The HTML container for announced string
     */
    announceContainer?: HTMLElement;
    /**
     * added and removed block elements when initialize
     */
    rewriteFromModel?: RewriteFromModel;
    /**
     * A callback to help get string template to announce, used for accessibility
     * @param key The key of known announce data
     * @returns A template string to announce, use placeholder such as "{0}" for variables if necessary
     */
    readonly announcerStringGetter?: (key: KnownAnnounceStrings) => string;
    /**
     * Style elements used for adding CSS rules for editor
     */
    readonly styleElements: Record<string, HTMLStyleElement>;
}

/**
 * The state object for EntityPlugin
 */
export interface EntityPluginState {
    /**
     * Entities cached for undo snapshot
     */
    entityMap: Record<string, KnownEntityItem>;
}

/**
 * Represents all info of a known entity, including its DOM element, whether it is deleted and if it can be persisted
 */
export interface KnownEntityItem {
    /**
     * The HTML element of entity wrapper
     */
    element: HTMLElement;
    /**
     * Whether this entity is deleted.
     */
    isDeleted?: boolean;
    /**
     * Whether we want to persist this entity element during undo/redo
     */
    canPersist?: boolean;
}

/**
 * The state object for SelectionPlugin
 */
export interface SelectionPluginState {
    /**
     * Cached selection range
     */
    selection: DOMSelection | null;
    /**
     * Table selection internal info for SelectionPlugin
     */
    tableSelection: TableSelectionInfo | null;
    /**
     * Disposer function for MouseMove event
     */
    mouseDisposer?: () => void;
    /**
     * When set to true, onFocus event will not trigger reselect cached range
     */
    skipReselectOnFocus?: boolean;
    /**
     * Color of the border of a selectedImage. Default color: '#DB626C'
     */
    imageSelectionBorderColor?: string;
    /**
     * Color of the border of a selectedImage in dark mode. Default color: '#DB626C'
     */
    imageSelectionBorderColorDark?: string;
    /**
     * Background color of a selected table cell. Default color: '#C6C6C6'
     */
    tableCellSelectionBackgroundColor?: string;
    /**
     * Background color of a selected table cell in dark mode. Default color: '#C6C6C6'
     */
    tableCellSelectionBackgroundColorDark?: string;
}

/**
 * Table selection internal info for SelectionPlugin
 */
export interface TableSelectionInfo {
    /**
     * Selected table
     */
    table: HTMLTableElement;
    /**
     * Parsed table structure, cache this value to avoid calculating again while selecting table
     */
    parsedTable: ParsedTable;
    /**
     * The node where the focus is at when start selection
     */
    startNode: Node;
    /**
     * Coordinate for first selected table cell
     */
    firstCo: TableCellCoordinate;
    /**
     * Coordinate for last selected table cell
     */
    lastCo?: TableCellCoordinate;
}

/**
 * Logical coordinate of a table cell
 */
export interface TableCellCoordinate {
    /**
     * Row index
     */
    row: number;
    /**
     * Column index
     */
    col: number;
}

/**
 * The state object for UndoPlugin
 */
export interface UndoPluginState {
    /**
     * Snapshot service for undo, it helps handle snapshot add, remove and retrieve
     */
    snapshotsManager: SnapshotsManager;
    /**
     * Whether restoring of undo snapshot is in progress.
     */
    isRestoring: boolean;
    /**
     * If addUndoSnapshot() or formatContentModel() is called nested in another one, this will be true
     */
    isNested: boolean;
    /**
     * Insert point after last auto complete. Undo autoComplete only works if the current position matches this one
     */
    autoCompleteInsertPoint: DOMInsertPoint | null;
    /**
     * Last key user pressed
     */
    lastKeyPress: string | null;
}

/**
 * Names of core plugins
 */
export type PluginKey = keyof EditorCorePlugins;

/**
 * Names of the core plugins that have plugin state
 */
export type KeyOfStatePlugin<Key extends PluginKey> = EditorCorePlugins[Key] extends PluginWithState<infer U> ? Key : never;

/**
 * Get type of a plugin with state
 */
export type TypeOfStatePlugin<Key extends PluginKey> = EditorCorePlugins[Key] extends PluginWithState<infer U> ? U : never;

/**
 * All names of plugins with plugin state
 */
export type StatePluginKeys<Key extends PluginKey> = {
    [P in Key]: KeyOfStatePlugin<P>;
}[Key];

/**
 * A type map from name of plugin with state to its plugin type
 */
export type GenericPluginState<Key extends PluginKey> = {
    [P in StatePluginKeys<Key>]: TypeOfStatePlugin<P>;
};

/**
 * Auto-calculated State object type for plugin with states
 */
export type PluginState = GenericPluginState<PluginKey>;

/**
 * The state object for DOMEventPlugin
 */
export interface ContextMenuPluginState {
    /**
     * Context menu providers, that can provide context menu items
     */
    contextMenuProviders: ContextMenuProvider<any>[];
}

/**
 * Options to customize the Auto link options in Auto Format Plugin
 */
export interface AutoLinkOptions {
    /**
     * When press backspace before a link, remove the hyperlink
     */
    autoUnlink?: boolean;
    /**
     * When paste or type content with a link, create hyperlink for the link
     */
    autoLink?: boolean;
    /**
     * When paste content or type content with telephone, create hyperlink for the telephone number
     */
    autoTel?: boolean;
    /**
     * When paste or type a content with mailto, create hyperlink for the content
     */
    autoMailto?: boolean;
}

/**
 * Current running environment
 */
export interface EditorEnvironment {
    /**
     * Whether editor is running on Mac
     */
    readonly isMac?: boolean;
    /**
     * Whether editor is running on Android
     */
    readonly isAndroid?: boolean;
    /**
     * Whether editor is running on Safari browser
     */
    readonly isSafari?: boolean;
    /**
     * Whether current browser is on mobile or a tablet
     */
    readonly isMobileOrTablet?: boolean;
    /**
     * Settings used by DOM to Content Model conversion
     */
    readonly domToModelSettings: ContentModelSettings<DomToModelOption, DomToModelSettings>;
    /**
     * Settings used by Content Model to DOM conversion
     */
    readonly modelToDomSettings: ContentModelSettings<ModelToDomOption, ModelToDomSettings>;
}

/**
 * Default DOM and Content Model conversion settings for an editor
 */
export interface ContentModelSettings<OptionType, ConfigType> {
    /**
     * Built in options used by editor
     */
    builtIn: OptionType;
    /**
     * Customize options passed in from Editor Options, used for overwrite default option.
     * This will also be used by copy/paste
     */
    customized: OptionType;
    /**
     * Configuration calculated from default and customized options.
     * This is a cached object so that we don't need to cache it every time when we use Content Model
     */
    calculated: ConfigType;
}

/**
 * State for an entity. This is used for storing entity undo snapshot
 */
export interface EntityState {
    /**
     * Type of the entity
     */
    type: string;
    /**
     * Id of the entity
     */
    id: string;
    /**
     * The state of this entity to store into undo snapshot.
     * The state can be any string, or a serialized JSON object.
     * We are using string here instead of a JSON object to make sure the whole state is serializable.
     */
    state: string;
}

/**
 * Represents an entity that is deleted by a specified entity operation
 */
export interface DeletedEntity {
    /**
     * The deleted entity
     */
    entity: ContentModelEntity;
    /**
     * The operation that causes this entity to be deleted
     */
    operation: EntityRemovalOperation;
}

/**
 * Context object for API formatWithContentModel
 */
export interface FormatContentModelContext {
    /**
     * New entities added during the format process. This value is only respected when autoDetectChangedEntities is not set to true
     */
    readonly newEntities: ContentModelEntity[];
    /**
     * Entities got deleted during formatting. Need to be set by the formatter function
     * This value is only respected when autoDetectChangedEntities is not set to true
     */
    readonly deletedEntities: DeletedEntity[];
    /**
     * Images inserted in the editor that needs to have their size adjusted
     */
    readonly newImages: ContentModelImage[];
    /**
     * A helper class to help find paragraph from its marker
     */
    readonly paragraphIndexer?: ParagraphIndexer;
    /**
     * Raw Event that triggers this format call
     */
    readonly rawEvent?: Event;
    /**
     * @optional
     * When pass true, skip adding undo snapshot when write Content Model back to DOM.
     * Need to be set by the formatter function
     * Default value is false, which means add undo snapshot
     * When set to true, it will skip adding undo snapshot but mark "hasNewContent" so that next undo snapshot will be added, this is same with "MarkNewContent"
     * When set to 'DoNotSkip', it will add undo snapshot (default behavior)
     * When set to 'MarkNewContent', it will skip adding undo snapshot but mark "hasNewContent" so that next undo snapshot will be added
     * When set to 'SkipAll', it will skip adding undo snapshot and not mark "hasNewContent", as if no change is made
     */
    skipUndoSnapshot?: boolean | 'DoNotSkip' | 'MarkNewContent' | 'SkipAll';
    /**
     * @optional
     * When set to true, formatWithContentModel API will not keep cached Content Model. Next time when we need a Content Model, a new one will be created
     */
    clearModelCache?: boolean;
    /**
     * @optional
     * Specify new pending format.
     * To keep current format event selection position is changed, set this value to "preserved", editor will update pending format position to the new position
     * To set a new pending format, set this property to the format object
     * Otherwise, leave it there and editor will automatically decide if the original pending format is still available
     */
    newPendingFormat?: ContentModelSegmentFormat | 'preserve';
    /**
     * @optional
     * Specify new pending format for paragraph
     * To keep current format event selection position is changed, set this value to "preserved", editor will update pending format position to the new position
     * To set a new pending format, set this property to the format object
     * Otherwise, leave it there and editor will automatically decide if the original pending format is still available
     */
    newPendingParagraphFormat?: ContentModelBlockFormat | 'preserve';
    /**
     * @optional Entity states related to the format API that will be added together with undo snapshot.
     * When entity states are set, each entity state will cause an EntityOperation event with operation = EntityOperation.UpdateEntityState
     * when undo/redo to this snapshot
     */
    entityStates?: EntityState[];
    /**
     * @optional Set to true if this action can be undone when user press Backspace key (aka Auto Complete).
     */
    canUndoByBackspace?: boolean;
    /**
     * @optional Set this value to tell AnnouncePlugin to announce the given information
     */
    announceData?: AnnounceData | null;
    /**
     * @optional When set to true, EntityPlugin will detect any entity changes during this process, newEntities and deletedEntities will be ignored
     */
    autoDetectChangedEntities?: boolean;
}

/**
 * Options for API formatWithContentModel
 */
export interface FormatContentModelOptions {
    /**
     * Name of the format API
     */
    apiName?: string;
    /**
     * Raw event object that triggers this call
     */
    rawEvent?: Event;
    /**
     * Change source used for triggering a ContentChanged event. @default ChangeSource.Format.
     */
    changeSource?: string;
    /**
     * An optional callback that will be called when a DOM node is created
     * @param modelElement The related Content Model element
     * @param node The node created for this model element
     */
    onNodeCreated?: OnNodeCreated;
    /**
     * Optional callback to get an object used for change data in ContentChangedEvent
     */
    getChangeData?: () => any;
    /**
     * When specified, use this selection range to override current selection inside editor
     */
    selectionOverride?: DOMSelection;
    /**
     * When pass to true, scroll the editing caret into view after write DOM tree if need
     */
    scrollCaretIntoView?: boolean;
}

/**
 * Type of formatter used for format Content Model.
 * @param model The source Content Model to format
 * @param context A context object used for pass in and out more parameters
 * @returns True means the model is changed and need to write back to editor, otherwise false
 */
export type ContentModelFormatter = (model: ShallowMutableContentModelDocument, context: FormatContentModelContext) => boolean;

/**
 * The format object state in Content Model
 */
export interface ContentModelFormatState {
    /**
     * Whether the text is bolded
     */
    isBold?: boolean;
    /**
     * Whether the text is italic
     */
    isItalic?: boolean;
    /**
     * Whether the text has underline
     */
    isUnderline?: boolean;
    /**
     * Whether the text has strike through line
     */
    isStrikeThrough?: boolean;
    /**
     * Whether the text is in subscript mode
     */
    isSubscript?: boolean;
    /**
     * Whether the text is in superscript mode
     */
    isSuperscript?: boolean;
    /**
     * Whether the text is in bullet mode
     */
    isBullet?: boolean;
    /**
     * Whether the text is in numbering mode
     */
    isNumbering?: boolean;
    /**
     * Whether the text is in block quote
     */
    isBlockQuote?: boolean;
    /**
     * Whether the text is in Code element
     */
    isCodeInline?: boolean;
    /**
     * Whether the text is in Code block
     */
    isCodeBlock?: boolean;
    /**
     * Whether unlink command can be called to the text
     */
    canUnlink?: boolean;
    /**
     * Whether the selected text is multiline
     */
    isMultilineSelection?: boolean;
    /**
     * Whether add image alt text command can be called to the text
     */
    canAddImageAltText?: boolean;
    /**
     * Heading level (0-6, 0 means no heading)
     */
    headingLevel?: number;
    /**
     * Whether the cursor is in table
     */
    isInTable?: boolean;
    /**
     * Format of table, if there is table at cursor position
     */
    tableFormat?: TableMetadataFormat;
    /**
     * If there is a table, whether the table has header row
     */
    tableHasHeader?: boolean;
    /**
     * Whether we can execute table cell merge operation
     */
    canMergeTableCell?: boolean;
    /**
     * Font name
     */
    fontName?: string;
    /**
     * Font size
     */
    fontSize?: string;
    /**
     * Background color
     */
    backgroundColor?: string;
    /**
     * Text color
     */
    textColor?: string;
    /**
     * Line height
     */
    lineHeight?: string;
    /**
     * Margin Top
     */
    marginTop?: string;
    /**
     * Margin Bottom
     */
    marginBottom?: string;
    /**
     * Text Align
     */
    textAlign?: string;
    /**
     * Direction of the element ('ltr' or 'rtl')
     */
    direction?: string;
    /**
     * Font weight
     */
    fontWeight?: string;
    /**
     * Format of image, if there is image at cursor position
     */
    imageFormat?: ImageFormatState;
    /**
     * Editing metadata of image, if there is image at cursor position
     */
    imageEditingMetadata?: ImageMetadataFormat | null;
    /**
     * Letter spacing
     */
    letterSpacing?: string;
    /**
     * Whether the content can be undone
     */
    canUndo?: boolean;
    /**
     * Whether the content ca nbe redone
     */
    canRedo?: boolean;
    /**
     * Whether editor is in dark mode
     */
    isDarkMode?: boolean;
}

/**
 * Represents the PasteType parameter used to set the paste type to use.
 * It can be either the Paste Type value or a callback that retuns the Paste Type to use.
 */
export type PasteTypeOrGetter = PasteType | ((document: Document | null, clipboardData: ClipboardData) => PasteType);

/**
 * Image Format
 */
export interface ImageFormatState {
    /**
     * Border color
     */
    borderColor?: string;
    /**
     * Border width
     */
    borderWidth?: string;
    /**
     * Border style
     */
    borderStyle?: string;
    /**
     * Border radius
     */
    borderRadius?: string;
    /**
     * Box Shadow style
     */
    boxShadow?: string;
}

/**
 * A combination of CSS border value.
 * See https://developer.mozilla.org/en-US/docs/Web/CSS/border for more information
 */
export interface Border {
    /**
     * Width of the border
     */
    width?: string;
    /**
     * Style of the border
     */
    style?: string;
    /**
     * Color of the border
     */
    color?: string;
}

/**
 * Options for insertEntity API
 */
export interface InsertEntityOptions {
    /**
     * Content node of the entity. If not passed, an empty entity will be created
     */
    contentNode?: Node;
    /**
     * Whether move focus after entity after insert
     */
    focusAfterEntity?: boolean;
    /**
     * "Display" value of the entity wrapper. By default, block entity will have no display, inline entity will have display: inline-block
     */
    wrapperDisplay?: 'inline' | 'block' | 'none' | 'inline-block';
    /**
     * Whether skip adding an undo snapshot around
     */
    skipUndoSnapshot?: boolean;
    /**
     * Initial entity state, this is used when restore an undo snapshot to right after entity is inserted, this state will be used for set initial state of entity
     */
    initialEntityState?: string;
}

/**
 * A context object used by DeleteSelectionStep
 */
export interface DeleteSelectionContext extends DeleteSelectionResult  {
    /**
     * Last paragraph after previous step
     */
    lastParagraph?: ShallowMutableContentModelParagraph;
    /**
     * Last table context after previous step
     */
    lastTableContext?: ReadonlyTableSelectionContext;
    /**
     * Format context provided by formatContentModel API
     */
    formatContext?: FormatContentModelContext;
    /**
     * To store those undeletable segments whose paragraph is deleted.
     * So at the end we can insert them back in to the remaining paragraph
     */
    undeletableSegments?: ShallowMutableContentModelSegment[];
}

/**
 * Result of deleteSelection API
 */
export interface DeleteSelectionResult {
    /**
     * Insert point position after delete, or null if there is no insert point
     */
    insertPoint: InsertPoint | null;
    /**
     * Delete result
     */
    deleteResult: DeleteResult;
}

/**
 * Represents a step function for deleteSelection API
 * @param context The valid delete selection context object returned from previous step
 */
export type DeleteSelectionStep = (context: ValidDeleteSelectionContext) => void;

/**
 * DeleteSelectionContext with a valid insert point that can be handled by next step
 */
export interface ValidDeleteSelectionContext extends DeleteSelectionContext  {
    /**
     * Insert point position after delete
     */
    insertPoint: InsertPoint;
}

/**
 * Base interface for selection info inside an Undo Snapshot
 */
export interface SnapshotSelectionBase<T extends SelectionType> {
    /**
     * Type of selection
     */
    type: T;
}

/**
 * Undo snapshot selection for range
 */
export interface RangeSnapshotSelection extends SnapshotSelectionBase<'range'> {
    /**
     * Start path of selection
     */
    start: number[];
    /**
     * End path of selection
     */
    end: number[];
    /**
     * Whether the selection was from left to right (in document order) or
     * right to left (reverse of document order)
     */
    isReverted: boolean;
}

/**
 * Undo snapshot selection for image
 */
export interface ImageSnapshotSelection extends SnapshotSelectionBase<'image'> {
    imageId: string;
}

/**
 * Undo snapshot selection from table
 */
export interface TableSnapshotSelection extends TableSelectionCoordinates, SnapshotSelectionBase<'table'> {
    /**
     * Id of selected table
     */
    tableId: string;
}

/**
 * Union type for all 3 selection types for Undo Snapshot
 */
export type SnapshotSelection = RangeSnapshotSelection | TableSnapshotSelection | ImageSnapshotSelection;

/**
 * Represents an undo snapshot
 */
export interface Snapshot {
    /**
     * HTML content string
     */
    html: string;
    /**
     * Additional state supplied by plugins. When doing an undo/redo to this snapshot, this state will be added to the
     * content model context as additional state.
     */
    additionalState?: {
        [key: string]: string;
    };
    /**
     * Entity states related to this undo snapshots. When undo/redo to this snapshot, each entity state will trigger
     * an EntityOperation event with operation = EntityOperation.UpdateEntityState
     */
    entityStates?: EntityState[];
    /**
     * Whether this snapshot was taken from dark mode
     */
    isDarkMode: boolean;
    /**
     * Selection of this snapshot
     */
    selection?: SnapshotSelection;
    /**
     * Path to logical root from physical at the time of snapshot
     */
    logicalRootPath?: number[];
}

/**
 * Represents a data structure of snapshots, this is usually used for undo snapshots
 */
export interface Snapshots {
    /**
     * The snapshot array
     */
    snapshots: Snapshot[];
    /**
     * Size of all snapshots
     */
    totalSize: number;
    /**
     * Current index
     */
    currentIndex: number;
    /**
     * Index of snapshot added before an auto complete action
     */
    autoCompleteIndex: number;
    /**
     * An optional callback to be invoked when snapshots are changed
     */
    onChanged?: (type: 'add' | 'move' | 'clear') => void;
    /**
     * Max size of all snapshots
     */
    readonly maxSize: number;
}

/**
 * Represent an interface to provide functionalities to manager undo snapshots
 */
export interface SnapshotsManager {
    /**
     * Whether there is now content changed after last snapshot was taken
     */
    hasNewContent: boolean;
    /**
     * Check whether can move current undo snapshot with the given step
     * @param step The step to check, can be positive, negative or 0
     * @returns True if can move current snapshot with the given step, otherwise false
     */
    canMove(step: number): boolean;
    /**
     * Move current snapshot with the given step if can move this step. Otherwise no action and return null
     * @param step The step to move
     * @returns If can move with the given step, returns the snapshot after move, otherwise null
     */
    move(step: number): Snapshot | null;
    /**
     * Add a new undo snapshot
     * @param snapshot The snapshot to add
     */
    addSnapshot(snapshot: Snapshot, isAutoCompleteSnapshot: boolean): void;
    /**
     * Clear all undo snapshots after the current one
     */
    clearRedo(): void;
    /**
     * Whether there is a snapshot added before auto complete and it can be undone now
     */
    canUndoAutoComplete(): boolean;
}

/**
 * Handler function type of DOM event
 */
export type DOMEventHandlerFunction<E = Event> = (event: E) => void;

/**
 * DOM event handler object with mapped plugin event type and handler function
 */
export interface DOMEventRecord<E = Event> {
    /**
     * Type of plugin event. The DOM event will be mapped with this plugin event type
     */
    pluginEventType?: PluginEventType | null;
    /**
     * Handler function. Besides the mapped plugin event type, this function will also be triggered
     * when correlated DOM event is fired
     */
    beforeDispatch?: DOMEventHandlerFunction<E> | null;
}

/**
 * The link preview pasted info provided by Edge
 */
export interface EdgeLinkPreview {
    /**
     * Domain of the source page
     */
    domain: string;
    /**
     * Preferred paste format
     */
    preferred_format: string;
    /**
     * Title of the source page
     */
    title: string;
    /**
     * Type of the paste content
     */
    type: string;
    /**
     * Url of the source page
     */
    url: string;
}

/**
 * An object contains all related data for pasting
 */
export interface ClipboardData {
    /**
     * Available types from clipboard event
     */
    types: string[];
    /**
     * Plain text from clipboard event
     */
    text: string;
    /**
     * HTML string from clipboard event.
     * When set to null, it means there's no HTML from clipboard event.
     * When set to undefined, it means there may be HTML in clipboard event, but fail to retrieve
     */
    rawHtml: string | null | undefined;
    /**
     * Link Preview information provided by Edge
     */
    linkPreview?: EdgeLinkPreview;
    /**
     * Image file from clipboard event
     */
    image: File | null;
    /**
     * General file from clipboard event
     */
    files?: File[];
    /**
     * Html extracted from raw html string and remove content before and after fragment tag
     */
    html?: string;
    /**
     * An editor content snapshot before pasting happens. This is used for changing paste format
     */
    modelBeforePaste?: ContentModelDocument;
    /**
     * BASE64 encoded data uri of the image if any
     */
    imageDataUri?: string | null;
    /**
     * Array of tag names of the first level child nodes
     */
    htmlFirstLevelChildTags?: string[];
    /**
     * Value of custom paste type. By default it is always empty.
     * To allow custom paste type, pass the allowed types to EditorOptions.allowedCustomPasteType
     */
    customValues: Record<string, string>;
    /**
     * If true, the event was triggered by a native paste event (keyboard or native context menu paste)
     */
    readonly pasteNativeEvent?: boolean;
}

/**
 * Represents data, that can be used to announce text to screen reader.
 */
export interface AnnounceData {
    /**
     * @optional Default announce strings built in Rooster
     */
    defaultStrings?: KnownAnnounceStrings;
    /**
     * @optional string to announce from this Content Changed event, will be the fallback value if default string
     * is not provided or if it is not found in the strings map.
     */
    text?: string;
    /**
     * @optional if provided, will attempt to replace {n} with each of the values inside of the array.
     */
    formatStrings?: string[];
    /**
     * @optional if provided, will set the ariaLive property of the announce container element to the provided value.
     * @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-live#values
     */
    ariaLiveMode?: 'assertive' | 'polite' | 'off';
}

/**
 * Known announce strings
 */
export type KnownAnnounceStrings = /**
 * String announced for a list item in a OL List
 * @example
 * Auto corrected, {0}
 * Where {0} is the new list item bullet
 */
'announceListItemNumbering'
/**
 * String announced for a list item in a UL List
 * @example
 * Auto corrected bullet
 */
 | 'announceListItemBullet'
/**
 * String announced when cursor is moved to the last cell in a table
 */
 | 'announceOnFocusLastCell';

/**
 * A handler type to convert HTML string to a trust HTML string or a DOM object
 */
export type TrustedHTMLHandler = DOMCreator | LegacyTrustedHTMLHandler;

/**
 * A handler type to convert HTML string to a DOM object
 */
export interface DOMCreator {
    /**
     * Callback to convert HTML string to a DOM object
     */
    htmlToDOM: (html: string) => Document;
    /**
     * Flag to indicate if this handler is bypassed or not.
     * If this is true, it means that when converting HTML string to DOM object, we don't need to do any conversion.
     */
    isBypassed?: boolean;
}

/**
 * @deprecated Use DOMCreator instead
 * A handler type to convert HTML string to a trust HTML string
 */
export type LegacyTrustedHTMLHandler = (html: string) => string;

/**
 * This represents a rect inside editor
 */
export interface Rect {
    /**
     * Top
     */
    top: number;
    /**
     * Bottom
     */
    bottom: number;
    /**
     * Left
     */
    left: number;
    /**
     * Right
     */
    right: number;
}

/**
 * Specify how to sanitize a value, can be a callback function or a boolean value.
 * True: Keep this value
 * False: Remove this value
 * A callback: Let the callback function to decide how to deal this value.
 * @param value The original value
 * @param tagName Tag name of the element of this value
 * @returns Return a non-empty string means use this value to replace the original value. Otherwise remove this value
 */
export type ValueSanitizer = ((value: string, tagName: string) => string | null) | boolean;

/**
 * A helper class to provide DOM access APIs
 */
export interface DOMHelper {
    /**
     * Check if the given DOM node is in editor
     * @param node The node to check
     * @param excludeRoot When pass true, the function will return false if the passed in node is the root node itself
     */
    isNodeInEditor(node: Node, excludeRoot?: boolean): boolean;
    /**
     * Query HTML elements in editor by tag name.
     * Be careful of this function since it will also return element under entity.
     * @param tag Tag name of the element to query
     * @returns HTML Element array of the query result
     */
    queryElements<TTag extends keyof HTMLElementTagNameMap>(tag: TTag): HTMLElementTagNameMap[TTag][];
    /**
     * Query HTML elements in editor by a selector string
     * Be careful of this function since it will also return element under entity.
     * @param selector Selector string to query
     * @returns HTML Element array of the query result
     */
    queryElements(selector: string): HTMLElement[];
    /**
     * Get plain text content of editor using textContent property
     */
    getTextContent(): string;
    /**
     * Calculate current zoom scale of editor
     */
    calculateZoomScale(): number;
    /**
     * Set DOM attribute of editor content DIV
     * @param name Name of the attribute
     * @param value Value of the attribute
     */
    setDomAttribute(name: string, value: string | null): void;
    /**
     * Get DOM attribute of editor content DIV, null if there is no such attribute.
     * @param name Name of the attribute
     */
    getDomAttribute(name: string): string | null;
    /**
     * Get DOM style of editor content DIV
     * @param style Name of the style
     */
    getDomStyle<T extends keyof CSSStyleDeclaration>(style: T): CSSStyleDeclaration[T];
    /**
     * Find closest element ancestor start from the given node which matches the given selector
     * @param node Find ancestor start from this node
     * @param selector The expected selector. If null, return the first HTML Element found from start node
     * @returns An HTML element which matches the given selector. If the given start node matches the selector,
     * returns the given node
     */
    findClosestElementAncestor<T extends keyof HTMLElementTagNameMap>(node: Node, selector?: T): HTMLElementTagNameMap[T] | null;
    /**
     * Find closest element ancestor start from the given node which matches the given selector
     * @param node Find ancestor start from this node
     * @param selector The expected selector. If null, return the first HTML Element found from start node
     * @returns An HTML element which matches the given selector. If the given start node matches the selector,
     * returns the given node
     */
    findClosestElementAncestor(node: Node, selector?: string): HTMLElement | null;
    /**
     * Check if the editor has focus now
     * @returns True if the editor has focus, otherwise false
     */
    hasFocus(): boolean;
    /**
     * Check if the root element is in RTL mode
     */
    isRightToLeft(): boolean;
    /**
     * Get the width of the editable area of the editor content div
     */
    getClientWidth(): number;
    /**
     * Get a deep cloned root element
     */
    getClonedRoot(): HTMLElement;
    /**
     * Get format of the container element
     */
    getContainerFormat(): ContentModelSegmentFormat;
}

/**
 * Type of image editing operations
 */
export type ImageEditOperation = /**
 * Resize an image
 */
'resize'
/**
 * Rotate an image
 */
 | 'rotate'
/**
 * Crop an image
 */
 | 'crop'
/**
 * Flip an image
 */
 | 'flip';

/**
 * Define the common operation of an image editor
 */
export interface ImageEditor {
    /**
     * Check if the given editing operation is allowed on current selected image
     * @param operation The operation to check
     * @returns True if the operation is allowed, otherwise false
     */
    isOperationAllowed(operation: ImageEditOperation): boolean;
    /**
     * Check if the given image can be regenerated by this image editor
     * @param image The image to check
     * @returns True if the image can be regenerated, otherwise false
     */
    canRegenerateImage(image: HTMLImageElement): boolean;
    /**
     * Rotate selected image to the given angle (in rad)
     * @param angleRad The angle to rotate to
     */
    rotateImage(angleRad: number): void;
    /**
     * Flip the image.
     * @param direction Direction of flip, can be vertical or horizontal
     */
    flipImage(direction: 'vertical' | 'horizontal'): void;
    /**
     * Start to crop selected image
     */
    cropImage(): void;
}

/**
 * Function type used for cloneModel API to specify how to handle cached element when clone a model
 * @param node The cached node
 * @param type Type of the node, it can be
 * - general: DOM element of ContentModelGeneralSegment or ContentModelGeneralBlock
 * - entity: Wrapper element in ContentModelEntity
 * - cache: Cached node in other model element that supports cache
 */
export type CachedElementHandler = (node: HTMLElement, type: 'general' | 'entity' | 'cache') => HTMLElement | undefined;

/**
 *
 * Options for cloneModel API
 */
export interface CloneModelOptions {
    /**
     * Specify how to deal with cached element, including cached block element, element in General Model, and wrapper element in Entity
     * - True: Cloned model will have the same reference to the cached element
     * - False/Not passed: For cached block element, cached element will be undefined. For General Model and Entity, the element will have deep clone and assign to the cloned model
     * - A callback: invoke the callback with the source cached element and a string to specify model type, let the callback return the expected value of cached element.
     * For General Model and Entity, the callback must return a valid element, otherwise there will be exception thrown.
     */
    includeCachedElement?: boolean | CachedElementHandler;
}

/**
 * Data of the matched link
 */
export interface LinkData {
    /**
     * Schema of a hyperlink
     */
    scheme: string;
    /**
     * Original url of a hyperlink
     */
    originalUrl: string;
    /**
     * Normalized url of a hyperlink
     */
    normalizedUrl: string;
}

/**
 * Options to specify how to merge models
 */
export interface MergeModelOption {
    /**
     * When there is only a table to merge, whether merge this table into current table (if any), or just directly insert (nested table).
     * This is usually used when paste table inside a table
     * @default false
     */
    mergeTable?: boolean;
    /**
     * Use this insert position to merge instead of querying selection from target model
     * @default undefined
     */
    insertPosition?: InsertPoint;
    /**
     * Use this to decide whether to change the source model format when doing the merge.
     * 'mergeAll': (deprecated) Use PreferSource Instead, segment format of the insert position will be merged into the content that is merged into current model.
     * If the source model already has some format, it will not be overwritten.
     * 'keepSourceEmphasisFormat': format of the insert position will be set into the content that is merged into current model.
     * If the source model already has emphasis format, such as, fontWeight, Italic or underline different than the default style, it will not be overwritten.
     * 'none' the source segment format will not be modified.
     * 'preferSource' Will merge both formatting, but source will overwrite target
     * 'preferTarget' Will merge both formatting, but target will overwrite source
     * @default undefined
     */
    mergeFormat?: 'mergeAll' | 'keepSourceEmphasisFormat' | 'none' | 'preferSource' | 'preferTarget';
    /**
     * Whether to add a paragraph after the merged content.
     */
    addParagraphAfterMergedContent?: boolean;
}

/**
 * The callback function type for iterateSelections
 * @param path The block group path of current selection
 * @param tableContext Table context of current selection
 * @param block Block of current selection
 * @param segments Segments of current selection
 * @returns True to stop iterating, otherwise keep going
 */
export type IterateSelectionsCallback = (path: ContentModelBlockGroup[], tableContext?: TableSelectionContext, block?: ContentModelBlock, segments?: ContentModelSegment[]) => void | boolean;

/**
 * Options for iterateSelections API
 */
export interface IterateSelectionsOption {
    /**
     * For selected table cell, this property determines how do we handle its content.
     * include: No matter if table cell is selected, always invoke callback function for selected content (default value)
     * ignoreForTable: When the whole table is selected we invoke callback for the table (using block parameter) but skip
     * all its cells and content, otherwise keep invoking callback for table cell and content
     * ignoreForTableOrCell: If whole table is selected, same with ignoreForTable, or if a table cell is selected, only
     * invoke callback for the table cell itself but not for its content, otherwise keep invoking callback for content.
     * @default include
     */
    contentUnderSelectedTableCell?: 'include' | 'ignoreForTable' | 'ignoreForTableOrCell';
    /**
     * For a selected general element, this property determines how do we handle its content.
     * contentOnly: (Default) When the whole general element is selected, we only invoke callback for its selected content
     * generalElementOnly: When the whole general element is selected, we only invoke callback for the general element (using block or
     * segment parameter depends on if it is a block or segment), but skip all its content.
     * both: When general element is selected, we invoke callback first for its content, then for general element itself
     */
    contentUnderSelectedGeneralElement?: 'contentOnly' | 'generalElementOnly' | 'both';
    /**
     * Whether call the callback for the list item format holder segment
     * anySegment: call the callback if any segment is selected under a list item
     * allSegments: call the callback only when all segments under the list item are selected
     * never: never call the callback for list item format holder
     * @default allSegments
     */
    includeListFormatHolder?: 'anySegment' | 'allSegments' | 'never';
}

/**
 * The callback function type for iterateSelections (Readonly)
 * @param path The block group path of current selection
 * @param tableContext Table context of current selection
 * @param block Block of current selection
 * @param segments Segments of current selection
 * @returns True to stop iterating, otherwise keep going
 */
export type ReadonlyIterateSelectionsCallback = (path: ReadonlyContentModelBlockGroup[], tableContext?: ReadonlyTableSelectionContext, block?: ReadonlyContentModelBlock, segments?: ReadonlyContentModelSegment[]) => void | boolean;

/**
 * A type map from node type number to its type declaration. This is used by utility function isNodeOfType()
 */
export interface NodeTypeMap {
    /**
     * Attribute node
     */
    ATTRIBUTE_NODE: Attr;
    /**
     * Comment node
     */
    COMMENT_NODE: Comment;
    /**
     * DocumentFragment node
     */
    DOCUMENT_FRAGMENT_NODE: DocumentFragment;
    /**
     * Document node
     */
    DOCUMENT_NODE: Document;
    /**
     * DocumentType node
     */
    DOCUMENT_TYPE_NODE: DocumentType;
    /**
     * HTMLElement node
     */
    ELEMENT_NODE: HTMLElement;
    /**
     * ProcessingInstruction node
     */
    PROCESSING_INSTRUCTION_NODE: ProcessingInstruction;
    /**
     * Text node
     */
    TEXT_NODE: Text;
}

/**
 * Retrieve block group type string from a given block group
 */
export type TypeOfBlockGroup<T extends ContentModelBlockGroup | ReadonlyContentModelBlockGroup> = T extends ContentModelBlockGroupBase<infer U> | ReadonlyContentModelBlockGroupBase<infer U> ? U : never;

/**
 * Represent a pair of parent block group and child block
 */
export type OperationalBlocks<T extends ContentModelBlockGroup> = {
    /**
     * The parent block group
     */
    parent: ContentModelBlockGroup;
    /**
     * The child block
     */
    block: ContentModelBlock | T;
    /**
     * Selection path of this block
     */
    path: ContentModelBlockGroup[];
};

/**
 * Represent a pair of parent block group and child block (Readonly)
 */
export type ReadonlyOperationalBlocks<T extends ReadonlyContentModelBlockGroup> = {
    /**
     * The parent block group
     */
    parent: ReadonlyContentModelBlockGroup;
    /**
     * The child block
     */
    block: ReadonlyContentModelBlock | T;
    /**
     * Selection path of this block
     */
    path: ReadonlyContentModelBlockGroup[];
};

/**
 * Represents a parsed table with its table cells
 */
export type ParsedTable = ParsedTableCell[][];

/**
 * Parse a table, this type represents a parsed table cell. It can be a cell element, or a string to indicate where it is spanned from
 */
export type ParsedTableCell = HTMLTableCellElement | 'spanLeft' | 'spanTop' | 'spanBoth';

/**
 * Callback function type for converting a given Content Model object to plain text
 * @param model The source model object to be converted to plain text
 */
export type ModelToTextCallback<T> = (model: T) => string;

/**
 * Callbacks to customize the behavior of contentModelToText function
 */
export interface ModelToTextCallbacks {
    /**
     * Customize the behavior of converting entity segment to plain text
     */
    onEntitySegment?: ModelToTextCallback<ContentModelEntity>;
    /**
     * Customize the behavior of converting entity block to plain text
     */
    onEntityBlock?: ModelToTextCallback<ContentModelEntity>;
    /**
     * Customize the behavior of converting general segment to plain text
     */
    onGeneralSegment?: ModelToTextCallback<ReadonlyContentModelGeneralSegment>;
    /**
     * Customize the behavior of converting text model to plain text
     */
    onText?: ModelToTextCallback<ReadonlyContentModelText>;
    /**
     * Customize the behavior of converting image model to plain text
     */
    onImage?: ModelToTextCallback<ReadonlyContentModelImage>;
    /**
     * Customize the behavior of converting divider model to plain text
     */
    onDivider?: ModelToTextCallback<ReadonlyContentModelDivider>;
    /**
     * Customize the check if we should convert a paragraph model to plain text
     */
    onParagraph?: ModelToTextChecker<ReadonlyContentModelParagraph>;
    /**
     * Customize the check if we should convert a table model to plain text
     */
    onTable?: ModelToTextChecker<ReadonlyContentModelTable>;
    /**
     * Customize the check if we should convert a block group model to plain text
     */
    onBlockGroup?: ModelToTextChecker<ReadonlyContentModelBlockGroup>;
}

/**
 * Callback function type for checking if we should convert to text for the given content model object
 * @param model The source model to check if we should convert it to plain text
 */
export type ModelToTextChecker<T> = (model: T) => boolean;

/**
 * Specify how to handle conflicts when retrieving format state
 * remove: removes the conflicting key from the result
 * keepFirst: retains the first value of the conflicting key
 * returnMultiple: sets 'Multiple' as the value if the conflicting value's type is string
 */
export type ConflictFormatSolution = 'remove' | 'keepFirst' | 'returnMultiple';

/**
 * ParagraphMap is used to map a paragraph marker to a paragraph in the model.
 */
export interface ParagraphMap {
    /**
     * When create content model from DOM, assign a marker to a paragraph in the model.
     * This marker is used to identify the paragraph in the model.
     * If the DOM element does not have a marker, a new marker will be generated and assigned to the paragraph and write back to DOM.
     * @param element The DOM element to assign marker to
     * @param paragraph The paragraph in the model to assign marker to
     */
    assignMarkerToModel(element: HTMLElement, paragraph: ContentModelParagraph): void;
    /**
     * When create DOM elements from content model, assign a marker to a paragraph in the DOM.
     * This marker is used to identify the paragraph in the model.
     * @param element The DOM element to assign marker to
     * @param paragraph The paragraph in the model to assign marker to
     */
    applyMarkerToDom(element: HTMLElement, paragraph: ContentModelParagraph): void;
    /**
     * Clear cached marker map
     */
    clear(): void;
}

/**
 * A helper class to help find paragraph from its marker
 */
export interface ParagraphIndexer {
    /**
     * Get paragraph using a previously marked paragraph
     * @param paragraphWithMarker The paragraph with marker to find
     */
    getParagraphFromMarker(paragraphWithMarker: ReadonlyContentModelParagraph): ReadonlyContentModelParagraph | null;
}

/**
 * Editor plugin event interface
 */
export interface BasePluginEvent<TPluginEventType extends PluginEventType> {
    /**
     * Type of this event
     */
    eventType: TPluginEventType;
    /**
     * An optional event cache.
     * This will be consumed by event cache API to store some expensive calculation result.
     * So that for the same event across plugins, the result doesn't need to be calculated again
     */
    eventDataCache?: {
        [key: string]: any;
    };
}

/**
 * Editor plugin event interface
 */
export interface BasePluginDomEvent<TPluginEventType extends PluginEventType, TRawEvent extends Event> extends BasePluginEvent<TPluginEventType> {
    /**
     * Raw DOM event
     */
    rawEvent: TRawEvent;
}

/**
 * Fired when an undo snapshot is about to be added
 */
export interface BeforeAddUndoSnapshotEvent extends BasePluginEvent<'beforeAddUndoSnapshot'> {
    /**
     * Additional state to be added to the snapshot
     */
    additionalState: {
        [key: string]: string;
    };
}

/**
 * Provides a chance for plugin to change the content before it is copied from editor.
 */
export interface BeforeCutCopyEvent extends BasePluginDomEvent<'beforeCutCopy', ClipboardEvent> {
    /**
     * An object contains all related data for pasting
     */
    clonedRoot: HTMLDivElement;
    /**
     * The selection range under cloned root
     */
    range: Range;
    /**
     * Whether this is a cut event
     */
    isCut: boolean;
}

/**
 * Provides a chance for plugin to change the content before it is pasted into editor.
 */
export interface BeforeDisposeEvent extends BasePluginEvent<'beforeDispose'> {
}

/**
 * Provides a chance for plugin to change the content before it is copied from editor.
 */
export interface BeforeKeyboardEditingEvent extends BasePluginDomEvent<'beforeKeyboardEditing', KeyboardEvent> {
}

/**
 * Data of BeforePasteEvent
 */
export interface BeforePasteEvent extends BasePluginEvent<'beforePaste'> {
    /**
     * An object contains all related data for pasting
     */
    readonly clipboardData: ClipboardData;
    /**
     * HTML Document Fragment which will be inserted into content
     */
    readonly fragment: DocumentFragment;
    /**
     * Stripped HTML string before "StartFragment" comment
     */
    readonly htmlBefore: string;
    /**
     * Stripped HTML string after "EndFragment" comment
     */
    readonly htmlAfter: string;
    /**
     * Attributes of the root "HTML" tag
     */
    readonly htmlAttributes: Record<string, string>;
    /**
     * Paste type option (as plain text, merge format, normal, as image)
     */
    readonly pasteType: PasteType;
    /**
     * domToModel Options to use when creating the content model from the paste fragment
     */
    readonly domToModelOption: DomToModelOptionForSanitizing;
    /**
     * customizedMerge Customized merge function to use when merging the paste fragment into the editor
     */
    customizedMerge?: MergePastedContentFunc;
    /**
     * Whether the current clipboard contains at least a block element.
     */
    readonly containsBlockElements?: boolean;
}

/**
 * A function type used by merging pasted content into current Content Model
 * @param target Target Content Model to merge into
 * @param source Source Content Model to merge from
 * @returns Insert point after merge
 */
export type MergePastedContentFunc = (target: ShallowMutableContentModelDocument, source: ContentModelDocument) => InsertPoint | null;

/**
 * The event to be triggered before SetContent API is called.
 * Handle this event to cache anything you need from editor before it is gone.
 */
export interface BeforeSetContentEvent extends BasePluginEvent<'beforeSetContent'> {
    /**
     * New content HTML that is about to set to editor
     */
    newContent: string;
}

/**
 * Represents a change to the editor made by another plugin with content model inside
 */
export interface ContentChangedEvent extends BasePluginEvent<'contentChanged'> {
    /**
     * The content model that is applied which causes this content changed event
     */
    readonly contentModel?: ContentModelDocument;
    /**
     * Selection range applied to the document
     */
    readonly selection?: DOMSelection;
    /**
     * Entities got changed (added or removed) during the content change process
     */
    readonly changedEntities?: ChangedEntity[];
    /**
     * Additional state added to the snapshot by plugins
     */
    readonly additionalState?: {
        [key: string]: string;
    };
    /**
     * Entity states related to this event
     */
    readonly entityStates?: EntityState[];
    /**
     * Source of the change
     */
    readonly source: string;
    /**
     * Optional related data
     */
    readonly data?: any;
    /**
     * Optional property to store the format api name when using ChangeSource.Format
     */
    readonly formatApiName?: string;
    /**
     * @deprecated Call editor.announce(announceData) directly insteaad
     */
    readonly announceData?: AnnounceData;
}

/**
 * Represents an entity that has been changed during a content change process
 */
export interface ChangedEntity {
    /**
     * The changed entity
     */
    entity: ContentModelEntity;
    /**
     * Operation that causes the change
     */
    operation: EntityRemovalOperation | 'newEntity';
    /**
     * @optional Raw DOM event that causes the change
     */
    rawEvent?: Event;
}

/**
 * This interface represents a PluginEvent wrapping native ContextMenu event
 */
export interface ContextMenuEvent extends BasePluginDomEvent<'contextMenu', MouseEvent> {
    /**
     * A callback array to let editor retrieve context menu item related to this event.
     * Plugins can add their own getter callback to this array,
     * items from each getter will be separated by a splitter item represented by null
     */
    items: any[];
}

/**
 * The event triggered when Content Model modifies editor DOM tree, provides added and removed block level elements
 */
export interface RewriteFromModelEvent extends RewriteFromModel, BasePluginEvent<'rewriteFromModel'> {
}

/**
 * Represents an event that will be fired when an inline image is edited by user, and the src
 * attribute of the image is about to be changed
 */
export interface EditImageEvent extends BasePluginEvent<'editImage'> {
    /**
     * The image element that is being changed
     */
    readonly image: HTMLImageElement;
    /**
     * Original src of the image before all editing in current editor session.
     */
    readonly originalSrc: string;
    /**
     * Src of the image before current batch of editing
     * Plugin can check this value to know which image is not used after the change.
     */
    readonly previousSrc: string;
    /**
     * New src of the changed image, in DataUri format.
     * Plugin can modify this string so that the modified one will be set to the image element
     */
    newSrc: string;
}

/**
 * Provides a chance for plugin to change the content before it is pasted into editor.
 */
export interface EditorReadyEvent extends RewriteFromModel, BasePluginEvent<'editorReady'> {
}

/**
 * Provide a chance for plugins to handle entity related events.
 * See type EntityOperation for more details about each operation
 */
export interface EntityOperationEvent extends BasePluginEvent<'entityOperation'> {
    /**
     * Operation to this entity
     */
    operation: EntityOperation;
    /**
     * The entity that editor is operating on
     */
    entity: Entity;
    /**
     * Optional raw event. Need to do null check before use its value
     */
    rawEvent?: Event;
    /**
     * For entity operation "updateEntityState", we use this object to pass the new entity state to plugin.
     * For other operation types, it is not used.
     */
    state?: string;
    /**
     * For entity operation "newEntity", plugin can set this property to true then the entity will be persisted.
     * A persisted entity won't be touched during undo/redo, unless it does not exist after undo/redo.
     * For other operation types, this value will be ignored.
     */
    shouldPersist?: boolean;
    /**
     * For entity operation "beforeFormat" (happens when user wants to do format change), we will set this array
     * in event and plugins can check if there is any elements inside the entity that should also apply the format
     */
    formattableRoots?: FormattableRoot[];
}

/**
 * Represent a combination of a root element under an entity and options to do DOM and content model conversion
 */
export interface FormattableRoot {
    /**
     * The root element to apply format under an entity
     */
    element: HTMLElement;
    /**
     * @optional DOM to Content Model option
     */
    domToModelOptions?: DomToModelOption;
    /**
     * @optional Content Model to DOM option
     */
    modelToDomOptions?: ModelToDomOption;
}

/**
 * Represents an entity in editor.
 */
export interface Entity {
    /**
     * Type of this entity. Specified when insert an entity, can be an valid CSS class-like string.
     */
    type: string;
    /**
     * Id of this entity, generated by editor code and will be unique within an editor
     */
    id: string;
    /**
     * The wrapper DOM node of this entity which holds the info CSS classes of this entity
     */
    wrapper: HTMLElement;
    /**
     * Whether this is a readonly entity
     */
    isReadonly: boolean;
}

/**
 * Extract Content with a DOM tree event
 * This event is triggered when getContent() is called with triggerExtractContentEvent = true
 * Plugin can handle this event to remove the UI only markups to return clean HTML
 * by operating on a cloned DOM tree
 */
export interface ExtractContentWithDomEvent extends BasePluginEvent<'extractContentWithDom'> {
    /**
     * Cloned root element of editor
     * Plugin can change this DOM tree to clean up the markups it added before
     */
    clonedRoot: HTMLElement;
}

/**
 * This interface represents a PluginEvent wrapping native input / textinput event
 */
export interface EditorInputEvent extends BasePluginEvent<'input'> {
    /**
     * Raw Input Event
     */
    rawEvent: InputEvent;
}

/**
 * This interface represents a PluginEvent wrapping native KeyDown event
 */
export interface KeyDownEvent extends BasePluginDomEvent<'keyDown', KeyboardEvent> {
    /**
     * Whether this event is handled by edit feature
     */
    handledByEditFeature?: boolean;
}

/**
 * This interface represents a PluginEvent wrapping native KeyPress event
 */
export interface KeyPressEvent extends BasePluginDomEvent<'keyPress', KeyboardEvent> {
}

/**
 * This interface represents a PluginEvent wrapping native KeyUp event
 */
export interface KeyUpEvent extends BasePluginDomEvent<'keyUp', KeyboardEvent> {
}

/**
 * This interface represents a PluginEvent wrapping native CompositionEnd event
 */
export interface CompositionEndEvent extends BasePluginDomEvent<'compositionEnd', CompositionEvent> {
}

/**
 * Fired when the logical root is about to be changed
 */
export interface BeforeLogicalRootChangeEvent extends BasePluginEvent<'beforeLogicalRootChange'> {
    /**
     * The logical root element that will no longer be the logical root
     */
    logicalRoot: HTMLDivElement;
}

/**
 * Fired when the logical root changes
 */
export interface LogicalRootChangedEvent extends BasePluginEvent<'logicalRootChanged'> {
    /**
     * The new logical root element
     */
    logicalRoot: HTMLDivElement;
}

/**
 * This interface represents a PluginEvent wrapping native MouseDown event
 */
export interface MouseDownEvent extends BasePluginDomEvent<'mouseDown', MouseEvent> {
}

/**
 * This interface represents a PluginEvent wrapping native MouseUp event
 */
export interface MouseUpEvent extends BasePluginDomEvent<'mouseUp', MouseEvent> {
    /**
     * Whether this is a mouse click event (mouse up and down on the same position)
     */
    isClicking?: boolean;
}

/**
 * Editor plugin event interface
 */
export type PluginEvent = BeforeAddUndoSnapshotEvent | BeforeCutCopyEvent | BeforeDisposeEvent | BeforeKeyboardEditingEvent | BeforeLogicalRootChangeEvent | BeforePasteEvent | BeforeSetContentEvent | CompositionEndEvent | ContentChangedEvent | ContextMenuEvent | RewriteFromModelEvent | EditImageEvent | EditorReadyEvent | EnterShadowEditEvent | EntityOperationEvent | ExtractContentWithDomEvent | EditorInputEvent | KeyDownEvent | KeyPressEvent | KeyUpEvent | LeaveShadowEditEvent | LogicalRootChangedEvent | MouseDownEvent | MouseUpEvent | ScrollEvent | SelectionChangedEvent | ZoomChangedEvent;

/**
 * A type to extract data part of a plugin event type. Data part is the plugin event without eventType field.
 */
export type PluginEventData<T extends PluginEventType> = PluginEventDataGeneric<PluginEvent, T>;

/**
 * A type to get specify plugin event type from eventType parameter.
 * This type is a middle result and only used by PluginEventFromType type
 */
export type PluginEventFromTypeGeneric<E extends PluginEvent, T extends PluginEventType> = E extends BasePluginEvent<T> ? E : never;

/**
 * A type to get specify plugin event type from eventType parameter.
 */
export type PluginEventFromType<T extends PluginEventType> = PluginEventFromTypeGeneric<PluginEvent, T>;

/**
 * A type to extract data part of a plugin event type. Data part is the plugin event without eventType field.
 * This type is a middle result and only used by PluginEventData type
 */
export type PluginEventDataGeneric<E extends PluginEvent, T extends PluginEventType> = E extends BasePluginEvent<T> ? Pick<E, Exclude<keyof E, 'eventType'>> : never;

/**
 * Type of plugin events
 */
export type PluginEventType = /**
 * HTML KeyDown event
 */
'keyDown'
/**
 * HTML KeyPress event
 */
 | 'keyPress'
/**
 * HTML KeyUp event
 */
 | 'keyUp'
/**
 * HTML Input / TextInput event
 */
 | 'input'
/**
 * HTML CompositionEnd event
 */
 | 'compositionEnd'
/**
 * HTML MouseDown event
 */
 | 'mouseDown'
/**
 * HTML MouseUp event
 */
 | 'mouseUp'
/**
 * Content changed event
 */
 | 'contentChanged'
/**
 * Extract Content with a DOM tree event
 * This event is triggered when getContent() is called with triggerExtractContentEvent = true
 * Plugin can handle this event to remove the UI only markups to return clean HTML
 * by operating on a cloned DOM tree
 */
 | 'extractContentWithDom'
/**
 * Before Paste event, provide a chance to change copied content
 */
 | 'beforeCutCopy'
/**
 * Before Paste event, provide a chance to change paste content
 */
 | 'beforePaste'
/**
 * Let plugin know editor is ready now
 */
 | 'editorReady'
/**
 * Let plugin know editor is about to dispose
 */
 | 'beforeDispose'
/**
 * Scroll event triggered by scroll container
 */
 | 'scroll'
/**
 * Operating on an entity. See enum EntityOperation for more details about each operation
 */
 | 'entityOperation'
/**
 * HTML ContextMenu event
 */
 | 'contextMenu'
/**
 * Editor has entered shadow edit mode
 */
 | 'enteredShadowEdit'
/**
 * Editor is about to leave shadow edit mode
 */
 | 'leavingShadowEdit'
/**
 * Content of image is being changed from client side
 */
 | 'editImage'
/**
 * Content of editor is about to be cleared by SetContent API, handle this event to cache anything you need
 * before it is gone
 */
 | 'beforeSetContent'
/**
 * Zoom scale value is changed, triggered by Editor.setZoomScale() when set a different scale number
 */
 | 'zoomChanged'
/**
 * Rewrite result information from Content Model
 */
 | 'rewriteFromModel'
/**
 * EXPERIMENTAL FEATURE
 * Editor changed the selection.
 */
 | 'selectionChanged'
/**
 * EXPERIMENTAL FEATURE
 * The logical root changed
 */
 | 'logicalRootChanged'
/**
 * EXPERIMENTAL FEATURE
 * Editor content is about to be changed by keyboard event.
 * This is only used by Content Model editing
 */
 | 'beforeKeyboardEditing'
/**
 * The logical root is about to change
 * This event is used to clean up any features from the old logical root
 * before the new logical root is set.
 */
 | 'beforeLogicalRootChange'
/**
 * Before an undo snapshot is added to the undo stack.
 * This event is used to give plugins a chance to add additional state to the snapshot.
 */
 | 'beforeAddUndoSnapshot';

/**
 * This interface represents a PluginEvent wrapping native scroll event
 */
export interface ScrollEvent extends BasePluginDomEvent<'scroll', Event> {
    /**
     * Current scroll container that triggers this scroll event
     */
    scrollContainer: HTMLElement;
}

/**
 * Represents an event that will be fired when the user changed the selection
 */
export interface SelectionChangedEvent extends BasePluginEvent<'selectionChanged'> {
    /**
     * The new selection after change
     */
    newSelection: DOMSelection | null;
}

/**
 * A plugin triggered right after editor has entered Shadow Edit mode
 */
export interface EnterShadowEditEvent extends BasePluginEvent<'enteredShadowEdit'> {
}

/**
 * A plugin triggered right before editor leave Shadow Edit mode
 */
export interface LeaveShadowEditEvent extends BasePluginEvent<'leavingShadowEdit'> {
}

/**
 * Represents an event object triggered from Editor.setZoomScale() API.
 * Plugins can handle this event when they need to do something for zoom changing.
 *
 */
export interface ZoomChangedEvent extends BasePluginEvent<'zoomChanged'> {
    /**
     * Zoom scale value after this change
     */
    newZoomScale: number;
}

/**
 * Create Content Model from DOM tree in this editor
 * @param root Root element of DOM tree to create Content Model from
 * @param context Context object for DOM to Content Model conversion
 * @returns A ContentModelDocument object that contains all the models created from the give root element
 */
export function domToContentModel(root: HTMLElement | DocumentFragment, context: DomToModelContext): ContentModelDocument;

/**
 * Create DOM tree fragment from Content Model document
 * @param doc Document object of the target DOM tree
 * @param root Target node that will become the container of new DOM tree.
 * When a DOM node with existing node is passed, it will be merged with content model so that unchanged blocks
 * won't be touched.
 * @param model The content model document to generate DOM tree from
 * @param context The context object for Content Model to DOM conversion
 * @returns The selection range created in DOM tree from this model, or null when there is no selection
 */
export function contentModelToDom(doc: Document, root: Node, model: ContentModelDocument, context: ModelToDomContext): DOMSelection | null;

/**
 * Convert Content Model to plain text
 * @param model The source Content Model
 * @param [separator='\r\n'] The separator string used for connect lines
 * @param callbacks  Callbacks to customize the behavior of contentModelToText function
 */
export function contentModelToText(model: ReadonlyContentModelDocument, separator?: string, callbacks?: ModelToTextCallbacks): string;

/**
 * Content Model Element Processor for child elements
 * @param group The parent block group
 * @param parent Parent DOM node to process
 * @param context DOM to Content Model context
 */
export const childProcessor: ElementProcessor<ParentNode>;

/**
 * Helper function to handle regular (range based) selection when process child node
 * @param index Index of current child node in its parent
 * @param context DOM to Content Model context
 * @param group The parent block group
 * @param nodeStartOffset Start offset of current regular selection
 * @param nodeEndOffset  End offset of current regular selection
 * @param container The container node of this selection
 */
export function handleRegularSelection(index: number, context: DomToModelContext, group: ContentModelBlockGroup, nodeStartOffset: number, nodeEndOffset: number, container?: Node): void;

/**
 * Helper function for processing child node
 * @param group The parent block group
 * @param parent Parent DOM node to process
 * @param context DOM to Content Model context
 *
 */
export function processChildNode(group: ContentModelBlockGroup, child: Node, context: DomToModelContext): void;

/**
 * Content Model Element Processor for entity
 * @param group The parent block group
 * @param parent Parent DOM node to process
 * @param context DOM to Content Model context
 */
export const entityProcessor: ElementProcessor<HTMLElement>;

/**
 * Content Model Element Processor for table
 *
 * For Table with merged/splitted cells, HTML uses colSpan and rowSpan attributes to specify how it should be rendered.
 * To make it easier to edit a table, we will use a different way to describe table.
 *
 * 1. For a m * n table (m rows, n columns), we always create a m * n array for the cells.
 * 2. For a regular table cell, it is mapped to one item of this array
 * 3. For a merged/splitted table cell, it will has colSpan/rowSpan value. We also created TableCell model for those spanned
 * cells, and use "spanLeft" and "spanAbove" to mark its state
 * 4. When edit table, we always edit on this mapped m * n array because it always has an item for each cell
 * 5. When write back to DOM, we create TD/TH elements for those non-spanned cells, and mark its colSpan/rowSpan value according
 * its neighbour cell's spanLeft/spanAbove attribute
 * @param group The parent block group
 * @param parent Parent DOM node to process
 * @param context DOM to Content Model context
 */
export const tableProcessor: ElementProcessor<HTMLTableElement>;

/**
 * Get offset numbers of a regular (range based) selection.
 * If the selection start/end position is not in the given node, it will return -1 for the related value
 * @param context DOM to Content Model context used for retrieve the selection
 * @param currentContainer The container node to check
 * @returns a tuple of start and end offsets. -1 means selection is not directly under the given node
 */
export function getRegularSelectionOffsets(context: DomToModelContext, currentContainer: Node): [number, number];

/**
 * Parse formats of the given HTML element using specified format parsers
 * @param element The element to parse format from
 * @param parsers The parses we are using to parse format
 * @param format The format object to hold result format
 * @param context DOM to Content Model context
 */
export function parseFormat<T extends ContentModelFormatBase>(element: HTMLElement, parsers: (FormatParser<T> | null)[], format: T, context: DomToModelContext): void;

/**
 * Check if the two given formats object are equal. This is a check to value but not to reference
 * @param f1 The first format object to check
 * @param f2 The second format object to check
 */
export function areSameFormats<T extends ContentModelFormatBase>(f1: T, f2: T): boolean;

/**
 * Check if the given element will be layout as a block
 * @param element The element to check
 * @param context The context of DOM to Content Model conversion
 */
export function isBlockElement(element: HTMLElement): boolean;

/**
 * Build a new selection marker with correct format according to its parent paragraph
 * @param group The BlockGroup that paragraph belongs to
 * @param context Current DOM to Model context
 * @param container @optional Container Node, used for retrieving pending format
 * @param offset @optional Container offset, used for retrieving pending format
 * @returns A new selection marker
 */
export function buildSelectionMarker(group: ContentModelBlockGroup, context: DomToModelContext, container?: Node, offset?: number): ContentModelSelectionMarker;

/**
 * Update metadata of the given model
 * @param model The model to update metadata to
 * @param callback A callback function to update metadata
 * @param definition @optional Metadata definition used for verify the metadata object
 * @returns The metadata object if any, or null
 */
export function updateMetadata<T>(model: ShallowMutableContentModelWithDataset<T>, callback?: (metadata: T | null) => T | null, definition?: Definition<T>): T | null;

/**
 * Retrieve metadata from the given model.
 * @param model The Content Model to retrieve metadata from
 * @param definition Definition of this metadata type, used for validate the metadata object
 * @returns Metadata of the model, or null if it does not contain a valid metadata
 */
export function getMetadata<T>(model: ReadonlyContentModelWithDataset<T>, definition?: Definition<T>): T | null;

/**
 * Check if the given model has metadata
 * @param model The content model to check
 */
export function hasMetadata<T>(model: ReadonlyContentModelWithDataset<T> | HTMLElement): boolean;

/**
 * Type checker for Node. Return true if it of the specified node type
 * @param node The node to check
 * @param expectedType The type to check
 */
export function isNodeOfType<T extends keyof NodeTypeMap>(node: Node | null | undefined, expectedType: T): node is NodeTypeMap[T];

/**
 * Check if the given element is of the type that we are checking according to its tag name
 * @param element The element to check
 * @param tag The HTML tag name to check
 * @returns True if the element has the given tag, otherwise false
 */
export function isElementOfType<Tag extends keyof HTMLElementTagNameMap>(element: HTMLElement, tag: Tag): element is HTMLElementTagNameMap[Tag];

/**
 * Provide a strong-typed version of Object.keys()
 * @param obj The source object
 * @returns Array of keys
 */
export function getObjectKeys<T extends string | number | symbol>(obj: Record<T, any> | Partial<Record<T, any>>): T[];

/**
 * Returns a safe Id to use in Native APIs.
 * IDs that start with number or hyphen can throw errors if used.
 * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id
 * @param id
 * @returns
 */
export function getSafeIdSelector(id: string): string;

/**
 * Convert a named node map to an array
 * @param collection The map to convert
 */
export function toArray(collection: NamedNodeMap): Attr[];

/**
 * Convert a named node map to an array
 * @param collection The map to convert
 */
export function toArray(collection: DataTransferItemList): DataTransferItem[];

/**
 * Convert a collection to an array
 * @param collection The collection to convert
 */
export function toArray<T extends Node>(collection: NodeListOf<T>): T[];

/**
 * Convert a collection to an array
 * @param collection The collection to convert
 */
export function toArray<T extends Element>(collection: HTMLCollectionOf<T>): T[];

/**
 * Convert an array to an array.
 * This is to satisfy typescript compiler. For some cases the object can be a collection at runtime,
 * but the declaration is an array. e.g. ClipboardData.types
 * @param array The array to convert
 */
export function toArray<T>(array: readonly T[]): T[];

/**
 * Replace all child nodes of the given target node to the child nodes of source node.
 * @param target Target node, all child nodes of this node will be removed if keepExistingChildren is not set to true
 * @param source (Optional) source node, all child nodes of this node will be move to target node
 * @param keepExistingChildren (Optional) When set to true, all existing child nodes of target will be kept
 */
export function moveChildNodes(target: Node, source?: Node, keepExistingChildren?: boolean): void;

/**
 * Wrap all child nodes of the given parent element using a new element with the given tag name
 * @param parent The parent element
 * @param tagName The tag name of new wrapper
 * @returns New wrapper element
 */
export function wrapAllChildNodes<T extends keyof HTMLElementTagNameMap>(parent: HTMLElement, tagName: T): HTMLElementTagNameMap[T];

/**
 * Wrap the given node with a new element, put the wrapper node under the parent of the first node
 * and return the wrapper element.
 * @param doc Parent document object
 * @param node The node to wrap
 * @param wrapperTag The tag of wrapper HTML element
 * @returns The wrapper element
 */
export function wrap<T extends keyof HTMLElementTagNameMap>(doc: Document, node: Node, wrapperTag: T): HTMLElementTagNameMap[T];

/**
 * Removes the node and keep all children in place, return the parentNode where the children are attached
 * @param node the node to remove
 */
export function unwrap(node: Node): Node | null;

/**
 * Check if the given DOM Node is an entity wrapper element
 */
export function isEntityElement(node: Node): boolean;

/**
 * Find the closest entity wrapper element from a given DOM node
 * @param node The node to start looking for entity wrapper
 * @param domHelper The DOM helper to use
 */
export function findClosestEntityWrapper(startNode: Node, domHelper: DOMHelper): HTMLElement | null;

/**
 * Get all entity wrapper elements under the given root element
 * @param root The root element to query from
 * @returns An array of entity wrapper elements
 */
export function getAllEntityWrappers(root: HTMLElement): HTMLElement[];

/**
 * Parse entity format from entity wrapper element
 * @param wrapper The wrapper element to parse entity format from
 * @returns Entity format
 */
export function parseEntityFormat(wrapper: HTMLElement): ContentModelEntityFormat;

/**
 * Generate Entity class names for an entity wrapper
 * @param format The source entity format object
 * @returns A combined CSS class name string for entity wrapper
 */
export function generateEntityClassNames(format: ContentModelEntityFormat): string;

/**
 * Adds delimiters to the element provided. If the delimiters already exists, will not be added
 * @param element the node to add the delimiters
 * @param format format to set to the delimiters, so when typing inside of one the format is not lost
 * @param context Model to Dom context to use.
 */
export function addDelimiters(doc: Document, element: HTMLElement, format?: ContentModelSegmentFormat | null, context?: ModelToDomContext): HTMLElement[];

/**
 * Checks whether the node provided is a Entity delimiter
 * @param node the node to check
 * @param isBefore True to match delimiter before entity only, false to match delimiter after entity, or undefined means match both
 * @return true if it is a delimiter
 */
export function isEntityDelimiter(element: HTMLElement, isBefore?: boolean): boolean;

/**
 * Check if the given element is a container element of block entity
 * @param element The element to check
 * @returns True if the element is a block entity container, otherwise false
 */
export function isBlockEntityContainer(element: HTMLElement): boolean;

/**
 * Find the closest block entity wrapper element from a given DOM node
 * @param node The node to start looking for entity container
 * @param domHelper The DOM helper
 * @returns
 */
export function findClosestBlockEntityContainer(node: Node, domHelper: DOMHelper): HTMLElement | null;

/**
 * When set a DOM tree into editor, reuse the existing element in editor and no need to change it
 * @param parent Parent node of the reused element
 * @param element The element to keep in parent node
 * @param refNode Reference node, it is point to current node that is being processed. It must be a child of parent node, or null.
 * We will start processing from this node, if it is not the same with element, remove it and keep processing its next sibling,
 * until we see an element that is the same with the passed in element or null.
 * @returns The new reference element
 */
export function reuseCachedElement(parent: Node, element: Node, refNode: Node | null, context?: RewriteFromModel): Node | null;

/**
 * Check if the given white-space style value will cause preserving white space
 * @param whiteSpace The white-space style value to check
 */
export function isWhiteSpacePreserved(whiteSpace: string | undefined): boolean;

/**
 * A ClientRect of all 0 is possible. i.e. chrome returns a ClientRect of 0 when the cursor is on an empty p
 * We validate that and only return a rect when the passed in ClientRect is valid
 * @param clientRect Client rect object normally retrieved from getBoundingClientRect function
 */
export function normalizeRect(clientRect: DOMRect): Rect | null;

/**
 * Set a hidden property on a link element to indicate whether it is undeletable or not.
 * This is used to prevent the link from being deleted when the user tries to delete it.
 * @param a The link element to set the property on
 * @param undeletable Whether the link is undeletable or not
 */
export function setLinkUndeletable(a: HTMLAnchorElement, undeletable: boolean): void;

/**
 * Check if a link element is undeletable or not.
 * This is used to determine if the link can be deleted when the user tries to delete it.
 * @param a The link element to check
 * @returns True if the link is undeletable, false otherwise
 */
export function isLinkUndeletable(a: HTMLAnchorElement): boolean;

/**
 * Create a ContentModelBr model
 * @param format @optional The format of this model
 */
export function createBr(format?: Readonly<ContentModelSegmentFormat>): ContentModelBr;

/**
 * Create a ContentModelListItem model
 * @param levels Existing list levels
 * @param format @optional The format of this model
 */
export function createListItem(levels: ReadonlyArray<ReadonlyContentModelListLevel>, format?: Readonly<ContentModelSegmentFormat>): ContentModelListItem;

/**
 * Create a ContentModelFormatContainer model
 * @param tag Tag name of this format container, in lower case
 * @param format @optional The format of this model
 */
export function createFormatContainer(tag: Lowercase<string>, format?: Readonly<ContentModelFormatContainerFormat>): ContentModelFormatContainer;

/**
 * Create a ContentModelParagraph model
 * @param isImplicit @optional Whether this is an implicit paragraph. An implicit paragraph is a paragraph that will not render with DOM element container
 * @param blockFormat @optional Format of this paragraph
 * @param segmentFormat @optional Segment format applied to this block
 * @param decorator @optional Decorator of this paragraph
 */
export function createParagraph(isImplicit?: boolean, blockFormat?: Readonly<ContentModelBlockFormat>, segmentFormat?: Readonly<ContentModelSegmentFormat>, decorator?: ReadonlyContentModelParagraphDecorator): ContentModelParagraph;

/**
 * Create a ContentModelSelectionMarker model
 * @param format @optional The format of this model
 */
export function createSelectionMarker(format?: Readonly<ContentModelSegmentFormat>): ContentModelSelectionMarker;

/**
 * Create a ContentModelTable model
 * @param rowCount Count of rows of this table
 * @param format @optional The format of this model
 */
export function createTable(rowCount: number, format?: Readonly<ContentModelTableFormat>): ContentModelTable;

/**
 * Create a ContentModelTableCell model
 * @param spanLeftOrColSpan @optional Whether this is a table cell merged with its left cell, or colspan number @default false
 * @param spanAboveOrRowSpan Whether this is a table cell merged with its upper cell, or rowSpan number @default false
 * @param isHeader @optional Whether this is a header cell @default false
 * @param format @optional The format of this model
 */
export function createTableCell(spanLeftOrColSpan?: boolean | number, spanAboveOrRowSpan?: boolean | number, isHeader?: boolean, format?: Readonly<ContentModelTableCellFormat>, dataset?: ReadonlyDatasetFormat): ContentModelTableCell;

/**
 * Create a ContentModelText model
 * @param text Text of this model
 * @param format @optional The format of this model
 * @param link @optional The link decorator
 * @param code @option The code decorator
 */
export function createText(text: string, format?: Readonly<ContentModelSegmentFormat>, link?: ReadonlyContentModelLink, code?: ReadonlyContentModelCode): ContentModelText;

/**
 * Create a ContentModelImage model
 * @param src Image source
 * @param format @optional The format of this model
 */
export function createImage(src: string, format?: Readonly<ContentModelImageFormat>): ContentModelImage;

/**
 * Create a ContentModelDocument model
 * @param defaultFormat @optional Default format of this model
 */
export function createContentModelDocument(defaultFormat?: Readonly<ContentModelSegmentFormat>): ContentModelDocument;

/**
 * Create a ContentModelParagraphDecorator model
 * @param tagName Tag name of this decorator
 * @param format @optional The format of this model
 */
export function createParagraphDecorator(tagName: string, format?: Readonly<ContentModelSegmentFormat>): ContentModelParagraphDecorator;

/**
 * Create a ContentModelGeneralSegment model
 * @param element The original DOM element
 * @param format @optional The format of this model
 */
export function createGeneralSegment(element: HTMLElement, format?: Readonly<ContentModelSegmentFormat>): ContentModelGeneralSegment;

/**
 * Create a ContentModelGeneralBlock model
 * @param element Original element of this model
 */
export function createGeneralBlock(element: HTMLElement): ContentModelGeneralBlock;

/**
 * Create a ContentModelEntity model
 * @param wrapper Wrapper element of this entity
 * @param isReadonly Whether this is a readonly entity @default true
 * @param segmentFormat @optional Segment format of this entity
 * @param type @optional Type of this entity
 * @param id @optional Id of this entity
 */
export function createEntity(wrapper: HTMLElement, isReadonly?: boolean, segmentFormat?: Readonly<ContentModelSegmentFormat>, type?: string, id?: string): ContentModelEntity;

/**
 * Create a ContentModelDivider model
 * @param tagName Tag name of this divider. Currently only hr and div are supported
 * @param format @optional The format of this model
 */
export function createDivider(tagName: 'hr' | 'div', format?: Readonly<ContentModelBlockFormat>): ContentModelDivider;

/**
 * Create a ContentModelListLevel model
 * @param listType Tag name of the list, either OL or UL
 * @param format @optional The format of this model
 * @param dataset @optional The dataset of this model
 */
export function createListLevel(listType: 'OL' | 'UL', format?: Readonly<ContentModelListItemLevelFormat>, dataset?: ReadonlyDatasetFormat): ContentModelListLevel;

/**
 * Create an empty Content Model Document with initial empty line and insert point with default format
 * @param format @optional The default format to be applied to this Content Model
 */
export function createEmptyModel(format?: Readonly<ContentModelSegmentFormat>): ContentModelDocument;

/**
 * Create a ContentModelTableRow model
 * @param format @optional The format of this model
 */
export function createTableRow(format?: Readonly<ContentModelBlockFormat>, height?: number): ContentModelTableRow;

/**
 * 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<T extends ReadonlyContentModelBlockGroup | ReadonlyContentModelBlock>(block: T): MutableType<T>;

/**
 * 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[]): [ShallowMutableContentModelParagraph, ShallowMutableContentModelSegment[], number[]];

/**
 * 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<T extends ReadonlyContentModelSegment>(paragraph: ReadonlyContentModelParagraph, segment: T, callback?: (segment: MutableType<T>, paragraph: ShallowMutableContentModelParagraph, index: number) => void): [ShallowMutableContentModelParagraph, MutableType<T> | null, number];

/**
 * Add a given block to block group
 * @param group The block group to add block into
 * @param block The block to add
 */
export function addBlock(group: ShallowMutableContentModelBlockGroup, block: ShallowMutableContentModelBlock): void;

/**
 * Add a code decorator into segment if any
 * @param segment The segment to add decorator to
 * @param code The code decorator to add
 */
export function addCode(segment: ShallowMutableContentModelSegment, code: ReadonlyContentModelCode): void;

/**
 * Add a new text segment to current paragraph
 * @param group Current BlockGroup that the paragraph belong to
 * @param text Text content of the text segment
 * @param context Current DOM to Model context
 * @returns A new Text segment, or undefined if the input text is empty
 */
export function addTextSegment(group: ContentModelBlockGroup, text: string, context: DomToModelContext): ContentModelText | undefined;

/**
 * @param paragraph The paragraph to normalize
 * Normalize a paragraph. If it is empty, add a BR segment to make sure it can insert content
 */
export function normalizeParagraph(paragraph: ReadonlyContentModelParagraph): void;

/**
 * For a given content model, normalize it to make the model be consistent.
 * This process includes:
 * - For a list item without any list level, unwrap the list item
 * - For a paragraph, make sure it has BR at the end if it is an empty paragraph
 * - For text segments under paragraph, make sure its space values are correct (use nbsp to replace space when necessary)
 * - For an empty block, remove it
 * @param group The root level block group of content model to normalize
 */
export function normalizeContentModel(group: ReadonlyContentModelBlockGroup): void;

/**
 * Check if the given block group is a general segment
 * @param group The group to check
 */
export function isGeneralSegment(group: ContentModelBlockGroup | ContentModelGeneralSegment): group is ContentModelGeneralSegment;

/**
 * Check if the given block group is a general segment (Shallow mutable)
 * @param group The group to check
 */
export function isGeneralSegment(group: ShallowMutableContentModelBlockGroup | ShallowMutableContentModelGeneralSegment): group is ShallowMutableContentModelGeneralSegment;

/**
 * Check if the given block group is a general segment (Readonly)
 * @param group The group to check
 */
export function isGeneralSegment(group: ReadonlyContentModelBlockGroup | ReadonlyContentModelGeneralSegment): group is ReadonlyContentModelGeneralSegment;

/**
 * Unwrap a given block group, move its child blocks to be under its parent group
 * @param parent Parent block group of the unwrapping group
 * @param groupToUnwrap  The block group to unwrap
 */
export function unwrapBlock(parent: ReadonlyContentModelBlockGroup | null, groupToUnwrap: ReadonlyContentModelBlockGroup & ReadonlyContentModelBlock, formatsToKeep?: (keyof ContentModelBlockFormat)[]): void;

/**
 * Add a given segment into a paragraph from its parent group. If the last block of the given group is not paragraph, create a new paragraph.
 * @param group The parent block group of the paragraph to add segment into
 * @param newSegment The segment to add
 * @param blockFormat The block format used for creating a new paragraph when need
 * @returns The parent paragraph where the segment is added to
 */
export function addSegment(group: ContentModelBlockGroup, newSegment: ContentModelSegment, blockFormat?: ContentModelBlockFormat, segmentFormat?: ContentModelSegmentFormat): ContentModelParagraph;

/**
 * Add a given segment into a paragraph from its parent group. If the last block of the given group is not paragraph, create a new paragraph. (Shallow mutable)
 * @param group The parent block group of the paragraph to add segment into
 * @param newSegment The segment to add
 * @param blockFormat The block format used for creating a new paragraph when need
 * @returns The parent paragraph where the segment is added to
 */
export function addSegment(group: ShallowMutableContentModelBlockGroup, newSegment: ContentModelSegment, blockFormat?: ContentModelBlockFormat, segmentFormat?: ContentModelSegmentFormat): ShallowMutableContentModelParagraph;

/**
 * Get whether the model is empty.
 * @returns true if the model is empty.
 */
export function isEmpty(model: ReadonlyContentModelBlock | ReadonlyContentModelBlockGroup | ReadonlyContentModelSegment): boolean;

/**
 * Normalize a given segment, make sure its spaces are correctly represented by space and non-break space
 * @param segment The segment to normalize
 * @param ignoreTrailingSpaces Whether we should ignore the trailing space of the text segment @default false
 */
export function normalizeSingleSegment(paragraph: ReadonlyContentModelParagraph, segment: ReadonlyContentModelSegment, ignoreTrailingSpaces?: boolean): void;

/**
 * Find continuous text segments that have the same format and decorators, merge them, So we can reduce total count of segments
 * @param block The parent paragraph to check.
 */
export function mergeTextSegments(block: ShallowMutableContentModelParagraph): void;

/**
 * Some format values can be changed when apply to DOM, such as font family.
 * This function will normalize the format and return the same string after DOM modification.
 * @param format The format to be normalized
 * @return Normalized format
 */
export function normalizeSegmentFormat(format: ContentModelSegmentFormat, environment: EditorEnvironment): ContentModelSegmentFormat;

/**
 * For a given block, if it is a paragraph, set it to be not-implicit
 * @param block The block to check
 */
export function setParagraphNotImplicit(block: ReadonlyContentModelBlock): void;

/**
 * Copy formats from source to target with only specified keys
 * @param targetFormat The format object to copy format to
 * @param sourceFormat The format object to copy format from
 * @param formatKeys The format keys to copy
 * @param deleteOriginalFormat True to delete the original format from sourceFormat, false to keep it. @default false
 */
export function copyFormat<T extends ContentModelFormatBase>(targetFormat: T, sourceFormat: T, formatKeys: (keyof T)[], deleteOriginalFormat?: boolean): void;

/**
 * When copy format from one block to another, these are all the formats that we can copy
 */
export const ListFormats: (keyof ContentModelBlockFormat)[];

/**
 * When copy format between list and paragraph, these are the formats that we can copy and keep in the source
 */
export const ListFormatsToKeep: (keyof ContentModelBlockFormat)[];

/**
 * When copy format between list and paragraph, these are the formats that we can copy and remove from the source
 */
export const ListFormatsToMove: (keyof ContentModelBlockFormat)[];

/**
 * When copy format between paragraphs, these are the formats that we can copy
 */
export const ParagraphFormats: (keyof ContentModelBlockFormat)[];

/**
 * Get the list number for a list item according to list style type and its index number
 * @param styleType The list style number, should be a value of NumberingListType type
 * @param listNumber List number, start from 1
 * @returns A string for this list item. For example, when pass in NumberingListType.LowerAlpha and 2, it returns "b"
 */
export function getOrderedListNumberStr(styleType: number, listNumber: number): string;

/**
 * Get automatic list style of a list item according to its lis type and metadata.
 * @param listType The list type, either OL or UL
 * @param metadata Metadata of this list item from list item model
 * @param depth Depth of list level, start from 0
 * @param existingStyleType Existing list style type in format, if any
 * @returns A number to represent list style type.
 * This will be the value of either NumberingListType (when listType is OL) or BulletListType (when listType is UL).
 * When there is a specified list style in its metadata, return this value, otherwise
 * When specified "applyListStyleFromLevel" in metadata, calculate auto list type from its depth, otherwise
 * When there is already listStyleType in list level format, find a related style type index, otherwise
 * return undefined
 */
export function getAutoListStyleType(listType: 'OL' | 'UL', metadata: ListMetadataFormat, depth: number, existingStyleType?: string): number | undefined;

/**
 * Parse unit value with its unit
 * @param value The source value to parse
 * @param currentSizePxOrElement The source element which has this unit value, or current font size (in px) from context.
 * @param resultUnit Unit for result, can be px or pt. @default px
 */
export function parseValueWithUnit(value?: string, currentSizePxOrElement?: number | HTMLElement, resultUnit?: 'px' | 'pt'): number;

/**
 * Keys of border items
 */
export const BorderKeys: (keyof BorderFormat & keyof CSSStyleDeclaration)[];

/**
 * List of deprecated colors
 */
export const DeprecatedColors: string[];

/**
 * Get color from given HTML element
 * @param element The element to get color from
 * @param isBackground True to get background color, false to get text color
 * @param isDarkMode Whether element is in dark mode now
 * @param darkColorHandler @optional The dark color handler object to help manager dark mode color
 */
export function getColor(element: HTMLElement, isBackground: boolean, isDarkMode: boolean, darkColorHandler?: DarkColorHandler): string | undefined;

/**
 * Set color to given HTML element
 * @param element The element to set color to
 * @param color The color to set, always pass in color in light mode
 * @param isBackground True to set background color, false to set text color
 * @param isDarkMode Whether element is in dark mode now
 * @param darkColorHandler @optional The dark color handler object to help manager dark mode color
 */
export function setColor(element: HTMLElement, color: string | null | undefined, isBackground: boolean, isDarkMode: boolean, darkColorHandler?: DarkColorHandler): void;

/**
 * Parse color string to r/g/b value.
 * If the given color is not in a recognized format, return null
 * @param color The source color to parse
 * @returns An array of Red/Green/Blue value, or null if fail to parse
 */
export function parseColor(color: string): [number, number, number] | null;

/**
 * Generate color key for dark color
 * @param lightColor The input light color
 * @returns Key of the color
 */
export const defaultGenerateColorKey: ColorTransformFunction;

/**
 * Create context object for DOM to Content Model conversion
 * @param editorContext Context of editor
 * @param options Option array to customize the DOM to Model conversion behavior
 */
export function createDomToModelContext(editorContext?: EditorContext, ...options: (DomToModelOption | undefined)[]): DomToModelContext;

/**
 * Create context object for DOM to Content Model conversion with an existing configure
 * @param config A full config object to define how to convert DOM tree to Content Model
 * @param editorContext Context of editor
 */
export function createDomToModelContextWithConfig(config: DomToModelSettings, editorContext?: EditorContext): any;

/**
 * Create Dom to Content Model Config object
 * @param options All customizations of content model creation
 */
export function createDomToModelConfig(options: (DomToModelOption | undefined)[]): DomToModelSettings;

/**
 * Create context object fro Content Model to DOM conversion
 * @param editorContext Context of editor
 * @param options Option array to customize the Model to DOM conversion behavior
 */
export function createModelToDomContext(editorContext?: EditorContext, ...options: (ModelToDomOption | undefined)[]): ModelToDomContext;

/**
 * Create context object for Content Model to DOM conversion with an existing configure
 * @param config A full config object to define how to convert Content Model to DOM tree
 * @param editorContext Context of editor
 */
export function createModelToDomContextWithConfig(config: ModelToDomSettings, editorContext?: EditorContext): ModelToDomContext;

/**
 * Create Content Model to DOM Config object
 * @param options All customizations of DOM creation
 */
export function createModelToDomConfig(options: (ModelToDomOption | undefined)[]): ModelToDomSettings;

/**
 * Check if the given bold style represents a bold style
 * @param boldStyle The style to check
 */
export function isBold(boldStyle?: string): boolean;

/**
 * Get root node of a given DOM selection
 * For table selection, root node is the selected table
 * For image selection, root node is the selected image
 * For range selection, root node is the common ancestor container node of the selection range
 * @param selection The selection to get root node from
 */
export function getSelectionRootNode(selection: DOMSelection | undefined): Node | undefined;

/**
 * Get bounding rect of the given DOM insert point
 * @param doc The document object
 * @param pos The input DOM insert point
 */
export function getDOMInsertPointRect(doc: Document, pos: DOMInsertPoint): Rect | null;

/**
 * Returns true when the event was fired from a key that produces a character value, otherwise false
 * This detection is not 100% accurate. event.key is not fully supported by all browsers, and in some browsers (e.g. IE),
 * event.key is longer than 1 for num pad input. But here we just want to improve performance as much as possible.
 * So if we missed some case here it is still acceptable.
 * @param event The keyboard event object
 */
export function isCharacterValue(event: KeyboardEvent): boolean;

/**
 * Returns true when the event was fired from a modifier key, otherwise false
 * @param event The keyboard event object
 */
export function isModifierKey(event: KeyboardEvent): boolean;

/**
 * Returns true if the given event is a cursor moving event (Left, Right, Up, Down, Home, End, Page Up, Page Down).
 * This does not check modifier keys (Ctrl, Alt, Meta). So if there are modifier keys pressed, it can still return true if one of the modifier key is pressed
 * @param event The keyboard event to check
 */
export function isCursorMovingKey(event: KeyboardEvent): boolean;

/**
 * Combine border value array back to string
 * @param values Input string values
 * @param initialValue Initial value for those items without valid value
 */
export function combineBorderValue(value: Border): string;

/**
 * Extract an integrated border string with border width, style, color to value tuple
 * @param combinedBorder The integrated border style string
 * @returns An array with the splitted values
 */
export function extractBorderValues(combinedBorder?: string): Border;

/**
 * Check if the given character is punctuation
 * @param char The character to check
 */
export function isPunctuation(char: string): boolean;

/**
 * Check if the give character is a space. A space can be normal ASCII pace (32) or non-break space (160) or other kinds of spaces
 * such as ZeroWidthSpace, ...
 * @param char The character to check
 */
export function isSpace(char: string): boolean;

/**
 * Normalize spaces of the given string. After normalization, all leading (for forward) or trailing (for backward) spaces
 * will be replaces with non-break space (160)
 * @param txt The string to normalize
 * @param isForward Whether normalize forward or backward
 */
export function normalizeText(txt: string, isForward: boolean): string;

/**
 * Parse a table into a two dimensions array of TD elements. For those merged cells, the value will be null.
 * @param table Input HTML Table element
 * @returns Array of TD elements
 */
export function parseTableCells(table: HTMLTableElement): ParsedTable;

/**
 * Read a file object and invoke a callback function with the data url of this file
 * @param file The file to read
 * @param callback the callback to invoke with data url of the file.
 * If fail to read, dataUrl will be null
 */
export function readFile(file: File, callback: (dataUrl: string | null) => void): void;

/**
 * Edit and transform color of elements between light mode and dark mode
 * @param rootNode The root DOM node to transform
 * @param includeSelf True to transform the root node as well, otherwise false
 * @param direction To specify the transform direction, light to dark, or dark to light
 * @param darkColorHandler The dark color handler object to help do color transformation
 */
export function transformColor(rootNode: Node, includeSelf: boolean, direction: 'lightToDark' | 'darkToLight', darkColorHandler?: DarkColorHandler): void;

/**
 * Normalize font family string to a standard format
 * Add quotes around font family names that contain non-alphanumeric/dash characters
 * @param fontFamily The font family string to normalize
 * @returns The normalized font family string
 */
export function normalizeFontFamily(fontFamily: string): string;

/**
 * Extract clipboard items to be a ClipboardData object for IE
 * @param items The clipboard items retrieve from a DataTransfer object
 * @param allowedCustomPasteType Allowed custom content type when paste besides text/plain, text/html and images
    Only text types are supported, and do not add "text/" prefix to the type values
 */
export function extractClipboardItems(items: DataTransferItem[], allowedCustomPasteType?: string[]): Promise<ClipboardData>;

/**
 * Gets the cached event data by cache key from event object if there is already one.
 * Otherwise, call getter function to create one, and cache it.
 * @param event The event object
 * @param key Cache key string, need to be unique
 * @param getter Getter function to get the object when it is not in cache yet
 */
export function cacheGetEventData<T, E extends PluginEvent>(event: E, key: string, getter: (event: E) => T): T;

/**
 * Set paragraph marker to element. This is used to mark the end of a paragraph in a block element.
 */
export function setParagraphMarker(element: HTMLElement, marker: string): void;

/**
 * Get paragraph marker from element. This is used to mark the end of a paragraph in a block element.
 */
export function getParagraphMarker(element: HTMLElement): string | undefined;

/**
 * Set image state to element. This is used to store a image state.
 */
export function setImageState(element: HTMLElement, marker: string): void;

/**
 * Get image state from element. This is used to store a image state.
 */
export function getImageState(element: HTMLElement): string | undefined;

/**
 * Check if the given content model block or block group is of the expected block group type
 * @param input The object to check
 * @param type The expected type
 */
export function isBlockGroupOfType<T extends ContentModelBlockGroup>(input: ContentModelBlock | ContentModelBlockGroup | null | undefined, type: TypeOfBlockGroup<T>): input is T;

/**
 * Check if the given content model block or block group is of the expected block group type (Readonly)
 * @param input The object to check
 * @param type The expected type
 */
export function isBlockGroupOfType<T extends ReadonlyContentModelBlockGroup>(input: ReadonlyContentModelBlock | ReadonlyContentModelBlockGroup | null | undefined, type: TypeOfBlockGroup<T>): input is T;

/**
 * Iterate all selected elements in a given model
 * @param group The given Content Model to iterate selection from
 * @param callback The callback function to access the selected element
 * @param option Option to determine how to iterate
 */
export function iterateSelections(group: ContentModelBlockGroup, callback: IterateSelectionsCallback, option?: IterateSelectionsOption): void;

/**
 * Iterate all selected elements in a given model (Readonly)
 * @param group The given Content Model to iterate selection from
 * @param callback The callback function to access the selected element
 * @param option Option to determine how to iterate
 */
export function iterateSelections(group: ReadonlyContentModelBlockGroup, callback: ReadonlyIterateSelectionsCallback, option?: IterateSelectionsOption): void;

/**
 * Get the first selected list item from content model
 * @param model The Content Model to get selection from
 */
export function getFirstSelectedListItem(model: ContentModelDocument): ContentModelListItem | undefined;

/**
 * Get the first selected list item from content model (Readonly)
 * @param model The Content Model to get selection from
 */
export function getFirstSelectedListItem(model: ReadonlyContentModelDocument): ReadonlyContentModelListItem | undefined;

/**
 * Get the first selected table from content model
 * @param model The Content Model to get selection from
 */
export function getFirstSelectedTable(model: ContentModelDocument): [ContentModelTable | undefined, ContentModelBlockGroup[]];

/**
 * Get the first selected table from content model (Readonly)
 * @param model The Content Model to get selection from
 */
export function getFirstSelectedTable(model: ReadonlyContentModelDocument): [ReadonlyContentModelTable | undefined, ReadonlyContentModelBlockGroup[]];

/**
 * Get an array of block group - block pair that is of the expected block group type from selection
 * @param group The root block group to search
 * @param blockGroupTypes The expected block group types
 * @param stopTypes Block group types that will stop searching when hit
 * @param deepFirst True means search in deep first, otherwise wide first
 */
export function getOperationalBlocks<T extends ContentModelBlockGroup>(group: ContentModelBlockGroup, blockGroupTypes: TypeOfBlockGroup<T>[], stopTypes: ContentModelBlockGroupType[], deepFirst?: boolean): OperationalBlocks<T>[];

/**
 * Get an array of block group - block pair that is of the expected block group type from selection (Readonly)
 * @param group The root block group to search
 * @param blockGroupTypes The expected block group types
 * @param stopTypes Block group types that will stop searching when hit
 * @param deepFirst True means search in deep first, otherwise wide first
 */
export function getOperationalBlocks<T extends ReadonlyContentModelBlockGroup>(group: ReadonlyContentModelBlockGroup, blockGroupTypes: TypeOfBlockGroup<T>[], stopTypes: ContentModelBlockGroupType[], deepFirst?: boolean): ReadonlyOperationalBlocks<T>[];

/**
 * Get any array of selected paragraphs from a content model
 * @param model The Content Model to get selection from
 */
export function getSelectedParagraphs(model: ContentModelDocument): ContentModelParagraph[];

/**
 * Get any array of selected paragraphs from a content model, return mutable paragraphs
 * @param model The Content Model to get selection from
 * @param mutate Set to true to indicate we will mutate the selected paragraphs
 */
export function getSelectedParagraphs(model: ReadonlyContentModelDocument, mutate: true): ShallowMutableContentModelParagraph[];

/**
 * Get any array of selected paragraphs from a content model (Readonly)
 * @param model The Content Model to get selection from
 */
export function getSelectedParagraphs(model: ReadonlyContentModelDocument): ReadonlyContentModelParagraph[];

/**
 * Get an array of selected segments from a content model
 * @param model The Content Model to get selection from
 * @param includingFormatHolder True means also include format holder as segment from list item
 */
export function getSelectedSegments(model: ContentModelDocument, includingFormatHolder: boolean): ContentModelSegment[];

/**
 * Get an array of selected segments from a content model, return mutable segments
 * @param model The Content Model to get selection from
 * @param includingFormatHolder True means also include format holder as segment from list item
 * @param mutate Set to true to indicate we will mutate the selected paragraphs
 */
export function getSelectedSegments(model: ReadonlyContentModelDocument, includingFormatHolder: boolean, mutate: true): ShallowMutableContentModelSegment[];

/**
 * Get an array of selected segments from a content model (Readonly)
 * @param model The Content Model to get selection from
 * @param includingFormatHolder True means also include format holder as segment from list item
 */
export function getSelectedSegments(model: ReadonlyContentModelDocument, includingFormatHolder: boolean): ReadonlyContentModelSegment[];

/**
 * Get an array of selected parent paragraph and child segment pair
 * @param model The Content Model to get selection from
 * @param includingFormatHolder True means also include format holder as segment from list item, in that case paragraph will be null
 * @param includingEntity True to include entity in result as well
 */
export function getSelectedSegmentsAndParagraphs(model: ContentModelDocument, includingFormatHolder: boolean, includingEntity?: boolean): [ContentModelSegment, ContentModelParagraph | null, ContentModelBlockGroup[]][];

/**
 * Get an array of selected parent paragraph and child segment pair, return mutable paragraph and segments
 * @param model The Content Model to get selection from
 * @param includingFormatHolder True means also include format holder as segment from list item, in that case paragraph will be null
 * @param includingEntity True to include entity in result as well
 * @param mutate Set to true to indicate we will mutate the selected paragraphs
 */
export function getSelectedSegmentsAndParagraphs(model: ReadonlyContentModelDocument, includingFormatHolder: boolean, includingEntity: boolean, mutate: true): [
    ShallowMutableContentModelSegment,
    ContentModelParagraph | null,
    ReadonlyContentModelBlockGroup[]
][];

/**
 * Get an array of selected parent paragraph and child segment pair (Readonly)
 * @param model The Content Model to get selection from
 * @param includingFormatHolder True means also include format holder as segment from list item, in that case paragraph will be null
 * @param includingEntity True to include entity in result as well
 */
export function getSelectedSegmentsAndParagraphs(model: ReadonlyContentModelDocument, includingFormatHolder: boolean, includingEntity?: boolean): [
    ReadonlyContentModelSegment,
    ReadonlyContentModelParagraph | null,
    ReadonlyContentModelBlockGroup[]
][];

/**
 * Get selection coordinates of a table. If there is no selection, return null
 * @param table The table model to get selection from
 */
export function getSelectedCells(table: ReadonlyContentModelTable): TableSelectionCoordinates | null;

/**
 * Check if there is selection within the given block
 * @param block The block to check
 */
export function hasSelectionInBlock(block: ReadonlyContentModelBlock): boolean;

/**
 * Check if there is selection within the given segment
 * @param segment The segment to check
 */
export function hasSelectionInSegment(segment: ReadonlyContentModelSegment): boolean;

/**
 * Check if there is selection within the given block
 * @param block The block to check
 */
export function hasSelectionInBlockGroup(group: ReadonlyContentModelBlockGroup): boolean;

/**
 * Set selection into Content Model. If the Content Model already has selection, existing selection will be overwritten by the new one.
 * @param group The root level group of Content Model
 * @param start The start selected element. If not passed, existing selection of content model will be cleared
 * @param end The end selected element. If not passed, only the start element will be selected. If passed, all elements between start and end elements will be selected
 */
export function setSelection(group: ReadonlyContentModelBlockGroup, start?: ReadonlySelectable, end?: ReadonlySelectable): void;

/**
 * Clone a content model
 * @param model The content model to clone
 * @param options @optional Options to specify customize the clone behavior
 */
export function cloneModel(model: ReadonlyContentModelDocument, options?: CloneModelOptions): ContentModelDocument;

/**
 * Merge source model into target mode
 * @param target Target Content Model that will merge content into
 * @param source Source Content Model will be merged to target model
 * @param context Format context. When call this function inside formatContentModel, provide this context so that formatContentModel will do extra handling to the result
 * @param options More options, see MergeModelOption
 * @returns Insert point after merge, or null if there is no insert point
 */
export function mergeModel(target: ReadonlyContentModelDocument, source: ContentModelDocument, context?: FormatContentModelContext, options?: MergeModelOption): InsertPoint | null;

/**
 * Delete selected content from Content Model
 * @param model The model to delete selected content from
 * @param additionalSteps @optional Addition delete steps
 * @param formatContext @optional A context object provided by formatContentModel API
 * @returns A DeleteSelectionResult object to specify the deletion result
 */
export function deleteSelection(model: ReadonlyContentModelDocument, additionalSteps?: (DeleteSelectionStep | null)[], formatContext?: FormatContentModelContext): DeleteSelectionResult;

/**
 * Delete a content model segment from current selection
 * @param readonlyParagraph Parent paragraph of the segment to delete
 * @param readonlySegmentToDelete The segment to delete
 * @param context @optional Context object provided by formatContentModel API
 * @param direction @optional Whether this is deleting forward or backward. This is only used for deleting entity.
 * @param undeletableSegments @optional When passed, if this segment is undeletable, it will be added to this array instead of being deleted.
 * If not specified, only selected entity will be deleted
 */
export function deleteSegment(readonlyParagraph: ReadonlyContentModelParagraph, readonlySegmentToDelete: ReadonlyContentModelSegment, context?: FormatContentModelContext, direction?: 'forward' | 'backward', undeletableSegments?: ShallowMutableContentModelSegment[]): boolean;

/**
 * Delete a content model block from current selection
 * @param blocks Array of the block to delete
 * @param blockToDelete The block to delete
 * @param replacement @optional If specified, use this block to replace the deleted block
 * @param context @optional Context object provided by formatContentModel API
 * @param direction @optional Whether this is deleting forward or backward. This is only used for deleting entity.
 * If not specified, only selected entity will be deleted
 */
export function deleteBlock(blocks: ReadonlyContentModelBlock[], blockToDelete: ReadonlyContentModelBlock, replacement?: ReadonlyContentModelBlock, context?: FormatContentModelContext, direction?: 'forward' | 'backward'): boolean;

/**
 * Apply table format from table metadata and the passed in new format
 * @param table The table to apply format to
 * @param newFormat @optional New format to apply. When passed, this value will be merged into existing metadata format and default format
 * @param keepCellShade @optional When pass true, table cells with customized shade color will not be overwritten. @default false
 */
export function applyTableFormat(table: ReadonlyContentModelTable, newFormat?: TableMetadataFormat, keepCellShade?: boolean): void;

/**
 * Set the first column format borders for the table as well as header property
 * @param rows The rows of the table
 * @param format The table metadata format
 */
export function setFirstColumnFormatBorders(rows: ShallowMutableContentModelTableRow[], format: Partial<TableMetadataFormat>): void;

/**
 * Normalize a Content Model table, make sure:
 * 1. Fist cells are not spanned
 * 2. Only first column and row can have headers
 * 3. All cells have content and width
 * 4. Table and table row have correct width/height
 * 5. Spanned cell has no child blocks
 * 6. default format is correctly applied
 * @param readonlyTable The table to normalize
 * @param defaultSegmentFormat @optional Default segment format to apply to cell
 */
export function normalizeTable(readonlyTable: ReadonlyContentModelTable, defaultSegmentFormat?: ContentModelSegmentFormat): void;

/**
 * Minimum width for a table cell
 */
export const MIN_ALLOWED_TABLE_CELL_WIDTH: number;

/**
 * Minimum height for a table cell
 */
export const MIN_ALLOWED_TABLE_CELL_HEIGHT: number;

/**
 * Set shade color of table cell
 * @param cell The cell to set shade color to
 * @param color The color to set
 * @param isColorOverride @optional When pass true, it means this shade color is not part of table format, so it can be preserved when apply table format
 * @param applyToSegments @optional When pass true, we will also apply text color from table cell to its child blocks and segments
 */
export function setTableCellBackgroundColor(cell: ShallowMutableContentModelTableCell, color: string | null | undefined, isColorOverride?: boolean, applyToSegments?: boolean): void;

/**
 * Retrieve format state from the given Content Model
 * @param model The Content Model to retrieve format state from
 * @param pendingFormat Existing pending format, if any
 * @param formatState Existing format state object, used for receiving the result
 * @param conflictSolution The strategy for handling format conflicts
 */
export function retrieveModelFormatState(model: ReadonlyContentModelDocument, pendingFormat: ContentModelSegmentFormat | null, formatState: ContentModelFormatState, conflictSolution?: ConflictFormatSolution, domHelper?: DOMHelper): void;

/**
 * Gets the list style type that the bullet is part of, using the Constant record
 * @param listType whether the list is ordered or unordered
 * @param bullet bullet string
 * @returns the number of the style override or undefined if was not found in the Record
 */
export function getListStyleTypeFromString(listType: 'OL' | 'UL', bullet: string): number | undefined;

/**
 * Get the text format of a segment, this function will return only format that is applicable to text
 * @param segment The segment to get format from
 * @param includingBIU When pass true, also get Bold/Italic/Underline format
 * @returns
 */
export function getSegmentTextFormat(segment: ReadonlyContentModelSegment, includingBIU?: boolean): ContentModelSegmentFormat;

/**
 * Get index of closest ancestor block group of the expected block group type. If not found, return -1
 * @param path The block group path, from the closest one to root
 * @param blockGroupTypes The expected block group types
 * @param stopTypes @optional Block group types that will cause stop searching
 */
export function getClosestAncestorBlockGroupIndex<T extends ContentModelBlockGroup>(path: ReadonlyContentModelBlockGroup[], blockGroupTypes: TypeOfBlockGroup<T>[], stopTypes?: ContentModelBlockGroupType[]): number;

/**
 * Run editing steps on top of a given context object which includes current insert point and previous editing result
 * @param steps The editing steps to run
 * @param context Context for the editing steps.
 */
export function runEditSteps(steps: DeleteSelectionStep[], context: DeleteSelectionResult): void;

/**
 * Update image metadata with a callback
 * @param image The image Content Model
 * @param callback The callback function used for updating metadata
 */
export function updateImageMetadata(image: ContentModelImage, callback?: (format: ImageMetadataFormat | null) => ImageMetadataFormat | null): ImageMetadataFormat | null;

/**
 * Get image metadata
 * @param image The image Content Model
 */
export function getImageMetadata(image: ReadonlyContentModelImage): ImageMetadataFormat | null;

/**
 * Update table cell metadata with a callback
 * @param cell The table cell Content Model
 * @param callback The callback function used for updating metadata
 */
export function updateTableCellMetadata(cell: ShallowMutableContentModelTableCell, callback?: (format: TableCellMetadataFormat | null) => TableCellMetadataFormat | null): TableCellMetadataFormat | null;

/**
 * Get table cell metadata
 * @param cell The table cell Content Model
 */
export function getTableCellMetadata(cell: ReadonlyContentModelTableCell): TableCellMetadataFormat | null;

/**
 * Update table metadata with a callback
 * @param table The table Content Model
 * @param callback The callback function used for updating metadata
 */
export function updateTableMetadata(table: ShallowMutableContentModelTable, callback?: (format: TableMetadataFormat | null) => TableMetadataFormat | null): TableMetadataFormat | null;

/**
 * Get table metadata
 * @param table The table Content Model
 */
export function getTableMetadata(table: ReadonlyContentModelTable): TableMetadataFormat | null;

/**
 * Update list metadata with a callback
 * @param list The list Content Model (metadata holder)
 * @param callback The callback function used for updating metadata
 */
export function updateListMetadata(list: ShallowMutableContentModelWithDataset<ListMetadataFormat>, callback?: (format: ListMetadataFormat | null) => ListMetadataFormat | null): ListMetadataFormat | null;

/**
 * Get list metadata
 * @param list The list Content Model (metadata holder)
 */
export function getListMetadata(list: ReadonlyContentModelWithDataset<ListMetadataFormat>): ListMetadataFormat | null;

/**
 * Metadata definition for List
 */
export const ListMetadataDefinition: ObjectDefinition<ListMetadataFormat>;

/**
 * Possible change sources. Here are the predefined sources.
 * It can also be other string if the change source can't fall into these sources.
 */
export const ChangeSource: {
    /**
     * Content changed by auto link
     */
    AutoLink: string;
    /**
     * Content changed by create link
     */
    CreateLink: string;
    /**
     * Content changed by format
     */
    Format: string;
    /**
     * Content changed by image resize
     */
    ImageResize: string;
    /**
     * Content changed by paste
     */
    Paste: string;
    /**
     * Content changed by setContent API
     */
    SetContent: string;
    /**
     * Content changed by cut operation
     */
    Cut: string;
    /**
     * Content changed by drag & drop operation
     */
    Drop: string;
    /**
     * Insert a new entity into editor
     */
    InsertEntity: string;
    /**
     * Editor is switched to dark mode, content color is changed
     */
    SwitchToDarkMode: string;
    /**
     * Editor is switched to light mode, content color is changed
     */
    SwitchToLightMode: string;
    /**
     * List chain reorganized numbers of lists
     */
    ListChain: string;
    /**
     * Keyboard event, used by Content Model.
     * Data of this event will be the key code number
     */
    Keyboard: string;
    /**
     * Content changed by auto format
     */
    AutoFormat: string;
};

/**
 *  Enum used to control the different types of bullet list
 */
export const BulletListType: {
    /**
     * Minimum value of the enum
     */
    Min: number;
    /**
     * Bullet triggered by *
     */
    Disc: number;
    /**
     * Bullet triggered by -
     */
    Dash: number;
    /**
     * Bullet triggered by --
     */
    Square: number;
    /**
     * Bullet triggered by >
     */
    ShortArrow: number;
    /**
     * Bullet triggered by ->
     */
    LongArrow: number;
    /**
     * Bullet triggered by =>
     */
    UnfilledArrow: number;
    /**
     * Bullet triggered by —
     */
    Hyphen: number;
    /**
     * Bullet triggered by -->
     */
    DoubleLongArrow: number;
    /**
     * Bullet type circle
     */
    Circle: number;
    /**
     * Box Shadow bullet type
     */
    BoxShadow: number;
    /**
     * Rhombus with a cross inside
     */
    Xrhombus: number;
    /**
     * Check mark bullet type
     */
    CheckMark: number;
    /**
     * Maximum value of the enum
     */
    Max: number;
};

/**
 *  Enum used to control the different types of numbering list
 */
export const NumberingListType: {
    /**
     * Minimum value of the enum
     */
    Min: number;
    /**
     * Numbering triggered by 1.
     */
    Decimal: number;
    /**
     * Numbering triggered by 1-
     */
    DecimalDash: number;
    /**
     * Numbering triggered by 1)
     */
    DecimalParenthesis: number;
    /**
     * Numbering triggered by (1)
     */
    DecimalDoubleParenthesis: number;
    /**
     * Numbering triggered by a.
     */
    LowerAlpha: number;
    /**
     * Numbering triggered by a)
     */
    LowerAlphaParenthesis: number;
    /**
     * Numbering triggered by (a)
     */
    LowerAlphaDoubleParenthesis: number;
    /**
     * Numbering triggered by a-
     */
    LowerAlphaDash: number;
    /**
     * Numbering triggered by A.
     */
    UpperAlpha: number;
    /**
     * Numbering triggered by A)
     */
    UpperAlphaParenthesis: number;
    /**
     * Numbering triggered by (A)
     */
    UpperAlphaDoubleParenthesis: number;
    /**
     * Numbering triggered by A-
     */
    UpperAlphaDash: number;
    /**
     * Numbering triggered by i.
     */
    LowerRoman: number;
    /**
     * Numbering triggered by i)
     */
    LowerRomanParenthesis: number;
    /**
     * Numbering triggered by (i)
     */
    LowerRomanDoubleParenthesis: number;
    /**
     * Numbering triggered by i-
     */
    LowerRomanDash: number;
    /**
     * Numbering triggered by I.
     */
    UpperRoman: number;
    /**
     * Numbering triggered by I)
     */
    UpperRomanParenthesis: number;
    /**
     * Numbering triggered by (I)
     */
    UpperRomanDoubleParenthesis: number;
    /**
     * Numbering triggered by I-
     */
    UpperRomanDash: number;
    /**
     * Maximum value of the enum
     */
    Max: number;
};

/**
 * Table format border
 */
export const TableBorderFormat: {
    /**
     * Minimum value
     */
    Min: number;
    /**
     * All border of the table are displayed
     *  __ __ __
     * |__|__|__|
     * |__|__|__|
     * |__|__|__|
     */
    Default: number;
    /**
     * Middle vertical border are not displayed
     *  __ __ __
     * |__ __ __|
     * |__ __ __|
     * |__ __ __|
     */
    ListWithSideBorders: number;
    /**
     * All borders except header rows borders are displayed
     *  __ __ __
     *  __|__|__
     *  __|__|__
     */
    NoHeaderBorders: number;
    /**
     * The left and right border of the table are not displayed
     *  __ __ __
     *  __|__|__
     *  __|__|__
     *  __|__|__
     */
    NoSideBorders: number;
    /**
     * Only the borders that divides the header row, first column and externals are displayed
     *  __ __ __
     * |__ __ __|
     * |  |     |
     * |__|__ __|
     */
    FirstColumnHeaderExternal: number;
    /**
     * The header row has no vertical border, except for the first one
     * The first column has no horizontal border, except for the first one
     *  __ __ __
     * |__ __ __
     * |  |__|__|
     * |  |__|__|
     */
    EspecialType1: number;
    /**
     * The header row has no vertical border, except for the first one
     * The only horizontal border of the table is the top and bottom of header row
     *  __ __ __
     * |__ __ __
     * |  |     |
     * |  |     |
     */
    EspecialType2: number;
    /**
     * The only borders are the bottom of header row and the right border of first column
     *  __ __ __
     *    |
     *    |
     */
    EspecialType3: number;
    /**
     * No border
     */
    Clear: number;
    /**
     * Maximum value
     */
    Max: number;
};

/**
 * Style map for ordered list
 */
export const OrderedListStyleMap: Record<number, string>;

/**
 * Style map for unordered list
 */
export const UnorderedListStyleMap: Record<number, string>;

/**
 * Provide a default empty instance of segment format with all its properties
 */
export const EmptySegmentFormat: Readonly<Required<ContentModelSegmentFormat>>;

/**
 * The main editor class based on Content Model
 */
export class Editor implements IEditor  {
    private core;
    /**
     * Creates an instance of Editor
     * @param contentDiv The DIV HTML element which will be the container element of editor
     * @param options An optional options object to customize the editor
     */
    constructor(contentDiv: HTMLDivElement, options?: EditorOptions);
    /**
     * Dispose this editor, dispose all plugins and custom data
     */
    dispose(): void;
    /**
     * Get whether this editor is disposed
     * @returns True if editor is disposed, otherwise false
     */
    isDisposed(): boolean;
    /**
     * Create Content Model from DOM tree in this editor
     * @param mode What kind of Content Model we want. Currently we support the following values:
     * - disconnected: Returns a disconnected clone of Content Model from editor which you can do any change on it and it won't impact the editor content.
     * If there is any entity in editor, the returned object will contain cloned copy of entity wrapper element.
     * If editor is in dark mode, the cloned entity will be converted back to light mode.
     * - clean: Similar with disconnected, this will return a disconnected model, the difference is "clean" mode will not include any selection info.
     * This is usually used for exporting content
     */
    getContentModelCopy(mode: 'connected' | 'disconnected' | 'clean'): ContentModelDocument;
    /**
     * Get current running environment, such as if editor is running on Mac
     */
    getEnvironment(): EditorEnvironment;
    /**
     * Get current DOM selection
     */
    getDOMSelection(): DOMSelection | null;
    /**
     * Set DOMSelection into editor content.
     * @param selection The selection to set
     */
    setDOMSelection(selection: DOMSelection | null): void;
    /**
     * Set a new logical root (most likely due to focus change)
     * @param logicalRoot The new logical root (has to be child of physicalRoot)
     */
    setLogicalRoot(logicalRoot: HTMLDivElement): void;
    /**
     * The general API to do format change with Content Model
     * It will grab a Content Model for current editor content, and invoke a callback function
     * to do format change. Then according to the return value, write back the modified content model into editor.
     * If there is cached model, it will be used and updated.
     * @param formatter Formatter function, see ContentModelFormatter
     * @param options More options, see FormatContentModelOptions
     */
    formatContentModel(formatter: ContentModelFormatter, options?: FormatContentModelOptions, domToModelOptions?: DomToModelOptionForCreateModel): void;
    /**
     * Get pending format of editor if any, or return null
     */
    getPendingFormat(): ContentModelSegmentFormat | null;
    /**
     * Get a DOM Helper object to help access DOM tree in editor
     */
    getDOMHelper(): DOMHelper;
    /**
     * Add a single undo snapshot to undo stack
     * @param entityState @optional State for entity if we want to add entity state for this snapshot
     */
    takeSnapshot(entityState?: EntityState): Snapshot | null;
    /**
     * Restore an undo snapshot into editor
     * @param snapshot The snapshot to restore
     */
    restoreSnapshot(snapshot: Snapshot): void;
    /**
     * Get document which contains this editor
     * @returns The HTML document which contains this editor
     */
    getDocument(): Document;
    /**
     * Focus to this editor, the selection was restored to where it was before, no unexpected scroll.
     */
    focus(): void;
    /**
     * Check if focus is in editor now
     * @returns true if focus is in editor, otherwise false
     */
    hasFocus(): boolean;
    /**
     * Trigger an event to be dispatched to all plugins
     * @param eventType Type of the event
     * @param data data of the event with given type, this is the rest part of PluginEvent with the given type
     * @param broadcast indicates if the event needs to be dispatched to all plugins
     * True means to all, false means to allow exclusive handling from one plugin unless no one wants that
     * @returns the event object which is really passed into plugins. Some plugin may modify the event object so
     * the result of this function provides a chance to read the modified result
     */
    triggerEvent<T extends PluginEventType>(eventType: T, data: PluginEventData<T>, broadcast?: boolean): PluginEventFromType<T>;
    /**
     * Attach a DOM event to the editor content DIV
     * @param eventMap A map from event name to its handler
     */
    attachDomEvent(eventMap: Record<string, DOMEventRecord>): () => void;
    /**
     * Get undo snapshots manager
     */
    getSnapshotsManager(): SnapshotsManager;
    /**
     * Check if the editor is in dark mode
     * @returns True if the editor is in dark mode, otherwise false
     */
    isDarkMode(): boolean;
    /**
     * Set the dark mode state and transforms the content to match the new state.
     * @param isDarkMode The next status of dark mode. True if the editor should be in dark mode, false if not.
     */
    setDarkModeState(isDarkMode?: boolean): void;
    /**
     * Check if editor is in Shadow Edit mode
     */
    isInShadowEdit(): boolean;
    /**
     * Make the editor in "Shadow Edit" mode.
     * In Shadow Edit mode, all format change will finally be ignored.
     * This can be used for building a live preview feature for format button, to allow user
     * see format result without really apply it.
     * This function can be called repeated. If editor is already in shadow edit mode, we can still
     * use this function to do more shadow edit operation.
     */
    startShadowEdit(): void;
    /**
     * Leave "Shadow Edit" mode, all changes made during shadow edit will be discarded
     */
    stopShadowEdit(): void;
    /**
     * Get a color manager object for this editor.
     */
    getColorManager(): DarkColorHandler;
    /**
     * @deprecated
     * Get a function to convert HTML string to trusted HTML string.
     * By default it will just return the input HTML directly. To override this behavior,
     * pass your own trusted HTML handler to EditorOptions.trustedHTMLHandler
     * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types
     */
    getTrustedHTMLHandler(): LegacyTrustedHTMLHandler;
    /**
     * Get a function to convert HTML string to a trust Document.
     * By default it will just convert the original HTML string into a Document object directly.
     * To override, pass your own trusted HTML handler to EditorOptions.trustedHTMLHandler
     * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types
     */
    getDOMCreator(): DOMCreator;
    /**
     * Get the scroll container of the editor
     */
    getScrollContainer(): HTMLElement;
    /**
     * Retrieves the rect of the visible viewport of the editor.
     */
    getVisibleViewport(): Rect | null;
    /**
     * Add CSS rules for editor
     * @param key A string to identify the CSS rule type. When set CSS rules with the same key again, existing rules with the same key will be replaced.
     * @param cssRule The CSS rule string, must be a valid CSS rule string, or browser may throw exception. Pass null to clear existing rules
     * @param subSelectors @optional If the rule is used for child element under editor, use this parameter to specify the child elements. Each item will be
     * combined with root selector together to build a separate rule.
     */
    setEditorStyle(key: string, cssRule: string | null, subSelectors?: 'before' | 'after' | string[]): void;
    /**
     * Announce the given data
     * @param announceData Data to announce
     */
    announce(announceData: AnnounceData): void;
    /**
     * Check if a given feature is enabled
     * @param featureName The name of feature to check
     */
    isExperimentalFeatureEnabled(featureName: ExperimentalFeature | string): boolean;
    /**
     * @returns the current EditorCore object
     * @throws a standard Error if there's no core object
     */
    protected getCore(): EditorCore;
    private cloneOptionCallback;
}

/**
 * Create Content Model from HTML string
 * @param html The source HTML string
 * @param options Options for DOM to Content Model conversion
 * @param trustedHTMLHandler A string handler to convert string to trusted string
 * @returns A Content Model Document object that contains the Content Model from the give HTML, or undefined if failed to parse the source HTML
 */
export function createModelFromHtml(html: string, options?: Partial<DomToModelOptionForSanitizing>, trustedHTMLHandler?: TrustedHTMLHandler, defaultSegmentFormat?: ContentModelSegmentFormat): ContentModelDocument;

/**
 * Export HTML content. If there are entities, this will cause EntityOperation event with option = 'replaceTemporaryContent' to get a dehydrated entity
 * @param editor The editor to get content from
 * @param mode Specify HTML to get plain text result. This is the default option
 * @param options @optional Options for Model to DOM conversion
 */
export function exportContent(editor: IEditor, mode?: 'HTML', options?: ModelToDomOption): string;

/**
 * Export plain text content
 * @param editor The editor to get content from
 * @param mode Specify PlainText to get plain text result
 * @param callbacks @optional Callbacks to customize conversion behavior
 */
export function exportContent(editor: IEditor, mode: 'PlainText', callbacks?: ModelToTextCallbacks): string;

/**
 * Export plain text using editor's textContent property directly
 * @param editor The editor to get content from
 * @param mode Specify PlainTextFast to get plain text result using textContent property
 * @param options @optional Options for Model to DOM conversion
 */
export function exportContent(editor: IEditor, mode: 'PlainTextFast'): string;

/**
 * Undo to last undo snapshot
 * @param editor The editor to undo with
 */
export function undo(editor: IEditor): void;

/**
 * Redo to next undo snapshot
 * @param editor The editor to undo with
 */
export function redo(editor: IEditor): void;

/**
 * Paste into editor using a clipboardData object
 * @param editor The Editor object.
 * @param clipboardData Clipboard data retrieved from clipboard
 * @param pasteTypeOrGetter Type of content to paste or function that returns the Paste Type to use based on the document and the clipboard Data. @default normal
 */
export function paste(editor: IEditor, clipboardData: ClipboardData, pasteTypeOrGetter?: PasteTypeOrGetter): void;

/**
 * Insert table into editor at current selection
 * @param editor The editor instance
 * @param columns Number of columns in table, it also controls the default table cell width:
 * if columns &lt;= 4, width = 120px; if columns &lt;= 6, width = 100px; else width = 70px
 * @param rows Number of rows in table
 * @param format (Optional) The table format. If not passed, the default format will be applied:
 * background color: #FFF; border color: #ABABAB
 */
export function insertTable(editor: IEditor, columns: number, rows: number, format?: Partial<TableMetadataFormat>): void;

/**
 * Format current focused table with the given format
 * @param editor The editor instance
 * @param format The table format to apply
 * @param keepCellShade Whether keep existing shade color when apply format if there is a manually set shade color
 */
export function formatTable(editor: IEditor, format: TableMetadataFormat, keepCellShade?: boolean): void;

/**
 * Set table cell shade color
 * @param editor The editor instance
 * @param color The color to set. Pass null to remove existing shade color
 */
export function setTableCellShade(editor: IEditor, color: string | null): void;

/**
 * Format current focused table with the given format
 * @param editor The editor instance
 * @param operation The table operation to apply
 */
export function editTable(editor: IEditor, operation: TableOperation): void;

/**
 * Operations to apply border
 * @param editor The editor instance
 * @param border The border to apply
 * @param operation The operation to apply
 */
export function applyTableBorderFormat(editor: IEditor, border: Border, operation: BorderOperations): void;

/**
 * Toggle bullet list type
 * - When there are some blocks not in bullet list, set all blocks to the given type
 * - When all blocks are already in bullet list, turn off / outdent there list type
 * @param editor The editor to operate on
 * @param removeMargins true to remove margins, false to keep margins @default false
 */
export function toggleBullet(editor: IEditor, removeMargins?: boolean): void;

/**
 * Toggle numbering list type
 * - When there are some blocks not in numbering list, set all blocks to the given type
 * - When all blocks are already in numbering list, turn off / outdent there list type
 * @param editor The editor to operate on
 * @param removeMargins true to remove margins, false to keep margins @default false
 */
export function toggleNumbering(editor: IEditor, removeMargins?: boolean): void;

/**
 * Toggle bold style
 * @param editor The editor to operate on
 */
export function toggleBold(editor: IEditor): void;

/**
 * Toggle italic style
 * @param editor The editor to operate on
 */
export function toggleItalic(editor: IEditor): void;

/**
 * Toggle underline style
 * @param editor The editor to operate on
 */
export function toggleUnderline(editor: IEditor): void;

/**
 * Toggle strikethrough style
 * @param editor The editor to operate on
 */
export function toggleStrikethrough(editor: IEditor): void;

/**
 * Toggle subscript style
 * @param editor The editor to operate on
 */
export function toggleSubscript(editor: IEditor): void;

/**
 * Toggle superscript style
 * @param editor The editor to operate on
 */
export function toggleSuperscript(editor: IEditor): void;

/**
 * Set background color
 * @param editor The editor to operate on
 * @param backgroundColor The color to set. Pass null to remove existing color.
 */
export function setBackgroundColor(editor: IEditor, backgroundColor: string | null): void;

/**
 * Set font name
 * @param editor The editor to operate on
 * @param fontName The font name to set
 */
export function setFontName(editor: IEditor, fontName: string): void;

/**
 * Set font size
 * @param editor The editor to operate on
 * @param fontSize The font size to set
 */
export function setFontSize(editor: IEditor, fontSize: string): void;

/**
 * Set text color
 * @param editor The editor to operate on
 * @param textColor The text color to set. Pass null to remove existing color.
 */
export function setTextColor(editor: IEditor, textColor: string | null): void;

/**
 * Increase or decrease font size in selection
 * @param editor The editor instance
 * @param change Whether increase or decrease font size
 * @param fontSizes A sorted font size array, in pt. Default value is FONT_SIZES
 */
export function changeFontSize(editor: IEditor, change: 'increase' | 'decrease', fontSizes?: number[]): void;

/**
 * Bulk apply segment format to all selected content. This is usually used for format painter.
 * @param editor The editor to operate on
 * @param newFormat The segment format to apply
 */
export function applySegmentFormat(editor: IEditor, newFormat: Readonly<ContentModelSegmentFormat>): void;

/**
 * Change the capitalization of text in the selection
 * @param editor The editor instance
 * @param capitalization The case option
 * @param language Optional parameter for language string that should comply to "IETF BCP 47 Tags for
 * Identifying Languages". For example: 'en' or 'en-US' for English, 'tr' for Turkish.
 * Default is the host environment’s current locale.
 */
export function changeCapitalization(editor: IEditor, capitalization: 'sentence' | 'lowerCase' | 'upperCase' | 'capitalize', language?: string): void;

/**
 * Split given text segments from the given range
 * @param textSegment segment to split
 * @param parent parent paragraph the text segment exist in
 * @param start starting point of the split
 * @param end ending point of the split
 * @returns text segment from the indicated split.
 */
export function splitTextSegment(textSegment: ContentModelText, parent: ShallowMutableContentModelParagraph, start: number, end: number): ContentModelText;

/**
 * Insert an image into current selected position
 * @param editor The editor to operate on
 * @param file Image Blob file or source string
 */
export function insertImage(editor: IEditor, imageFileOrSrc: File | string): void;

/**
 * Set style of list items with in same thread of current item
 * @param editor The editor to operate on
 * @param style The target list item style to set
 */
export function setListStyle(editor: IEditor, style: ListMetadataFormat): void;

/**
 * Set start number of a list item
 * @param editor The editor to operate on
 * @param value The number to set to, must be equal or greater than 1
 */
export function setListStartNumber(editor: IEditor, value: number): void;

/**
 * Indent or outdent to selected paragraphs
 * @param editor The editor to operate on
 * @param indentation Whether indent or outdent
 * @param length The length of pixel to indent/outdent @default 40
 */
export function setIndentation(editor: IEditor, indentation: 'indent' | 'outdent', length?: number): void;

/**
 * Set text alignment of selected paragraphs
 * @param editor The editor to set alignment
 * @param alignment Alignment value: left, center or right
 */
export function setAlignment(editor: IEditor, alignment: 'left' | 'center' | 'right' | 'justify'): void;

/**
 * Set text direction of selected paragraphs (Left to right or Right to left)
 * @param editor The editor to set alignment
 * @param direction Direction value: ltr (Left to right) or rtl (Right to left)
 */
export function setDirection(editor: IEditor, direction: 'ltr' | 'rtl'): void;

/**
 * Set heading level of selected paragraphs
 * @param editor The editor to set heading level to
 * @param headingLevel Level of heading, from 1 to 6. Set to 0 means set it back to a regular paragraph
 */
export function setHeadingLevel(editor: IEditor, headingLevel: 0 | 1 | 2 | 3 | 4 | 5 | 6): void;

/**
 * Toggle BLOCKQUOTE state of selected paragraphs.
 * If any selected paragraph is not under a BLOCKQUOTE, wrap them into a BLOCKQUOTE.
 * Otherwise, unwrap all related BLOCKQUOTEs.
 * @param editor The editor object to toggle BLOCKQUOTE onto
 * @param quoteFormat @optional Block format for the new quote object
 */
export function toggleBlockQuote(editor: IEditor, quoteFormat?: ContentModelFormatContainerFormat, quoteFormatRtl?: ContentModelFormatContainerFormat): void;

/**
 * Sets current selected block(s) line-height property and wipes such property from child segments
 * @param editor The editor to operate on
 * @param spacing Unitless/px value to set line height
 */
export function setSpacing(editor: IEditor, spacing: number | string): void;

/**
 * Set image border style for all selected images at selection.
 * @param editor The editor instance
 * @param border the border format object. Ex: { color: 'red', width: '10px', style: 'solid'}, if one of the value in object is undefined
 * its value will not be changed. Passing null instead of an object will remove the border
 * @param borderRadius the border radius value, if undefined, the border radius will keep the actual value
 */
export function setImageBorder(editor: IEditor, border: Border | null, borderRadius?: string): void;

/**
 * Set image box shadow for all selected images at selection.
 * @param editor The editor instance
 * @param boxShadow The image box boxShadow
 * @param margin The image margin for all sides (eg. "4px"), null to remove margin
 */
export function setImageBoxShadow(editor: IEditor, boxShadow: string, margin?: string | null): void;

/**
 * Change the selected image src
 * @param editor The editor instance
 * @param file The image file
 */
export function changeImage(editor: IEditor, file: File): void;

/**
 * Get current format state
 * @param editor The editor to get format from
 * @param conflictSolution The strategy for handling format conflicts
 */
export function getFormatState(editor: IEditor, conflictSolution?: ConflictFormatSolution): ContentModelFormatState;

/**
 * Clear format of selection
 * @param editor The editor to clear format from
 */
export function clearFormat(editor: IEditor): void;

/**
 * Insert a hyperlink at cursor.
 * When there is a selection, hyperlink will be applied to the selection,
 * otherwise a hyperlink will be inserted to the cursor position.
 * @param editor Editor object
 * @param link Link address, can be http(s), mailto, notes, file, unc, ftp, news, telnet, gopher, wais.
 * When protocol is not specified, a best matched protocol will be predicted.
 * @param anchorTitle Optional alt text of the link, will be shown when hover on the link
 * @param displayText Optional display text for the link.
 * @param target Optional display target for the link ("_blank"|"_self"|"_parent"|"_top"|"{framename}")
 * If specified, the display text of link will be replaced with this text.
 * If not specified and there wasn't a link, the link url will be used as display text.
 */
export function insertLink(editor: IEditor, link: string, anchorTitle?: string, displayText?: string, target?: string): void;

/**
 * Remove link at selection. If no links at selection, do nothing.
 * If selection contains multiple links, all of the link styles will be removed.
 * If only part of a link is selected, the whole link style will be removed.
 * @param editor The editor instance
 */
export function removeLink(editor: IEditor): void;

/**
 * Adjust selection to make sure select a hyperlink if any, or a word if original selection is collapsed
 * @return A combination of existing link display text and url if any. If there is no existing link, return selected text and null
 */
export function adjustLinkSelection(editor: IEditor): [string, string | null];

/**
 * Set image alt text for all selected images at selection. If no images is contained
 * in selection, do nothing.
 * @param editor The editor instance
 * @param altText The image alt text
 */
export function setImageAltText(editor: IEditor, altText: string): void;

/**
 * Adjust selection to make sure select an image if any
 * @return Content Model Image object if an image is select, or null
 */
export function adjustImageSelection(editor: IEditor): ContentModelImage | null;

/**
 * Toggles the current block(s) margin properties.
 * null deletes any existing value, undefined is ignored
 * @param editor The editor to operate on
 * @param marginTop value for top margin
 * @param marginBottom value for bottom margin
 */
export function setParagraphMargin(editor: IEditor, marginTop?: string | null, marginBottom?: string | null): void;

/**
 * Toggle italic style
 * @param editor The editor to operate on
 */
export function toggleCode(editor: IEditor): void;

/**
 * Insert an entity into editor
 * @param editor The editor object
 * @param type Type of entity
 * @param isBlock True to insert a block entity, false to insert an inline entity
 * @param position Position of the entity to insert. It can be
 * Value of InsertEntityPosition: see InsertEntityPosition
 * selectionRangeEx: Use this range instead of current focus position to insert. After insert, focus will be moved to
 * the beginning of this range (when focusAfterEntity is not set to true) or after the new entity (when focusAfterEntity is set to true)
 * @param options Move options to insert. See InsertEntityOptions
 */
export function insertEntity(editor: IEditor, type: string, isBlock: boolean, position: 'focus' | 'begin' | 'end' | DOMInsertPoint, options?: InsertEntityOptions): ContentModelEntity | null;

/**
 * Insert a block entity into editor
 * @param editor The editor object
 * @param type Type of entity
 * @param isBlock Must be true for a block entity
 * @param position Position of the entity to insert. It can be
 * Value of InsertEntityPosition: see InsertEntityPosition
 * selectionRangeEx: Use this range instead of current focus position to insert. After insert, focus will be moved to
 * the beginning of this range (when focusAfterEntity is not set to true) or after the new entity (when focusAfterEntity is set to true)
 * @param options Move options to insert. See InsertEntityOptions
 */
export function insertEntity(editor: IEditor, type: string, isBlock: true, position: InsertEntityPosition | DOMInsertPoint, options?: InsertEntityOptions): ContentModelEntity | null;

/**
 * Insert a row to the table
 * @param table The table model where the row is to be inserted
 * @param operation The operation to be performed
 */
export function insertTableRow(table: ShallowMutableContentModelTable, operation: TableVerticalInsertOperation): void;

/**
 * Insert a column to the table
 * @param table The table model where the column is to be inserted
 * @param operation The operation to be performed
 */
export function insertTableColumn(table: ShallowMutableContentModelTable, operation: TableHorizontalInsertOperation): void;

/**
 * Clear selection of a table.
 * @param table The table model where the selection is to be cleared
 * @param sel The selection coordinates to be cleared
 */
export function clearSelectedCells(table: ReadonlyContentModelTable, sel: TableSelectionCoordinates): void;

/**
 * Create an EditorContext for an entity
 * @param editor The editor object
 * @param entity The entity to create the context for
 * @returns The generated EditorContext for the entity
 */
export function createEditorContextForEntity(editor: IEditor, entity: ContentModelEntity): EditorContext;

/**
 * Invoke a callback to format the selected table using Content Model
 * @param editor The editor object
 * @param apiName Name of API this calling this function. This is mostly for logging.
 * @param callback The callback to format the table. It will be called with current selected table. If no table is selected, it will not be called.
 * @param selectionOverride Override the current selection. If we want to format a table even currently it is not selected, we can use this parameter to override current selection
 */
export function formatTableWithContentModel(editor: IEditor, apiName: string, callback: (tableModel: ShallowMutableContentModelTable) => void, selectionOverride?: TableSelection): void;

/**
 * Invoke a callback to format the selected image using Content Model
 * @param editor The editor object
 * @param apiName Name of API this calling this function. This is mostly for logging.
 * @param callback The callback to format the image. It will be called with current selected table. If no table is selected, it will not be called.
 */
export function formatImageWithContentModel(editor: IEditor, apiName: string, callback: (segment: ContentModelImage) => void): void;

/**
 * Invoke a callback to format the selected paragraph using Content Model
 * @param editor The editor object
 * @param apiName Name of API this calling this function. This is mostly for logging.
 * @param setStyleCallback The callback to format the paragraph. It will be called with current selected table. If no table is selected, it will not be called.
 */
export function formatParagraphWithContentModel(editor: IEditor, apiName: string, setStyleCallback: (paragraph: ShallowMutableContentModelParagraph) => void): void;

/**
 * Invoke a callback to format the selected segment using Content Model
 * @param editor The editor object
 * @param apiName Name of API this calling this function. This is mostly for logging.
 * @param toggleStyleCallback The callback to format the segment. It will be called with current selected table. If no table is selected, it will not be called.
 * @param segmentHasStyleCallback The callback used for checking if the given segment already has required format
 * @param includingFormatHolder True to also include format holder of list item when search selected segments
 * @param afterFormatCallback A callback to invoke after format is applied to all selected segments and before the change is applied to DOM tree
 */
export function formatSegmentWithContentModel(editor: IEditor, apiName: string, toggleStyleCallback: (format: ContentModelSegmentFormat, isTuringOn: boolean, segment: ShallowMutableContentModelSegment | null, paragraph: ShallowMutableContentModelParagraph | null) => void, segmentHasStyleCallback?: (format: ContentModelSegmentFormat, segment: ShallowMutableContentModelSegment | null, paragraph: ShallowMutableContentModelParagraph | null) => boolean, includingFormatHolder?: boolean, afterFormatCallback?: (model: ReadonlyContentModelDocument) => void): void;

/**
 * Invoke a callback to format the text segment before the selection marker using Content Model
 * @param editor The editor object
 * @param callback The callback to format the text segment.
 * @returns True if the segment before cursor is found and callback is called, otherwise false
 */
export function formatTextSegmentBeforeSelectionMarker(editor: IEditor, callback: (model: ShallowMutableContentModelDocument, previousSegment: ContentModelText, paragraph: ShallowMutableContentModelParagraph, markerFormat: ContentModelSegmentFormat, context: FormatContentModelContext) => boolean, options?: FormatContentModelOptions): boolean;

/**
 * Invoke a callback to format the content in a specific position  using Content Model
 * @param editor The editor object
 * @param insertPoint The insert position.
 * @param callback The callback to insert the format.
 * @param options More options, @see FormatContentModelOptions
 */
export function formatInsertPointWithContentModel(editor: IEditor, insertPoint: DOMInsertPoint, callback: (model: ShallowMutableContentModelDocument, context: FormatContentModelContext, insertPoint?: InsertPoint) => void, options?: FormatContentModelOptions): void;

/**
 * Set a list type to content model
 * @param model the model document
 * @param listType the list type OL | UL
 * @param removeMargins true to remove margins, false to keep margins @default false
 */
export function setListType(model: ReadonlyContentModelDocument, listType: 'OL' | 'UL', removeMargins?: boolean): boolean;

/**
 * Set style of list items with in same thread of current item
 * @param model The model document
 * @param style The style to set
 */
export function setModelListStyle(model: ReadonlyContentModelDocument, style: ListMetadataFormat): boolean;

/**
 * Set start number of a list item
 * @param model The model document
 * @param value The number to set to, must be equal or greater than 1
 */
export function setModelListStartNumber(model: ReadonlyContentModelDocument, value: number): boolean;

/**
 * Search for all list items in the same thread as the current list item
 * @param model The content model
 * @param currentItem The current list item
 */
export function findListItemsInSameThread(group: ContentModelBlockGroup, currentItem: ContentModelListItem): ContentModelListItem[];

/**
 * Search for all list items in the same thread as the current list item (Readonly)
 * @param model The content model
 * @param currentItem The current list item
 */
export function findListItemsInSameThread(group: ReadonlyContentModelBlockGroup, currentItem: ReadonlyContentModelListItem): ReadonlyContentModelListItem[];

/**
 * @param model The content model to set indentation
 * @param indentation The indentation type, 'indent' to indent, 'outdent' to outdent
 * @param length The length of indentation in pixel, default value is 40
 * Set indentation for selected list items or paragraphs
 */
export function setModelIndentation(model: ReadonlyContentModelDocument, indentation: 'indent' | 'outdent', length?: number, context?: FormatContentModelContext): boolean;

/**
 * Try to match a given string with link match rules, return matched link
 * @param url Input url to match
 * @param option Link match option, exact or partial. If it is exact match, we need
 * to check the length of matched link and url
 * @param rules Optional link match rules, if not passed, only the default link match
 * rules will be applied
 * @returns The matched link data, or null if no match found.
 * The link data includes an original url and a normalized url
 */
export function matchLink(url: string): LinkData | null;

/**
 * Promote the given text segment to a hyper link when the segment text is ending with a valid link format.
 * When the whole text segment if of a link, promote the whole segment.
 * When the text segment ends with a link format, split the segment and promote the second part
 * When link is in middle of the text segment, no action.
 * This is mainly used for doing auto link when there is a link before cursor
 * @param segment The text segment to search link text from
 * @param paragraph Parent paragraph of the segment
 * @param options Options of auto link
 * @returns If a link is promoted, return this segment. Otherwise return null
 */
export function promoteLink(segment: ContentModelText, paragraph: ShallowMutableContentModelParagraph, autoLinkOptions: AutoLinkOptions): ContentModelText | null;

/**
 * Get announce data for list item
 * @param path Content model path that include the list item
 * @returns Announce data of current list item if any, or null
 */
export function getListAnnounceData(path: ReadonlyContentModelBlockGroup[]): AnnounceData | null;

/**
 * Query content model blocks
 * @param group The block group to query
 * @param type The type of block to query
 * @param filter Optional selector to filter the blocks
 * @param findFirstOnly True to return the first block only, false to return all blocks
 * @param shouldExpandEntity Optional function to determine if an entity's children should be recursively queried, should return a EditorContext if the entity should be expanded, or null if not
 */
export function queryContentModelBlocks<T extends ReadonlyContentModelBlock>(group: ReadonlyContentModelBlockGroup, type: T extends ReadonlyContentModelBlockBase<infer U> ? U : never, filter?: (element: T) => element is T, findFirstOnly?: boolean, shouldExpandEntity?: (entity: ContentModelEntity) => EditorContext | null): T[];

/**
 * TableEdit plugin, provides the ability to resize a table by drag-and-drop
 */
export class TableEditPlugin implements EditorPlugin  {
    private anchorContainerSelector?;
    private onTableEditorCreated?;
    private disableFeatures?;
    private tableSelector;
    private editor;
    private onMouseMoveDisposer;
    private tableRectMap;
    private tableEditor;
    /**
     * Construct a new instance of TableResize plugin
     * @param anchorContainerSelector An optional selector string to specify the container to host the plugin.
     * The container must not be affected by transform: scale(), otherwise the position calculation will be wrong.
     * If not specified, the plugin will be inserted in document.body
     * @param onTableEditorCreated An optional callback to customize the Table Editors elements when created.
     * @param disableFeatures An optional array of TableEditFeatures to disable
     * @param tableSelector A function to select the tables to be edited. By default, it selects all contentEditable tables.
     */
    constructor(anchorContainerSelector?: string | undefined, onTableEditorCreated?: OnTableEditorCreatedCallback | undefined, disableFeatures?: TableEditFeatureName[] | undefined, tableSelector?: (domHelper: DOMHelper) => TableWithRoot[]);
    /**
     * Get a friendly name of this plugin
     */
    getName(): string;
    /**
     * Initialize this plugin. This should only be called from Editor
     * @param editor Editor instance
     */
    initialize(editor: IEditor): void;
    private onMouseOut;
    /**
     * Dispose this plugin
     */
    dispose(): void;
    /**
     * Handle events triggered from editor
     * @param event PluginEvent object
     */
    onPluginEvent(e: PluginEvent): void;
    private onMouseMove;
    /**
     * @internal Public only for unit test
     * @param entry Table to use when setting the Editors
     * @param event (Optional) Mouse event
     */
    setTableEditor(entry: TableWithRoot | null, event?: MouseEvent): void;
    private invalidateTableRects;
    private disposeTableEditor;
    private ensureTableRects;
}

/**
 * Optional callback when creating a TableEditPlugin, allows to customize the Selectors element as required.
 */
export type OnTableEditorCreatedCallback = (featureType: TableEditFeatureName, element: HTMLElement) => () => void;

/**
 * Names of table edit features
 */
export type TableEditFeatureName = 'HorizontalTableInserter' | 'VerticalTableInserter' | 'TableMover' | 'TableResizer' | 'TableSelector' | 'CellResizer';

/**
 * Represents a table and its container (logical root)
 */
export interface TableWithRoot {
    /**
     * The table element
     */
    table: HTMLTableElement;
    /**
     * The logical root element of the table
     * This is the element that contains the table and all its ancestors
     * It is used to determine the logical root of the table
     */
    logicalRoot: HTMLDivElement | null;
}

/**
 * Paste plugin, handles BeforePaste event and reformat some special content, including:
 * 1. Content copied from Word
 * 2. Content copied from Excel
 * 3. Content copied from Word Online or OneNote Online
 * 4. Content copied from Power Point
 */
export class PastePlugin implements EditorPlugin  {
    private allowExcelNoBorderTable?;
    private domToModelForSanitizing;
    private editor;
    /**
     * Construct a new instance of Paste class
     * @param unknownTagReplacement Replace solution of unknown tags, default behavior is to replace with SPAN
     * @param allowExcelNoBorderTable Allow table copied from Excel without border
     */
    constructor(allowExcelNoBorderTable?: boolean | undefined, domToModelForSanitizing?: Pick<DomToModelOptionForSanitizing, 'additionalAllowedTags' | 'additionalDisallowedTags' | 'styleSanitizers' | 'attributeSanitizers'>);
    /**
     * Get name of this plugin
     */
    getName(): string;
    /**
     * The first method that editor will call to a plugin when editor is initializing.
     * It will pass in the editor instance, plugin should take this chance to save the
     * editor reference so that it can call to any editor method or format API later.
     * @param editor The editor object
     */
    initialize(editor: IEditor): void;
    /**
     * The last method that editor will call to a plugin before it is disposed.
     * Plugin can take this chance to clear the reference to editor. After this method is
     * called, plugin should not call to any editor method since it will result in error.
     */
    dispose(): void;
    /**
     * Core method for a plugin. Once an event happens in editor, editor will call this
     * method of each plugin to handle the event as long as the event is not handled
     * exclusively by another plugin.
     * @param event The event to handle:
     */
    onPluginEvent(event: PluginEvent): void;
    private setEventSanitizers;
}

/**
 * Default style sanitizers for PastePlugin.
 */
export const DefaultSanitizers: Record<string, ValueSanitizer>;

/**
 * Edit plugins helps editor to do editing operation on top of content model.
 * This includes:
 * 1. Delete Key
 * 2. Backspace Key
 * 3. Tab Key
 */
export class EditPlugin implements EditorPlugin  {
    private options;
    private editor;
    private disposer;
    private shouldHandleNextInputEvent;
    private selectionAfterDelete;
    private handleNormalEnter;
    /**
     * @param options An optional parameter that takes in an object of type EditOptions, which includes the following properties:
     * handleTabKey: A boolean that enables or disables Tab key handling. Defaults to true.
     */
    constructor(options?: EditOptions);
    private createNormalEnterChecker;
    private getHandleNormalEnter;
    /**
     * Get name of this plugin
     */
    getName(): string;
    /**
     * The first method that editor will call to a plugin when editor is initializing.
     * It will pass in the editor instance, plugin should take this chance to save the
     * editor reference so that it can call to any editor method or format API later.
     * @param editor The editor object
     */
    initialize(editor: IEditor): void;
    /**
     * The last method that editor will call to a plugin before it is disposed.
     * Plugin can take this chance to clear the reference to editor. After this method is
     * called, plugin should not call to any editor method since it will result in error.
     */
    dispose(): void;
    /**
     * Core method for a plugin. Once an event happens in editor, editor will call this
     * method of each plugin to handle the event as long as the event is not handled
     * exclusively by another plugin.
     * @param event The event to handle:
     */
    onPluginEvent(event: PluginEvent): void;
    /**
     * Check if the plugin should handle the given event exclusively.
     * Handle an event exclusively means other plugin will not receive this event in
     * onPluginEvent method.
     * If two plugins will return true in willHandleEventExclusively() for the same event,
     * the final result depends on the order of the plugins are added into editor
     * @param event The event to check:
     */
    willHandleEventExclusively(event: PluginEvent): boolean;
    private handleKeyDownEvent;
    private handleBeforeInputEvent;
}

/**
 * Options to customize the keyboard handling behavior of Edit plugin
 */
export type EditOptions = {
    /**
     * Whether to handle Tab key in keyboard. @default true
     */
    handleTabKey?: boolean;
    /**
     * Whether expanded selection within a text node should be handled by CM when pressing Backspace/Delete key.
     * @default true
     */
    handleExpandedSelectionOnDelete?: boolean;
    /**
     * Callback function to determine whether the Rooster should handle the Enter key press.
     * If the function returns true, the Rooster will handle the Enter key press instead of the browser.
     * @param editor - The editor instance.
     * @returns A boolean
     */
    shouldHandleEnterKey?: ((editor: IEditor) => boolean) | boolean;
};

/**
 * Auto Format plugin handles auto formatting, such as transforming * characters into a bullet list.
 * It can be customized with options to enable or disable auto list features.
 */
export class AutoFormatPlugin implements EditorPlugin  {
    private options;
    private editor;
    /**
     * @param options An optional parameter that takes in an object of type AutoFormatOptions, which includes the following properties:
     *  - autoBullet: A boolean that enables or disables automatic bullet list formatting. Defaults to false.
     *  - autoNumbering: A boolean that enables or disables automatic numbering formatting. Defaults to false.
     *  - removeListMargins: A boolean to remove list margins when it is automatically triggered. Defaults to false.
     *  - autoHyphen: A boolean that enables or disables automatic hyphen transformation. Defaults to false.
     *  - autoFraction: A boolean that enables or disables automatic fraction transformation. Defaults to false.
     *  - autoOrdinals: A boolean that enables or disables automatic ordinal number transformation. Defaults to false.
     *  - autoLink: A boolean that enables or disables automatic hyperlink url address creation when pasting or typing content. Defaults to false.
     *  - autoUnlink: A boolean that enables or disables automatic hyperlink removal when pressing backspace. Defaults to false.
     *  - autoTel: A boolean that enables or disables automatic hyperlink telephone numbers transformation. Defaults to false.
     *  - autoMailto: A boolean that enables or disables automatic hyperlink email address transformation. Defaults to false.
     *  - autoHorizontalLine: A boolean that enables or disables automatic horizontal line creation. Defaults to false.
     */
    constructor(options?: AutoFormatOptions);
    /**
     * Get name of this plugin
     */
    getName(): string;
    /**
     * The first method that editor will call to a plugin when editor is initializing.
     * It will pass in the editor instance, plugin should take this chance to save the
     * editor reference so that it can call to any editor method or format API later.
     * @param editor The editor object
     */
    initialize(editor: IEditor): void;
    /**
     * The last method that editor will call to a plugin before it is disposed.
     * Plugin can take this chance to clear the reference to editor. After this method is
     * called, plugin should not call to any editor method since it will result in error.
     */
    dispose(): void;
    /**
     * Core method for a plugin. Once an event happens in editor, editor will call this
     * method of each plugin to handle the event as long as the event is not handled
     * exclusively by another plugin.
     * @param event The event to handle:
     */
    onPluginEvent(event: PluginEvent): void;
    private autoLink;
    private tabFeatures;
    private features;
    private enterFeatures;
    private handleKeyboardEvents;
    private handleEditorInputEvent;
    private handleKeyDownEvent;
    private handleContentChangedEvent;
}

/**
 * Options to customize the Content Model Auto Format Plugin
 */
export interface AutoFormatOptions extends AutoLinkOptions  {
    /**
     * When true, after type *, ->, -, --, => , —, > and space key a type of bullet list will be triggered.
     */
    autoBullet?: boolean;
    /**
     * When true, after type 1, A, a, i, I followed by ., ), - or between () and space key a type of numbering list will be triggered.
     */
    autoNumbering?: boolean;
    /**
     * Transform -- into hyphen, if typed between two words
     */
    autoHyphen?: boolean;
    /**
     * Transform 1/2, 1/4, 3/4 into fraction character
     */
    autoFraction?: boolean;
    /**
     * Transform ordinal numbers into superscript
     */
    autoOrdinals?: boolean;
    /**
     * Remove the margins of auto triggered list
     */
    removeListMargins?: boolean;
    /**
     * Auto Horizontal line
     */
    autoHorizontalLine?: boolean;
}

/**
 * Shortcut command for Bold
 * Windows: Ctrl + B
 * MacOS: Meta + B
 */
export const ShortcutBold: ShortcutCommand;

/**
 * Shortcut command for Italic
 * Windows: Ctrl + I
 * MacOS: Meta + I
 */
export const ShortcutItalic: ShortcutCommand;

/**
 * Shortcut command for Underline
 * Windows: Ctrl + U
 * MacOS: Meta + U
 */
export const ShortcutUnderline: ShortcutCommand;

/**
 * Shortcut command for Clear Format
 * Windows: Ctrl + Space
 * MacOS: Meta + Space, this shortcut is the same as the default global spotlight shortcut, so it is invalid if the user keeps spotlight‘s.
 */
export const ShortcutClearFormat: ShortcutCommand;

/**
 * Shortcut command for Undo 1
 * Windows: Ctrl + Z
 * MacOS: Meta + Z
 */
export const ShortcutUndo: ShortcutCommand;

/**
 * Shortcut command for Undo 2
 * Windows: Alt + Backspace
 * MacOS: N/A
 */
export const ShortcutUndo2: ShortcutCommand;

/**
 * Shortcut command for Redo 1
 * Windows: Ctrl + Y
 * MacOS: N/A
 */
export const ShortcutRedo: ShortcutCommand;

/**
 * Shortcut command for Redo 3
 * Windows: Ctrl + Shift + Z
 * MacOS: Meta + Shift + Z
 */
export const ShortcutRedoAlt: ShortcutCommand;

/**
 * @deprecated
 * Shortcut command for Redo 2
 * Windows: N/A
 * MacOS: Meta + Shift + Z
 */
export const ShortcutRedoMacOS: ShortcutCommand;

/**
 * Shortcut command for Bullet List
 * Windows: Ctrl + . (Period)
 * MacOS: Meta + . (Period)
 */
export const ShortcutBullet: ShortcutCommand;

/**
 * Shortcut command for Numbering List
 * Windows: Ctrl + / (Forward slash)
 * MacOS: Meta + / (Forward slash)
 */
export const ShortcutNumbering: ShortcutCommand;

/**
 * Shortcut command for Increase Font
 * Windows: Ctrl + Shift + . (Period)
 * MacOS: Meta + Shift + . (Period)
 */
export const ShortcutIncreaseFont: ShortcutCommand;

/**
 * Shortcut command for Decrease Font
 * Windows: Ctrl + Shift + , (Comma)
 * MacOS: Meta + Shift + , (Comma)
 */
export const ShortcutDecreaseFont: ShortcutCommand;

/**
 * Shortcut command for Intent list
 * Windows: Alt + Shift + Arrow Right
 * MacOS: N/A
 */
export const ShortcutIndentList: ShortcutCommand;

/**
 * Shortcut command for Outdent list
 * Windows: Alt + Shift + Arrow Left
 * MacOS: N/A
 */
export const ShortcutOutdentList: ShortcutCommand;

/**
 * Shortcut plugin hook on the specified shortcut keys and trigger related format API
 */
export class ShortcutPlugin implements EditorPlugin  {
    private shortcuts;
    private editor;
    private isMac;
    /**
     * Create a new instance of ShortcutPlugin
     * @param [shortcuts=defaultShortcuts] Allowed commands
     */
    constructor(shortcuts?: ShortcutCommand[]);
    /**
     * Get name of this plugin
     */
    getName(): string;
    /**
     * The first method that editor will call to a plugin when editor is initializing.
     * It will pass in the editor instance, plugin should take this chance to save the
     * editor reference so that it can call to any editor method or format API later.
     * @param editor The editor object
     */
    initialize(editor: IEditor): void;
    /**
     * The last method that editor will call to a plugin before it is disposed.
     * Plugin can take this chance to clear the reference to editor. After this method is
     * called, plugin should not call to any editor method since it will result in error.
     */
    dispose(): void;
    /**
     * Check if the plugin should handle the given event exclusively.
     * Handle an event exclusively means other plugin will not receive this event in
     * onPluginEvent method.
     * If two plugins will return true in willHandleEventExclusively() for the same event,
     * the final result depends on the order of the plugins are added into editor
     * @param event The event to check:
     */
    willHandleEventExclusively(event: PluginEvent): boolean;
    /**
     * Core method for a plugin. Once an event happens in editor, editor will call this
     * method of each plugin to handle the event as long as the event is not handled
     * exclusively by another plugin.
     * @param event The event to handle:
     */
    onPluginEvent(event: PluginEvent): void;
    private cacheGetCommand;
    private matchOS;
    private matchShortcut;
}

/**
 * Definition of the shortcut key
 */
export interface ShortcutKeyDefinition {
    /**
     * Modifier key for this shortcut, allowed values are:
     * ctrl: Ctrl key (or Meta key on MacOS)
     * alt: Alt key
     */
    modifierKey: 'ctrl' | 'alt';
    /**
     * Whether ALT key is required for this shortcut
     */
    shiftKey: boolean;
    /**
     * Key code for this shortcut. The value should be the value of KeyboardEvent.which
     * We are still using key code here rather than key name (event.key)  although event.which is deprecated because of globalization.
     * For example, on US keyboard, Shift+Comma="<" but on Spanish keyboard it is ":"
     * And we still want the shortcut key to be registered on  the same key, in that case key name is different but key code keeps the same.
     */
    which: number;
}

/**
 * Represents a command for shortcut
 */
export interface ShortcutCommand {
    /**
     * Definition of the shortcut key
     */
    shortcutKey: ShortcutKeyDefinition;
    /**
     * @optional Required environment for this command
     * all: (Default) This feature is available for all environments
     * mac: This feature is available on MacOS only
     * nonMac: This feature is available on OS other than MacOS
     */
    environment?: 'all' | 'mac' | 'nonMac';
    /**
     * The callback function to invoke when this shortcut is triggered
     * @param editor The editor object
     */
    onClick: (editor: IEditor) => void;
}

/**
 * An editor plugin that support showing a context menu using render() function from options parameter
 */
export class ContextMenuPluginBase<T> implements EditorPlugin  {
    private options;
    private container;
    private editor;
    private isMenuShowing;
    /**
     * Create a new instance of ContextMenu class
     * @param options An options object to determine how to show/hide the context menu
     */
    constructor(options: ContextMenuOptions<T>);
    /**
     * Get a friendly name of  this plugin
     */
    getName(): string;
    /**
     * Initialize this plugin
     * @param editor The editor instance
     */
    initialize(editor: IEditor): void;
    /**
     * Dispose this plugin
     */
    dispose(): void;
    /**
     * Handle events triggered from editor
     * @param event PluginEvent object
     */
    onPluginEvent(event: PluginEvent): void;
    private initContainer;
    private onDismiss;
}

/**
 * Context Menu options for ContextMenu plugin
 */
export interface ContextMenuOptions<T> {
    /**
     * Render function for the context menu
     * @param container The container HTML element, it will be located at the mouse click position,
     * so the callback just need to render menu content into this container
     * @param onDismiss The onDismiss callback, some menu render need to know this callback so that
     * it can handle the dismiss event
     */
    render: (container: HTMLElement, items: (T | null)[], onDismiss: () => void) => void;
    /**
     * Dismiss function for the context menu, it will be called when user wants to dismiss this context menu
     * e.g. user click away so the menu should be dismissed
     * @param container The container HTML element
     */
    dismiss?: (container: HTMLElement) => void;
    /**
     * Whether the default context menu is allowed. @default false
     */
    allowDefaultMenu?: boolean;
}

/**
 * A watermark plugin to manage watermark string for roosterjs
 */
export class WatermarkPlugin implements EditorPlugin  {
    protected watermark: string;
    private editor;
    private format;
    private isShowing;
    private darkTextColor;
    private disposer;
    /**
     * Create an instance of Watermark plugin
     * @param watermark The watermark string
     */
    constructor(watermark: string, format?: WatermarkFormat);
    /**
     * Get a friendly name of  this plugin
     */
    getName(): string;
    /**
     * Initialize this plugin. This should only be called from Editor
     * @param editor Editor instance
     */
    initialize(editor: IEditor): void;
    /**
     * Dispose this plugin
     */
    dispose(): void;
    /**
     * Handle events triggered from editor
     * @param event PluginEvent object
     */
    onPluginEvent(event: PluginEvent): void;
    private onCompositionStart;
    private update;
    private showHide;
    protected show(editor: IEditor): void;
    private applyWatermarkStyle;
    protected hide(editor: IEditor): void;
}

/**
 * Format type of watermark text
 */
export type WatermarkFormat = FontFamilyFormat & FontSizeFormat & TextColorFormat;

/**
 * A fast way to check if content model is empty
 */
export function isModelEmptyFast(model: ReadonlyContentModelBlockGroup): boolean;

/**
 * Markdown plugin handles markdown formatting, such as transforming * characters into bold text.
 */
export class MarkdownPlugin implements EditorPlugin  {
    private options;
    private editor;
    private shouldBold;
    private shouldItalic;
    private shouldStrikethrough;
    private shouldCode;
    private lastKeyTyped;
    /**
     * @param options An optional parameter that takes in an object of type MarkdownOptions, which includes the following properties:
     *  - strikethrough: If true text between ~ will receive strikethrough format. Defaults to false.
     *  - bold: If true text between * will receive bold format. Defaults to false.
     *  - italic: If true text between _ will receive italic format. Defaults to false.
     *  - codeFormat: If provided, text between ` will receive code format. Defaults to undefined.
     */
    constructor(options?: MarkdownOptions);
    /**
     * Get name of this plugin
     */
    getName(): string;
    /**
     * The first method that editor will call to a plugin when editor is initializing.
     * It will pass in the editor instance, plugin should take this chance to save the
     * editor reference so that it can call to any editor method or format API later.
     * @param editor The editor object
     */
    initialize(editor: IEditor): void;
    /**
     * The last method that editor will call to a plugin before it is disposed.
     * Plugin can take this chance to clear the reference to editor. After this method is
     * called, plugin should not call to any editor method since it will result in error.
     */
    dispose(): void;
    /**
     * Core method for a plugin. Once an event happens in editor, editor will call this
     * method of each plugin to handle the event as long as the event is not handled
     * exclusively by another plugin.
     * @param event The event to handle:
     */
    onPluginEvent(event: PluginEvent): void;
    private handleEditorInputEvent;
    private handleKeyDownEvent;
    private handleBackspaceEvent;
    private handleContentChangedEvent;
    private disableAllFeatures;
}

/**
 *
 * Options for Markdown plugin
 *  - strikethrough: If true text between ~ will receive strikethrough format.
 *  - bold: If true text between * will receive bold format.
 *  - italic: If true text between _ will receive italic format.
 *  - codeFormat: If provided, text between ` will receive code format. If equal to {}, it will set the default code format.
 */
export interface MarkdownOptions {
    strikethrough?: boolean;
    bold?: boolean;
    italic?: boolean;
    codeFormat?: ContentModelCodeFormat;
}

/**
 * Hyperlink plugin does the following jobs for a hyperlink in editor:
 * 1. When hover on a link, show a tool tip
 * 2. When Ctrl+Click on a link, open a new window with the link
 * 3. When type directly on a link whose text matches its link url, update the link url with the link text
 */
export class HyperlinkPlugin implements EditorPlugin  {
    private tooltip;
    private target?;
    private onLinkClick?;
    private editor;
    private domHelper;
    private isMac;
    private disposer;
    private currentNode;
    private currentLink;
    /**
     * Create a new instance of HyperLink class
     * @param tooltip Tooltip to show when mouse hover over a link
     * Default value is to return the href itself. If null, there will be no tooltip text.
     * @param target (Optional) Target window name for hyperlink. If null, will use "_blank"
     * @param onLinkClick (Optional) Open link callback (return false to use default behavior)
     */
    constructor(tooltip?: HyperlinkToolTip, target?: string | undefined, onLinkClick?: ((anchor: HTMLAnchorElement, mouseEvent: MouseEvent) => boolean | void) | undefined);
    /**
     * Get a friendly name of this plugin
     */
    getName(): string;
    /**
     * Initialize this plugin
     * @param editor The editor instance
     */
    initialize(editor: IEditor): void;
    /**
     * Dispose this plugin
     */
    dispose(): void;
    /**
     * Handle events triggered from editor
     * @param event PluginEvent object
     */
    onPluginEvent(event: PluginEvent): void;
    protected onMouse: (e: Event) => void;
    private runWithHyperlink;
    private isCtrlOrMetaPressed;
}

/**
 * A type to specify how to get a tool tip of hyperlink in editor
 * string: Use this string as tooltip
 * null: No tooltip
 * function: Call this function to get a tooltip
 */
export type HyperlinkToolTip = string | null | ((url: string, anchor: HTMLAnchorElement) => string);

/**
 * PickerPlugin represents a plugin of editor which can handle picker related behaviors, including
 * - Show picker when special trigger key is pressed
 * - Hide picker
 * - Change selection in picker by Up/Down/Left/Right
 * - Apply selected item in picker
 *
 * PickerPlugin doesn't provide any UI, it just wraps related DOM events and invoke callback functions.
 */
export class PickerPlugin implements EditorPlugin  {
    private triggerCharacter;
    private readonly handler;
    private isMac;
    private lastQueryString;
    private helper;
    /**
     * Construct a new instance of PickerPlugin class
     * @param triggerCharacter The character to trigger a picker to be shown
     * @param handler Picker handler for receiving picker state change events
     */
    constructor(triggerCharacter: string, handler: PickerHandler);
    /**
     * Get a friendly name
     */
    getName(): string;
    /**
     * Initialize this plugin. This should only be called from Editor
     * @param editor Editor instance
     */
    initialize(editor: IEditor): void;
    /**
     * Dispose this plugin
     */
    dispose(): void;
    /**
     * Check if the plugin should handle the given event exclusively.
     * Handle an event exclusively means other plugin will not receive this event in
     * onPluginEvent method.
     * If two plugins will return true in willHandleEventExclusively() for the same event,
     * the final result depends on the order of the plugins are added into editor
     * @param event The event to check
     */
    willHandleEventExclusively(event: PluginEvent): boolean;
    /**
     * Handle events triggered from editor
     * @param event PluginEvent object
     */
    onPluginEvent(event: PluginEvent): void;
    private onSuggestingKeyDown;
    private onSuggestingInput;
    private onInput;
}

/**
 * Represents the interface of picker plugin, provides necessary utility functions for pickers
 */
export interface PickerHelper {
    /**
     * The editor instance
     */
    readonly editor: IEditor;
    /**
     * Replace the query string with a given Content Model.
     * This is used for commit a change from picker and insert the committed content into editor.
     * @param model The Content Model to insert
     * @param options Options for formatting content model
     * @param canUndoByBackspace Whether this change can be undone using Backspace key
     */
    replaceQueryString: (model: ContentModelDocument, options?: FormatContentModelOptions, canUndoByBackspace?: boolean) => void;
    /**
     * Notify Picker Plugin that picker is closed from the handler code, so picker plugin can quit the suggesting state
     */
    closePicker: () => void;
}

/**
 * Change mode that PickerPlugin will pass to child class
 */
export type PickerSelectionChangMode = /**
 * When user press Right ("horizontal" mode or "both" mode) (Left in RTL) or Down ("vertical" mode),
 * select the next option
 */
'next'
/**
 * When user press Left ("horizontal" mode or "both" mode) (Right in RTL) or Up ("vertical" mode),
 * select the previous option
 */
 | 'previous'
/**
 * When user press Down ("both" mode),
 * select the next row
 */
 | 'nextRow'
/**
 * When user press Up ("both" mode),
 * select the previous row
 */
 | 'previousRow'
/**
 * When user press PageDown,
 * switch to next page
 */
 | 'nextPage'
/**
 * When user press PageUp,
 * switch to previous page
 */
 | 'previousPage'
/**
 * When user press Home,
 * Select the first item in current row
 */
 | 'firstInRow'
/**
 * When user press End,
 * Select the last item in current row
 */
 | 'lastInRow'
/**
 * When user press CTRL (or META on Mac) + Home,
 * Select the very first item
 */
 | 'first'
/**
 * When user press CTRL (or META on Mac) + End,
 * Select the very last item
 */
 | 'last';

/**
 * Direction option for picker
 */
export type PickerDirection = /**
 * Show options horizontally
 */
'horizontal'
/**
 * Show options vertically
 */
 | 'vertical'
/**
 * Show options in both direction (2-D picker)
 */
 | 'both';

/**
 * Represents the interface a handler for picker plugin. Developer need to implement this interface to create a new type of picker
 */
export interface PickerHandler {
    /**
     * Initialize the picker handler, pass in editor and PickerPlugin instance so that the handler can save them
     * @param editor The editor instance
     * @param pickerPlugin The PickerPlugin instance
     */
    onInitialize: (helper: PickerHelper) => void;
    /**
     * Dispose the picker handler
     */
    onDispose: () => void;
    /**
     * Notify the picker handler that user has typed trigger character so handler should show picker now
     * @param queryString Current query string
     * @param insertPoint Insert point where user is typing, can be used for calculating picker position
     * @returns A picker direction to let picker plugin know what kind of picker is opened. Picker plugin will use this value
     * to decide how to handle keyboard event to change selection. Return null means picker is not actually opened
     */
    onTrigger: (queryString: string, insertPoint: DOMInsertPoint) => PickerDirection | null;
    /**
     * Notify the picker handler that picker should be closed now
     */
    onClosePicker?(): void;
    /**
     * Notify the picker handler that user has changed current typed query string
     */
    onQueryStringChanged?(queryString: string): void;
    /**
     * Notify the picker handler that user has decide to select the current option in picker
     */
    onSelect?(): void;
    /**
     * Notify the picker handler that user is using keyboard to change current selection
     * @param mode The moving mode. Handler code can use this value to decide which item need to be selected
     */
    onSelectionChanged?(mode: PickerSelectionChangMode): void;
}

/**
 * CustomReplacePlugin is a plugin that allows you to replace a string with another string in the editor.
 */
export class CustomReplacePlugin implements EditorPlugin  {
    private customReplacements;
    private editor;
    private triggerKeys;
    /**
     * @param customReplacements Custom replacement rules.
     * Ex: [{ stringToReplace: ':)', replacementString: '🙂', replacementHandler: replaceEmojis }]
     */
    constructor(customReplacements: CustomReplace[]);
    /**
     * Get name of this plugin
     */
    getName(): string;
    /**
     * The first method that editor will call to a plugin when editor is initializing.
     * It will pass in the editor instance, plugin should take this chance to save the
     * editor reference so that it can call to any editor method or format API later.
     * @param editor The editor object
     */
    initialize(editor: IEditor): void;
    /**
     * The last method that editor will call to a plugin before it is disposed.
     * Plugin can take this chance to clear the reference to editor. After this method is
     * called, plugin should not call to any editor method since it will result in error.
     */
    dispose(): void;
    /**
     * Core method for a plugin. Once an event happens in editor, editor will call this
     * method of each plugin to handle the event as long as the event is not handled
     * exclusively by another plugin.
     * @param event The event to handle:
     */
    onPluginEvent(event: PluginEvent): void;
    private handleEditorInputEvent;
}

/**
 * The CustomReplace interface defines a custom replacement that can be used in CustomReplacePlugin.
 */
export interface CustomReplace {
    /**
     * The string to replace in the editor.
     */
    stringToReplace: string;
    /**
     * The string to replace with.
     */
    replacementString: string;
    /**
     * The handler to replace the string.
     * @param previousSegment The text segment to replace.
     * @param stringToReplace The string to replace.
     * @param replacementString The string to replace with.
     * @param paragraph The paragraph that contains the text segment.
     * @returns True if the string is replaced successfully, otherwise false.
     */
    replacementHandler: (previousSegment: ContentModelText, stringToReplace: string, replacementString: string, paragraph?: ShallowMutableContentModelParagraph) => boolean;
}

/**
 * ImageEdit plugin handles the following image editing features:
 * - Resize image
 * - Crop image
 * - Rotate image
 * - Flip image
 */
export class ImageEditPlugin implements ImageEditor, EditorPlugin  {
    protected options: ImageEditOptions;
    protected editor: IEditor | null;
    private shadowSpan;
    private selectedImage;
    protected wrapper: HTMLSpanElement | null;
    protected imageEditInfo: ImageMetadataFormat | null;
    private imageHTMLOptions;
    private dndHelpers;
    private clonedImage;
    private lastSrc;
    private wasImageResized;
    private isCropMode;
    private resizers;
    private rotators;
    private croppers;
    private zoomScale;
    private disposer;
    protected isEditing: boolean;
    constructor(options?: ImageEditOptions);
    /**
     * Get name of this plugin
     */
    getName(): string;
    /**
     * The first method that editor will call to a plugin when editor is initializing.
     * It will pass in the editor instance, plugin should take this chance to save the
     * editor reference so that it can call to any editor method or format API later.
     * @param editor The editor object
     */
    initialize(editor: IEditor): void;
    /**
     * The last method that editor will call to a plugin before it is disposed.
     * Plugin can take this chance to clear the reference to editor. After this method is
     * called, plugin should not call to any editor method since it will result in error.
     */
    dispose(): void;
    /**
     * Core method for a plugin. Once an event happens in editor, editor will call this
     * method of each plugin to handle the event as long as the event is not handled
     * exclusively by another plugin.
     * @param event The event to handle:
     */
    onPluginEvent(event: PluginEvent): void;
    private handleBeforeLogicalRootChange;
    private removeImageEditing;
    private isImageSelection;
    private mouseUpHandler;
    private mouseDownHandler;
    private onDropHandler;
    private keyDownHandler;
    private setContentHandler;
    private formatEventHandler;
    private contentChangedHandler;
    /**
     * EXPOSED FOR TESTING PURPOSE ONLY
     */
    protected applyFormatWithContentModel(editor: IEditor, isCropMode: boolean, shouldSelectImage: boolean, isApiOperation?: boolean): void;
    private startEditing;
    startRotateAndResize(editor: IEditor, image: HTMLImageElement): void;
    private updateRotateHandleState;
    isOperationAllowed(operation: ImageEditOperation): boolean;
    canRegenerateImage(image: HTMLImageElement): boolean;
    private startCropMode;
    cropImage(): void;
    private editImage;
    /**
     * Exported for testing purpose only
     */
    cleanInfo(): void;
    private removeImageWrapper;
    flipImage(direction: 'horizontal' | 'vertical'): void;
    rotateImage(angleRad: number): void;
}

/**
 * Options for customize ImageEdit plugin
 */
export interface ImageEditOptions {
    /**
     * Color of resize/rotate border, handle and icon
     * @default #DB626C
     */
    borderColor?: string;
    /**
     * Minimum resize/crop width
     * @default 10
     */
    minWidth?: number;
    /**
     * Minimum resize/crop height
     * @default 10
     */
    minHeight?: number;
    /**
     * Whether preserve width/height ratio when resize
     * Pressing SHIFT key when resize will for preserve ratio even this value is set to false
     * @default false
     */
    preserveRatio?: boolean;
    /**
     * Minimum degree increase/decrease when rotate image.
     * Pressing SHIFT key when rotate will ignore this value and rotate by any degree with mouse moving
     * @default 5
     */
    minRotateDeg?: number;
    /**
     * Selector of the image that allows editing
     * @default img
     */
    imageSelector?: string;
    /**
     * Whether side resizing (single direction resizing) is disabled. @default false
     */
    disableSideResize?: boolean;
    /**
     * Whether image rotate is disabled. @default false
     */
    disableRotate?: boolean;
    /**
     * Whether image crop is disabled. @default false
     */
    disableCrop?: boolean;
    /**
     * Which operations will be executed when image is selected
     * @default resizeAndRotate
     */
    onSelectState?: ImageEditOperation[];
}

/**
 * HiddenPropertyPlugin helps editor to maintain hidden properties in DOM after editor content is reset using HTML
 */
export class HiddenPropertyPlugin implements EditorPlugin  {
    private option;
    private editor;
    /**
     * Construct a new instance of FormatPlugin class
     * @param option The editor option
     */
    constructor(option: HiddenPropertyOptions);
    /**
     * Get name of this plugin
     */
    getName(): string;
    /**
     * The first method that editor will call to a plugin when editor is initializing.
     * It will pass in the editor instance, plugin should take this chance to save the
     * editor reference so that it can call to any editor method or format API later.
     * @param editor The editor object
     */
    initialize(editor: IEditor): void;
    /**
     * The last method that editor will call to a plugin before it is disposed.
     * Plugin can take this chance to clear the reference to editor. After this method is
     * called, plugin should not call to any editor method since it will result in error.
     */
    dispose(): void;
    /**
     * Core method for a plugin. Once an event happens in editor, editor will call this
     * method of each plugin to handle the event as long as the event is not handled
     * exclusively by another plugin.
     * @param event The event to handle:
     */
    onPluginEvent(event: PluginEvent): void;
}

/**
 * Options for HiddenProperty plugin
 */
export interface HiddenPropertyOptions {
    /**
     * A helper function to check if a link should be undeletable or not.
     * @param link The link to check
     * @returns True if the link should be undeletable, false otherwise
     */
    undeletableLinkChecker?: (link: HTMLAnchorElement) => boolean;
}

/**
 * Get dark mode color for a given color
 * @param color The color to calculate from
 * @param baseLValue The Light value for base dark color in LAB format. @default the Light value for #333333
 */
export function getDarkColor(color: string, baseLValue?: number): string;

/**
 * Convert the whole content to ContentModel with the given plain text
 * @param editor The editor instance
 * @param text The markdown text
 * @param splitLinesPattern The pattern to split lines. Default is /\r\n|\r|\\n|\n/
 * @returns The ContentModelDocument
 */
export function convertMarkdownToContentModel(text: string, splitLinesPattern?: string): ContentModelDocument;

/**
 * Export content model document to markdown
 * @param selection The editor selection
 * @param newLine The new line string to use. Default is '\n\n'
 * @returns The markdown string
 */
export function convertContentModelToMarkdown(model: ContentModelDocument, newLine?: MarkdownLineBreaks): string;

/**
 * The characters to add line breaks and new lines
 */
export interface MarkdownLineBreaks {
    newLine: string;
    lineBreak: string;
}

