diff --git a/packages/docs/src/commands/commands/ime-input.command.ts b/packages/docs/src/commands/commands/ime-input.command.ts index 183e31c8b9..fb793ff175 100644 --- a/packages/docs/src/commands/commands/ime-input.command.ts +++ b/packages/docs/src/commands/commands/ime-input.command.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import type { ICommand, ICommandInfo, ITextRange } from '@univerjs/core'; +import type { ICommand, ICommandInfo } from '@univerjs/core'; import { CommandType, ICommandService, TextX, TextXActionType } from '@univerjs/core'; import type { ITextRangeWithStyle } from '@univerjs/engine-render'; @@ -27,10 +27,8 @@ export interface IIMEInputCommandParams { unitId: string; newText: string; oldTextLen: number; - range: ITextRange; - textRanges: ITextRangeWithStyle[]; + isCompositionStart: boolean; isCompositionEnd: boolean; - segmentId?: string; } export const IMEInputCommand: ICommand = { @@ -39,9 +37,26 @@ export const IMEInputCommand: ICommand = { type: CommandType.COMMAND, handler: async (accessor, params: IIMEInputCommandParams) => { - const { unitId, newText, oldTextLen, range, segmentId, textRanges, isCompositionEnd } = params; + const { unitId, newText, oldTextLen, isCompositionEnd, isCompositionStart } = params; const commandService = accessor.get(ICommandService); const imeInputManagerService = accessor.get(IMEInputManagerService); + const previousActiveRange = imeInputManagerService.getActiveRange(); + + if (previousActiveRange == null) { + return false; + } + + const { startOffset, style, segmentId } = previousActiveRange; + const len = newText.length; + + const textRanges: ITextRangeWithStyle[] = [ + { + startOffset: startOffset + len, + endOffset: startOffset + len, + collapsed: true, + style, + }, + ]; const doMutation: ICommandInfo = { id: RichTextEditingMutation.id, @@ -54,14 +69,14 @@ export const IMEInputCommand: ICommand = { const textX = new TextX(); - if (range.collapsed) { + if (!previousActiveRange.collapsed && isCompositionStart) { + textX.push(...getRetainAndDeleteFromReplace(previousActiveRange, segmentId)); + } else { textX.push({ t: TextXActionType.RETAIN, - len: range.startOffset, + len: startOffset, segmentId, }); - } else { - textX.push(...getRetainAndDeleteFromReplace(range, segmentId)); } if (oldTextLen > 0) { diff --git a/packages/docs/src/controllers/ime-input.controller.ts b/packages/docs/src/controllers/ime-input.controller.ts index 023b86783a..3ae732a5ac 100644 --- a/packages/docs/src/controllers/ime-input.controller.ts +++ b/packages/docs/src/controllers/ime-input.controller.ts @@ -23,7 +23,7 @@ import { OnLifecycle, Tools, } from '@univerjs/core'; -import type { IEditorInputConfig, ITextRangeWithStyle } from '@univerjs/engine-render'; +import type { IEditorInputConfig } from '@univerjs/engine-render'; import { ITextSelectionRenderManager } from '@univerjs/engine-render'; import { Inject } from '@wendellhu/redi'; import type { Subscription } from 'rxjs'; @@ -36,7 +36,7 @@ import { IMEInputManagerService } from '../services/ime-input-manager.service'; export class IMEInputController extends Disposable { private _previousIMEContent: string = ''; - private _previousIMERange: Nullable; + private _isCompositionStart: boolean = true; private _onStartSubscription: Nullable; @@ -86,7 +86,7 @@ export class IMEInputController extends Disposable { this._imeInputManagerService.setActiveRange(Tools.deepClone(activeRange)); - this._previousIMERange = activeRange; + this._isCompositionStart = true; }); } @@ -105,7 +105,7 @@ export class IMEInputController extends Disposable { private async _updateContent(config: Nullable, isUpdate: boolean) { const skeleton = this._docSkeletonManagerService.getCurrent()?.skeleton; - if (this._previousIMERange == null || config == null || skeleton == null) { + if (config == null || skeleton == null) { return; } @@ -113,8 +113,6 @@ export class IMEInputController extends Disposable { const { event, activeRange } = config; - const { startOffset, segmentId, style } = this._previousIMERange; - if (skeleton == null || activeRange == null) { return; } @@ -127,29 +125,17 @@ export class IMEInputController extends Disposable { return; } - const len = content.length; - - const textRanges = [ - { - startOffset: startOffset + len, - endOffset: startOffset + len, - style, - }, - ]; - await this._commandService.executeCommand(IMEInputCommand.id, { unitId: documentModel.getUnitId(), newText: content, oldTextLen: this._previousIMEContent.length, - range: this._previousIMERange, - textRanges, + isCompositionStart: this._isCompositionStart, isCompositionEnd: !isUpdate, - segmentId, }); if (isUpdate) { - if (!this._previousIMERange.collapsed) { - this._previousIMERange.collapsed = true; + if (this._isCompositionStart) { + this._isCompositionStart = false; } this._previousIMEContent = content; @@ -161,7 +147,7 @@ export class IMEInputController extends Disposable { private _resetIME() { this._previousIMEContent = ''; - this._previousIMERange = null; + this._isCompositionStart = true; this._imeInputManagerService.clearUndoRedoMutationParamsCache();