@blocknote/core 0.38.0 → 0.39.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/BlockNoteSchema-DmZ6UQfY.cjs +11 -0
- package/dist/BlockNoteSchema-DmZ6UQfY.cjs.map +1 -0
- package/dist/BlockNoteSchema-oR047ACf.js +4275 -0
- package/dist/BlockNoteSchema-oR047ACf.js.map +1 -0
- package/dist/blocknote.cjs +4 -12
- package/dist/blocknote.cjs.map +1 -1
- package/dist/blocknote.js +3401 -7305
- package/dist/blocknote.js.map +1 -1
- package/dist/blocks.cjs +2 -0
- package/dist/blocks.cjs.map +1 -0
- package/dist/blocks.js +71 -0
- package/dist/blocks.js.map +1 -0
- package/dist/style.css +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/webpack-stats.json +1 -1
- package/package.json +19 -16
- package/src/api/blockManipulation/commands/insertBlocks/insertBlocks.ts +1 -1
- package/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.ts +2 -2
- package/src/api/blockManipulation/commands/splitBlock/splitBlock.ts +34 -25
- package/src/api/blockManipulation/setupTestEnv.ts +0 -1
- package/src/api/clipboard/fromClipboard/handleFileInsertion.ts +6 -10
- package/src/api/clipboard/fromClipboard/pasteExtension.ts +1 -1
- package/src/api/clipboard/toClipboard/copyExtension.ts +1 -1
- package/src/api/exporters/html/util/serializeBlocksExternalHTML.ts +128 -28
- package/src/api/exporters/html/util/serializeBlocksInternalHTML.ts +101 -41
- package/src/api/pmUtil.ts +1 -1
- package/src/api/positionMapping.test.ts +58 -15
- package/src/api/positionMapping.ts +2 -4
- package/src/blocks/Audio/block.ts +174 -0
- package/src/blocks/BlockNoteSchema.ts +59 -0
- package/src/blocks/Code/block.ts +303 -0
- package/src/blocks/Code/shiki.ts +73 -0
- package/src/blocks/File/block.ts +98 -0
- package/src/blocks/{FileBlockContent → File}/helpers/render/createAddFileButton.ts +5 -2
- package/src/blocks/{FileBlockContent → File}/helpers/render/createFileBlockWrapper.ts +15 -6
- package/src/blocks/{FileBlockContent → File}/helpers/render/createFileNameWithIcon.ts +15 -2
- package/src/blocks/{FileBlockContent → File}/helpers/render/createResizableFileBlockWrapper.ts +21 -2
- package/src/blocks/Heading/block.ts +138 -0
- package/src/blocks/Image/block.ts +190 -0
- package/src/blocks/ListItem/BulletListItem/block.ts +116 -0
- package/src/blocks/ListItem/CheckListItem/block.ts +175 -0
- package/src/blocks/ListItem/NumberedListItem/IndexingPlugin.ts +173 -0
- package/src/blocks/ListItem/NumberedListItem/block.ts +133 -0
- package/src/blocks/ListItem/ToggleListItem/block.ts +78 -0
- package/src/blocks/PageBreak/block.ts +72 -0
- package/src/blocks/{PageBreakBlockContent → PageBreak}/getPageBreakSlashMenuItems.ts +9 -7
- package/src/blocks/Paragraph/block.ts +80 -0
- package/src/blocks/Quote/block.ts +90 -0
- package/src/blocks/{TableBlockContent/TableBlockContent.ts → Table/block.ts} +169 -51
- package/src/blocks/ToggleWrapper/createToggleWrapper.ts +1 -1
- package/src/blocks/Video/block.ts +143 -0
- package/src/blocks/defaultBlockHelpers.ts +2 -2
- package/src/blocks/defaultBlockTypeGuards.ts +143 -174
- package/src/blocks/defaultBlocks.ts +107 -35
- package/src/blocks/defaultProps.ts +145 -4
- package/src/blocks/index.ts +26 -0
- package/src/blocks/utils/listItemEnterHandler.ts +42 -0
- package/src/editor/Block.css +54 -18
- package/src/editor/BlockNoteEditor.ts +256 -211
- package/src/editor/BlockNoteExtension.ts +92 -0
- package/src/editor/BlockNoteExtensions.ts +18 -17
- package/src/editor/defaultColors.ts +2 -2
- package/src/exporter/Exporter.ts +1 -1
- package/src/exporter/mapping.ts +1 -1
- package/src/extensions/BackgroundColor/BackgroundColorExtension.ts +3 -20
- package/src/extensions/BackgroundColor/BackgroundColorMark.ts +6 -8
- package/src/extensions/BlockChange/BlockChangePlugin.ts +2 -1
- package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-editor-forked.json +2 -2
- package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-editor.json +2 -2
- package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-forked.html +1 -1
- package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap.html +1 -1
- package/src/extensions/Collaboration/schemaMigration/SchemaMigrationPlugin.ts +52 -0
- package/src/extensions/Collaboration/schemaMigration/migrationRules/index.ts +4 -0
- package/src/extensions/Collaboration/schemaMigration/migrationRules/migrationRule.ts +4 -0
- package/src/extensions/Collaboration/schemaMigration/migrationRules/moveColorAttributes.ts +78 -0
- package/src/extensions/Comments/CommentsPlugin.ts +1 -1
- package/src/extensions/FilePanel/FilePanelPlugin.ts +5 -10
- package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +1 -1
- package/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.ts +4 -3
- package/src/extensions/Placeholder/PlaceholderPlugin.ts +6 -6
- package/src/extensions/PreviousBlockType/PreviousBlockTypePlugin.ts +1 -23
- package/src/extensions/SideMenu/SideMenuPlugin.ts +1 -3
- package/src/extensions/SideMenu/dragging.ts +2 -2
- package/src/extensions/SuggestionMenu/SuggestionPlugin.ts +4 -7
- package/src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.ts +6 -2
- package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +24 -17
- package/src/extensions/TableHandles/TableHandlesPlugin.ts +8 -8
- package/src/extensions/TextAlignment/TextAlignmentExtension.ts +5 -11
- package/src/extensions/TextColor/TextColorExtension.ts +3 -17
- package/src/extensions/TextColor/TextColorMark.ts +4 -9
- package/src/extensions/UniqueID/UniqueID.ts +6 -13
- package/src/index.ts +2 -28
- package/src/schema/blocks/createSpec.ts +342 -169
- package/src/schema/blocks/internal.ts +77 -138
- package/src/schema/blocks/types.ts +264 -94
- package/src/schema/index.ts +1 -0
- package/src/schema/inlineContent/createSpec.ts +99 -21
- package/src/schema/inlineContent/internal.ts +16 -7
- package/src/schema/inlineContent/types.ts +24 -2
- package/src/schema/propTypes.ts +15 -9
- package/src/schema/schema.ts +209 -0
- package/src/schema/styles/createSpec.ts +79 -31
- package/src/schema/styles/internal.ts +61 -2
- package/src/schema/styles/types.ts +17 -3
- package/src/util/topo-sort.test.ts +125 -0
- package/src/util/topo-sort.ts +160 -0
- package/types/src/api/blockManipulation/commands/splitBlock/splitBlock.d.ts +2 -1
- package/types/src/api/blockManipulation/selections/selection.d.ts +1 -1
- package/types/src/api/blockManipulation/setupTestEnv.d.ts +29 -543
- package/types/src/api/exporters/html/util/serializeBlocksExternalHTML.d.ts +1 -1
- package/types/src/api/exporters/html/util/serializeBlocksInternalHTML.d.ts +1 -1
- package/types/src/api/pmUtil.d.ts +1 -1
- package/types/src/blocks/Audio/block.d.ts +58 -0
- package/types/src/blocks/BlockNoteSchema.d.ts +18 -0
- package/types/src/blocks/{CodeBlockContent/CodeBlockContent.d.ts → Code/block.d.ts} +25 -26
- package/types/src/blocks/Code/shiki.d.ts +4 -0
- package/types/src/blocks/File/block.d.ts +37 -0
- package/types/src/blocks/File/helpers/render/createAddFileButton.d.ts +6 -0
- package/types/src/blocks/File/helpers/render/createFileBlockWrapper.d.ts +25 -0
- package/types/src/blocks/{FileBlockContent → File}/helpers/render/createFileNameWithIcon.d.ts +6 -2
- package/types/src/blocks/File/helpers/render/createResizableFileBlockWrapper.d.ts +31 -0
- package/types/src/blocks/Heading/block.d.ts +71 -0
- package/types/src/blocks/Image/block.d.ts +102 -0
- package/types/src/blocks/ListItem/BulletListItem/block.d.ts +25 -0
- package/types/src/blocks/ListItem/CheckListItem/block.d.ts +33 -0
- package/types/src/blocks/ListItem/NumberedListItem/IndexingPlugin.d.ts +8 -0
- package/types/src/blocks/ListItem/NumberedListItem/block.d.ts +33 -0
- package/types/src/blocks/ListItem/ToggleListItem/block.d.ts +25 -0
- package/types/src/blocks/PageBreak/block.d.ts +11 -0
- package/types/src/blocks/{PageBreakBlockContent → PageBreak}/getPageBreakSlashMenuItems.d.ts +4 -2
- package/types/src/blocks/Paragraph/block.d.ts +25 -0
- package/types/src/blocks/Quote/block.d.ts +17 -0
- package/types/src/blocks/Table/block.d.ts +21 -0
- package/types/src/blocks/Video/block.d.ts +67 -0
- package/types/src/blocks/defaultBlockHelpers.d.ts +1 -1
- package/types/src/blocks/defaultBlockTypeGuards.d.ts +15 -36
- package/types/src/blocks/defaultBlocks.d.ts +221 -1060
- package/types/src/blocks/defaultProps.d.ts +17 -1
- package/types/src/blocks/index.d.ts +24 -0
- package/types/src/blocks/utils/listItemEnterHandler.d.ts +2 -0
- package/types/src/editor/BlockNoteEditor.d.ts +36 -67
- package/types/src/editor/BlockNoteExtension.d.ts +67 -0
- package/types/src/editor/BlockNoteExtensions.d.ts +1 -1
- package/types/src/editor/defaultColors.d.ts +8 -76
- package/types/src/exporter/Exporter.d.ts +1 -1
- package/types/src/exporter/mapping.d.ts +1 -1
- package/types/src/extensions/BackgroundColor/BackgroundColorMark.d.ts +4 -1
- package/types/src/extensions/Collaboration/schemaMigration/SchemaMigrationPlugin.d.ts +7 -0
- package/types/src/extensions/Collaboration/schemaMigration/migrationRules/index.d.ts +3 -0
- package/types/src/extensions/Collaboration/schemaMigration/migrationRules/migrationRule.d.ts +3 -0
- package/types/src/extensions/Collaboration/schemaMigration/migrationRules/moveColorAttributes.d.ts +2 -0
- package/types/src/extensions/Comments/CommentsPlugin.d.ts +1 -1
- package/types/src/extensions/FilePanel/FilePanelPlugin.d.ts +4 -4
- package/types/src/extensions/TextColor/TextColorMark.d.ts +4 -1
- package/types/src/index.d.ts +2 -25
- package/types/src/schema/blocks/createSpec.d.ts +16 -36
- package/types/src/schema/blocks/internal.d.ts +11 -33
- package/types/src/schema/blocks/types.d.ts +181 -57
- package/types/src/schema/index.d.ts +1 -0
- package/types/src/schema/inlineContent/createSpec.d.ts +36 -2
- package/types/src/schema/inlineContent/internal.d.ts +7 -15
- package/types/src/schema/inlineContent/types.d.ts +15 -1
- package/types/src/schema/propTypes.d.ts +4 -4
- package/types/src/schema/schema.d.ts +40 -0
- package/types/src/schema/styles/createSpec.d.ts +6 -4
- package/types/src/schema/styles/internal.d.ts +6 -3
- package/types/src/schema/styles/types.d.ts +11 -2
- package/types/src/util/topo-sort.d.ts +18 -0
- package/types/src/util/topo-sort.test.d.ts +1 -0
- package/src/blocks/AudioBlockContent/AudioBlockContent.ts +0 -144
- package/src/blocks/CodeBlockContent/CodeBlockContent.ts +0 -445
- package/src/blocks/FileBlockContent/FileBlockContent.ts +0 -100
- package/src/blocks/HeadingBlockContent/HeadingBlockContent.ts +0 -159
- package/src/blocks/ImageBlockContent/ImageBlockContent.ts +0 -159
- package/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +0 -134
- package/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.ts +0 -299
- package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts +0 -86
- package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +0 -172
- package/src/blocks/ListItemBlockContent/ToggleListItemBlockContent/ToggleListItemBlockContent.ts +0 -104
- package/src/blocks/PageBreakBlockContent/PageBreakBlockContent.ts +0 -49
- package/src/blocks/PageBreakBlockContent/schema.ts +0 -40
- package/src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts +0 -78
- package/src/blocks/QuoteBlockContent/QuoteBlockContent.ts +0 -121
- package/src/blocks/VideoBlockContent/VideoBlockContent.ts +0 -158
- package/src/editor/BlockNoteSchema.ts +0 -107
- package/src/editor/BlockNoteTipTapEditor.ts +0 -335
- package/types/src/blocks/AudioBlockContent/AudioBlockContent.d.ts +0 -99
- package/types/src/blocks/FileBlockContent/FileBlockContent.d.ts +0 -90
- package/types/src/blocks/FileBlockContent/helpers/render/createAddFileButton.d.ts +0 -6
- package/types/src/blocks/FileBlockContent/helpers/render/createFileBlockWrapper.d.ts +0 -9
- package/types/src/blocks/FileBlockContent/helpers/render/createResizableFileBlockWrapper.d.ts +0 -9
- package/types/src/blocks/HeadingBlockContent/HeadingBlockContent.d.ts +0 -67
- package/types/src/blocks/ImageBlockContent/ImageBlockContent.d.ts +0 -131
- package/types/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.d.ts +0 -46
- package/types/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.d.ts +0 -55
- package/types/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.d.ts +0 -2
- package/types/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.d.ts +0 -58
- package/types/src/blocks/ListItemBlockContent/ToggleListItemBlockContent/ToggleListItemBlockContent.d.ts +0 -46
- package/types/src/blocks/PageBreakBlockContent/PageBreakBlockContent.d.ts +0 -31
- package/types/src/blocks/PageBreakBlockContent/schema.d.ts +0 -86
- package/types/src/blocks/ParagraphBlockContent/ParagraphBlockContent.d.ts +0 -52
- package/types/src/blocks/QuoteBlockContent/QuoteBlockContent.d.ts +0 -52
- package/types/src/blocks/TableBlockContent/TableBlockContent.d.ts +0 -39
- package/types/src/blocks/VideoBlockContent/VideoBlockContent.d.ts +0 -131
- package/types/src/editor/BlockNoteSchema.d.ts +0 -34
- package/types/src/editor/BlockNoteTipTapEditor.d.ts +0 -43
- /package/src/blocks/{AudioBlockContent → Audio}/parseAudioElement.ts +0 -0
- /package/src/blocks/{FileBlockContent → File}/helpers/parse/parseEmbedElement.ts +0 -0
- /package/src/blocks/{FileBlockContent → File}/helpers/parse/parseFigureElement.ts +0 -0
- /package/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createFigureWithCaption.ts +0 -0
- /package/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createLinkWithCaption.ts +0 -0
- /package/src/blocks/{FileBlockContent → File/helpers}/uploadToTmpFilesDotOrg_DEV_ONLY.ts +0 -0
- /package/src/blocks/{ImageBlockContent → Image}/parseImageElement.ts +0 -0
- /package/src/blocks/{ListItemBlockContent → ListItem}/ListItemKeyboardShortcuts.ts +0 -0
- /package/src/blocks/{ListItemBlockContent → ListItem}/getListItemContent.ts +0 -0
- /package/src/blocks/{TableBlockContent → Table}/TableExtension.ts +0 -0
- /package/src/blocks/{VideoBlockContent → Video}/parseVideoElement.ts +0 -0
- /package/types/src/blocks/{AudioBlockContent → Audio}/parseAudioElement.d.ts +0 -0
- /package/types/src/blocks/{FileBlockContent → File}/helpers/parse/parseEmbedElement.d.ts +0 -0
- /package/types/src/blocks/{FileBlockContent → File}/helpers/parse/parseFigureElement.d.ts +0 -0
- /package/types/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createFigureWithCaption.d.ts +0 -0
- /package/types/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createLinkWithCaption.d.ts +0 -0
- /package/types/src/blocks/{FileBlockContent → File/helpers}/uploadToTmpFilesDotOrg_DEV_ONLY.d.ts +0 -0
- /package/types/src/blocks/{ImageBlockContent → Image}/parseImageElement.d.ts +0 -0
- /package/types/src/blocks/{ListItemBlockContent → ListItem}/ListItemKeyboardShortcuts.d.ts +0 -0
- /package/types/src/blocks/{ListItemBlockContent → ListItem}/getListItemContent.d.ts +0 -0
- /package/types/src/blocks/{TableBlockContent → Table}/TableExtension.d.ts +0 -0
- /package/types/src/blocks/{VideoBlockContent → Video}/parseVideoElement.d.ts +0 -0
|
@@ -1,69 +1,21 @@
|
|
|
1
|
-
import { Editor } from "@tiptap/core";
|
|
2
|
-
import { TagParseRule } from "@tiptap/pm/model";
|
|
3
|
-
import { NodeView
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import { Editor, Node } from "@tiptap/core";
|
|
2
|
+
import { DOMParser, Fragment, TagParseRule } from "@tiptap/pm/model";
|
|
3
|
+
import { NodeView } from "@tiptap/pm/view";
|
|
4
|
+
import { mergeParagraphs } from "../../blocks/defaultBlockHelpers.js";
|
|
5
|
+
import { BlockNoteExtension } from "../../editor/BlockNoteExtension.js";
|
|
6
|
+
import { PropSchema } from "../propTypes.js";
|
|
7
7
|
import {
|
|
8
|
-
createInternalBlockSpec,
|
|
9
|
-
createStronglyTypedTiptapNode,
|
|
10
8
|
getBlockFromPos,
|
|
11
9
|
propsToAttributes,
|
|
12
10
|
wrapInBlockStructure,
|
|
13
11
|
} from "./internal.js";
|
|
14
12
|
import {
|
|
15
13
|
BlockConfig,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
BlockImplementation,
|
|
15
|
+
BlockSpec,
|
|
16
|
+
LooseBlockSpec,
|
|
19
17
|
} from "./types.js";
|
|
20
18
|
|
|
21
|
-
// restrict content to "inline" and "none" only
|
|
22
|
-
export type CustomBlockConfig = BlockConfig & {
|
|
23
|
-
content: "inline" | "none";
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export type CustomBlockImplementation<
|
|
27
|
-
T extends CustomBlockConfig,
|
|
28
|
-
I extends InlineContentSchema,
|
|
29
|
-
S extends StyleSchema,
|
|
30
|
-
> = {
|
|
31
|
-
render: (
|
|
32
|
-
/**
|
|
33
|
-
* The custom block to render
|
|
34
|
-
*/
|
|
35
|
-
block: BlockFromConfig<T, I, S>,
|
|
36
|
-
/**
|
|
37
|
-
* The BlockNote editor instance
|
|
38
|
-
* This is typed generically. If you want an editor with your custom schema, you need to
|
|
39
|
-
* cast it manually, e.g.: `const e = editor as BlockNoteEditor<typeof mySchema>;`
|
|
40
|
-
*/
|
|
41
|
-
editor: BlockNoteEditor<BlockSchemaWithBlock<T["type"], T>, I, S>,
|
|
42
|
-
// (note) if we want to fix the manual cast, we need to prevent circular references and separate block definition and render implementations
|
|
43
|
-
// or allow manually passing <BSchema>, but that's not possible without passing the other generics because Typescript doesn't support partial inferred generics
|
|
44
|
-
) => {
|
|
45
|
-
dom: HTMLElement;
|
|
46
|
-
contentDOM?: HTMLElement;
|
|
47
|
-
ignoreMutation?: (mutation: ViewMutationRecord) => boolean;
|
|
48
|
-
destroy?: () => void;
|
|
49
|
-
};
|
|
50
|
-
// Exports block to external HTML. If not defined, the output will be the same
|
|
51
|
-
// as `render(...).dom`. Used to create clipboard data when pasting outside
|
|
52
|
-
// BlockNote.
|
|
53
|
-
// TODO: Maybe can return undefined to ignore when serializing?
|
|
54
|
-
toExternalHTML?: (
|
|
55
|
-
block: BlockFromConfig<T, I, S>,
|
|
56
|
-
editor: BlockNoteEditor<BlockSchemaWithBlock<T["type"], T>, I, S>,
|
|
57
|
-
) => {
|
|
58
|
-
dom: HTMLElement;
|
|
59
|
-
contentDOM?: HTMLElement;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
parse?: (
|
|
63
|
-
el: HTMLElement,
|
|
64
|
-
) => PartialBlockFromConfig<T, I, S>["props"] | undefined;
|
|
65
|
-
};
|
|
66
|
-
|
|
67
19
|
// Function that causes events within non-selectable blocks to be handled by the
|
|
68
20
|
// browser instead of the editor.
|
|
69
21
|
export function applyNonSelectableBlockFix(nodeView: NodeView, editor: Editor) {
|
|
@@ -84,9 +36,13 @@ export function applyNonSelectableBlockFix(nodeView: NodeView, editor: Editor) {
|
|
|
84
36
|
// Function that uses the 'parse' function of a blockConfig to create a
|
|
85
37
|
// TipTap node's `parseHTML` property. This is only used for parsing content
|
|
86
38
|
// from the clipboard.
|
|
87
|
-
export function getParseRules
|
|
88
|
-
|
|
89
|
-
|
|
39
|
+
export function getParseRules<
|
|
40
|
+
TName extends string,
|
|
41
|
+
TProps extends PropSchema,
|
|
42
|
+
TContent extends "inline" | "none" | "table",
|
|
43
|
+
>(
|
|
44
|
+
config: BlockConfig<TName, TProps, TContent>,
|
|
45
|
+
implementation: BlockImplementation<TName, TProps, TContent>,
|
|
90
46
|
) {
|
|
91
47
|
const rules: TagParseRule[] = [
|
|
92
48
|
{
|
|
@@ -95,7 +51,7 @@ export function getParseRules(
|
|
|
95
51
|
},
|
|
96
52
|
];
|
|
97
53
|
|
|
98
|
-
if (
|
|
54
|
+
if (implementation.parse) {
|
|
99
55
|
rules.push({
|
|
100
56
|
tag: "*",
|
|
101
57
|
getAttrs(node: string | HTMLElement) {
|
|
@@ -103,7 +59,7 @@ export function getParseRules(
|
|
|
103
59
|
return false;
|
|
104
60
|
}
|
|
105
61
|
|
|
106
|
-
const props =
|
|
62
|
+
const props = implementation.parse?.(node);
|
|
107
63
|
|
|
108
64
|
if (props === undefined) {
|
|
109
65
|
return false;
|
|
@@ -111,6 +67,40 @@ export function getParseRules(
|
|
|
111
67
|
|
|
112
68
|
return props;
|
|
113
69
|
},
|
|
70
|
+
getContent:
|
|
71
|
+
config.content === "inline" || config.content === "none"
|
|
72
|
+
? (node, schema) => {
|
|
73
|
+
if (implementation.parseContent) {
|
|
74
|
+
return implementation.parseContent({
|
|
75
|
+
el: node as HTMLElement,
|
|
76
|
+
schema,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (config.content === "inline") {
|
|
81
|
+
// Parse the inline content if it exists
|
|
82
|
+
const element = node as HTMLElement;
|
|
83
|
+
|
|
84
|
+
// Clone to avoid modifying the original
|
|
85
|
+
const clone = element.cloneNode(true) as HTMLElement;
|
|
86
|
+
|
|
87
|
+
// Merge multiple paragraphs into one with line breaks
|
|
88
|
+
mergeParagraphs(
|
|
89
|
+
clone,
|
|
90
|
+
implementation.meta?.code ? "\n" : "<br>",
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
// Parse the content directly as a paragraph to extract inline content
|
|
94
|
+
const parser = DOMParser.fromSchema(schema);
|
|
95
|
+
const parsed = parser.parse(clone, {
|
|
96
|
+
topNode: schema.nodes.paragraph.create(),
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return parsed.content;
|
|
100
|
+
}
|
|
101
|
+
return Fragment.empty;
|
|
102
|
+
}
|
|
103
|
+
: undefined,
|
|
114
104
|
});
|
|
115
105
|
}
|
|
116
106
|
// getContent(node, schema) {
|
|
@@ -134,84 +124,90 @@ export function getParseRules(
|
|
|
134
124
|
|
|
135
125
|
// A function to create custom block for API consumers
|
|
136
126
|
// we want to hide the tiptap node from API consumers and provide a simpler API surface instead
|
|
137
|
-
export function
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
127
|
+
export function addNodeAndExtensionsToSpec<
|
|
128
|
+
TName extends string,
|
|
129
|
+
TProps extends PropSchema,
|
|
130
|
+
TContent extends "inline" | "none" | "table",
|
|
141
131
|
>(
|
|
142
|
-
blockConfig:
|
|
143
|
-
blockImplementation:
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
132
|
+
blockConfig: BlockConfig<TName, TProps, TContent>,
|
|
133
|
+
blockImplementation: BlockImplementation<TName, TProps, TContent>,
|
|
134
|
+
extensions?: BlockNoteExtension<any>[],
|
|
135
|
+
priority?: number,
|
|
136
|
+
): LooseBlockSpec<TName, TProps, TContent> {
|
|
137
|
+
const node =
|
|
138
|
+
((blockImplementation as any).node as Node) ||
|
|
139
|
+
Node.create({
|
|
140
|
+
name: blockConfig.type,
|
|
141
|
+
content: (blockConfig.content === "inline"
|
|
142
|
+
? "inline*"
|
|
143
|
+
: blockConfig.content === "none"
|
|
144
|
+
? ""
|
|
145
|
+
: blockConfig.content) as TContent extends "inline" ? "inline*" : "",
|
|
146
|
+
group: "blockContent",
|
|
147
|
+
selectable: blockImplementation.meta?.selectable ?? true,
|
|
148
|
+
isolating: blockImplementation.meta?.isolating ?? true,
|
|
149
|
+
code: blockImplementation.meta?.code ?? false,
|
|
150
|
+
defining: blockImplementation.meta?.defining ?? true,
|
|
151
|
+
priority,
|
|
152
|
+
addAttributes() {
|
|
153
|
+
return propsToAttributes(blockConfig.propSchema);
|
|
154
|
+
},
|
|
160
155
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
// structured correctly as this is what's used for parsing blocks. We
|
|
165
|
-
// just render a placeholder div inside as the `blockContent` element
|
|
166
|
-
// already has all the information needed for proper parsing.
|
|
167
|
-
const div = document.createElement("div");
|
|
168
|
-
return wrapInBlockStructure(
|
|
169
|
-
{
|
|
170
|
-
dom: div,
|
|
171
|
-
contentDOM: blockConfig.content === "inline" ? div : undefined,
|
|
172
|
-
},
|
|
173
|
-
blockConfig.type,
|
|
174
|
-
{},
|
|
175
|
-
blockConfig.propSchema,
|
|
176
|
-
blockConfig.isFileBlock,
|
|
177
|
-
HTMLAttributes,
|
|
178
|
-
);
|
|
179
|
-
},
|
|
156
|
+
parseHTML() {
|
|
157
|
+
return getParseRules(blockConfig, blockImplementation);
|
|
158
|
+
},
|
|
180
159
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
//
|
|
184
|
-
|
|
185
|
-
//
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
160
|
+
renderHTML({ HTMLAttributes }) {
|
|
161
|
+
// renderHTML is used for copy/pasting content from the editor back into
|
|
162
|
+
// the editor, so we need to make sure the `blockContent` element is
|
|
163
|
+
// structured correctly as this is what's used for parsing blocks. We
|
|
164
|
+
// just render a placeholder div inside as the `blockContent` element
|
|
165
|
+
// already has all the information needed for proper parsing.
|
|
166
|
+
const div = document.createElement("div");
|
|
167
|
+
return wrapInBlockStructure(
|
|
168
|
+
{
|
|
169
|
+
dom: div,
|
|
170
|
+
contentDOM: blockConfig.content === "inline" ? div : undefined,
|
|
171
|
+
},
|
|
190
172
|
blockConfig.type,
|
|
173
|
+
{},
|
|
174
|
+
blockConfig.propSchema,
|
|
175
|
+
blockImplementation.meta?.fileBlockAccept !== undefined,
|
|
176
|
+
HTMLAttributes,
|
|
191
177
|
);
|
|
192
|
-
|
|
193
|
-
const blockContentDOMAttributes =
|
|
194
|
-
this.options.domAttributes?.blockContent || {};
|
|
178
|
+
},
|
|
195
179
|
|
|
196
|
-
|
|
180
|
+
addNodeView() {
|
|
181
|
+
return (props) => {
|
|
182
|
+
// Gets the BlockNote editor instance
|
|
183
|
+
const editor = this.options.editor;
|
|
184
|
+
// Gets the block
|
|
185
|
+
const block = getBlockFromPos(
|
|
186
|
+
props.getPos,
|
|
187
|
+
editor,
|
|
188
|
+
this.editor,
|
|
189
|
+
blockConfig.type,
|
|
190
|
+
);
|
|
191
|
+
// Gets the custom HTML attributes for `blockContent` nodes
|
|
192
|
+
const blockContentDOMAttributes =
|
|
193
|
+
this.options.domAttributes?.blockContent || {};
|
|
197
194
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
blockConfig.isFileBlock,
|
|
204
|
-
blockContentDOMAttributes,
|
|
205
|
-
);
|
|
195
|
+
const nodeView = blockImplementation.render.call(
|
|
196
|
+
{ blockContentDOMAttributes, props, renderType: "nodeView" },
|
|
197
|
+
block as any,
|
|
198
|
+
editor as any,
|
|
199
|
+
);
|
|
206
200
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
201
|
+
if (blockImplementation.meta?.selectable === false) {
|
|
202
|
+
applyNonSelectableBlockFix(nodeView, this.editor);
|
|
203
|
+
}
|
|
210
204
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
205
|
+
// See explanation for why `update` is not implemented for NodeViews
|
|
206
|
+
// https://github.com/TypeCellOS/BlockNote/pull/1904#discussion_r2313461464
|
|
207
|
+
return nodeView;
|
|
208
|
+
};
|
|
209
|
+
},
|
|
210
|
+
});
|
|
215
211
|
|
|
216
212
|
if (node.name !== blockConfig.type) {
|
|
217
213
|
throw new Error(
|
|
@@ -219,43 +215,220 @@ export function createBlockSpec<
|
|
|
219
215
|
);
|
|
220
216
|
}
|
|
221
217
|
|
|
222
|
-
return
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
218
|
+
return {
|
|
219
|
+
config: blockConfig,
|
|
220
|
+
implementation: {
|
|
221
|
+
node,
|
|
222
|
+
render(block, editor) {
|
|
223
|
+
const blockContentDOMAttributes =
|
|
224
|
+
node.options.domAttributes?.blockContent || {};
|
|
225
|
+
|
|
226
|
+
return blockImplementation.render.call(
|
|
227
|
+
{
|
|
228
|
+
blockContentDOMAttributes,
|
|
229
|
+
props: undefined,
|
|
230
|
+
renderType: "dom",
|
|
231
|
+
},
|
|
232
|
+
block as any,
|
|
233
|
+
editor as any,
|
|
234
|
+
);
|
|
235
|
+
},
|
|
236
|
+
// TODO: this should not have wrapInBlockStructure and generally be a lot simpler
|
|
237
|
+
// post-processing in externalHTMLExporter should not be necessary
|
|
238
|
+
toExternalHTML: (block, editor) => {
|
|
239
|
+
const blockContentDOMAttributes =
|
|
240
|
+
node.options.domAttributes?.blockContent || {};
|
|
241
|
+
|
|
242
|
+
return (
|
|
243
|
+
blockImplementation.toExternalHTML?.call(
|
|
244
|
+
{ blockContentDOMAttributes },
|
|
245
|
+
block as any,
|
|
246
|
+
editor as any,
|
|
247
|
+
) ??
|
|
248
|
+
blockImplementation.render.call(
|
|
249
|
+
{ blockContentDOMAttributes, renderType: "dom", props: undefined },
|
|
250
|
+
block as any,
|
|
251
|
+
editor as any,
|
|
252
|
+
)
|
|
253
|
+
);
|
|
254
|
+
},
|
|
259
255
|
},
|
|
260
|
-
|
|
256
|
+
extensions,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Helper function to create a block config.
|
|
262
|
+
*/
|
|
263
|
+
export function createBlockConfig<
|
|
264
|
+
TCallback extends (
|
|
265
|
+
options: Partial<Record<string, any>>,
|
|
266
|
+
) => BlockConfig<any, any, any>,
|
|
267
|
+
TOptions extends Parameters<TCallback>[0],
|
|
268
|
+
TName extends ReturnType<TCallback>["type"],
|
|
269
|
+
TProps extends ReturnType<TCallback>["propSchema"],
|
|
270
|
+
TContent extends ReturnType<TCallback>["content"],
|
|
271
|
+
>(
|
|
272
|
+
callback: TCallback,
|
|
273
|
+
): TOptions extends undefined
|
|
274
|
+
? () => BlockConfig<TName, TProps, TContent>
|
|
275
|
+
: (options: TOptions) => BlockConfig<TName, TProps, TContent> {
|
|
276
|
+
return callback as any;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Helper function to create a block definition.
|
|
281
|
+
* Can accept either functions that return the required objects, or the objects directly.
|
|
282
|
+
*/
|
|
283
|
+
export function createBlockSpec<
|
|
284
|
+
const TName extends string,
|
|
285
|
+
const TProps extends PropSchema,
|
|
286
|
+
const TContent extends "inline" | "none",
|
|
287
|
+
const TOptions extends Partial<Record<string, any>> | undefined = undefined,
|
|
288
|
+
>(
|
|
289
|
+
blockConfigOrCreator: BlockConfig<TName, TProps, TContent>,
|
|
290
|
+
blockImplementationOrCreator:
|
|
291
|
+
| BlockImplementation<TName, TProps, TContent>
|
|
292
|
+
| (TOptions extends undefined
|
|
293
|
+
? () => BlockImplementation<TName, TProps, TContent>
|
|
294
|
+
: (
|
|
295
|
+
options: Partial<TOptions>,
|
|
296
|
+
) => BlockImplementation<TName, TProps, TContent>),
|
|
297
|
+
extensionsOrCreator?:
|
|
298
|
+
| BlockNoteExtension<any>[]
|
|
299
|
+
| (TOptions extends undefined
|
|
300
|
+
? () => BlockNoteExtension<any>[]
|
|
301
|
+
: (options: Partial<TOptions>) => BlockNoteExtension<any>[]),
|
|
302
|
+
): (options?: Partial<TOptions>) => BlockSpec<TName, TProps, TContent>;
|
|
303
|
+
export function createBlockSpec<
|
|
304
|
+
const TName extends string,
|
|
305
|
+
const TProps extends PropSchema,
|
|
306
|
+
const TContent extends "inline" | "none",
|
|
307
|
+
const BlockConf extends BlockConfig<TName, TProps, TContent>,
|
|
308
|
+
const TOptions extends Partial<Record<string, any>>,
|
|
309
|
+
>(
|
|
310
|
+
blockCreator: (options: Partial<TOptions>) => BlockConf,
|
|
311
|
+
blockImplementationOrCreator:
|
|
312
|
+
| BlockImplementation<
|
|
313
|
+
BlockConf["type"],
|
|
314
|
+
BlockConf["propSchema"],
|
|
315
|
+
BlockConf["content"]
|
|
316
|
+
>
|
|
317
|
+
| (TOptions extends undefined
|
|
318
|
+
? () => BlockImplementation<
|
|
319
|
+
BlockConf["type"],
|
|
320
|
+
BlockConf["propSchema"],
|
|
321
|
+
BlockConf["content"]
|
|
322
|
+
>
|
|
323
|
+
: (
|
|
324
|
+
options: Partial<TOptions>,
|
|
325
|
+
) => BlockImplementation<
|
|
326
|
+
BlockConf["type"],
|
|
327
|
+
BlockConf["propSchema"],
|
|
328
|
+
BlockConf["content"]
|
|
329
|
+
>),
|
|
330
|
+
extensionsOrCreator?:
|
|
331
|
+
| BlockNoteExtension<any>[]
|
|
332
|
+
| (TOptions extends undefined
|
|
333
|
+
? () => BlockNoteExtension<any>[]
|
|
334
|
+
: (options: Partial<TOptions>) => BlockNoteExtension<any>[]),
|
|
335
|
+
): (
|
|
336
|
+
options?: Partial<TOptions>,
|
|
337
|
+
) => BlockSpec<
|
|
338
|
+
BlockConf["type"],
|
|
339
|
+
BlockConf["propSchema"],
|
|
340
|
+
BlockConf["content"]
|
|
341
|
+
>;
|
|
342
|
+
export function createBlockSpec<
|
|
343
|
+
const TName extends string,
|
|
344
|
+
const TProps extends PropSchema,
|
|
345
|
+
const TContent extends "inline" | "none",
|
|
346
|
+
const TOptions extends Partial<Record<string, any>> | undefined = undefined,
|
|
347
|
+
>(
|
|
348
|
+
blockConfigOrCreator:
|
|
349
|
+
| BlockConfig<TName, TProps, TContent>
|
|
350
|
+
| (TOptions extends undefined
|
|
351
|
+
? () => BlockConfig<TName, TProps, TContent>
|
|
352
|
+
: (options: Partial<TOptions>) => BlockConfig<TName, TProps, TContent>),
|
|
353
|
+
blockImplementationOrCreator:
|
|
354
|
+
| BlockImplementation<TName, TProps, TContent>
|
|
355
|
+
| (TOptions extends undefined
|
|
356
|
+
? () => BlockImplementation<TName, TProps, TContent>
|
|
357
|
+
: (
|
|
358
|
+
options: Partial<TOptions>,
|
|
359
|
+
) => BlockImplementation<TName, TProps, TContent>),
|
|
360
|
+
extensionsOrCreator?:
|
|
361
|
+
| BlockNoteExtension<any>[]
|
|
362
|
+
| (TOptions extends undefined
|
|
363
|
+
? () => BlockNoteExtension<any>[]
|
|
364
|
+
: (options: Partial<TOptions>) => BlockNoteExtension<any>[]),
|
|
365
|
+
): (options?: Partial<TOptions>) => BlockSpec<TName, TProps, TContent> {
|
|
366
|
+
return (options = {} as TOptions) => {
|
|
367
|
+
const blockConfig =
|
|
368
|
+
typeof blockConfigOrCreator === "function"
|
|
369
|
+
? blockConfigOrCreator(options as any)
|
|
370
|
+
: blockConfigOrCreator;
|
|
371
|
+
|
|
372
|
+
const blockImplementation =
|
|
373
|
+
typeof blockImplementationOrCreator === "function"
|
|
374
|
+
? blockImplementationOrCreator(options as any)
|
|
375
|
+
: blockImplementationOrCreator;
|
|
376
|
+
|
|
377
|
+
const extensions = extensionsOrCreator
|
|
378
|
+
? typeof extensionsOrCreator === "function"
|
|
379
|
+
? extensionsOrCreator(options as any)
|
|
380
|
+
: extensionsOrCreator
|
|
381
|
+
: undefined;
|
|
382
|
+
|
|
383
|
+
return {
|
|
384
|
+
config: blockConfig,
|
|
385
|
+
implementation: {
|
|
386
|
+
...blockImplementation,
|
|
387
|
+
// TODO: this should not have wrapInBlockStructure and generally be a lot simpler
|
|
388
|
+
// post-processing in externalHTMLExporter should not be necessary
|
|
389
|
+
toExternalHTML(block, editor) {
|
|
390
|
+
const output = blockImplementation.toExternalHTML?.call(
|
|
391
|
+
{ blockContentDOMAttributes: this.blockContentDOMAttributes },
|
|
392
|
+
block as any,
|
|
393
|
+
editor as any,
|
|
394
|
+
);
|
|
395
|
+
|
|
396
|
+
if (output === undefined) {
|
|
397
|
+
return undefined;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
return wrapInBlockStructure(
|
|
401
|
+
output,
|
|
402
|
+
block.type,
|
|
403
|
+
block.props,
|
|
404
|
+
blockConfig.propSchema,
|
|
405
|
+
blockImplementation.meta?.fileBlockAccept !== undefined,
|
|
406
|
+
);
|
|
407
|
+
},
|
|
408
|
+
render(block, editor) {
|
|
409
|
+
const output = blockImplementation.render.call(
|
|
410
|
+
{
|
|
411
|
+
blockContentDOMAttributes: this.blockContentDOMAttributes,
|
|
412
|
+
renderType: this.renderType,
|
|
413
|
+
props: this.props as any,
|
|
414
|
+
},
|
|
415
|
+
block as any,
|
|
416
|
+
editor as any,
|
|
417
|
+
);
|
|
418
|
+
|
|
419
|
+
const nodeView = wrapInBlockStructure(
|
|
420
|
+
output,
|
|
421
|
+
block.type,
|
|
422
|
+
block.props,
|
|
423
|
+
blockConfig.propSchema,
|
|
424
|
+
blockImplementation.meta?.fileBlockAccept !== undefined,
|
|
425
|
+
this.blockContentDOMAttributes,
|
|
426
|
+
) satisfies NodeView;
|
|
427
|
+
|
|
428
|
+
return nodeView;
|
|
429
|
+
},
|
|
430
|
+
},
|
|
431
|
+
extensions: extensions,
|
|
432
|
+
};
|
|
433
|
+
};
|
|
261
434
|
}
|