From d23c3e7a6756949daa727ad566a44a65cf19b2d5 Mon Sep 17 00:00:00 2001 From: evilchili Date: Fri, 29 May 2026 14:09:35 -0700 Subject: [PATCH] bugfix --- src/ts/ribbit-editor.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/ts/ribbit-editor.ts b/src/ts/ribbit-editor.ts index bf13d58..1ba0dfe 100644 --- a/src/ts/ribbit-editor.ts +++ b/src/ts/ribbit-editor.ts @@ -549,14 +549,16 @@ export class RibbitEditor extends Ribbit { #updateCurrentBlock(): void { const block = this.#findCurrentBlock(); if (!block) return; - + const caretOffset = this.#getCaretOffset(block); const lineText = block.textContent!.replace(/\u00A0/g, ' '); const newBlock = this.#buildBlock(lineText); block.className = newBlock.className; block.innerHTML = ''; - while (newBlock.firstChild) block.appendChild(newBlock.firstChild); + while (newBlock.firstChild) { + block.appendChild(newBlock.firstChild); + } // Place caret after any prefix span, never inside it const prefixSpan = block.firstElementChild; @@ -578,6 +580,13 @@ export class RibbitEditor extends Ribbit { sel.removeAllRanges(); sel.addRange(range); } else { + + // switch spaces back to non-breaking spaces to avoid a chromium bug where a trailing space is ignored when + // positioning the caret. We only do this if the last character is a space; if we do it unconditionally it + // breaks detection of header nodes etc. + if (lineText.endsWith(' ')) { + block.innerHTML = block.innerHTML.replace(/\s/g, '\u00A0'); + } this.#restoreCaret(block, caretOffset); } } @@ -748,6 +757,7 @@ export class RibbitEditor extends Ribbit { let remaining = offset; const placed = this.#walkForCaret(block, range, remaining); + if (!placed) { range.selectNodeContents(block); range.collapse(false);