From 879d7eef5ff48ca6979b31b135ad72ead021e3cb Mon Sep 17 00:00:00 2001 From: yanmao <55792257+yanmao-cc@users.noreply.github.com> Date: Wed, 24 Nov 2021 18:12:48 +0800 Subject: [PATCH] =?UTF-8?q?fix(ot):=20=E7=9B=B8=E5=90=8C=E7=94=A8=E6=88=B7?= =?UTF-8?q?id=E7=BC=96=E8=BE=91=E6=97=B6=E4=BC=9A=E5=87=BA=E7=8E=B0?= =?UTF-8?q?=E6=AD=BB=E5=BE=AA=E7=8E=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/engine/src/ot/index.ts | 17 +++++++++++++++-- plugins/quote/src/index.ts | 21 ++++++++++++++++++++- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/packages/engine/src/ot/index.ts b/packages/engine/src/ot/index.ts index 3dec4a0d..47d60848 100644 --- a/packages/engine/src/ot/index.ts +++ b/packages/engine/src/ot/index.ts @@ -20,7 +20,7 @@ import RangeColoring from './range-coloring'; import OTDoc from './doc'; import Consumer from './consumer'; import Mutation from './mutation'; -import { toJSON0 } from './utils'; +import { toJSON0, isCursorOp } from './utils'; import { random } from '../utils'; import './index.css'; @@ -61,7 +61,20 @@ class OTModel extends EventEmitter2 implements OTInterface { const operations = filterOperations(this.waitingOps); if (operations.length > 0) { this.waitingOps = []; - this.apply(operations); + this.apply( + operations.filter((op) => { + // 过滤掉修改自身光标位置的操作 + if ( + isCursorOp(op) && + op.p.includes( + `data-selection-${this.currentMember?.uuid}`, + ) + ) { + return false; + } + return true; + }), + ); this.engine.history.handleRemoteOps(operations); const selections = this.selection.getSelections(); this.renderSelection(selections); diff --git a/plugins/quote/src/index.ts b/plugins/quote/src/index.ts index 83fbcf1b..f23d88b1 100644 --- a/plugins/quote/src/index.ts +++ b/plugins/quote/src/index.ts @@ -173,7 +173,26 @@ export default class extends BlockPlugin { const { change, node } = this.editor; const range = change.range.get(); const blockApi = this.editor.block; - if (!blockApi.isFirstOffset(range, 'start')) return; + + const inEnd = blockApi.isLastOffset(range, 'end'); + if (inEnd && !range.collapsed) { + const startBlock = blockApi.closest(range.startNode); + const endBlock = blockApi.closest(range.endNode); + const startParentBlock = startBlock.parent(); + const endParentBlock = endBlock.parent(); + if ( + startParentBlock && + endParentBlock && + endParentBlock.name === 'blockquote' && + !startParentBlock.equal(endParentBlock) + ) { + endParentBlock.remove(); + return; + } + } + + const inFirst = blockApi.isFirstOffset(range, 'start'); + if (!inFirst) return; const block = blockApi.closest(range.startNode); const parentBlock = block.parent();