@blocknote/core 0.4.0 → 0.4.2
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/blocknote.js +2043 -1918
- package/dist/blocknote.js.map +1 -1
- package/dist/blocknote.umd.cjs +20 -20
- package/dist/blocknote.umd.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +2 -2
- package/src/BlockNoteEditor.ts +5 -4
- package/src/BlockNoteExtensions.ts +11 -11
- package/src/api/Editor.ts +90 -6
- package/src/api/blockManipulation/__snapshots__/blockManipulation.test.ts.snap +616 -0
- package/src/api/blockManipulation/blockManipulation.test.ts +172 -0
- package/src/api/blockManipulation/blockManipulation.ts +25 -14
- package/src/api/formatConversions/__snapshots__/formatConversions.test.ts.snap +346 -0
- package/src/api/formatConversions/formatConversions.test.ts +766 -0
- package/src/api/nodeConversions/__snapshots__/nodeConversions.test.ts.snap +268 -0
- package/src/api/nodeConversions/nodeConversions.test.ts +244 -0
- package/src/api/nodeConversions/nodeConversions.ts +167 -58
- package/src/api/nodeConversions/testUtil.ts +61 -0
- package/src/api/util/nodeUtil.ts +38 -0
- package/src/editor.module.css +1 -0
- package/src/extensions/Blocks/api/blockTypes.ts +14 -9
- package/src/extensions/Blocks/api/inlineContentTypes.ts +27 -36
- package/src/extensions/Blocks/nodes/Block.module.css +39 -36
- package/src/extensions/Blocks/nodes/BlockContainer.ts +15 -14
- package/src/extensions/DraggableBlocks/DraggableBlocksPlugin.ts +149 -87
- package/src/shared/utils.ts +6 -0
- package/types/src/BlockNoteEditor.d.ts +2 -2
- package/types/src/api/Editor.d.ts +26 -6
- package/types/src/api/blockManipulation/blockManipulation.d.ts +5 -5
- package/types/src/api/blockManipulation/blockManipulation.test.d.ts +1 -0
- package/types/src/api/formatConversions/formatConversions.test.d.ts +1 -0
- package/types/src/api/nodeConversions/nodeConversions.d.ts +11 -4
- package/types/src/api/nodeConversions/nodeConversions.test.d.ts +1 -0
- package/types/src/api/nodeConversions/testUtil.d.ts +2 -0
- package/types/src/api/util/nodeUtil.d.ts +8 -0
- package/types/src/extensions/Blocks/api/blockTypes.d.ts +10 -9
- package/types/src/extensions/Blocks/api/inlineContentTypes.d.ts +25 -19
- package/types/src/extensions/DraggableBlocks/DraggableBlocksPlugin.d.ts +15 -0
- package/types/src/shared/utils.d.ts +3 -0
- package/types/src/EditorElement.d.ts +0 -7
- package/types/src/api/Document.d.ts +0 -5
- package/types/src/api/removeUnderlinesRehypePlugin.d.ts +0 -6
- package/types/src/api/simplifyBlocksRehypePlugin.d.ts +0 -16
- package/types/src/extensions/Blocks/BlockAttributes.d.ts +0 -2
- package/types/src/extensions/Blocks/MultipleNodeSelection.d.ts +0 -24
- package/types/src/extensions/Blocks/api/apiTypes.d.ts +0 -18
- package/types/src/extensions/Blocks/api/styleTypes.d.ts +0 -22
- package/types/src/extensions/Blocks/apiTypes.d.ts +0 -16
- package/types/src/extensions/Blocks/nodes/Block.d.ts +0 -24
- package/types/src/extensions/Blocks/nodes/BlockContent/BlockContentTypes.d.ts +0 -4
- package/types/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContentTypes.d.ts +0 -4
- package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContentTypes.d.ts +0 -2
- package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContentTypes.d.ts +0 -2
- package/types/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContentTypes.d.ts +0 -2
- package/types/src/extensions/Blocks/nodes/BlockTypes/HeadingBlock/HeadingContent.d.ts +0 -8
- package/types/src/extensions/Blocks/nodes/BlockTypes/ListItemBlock/ListItemContent.d.ts +0 -8
- package/types/src/extensions/Blocks/nodes/BlockTypes/ListItemBlock/OrderedListItemIndexPlugin.d.ts +0 -2
- package/types/src/extensions/Blocks/nodes/BlockTypes/TextBlock/TextContent.d.ts +0 -6
- package/types/src/extensions/BubbleMenu/BubbleMenuExtension.d.ts +0 -8
- package/types/src/extensions/BubbleMenu/BubbleMenuFactoryTypes.d.ts +0 -27
- package/types/src/extensions/BubbleMenu/BubbleMenuPlugin.d.ts +0 -44
- package/types/src/extensions/DraggableBlocks/BlockMenuFactoryTypes.d.ts +0 -12
- package/types/src/extensions/DraggableBlocks/DragMenuFactoryTypes.d.ts +0 -18
- package/types/src/extensions/Hyperlinks/HyperlinkMark.d.ts +0 -8
- package/types/src/extensions/Hyperlinks/HyperlinkMenuFactoryTypes.d.ts +0 -11
- package/types/src/extensions/Hyperlinks/HyperlinkMenuPlugin.d.ts +0 -11
- package/types/src/extensions/Paragraph/FixedParagraph.d.ts +0 -1
- package/types/src/extensions/SlashMenu/defaultCommands.d.ts +0 -8
- package/types/src/utils.d.ts +0 -2
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { mergeAttributes, Node } from "@tiptap/core";
|
|
2
2
|
import { Fragment, Node as PMNode, Slice } from "prosemirror-model";
|
|
3
3
|
import { TextSelection } from "prosemirror-state";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
blockToNode,
|
|
6
|
+
inlineContentToNodes,
|
|
7
|
+
} from "../../../api/nodeConversions/nodeConversions";
|
|
5
8
|
import { PartialBlock } from "../api/blockTypes";
|
|
6
9
|
import { getBlockInfoFromPos } from "../helpers/getBlockInfoFromPos";
|
|
7
10
|
import { PreviousBlockTypePlugin } from "../PreviousBlockTypePlugin";
|
|
@@ -329,15 +332,7 @@ export const BlockContainer = Node.create<IBlock>({
|
|
|
329
332
|
} else {
|
|
330
333
|
// Adds a text node with the provided styles converted into marks to the content, for each InlineContent
|
|
331
334
|
// object.
|
|
332
|
-
|
|
333
|
-
const marks = [];
|
|
334
|
-
|
|
335
|
-
for (const style of styledText.styles) {
|
|
336
|
-
marks.push(state.schema.mark(style.type, style.props));
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
content.push(state.schema.text(styledText.text, marks));
|
|
340
|
-
}
|
|
335
|
+
content = inlineContentToNodes(block.content, state.schema);
|
|
341
336
|
}
|
|
342
337
|
|
|
343
338
|
// Replaces the contents of the blockContent node with the previously created text node(s).
|
|
@@ -350,10 +345,16 @@ export const BlockContainer = Node.create<IBlock>({
|
|
|
350
345
|
|
|
351
346
|
// Changes the block type and adds the provided props as node attributes. Also preserves all existing node
|
|
352
347
|
// attributes that are compatible with the new type.
|
|
353
|
-
state.tr.setNodeMarkup(
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
348
|
+
state.tr.setNodeMarkup(
|
|
349
|
+
startPos,
|
|
350
|
+
block.type === undefined
|
|
351
|
+
? undefined
|
|
352
|
+
: state.schema.nodes[block.type],
|
|
353
|
+
{
|
|
354
|
+
...contentNode.attrs,
|
|
355
|
+
...block.props,
|
|
356
|
+
}
|
|
357
|
+
);
|
|
357
358
|
}
|
|
358
359
|
|
|
359
360
|
return true;
|
|
@@ -150,8 +150,10 @@ function setDragImage(view: EditorView, from: number, to = from) {
|
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
// dataTransfer.setDragImage(element) only works if element is attached to the DOM.
|
|
153
|
+
unsetDragImage();
|
|
153
154
|
dragImageElement = parentClone;
|
|
154
|
-
dragImageElement.className =
|
|
155
|
+
dragImageElement.className =
|
|
156
|
+
dragImageElement.className + " " + styles.dragPreview;
|
|
155
157
|
document.body.appendChild(dragImageElement);
|
|
156
158
|
}
|
|
157
159
|
|
|
@@ -245,104 +247,164 @@ export class BlockMenuView {
|
|
|
245
247
|
|
|
246
248
|
this.blockMenu = blockMenuFactory(this.getStaticParams());
|
|
247
249
|
|
|
250
|
+
document.body.addEventListener("drop", this.onDrop, true);
|
|
251
|
+
document.body.addEventListener("dragover", this.onDragOver);
|
|
252
|
+
|
|
248
253
|
// Shows or updates menu position whenever the cursor moves, if the menu isn't frozen.
|
|
249
|
-
document.body.addEventListener(
|
|
250
|
-
"mousemove",
|
|
251
|
-
(event) => {
|
|
252
|
-
if (this.menuFrozen) {
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// Editor itself may have padding or other styling which affects size/position, so we get the boundingRect of
|
|
257
|
-
// the first child (i.e. the blockGroup that wraps all blocks in the editor) for a more accurate bounding box.
|
|
258
|
-
const editorBoundingBox = (
|
|
259
|
-
this.editor.view.dom.firstChild! as HTMLElement
|
|
260
|
-
).getBoundingClientRect();
|
|
261
|
-
|
|
262
|
-
this.horizontalPosAnchor = editorBoundingBox.x;
|
|
263
|
-
|
|
264
|
-
// Gets block at mouse cursor's vertical position.
|
|
265
|
-
const coords = {
|
|
266
|
-
left: editorBoundingBox.left + editorBoundingBox.width / 2, // take middle of editor
|
|
267
|
-
top: event.clientY,
|
|
268
|
-
};
|
|
269
|
-
const block = getDraggableBlockFromCoords(coords, this.editor.view);
|
|
270
|
-
|
|
271
|
-
// Closes the menu if the mouse cursor is beyond the editor vertically.
|
|
272
|
-
if (!block) {
|
|
273
|
-
if (this.menuOpen) {
|
|
274
|
-
this.menuOpen = false;
|
|
275
|
-
this.blockMenu.hide();
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
return;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// Doesn't update if the menu is already open and the mouse cursor is still hovering the same block.
|
|
282
|
-
if (
|
|
283
|
-
this.menuOpen &&
|
|
284
|
-
this.hoveredBlockContent?.hasAttribute("data-id") &&
|
|
285
|
-
this.hoveredBlockContent?.getAttribute("data-id") === block.id
|
|
286
|
-
) {
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// Gets the block's content node, which lets to ignore child blocks when determining the block menu's position.
|
|
291
|
-
const blockContent = block.node.firstChild as HTMLElement;
|
|
292
|
-
this.hoveredBlockContent = blockContent;
|
|
293
|
-
|
|
294
|
-
if (!blockContent) {
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// Shows or updates elements.
|
|
299
|
-
if (!this.menuOpen) {
|
|
300
|
-
this.menuOpen = true;
|
|
301
|
-
this.blockMenu.render(this.getDynamicParams(), true);
|
|
302
|
-
} else {
|
|
303
|
-
this.blockMenu.render(this.getDynamicParams(), false);
|
|
304
|
-
}
|
|
305
|
-
},
|
|
306
|
-
true
|
|
307
|
-
);
|
|
254
|
+
document.body.addEventListener("mousemove", this.onMouseMove, true);
|
|
308
255
|
|
|
309
256
|
// Hides and unfreezes the menu whenever the user selects the editor with the mouse or presses a key.
|
|
310
257
|
// TODO: Better integration with suggestions menu and only editor scope?
|
|
311
|
-
document.body.addEventListener(
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
if (this.blockMenu.element?.contains(event.target as HTMLElement)) {
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
if (this.menuOpen) {
|
|
319
|
-
this.menuOpen = false;
|
|
320
|
-
this.blockMenu.hide();
|
|
321
|
-
}
|
|
258
|
+
document.body.addEventListener("mousedown", this.onMouseDown, true);
|
|
259
|
+
document.body.addEventListener("keydown", this.onKeyDown, true);
|
|
260
|
+
}
|
|
322
261
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
262
|
+
/**
|
|
263
|
+
* If the event is outside of the editor contents,
|
|
264
|
+
* we dispatch a fake event, so that we can still drop the content
|
|
265
|
+
* when dragging / dropping to the side of the editor
|
|
266
|
+
*/
|
|
267
|
+
onDrop = (event: DragEvent) => {
|
|
268
|
+
if ((event as any).synthetic) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
let pos = this.editor.view.posAtCoords({
|
|
272
|
+
left: event.clientX,
|
|
273
|
+
top: event.clientY,
|
|
274
|
+
});
|
|
334
275
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
276
|
+
if (!pos || pos.inside === -1) {
|
|
277
|
+
const evt = new Event("drop", event) as any;
|
|
278
|
+
const editorBoundingBox = (
|
|
279
|
+
this.editor.view.dom.firstChild! as HTMLElement
|
|
280
|
+
).getBoundingClientRect();
|
|
281
|
+
evt.clientX = editorBoundingBox.left + editorBoundingBox.width / 2;
|
|
282
|
+
evt.clientY = event.clientY;
|
|
283
|
+
evt.dataTransfer = event.dataTransfer;
|
|
284
|
+
evt.preventDefault = () => event.preventDefault();
|
|
285
|
+
evt.synthetic = true; // prevent recursion
|
|
286
|
+
// console.log("dispatch fake drop");
|
|
287
|
+
this.editor.view.dom.dispatchEvent(evt);
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* If the event is outside of the editor contents,
|
|
293
|
+
* we dispatch a fake event, so that we can still drop the content
|
|
294
|
+
* when dragging / dropping to the side of the editor
|
|
295
|
+
*/
|
|
296
|
+
onDragOver = (event: DragEvent) => {
|
|
297
|
+
if ((event as any).synthetic) {
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
let pos = this.editor.view.posAtCoords({
|
|
301
|
+
left: event.clientX,
|
|
302
|
+
top: event.clientY,
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
if (!pos || pos.inside === -1) {
|
|
306
|
+
const evt = new Event("dragover", event) as any;
|
|
307
|
+
const editorBoundingBox = (
|
|
308
|
+
this.editor.view.dom.firstChild! as HTMLElement
|
|
309
|
+
).getBoundingClientRect();
|
|
310
|
+
evt.clientX = editorBoundingBox.left + editorBoundingBox.width / 2;
|
|
311
|
+
evt.clientY = event.clientY;
|
|
312
|
+
evt.dataTransfer = event.dataTransfer;
|
|
313
|
+
evt.preventDefault = () => event.preventDefault();
|
|
314
|
+
evt.synthetic = true; // prevent recursion
|
|
315
|
+
// console.log("dispatch fake dragover");
|
|
316
|
+
this.editor.view.dom.dispatchEvent(evt);
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
onKeyDown = (_event: KeyboardEvent) => {
|
|
321
|
+
if (this.menuOpen) {
|
|
322
|
+
this.menuOpen = false;
|
|
323
|
+
this.blockMenu.hide();
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
this.menuFrozen = false;
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
onMouseDown = (event: MouseEvent) => {
|
|
330
|
+
if (this.blockMenu.element?.contains(event.target as HTMLElement)) {
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (this.menuOpen) {
|
|
335
|
+
this.menuOpen = false;
|
|
336
|
+
this.blockMenu.hide();
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
this.menuFrozen = false;
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
onMouseMove = (event: MouseEvent) => {
|
|
343
|
+
if (this.menuFrozen) {
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Editor itself may have padding or other styling which affects size/position, so we get the boundingRect of
|
|
348
|
+
// the first child (i.e. the blockGroup that wraps all blocks in the editor) for a more accurate bounding box.
|
|
349
|
+
const editorBoundingBox = (
|
|
350
|
+
this.editor.view.dom.firstChild! as HTMLElement
|
|
351
|
+
).getBoundingClientRect();
|
|
352
|
+
|
|
353
|
+
this.horizontalPosAnchor = editorBoundingBox.x;
|
|
354
|
+
|
|
355
|
+
// Gets block at mouse cursor's vertical position.
|
|
356
|
+
const coords = {
|
|
357
|
+
left: editorBoundingBox.left + editorBoundingBox.width / 2, // take middle of editor
|
|
358
|
+
top: event.clientY,
|
|
359
|
+
};
|
|
360
|
+
const block = getDraggableBlockFromCoords(coords, this.editor.view);
|
|
361
|
+
|
|
362
|
+
// Closes the menu if the mouse cursor is beyond the editor vertically.
|
|
363
|
+
if (!block) {
|
|
364
|
+
if (this.menuOpen) {
|
|
365
|
+
this.menuOpen = false;
|
|
366
|
+
this.blockMenu.hide();
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Doesn't update if the menu is already open and the mouse cursor is still hovering the same block.
|
|
373
|
+
if (
|
|
374
|
+
this.menuOpen &&
|
|
375
|
+
this.hoveredBlockContent?.hasAttribute("data-id") &&
|
|
376
|
+
this.hoveredBlockContent?.getAttribute("data-id") === block.id
|
|
377
|
+
) {
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Gets the block's content node, which lets to ignore child blocks when determining the block menu's position.
|
|
382
|
+
const blockContent = block.node.firstChild as HTMLElement;
|
|
383
|
+
this.hoveredBlockContent = blockContent;
|
|
384
|
+
|
|
385
|
+
if (!blockContent) {
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// Shows or updates elements.
|
|
390
|
+
if (!this.menuOpen) {
|
|
391
|
+
this.menuOpen = true;
|
|
392
|
+
this.blockMenu.render(this.getDynamicParams(), true);
|
|
393
|
+
} else {
|
|
394
|
+
this.blockMenu.render(this.getDynamicParams(), false);
|
|
395
|
+
}
|
|
396
|
+
};
|
|
340
397
|
|
|
341
398
|
destroy() {
|
|
342
399
|
if (this.menuOpen) {
|
|
343
400
|
this.menuOpen = false;
|
|
344
401
|
this.blockMenu.hide();
|
|
345
402
|
}
|
|
403
|
+
document.body.removeEventListener("mousemove", this.onMouseMove);
|
|
404
|
+
document.body.removeEventListener("dragover", this.onDragOver);
|
|
405
|
+
document.body.removeEventListener("drop", this.onDrop);
|
|
406
|
+
document.body.removeEventListener("mousedown", this.onMouseDown);
|
|
407
|
+
document.body.removeEventListener("keydown", this.onKeyDown);
|
|
346
408
|
}
|
|
347
409
|
|
|
348
410
|
addBlock() {
|
package/src/shared/utils.ts
CHANGED
|
@@ -9,8 +9,8 @@ export type BlockNoteEditorOptions = {
|
|
|
9
9
|
slashCommands: SlashCommand[];
|
|
10
10
|
parentElement: HTMLElement;
|
|
11
11
|
editorDOMAttributes: Record<string, string>;
|
|
12
|
-
onUpdate: () => void;
|
|
13
|
-
onCreate: () => void;
|
|
12
|
+
onUpdate: (editor: BlockNoteEditor) => void;
|
|
13
|
+
onCreate: (editor: BlockNoteEditor) => void;
|
|
14
14
|
_tiptapOptions: any;
|
|
15
15
|
};
|
|
16
16
|
export declare class BlockNoteEditor extends EditorAPI {
|
|
@@ -1,17 +1,33 @@
|
|
|
1
1
|
import { Editor as TiptapEditor } from "@tiptap/core";
|
|
2
2
|
import { Node } from "prosemirror-model";
|
|
3
|
-
import { Block, PartialBlock } from "../extensions/Blocks/api/blockTypes";
|
|
3
|
+
import { Block, BlockIdentifier, PartialBlock } from "../extensions/Blocks/api/blockTypes";
|
|
4
4
|
import { TextCursorPosition } from "../extensions/Blocks/api/cursorPositionTypes";
|
|
5
5
|
export declare class Editor {
|
|
6
6
|
private tiptapEditor;
|
|
7
7
|
private blockCache;
|
|
8
8
|
constructor(tiptapEditor: TiptapEditor, blockCache?: WeakMap<Node, Block>);
|
|
9
9
|
/**
|
|
10
|
-
* Gets a
|
|
10
|
+
* Gets a snapshot of all top-level blocks that are in the editor.
|
|
11
|
+
* @returns An array containing a snapshot of all top-level (non-nested) blocks in the editor.
|
|
11
12
|
*/
|
|
12
|
-
get
|
|
13
|
+
get topLevelBlocks(): Block[];
|
|
13
14
|
/**
|
|
14
|
-
*
|
|
15
|
+
* Retrieves a snapshot of an existing block from the editor.
|
|
16
|
+
* @param block The identifier of an existing block that should be retrieved.
|
|
17
|
+
* @returns The block that matches the identifier, or undefined if no matching block was found.
|
|
18
|
+
*/
|
|
19
|
+
getBlock(block: BlockIdentifier): Block | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Traverses all blocks in the editor, including all nested blocks, and executes a callback for each. The traversal is
|
|
22
|
+
* depth-first, which is the same order as blocks appear in the editor by y-coordinate. Stops traversal if the callback
|
|
23
|
+
* returns false;
|
|
24
|
+
* @param callback The callback to execute for each block.
|
|
25
|
+
* @param reverse Whether the blocks should be traversed in reverse order.
|
|
26
|
+
*/
|
|
27
|
+
forEachBlock(callback: (block: Block) => boolean, reverse?: boolean): void;
|
|
28
|
+
/**
|
|
29
|
+
* Gets a snapshot of the text cursor position within the editor.
|
|
30
|
+
* @returns A snapshot of the text cursor position.
|
|
15
31
|
*/
|
|
16
32
|
get textCursorPosition(): TextCursorPosition;
|
|
17
33
|
/**
|
|
@@ -42,7 +58,7 @@ export declare class Editor {
|
|
|
42
58
|
*/
|
|
43
59
|
replaceBlocks(blocksToRemove: Block[], blocksToInsert: PartialBlock[]): void;
|
|
44
60
|
/**
|
|
45
|
-
* Executes a callback function whenever the editor's
|
|
61
|
+
* Executes a callback function whenever the editor's contents change.
|
|
46
62
|
* @param callback The callback function to execute.
|
|
47
63
|
*/
|
|
48
64
|
onContentChange(callback: () => void): void;
|
|
@@ -51,23 +67,27 @@ export declare class Editor {
|
|
|
51
67
|
* is simplified in order to better conform to HTML standards. Block structuring elements are removed, children of
|
|
52
68
|
* blocks which aren't list items are lifted out of them, and list items blocks are wrapped in `ul`/`ol` tags.
|
|
53
69
|
* @param blocks The list of blocks to serialize into HTML.
|
|
70
|
+
* @returns An HTML representation of the blocks.
|
|
54
71
|
*/
|
|
55
72
|
blocksToHTML(blocks: Block[]): Promise<string>;
|
|
56
73
|
/**
|
|
57
74
|
* Creates a list of blocks from an HTML string.
|
|
58
75
|
* @param htmlString The HTML string to create a list of blocks from.
|
|
76
|
+
* @returns A list of blocks parsed from the HTML string.
|
|
59
77
|
*/
|
|
60
78
|
HTMLToBlocks(htmlString: string): Promise<Block[]>;
|
|
61
79
|
/**
|
|
62
80
|
* Serializes a list of blocks into a Markdown string. The output is simplified as Markdown does not support all
|
|
63
81
|
* features of BlockNote. Block structuring elements are removed, children of blocks which aren't list items are
|
|
64
|
-
*
|
|
82
|
+
* un-nested, and certain styles are removed.
|
|
65
83
|
* @param blocks The list of blocks to serialize into Markdown.
|
|
84
|
+
* @returns A Markdown representation of the blocks.
|
|
66
85
|
*/
|
|
67
86
|
blocksToMarkdown(blocks: Block[]): Promise<string>;
|
|
68
87
|
/**
|
|
69
88
|
* Creates a list of blocks from a Markdown string.
|
|
70
89
|
* @param markdownString The Markdown string to create a list of blocks from.
|
|
90
|
+
* @returns A list of blocks parsed from the Markdown string.
|
|
71
91
|
*/
|
|
72
92
|
markdownToBlocks(markdownString: string): Promise<Block[]>;
|
|
73
93
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Editor } from "@tiptap/core";
|
|
2
|
-
import {
|
|
3
|
-
export declare function insertBlocks(blocksToInsert: PartialBlock[],
|
|
4
|
-
export declare function updateBlock(blockToUpdate:
|
|
5
|
-
export declare function removeBlocks(blocksToRemove:
|
|
6
|
-
export declare function replaceBlocks(blocksToRemove:
|
|
2
|
+
import { BlockIdentifier, PartialBlock } from "../../extensions/Blocks/api/blockTypes";
|
|
3
|
+
export declare function insertBlocks(blocksToInsert: PartialBlock[], referenceBlock: BlockIdentifier, placement: "before" | "after" | "nested" | undefined, editor: Editor): void;
|
|
4
|
+
export declare function updateBlock(blockToUpdate: BlockIdentifier, update: PartialBlock, editor: Editor): void;
|
|
5
|
+
export declare function removeBlocks(blocksToRemove: BlockIdentifier[], editor: Editor): void;
|
|
6
|
+
export declare function replaceBlocks(blocksToRemove: BlockIdentifier[], blocksToInsert: PartialBlock[], editor: Editor): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { Node, Schema } from "prosemirror-model";
|
|
2
2
|
import { Block, PartialBlock } from "../../extensions/Blocks/api/blockTypes";
|
|
3
|
+
import { PartialInlineContent } from "../../extensions/Blocks/api/inlineContentTypes";
|
|
4
|
+
/**
|
|
5
|
+
* converts an array of inline content elements to prosemirror nodes
|
|
6
|
+
*/
|
|
7
|
+
export declare function inlineContentToNodes(blockContent: PartialInlineContent[], schema: Schema): Node[];
|
|
8
|
+
/**
|
|
9
|
+
* Converts a BlockNote block to a TipTap node.
|
|
10
|
+
*/
|
|
3
11
|
export declare function blockToNode(block: PartialBlock, schema: Schema): Node;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
};
|
|
12
|
+
/**
|
|
13
|
+
* Convert a TipTap node to a BlockNote block.
|
|
14
|
+
*/
|
|
8
15
|
export declare function nodeToBlock(node: Node, blockCache?: WeakMap<Node, Block>): Block;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Define the main block types **/
|
|
2
|
-
import { InlineContent } from "./inlineContentTypes";
|
|
2
|
+
import { InlineContent, PartialInlineContent } from "./inlineContentTypes";
|
|
3
3
|
export type BlockTemplate<Type extends string, Props extends Record<string, string>> = {
|
|
4
4
|
id: string;
|
|
5
5
|
type: Type;
|
|
@@ -7,23 +7,24 @@ export type BlockTemplate<Type extends string, Props extends Record<string, stri
|
|
|
7
7
|
content: InlineContent[];
|
|
8
8
|
children: Block[];
|
|
9
9
|
};
|
|
10
|
-
export type
|
|
10
|
+
export type DefaultBlockProps = {
|
|
11
11
|
backgroundColor: string;
|
|
12
12
|
textColor: string;
|
|
13
13
|
textAlignment: "left" | "center" | "right" | "justify";
|
|
14
14
|
};
|
|
15
|
-
export type NumberedListItemBlock = BlockTemplate<"numberedListItem",
|
|
16
|
-
export type BulletListItemBlock = BlockTemplate<"bulletListItem",
|
|
17
|
-
export type HeadingBlock = BlockTemplate<"heading",
|
|
15
|
+
export type NumberedListItemBlock = BlockTemplate<"numberedListItem", DefaultBlockProps>;
|
|
16
|
+
export type BulletListItemBlock = BlockTemplate<"bulletListItem", DefaultBlockProps>;
|
|
17
|
+
export type HeadingBlock = BlockTemplate<"heading", DefaultBlockProps & {
|
|
18
18
|
level: "1" | "2" | "3";
|
|
19
19
|
}>;
|
|
20
|
-
export type ParagraphBlock = BlockTemplate<"paragraph",
|
|
20
|
+
export type ParagraphBlock = BlockTemplate<"paragraph", DefaultBlockProps>;
|
|
21
21
|
export type Block = ParagraphBlock | HeadingBlock | BulletListItemBlock | NumberedListItemBlock;
|
|
22
|
+
export type BlockIdentifier = string | Block;
|
|
22
23
|
/** Define "Partial Blocks", these are for updating or creating blocks */
|
|
23
24
|
export type PartialBlockTemplate<B extends Block> = B extends Block ? Partial<Omit<B, "props" | "children" | "content" | "type">> & {
|
|
24
|
-
type
|
|
25
|
+
type?: B["type"];
|
|
25
26
|
props?: Partial<B["props"]>;
|
|
26
|
-
content?: string |
|
|
27
|
+
content?: string | PartialInlineContent[];
|
|
27
28
|
children?: PartialBlock[];
|
|
28
29
|
} : never;
|
|
29
30
|
export type PartialBlock = PartialBlockTemplate<Block>;
|
|
@@ -32,5 +33,5 @@ export type BlockPropsTemplate<Props> = Props extends Block["props"] ? keyof Pro
|
|
|
32
33
|
* Expose blockProps. This is currently not very nice, but it's expected this
|
|
33
34
|
* will change anyway once we allow for custom blocks
|
|
34
35
|
*/
|
|
35
|
-
export declare const globalProps: Array<keyof
|
|
36
|
+
export declare const globalProps: Array<keyof DefaultBlockProps>;
|
|
36
37
|
export declare const blockProps: Record<Block["type"], Set<string>>;
|
|
@@ -1,23 +1,29 @@
|
|
|
1
|
-
export type
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export type Styles = {
|
|
2
|
+
bold?: true;
|
|
3
|
+
italic?: true;
|
|
4
|
+
underline?: true;
|
|
5
|
+
strike?: true;
|
|
6
|
+
textColor?: string;
|
|
7
|
+
backgroundColor?: string;
|
|
4
8
|
};
|
|
5
|
-
export type
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export type
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}>;
|
|
12
|
-
export type BackgroundColor = StyleTemplate<"backgroundColor", {
|
|
13
|
-
color: string;
|
|
14
|
-
}>;
|
|
15
|
-
export type Link = StyleTemplate<"link", {
|
|
16
|
-
href: string;
|
|
17
|
-
}>;
|
|
18
|
-
export type Style = Bold | Italic | Underline | Strikethrough | TextColor | BackgroundColor | Link;
|
|
9
|
+
export type ToggledStyles = {
|
|
10
|
+
[K in keyof Styles]-?: Required<Styles>[K] extends true ? K : never;
|
|
11
|
+
}[keyof Styles];
|
|
12
|
+
export type ColorStyles = {
|
|
13
|
+
[K in keyof Styles]-?: Required<Styles>[K] extends string ? K : never;
|
|
14
|
+
}[keyof Styles];
|
|
19
15
|
export type StyledText = {
|
|
16
|
+
type: "text";
|
|
20
17
|
text: string;
|
|
21
|
-
styles:
|
|
18
|
+
styles: Styles;
|
|
19
|
+
};
|
|
20
|
+
export type Link = {
|
|
21
|
+
type: "link";
|
|
22
|
+
href: string;
|
|
23
|
+
content: StyledText[];
|
|
24
|
+
};
|
|
25
|
+
export type PartialLink = Omit<Link, "content"> & {
|
|
26
|
+
content: string | Link["content"];
|
|
22
27
|
};
|
|
23
|
-
export type InlineContent = StyledText;
|
|
28
|
+
export type InlineContent = StyledText | Link;
|
|
29
|
+
export type PartialInlineContent = StyledText | PartialLink;
|
|
@@ -24,6 +24,21 @@ export declare class BlockMenuView {
|
|
|
24
24
|
menuOpen: boolean;
|
|
25
25
|
menuFrozen: boolean;
|
|
26
26
|
constructor({ editor, blockMenuFactory, horizontalPosAnchoredAtRoot, }: BlockMenuViewProps);
|
|
27
|
+
/**
|
|
28
|
+
* If the event is outside of the editor contents,
|
|
29
|
+
* we dispatch a fake event, so that we can still drop the content
|
|
30
|
+
* when dragging / dropping to the side of the editor
|
|
31
|
+
*/
|
|
32
|
+
onDrop: (event: DragEvent) => void;
|
|
33
|
+
/**
|
|
34
|
+
* If the event is outside of the editor contents,
|
|
35
|
+
* we dispatch a fake event, so that we can still drop the content
|
|
36
|
+
* when dragging / dropping to the side of the editor
|
|
37
|
+
*/
|
|
38
|
+
onDragOver: (event: DragEvent) => void;
|
|
39
|
+
onKeyDown: (_event: KeyboardEvent) => void;
|
|
40
|
+
onMouseDown: (event: MouseEvent) => void;
|
|
41
|
+
onMouseMove: (event: MouseEvent) => void;
|
|
27
42
|
destroy(): void;
|
|
28
43
|
addBlock(): void;
|
|
29
44
|
deleteBlock(): void;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export declare type EditorElement<ElementParams extends Record<string, any>> = {
|
|
2
|
-
element: HTMLElement | undefined;
|
|
3
|
-
show: (params: ElementParams) => void;
|
|
4
|
-
hide: () => void;
|
|
5
|
-
update: (params: ElementParams) => void;
|
|
6
|
-
};
|
|
7
|
-
export declare type ElementFactory<ElementParams extends Record<string, any>> = (params: ElementParams) => EditorElement<ElementParams>;
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { Node } from "prosemirror-model";
|
|
2
|
-
import { EditorState } from "prosemirror-state";
|
|
3
|
-
import { Block, Document } from "../extensions/Blocks/apiTypes";
|
|
4
|
-
export declare function BlockFromPMNode(node: Node): Block;
|
|
5
|
-
export declare function DocumentFromPMState(_state: EditorState): Document;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { Parent as HASTParent } from "hast";
|
|
2
|
-
/**
|
|
3
|
-
* Rehype plugin which removes <u> tags. Used to remove underlines before converting HTML to markdown, as Markdown
|
|
4
|
-
* doesn't support underlines.
|
|
5
|
-
*/
|
|
6
|
-
export declare function removeUnderlines(): (tree: HASTParent) => void;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { Parent as HASTParent } from "hast";
|
|
2
|
-
type SimplifyBlocksOptions = {
|
|
3
|
-
orderedListItemBlockTypes: Set<string>;
|
|
4
|
-
unorderedListItemBlockTypes: Set<string>;
|
|
5
|
-
};
|
|
6
|
-
/**
|
|
7
|
-
* Rehype plugin which converts the HTML output string rendered by BlockNote into a simplified structure which better
|
|
8
|
-
* follows HTML standards. It does several things:
|
|
9
|
-
* - Removes all block related div elements, leaving only the actual content inside the block.
|
|
10
|
-
* - Lifts nested blocks to a higher level for all block types that don't represent list items.
|
|
11
|
-
* - Wraps blocks which represent list items in corresponding ul/ol HTML elements and restructures them to comply
|
|
12
|
-
* with HTML list structure.
|
|
13
|
-
* @param options Options for specifying which block types represent ordered and unordered list items.
|
|
14
|
-
*/
|
|
15
|
-
export declare function simplifyBlocks(options: SimplifyBlocksOptions): (tree: HASTParent) => void;
|
|
16
|
-
export {};
|