add keepOnSplit option to attributes

This commit is contained in:
Philipp Kühn 2021-01-28 19:56:35 +01:00
parent cde0d8690a
commit ee7daa3f43
5 changed files with 39 additions and 19 deletions

View File

@ -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,

View File

@ -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<SplitBlockOptions> = {}): Command => ({ tr, state, dispatch }) => {
export const splitBlock = (options: Partial<SplitBlockOptions> = {}): 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<SplitBlockOptions> = {}): 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<SplitBlockOptions> = {}): Command =>
types = deflt
? [{
type: deflt,
attrs: config.withAttributes
? $from.node().attrs
: {},
attrs: newAttributes,
}]
: undefined
}

View File

@ -20,6 +20,7 @@ export default function getAttributesFromExtensions(extensions: Extensions): Ext
rendered: true,
renderHTML: null,
parseHTML: null,
keepOnSplit: true,
}
extensions.forEach(extension => {

View File

@ -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 = {

View File

@ -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'),