Merge branch 'main' of github.com:ueberdosis/tiptap-next into main

This commit is contained in:
Hans Pagel
2020-11-30 13:35:57 +01:00
61 changed files with 209 additions and 147 deletions

View File

@@ -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',

View File

@@ -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>
@@ -73,40 +73,50 @@ export default {
HardBreak, HardBreak,
], ],
content: ` content: `
<h3>Girls Just Want to Have Fun (Cyndi Lauper)</h2> <h3>
<p>I come home in the morning light<br> Girls Just Want to Have Fun (Cyndi Lauper)
My mother says, “When you gonna live your life right?”<br> </h3>
Oh mother dear were not the fortunate ones<br> <p>
And girls, they wanna have fun<br> I come home in the morning light<br>
Oh girls just want to have fun</p> My mother says, “When you gonna live your life right?”<br>
<p style="text-align: center">The phone rings in the middle of the night<br> Oh mother dear were not the fortunate ones<br>
My father yells, "What you gonna do with your life?"<br> And girls, they wanna have fun<br>
Oh daddy dear, you know youre still number one<br> Oh girls just want to have fun</p>
But girls, they wanna have fun<br> <p style="text-align: center">The phone rings in the middle of the night<br>
Oh girls just want to have</p> My father yells, "What you gonna do with your life?"<br>
<p style="text-align:right">Thats all they really want<br> Oh daddy dear, you know youre still number one<br>
Some fun<br> But girls, they wanna have fun<br>
When the working day is done<br> Oh girls just want to have
Oh girls, they wanna have fun<br> </p>
Oh girls just wanna have fun<br> <p style="text-align:right">
(girls, they wanna, wanna have fun, girls wanna have)</p> Thats all they really want<br>
<p style="text-align:justify">Some boys take a beautiful girl Some fun<br>
And hide her away from the rest of the world When the working day is done<br>
I want to be the one to walk in the sun Oh girls, they wanna have fun<br>
Oh girls, they wanna have fun Oh girls just wanna have fun<br>
Oh girls just wanna have</p> (girls, they wanna, wanna have fun, girls wanna have)
<p style="text-align:justify">That's all they really want </p>
Some fun <p style="text-align:justify">
When the working day is done Some boys take a beautiful girl
Oh girls, they wanna have fun And hide her away from the rest of the world
Oh girls just want to have fun (girls, they wanna, wanna have fun, girls wanna have) I want to be the one to walk in the sun
They just wanna, they just wanna (girls) Oh girls, they wanna have fun
They just wanna, they just wanna, oh girl (girls just wanna have fun) Oh girls just wanna have
Girls just wanna have fun </p>
They just wanna, they just wanna <p style="text-align:justify">
They just wanna, they just wanna (girls) That's all they really want
They just wanna, they just wanna, oh girl (girls just wanna have fun) Some fun
Girls just want to have fun</p> When the working day is done
Oh girls, they wanna have fun
Oh girls just want to have fun (girls, they wanna, wanna have fun, girls wanna have)
They just wanna, they just wanna (girls)
They just wanna, they just wanna, oh girl (girls just wanna have fun)
Girls just wanna have fun
They just wanna, they just wanna
They just wanna, they just wanna (girls)
They just wanna, they just wanna, oh girl (girls just wanna have fun)
Girls just want to have fun
</p>
`, `,
}) })
}, },

View File

@@ -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()">

View File

