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

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

View File

@@ -1,24 +1,18 @@
import { EditorState, Plugin, Transaction } from 'prosemirror-state'
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 removeElement from './utils/removeElement'
import getSchemaTypeNameByName from './utils/getSchemaTypeNameByName'
import getHTMLFromFragment from './utils/getHTMLFromFragment'
import createStyleTag from './utils/createStyleTag'
import magicMethods from './utilities/magicMethods'
import elementFromString from './utilities/elementFromString'
import getNodeAttributes from './helpers/getNodeAttributes'
import getMarkAttributes from './helpers/getMarkAttributes'
import isActive from './helpers/isActive'
import removeElement from './utilities/removeElement'
import getHTMLFromFragment from './helpers/getHTMLFromFragment'
import createStyleTag from './utilities/createStyleTag'
import CommandManager from './CommandManager'
import ExtensionManager from './ExtensionManager'
import EventEmitter from './EventEmitter'
import {
EditorOptions,
EditorContent,
CommandSpec,
} from './types'
import { EditorOptions, EditorContent, CommandSpec } from './types'
import * as extensions from './extensions'
import style from './style'
@@ -334,7 +328,7 @@ export class Editor extends EventEmitter {
* @param name Name of the node
*/
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
*/
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.
*
* @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)
}
/**

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,7 +1,9 @@
import { EditorState } from 'prosemirror-state'
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
let marks: Mark[] = []

View File

@@ -1,7 +1,9 @@
import { EditorState } from 'prosemirror-state'
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
let nodes: Node[] = []

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
import { ParseRule } from 'prosemirror-model'
import { ExtensionAttribute } from '../types'
import fromString from './fromString'
import fromString from '../utilities/fromString'
/**
* 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 splitExtensions from './splitExtensions'
import callOrReturn from './callOrReturn'
import callOrReturn from '../utilities/callOrReturn'
export default function isList(name: string, extensions: 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 { MarkType } from 'prosemirror-model'
import markHasAttributes from './markHasAttributes'
import isEmptyObject from './isEmptyObject'
export default function markIsActive(state: EditorState, type: MarkType, attributes = {}) {
const {
@@ -17,7 +16,5 @@ export default function markIsActive(state: EditorState, type: MarkType, attribu
const hasAttributes = markHasAttributes(state, type, attributes)
return isEmptyObject(attributes)
? hasMark
: hasMark && hasAttributes
return hasMark && hasAttributes
}

View File

@@ -2,14 +2,17 @@ import { findParentNode, findSelectedNodeOfType } from 'prosemirror-utils'
import { EditorState } from 'prosemirror-state'
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 node = findSelectedNodeOfType(type)(state.selection)
|| findParentNode(predicate)(state.selection)
if (!Object.keys(attrs).length || !node) {
if (!Object.keys(attributes).length || !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 markPasteRule } from './pasteRules/markPasteRule'
export { default as getSchema } from './utils/getSchema'
export { default as generateHTML } from './utils/generateHTML'
export { default as getHTMLFromFragment } from './utils/getHTMLFromFragment'
export { default as getMarkAttributes } from './utils/getMarkAttributes'
export { default as mergeAttributes } from './utils/mergeAttributes'
export { default as getSchema } from './helpers/getSchema'
export { default as generateHTML } from './helpers/generateHTML'
export { default as getHTMLFromFragment } from './helpers/getHTMLFromFragment'
export { default as getMarkAttributes } from './helpers/getMarkAttributes'
export { default as mergeAttributes } from './utilities/mergeAttributes'
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))
}