refactor(editor): unify directories naming (#11516)

**Directory Structure Changes**

- Renamed multiple block-related directories by removing the "block-" prefix:
  - `block-attachment` → `attachment`
  - `block-bookmark` → `bookmark`
  - `block-callout` → `callout`
  - `block-code` → `code`
  - `block-data-view` → `data-view`
  - `block-database` → `database`
  - `block-divider` → `divider`
  - `block-edgeless-text` → `edgeless-text`
  - `block-embed` → `embed`
This commit is contained in:
Saul-Mirone
2025-04-07 12:34:40 +00:00
parent e1bd2047c4
commit 1f45cc5dec
893 changed files with 439 additions and 460 deletions

View File

@@ -0,0 +1,75 @@
import { ListBlockModel } from '@blocksuite/affine-model';
import {
getNextContentBlock,
matchModels,
} from '@blocksuite/affine-shared/utils';
import { type BlockStdScope, TextSelection } from '@blocksuite/std';
import type { Text } from '@blocksuite/store';
// When deleting at line end of a list block,
// check current block's children and siblings
/**
* Example:
- Line1 <-(cursor here)
- Line2
- Line3
- Line4
- Line5
- Line6
- Line7
- Line8
- Line9
*/
export function forwardDelete(std: BlockStdScope): true | undefined {
const text = std.selection.find(TextSelection);
if (!text) return;
const isCollapsed = text.isCollapsed();
const doc = std.store;
const model = doc.getBlock(text.from.blockId)?.model;
if (!model || !matchModels(model, [ListBlockModel])) return;
const isEnd = isCollapsed && text.from.index === model.props.text.length;
if (!isEnd) return;
// Has children in list
const firstChild = model.firstChild();
if (firstChild) {
model.props.text.join(firstChild.text as Text);
const grandChildren = firstChild.children;
if (grandChildren) {
doc.moveBlocks(grandChildren, model);
doc.deleteBlock(firstChild);
return true;
}
doc.deleteBlock(firstChild);
return true;
}
const parent = doc.getParent(model);
// Has text sibling
const nextSibling = doc.getNext(model);
const nextText = nextSibling?.text;
if (nextSibling && nextText) {
model.props.text.join(nextText);
if (nextSibling.children) {
if (!parent) return;
doc.moveBlocks(nextSibling.children, parent, model, false);
}
doc.deleteBlock(nextSibling);
return true;
}
// Has next text block in other note block
const nextBlock = getNextContentBlock(std.host, model);
const nextBlockText = nextBlock?.text;
if (nextBlock && nextBlockText) {
model.props.text.join(nextBlock.text as Text);
if (nextBlock.children) {
const nextBlockParent = doc.getParent(nextBlock);
if (!nextBlockParent) return;
doc.moveBlocks(nextBlock.children, nextBlockParent, parent, false);
}
doc.deleteBlock(nextBlock);
}
return true;
}

View File

@@ -0,0 +1,78 @@
import type { ListBlockModel } from '@blocksuite/affine-model';
import {
BulletedList01Icon,
BulletedList02Icon,
BulletedList03Icon,
BulletedList04Icon,
CheckBoxCheckSolidIcon,
CheckBoxUnIcon,
ToggleDownIcon,
ToggleRightIcon,
} from '@blocksuite/icons/lit';
import { html } from 'lit';
import { getNumberPrefix } from './get-number-prefix.js';
const getListDeep = (model: ListBlockModel): number => {
let deep = 0;
let parent = model.doc.getParent(model);
while (parent?.flavour === model.flavour) {
deep++;
parent = model.doc.getParent(parent);
}
return deep;
};
const BulletIcons = [
BulletedList01Icon({ width: '24px', height: '24px' }),
BulletedList02Icon({ width: '24px', height: '24px' }),
BulletedList03Icon({ width: '24px', height: '24px' }),
BulletedList04Icon({ width: '24px', height: '24px' }),
];
export function getListIcon(
model: ListBlockModel,
showChildren: boolean,
onClick: (e: MouseEvent) => void
) {
const deep = getListDeep(model);
switch (model.props.type) {
case 'bulleted':
return html`<div
contenteditable="false"
class="affine-list-block__prefix"
@click=${onClick}
>
${BulletIcons[deep % BulletIcons.length]}
</div>`;
case 'numbered':
return html`<div
contenteditable="false"
class="affine-list-block__prefix affine-list-block__numbered"
@click=${onClick}
>
${model.props.order ? getNumberPrefix(model.props.order, deep) : '1.'}
</div>`;
case 'todo':
return html`<div
contenteditable="false"
class=${`affine-list-block__prefix affine-list-block__todo-prefix ${model.doc.readonly ? 'readonly' : ''}`}
@click=${onClick}
>
${model.props.checked
? CheckBoxCheckSolidIcon({ style: 'color: #1E96EB' })
: CheckBoxUnIcon()}
</div>`;
case 'toggle':
return html`<div
contenteditable="false"
class="affine-list-block__prefix"
@click=${onClick}
>
${showChildren ? ToggleDownIcon() : ToggleRightIcon()}
</div>`;
default:
console.error('Unknown list type', model.props.type, model);
return null;
}
}

View File

@@ -0,0 +1,52 @@
function number2letter(n: number) {
const ordA = 'a'.charCodeAt(0);
const ordZ = 'z'.charCodeAt(0);
const len = ordZ - ordA + 1;
let s = '';
while (n >= 0) {
s = String.fromCharCode((n % len) + ordA) + s;
n = Math.floor(n / len) - 1;
}
return s;
}
// Derive from https://gist.github.com/imilu/00f32c61e50b7ca296f91e9d96d8e976
export function number2roman(num: number) {
const lookup: Record<string, number> = {
M: 1000,
CM: 900,
D: 500,
CD: 400,
C: 100,
XC: 90,
L: 50,
XL: 40,
X: 10,
IX: 9,
V: 5,
IV: 4,
I: 1,
};
let romanStr = '';
for (const i in lookup) {
while (num >= lookup[i]) {
romanStr += i;
num -= lookup[i];
}
}
return romanStr;
}
function getPrefix(depth: number, index: number) {
const map = [
() => index,
() => number2letter(index - 1),
() => number2roman(index),
];
return map[depth % map.length]();
}
export function getNumberPrefix(index: number, depth: number) {
const prefix = getPrefix(depth, index);
return `${prefix}.`;
}