|
@@ -1,15 +1,26 @@
|
|
-import { BaseEditor, BaseSelection, Descendant } from "slate";
|
|
|
|
|
|
+import { BaseEditor, BaseSelection, Descendant, Editor, Transforms } from "slate";
|
|
import { TreeNode } from '$app/block_editor/view/tree_node';
|
|
import { TreeNode } from '$app/block_editor/view/tree_node';
|
|
import { Operation } from "$app/block_editor/core/operation";
|
|
import { Operation } from "$app/block_editor/core/operation";
|
|
import { TextBlockSelectionManager } from './text_selection';
|
|
import { TextBlockSelectionManager } from './text_selection';
|
|
import { BlockType } from "@/appflowy_app/interfaces";
|
|
import { BlockType } from "@/appflowy_app/interfaces";
|
|
|
|
+import { ReactEditor } from "slate-react";
|
|
|
|
|
|
export class TextBlockManager {
|
|
export class TextBlockManager {
|
|
public selectionManager: TextBlockSelectionManager;
|
|
public selectionManager: TextBlockSelectionManager;
|
|
|
|
+ private editorMap: Map<string, BaseEditor & ReactEditor> = new Map();
|
|
|
|
+
|
|
constructor(private rootId: string, private operation: Operation) {
|
|
constructor(private rootId: string, private operation: Operation) {
|
|
this.selectionManager = new TextBlockSelectionManager();
|
|
this.selectionManager = new TextBlockSelectionManager();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ register(id: string, editor: BaseEditor & ReactEditor) {
|
|
|
|
+ this.editorMap.set(id, editor);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ unregister(id: string) {
|
|
|
|
+ this.editorMap.delete(id);
|
|
|
|
+ }
|
|
|
|
+
|
|
setSelection(node: TreeNode, selection: BaseSelection) {
|
|
setSelection(node: TreeNode, selection: BaseSelection) {
|
|
// console.log(node.id, selection);
|
|
// console.log(node.id, selection);
|
|
this.selectionManager.setSelection(node.id, selection)
|
|
this.selectionManager.setSelection(node.id, selection)
|
|
@@ -22,19 +33,41 @@ export class TextBlockManager {
|
|
deleteNode(node: TreeNode) {
|
|
deleteNode(node: TreeNode) {
|
|
if (node.type !== BlockType.TextBlock) {
|
|
if (node.type !== BlockType.TextBlock) {
|
|
this.operation.updateNode(node.id, ['type'], BlockType.TextBlock);
|
|
this.operation.updateNode(node.id, ['type'], BlockType.TextBlock);
|
|
|
|
+ this.operation.updateNode(node.id, ['data'], { content: node.data.content });
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- if (node.parent!.id !== this.rootId) {
|
|
|
|
|
|
+
|
|
|
|
+ if (!node.block.next && node.parent!.id !== this.rootId) {
|
|
const newParent = node.parent!.parent!;
|
|
const newParent = node.parent!.parent!;
|
|
const newPrev = node.parent;
|
|
const newPrev = node.parent;
|
|
this.operation.moveNode(node.id, newParent.id, newPrev?.id || '');
|
|
this.operation.moveNode(node.id, newParent.id, newPrev?.id || '');
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
if (!node.prevLine) return;
|
|
if (!node.prevLine) return;
|
|
|
|
+
|
|
|
|
+ const retainData = node.prevLine.data.content;
|
|
|
|
+ const editor = this.editorMap.get(node.prevLine.id);
|
|
|
|
+ if (editor) {
|
|
|
|
+ const index = retainData.length - 1;
|
|
|
|
+ const anchor = {
|
|
|
|
+ path: [0, index],
|
|
|
|
+ offset: retainData[index].text.length,
|
|
|
|
+ };
|
|
|
|
+ const selection = {
|
|
|
|
+ anchor,
|
|
|
|
+ focus: {...anchor}
|
|
|
|
+ };
|
|
|
|
+ ReactEditor.focus(editor);
|
|
|
|
+ Transforms.select(editor, selection);
|
|
|
|
+ }
|
|
|
|
+
|
|
this.operation.updateNode(node.prevLine.id, ['data', 'content'], [
|
|
this.operation.updateNode(node.prevLine.id, ['data', 'content'], [
|
|
- ...node.prevLine.data.content,
|
|
|
|
|
|
+ ...retainData,
|
|
...node.data.content,
|
|
...node.data.content,
|
|
]);
|
|
]);
|
|
|
|
+
|
|
this.operation.deleteNode(node.id);
|
|
this.operation.deleteNode(node.id);
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
splitNode(node: TreeNode, editor: BaseEditor) {
|
|
splitNode(node: TreeNode, editor: BaseEditor) {
|