Replacing a selection by inserting text

Hi there,

I’m not confident yet that it’s a bug.

The scenario: We’re using ProseMirror in a React environment where we built our own menu components to compliment the editor itself. One of the use cases is an emoji menu that inserts an emoji as text when you pick one in a popover component.

The insertion itself is not a problem. But as soon as the selection spans one or more positions, after applying the transaction the whole word will be selected.

Example text: My example Selected text: xam Selected text after insertion: My e👍ple

I’ve already tried several variants of inserting/replacing and manually selecting. But even if I inspect the transaction right before dispatching, the selection doesn’t match the result I’m seeing.

While researching the problem I noticed that there were several Chrome issues related to selections as well. Could this be a side effect of one of the fixes?

Thanks in advance Sebastian

You didn’t really mention how you’re doing the insertion. tr.replaceSelection should work for this, and makes sure the new selection ends up at the end of the insertion.

Sorry for the missing details. I’ve tried several variations of these:


const node = currentState.schema.text(text);

const frag = Fragment.from(node);

const slice = new Slice(frag, 0, 0);

const transaction = currentState.tr.replaceSelection(slice);

// apply transaction


const node = currentState.schema.text(text);

const transaction = currentState.tr.replaceSelectionWith(node);

// apply transaction


const cursorPositionBefore = currentState.selection.$from.pos;

let transaction = currentState.tr.deleteSelection();

transaction = currentState.tr.insertText(text, currentState.selection.$from.pos, currentState.selection.$to.pos);

const newSelection = transaction.doc.resolve(cursorPositionBefore);

transaction = currentState.tr.setSelection(new TextSelection(newSelection, newSelection));

// apply transaction

I gotta admit that I’ve only tried replaceSelection after your suggestion, because I felt more comfortable using replaceSelectionWith.

The behavior is the same for me across all these variants though (whole text gets selected).

replaceSelectionWith should also work. Can you reproduce this problem in a minimal editor outside of your code base, where you just dispatch a simple transaction?

Also look into the DOM events that are involved—depending on where the control to activate this is, and how you’re handling events, you may be seeing a native double-click happening alongside your own effect.

I tried to replicate the scenario with a basic react setup in this sandbox - just try to select some of the text and press the test-button on top:

The problem doesn’t occur here so I’m fairly certain the fixes I mentioned are not responsible for my problem.

I checked the DOM events surrounding the editor, but I didn’t notice anything I wasn’t expecting (no unwanted clicks, focus or blur events - just those necessary).

I’ll try to investigate this further and post an update once I got my head around the root cause.

Thanks so far.