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 f408808..f84fee2 100644 Binary files a/lexai-chrome-mv3.zip and b/lexai-chrome-mv3.zip differ