Skip to content

Commit

Permalink
[Feat] Implement creation of empty nodes for ProseMirror
Browse files Browse the repository at this point in the history
  • Loading branch information
Bistard committed Feb 14, 2025
1 parent 774d8b6 commit e0d4ba2
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 62 deletions.
96 changes: 95 additions & 1 deletion src/editor/common/markdown.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
import type { ProseAttrs, ProseEditorState, ProseNode } from "src/editor/common/proseMirror";
import type { BlockquoteAttrs } from "src/editor/model/documentNode/node/blockquote";
import type { CodeBlockAttrs } from "src/editor/model/documentNode/node/codeBlock/codeBlock";
import type { HeadingAttrs } from "src/editor/model/documentNode/node/heading";
import type { HorizontalRuleAttrs } from "src/editor/model/documentNode/node/horizontalRule";
import type { HTMLAttrs } from "src/editor/model/documentNode/node/html";
import type { ImageAttrs } from "src/editor/model/documentNode/node/image";
import type { ListAttrs } from "src/editor/model/documentNode/node/list";
import type { MathBlockAttrs } from "src/editor/model/documentNode/node/mathBlock";
import type { ParagraphAttrs } from "src/editor/model/documentNode/node/paragraph";
import type { II18nService } from "src/platform/i18n/browser/i18nService";
import { ProseTools } from "src/editor/common/proseUtility";

/**
* Those token types are identical to {@link marked.Tokens.type}.
Expand Down Expand Up @@ -53,4 +64,87 @@ export function getTokenReadableName(i18n: II18nService, token: string | TokenEn
};

return TOKEN_READABLE_NAMES[token] ?? 'UNKNOWN';
}
}

export namespace Markdown {
export namespace Create {
export const empty = __createEmptyNodeByType;
}
}

let cached: Record<string, (state: ProseEditorState, attr: ProseAttrs) => ProseNode>;

/**
* @description Construct an empty node by the given `type`.
* @returns `undefined` if the `type` is invalid.
*/
function __createEmptyNodeByType(state: ProseEditorState, type: string, attr: ProseAttrs): ProseNode | undefined {
cached ??= {
[TokenEnum.Heading]: __createHeading,
[TokenEnum.Paragraph]: __createParagraph,
[TokenEnum.Image]: __createImage,
[TokenEnum.CodeBlock]: __createCodeBlock,
[TokenEnum.MathBlock]: __createMathBlock,
[TokenEnum.HTML]: __createHTML,
[TokenEnum.HorizontalRule]: __createHorizontalRule,
[TokenEnum.Blockquote]: __createBlockquote,
[TokenEnum.List]: __createList,
};

const ctor = cached[type];
if (!ctor) {
return undefined;
}
return ctor(state, attr);
}

function __createHeading(state: ProseEditorState, attr: HeadingAttrs): ProseNode {
return ProseTools.Node.createNode(state, TokenEnum.Heading, attr);
}

function __createParagraph(state: ProseEditorState, attr: ParagraphAttrs): ProseNode {
return ProseTools.Node.createNode(state, TokenEnum.Paragraph, attr);
}

function __createBlockquote(state: ProseEditorState, attr: BlockquoteAttrs): ProseNode {
return ProseTools.Node.createNode(
state,
TokenEnum.Blockquote,
attr,
__createParagraph(state, {}),
);
}

function __createImage(state: ProseEditorState, attr: ImageAttrs): ProseNode {
return ProseTools.Node.createNode(state, TokenEnum.Image, attr);
}

function __createList(state: ProseEditorState, attr: ListAttrs): ProseNode {
return ProseTools.Node.createNode(
state,
TokenEnum.List,
attr,
ProseTools.Node.createNode(
state,
TokenEnum.ListItem,
{},
__createParagraph(state, {}),
)
);
}

function __createCodeBlock(state: ProseEditorState, attr: CodeBlockAttrs): ProseNode {
return ProseTools.Node.createNode(state, TokenEnum.CodeBlock, attr);
}

function __createMathBlock(state: ProseEditorState, attr: MathBlockAttrs): ProseNode {
return ProseTools.Node.createNode(state, TokenEnum.MathBlock, attr);
}

function __createHTML(state: ProseEditorState, attr: HTMLAttrs): ProseNode {
return ProseTools.Node.createNode(state, TokenEnum.HTML, attr);
}

