mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-31 17:19:56 +08:00
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:
@@ -0,0 +1,21 @@
|
||||
import {
|
||||
EdgelessSurfaceBlockMarkdownAdapterExtension,
|
||||
SurfaceBlockMarkdownAdapterExtension,
|
||||
} from './markdown/markdown.js';
|
||||
import {
|
||||
EdgelessSurfaceBlockPlainTextAdapterExtension,
|
||||
SurfaceBlockPlainTextAdapterExtension,
|
||||
} from './plain-text/plain-text.js';
|
||||
|
||||
export const SurfaceBlockAdapterExtensions = [
|
||||
SurfaceBlockPlainTextAdapterExtension,
|
||||
SurfaceBlockMarkdownAdapterExtension,
|
||||
];
|
||||
|
||||
export const EdgelessSurfaceBlockAdapterExtensions = [
|
||||
EdgelessSurfaceBlockPlainTextAdapterExtension,
|
||||
EdgelessSurfaceBlockMarkdownAdapterExtension,
|
||||
];
|
||||
|
||||
export * from './markdown/element-adapter/index.js';
|
||||
export * from './plain-text/element-adapter/index.js';
|
||||
@@ -0,0 +1,20 @@
|
||||
import {
|
||||
BlockHtmlAdapterExtension,
|
||||
type BlockHtmlAdapterMatcher,
|
||||
} from '@blocksuite/affine-shared/adapters';
|
||||
|
||||
export const surfaceBlockHtmlAdapterMatcher: BlockHtmlAdapterMatcher = {
|
||||
flavour: 'affine:surface',
|
||||
toMatch: () => false,
|
||||
fromMatch: o => o.node.flavour === 'affine:surface',
|
||||
toBlockSnapshot: {},
|
||||
fromBlockSnapshot: {
|
||||
enter: (_, context) => {
|
||||
context.walkerContext.skipAllChildren();
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const SurfaceBlockHtmlAdapterExtension = BlockHtmlAdapterExtension(
|
||||
surfaceBlockHtmlAdapterMatcher
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
export * from './extension.js';
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { MarkdownAST } from '@blocksuite/affine-shared/adapters';
|
||||
|
||||
import {
|
||||
ElementModelAdapter,
|
||||
type ElementModelAdapterContext,
|
||||
} from '../../type.js';
|
||||
import type { ElementToMarkdownAdapterMatcher } from './type.js';
|
||||
|
||||
export class MarkdownElementModelAdapter extends ElementModelAdapter<
|
||||
MarkdownAST,
|
||||
MarkdownAST
|
||||
> {
|
||||
constructor(
|
||||
readonly elementModelMatchers: ElementToMarkdownAdapterMatcher[]
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
fromElementModel(
|
||||
element: Record<string, unknown>,
|
||||
context: ElementModelAdapterContext<MarkdownAST>
|
||||
) {
|
||||
const markdownAST: MarkdownAST | null = null;
|
||||
for (const matcher of this.elementModelMatchers) {
|
||||
if (matcher.match(element)) {
|
||||
return matcher.toAST(element, context);
|
||||
}
|
||||
}
|
||||
return markdownAST;
|
||||
}
|
||||
}
|
||||
|
||||
export * from './type.js';
|
||||
@@ -0,0 +1,29 @@
|
||||
import type { ExtensionType } from '@blocksuite/affine/store';
|
||||
import type { MarkdownAST } from '@blocksuite/affine-shared/adapters';
|
||||
import {
|
||||
createIdentifier,
|
||||
type ServiceIdentifier,
|
||||
} from '@blocksuite/global/di';
|
||||
|
||||
import type { ElementModelMatcher } from '../../type.js';
|
||||
|
||||
export type ElementToMarkdownAdapterMatcher = ElementModelMatcher<MarkdownAST>;
|
||||
|
||||
export const ElementToMarkdownAdapterMatcherIdentifier =
|
||||
createIdentifier<ElementToMarkdownAdapterMatcher>(
|
||||
'elementToMarkdownAdapterMatcher'
|
||||
);
|
||||
|
||||
export function ElementToMarkdownAdapterExtension(
|
||||
matcher: ElementToMarkdownAdapterMatcher
|
||||
): ExtensionType & {
|
||||
identifier: ServiceIdentifier<ElementToMarkdownAdapterMatcher>;
|
||||
} {
|
||||
const identifier = ElementToMarkdownAdapterMatcherIdentifier(matcher.name);
|
||||
return {
|
||||
setup: di => {
|
||||
di.addImpl(identifier, () => matcher);
|
||||
},
|
||||
identifier,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import { getMindMapNodeMap } from '@blocksuite/affine-model';
|
||||
import {
|
||||
BlockMarkdownAdapterExtension,
|
||||
type BlockMarkdownAdapterMatcher,
|
||||
} from '@blocksuite/affine-shared/adapters';
|
||||
|
||||
import { MarkdownElementModelAdapter } from './element-adapter/index.js';
|
||||
import { ElementToMarkdownAdapterMatcherIdentifier } from './element-adapter/type.js';
|
||||
|
||||
export const surfaceBlockMarkdownAdapterMatcher: BlockMarkdownAdapterMatcher = {
|
||||
flavour: 'affine:surface',
|
||||
toMatch: () => false,
|
||||
fromMatch: o => o.node.flavour === 'affine:surface',
|
||||
toBlockSnapshot: {},
|
||||
fromBlockSnapshot: {
|
||||
enter: (_, context) => {
|
||||
context.walkerContext.skipAllChildren();
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const SurfaceBlockMarkdownAdapterExtension =
|
||||
BlockMarkdownAdapterExtension(surfaceBlockMarkdownAdapterMatcher);
|
||||
|
||||
export const edgelessSurfaceBlockMarkdownAdapterMatcher: BlockMarkdownAdapterMatcher =
|
||||
{
|
||||
flavour: 'affine:surface',
|
||||
toMatch: () => false,
|
||||
fromMatch: o => o.node.flavour === 'affine:surface',
|
||||
toBlockSnapshot: {},
|
||||
fromBlockSnapshot: {
|
||||
enter: (o, context) => {
|
||||
const { walkerContext, provider } = context;
|
||||
if (!provider) {
|
||||
context.walkerContext.skipAllChildren();
|
||||
return;
|
||||
}
|
||||
|
||||
const elementModelMatchers = Array.from(
|
||||
provider.getAll(ElementToMarkdownAdapterMatcherIdentifier).values()
|
||||
);
|
||||
const markdownElementModelAdapter = new MarkdownElementModelAdapter(
|
||||
elementModelMatchers
|
||||
);
|
||||
if ('elements' in o.node.props) {
|
||||
const elements = o.node.props.elements as Record<
|
||||
string,
|
||||
Record<string, unknown>
|
||||
>;
|
||||
// Get all the node maps of mindMap elements
|
||||
const mindMapArray = Object.entries(elements)
|
||||
.filter(([_, element]) => element.type === 'mindmap')
|
||||
.map(([_, element]) => getMindMapNodeMap(element));
|
||||
walkerContext.setGlobalContext(
|
||||
'surface:mindMap:nodeMapArray',
|
||||
mindMapArray
|
||||
);
|
||||
|
||||
Object.entries(
|
||||
o.node.props.elements as Record<string, Record<string, unknown>>
|
||||
).forEach(([_, element]) => {
|
||||
const markdownAST = markdownElementModelAdapter.fromElementModel(
|
||||
element,
|
||||
{ walkerContext, elements }
|
||||
);
|
||||
if (markdownAST) {
|
||||
walkerContext.openNode(markdownAST, 'children').closeNode();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const EdgelessSurfaceBlockMarkdownAdapterExtension =
|
||||
BlockMarkdownAdapterExtension(edgelessSurfaceBlockMarkdownAdapterMatcher);
|
||||
@@ -0,0 +1,32 @@
|
||||
import type { TextBuffer } from '@blocksuite/affine-shared/adapters';
|
||||
|
||||
import {
|
||||
ElementModelAdapter,
|
||||
type ElementModelAdapterContext,
|
||||
} from '../../type.js';
|
||||
import type { ElementToPlainTextAdapterMatcher } from './type.js';
|
||||
|
||||
export class PlainTextElementModelAdapter extends ElementModelAdapter<
|
||||
string,
|
||||
TextBuffer
|
||||
> {
|
||||
constructor(
|
||||
readonly elementModelMatchers: ElementToPlainTextAdapterMatcher[]
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
fromElementModel(
|
||||
element: Record<string, unknown>,
|
||||
context: ElementModelAdapterContext<TextBuffer>
|
||||
) {
|
||||
for (const matcher of this.elementModelMatchers) {
|
||||
if (matcher.match(element)) {
|
||||
return matcher.toAST(element, context)?.content ?? '';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
export * from './type.js';
|
||||
@@ -0,0 +1,29 @@
|
||||
import type { TextBuffer } from '@blocksuite/affine-shared/adapters';
|
||||
import {
|
||||
createIdentifier,
|
||||
type ServiceIdentifier,
|
||||
} from '@blocksuite/global/di';
|
||||
import type { ExtensionType } from '@blocksuite/store';
|
||||
|
||||
import type { ElementModelMatcher } from '../../type.js';
|
||||
|
||||
export type ElementToPlainTextAdapterMatcher = ElementModelMatcher<TextBuffer>;
|
||||
|
||||
export const ElementToPlainTextAdapterMatcherIdentifier =
|
||||
createIdentifier<ElementToPlainTextAdapterMatcher>(
|
||||
'elementToPlainTextAdapterMatcher'
|
||||
);
|
||||
|
||||
export function ElementToPlainTextAdapterExtension(
|
||||
matcher: ElementToPlainTextAdapterMatcher
|
||||
): ExtensionType & {
|
||||
identifier: ServiceIdentifier<ElementToPlainTextAdapterMatcher>;
|
||||
} {
|
||||
const identifier = ElementToPlainTextAdapterMatcherIdentifier(matcher.name);
|
||||
return {
|
||||
setup: di => {
|
||||
di.addImpl(identifier, () => matcher);
|
||||
},
|
||||
identifier,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import { getMindMapNodeMap } from '@blocksuite/affine-model';
|
||||
import {
|
||||
BlockPlainTextAdapterExtension,
|
||||
type BlockPlainTextAdapterMatcher,
|
||||
} from '@blocksuite/affine-shared/adapters';
|
||||
|
||||
import { PlainTextElementModelAdapter } from './element-adapter/index.js';
|
||||
import { ElementToPlainTextAdapterMatcherIdentifier } from './element-adapter/type.js';
|
||||
|
||||
export const surfaceBlockPlainTextAdapterMatcher: BlockPlainTextAdapterMatcher =
|
||||
{
|
||||
flavour: 'affine:surface',
|
||||
toMatch: () => false,
|
||||
fromMatch: o => o.node.flavour === 'affine:surface',
|
||||
toBlockSnapshot: {},
|
||||
fromBlockSnapshot: {
|
||||
enter: (_, context) => {
|
||||
context.walkerContext.skipAllChildren();
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const SurfaceBlockPlainTextAdapterExtension =
|
||||
BlockPlainTextAdapterExtension(surfaceBlockPlainTextAdapterMatcher);
|
||||
|
||||
export const edgelessSurfaceBlockPlainTextAdapterMatcher: BlockPlainTextAdapterMatcher =
|
||||
{
|
||||
flavour: 'affine:surface',
|
||||
toMatch: () => false,
|
||||
fromMatch: o => o.node.flavour === 'affine:surface',
|
||||
toBlockSnapshot: {},
|
||||
fromBlockSnapshot: {
|
||||
enter: (o, context) => {
|
||||
const { walkerContext, provider } = context;
|
||||
if (!provider) {
|
||||
context.walkerContext.skipAllChildren();
|
||||
return;
|
||||
}
|
||||
|
||||
const elementModelMatchers = Array.from(
|
||||
provider.getAll(ElementToPlainTextAdapterMatcherIdentifier).values()
|
||||
);
|
||||
const plainTextElementModelAdapter = new PlainTextElementModelAdapter(
|
||||
elementModelMatchers
|
||||
);
|
||||
if ('elements' in o.node.props) {
|
||||
const elements = o.node.props.elements as Record<
|
||||
string,
|
||||
Record<string, unknown>
|
||||
>;
|
||||
// Get all the node maps of mindMap elements
|
||||
const mindMapArray = Object.entries(elements)
|
||||
.filter(([_, element]) => element.type === 'mindmap')
|
||||
.map(([_, element]) => getMindMapNodeMap(element));
|
||||
walkerContext.setGlobalContext(
|
||||
'surface:mindMap:nodeMapArray',
|
||||
mindMapArray
|
||||
);
|
||||
|
||||
Object.entries(
|
||||
o.node.props.elements as Record<string, Record<string, unknown>>
|
||||
).forEach(([_, element]) => {
|
||||
const plainText = plainTextElementModelAdapter.fromElementModel(
|
||||
element,
|
||||
{ walkerContext, elements }
|
||||
);
|
||||
if (plainText) {
|
||||
context.textBuffer.content += plainText + '\n';
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const EdgelessSurfaceBlockPlainTextAdapterExtension =
|
||||
BlockPlainTextAdapterExtension(edgelessSurfaceBlockPlainTextAdapterMatcher);
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { ASTWalkerContext } from '@blocksuite/store';
|
||||
|
||||
import type { ElementModelMap } from '../element-model/index.js';
|
||||
|
||||
export type ElementModelAdapterContext<TNode extends object = never> = {
|
||||
walkerContext: ASTWalkerContext<TNode>;
|
||||
elements: Record<string, Record<string, unknown>>;
|
||||
};
|
||||
|
||||
export type ElementModelMatcher<TNode extends object = never> = {
|
||||
name: keyof ElementModelMap;
|
||||
match: (element: Record<string, unknown>) => boolean;
|
||||
toAST: (
|
||||
element: Record<string, unknown>,
|
||||
context: ElementModelAdapterContext<TNode>
|
||||
) => TNode | null;
|
||||
};
|
||||
|
||||
export abstract class ElementModelAdapter<
|
||||
AST = unknown,
|
||||
TNode extends object = never,
|
||||
> {
|
||||
/**
|
||||
* Convert element model to AST format
|
||||
*/
|
||||
abstract fromElementModel(
|
||||
element: Record<string, unknown>,
|
||||
context: ElementModelAdapterContext<TNode>
|
||||
): AST | null;
|
||||
}
|
||||
Reference in New Issue
Block a user