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
})
Другие вопросы по тегам