add type to this context in extensions

This commit is contained in:
Philipp Kühn 2020-10-22 23:21:52 +02:00
parent 6746163dda
commit d8d33c7429
8 changed files with 258 additions and 64 deletions

View File

@ -8,7 +8,7 @@ import markIsActive from './utils/markIsActive'
import getNodeAttrs from './utils/getNodeAttrs'
import getMarkAttrs from './utils/getMarkAttrs'
import removeElement from './utils/removeElement'
import getSchemaTypeByName from './utils/getSchemaTypeByName'
import getSchemaTypeNameByName from './utils/getSchemaTypeNameByName'
import getHtmlFromFragment from './utils/getHtmlFromFragment'
import createStyleTag from './utils/createStyleTag'
import CommandManager from './CommandManager'
@ -109,7 +109,6 @@ export class Editor extends EventEmitter {
this.createCommandManager()
this.createExtensionManager()
this.createSchema()
// this.extensionManager.resolveConfigs()
this.createView()
this.registerCommands(coreCommands)
this.injectCSS()
@ -338,7 +337,7 @@ export class Editor extends EventEmitter {
* @param attrs Attributes of the node or mark
*/
public isActive(name: string, attrs = {}) {
const schemaType = getSchemaTypeByName(name, this.schema)
const schemaType = getSchemaTypeNameByName(name, this.schema)
if (schemaType === 'node') {
return nodeIsActive(this.state, this.schema.nodes[name], attrs)

View File

@ -1,3 +1,4 @@
import { MarkType, NodeType } from 'prosemirror-model'
import { Plugin } from 'prosemirror-state'
import { Editor } from './Editor'
import { GlobalAttributes } from './types'
@ -16,11 +17,9 @@ export interface ExtensionSpec<Options = {}, Commands = {}> {
/**
* Global attributes
*/
addGlobalAttributes?: (
this: {
options: Options,
},
) => GlobalAttributes,
addGlobalAttributes?: (this: {
options: Options,
}) => GlobalAttributes,
/**
* Commands
@ -28,6 +27,7 @@ export interface ExtensionSpec<Options = {}, Commands = {}> {
addCommands?: (this: {
options: Options,
editor: Editor,
type: NodeType | MarkType,
}) => Commands,
/**
@ -36,6 +36,7 @@ export interface ExtensionSpec<Options = {}, Commands = {}> {
addKeyboardShortcuts?: (this: {
options: Options,
editor: Editor,
type: NodeType | MarkType,
}) => {
[key: string]: any
},
@ -46,6 +47,7 @@ export interface ExtensionSpec<Options = {}, Commands = {}> {
addInputRules?: (this: {
options: Options,
editor: Editor,
// type: NodeType | MarkType,
}) => any[],
/**
@ -54,6 +56,7 @@ export interface ExtensionSpec<Options = {}, Commands = {}> {
addPasteRules?: (this: {
options: Options,
editor: Editor,
type: NodeType | MarkType,
}) => any[],
/**
@ -62,6 +65,7 @@ export interface ExtensionSpec<Options = {}, Commands = {}> {
addProseMirrorPlugins?: (this: {
options: Options,
editor: Editor,
type: NodeType | MarkType,
}) => Plugin[],
}

View File

@ -3,11 +3,11 @@ import { keymap } from 'prosemirror-keymap'
// import { Schema, Node as ProsemirrorNode } from 'prosemirror-model'
import { inputRules } from 'prosemirror-inputrules'
// import { EditorView, Decoration } from 'prosemirror-view'
import { Editor } from './Editor'
// import capitalize from './utils/capitalize'
import { Extensions } from './types'
import getSchema from './utils/getSchema'
import getSchemaTypeByName from './utils/getSchemaTypeByName'
export default class ExtensionManager {
@ -18,54 +18,39 @@ export default class ExtensionManager {
constructor(extensions: Extensions, editor: Editor) {
this.editor = editor
this.extensions = extensions
this.extensions.forEach(extension => {
const context = {
options: extension.options,
editor: this.editor,
type: getSchemaTypeByName(extension.name, this.schema),
}
const commands = extension.addCommands.bind(context)()
editor.registerCommands(commands)
})
}
// resolveConfigs() {
// this.extensions.forEach(extension => {
// const { editor } = this
// const { name } = extension.config
// const options = {
// ...extension.config.defaults,
// ...extension.options,
// }
// const type = extension.type === 'node'
// ? editor.schema.nodes[name]
// : editor.schema.marks[name]
// resolveExtensionConfig(extension, 'commands', {
// name, options, editor, type,
// })
// resolveExtensionConfig(extension, 'inputRules', {
// name, options, editor, type,
// })
// resolveExtensionConfig(extension, 'pasteRules', {
// name, options, editor, type,
// })
// resolveExtensionConfig(extension, 'keys', {
// name, options, editor, type,
// })
// resolveExtensionConfig(extension, 'plugins', {
// name, options, editor, type,
// })
// if (extension.config.commands) {
// editor.registerCommands(extension.config.commands)
// }
// })
// }
get schema() {
return getSchema(this.extensions)
}
get plugins(): Plugin[] {
// const plugins = collect(this.extensions)
// .flatMap(extension => extension.config.plugins)
// .filter(plugin => plugin)
// .toArray()
const plugins = this.extensions
.map(extension => {
const context = {
options: extension.options,
editor: this.editor,
type: getSchemaTypeByName(extension.name, this.schema),
}
return extension.addProseMirrorPlugins.bind(context)()
})
.flat()
return [
// ...plugins,
...plugins,
...this.keymaps,
...this.pasteRules,
inputRules({ rules: this.inputRules }),
@ -73,19 +58,31 @@ export default class ExtensionManager {
}
get inputRules(): any {
return []
// return collect(this.extensions)
// .flatMap(extension => extension.config.inputRules)
// .filter(plugin => plugin)
// .toArray()
return this.extensions
.map(extension => {
const context = {
options: extension.options,
editor: this.editor,
type: getSchemaTypeByName(extension.name, this.schema),
}
return extension.addInputRules.bind(context)()
})
.flat()
}
get pasteRules(): any {
return []
// return collect(this.extensions)
// .flatMap(extension => extension.config.pasteRules)
// .filter(plugin => plugin)
// .toArray()
return this.extensions
.map(extension => {
const context = {
options: extension.options,
editor: this.editor,
type: getSchemaTypeByName(extension.name, this.schema),
}
return extension.addPasteRules.bind(context)()
})
.flat()
}
get keymaps() {
@ -93,6 +90,7 @@ export default class ExtensionManager {
const context = {
options: extension.options,
editor: this.editor,
type: getSchemaTypeByName(extension.name, this.schema),
}
return keymap(extension.addKeyboardShortcuts.bind(context)())

View File

@ -1,17 +1,44 @@
import { DOMOutputSpec, MarkSpec, Mark } from 'prosemirror-model'
import {
DOMOutputSpec, MarkSpec, Mark, MarkType,
} from 'prosemirror-model'
import { Plugin } from 'prosemirror-state'
import { ExtensionSpec, defaultExtension } from './Extension'
import { Attributes } from './types'
import { Editor } from './Editor'
export interface MarkExtensionSpec<Options = {}, Commands = {}> extends ExtensionSpec<Options, Commands> {
/**
* Inclusive
*/
inclusive?: MarkSpec['inclusive'],
/**
* Excludes
*/
excludes?: MarkSpec['excludes'],
/**
* Group
*/
group?: MarkSpec['group'],
/**
* Spanning
*/
spanning?: MarkSpec['spanning'],
/**
* Parse HTML
*/
parseHTML?: (
this: {
options: Options,
},
) => MarkSpec['parseDOM'],
/**
* Render HTML
*/
renderHTML?: (
this: {
options: Options,
@ -21,11 +48,62 @@ export interface MarkExtensionSpec<Options = {}, Commands = {}> extends Extensio
attributes: { [key: string]: any },
}
) => DOMOutputSpec,
/**
* Attributes
*/
addAttributes?: (
this: {
options: Options,
},
) => Attributes,
/**
* Commands
*/
addCommands?: (this: {
options: Options,
editor: Editor,
type: MarkType,
}) => Commands,
/**
* Keyboard shortcuts
*/
addKeyboardShortcuts?: (this: {
options: Options,
editor: Editor,
type: MarkType,
}) => {
[key: string]: any
},
/**
* Input rules
*/
addInputRules?: (this: {
options: Options,
editor: Editor,
type: MarkType,
}) => any[],
/**
* Paste rules
*/
addPasteRules?: (this: {
options: Options,
editor: Editor,
type: MarkType,
}) => any[],
/**
* ProseMirror plugins
*/
addProseMirrorPlugins?: (this: {
options: Options,
editor: Editor,
type: MarkType,
}) => Plugin[],
}
export type MarkExtension = Required<Omit<MarkExtensionSpec, 'defaultOptions'> & {

View File

@ -1,28 +1,79 @@
import { DOMOutputSpec, NodeSpec, Node } from 'prosemirror-model'
import {
DOMOutputSpec, NodeSpec, Node, NodeType,
} from 'prosemirror-model'
import { Plugin } from 'prosemirror-state'
import { ExtensionSpec, defaultExtension } from './Extension'
import { Attributes } from './types'
import { Editor } from './Editor'
export interface NodeExtensionSpec<Options = {}, Commands = {}> extends ExtensionSpec<Options, Commands> {
/**
* TopNode
*/
topNode?: boolean,
/**
* content
* Content
*/
content?: NodeSpec['content'],
/**
* Marks
*/
marks?: NodeSpec['marks'],
/**
* Group
*/
group?: NodeSpec['group'],
/**
* Inline
*/
inline?: NodeSpec['inline'],
/**
* Atom
*/
atom?: NodeSpec['atom'],
/**
* Selectable
*/
selectable?: NodeSpec['selectable'],
/**
* Draggable
*/
draggable?: NodeSpec['draggable'],
/**
* Code
*/
code?: NodeSpec['code'],
/**
* Defining
*/
defining?: NodeSpec['defining'],
/**
* Isolating
*/
isolating?: NodeSpec['isolating'],
/**
* Parse HTML
*/
parseHTML?: (
this: {
options: Options,
},
) => NodeSpec['parseDOM'],
/**
* Render HTML
*/
renderHTML?: (
this: {
options: Options,
@ -32,11 +83,62 @@ export interface NodeExtensionSpec<Options = {}, Commands = {}> extends Extensio
attributes: { [key: string]: any },
}
) => DOMOutputSpec,
/**
* Add Attributes
*/
addAttributes?: (
this: {
options: Options,
},
) => Attributes,
/**
* Commands
*/
addCommands?: (this: {
options: Options,
editor: Editor,
type: NodeType,
}) => Commands,
/**
* Keyboard shortcuts
*/
addKeyboardShortcuts?: (this: {
options: Options,
editor: Editor,
type: NodeType,
}) => {
[key: string]: any
},
/**
* Input rules
*/
addInputRules?: (this: {
options: Options,
editor: Editor,
type: NodeType,
}) => any[],
/**
* Paste rules
*/
addPasteRules?: (this: {
options: Options,
editor: Editor,
type: NodeType,
}) => any[],
/**
* ProseMirror plugins
*/
addProseMirrorPlugins?: (this: {
options: Options,
editor: Editor,
type: NodeType,
}) => Plugin[],
}
export type NodeExtension = Required<Omit<NodeExtensionSpec, 'defaultOptions'> & {

View File

@ -2,11 +2,11 @@ import { Schema } from 'prosemirror-model'
export default function getSchemaTypeByName(name: string, schema: Schema) {
if (schema.nodes[name]) {
return 'node'
return schema.nodes[name]
}
if (schema.marks[name]) {
return 'mark'
return schema.marks[name]
}
return null

View File

@ -0,0 +1,13 @@
import { Schema } from 'prosemirror-model'
export default function getSchemaTypeNameByName(name: string, schema: Schema) {
if (schema.nodes[name]) {
return 'node'
}
if (schema.marks[name]) {
return 'mark'
}
return null
}

View File

@ -17,7 +17,7 @@ const Code = createMark({
},
renderHTML({ attributes }) {
return ['strong', attributes, 0]
return ['code', attributes, 0]
},
addCommands() {