tiptap/packages/core/src/commands/focus.ts

73 lines
1.6 KiB
TypeScript
Raw Normal View History

2020-11-21 06:44:23 +08:00
import { EditorState, TextSelection } from 'prosemirror-state'
2021-02-10 16:59:35 +08:00
import { Command, Commands, FocusPosition } from '../types'
2020-11-30 16:42:53 +08:00
import minMax from '../utilities/minMax'
2021-01-23 06:56:33 +08:00
import isTextSelection from '../helpers/isTextSelection'
2020-11-05 05:38:52 +08:00
2020-11-21 06:44:23 +08:00
function resolveSelection(state: EditorState, position: FocusPosition = null) {
if (!position) {
return null
2020-11-05 05:38:52 +08:00
}
if (position === 'start' || position === true) {
return {
from: 0,
to: 0,
}
}
if (position === 'end') {
2020-11-21 06:44:23 +08:00
const { size } = state.doc.content
2020-11-05 05:38:52 +08:00
return {
from: size,
2020-11-21 06:44:23 +08:00
to: size,
2020-11-05 05:38:52 +08:00
}
}
return {
2020-11-21 06:44:23 +08:00
from: position,
to: position,
2020-11-05 05:38:52 +08:00
}
}
2021-02-11 01:05:02 +08:00
declare module '@tiptap/core' {
2021-02-16 18:27:58 +08:00
interface AllCommands {
focus: {
/**
* Focus the editor at the given position.
*/
focus: (position?: FocusPosition) => Command,
}
2021-02-11 01:05:02 +08:00
}
}
2021-02-10 16:59:35 +08:00
export const focus: Commands['focus'] = (position = null) => ({
2020-11-18 02:36:27 +08:00
editor,
view,
tr,
dispatch,
2020-11-05 05:38:52 +08:00
}) => {
if ((view.hasFocus() && position === null) || position === false) {
return true
}
2021-01-23 06:56:33 +08:00
// we dont try to resolve a NodeSelection or CellSelection
if (dispatch && position === null && !isTextSelection(editor.state.selection)) {
view.focus()
return true
}
2020-11-27 21:52:19 +08:00
const { from, to } = resolveSelection(editor.state, position) || editor.state.selection
2020-11-05 05:38:52 +08:00
const { doc } = tr
const resolvedFrom = minMax(from, 0, doc.content.size)
const resolvedEnd = minMax(to, 0, doc.content.size)
const selection = TextSelection.create(doc, resolvedFrom, resolvedEnd)
if (dispatch) {
tr.setSelection(selection)
view.focus()
}
return true
}