mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-22 00:37:05 +08:00
chore: merge blocksuite source code (#9213)
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
import { EMBED_BLOCK_FLAVOUR_LIST } from '@blocksuite/affine-shared/consts';
|
||||
import {
|
||||
getNextContentBlock,
|
||||
matchFlavours,
|
||||
} from '@blocksuite/affine-shared/utils';
|
||||
import type { BlockStdScope } from '@blocksuite/block-std';
|
||||
|
||||
export function forwardDelete(std: BlockStdScope) {
|
||||
const { doc, host } = std;
|
||||
const text = std.selection.find('text');
|
||||
if (!text) return;
|
||||
const isCollapsed = text.isCollapsed();
|
||||
const model = doc.getBlock(text.from.blockId)?.model;
|
||||
if (!model || !matchFlavours(model, ['affine:paragraph'])) return;
|
||||
const isEnd = isCollapsed && text.from.index === model.text.length;
|
||||
if (!isEnd) return;
|
||||
const parent = doc.getParent(model);
|
||||
if (!parent) return;
|
||||
|
||||
const nextSibling = doc.getNext(model);
|
||||
const ignoreForwardDeleteFlavourList: BlockSuite.Flavour[] = [
|
||||
'affine:attachment',
|
||||
'affine:bookmark',
|
||||
// @ts-expect-error TODO: should be fixed after database model is migrated to affine-models
|
||||
'affine:database',
|
||||
'affine:code',
|
||||
'affine:image',
|
||||
'affine:divider',
|
||||
...EMBED_BLOCK_FLAVOUR_LIST,
|
||||
];
|
||||
|
||||
if (matchFlavours(nextSibling, ignoreForwardDeleteFlavourList)) {
|
||||
std.selection.setGroup('note', [
|
||||
std.selection.create('block', { blockId: nextSibling.id }),
|
||||
]);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (nextSibling?.text) {
|
||||
model.text.join(nextSibling.text);
|
||||
if (nextSibling.children) {
|
||||
const parent = doc.getParent(nextSibling);
|
||||
if (!parent) return false;
|
||||
doc.moveBlocks(nextSibling.children, parent, model, false);
|
||||
}
|
||||
|
||||
doc.deleteBlock(nextSibling);
|
||||
return true;
|
||||
}
|
||||
|
||||
const nextBlock = getNextContentBlock(host, model);
|
||||
if (nextBlock?.text) {
|
||||
model.text.join(nextBlock.text);
|
||||
if (nextBlock.children) {
|
||||
const parent = doc.getParent(nextBlock);
|
||||
if (!parent) return false;
|
||||
doc.moveBlocks(nextBlock.children, parent, doc.getParent(model), false);
|
||||
}
|
||||
doc.deleteBlock(nextBlock);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (nextBlock) {
|
||||
std.selection.setGroup('note', [
|
||||
std.selection.create('block', { blockId: nextBlock.id }),
|
||||
]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
141
blocksuite/affine/block-paragraph/src/utils/merge-with-prev.ts
Normal file
141
blocksuite/affine/block-paragraph/src/utils/merge-with-prev.ts
Normal file
@@ -0,0 +1,141 @@
|
||||
import {
|
||||
asyncSetInlineRange,
|
||||
focusTextModel,
|
||||
} from '@blocksuite/affine-components/rich-text';
|
||||
import type { RootBlockModel } from '@blocksuite/affine-model';
|
||||
import { EMBED_BLOCK_FLAVOUR_LIST } from '@blocksuite/affine-shared/consts';
|
||||
import type { ExtendedModel } from '@blocksuite/affine-shared/types';
|
||||
import {
|
||||
focusTitle,
|
||||
getDocTitleInlineEditor,
|
||||
getPrevContentBlock,
|
||||
matchFlavours,
|
||||
} from '@blocksuite/affine-shared/utils';
|
||||
import type { EditorHost } from '@blocksuite/block-std';
|
||||
import type { BlockModel, Text } from '@blocksuite/store';
|
||||
|
||||
/**
|
||||
* Merge the paragraph with prev block
|
||||
*
|
||||
* Before press backspace
|
||||
* - line1
|
||||
* - line2
|
||||
* - |aaa
|
||||
* - line3
|
||||
*
|
||||
* After press backspace
|
||||
* - line1
|
||||
* - line2|aaa
|
||||
* - line3
|
||||
*/
|
||||
export function mergeWithPrev(editorHost: EditorHost, model: BlockModel) {
|
||||
const doc = model.doc;
|
||||
const parent = doc.getParent(model);
|
||||
if (!parent) return false;
|
||||
|
||||
if (matchFlavours(parent, ['affine:edgeless-text'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const prevBlock = getPrevContentBlock(editorHost, model);
|
||||
if (!prevBlock) {
|
||||
return handleNoPreviousSibling(editorHost, model);
|
||||
}
|
||||
|
||||
if (matchFlavours(prevBlock, ['affine:paragraph', 'affine:list'])) {
|
||||
const modelIndex = parent.children.indexOf(model);
|
||||
if (
|
||||
(modelIndex === -1 || modelIndex === parent.children.length - 1) &&
|
||||
parent.role === 'content'
|
||||
)
|
||||
return false;
|
||||
|
||||
const lengthBeforeJoin = prevBlock.text?.length ?? 0;
|
||||
prevBlock.text.join(model.text as Text);
|
||||
doc.deleteBlock(model, {
|
||||
bringChildrenTo: parent,
|
||||
});
|
||||
asyncSetInlineRange(editorHost, prevBlock, {
|
||||
index: lengthBeforeJoin,
|
||||
length: 0,
|
||||
}).catch(console.error);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
matchFlavours(prevBlock, [
|
||||
'affine:attachment',
|
||||
'affine:bookmark',
|
||||
'affine:code',
|
||||
'affine:image',
|
||||
'affine:divider',
|
||||
...EMBED_BLOCK_FLAVOUR_LIST,
|
||||
])
|
||||
) {
|
||||
const selection = editorHost.selection.create('block', {
|
||||
blockId: prevBlock.id,
|
||||
});
|
||||
editorHost.selection.setGroup('note', [selection]);
|
||||
|
||||
if (model.text?.length === 0) {
|
||||
doc.deleteBlock(model, {
|
||||
bringChildrenTo: parent,
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// @ts-expect-error TODO: should be fixed after database model is migrated to affine-models
|
||||
if (matchFlavours(parent, ['affine:database'])) {
|
||||
doc.deleteBlock(model);
|
||||
focusTextModel(editorHost.std, prevBlock.id, prevBlock.text?.yText.length);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function handleNoPreviousSibling(editorHost: EditorHost, model: ExtendedModel) {
|
||||
const doc = model.doc;
|
||||
const text = model.text;
|
||||
const parent = doc.getParent(model);
|
||||
if (!parent) return false;
|
||||
const titleEditor = getDocTitleInlineEditor(editorHost);
|
||||
// Probably no title, e.g. in edgeless mode
|
||||
if (!titleEditor) {
|
||||
if (
|
||||
matchFlavours(parent, ['affine:edgeless-text']) ||
|
||||
model.children.length > 0
|
||||
) {
|
||||
doc.deleteBlock(model, {
|
||||
bringChildrenTo: parent,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const rootModel = model.doc.root as RootBlockModel;
|
||||
const title = rootModel.title;
|
||||
|
||||
doc.captureSync();
|
||||
let textLength = 0;
|
||||
if (text) {
|
||||
textLength = text.length;
|
||||
title.join(text);
|
||||
}
|
||||
|
||||
// Preserve at least one block to be able to focus on container click
|
||||
if (doc.getNext(model) || model.children.length > 0) {
|
||||
const parent = doc.getParent(model);
|
||||
if (!parent) return false;
|
||||
doc.deleteBlock(model, {
|
||||
bringChildrenTo: parent,
|
||||
});
|
||||
} else {
|
||||
text?.clear();
|
||||
}
|
||||
focusTitle(editorHost, title.length - textLength);
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user