@@ -6,7 +6,7 @@ import {
CanCommands, CanCommands,
CommandSpec, CommandSpec,
} from './types' } from './types'
import getAllMethodNames from './utils/getAllMethodNames' import getAllMethodNames from './utilities/getAllMethodNames'
export default class CommandManager { export default class CommandManager {

View File

@@ -1,24 +1,18 @@
import { EditorState, Plugin, Transaction } from 'prosemirror-state' import { EditorState, Plugin, Transaction } from 'prosemirror-state'
import { EditorView } from 'prosemirror-view' 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 './utilities/magicMethods'
import elementFromString from './utils/elementFromString' import elementFromString from './utilities/elementFromString'
import nodeIsActive from './utils/nodeIsActive' import getNodeAttributes from './helpers/getNodeAttributes'
import markIsActive from './utils/markIsActive' import getMarkAttributes from './helpers/getMarkAttributes'
import getNodeAttributes from './utils/getNodeAttributes' import isActive from './helpers/isActive'
import getMarkAttributes from './utils/getMarkAttributes' import removeElement from './utilities/removeElement'
import removeElement from './utils/removeElement' import getHTMLFromFragment from './helpers/getHTMLFromFragment'
import getSchemaTypeNameByName from './utils/getSchemaTypeNameByName' import createStyleTag from './utilities/createStyleTag'
import getHTMLFromFragment from './utils/getHTMLFromFragment'
import createStyleTag from './utils/createStyleTag'
import CommandManager from './CommandManager' import CommandManager from './CommandManager'
import ExtensionManager from './ExtensionManager' import ExtensionManager from './ExtensionManager'
import EventEmitter from './EventEmitter' import EventEmitter from './EventEmitter'
import { import { EditorOptions, EditorContent, CommandSpec } from './types'
EditorOptions,
EditorContent,
CommandSpec,
} from './types'
import * as extensions from './extensions' import * as extensions from './extensions'
import style from './style' import style from './style'
@@ -334,7 +328,7 @@ export class Editor extends EventEmitter {
* @param name Name of the node * @param name Name of the node
*/ */
public getNodeAttributes(name: string) { public getNodeAttributes(name: string) {
return getNodeAttributes(this.state, this.schema.nodes[name]) return getNodeAttributes(this.state, name)
} }
/** /**
@@ -343,25 +337,27 @@ export class Editor extends EventEmitter {
* @param name Name of the mark * @param name Name of the mark
*/ */
public getMarkAttributes(name: string) { public getMarkAttributes(name: string) {
return getMarkAttributes(this.state, this.schema.marks[name]) return getMarkAttributes(this.state, name)
} }
/** /**
* 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)
} }
/** /**

View File

@@ -4,11 +4,11 @@ import { inputRules } from 'prosemirror-inputrules'
import { EditorView, Decoration } from 'prosemirror-view' import { EditorView, Decoration } from 'prosemirror-view'
import { Editor } from './Editor' import { Editor } from './Editor'
import { Extensions, NodeViewRenderer } from './types' import { Extensions, NodeViewRenderer } from './types'
import getSchema from './utils/getSchema' import getSchema from './helpers/getSchema'
import getSchemaTypeByName from './utils/getSchemaTypeByName' import getSchemaTypeByName from './helpers/getSchemaTypeByName'
import splitExtensions from './utils/splitExtensions' import splitExtensions from './helpers/splitExtensions'
import getAttributesFromExtensions from './utils/getAttributesFromExtensions' import getAttributesFromExtensions from './helpers/getAttributesFromExtensions'
import getRenderedAttributes from './utils/getRenderedAttributes' import getRenderedAttributes from './helpers/getRenderedAttributes'
export default class ExtensionManager { export default class ExtensionManager {

View File

@@ -1,8 +1,8 @@
import { TextSelection } from 'prosemirror-state' import { TextSelection } from 'prosemirror-state'
import { MarkType } from 'prosemirror-model' import { MarkType } from 'prosemirror-model'
import { Command } from '../types' import { Command } from '../types'
import getMarkType from '../utils/getMarkType' import getMarkType from '../helpers/getMarkType'
import getMarkRange from '../utils/getMarkRange' import getMarkRange from '../helpers/getMarkRange'
/** /**
* Extends the text selection to the current mark. * Extends the text selection to the current mark.

View File

@@ -1,6 +1,6 @@
import { EditorState, TextSelection } from 'prosemirror-state' import { EditorState, TextSelection } from 'prosemirror-state'
import { Command, FocusPosition } from '../types' import { Command, FocusPosition } from '../types'
import minMax from '../utils/minMax' import minMax from '../utilities/minMax'
function resolveSelection(state: EditorState, position: FocusPosition = null) { function resolveSelection(state: EditorState, position: FocusPosition = null) {
if (!position) { if (!position) {

View File

@@ -1,7 +1,7 @@
import { DOMParser } from 'prosemirror-model' import { DOMParser } from 'prosemirror-model'
import { Selection, Transaction } from 'prosemirror-state' import { Selection, Transaction } from 'prosemirror-state'
import { ReplaceStep, ReplaceAroundStep } from 'prosemirror-transform' import { ReplaceStep, ReplaceAroundStep } from 'prosemirror-transform'
import elementFromString from '../utils/elementFromString' import elementFromString from '../utilities/elementFromString'
import { Command } from '../types' import { Command } from '../types'
// TODO: move to utils // TODO: move to utils

View File

@@ -1,8 +1,8 @@
import { lift as originalLift } from 'prosemirror-commands' import { lift as originalLift } from 'prosemirror-commands'
import { NodeType } from 'prosemirror-model' import { NodeType } from 'prosemirror-model'
import { Command } from '../types' import { Command } from '../types'
import nodeIsActive from '../utils/nodeIsActive' import nodeIsActive from '../helpers/nodeIsActive'
import getNodeType from '../utils/getNodeType' import getNodeType from '../helpers/getNodeType'
/** /**
* Removes an existing wrap. * Removes an existing wrap.

View File

@@ -1,7 +1,7 @@
import { liftListItem as originalLiftListItem } from 'prosemirror-schema-list' import { liftListItem as originalLiftListItem } from 'prosemirror-schema-list'
import { NodeType } from 'prosemirror-model' import { NodeType } from 'prosemirror-model'
import { Command } from '../types' import { Command } from '../types'
import getNodeType from '../utils/getNodeType' import getNodeType from '../helpers/getNodeType'
/** /**
* Lift the list item into a wrapping list. * Lift the list item into a wrapping list.

View File

@@ -1,6 +1,6 @@
import { NodeType } from 'prosemirror-model' import { NodeType } from 'prosemirror-model'
import getNodeType from '../utils/getNodeType' import getNodeType from '../helpers/getNodeType'
import deleteProps from '../utils/deleteProps' import deleteProps from '../utilities/deleteProps'
import { Command } from '../types' import { Command } from '../types'
/** /**

View File

@@ -1,7 +1,7 @@
import { MarkType } from 'prosemirror-model' import { MarkType } from 'prosemirror-model'
import { Command } from '../types' import { Command } from '../types'
import getMarkType from '../utils/getMarkType' import getMarkType from '../helpers/getMarkType'
import getMarkAttributes from '../utils/getMarkAttributes' import getMarkAttributes from '../helpers/getMarkAttributes'
/** /**
* Add a mark with new attributes. * Add a mark with new attributes.

View File

@@ -1,7 +1,7 @@
import { NodeType } from 'prosemirror-model' import { NodeType } from 'prosemirror-model'
import { setBlockType } from 'prosemirror-commands' import { setBlockType } from 'prosemirror-commands'
import { Command } from '../types' import { Command } from '../types'
import getNodeType from '../utils/getNodeType' import getNodeType from '../helpers/getNodeType'
/** /**
* Replace a given range with a node. * Replace a given range with a node.

View File

@@ -1,7 +1,7 @@
import { sinkListItem as originalSinkListItem } from 'prosemirror-schema-list' import { sinkListItem as originalSinkListItem } from 'prosemirror-schema-list'
import { NodeType } from 'prosemirror-model' import { NodeType } from 'prosemirror-model'
import { Command } from '../types' import { Command } from '../types'
import getNodeType from '../utils/getNodeType' import getNodeType from '../helpers/getNodeType'
/** /**
* Sink the list item down into an inner list. * Sink the list item down into an inner list.

View File

@@ -1,7 +1,7 @@
import { splitListItem as originalSplitListItem } from 'prosemirror-schema-list' import { splitListItem as originalSplitListItem } from 'prosemirror-schema-list'
import { NodeType } from 'prosemirror-model' import { NodeType } from 'prosemirror-model'
import { Command } from '../types' import { Command } from '../types'
import getNodeType from '../utils/getNodeType' import getNodeType from '../helpers/getNodeType'
/** /**
* Splits one list item into two list items. * Splits one list item into two list items.

View File

@@ -1,8 +1,8 @@
import { findParentNode } from 'prosemirror-utils' import { findParentNode } from 'prosemirror-utils'
import { NodeType } from 'prosemirror-model' import { NodeType } from 'prosemirror-model'
import { Command } from '../types' import { Command } from '../types'
import getNodeType from '../utils/getNodeType' import getNodeType from '../helpers/getNodeType'
import isList from '../utils/isList' import isList from '../helpers/isList'
/** /**
* Toggle between different list types. * Toggle between different list types.

View File

@@ -1,8 +1,8 @@
import { toggleMark as originalToggleMark } from 'prosemirror-commands' import { toggleMark as originalToggleMark } from 'prosemirror-commands'
import { MarkType } from 'prosemirror-model' import { MarkType } from 'prosemirror-model'
import { Command } from '../types' import { Command } from '../types'
import getMarkType from '../utils/getMarkType' import getMarkType from '../helpers/getMarkType'
import markIsActive from '../utils/markIsActive' import markIsActive from '../helpers/markIsActive'
/** /**
* Toggle a mark on and off. * Toggle a mark on and off.

View File

@@ -1,7 +1,7 @@
import { NodeType } from 'prosemirror-model' import { NodeType } from 'prosemirror-model'
import { Command } from '../types' import { Command } from '../types'
import nodeIsActive from '../utils/nodeIsActive' import nodeIsActive from '../helpers/nodeIsActive'
import getNodeType from '../utils/getNodeType' import getNodeType from '../helpers/getNodeType'
/** /**
* Toggle a node with another node. * Toggle a node with another node.

View File

@@ -1,8 +1,8 @@
import { wrapIn, lift } from 'prosemirror-commands' import { wrapIn, lift } from 'prosemirror-commands'
import { NodeType } from 'prosemirror-model' import { NodeType } from 'prosemirror-model'
import { Command } from '../types' import { Command } from '../types'
import nodeIsActive from '../utils/nodeIsActive' import nodeIsActive from '../helpers/nodeIsActive'
import getNodeType from '../utils/getNodeType' import getNodeType from '../helpers/getNodeType'
/** /**
* Wraps nodes in another node, or removes an existing wrap. * Wraps nodes in another node, or removes an existing wrap.

View File

@@ -1,7 +1,7 @@
import { MarkType } from 'prosemirror-model' import { MarkType } from 'prosemirror-model'
import { Command } from '../types' import { Command } from '../types'
import getMarkType from '../utils/getMarkType' import getMarkType from '../helpers/getMarkType'
import getMarkRange from '../utils/getMarkRange' import getMarkRange from '../helpers/getMarkRange'
/** /**
* Remove all marks in the current selection. * Remove all marks in the current selection.

View File

@@ -1,5 +1,5 @@
import { NodeType } from 'prosemirror-model' import { NodeType } from 'prosemirror-model'
import getNodeType from '../utils/getNodeType' import getNodeType from '../helpers/getNodeType'
import { Command } from '../types' import { Command } from '../types'
/** /**

View File

@@ -1,8 +1,8 @@
import { wrapIn as originalWrapIn } from 'prosemirror-commands' import { wrapIn as originalWrapIn } from 'prosemirror-commands'
import { NodeType } from 'prosemirror-model' import { NodeType } from 'prosemirror-model'
import { Command } from '../types' import { Command } from '../types'
import nodeIsActive from '../utils/nodeIsActive' import nodeIsActive from '../helpers/nodeIsActive'
import getNodeType from '../utils/getNodeType' import getNodeType from '../helpers/getNodeType'
/** /**
* Wraps nodes in another node. * Wraps nodes in another node.

View File

@@ -1,7 +1,7 @@
import { wrapInList as originalWrapInList } from 'prosemirror-schema-list' import { wrapInList as originalWrapInList } from 'prosemirror-schema-list'
import { NodeType } from 'prosemirror-model' import { NodeType } from 'prosemirror-model'
import { Command } from '../types' import { Command } from '../types'
import getNodeType from '../utils/getNodeType' import getNodeType from '../helpers/getNodeType'
/** /**
* Wrap a node in a list. * Wrap a node in a list.

View File

@@ -1,7 +1,9 @@
import { EditorState } from 'prosemirror-state' import { EditorState } from 'prosemirror-state'
import { Mark, MarkType } from 'prosemirror-model' import { Mark, MarkType } from 'prosemirror-model'
import getMarkType from './getMarkType'
export default function getMarkAttributes(state: EditorState, type: MarkType) { export default function getMarkAttributes(state: EditorState, typeOrName: string | MarkType) {
const type = getMarkType(typeOrName, state.schema)
const { from, to, empty } = state.selection const { from, to, empty } = state.selection
let marks: Mark[] = [] let marks: Mark[] = []

View File

@@ -1,7 +1,9 @@
import { EditorState } from 'prosemirror-state' import { EditorState } from 'prosemirror-state'
import { Node, NodeType } from 'prosemirror-model' import { Node, NodeType } from 'prosemirror-model'
import getNodeType from './getNodeType'
export default function getNodeAttributes(state: EditorState, type: NodeType) { export default function getNodeAttributes(state: EditorState, typeOrName: string | NodeType) {
const type = getNodeType(typeOrName, state.schema)
const { from, to } = state.selection const { from, to } = state.selection
let nodes: Node[] = [] let nodes: Node[] = []

View File

@@ -1,6 +1,6 @@
import { Node, Mark } from 'prosemirror-model' import { Node, Mark } from 'prosemirror-model'
import { ExtensionAttribute, AnyObject } from '../types' import { ExtensionAttribute, AnyObject } from '../types'
import mergeAttributes from './mergeAttributes' import mergeAttributes from '../utilities/mergeAttributes'
export default function getRenderedAttributes(nodeOrMark: Node | Mark, extensionAttributes: ExtensionAttribute[]): AnyObject { export default function getRenderedAttributes(nodeOrMark: Node | Mark, extensionAttributes: ExtensionAttribute[]): AnyObject {
return extensionAttributes return extensionAttributes

View File

@@ -3,9 +3,9 @@ import { Extensions } from '../types'
import splitExtensions from './splitExtensions' import splitExtensions from './splitExtensions'
import getAttributesFromExtensions from './getAttributesFromExtensions' import getAttributesFromExtensions from './getAttributesFromExtensions'
import getRenderedAttributes from './getRenderedAttributes' import getRenderedAttributes from './getRenderedAttributes'
import isEmptyObject from './isEmptyObject' import isEmptyObject from '../utilities/isEmptyObject'
import injectExtensionAttributesToParseRule from './injectExtensionAttributesToParseRule' import injectExtensionAttributesToParseRule from './injectExtensionAttributesToParseRule'
import callOrReturn from './callOrReturn' import callOrReturn from '../utilities/callOrReturn'
function cleanUpSchemaItem<T>(data: T) { function cleanUpSchemaItem<T>(data: T) {
return Object.fromEntries(Object.entries(data).filter(([key, value]) => { return Object.fromEntries(Object.entries(data).filter(([key, value]) => {

View File

@@ -1,6 +1,6 @@
import { ParseRule } from 'prosemirror-model' import { ParseRule } from 'prosemirror-model'
import { ExtensionAttribute } from '../types' import { ExtensionAttribute } from '../types'
import fromString from './fromString' import fromString from '../utilities/fromString'
/** /**
* This function merges extension attributes into parserule attributes (`attrs` or `getAttrs`). * This function merges extension attributes into parserule attributes (`attrs` or `getAttrs`).

View 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 '../utilities/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
}

View File

@@ -1,6 +1,6 @@
import { Extensions } from '../types' import { Extensions } from '../types'
import splitExtensions from './splitExtensions' import splitExtensions from './splitExtensions'
import callOrReturn from './callOrReturn' import callOrReturn from '../utilities/callOrReturn'
export default function isList(name: string, extensions: Extensions) { export default function isList(name: string, extensions: Extensions) {
const { nodeExtensions } = splitExtensions(extensions) const { nodeExtensions } = splitExtensions(extensions)

View File

@@ -0,0 +1,15 @@
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)
}

View File

@@ -1,7 +1,6 @@
import { EditorState } from 'prosemirror-state' import { EditorState } from 'prosemirror-state'
import { MarkType } from 'prosemirror-model' import { MarkType } from 'prosemirror-model'
import markHasAttributes from './markHasAttributes' import markHasAttributes from './markHasAttributes'
import isEmptyObject from './isEmptyObject'
export default function markIsActive(state: EditorState, type: MarkType, attributes = {}) { export default function markIsActive(state: EditorState, type: MarkType, attributes = {}) {
const { const {
@@ -17,7 +16,5 @@ export default function markIsActive(state: EditorState, type: MarkType, attribu
const hasAttributes = markHasAttributes(state, type, attributes) const hasAttributes = markHasAttributes(state, type, attributes)
return isEmptyObject(attributes) return hasMark && hasAttributes
? hasMark
: hasMark && hasAttributes
} }

View File

@@ -2,14 +2,17 @@ import { findParentNode, findSelectedNodeOfType } from 'prosemirror-utils'
import { EditorState } from 'prosemirror-state' import { EditorState } from 'prosemirror-state'
import { Node, NodeType } from 'prosemirror-model' import { Node, NodeType } from 'prosemirror-model'
export default function nodeIsActive(state: EditorState, type: NodeType, attrs = {}) { export default function nodeIsActive(state: EditorState, type: NodeType, attributes = {}) {
const predicate = (node: Node) => node.type === type const predicate = (node: Node) => node.type === type
const node = findSelectedNodeOfType(type)(state.selection) const node = findSelectedNodeOfType(type)(state.selection)
|| findParentNode(predicate)(state.selection) || findParentNode(predicate)(state.selection)
if (!Object.keys(attrs).length || !node) { if (!Object.keys(attributes).length || !node) {
return !!node return !!node
} }
return node.node.hasMarkup(type, { ...node.node.attrs, ...attrs }) return node.node.hasMarkup(type, {
...node.node.attrs,
...attributes,
})
} }

View File

@@ -8,10 +8,10 @@ export { default as nodeInputRule } from './inputRules/nodeInputRule'
export { default as markInputRule } from './inputRules/markInputRule' export { default as markInputRule } from './inputRules/markInputRule'
export { default as markPasteRule } from './pasteRules/markPasteRule' export { default as markPasteRule } from './pasteRules/markPasteRule'
export { default as getSchema } from './utils/getSchema' export { default as getSchema } from './helpers/getSchema'
export { default as generateHTML } from './utils/generateHTML' export { default as generateHTML } from './helpers/generateHTML'
export { default as getHTMLFromFragment } from './utils/getHTMLFromFragment' export { default as getHTMLFromFragment } from './helpers/getHTMLFromFragment'
export { default as getMarkAttributes } from './utils/getMarkAttributes' export { default as getMarkAttributes } from './helpers/getMarkAttributes'
export { default as mergeAttributes } from './utils/mergeAttributes' export { default as mergeAttributes } from './utilities/mergeAttributes'
export interface AllExtensions {} export interface AllExtensions {}

View File

@@ -0,0 +1,11 @@
/**
* Check if object1 includes object2
* @param object1 Object
* @param object2 Object
*/
export default function objectIncludes(object1: { [key: string ]: any }, object2: { [key: string ]: any }): boolean {
return !!Object
.keys(object2)
.filter(key => object2[key] === object1[key])
.length
}

View File

@@ -1,18 +0,0 @@
import { EditorState } from 'prosemirror-state'
import { MarkType } from 'prosemirror-model'
import getMarkAttributes from './getMarkAttributes'
import { AnyObject } from '../types'
import isEmptyObject from './isEmptyObject'
export default function markHasAttributes(state: EditorState, type: MarkType, attributes: AnyObject) {
if (isEmptyObject(attributes)) {
return true
}
const originalAttrs = getMarkAttributes(state, type)
return !!Object
.keys(attributes)
.filter(key => attributes[key] === originalAttrs[key])
.length
}

View File

@@ -1,3 +0,0 @@
export default function sleep(milliseconds: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, milliseconds))
}

View File

@@ -1,6 +1,6 @@
/// <reference types="cypress" /> /// <reference types="cypress" />
import fromString from '@tiptap/core/src/utils/fromString' import fromString from '@tiptap/core/src/utilities/fromString'
describe('fromString', () => { describe('fromString', () => {
it('should return a string', () => { it('should return a string', () => {

View File

@@ -1,6 +1,6 @@
/// <reference types="cypress" /> /// <reference types="cypress" />
import mergeAttributes from '@tiptap/core/src/utils/mergeAttributes' import mergeAttributes from '@tiptap/core/src/utilities/mergeAttributes'
describe('mergeAttributes', () => { describe('mergeAttributes', () => {
it('should merge two objects', () => { it('should merge two objects', () => {

View File

@@ -12370,9 +12370,9 @@ rollup-pluginutils@^2.8.2:
estree-walker "^0.6.1" estree-walker "^0.6.1"
rollup@^2.33.3: rollup@^2.33.3:
version "2.33.3" version "2.34.0"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.33.3.tgz#ae72ce31f992b09a580072951bfea76e9df17342" resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.34.0.tgz#ecc7f1d4ce2cb88bb51bec2f56b984f3c35b8271"
integrity sha512-RpayhPTe4Gu/uFGCmk7Gp5Z9Qic2VsqZ040G+KZZvsZYdcuWaJg678JeDJJvJeEQXminu24a2au+y92CUWVd+w== integrity sha512-dW5iLvttZzdVehjEuNJ1bWvuMEJjOWGmnuFS82WeKHTGXDkRHQeq/ExdifkSyJv9dLcR86ysKRmrIDyR6O0X8g==
optionalDependencies: optionalDependencies:
fsevents "~2.1.2" fsevents "~2.1.2"