43 lines
1.3 KiB
JavaScript
43 lines
1.3 KiB
JavaScript
// @flow
|
|
import { cloneDeep } from 'lodash';
|
|
import { Block, SlateError, Editor } from 'slate';
|
|
import { schema as originalSchema } from 'rich-markdown-editor';
|
|
|
|
const schema = cloneDeep(originalSchema);
|
|
|
|
// add rules to the schema to ensure the first node is a heading
|
|
schema.document.nodes.unshift({ match: { type: 'heading1' }, min: 1, max: 1 });
|
|
schema.document.normalize = (editor: Editor, error: SlateError) => {
|
|
switch (error.code) {
|
|
case 'child_max_invalid': {
|
|
return editor.setNodeByKey(
|
|
error.child.key,
|
|
error.index === 0 ? 'heading1' : 'paragraph'
|
|
);
|
|
}
|
|
case 'child_min_invalid': {
|
|
const missingTitle = error.index === 0;
|
|
const firstNode = editor.value.document.nodes.get(0);
|
|
if (!firstNode) {
|
|
editor.insertNodeByKey(error.node.key, 0, Block.create('heading1'));
|
|
} else {
|
|
editor.setNodeByKey(firstNode.key, { type: 'heading1' });
|
|
}
|
|
|
|
const secondNode = editor.value.document.nodes.get(1);
|
|
if (!secondNode) {
|
|
editor.insertNodeByKey(error.node.key, 1, Block.create('paragraph'));
|
|
} else {
|
|
editor.setNodeByKey(secondNode.key, { type: 'paragraph' });
|
|
}
|
|
|
|
if (missingTitle) setImmediate(() => editor.moveFocusToStartOfDocument());
|
|
|
|
return editor;
|
|
}
|
|
default:
|
|
}
|
|
};
|
|
|
|
export default schema;
|