From 47ffaf9ca3c5f251661346d4ae6abae9d923aba5 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 22 Sep 2023 18:08:01 +0200 Subject: [PATCH] Fix an issue in the way the DOMReader treats positions in opaque nodes FIX: Fix an issue in the way the DOM selection is being read that could break backspacing of widgets on Android. See https://discuss.codemirror.net/t/backspace-on-decoration-work-strangely-in-mobile-keyboard/7009 --- src/domreader.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/domreader.ts b/src/domreader.ts index 15d296e..61de027 100644 --- a/src/domreader.ts +++ b/src/domreader.ts @@ -1,4 +1,5 @@ import {ContentView} from "./contentview" +import {domIndex, maxOffset} from "./dom" import {EditorState} from "@codemirror/state" export const LineBreakPlaceholder = "\uffff" @@ -88,10 +89,19 @@ export class DOMReader { point.pos = this.text.length } - findPointInside(node: Node, maxLen: number) { + findPointInside(node: Node, length: number) { for (let point of this.points) if (node.nodeType == 3 ? point.node == node : node.contains(point.node)) - point.pos = this.text.length + Math.min(maxLen, point.offset) + point.pos = this.text.length + (isAtEnd(node, point.node, point.offset) ? length : 0) + } +} + +function isAtEnd(parent: Node, node: Node | null, offset: number) { + for (;;) { + if (!node || offset < maxOffset(node)) return false + if (node == parent) return true + offset = domIndex(node) + 1 + node = node.parentNode } }