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

32 lines
1.2 KiB
TypeScript
Raw Normal View History

2019-12-15 06:54:20 +08:00
import { DOMParser } from 'prosemirror-model'
2020-09-22 05:44:35 +08:00
import { Selection, Transaction } from 'prosemirror-state'
2020-09-24 06:29:05 +08:00
import { ReplaceStep, ReplaceAroundStep } from 'prosemirror-transform'
2019-12-17 06:51:18 +08:00
import elementFromString from '../utils/elementFromString'
2020-11-17 04:42:35 +08:00
import { Command } from '../types'
2019-12-15 06:54:20 +08:00
2020-09-21 05:19:27 +08:00
// TODO: move to utils
// https://github.com/ProseMirror/prosemirror-state/blob/master/src/selection.js#L466
2020-09-22 05:44:35 +08:00
function selectionToInsertionEnd(tr: Transaction, startLen: number, bias: number) {
2020-09-24 06:29:05 +08:00
const last = tr.steps.length - 1
2020-09-21 05:19:27 +08:00
if (last < startLen) return
2020-09-24 06:29:05 +08:00
const step = tr.steps[last]
2020-09-21 05:19:27 +08:00
if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep)) return
2020-09-24 06:29:05 +08:00
const map = tr.mapping.maps[last]
2020-09-22 05:44:35 +08:00
let end = 0
2020-09-24 06:29:05 +08:00
map.forEach((_from, _to, _newFrom, newTo) => { if (end === 0) end = newTo })
2020-09-22 05:44:35 +08:00
tr.setSelection(Selection.near(tr.doc.resolve(end as unknown as number), bias))
2020-09-21 05:19:27 +08:00
}
2020-11-05 05:38:52 +08:00
export default (value: string): Command => ({ tr, state, dispatch }) => {
const { selection } = tr
const element = elementFromString(value)
const slice = DOMParser.fromSchema(state.schema).parseSlice(element)
2020-10-23 16:44:30 +08:00
2020-11-05 05:38:52 +08:00
if (dispatch) {
tr.insert(selection.anchor, slice.content)
selectionToInsertionEnd(tr, tr.steps.length - 1, -1)
2020-10-23 16:44:30 +08:00
}
2020-11-05 05:38:52 +08:00
return true
2020-09-24 06:29:05 +08:00
}