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
@@ -0,0 +1,2 @@
export * from './page-clipboard.js';
export * from './readonly-clipboard.js';
@@ -0,0 +1,171 @@
import { deleteTextCommand } from '@blocksuite/affine-inline-preset';
import {
pasteMiddleware,
replaceIdMiddleware,
surfaceRefToEmbed,
} from '@blocksuite/affine-shared/adapters';
import {
clearAndSelectFirstModelCommand,
deleteSelectedModelsCommand,
getBlockIndexCommand,
getBlockSelectionsCommand,
getImageSelectionsCommand,
getSelectedModelsCommand,
getTextSelectionCommand,
retainFirstModelCommand,
} from '@blocksuite/affine-shared/commands';
import { DisposableGroup } from '@blocksuite/global/disposable';
import type { UIEventHandler } from '@blocksuite/std';
import type { BlockSnapshot, Store } from '@blocksuite/store';
import { ReadOnlyClipboard } from './readonly-clipboard';
/**
* PageClipboard is a class that provides a clipboard for the page root block.
* It is supported to copy and paste models in the page root block.
*/
export class PageClipboard extends ReadOnlyClipboard {
static override key = 'affine-page-clipboard';
protected _init = () => {
this._initAdapters();
const paste = pasteMiddleware(this.std);
// Use surfaceRefToEmbed middleware to convert surface-ref to embed-linked-doc
// When pastina a surface-ref block to another doc
const surfaceRefToEmbedMiddleware = surfaceRefToEmbed(this.std);
const replaceId = replaceIdMiddleware(this.std.store.workspace.idGenerator);
this.std.clipboard.use(paste);
this.std.clipboard.use(surfaceRefToEmbedMiddleware);
this.std.clipboard.use(replaceId);
this._disposables.add({
dispose: () => {
this.std.clipboard.unuse(paste);
this.std.clipboard.unuse(surfaceRefToEmbedMiddleware);
this.std.clipboard.unuse(replaceId);
},
});
};
onBlockSnapshotPaste = async (
snapshot: BlockSnapshot,
doc: Store,
parent?: string,
index?: number
) => {
const block = await this.std.clipboard.pasteBlockSnapshot(
snapshot,
doc,
parent,
index
);
return block?.id ?? null;
};
onPageCut: UIEventHandler = ctx => {
const e = ctx.get('clipboardState').raw;
e.preventDefault();
this._copySelected(() => {
this.std.command
.chain()
.try<{}>(cmd => [
cmd.pipe(getTextSelectionCommand).pipe(deleteTextCommand),
cmd.pipe(getSelectedModelsCommand).pipe(deleteSelectedModelsCommand),
])
.run();
}).run();
};
onPagePaste: UIEventHandler = ctx => {
const e = ctx.get('clipboardState').raw;
e.preventDefault();
this.std.store.captureSync();
this.std.command
.chain()
.try<{}>(cmd => [
cmd.pipe(getTextSelectionCommand).pipe((ctx, next) => {
const { currentTextSelection } = ctx;
if (!currentTextSelection) {
return;
}
const { from, to } = currentTextSelection;
if (to && from.blockId !== to.blockId) {
this.std.command.exec(deleteTextCommand, {
currentTextSelection,
});
}
return next();
}),
cmd
.pipe(getSelectedModelsCommand)
.pipe(clearAndSelectFirstModelCommand)
.pipe(retainFirstModelCommand)
.pipe(deleteSelectedModelsCommand),
])
.try<{ currentSelectionPath: string }>(cmd => [
cmd.pipe(getTextSelectionCommand).pipe((ctx, next) => {
const textSelection = ctx.currentTextSelection;
if (!textSelection) {
return;
}
next({ currentSelectionPath: textSelection.from.blockId });
}),
cmd.pipe(getBlockSelectionsCommand).pipe((ctx, next) => {
const currentBlockSelections = ctx.currentBlockSelections;
if (!currentBlockSelections) {
return;
}
const blockSelection = currentBlockSelections.at(-1);
if (!blockSelection) {
return;
}
next({ currentSelectionPath: blockSelection.blockId });
}),
cmd.pipe(getImageSelectionsCommand).pipe((ctx, next) => {
const currentImageSelections = ctx.currentImageSelections;
if (!currentImageSelections) {
return;
}
const imageSelection = currentImageSelections.at(-1);
if (!imageSelection) {
return;
}
next({ currentSelectionPath: imageSelection.blockId });
}),
])
.pipe(getBlockIndexCommand)
.pipe((ctx, next) => {
if (!ctx.parentBlock) {
return;
}
this.std.clipboard
.paste(
e,
this.std.store,
ctx.parentBlock.model.id,
ctx.blockIndex ? ctx.blockIndex + 1 : 1
)
.catch(console.error);
return next();
})
.run();
};
override mounted() {
if (!navigator.clipboard) {
console.error(
'navigator.clipboard is not supported in current environment.'
);
return;
}
if (this._disposables.disposed) {
this._disposables = new DisposableGroup();
}
this.std.event.add('copy', this.onPageCopy);
this.std.event.add('paste', this.onPagePaste);
this.std.event.add('cut', this.onPageCut);
this._init();
}
}
@@ -0,0 +1,137 @@
import { defaultImageProxyMiddleware } from '@blocksuite/affine-block-image';
import {
AttachmentAdapter,
ClipboardAdapter,
copyMiddleware,
HtmlAdapter,
ImageAdapter,
MixTextAdapter,
NotionTextAdapter,
titleMiddleware,
} from '@blocksuite/affine-shared/adapters';
import {
copySelectedModelsCommand,
draftSelectedModelsCommand,
getSelectedModelsCommand,
} from '@blocksuite/affine-shared/commands';
import { DisposableGroup } from '@blocksuite/global/disposable';
import {
ClipboardAdapterConfigExtension,
LifeCycleWatcher,
type UIEventHandler,
} from '@blocksuite/std';
import type { ExtensionType } from '@blocksuite/store';
const SnapshotClipboardConfig = ClipboardAdapterConfigExtension({
mimeType: ClipboardAdapter.MIME,
adapter: ClipboardAdapter,
priority: 100,
});
const NotionClipboardConfig = ClipboardAdapterConfigExtension({
mimeType: 'text/_notion-text-production',
adapter: NotionTextAdapter,
priority: 95,
});
const HtmlClipboardConfig = ClipboardAdapterConfigExtension({
mimeType: 'text/html',
adapter: HtmlAdapter,
priority: 90,
});
const imageClipboardConfigs = [
'image/apng',
'image/avif',
'image/gif',
'image/jpeg',
'image/png',
'image/svg+xml',
'image/webp',
].map(mimeType => {
return ClipboardAdapterConfigExtension({
mimeType,
adapter: ImageAdapter,
priority: 80,
});
});
const PlainTextClipboardConfig = ClipboardAdapterConfigExtension({
mimeType: 'text/plain',
adapter: MixTextAdapter,
priority: 70,
});
const AttachmentClipboardConfig = ClipboardAdapterConfigExtension({
mimeType: '*/*',
adapter: AttachmentAdapter,
priority: 60,
});
export const clipboardConfigs: ExtensionType[] = [
SnapshotClipboardConfig,
NotionClipboardConfig,
HtmlClipboardConfig,
...imageClipboardConfigs,
PlainTextClipboardConfig,
AttachmentClipboardConfig,
];
/**
* ReadOnlyClipboard is a class that provides a read-only clipboard for the root block.
* It is supported to copy models in the root block.
*/
export class ReadOnlyClipboard extends LifeCycleWatcher {
static override key = 'affine-readonly-clipboard';
protected readonly _copySelected = (onCopy?: () => void) => {
return this.std.command
.chain()
.with({ onCopy })
.pipe(getSelectedModelsCommand)
.pipe(draftSelectedModelsCommand)
.pipe(copySelectedModelsCommand);
};
protected _disposables = new DisposableGroup();
protected _initAdapters = () => {
const copy = copyMiddleware(this.std);
this.std.clipboard.use(copy);
this.std.clipboard.use(
titleMiddleware(this.std.store.workspace.meta.docMetas)
);
this.std.clipboard.use(defaultImageProxyMiddleware);
this._disposables.add({
dispose: () => {
this.std.clipboard.unuse(copy);
this.std.clipboard.unuse(
titleMiddleware(this.std.store.workspace.meta.docMetas)
);
this.std.clipboard.unuse(defaultImageProxyMiddleware);
},
});
};
onPageCopy: UIEventHandler = ctx => {
const e = ctx.get('clipboardState').raw;
e.preventDefault();
this._copySelected().run();
};
override mounted(): void {
if (!navigator.clipboard) {
console.error(
'navigator.clipboard is not supported in current environment.'
);
return;
}
if (this._disposables.disposed) {
this._disposables = new DisposableGroup();
}
this.std.event.add('copy', this.onPageCopy);
this._initAdapters();
}
}