chore: merge blocksuite source code (#9213)

This commit is contained in:
Mirone
2024-12-20 15:38:06 +08:00
committed by GitHub
parent 2c9ef916f4
commit 30200ff86d
2031 changed files with 238888 additions and 229 deletions
@@ -0,0 +1,41 @@
import type { Command } from '@blocksuite/block-std';
export const clearAndSelectFirstModelCommand: Command<'selectedModels'> = (
ctx,
next
) => {
const models = ctx.selectedModels;
if (!models) {
console.error(
'`selectedModels` is required, you need to use `getSelectedModels` command before adding this command to the pipeline.'
);
return;
}
if (models.length > 0) {
const firstModel = models[0];
if (firstModel.text) {
firstModel.text.clear();
const selection = ctx.std.selection.create('text', {
from: {
blockId: firstModel.id,
index: 0,
length: 0,
},
to: null,
});
ctx.std.selection.setGroup('note', [selection]);
}
}
return next();
};
declare global {
namespace BlockSuite {
interface Commands {
clearAndSelectFirstModel: typeof clearAndSelectFirstModelCommand;
}
}
}
@@ -0,0 +1,36 @@
import type { Command } from '@blocksuite/block-std';
import { Slice } from '@blocksuite/store';
export const copySelectedModelsCommand: Command<'draftedModels' | 'onCopy'> = (
ctx,
next
) => {
const models = ctx.draftedModels;
if (!models) {
console.error(
'`draftedModels` is required, you need to use `draftSelectedModels` command before adding this command to the pipeline.'
);
return;
}
models
.then(models => {
const slice = Slice.fromModels(ctx.std.doc, models);
return ctx.std.clipboard.copy(slice);
})
.then(() => ctx.onCopy?.())
.catch(console.error);
return next();
};
declare global {
namespace BlockSuite {
interface CommandContext {
onCopy?: () => void;
}
interface Commands {
copySelectedModels: typeof copySelectedModelsCommand;
}
}
}
@@ -0,0 +1,29 @@
import type { Command } from '@blocksuite/block-std';
export const deleteSelectedModelsCommand: Command<'selectedModels'> = (
ctx,
next
) => {
const models = ctx.selectedModels;
if (!models) {
console.error(
'`selectedModels` is required, you need to use `getSelectedModels` command before adding this command to the pipeline.'
);
return;
}
models.forEach(model => {
ctx.std.doc.deleteBlock(model);
});
return next();
};
declare global {
namespace BlockSuite {
interface Commands {
deleteSelectedModels: typeof deleteSelectedModelsCommand;
}
}
}
@@ -0,0 +1,58 @@
import type { Command } from '@blocksuite/block-std';
import {
type BlockModel,
type DraftModel,
toDraftModel,
} from '@blocksuite/store';
export const draftSelectedModelsCommand: Command<
'selectedModels',
'draftedModels'
> = (ctx, next) => {
const models = ctx.selectedModels;
if (!models) {
console.error(
'`selectedModels` is required, you need to use `getSelectedModels` command before adding this command to the pipeline.'
);
return;
}
const draftedModelsPromise = new Promise<DraftModel[]>(resolve => {
const draftedModels = models.map(toDraftModel);
const modelMap = new Map(draftedModels.map(model => [model.id, model]));
const traverse = (model: DraftModel) => {
const isDatabase = model.flavour === 'affine:database';
const children = isDatabase
? model.children
: model.children.filter(child => modelMap.has(child.id));
children.forEach(child => {
modelMap.delete(child.id);
traverse(child);
});
model.children = children;
};
draftedModels.forEach(traverse);
const remainingDraftedModels = Array.from(modelMap.values());
resolve(remainingDraftedModels);
});
return next({ draftedModels: draftedModelsPromise });
};
declare global {
namespace BlockSuite {
interface CommandContext {
draftedModels?: Promise<DraftModel<BlockModel<object>>[]>;
}
interface Commands {
draftSelectedModels: typeof draftSelectedModelsCommand;
}
}
}
@@ -0,0 +1,38 @@
import type { Command } from '@blocksuite/block-std';
import { Slice } from '@blocksuite/store';
export const duplicateSelectedModelsCommand: Command<
'draftedModels' | 'selectedModels'
> = (ctx, next) => {
const { std, draftedModels, selectedModels } = ctx;
if (!draftedModels || !selectedModels) return;
const model = selectedModels[selectedModels.length - 1];
const parentModel = std.doc.getParent(model.id);
if (!parentModel) return;
const index = parentModel.children.findIndex(x => x.id === model.id);
draftedModels
.then(models => {
const slice = Slice.fromModels(std.doc, models);
return std.clipboard.duplicateSlice(
slice,
std.doc,
parentModel.id,
index + 1
);
})
.catch(console.error);
return next();
};
declare global {
namespace BlockSuite {
interface Commands {
duplicateSelectedModels: typeof duplicateSelectedModelsCommand;
}
}
}
@@ -0,0 +1,72 @@
import type { Command } from '@blocksuite/block-std';
import type { BlockModel } from '@blocksuite/store';
/**
* Retrieves the selected models based on the provided selection types and mode.
*
* @param ctx - The command context, which includes the types of selections to be retrieved and the mode of the selection.
* @param ctx.types - The selection types to be retrieved. Can be an array of 'block', 'text', or 'image'.
* @param ctx.mode - The mode of the selection. Can be 'all', 'flat', or 'highest'.
* @example
* // Assuming `commandContext` is an instance of the command context
* getSelectedModelsCommand(commandContext, (result) => {
* console.log(result.selectedModels);
* });
*
* // Example selection:
* // aaa
* // b[bb
* // ccc
* // ddd
* // ee]e
*
* // all mode: [aaa, bbb, ccc, ddd, eee]
* // flat mode: [bbb, ccc, ddd, eee]
* // highest mode: [bbb, ddd]
*
* // The match function will be evaluated before filtering using mode
* @param next - The next function to be called.
* @returns An object containing the selected models as an array of BlockModel instances.
*/
export const getSelectedModelsCommand: Command<
never,
'selectedModels',
{
types?: Extract<BlockSuite.SelectionType, 'block' | 'text' | 'image'>[];
mode?: 'all' | 'flat' | 'highest';
}
> = (ctx, next) => {
const types = ctx.types ?? ['block', 'text', 'image'];
const mode = ctx.mode ?? 'flat';
const selectedModels: BlockModel[] = [];
ctx.std.command
.chain()
.tryAll(chain => [
chain.getTextSelection(),
chain.getBlockSelections(),
chain.getImageSelections(),
])
.getSelectedBlocks({
types,
mode,
})
.inline(ctx => {
const { selectedBlocks = [] } = ctx;
selectedModels.push(...selectedBlocks.map(el => el.model));
})
.run();
next({ selectedModels });
};
declare global {
namespace BlockSuite {
interface CommandContext {
selectedModels?: BlockModel[];
}
interface Commands {
getSelectedModels: typeof getSelectedModelsCommand;
}
}
}
@@ -0,0 +1,7 @@
export { clearAndSelectFirstModelCommand } from './clear-and-select-first-model.js';
export { copySelectedModelsCommand } from './copy-selected-models.js';
export { deleteSelectedModelsCommand } from './delete-selected-models.js';
export { draftSelectedModelsCommand } from './draft-selected-models.js';
export { duplicateSelectedModelsCommand } from './duplicate-selected-model.js';
export { getSelectedModelsCommand } from './get-selected-models.js';
export { retainFirstModelCommand } from './retain-first-model.js';
@@ -0,0 +1,27 @@
import type { Command } from '@blocksuite/block-std';
export const retainFirstModelCommand: Command<'selectedModels'> = (
ctx,
next
) => {
if (!ctx.selectedModels) {
console.error(
'`selectedModels` is required, you need to use `getSelectedModels` command before adding this command to the pipeline.'
);
return;
}
if (ctx.selectedModels.length > 0) {
ctx.selectedModels.shift();
}
return next();
};
declare global {
namespace BlockSuite {
interface Commands {
retainFirstModel: typeof retainFirstModelCommand;
}
}
}