mirror of
https://github.com/ueberdosis/tiptap.git
synced 2024-11-27 14:59:27 +08:00
add support for only checking attributes in isActive
This commit is contained in:
parent
9a18cce546
commit
ec56158739
@ -66,6 +66,8 @@ module.exports = {
|
||||
'@typescript-eslint/no-use-before-define': ['error'],
|
||||
'no-dupe-class-members': 'off',
|
||||
'@typescript-eslint/no-dupe-class-members': ['error'],
|
||||
'lines-between-class-members': 'off',
|
||||
'@typescript-eslint/lines-between-class-members': ['error'],
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-empty-interface': 'off',
|
||||
'@typescript-eslint/explicit-module-boundary-type': 'off',
|
||||
|
@ -19,16 +19,16 @@
|
||||
<button @click="editor.chain().focus().setParagraph().run()" :class="{ 'is-active': editor.isActive('paragraph') }">
|
||||
paragraph
|
||||
</button>
|
||||
<button @click="editor.chain().focus().setTextAlign('left').run()">
|
||||
<button @click="editor.chain().focus().setTextAlign('left').run()" :class="{ 'is-active': editor.isActive({ textAlign: 'left' }) }">
|
||||
left
|
||||
</button>
|
||||
<button @click="editor.chain().focus().setTextAlign('center').run()">
|
||||
<button @click="editor.chain().focus().setTextAlign('center').run()" :class="{ 'is-active': editor.isActive({ textAlign: 'center' }) }">
|
||||
center
|
||||
</button>
|
||||
<button @click="editor.chain().focus().setTextAlign('right').run()">
|
||||
<button @click="editor.chain().focus().setTextAlign('right').run()" :class="{ 'is-active': editor.isActive({ textAlign: 'right' }) }">
|
||||
right
|
||||
</button>
|
||||
<button @click="editor.chain().focus().setTextAlign('justify').run()">
|
||||
<button @click="editor.chain().focus().setTextAlign('justify').run()" :class="{ 'is-active': editor.isActive({ textAlign: 'justify' }) }">
|
||||
justify
|
||||
</button>
|
||||
</div>
|
||||
|
@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<div v-if="editor">
|
||||
<button @click="editor.chain().focus().setTextAlign('left').run()">
|
||||
<button @click="editor.chain().focus().setTextAlign('left').run()" :class="{ 'is-active': editor.isActive({ textAlign: 'left' }) }">
|
||||
left
|
||||
</button>
|
||||
<button @click="editor.chain().focus().setTextAlign('center').run()">
|
||||
<button @click="editor.chain().focus().setTextAlign('center').run()" :class="{ 'is-active': editor.isActive({ textAlign: 'center' }) }">
|
||||
center
|
||||
</button>
|
||||
<button @click="editor.chain().focus().setTextAlign('right').run()">
|
||||
<button @click="editor.chain().focus().setTextAlign('right').run()" :class="{ 'is-active': editor.isActive({ textAlign: 'right' }) }">
|
||||
right
|
||||
</button>
|
||||
<button @click="editor.chain().focus().setTextAlign('justify').run()">
|
||||
<button @click="editor.chain().focus().setTextAlign('justify').run()" :class="{ 'is-active': editor.isActive({ textAlign: 'justify' }) }">
|
||||
justify
|
||||
</button>
|
||||
<button @click="editor.chain().focus().unsetTextAlign().run()">
|
||||
|
@ -3,12 +3,10 @@ import { EditorView } from 'prosemirror-view'
|
||||
import { Schema, DOMParser, Node } from 'prosemirror-model'
|
||||
import magicMethods from './utils/magicMethods'
|
||||
import elementFromString from './utils/elementFromString'
|
||||
import nodeIsActive from './utils/nodeIsActive'
|
||||
import markIsActive from './utils/markIsActive'
|
||||
import getNodeAttributes from './utils/getNodeAttributes'
|
||||
import getMarkAttributes from './utils/getMarkAttributes'
|
||||
import isActive from './utils/isActive'
|
||||
import removeElement from './utils/removeElement'
|
||||
import getSchemaTypeNameByName from './utils/getSchemaTypeNameByName'
|
||||
import getHTMLFromFragment from './utils/getHTMLFromFragment'
|
||||
import createStyleTag from './utils/createStyleTag'
|
||||
import CommandManager from './CommandManager'
|
||||
@ -350,18 +348,20 @@ export class Editor extends EventEmitter {
|
||||
* Returns if the currently selected node or mark is active.
|
||||
*
|
||||
* @param name Name of the node or mark
|
||||
* @param attrs Attributes of the node or mark
|
||||
* @param attributes Attributes of the node or mark
|
||||
*/
|
||||
public isActive(name: string, attrs = {}) {
|
||||
const schemaType = getSchemaTypeNameByName(name, this.schema)
|
||||
public isActive(name: string, attributes?: {}): boolean;
|
||||
public isActive(attributes: {}): boolean;
|
||||
public isActive(nameOrAttributes: string, attributesOrUndefined?: {}): boolean {
|
||||
const name = typeof nameOrAttributes === 'string'
|
||||
? nameOrAttributes
|
||||
: null
|
||||
|
||||
if (schemaType === 'node') {
|
||||
return nodeIsActive(this.state, this.schema.nodes[name], attrs)
|
||||
} if (schemaType === 'mark') {
|
||||
return markIsActive(this.state, this.schema.marks[name], attrs)
|
||||
}
|
||||
const attributes = typeof nameOrAttributes === 'string'
|
||||
? attributesOrUndefined
|
||||
: nameOrAttributes
|
||||
|
||||
return false
|
||||
return isActive(this.state, name, attributes)
|
||||
}
|
||||
|
||||
/**
|
||||
|
45
packages/core/src/utils/isActive.ts
Normal file
45
packages/core/src/utils/isActive.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { EditorState } from 'prosemirror-state'
|
||||
import { Node, Mark } from 'prosemirror-model'
|
||||
import nodeIsActive from './nodeIsActive'
|
||||
import markIsActive from './markIsActive'
|
||||
import objectIncludes from './objectIncludes'
|
||||
import getSchemaTypeNameByName from './getSchemaTypeNameByName'
|
||||
|
||||
export default function isActive(state: EditorState, name: string | null, attributes: { [key: string ]: any } = {}): boolean {
|
||||
if (name) {
|
||||
const schemaType = getSchemaTypeNameByName(name, state.schema)
|
||||
|
||||
if (schemaType === 'node') {
|
||||
return nodeIsActive(state, state.schema.nodes[name], attributes)
|
||||
} if (schemaType === 'mark') {
|
||||
return markIsActive(state, state.schema.marks[name], attributes)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
@ -3,16 +3,14 @@ import { MarkType } from 'prosemirror-model'
|
||||
import getMarkAttributes from './getMarkAttributes'
|
||||
import { AnyObject } from '../types'
|
||||
import isEmptyObject from './isEmptyObject'
|
||||
import objectIncludes from './objectIncludes'
|
||||
|
||||
export default function markHasAttributes(state: EditorState, type: MarkType, attributes: AnyObject) {
|
||||
if (isEmptyObject(attributes)) {
|
||||
return true
|
||||
}
|
||||
|
||||
const originalAttrs = getMarkAttributes(state, type)
|
||||
const originalAttributes = getMarkAttributes(state, type)
|
||||
|
||||
return !!Object
|
||||
.keys(attributes)
|
||||
.filter(key => attributes[key] === originalAttrs[key])
|
||||
.length
|
||||
return objectIncludes(originalAttributes, attributes)
|
||||
}
|
||||
|
6
packages/core/src/utils/objectIncludes.ts
Normal file
6
packages/core/src/utils/objectIncludes.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export default function objectIncludes(object1: { [key: string ]: any }, object2: { [key: string ]: any }): boolean {
|
||||
return !!Object
|
||||
.keys(object2)
|
||||
.filter(key => object2[key] === object1[key])
|
||||
.length
|
||||
}
|
Loading…
Reference in New Issue
Block a user