invert markIsActive

This commit is contained in:
Philipp Kühn
2020-11-30 20:53:02 +01:00
parent dd840703d9
commit bdc5998bb1

View File

@@ -3,31 +3,62 @@ import { Mark, MarkType } from 'prosemirror-model'
import objectIncludes from '../utilities/objectIncludes' import objectIncludes from '../utilities/objectIncludes'
import getMarkType from '../helpers/getMarkType' import getMarkType from '../helpers/getMarkType'
type MarkRange = {
mark: Mark,
from: number,
to: number,
}
export default function markIsActive(state: EditorState, typeOrName: MarkType | string | null, attributes = {}) { export default function markIsActive(state: EditorState, typeOrName: MarkType | string | null, attributes = {}) {
const { from, to, empty } = state.selection const { from, to, empty } = state.selection
const type = typeOrName const type = typeOrName
? getMarkType(typeOrName, state.schema) ? getMarkType(typeOrName, state.schema)
: null : null
let marks: Mark[] = []
if (empty) { if (empty) {
marks = state.selection.$head.marks() return !!state.selection.$head.marks()
} else { .filter(mark => {
state.doc.nodesBetween(from, to, node => { if (!type) {
marks = [...marks, ...node.marks] return true
}) }
return type.name === mark.type.name
})
.find(mark => objectIncludes(mark.attrs, attributes))
} }
const markWithAttributes = marks let selectionRange = 0
.filter(mark => { let markRanges: MarkRange[] = []
state.doc.nodesBetween(from, to, (node, pos) => {
if (node.isInline) {
const relativeFrom = Math.max(from, pos)
const relativeTo = Math.min(to, pos + node.nodeSize)
const range = relativeTo - relativeFrom
selectionRange += range
markRanges = [...markRanges, ...node.marks.map(mark => ({
mark,
from: relativeFrom,
to: relativeTo,
}))]
}
})
const range = markRanges
.filter(markRange => {
if (!type) { if (!type) {
return true return true
} }
return type.name === mark.type.name return type.name === markRange.mark.type.name
}) })
.find(mark => objectIncludes(mark.attrs, attributes)) .filter(markRange => objectIncludes(markRange.mark.attrs, attributes))
.reduce((sum, markRange) => {
const size = markRange.to - markRange.from
return sum + size
}, 0)
return !!markWithAttributes return selectionRange <= range
} }