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