Skip to content

Commit 66de15e

Browse files
committed
feat(core)!: use one builder for all plug-in extensions
1 parent dc66438 commit 66de15e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+170
-361
lines changed

demo/Playground.tsx

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ import {RadioButton, TextInput} from '@gravity-ui/uikit';
55
import {
66
BasePreset,
77
BehaviorPreset,
8-
createExtension,
98
MarkdownBlocksPreset,
109
MarkdownMarksPreset,
1110
MarkupString,
1211
YfmEditorComponent,
1312
useYfmEditor,
1413
YfmPreset,
14+
Extension,
1515
} from '../src';
1616
import {PlaygroundHtmlPreview} from './HtmlPreview';
1717
import {logger} from '../src/index';
@@ -43,33 +43,31 @@ export const Playground = React.memo<PlaygroundProps>((props) => {
4343
const [previewType, setPreviewType] = React.useState<string>(PreviewType.Markup);
4444
const [yfmRaw, setYfmRaw] = React.useState<MarkupString>(initial || '');
4545

46-
const extensions = React.useMemo(() => {
47-
return [
48-
createExtension((builder) =>
49-
builder
50-
.use(BasePreset, {})
51-
.use(BehaviorPreset, {
52-
history: {
53-
undoKey: keys.undo,
54-
redoKey: keys.redo,
55-
},
56-
})
57-
.use(MarkdownBlocksPreset, {
58-
image: false,
59-
heading: false,
60-
breaks: {preferredBreak: breaks ? 'soft' : 'hard'},
61-
})
62-
.use(MarkdownMarksPreset, {
63-
bold: {boldKey: keys.bold},
64-
italic: {italicKey: keys.italic},
65-
strike: {strikeKey: keys.strike},
66-
underline: {underlineKey: keys.underline},
67-
code: {codeKey: keys.code},
68-
})
69-
.use(YfmPreset, {}),
70-
)(),
71-
];
72-
}, [breaks]);
46+
const extensions = React.useMemo<Extension>(
47+
() => (builder) =>
48+
builder
49+
.use(BasePreset, {})
50+
.use(BehaviorPreset, {
51+
history: {
52+
undoKey: keys.undo,
53+
redoKey: keys.redo,
54+
},
55+
})
56+
.use(MarkdownBlocksPreset, {
57+
image: false,
58+
heading: false,
59+
breaks: {preferredBreak: breaks ? 'soft' : 'hard'},
60+
})
61+
.use(MarkdownMarksPreset, {
62+
bold: {boldKey: keys.bold},
63+
italic: {italicKey: keys.italic},
64+
strike: {strikeKey: keys.strike},
65+
underline: {underlineKey: keys.underline},
66+
code: {codeKey: keys.code},
67+
})
68+
.use(YfmPreset, {}),
69+
[breaks],
70+
);
7371

7472
const editor = useYfmEditor({
7573
linkify,

src/core/Editor.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {EditorView} from 'prosemirror-view';
22
import {EditorState} from 'prosemirror-state';
33

44
import type {CommonEditor, ContentHandler, MarkupString} from '../common';
5-
import type {ExtensionSpec} from './types/extension';
5+
import type {Extension} from './types/extension';
66
import {bindActions} from './utils/actions';
77
import type {Serializer} from './types/serializer';
88
import {ExtensionsManager} from './ExtensionsManager';
@@ -17,7 +17,7 @@ export type YfmEditorOptions = {
1717
domElem?: Element;
1818
/** yfm markup */
1919
initialContent?: string;
20-
extensions?: ExtensionSpec[];
20+
extensions?: Extension;
2121
allowHTML?: boolean;
2222
linkify?: boolean;
2323
/** markdown-it-attrs options */
@@ -48,7 +48,7 @@ export class YfmEditor implements CommonEditor, ActionStorage {
4848
constructor({
4949
domElem,
5050
initialContent = '',
51-
extensions = [],
51+
extensions = () => {},
5252
attrs: attrsOpts,
5353
allowHTML,
5454
linkify,

src/core/ExtensionsManager.ts

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
import MarkdownIt from 'markdown-it';
22
import type {Plugin} from 'prosemirror-state';
33
import {ActionsManager} from './ActionsManager';
4+
import {ExtensionBuilder} from './ExtensionBuilder';
45
import {ParserTokensRegistry} from './ParserTokensRegistry';
56
import {SchemaSpecRegistry} from './SchemaSpecRegistry';
67
import {SerializerTokensRegistry} from './SerializerTokensRegistry';
78
import type {ActionSpec} from './types/actions';
8-
import type {ExtensionDeps, ExtensionSpec, YEMarkSpec, YENodeSpec} from './types/extension';
9+
import type {
10+
Extension,
11+
ExtensionDeps,
12+
ExtensionSpec,
13+
YEMarkSpec,
14+
YENodeSpec,
15+
} from './types/extension';
916
import type {MarkViewConstructor, NodeViewConstructor} from './types/node-views';
1017

1118
const attrs = require('markdown-it-attrs');
1219

1320
type ExtensionsManagerParams = {
14-
extensions: ExtensionSpec[];
21+
extensions: Extension;
1522
options?: ExtensionsManagerOptions;
1623
};
1724

@@ -25,7 +32,7 @@ type ExtensionsManagerOptions = {
2532
};
2633

2734
export class ExtensionsManager {
28-
static process(extensions: ExtensionSpec[], options: ExtensionsManagerOptions) {
35+
static process(extensions: Extension, options: ExtensionsManagerOptions) {
2936
return new this({extensions, options}).build();
3037
}
3138

@@ -38,8 +45,10 @@ export class ExtensionsManager {
3845

3946
#md: MarkdownIt;
4047
#mdWithoutAttrs: MarkdownIt;
41-
#extensions: ExtensionSpec[];
48+
#extensions: Extension;
49+
#builder: ExtensionBuilder;
4250

51+
#spec!: ExtensionSpec;
4352
#deps!: ExtensionDeps;
4453
#plugins: Plugin[] = [];
4554
#actions: Record<string, ActionSpec> = {};
@@ -51,6 +60,9 @@ export class ExtensionsManager {
5160

5261
this.#md = new MarkdownIt(options.mdOpts ?? {}).use(attrs, options.attrsOpts ?? {});
5362
this.#mdWithoutAttrs = new MarkdownIt(options.mdOpts ?? {});
63+
64+
// TODO: add prefilled context
65+
this.#builder = new ExtensionBuilder();
5466
}
5567

5668
build() {
@@ -75,12 +87,11 @@ export class ExtensionsManager {
7587
}
7688

7789
private processExtensions() {
78-
for (const ext of this.#extensions) {
79-
this.#md = ext.configureMd(this.#md);
80-
this.#mdWithoutAttrs = ext.configureMd(this.#mdWithoutAttrs);
81-
ext.nodes().forEach(this.processNode);
82-
ext.marks().forEach(this.processMark);
83-
}
90+
this.#spec = this.#builder.use(this.#extensions).build();
91+
this.#md = this.#spec.configureMd(this.#md);
92+
this.#mdWithoutAttrs = this.#spec.configureMd(this.#mdWithoutAttrs);
93+
this.#spec.nodes().forEach(this.processNode);
94+
this.#spec.marks().forEach(this.processMark);
8495
}
8596

8697
private processNode = (name: string, {spec, fromYfm, toYfm, view}: YENodeSpec) => {
@@ -114,10 +125,8 @@ export class ExtensionsManager {
114125

115126
private createDerived() {
116127
const plugins: {plugin: Plugin; priority: number}[] = [];
117-
for (const ext of this.#extensions) {
118-
plugins.push(...ext.plugins(this.#deps));
119-
Object.assign(this.#actions, ext.actions(this.#deps));
120-
}
128+
plugins.push(...this.#spec.plugins(this.#deps));
129+
Object.assign(this.#actions, this.#spec.actions(this.#deps));
121130

122131
// TODO: move sorting to ExtensionBuilder after WIKI-16660
123132
this.#plugins = plugins.sort((a, b) => b.priority - a.priority).map((item) => item.plugin);

src/core/createExtension.ts

Lines changed: 0 additions & 11 deletions
This file was deleted.

src/core/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
export * from './Editor';
22
export * from './ExtensionBuilder';
33
export * from './ExtensionsManager';
4-
export * from './createExtension';
54
export {bindActions} from './utils/actions';
65
export {trackTransactionMetrics} from './utils/metrics';
76
export type {Keymap} from './types/keymap';
@@ -10,7 +9,6 @@ export type {
109
Extension,
1110
ExtensionAuto,
1211
ExtensionWithOptions,
13-
ExtensionSpec,
1412
ExtensionDeps,
1513
YENodeSpec,
1614
YEMarkSpec,

src/extensions/base/BaseSchema/BaseSchema.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import {builders} from 'prosemirror-test-builder';
22
import {createMarkupChecker} from '../../../../tests/sameMarkup';
33
import {ExtensionsManager} from '../../../core';
4-
import {BaseNode, BaseSchemaE} from './index';
4+
import {BaseNode, BaseSchema} from './index';
55

66
const {schema, parser, serializer} = new ExtensionsManager({
7-
extensions: [BaseSchemaE()],
7+
extensions: (builder) => builder.use(BaseSchema, {}),
88
}).buildDeps();
99

1010
const {doc, p} = builders(schema, {

src/extensions/base/BaseSchema/index.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type {NodeSpec} from 'prosemirror-model';
22
import type {Command} from 'prosemirror-state';
33
import {setBlockType} from 'prosemirror-commands';
44
import {hasParentNodeOfType} from 'prosemirror-utils';
5-
import {Action, createExtension, ExtensionAuto} from '../../../core';
5+
import type {Action, ExtensionAuto} from '../../../core';
66
import {nodeTypeFactory} from '../../../utils/schema';
77

88
export enum BaseNode {
@@ -82,13 +82,6 @@ export const BaseSchema: ExtensionAuto<BaseSchemaOptions> = (builder, opts) => {
8282
});
8383
};
8484

85-
/**
86-
* @deprecated
87-
* For tests only.
88-
* Remove after WIKI-16660
89-
*/
90-
export const BaseSchemaE = createExtension<BaseSchemaOptions>((b, o) => b.use(BaseSchema, o ?? {}));
91-
9285
declare global {
9386
namespace YfmEditor {
9487
interface Actions {

src/extensions/base/index.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {createExtension, ExtensionAuto} from '../../core';
1+
import type {ExtensionAuto} from '../../core';
22

33
import {BaseSchema, BaseSchemaOptions} from './BaseSchema';
44
import {BaseInputRules} from './BaseInputRules';
@@ -21,6 +21,3 @@ export const BasePreset: ExtensionAuto<BasePresetOptions> = (builder, opts) => {
2121
.use(BaseInputRules)
2222
.use(BaseStyles);
2323
};
24-
25-
/** @deprecated */
26-
export const BasePresetE = createExtension<BasePresetOptions>((b, o = {}) => b.use(BasePreset, o));

src/extensions/markdown/Blockquote/Blockquote.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import {builders} from 'prosemirror-test-builder';
22
import {createMarkupChecker} from '../../../../tests/sameMarkup';
33
import {ExtensionsManager} from '../../../core';
4-
import {BaseNode, BaseSchemaE} from '../../base/BaseSchema';
5-
import {blockquote, BlockquoteE} from './index';
4+
import {BaseNode, BaseSchema} from '../../base/BaseSchema';
5+
import {blockquote, Blockquote} from './index';
66

77
const {schema, parser, serializer} = new ExtensionsManager({
8-
extensions: [BaseSchemaE(), BlockquoteE()],
8+
extensions: (builder) => builder.use(BaseSchema, {}).use(Blockquote, {}),
99
}).buildDeps();
1010

1111
const {doc, p, q} = builders(schema, {

src/extensions/markdown/Blockquote/index.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {chainCommands, wrapIn} from 'prosemirror-commands';
22
import type {NodeType} from 'prosemirror-model';
33
import {wrappingInputRule} from 'prosemirror-inputrules';
44
import {hasParentNodeOfType} from 'prosemirror-utils';
5-
import {Action, createExtension, ExtensionAuto} from '../../../core';
5+
import type {Action, ExtensionAuto} from '../../../core';
66
import {selectQuoteBeforeCursor, liftFromQuote, toggleQuote} from './commands';
77
import {blockquote, bqType} from './const';
88

@@ -51,13 +51,6 @@ export const Blockquote: ExtensionAuto<BlockquoteOptions> = (builder, opts) => {
5151
});
5252
};
5353

54-
/**
55-
* @deprecated
56-
* For tests only.
57-
* Remove after WIKI-16660
58-
*/
59-
export const BlockquoteE = createExtension<BlockquoteOptions>((b, o = {}) => b.use(Blockquote, o));
60-
6154
declare global {
6255
namespace YfmEditor {
6356
interface Actions {

0 commit comments

Comments
 (0)