From 5370c46dd17c99275b0888f840d62e6da41e842d Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 31 Aug 2024 05:04:24 +0300 Subject: [PATCH] feat(block-tool-adapter): split (#94) * simple split * unhardcode paragraph * lint fix --- packages/core/src/components/BlockManager.ts | 10 +++- packages/core/src/ui/Toolbox/index.ts | 1 + packages/dom-adapters/.eslintrc.yml | 2 + .../src/BlockToolAdapter/index.ts | 52 ++++++++++++++++++- 4 files changed, 63 insertions(+), 2 deletions(-) diff --git a/packages/core/src/components/BlockManager.ts b/packages/core/src/components/BlockManager.ts index cc668dc7..260972ac 100644 --- a/packages/core/src/components/BlockManager.ts +++ b/packages/core/src/components/BlockManager.ts @@ -159,7 +159,15 @@ export class BlocksManager { throw new Error('[BlockManager] Block index should be defined. Probably something wrong with the Editor Model. Please, report this issue'); } - const blockToolAdapter = new BlockToolAdapter(this.#model, this.#caretAdapter, index.blockIndex, this.#formattingAdapter); + const toolName = event.detail.data.name; + + const blockToolAdapter = new BlockToolAdapter( + this.#model, + this.#caretAdapter, + index.blockIndex, + this.#formattingAdapter, + toolName + ); const tool = this.#toolsManager.blockTools.get(data.name); diff --git a/packages/core/src/ui/Toolbox/index.ts b/packages/core/src/ui/Toolbox/index.ts index 14802565..acfff94e 100644 --- a/packages/core/src/ui/Toolbox/index.ts +++ b/packages/core/src/ui/Toolbox/index.ts @@ -62,6 +62,7 @@ export class ToolboxUI { this.#nodes.holder = make('div'); this.#nodes.holder.style.display = 'flex'; + this.#nodes.holder.style.marginBottom = '10px'; this.#eventBus.dispatchEvent(new ToolboxRenderedUIEvent({ toolbox: this.#nodes.holder, diff --git a/packages/dom-adapters/.eslintrc.yml b/packages/dom-adapters/.eslintrc.yml index 0b55b726..5ad199a0 100644 --- a/packages/dom-adapters/.eslintrc.yml +++ b/packages/dom-adapters/.eslintrc.yml @@ -18,6 +18,8 @@ rules: - always '@typescript-eslint/no-unsafe-declaration-merging': - 0 +env: + browser: true overrides: - files: diff --git a/packages/dom-adapters/src/BlockToolAdapter/index.ts b/packages/dom-adapters/src/BlockToolAdapter/index.ts index 2222c06d..40b1c0bf 100644 --- a/packages/dom-adapters/src/BlockToolAdapter/index.ts +++ b/packages/dom-adapters/src/BlockToolAdapter/index.ts @@ -49,6 +49,11 @@ export class BlockToolAdapter implements BlockToolAdapterInterface { */ #formattingAdapter: FormattingAdapter; + /** + * Name of the tool that this adapter is connected to + */ + #toolName: string; + /** * BlockToolAdapter constructor * @@ -56,12 +61,14 @@ export class BlockToolAdapter implements BlockToolAdapterInterface { * @param caretAdapter - CaretAdapter instance * @param blockIndex - index of the block that this adapter is connected to * @param formattingAdapter - needed to render formatted text + * @param toolName - tool name of the block */ - constructor(model: EditorJSModel, caretAdapter: CaretAdapter, blockIndex: number, formattingAdapter: FormattingAdapter) { + constructor(model: EditorJSModel, caretAdapter: CaretAdapter, blockIndex: number, formattingAdapter: FormattingAdapter, toolName: string) { this.#model = model; this.#blockIndex = blockIndex; this.#caretAdapter = caretAdapter; this.#formattingAdapter = formattingAdapter; + this.#toolName = toolName; } /** @@ -309,6 +316,9 @@ export class BlockToolAdapter implements BlockToolAdapterInterface { break; } + case InputType.InsertParagraph: + this.#handleSplit(key, start, end); + break; case InputType.InsertLineBreak: /** * @todo Think if we need to keep that or not @@ -316,10 +326,50 @@ export class BlockToolAdapter implements BlockToolAdapterInterface { if (isInputNative === true) { this.#model.insertText(this.#blockIndex, key, '\n', start); } + break; default: } }; + /** + * Splits the current block's data field at the specified index + * Removes selected range if it's not collapsed + * Sets caret to the beginning of the next block + * + * @param key - data key to split + * @param start - start index of the split + * @param end - end index of the selected range + */ + #handleSplit(key: DataKey, start: number, end: number): void { + const currentValue = this.#model.getText(this.#blockIndex, key); + const newValueAfter = currentValue.slice(end); + + this.#model.removeText(this.#blockIndex, key, start, currentValue.length); + this.#model.addBlock({ + name: this.#toolName, + data : { + [key]: { + $t: 't', + value: newValueAfter, + fragments: [], + }, + }, + }, this.#blockIndex + 1); + + /** + * Raf is needed to ensure that the new block is added so caret can be moved to it + */ + requestAnimationFrame(() => { + this.#caretAdapter.updateIndex( + new IndexBuilder() + .addBlockIndex(this.#blockIndex + 1) + .addDataKey(key) + .addTextRange([0, 0]) + .build() + ); + }); + } + /** * Handles model update events for native inputs and updates DOM *