diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setAlignment.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setAlignment.ts index 332ce3d0a53..fadbcc769a4 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setAlignment.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setAlignment.ts @@ -11,5 +11,7 @@ export default function setAlignment( editor: IContentModelEditor, alignment: 'left' | 'center' | 'right' ) { + editor.focus(); + formatWithContentModel(editor, 'setAlignment', model => setModelAlignment(model, alignment)); } diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setDirection.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setDirection.ts index 6e68c92d2d5..83804c4dabe 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setDirection.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setDirection.ts @@ -8,5 +8,7 @@ import type { IContentModelEditor } from '../../publicTypes/IContentModelEditor' * @param direction Direction value: ltr (Left to right) or rtl (Right to left) */ export default function setDirection(editor: IContentModelEditor, direction: 'ltr' | 'rtl') { + editor.focus(); + formatWithContentModel(editor, 'setDirection', model => setModelDirection(model, direction)); } diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setHeadingLevel.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setHeadingLevel.ts index baef24b5e46..0a172bb41d1 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setHeadingLevel.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setHeadingLevel.ts @@ -22,6 +22,8 @@ export default function setHeadingLevel( editor: IContentModelEditor, headingLevel: 0 | 1 | 2 | 3 | 4 | 5 | 6 ) { + editor.focus(); + formatParagraphWithContentModel(editor, 'setHeadingLevel', para => { const tagName = headingLevel > 0 diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setIndentation.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setIndentation.ts index 02b2f932f67..6c01898cec3 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setIndentation.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setIndentation.ts @@ -14,6 +14,8 @@ export default function setIndentation( indentation: 'indent' | 'outdent', length?: number ) { + editor.focus(); + formatWithContentModel( editor, 'setIndentation', diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setParagraphMargin.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setParagraphMargin.ts index 637282ca2e2..903f8cae4e9 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setParagraphMargin.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setParagraphMargin.ts @@ -14,6 +14,8 @@ export default function setParagraphMargin( marginTop?: string | null, marginBottom?: string | null ) { + editor.focus(); + formatParagraphWithContentModel(editor, 'setParagraphMargin', para => { if (!para.decorator) { para.decorator = createParagraphDecorator('p'); diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setSpacing.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setSpacing.ts index 9a9b8da2180..f5c36d46448 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setSpacing.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/setSpacing.ts @@ -7,6 +7,8 @@ import type { IContentModelEditor } from '../../publicTypes/IContentModelEditor' * @param spacing Unitless/px value to set line height */ export default function setSpacing(editor: IContentModelEditor, spacing: number | string) { + editor.focus(); + formatParagraphWithContentModel(editor, 'setSpacing', paragraph => { paragraph.format.lineHeight = spacing.toString(); paragraph.segments.forEach(segment => { diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/toggleBlockQuote.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/toggleBlockQuote.ts index 95823d3fbb9..d3f4a69c6ef 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/toggleBlockQuote.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/block/toggleBlockQuote.ts @@ -31,6 +31,8 @@ export default function toggleBlockQuote( ...quoteFormat, }; + editor.focus(); + formatWithContentModel( editor, 'toggleBlockQuote', diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/format/clearFormat.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/format/clearFormat.ts index 678f489785f..285ba03b6b7 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/format/clearFormat.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/format/clearFormat.ts @@ -14,6 +14,8 @@ import type { * @param editor The editor to clear format from */ export default function clearFormat(editor: IContentModelEditor) { + editor.focus(); + formatWithContentModel(editor, 'clearFormat', model => { const blocksToClear: [ContentModelBlockGroup[], ContentModelBlock][] = []; const segmentsToClear: ContentModelSegment[] = []; diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/changeImage.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/changeImage.ts index 128c81256f5..b87c7db6cc8 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/changeImage.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/changeImage.ts @@ -9,6 +9,8 @@ import type { IContentModelEditor } from '../../publicTypes/IContentModelEditor' * @param file The image file */ export default function changeImage(editor: IContentModelEditor, file: File) { + editor.focus(); + const selection = editor.getDOMSelection(); readFile(file, dataUrl => { if (dataUrl && !editor.isDisposed() && selection?.type === 'image') { diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/insertImage.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/insertImage.ts index ffe02709b98..32d60e9b203 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/insertImage.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/insertImage.ts @@ -10,6 +10,8 @@ import type { IContentModelEditor } from '../../publicTypes/IContentModelEditor' * @param file Image Blob file or source string */ export default function insertImage(editor: IContentModelEditor, imageFileOrSrc: File | string) { + editor.focus(); + if (typeof imageFileOrSrc == 'string') { insertImageWithSrc(editor, imageFileOrSrc); } else { diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/setImageAltText.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/setImageAltText.ts index 269b56e4e9a..fc40ca1c4ad 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/setImageAltText.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/setImageAltText.ts @@ -9,6 +9,8 @@ import type { IContentModelEditor } from '../../publicTypes/IContentModelEditor' * @param altText The image alt text */ export default function setImageAltText(editor: IContentModelEditor, altText: string) { + editor.focus(); + formatImageWithContentModel(editor, 'setImageAltText', (image: ContentModelImage) => { image.alt = altText; }); diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/setImageBorder.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/setImageBorder.ts index 15272982828..9774b47a1e6 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/setImageBorder.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/setImageBorder.ts @@ -16,6 +16,8 @@ export default function setImageBorder( border: Border | null, borderRadius?: string ) { + editor.focus(); + formatImageWithContentModel(editor, 'setImageBorder', (image: ContentModelImage) => { applyImageBorderFormat(image, border, borderRadius); }); diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/setImageBoxShadow.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/setImageBoxShadow.ts index 53390f1fcb3..014221dce4c 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/setImageBoxShadow.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/image/setImageBoxShadow.ts @@ -13,6 +13,8 @@ export default function setImageBoxShadow( boxShadow: string, margin?: string | null ) { + editor.focus(); + formatImageWithContentModel(editor, 'setImageBoxShadow', (image: ContentModelImage) => { image.format.boxShadow = boxShadow; if (margin) { diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/link/insertLink.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/link/insertLink.ts index 57efb07ab2c..c88f826ac07 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/link/insertLink.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/link/insertLink.ts @@ -40,6 +40,8 @@ export default function insertLink( displayText?: string, target?: string ) { + editor.focus(); + let url = (checkXss(link) || '').trim(); if (url) { const linkData = matchLink(url); diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/link/removeLink.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/link/removeLink.ts index 94d75d64525..45684396f2f 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/link/removeLink.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/link/removeLink.ts @@ -10,6 +10,8 @@ import type { IContentModelEditor } from '../../publicTypes/IContentModelEditor' * @param editor The editor instance */ export default function removeLink(editor: IContentModelEditor) { + editor.focus(); + formatWithContentModel(editor, 'removeLink', model => { adjustSegmentSelection( model, diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/list/setListStartNumber.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/list/setListStartNumber.ts index 5185b94e5f4..a1ebe108070 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/list/setListStartNumber.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/list/setListStartNumber.ts @@ -8,6 +8,8 @@ import type { IContentModelEditor } from '../../publicTypes/IContentModelEditor' * @param value The number to set to, must be equal or greater than 1 */ export default function setListStartNumber(editor: IContentModelEditor, value: number) { + editor.focus(); + formatWithContentModel(editor, 'setListStartNumber', model => { const listItem = getFirstSelectedListItem(model); const level = listItem?.levels[listItem?.levels.length - 1]; diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/list/setListStyle.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/list/setListStyle.ts index 67df9e93c68..5d08bc38cc2 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/list/setListStyle.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/list/setListStyle.ts @@ -11,6 +11,8 @@ import type { ListMetadataFormat } from 'roosterjs-content-model-types'; * @param style The target list item style to set */ export default function setListStyle(editor: IContentModelEditor, style: ListMetadataFormat) { + editor.focus(); + formatWithContentModel(editor, 'setListStyle', model => { const listItem = getFirstSelectedListItem(model); diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/list/toggleBullet.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/list/toggleBullet.ts index fc45af59a6e..379ede04394 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/list/toggleBullet.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/list/toggleBullet.ts @@ -9,6 +9,8 @@ import type { IContentModelEditor } from '../../publicTypes/IContentModelEditor' * @param editor The editor to operate on */ export default function toggleBullet(editor: IContentModelEditor) { + editor.focus(); + formatWithContentModel(editor, 'toggleBullet', model => setListType(model, 'UL'), { preservePendingFormat: true, }); diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/list/toggleNumbering.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/list/toggleNumbering.ts index 702cb981b55..7400d3d0c0b 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/list/toggleNumbering.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/list/toggleNumbering.ts @@ -9,6 +9,8 @@ import type { IContentModelEditor } from '../../publicTypes/IContentModelEditor' * @param editor The editor to operate on */ export default function toggleNumbering(editor: IContentModelEditor) { + editor.focus(); + formatWithContentModel(editor, 'toggleNumbering', model => setListType(model, 'OL'), { preservePendingFormat: true, }); diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/changeCapitalization.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/changeCapitalization.ts index 3dbae752bcb..e0f11220813 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/changeCapitalization.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/changeCapitalization.ts @@ -14,6 +14,8 @@ export default function changeCapitalization( capitalization: 'sentence' | 'lowerCase' | 'upperCase' | 'capitalize', language?: string ) { + editor.focus(); + formatSegmentWithContentModel(editor, 'changeCapitalization', (_, __, segment) => { if (segment?.segmentType == 'Text') { switch (capitalization) { diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/changeFontSize.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/changeFontSize.ts index 140f1834dfd..f37953262ce 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/changeFontSize.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/changeFontSize.ts @@ -25,6 +25,8 @@ export default function changeFontSize( editor: IContentModelEditor, change: 'increase' | 'decrease' ) { + editor.focus(); + formatSegmentWithContentModel( editor, 'changeFontSize', diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setBackgroundColor.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setBackgroundColor.ts index 829f78d4bd4..3f8e769b69d 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setBackgroundColor.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setBackgroundColor.ts @@ -13,6 +13,8 @@ export default function setBackgroundColor( editor: IContentModelEditor, backgroundColor: string | null ) { + editor.focus(); + let lastParagraph: ContentModelParagraph | null = null; let lastSegmentIndex: number = -1; diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setFontName.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setFontName.ts index e45c9c1ebcc..64b8014f39f 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setFontName.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setFontName.ts @@ -7,6 +7,8 @@ import type { IContentModelEditor } from '../../publicTypes/IContentModelEditor' * @param fontName The font name to set */ export default function setFontName(editor: IContentModelEditor, fontName: string) { + editor.focus(); + formatSegmentWithContentModel( editor, 'setFontName', diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setFontSize.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setFontSize.ts index 39983909842..e958825158f 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setFontSize.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setFontSize.ts @@ -11,6 +11,8 @@ import type { IContentModelEditor } from '../../publicTypes/IContentModelEditor' * @param fontSize The font size to set */ export default function setFontSize(editor: IContentModelEditor, fontSize: string) { + editor.focus(); + formatSegmentWithContentModel( editor, 'setFontSize', diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setTextColor.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setTextColor.ts index 14b8938eea6..60d51fcaae3 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setTextColor.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/setTextColor.ts @@ -7,6 +7,8 @@ import type { IContentModelEditor } from '../../publicTypes/IContentModelEditor' * @param textColor The text color to set. Pass null to remove existing color. */ export default function setTextColor(editor: IContentModelEditor, textColor: string | null) { + editor.focus(); + formatSegmentWithContentModel( editor, 'setTextColor', diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleBold.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleBold.ts index f111e136bec..f31e6a73981 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleBold.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleBold.ts @@ -6,6 +6,8 @@ import type { IContentModelEditor } from '../../publicTypes/IContentModelEditor' * @param editor The editor to operate on */ export default function toggleBold(editor: IContentModelEditor) { + editor.focus(); + formatSegmentWithContentModel( editor, 'toggleBold', diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleCode.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleCode.ts index cc2bb6d6701..05a9d49f62f 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleCode.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleCode.ts @@ -14,6 +14,8 @@ const DefaultCode: ContentModelCode = { * @param editor The editor to operate on */ export default function toggleCode(editor: IContentModelEditor) { + editor.focus(); + formatSegmentWithContentModel( editor, 'toggleCode', diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleItalic.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleItalic.ts index 4ba96bfd407..70a8d718153 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleItalic.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleItalic.ts @@ -6,6 +6,8 @@ import type { IContentModelEditor } from '../../publicTypes/IContentModelEditor' * @param editor The editor to operate on */ export default function toggleItalic(editor: IContentModelEditor) { + editor.focus(); + formatSegmentWithContentModel( editor, 'toggleItalic', diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleStrikethrough.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleStrikethrough.ts index b7ab20b7f18..075eb2ebefa 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleStrikethrough.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleStrikethrough.ts @@ -6,6 +6,8 @@ import type { IContentModelEditor } from '../../publicTypes/IContentModelEditor' * @param editor The editor to operate on */ export default function toggleStrikethrough(editor: IContentModelEditor) { + editor.focus(); + formatSegmentWithContentModel( editor, 'toggleStrikethrough', diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleSubscript.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleSubscript.ts index 2e788b91946..8e1d177a21d 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleSubscript.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleSubscript.ts @@ -6,6 +6,8 @@ import type { IContentModelEditor } from '../../publicTypes/IContentModelEditor' * @param editor The editor to operate on */ export default function toggleSubscript(editor: IContentModelEditor) { + editor.focus(); + formatSegmentWithContentModel( editor, 'toggleSubscript', diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleSuperscript.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleSuperscript.ts index 3c7dd0d19f0..716838ae7da 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleSuperscript.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleSuperscript.ts @@ -6,6 +6,8 @@ import type { IContentModelEditor } from '../../publicTypes/IContentModelEditor' * @param editor The editor to operate on */ export default function toggleSuperscript(editor: IContentModelEditor) { + editor.focus(); + formatSegmentWithContentModel( editor, 'toggleSuperscript', diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleUnderline.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleUnderline.ts index d3598217107..6fdd7cd2aec 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleUnderline.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/segment/toggleUnderline.ts @@ -6,6 +6,8 @@ import type { IContentModelEditor } from '../../publicTypes/IContentModelEditor' * @param editor The editor to operate on */ export default function toggleUnderline(editor: IContentModelEditor) { + editor.focus(); + formatSegmentWithContentModel( editor, 'toggleUnderline', diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/table/editTable.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/table/editTable.ts index 19279c773b6..71a71d72fe8 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/table/editTable.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/table/editTable.ts @@ -31,6 +31,8 @@ import { * @param operation The table operation to apply */ export default function editTable(editor: IContentModelEditor, operation: TableOperation) { + editor.focus(); + formatWithContentModel(editor, 'editTable', model => { const [tableModel, path] = getFirstSelectedTable(model); diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/table/formatTable.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/table/formatTable.ts index de3f157a885..eccafb745f3 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/table/formatTable.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/table/formatTable.ts @@ -15,6 +15,8 @@ export default function formatTable( format: TableMetadataFormat, keepCellShade?: boolean ) { + editor.focus(); + formatWithContentModel(editor, 'formatTable', model => { const [tableModel] = getFirstSelectedTable(model); diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/table/insertTable.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/table/insertTable.ts index d2a8b8b4a0c..c46dc0b5e85 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/table/insertTable.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/table/insertTable.ts @@ -25,6 +25,8 @@ export default function insertTable( rows: number, format?: Partial ) { + editor.focus(); + formatWithContentModel(editor, 'insertTable', (model, context) => { const insertPosition = deleteSelection(model, [], context).insertPoint; diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/table/setTableCellShade.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/table/setTableCellShade.ts index c26865d23de..f9483e86267 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/table/setTableCellShade.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/table/setTableCellShade.ts @@ -11,6 +11,8 @@ import type { IContentModelEditor } from '../../publicTypes/IContentModelEditor' * @param color The color to set. Pass null to remove existing shade color */ export default function setTableCellShade(editor: IContentModelEditor, color: string | null) { + editor.focus(); + formatWithContentModel(editor, 'setTableCellShade', model => { const [table] = getFirstSelectedTable(model); diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/utils/formatWithContentModel.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/utils/formatWithContentModel.ts index 6b09c57efb2..765f2afcde4 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/utils/formatWithContentModel.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/utils/formatWithContentModel.ts @@ -35,8 +35,6 @@ export function formatWithContentModel( selectionOverride, } = options || {}; - editor.focus(); - const model = editor.createContentModel(undefined /*option*/, selectionOverride); const context: FormatWithContentModelContext = { newEntities: [], diff --git a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/utils/paste.ts b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/utils/paste.ts index 2f42372f336..85a04fcc85d 100644 --- a/packages-content-model/roosterjs-content-model-editor/lib/publicApi/utils/paste.ts +++ b/packages-content-model/roosterjs-content-model-editor/lib/publicApi/utils/paste.ts @@ -48,6 +48,8 @@ export default function paste( clipboardData.snapshotBeforePaste = editor.getContent(GetContentMode.RawHTMLWithSelection); } + editor.focus(); + formatWithContentModel( editor, 'Paste', diff --git a/packages-content-model/roosterjs-content-model-editor/test/publicApi/format/clearFormatTest.ts b/packages-content-model/roosterjs-content-model-editor/test/publicApi/format/clearFormatTest.ts index 8326fb0fb1f..7eddbeba0bf 100644 --- a/packages-content-model/roosterjs-content-model-editor/test/publicApi/format/clearFormatTest.ts +++ b/packages-content-model/roosterjs-content-model-editor/test/publicApi/format/clearFormatTest.ts @@ -7,7 +7,9 @@ import { IContentModelEditor } from '../../../lib/publicTypes/IContentModelEdito describe('clearFormat', () => { it('Clear format', () => { - const editor = ({} as any) as IContentModelEditor; + const editor = ({ + focus: () => {}, + } as any) as IContentModelEditor; const model = ('Model' as any) as ContentModelDocument; spyOn(formatWithContentModel, 'formatWithContentModel').and.callFake( diff --git a/packages-content-model/roosterjs-content-model-editor/test/publicApi/list/setListStartNumberTest.ts b/packages-content-model/roosterjs-content-model-editor/test/publicApi/list/setListStartNumberTest.ts index 0517b52110f..1aec33f79ae 100644 --- a/packages-content-model/roosterjs-content-model-editor/test/publicApi/list/setListStartNumberTest.ts +++ b/packages-content-model/roosterjs-content-model-editor/test/publicApi/list/setListStartNumberTest.ts @@ -21,7 +21,12 @@ describe('setListStartNumber', () => { } ); - setListStartNumber(null!, 2); + setListStartNumber( + { + focus: () => {}, + } as any, + 2 + ); expect(formatWithContentModel.formatWithContentModel).toHaveBeenCalledTimes(1); expect(input).toEqual(expectedModel); diff --git a/packages-content-model/roosterjs-content-model-editor/test/publicApi/list/setListStyleTest.ts b/packages-content-model/roosterjs-content-model-editor/test/publicApi/list/setListStyleTest.ts index 2bc22075ada..14efd88584e 100644 --- a/packages-content-model/roosterjs-content-model-editor/test/publicApi/list/setListStyleTest.ts +++ b/packages-content-model/roosterjs-content-model-editor/test/publicApi/list/setListStyleTest.ts @@ -22,7 +22,12 @@ describe('setListStyle', () => { } ); - setListStyle(null!, style); + setListStyle( + { + focus: () => {}, + } as any, + style + ); expect(formatWithContentModel.formatWithContentModel).toHaveBeenCalledTimes(1); expect(input).toEqual(expectedModel); diff --git a/packages-content-model/roosterjs-content-model-editor/test/publicApi/utils/formatWithContentModelTest.ts b/packages-content-model/roosterjs-content-model-editor/test/publicApi/utils/formatWithContentModelTest.ts index 30bf7819871..6caa0f9297d 100644 --- a/packages-content-model/roosterjs-content-model-editor/test/publicApi/utils/formatWithContentModelTest.ts +++ b/packages-content-model/roosterjs-content-model-editor/test/publicApi/utils/formatWithContentModelTest.ts @@ -10,7 +10,6 @@ describe('formatWithContentModel', () => { let addUndoSnapshot: jasmine.Spy; let createContentModel: jasmine.Spy; let setContentModel: jasmine.Spy; - let focus: jasmine.Spy; let mockedModel: ContentModelDocument; let cacheContentModel: jasmine.Spy; let getFocusedPosition: jasmine.Spy; @@ -26,14 +25,12 @@ describe('formatWithContentModel', () => { addUndoSnapshot = jasmine.createSpy('addUndoSnapshot').and.callFake(callback => callback()); createContentModel = jasmine.createSpy('createContentModel').and.returnValue(mockedModel); setContentModel = jasmine.createSpy('setContentModel'); - focus = jasmine.createSpy('focus'); cacheContentModel = jasmine.createSpy('cacheContentModel'); getFocusedPosition = jasmine.createSpy('getFocusedPosition').and.returnValue(mockedPos); triggerPluginEvent = jasmine.createSpy('triggerPluginEvent'); getVisibleViewport = jasmine.createSpy('getVisibleViewport'); editor = ({ - focus, addUndoSnapshot, createContentModel, setContentModel, @@ -59,7 +56,6 @@ describe('formatWithContentModel', () => { expect(createContentModel).toHaveBeenCalledTimes(1); expect(addUndoSnapshot).not.toHaveBeenCalled(); expect(setContentModel).not.toHaveBeenCalled(); - expect(focus).toHaveBeenCalled(); }); it('Callback return true', () => { @@ -82,7 +78,6 @@ describe('formatWithContentModel', () => { }); expect(setContentModel).toHaveBeenCalledTimes(1); expect(setContentModel).toHaveBeenCalledWith(mockedModel, undefined, undefined); - expect(focus).toHaveBeenCalledTimes(1); }); it('Preserve pending format', () => { diff --git a/packages/roosterjs-editor-api/lib/format/insertEntity.ts b/packages/roosterjs-editor-api/lib/format/insertEntity.ts index ab5bab68c54..e2b4623c3d0 100644 --- a/packages/roosterjs-editor-api/lib/format/insertEntity.ts +++ b/packages/roosterjs-editor-api/lib/format/insertEntity.ts @@ -148,7 +148,8 @@ export default function insertEntity( } } else if (isReadonly) { addDelimiters(entity.wrapper); - if (entity.wrapper.nextElementSibling) { + + if (entity.wrapper.nextElementSibling && editor.hasFocus()) { editor.select(new Position(entity.wrapper.nextElementSibling, PositionType.After)); } }