diff --git a/packages/docs/src/commands/operations/select-all.operation.ts b/packages/docs/src/commands/operations/select-all.operation.ts index 501f7d43a9..7a0193b0eb 100644 --- a/packages/docs/src/commands/operations/select-all.operation.ts +++ b/packages/docs/src/commands/operations/select-all.operation.ts @@ -43,7 +43,7 @@ export const SelectAllOperation: ICommand = { }, ]; - textSelectionManagerService.replaceTextRanges(textRanges); + textSelectionManagerService.replaceTextRanges(textRanges, false); return true; }, diff --git a/packages/docs/src/commands/operations/text-selection.operation.ts b/packages/docs/src/commands/operations/text-selection.operation.ts index 9b51e63459..7cea2d4234 100644 --- a/packages/docs/src/commands/operations/text-selection.operation.ts +++ b/packages/docs/src/commands/operations/text-selection.operation.ts @@ -22,6 +22,8 @@ export interface ISetTextSelectionsOperationParams { unitId: string; subUnitId: string; segmentId: string; + // Whether it occurs at the same time as text editing. + isEditing: boolean; style: ITextSelectionStyle; ranges: ITextRangeWithStyle[]; } @@ -31,8 +33,8 @@ export const SetTextSelectionsOperation: IOperation { - // for live share and share cursor. + handler: (_, __) => { + // for menu highlight use and share cursor. return true; }, }; diff --git a/packages/docs/src/controllers/move-cursor.controller.ts b/packages/docs/src/controllers/move-cursor.controller.ts index 9febae7d09..1efcf75d16 100644 --- a/packages/docs/src/controllers/move-cursor.controller.ts +++ b/packages/docs/src/controllers/move-cursor.controller.ts @@ -122,7 +122,7 @@ export class MoveCursorController extends Disposable { endOffset: direction === Direction.LEFT || direction === Direction.UP ? min : max, style, }, - ]); + ], false); return; } @@ -151,7 +151,7 @@ export class MoveCursorController extends Disposable { endOffset: focusOffset, style, }, - ]); + ], false); } else { const focusSpan = skeleton.findNodeByCharIndex(focusOffset); @@ -172,7 +172,7 @@ export class MoveCursorController extends Disposable { endOffset: newFocusOffset, style, }, - ]); + ], false); return; } @@ -189,7 +189,7 @@ export class MoveCursorController extends Disposable { endOffset: newActiveRange.endOffset, style, }, - ]); + ], false); } } @@ -241,7 +241,7 @@ export class MoveCursorController extends Disposable { endOffset: cursor, style, }, - ]); + ], false); } else { const startNode = skeleton.findNodeByCharIndex(startOffset); const endNode = skeleton.findNodeByCharIndex(endOffset); @@ -273,7 +273,7 @@ export class MoveCursorController extends Disposable { endOffset: cursor, style, }, - ]); + ], false); return; } @@ -288,7 +288,7 @@ export class MoveCursorController extends Disposable { ...newActiveRange, style, }, - ]); + ], false); } } diff --git a/packages/docs/src/services/text-selection-manager.service.ts b/packages/docs/src/services/text-selection-manager.service.ts index a852a63ef3..b6a7d8df7d 100644 --- a/packages/docs/src/services/text-selection-manager.service.ts +++ b/packages/docs/src/services/text-selection-manager.service.ts @@ -154,7 +154,7 @@ export class TextSelectionManagerService extends RxDisposable { } // **Only used in test case** because this does not go through the render layer. - add(textRanges: ISuccinctTextRangeParam[]) { + add(textRanges: ISuccinctTextRangeParam[], isEditing = true) { if (this._currentSelection == null) { return; } @@ -163,18 +163,20 @@ export class TextSelectionManagerService extends RxDisposable { ...this._currentSelection, textRanges: textRanges as TextRange[], segmentId: '', + isEditing, style: NORMAL_TEXT_SELECTION_PLUGIN_STYLE, // mock style. }); } - replaceTextRanges(textRanges: ISuccinctTextRangeParam[]) { + replaceTextRanges(textRanges: ISuccinctTextRangeParam[], isEditing = true) { if (this._currentSelection == null) { return; } // Remove all textRanges. this._textSelectionRenderManager.removeAllTextRanges(); - this._textSelectionRenderManager.addTextRanges(textRanges); + // Add new textRanges. + this._textSelectionRenderManager.addTextRanges(textRanges, isEditing); } // All textRanges should be synchronized from the render layer. @@ -204,14 +206,15 @@ export class TextSelectionManagerService extends RxDisposable { // Broadcast textSelection changes, this should be used within the application. this._textSelection$.next(params); - const { unitId, subUnitId, segmentId, style, textRanges } = params; + const { unitId, subUnitId, segmentId, style, textRanges, isEditing } = params; - // For live share only. + // For menu status. this._commandService.executeCommand(SetTextSelectionsOperation.id, { unitId, subUnitId, segmentId, style, + isEditing, ranges: textRanges.map(serializeTextRange), }); } @@ -242,7 +245,7 @@ export class TextSelectionManagerService extends RxDisposable { } private _replaceByParam(insertParam: ITextSelectionManagerInsertParam) { - const { unitId, subUnitId, style, segmentId, textRanges } = insertParam; + const { unitId, subUnitId, style, segmentId, textRanges, isEditing } = insertParam; if (!this._textSelectionInfo.has(unitId)) { this._textSelectionInfo.set(unitId, new Map()); @@ -250,11 +253,11 @@ export class TextSelectionManagerService extends RxDisposable { const unitTextRange = this._textSelectionInfo.get(unitId)!; - unitTextRange.set(subUnitId, { textRanges, style, segmentId }); + unitTextRange.set(subUnitId, { textRanges, style, segmentId, isEditing }); } private _addByParam(insertParam: ITextSelectionManagerInsertParam): void { - const { unitId, subUnitId, textRanges, style, segmentId } = insertParam; + const { unitId, subUnitId, textRanges, style, segmentId, isEditing } = insertParam; if (!this._textSelectionInfo.has(unitId)) { this._textSelectionInfo.set(unitId, new Map()); @@ -263,7 +266,7 @@ export class TextSelectionManagerService extends RxDisposable { const unitTextRange = this._textSelectionInfo.get(unitId)!; if (!unitTextRange.has(subUnitId)) { - unitTextRange.set(subUnitId, { textRanges, style, segmentId }); + unitTextRange.set(subUnitId, { textRanges, style, segmentId, isEditing }); } else { const OldTextRanges = unitTextRange.get(subUnitId)!; OldTextRanges.textRanges.push(...textRanges); diff --git a/packages/engine-render/src/components/docs/text-selection-render-manager.ts b/packages/engine-render/src/components/docs/text-selection-render-manager.ts index d885ba0ebd..747df2f94d 100644 --- a/packages/engine-render/src/components/docs/text-selection-render-manager.ts +++ b/packages/engine-render/src/components/docs/text-selection-render-manager.ts @@ -108,6 +108,7 @@ interface IAddTextRangesConfig { export interface ITextSelectionInnerParam { textRanges: TextRange[]; segmentId: string; + isEditing: boolean; style: ITextSelectionStyle; } @@ -151,7 +152,7 @@ export interface ITextSelectionRenderManager { removeAllTextRanges(): void; - addTextRanges(ranges: ISuccinctTextRangeParam[], config?: IAddTextRangesConfig): void; + addTextRanges(ranges: ISuccinctTextRangeParam[], isEditing?: boolean): void; sync(): void; @@ -290,7 +291,7 @@ export class TextSelectionRenderManager extends RxDisposable implements ITextSel this._isSelectionEnabled = false; } - addTextRanges(ranges: ISuccinctTextRangeParam[]) { + addTextRanges(ranges: ISuccinctTextRangeParam[], isEditing = true) { const { _scene: scene, _docSkeleton: docSkeleton } = this; for (const range of ranges) { @@ -303,6 +304,7 @@ export class TextSelectionRenderManager extends RxDisposable implements ITextSel textRanges: this._getAllTextRanges(), segmentId: this._currentSegmentId, style: this._selectionStyle, + isEditing, }); this._updateDomCursorPositionAndSize(); @@ -389,8 +391,7 @@ export class TextSelectionRenderManager extends RxDisposable implements ITextSel return; } - // Firefox do not support Segmenter, so you need a Segmenter polyfill if you want use it in Firefox. - // TODO: @JOCS write this in DOCS or README when we publish the package. + // Firefox do not support Segmenter in an old version, so you need a Segmenter polyfill if you want use it in Firefox. if (Intl.Segmenter == null) { return; } @@ -518,10 +519,10 @@ export class TextSelectionRenderManager extends RxDisposable implements ITextSel return; } - this._moving(moveOffsetX, moveOffsetY, scrollTimer); + this._moving(moveOffsetX, moveOffsetY); scrollTimer.scrolling(moveOffsetX, moveOffsetY, () => { - this._moving(moveOffsetX, moveOffsetY, scrollTimer); + this._moving(moveOffsetX, moveOffsetY); }); preMoveOffsetX = moveOffsetX; @@ -538,6 +539,7 @@ export class TextSelectionRenderManager extends RxDisposable implements ITextSel textRanges: this._getAllTextRanges(), segmentId: this._currentSegmentId, style: this._selectionStyle, + isEditing: false, }); scrollTimer.dispose(); @@ -914,7 +916,7 @@ export class TextSelectionRenderManager extends RxDisposable implements ITextSel this.activate(canvasLeft, canvasTop); } - private _moving(moveOffsetX: number, moveOffsetY: number, scrollTimer: ScrollTimer) { + private _moving(moveOffsetX: number, moveOffsetY: number) { if (this._docSkeleton == null) { return; }