diff --git a/docs/src/demos/Examples/Focus/index.vue b/docs/src/demos/Examples/Focus/index.vue index c7c08a5f..d2e65384 100644 --- a/docs/src/demos/Examples/Focus/index.vue +++ b/docs/src/demos/Examples/Focus/index.vue @@ -31,16 +31,16 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - new Document(), - new History(), - new Paragraph(), - new Text(), - new Bold(), - new Italic(), - new Code(), - new CodeBlock(), - new Heading(), - new Focus({ + Document(), + History(), + Paragraph(), + Text(), + Bold(), + Italic(), + Code(), + CodeBlock(), + Heading(), + Focus({ className: 'has-focus', nested: true, }), diff --git a/docs/src/demos/Examples/Simple/index.vue b/docs/src/demos/Examples/Simple/index.vue index 1f442f70..01387fdd 100644 --- a/docs/src/demos/Examples/Simple/index.vue +++ b/docs/src/demos/Examples/Simple/index.vue @@ -24,9 +24,9 @@ export default { this.editor = new Editor({ content: '
This is a radically reduced version of tiptap for minimalisits. It has only support for a document, paragraphs and text, that’s it.
', extensions: [ - new Document(), - new Paragraph(), - new Text(), + Document(), + Paragraph(), + Text(), ], }) diff --git a/docs/src/demos/ExtensionConfiguration/index.vue b/docs/src/demos/ExtensionConfiguration/index.vue index 3a7b5cbd..e060ebfe 100644 --- a/docs/src/demos/ExtensionConfiguration/index.vue +++ b/docs/src/demos/ExtensionConfiguration/index.vue @@ -26,10 +26,10 @@ export default { this.editor = new Editor({ content: 'I’m running tiptap with Vue.js. This demo is interactive, try to edit the text.
', extensions: [ - new Document(), - new Paragraph(), - new Text(), - new Bold(), + Document(), + Paragraph(), + Text(), + Bold(), ], }) }, diff --git a/docs/src/demos/Extensions/Bold/index.vue b/docs/src/demos/Extensions/Bold/index.vue index 7416151b..fd96bf11 100644 --- a/docs/src/demos/Extensions/Bold/index.vue +++ b/docs/src/demos/Extensions/Bold/index.vue @@ -30,10 +30,10 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - new Document(), - new Paragraph(), - new Text(), - new Bold(), + Document(), + Paragraph(), + Text(), + Bold(), ], content: `This isn’t bold.
diff --git a/docs/src/demos/Extensions/Code/index.vue b/docs/src/demos/Extensions/Code/index.vue index 4f51c0cd..4a89e425 100644 --- a/docs/src/demos/Extensions/Code/index.vue +++ b/docs/src/demos/Extensions/Code/index.vue @@ -30,10 +30,10 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - new Document(), - new Paragraph(), - new Text(), - new Code(), + Document(), + Paragraph(), + Text(), + Code(), ], content: `This isn’t code.
diff --git a/docs/src/demos/Extensions/History/index.vue b/docs/src/demos/Extensions/History/index.vue index 95b72d4d..40f022c5 100644 --- a/docs/src/demos/Extensions/History/index.vue +++ b/docs/src/demos/Extensions/History/index.vue @@ -33,10 +33,10 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - new Document(), - new Paragraph(), - new Text(), - new History(), + Document(), + Paragraph(), + Text(), + History(), ], content: `Edit this text and press undo to test this extension.
diff --git a/docs/src/demos/Extensions/Italic/index.vue b/docs/src/demos/Extensions/Italic/index.vue index 65e46a82..d86c3c9a 100644 --- a/docs/src/demos/Extensions/Italic/index.vue +++ b/docs/src/demos/Extensions/Italic/index.vue @@ -30,10 +30,10 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - new Document(), - new Paragraph(), - new Text(), - new Italic(), + Document(), + Paragraph(), + Text(), + Italic(), ], content: `This isn’t italic.
diff --git a/docs/src/demos/Guide/BuildYourEditor/index.vue b/docs/src/demos/Guide/BuildYourEditor/index.vue index 60534007..7aafa12d 100644 --- a/docs/src/demos/Guide/BuildYourEditor/index.vue +++ b/docs/src/demos/Guide/BuildYourEditor/index.vue @@ -55,15 +55,15 @@ export default { this.editor = new Editor({ content: 'This editor is based on Prosemirror, fully extendable and renderless. You can easily add custom nodes as Vue components.
', extensions: [ - new Document(), - new Paragraph(), - new Text(), - new CodeBlock(), - new History(), - new Bold(), - new Italic(), - new Code(), - new Heading(), + Document(), + Paragraph(), + Text(), + CodeBlock(), + History(), + Bold(), + Italic(), + Code(), + Heading(), ], }) }, diff --git a/docs/src/docPages/api/extensions/blockquote.md b/docs/src/docPages/api/extensions/blockquote.md index 0e899d1f..bb26f119 100644 --- a/docs/src/docPages/api/extensions/blockquote.md +++ b/docs/src/docPages/api/extensions/blockquote.md @@ -39,7 +39,7 @@ export default { return { editor: new Editor({ extensions: [ - new Blockquote(), + Blockquote(), ], content: `diff --git a/docs/src/docPages/api/extensions/bullet-list.md b/docs/src/docPages/api/extensions/bullet-list.md index d547079b..124a5a46 100644 --- a/docs/src/docPages/api/extensions/bullet-list.md +++ b/docs/src/docPages/api/extensions/bullet-list.md @@ -43,7 +43,7 @@ export default { return { editor: new Editor({ extensions: [ - new BulletList(), + BulletList(), ], content: `diff --git a/docs/src/docPages/api/extensions/heading.md b/docs/src/docPages/api/extensions/heading.md index 54485c51..5f333d6d 100644 --- a/docs/src/docPages/api/extensions/heading.md +++ b/docs/src/docPages/api/extensions/heading.md @@ -51,7 +51,7 @@ export default { return { editor: new Editor({ extensions: [ - new Heading({ + Heading({ levels: [1, 2], }), ], diff --git a/docs/src/docPages/api/extensions/horizontal-rule.md b/docs/src/docPages/api/extensions/horizontal-rule.md index d70138b4..00fac88e 100644 --- a/docs/src/docPages/api/extensions/horizontal-rule.md +++ b/docs/src/docPages/api/extensions/horizontal-rule.md @@ -39,7 +39,7 @@ export default { return { editor: new Editor({ extensions: [ - new HorizontalRule(), + HorizontalRule(), ], content: `
Some text.
diff --git a/docs/src/docPages/api/extensions/ordered-list.md b/docs/src/docPages/api/extensions/ordered-list.md index 390c2c40..67f104a0 100644 --- a/docs/src/docPages/api/extensions/ordered-list.md +++ b/docs/src/docPages/api/extensions/ordered-list.md @@ -43,7 +43,7 @@ export default { return { editor: new Editor({ extensions: [ - new OrderedList(), + OrderedList(), ], content: `diff --git a/docs/src/docPages/api/extensions/placeholder.md b/docs/src/docPages/api/extensions/placeholder.md index b5ad0ba4..b29df1fd 100644 --- a/docs/src/docPages/api/extensions/placeholder.md +++ b/docs/src/docPages/api/extensions/placeholder.md @@ -66,10 +66,10 @@ You have to include all table extensions (`TableHeader`, `TableCell` & `TableRow return { editor: new Editor({ extensions: [ - new Table(), - new TableCell(), - new TableHeader(), - new TableRow(), + Table(), + TableCell(), + TableHeader(), + TableRow(), ], content: '' }), diff --git a/docs/src/docPages/api/extensions/strike.md b/docs/src/docPages/api/extensions/strike.md index 463de394..b2a98fec 100644 --- a/docs/src/docPages/api/extensions/strike.md +++ b/docs/src/docPages/api/extensions/strike.md @@ -40,7 +40,7 @@ export default { return { editor: new Editor({ extensions: [ - new Strike(), + Strike(), ], content: `
diff --git a/docs/src/docPages/api/extensions/todo-list.md b/docs/src/docPages/api/extensions/todo-list.md index 89f0f89a..2fefea44 100644 --- a/docs/src/docPages/api/extensions/todo-list.md +++ b/docs/src/docPages/api/extensions/todo-list.md @@ -43,10 +43,10 @@ export default { return { editor: new Editor({ extensions: [ - new TodoItem({ + TodoItem({ nested: true, }), - new TodoList(), + TodoList(), ], content: `
That's strikethrough.diff --git a/docs/src/docPages/api/extensions/underline.md b/docs/src/docPages/api/extensions/underline.md index 8e639900..07fd1418 100644 --- a/docs/src/docPages/api/extensions/underline.md +++ b/docs/src/docPages/api/extensions/underline.md @@ -40,7 +40,7 @@ export default { return { editor: new Editor({ extensions: [ - new Underline(), + Underline(), ], content: `
This is underlined.
diff --git a/docs/src/docPages/general/roadmap.md b/docs/src/docPages/general/roadmap.md index d33779a2..04e8022d 100644 --- a/docs/src/docPages/general/roadmap.md +++ b/docs/src/docPages/general/roadmap.md @@ -2,7 +2,7 @@ ## New features -* generate schema without initializing tiptap, to make SSR easier (e. g. `getSchema([new Doc(), new Paragraph()])`) +* generate schema without initializing tiptap, to make SSR easier (e. g. `getSchema([Doc(), Paragraph()])`) ## Requested features diff --git a/packages/core/src/Editor.ts b/packages/core/src/Editor.ts index 95047928..8fb3ca02 100644 --- a/packages/core/src/Editor.ts +++ b/packages/core/src/Editor.ts @@ -12,6 +12,9 @@ import removeElement from './utils/removeElement' import getSchemaTypeByName from './utils/getSchemaTypeByName' import ExtensionManager from './ExtensionManager' import EventEmitter from './EventEmitter' +import Extension from './Extension' +import Node from './Node' +import Mark from './Mark' import ComponentRenderer from './ComponentRenderer' import defaultPlugins from './plugins' import * as commands from './commands' @@ -27,7 +30,7 @@ type EditorContent = string | JSON | null interface EditorOptions { element: Element, content: EditorContent, - extensions: Function[], + extensions: (Extension | Node | Mark)[], injectCSS: boolean, autoFocus: 'start' | 'end' | number | boolean | null, editable: boolean, diff --git a/packages/core/src/Extension.ts b/packages/core/src/Extension.ts index 7ecce474..649e2f27 100644 --- a/packages/core/src/Extension.ts +++ b/packages/core/src/Extension.ts @@ -78,9 +78,15 @@ export interface ExtensionExtends{ plugins: (params: Callback) => Plugin[] } -export default class Extension { +export default class Extension { type = 'extension' - configs: any = {} + config: any = {} + configs: { + [key: string]: { + stategy: 'extend' | 'overwrite' + value: any + }[] + } = {} usedOptions: Partial = {} protected storeConfig(key: string, value: any, stategy: 'extend' | 'overwrite') { diff --git a/packages/core/src/ExtensionManager.ts b/packages/core/src/ExtensionManager.ts index 0559d3c7..7e694158 100644 --- a/packages/core/src/ExtensionManager.ts +++ b/packages/core/src/ExtensionManager.ts @@ -1,3 +1,4 @@ +import deepmerge from 'deepmerge' import collect from 'collect.js' import { Plugin } from 'prosemirror-state' import { keymap } from 'prosemirror-keymap' @@ -10,8 +11,7 @@ import Node from './Node' import Mark from './Mark' import capitalize from './utils/capitalize' -// type Extensions = (Extension | Node | Mark)[] -type Extensions = Function[] +type Extensions = (Extension | Node | Mark)[] export default class ExtensionManager { @@ -22,77 +22,106 @@ export default class ExtensionManager { this.editor = editor this.extensions = extensions this.extensions.forEach(extension => { - console.log({extension}) - // extension.bindEditor(editor) - // editor.on('schemaCreated', () => { - // this.editor.registerCommands(extension.commands()) - // extension.created() - // }) + const simpleConfigs = ['name', 'defaults'] + + Object + .entries(extension.configs) + .sort(([name]) => simpleConfigs.includes(name) ? -1 : 1) + .forEach(([name, configs]) => { + extension.config[name] = configs.reduce((accumulator, { stategy, value: rawValue }) => { + const isSimpleConfig = simpleConfigs.includes(name) + const props = isSimpleConfig + ? undefined + : { + editor, + options: deepmerge(extension.config.defaults, extension.usedOptions), + type: {}, + name: '', + } + const value = typeof rawValue === 'function' + ? rawValue(props) + : rawValue + + if (accumulator === undefined) { + return value + } + + if (stategy === 'overwrite') { + return value + } + + if (stategy === 'extend') { + return deepmerge(accumulator, value) + } + + return accumulator + }, undefined) + }) + + editor.on('schemaCreated', () => { + if (extension.config.commands) { + this.editor.registerCommands(extension.config.commands) + } + }) }) } get topNode() { - const topNode = collect(this.extensions).firstWhere('topNode', true) + const topNode = collect(this.extensions).firstWhere('config.topNode', true) if (topNode) { - return topNode.name + return topNode.config.name } } get nodes(): any { - // return collect(this.extensions) - // .where('extensionType', 'node') - // .mapWithKeys((extension: Node) => [extension.name, extension.schema()]) - // .all() - return [] + return collect(this.extensions) + .where('type', 'node') + .mapWithKeys((extension: Node) => [extension.config.name, extension.config.schema]) + .all() } get marks(): any { - // return collect(this.extensions) - // .where('extensionType', 'mark') - // .mapWithKeys((extension: Mark) => [extension.name, extension.schema()]) - // .all() - return [] + return collect(this.extensions) + .where('type', 'mark') + .mapWithKeys((extension: Mark) => [extension.config.name, extension.config.schema]) + .all() } get plugins(): Plugin[] { - // const plugins = collect(this.extensions) - // .flatMap(extension => extension.plugins()) - // .toArray() + const plugins = collect(this.extensions) + .flatMap(extension => extension.config.plugins) + .filter(plugin => plugin) + .toArray() - // return [ - // ...plugins, - // ...this.keymaps, - // ...this.pasteRules, - // inputRules({ rules: this.inputRules }), - // ] - - return [] + return [ + ...plugins, + ...this.keymaps, + ...this.pasteRules, + inputRules({ rules: this.inputRules }), + ] } get inputRules(): any { - // return collect(this.extensions) - // .flatMap(extension => extension.inputRules()) - // .toArray() - - return {} + return collect(this.extensions) + .flatMap(extension => extension.config.inputRules) + .filter(plugin => plugin) + .toArray() } get pasteRules(): any { - // return collect(this.extensions) - // .flatMap(extension => extension.pasteRules()) - // .toArray() - return {} + return collect(this.extensions) + .flatMap(extension => extension.config.pasteRules) + .filter(plugin => plugin) + .toArray() } get keymaps() { - // return collect(this.extensions) - // .map(extension => extension.keys()) - // .filter(keys => !!Object.keys(keys).length) - // // @ts-ignore - // .map(keys => keymap(keys)) - // .toArray() - return [] + return collect(this.extensions) + .map(extension => extension.config.keys) + .filter(keys => keys) + .map(keys => keymap(keys)) + .toArray() } get nodeViews() { diff --git a/packages/core/src/test.ts b/packages/core/src/test.ts index cff68258..38989b25 100644 --- a/packages/core/src/test.ts +++ b/packages/core/src/test.ts @@ -1,9 +1,294 @@ -import { NodeSpec, NodeType } from "prosemirror-model"; -import deepmerge from 'deepmerge' -import collect from 'collect.js' -import { Editor, CommandSpec, ComponentRenderer } from '@tiptap/core' -import cloneDeep from 'clone-deep' -import { Plugin } from "prosemirror-state"; +// import { NodeSpec, NodeType } from "prosemirror-model"; +// import deepmerge from 'deepmerge' +// import collect from 'collect.js' +// import { Editor, CommandSpec, ComponentRenderer } from '@tiptap/core' +// import cloneDeep from 'clone-deep' +// import { Plugin } from "prosemirror-state"; + +// // type RecursivePartial = { +// // [P in keyof T]?: +// // T[P] extends (infer U)[] ? RecursivePartial[] : +// // T[P] extends object ? RecursivePartial : +// // T[P]; +// // } + +// // type Extension = { +// // name: string +// // defaultOptions?: Options | (() => Options) +// // bla?: number[] | ((this: ExtensionOptions ) => number[]) +// // blub?: number[] | (() => number[]) +// // schema?: () => NodeSpec +// // } + +// // type ExtensionOptions = { +// // options: T +// // } + +// // function Extension (config: Extension ) { +// // const instance = (options: Options) => { +// // const extensionInstance = { +// // ...config, +// // options, +// // } + +// // if (typeof extensionInstance.name === 'function') { +// // // @ts-ignore +// // extensionInstance.name() +// // } + +// // return extensionInstance +// // } + +// // instance.extend = (extendConfig: RecursivePartial ) => { +// // return Extension (deepmerge({...config}, {...extendConfig}) as Extension) +// // } + +// // return instance +// // } + +// // type HeadingOptions = { +// // levels?: number[] +// // } + +// // const Heading = Extension ({ +// // name: 'heading', +// // defaultOptions: { +// // levels: [1, 2, 3, 4, 5, 6], +// // }, +// // schema() { +// // return { +// // defining: true +// // } +// // } +// // }) + +// // // Heading +// // const h = Heading.extend({ +// // name: '123', +// // })({ +// // levels: [1, 2] +// // }) + +// // console.log({h}) + + + + + + + + + + + +// // const bla = Extension(options => { +// // name: 'heading', +// // bla: () => { +// // return [1, 2] +// // }, +// // }) + +// // const Heading1 = Heading.extend({ +// // name: 'heading 1' +// // }) + +// // console.log(Heading(1), Heading1(2)) + + + + +// // interface ExtenstionClass { +// // new (options?: T): ExtenstionClass +// // name?: string +// // bla?: number[] | (() => number[]) +// // } + +// // // class ExtenstionClass implements ExtenstionClass { +// // class ExtenstionClass { +// // // name: '124' + +// // // bla() { +// // // return [1, 2] +// // // } +// // } + +// // class Whatever extends ExtenstionClass { +// // name: '1243' +// // } + +// // new Whatever({ +// // bla: 124, +// // }) + + + + + +// // interface ExxxtensionConstructor { +// // new (options: Partial ): any +// // } + +// // interface Exxxtension { +// // name: string +// // } + +// // const Exxxtension: ExxxtensionConstructor = class Exxxtension implements Exxxtension { +// // name = '1' +// // }; + +// // new Exxxtension({ +// // levels: [1, 2], +// // // test: 'bla', +// // }) + + + + +// // interface ExxxtensionConstructor { +// // new (options: Partial ): any +// // } + +// // interface Exxxtension { +// // name: string +// // } + +// // interface NodeExtension extends Exxxtension { +// // schema(): NodeSpec +// // what: number +// // } + +// // class Exxxtension implements Exxxtension { +// // // public topNode = false +// // } + +// // class NodeExtension implements NodeExtension { +// // // public topNode = false +// // } + +// // const HeadingNode: ExxxtensionConstructor = class HeadingNode extends NodeExtension implements NodeExtension { +// // name = 'heading' + +// // // what = 's' + +// // schema() { +// // return { +// // defining: true +// // } +// // } +// // } + +// // new HeadingNode({ +// // levels: [1, 2], +// // // test: 'bla', +// // }) + + + + +// // interface ExtenstionClass { +// // // new (options?: T): ExtenstionClass +// // name?: string +// // schema?: () => NodeSpec +// // } + + + + + + + + + + +// // type ExtensionConfig = { +// // name: string +// // defaultOptions: Options +// // } + +// // type NodeConfig = ExtensionConfig & { +// // schema?: () => NodeSpec +// // } + +// // class BaseExtension { +// // // config: Config +// // options!: Options + +// // // config = { +// // // name: 'extension', +// // // defaultOptions: {}, +// // // } + +// // // defaultConfig = { +// // // name: 'extension', +// // // defaultOptions: {}, +// // // } + +// // // get defaultConfig(): Config { +// // // return { +// // // name: 'extension', +// // // // defaultOptions: {}, +// // // } +// // // } + +// // config: Config + +// // constructor(config: Config) { +// // this.config = { +// // // ...this.defaultConfig, +// // ...{ +// // name: 'extension', +// // defaultOptions: {}, +// // }, +// // ...config, +// // } +// // this.options = this.config.defaultOptions +// // } + +// // set(options: Partial ) { +// // console.log(this.config.defaultOptions) +// // this.options = { +// // ...this.config.defaultOptions, +// // ...options, +// // } as Options + +// // console.log(this) +// // } +// // } + +// // // class Extension extends BaseExtension > { +// // // defaultConfig: ExtensionConfig = { +// // // name: 'extension', +// // // defaultOptions: {}, +// // // } +// // // } + +// // class Node extends BaseExtension > { +// // // defaultConfig: NodeConfig = { +// // // name: 'extension', +// // // defaultOptions: {}, +// // // schema() { +// // // return {} +// // // } +// // // } +// // } + +// // type HeadingOptions = { +// // levels: number[] +// // } + +// // const Headingg = new Node ({ +// // name: 'heading', +// // defaultOptions: { +// // levels: [1, 2, 3, 4, 5, 6] +// // }, +// // }) + +// // Headingg.set({ +// // levels: [1, 2] +// // }) + + + // type RecursivePartial = { // [P in keyof T]?: @@ -12,686 +297,401 @@ import { Plugin } from "prosemirror-state"; // T[P]; // } -// type Extension = { +// type AnyObject = { +// [key: string]: any +// } + +// type ExtensionConfig = { // name: string -// defaultOptions?: Options | (() => Options) -// bla?: number[] | ((this: ExtensionOptions ) => number[]) -// blub?: number[] | (() => number[]) -// schema?: () => NodeSpec +// defaultOptions: Options | (() => Options) // } -// type ExtensionOptions = { -// options: T -// } - -// function Extension (config: Extension ) { -// const instance = (options: Options) => { -// const extensionInstance = { -// ...config, -// options, -// } - -// if (typeof extensionInstance.name === 'function') { -// // @ts-ignore -// extensionInstance.name() -// } - -// return extensionInstance -// } - -// instance.extend = (extendConfig: RecursivePartial ) => { -// return Extension (deepmerge({...config}, {...extendConfig}) as Extension) -// } - -// return instance -// } - -// type HeadingOptions = { -// levels?: number[] -// } - -// const Heading = Extension ({ -// name: 'heading', -// defaultOptions: { -// levels: [1, 2, 3, 4, 5, 6], -// }, -// schema() { -// return { -// defining: true -// } -// } -// }) - -// // Heading -// const h = Heading.extend({ -// name: '123', -// })({ -// levels: [1, 2] -// }) - -// console.log({h}) - - - - - - - - - - - -// const bla = Extension(options => { -// name: 'heading', -// bla: () => { -// return [1, 2] -// }, -// }) - -// const Heading1 = Heading.extend({ -// name: 'heading 1' -// }) - -// console.log(Heading(1), Heading1(2)) - - - - -// interface ExtenstionClass { -// new (options?: T): ExtenstionClass -// name?: string -// bla?: number[] | (() => number[]) -// } - -// // class ExtenstionClass implements ExtenstionClass { -// class ExtenstionClass { -// // name: '124' - -// // bla() { -// // return [1, 2] -// // } -// } - -// class Whatever extends ExtenstionClass { -// name: '1243' -// } - -// new Whatever({ -// bla: 124, -// }) - - - - - -// interface ExxxtensionConstructor { -// new (options: Partial ): any -// } - -// interface Exxxtension { -// name: string -// } - -// const Exxxtension: ExxxtensionConstructor = class Exxxtension implements Exxxtension { -// name = '1' -// }; - -// new Exxxtension({ -// levels: [1, 2], -// // test: 'bla', -// }) - - - - -// interface ExxxtensionConstructor { -// new (options: Partial ): any -// } - -// interface Exxxtension { -// name: string -// } - -// interface NodeExtension extends Exxxtension { -// schema(): NodeSpec -// what: number -// } - -// class Exxxtension implements Exxxtension { -// // public topNode = false -// } - -// class NodeExtension implements NodeExtension { -// // public topNode = false -// } - -// const HeadingNode: ExxxtensionConstructor = class HeadingNode extends NodeExtension implements NodeExtension { -// name = 'heading' - -// // what = 's' - -// schema() { -// return { -// defining: true -// } -// } -// } - -// new HeadingNode({ -// levels: [1, 2], -// // test: 'bla', -// }) - - - - -// interface ExtenstionClass { -// // new (options?: T): ExtenstionClass -// name?: string +// type NodeConfig = ExtensionConfig & { // schema?: () => NodeSpec // } - - - - - - - -// type ExtensionConfig = { -// name: string -// defaultOptions: Options -// } - -// type NodeConfig = ExtensionConfig & { -// schema?: () => NodeSpec -// } - // class BaseExtension { -// // config: Config -// options!: Options +// options!: Partial -// // config = { -// // name: 'extension', -// // defaultOptions: {}, -// // } +// defaultConfig = { +// name: 'extension', +// defaultOptions: {}, +// } -// // defaultConfig = { -// // name: 'extension', -// // defaultOptions: {}, -// // } +// configs: AnyObject = {} -// // get defaultConfig(): Config { -// // return { -// // name: 'extension', -// // // defaultOptions: {}, -// // } -// // } - -// config: Config - -// constructor(config: Config) { -// this.config = { -// // ...this.defaultConfig, -// ...{ -// name: 'extension', -// defaultOptions: {}, -// }, +// constructor(config: AnyObject) { +// this.storeConfig({ +// ...this.defaultConfig, // ...config, -// } -// this.options = this.config.defaultOptions +// }, 'overwrite') +// } + +// storeConfig(config: AnyObject, stategy: ('extend' | 'overwrite')) { +// Object.entries(config).forEach(([key, value]) => { +// const item = { +// stategy, +// value, +// } + +// if (this.configs[key]) { +// this.configs[key].push(item) +// } else { +// this.configs[key] = [item] +// } +// }) // } // set(options: Partial ) { -// console.log(this.config.defaultOptions) -// this.options = { -// ...this.config.defaultOptions, -// ...options, -// } as Options +// this.options = options +// } -// console.log(this) +// extend(config: RecursivePartial ) { +// this.storeConfig(config, 'extend') + +// return this +// } + +// overwrite(config: Partial ) { +// this.storeConfig(config, 'overwrite') + +// return this // } // } -// // class Extension extends BaseExtension > { -// // defaultConfig: ExtensionConfig = { +// // class Extension extends BaseExtension { +// // defaultConfig: ExtensionConfig = { // // name: 'extension', // // defaultOptions: {}, // // } + +// // constructor(config: ExtensionConfig ) { +// // super(config) +// // } // // } // class Node extends BaseExtension > { -// // defaultConfig: NodeConfig = { -// // name: 'extension', -// // defaultOptions: {}, -// // schema() { -// // return {} -// // } -// // } +// defaultConfig: NodeConfig = { +// name: 'extension', +// defaultOptions: {}, +// schema() { +// return {} +// } +// } + +// constructor(config: NodeConfig ) { +// super(config) +// } // } // type HeadingOptions = { // levels: number[] +// bla: string // } // const Headingg = new Node ({ // name: 'heading', // defaultOptions: { +// bla: 'hey', // levels: [1, 2, 3, 4, 5, 6] // }, // }) -// Headingg.set({ -// levels: [1, 2] -// }) - - - - -type RecursivePartial = { - [P in keyof T]?: - T[P] extends (infer U)[] ? RecursivePartial[] : - T[P] extends object ? RecursivePartial : - T[P]; -} - -type AnyObject = { - [key: string]: any -} - -type ExtensionConfig = { - name: string - defaultOptions: Options | (() => Options) -} - -type NodeConfig = ExtensionConfig & { - schema?: () => NodeSpec -} - - - -class BaseExtension { - options!: Partial - - defaultConfig = { - name: 'extension', - defaultOptions: {}, - } - - configs: AnyObject = {} - - constructor(config: AnyObject) { - this.storeConfig({ - ...this.defaultConfig, - ...config, - }, 'overwrite') - } - - storeConfig(config: AnyObject, stategy: ('extend' | 'overwrite')) { - Object.entries(config).forEach(([key, value]) => { - const item = { - stategy, - value, - } - - if (this.configs[key]) { - this.configs[key].push(item) - } else { - this.configs[key] = [item] - } - }) - } - - set(options: Partial ) { - this.options = options - } - - extend(config: RecursivePartial ) { - this.storeConfig(config, 'extend') - - return this - } - - overwrite(config: Partial ) { - this.storeConfig(config, 'overwrite') - - return this - } -} - -// class Extension extends BaseExtension { -// defaultConfig: ExtensionConfig = { -// name: 'extension', -// defaultOptions: {}, -// } - -// constructor(config: ExtensionConfig ) { -// super(config) -// } -// } - -class Node extends BaseExtension > { - defaultConfig: NodeConfig = { - name: 'extension', - defaultOptions: {}, - schema() { - return {} - } - } - - constructor(config: NodeConfig ) { - super(config) - } -} - -type HeadingOptions = { - levels: number[] - bla: string -} - -const Headingg = new Node ({ - name: 'heading', - defaultOptions: { - bla: 'hey', - levels: [1, 2, 3, 4, 5, 6] - }, -}) - -// Headingg.set({ -// levels: [1, 2] -// }) - -const h2 = Headingg.extend({ - name: 'headliiiine', - defaultOptions() { - console.log('this:', this) - return { - levels: [5, 6] - } - }, -}) - -const h3 = h2.extend({ - name: 'wtf', -}) - -h3.set({ - levels: [1, 2] -}) - -// const entries = Object -// .entries(h3.configs) -// .map(([key, value]) => { - -// const mergedValue = value.reduce((acc: any, item: any) => { -// const { stategy, value } = item -// const called = typeof value === 'function' ? value() : value -// const isObject = called !== null && typeof called === 'object' - -// if (isObject && stategy === 'extend') { -// return deepmerge(acc, called, { -// arrayMerge: (destinationArray, sourceArray, options) => sourceArray -// }) -// } - -// return called -// }, {}) - -// return [key, mergedValue] -// }) - -// console.log(entries) - -// const bla = Object.fromEntries(entries) - -// console.log(h3, bla) - -// interface Testi { -// name: string -// defaultOptions: { -// levels: number -// } -// } - -// class Test implements Testi { - -// name = '12' - -// defaultOptions = { -// le -// } - -// } - - - - - - - - - - - - - - - - - - - - - - -// const Heading = Extension(options => ({ -// defaultOptions: { -// name: 'heading', -// }, -// schema: { -// parseDOM: options.levels -// .map(level => ({ -// tag: `h${level}`, -// attrs: { level }, -// })), -// }, -// })) - -// const Heading = new Node() -// .name('heading') -// .options({ -// levels: [1, 2, 3] -// }) -// .config(({ options }) => ({ -// schema: { -// parseDOM: options.levels -// .map(level => ({ -// tag: `h${level}`, -// attrs: { level }, -// })), -// toDOM: node => [`h${node.attrs.level}`, 0], -// }, -// plugins: { -// get() { - - -// }, -// }, -// })) - -// Heading -// .extendOptions({ -// class: 'my-heading' -// }) -// .extendConfig(({ options }) => ({ -// schema: { -// toDOM: node => [`h${node.attrs.level}`, { class: options.class }, 0], -// }, -// })) - -// @ts-ignore -function copyProperties(target, source) { - Object.getOwnPropertyNames(source).forEach(name => { - Object.defineProperty( - target, - name, - // @ts-ignore - Object.getOwnPropertyDescriptor(source, name) - ); - }); - return target; -} - -// @ts-ignore -// function mix (...sources) { -// const result = {} -// for (const source of sources) { -// const props = Object.keys(source) -// for (const prop of props) { -// const descriptor = Object.getOwnPropertyDescriptor(source, prop) -// // @ts-ignore -// Object.defineProperty(result, prop, descriptor) +// // Headingg.set({ +// // levels: [1, 2] +// // }) + +// const h2 = Headingg.extend({ +// name: 'headliiiine', +// defaultOptions() { +// console.log('this:', this) +// return { +// levels: [5, 6] // } -// } -// return result +// }, +// }) + +// const h3 = h2.extend({ +// name: 'wtf', +// }) + +// h3.set({ +// levels: [1, 2] +// }) + +// // const entries = Object +// // .entries(h3.configs) +// // .map(([key, value]) => { + +// // const mergedValue = value.reduce((acc: any, item: any) => { +// // const { stategy, value } = item +// // const called = typeof value === 'function' ? value() : value +// // const isObject = called !== null && typeof called === 'object' + +// // if (isObject && stategy === 'extend') { +// // return deepmerge(acc, called, { +// // arrayMerge: (destinationArray, sourceArray, options) => sourceArray +// // }) +// // } + +// // return called +// // }, {}) + +// // return [key, mergedValue] +// // }) + +// // console.log(entries) + +// // const bla = Object.fromEntries(entries) + +// // console.log(h3, bla) + +// // interface Testi { +// // name: string +// // defaultOptions: { +// // levels: number +// // } +// // } + +// // class Test implements Testi { + +// // name = '12' + +// // defaultOptions = { +// // le +// // } + +// // } + + + + + + + + + + + + + + + + + + + + + + +// // const Heading = Extension(options => ({ +// // defaultOptions: { +// // name: 'heading', +// // }, +// // schema: { +// // parseDOM: options.levels +// // .map(level => ({ +// // tag: `h${level}`, +// // attrs: { level }, +// // })), +// // }, +// // })) + +// // const Heading = new Node() +// // .name('heading') +// // .options({ +// // levels: [1, 2, 3] +// // }) +// // .config(({ options }) => ({ +// // schema: { +// // parseDOM: options.levels +// // .map(level => ({ +// // tag: `h${level}`, +// // attrs: { level }, +// // })), +// // toDOM: node => [`h${node.attrs.level}`, 0], +// // }, +// // plugins: { +// // get() { + + +// // }, +// // }, +// // })) + +// // Heading +// // .extendOptions({ +// // class: 'my-heading' +// // }) +// // .extendConfig(({ options }) => ({ +// // schema: { +// // toDOM: node => [`h${node.attrs.level}`, { class: options.class }, 0], +// // }, +// // })) + +// // @ts-ignore +// function copyProperties(target, source) { +// Object.getOwnPropertyNames(source).forEach(name => { +// Object.defineProperty( +// target, +// name, +// // @ts-ignore +// Object.getOwnPropertyDescriptor(source, name) +// ); +// }); +// return target; // } -let one = { - count: 1, - // arr: [1], - get multiply() { - // console.log(this.count) - return this.count * 2 - }, - // nested: { - // foo: 'bar', - // }, - // get nested() { - // return { - // foo: 'bar' - // } - // } -} +// // @ts-ignore +// // function mix (...sources) { +// // const result = {} +// // for (const source of sources) { +// // const props = Object.keys(source) +// // for (const prop of props) { +// // const descriptor = Object.getOwnPropertyDescriptor(source, prop) +// // // @ts-ignore +// // Object.defineProperty(result, prop, descriptor) +// // } +// // } +// // return result +// // } -let two = { - count: 2, - // arr: [2], - get multiply() { - // console.log(this.count) - return this.count * 3 - }, -} - -// let three = { -// ...one, -// ...two +// let one = { +// count: 1, +// // arr: [1], +// get multiply() { +// // console.log(this.count) +// return this.count * 2 +// }, +// // nested: { +// // foo: 'bar', +// // }, +// // get nested() { +// // return { +// // foo: 'bar' +// // } +// // } // } +// let two = { +// count: 2, +// // arr: [2], +// get multiply() { +// // console.log(this.count) +// return this.count * 3 +// }, +// } + +// // let three = { +// // ...one, +// // ...two +// // } + +// // let three = copyProperties(one, two) // let three = copyProperties(one, two) -let three = copyProperties(one, two) -// let three = deepmerge(one, two, {clone: false}) -// let three = merge(one, two) -// console.log(three) +// // let three = deepmerge(one, two, {clone: false}) +// // let three = merge(one, two) +// // console.log(three) -// class Test { -// constructor() { -// // this.op = config -// // @ts-ignore -// this.name = 'test' -// } +// // class Test { +// // constructor() { +// // // this.op = config +// // // @ts-ignore +// // this.name = 'test' +// // } -// config(fn: any) { -// this.config = fn.bind(this)() +// // config(fn: any) { +// // this.config = fn.bind(this)() -// return this -// } +// // return this +// // } -// extend(fn: any) { -// this.config = deepmerge(this.config, fn.bind(this)()) +// // extend(fn: any) { +// // this.config = deepmerge(this.config, fn.bind(this)()) -// return this -// } -// } +// // return this +// // } +// // } -// const bla = new Test() -// .config(function() { -// //@ts-ignore -// // console.log(this) -// return { -// schema: { -// one: 1, -// //@ts-ignore -// foo: this.name + ' bar', -// }, -// } -// }) -// .extend(function() { -// //@ts-ignore -// // console.log(this) -// return { -// schema: { -// two: 2, -// //@ts-ignore -// foo: this.name + ' barrrrr', -// }, -// } -// }) -// // .extend(() => ({ -// // schema: { -// // two: 2, -// // //@ts-ignore -// // foo: this.name + ' barrrrr', -// // }, -// // })) +// // const bla = new Test() +// // .config(function() { +// // //@ts-ignore +// // // console.log(this) +// // return { +// // schema: { +// // one: 1, +// // //@ts-ignore +// // foo: this.name + ' bar', +// // }, +// // } +// // }) +// // .extend(function() { +// // //@ts-ignore +// // // console.log(this) +// // return { +// // schema: { +// // two: 2, +// // //@ts-ignore +// // foo: this.name + ' barrrrr', +// // }, +// // } +// // }) +// // // .extend(() => ({ +// // // schema: { +// // // two: 2, +// // // //@ts-ignore +// // // foo: this.name + ' barrrrr', +// // // }, +// // // })) -// console.log(bla.config) +// // console.log(bla.config) -// const Heading = new Node() -// .name('heading') -// .options({ -// levels: [1, 2, 3] -// }) -// .config(({ name, options }) => ({ -// schema: { -// parseDOM: options.levels.map(level => ({ -// tag: `h${level}`, -// attrs: { level }, -// })), -// toDOM: node => [`h${node.attrs.level}`, 0], -// }, -// })) +// // const Heading = new Node() +// // .name('heading') +// // .options({ +// // levels: [1, 2, 3] +// // }) +// // .config(({ name, options }) => ({ +// // schema: { +// // parseDOM: options.levels.map(level => ({ +// // tag: `h${level}`, +// // attrs: { level }, +// // })), +// // toDOM: node => [`h${node.attrs.level}`, 0], +// // }, +// // })) -// const CustomHeading = Heading.extend(({ name, options }) => ({ -// schema: { -// toDOM: node => [`h${node.attrs.level}`, { class: 'custom-class' }, 0], -// }, -// })) +// // const CustomHeading = Heading.extend(({ name, options }) => ({ +// // schema: { +// // toDOM: node => [`h${node.attrs.level}`, { class: 'custom-class' }, 0], +// // }, +// // })) -// const Heading = new Node() -// .name('heading') -// .options({ -// levels: [1, 2, 3] -// }) -// .schema(options => ({ -// parseDOM: options.levels.map(level => ({ -// tag: `h${level}`, -// attrs: { level }, -// })), -// toDOM: node => [`h${node.attrs.level}`, 0], -// })) +// // const Heading = new Node() +// // .name('heading') +// // .options({ +// // levels: [1, 2, 3] +// // }) +// // .schema(options => ({ +// // parseDOM: options.levels.map(level => ({ +// // tag: `h${level}`, +// // attrs: { level }, +// // })), +// // toDOM: node => [`h${node.attrs.level}`, 0], +// // })) -// const CustomHeading = Heading.extend('schema', options => ({ -// toDOM: node => [`h${node.attrs.level}`, { class: 'custom-class' }, 0], -// })) +// // const CustomHeading = Heading.extend('schema', options => ({ +// // toDOM: node => [`h${node.attrs.level}`, { class: 'custom-class' }, 0], +// // })) @@ -710,22 +710,99 @@ let three = copyProperties(one, two) -// type Bla = { +// // type Bla = { +// // name: string +// // options: any +// // } + +// // type TypeName = "name" | "schema"; + +// // type ObjectType = +// // T extends "name" ? string : +// // T extends "schema" ? (bla: Bla) => NodeSpec : +// // never; + +// // class Test { +// // configs: any = {} + +// // storeConfig(key: string, value: any, stategy: ('extend' | 'overwrite')) { +// // const item = { +// // stategy, +// // value, +// // } + +// // if (this.configs[key]) { +// // this.configs[key].push(item) +// // } else { +// // this.configs[key] = [item] +// // } +// // } + +// // name(value: string) { +// // this.storeConfig('name', value, 'overwrite') +// // return this +// // } + +// // schema(value: (bla: Bla) => NodeSpec) { +// // this.storeConfig('schema', value, 'overwrite') +// // return this +// // } + +// // extend (key: T, value: ObjectType ) { +// // this.storeConfig(key, value, 'extend') +// // return this +// // } + +// // clone() { +// // return Object.assign( +// // Object.create( +// // // Set the prototype of the new object to the prototype of the instance. +// // // Used to allow new object behave like class instance. +// // Object.getPrototypeOf(this), +// // ), +// // // Prevent shallow copies of nested structures like arrays, etc +// // JSON.parse(JSON.stringify(this)), +// // ) +// // } +// // } + +// // const Bla = new Test() +// // .name('hey') + +// // const Bla2 = Bla +// // .clone() +// // .name('ho') + +// // console.log(Bla, Bla2) + + + + +// type NoInfer = [T][T extends any ? 0 : never]; + +// interface ExtensionCallback { // name: string -// options: any +// editor: Editor // } -// type TypeName = "name" | "schema"; +// interface ExtensionExtends { +// name: string +// options: AnyObject +// commands: (params: Callback) => CommandSpec +// inputRules: (params: Callback) => any[] +// pasteRules: (params: Callback) => any[] +// keys: (params: Callback) => { +// [key: string]: Function +// } +// plugins: (params: Callback) => Plugin[] +// } -// type ObjectType = -// T extends "name" ? string : -// T extends "schema" ? (bla: Bla) => NodeSpec : -// never; - -// class Test { +// class ExtensionTest { +// type = 'extension' // configs: any = {} +// usedOptions: Partial = {} -// storeConfig(key: string, value: any, stategy: ('extend' | 'overwrite')) { +// protected storeConfig(key: string, value: any, stategy: 'extend' | 'overwrite') { // const item = { // stategy, // value, @@ -738,355 +815,278 @@ let three = copyProperties(one, two) // } // } -// name(value: string) { +// public configure(options: Partial ) { +// this.usedOptions = { ...this.usedOptions, ...options } +// return this +// } + +// public name(value: Extends['name']) { // this.storeConfig('name', value, 'overwrite') // return this // } -// schema(value: (bla: Bla) => NodeSpec) { -// this.storeConfig('schema', value, 'overwrite') +// public defaultOptions(value: Options) { +// this.storeConfig('defaultOptions', value, 'overwrite') // return this // } -// extend (key: T, value: ObjectType ) { +// public commands(value: Extends['commands']) { +// this.storeConfig('commands', value, 'overwrite') +// return this +// } + +// public keys(value: Extends['keys']) { +// this.storeConfig('keys', value, 'overwrite') +// return this +// } + +// public inputRules(value: Extends['inputRules']) { +// this.storeConfig('inputRules', value, 'overwrite') +// return this +// } + +// public pasteRules(value: Extends['pasteRules']) { +// this.storeConfig('pasteRules', value, 'overwrite') +// return this +// } + +// public plugins(value: Extends['plugins']) { +// this.storeConfig('plugins', value, 'overwrite') +// return this +// } + +// public extend >(key: T, value: Extends[T]) { // this.storeConfig(key, value, 'extend') // return this // } + +// public create() { +// type ParentOptions = Options -// clone() { -// return Object.assign( -// Object.create( -// // Set the prototype of the new object to the prototype of the instance. -// // Used to allow new object behave like class instance. -// Object.getPrototypeOf(this), -// ), -// // Prevent shallow copies of nested structures like arrays, etc -// JSON.parse(JSON.stringify(this)), -// ) +// return (options?: Partial >) => { +// return cloneDeep(this, true).configure(options as Options) +// } // } // } -// const Bla = new Test() -// .name('hey') - -// const Bla2 = Bla -// .clone() -// .name('ho') - -// console.log(Bla, Bla2) - - - - -type NoInfer = [T][T extends any ? 0 : never]; - -interface ExtensionCallback { - name: string - editor: Editor -} - -interface ExtensionExtends { - name: string - options: AnyObject - commands: (params: Callback) => CommandSpec - inputRules: (params: Callback) => any[] - pasteRules: (params: Callback) => any[] - keys: (params: Callback) => { - [key: string]: Function - } - plugins: (params: Callback) => Plugin[] -} - -class ExtensionTest { - type = 'extension' - configs: any = {} - usedOptions: Partial = {} - - protected storeConfig(key: string, value: any, stategy: 'extend' | 'overwrite') { - const item = { - stategy, - value, - } - - if (this.configs[key]) { - this.configs[key].push(item) - } else { - this.configs[key] = [item] - } - } - - public configure(options: Partial ) { - this.usedOptions = { ...this.usedOptions, ...options } - return this - } - - public name(value: Extends['name']) { - this.storeConfig('name', value, 'overwrite') - return this - } - - public defaultOptions(value: Options) { - this.storeConfig('defaultOptions', value, 'overwrite') - return this - } - - public commands(value: Extends['commands']) { - this.storeConfig('commands', value, 'overwrite') - return this - } - - public keys(value: Extends['keys']) { - this.storeConfig('keys', value, 'overwrite') - return this - } - - public inputRules(value: Extends['inputRules']) { - this.storeConfig('inputRules', value, 'overwrite') - return this - } - - public pasteRules(value: Extends['pasteRules']) { - this.storeConfig('pasteRules', value, 'overwrite') - return this - } - - public plugins(value: Extends['plugins']) { - this.storeConfig('plugins', value, 'overwrite') - return this - } - - public extend >(key: T, value: Extends[T]) { - this.storeConfig(key, value, 'extend') - return this - } - - public create() { - type ParentOptions = Options - - return (options?: Partial >) => { - return cloneDeep(this, true).configure(options as Options) - } - } -} - -interface NodeCallback extends ExtensionCallback { - // TODO: fix optional - type?: NodeType -} - -interface NodeExtends extends ExtensionExtends { - topNode: boolean - schema: (params: Callback) => NodeSpec -} - -class NodeTest extends ExtensionTest { - type = 'node' - - public topNode(value: NodeExtends['topNode'] = true) { - this.storeConfig('topNode', value, 'overwrite') - return this - } - - public schema(value: NodeExtends['schema']) { - this.storeConfig('schema', value, 'overwrite') - return this - } -} - -interface TestOptions { - trigger: string -} - -const Suggestion = new NodeTest () - .name('suggestion') - .defaultOptions({ - trigger: '@' - }) - .schema(() => ({ - toDOM: () => ['div', 0] - })) - .keys(({ editor }) => ({ - 'Mod-i': () => editor.italic(), - })) - .commands(({ editor, name }) => ({ - [name]: next => () => { - editor.toggleMark(name) - next() - }, - })) - .plugins(() => [ - new Plugin({}), - ]) - .extend('schema', () => ({ - toDOM: () => ['span', 0], - })) - .create() - -// TODO: Erweitern -// const CustomHeadlineAligned = new Headline() -// .name('custom_headline') -// .extend('defaults', { -// levels: [1, 2, 3], -// class: 'font-xs text-outline text-center', -// alignments: ['left', 'center', 'right'], -// }) - -// const CustomHeadlineTag = new Headline() -// .name('custom_headline') -// .configure({ -// class: 'custom-headline', -// }) -// .schema(() => ({ -// toDOM: () => ['h1', 0], -// toVue: Component, -// })) -// .merge('schema', () => ({ -// parseDOM: [ -// { -// tag: 'x-custom-headline', -// } -// ], -// })) - - - - - -// const Blub = new ExtensionTest () -// .name('bla') -// .create() - -console.log(Suggestion()) - - - - - -// export const Suggestion = new Suggestion() -// .name('suggestion') -// .defaults({ -// trigger: '@', -// levels: [1, 2, 3], -// }) -// .extend('schema', ({ editor, name, type}) => ({ -// // levels: [1, 2, 3, 4, 5, 6], -// toDOM: () => ['strong', 0], -// })) -// .create() - - -// const Mention = Suggestion() -// .name('mention') -// .configure({ -// trigger: '@' -// }) -// .create() - -// const Hashtag = Suggestion() -// .name('hashtag') -// .options({ -// trigger: '#' -// }) -// .create() - - -// new Editor({ -// extensions: [ -// // Mention({}), -// // Hashtag(), -// // Suggestion({ trigger: '#'}).name('hashtag'), - -// // Suggestion.option({ trigger: '@'}).name('mention'), -// ] -// }) - -// interface MentionOptions { -// trigger: string -// foo: string +// interface NodeCallback extends ExtensionCallback { +// // TODO: fix optional +// type?: NodeType // } -// const Mention = Suggestion () -// .name('mention') -// .create({ -// trigger: '@' -// }) +// interface NodeExtends extends ExtensionExtends { +// topNode: boolean +// schema: (params: Callback) => NodeSpec +// } -// const Hashtag = Suggestion({ -// trigger: '#' -// }) -// .create() +// class NodeTest extends ExtensionTest { +// type = 'node' -// console.log(Mention(), Hashtag()) +// public topNode(value: NodeExtends['topNode'] = true) { +// this.storeConfig('topNode', value, 'overwrite') +// return this +// } +// public schema(value: NodeExtends['schema']) { +// this.storeConfig('schema', value, 'overwrite') +// return this +// } +// } +// interface TestOptions { +// trigger: string +// } - - -// // create extension -// const Suggestion = new Node() +// const Suggestion = new NodeTest () // .name('suggestion') -// .options({ -// trigger: '@', -// }) -// .create() - -// // use extension -// new Editor({ -// extensions: [ -// Suggestion(), -// ], -// }) - -// // use extension with setting options -// new Editor({ -// extensions: [ -// Suggestion({ -// trigger: '@', -// }), -// ], -// }) - -// // create extended nodes -// const Mention = Suggestion() -// .name('mention') -// .create({ +// .defaultOptions({ // trigger: '@' // }) -// const Hashtag = Suggestion() -// .name('hashtag') -// .create({ -// trigger: '#' -// }) - -// new Editor({ -// extensions: [ -// Mention(), -// Hashtag(), -// ], -// }) - -// // extend nodes -// const Whatever = Suggestion() -// .extend('options', { -// foo: 'bar', -// }) +// .schema(() => ({ +// toDOM: () => ['div', 0] +// })) +// .keys(({ editor }) => ({ +// 'Mod-i': () => editor.italic(), +// })) +// .commands(({ editor, name }) => ({ +// [name]: next => () => { +// editor.toggleMark(name) +// next() +// }, +// })) +// .plugins(() => [ +// new Plugin({}), +// ]) +// .extend('schema', () => ({ +// toDOM: () => ['span', 0], +// })) // .create() -// // btw: this... -// Suggestion({ -// trigger: '@' -// }) +// // TODO: Erweitern +// // const CustomHeadlineAligned = new Headline() +// // .name('custom_headline') +// // .extend('defaults', { +// // levels: [1, 2, 3], +// // class: 'font-xs text-outline text-center', +// // alignments: ['left', 'center', 'right'], +// // }) -// // ...is equivalent to -// Suggestion().create({ -// trigger: '@' -// }) - -// Suggestion() -// .name('mention') - -// // would be the same -// Suggestion() -// .override('name', 'mention') +// // const CustomHeadlineTag = new Headline() +// // .name('custom_headline') +// // .configure({ +// // class: 'custom-headline', +// // }) +// // .schema(() => ({ +// // toDOM: () => ['h1', 0], +// // toVue: Component, +// // })) +// // .merge('schema', () => ({ +// // parseDOM: [ +// // { +// // tag: 'x-custom-headline', +// // } +// // ], +// // })) + + + + + +// // const Blub = new ExtensionTest () +// // .name('bla') +// // .create() + +// console.log(Suggestion()) + + + + + +// // export const Suggestion = new Suggestion() +// // .name('suggestion') +// // .defaults({ +// // trigger: '@', +// // levels: [1, 2, 3], +// // }) +// // .extend('schema', ({ editor, name, type}) => ({ +// // // levels: [1, 2, 3, 4, 5, 6], +// // toDOM: () => ['strong', 0], +// // })) +// // .create() + + +// // const Mention = Suggestion() +// // .name('mention') +// // .configure({ +// // trigger: '@' +// // }) +// // .create() + +// // const Hashtag = Suggestion() +// // .name('hashtag') +// // .options({ +// // trigger: '#' +// // }) +// // .create() + + +// // new Editor({ +// // extensions: [ +// // // Mention({}), +// // // Hashtag(), +// // // Suggestion({ trigger: '#'}).name('hashtag'), + +// // // Suggestion.option({ trigger: '@'}).name('mention'), +// // ] +// // }) + +// // interface MentionOptions { +// // trigger: string +// // foo: string +// // } + +// // const Mention = Suggestion () +// // .name('mention') +// // .create({ +// // trigger: '@' +// // }) + +// // const Hashtag = Suggestion({ +// // trigger: '#' +// // }) +// // .create() + +// // console.log(Mention(), Hashtag()) + + + + + +// // // create extension +// // const Suggestion = new Node() +// // .name('suggestion') +// // .options({ +// // trigger: '@', +// // }) +// // .create() + +// // // use extension +// // new Editor({ +// // extensions: [ +// // Suggestion(), +// // ], +// // }) + +// // // use extension with setting options +// // new Editor({ +// // extensions: [ +// // Suggestion({ +// // trigger: '@', +// // }), +// // ], +// // }) + +// // // create extended nodes +// // const Mention = Suggestion() +// // .name('mention') +// // .create({ +// // trigger: '@' +// // }) +// // const Hashtag = Suggestion() +// // .name('hashtag') +// // .create({ +// // trigger: '#' +// // }) + +// // new Editor({ +// // extensions: [ +// // Mention(), +// // Hashtag(), +// // ], +// // }) + +// // // extend nodes +// // const Whatever = Suggestion() +// // .extend('options', { +// // foo: 'bar', +// // }) +// // .create() + +// // // btw: this... +// // Suggestion({ +// // trigger: '@' +// // }) + +// // // ...is equivalent to +// // Suggestion().create({ +// // trigger: '@' +// // }) + +// // Suggestion() +// // .name('mention') + +// // // would be the same +// // Suggestion() +// // .override('name', 'mention')