diff --git a/packages/dom-adapters/src/BlockToolAdapter/index.ts b/packages/dom-adapters/src/BlockToolAdapter/index.ts index 7f71bce..88d8b42 100644 --- a/packages/dom-adapters/src/BlockToolAdapter/index.ts +++ b/packages/dom-adapters/src/BlockToolAdapter/index.ts @@ -359,6 +359,16 @@ export class BlockToolAdapter implements BlockToolAdapterInterface { const currentValue = this.#model.getText(this.#blockIndex, key); const newValueAfter = currentValue.slice(end); + const relatedFragments = this.#model.getFragments(this.#blockIndex, key, end, currentValue.length); + + /** + * Fragment ranges bounds should be decreased by end index, because end is the index of the first character of the new block + */ + relatedFragments.forEach(fragment => { + fragment.range[0] = Math.max(0, fragment.range[0] - end); + fragment.range[1] -= end; + }); + this.#model.removeText(this.#config.userId, this.#blockIndex, key, start, currentValue.length); this.#model.addBlock( this.#config.userId, @@ -368,7 +378,7 @@ export class BlockToolAdapter implements BlockToolAdapterInterface { [key]: { $t: 't', value: newValueAfter, - fragments: [], + fragments: relatedFragments, }, }, }, diff --git a/packages/dom-adapters/src/CaretAdapter/index.ts b/packages/dom-adapters/src/CaretAdapter/index.ts index cd1773b..6f0e113 100644 --- a/packages/dom-adapters/src/CaretAdapter/index.ts +++ b/packages/dom-adapters/src/CaretAdapter/index.ts @@ -264,21 +264,29 @@ export class CaretAdapter extends EventTarget { const selection = document.getSelection()!; - let absoluteStartOffset = getAbsoluteRangeOffset(input, selection.anchorNode!, selection.anchorOffset); - let absoluteEndOffset = getAbsoluteRangeOffset(input, selection.focusNode!, selection.focusOffset); + let isStartEqualsCurrent = false; + let isEndEqualsCurrent = false; + + const start = getBoundaryPointByAbsoluteOffset(input, textRange[0]); + const end = getBoundaryPointByAbsoluteOffset(input, textRange[1]); /** - * For right-to-left selection, we need to swap start and end offsets to compare with model range + * If selection is outside of the input, it is different from the model range */ - if (absoluteStartOffset > absoluteEndOffset) { - [absoluteStartOffset, absoluteEndOffset] = [absoluteEndOffset, absoluteStartOffset]; - } + if (input.contains(selection.anchorNode!) && input.contains(selection.focusNode!)) { + let absoluteStartOffset = getAbsoluteRangeOffset(input, selection.anchorNode!, selection.anchorOffset); + let absoluteEndOffset = getAbsoluteRangeOffset(input, selection.focusNode!, selection.focusOffset); - const start = getBoundaryPointByAbsoluteOffset(input, textRange[0]); - const end = getBoundaryPointByAbsoluteOffset(input, textRange[1]); + /** + * For right-to-left selection, we need to swap start and end offsets to compare with model range + */ + if (absoluteStartOffset > absoluteEndOffset) { + [absoluteStartOffset, absoluteEndOffset] = [absoluteEndOffset, absoluteStartOffset]; + } - const isStartEqualsCurrent = textRange[0] === absoluteStartOffset; - const isEndEqualsCurrent = textRange[1] === absoluteEndOffset; + isStartEqualsCurrent = textRange[0] === absoluteStartOffset; + isEndEqualsCurrent = textRange[1] === absoluteEndOffset; + } /** * If selection is already the same, we don't need to update it to not interrupt browser's behaviour