Merge pull request #20 from fantasticit/bugfix/title

This commit is contained in:
fantasticit 2022-03-29 14:55:29 +08:00 committed by GitHub
commit 2c600e2163
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 0 deletions

View File

@ -1,4 +1,7 @@
import { Node, mergeAttributes } from '@tiptap/core'; import { Node, mergeAttributes } from '@tiptap/core';
import { Plugin, PluginKey } from 'prosemirror-state';
import { isInTitle } from '../services/node';
import { TextSelection } from 'prosemirror-state';
export interface TitleOptions { export interface TitleOptions {
HTMLAttributes: Record<string, any>; HTMLAttributes: Record<string, any>;
@ -26,6 +29,7 @@ export const Title = Node.create<TitleOptions>({
}, },
}; };
}, },
parseHTML() { parseHTML() {
return [ return [
{ {
@ -37,4 +41,37 @@ export const Title = Node.create<TitleOptions>({
renderHTML({ HTMLAttributes }) { renderHTML({ HTMLAttributes }) {
return ['p', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; return ['p', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
}, },
addProseMirrorPlugins() {
return [
new Plugin({
key: new PluginKey(this.name),
props: {
handleKeyDown(view, evt) {
const { state, dispatch } = view;
if (isInTitle(view.state) && evt.code === 'Enter') {
evt.preventDefault();
const paragraph = state.schema.nodes.paragraph;
if (!paragraph) {
return;
}
const $head = state.selection.$head;
const titleNode = $head.node($head.depth);
const insertPos = titleNode.firstChild.nodeSize + 1;
dispatch(state.tr.insert(insertPos, paragraph.create()));
const newState = view.state;
const next = new TextSelection(newState.doc.resolve(insertPos + 1));
dispatch(newState.tr.setSelection(next));
return true;
}
},
},
}),
];
},
}); });

View File

@ -1,4 +1,5 @@
import { Node } from 'prosemirror-model'; import { Node } from 'prosemirror-model';
import { EditorState } from 'prosemirror-state';
export function isTitleNode(node: Node): boolean { export function isTitleNode(node: Node): boolean {
return node.type.name === 'title'; return node.type.name === 'title';
@ -19,3 +20,12 @@ export function isTodoListNode(node: Node): boolean {
export function isListNode(node: Node): boolean { export function isListNode(node: Node): boolean {
return isBulletListNode(node) || isOrderedListNode(node) || isTodoListNode(node); return isBulletListNode(node) || isOrderedListNode(node) || isTodoListNode(node);
} }
export function isInTitle(state: EditorState): boolean {
const $head = state.selection.$head;
for (let d = $head.depth; d > 0; d--) {
if ($head.node(d).type === state.schema.nodes.title) {
return true;
}
}
}