From f8d95757326a197c2e4ea54c4e16db5b9b17f000 Mon Sep 17 00:00:00 2001 From: e11sy <130844513+e11sy@users.noreply.github.com> Date: Thu, 10 Apr 2025 03:34:28 +0200 Subject: [PATCH 1/6] imp(dom-adapters): save formatting on block split --- packages/dom-adapters/src/BlockToolAdapter/index.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/dom-adapters/src/BlockToolAdapter/index.ts b/packages/dom-adapters/src/BlockToolAdapter/index.ts index dc96b238..0cb4fd53 100644 --- a/packages/dom-adapters/src/BlockToolAdapter/index.ts +++ b/packages/dom-adapters/src/BlockToolAdapter/index.ts @@ -349,6 +349,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, start, currentValue.length); + + /** + * Adjust fragments ranges respectfully to the removed text + */ + 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, @@ -358,7 +368,7 @@ export class BlockToolAdapter implements BlockToolAdapterInterface { [key]: { $t: 't', value: newValueAfter, - fragments: [], + fragments: relatedFragments, }, }, }, From 591b1083fca3d1296f8d9f2a5e9a188efe8b95cc Mon Sep 17 00:00:00 2001 From: e11sy <130844513+e11sy@users.noreply.github.com> Date: Thu, 10 Apr 2025 03:35:00 +0200 Subject: [PATCH 2/6] imp(dom-adapter): cover case with different inputs --- .../dom-adapters/src/CaretAdapter/index.ts | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/packages/dom-adapters/src/CaretAdapter/index.ts b/packages/dom-adapters/src/CaretAdapter/index.ts index efd9f527..fe194943 100644 --- a/packages/dom-adapters/src/CaretAdapter/index.ts +++ b/packages/dom-adapters/src/CaretAdapter/index.ts @@ -236,22 +236,30 @@ 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 From 40e4fa17f3ac66b952d4a47c21a7147f5870503d Mon Sep 17 00:00:00 2001 From: e11sy <130844513+e11sy@users.noreply.github.com> Date: Thu, 10 Apr 2025 03:47:45 +0200 Subject: [PATCH 3/6] chore(dom-adapters): lint fix --- packages/dom-adapters/src/BlockToolAdapter/index.ts | 4 ++-- packages/dom-adapters/src/CaretAdapter/index.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/dom-adapters/src/BlockToolAdapter/index.ts b/packages/dom-adapters/src/BlockToolAdapter/index.ts index e1f92faa..f07b92d3 100644 --- a/packages/dom-adapters/src/BlockToolAdapter/index.ts +++ b/packages/dom-adapters/src/BlockToolAdapter/index.ts @@ -351,13 +351,13 @@ 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, start, currentValue.length); + const relatedFragments = this.#model.getFragments(this.#blockIndex, key, end, currentValue.length); /** * Adjust fragments ranges respectfully to the removed text */ relatedFragments.forEach(fragment => { - fragment.range[0] = Math.max(0, fragment.range[0] - end); + fragment.range[0] -=end; fragment.range[1] -= end; }); diff --git a/packages/dom-adapters/src/CaretAdapter/index.ts b/packages/dom-adapters/src/CaretAdapter/index.ts index fe194943..93a447aa 100644 --- a/packages/dom-adapters/src/CaretAdapter/index.ts +++ b/packages/dom-adapters/src/CaretAdapter/index.ts @@ -236,10 +236,10 @@ export class CaretAdapter extends EventTarget { } const selection = document.getSelection()!; - + let isStartEqualsCurrent = false; let isEndEqualsCurrent = false; - + const start = getBoundaryPointByAbsoluteOffset(input, textRange[0]); const end = getBoundaryPointByAbsoluteOffset(input, textRange[1]); From 560d7aaa95fca99885948b160a77cadbd3f3efec Mon Sep 17 00:00:00 2001 From: e11sy <130844513+e11sy@users.noreply.github.com> Date: Thu, 10 Apr 2025 15:11:25 +0300 Subject: [PATCH 4/6] Update packages/dom-adapters/src/BlockToolAdapter/index.ts Co-authored-by: George Berezhnoy --- packages/dom-adapters/src/BlockToolAdapter/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dom-adapters/src/BlockToolAdapter/index.ts b/packages/dom-adapters/src/BlockToolAdapter/index.ts index f07b92d3..24063809 100644 --- a/packages/dom-adapters/src/BlockToolAdapter/index.ts +++ b/packages/dom-adapters/src/BlockToolAdapter/index.ts @@ -357,7 +357,7 @@ export class BlockToolAdapter implements BlockToolAdapterInterface { * Adjust fragments ranges respectfully to the removed text */ relatedFragments.forEach(fragment => { - fragment.range[0] -=end; + fragment.range[0] -= Math.max(0, end); fragment.range[1] -= end; }); From f48faad6788dda6da7ff18c62ae8809f943c50e5 Mon Sep 17 00:00:00 2001 From: e11sy <130844513+e11sy@users.noreply.github.com> Date: Thu, 10 Apr 2025 14:17:51 +0200 Subject: [PATCH 5/6] imp(dom-adapters): description --- packages/dom-adapters/src/BlockToolAdapter/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dom-adapters/src/BlockToolAdapter/index.ts b/packages/dom-adapters/src/BlockToolAdapter/index.ts index 24063809..697930ab 100644 --- a/packages/dom-adapters/src/BlockToolAdapter/index.ts +++ b/packages/dom-adapters/src/BlockToolAdapter/index.ts @@ -354,10 +354,10 @@ export class BlockToolAdapter implements BlockToolAdapterInterface { const relatedFragments = this.#model.getFragments(this.#blockIndex, key, end, currentValue.length); /** - * Adjust fragments ranges respectfully to the removed text + * 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, end); + fragment.range[0] = Math.max(0, fragment.range[0] - start); fragment.range[1] -= end; }); From dd7aecf0799b9bcdcdddddf7116dc952e857faf1 Mon Sep 17 00:00:00 2001 From: e11sy <130844513+e11sy@users.noreply.github.com> Date: Thu, 10 Apr 2025 14:25:39 +0200 Subject: [PATCH 6/6] chore(dom-adapters): fix --- packages/dom-adapters/src/BlockToolAdapter/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dom-adapters/src/BlockToolAdapter/index.ts b/packages/dom-adapters/src/BlockToolAdapter/index.ts index 71a3f689..88d8b427 100644 --- a/packages/dom-adapters/src/BlockToolAdapter/index.ts +++ b/packages/dom-adapters/src/BlockToolAdapter/index.ts @@ -365,7 +365,7 @@ export class BlockToolAdapter implements BlockToolAdapterInterface { * 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] - start); + fragment.range[0] = Math.max(0, fragment.range[0] - end); fragment.range[1] -= end; });