refactor: reorganize specs and adapter extensions (#10359)

### TL;DR
Refactored `SpecProvider` singleton access pattern and reorganized adapter/extension code structure.

### What changed?
- Changed `SpecProvider.getInstance()` to `SpecProvider._` for cleaner singleton access
- Moved adapter/extension code from `_common` directory to dedicated `adapters` and `extensions` folders
- Consolidated adapter extensions into a single file
- Removed unused dependencies from package.json
- Deleted unnecessary schema files
- Extracted `MobileSpecsPatches` class into the mobile patching code
- Updated all references to use the new `SpecProvider._` accessor

### How to test?
- Verify all specs are properly registered and accessible via `SpecProvider._`
- Test adapter functionality for HTML, Markdown, Notion HTML and plain text
- Check mobile-specific features and patches work correctly
- Ensure preview functionality works in both page and edgeless modes

### Why make this change?
- Improves code organization by properly separating adapters and extensions
- Simplifies singleton access pattern
- Removes unnecessary dependencies and files
- Makes the codebase more maintainable by consolidating related functionality
This commit is contained in:
Saul-Mirone
2025-02-21 14:25:35 +00:00
parent 72b751943c
commit 2cf9a8f286
49 changed files with 224 additions and 320 deletions

View File

@@ -244,11 +244,10 @@ export const extendEdgelessPreviewSpec = (function () {
if (framework === _framework && _extension) {
return _extension;
} else {
_extension &&
SpecProvider.getInstance().omitSpec('preview:edgeless', _extension);
_extension && SpecProvider._.omitSpec('preview:edgeless', _extension);
_extension = getThemeExtension(framework);
_framework = framework;
SpecProvider.getInstance().extendSpec('preview:edgeless', [_extension]);
SpecProvider._.extendSpec('preview:edgeless', [_extension]);
return _extension;
}
};

View File

@@ -32,11 +32,15 @@ import { I18n } from '@affine/i18n';
import { track } from '@affine/track';
import {
BlockServiceWatcher,
type BlockStdScope,
BlockViewIdentifier,
ConfigIdentifier,
LifeCycleWatcher,
type WidgetComponent,
} from '@blocksuite/affine/block-std';
import type {
AffineReference,
CodeBlockConfig,
DocMode,
DocModeProvider,
OpenDocConfig,
@@ -44,6 +48,7 @@ import type {
PeekOptions,
PeekViewService as BSPeekViewService,
QuickSearchResult,
ReferenceNodeConfig,
RootBlockConfig,
} from '@blocksuite/affine/blocks';
import {
@@ -52,20 +57,23 @@ import {
DocModeExtension,
EdgelessRootBlockComponent,
EmbedLinkedDocBlockComponent,
FeatureFlagService,
GenerateDocUrlExtension,
insertLinkByQuickSearchCommand,
MobileSpecsPatches,
NativeClipboardExtension,
NoteConfigExtension,
NotificationExtension,
OpenDocExtension,
ParagraphBlockService,
ParseDocUrlExtension,
PeekViewExtension,
QuickSearchExtension,
ReferenceNodeConfigExtension,
ReferenceNodeConfigIdentifier,
RootBlockConfigExtension,
SidebarExtension,
} from '@blocksuite/affine/blocks';
import type { Container } from '@blocksuite/affine/global/di';
import { Bound } from '@blocksuite/affine/global/utils';
import {
type BlockSnapshot,
@@ -602,6 +610,66 @@ export function patchForSharedPage() {
}
export function patchForMobile() {
class MobileSpecsPatches extends LifeCycleWatcher {
static override key = 'mobile-patches';
constructor(std: BlockStdScope) {
super(std);
const featureFlagService = std.get(FeatureFlagService);
featureFlagService.setFlag('enable_mobile_keyboard_toolbar', 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;
});
}
}
override mounted() {
// remove slash placeholder for mobile: `type / ...`
{
const paragraphService = this.std.get(ParagraphBlockService);
if (!paragraphService) return;
paragraphService.placeholderGenerator = model => {
const placeholders = {
text: '',
h1: 'Heading 1',
h2: 'Heading 2',
h3: 'Heading 3',
h4: 'Heading 4',
h5: 'Heading 5',
h6: 'Heading 6',
quote: '',
};
return placeholders[model.type];
};
}
}
}
const extensions: ExtensionType[] = [
{
setup: di => {

View File

@@ -17,7 +17,7 @@ export function createEdgelessModeSpecs(
): SpecBuilder {
const featureFlagService = framework.get(FeatureFlagService);
const enableAI = featureFlagService.flags.enable_ai.value;
const edgelessSpec = SpecProvider.getInstance().getSpec('edgeless');
const edgelessSpec = SpecProvider._.getSpec('edgeless');
enableAffineExtension(framework, edgelessSpec);
if (enableAI) {
enableAIExtension(edgelessSpec);

View File

@@ -12,7 +12,7 @@ import { enableAffineExtension, enableAIExtension } from './custom/root-block';
export function createPageModeSpecs(framework: FrameworkProvider): SpecBuilder {
const featureFlagService = framework.get(FeatureFlagService);
const enableAI = featureFlagService.flags.enable_ai.value;
const provider = SpecProvider.getInstance();
const provider = SpecProvider._;
const pageSpec = provider.getSpec('page');
enableAffineExtension(framework, pageSpec);
if (enableAI) {

View File

@@ -33,7 +33,7 @@ function patchPreviewSpec(
id: 'preview:edgeless' | 'preview:page',
specs: ExtensionType[]
) {
const specProvider = SpecProvider.getInstance();
const specProvider = SpecProvider._;
specProvider.extendSpec(id, specs);
}
@@ -100,7 +100,7 @@ export function getPagePreviewThemeExtension(framework: FrameworkProvider) {
export function createPageModePreviewSpecs(
framework: FrameworkProvider
): SpecBuilder {
const specProvider = SpecProvider.getInstance();
const specProvider = SpecProvider._;
const pagePreviewSpec = specProvider.getSpec('preview:page');
// Enable theme extension, doc display meta extension and peek view service
const peekViewService = framework.get(PeekViewService);