diff --git a/docs/src/demos/Api/Schema/GenerateHTML/index.vue b/docs/src/demos/Api/Schema/GenerateHTML/index.vue index b0a6eda4..1fa55904 100644 --- a/docs/src/demos/Api/Schema/GenerateHTML/index.vue +++ b/docs/src/demos/Api/Schema/GenerateHTML/index.vue @@ -27,9 +27,9 @@ export default { mounted() { this.html = generateHTML(this.json, [ - Document(), - Paragraph(), - Text(), + Document, + Paragraph, + Text, ]) }, } diff --git a/docs/src/demos/Examples/CollaborativeEditing/index.vue b/docs/src/demos/Examples/CollaborativeEditing/index.vue index 36403f81..f1be445c 100644 --- a/docs/src/demos/Examples/CollaborativeEditing/index.vue +++ b/docs/src/demos/Examples/CollaborativeEditing/index.vue @@ -135,11 +135,11 @@ export default { this.editor = new Editor({ extensions: [ ...defaultExtensions(), - Collaboration({ + Collaboration.set({ provider: this.provider, type: this.type, }), - CollaborationCursor({ + CollaborationCursor.set({ provider: this.provider, name: this.name, color: this.color, diff --git a/docs/src/demos/Examples/Formatting/index.vue b/docs/src/demos/Examples/Formatting/index.vue index ce9c2a99..a42d1dbd 100644 --- a/docs/src/demos/Examples/Formatting/index.vue +++ b/docs/src/demos/Examples/Formatting/index.vue @@ -61,16 +61,16 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - Heading({ + Document, + Paragraph, + Text, + Heading.set({ level: [1, 2, 3], }), - Bold(), - Italic(), - TextAlign(), - HardBreak(), + Bold, + Italic, + TextAlign, + HardBreak, ], content: `
diff --git a/docs/src/demos/Examples/MarkdownShortcuts/index.vue b/docs/src/demos/Examples/MarkdownShortcuts/index.vue index 5bd851c1..c5f69fb3 100644 --- a/docs/src/demos/Examples/MarkdownShortcuts/index.vue +++ b/docs/src/demos/Examples/MarkdownShortcuts/index.vue @@ -37,7 +37,7 @@ export default { `, extensions: [ ...defaultExtensions(), - Highlight(), + Highlight, ], }) }, diff --git a/docs/src/demos/Examples/Minimalist/index.vue b/docs/src/demos/Examples/Minimalist/index.vue index 8f53dc21..8eeccee3 100644 --- a/docs/src/demos/Examples/Minimalist/index.vue +++ b/docs/src/demos/Examples/Minimalist/index.vue @@ -22,9 +22,9 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), + Document, + Paragraph, + Text, ], content: `
diff --git a/docs/src/demos/Examples/TodoApp/index.vue b/docs/src/demos/Examples/TodoApp/index.vue index 702d9499..f72fd71a 100644 --- a/docs/src/demos/Examples/TodoApp/index.vue +++ b/docs/src/demos/Examples/TodoApp/index.vue @@ -35,11 +35,11 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - CustomDocument(), - Paragraph(), - Text(), - TaskList(), - CustomTaskItem(), + CustomDocument, + Paragraph, + Text, + TaskList, + CustomTaskItem, ], content: `
I’m running tiptap with Vue.js. This demo is interactive, try to edit the text.
', extensions: [ - Document(), - Paragraph(), - Text(), - Bold(), + Document, + Paragraph, + Text, + Bold, ], }) }, diff --git a/docs/src/demos/Extensions/Collaboration/index.vue b/docs/src/demos/Extensions/Collaboration/index.vue index 7a95586a..73d8e929 100644 --- a/docs/src/demos/Extensions/Collaboration/index.vue +++ b/docs/src/demos/Extensions/Collaboration/index.vue @@ -37,10 +37,10 @@ export default { //Example Text
// `, extensions: [ - Document(), - Paragraph(), - Text(), - Collaboration({ + Document, + Paragraph, + Text, + Collaboration.set({ provider: this.provider, type: this.type, }), diff --git a/docs/src/demos/Extensions/CollaborationCursor/index.vue b/docs/src/demos/Extensions/CollaborationCursor/index.vue index a7314bdf..ed764a06 100644 --- a/docs/src/demos/Extensions/CollaborationCursor/index.vue +++ b/docs/src/demos/Extensions/CollaborationCursor/index.vue @@ -38,14 +38,14 @@ export default { //Example Text
// `, extensions: [ - Document(), - Paragraph(), - Text(), - Collaboration({ + Document, + Paragraph, + Text, + Collaboration.set({ provider: this.provider, type: this.type, }), - CollaborationCursor({ + CollaborationCursor.set({ provider: this.provider, name: 'Cyndi Lauper', color: '#f783ac', diff --git a/docs/src/demos/Extensions/Dropcursor/index.vue b/docs/src/demos/Extensions/Dropcursor/index.vue index 613f754d..4414f5c1 100644 --- a/docs/src/demos/Extensions/Dropcursor/index.vue +++ b/docs/src/demos/Extensions/Dropcursor/index.vue @@ -26,11 +26,11 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - Image(), - Dropcursor(), + Document, + Paragraph, + Text, + Image, + Dropcursor, ], content: `Try to drag around the image. While you drag, the editor should show a decoration under your cursor. The so called dropcursor.
diff --git a/docs/src/demos/Extensions/Focus/index.vue b/docs/src/demos/Extensions/Focus/index.vue index fa38363e..7da2bc89 100644 --- a/docs/src/demos/Extensions/Focus/index.vue +++ b/docs/src/demos/Extensions/Focus/index.vue @@ -28,16 +28,16 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - Focus({ + Document, + Paragraph, + Text, + Focus.set({ className: 'has-focus', nested: true, }), - Code(), - BulletList(), - ListItem(), + Code, + BulletList, + ListItem, ], autoFocus: true, content: ` diff --git a/docs/src/demos/Extensions/FontFamily/index.vue b/docs/src/demos/Extensions/FontFamily/index.vue index a76515b3..b2a43a4a 100644 --- a/docs/src/demos/Extensions/FontFamily/index.vue +++ b/docs/src/demos/Extensions/FontFamily/index.vue @@ -46,11 +46,11 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - TextStyle(), - FontFamily(), + Document, + Paragraph, + Text, + TextStyle, + FontFamily, ], content: `Did you know that Inter is a really nice font for interfaces?
diff --git a/docs/src/demos/Extensions/Gapcursor/index.vue b/docs/src/demos/Extensions/Gapcursor/index.vue index ce5a475d..1abcee45 100644 --- a/docs/src/demos/Extensions/Gapcursor/index.vue +++ b/docs/src/demos/Extensions/Gapcursor/index.vue @@ -26,11 +26,11 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - Image(), - Gapcursor(), + Document, + Paragraph, + Text, + Image, + Gapcursor, ], content: `Try to set the cursor behind the image with your arrow keys! You should see big blinking cursor right from the image. This is the gapcursor.
diff --git a/docs/src/demos/Extensions/History/index.vue b/docs/src/demos/Extensions/History/index.vue index b44d168e..3946b239 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: [ - Document(), - Paragraph(), - Text(), - History(), + Document, + Paragraph, + Text, + History, ], content: `diff --git a/docs/src/demos/Extensions/TextAlign/index.vue b/docs/src/demos/Extensions/TextAlign/index.vue index 8b5e963a..c7ff0694 100644 --- a/docs/src/demos/Extensions/TextAlign/index.vue +++ b/docs/src/demos/Extensions/TextAlign/index.vue @@ -42,11 +42,11 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - Heading(), - TextAlign(), + Document, + Paragraph, + Text, + Heading, + TextAlign, ], content: `
“I have been suffering from Typomania all my life, a sickness that is incurable but not lethal.”
diff --git a/docs/src/demos/Guide/BuildYourEditor/index.vue b/docs/src/demos/Guide/BuildYourEditor/index.vue index 07fa9eb5..5229d4c9 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 headless. You can easily add custom nodes as Vue components.
', extensions: [ - Document(), - Paragraph(), - Text(), - CodeBlock(), - History(), - Bold(), - Italic(), - Code(), - Heading(), + Document, + Paragraph, + Text, + CodeBlock, + History, + Bold, + Italic, + Code, + Heading, ], }) }, diff --git a/docs/src/demos/Marks/Bold/index.vue b/docs/src/demos/Marks/Bold/index.vue index 8cc71857..4639ece4 100644 --- a/docs/src/demos/Marks/Bold/index.vue +++ b/docs/src/demos/Marks/Bold/index.vue @@ -30,10 +30,10 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - Bold(), + Document, + Paragraph, + Text, + Bold, ], content: `This isn’t bold.
diff --git a/docs/src/demos/Marks/Code/index.vue b/docs/src/demos/Marks/Code/index.vue index 78d782dd..ac874df5 100644 --- a/docs/src/demos/Marks/Code/index.vue +++ b/docs/src/demos/Marks/Code/index.vue @@ -30,10 +30,10 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - Code(), + Document, + Paragraph, + Text, + Code, ], content: `This isn’t code.
diff --git a/docs/src/demos/Marks/Highlight/index.vue b/docs/src/demos/Marks/Highlight/index.vue index 1028d415..1d766605 100644 --- a/docs/src/demos/Marks/Highlight/index.vue +++ b/docs/src/demos/Marks/Highlight/index.vue @@ -61,10 +61,10 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - Highlight(), + Document, + Paragraph, + Text, + Highlight, ], content: `This isn’t highlighted.
diff --git a/docs/src/demos/Marks/Italic/index.vue b/docs/src/demos/Marks/Italic/index.vue index ae605f45..c736e023 100644 --- a/docs/src/demos/Marks/Italic/index.vue +++ b/docs/src/demos/Marks/Italic/index.vue @@ -30,10 +30,10 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - Italic(), + Document, + Paragraph, + Text, + Italic, ], content: `This isn’t italic.
diff --git a/docs/src/demos/Marks/Link/index.vue b/docs/src/demos/Marks/Link/index.vue index 4297b8c1..296f6e8c 100644 --- a/docs/src/demos/Marks/Link/index.vue +++ b/docs/src/demos/Marks/Link/index.vue @@ -32,10 +32,10 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - Link(), + Document, + Paragraph, + Text, + Link, ], content: `diff --git a/docs/src/demos/Marks/Strike/index.vue b/docs/src/demos/Marks/Strike/index.vue index eb5ab579..c3dc75d0 100644 --- a/docs/src/demos/Marks/Strike/index.vue +++ b/docs/src/demos/Marks/Strike/index.vue @@ -30,10 +30,10 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - Strike(), + Document, + Paragraph, + Text, + Strike, ], content: `
This isn’t striked through.
diff --git a/docs/src/demos/Marks/TextStyle/index.vue b/docs/src/demos/Marks/TextStyle/index.vue index 32cfbe85..40a06983 100644 --- a/docs/src/demos/Marks/TextStyle/index.vue +++ b/docs/src/demos/Marks/TextStyle/index.vue @@ -26,10 +26,10 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - TextStyle(), + Document, + Paragraph, + Text, + TextStyle, ], content: `This has a <span> tag without a style attribute, so it’s thrown away.
diff --git a/docs/src/demos/Marks/Underline/index.vue b/docs/src/demos/Marks/Underline/index.vue index 1ea31b47..a1511948 100644 --- a/docs/src/demos/Marks/Underline/index.vue +++ b/docs/src/demos/Marks/Underline/index.vue @@ -30,10 +30,10 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - Underline(), + Document, + Paragraph, + Text, + Underline, ], content: `There is no underline here.
diff --git a/docs/src/demos/Nodes/Blockquote/index.vue b/docs/src/demos/Nodes/Blockquote/index.vue index 4f584035..15148420 100644 --- a/docs/src/demos/Nodes/Blockquote/index.vue +++ b/docs/src/demos/Nodes/Blockquote/index.vue @@ -30,10 +30,10 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - Blockquote(), + Document, + Paragraph, + Text, + Blockquote, ], content: `diff --git a/docs/src/demos/Nodes/BulletList/index.vue b/docs/src/demos/Nodes/BulletList/index.vue index 70491f71..c501ef12 100644 --- a/docs/src/demos/Nodes/BulletList/index.vue +++ b/docs/src/demos/Nodes/BulletList/index.vue @@ -31,11 +31,11 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - BulletList(), - ListItem(), + Document, + Paragraph, + Text, + BulletList, + ListItem, ], content: `diff --git a/docs/src/demos/Nodes/CodeBlock/index.vue b/docs/src/demos/Nodes/CodeBlock/index.vue index 9eb2b818..4da9c34e 100644 --- a/docs/src/demos/Nodes/CodeBlock/index.vue +++ b/docs/src/demos/Nodes/CodeBlock/index.vue @@ -30,10 +30,10 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - CodeBlock(), + Document, + Paragraph, + Text, + CodeBlock, ], content: `
diff --git a/docs/src/demos/Nodes/Document/index.vue b/docs/src/demos/Nodes/Document/index.vue index 349a817e..18afe7bf 100644 --- a/docs/src/demos/Nodes/Document/index.vue +++ b/docs/src/demos/Nodes/Document/index.vue @@ -25,9 +25,9 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), + Document, + Paragraph, + Text, ], content: `
The Document extension is required. Though, you can write your own implementation, e. g. to give it custom name.
diff --git a/docs/src/demos/Nodes/HardBreak/index.vue b/docs/src/demos/Nodes/HardBreak/index.vue index 8eed497b..ea2bee88 100644 --- a/docs/src/demos/Nodes/HardBreak/index.vue +++ b/docs/src/demos/Nodes/HardBreak/index.vue @@ -30,10 +30,10 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - HardBreak(), + Document, + Paragraph, + Text, + HardBreak, ], content: `diff --git a/docs/src/demos/Nodes/Heading/index.vue b/docs/src/demos/Nodes/Heading/index.vue index ce4e0f43..2f8c474d 100644 --- a/docs/src/demos/Nodes/Heading/index.vue +++ b/docs/src/demos/Nodes/Heading/index.vue @@ -36,10 +36,10 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - Heading({ + Document, + Paragraph, + Text, + Heading.set({ levels: [1, 2, 3], }), ], diff --git a/docs/src/demos/Nodes/HorizontalRule/index.vue b/docs/src/demos/Nodes/HorizontalRule/index.vue index 4b4f23e2..a2743866 100644 --- a/docs/src/demos/Nodes/HorizontalRule/index.vue +++ b/docs/src/demos/Nodes/HorizontalRule/index.vue @@ -30,10 +30,10 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - HorizontalRule(), + Document, + Paragraph, + Text, + HorizontalRule, ], content: `
This is a paragraph.
diff --git a/docs/src/demos/Nodes/Image/index.vue b/docs/src/demos/Nodes/Image/index.vue index a101cda5..143b1322 100644 --- a/docs/src/demos/Nodes/Image/index.vue +++ b/docs/src/demos/Nodes/Image/index.vue @@ -38,11 +38,11 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - Image(), - Dropcursor(), + Document, + Paragraph, + Text, + Image, + Dropcursor, ], content: `This is a basic example of implementing images. Drag to re-order.
diff --git a/docs/src/demos/Nodes/ListItem/index.vue b/docs/src/demos/Nodes/ListItem/index.vue index 86137256..9cc93b50 100644 --- a/docs/src/demos/Nodes/ListItem/index.vue +++ b/docs/src/demos/Nodes/ListItem/index.vue @@ -35,12 +35,12 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - BulletList(), - OrderedList(), - ListItem(), + Document, + Paragraph, + Text, + BulletList, + OrderedList, + ListItem, ], content: `diff --git a/docs/src/demos/Nodes/OrderedList/index.vue b/docs/src/demos/Nodes/OrderedList/index.vue index 0677b451..45eda95c 100644 --- a/docs/src/demos/Nodes/OrderedList/index.vue +++ b/docs/src/demos/Nodes/OrderedList/index.vue @@ -31,11 +31,11 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - OrderedList(), - ListItem(), + Document, + Paragraph, + Text, + OrderedList, + ListItem, ], content: `
diff --git a/docs/src/demos/Nodes/Paragraph/index.vue b/docs/src/demos/Nodes/Paragraph/index.vue index 971711b8..f296f183 100644 --- a/docs/src/demos/Nodes/Paragraph/index.vue +++ b/docs/src/demos/Nodes/Paragraph/index.vue @@ -25,9 +25,9 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), + Document, + Paragraph, + Text, ], content: `
The Paragraph extension is not required, but it’s very likely you want to use it. It’s needed to write paragraphs of text. 🤓
diff --git a/docs/src/demos/Nodes/TaskItem/index.vue b/docs/src/demos/Nodes/TaskItem/index.vue index db0385f3..4e279bc3 100644 --- a/docs/src/demos/Nodes/TaskItem/index.vue +++ b/docs/src/demos/Nodes/TaskItem/index.vue @@ -27,11 +27,11 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - TaskList(), - TaskItem(), + Document, + Paragraph, + Text, + TaskList, + TaskItem, ], content: `diff --git a/docs/src/demos/Nodes/TaskList/index.vue b/docs/src/demos/Nodes/TaskList/index.vue index 6baf52e5..4627bc7b 100644 --- a/docs/src/demos/Nodes/TaskList/index.vue +++ b/docs/src/demos/Nodes/TaskList/index.vue @@ -31,11 +31,11 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), - TaskList(), - TaskItem(), + Document, + Paragraph, + Text, + TaskList, + TaskItem, ], content: `
diff --git a/docs/src/demos/Nodes/Text/index.vue b/docs/src/demos/Nodes/Text/index.vue index a3557624..af5648d5 100644 --- a/docs/src/demos/Nodes/Text/index.vue +++ b/docs/src/demos/Nodes/Text/index.vue @@ -25,9 +25,9 @@ export default { mounted() { this.editor = new Editor({ extensions: [ - Document(), - Paragraph(), - Text(), + Document, + Paragraph, + Text, ], content: `
The Text extension is required, at least if you want to have text in your text editor and that’s very likely.
diff --git a/packages/core/src/Editor.ts b/packages/core/src/Editor.ts index 8757cabb..7350a28c 100644 --- a/packages/core/src/Editor.ts +++ b/packages/core/src/Editor.ts @@ -14,6 +14,9 @@ import createStyleTag from './utils/createStyleTag' import CommandManager from './CommandManager' import ExtensionManager from './ExtensionManager' import EventEmitter from './EventEmitter' +import { Extension } from './Extension' +import { NodeExtension } from './NodeExtension' +import { MarkExtension } from './MarkExtension' import { Extensions, UnionToIntersection, PickValue } from './types' import * as extensions from './extensions' import style from './style' @@ -37,7 +40,62 @@ export interface CommandsSpec { export interface AllExtensions {} -export type AllCommands = UnionToIntersection, 'addCommands'>>> +// type names = AllExtensions[keyof AllExtensions] +// type onlyExtensions = AllExtensions[keyof AllExtensions] extends Extension ? '1' : '0' +// type onlyExtensions = AllExtensions[keyof AllExtensions extends Extension ? '1' : '0'] + +// export type OnlyExtensions = { +// [Item in keyof AllExtensions]: AllExtensions[Item] extends Extension +// ? AllExtensions[Item] +// : never +// } + +// type ExtractCat = A extends Extension ? A : never + +// export type OnlyExtensions = ExtractCat - + +// type ExtractCommands
= G extends Extension ? S : never +// type Test = UnionToIntersection > + +// type SubType = Pick ; + +// type OnlyExtensions = SubType +// type ExtractCommands = G extends Extension ? S : never +// type Test = ExtractCommands + +// type ExtractCommands = G extends Extension +// ? never +// : G extends NodeExtension +// ? never +// : G extends MarkExtension +// ? U +// : never + +// export type Bla = { +// [Item in keyof AllExtensions]: AllExtensions[Item] extends Extension +// ? S +// : AllExtensions[Item] extends NodeExtension +// ? T +// : AllExtensions[Item] extends MarkExtension +// ? U +// : never +// } + +export type Bla = { + [Item in keyof AllExtensions]: AllExtensions[Item] extends Extension + ? ExtensionCommands + : AllExtensions[Item] extends NodeExtension + ? NodeExtensionCommands + : AllExtensions[Item] extends MarkExtension + ? MarkExtensionCommands + : never +} + +type ValuesOf = T[keyof T]; +type KeysWithTypeOf = ({[P in keyof T]: T[P] extends Type ? P : never })[keyof T] +type AllCommands = UnionToIntersection >>> export type SingleCommands = { [Item in keyof AllCommands]: AllCommands[Item] extends (...args: any[]) => any @@ -239,7 +297,7 @@ export class Editor extends EventEmitter { * Creates an extension manager. */ private createExtensionManager() { - const coreExtensions = Object.entries(extensions).map(([, extension]) => extension()) + const coreExtensions = Object.entries(extensions).map(([, extension]) => extension) const allExtensions = [...this.options.extensions, ...coreExtensions] this.extensionManager = new ExtensionManager(allExtensions, this.proxy) diff --git a/packages/core/src/Extension.ts b/packages/core/src/Extension.ts index 48d23b4e..aec32953 100644 --- a/packages/core/src/Extension.ts +++ b/packages/core/src/Extension.ts @@ -63,55 +63,6 @@ export interface ExtensionSpec { }) => Plugin[], } -// /** -// * Extension interface for internal usage -// */ -// export type Extension = Required & { -// type: string, -// options: { -// [key: string]: any -// }, -// }> - -// /** -// * Default extension -// */ -// export const defaultExtension: Extension = { -// name: 'extension', -// type: 'extension', -// options: {}, -// addGlobalAttributes: () => [], -// addCommands: () => ({}), -// addKeyboardShortcuts: () => ({}), -// addInputRules: () => [], -// addPasteRules: () => [], -// addProseMirrorPlugins: () => [], -// } - -// export function createExtension (config: ExtensionSpec ) { -// const extend = (extendedConfig: Partial >) => { -// return createExtension({ -// ...config, -// ...extendedConfig, -// } as ExtensionSpec ) -// } - -// const setOptions = (options?: Partial ) => { -// const { defaultOptions, ...rest } = config - -// return { -// ...defaultExtension, -// ...rest, -// options: { -// ...defaultOptions, -// ...options, -// } as Options, -// } -// } - -// return Object.assign(setOptions, { config, extend }) -// } - export class Extension { config: Required = { name: 'extension', @@ -144,6 +95,8 @@ export class Extension { ...this.config.defaultOptions, ...options, } + + return this } extend (extendedConfig: Partial >) { diff --git a/packages/core/src/ExtensionManager.ts b/packages/core/src/ExtensionManager.ts index 5c6ea347..eb10635a 100644 --- a/packages/core/src/ExtensionManager.ts +++ b/packages/core/src/ExtensionManager.ts @@ -28,10 +28,10 @@ export default class ExtensionManager { const context = { options: extension.options, editor: this.editor, - type: getSchemaTypeByName(extension.name, this.schema), + type: getSchemaTypeByName(extension.config.name, this.schema), } - const commands = extension.addCommands.bind(context)() + const commands = extension.config.addCommands.bind(context)() editor.registerCommands(commands) }) @@ -43,10 +43,10 @@ export default class ExtensionManager { const context = { options: extension.options, editor: this.editor, - type: getSchemaTypeByName(extension.name, this.schema), + type: getSchemaTypeByName(extension.config.name, this.schema), } - return extension.addProseMirrorPlugins.bind(context)() + return extension.config.addProseMirrorPlugins.bind(context)() }) .flat() @@ -64,10 +64,10 @@ export default class ExtensionManager { const context = { options: extension.options, editor: this.editor, - type: getSchemaTypeByName(extension.name, this.schema), + type: getSchemaTypeByName(extension.config.name, this.schema), } - return extension.addInputRules.bind(context)() + return extension.config.addInputRules.bind(context)() }) .flat() } @@ -78,10 +78,10 @@ export default class ExtensionManager { const context = { options: extension.options, editor: this.editor, - type: getSchemaTypeByName(extension.name, this.schema), + type: getSchemaTypeByName(extension.config.name, this.schema), } - return extension.addPasteRules.bind(context)() + return extension.config.addPasteRules.bind(context)() }) .flat() } @@ -91,10 +91,10 @@ export default class ExtensionManager { const context = { options: extension.options, editor: this.editor, - type: getSchemaTypeByName(extension.name, this.schema), + type: getSchemaTypeByName(extension.config.name, this.schema), } - return keymap(extension.addKeyboardShortcuts.bind(context)()) + return keymap(extension.config.addKeyboardShortcuts.bind(context)()) }) } @@ -104,17 +104,17 @@ export default class ExtensionManager { const allAttributes = getAttributesFromExtensions(this.extensions) return Object.fromEntries(nodeExtensions - .filter(extension => !!extension.addNodeView) + .filter(extension => !!extension.config.addNodeView) .map(extension => { - const extensionAttributes = allAttributes.filter(attribute => attribute.type === extension.name) + const extensionAttributes = allAttributes.filter(attribute => attribute.type === extension.config.name) const context = { options: extension.options, editor, - type: getSchemaTypeByName(extension.name, this.schema), + type: getSchemaTypeByName(extension.config.name, this.schema), } // @ts-ignore - const renderer = extension.addNodeView?.bind(context)?.() as NodeViewRenderer + const renderer = extension.config.addNodeView?.bind(context)?.() as NodeViewRenderer const nodeview = ( node: ProsemirrorNode, @@ -133,7 +133,7 @@ export default class ExtensionManager { }) } - return [extension.name, nodeview] + return [extension.config.name, nodeview] })) } diff --git a/packages/core/src/MarkExtension.ts b/packages/core/src/MarkExtension.ts index 971ba1a9..64a7e9e6 100644 --- a/packages/core/src/MarkExtension.ts +++ b/packages/core/src/MarkExtension.ts @@ -106,51 +106,7 @@ export interface MarkExtensionSpec extends Overwri }) => Plugin[], }> {} -// export type MarkExtension = Required & { -// type: string, -// options: { -// [key: string]: any -// }, -// }> - -// const defaultMark: MarkExtension = { -// ...defaultExtension, -// type: 'mark', -// name: 'mark', -// inclusive: null, -// excludes: null, -// group: null, -// spanning: null, -// parseHTML: () => null, -// renderHTML: null, -// addAttributes: () => ({}), -// } - -// export function createMark (config: MarkExtensionSpec ) { -// const extend = (extendedConfig: Partial >) => { -// return createMark({ -// ...config, -// ...extendedConfig, -// } as MarkExtensionSpec ) -// } - -// const setOptions = (options?: Partial ) => { -// const { defaultOptions, ...rest } = config - -// return { -// ...defaultMark, -// ...rest, -// options: { -// ...defaultOptions, -// ...options, -// } as Options, -// } -// } - -// return Object.assign(setOptions, { config, extend }) -// } - -export class MarkExtension { +export class MarkExtension { config: Required = { name: 'mark', defaultOptions: {}, @@ -189,6 +145,8 @@ export class MarkExtension { ...this.config.defaultOptions, ...options, } + + return this } extend (extendedConfig: Partial >) { diff --git a/packages/core/src/NodeExtension.ts b/packages/core/src/NodeExtension.ts index 92a9e05f..79991887 100644 --- a/packages/core/src/NodeExtension.ts +++ b/packages/core/src/NodeExtension.ts @@ -150,59 +150,7 @@ export interface NodeExtensionSpec extends Overwri }) => NodeViewRenderer) | null, }> {} -// export type NodeExtension = Required & { -// type: string, -// options: { -// [key: string]: any -// }, -// }> - -// const defaultNode: NodeExtension = { -// ...defaultExtension, -// type: 'node', -// name: 'node', -// topNode: false, -// content: null, -// marks: null, -// group: null, -// inline: null, -// atom: null, -// selectable: null, -// draggable: null, -// code: null, -// defining: null, -// isolating: null, -// parseHTML: () => null, -// renderHTML: null, -// addAttributes: () => ({}), -// addNodeView: 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 }) -// } - -export class NodeExtension { +export class NodeExtension { config: Required = { name: 'node', defaultOptions: {}, @@ -249,6 +197,8 @@ export class NodeExtension { ...this.config.defaultOptions, ...options, } + + return this } extend (extendedConfig: Partial >) { diff --git a/packages/core/src/utils/getAttributesFromExtensions.ts b/packages/core/src/utils/getAttributesFromExtensions.ts index 62a327c3..389d435a 100644 --- a/packages/core/src/utils/getAttributesFromExtensions.ts +++ b/packages/core/src/utils/getAttributesFromExtensions.ts @@ -27,7 +27,7 @@ export default function getAttributesFromExtensions(extensions: Extensions) { options: extension.options, } - const globalAttributes = extension.addGlobalAttributes.bind(context)() as GlobalAttributes + const globalAttributes = extension.config.addGlobalAttributes.bind(context)() as GlobalAttributes globalAttributes.forEach(globalAttribute => { globalAttribute.types.forEach(type => { @@ -52,13 +52,13 @@ export default function getAttributesFromExtensions(extensions: Extensions) { options: extension.options, } - const attributes = extension.addAttributes.bind(context)() as Attributes + const attributes = extension.config.addAttributes.bind(context)() as Attributes Object .entries(attributes) .forEach(([name, attribute]) => { extensionAttributes.push({ - type: extension.name, + type: extension.config.name, name, attribute: { ...defaultAttribute, diff --git a/packages/core/src/utils/getSchema.ts b/packages/core/src/utils/getSchema.ts index ee0bed4d..39bb24c4 100644 --- a/packages/core/src/utils/getSchema.ts +++ b/packages/core/src/utils/getSchema.ts @@ -21,35 +21,35 @@ function cleanUpSchemaItem (data: T) { export default function getSchema(extensions: Extensions): Schema { const allAttributes = getAttributesFromExtensions(extensions) const { nodeExtensions, markExtensions } = splitExtensions(extensions) - const topNode = nodeExtensions.find(extension => extension.topNode)?.name + const topNode = nodeExtensions.find(extension => extension.config.topNode)?.config.name const nodes = Object.fromEntries(nodeExtensions.map(extension => { - const extensionAttributes = allAttributes.filter(attribute => attribute.type === extension.name) + const extensionAttributes = allAttributes.filter(attribute => attribute.type === extension.config.name) const context = { options: extension.options } const schema: NodeSpec = cleanUpSchemaItem({ - content: callOrReturn(extension.content, context), - marks: callOrReturn(extension.marks, context), - group: callOrReturn(extension.group, context), - inline: callOrReturn(extension.inline, context), - atom: callOrReturn(extension.atom, context), - selectable: callOrReturn(extension.selectable, context), - draggable: callOrReturn(extension.draggable, context), - code: callOrReturn(extension.code, context), - defining: callOrReturn(extension.defining, context), - isolating: callOrReturn(extension.isolating, context), + content: callOrReturn(extension.config.content, context), + marks: callOrReturn(extension.config.marks, context), + group: callOrReturn(extension.config.group, context), + inline: callOrReturn(extension.config.inline, context), + atom: callOrReturn(extension.config.atom, context), + selectable: callOrReturn(extension.config.selectable, context), + draggable: callOrReturn(extension.config.draggable, context), + code: callOrReturn(extension.config.code, context), + defining: callOrReturn(extension.config.defining, context), + isolating: callOrReturn(extension.config.isolating, context), attrs: Object.fromEntries(extensionAttributes.map(extensionAttribute => { return [extensionAttribute.name, { default: extensionAttribute?.attribute?.default }] })), }) - if (extension.parseHTML) { - schema.parseDOM = extension.parseHTML + if (extension.config.parseHTML) { + schema.parseDOM = extension.config.parseHTML .bind(context)() ?.map(parseRule => injectExtensionAttributesToParseRule(parseRule, extensionAttributes)) } - if (extension.renderHTML) { - schema.toDOM = node => (extension.renderHTML as Function)?.bind(context)({ + if (extension.config.renderHTML) { + schema.toDOM = node => (extension.config.renderHTML as Function)?.bind(context)({ node, HTMLAttributes: mergeAttributes( extension.options.HTMLAttributes, @@ -58,30 +58,30 @@ export default function getSchema(extensions: Extensions): Schema { }) } - return [extension.name, schema] + return [extension.config.name, schema] })) const marks = Object.fromEntries(markExtensions.map(extension => { - const extensionAttributes = allAttributes.filter(attribute => attribute.type === extension.name) + const extensionAttributes = allAttributes.filter(attribute => attribute.type === extension.config.name) const context = { options: extension.options } const schema: MarkSpec = cleanUpSchemaItem({ - inclusive: callOrReturn(extension.inclusive, context), - excludes: callOrReturn(extension.excludes, context), - group: callOrReturn(extension.group, context), - spanning: callOrReturn(extension.spanning, context), + inclusive: callOrReturn(extension.config.inclusive, context), + excludes: callOrReturn(extension.config.excludes, context), + group: callOrReturn(extension.config.group, context), + spanning: callOrReturn(extension.config.spanning, context), attrs: Object.fromEntries(extensionAttributes.map(extensionAttribute => { return [extensionAttribute.name, { default: extensionAttribute?.attribute?.default }] })), }) - if (extension.parseHTML) { - schema.parseDOM = extension.parseHTML + if (extension.config.parseHTML) { + schema.parseDOM = extension.config.parseHTML .bind(context)() ?.map(parseRule => injectExtensionAttributesToParseRule(parseRule, extensionAttributes)) } - if (extension.renderHTML) { - schema.toDOM = mark => (extension.renderHTML as Function)?.bind(context)({ + if (extension.config.renderHTML) { + schema.toDOM = mark => (extension.config.renderHTML as Function)?.bind(context)({ mark, HTMLAttributes: mergeAttributes( extension.options.HTMLAttributes, @@ -90,7 +90,7 @@ export default function getSchema(extensions: Extensions): Schema { }) } - return [extension.name, schema] + return [extension.config.name, schema] })) return new Schema({ diff --git a/packages/core/src/utils/isList.ts b/packages/core/src/utils/isList.ts index 860e3f64..808f220f 100644 --- a/packages/core/src/utils/isList.ts +++ b/packages/core/src/utils/isList.ts @@ -4,13 +4,13 @@ import callOrReturn from './callOrReturn' export default function isList(name: string, extensions: Extensions) { const { nodeExtensions } = splitExtensions(extensions) - const extension = nodeExtensions.find(item => item.name === name) + const extension = nodeExtensions.find(item => item.config.name === name) if (!extension) { return false } - const groups = callOrReturn(extension.group, { options: extension.options }) + const groups = callOrReturn(extension.config.group, { options: extension.options }) if (typeof groups !== 'string') { return false diff --git a/packages/core/src/utils/splitExtensions.ts b/packages/core/src/utils/splitExtensions.ts index b34a853d..1b69ab7e 100644 --- a/packages/core/src/utils/splitExtensions.ts +++ b/packages/core/src/utils/splitExtensions.ts @@ -4,9 +4,9 @@ import { NodeExtension } from '../NodeExtension' import { MarkExtension } from '../MarkExtension' export default function splitExtensions(extensions: Extensions) { - const baseExtensions = extensions.filter(extension => extension.type === 'extension') as Extension[] - const nodeExtensions = extensions.filter(extension => extension.type === 'node') as NodeExtension[] - const markExtensions = extensions.filter(extension => extension.type === 'mark') as MarkExtension[] + const baseExtensions = extensions.filter(extension => extension instanceof Extension) as Extension[] + const nodeExtensions = extensions.filter(extension => extension instanceof NodeExtension) as NodeExtension[] + const markExtensions = extensions.filter(extension => extension instanceof MarkExtension) as MarkExtension[] return { baseExtensions, diff --git a/tests/cypress/integration/core/generateHTML.spec.ts b/tests/cypress/integration/core/generateHTML.spec.ts index 05b553dd..39bfacd2 100644 --- a/tests/cypress/integration/core/generateHTML.spec.ts +++ b/tests/cypress/integration/core/generateHTML.spec.ts @@ -19,9 +19,9 @@ describe('generateHTML', () => { } const html = generateHTML(json, [ - Document(), - Paragraph(), - Text(), + Document, + Paragraph, + Text, ]) expect(html).to.eq(' Example Text
')