refactor(editor): improve config extension (#11006)

This commit is contained in:
Saul-Mirone
2025-03-19 13:38:09 +00:00
parent c1e16aeaa7
commit 1c6a876e6a
6 changed files with 37 additions and 65 deletions

View File

@@ -11,7 +11,7 @@ import { FootNoteNodeConfigIdentifier } from './nodes/footnote-node/footnote-con
import { builtinInlineLinkToolbarConfig } from './nodes/link-node/configs/toolbar.js'; import { builtinInlineLinkToolbarConfig } from './nodes/link-node/configs/toolbar.js';
import { builtinInlineReferenceToolbarConfig } from './nodes/reference-node/configs/toolbar.js'; import { builtinInlineReferenceToolbarConfig } from './nodes/reference-node/configs/toolbar.js';
import { import {
ReferenceNodeConfigIdentifier, ReferenceNodeConfigExtension,
ReferenceNodeConfigProvider, ReferenceNodeConfigProvider,
} from './nodes/reference-node/reference-config.js'; } from './nodes/reference-node/reference-config.js';
@@ -123,7 +123,8 @@ export const ReferenceInlineSpecExtension = InlineSpecExtension(
provider => { provider => {
const std = provider.get(StdIdentifier); const std = provider.get(StdIdentifier);
const configProvider = new ReferenceNodeConfigProvider(std); const configProvider = new ReferenceNodeConfigProvider(std);
const config = provider.getOptional(ReferenceNodeConfigIdentifier) ?? {}; const config =
provider.getOptional(ReferenceNodeConfigExtension.identifier) ?? {};
if (config.customContent) { if (config.customContent) {
configProvider.setCustomContent(config.customContent); configProvider.setCustomContent(config.customContent);
} }

View File

@@ -1,6 +1,7 @@
import type { BlockStdScope } from '@blocksuite/block-std'; import {
import { createIdentifier } from '@blocksuite/global/di'; type BlockStdScope,
import type { ExtensionType } from '@blocksuite/store'; ConfigExtensionFactory,
} from '@blocksuite/block-std';
import type { TemplateResult } from 'lit'; import type { TemplateResult } from 'lit';
import type { AffineReference } from './reference-node'; import type { AffineReference } from './reference-node';
@@ -11,18 +12,8 @@ export interface ReferenceNodeConfig {
hidePopup?: boolean; hidePopup?: boolean;
} }
export const ReferenceNodeConfigIdentifier = export const ReferenceNodeConfigExtension =
createIdentifier<ReferenceNodeConfig>('AffineReferenceNodeConfig'); ConfigExtensionFactory<ReferenceNodeConfig>('AffineReferenceNodeConfig');
export function ReferenceNodeConfigExtension(
config: ReferenceNodeConfig
): ExtensionType {
return {
setup: di => {
di.addImpl(ReferenceNodeConfigIdentifier, () => ({ ...config }));
},
};
}
export class ReferenceNodeConfigProvider { export class ReferenceNodeConfigProvider {
private _customContent: private _customContent:

View File

@@ -6,13 +6,13 @@
# Function: ConfigExtensionFactory() # Function: ConfigExtensionFactory()
> **ConfigExtensionFactory**\<`Config`\>(`flavor`): (`config`) => `ExtensionType` & `object` > **ConfigExtensionFactory**\<`Config`\>(`configId`): `ConfigFactory`\<`Config`\>
Create a config extension. Create a config extension.
A config extension provides a configuration object for a block flavour. A config extension provides a configuration object for a block flavour.
The configuration object can be used like: The configuration object can be used like:
```ts ```ts
const config = std.provider.get(ConfigIdentifier('my-flavour')); const config = std.provider.getOptional(ConfigIdentifier('my-flavour'));
``` ```
## Type Parameters ## Type Parameters
@@ -23,15 +23,15 @@ const config = std.provider.get(ConfigIdentifier('my-flavour'));
## Parameters ## Parameters
### flavor ### configId
`string` `string`
The flavour of the block that the config is for. The id of the config. Should be unique for each config.
## Returns ## Returns
(`config`) => `ExtensionType` & `object` `ConfigFactory`\<`Config`\>
## Example ## Example

View File

@@ -3,16 +3,20 @@ import type { ExtensionType } from '@blocksuite/store';
import { ConfigIdentifier } from '../identifier.js'; import { ConfigIdentifier } from '../identifier.js';
export interface ConfigFactory<Config extends Record<string, any>> {
(config: Config): ExtensionType;
identifier: ServiceIdentifier<Config>;
}
/** /**
* Create a config extension. * Create a config extension.
* A config extension provides a configuration object for a block flavour. * A config extension provides a configuration object for a block flavour.
* The configuration object can be used like: * The configuration object can be used like:
* ```ts * ```ts
* const config = std.provider.get(ConfigIdentifier('my-flavour')); * const config = std.provider.getOptional(ConfigIdentifier('my-flavour'));
* ``` * ```
* *
* @param flavor The flavour of the block that the config is for. * @param configId The id of the config. Should be unique for each config.
* @param config The configuration object.
* *
* @example * @example
* ```ts * ```ts
@@ -25,14 +29,14 @@ import { ConfigIdentifier } from '../identifier.js';
* ``` * ```
*/ */
export function ConfigExtensionFactory<Config extends Record<string, any>>( export function ConfigExtensionFactory<Config extends Record<string, any>>(
flavor: string configId: string
): ((config: Config) => ExtensionType) & { ): ConfigFactory<Config> {
identifier: ServiceIdentifier<Config>; const identifier = ConfigIdentifier(configId) as ServiceIdentifier<Config>;
} {
const identifier = ConfigIdentifier(flavor) as ServiceIdentifier<Config>;
const extensionFactory = (config: Config): ExtensionType => ({ const extensionFactory = (config: Config): ExtensionType => ({
setup: di => { setup: di => {
di.override(ConfigIdentifier(flavor), () => config); di.override(ConfigIdentifier(configId), () => {
return config;
});
}, },
}); });
extensionFactory.identifier = identifier; extensionFactory.identifier = identifier;

View File

@@ -1,12 +1,13 @@
import { VirtualKeyboardProvider } from '@affine/core/mobile/modules/virtual-keyboard'; import { VirtualKeyboardProvider } from '@affine/core/mobile/modules/virtual-keyboard';
import { import {
type BlockStdScope, type BlockStdScope,
ConfigIdentifier,
LifeCycleWatcher, LifeCycleWatcher,
LifeCycleWatcherIdentifier, LifeCycleWatcherIdentifier,
} from '@blocksuite/affine/block-std'; } from '@blocksuite/affine/block-std';
import type { CodeBlockConfig } from '@blocksuite/affine/blocks/code'; import {
import { codeToolbarWidget } from '@blocksuite/affine/blocks/code'; CodeBlockConfigExtension,
codeToolbarWidget,
} from '@blocksuite/affine/blocks/code';
import { imageToolbarWidget } from '@blocksuite/affine/blocks/image'; import { imageToolbarWidget } from '@blocksuite/affine/blocks/image';
import { ParagraphBlockConfigExtension } from '@blocksuite/affine/blocks/paragraph'; import { ParagraphBlockConfigExtension } from '@blocksuite/affine/blocks/paragraph';
import { surfaceRefToolbarWidget } from '@blocksuite/affine/blocks/surface-ref'; import { surfaceRefToolbarWidget } from '@blocksuite/affine/blocks/surface-ref';
@@ -15,10 +16,6 @@ import type {
ServiceIdentifier, ServiceIdentifier,
} from '@blocksuite/affine/global/di'; } from '@blocksuite/affine/global/di';
import { DisposableGroup } from '@blocksuite/affine/global/disposable'; import { DisposableGroup } from '@blocksuite/affine/global/disposable';
import {
type ReferenceNodeConfig,
ReferenceNodeConfigIdentifier,
} from '@blocksuite/affine/rich-text';
import { import {
DocModeProvider, DocModeProvider,
FeatureFlagService, FeatureFlagService,
@@ -41,33 +38,6 @@ class MobileSpecsPatches extends LifeCycleWatcher {
featureFlagService.setFlag('enable_mobile_keyboard_toolbar', true); featureFlagService.setFlag('enable_mobile_keyboard_toolbar', true);
featureFlagService.setFlag('enable_mobile_linked_doc_menu', true); featureFlagService.setFlag('enable_mobile_linked_doc_menu', true);
} }
static override setup(di: Container) {
super.setup(di);
// Hide reference popup on mobile.
{
const prev = di.getFactory(ReferenceNodeConfigIdentifier);
di.override(ReferenceNodeConfigIdentifier, provider => {
return {
...prev?.(provider),
hidePopup: true,
} satisfies ReferenceNodeConfig;
});
}
// Hide number lines for code block on mobile.
{
const codeConfigIdentifier = ConfigIdentifier('affine:code');
const prev = di.getFactory(codeConfigIdentifier);
di.override(codeConfigIdentifier, provider => {
return {
...prev?.(provider),
showLineNumbers: false,
} satisfies CodeBlockConfig;
});
}
}
} }
const mobileParagraphConfig = ParagraphBlockConfigExtension({ const mobileParagraphConfig = ParagraphBlockConfigExtension({
@@ -86,6 +56,10 @@ const mobileParagraphConfig = ParagraphBlockConfigExtension({
}, },
}); });
const mobileCodeConfig = CodeBlockConfigExtension({
showLineNumbers: false,
});
function KeyboardToolbarExtension(framework: FrameworkProvider): ExtensionType { function KeyboardToolbarExtension(framework: FrameworkProvider): ExtensionType {
const affineVirtualKeyboardProvider = framework.get(VirtualKeyboardProvider); const affineVirtualKeyboardProvider = framework.get(VirtualKeyboardProvider);
@@ -169,5 +143,6 @@ export function enableMobileExtension(
MobileSpecsPatches, MobileSpecsPatches,
KeyboardToolbarExtension(framework), KeyboardToolbarExtension(framework),
mobileParagraphConfig, mobileParagraphConfig,
mobileCodeConfig,
]); ]);
} }

View File

@@ -19,5 +19,6 @@ export function patchReferenceRenderer(
return ReferenceNodeConfigExtension({ return ReferenceNodeConfigExtension({
customContent, customContent,
hidePopup: BUILD_CONFIG.isMobileEdition,
}); });
} }