From ec3ece0ea122f16a7d65902f3124fb77b53c2594 Mon Sep 17 00:00:00 2001 From: Forge Date: Fri, 6 Mar 2026 14:45:34 +0800 Subject: [PATCH] fix: simplify contenteditable replace - restore selection + execCommand, no manual delete --- entrypoints/content.ts | 32 +++++++------------------------- lexai-chrome-mv3.zip | Bin 74805 -> 74738 bytes 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/entrypoints/content.ts b/entrypoints/content.ts index f7c7d5d..ba2fc1e 100644 --- a/entrypoints/content.ts +++ b/entrypoints/content.ts @@ -494,37 +494,19 @@ export default defineContentScript({ snapElement.focus(); } else if (snapRange) { // contenteditable / DOM range path - console.log('[LexAI Replace] using DOM range'); + // Strategy: restore the original selection, then just "type" the new text. + // The browser automatically replaces selected text on insert — no manual + // deleteContents() needed (and safer since stale range deletes can go wrong). + console.log('[LexAI Replace] using DOM range — restoring selection + inserting'); try { - // 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(); - 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); - } + sel.addRange(snapRange); // restore original highlighted selection } + document.execCommand('insertText', false, resultText); // replaces selection } catch (err) { - console.warn('[LexAI Replace] range replace failed:', err); - // Last resort: execCommand - try { document.execCommand('insertText', false, resultText); } catch (_) {} + console.warn('[LexAI Replace] execCommand failed:', err); } } 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 f408808f1f86254f9be003ab078796e2964dfc4f..f84fee2831e0b059484b478af44f96809c6acc4b 100644 GIT binary patch delta 5249 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 delta 5295 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