function __createHorizontalRule(state: ProseEditorState, attr: HorizontalRuleAttrs): ProseNode {
return ProseTools.Node.createNode(state, TokenEnum.HorizontalRule, attr);
}
65 changes: 4 additions & 61 deletions src/editor/common/proseUtility.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
import { Numbers } from "src/base/common/utilities/number";
import { assert } from "src/base/common/utilities/panic";
import { TokenEnum } from "src/editor/common/markdown";
import { ProseSelection, ProseCursor, ProseEditorState, ProseNode, ProseTransaction, ProseResolvedPos, ProseNodeType, ProseContentMatch, ProseAllSelection, ProseAttrs, ProseTextSelection } from "src/editor/common/proseMirror";
import { BlockquoteAttrs } from "src/editor/model/documentNode/node/blockquote";
import { CodeBlockAttrs } from "src/editor/model/documentNode/node/codeBlock/codeBlock";
import { HeadingAttrs } from "src/editor/model/documentNode/node/heading";
import { HorizontalRuleAttrs } from "src/editor/model/documentNode/node/horizontalRule";
import { HTMLAttrs } from "src/editor/model/documentNode/node/html";
import { ImageAttrs } from "src/editor/model/documentNode/node/image";
import { ListAttrs } from "src/editor/model/documentNode/node/list";
import { MathBlockAttrs } from "src/editor/model/documentNode/node/mathBlock";
import { ParagraphAttrs } from "src/editor/model/documentNode/node/paragraph";
import { ProseSelection, ProseCursor, ProseEditorState, ProseNode, ProseTransaction, ProseResolvedPos, ProseNodeType, ProseContentMatch, ProseAllSelection, ProseAttrs, ProseTextSelection, ProseFragment, ProseMark } from "src/editor/common/proseMirror";

/**
* @description Contains a list of helper functions that relates to ProseMirror.
Expand Down Expand Up @@ -71,17 +61,7 @@ export namespace ProseTools {
export const getNextValidDefaultNodeType = __getNextValidDefaultNodeType;

export const createNode = __createNode;
export namespace Create {
export const heading = __createHeading;
export const paragraph = __createParagraph;
export const blockquote = __createBlockquote;
export const image = __createImage;
export const list = __createList;
export const codeBlock = __createCodeBlock;
export const mathBlock = __createMathBlock;
export const HTML = __createHTML;
export const HorizontalRule = __createHorizontalRule;
}

}

export namespace Text {
Expand Down Expand Up @@ -266,43 +246,6 @@ function __appendTextToEnd(state: ProseEditorState, text: string): ProseTransact
return state.tr.insertText(text, docEnd);
}

function __createNode(state: ProseEditorState, type: string, attrs: ProseAttrs): ProseNode {
return state.schema.node(type, attrs);
}

function __createHeading(state: ProseEditorState, attr: HeadingAttrs): ProseNode {
return __createNode(state, TokenEnum.Heading, attr);
}

function __createParagraph(state: ProseEditorState, attr: ParagraphAttrs): ProseNode {
return __createNode(state, TokenEnum.Paragraph, attr);
}

function __createBlockquote(state: ProseEditorState, attr: BlockquoteAttrs): ProseNode {
return __createNode(state, TokenEnum.Blockquote, attr);
}

function __createImage(state: ProseEditorState, attr: ImageAttrs): ProseNode {
return __createNode(state, TokenEnum.Image, attr);
}

function __createList(state: ProseEditorState, attr: ListAttrs): ProseNode {
return __createNode(state, TokenEnum.List, attr);
}

function __createCodeBlock(state: ProseEditorState, attr: CodeBlockAttrs): ProseNode {
return __createNode(state, TokenEnum.CodeBlock, attr);
}

function __createMathBlock(state: ProseEditorState, attr: MathBlockAttrs): ProseNode {
return __createNode(state, TokenEnum.MathBlock, attr);
function __createNode(state: ProseEditorState, type: string, attrs: ProseAttrs, content?: ProseFragment | ProseNode | readonly ProseNode[], marks?: readonly ProseMark[]): ProseNode {
return state.schema.node(type, attrs, content, marks);
}

function __createHTML(state: ProseEditorState, attr: HTMLAttrs): ProseNode {
return __createNode(state, TokenEnum.HTML, attr);
}

function __createHorizontalRule(state: ProseEditorState, attr: HorizontalRuleAttrs): ProseNode {
return __createNode(state, TokenEnum.HorizontalRule, attr);
}

0 comments on commit e0d4ba2

Please sign in to comment.