remove registerCommands

This commit is contained in:
Philipp Kühn
2021-02-10 14:52:08 +01:00
parent 290ff76e37
commit 2340840621
4 changed files with 25 additions and 61 deletions

View File

@@ -4,6 +4,7 @@ import {
SingleCommands, SingleCommands,
ChainedCommands, ChainedCommands,
CanCommands, CanCommands,
Commands,
CommandSpec, CommandSpec,
CommandProps, CommandProps,
} from './types' } from './types'
@@ -13,35 +14,16 @@ export default class CommandManager {
editor: Editor editor: Editor
commands: { [key: string]: any } = {} commands: Commands
methodNames: string[] = [] methodNames: string[] = []
constructor(editor: Editor) { constructor(editor: Editor, commands: Commands) {
this.editor = editor this.editor = editor
this.commands = commands
this.methodNames = getAllMethodNames(this.editor) this.methodNames = getAllMethodNames(this.editor)
} }
/**
* Register a command.
*
* @param name The name of your command
* @param callback The method of your command
*/
public registerCommand(name: string, callback: CommandSpec): Editor {
if (this.commands[name]) {
throw new Error(`tiptap: command '${name}' is already defined.`)
}
if (this.methodNames.includes(name)) {
throw new Error(`tiptap: '${name}' is a protected name.`)
}
this.commands[name] = callback
return this.editor
}
public createCommands(): SingleCommands { public createCommands(): SingleCommands {
const { commands, editor } = this const { commands, editor } = this
const { state, view } = editor const { state, view } = editor
@@ -73,7 +55,7 @@ export default class CommandManager {
const tr = startTr || state.tr const tr = startTr || state.tr
return new Proxy({}, { return new Proxy({}, {
get: (_, name: string, proxy) => { get: (_, name: keyof ChainedCommands, proxy) => {
if (name === 'run') { if (name === 'run') {
if (!hasStartTransaction && shouldDispatch && !tr.getMeta('preventDispatch')) { if (!hasStartTransaction && shouldDispatch && !tr.getMeta('preventDispatch')) {
view.dispatch(tr) view.dispatch(tr)
@@ -82,13 +64,13 @@ export default class CommandManager {
return () => callbacks.every(callback => callback === true) return () => callbacks.every(callback => callback === true)
} }
const command = commands[name] const command = commands[name] as CommandSpec
if (!command) { if (!command) {
throw new Error(`tiptap: command '${name}' not found.`) throw new Error(`tiptap: command '${name}' not found.`)
} }
return (...args: any) => { return (...args: any[]) => {
const props = this.buildProps(tr, shouldDispatch) const props = this.buildProps(tr, shouldDispatch)
const callback = command(...args)(props) const callback = command(...args)(props)

View File

@@ -15,8 +15,6 @@ import EventEmitter from './EventEmitter'
import { import {
EditorOptions, EditorOptions,
EditorContent, EditorContent,
CommandSpec,
Commands,
CanCommands, CanCommands,
ChainedCommands, ChainedCommands,
SingleCommands, SingleCommands,
@@ -78,8 +76,8 @@ export class Editor extends EventEmitter {
* This method is called after the proxy is initialized. * This method is called after the proxy is initialized.
*/ */
private init(): void { private init(): void {
this.createCommandManager()
this.createExtensionManager() this.createExtensionManager()
this.createCommandManager()
this.createSchema() this.createSchema()
this.createView() this.createView()
this.injectCSS() this.injectCSS()
@@ -164,29 +162,6 @@ export class Editor extends EventEmitter {
return this.view.state return this.view.state
} }
/**
* Register a list of commands.
*
* @param commands A list of commands
*/
public registerCommands(commands: { [key: string]: CommandSpec }): void {
Object
.entries(commands)
.forEach(([name, command]) => this.registerCommand(name, command))
}
/**
* Register a command.
*
* @param name The name of your command
* @param callback The method of your command
*/
public registerCommand(name: string, callback: CommandSpec): Editor {
this.commandManager.registerCommand(name, callback)
return this.proxy
}
/** /**
* Register a ProseMirror plugin. * Register a ProseMirror plugin.
* *
@@ -233,7 +208,7 @@ export class Editor extends EventEmitter {
* Creates an command manager. * Creates an command manager.
*/ */
private createCommandManager(): void { private createCommandManager(): void {
this.commandManager = new CommandManager(this.proxy) this.commandManager = new CommandManager(this.proxy, this.extensionManager.commands)
} }
/** /**

View File

@@ -4,7 +4,7 @@ import { inputRules as inputRulesPlugin } from 'prosemirror-inputrules'
import { EditorView, Decoration } from 'prosemirror-view' import { EditorView, Decoration } from 'prosemirror-view'
import { Plugin } from 'prosemirror-state' import { Plugin } from 'prosemirror-state'
import { Editor } from './Editor' import { Editor } from './Editor'
import { Extensions, NodeViewRenderer } from './types' import { Extensions, NodeViewRenderer, Commands } from './types'
import getSchema from './helpers/getSchema' import getSchema from './helpers/getSchema'
import getSchemaTypeByName from './helpers/getSchemaTypeByName' import getSchemaTypeByName from './helpers/getSchemaTypeByName'
import getNodeType from './helpers/getNodeType' import getNodeType from './helpers/getNodeType'
@@ -32,11 +32,6 @@ export default class ExtensionManager {
type: getSchemaTypeByName(extension.config.name, this.schema), type: getSchemaTypeByName(extension.config.name, this.schema),
} }
const commands = extension.config.addCommands.bind(context)()
// @ts-ignore
editor.registerCommands(commands)
if (typeof extension.config.onCreate === 'function') { if (typeof extension.config.onCreate === 'function') {
this.editor.on('create', extension.config.onCreate.bind(context)) this.editor.on('create', extension.config.onCreate.bind(context))
} }
@@ -67,6 +62,21 @@ export default class ExtensionManager {
}) })
} }
get commands(): Commands {
return this.extensions.reduce((extensions, extension) => {
const context = {
options: extension.options,
editor: this.editor,
type: getSchemaTypeByName(extension.config.name, this.schema),
}
return {
...extensions,
...extension.config.addCommands.bind(context)(),
}
}, {} as Commands)
}
get plugins(): Plugin[] { get plugins(): Plugin[] {
return [...this.extensions] return [...this.extensions]
.reverse() .reverse()

View File

@@ -120,9 +120,6 @@ export type NodeViewRenderer = (props: NodeViewRendererProps) => (NodeView | {})
export type ValuesOf<T> = T[keyof T]; export type ValuesOf<T> = T[keyof T];
export type KeysWithTypeOf<T, Type> = ({[P in keyof T]: T[P] extends Type ? P : never })[keyof T] export type KeysWithTypeOf<T, Type> = ({[P in keyof T]: T[P] extends Type ? P : never })[keyof T]
// export type Commands = UnionToIntersection<ValuesOf<Pick<UnfilteredCommands, KeysWithTypeOf<UnfilteredCommands, {}>>>>
// export type Commands = Commands
export type SingleCommands = { export type SingleCommands = {
[Item in keyof Commands]: Commands[Item] extends (...args: any[]) => any [Item in keyof Commands]: Commands[Item] extends (...args: any[]) => any