Skip to content

Commit

Permalink
refactor(editor): extensionalize plain text adapter (#9330)
Browse files Browse the repository at this point in the history
  • Loading branch information
donteatfriedrice committed Dec 26, 2024
1 parent 45acdbd commit cadb921
Show file tree
Hide file tree
Showing 27 changed files with 226 additions and 120 deletions.
3 changes: 3 additions & 0 deletions blocksuite/affine/block-surface/src/adapters/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@ import {
EdgelessSurfaceBlockMarkdownAdapterExtension,
SurfaceBlockMarkdownAdapterExtension,
} from './markdown/markdown.js';
import { elementToPlainTextAdapterMatchers } from './plain-text/element-adapter/elements/index.js';
import {
EdgelessSurfaceBlockPlainTextAdapterExtension,
SurfaceBlockPlainTextAdapterExtension,
} from './plain-text/plain-text.js';

export const SurfaceBlockAdapterExtensions = [
...elementToPlainTextAdapterMatchers,
SurfaceBlockPlainTextAdapterExtension,
SurfaceBlockMarkdownAdapterExtension,
];

export const EdgelessSurfaceBlockAdapterExtensions = [
...elementToPlainTextAdapterMatchers,
EdgelessSurfaceBlockPlainTextAdapterExtension,
EdgelessSurfaceBlockMarkdownAdapterExtension,
];
4 changes: 4 additions & 0 deletions blocksuite/affine/block-surface/src/adapters/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export {
EdgelessSurfaceBlockAdapterExtensions,
SurfaceBlockAdapterExtensions,
} from './extension.js';
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { ElementModelToPlainTextAdapterMatcher } from '../type.js';
import { ElementToPlainTextAdapterExtension } from '../type.js';

export const brushToPlainTextAdapterMatcher: ElementModelToPlainTextAdapterMatcher =
{
export const brushToPlainTextAdapterMatcher =
ElementToPlainTextAdapterExtension({
name: 'brush',
match: elementModel => elementModel.type === 'brush',
toAST: () => {
const content = `Brush Stroke`;
return { content };
},
};
});
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { getConnectorText } from '../../../utils/text.js';
import type { ElementModelToPlainTextAdapterMatcher } from '../type.js';
import { ElementToPlainTextAdapterExtension } from '../type.js';

export const connectorToPlainTextAdapterMatcher: ElementModelToPlainTextAdapterMatcher =
{
export const connectorToPlainTextAdapterMatcher =
ElementToPlainTextAdapterExtension({
name: 'connector',
match: elementModel => elementModel.type === 'connector',
toAST: elementModel => {
const text = getConnectorText(elementModel);
const content = `Connector, with text label "${text}"`;
return { content };
},
};
});
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { getGroupTitle } from '../../../utils/text.js';
import type { ElementModelToPlainTextAdapterMatcher } from '../type.js';
import { ElementToPlainTextAdapterExtension } from '../type.js';

export const groupToPlainTextAdapterMatcher: ElementModelToPlainTextAdapterMatcher =
{
export const groupToPlainTextAdapterMatcher =
ElementToPlainTextAdapterExtension({
name: 'group',
match: elementModel => elementModel.type === 'group',
toAST: elementModel => {
const title = getGroupTitle(elementModel);
const content = `Group, with title "${title}"`;
return { content };
},
};
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { mindmapToPlainTextAdapterMatcher } from './mindmap.js';
import { shapeToPlainTextAdapterMatcher } from './shape.js';
import { textToPlainTextAdapterMatcher } from './text.js';

export const elementModelToPlainTextAdapterMatchers = [
export const elementToPlainTextAdapterMatchers = [
groupToPlainTextAdapterMatcher,
shapeToPlainTextAdapterMatcher,
connectorToPlainTextAdapterMatcher,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { getMindMapTreeText } from '../../../utils/text.js';
import type { ElementModelToPlainTextAdapterMatcher } from '../type.js';
import { ElementToPlainTextAdapterExtension } from '../type.js';

export const mindmapToPlainTextAdapterMatcher: ElementModelToPlainTextAdapterMatcher =
{
export const mindmapToPlainTextAdapterMatcher =
ElementToPlainTextAdapterExtension({
name: 'mindmap',
match: elementModel => elementModel.type === 'mindmap',
toAST: (elementModel, context) => {
const mindMapContent = getMindMapTreeText(elementModel, context.elements);
return { content: mindMapContent };
},
};
});
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { MindMapTreeNode } from '../../../types/mindmap.js';
import { getShapeText, getShapeType } from '../../../utils/text.js';
import type { ElementModelToPlainTextAdapterMatcher } from '../type.js';
import { ElementToPlainTextAdapterExtension } from '../type.js';

export const shapeToPlainTextAdapterMatcher: ElementModelToPlainTextAdapterMatcher =
{
export const shapeToPlainTextAdapterMatcher =
ElementToPlainTextAdapterExtension({
name: 'shape',
match: elementModel => elementModel.type === 'shape',
toAST: (elementModel, context) => {
Expand Down Expand Up @@ -31,4 +31,4 @@ export const shapeToPlainTextAdapterMatcher: ElementModelToPlainTextAdapterMatch
content = `${shapeType}, with text label "${text}"`;
return { content };
},
};
});
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { getTextElementText } from '../../../utils/text.js';
import type { ElementModelToPlainTextAdapterMatcher } from '../type.js';
import { ElementToPlainTextAdapterExtension } from '../type.js';

export const textToPlainTextAdapterMatcher: ElementModelToPlainTextAdapterMatcher =
export const textToPlainTextAdapterMatcher = ElementToPlainTextAdapterExtension(
{
name: 'text',
match: elementModel => elementModel.type === 'text',
toAST: elementModel => {
const content = getTextElementText(elementModel);
return { content };
},
};
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import {
ElementModelAdapter,
type ElementModelAdapterContext,
} from '../../type.js';
import { elementModelToPlainTextAdapterMatchers } from './elements/index.js';
import type { ElementModelToPlainTextAdapterMatcher } from './type.js';
import type { ElementToPlainTextAdapterMatcher } from './type.js';

export class PlainTextElementModelAdapter extends ElementModelAdapter<
string,
TextBuffer
> {
constructor(
readonly elementModelMatchers: ElementModelToPlainTextAdapterMatcher[] = elementModelToPlainTextAdapterMatchers
readonly elementModelMatchers: ElementToPlainTextAdapterMatcher[]
) {
super();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
import type { TextBuffer } from '@blocksuite/affine-shared/adapters';
import type { ExtensionType } from '@blocksuite/block-std';
import {
createIdentifier,
type ServiceIdentifier,
} from '@blocksuite/global/di';

import type { ElementModelMatcher } from '../../type.js';

export type ElementModelToPlainTextAdapterMatcher =
ElementModelMatcher<TextBuffer>;
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,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {

import { getMindMapNodeMap } from '../utils/mindmap.js';
import { PlainTextElementModelAdapter } from './element-adapter/index.js';
import { ElementToPlainTextAdapterMatcherIdentifier } from './element-adapter/type.js';

export const surfaceBlockPlainTextAdapterMatcher: BlockPlainTextAdapterMatcher =
{
Expand All @@ -30,8 +31,18 @@ export const edgelessSurfaceBlockPlainTextAdapterMatcher: BlockPlainTextAdapterM
toBlockSnapshot: {},
fromBlockSnapshot: {
enter: (o, context) => {
const { walkerContext } = context;
const plainTextElementModelAdapter = new PlainTextElementModelAdapter();
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,
Expand Down
4 changes: 4 additions & 0 deletions blocksuite/affine/block-surface/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ import {
isSameFontFamily,
wrapFontFamily,
} from './utils/font.js';
export {
EdgelessSurfaceBlockAdapterExtensions,
SurfaceBlockAdapterExtensions,
} from './adapters/index.js';
export type { SurfaceContext } from './surface-block.js';
export { SurfaceBlockComponent } from './surface-block.js';
export { SurfaceBlockModel, SurfaceBlockSchema } from './surface-model.js';
Expand Down
4 changes: 4 additions & 0 deletions blocksuite/affine/shared/src/adapters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,13 @@ export {
BlockPlainTextAdapterExtension,
type BlockPlainTextAdapterMatcher,
BlockPlainTextAdapterMatcherIdentifier,
InlineDeltaToPlainTextAdapterExtension,
type InlineDeltaToPlainTextAdapterMatcher,
InlineDeltaToPlainTextAdapterMatcherIdentifier,
type PlainText,
PlainTextAdapter,
PlainTextAdapterFactoryExtension,
PlainTextAdapterFactoryIdentifier,
PlainTextDeltaConverter,
} from './plain-text';
export {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { createIdentifier } from '@blocksuite/global/di';
import type { ExtensionType } from '@blocksuite/block-std';
import {
createIdentifier,
type ServiceIdentifier,
} from '@blocksuite/global/di';
import type { DeltaInsert } from '@blocksuite/inline';

import type { AffineTextAttributes } from '../../types/index.js';
Expand All @@ -17,6 +21,22 @@ export const InlineDeltaToPlainTextAdapterMatcherIdentifier =
'InlineDeltaToPlainTextAdapterMatcher'
);

export function InlineDeltaToPlainTextAdapterExtension(
matcher: InlineDeltaToPlainTextAdapterMatcher
): ExtensionType & {
identifier: ServiceIdentifier<InlineDeltaToPlainTextAdapterMatcher>;
} {
const identifier = InlineDeltaToPlainTextAdapterMatcherIdentifier(
matcher.name
);
return {
setup: di => {
di.addImpl(identifier, () => matcher);
},
identifier,
};
}

export type PlainTextASTToDeltaMatcher = ASTToDeltaMatcher<string>;

export class PlainTextDeltaConverter extends DeltaASTConverter<
Expand Down
2 changes: 1 addition & 1 deletion blocksuite/affine/shared/src/adapters/plain-text/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export * from './block-adapter.js';
export * from './delta-converter.js';
export * from './type.js';
export * from './plain-text.js';
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,8 @@ import {
DEFAULT_NOTE_BACKGROUND_COLOR,
NoteDisplayMode,
} from '@blocksuite/affine-model';
import {
type AdapterContext,
AdapterFactoryIdentifier,
type BlockPlainTextAdapterMatcher,
BlockPlainTextAdapterMatcherIdentifier,
type PlainText,
PlainTextDeltaConverter,
type TextBuffer,
} from '@blocksuite/affine-shared/adapters';
import type { ExtensionType } from '@blocksuite/block-std';
import type { ServiceProvider } from '@blocksuite/global/di';
import {
type AssetsManager,
ASTWalker,
Expand All @@ -32,8 +24,21 @@ import {
type ToDocSnapshotPayload,
} from '@blocksuite/store';

import { defaultBlockPlainTextAdapterMatchers } from './block-matcher.js';
import { inlineDeltaToPlainTextAdapterMatchers } from './delta-converter/inline-delta.js';
import {
type AdapterContext,
AdapterFactoryIdentifier,
type TextBuffer,
} from '../types';
import {
type BlockPlainTextAdapterMatcher,
BlockPlainTextAdapterMatcherIdentifier,
} from './block-adapter';
import {
InlineDeltaToPlainTextAdapterMatcherIdentifier,
PlainTextDeltaConverter,
} from './delta-converter';

export type PlainText = string;

type PlainTextToSliceSnapshotPayload = {
file: PlainText;
Expand All @@ -46,11 +51,20 @@ type PlainTextToSliceSnapshotPayload = {
export class PlainTextAdapter extends BaseAdapter<PlainText> {
deltaConverter: PlainTextDeltaConverter;

readonly blockMatchers: BlockPlainTextAdapterMatcher[];

constructor(
job: Job,
readonly blockMatchers: BlockPlainTextAdapterMatcher[] = defaultBlockPlainTextAdapterMatchers
readonly provider: ServiceProvider
) {
super(job);
const blockMatchers = Array.from(
provider.getAll(BlockPlainTextAdapterMatcherIdentifier).values()
);
const inlineDeltaToPlainTextAdapterMatchers = Array.from(
provider.getAll(InlineDeltaToPlainTextAdapterMatcherIdentifier).values()
);
this.blockMatchers = blockMatchers;
this.deltaConverter = new PlainTextDeltaConverter(
job.adapterConfigs,
inlineDeltaToPlainTextAdapterMatchers,
Expand Down Expand Up @@ -78,6 +92,7 @@ export class PlainTextAdapter extends BaseAdapter<PlainText> {
configs: this.configs,
job: this.job,
deltaConverter: this.deltaConverter,
provider: this.provider,
textBuffer,
};
await matcher.fromBlockSnapshot.enter?.(o, adapterContext);
Expand All @@ -93,6 +108,7 @@ export class PlainTextAdapter extends BaseAdapter<PlainText> {
configs: this.configs,
job: this.job,
deltaConverter: this.deltaConverter,
provider: this.provider,
textBuffer,
};
await matcher.fromBlockSnapshot.leave?.(o, adapterContext);
Expand Down Expand Up @@ -309,13 +325,7 @@ export const PlainTextAdapterFactoryIdentifier =
export const PlainTextAdapterFactoryExtension: ExtensionType = {
setup: di => {
di.addImpl(PlainTextAdapterFactoryIdentifier, provider => ({
get: (job: Job) =>
new PlainTextAdapter(
job,
Array.from(
provider.getAll(BlockPlainTextAdapterMatcherIdentifier).values()
)
),
get: (job: Job) => new PlainTextAdapter(job, provider),
}));
},
};
1 change: 0 additions & 1 deletion blocksuite/affine/shared/src/adapters/plain-text/type.ts

This file was deleted.

3 changes: 2 additions & 1 deletion blocksuite/affine/shared/src/adapters/types/adapter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createIdentifier } from '@blocksuite/global/di';
import { createIdentifier, type ServiceProvider } from '@blocksuite/global/di';
import type { BaseTextAttributes, DeltaInsert } from '@blocksuite/inline';
import {
type AssetsManager,
Expand Down Expand Up @@ -38,6 +38,7 @@ export type AdapterContext<
job: Job;
deltaConverter: TConverter;
textBuffer: TextBuffer;
provider?: ServiceProvider;
assets?: AssetsManager;
pageMap?: Map<string, string>;
updateAssetIds?: (assetsId: string) => void;
Expand Down
Loading

0 comments on commit cadb921

Please sign in to comment.