@milkdown/plugin-block
Version:
The block plugin of [milkdown](https://milkdown.dev/).
50 lines (38 loc) • 1.38 kB
text/typescript
import type { EditorView } from '@milkdown/prose/view'
import type { FilterNodes } from '../block-config'
import type { ActiveNode } from '../types'
export function selectRootNodeByDom(
view: EditorView,
coords: { x: number; y: number },
filterNodes: FilterNodes
): ActiveNode | null {
const root = view.dom.parentElement
if (!root) return null
try {
const pos = view.posAtCoords({
left: coords.x,
top: coords.y,
})?.inside
if (pos == null || pos < 0) return null
let $pos = view.state.doc.resolve(pos)
let node = view.state.doc.nodeAt(pos)
let element = view.nodeDOM(pos) as HTMLElement | null
const filter = (needLookup: boolean) => {
const checkDepth = $pos.depth >= 1 && $pos.index($pos.depth) === 0
const shouldLookUp = needLookup || checkDepth
if (!shouldLookUp) return
const ancestorPos = $pos.before($pos.depth)
node = view.state.doc.nodeAt(ancestorPos)
element = view.nodeDOM(ancestorPos) as HTMLElement | null
$pos = view.state.doc.resolve(ancestorPos)
if (!filterNodes($pos, node!)) filter(true)
}
// If filterNodes returns false, we should look up the parent node.
const filterResult = filterNodes($pos, node!)
filter(!filterResult)
if (!element || !node) return null
return { node, $pos, el: element }
} catch {
return null
}
}