mirror of
https://github.com/ueberdosis/tiptap.git
synced 2024-11-24 19:59:02 +08:00
improve isActive for marks
This commit is contained in:
parent
4fbdb0ff0c
commit
c0911c315c
@ -1,8 +1,6 @@
|
||||
import { EditorState } from 'prosemirror-state'
|
||||
import { Node, Mark } from 'prosemirror-model'
|
||||
import nodeIsActive from './nodeIsActive'
|
||||
import markIsActive from './markIsActive'
|
||||
import objectIncludes from '../utilities/objectIncludes'
|
||||
import getSchemaTypeNameByName from './getSchemaTypeNameByName'
|
||||
|
||||
export default function isActive(state: EditorState, name: string | null, attributes: { [key: string ]: any } = {}): boolean {
|
||||
@ -14,32 +12,9 @@ export default function isActive(state: EditorState, name: string | null, attrib
|
||||
} if (schemaType === 'mark') {
|
||||
return markIsActive(state, state.schema.marks[name], attributes)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
const { from, to, empty } = state.selection
|
||||
let nodes: Node[] = []
|
||||
let marks: Mark[] = []
|
||||
|
||||
if (empty) {
|
||||
marks = state.selection.$head.marks()
|
||||
}
|
||||
|
||||
state.doc.nodesBetween(from, to, node => {
|
||||
nodes = [...nodes, node]
|
||||
|
||||
if (!empty) {
|
||||
marks = [...marks, ...node.marks]
|
||||
}
|
||||
})
|
||||
|
||||
const anyNodeWithAttributes = nodes.find(node => objectIncludes(node.attrs, attributes))
|
||||
const anyMarkWithAttributes = marks.find(mark => objectIncludes(mark.attrs, attributes))
|
||||
|
||||
if (anyNodeWithAttributes || anyMarkWithAttributes) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
return nodeIsActive(state, null, attributes) || markIsActive(state, null, attributes)
|
||||
}
|
||||
|
@ -1,15 +0,0 @@
|
||||
import { EditorState } from 'prosemirror-state'
|
||||
import { MarkType } from 'prosemirror-model'
|
||||
import getMarkAttributes from './getMarkAttributes'
|
||||
import isEmptyObject from '../utilities/isEmptyObject'
|
||||
import objectIncludes from '../utilities/objectIncludes'
|
||||
|
||||
export default function markHasAttributes(state: EditorState, type: MarkType, attributes: {}) {
|
||||
if (isEmptyObject(attributes)) {
|
||||
return true
|
||||
}
|
||||
|
||||
const originalAttributes = getMarkAttributes(state, type)
|
||||
|
||||
return objectIncludes(originalAttributes, attributes)
|
||||
}
|
@ -1,20 +1,33 @@
|
||||
import { EditorState } from 'prosemirror-state'
|
||||
import { MarkType } from 'prosemirror-model'
|
||||
import markHasAttributes from './markHasAttributes'
|
||||
import { Mark, MarkType } from 'prosemirror-model'
|
||||
import objectIncludes from '../utilities/objectIncludes'
|
||||
import getMarkType from '../helpers/getMarkType'
|
||||
|
||||
export default function markIsActive(state: EditorState, type: MarkType, attributes = {}) {
|
||||
const {
|
||||
from,
|
||||
$from,
|
||||
to,
|
||||
empty,
|
||||
} = state.selection
|
||||
export default function markIsActive(state: EditorState, typeOrName: MarkType | string | null, attributes = {}) {
|
||||
const { from, to, empty } = state.selection
|
||||
const type = typeOrName
|
||||
? getMarkType(typeOrName, state.schema)
|
||||
: null
|
||||
|
||||
const hasMark = empty
|
||||
? !!(type.isInSet(state.storedMarks || $from.marks()))
|
||||
: state.doc.rangeHasMark(from, to, type)
|
||||
let marks: Mark[] = []
|
||||
|
||||
const hasAttributes = markHasAttributes(state, type, attributes)
|
||||
if (empty) {
|
||||
marks = state.selection.$head.marks()
|
||||
} else {
|
||||
state.doc.nodesBetween(from, to, node => {
|
||||
marks = [...marks, ...node.marks]
|
||||
})
|
||||
}
|
||||
|
||||
return hasMark && hasAttributes
|
||||
const markWithAttributes = marks
|
||||
.filter(mark => {
|
||||
if (!type) {
|
||||
return true
|
||||
}
|
||||
|
||||
return type.name === mark.type.name
|
||||
})
|
||||
.find(mark => objectIncludes(mark.attrs, attributes))
|
||||
|
||||
return !!markWithAttributes
|
||||
}
|
||||
|
@ -1,18 +1,29 @@
|
||||
import { findParentNode, findSelectedNodeOfType } from 'prosemirror-utils'
|
||||
import { EditorState } from 'prosemirror-state'
|
||||
import { Node, NodeType } from 'prosemirror-model'
|
||||
import objectIncludes from '../utilities/objectIncludes'
|
||||
import getNodeType from '../helpers/getNodeType'
|
||||
|
||||
export default function nodeIsActive(state: EditorState, type: NodeType, attributes = {}) {
|
||||
const predicate = (node: Node) => node.type === type
|
||||
const node = findSelectedNodeOfType(type)(state.selection)
|
||||
|| findParentNode(predicate)(state.selection)
|
||||
export default function nodeIsActive(state: EditorState, typeOrName: NodeType | string | null, attributes = {}) {
|
||||
const { from, to } = state.selection
|
||||
const type = typeOrName
|
||||
? getNodeType(typeOrName, state.schema)
|
||||
: null
|
||||
|
||||
if (!Object.keys(attributes).length || !node) {
|
||||
return !!node
|
||||
}
|
||||
let nodes: Node[] = []
|
||||
|
||||
return node.node.hasMarkup(type, {
|
||||
...node.node.attrs,
|
||||
...attributes,
|
||||
state.doc.nodesBetween(from, to, node => {
|
||||
nodes = [...nodes, node]
|
||||
})
|
||||
|
||||
const nodeWithAttributes = nodes
|
||||
.filter(node => {
|
||||
if (!type) {
|
||||
return true
|
||||
}
|
||||
|
||||
return type.name === node.type.name
|
||||
})
|
||||
.find(node => objectIncludes(node.attrs, attributes))
|
||||
|
||||
return !!nodeWithAttributes
|
||||
}
|
||||
|
@ -4,8 +4,13 @@
|
||||
* @param object2 Object
|
||||
*/
|
||||
export default function objectIncludes(object1: { [key: string ]: any }, object2: { [key: string ]: any }): boolean {
|
||||
return !!Object
|
||||
.keys(object2)
|
||||
const keys = Object.keys(object2)
|
||||
|
||||
if (!keys.length) {
|
||||
return true
|
||||
}
|
||||
|
||||
return !!keys
|
||||
.filter(key => object2[key] === object1[key])
|
||||
.length
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user