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-21 05:19:27 +08:00
|
|
|
import { Command } from '../Editor'
|
2019-12-17 06:51:18 +08:00
|
|
|
import elementFromString from '../utils/elementFromString'
|
2020-09-21 05:19:27 +08:00
|
|
|
import {ReplaceStep, ReplaceAroundStep} from "prosemirror-transform"
|
2019-12-15 06:54:20 +08:00
|
|
|
|
2020-09-21 05:19:27 +08:00
|
|
|
type InsertHTMLCommand = (value: string) => Command
|
2020-04-22 05:22:27 +08:00
|
|
|
|
2019-12-15 06:54:20 +08:00
|
|
|
declare module '../Editor' {
|
2020-09-22 16:49:38 +08:00
|
|
|
interface Commands {
|
2020-08-17 22:38:13 +08:00
|
|
|
insertHTML: InsertHTMLCommand,
|
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-21 05:19:27 +08:00
|
|
|
let last = tr.steps.length - 1
|
|
|
|
if (last < startLen) return
|
|
|
|
let step = tr.steps[last]
|
|
|
|
if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep)) return
|
2020-09-22 05:44:35 +08:00
|
|
|
let map = tr.mapping.maps[last]
|
|
|
|
let end = 0
|
|
|
|
map.forEach((_from, _to, _newFrom, newTo) => { if (end == 0) end = newTo })
|
|
|
|
tr.setSelection(Selection.near(tr.doc.resolve(end as unknown as number), bias))
|
2020-09-21 05:19:27 +08:00
|
|
|
}
|
|
|
|
|
2020-09-22 21:22:24 +08:00
|
|
|
export const insertHTML: InsertHTMLCommand = value => ({ tr, state }) => {
|
2020-09-21 05:19:27 +08:00
|
|
|
const { selection } = tr
|
2019-12-17 06:51:18 +08:00
|
|
|
const element = elementFromString(value)
|
2019-12-15 06:54:20 +08:00
|
|
|
const slice = DOMParser.fromSchema(state.schema).parseSlice(element)
|
|
|
|
|
2020-09-21 05:19:27 +08:00
|
|
|
tr.insert(selection.anchor, slice.content)
|
|
|
|
selectionToInsertionEnd(tr, tr.steps.length - 1, -1)
|
|
|
|
|
|
|
|
return true
|
2019-12-15 06:54:20 +08:00
|
|
|
}
|