A reviewer is reading an equipment procedure and wants to put one selected instruction into a comment draft. The operation should copy the instruction as plain text, leave the procedure unchanged, and explain when no text is selected. A whole-document export or a formatting toolbar answers a different request.
Capture the current text selection when the action runs
For an existing Tiptap editor, this function returns an excerpt from its current state:
function selectedExcerpt(editor) {
const { state } = editor;
const { from, to, empty } = state.selection;
if (empty) return '';
return state.doc.textBetween(from, to, '\n');
}
from and to describe the ordered document range even when the person drags backward. They are positions in ProseMirror's document structure, not character indexes in editor.getHTML(). Tags, paragraph boundaries, and non-text nodes make those coordinate systems different.
The newline argument separates text blocks in an excerpt spanning paragraphs. This is a plain-text extraction. It deliberately does not preserve bold marks, links, tables, or image data. A selected image can therefore produce no useful text even though the selection itself is not empty. If your application needs rich fragments, design that output separately instead of calling this function a rich copy operation.
Put the excerpt in a comment draft as text
With an existing editor, connect a button and a destination outside the editing surface:
<button type="button" id="use-passage">Use selected passage</button>
<label for="comment-passage">Passage for the comment</label>
<textarea id="comment-passage"></textarea>
<p id="passage-status" role="status"></p>
const usePassage = document.querySelector('#use-passage');
const destination = document.querySelector('#comment-passage');
const status = document.querySelector('#passage-status');
function insertSelectedPassage() {
const excerpt = selectedExcerpt(editor);
if (!excerpt.trim()) {
status.textContent = 'Select instruction text first.';
return;
}
destination.value = excerpt;
status.textContent = 'Selected passage added to the comment draft.';
}
usePassage.addEventListener('click', insertSelectedPassage);
Assigning a textarea's value keeps literal < characters as text. It does not interpret the passage as HTML. The button has type="button" so an enclosing form does not submit the document while the reviewer prepares a comment. Remove this listener when its component is destroyed.
Read the selection inside the action rather than caching offsets from an earlier pointer event. Intervening edits can change which passage those offsets identify. The Tiptap events API provides selectionUpdate for interface state, but an enabled button is only a cue: the action must still check the current selection.
Select a known range only in the matching document
An isolated development fixture makes the position convention visible:
editor.commands.setContent('<p>Check seal.</p>');
editor.commands.setTextSelection({ from: 1, to: 6 });
console.log(selectedExcerpt(editor)); // Check
The opening paragraph's text starts at document position 1 in this fixture. The positions select Check, excluding the space after it. Do not reuse those numbers in an unrelated procedure. Replacing the content here is a fixture setup step, not part of the excerpt action in a live document.
setTextSelection(6) instead places a collapsed cursor at that position. The excerpt function then returns an empty string. Moving a text selection is also different from applying a stored highlight mark or adding a Focus extension outline. Neither formatting change is needed to prepare a plain-text comment.
Check the passage and the unchanged procedure
In a disposable copy, select Check from the fixture and activate the button. The comment field should contain exactly Check. Collapse the cursor and repeat; the status should ask for text and the previous comment field should remain unchanged. Select across two paragraphs and inspect the newline between their text.
Finally, compare editor.getHTML() before and after the excerpt action. The source procedure should be identical. The reviewer can now add a specific comment about the selected instruction, while the document continues to contain the original passage.