From 8d3887a0af761dbf85ca08824f2834c61450dcb2 Mon Sep 17 00:00:00 2001 From: Forge Date: Fri, 6 Mar 2026 14:44:05 +0800 Subject: [PATCH] fix: use execCommand insertText for contenteditable replace - fixes delete-without-paste bug --- entrypoints/content.ts | 30 +++++++++++++++++++++++------- lexai-chrome-mv3.zip | Bin 74760 -> 74805 bytes 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/entrypoints/content.ts b/entrypoints/content.ts index 10b8216..f7c7d5d 100644 --- a/entrypoints/content.ts +++ b/entrypoints/content.ts @@ -496,19 +496,35 @@ export default defineContentScript({ // contenteditable / DOM range path console.log('[LexAI Replace] using DOM range'); try { - snapRange.deleteContents(); - const textNode = document.createTextNode(resultText); - snapRange.insertNode(textNode); + // Strategy: restore the selection from the cloned range, then use + // execCommand('insertText') which works reliably on contenteditable. + // insertNode() on stale ranges often fails after async operations. const sel = window.getSelection(); if (sel) { sel.removeAllRanges(); - const newRange = document.createRange(); - newRange.setStartAfter(textNode); - newRange.collapse(true); - sel.addRange(newRange); + sel.addRange(snapRange); // restore original selection + } + + // Try execCommand first (works on most contenteditable editors) + const inserted = document.execCommand('insertText', false, resultText); + + if (!inserted) { + // Fallback: direct DOM manipulation + snapRange.deleteContents(); + const textNode = document.createTextNode(resultText); + snapRange.insertNode(textNode); + if (sel) { + sel.removeAllRanges(); + const newRange = document.createRange(); + newRange.setStartAfter(textNode); + newRange.collapse(true); + sel.addRange(newRange); + } } } catch (err) { console.warn('[LexAI Replace] range replace failed:', err); + // Last resort: execCommand + try { document.execCommand('insertText', false, resultText); } catch (_) {} } } else { console.warn('[LexAI Replace] NO VALID SNAP STATE — snapStart:', snapStart, 'snapEnd:', snapEnd, 'snapElement:', snapElement, 'snapRange:', snapRange); diff --git a/lexai-chrome-mv3.zip b/lexai-chrome-mv3.zip index 17be447ec4f9a151c3bf2a8763cd7f48cfb35bd4..f408808f1f86254f9be003ab078796e2964dfc4f 100644 GIT binary patch delta 5478 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