mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-12 15:46:29 +08:00
Merge pull request #265 from toeverything/fix/text-with-root-id
Fix/text with root id
This commit is contained in:
@@ -2,13 +2,11 @@ import { useState } from 'react';
|
||||
|
||||
import { CustomText, TextProps } from '@toeverything/components/common';
|
||||
import {
|
||||
mergeGroup,
|
||||
BlockPendantProvider,
|
||||
RenderBlockChildren,
|
||||
splitGroup,
|
||||
supportChildren,
|
||||
unwrapGroup,
|
||||
useOnSelect,
|
||||
BlockPendantProvider,
|
||||
} from '@toeverything/components/editor-core';
|
||||
import { styled } from '@toeverything/components/ui';
|
||||
import { Protocol } from '@toeverything/datasource/db-service';
|
||||
@@ -69,24 +67,36 @@ export const TextView = ({
|
||||
const { contentBeforeSelection, contentAfterSelection } = splitContents;
|
||||
const before = [...contentBeforeSelection.content];
|
||||
const after = [...contentAfterSelection.content];
|
||||
const _nextBlockChildren = await block.children();
|
||||
const _nextBlock = await editor.createBlock('text');
|
||||
await _nextBlock.setProperty('text', {
|
||||
const nextBlockChildren = await block.children();
|
||||
const nextBlock = await editor.createBlock('text');
|
||||
if (!nextBlock) {
|
||||
throw new Error('Failed to create text block');
|
||||
}
|
||||
await nextBlock.setProperty('text', {
|
||||
value: after as CustomText[],
|
||||
});
|
||||
_nextBlock.append(..._nextBlockChildren);
|
||||
block.removeChildren();
|
||||
await block.setProperty('text', {
|
||||
value: before as CustomText[],
|
||||
});
|
||||
await block.after(_nextBlock);
|
||||
|
||||
editor.selectionManager.activeNodeByNodeId(_nextBlock.id);
|
||||
if (editor.getRootBlockId() === block.id) {
|
||||
// If the block is the root block,
|
||||
// new block can not append as next sibling,
|
||||
// all new blocks should be append as children.
|
||||
await block.insert(0, [nextBlock]);
|
||||
editor.selectionManager.activeNodeByNodeId(nextBlock.id);
|
||||
return true;
|
||||
}
|
||||
await nextBlock.append(...nextBlockChildren);
|
||||
await block.removeChildren();
|
||||
await block.after(nextBlock);
|
||||
|
||||
editor.selectionManager.activeNodeByNodeId(nextBlock.id);
|
||||
return true;
|
||||
};
|
||||
|
||||
const onBackspace: TextProps['handleBackSpace'] = async props => {
|
||||
return await editor.withSuspend(async () => {
|
||||
const onBackspace: TextProps['handleBackSpace'] = editor.withBatch(
|
||||
async props => {
|
||||
const { isCollAndStart } = props;
|
||||
if (!isCollAndStart) {
|
||||
return false;
|
||||
@@ -95,20 +105,27 @@ export const TextView = ({
|
||||
await block.setType('text');
|
||||
return true;
|
||||
}
|
||||
if (editor.getRootBlockId() === block.id) {
|
||||
// Can not delete
|
||||
return false;
|
||||
}
|
||||
const parentBlock = await block.parent();
|
||||
|
||||
if (!parentBlock) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const preParent = await parentBlock.previousSibling();
|
||||
if (Protocol.Block.Type.group === parentBlock.type) {
|
||||
if (
|
||||
Protocol.Block.Type.group === parentBlock.type ||
|
||||
editor.getRootBlockId() === parentBlock.id
|
||||
) {
|
||||
const children = await block.children();
|
||||
const preNode = await block.physicallyPerviousSibling();
|
||||
// FIXME support children do not means has textBlock
|
||||
// TODO: abstract this part of code
|
||||
if (preNode) {
|
||||
if (supportChildren(preNode)) {
|
||||
editor.suspend(true);
|
||||
await editor.selectionManager.activePreviousNode(
|
||||
block.id,
|
||||
'end'
|
||||
@@ -127,7 +144,6 @@ export const TextView = ({
|
||||
}
|
||||
await preNode.append(...children);
|
||||
await block.remove();
|
||||
editor.suspend(false);
|
||||
} else {
|
||||
// TODO: point does not clear
|
||||
await editor.selectionManager.activePreviousNode(
|
||||
@@ -194,8 +210,9 @@ export const TextView = ({
|
||||
);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
const handleConvert = async (
|
||||
toType: string,
|
||||
options?: Record<string, unknown>
|
||||
|
||||
@@ -2,40 +2,40 @@
|
||||
import HotKeys from 'hotkeys-js';
|
||||
import LRUCache from 'lru-cache';
|
||||
|
||||
import { services } from '@toeverything/datasource/db-service';
|
||||
import type { PatchNode } from '@toeverything/components/ui';
|
||||
import type {
|
||||
BlockFlavors,
|
||||
ReturnEditorBlock,
|
||||
UpdateEditorBlock,
|
||||
} from '@toeverything/datasource/db-service';
|
||||
import type { PatchNode } from '@toeverything/components/ui';
|
||||
import { services } from '@toeverything/datasource/db-service';
|
||||
|
||||
import { AsyncBlock } from './block';
|
||||
import type { WorkspaceAndBlockId } from './block';
|
||||
import type { BaseView } from './views/base-view';
|
||||
import { SelectionManager } from './selection';
|
||||
import { Hooks, PluginManager } from './plugin';
|
||||
import { EditorCommands } from './commands';
|
||||
import {
|
||||
Virgo,
|
||||
HooksRunner,
|
||||
PluginHooks,
|
||||
PluginCreator,
|
||||
StorageManager,
|
||||
VirgoSelection,
|
||||
PluginManagerInterface,
|
||||
} from './types';
|
||||
import { KeyboardManager } from './keyboard';
|
||||
import { MouseManager } from './mouse';
|
||||
import { ScrollManager } from './scroll';
|
||||
import assert from 'assert';
|
||||
import { domToRect, last, Point, sleep } from '@toeverything/utils';
|
||||
import { Commands } from '@toeverything/datasource/commands';
|
||||
import { domToRect, last, Point, sleep } from '@toeverything/utils';
|
||||
import assert from 'assert';
|
||||
import type { WorkspaceAndBlockId } from './block';
|
||||
import { AsyncBlock } from './block';
|
||||
import { BlockHelper } from './block/block-helper';
|
||||
import { BrowserClipboard } from './clipboard/browser-clipboard';
|
||||
import { ClipboardPopulator } from './clipboard/clipboard-populator';
|
||||
import { BlockHelper } from './block/block-helper';
|
||||
import { DragDropManager } from './drag-drop';
|
||||
import { EditorCommands } from './commands';
|
||||
import { EditorConfig } from './config';
|
||||
import { DragDropManager } from './drag-drop';
|
||||
import { KeyboardManager } from './keyboard';
|
||||
import { MouseManager } from './mouse';
|
||||
import { Hooks, PluginManager } from './plugin';
|
||||
import { ScrollManager } from './scroll';
|
||||
import { SelectionManager } from './selection';
|
||||
import {
|
||||
HooksRunner,
|
||||
PluginCreator,
|
||||
PluginHooks,
|
||||
PluginManagerInterface,
|
||||
StorageManager,
|
||||
Virgo,
|
||||
VirgoSelection,
|
||||
} from './types';
|
||||
import type { BaseView } from './views/base-view';
|
||||
|
||||
export interface EditorCtorProps {
|
||||
workspace: string;
|
||||
@@ -148,18 +148,41 @@ export class Editor implements Virgo {
|
||||
public get container() {
|
||||
return this.ui_container;
|
||||
}
|
||||
// preference to use withSuspend
|
||||
|
||||
/**
|
||||
* Use it discreetly.
|
||||
* Preference to use {@link withBatch}
|
||||
*/
|
||||
public suspend(flag: boolean) {
|
||||
services.api.editorBlock.suspend(this.workspace, flag);
|
||||
}
|
||||
|
||||
public async withSuspend<T extends (...args: any[]) => any>(
|
||||
// TODO support suspend recursion
|
||||
private _isSuspend = false;
|
||||
public withBatch<T extends (...args: any[]) => Promise<any>>(fn: T): T {
|
||||
return (async (...args) => {
|
||||
if (this._isSuspend) {
|
||||
console.warn(
|
||||
'The editor currently has suspend! Please do not call batch method repeatedly!'
|
||||
);
|
||||
}
|
||||
this._isSuspend = true;
|
||||
services.api.editorBlock.suspend(this.workspace, true);
|
||||
const result = await fn(...args);
|
||||
services.api.editorBlock.suspend(this.workspace, false);
|
||||
this._isSuspend = false;
|
||||
return result;
|
||||
}) as T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use it discreetly.
|
||||
* Preference to use {@link withBatch}
|
||||
*/
|
||||
public async batch<T extends (...args: any[]) => any>(
|
||||
fn: T
|
||||
): Promise<Awaited<ReturnType<T>>> {
|
||||
services.api.editorBlock.suspend(this.workspace, true);
|
||||
const result = await fn();
|
||||
services.api.editorBlock.suspend(this.workspace, false);
|
||||
return result;
|
||||
return this.withBatch(fn)();
|
||||
}
|
||||
|
||||
public setReactRenderRoot(props: {
|
||||
|
||||
Reference in New Issue
Block a user