ProseMirror - установить позицию курсора в конец выбранного узла
После выполнения команды ({ href: url }) я хотел бы отменить выбор текущего выделения и установить позицию курсора в конец выбранного узла. ПРИМЕЧАНИЕ: я использую TipTap
setLinkUrl(command, url) {
command({ href: url })
this.hideLinkMenu()
// Set cursor position after highlighted link
var tag = document.getElementById("editor")
var setpos = document.createRange()
var set = window.getSelection()
const state = this.editor.state
let sel = state.selection
// TODO: Check if sel range > 0
let resolvedPos = state.doc.resolve(sel.from)
let node = resolvedPos.node(resolvedPos.depth)
// This is where I want to set the caret position to the end of the currently selected node
// Currently, I'm using hardcoded indices as proof of concept while the editor contains three paragraph nodes
setpos.setStart(document.getElementById("editor").childNodes[0].childNodes[1], 1)
setpos.setEnd(document.getElementById("editor").childNodes[0].childNodes[1], 1)
setpos.collapse(true)
set.removeAllRanges()
set.addRange(setpos)
tag.focus()
1 ответ
Это то, как вы бы сделали это с ProseMirror, я думаю, это должно быть переведено и на TipTap.
Выделение может охватывать несколько узлов, поэтому мы собираемся переместить курсор в конец конца последнего выбранного узла.
Разрешенная позиция конца выделения находится на
selection.$to
. В ProseMirror принято, что разрешенные позиции начинаются с
$
.
Чтобы найти следующий «разрез» в конце текущего узла разрешенной позиции, вы можете использовать метод after() . Это вернет позицию после завершения узла, поэтому нам нужно вычесть из нее единицу.
Наконец, нам нужно создать новый выбор и применить его, отправив преобразование документа с помощью метода setSelection() . Помните, что TextSelection требует создания экземпляра разрешенной позиции, а не номера позиции.
Если мы сложим все это вместе, мы сможем создать команду для этого:
import {TextSelection} from "prosemirror-state";
function moveToEnd (state, dispatch, view) {
// Don't dispatch this command if the selection is empty
if (state.selection.empty) return false;
// Subtract one so that it falls within the current node
const endPos = state.selection.$to.after() - 1;
const selection = new TextSelection(state.doc.resolve(endPos));
let transaction = state.tr.setSelection(selection);
if (dispatch) dispatch(transaction.scrollIntoView());
return true;
}
Вы можете использовать эту команду с модулем раскладки клавиатуры при создании экземпляра редактора:
keymap({
'Mod-Shift-j': moveToEnd
})