From 6e641592a5382bf07417e1521c4dd52bf0269f30 Mon Sep 17 00:00:00 2001 From: Bassea Date: Mon, 6 Nov 2023 16:22:00 +0100 Subject: [PATCH 1/5] Added editor option to disable nested block --- packages/core/src/BlockNoteEditor.ts | 6 ++++++ .../core/src/extensions/Blocks/nodes/BlockContainer.ts | 8 ++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/core/src/BlockNoteEditor.ts b/packages/core/src/BlockNoteEditor.ts index 84ddb8d74..76af2c681 100644 --- a/packages/core/src/BlockNoteEditor.ts +++ b/packages/core/src/BlockNoteEditor.ts @@ -91,6 +91,10 @@ export type BlockNoteEditorOptions = { * Locks the editor from being editable by the user if set to `false`. */ editable: boolean; + /** + * Disables block nesting by the user if set to `false`. + */ + canNestBlock: boolean; /** * The content that should be in the editor when it's created, represented as an array of partial block objects. */ @@ -283,6 +287,8 @@ export class BlockNoteEditor { newOptions.onTextCursorPositionChange?.(this); }, + canNestBlock: + options.canNestBlock !== undefined ? options.canNestBlock : true, editable: options.editable !== undefined ? options.editable diff --git a/packages/core/src/extensions/Blocks/nodes/BlockContainer.ts b/packages/core/src/extensions/Blocks/nodes/BlockContainer.ts index 2265668ed..4385b5322 100644 --- a/packages/core/src/extensions/Blocks/nodes/BlockContainer.ts +++ b/packages/core/src/extensions/Blocks/nodes/BlockContainer.ts @@ -621,11 +621,15 @@ export const BlockContainer = Node.create<{ // Always returning true for tab key presses ensures they're not captured by the browser. Otherwise, they blur the // editor since the browser will try to use tab for keyboard navigation. Tab: () => { - this.editor.commands.sinkListItem("blockContainer"); + if (this.editor.options.canNestBlock) { + this.editor.commands.sinkListItem("blockContainer"); + } return true; }, "Shift-Tab": () => { - this.editor.commands.liftListItem("blockContainer"); + if (!this.editor.options.canNestBlock) { + this.editor.commands.liftListItem("blockContainer"); + } return true; }, "Mod-Alt-0": () => From d700bc01b98cf7402468d81e4e09f4ef94084494 Mon Sep 17 00:00:00 2001 From: Wiebke Vogel <54707973+wiebkevogel@users.noreply.github.com> Date: Tue, 14 Nov 2023 16:20:09 +0100 Subject: [PATCH 2/5] Added property to enable/disable nested blocks in Blocknote --- packages/core/src/BlockNoteEditor.ts | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/core/src/BlockNoteEditor.ts b/packages/core/src/BlockNoteEditor.ts index 76af2c681..d0c104aad 100644 --- a/packages/core/src/BlockNoteEditor.ts +++ b/packages/core/src/BlockNoteEditor.ts @@ -94,7 +94,7 @@ export type BlockNoteEditorOptions = { /** * Disables block nesting by the user if set to `false`. */ - canNestBlock: boolean; + enableNestedBlocks: boolean; /** * The content that should be in the editor when it's created, represented as an array of partial block objects. */ @@ -287,14 +287,16 @@ export class BlockNoteEditor { newOptions.onTextCursorPositionChange?.(this); }, - canNestBlock: - options.canNestBlock !== undefined ? options.canNestBlock : true, editable: options.editable !== undefined ? options.editable : newOptions._tiptapOptions?.editable !== undefined ? newOptions._tiptapOptions?.editable : true, + enableNestedBlocks: + options.enableNestedBlocks !== undefined + ? options.enableNestedBlocks + : true, extensions: newOptions.enableBlockNoteExtensions === false ? newOptions._tiptapOptions?.extensions || [] @@ -761,6 +763,13 @@ export class BlockNoteEditor { * Checks if the block containing the text cursor can be nested. */ public canNestBlock() { + if ( + typeof this._tiptapEditor.options.enableNestedBlocks === "boolean" && + !this._tiptapEditor.options.enableNestedBlocks + ) { + return false; + } + const { startPos, depth } = getBlockInfoFromPos( this._tiptapEditor.state.doc, this._tiptapEditor.state.selection.from @@ -780,6 +789,13 @@ export class BlockNoteEditor { * Checks if the block containing the text cursor is nested. */ public canUnnestBlock() { + if ( + typeof this._tiptapEditor.options.enableNestedBlocks === "boolean" && + !this._tiptapEditor.options.enableNestedBlocks + ) { + return false; + } + const { depth } = getBlockInfoFromPos( this._tiptapEditor.state.doc, this._tiptapEditor.state.selection.from From c61b253ba3b0d6cfd1cd47840c098bd6a58b85ee Mon Sep 17 00:00:00 2001 From: Wiebke Vogel <54707973+wiebkevogel@users.noreply.github.com> Date: Tue, 14 Nov 2023 16:22:59 +0100 Subject: [PATCH 3/5] Added property to enable/disable nested blocks to BlockContainer --- .../extensions/Blocks/nodes/BlockContainer.ts | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/packages/core/src/extensions/Blocks/nodes/BlockContainer.ts b/packages/core/src/extensions/Blocks/nodes/BlockContainer.ts index 4385b5322..9ab13e573 100644 --- a/packages/core/src/extensions/Blocks/nodes/BlockContainer.ts +++ b/packages/core/src/extensions/Blocks/nodes/BlockContainer.ts @@ -46,7 +46,16 @@ export const BlockContainer = Node.create<{ name: "blockContainer", group: "blockContainer", // A block always contains content, and optionally a blockGroup which contains nested blocks - content: "blockContent blockGroup?", + content() { + if ( + typeof this.editor?.options.enableNestedBlocks === "boolean" && + !this.editor?.options.enableNestedBlocks + ) { + return "blockContent"; + } + + return "blockContent blockGroup?"; + }, // Ensures content-specific keyboard handlers trigger first. priority: 50, defining: true, @@ -621,15 +630,25 @@ export const BlockContainer = Node.create<{ // Always returning true for tab key presses ensures they're not captured by the browser. Otherwise, they blur the // editor since the browser will try to use tab for keyboard navigation. Tab: () => { - if (this.editor.options.canNestBlock) { - this.editor.commands.sinkListItem("blockContainer"); + if ( + typeof this.editor.options.enableNestedBlocks === "boolean" && + !this.editor.options.enableNestedBlocks + ) { + return false; } + + this.editor.commands.sinkListItem("blockContainer"); return true; }, "Shift-Tab": () => { - if (!this.editor.options.canNestBlock) { - this.editor.commands.liftListItem("blockContainer"); + if ( + typeof this.editor.options.enableNestedBlocks === "boolean" && + !this.editor.options.enableNestedBlocks + ) { + return false; } + + this.editor.commands.liftListItem("blockContainer"); return true; }, "Mod-Alt-0": () => From 39e4a5da47264d9fad82a73a907e16623a2bef88 Mon Sep 17 00:00:00 2001 From: Bassea Date: Tue, 14 Nov 2023 16:47:53 +0100 Subject: [PATCH 4/5] Handle return value --- .../core/src/extensions/Blocks/nodes/BlockContainer.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/core/src/extensions/Blocks/nodes/BlockContainer.ts b/packages/core/src/extensions/Blocks/nodes/BlockContainer.ts index 9ab13e573..e8a3f9681 100644 --- a/packages/core/src/extensions/Blocks/nodes/BlockContainer.ts +++ b/packages/core/src/extensions/Blocks/nodes/BlockContainer.ts @@ -632,23 +632,21 @@ export const BlockContainer = Node.create<{ Tab: () => { if ( typeof this.editor.options.enableNestedBlocks === "boolean" && - !this.editor.options.enableNestedBlocks + this.editor.options.enableNestedBlocks ) { - return false; + this.editor.commands.sinkListItem("blockContainer"); } - this.editor.commands.sinkListItem("blockContainer"); return true; }, "Shift-Tab": () => { if ( typeof this.editor.options.enableNestedBlocks === "boolean" && - !this.editor.options.enableNestedBlocks + this.editor.options.enableNestedBlocks ) { - return false; + this.editor.commands.liftListItem("blockContainer"); } - this.editor.commands.liftListItem("blockContainer"); return true; }, "Mod-Alt-0": () => From 62c9491e6130bfec2d58cef22b43b1bb9b032401 Mon Sep 17 00:00:00 2001 From: Wiebke Vogel Date: Wed, 15 Nov 2023 09:04:21 +0100 Subject: [PATCH 5/5] Move enableNestedBlock property from tiptap to editor options --- packages/core/src/BlockNoteEditor.ts | 19 +++++++------------ packages/core/src/BlockNoteExtensions.ts | 1 + .../extensions/Blocks/nodes/BlockContainer.ts | 16 ++++------------ 3 files changed, 12 insertions(+), 24 deletions(-) diff --git a/packages/core/src/BlockNoteEditor.ts b/packages/core/src/BlockNoteEditor.ts index d0c104aad..d059a5cbe 100644 --- a/packages/core/src/BlockNoteEditor.ts +++ b/packages/core/src/BlockNoteEditor.ts @@ -158,6 +158,7 @@ export class BlockNoteEditor { public blockCache = new WeakMap>(); public readonly schema: BSchema; public ready = false; + public enableNestedBlocks = true; public readonly sideMenu: SideMenuProsemirrorPlugin; public readonly formattingToolbar: FormattingToolbarProsemirrorPlugin; @@ -194,6 +195,10 @@ export class BlockNoteEditor { ); this.hyperlinkToolbar = new HyperlinkToolbarProsemirrorPlugin(this); this.imageToolbar = new ImageToolbarProsemirrorPlugin(this); + this.enableNestedBlocks = + options.enableNestedBlocks !== undefined + ? options.enableNestedBlocks + : true; const extensions = getBlockNoteExtensions({ editor: this, @@ -293,10 +298,6 @@ export class BlockNoteEditor { : newOptions._tiptapOptions?.editable !== undefined ? newOptions._tiptapOptions?.editable : true, - enableNestedBlocks: - options.enableNestedBlocks !== undefined - ? options.enableNestedBlocks - : true, extensions: newOptions.enableBlockNoteExtensions === false ? newOptions._tiptapOptions?.extensions || [] @@ -763,10 +764,7 @@ export class BlockNoteEditor { * Checks if the block containing the text cursor can be nested. */ public canNestBlock() { - if ( - typeof this._tiptapEditor.options.enableNestedBlocks === "boolean" && - !this._tiptapEditor.options.enableNestedBlocks - ) { + if (!this.enableNestedBlocks) { return false; } @@ -789,10 +787,7 @@ export class BlockNoteEditor { * Checks if the block containing the text cursor is nested. */ public canUnnestBlock() { - if ( - typeof this._tiptapEditor.options.enableNestedBlocks === "boolean" && - !this._tiptapEditor.options.enableNestedBlocks - ) { + if (!this.enableNestedBlocks) { return false; } diff --git a/packages/core/src/BlockNoteExtensions.ts b/packages/core/src/BlockNoteExtensions.ts index d328c329b..c2d93f746 100644 --- a/packages/core/src/BlockNoteExtensions.ts +++ b/packages/core/src/BlockNoteExtensions.ts @@ -94,6 +94,7 @@ export const getBlockNoteExtensions = (opts: { Doc, BlockContainer.configure({ domAttributes: opts.domAttributes, + enableNestedBlocks: opts.editor.enableNestedBlocks, }), BlockGroup.configure({ domAttributes: opts.domAttributes, diff --git a/packages/core/src/extensions/Blocks/nodes/BlockContainer.ts b/packages/core/src/extensions/Blocks/nodes/BlockContainer.ts index e8a3f9681..080fba6df 100644 --- a/packages/core/src/extensions/Blocks/nodes/BlockContainer.ts +++ b/packages/core/src/extensions/Blocks/nodes/BlockContainer.ts @@ -42,15 +42,13 @@ declare module "@tiptap/core" { */ export const BlockContainer = Node.create<{ domAttributes?: BlockNoteDOMAttributes; + enableNestedBlocks?: boolean; }>({ name: "blockContainer", group: "blockContainer", // A block always contains content, and optionally a blockGroup which contains nested blocks content() { - if ( - typeof this.editor?.options.enableNestedBlocks === "boolean" && - !this.editor?.options.enableNestedBlocks - ) { + if (!this.options.enableNestedBlocks) { return "blockContent"; } @@ -630,20 +628,14 @@ export const BlockContainer = Node.create<{ // Always returning true for tab key presses ensures they're not captured by the browser. Otherwise, they blur the // editor since the browser will try to use tab for keyboard navigation. Tab: () => { - if ( - typeof this.editor.options.enableNestedBlocks === "boolean" && - this.editor.options.enableNestedBlocks - ) { + if (this.options.enableNestedBlocks) { this.editor.commands.sinkListItem("blockContainer"); } return true; }, "Shift-Tab": () => { - if ( - typeof this.editor.options.enableNestedBlocks === "boolean" && - this.editor.options.enableNestedBlocks - ) { + if (this.options.enableNestedBlocks) { this.editor.commands.liftListItem("blockContainer"); }