|
1 | 1 | import type {ReactNode} from 'react'; |
2 | 2 |
|
3 | | -import type {Extension as CodemirrorExtension} from '@codemirror/state'; |
4 | 3 | import {EditorView as CMEditorView} from '@codemirror/view'; |
5 | 4 | import {TextSelection} from 'prosemirror-state'; |
6 | 5 | import {EditorView as PMEditorView} from 'prosemirror-view'; |
7 | 6 |
|
8 | | -import {CommonEditor, MarkupString} from '../common'; |
9 | | -import {ActionStorage, WysiwygEditor, WysiwygEditorOptions} from '../core'; |
10 | | -import {ReactRenderStorage, RenderStorage} from '../extensions'; |
| 7 | +import type {CommonEditor, MarkupString} from '../common'; |
| 8 | +import { |
| 9 | + type ActionStorage, |
| 10 | + type EscapeConfig, |
| 11 | + WysiwygEditor, |
| 12 | + type WysiwygEditorOptions, |
| 13 | +} from '../core'; |
| 14 | +import {ReactRenderStorage, type RenderStorage} from '../extensions'; |
11 | 15 | import {i18n} from '../i18n/bundle'; |
12 | 16 | import {logger} from '../logger'; |
13 | | -import {type CreateCodemirrorParams, createCodemirror} from '../markup/codemirror'; |
14 | | -import type {YfmLangOptions} from '../markup/codemirror/yfm'; |
15 | | -import {CodeEditor, Editor as MarkupEditor} from '../markup/editor'; |
16 | | -import {Emitter, Receiver, SafeEventEmitter} from '../utils/event-emitter'; |
| 17 | +import {createCodemirror} from '../markup/codemirror'; |
| 18 | +import {type CodeEditor, Editor as MarkupEditor} from '../markup/editor'; |
| 19 | +import {type Emitter, type Receiver, SafeEventEmitter} from '../utils/event-emitter'; |
17 | 20 | import type {FileUploadHandler} from '../utils/upload'; |
18 | 21 |
|
19 | | -export type EditorMode = 'wysiwyg' | 'markup'; |
20 | | -export type SplitMode = false | 'horizontal' | 'vertical'; |
21 | | -export type EditorPreset = 'zero' | 'commonmark' | 'default' | 'yfm' | 'full'; |
22 | | -export type RenderPreview = ({ |
23 | | - getValue, |
24 | | - mode, |
25 | | -}: { |
26 | | - getValue: () => MarkupString; |
27 | | - mode: 'preview' | 'split'; |
28 | | -}) => ReactNode; |
| 22 | +import type { |
| 23 | + MarkdownEditorMode as EditorMode, |
| 24 | + MarkdownEditorPreset as EditorPreset, |
| 25 | + MarkdownEditorOptions, |
| 26 | + MarkdownEditorMarkupConfig as MarkupConfig, |
| 27 | + RenderPreview, |
| 28 | + MarkdownEditorSplitMode as SplitMode, |
| 29 | +} from './types'; |
29 | 30 |
|
30 | 31 | export type ToolbarActionData = { |
31 | 32 | editorMode: EditorMode; |
@@ -105,72 +106,18 @@ export interface EditorInt |
105 | 106 |
|
106 | 107 | type SetEditorModeOptions = Pick<ChangeEditorModeOptions, 'emit'>; |
107 | 108 |
|
108 | | -type ChangeEditorModeOptions = { |
| 109 | +export type ChangeEditorModeOptions = { |
109 | 110 | mode: EditorMode; |
110 | 111 | reason: 'error-boundary' | 'settings' | 'manually'; |
111 | 112 | emit?: boolean; |
112 | 113 | }; |
113 | 114 |
|
114 | | -export type MarkupConfig = { |
115 | | - /** Additional extensions for codemirror instance. */ |
116 | | - extensions?: CreateCodemirrorParams['extensions']; |
117 | | - /** Can be used to disable some of the default extensions */ |
118 | | - disabledExtensions?: CreateCodemirrorParams['disabledExtensions']; |
119 | | - /** Additional keymaps for codemirror instance */ |
120 | | - keymaps?: CreateCodemirrorParams['keymaps']; |
121 | | - /** Overrides the default placeholder content. */ |
122 | | - placeholder?: CreateCodemirrorParams['placeholder']; |
123 | | - /** |
124 | | - * Additional language data for markdown language in codemirror. |
125 | | - * Can be used to configure additional autocompletions and others. |
126 | | - * See more https://codemirror.net/docs/ref/#state.EditorState.languageDataAt |
127 | | - */ |
128 | | - languageData?: YfmLangOptions['languageData']; |
129 | | - /** Config for @codemirror/autocomplete https://codemirror.net/docs/ref/#autocomplete.autocompletion%5Econfig */ |
130 | | - autocompletion?: CreateCodemirrorParams['autocompletion']; |
131 | | -}; |
132 | | - |
133 | | -export type EscapeConfig = { |
134 | | - commonEscape?: RegExp; |
135 | | - startOfLineEscape?: RegExp; |
136 | | -}; |
137 | | - |
138 | 115 | export type EditorOptions = Pick< |
139 | | - WysiwygEditorOptions, |
140 | | - 'allowHTML' | 'linkify' | 'linkifyTlds' | 'extensions' |
| 116 | + MarkdownEditorOptions, |
| 117 | + 'md' | 'initial' | 'handlers' | 'experimental' | 'markupConfig' | 'wysiwygConfig' |
141 | 118 | > & { |
142 | | - initialMarkup?: MarkupString; |
143 | | - /** @default 'wysiwyg' */ |
144 | | - initialEditorMode?: EditorMode; |
145 | | - /** @default true */ |
146 | | - initialToolbarVisible?: boolean; |
147 | | - /** @default false |
148 | | - * Has no effect if splitMode is false or undefined |
149 | | - */ |
150 | | - initialSplitModeEnabled?: boolean; |
151 | 119 | renderStorage: ReactRenderStorage; |
152 | | - fileUploadHandler?: FileUploadHandler; |
153 | | - /** |
154 | | - * If we need to set dimensions for uploaded images |
155 | | - * |
156 | | - * @default false |
157 | | - */ |
158 | | - needToSetDimensionsForUploadedImages?: boolean; |
159 | | - /** |
160 | | - * Called before switching from the markup editor to the wysiwyg editor. |
161 | | - * You can use it to pre-process the value from the markup editor before it gets into the wysiwyg editor. |
162 | | - */ |
163 | | - prepareRawMarkup?: (value: MarkupString) => MarkupString; |
164 | | - experimental_beforeEditorModeChange?: ( |
165 | | - options: Pick<ChangeEditorModeOptions, 'mode' | 'reason'>, |
166 | | - ) => boolean | undefined; |
167 | | - splitMode?: SplitMode; |
168 | | - renderPreview?: RenderPreview; |
169 | 120 | preset: EditorPreset; |
170 | | - /** @deprecated Put extra extensions via MarkdownEditorMarkupConfig */ |
171 | | - extraMarkupExtensions?: CodemirrorExtension[]; |
172 | | - markupConfig?: MarkupConfig; |
173 | | - escapeConfig?: EscapeConfig; |
174 | 121 | }; |
175 | 122 |
|
176 | 123 | /** @internal */ |
@@ -337,30 +284,39 @@ export class EditorImpl extends SafeEventEmitter<EventMapInt> implements EditorI |
337 | 284 |
|
338 | 285 | constructor(opts: EditorOptions) { |
339 | 286 | super({onError: logger.error.bind(logger)}); |
340 | | - this.#editorMode = opts.initialEditorMode ?? 'wysiwyg'; |
341 | | - this.#toolbarVisible = Boolean(opts.initialToolbarVisible); |
342 | | - this.#splitMode = (opts.renderPreview && opts.splitMode) ?? false; |
343 | | - this.#splitModeEnabled = (this.#splitMode && opts.initialSplitModeEnabled) ?? false; |
344 | | - this.#renderPreview = opts.renderPreview; |
345 | 287 |
|
346 | | - this.#markup = opts.initialMarkup ?? ''; |
| 288 | + const { |
| 289 | + md = {}, |
| 290 | + initial = {}, |
| 291 | + handlers = {}, |
| 292 | + experimental = {}, |
| 293 | + markupConfig = {}, |
| 294 | + wysiwygConfig = {}, |
| 295 | + } = opts; |
| 296 | + |
| 297 | + this.#editorMode = initial.mode ?? 'wysiwyg'; |
| 298 | + this.#toolbarVisible = initial.toolbarVisible ?? true; |
| 299 | + this.#splitMode = (markupConfig.renderPreview && markupConfig.splitMode) ?? false; |
| 300 | + this.#splitModeEnabled = (this.#splitMode && initial.splitModeEnabled) ?? false; |
| 301 | + this.#renderPreview = markupConfig.renderPreview; |
| 302 | + |
| 303 | + this.#markup = initial.markup ?? ''; |
347 | 304 |
|
348 | 305 | this.#preset = opts.preset ?? 'full'; |
349 | | - this.#linkify = opts.linkify; |
350 | | - this.#linkifyTlds = opts.linkifyTlds; |
351 | | - this.#allowHTML = opts.allowHTML; |
352 | | - this.#extensions = opts.extensions; |
| 306 | + this.#linkify = md.linkify; |
| 307 | + this.#linkifyTlds = md.linkifyTlds; |
| 308 | + this.#allowHTML = md.html; |
| 309 | + this.#extensions = wysiwygConfig.extensions; |
353 | 310 | this.#markupConfig = {...opts.markupConfig}; |
354 | | - this.#markupConfig.extensions ??= opts.extraMarkupExtensions; |
355 | 311 |
|
356 | 312 | this.#renderStorage = opts.renderStorage; |
357 | | - this.#fileUploadHandler = opts.fileUploadHandler; |
| 313 | + this.#fileUploadHandler = handlers.uploadFile; |
358 | 314 | this.#needToSetDimensionsForUploadedImages = Boolean( |
359 | | - opts.needToSetDimensionsForUploadedImages, |
| 315 | + experimental.needToSetDimensionsForUploadedImages, |
360 | 316 | ); |
361 | | - this.#prepareRawMarkup = opts.prepareRawMarkup; |
362 | | - this.#escapeConfig = opts.escapeConfig; |
363 | | - this.#beforeEditorModeChange = opts.experimental_beforeEditorModeChange; |
| 317 | + this.#prepareRawMarkup = experimental.prepareRawMarkup; |
| 318 | + this.#escapeConfig = wysiwygConfig.escapeConfig; |
| 319 | + this.#beforeEditorModeChange = experimental.beforeEditorModeChange; |
364 | 320 | } |
365 | 321 |
|
366 | 322 | // ---> implements CodeEditor |
|
0 commit comments