From 020483f0b2085395dec83f4c2ddd0e8c9ea0f51a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Wed, 21 Oct 2020 15:17:05 +0200 Subject: [PATCH] add basic new syntax --- .eslintrc.js | 2 + packages/core/index.ts | 8 +- packages/core/src/Extension.ts | 60 ++++++++--- packages/core/src/Mark.ts | 26 ++--- packages/core/src/Node.ts | 138 ++++++++++++++++++++------ packages/core/src/utils/getSchema.ts | 21 ++-- packages/extension-document/index.ts | 20 ++-- packages/extension-paragraph/index.ts | 58 +++++++---- packages/extension-text/index.ts | 16 ++- packages/vue-starter-kit/index.ts | 10 +- 10 files changed, 249 insertions(+), 110 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index de47e986..44e8122a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -56,6 +56,8 @@ module.exports = { 'no-param-reassign': 'off', 'import/prefer-default-export': 'off', 'consistent-return': 'off', + 'no-redeclare': 'off', + '@typescript-eslint/no-redeclare': ['error'], 'no-unused-vars': 'off', '@typescript-eslint/no-unused-vars': ['error'], 'no-use-before-define': 'off', diff --git a/packages/core/index.ts b/packages/core/index.ts index 82b838f5..14693667 100644 --- a/packages/core/index.ts +++ b/packages/core/index.ts @@ -3,10 +3,12 @@ import { Editor, Command, CommandsSpec } from './src/Editor' export default Editor export { Editor, Command, CommandsSpec } export { default as ComponentRenderer } from './src/ComponentRenderer' -export { default as Extension } from './src/Extension' -export { default as Node } from './src/Node' +// export { default as Extension } from './src/Extension' +// export { default as Node } from './src/Node' +export * from './src/Extension' export * from './src/Node' -export { default as Mark } from './src/Mark' +export * from './src/Mark' +// export { default as Mark } from './src/Mark' export { Extensions } from './src/types' export { default as nodeInputRule } from './src/inputRules/nodeInputRule' diff --git a/packages/core/src/Extension.ts b/packages/core/src/Extension.ts index 4a166300..0a7d6044 100644 --- a/packages/core/src/Extension.ts +++ b/packages/core/src/Extension.ts @@ -113,27 +113,55 @@ // } // } -export default class Extension { +export interface Extension { + type: string, + name: string, + options: { + [key: string]: any + }, + createCommands(): { + [key: string]: any + }, +} - name = 'extension' +export interface ExtensionSpec { + name: string, + defaultOptions?: Options, + createCommands?(this: { + options: Options, + // editor: Editor, + }): Commands, +} - type = 'extension' +const defaultExtension: Extension = { + type: 'extension', + name: 'extension', + options: {}, + createCommands() { + return {} + }, +} - options: Partial = {} +export function createExtension(config: ExtensionSpec) { + const extend = (extendedConfig: Partial>) => { + return createExtension({ + ...config, + ...extendedConfig, + } as ExtensionSpec) + } - constructor(options?: Partial) { - this.options = { - ...this.createDefaultOptions(), - ...options, + const setOptions = (options?: Partial) => { + const { defaultOptions, ...rest } = config + + return { + ...defaultExtension, + ...rest, + options: { + ...defaultOptions, + ...options, + } as Options, } } - createDefaultOptions() { - return {} - } - - createCommands() { - return {} - } - + return Object.assign(setOptions, { config, extend }) } diff --git a/packages/core/src/Mark.ts b/packages/core/src/Mark.ts index 86e54553..37ccea81 100644 --- a/packages/core/src/Mark.ts +++ b/packages/core/src/Mark.ts @@ -27,22 +27,22 @@ // } // } -import Extension from './Extension' +// import Extension from './Extension' -export default class Node extends Extension { +// export default class Node extends Extension { - type = 'mark' +// type = 'mark' - createAttributes() { - return {} - } +// createAttributes() { +// return {} +// } - parseHTML() { - return [] - } +// parseHTML() { +// return [] +// } - renderHTML() { - return [] - } +// renderHTML() { +// return [] +// } -} +// } diff --git a/packages/core/src/Node.ts b/packages/core/src/Node.ts index 2720fa81..1db7f738 100644 --- a/packages/core/src/Node.ts +++ b/packages/core/src/Node.ts @@ -32,39 +32,113 @@ // } // } -import { DOMOutputSpec, DOMOutputSpecArray } from 'prosemirror-model' -import Extension from './Extension' +// import { DOMOutputSpec, DOMOutputSpecArray } from 'prosemirror-model' +// import Extension from './Extension' -export interface INode { - type: string - topNode: boolean - group: string - content: string - createAttributes(): any - parseHTML(): any - renderHTML(props: number): DOMOutputSpec +// export interface INode { +// type: string +// topNode: boolean +// group: string +// content: string +// createAttributes(): any +// parseHTML(): any +// renderHTML(props: number): DOMOutputSpec +// } + +// export default class Node extends Extension implements INode { + +// type = 'node' + +// topNode = false + +// group = '' + +// content = '' + +// createAttributes() { +// return {} +// } + +// parseHTML() { +// return [] +// } + +// renderHTML() { +// return null +// } + +// } + +import { DOMOutputSpec, NodeSpec, Node } from 'prosemirror-model' +import { Extension, ExtensionSpec } from './Extension' + +export interface NodeExtension extends Extension { + topNode: boolean, + content: NodeSpec['content'], + marks: NodeSpec['marks'], + group: NodeSpec['group'], + inline: NodeSpec['inline'], + atom: NodeSpec['atom'], + parseHTML: () => NodeSpec['parseDOM'], + renderHTML: (props: { + node: Node, + attributes: { + [key: string]: any, + }, + }) => DOMOutputSpec, } -export default class Node extends Extension implements INode { - - type = 'node' - - topNode = false - - group = '' - - content = '' - - createAttributes() { - return {} - } - - parseHTML() { - return [] - } - - renderHTML() { - return null - } - +export interface NodeExtensionSpec extends ExtensionSpec { + topNode?: boolean, + content?: NodeSpec['content'], + marks?: NodeSpec['marks'], + group?: NodeSpec['group'], + inline?: NodeSpec['inline'], + atom?: NodeSpec['atom'], + parseHTML?: () => NodeSpec['parseDOM'], + renderHTML?: (props: { + node: Node, + attributes: { + [key: string]: any, + }, + }) => DOMOutputSpec, +} + +const defaultNode: NodeExtension = { + type: 'node', + name: 'node', + options: {}, + topNode: false, + content: null, + marks: null, + group: null, + inline: null, + atom: null, + createCommands: () => ({}), + parseHTML: () => null, + renderHTML: () => null, +} + +export function createNode(config: NodeExtensionSpec) { + const extend = (extendedConfig: Partial>) => { + return createNode({ + ...config, + ...extendedConfig, + } as NodeExtensionSpec) + } + + const setOptions = (options?: Partial) => { + const { defaultOptions, ...rest } = config + + return { + ...defaultNode, + ...rest, + options: { + ...defaultOptions, + ...options, + } as Options, + } + } + + return Object.assign(setOptions, { config, extend }) } diff --git a/packages/core/src/utils/getSchema.ts b/packages/core/src/utils/getSchema.ts index b15acd06..fb6cf6dd 100644 --- a/packages/core/src/utils/getSchema.ts +++ b/packages/core/src/utils/getSchema.ts @@ -5,32 +5,28 @@ import getTopNodeFromExtensions from './getTopNodeFromExtensions' import getNodesFromExtensions from './getNodesFromExtensions' import getMarksFromExtensions from './getMarksFromExtensions' import resolveExtensionConfig from './resolveExtensionConfig' -import Node from '../Node' +import { Node } from '../Node' import Mark from '../Mark' import Extension from '../Extension' export default function getSchema(extensions: Extensions): Schema { - const baseExtensions = extensions.filter(extension => extension.type === 'extension') as Extension[] + // const baseExtensions = extensions.filter(extension => extension.type === 'extension') as Extension[] const nodeExtensions = extensions.filter(extension => extension.type === 'node') as Node[] - const markExtensions = extensions.filter(extension => extension.type === 'mark') as Mark[] + // const markExtensions = extensions.filter(extension => extension.type === 'mark') as Mark[] + + // console.log({ extensions }) const nodes = Object.fromEntries(nodeExtensions.map(extension => { - const schema: NodeSpec = { content: extension.content, group: extension.group, parseDOM: extension.parseHTML(), - toDOM: node => extension.renderHTML({ node, attributes: { class: 'hee' } }), + toDOM: node => extension.renderHTML({ node, attributes: { class: 'test' } }), } - return [ - extension.name, - schema, - ] + return [extension.name, schema] })) - console.log({ nodes }) - const topNode = nodeExtensions.find(extension => extension.topNode)?.name // extensions.forEach(extension => { @@ -57,8 +53,5 @@ export default function getSchema(extensions: Extensions): Schema { topNode, nodes, marks: {}, - // topNode: getTopNodeFromExtensions(extensions), - // nodes: getNodesFromExtensions(extensions), - // marks: getMarksFromExtensions(extensions), }) } diff --git a/packages/extension-document/index.ts b/packages/extension-document/index.ts index d0a39bd6..90a08e89 100644 --- a/packages/extension-document/index.ts +++ b/packages/extension-document/index.ts @@ -1,4 +1,4 @@ -import { Node } from '@tiptap/core' +import { createNode } from '@tiptap/core' // export default new Node() // .name('document') @@ -8,12 +8,20 @@ import { Node } from '@tiptap/core' // })) // .create() -export default class Document extends Node { +// export default class Document extends Node { - name = 'document' +// name = 'document' - topNode = true +// topNode = true - content = 'block+' +// content = 'block+' -} +// } + +export default createNode({ + name: 'document', + + topNode: true, + + content: 'block+', +}) diff --git a/packages/extension-paragraph/index.ts b/packages/extension-paragraph/index.ts index f4d48c8e..6dea2e79 100644 --- a/packages/extension-paragraph/index.ts +++ b/packages/extension-paragraph/index.ts @@ -1,5 +1,5 @@ -import { Command, Node, INode } from '@tiptap/core' -import { DOMOutputSpecArray } from 'prosemirror-model' +import { createNode } from '@tiptap/core' +// import { DOMOutputSpecArray } from 'prosemirror-model' // import ParagraphComponent from './paragraph.vue' // export type ParagraphCommand = () => Command @@ -29,31 +29,49 @@ import { DOMOutputSpecArray } from 'prosemirror-model' // })) // .create() -export default class Paragraph extends Node implements INode { +// export default class Paragraph extends Node implements INode { - name = 'paragraph' +// name = 'paragraph' - group = 'block' +// group = 'block' - content = 'inline*' +// content = 'inline*' - createAttributes() { - return { - // default rendering - class: { - default: 'jooo', - }, - } - } +// createAttributes() { +// return { +// // default rendering +// class: { +// default: 'jooo', +// }, +// } +// } + +// parseHTML() { +// return [ +// { tag: 'p' }, +// ] +// } + +// renderHTML() { +// return ['p', 0] as const +// } + +// } + +export default createNode({ + name: 'paragraph', + + group: 'block', + + content: 'inline*', parseHTML() { return [ { tag: 'p' }, ] - } + }, - renderHTML() { - return ['p', 0] as const - } - -} + renderHTML({ attributes }) { + return ['p', attributes, 0] + }, +}) diff --git a/packages/extension-text/index.ts b/packages/extension-text/index.ts index 567d5b3d..65d5878d 100644 --- a/packages/extension-text/index.ts +++ b/packages/extension-text/index.ts @@ -1,4 +1,4 @@ -import { Node } from '@tiptap/core' +import { createNode } from '@tiptap/core' // export default new Node() // .name('text') @@ -7,10 +7,16 @@ import { Node } from '@tiptap/core' // })) // .create() -export default class Text extends Node { +// export default class Text extends Node { - name = 'text' +// name = 'text' - group = 'inline' +// group = 'inline' -} +// } + +export default createNode({ + name: 'text', + + group: 'inline', +}) diff --git a/packages/vue-starter-kit/index.ts b/packages/vue-starter-kit/index.ts index 9ae43c4a..468af73e 100644 --- a/packages/vue-starter-kit/index.ts +++ b/packages/vue-starter-kit/index.ts @@ -1,8 +1,16 @@ // import originalDefaultExtensions from '@tiptap/starter-kit' +import Document from '@tiptap/extension-document' +import Text from '@tiptap/extension-text' +import Paragraph from '@tiptap/extension-paragraph' + export * from '@tiptap/vue' export function defaultExtensions() { - return [] + return [ + Document(), + Text(), + Paragraph(), + ] // return originalDefaultExtensions() }