refactor(editor): getFirstContentBlock -> getFirstBlock & getLastContentBlock -> getLastBlock (#10809)

This commit is contained in:
yoyoyohamapi
2025-03-14 02:35:22 +00:00
parent d3aae962bc
commit e086fd2a43
10 changed files with 530 additions and 325 deletions

View File

@@ -1,35 +1,57 @@
import type { Command } from '@blocksuite/block-std';
import type { BlockModel } from '@blocksuite/store';
import { getFirstNoteBlock } from '../../utils';
type Role = 'content' | 'hub';
/**
* Get the first content block in the document
* Get the first block with specified roles and flavours in the document
*
* @param ctx - Command context
* @param ctx.root - The root note block model
* @param ctx.role - The roles to match, can be string or string array. If not provided, default to all supported roles.
* @param ctx.flavour - The flavours to match, can be string or string array. If not provided, match any flavour.
* @param next - Next handler function
* @returns The first content block model or null
* @returns The first block model matched or null
*/
export const getFirstContentBlockCommand: Command<
export const getFirstBlockCommand: Command<
{
root?: BlockModel;
role?: Role | Role[];
flavour?: string | string[];
},
{
firstBlock: BlockModel | null;
}
> = (ctx, next) => {
const doc = ctx.std.host.doc;
const noteBlock = ctx.root ?? getFirstNoteBlock(doc);
if (!noteBlock) {
const root = ctx.root || ctx.std.host.doc.root;
if (!root) {
next({
firstBlock: null,
});
return;
}
for (const child of noteBlock.children) {
if (child.role === 'content') {
const defaultRoles = ['content', 'hub'];
const rolesToMatch = ctx.role
? Array.isArray(ctx.role)
? ctx.role
: [ctx.role]
: defaultRoles;
const flavoursToMatch = ctx.flavour
? Array.isArray(ctx.flavour)
? ctx.flavour
: [ctx.flavour]
: null;
for (const child of root.children) {
const roleMatches = rolesToMatch.includes(child.role);
const flavourMatches =
!flavoursToMatch || flavoursToMatch.includes(child.flavour);
if (roleMatches && flavourMatches) {
next({
firstBlock: child,
});

View File

@@ -1,35 +1,59 @@
import type { Command } from '@blocksuite/block-std';
import type { BlockModel } from '@blocksuite/store';
import { getLastNoteBlock } from '../../utils';
type Role = 'content' | 'hub';
/**
* Get the last content block in the document
* Get the last block with specified roles and flavours in the document
*
* @param ctx - Command context
* @param ctx.root - The root note block model
* @param ctx.role - The roles to match, can be string or string array. If not provided, default to all supported roles.
* @param ctx.flavour - The flavours to match, can be string or string array. If not provided, match any flavour.
* @param next - Next handler function
* @returns The last content block model or null
* @returns The last block model matched or null
*/
export const getLastContentBlockCommand: Command<
export const getLastBlockCommand: Command<
{
root?: BlockModel;
role?: Role | Role[];
flavour?: string | string[];
},
{
lastBlock: BlockModel | null;
}
> = (ctx, next) => {
const noteBlock = ctx.root ?? getLastNoteBlock(ctx.std.host.doc);
if (!noteBlock) {
const root = ctx.root || ctx.std.host.doc.root;
if (!root) {
next({
lastBlock: null,
});
return;
}
const children = noteBlock.children;
const defaultRoles = ['content', 'hub'];
const rolesToMatch = ctx.role
? Array.isArray(ctx.role)
? ctx.role
: [ctx.role]
: defaultRoles;
const flavoursToMatch = ctx.flavour
? Array.isArray(ctx.flavour)
? ctx.flavour
: [ctx.flavour]
: null;
const children = root.children;
for (let i = children.length - 1; i >= 0; i--) {
if (children[i].role === 'content') {
const roleMatches = rolesToMatch.includes(children[i].role);
const flavourMatches =
!flavoursToMatch || flavoursToMatch.includes(children[i].flavour);
// Both role and flavour must match
if (roleMatches && flavourMatches) {
next({
lastBlock: children[i],
});

View File

@@ -1,6 +1,6 @@
export { getBlockIndexCommand } from './get-block-index.js';
export { getFirstContentBlockCommand } from './get-first-content-block.js';
export { getLastContentBlockCommand } from './get-last-content-block.js';
export { getFirstBlockCommand } from './get-first-content-block.js';
export { getLastBlockCommand } from './get-last-content-block.js';
export { getNextBlockCommand } from './get-next-block.js';
export { getPrevBlockCommand } from './get-prev-block.js';
export { getSelectedBlocksCommand } from './get-selected-blocks.js';

View File

@@ -1,7 +1,7 @@
export {
getBlockIndexCommand,
getFirstContentBlockCommand,
getLastContentBlockCommand,
getFirstBlockCommand,
getLastBlockCommand,
getNextBlockCommand,
getPrevBlockCommand,
getSelectedBlocksCommand,