diff --git a/packages/core/src/ExtensionManager.ts b/packages/core/src/ExtensionManager.ts index 6b680dbc2..96b19c33c 100644 --- a/packages/core/src/ExtensionManager.ts +++ b/packages/core/src/ExtensionManager.ts @@ -95,15 +95,18 @@ export default class ExtensionManager { .flat() } + get attributes() { + return getAttributesFromExtensions(this.extensions) + } + get nodeViews() { const { editor } = this const { nodeExtensions } = splitExtensions(this.extensions) - const allAttributes = getAttributesFromExtensions(this.extensions) return Object.fromEntries(nodeExtensions .filter(extension => !!extension.config.addNodeView) .map(extension => { - const extensionAttributes = allAttributes.filter(attribute => attribute.type === extension.config.name) + const extensionAttributes = this.attributes.filter(attribute => attribute.type === extension.config.name) const context = { options: extension.options, editor, diff --git a/packages/core/src/commands/splitBlock.ts b/packages/core/src/commands/splitBlock.ts index 5f26c29d0..f2236a8ed 100644 --- a/packages/core/src/commands/splitBlock.ts +++ b/packages/core/src/commands/splitBlock.ts @@ -15,7 +15,6 @@ function defaultBlockAt(match: ContentMatch) { } export interface SplitBlockOptions { - withAttributes: boolean, withMarks: boolean, } @@ -31,15 +30,35 @@ function keepMarks(state: EditorState) { /** * Forks a new node from an existing node. */ -export const splitBlock = (options: Partial = {}): Command => ({ tr, state, dispatch }) => { +export const splitBlock = (options: Partial = {}): Command => ({ + tr, + state, + dispatch, + editor, +}) => { const defaultOptions: SplitBlockOptions = { - withAttributes: false, withMarks: true, } const config = { ...defaultOptions, ...options } const { selection, doc } = tr const { $from, $to } = selection + const extensionAttributes = editor.extensionManager.attributes + .filter(item => item.type === $from.node().type.name) + + const currentAttributes = $from.node().attrs + const newAttributes = Object.fromEntries(Object + .entries(currentAttributes) + .filter(([name]) => { + const extensionAttribute = extensionAttributes.find(item => item.name === name) + + if (!extensionAttribute) { + return false + } + + return extensionAttribute.attribute.keepOnSplit + })) + if (selection instanceof NodeSelection && selection.node.isBlock) { if (!$from.parentOffset || !canSplit(doc, $from.pos)) { return false @@ -74,9 +93,7 @@ export const splitBlock = (options: Partial = {}): Command => let types = atEnd && deflt ? [{ type: deflt, - attrs: config.withAttributes - ? $from.node().attrs - : {}, + attrs: newAttributes, }] : undefined @@ -91,9 +108,7 @@ export const splitBlock = (options: Partial = {}): Command => types = deflt ? [{ type: deflt, - attrs: config.withAttributes - ? $from.node().attrs - : {}, + attrs: newAttributes, }] : undefined } diff --git a/packages/core/src/helpers/getAttributesFromExtensions.ts b/packages/core/src/helpers/getAttributesFromExtensions.ts index 9136be1c8..b7a64b18e 100644 --- a/packages/core/src/helpers/getAttributesFromExtensions.ts +++ b/packages/core/src/helpers/getAttributesFromExtensions.ts @@ -20,6 +20,7 @@ export default function getAttributesFromExtensions(extensions: Extensions): Ext rendered: true, renderHTML: null, parseHTML: null, + keepOnSplit: true, } extensions.forEach(extension => { diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index aec14f17a..f1f5bcb63 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -60,6 +60,7 @@ export type Attribute = { rendered?: boolean, renderHTML?: ((attributes: { [key: string]: any }) => { [key: string]: any } | null) | null, parseHTML?: ((element: HTMLElement) => { [key: string]: any } | null) | null, + keepOnSplit: boolean, } export type Attributes = { diff --git a/packages/extension-text-align/src/text-align.ts b/packages/extension-text-align/src/text-align.ts index 7d766eba5..8984a0b0a 100644 --- a/packages/extension-text-align/src/text-align.ts +++ b/packages/extension-text-align/src/text-align.ts @@ -59,14 +59,14 @@ export const TextAlign = Extension.create({ return { // TODO: re-use only 'textAlign' attribute // TODO: use custom splitBlock only for `this.options.types` - Enter: () => this.editor.commands.first(({ commands }) => [ - () => commands.newlineInCode(), - () => commands.createParagraphNear(), - () => commands.liftEmptyBlock(), - () => commands.splitBlock({ - withAttributes: true, - }), - ]), + // Enter: () => this.editor.commands.first(({ commands }) => [ + // () => commands.newlineInCode(), + // () => commands.createParagraphNear(), + // () => commands.liftEmptyBlock(), + // () => commands.splitBlock({ + // withAttributes: true, + // }), + // ]), 'Mod-Shift-l': () => this.editor.commands.setTextAlign('left'), 'Mod-Shift-e': () => this.editor.commands.setTextAlign('center'), 'Mod-Shift-r': () => this.editor.commands.setTextAlign('right'),