@blocknote/core 0.11.2 → 0.12.0
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/README.md +13 -17
- package/dist/blocknote.js +1600 -1403
- package/dist/blocknote.js.map +1 -1
- package/dist/blocknote.umd.cjs +6 -6
- package/dist/blocknote.umd.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/dist/webpack-stats.json +1 -1
- package/package.json +7 -3
- package/src/api/blockManipulation/blockManipulation.test.ts +19 -15
- package/src/api/blockManipulation/blockManipulation.ts +107 -17
- package/src/api/exporters/html/externalHTMLExporter.ts +3 -7
- package/src/api/exporters/html/htmlConversion.test.ts +6 -3
- package/src/api/exporters/html/internalHTMLSerializer.ts +3 -7
- package/src/api/exporters/html/util/sharedHTMLConversion.ts +3 -3
- package/src/api/exporters/markdown/markdownExporter.test.ts +7 -3
- package/src/api/exporters/markdown/markdownExporter.ts +2 -6
- package/src/api/nodeConversions/nodeConversions.test.ts +14 -7
- package/src/api/nodeConversions/nodeConversions.ts +1 -2
- package/src/api/parsers/html/parseHTML.test.ts +5 -1
- package/src/api/parsers/html/parseHTML.ts +2 -6
- package/src/api/parsers/html/util/nestedLists.ts +11 -1
- package/src/api/parsers/markdown/parseMarkdown.test.ts +3 -0
- package/src/api/parsers/markdown/parseMarkdown.ts +2 -6
- package/src/api/testUtil/cases/customBlocks.ts +18 -16
- package/src/api/testUtil/cases/customInlineContent.ts +12 -13
- package/src/api/testUtil/cases/customStyles.ts +12 -10
- package/src/api/testUtil/index.ts +4 -2
- package/src/api/testUtil/partialBlockTestUtil.ts +2 -6
- package/src/blocks/ImageBlockContent/ImageBlockContent.ts +1 -2
- package/src/blocks/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.ts +8 -1
- package/src/blocks/defaultBlockHelpers.ts +3 -3
- package/src/blocks/defaultBlockTypeGuards.ts +84 -0
- package/src/blocks/defaultBlocks.ts +29 -3
- package/src/editor/Block.css +2 -31
- package/src/editor/BlockNoteEditor.ts +218 -262
- package/src/editor/BlockNoteExtensions.ts +5 -2
- package/src/editor/BlockNoteSchema.ts +98 -0
- package/src/editor/BlockNoteTipTapEditor.ts +162 -0
- package/src/editor/cursorPositionTypes.ts +2 -6
- package/src/editor/editor.css +0 -1
- package/src/editor/selectionTypes.ts +2 -6
- package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +22 -29
- package/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts +26 -27
- package/src/extensions/ImageToolbar/ImageToolbarPlugin.ts +45 -51
- package/src/extensions/Placeholder/PlaceholderExtension.ts +81 -88
- package/src/extensions/SideMenu/SideMenuPlugin.ts +55 -56
- package/src/extensions/SuggestionMenu/DefaultSuggestionItem.ts +8 -0
- package/src/extensions/SuggestionMenu/SuggestionPlugin.ts +353 -0
- package/src/extensions/{SlashMenu/defaultSlashMenuItems.ts → SuggestionMenu/getDefaultSlashMenuItems.ts} +119 -89
- package/src/extensions/TableHandles/TableHandlesPlugin.ts +62 -45
- package/src/extensions-shared/UiElementPosition.ts +4 -0
- package/src/index.ts +6 -6
- package/src/pm-nodes/BlockContainer.ts +5 -5
- package/src/schema/blocks/types.ts +15 -15
- package/src/schema/inlineContent/createSpec.ts +2 -2
- package/src/schema/inlineContent/types.ts +1 -1
- package/src/util/browser.ts +6 -4
- package/src/util/typescript.ts +7 -4
- package/types/src/api/blockManipulation/blockManipulation.d.ts +6 -1
- package/types/src/api/exporters/html/externalHTMLExporter.d.ts +2 -1
- package/types/src/api/exporters/html/internalHTMLSerializer.d.ts +2 -1
- package/types/src/api/exporters/markdown/markdownExporter.d.ts +2 -1
- package/types/src/api/nodeConversions/nodeConversions.d.ts +2 -1
- package/types/src/api/parsers/html/parseHTML.d.ts +2 -1
- package/types/src/api/parsers/markdown/parseMarkdown.d.ts +2 -1
- package/types/src/api/testUtil/cases/customBlocks.d.ts +72 -13
- package/types/src/api/testUtil/cases/customInlineContent.d.ts +281 -6
- package/types/src/api/testUtil/cases/customStyles.d.ts +247 -13
- package/types/src/api/testUtil/index.d.ts +4 -2
- package/types/src/api/testUtil/partialBlockTestUtil.d.ts +2 -1
- package/types/src/blocks/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.d.ts +6 -1
- package/types/src/blocks/defaultBlockHelpers.d.ts +2 -2
- package/types/src/blocks/defaultBlockTypeGuards.d.ts +24 -0
- package/types/src/blocks/defaultBlocks.d.ts +21 -15
- package/types/src/editor/BlockNoteEditor.d.ts +48 -53
- package/types/src/editor/BlockNoteExtensions.d.ts +1 -0
- package/types/src/editor/BlockNoteSchema.d.ts +34 -0
- package/types/src/editor/BlockNoteTipTapEditor.d.ts +28 -0
- package/types/src/editor/cursorPositionTypes.d.ts +2 -1
- package/types/src/editor/selectionTypes.d.ts +2 -1
- package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +5 -6
- package/types/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.d.ts +2 -2
- package/types/src/extensions/ImageToolbar/ImageToolbarPlugin.d.ts +15 -14
- package/types/src/extensions/Placeholder/PlaceholderExtension.d.ts +2 -15
- package/types/src/extensions/SideMenu/SideMenuPlugin.d.ts +8 -7
- package/types/src/extensions/SuggestionMenu/DefaultSuggestionItem.d.ts +8 -0
- package/types/src/extensions/SuggestionMenu/SuggestionPlugin.d.ts +31 -0
- package/types/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.d.ts +10 -0
- package/types/src/extensions/TableHandles/TableHandlesPlugin.d.ts +7 -7
- package/types/src/extensions-shared/UiElementPosition.d.ts +4 -0
- package/types/src/index.d.ts +6 -6
- package/types/src/pm-nodes/BlockContainer.d.ts +3 -2
- package/types/src/pm-nodes/BlockGroup.d.ts +1 -1
- package/types/src/schema/blocks/types.d.ts +15 -15
- package/types/src/schema/inlineContent/types.d.ts +1 -1
- package/types/src/util/browser.d.ts +1 -0
- package/types/src/util/typescript.d.ts +1 -0
- package/src/extensions/SlashMenu/BaseSlashMenuItem.ts +0 -12
- package/src/extensions/SlashMenu/SlashMenuPlugin.ts +0 -53
- package/src/extensions-shared/BaseUiElementTypes.ts +0 -8
- package/src/extensions-shared/README.md +0 -3
- package/src/extensions-shared/suggestion/SuggestionItem.ts +0 -3
- package/src/extensions-shared/suggestion/SuggestionPlugin.ts +0 -448
- package/types/src/extensions/SlashMenu/BaseSlashMenuItem.d.ts +0 -7
- package/types/src/extensions/SlashMenu/SlashMenuPlugin.d.ts +0 -13
- package/types/src/extensions/SlashMenu/defaultSlashMenuItems.d.ts +0 -3
- package/types/src/extensions-shared/BaseUiElementTypes.d.ts +0 -7
- package/types/src/extensions-shared/suggestion/SuggestionItem.d.ts +0 -3
- package/types/src/extensions-shared/suggestion/SuggestionPlugin.d.ts +0 -36
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-100.woff +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-100.woff2 +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-200.woff +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-200.woff2 +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-300.woff +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-300.woff2 +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-500.woff +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-500.woff2 +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-600.woff +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-600.woff2 +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-700.woff +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-700.woff2 +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-800.woff +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-800.woff2 +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-900.woff +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-900.woff2 +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-regular.woff +0 -0
- /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-regular.woff2 +0 -0
- /package/src/{assets/fonts-inter.css → fonts/inter.css} +0 -0
|
@@ -39,6 +39,7 @@ export const getBlockNoteExtensions = <
|
|
|
39
39
|
S extends StyleSchema
|
|
40
40
|
>(opts: {
|
|
41
41
|
editor: BlockNoteEditor<BSchema, I, S>;
|
|
42
|
+
placeholders?: Record<string | "default", string>;
|
|
42
43
|
domAttributes: Partial<BlockNoteDOMAttributes>;
|
|
43
44
|
blockSchema: BSchema;
|
|
44
45
|
blockSpecs: BlockSpecs;
|
|
@@ -66,8 +67,10 @@ export const getBlockNoteExtensions = <
|
|
|
66
67
|
|
|
67
68
|
// DropCursor,
|
|
68
69
|
Placeholder.configure({
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
// TODO: This shorthand is kind of ugly
|
|
71
|
+
...(opts.placeholders !== undefined
|
|
72
|
+
? { placeholders: opts.placeholders }
|
|
73
|
+
: {}),
|
|
71
74
|
}),
|
|
72
75
|
UniqueID.configure({
|
|
73
76
|
types: ["blockContainer"],
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defaultBlockSpecs,
|
|
3
|
+
defaultInlineContentSpecs,
|
|
4
|
+
defaultStyleSpecs,
|
|
5
|
+
} from "../blocks/defaultBlocks";
|
|
6
|
+
import {
|
|
7
|
+
BlockSchema,
|
|
8
|
+
BlockSchemaFromSpecs,
|
|
9
|
+
BlockSpecs,
|
|
10
|
+
InlineContentSchema,
|
|
11
|
+
InlineContentSchemaFromSpecs,
|
|
12
|
+
InlineContentSpecs,
|
|
13
|
+
StyleSchema,
|
|
14
|
+
StyleSchemaFromSpecs,
|
|
15
|
+
StyleSpecs,
|
|
16
|
+
getBlockSchemaFromSpecs,
|
|
17
|
+
getInlineContentSchemaFromSpecs,
|
|
18
|
+
getStyleSchemaFromSpecs,
|
|
19
|
+
} from "../schema";
|
|
20
|
+
import type {
|
|
21
|
+
BlockNoDefaults,
|
|
22
|
+
PartialBlockNoDefaults,
|
|
23
|
+
} from "../schema/blocks/types";
|
|
24
|
+
import type { BlockNoteEditor } from "./BlockNoteEditor";
|
|
25
|
+
|
|
26
|
+
export class BlockNoteSchema<
|
|
27
|
+
BSchema extends BlockSchema,
|
|
28
|
+
ISchema extends InlineContentSchema,
|
|
29
|
+
SSchema extends StyleSchema
|
|
30
|
+
> {
|
|
31
|
+
public readonly blockSpecs: BlockSpecs;
|
|
32
|
+
public readonly inlineContentSpecs: InlineContentSpecs;
|
|
33
|
+
public readonly styleSpecs: StyleSpecs;
|
|
34
|
+
|
|
35
|
+
public readonly blockSchema: BSchema;
|
|
36
|
+
public readonly inlineContentSchema: ISchema;
|
|
37
|
+
public readonly styleSchema: SSchema;
|
|
38
|
+
|
|
39
|
+
// Helper so that you can use typeof schema.BlockNoteEditor
|
|
40
|
+
public readonly BlockNoteEditor: BlockNoteEditor<BSchema, ISchema, SSchema> =
|
|
41
|
+
"only for types" as any;
|
|
42
|
+
|
|
43
|
+
public readonly Block: BlockNoDefaults<BSchema, ISchema, SSchema> =
|
|
44
|
+
"only for types" as any;
|
|
45
|
+
|
|
46
|
+
public readonly PartialBlock: PartialBlockNoDefaults<
|
|
47
|
+
BSchema,
|
|
48
|
+
ISchema,
|
|
49
|
+
SSchema
|
|
50
|
+
> = "only for types" as any;
|
|
51
|
+
|
|
52
|
+
public static create<
|
|
53
|
+
BSpecs extends BlockSpecs = typeof defaultBlockSpecs,
|
|
54
|
+
ISpecs extends InlineContentSpecs = typeof defaultInlineContentSpecs,
|
|
55
|
+
SSpecs extends StyleSpecs = typeof defaultStyleSpecs
|
|
56
|
+
>(options?: {
|
|
57
|
+
/**
|
|
58
|
+
* A list of custom block types that should be available in the editor.
|
|
59
|
+
*/
|
|
60
|
+
blockSpecs?: BSpecs;
|
|
61
|
+
/**
|
|
62
|
+
* A list of custom InlineContent types that should be available in the editor.
|
|
63
|
+
*/
|
|
64
|
+
inlineContentSpecs?: ISpecs;
|
|
65
|
+
/**
|
|
66
|
+
* A list of custom Styles that should be available in the editor.
|
|
67
|
+
*/
|
|
68
|
+
styleSpecs?: SSpecs;
|
|
69
|
+
}) {
|
|
70
|
+
return new BlockNoteSchema<
|
|
71
|
+
BlockSchemaFromSpecs<BSpecs>,
|
|
72
|
+
InlineContentSchemaFromSpecs<ISpecs>,
|
|
73
|
+
StyleSchemaFromSpecs<SSpecs>
|
|
74
|
+
>(options);
|
|
75
|
+
// as BlockNoteSchema<
|
|
76
|
+
// BlockSchemaFromSpecs<BSpecs>,
|
|
77
|
+
// InlineContentSchemaFromSpecs<ISpecs>,
|
|
78
|
+
// StyleSchemaFromSpecs<SSpecs>
|
|
79
|
+
// >;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
constructor(opts?: {
|
|
83
|
+
blockSpecs?: BlockSpecs;
|
|
84
|
+
inlineContentSpecs?: InlineContentSpecs;
|
|
85
|
+
styleSpecs?: StyleSpecs;
|
|
86
|
+
}) {
|
|
87
|
+
this.blockSpecs = opts?.blockSpecs || defaultBlockSpecs;
|
|
88
|
+
this.inlineContentSpecs =
|
|
89
|
+
opts?.inlineContentSpecs || defaultInlineContentSpecs;
|
|
90
|
+
this.styleSpecs = opts?.styleSpecs || defaultStyleSpecs;
|
|
91
|
+
|
|
92
|
+
this.blockSchema = getBlockSchemaFromSpecs(this.blockSpecs) as any;
|
|
93
|
+
this.inlineContentSchema = getInlineContentSchemaFromSpecs(
|
|
94
|
+
this.inlineContentSpecs
|
|
95
|
+
) as any;
|
|
96
|
+
this.styleSchema = getStyleSchemaFromSpecs(this.styleSpecs) as any;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { EditorOptions, createDocument } from "@tiptap/core";
|
|
2
|
+
// import "./blocknote.css";
|
|
3
|
+
import { Editor as TiptapEditor } from "@tiptap/core";
|
|
4
|
+
import { Node } from "@tiptap/pm/model";
|
|
5
|
+
import { EditorView } from "@tiptap/pm/view";
|
|
6
|
+
import { EditorState } from "prosemirror-state";
|
|
7
|
+
|
|
8
|
+
import { blockToNode } from "../api/nodeConversions/nodeConversions";
|
|
9
|
+
import { PartialBlock } from "../blocks/defaultBlocks";
|
|
10
|
+
import { StyleSchema } from "../schema";
|
|
11
|
+
|
|
12
|
+
export type BlockNoteTipTapEditorOptions = Partial<
|
|
13
|
+
Omit<EditorOptions, "content">
|
|
14
|
+
> & {
|
|
15
|
+
content: PartialBlock<any, any, any>[];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Custom Editor class that extends TiptapEditor and separates
|
|
20
|
+
* the creation of the view from the constructor.
|
|
21
|
+
*/
|
|
22
|
+
// @ts-ignore
|
|
23
|
+
export class BlockNoteTipTapEditor extends TiptapEditor {
|
|
24
|
+
private _state: EditorState;
|
|
25
|
+
|
|
26
|
+
constructor(options: BlockNoteTipTapEditorOptions, styleSchema: StyleSchema) {
|
|
27
|
+
// possible fix for next.js server side rendering
|
|
28
|
+
// const d = globalThis.document;
|
|
29
|
+
// const w = globalThis.window;
|
|
30
|
+
// if (!globalThis.document) {
|
|
31
|
+
// globalThis.document = {
|
|
32
|
+
// createElement: () => {},
|
|
33
|
+
// };
|
|
34
|
+
// }
|
|
35
|
+
// if (!globalThis.window) {
|
|
36
|
+
// globalThis.window = {
|
|
37
|
+
// setTimeout: () => {},
|
|
38
|
+
// };
|
|
39
|
+
// }
|
|
40
|
+
// options.injectCSS = false
|
|
41
|
+
super({ ...options, content: undefined });
|
|
42
|
+
|
|
43
|
+
// try {
|
|
44
|
+
// globalThis.window = w;
|
|
45
|
+
// } catch(e) {}
|
|
46
|
+
// try {
|
|
47
|
+
// globalThis.document = d;
|
|
48
|
+
// } catch(e) {}
|
|
49
|
+
|
|
50
|
+
// This is a hack to make "initial content detection" by y-prosemirror (and also tiptap isEmpty)
|
|
51
|
+
// properly detect whether or not the document has changed.
|
|
52
|
+
// We change the doc.createAndFill function to make sure the initial block id is set, instead of null
|
|
53
|
+
const schema = this.schema;
|
|
54
|
+
let cache: any;
|
|
55
|
+
const oldCreateAndFill = schema.nodes.doc.createAndFill;
|
|
56
|
+
(schema.nodes.doc as any).createAndFill = (...args: any) => {
|
|
57
|
+
if (cache) {
|
|
58
|
+
return cache;
|
|
59
|
+
}
|
|
60
|
+
const ret = oldCreateAndFill.apply(schema.nodes.doc, args);
|
|
61
|
+
|
|
62
|
+
// create a copy that we can mutate (otherwise, assigning attrs is not safe and corrupts the pm state)
|
|
63
|
+
const jsonNode = JSON.parse(JSON.stringify(ret!.toJSON()));
|
|
64
|
+
jsonNode.content[0].content[0].attrs.id = "initialBlockId";
|
|
65
|
+
|
|
66
|
+
cache = Node.fromJSON(schema, jsonNode);
|
|
67
|
+
return cache;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
let doc: Node;
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
const pmNodes = options?.content.map((b) =>
|
|
74
|
+
blockToNode(b, this.schema, styleSchema).toJSON()
|
|
75
|
+
);
|
|
76
|
+
doc = createDocument(
|
|
77
|
+
{
|
|
78
|
+
type: "doc",
|
|
79
|
+
content: [
|
|
80
|
+
{
|
|
81
|
+
type: "blockGroup",
|
|
82
|
+
content: pmNodes,
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
this.schema,
|
|
87
|
+
this.options.parseOptions
|
|
88
|
+
);
|
|
89
|
+
} catch (e) {
|
|
90
|
+
console.error(
|
|
91
|
+
"Error creating document from blocks passed as `initialContent`. Caused by exception: ",
|
|
92
|
+
e
|
|
93
|
+
);
|
|
94
|
+
throw new Error(
|
|
95
|
+
"Error creating document from blocks passed as `initialContent`:\n" +
|
|
96
|
+
+JSON.stringify(options.content)
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Create state immediately, so that it's available independently from the View,
|
|
101
|
+
// the way Prosemirror "intends it to be". This also makes sure that we can access
|
|
102
|
+
// the state before the view is created / mounted.
|
|
103
|
+
this._state = EditorState.create({
|
|
104
|
+
doc,
|
|
105
|
+
schema: this.schema,
|
|
106
|
+
// selection: selection || undefined,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
get state() {
|
|
111
|
+
if (this.view) {
|
|
112
|
+
this._state = this.view.state;
|
|
113
|
+
}
|
|
114
|
+
return this._state;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
createView() {
|
|
118
|
+
// no-op
|
|
119
|
+
// Disable default call to `createView` in the Editor constructor.
|
|
120
|
+
// We should call `createView` manually only when a DOM element is available
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Replace the default `createView` method with a custom one - which we call on mount
|
|
125
|
+
*/
|
|
126
|
+
private createViewAlternative() {
|
|
127
|
+
// Without queueMicrotask, custom IC / styles will give a React FlushSync error
|
|
128
|
+
queueMicrotask(() => {
|
|
129
|
+
this.view = new EditorView(this.options.element, {
|
|
130
|
+
...this.options.editorProps,
|
|
131
|
+
// @ts-ignore
|
|
132
|
+
dispatchTransaction: this.dispatchTransaction.bind(this),
|
|
133
|
+
state: this.state,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// `editor.view` is not yet available at this time.
|
|
137
|
+
// Therefore we will add all plugins and node views directly afterwards.
|
|
138
|
+
const newState = this.state.reconfigure({
|
|
139
|
+
plugins: this.extensionManager.plugins,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
this.view.updateState(newState);
|
|
143
|
+
|
|
144
|
+
this.createNodeViews();
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Mounts / unmounts the editor to a dom element
|
|
150
|
+
*
|
|
151
|
+
* @param element DOM element to mount to, ur null / undefined to destroy
|
|
152
|
+
*/
|
|
153
|
+
public mount = (element?: HTMLElement | null) => {
|
|
154
|
+
if (!element) {
|
|
155
|
+
this.destroy();
|
|
156
|
+
} else {
|
|
157
|
+
this.options.element = element;
|
|
158
|
+
// @ts-ignore
|
|
159
|
+
this.createViewAlternative();
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
BlockSchema,
|
|
4
|
-
InlineContentSchema,
|
|
5
|
-
StyleSchema,
|
|
6
|
-
} from "../schema";
|
|
1
|
+
import { Block } from "../blocks/defaultBlocks";
|
|
2
|
+
import { BlockSchema, InlineContentSchema, StyleSchema } from "../schema";
|
|
7
3
|
|
|
8
4
|
export type TextCursorPosition<
|
|
9
5
|
BSchema extends BlockSchema,
|
package/src/editor/editor.css
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
BlockSchema,
|
|
4
|
-
InlineContentSchema,
|
|
5
|
-
StyleSchema,
|
|
6
|
-
} from "../schema";
|
|
1
|
+
import { Block } from "../blocks/defaultBlocks";
|
|
2
|
+
import { BlockSchema, InlineContentSchema, StyleSchema } from "../schema";
|
|
7
3
|
|
|
8
4
|
export type Selection<
|
|
9
5
|
BSchema extends BlockSchema,
|
|
@@ -3,20 +3,15 @@ import { EditorState, Plugin, PluginKey } from "prosemirror-state";
|
|
|
3
3
|
import { EditorView } from "prosemirror-view";
|
|
4
4
|
|
|
5
5
|
import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
|
|
6
|
-
import {
|
|
7
|
-
BaseUiElementCallbacks,
|
|
8
|
-
BaseUiElementState,
|
|
9
|
-
} from "../../extensions-shared/BaseUiElementTypes";
|
|
6
|
+
import { UiElementPosition } from "../../extensions-shared/UiElementPosition";
|
|
10
7
|
import { BlockSchema, InlineContentSchema, StyleSchema } from "../../schema";
|
|
11
8
|
import { EventEmitter } from "../../util/EventEmitter";
|
|
12
9
|
|
|
13
|
-
export type
|
|
14
|
-
|
|
15
|
-
export type FormattingToolbarState = BaseUiElementState;
|
|
10
|
+
export type FormattingToolbarState = UiElementPosition;
|
|
16
11
|
|
|
17
12
|
export class FormattingToolbarView {
|
|
18
|
-
|
|
19
|
-
public
|
|
13
|
+
public state?: FormattingToolbarState;
|
|
14
|
+
public emitUpdate: () => void;
|
|
20
15
|
|
|
21
16
|
public preventHide = false;
|
|
22
17
|
public preventShow = false;
|
|
@@ -36,18 +31,16 @@ export class FormattingToolbarView {
|
|
|
36
31
|
StyleSchema
|
|
37
32
|
>,
|
|
38
33
|
private readonly pmView: EditorView,
|
|
39
|
-
|
|
40
|
-
formattingToolbarState: FormattingToolbarState
|
|
41
|
-
) => void
|
|
34
|
+
emitUpdate: (state: FormattingToolbarState) => void
|
|
42
35
|
) {
|
|
43
|
-
this.
|
|
44
|
-
if (!this.
|
|
36
|
+
this.emitUpdate = () => {
|
|
37
|
+
if (!this.state) {
|
|
45
38
|
throw new Error(
|
|
46
39
|
"Attempting to update uninitialized formatting toolbar"
|
|
47
40
|
);
|
|
48
41
|
}
|
|
49
42
|
|
|
50
|
-
|
|
43
|
+
emitUpdate(this.state);
|
|
51
44
|
};
|
|
52
45
|
|
|
53
46
|
pmView.dom.addEventListener("mousedown", this.viewMousedownHandler);
|
|
@@ -72,9 +65,9 @@ export class FormattingToolbarView {
|
|
|
72
65
|
|
|
73
66
|
// For dragging the whole editor.
|
|
74
67
|
dragHandler = () => {
|
|
75
|
-
if (this.
|
|
76
|
-
this.
|
|
77
|
-
this.
|
|
68
|
+
if (this.state?.show) {
|
|
69
|
+
this.state.show = false;
|
|
70
|
+
this.emitUpdate();
|
|
78
71
|
}
|
|
79
72
|
};
|
|
80
73
|
|
|
@@ -105,16 +98,16 @@ export class FormattingToolbarView {
|
|
|
105
98
|
return;
|
|
106
99
|
}
|
|
107
100
|
|
|
108
|
-
if (this.
|
|
109
|
-
this.
|
|
110
|
-
this.
|
|
101
|
+
if (this.state?.show) {
|
|
102
|
+
this.state.show = false;
|
|
103
|
+
this.emitUpdate();
|
|
111
104
|
}
|
|
112
105
|
};
|
|
113
106
|
|
|
114
107
|
scrollHandler = () => {
|
|
115
|
-
if (this.
|
|
116
|
-
this.
|
|
117
|
-
this.
|
|
108
|
+
if (this.state?.show) {
|
|
109
|
+
this.state.referencePos = this.getSelectionBoundingBox();
|
|
110
|
+
this.emitUpdate();
|
|
118
111
|
}
|
|
119
112
|
};
|
|
120
113
|
|
|
@@ -152,24 +145,24 @@ export class FormattingToolbarView {
|
|
|
152
145
|
!this.preventShow &&
|
|
153
146
|
(shouldShow || this.preventHide)
|
|
154
147
|
) {
|
|
155
|
-
this.
|
|
148
|
+
this.state = {
|
|
156
149
|
show: true,
|
|
157
150
|
referencePos: this.getSelectionBoundingBox(),
|
|
158
151
|
};
|
|
159
152
|
|
|
160
|
-
this.
|
|
153
|
+
this.emitUpdate();
|
|
161
154
|
|
|
162
155
|
return;
|
|
163
156
|
}
|
|
164
157
|
|
|
165
158
|
// Checks if menu should be hidden.
|
|
166
159
|
if (
|
|
167
|
-
this.
|
|
160
|
+
this.state?.show &&
|
|
168
161
|
!this.preventHide &&
|
|
169
162
|
(!shouldShow || this.preventShow || !this.editor.isEditable)
|
|
170
163
|
) {
|
|
171
|
-
this.
|
|
172
|
-
this.
|
|
164
|
+
this.state.show = false;
|
|
165
|
+
this.emitUpdate();
|
|
173
166
|
|
|
174
167
|
return;
|
|
175
168
|
}
|
|
@@ -2,12 +2,13 @@ import { getMarkRange, posToDOMRect, Range } from "@tiptap/core";
|
|
|
2
2
|
import { EditorView } from "@tiptap/pm/view";
|
|
3
3
|
import { Mark } from "prosemirror-model";
|
|
4
4
|
import { Plugin, PluginKey } from "prosemirror-state";
|
|
5
|
+
|
|
5
6
|
import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
|
|
6
|
-
import { BaseUiElementState } from "../../extensions-shared/BaseUiElementTypes";
|
|
7
7
|
import { BlockSchema, InlineContentSchema, StyleSchema } from "../../schema";
|
|
8
|
+
import { UiElementPosition } from "../../extensions-shared/UiElementPosition";
|
|
8
9
|
import { EventEmitter } from "../../util/EventEmitter";
|
|
9
10
|
|
|
10
|
-
export type HyperlinkToolbarState =
|
|
11
|
+
export type HyperlinkToolbarState = UiElementPosition & {
|
|
11
12
|
// The hovered hyperlink's URL, and the text it's displayed with in the
|
|
12
13
|
// editor.
|
|
13
14
|
url: string;
|
|
@@ -15,8 +16,8 @@ export type HyperlinkToolbarState = BaseUiElementState & {
|
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
class HyperlinkToolbarView {
|
|
18
|
-
|
|
19
|
-
public
|
|
19
|
+
public state?: HyperlinkToolbarState;
|
|
20
|
+
public emitUpdate: () => void;
|
|
20
21
|
|
|
21
22
|
menuUpdateTimer: ReturnType<typeof setTimeout> | undefined;
|
|
22
23
|
startMenuUpdateTimer: () => void;
|
|
@@ -34,16 +35,14 @@ class HyperlinkToolbarView {
|
|
|
34
35
|
constructor(
|
|
35
36
|
private readonly editor: BlockNoteEditor<any, any, any>,
|
|
36
37
|
private readonly pmView: EditorView,
|
|
37
|
-
|
|
38
|
-
hyperlinkToolbarState: HyperlinkToolbarState
|
|
39
|
-
) => void
|
|
38
|
+
emitUpdate: (state: HyperlinkToolbarState) => void
|
|
40
39
|
) {
|
|
41
|
-
this.
|
|
42
|
-
if (!this.
|
|
40
|
+
this.emitUpdate = () => {
|
|
41
|
+
if (!this.state) {
|
|
43
42
|
throw new Error("Attempting to update uninitialized hyperlink toolbar");
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
|
|
45
|
+
emitUpdate(this.state);
|
|
47
46
|
};
|
|
48
47
|
|
|
49
48
|
this.startMenuUpdateTimer = () => {
|
|
@@ -124,22 +123,22 @@ class HyperlinkToolbarView {
|
|
|
124
123
|
editorWrapper.contains(event.target as Node)
|
|
125
124
|
)
|
|
126
125
|
) {
|
|
127
|
-
if (this.
|
|
128
|
-
this.
|
|
129
|
-
this.
|
|
126
|
+
if (this.state?.show) {
|
|
127
|
+
this.state.show = false;
|
|
128
|
+
this.emitUpdate();
|
|
130
129
|
}
|
|
131
130
|
}
|
|
132
131
|
};
|
|
133
132
|
|
|
134
133
|
scrollHandler = () => {
|
|
135
134
|
if (this.hyperlinkMark !== undefined) {
|
|
136
|
-
if (this.
|
|
137
|
-
this.
|
|
135
|
+
if (this.state?.show) {
|
|
136
|
+
this.state.referencePos = posToDOMRect(
|
|
138
137
|
this.pmView,
|
|
139
138
|
this.hyperlinkMarkRange!.from,
|
|
140
139
|
this.hyperlinkMarkRange!.to
|
|
141
140
|
);
|
|
142
|
-
this.
|
|
141
|
+
this.emitUpdate();
|
|
143
142
|
}
|
|
144
143
|
}
|
|
145
144
|
};
|
|
@@ -158,9 +157,9 @@ class HyperlinkToolbarView {
|
|
|
158
157
|
this.pmView.dispatch(tr);
|
|
159
158
|
this.pmView.focus();
|
|
160
159
|
|
|
161
|
-
if (this.
|
|
162
|
-
this.
|
|
163
|
-
this.
|
|
160
|
+
if (this.state?.show) {
|
|
161
|
+
this.state.show = false;
|
|
162
|
+
this.emitUpdate();
|
|
164
163
|
}
|
|
165
164
|
}
|
|
166
165
|
|
|
@@ -176,9 +175,9 @@ class HyperlinkToolbarView {
|
|
|
176
175
|
);
|
|
177
176
|
this.pmView.focus();
|
|
178
177
|
|
|
179
|
-
if (this.
|
|
180
|
-
this.
|
|
181
|
-
this.
|
|
178
|
+
if (this.state?.show) {
|
|
179
|
+
this.state.show = false;
|
|
180
|
+
this.emitUpdate();
|
|
182
181
|
}
|
|
183
182
|
}
|
|
184
183
|
|
|
@@ -232,7 +231,7 @@ class HyperlinkToolbarView {
|
|
|
232
231
|
}
|
|
233
232
|
|
|
234
233
|
if (this.hyperlinkMark && this.editor.isEditable) {
|
|
235
|
-
this.
|
|
234
|
+
this.state = {
|
|
236
235
|
show: true,
|
|
237
236
|
referencePos: posToDOMRect(
|
|
238
237
|
this.pmView,
|
|
@@ -245,19 +244,19 @@ class HyperlinkToolbarView {
|
|
|
245
244
|
this.hyperlinkMarkRange!.to
|
|
246
245
|
),
|
|
247
246
|
};
|
|
248
|
-
this.
|
|
247
|
+
this.emitUpdate();
|
|
249
248
|
|
|
250
249
|
return;
|
|
251
250
|
}
|
|
252
251
|
|
|
253
252
|
// Hides menu.
|
|
254
253
|
if (
|
|
255
|
-
this.
|
|
254
|
+
this.state?.show &&
|
|
256
255
|
prevHyperlinkMark &&
|
|
257
256
|
(!this.hyperlinkMark || !this.editor.isEditable)
|
|
258
257
|
) {
|
|
259
|
-
this.
|
|
260
|
-
this.
|
|
258
|
+
this.state.show = false;
|
|
259
|
+
this.emitUpdate();
|
|
261
260
|
|
|
262
261
|
return;
|
|
263
262
|
}
|