@gravity-ui/markdown-editor 14.11.1 → 14.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/build/cjs/bundle/Editor.js +9 -2
  2. package/build/cjs/bundle/MarkupManager.d.ts +54 -0
  3. package/build/cjs/bundle/MarkupManager.js +68 -0
  4. package/build/cjs/bundle/config/dynamicModifiers.d.ts +3 -0
  5. package/build/cjs/bundle/config/dynamicModifiers.js +76 -0
  6. package/build/cjs/bundle/config/markup.js +7 -0
  7. package/build/cjs/bundle/config/previews/ActionPreview.css +45 -0
  8. package/build/cjs/bundle/config/previews/ActionPreview.d.ts +4 -0
  9. package/build/cjs/bundle/config/previews/ActionPreview.js +11 -0
  10. package/build/cjs/bundle/config/previews/HeadingPreview.d.ts +5 -0
  11. package/build/cjs/bundle/config/previews/HeadingPreview.js +16 -0
  12. package/build/cjs/bundle/config/previews/TextPreview.d.ts +1 -0
  13. package/build/cjs/bundle/config/previews/TextPreview.js +14 -0
  14. package/build/cjs/bundle/config/w-heading-config.js +11 -0
  15. package/build/cjs/bundle/toolbar/utils/toolbarsConfigs.js +2 -1
  16. package/build/cjs/bundle/types.d.ts +11 -0
  17. package/build/cjs/core/Editor.d.ts +2 -2
  18. package/build/cjs/core/Editor.js +16 -1
  19. package/build/cjs/core/ExtensionsManager.d.ts +12 -2
  20. package/build/cjs/core/ExtensionsManager.js +29 -13
  21. package/build/cjs/core/ParserTokensRegistry.d.ts +2 -1
  22. package/build/cjs/core/ParserTokensRegistry.js +2 -2
  23. package/build/cjs/core/SchemaDynamicModifier.d.ts +3 -0
  24. package/build/cjs/core/SchemaDynamicModifier.js +25 -0
  25. package/build/cjs/core/SchemaSpecRegistry.d.ts +2 -1
  26. package/build/cjs/core/SchemaSpecRegistry.js +9 -4
  27. package/build/cjs/core/SerializerTokensRegistry.d.ts +2 -1
  28. package/build/cjs/core/SerializerTokensRegistry.js +2 -2
  29. package/build/cjs/core/index.d.ts +2 -0
  30. package/build/cjs/core/markdown/MarkdownParser.d.ts +7 -3
  31. package/build/cjs/core/markdown/MarkdownParser.js +85 -16
  32. package/build/cjs/core/markdown/MarkdownSerializer.d.ts +4 -2
  33. package/build/cjs/core/markdown/MarkdownSerializer.js +16 -6
  34. package/build/cjs/core/markdown/MarkdownSerializerDynamicModifier.d.ts +1 -0
  35. package/build/cjs/core/markdown/MarkdownSerializerDynamicModifier.js +47 -0
  36. package/build/cjs/core/types/dynamicModifiers.d.ts +1 -0
  37. package/build/cjs/core/types/dynamicModifiers.js +2 -0
  38. package/build/cjs/core/utils/dynamicModifiers.d.ts +9 -0
  39. package/build/cjs/core/utils/dynamicModifiers.js +48 -0
  40. package/build/cjs/extensions/behavior/CommandMenu/component.d.ts +1 -1
  41. package/build/cjs/extensions/behavior/CommandMenu/component.js +10 -8
  42. package/build/cjs/i18n/action-previews/en.json +5 -0
  43. package/build/cjs/i18n/action-previews/index.d.ts +7 -0
  44. package/build/cjs/i18n/action-previews/index.js +9 -0
  45. package/build/cjs/i18n/action-previews/ru.json +5 -0
  46. package/build/cjs/modules/toolbars/items.js +9 -0
  47. package/build/cjs/modules/toolbars/types.d.ts +1 -0
  48. package/build/cjs/toolbar/PreviewTooltip.css +8 -0
  49. package/build/cjs/toolbar/PreviewTooltip.d.ts +7 -0
  50. package/build/cjs/toolbar/PreviewTooltip.js +13 -0
  51. package/build/cjs/toolbar/ToolbarListButton.js +23 -18
  52. package/build/cjs/toolbar/types.d.ts +1 -0
  53. package/build/cjs/version.js +1 -1
  54. package/build/esm/bundle/Editor.js +9 -2
  55. package/build/esm/bundle/MarkupManager.d.ts +54 -0
  56. package/build/esm/bundle/MarkupManager.js +64 -0
  57. package/build/esm/bundle/config/dynamicModifiers.d.ts +3 -0
  58. package/build/esm/bundle/config/dynamicModifiers.js +72 -0
  59. package/build/esm/bundle/config/markup.js +7 -0
  60. package/build/esm/bundle/config/previews/ActionPreview.css +45 -0
  61. package/build/esm/bundle/config/previews/ActionPreview.d.ts +5 -0
  62. package/build/esm/bundle/config/previews/ActionPreview.js +7 -0
  63. package/build/esm/bundle/config/previews/HeadingPreview.d.ts +6 -0
  64. package/build/esm/bundle/config/previews/HeadingPreview.js +12 -0
  65. package/build/esm/bundle/config/previews/TextPreview.d.ts +2 -0
  66. package/build/esm/bundle/config/previews/TextPreview.js +10 -0
  67. package/build/esm/bundle/config/w-heading-config.js +10 -0
  68. package/build/esm/bundle/toolbar/utils/toolbarsConfigs.js +2 -1
  69. package/build/esm/bundle/types.d.ts +11 -0
  70. package/build/esm/core/Editor.d.ts +2 -2
  71. package/build/esm/core/Editor.js +16 -1
  72. package/build/esm/core/ExtensionsManager.d.ts +12 -2
  73. package/build/esm/core/ExtensionsManager.js +29 -13
  74. package/build/esm/core/ParserTokensRegistry.d.ts +2 -1
  75. package/build/esm/core/ParserTokensRegistry.js +2 -2
  76. package/build/esm/core/SchemaDynamicModifier.d.ts +3 -0
  77. package/build/esm/core/SchemaDynamicModifier.js +21 -0
  78. package/build/esm/core/SchemaSpecRegistry.d.ts +2 -1
  79. package/build/esm/core/SchemaSpecRegistry.js +9 -4
  80. package/build/esm/core/SerializerTokensRegistry.d.ts +2 -1
  81. package/build/esm/core/SerializerTokensRegistry.js +2 -2
  82. package/build/esm/core/index.d.ts +2 -0
  83. package/build/esm/core/markdown/MarkdownParser.d.ts +7 -3
  84. package/build/esm/core/markdown/MarkdownParser.js +83 -15
  85. package/build/esm/core/markdown/MarkdownSerializer.d.ts +4 -2
  86. package/build/esm/core/markdown/MarkdownSerializer.js +16 -6
  87. package/build/esm/core/markdown/MarkdownSerializerDynamicModifier.d.ts +1 -0
  88. package/build/esm/core/markdown/MarkdownSerializerDynamicModifier.js +43 -0
  89. package/build/esm/core/types/dynamicModifiers.d.ts +1 -0
  90. package/build/esm/core/types/dynamicModifiers.js +1 -0
  91. package/build/esm/core/utils/dynamicModifiers.d.ts +9 -0
  92. package/build/esm/core/utils/dynamicModifiers.js +44 -0
  93. package/build/esm/extensions/behavior/CommandMenu/component.d.ts +1 -1
  94. package/build/esm/extensions/behavior/CommandMenu/component.js +10 -8
  95. package/build/esm/i18n/action-previews/en.json +5 -0
  96. package/build/esm/i18n/action-previews/index.d.ts +7 -0
  97. package/build/esm/i18n/action-previews/index.js +5 -0
  98. package/build/esm/i18n/action-previews/ru.json +5 -0
  99. package/build/esm/modules/toolbars/items.js +9 -0
  100. package/build/esm/modules/toolbars/types.d.ts +1 -0
  101. package/build/esm/toolbar/PreviewTooltip.css +8 -0
  102. package/build/esm/toolbar/PreviewTooltip.d.ts +8 -0
  103. package/build/esm/toolbar/PreviewTooltip.js +9 -0
  104. package/build/esm/toolbar/ToolbarListButton.js +23 -18
  105. package/build/esm/toolbar/types.d.ts +1 -0
  106. package/build/esm/version.js +1 -1
  107. package/build/styles.css +53 -0
  108. package/package.json +5 -4
@@ -0,0 +1,2 @@
1
+ import './ActionPreview.css';
2
+ export declare const TextPreview: () => JSX.Element;
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import { cn } from '../../../classname';
3
+ import { i18n } from '../../../i18n/action-previews';
4
+ import { ActionPreview } from './ActionPreview';
5
+ import './ActionPreview.css';
6
+ const b = cn('action-preview');
7
+ export const TextPreview = () => {
8
+ return (React.createElement(ActionPreview, null,
9
+ React.createElement("p", { className: b('text') }, i18n('text'))));
10
+ };
@@ -1,7 +1,10 @@
1
+ import React from 'react';
1
2
  import { i18n } from '../../i18n/menubar';
2
3
  import { Action as A, formatter as f } from '../../shortcuts';
3
4
  import { ActionName } from './action-names';
4
5
  import { icons } from './icons';
6
+ import { HeadingPreview } from './previews/HeadingPreview';
7
+ import { TextPreview } from './previews/TextPreview';
5
8
  export const wTextItemData = {
6
9
  id: ActionName.paragraph,
7
10
  title: i18n.bind(null, 'text'),
@@ -11,6 +14,7 @@ export const wTextItemData = {
11
14
  isActive: (e) => e.actions.toParagraph.isActive(),
12
15
  isEnable: (e) => e.actions.toParagraph.isEnable(),
13
16
  doNotActivateList: true,
17
+ preview: React.createElement(TextPreview, null),
14
18
  };
15
19
  export const wHeading1ItemData = {
16
20
  id: ActionName.heading1,
@@ -20,6 +24,7 @@ export const wHeading1ItemData = {
20
24
  exec: (e) => e.actions.toH1.run(),
21
25
  isActive: (e) => e.actions.toH1.isActive(),
22
26
  isEnable: (e) => e.actions.toH1.isEnable(),
27
+ preview: React.createElement(HeadingPreview, { level: 1 }),
23
28
  };
24
29
  export const wHeading2ItemData = {
25
30
  id: ActionName.heading2,
@@ -29,6 +34,7 @@ export const wHeading2ItemData = {
29
34
  exec: (e) => e.actions.toH2.run(),
30
35
  isActive: (e) => e.actions.toH2.isActive(),
31
36
  isEnable: (e) => e.actions.toH2.isEnable(),
37
+ preview: React.createElement(HeadingPreview, { level: 2 }),
32
38
  };
33
39
  export const wHeading3ItemData = {
34
40
  id: ActionName.heading3,
@@ -38,6 +44,7 @@ export const wHeading3ItemData = {
38
44
  exec: (e) => e.actions.toH3.run(),
39
45
  isActive: (e) => e.actions.toH3.isActive(),
40
46
  isEnable: (e) => e.actions.toH3.isEnable(),
47
+ preview: React.createElement(HeadingPreview, { level: 3 }),
41
48
  };
42
49
  export const wHeading4ItemData = {
43
50
  id: ActionName.heading4,
@@ -47,6 +54,7 @@ export const wHeading4ItemData = {
47
54
  exec: (e) => e.actions.toH4.run(),
48
55
  isActive: (e) => e.actions.toH4.isActive(),
49
56
  isEnable: (e) => e.actions.toH4.isEnable(),
57
+ preview: React.createElement(HeadingPreview, { level: 4 }),
50
58
  };
51
59
  export const wHeading5ItemData = {
52
60
  id: ActionName.heading5,
@@ -56,6 +64,7 @@ export const wHeading5ItemData = {
56
64
  exec: (e) => e.actions.toH5.run(),
57
65
  isActive: (e) => e.actions.toH5.isActive(),
58
66
  isEnable: (e) => e.actions.toH5.isEnable(),
67
+ preview: React.createElement(HeadingPreview, { level: 5 }),
59
68
  };
60
69
  export const wHeading6ItemData = {
61
70
  id: ActionName.heading6,
@@ -65,6 +74,7 @@ export const wHeading6ItemData = {
65
74
  exec: (e) => e.actions.toH6.run(),
66
75
  isActive: (e) => e.actions.toH6.isActive(),
67
76
  isEnable: (e) => e.actions.toH6.isEnable(),
77
+ preview: React.createElement(HeadingPreview, { level: 6 }),
68
78
  };
69
79
  export const wHeadingListConfig = {
70
80
  icon: icons.headline,
@@ -16,7 +16,8 @@ const transformItem = (type, item, id = 'unknown') => {
16
16
  return {};
17
17
  }
18
18
  const isListButton = item.view.type === ToolbarDataType.ListButton;
19
- return Object.assign(Object.assign(Object.assign({ type: (_a = item.view.type) !== null && _a !== void 0 ? _a : ToolbarDataType.SingleButton, id, title: item.view.title, hint: item.view.hint, icon: item.view.icon, hotkey: item.view.hotkey }, (isListButton && { withArrow: item.view.withArrow })), (type === 'wysiwyg' && item.wysiwyg && Object.assign({}, item.wysiwyg))), (type === 'markup' && item.markup && Object.assign({}, item.markup)));
19
+ const isSingleButton = item.view.type === ToolbarDataType.SingleButton;
20
+ return Object.assign(Object.assign(Object.assign(Object.assign({ type: (_a = item.view.type) !== null && _a !== void 0 ? _a : ToolbarDataType.SingleButton, id, title: item.view.title, hint: item.view.hint, icon: item.view.icon, hotkey: item.view.hotkey }, (isSingleButton && { preview: item.view.preview })), (isListButton && { withArrow: item.view.withArrow })), (type === 'wysiwyg' && item.wysiwyg && Object.assign({}, item.wysiwyg))), (type === 'markup' && item.markup && Object.assign({}, item.markup)));
20
21
  };
21
22
  export const createToolbarConfig = (editorType, toolbarPreset, toolbarName) => {
22
23
  var _a;
@@ -99,6 +99,17 @@ export declare type MarkdownEditorExperimentalOptions = {
99
99
  * @default false
100
100
  */
101
101
  preserveEmptyRows?: boolean;
102
+ /**
103
+ * Preserves the original formatting of unmodified blocks,
104
+ * restoring their structure during serialization
105
+ *
106
+ * **Use case:** Maintain consistent markup when switching modes
107
+ *
108
+ * **Note:** Applies to tracked blocks: `yfm_table`
109
+ *
110
+ * @default false
111
+ */
112
+ preserveMarkupFormatting?: boolean;
102
113
  };
103
114
  export declare type MarkdownEditorMarkupConfig = {
104
115
  /**
@@ -4,7 +4,7 @@ import { TransformFn } from './markdown/ProseMirrorTransformer';
4
4
  import type { ActionStorage } from './types/actions';
5
5
  import type { Extension } from './types/extension';
6
6
  import type { Parser } from './types/parser';
7
- import type { Serializer } from './types/serializer';
7
+ import { Serializer } from './types/serializer';
8
8
  declare type OnChange = (editor: WysiwygEditor) => void;
9
9
  export declare type EscapeConfig = {
10
10
  commonEscape?: RegExp;
@@ -33,7 +33,7 @@ export declare class WysiwygEditor implements CommonEditor, ActionStorage {
33
33
  get serializer(): Serializer;
34
34
  get parser(): Parser;
35
35
  get actions(): WysiwygEditor.Actions;
36
- constructor({ domElem, initialContent, extensions, allowHTML, mdPreset, linkify, pmTransformers, linkifyTlds, escapeConfig, onChange, onDocChange, }: WysiwygEditorOptions);
36
+ constructor({ domElem, initialContent, extensions, allowHTML, mdPreset, linkify, pmTransformers, linkifyTlds, escapeConfig, onChange, onDocChange, modifiers, }: WysiwygEditorOptions);
37
37
  action<T extends keyof WysiwygEditor.Actions>(actionName: T): WysiwygEditor.Actions[T];
38
38
  focus(): void;
39
39
  hasFocus(): boolean;
@@ -4,21 +4,36 @@ import { EditorState } from 'prosemirror-state';
4
4
  import { EditorView } from 'prosemirror-view';
5
5
  import { WysiwygContentHandler } from './ContentHandler';
6
6
  import { ExtensionsManager } from './ExtensionsManager';
7
+ import { SchemaDynamicModifier } from './SchemaDynamicModifier';
8
+ import { MarkdownParserDynamicModifier } from './markdown/MarkdownParser';
9
+ import { MarkdownSerializerDynamicModifier } from './markdown/MarkdownSerializerDynamicModifier';
7
10
  import { bindActions } from './utils/actions';
11
+ import { convertDynamicModifiersConfigs } from './utils/dynamicModifiers';
8
12
  import { logTransactionMetrics } from './utils/metrics';
9
13
  export class WysiwygEditor {
10
- constructor({ domElem, initialContent = '', extensions = () => { }, allowHTML, mdPreset, linkify, pmTransformers, linkifyTlds, escapeConfig, onChange, onDocChange, }) {
14
+ constructor({ domElem, initialContent = '', extensions = () => { }, allowHTML, mdPreset, linkify, pmTransformers, linkifyTlds, escapeConfig, onChange, onDocChange, modifiers, }) {
11
15
  _WysiwygEditor_view.set(this, void 0);
12
16
  _WysiwygEditor_serializer.set(this, void 0);
13
17
  _WysiwygEditor_parser.set(this, void 0);
14
18
  _WysiwygEditor_actions.set(this, void 0);
15
19
  _WysiwygEditor_contentHandler.set(this, void 0);
16
20
  _WysiwygEditor_escapeConfig.set(this, void 0);
21
+ const dynamicModifiersConfig = modifiers
22
+ ? convertDynamicModifiersConfigs(modifiers)
23
+ : undefined;
24
+ const dynamicModifiers = dynamicModifiersConfig
25
+ ? {
26
+ schema: new SchemaDynamicModifier(dynamicModifiersConfig.schema),
27
+ parser: new MarkdownParserDynamicModifier(dynamicModifiersConfig.parser),
28
+ serializer: new MarkdownSerializerDynamicModifier(dynamicModifiersConfig.serializer),
29
+ }
30
+ : undefined;
17
31
  const { schema, markupParser: parser, serializer, nodeViews, markViews, plugins, rawActions, actions, } = ExtensionsManager.process(extensions, {
18
32
  // "breaks" option only affects the renderer, but not the parser
19
33
  mdOpts: { html: allowHTML, linkify, breaks: true, preset: mdPreset },
20
34
  linkifyTlds,
21
35
  pmTransformers,
36
+ dynamicModifiers,
22
37
  });
23
38
  const state = EditorState.create({
24
39
  schema,
@@ -1,6 +1,10 @@
1
1
  import MarkdownIt, { PresetName } from 'markdown-it';
2
+ import { Schema } from 'prosemirror-model';
2
3
  import type { Plugin } from 'prosemirror-state';
3
4
  import { ActionsManager } from './ActionsManager';
5
+ import { SchemaDynamicModifier } from './SchemaDynamicModifier';
6
+ import { MarkdownParserDynamicModifier } from './markdown/MarkdownParser';
7
+ import { MarkdownSerializerDynamicModifier } from './markdown/MarkdownSerializerDynamicModifier';
4
8
  import { TransformFn } from './markdown/ProseMirrorTransformer';
5
9
  import type { ActionSpec } from './types/actions';
6
10
  import type { Extension, ExtensionDeps } from './types/extension';
@@ -15,6 +19,11 @@ declare type ExtensionsManagerOptions = {
15
19
  };
16
20
  linkifyTlds?: string | string[];
17
21
  pmTransformers?: TransformFn[];
22
+ dynamicModifiers?: {
23
+ parser?: MarkdownParserDynamicModifier;
24
+ serializer?: MarkdownSerializerDynamicModifier;
25
+ schema?: SchemaDynamicModifier;
26
+ };
18
27
  };
19
28
  export declare class ExtensionsManager {
20
29
  #private;
@@ -24,7 +33,7 @@ export declare class ExtensionsManager {
24
33
  plugins: Plugin<any>[];
25
34
  nodeViews: Record<string, NodeViewConstructor>;
26
35
  markViews: Record<string, MarkViewConstructor>;
27
- schema: import("prosemirror-model").Schema<any, any>;
36
+ schema: Schema<any, any>;
28
37
  textParser: import(".").Parser;
29
38
  markupParser: import(".").Parser;
30
39
  serializer: import(".").Serializer;
@@ -36,7 +45,7 @@ export declare class ExtensionsManager {
36
45
  plugins: Plugin<any>[];
37
46
  nodeViews: Record<string, NodeViewConstructor>;
38
47
  markViews: Record<string, MarkViewConstructor>;
39
- schema: import("prosemirror-model").Schema<any, any>;
48
+ schema: Schema<any, any>;
40
49
  textParser: import(".").Parser;
41
50
  markupParser: import(".").Parser;
42
51
  serializer: import(".").Serializer;
@@ -45,6 +54,7 @@ export declare class ExtensionsManager {
45
54
  private processExtensions;
46
55
  private processNode;
47
56
  private processMark;
57
+ private createParser;
48
58
  private createDeps;
49
59
  private createDerived;
50
60
  }
@@ -1,4 +1,4 @@
1
- var _ExtensionsManager_schemaRegistry, _ExtensionsManager_parserRegistry, _ExtensionsManager_serializerRegistry, _ExtensionsManager_nodeViewCreators, _ExtensionsManager_markViewCreators, _ExtensionsManager_pmTransformers, _ExtensionsManager_mdForMarkup, _ExtensionsManager_mdForText, _ExtensionsManager_extensions, _ExtensionsManager_builder, _ExtensionsManager_spec, _ExtensionsManager_deps, _ExtensionsManager_plugins, _ExtensionsManager_actions, _ExtensionsManager_nodeViews, _ExtensionsManager_markViews;
1
+ var _ExtensionsManager_schemaRegistry, _ExtensionsManager_parserRegistry, _ExtensionsManager_serializerRegistry, _ExtensionsManager_nodeViewCreators, _ExtensionsManager_markViewCreators, _ExtensionsManager_pmTransformers, _ExtensionsManager_mdForMarkup, _ExtensionsManager_mdForText, _ExtensionsManager_extensions, _ExtensionsManager_builder, _ExtensionsManager_spec, _ExtensionsManager_deps, _ExtensionsManager_plugins, _ExtensionsManager_actions, _ExtensionsManager_nodeViews, _ExtensionsManager_markViews, _ExtensionsManager_serializerDynamicModifier, _ExtensionsManager_parserDynamicModifier;
2
2
  import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib";
3
3
  import MarkdownIt from 'markdown-it';
4
4
  import { ActionsManager } from './ActionsManager';
@@ -8,10 +8,10 @@ import { SchemaSpecRegistry } from './SchemaSpecRegistry';
8
8
  import { SerializerTokensRegistry } from './SerializerTokensRegistry';
9
9
  export class ExtensionsManager {
10
10
  constructor({ extensions, options = {} }) {
11
- var _a, _b, _c, _d;
12
- _ExtensionsManager_schemaRegistry.set(this, new SchemaSpecRegistry());
13
- _ExtensionsManager_parserRegistry.set(this, new ParserTokensRegistry());
14
- _ExtensionsManager_serializerRegistry.set(this, new SerializerTokensRegistry());
11
+ var _a, _b, _c, _d, _e, _f, _g;
12
+ _ExtensionsManager_schemaRegistry.set(this, void 0);
13
+ _ExtensionsManager_parserRegistry.set(this, void 0);
14
+ _ExtensionsManager_serializerRegistry.set(this, void 0);
15
15
  _ExtensionsManager_nodeViewCreators.set(this, new Map());
16
16
  _ExtensionsManager_markViewCreators.set(this, new Map());
17
17
  _ExtensionsManager_pmTransformers.set(this, []);
@@ -25,6 +25,8 @@ export class ExtensionsManager {
25
25
  _ExtensionsManager_actions.set(this, {});
26
26
  _ExtensionsManager_nodeViews.set(this, {});
27
27
  _ExtensionsManager_markViews.set(this, {});
28
+ _ExtensionsManager_serializerDynamicModifier.set(this, void 0);
29
+ _ExtensionsManager_parserDynamicModifier.set(this, void 0);
28
30
  this.processNode = (name, { spec, fromMd, toMd: toMd, view }) => {
29
31
  __classPrivateFieldGet(this, _ExtensionsManager_schemaRegistry, "f").addNode(name, spec);
30
32
  __classPrivateFieldGet(this, _ExtensionsManager_parserRegistry, "f").addToken(fromMd.tokenName || name, fromMd.tokenSpec);
@@ -41,10 +43,17 @@ export class ExtensionsManager {
41
43
  __classPrivateFieldGet(this, _ExtensionsManager_markViewCreators, "f").set(name, view);
42
44
  }
43
45
  };
46
+ __classPrivateFieldSet(this, _ExtensionsManager_schemaRegistry, new SchemaSpecRegistry(undefined, (_a = options.dynamicModifiers) === null || _a === void 0 ? void 0 : _a.schema), "f");
47
+ __classPrivateFieldSet(this, _ExtensionsManager_parserRegistry, new ParserTokensRegistry(), "f");
48
+ __classPrivateFieldSet(this, _ExtensionsManager_serializerRegistry, new SerializerTokensRegistry(), "f");
49
+ if (options.dynamicModifiers) {
50
+ __classPrivateFieldSet(this, _ExtensionsManager_parserDynamicModifier, (_b = options.dynamicModifiers) === null || _b === void 0 ? void 0 : _b.parser, "f");
51
+ __classPrivateFieldSet(this, _ExtensionsManager_serializerDynamicModifier, (_c = options.dynamicModifiers) === null || _c === void 0 ? void 0 : _c.serializer, "f");
52
+ }
44
53
  __classPrivateFieldSet(this, _ExtensionsManager_extensions, extensions, "f");
45
- const mdPreset = (_b = (_a = options.mdOpts) === null || _a === void 0 ? void 0 : _a.preset) !== null && _b !== void 0 ? _b : 'default';
46
- __classPrivateFieldSet(this, _ExtensionsManager_mdForMarkup, new MarkdownIt(mdPreset, (_c = options.mdOpts) !== null && _c !== void 0 ? _c : {}), "f");
47
- __classPrivateFieldSet(this, _ExtensionsManager_mdForText, new MarkdownIt(mdPreset, (_d = options.mdOpts) !== null && _d !== void 0 ? _d : {}), "f");
54
+ const mdPreset = (_e = (_d = options.mdOpts) === null || _d === void 0 ? void 0 : _d.preset) !== null && _e !== void 0 ? _e : 'default';
55
+ __classPrivateFieldSet(this, _ExtensionsManager_mdForMarkup, new MarkdownIt(mdPreset, (_f = options.mdOpts) !== null && _f !== void 0 ? _f : {}), "f");
56
+ __classPrivateFieldSet(this, _ExtensionsManager_mdForText, new MarkdownIt(mdPreset, (_g = options.mdOpts) !== null && _g !== void 0 ? _g : {}), "f");
48
57
  if (options.linkifyTlds) {
49
58
  __classPrivateFieldGet(this, _ExtensionsManager_mdForMarkup, "f").linkify.tlds(options.linkifyTlds, true);
50
59
  __classPrivateFieldGet(this, _ExtensionsManager_mdForText, "f").linkify.tlds(options.linkifyTlds, true);
@@ -76,14 +85,21 @@ export class ExtensionsManager {
76
85
  __classPrivateFieldGet(this, _ExtensionsManager_spec, "f").nodes().forEach(this.processNode);
77
86
  __classPrivateFieldGet(this, _ExtensionsManager_spec, "f").marks().forEach(this.processMark);
78
87
  }
88
+ createParser(schema, mdInstance) {
89
+ return __classPrivateFieldGet(this, _ExtensionsManager_parserRegistry, "f").createParser(schema, mdInstance, __classPrivateFieldGet(this, _ExtensionsManager_pmTransformers, "f"), __classPrivateFieldGet(this, _ExtensionsManager_parserDynamicModifier, "f"));
90
+ }
79
91
  createDeps() {
92
+ const actions = new ActionsManager();
80
93
  const schema = __classPrivateFieldGet(this, _ExtensionsManager_schemaRegistry, "f").createSchema();
94
+ const markupParser = this.createParser(schema, __classPrivateFieldGet(this, _ExtensionsManager_mdForMarkup, "f"));
95
+ const textParser = this.createParser(schema, __classPrivateFieldGet(this, _ExtensionsManager_mdForText, "f"));
96
+ const serializer = __classPrivateFieldGet(this, _ExtensionsManager_serializerRegistry, "f").createSerializer(__classPrivateFieldGet(this, _ExtensionsManager_serializerDynamicModifier, "f"));
81
97
  __classPrivateFieldSet(this, _ExtensionsManager_deps, {
82
98
  schema,
83
- actions: new ActionsManager(),
84
- markupParser: __classPrivateFieldGet(this, _ExtensionsManager_parserRegistry, "f").createParser(schema, __classPrivateFieldGet(this, _ExtensionsManager_mdForMarkup, "f"), __classPrivateFieldGet(this, _ExtensionsManager_pmTransformers, "f")),
85
- textParser: __classPrivateFieldGet(this, _ExtensionsManager_parserRegistry, "f").createParser(schema, __classPrivateFieldGet(this, _ExtensionsManager_mdForText, "f"), __classPrivateFieldGet(this, _ExtensionsManager_pmTransformers, "f")),
86
- serializer: __classPrivateFieldGet(this, _ExtensionsManager_serializerRegistry, "f").createSerializer(),
99
+ actions,
100
+ markupParser,
101
+ textParser,
102
+ serializer,
87
103
  }, "f");
88
104
  }
89
105
  createDerived() {
@@ -97,4 +113,4 @@ export class ExtensionsManager {
97
113
  }
98
114
  }
99
115
  }
100
- _ExtensionsManager_schemaRegistry = new WeakMap(), _ExtensionsManager_parserRegistry = new WeakMap(), _ExtensionsManager_serializerRegistry = new WeakMap(), _ExtensionsManager_nodeViewCreators = new WeakMap(), _ExtensionsManager_markViewCreators = new WeakMap(), _ExtensionsManager_pmTransformers = new WeakMap(), _ExtensionsManager_mdForMarkup = new WeakMap(), _ExtensionsManager_mdForText = new WeakMap(), _ExtensionsManager_extensions = new WeakMap(), _ExtensionsManager_builder = new WeakMap(), _ExtensionsManager_spec = new WeakMap(), _ExtensionsManager_deps = new WeakMap(), _ExtensionsManager_plugins = new WeakMap(), _ExtensionsManager_actions = new WeakMap(), _ExtensionsManager_nodeViews = new WeakMap(), _ExtensionsManager_markViews = new WeakMap();
116
+ _ExtensionsManager_schemaRegistry = new WeakMap(), _ExtensionsManager_parserRegistry = new WeakMap(), _ExtensionsManager_serializerRegistry = new WeakMap(), _ExtensionsManager_nodeViewCreators = new WeakMap(), _ExtensionsManager_markViewCreators = new WeakMap(), _ExtensionsManager_pmTransformers = new WeakMap(), _ExtensionsManager_mdForMarkup = new WeakMap(), _ExtensionsManager_mdForText = new WeakMap(), _ExtensionsManager_extensions = new WeakMap(), _ExtensionsManager_builder = new WeakMap(), _ExtensionsManager_spec = new WeakMap(), _ExtensionsManager_deps = new WeakMap(), _ExtensionsManager_plugins = new WeakMap(), _ExtensionsManager_actions = new WeakMap(), _ExtensionsManager_nodeViews = new WeakMap(), _ExtensionsManager_markViews = new WeakMap(), _ExtensionsManager_serializerDynamicModifier = new WeakMap(), _ExtensionsManager_parserDynamicModifier = new WeakMap();
@@ -1,9 +1,10 @@
1
1
  import type MarkdownIt from 'markdown-it';
2
2
  import type { Schema } from 'prosemirror-model';
3
+ import { MarkdownParserDynamicModifier } from './markdown/MarkdownParser';
3
4
  import { TransformFn } from './markdown/ProseMirrorTransformer';
4
5
  import type { Parser, ParserToken } from './types/parser';
5
6
  export declare class ParserTokensRegistry {
6
7
  #private;
7
8
  addToken(name: string, token: ParserToken): this;
8
- createParser(schema: Schema, tokenizer: MarkdownIt, pmTransformers: TransformFn[]): Parser;
9
+ createParser(schema: Schema, tokenizer: MarkdownIt, pmTransformers: TransformFn[], dynamicModifier?: MarkdownParserDynamicModifier): Parser;
9
10
  }
@@ -9,8 +9,8 @@ export class ParserTokensRegistry {
9
9
  __classPrivateFieldGet(this, _ParserTokensRegistry_tokens, "f")[name] = token;
10
10
  return this;
11
11
  }
12
- createParser(schema, tokenizer, pmTransformers) {
13
- return new MarkdownParser(schema, tokenizer, __classPrivateFieldGet(this, _ParserTokensRegistry_tokens, "f"), pmTransformers);
12
+ createParser(schema, tokenizer, pmTransformers, dynamicModifier) {
13
+ return new MarkdownParser(schema, tokenizer, __classPrivateFieldGet(this, _ParserTokensRegistry_tokens, "f"), pmTransformers, dynamicModifier);
14
14
  }
15
15
  }
16
16
  _ParserTokensRegistry_tokens = new WeakMap();
@@ -0,0 +1,3 @@
1
+ export declare type TokenAttrs = {
2
+ [name: string]: unknown;
3
+ };
@@ -0,0 +1,21 @@
1
+ /** @internal */
2
+ export class SchemaDynamicModifier {
3
+ constructor(config) {
4
+ this.nodeSpecsProcessors = new Map(Object.entries(config));
5
+ }
6
+ processNodeSpec(name, nodeSpec) {
7
+ let updatedSpec = nodeSpec;
8
+ this.nodeSpecsProcessors.forEach((processor, elementType) => {
9
+ if (name === elementType &&
10
+ processor.allowedAttrs &&
11
+ processor.allowedAttrs.length > 0 &&
12
+ nodeSpec) {
13
+ updatedSpec = Object.assign(Object.assign({}, nodeSpec), { attrs: Object.assign(Object.assign({}, nodeSpec.attrs), processor.allowedAttrs.reduce((acc, key) => {
14
+ acc[key] = { default: null };
15
+ return acc;
16
+ }, {})) });
17
+ }
18
+ });
19
+ return updatedSpec;
20
+ }
21
+ }
@@ -1,7 +1,8 @@
1
1
  import { MarkSpec, NodeSpec, Schema } from 'prosemirror-model';
2
+ import { SchemaDynamicModifier } from './SchemaDynamicModifier';
2
3
  export declare class SchemaSpecRegistry {
3
4
  #private;
4
- constructor(topNode?: string);
5
+ constructor(topNode?: string, dynamicModifier?: SchemaDynamicModifier);
5
6
  addNode(name: string, spec: NodeSpec): this;
6
7
  addMark(name: string, spec: MarkSpec): this;
7
8
  createSchema(): Schema<string, string>;
@@ -1,13 +1,18 @@
1
- var _SchemaSpecRegistry_spec;
1
+ var _SchemaSpecRegistry_spec, _SchemaSpecRegistry_dynamicModifier;
2
2
  import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib";
3
3
  import { Schema } from 'prosemirror-model';
4
4
  export class SchemaSpecRegistry {
5
- constructor(topNode) {
5
+ constructor(topNode, dynamicModifier) {
6
6
  _SchemaSpecRegistry_spec.set(this, void 0);
7
+ _SchemaSpecRegistry_dynamicModifier.set(this, void 0);
7
8
  __classPrivateFieldSet(this, _SchemaSpecRegistry_spec, { topNode, nodes: {}, marks: {} }, "f");
9
+ __classPrivateFieldSet(this, _SchemaSpecRegistry_dynamicModifier, dynamicModifier, "f");
8
10
  }
9
11
  addNode(name, spec) {
10
- __classPrivateFieldGet(this, _SchemaSpecRegistry_spec, "f").nodes[name] = spec;
12
+ const modifiedSpec = __classPrivateFieldGet(this, _SchemaSpecRegistry_dynamicModifier, "f")
13
+ ? __classPrivateFieldGet(this, _SchemaSpecRegistry_dynamicModifier, "f").processNodeSpec(name, spec)
14
+ : spec;
15
+ __classPrivateFieldGet(this, _SchemaSpecRegistry_spec, "f").nodes[name] = modifiedSpec;
11
16
  return this;
12
17
  }
13
18
  addMark(name, spec) {
@@ -18,4 +23,4 @@ export class SchemaSpecRegistry {
18
23
  return new Schema(__classPrivateFieldGet(this, _SchemaSpecRegistry_spec, "f"));
19
24
  }
20
25
  }
21
- _SchemaSpecRegistry_spec = new WeakMap();
26
+ _SchemaSpecRegistry_spec = new WeakMap(), _SchemaSpecRegistry_dynamicModifier = new WeakMap();
@@ -1,7 +1,8 @@
1
+ import { MarkdownSerializerDynamicModifier } from './markdown/MarkdownSerializerDynamicModifier';
1
2
  import type { Serializer, SerializerMarkToken, SerializerNodeToken } from './types/serializer';
2
3
  export declare class SerializerTokensRegistry {
3
4
  #private;
4
5
  addNode(name: string, node: SerializerNodeToken): this;
5
6
  addMark(name: string, mark: SerializerMarkToken): this;
6
- createSerializer(): Serializer;
7
+ createSerializer(dynamicModifier?: MarkdownSerializerDynamicModifier): Serializer;
7
8
  }
@@ -14,8 +14,8 @@ export class SerializerTokensRegistry {
14
14
  __classPrivateFieldGet(this, _SerializerTokensRegistry_marks, "f")[name] = mark;
15
15
  return this;
16
16
  }
17
- createSerializer() {
18
- return new MarkdownSerializer(__classPrivateFieldGet(this, _SerializerTokensRegistry_nodes, "f"), __classPrivateFieldGet(this, _SerializerTokensRegistry_marks, "f"));
17
+ createSerializer(dynamicModifier) {
18
+ return new MarkdownSerializer(__classPrivateFieldGet(this, _SerializerTokensRegistry_nodes, "f"), __classPrivateFieldGet(this, _SerializerTokensRegistry_marks, "f"), dynamicModifier);
19
19
  }
20
20
  }
21
21
  _SerializerTokensRegistry_nodes = new WeakMap(), _SerializerTokensRegistry_marks = new WeakMap();
@@ -9,3 +9,5 @@ export type { Extension, ExtensionAuto, ExtensionWithOptions, ExtensionDeps, Ext
9
9
  export type { Parser, ParserToken } from './types/parser';
10
10
  export type { Serializer, SerializerState, SerializerNodeToken, SerializerMarkToken, } from './types/serializer';
11
11
  export type { NodeViewConstructor, MarkViewConstructor } from './types/node-views';
12
+ export type { MarkdownParserDynamicModifierConfig } from './markdown/MarkdownParser';
13
+ export type { MarkdownSerializerDynamicModifierConfig } from './markdown/MarkdownSerializerDynamicModifier';
@@ -1,9 +1,10 @@
1
1
  import type { Match } from 'linkify-it';
2
2
  import type MarkdownIt from 'markdown-it';
3
+ import type Token from 'markdown-it/lib/token';
3
4
  import { Mark, Node, NodeType, Schema } from 'prosemirror-model';
4
5
  import type { Parser, ParserToken } from '../types/parser';
5
6
  import { TransformFn } from './ProseMirrorTransformer';
6
- declare type TokenAttrs = {
7
+ export declare type TokenAttrs = {
7
8
  [name: string]: unknown;
8
9
  };
9
10
  export declare class MarkdownParser implements Parser {
@@ -17,7 +18,8 @@ export declare class MarkdownParser implements Parser {
17
18
  tokens: Record<string, ParserToken>;
18
19
  tokenizer: MarkdownIt;
19
20
  pmTransformers: TransformFn[];
20
- constructor(schema: Schema, tokenizer: MarkdownIt, tokens: Record<string, ParserToken>, pmTransformers: TransformFn[]);
21
+ dynamicModifier: MarkdownParserDynamicModifier | null;
22
+ constructor(schema: Schema, tokenizer: MarkdownIt, tokens: Record<string, ParserToken>, pmTransformers: TransformFn[], dynamicModifier?: MarkdownParserDynamicModifier);
21
23
  validateLink(url: string): boolean;
22
24
  normalizeLink(url: string): string;
23
25
  normalizeLinkText(url: string): string;
@@ -30,6 +32,7 @@ export declare class MarkdownParser implements Parser {
30
32
  private getTokenType;
31
33
  private handlePrimitiveToken;
32
34
  private handleMark;
35
+ private getNodeSchema;
33
36
  private handleNode;
34
37
  private handleBlock;
35
38
  private handleToken;
@@ -41,4 +44,5 @@ export declare class MarkdownParser implements Parser {
41
44
  private closeMark;
42
45
  private parseTokens;
43
46
  }
44
- export {};
47
+ export declare type ProcessNodeAttrs = (token: Token, attrs: TokenAttrs, allowedAttrs?: string[]) => TokenAttrs;
48
+ export declare type ProcessNode = (node: Node) => Node;
@@ -9,14 +9,23 @@ var TokenType;
9
9
  TokenType["close"] = "close";
10
10
  TokenType["default"] = "default";
11
11
  })(TokenType || (TokenType = {}));
12
+ /**
13
+ * Remove suffixes from the node name.
14
+ * Crops specified `openSuffix` and `closeSuffix` from the end of the given `tokName`.
15
+ */
16
+ function cropNodeName(tokName, openSuffix, closeSuffix) {
17
+ const regex = new RegExp(`(${openSuffix})$|(${closeSuffix})$`);
18
+ return tokName.replace(regex, '');
19
+ }
12
20
  export class MarkdownParser {
13
- constructor(schema, tokenizer, tokens, pmTransformers) {
21
+ constructor(schema, tokenizer, tokens, pmTransformers, dynamicModifier) {
14
22
  this.stack = [];
15
23
  this.schema = schema;
16
24
  this.marks = Mark.none;
17
25
  this.tokens = tokens;
18
26
  this.tokenizer = tokenizer;
19
27
  this.pmTransformers = pmTransformers;
28
+ this.dynamicModifier = dynamicModifier !== null && dynamicModifier !== void 0 ? dynamicModifier : null;
20
29
  }
21
30
  validateLink(url) {
22
31
  return this.tokenizer.validateLink(url);
@@ -37,6 +46,9 @@ export class MarkdownParser {
37
46
  let mdItTokens;
38
47
  try {
39
48
  mdItTokens = this.tokenizer.parse(text, {});
49
+ if (this.dynamicModifier) {
50
+ mdItTokens = this.dynamicModifier.processTokens(mdItTokens, text);
51
+ }
40
52
  }
41
53
  catch (err) {
42
54
  const e = err;
@@ -65,11 +77,20 @@ export class MarkdownParser {
65
77
  }
66
78
  //#region helpers
67
79
  getTokenAttrs(token, tokenSpec, tokenStream, i) {
68
- if (tokenSpec.getAttrs)
69
- return tokenSpec.getAttrs(token, tokenStream, i);
70
- else if (tokenSpec.attrs instanceof Function)
71
- return tokenSpec.attrs(token);
72
- return tokenSpec.attrs;
80
+ let attrs = {};
81
+ if (tokenSpec.getAttrs) {
82
+ attrs = tokenSpec.getAttrs(token, tokenStream, i);
83
+ }
84
+ else if (tokenSpec.attrs instanceof Function) {
85
+ attrs = tokenSpec.attrs(token);
86
+ }
87
+ else {
88
+ attrs = tokenSpec.attrs;
89
+ }
90
+ if (this.dynamicModifier) {
91
+ attrs = this.dynamicModifier.processAttrs(token, attrs !== null && attrs !== void 0 ? attrs : {});
92
+ }
93
+ return attrs;
73
94
  }
74
95
  getTokenSpec(token) {
75
96
  var _a;
@@ -77,12 +98,14 @@ export class MarkdownParser {
77
98
  let tokName = ((_a = token.meta) === null || _a === void 0 ? void 0 : _a['pm-node']) || token.type;
78
99
  // Cropping _open and _close from node name end
79
100
  // e.g. paragraph_open -> paragraph
80
- tokName = tokName.replace(new RegExp(`(${openSuffix})$|(${closeSuffix})$`), '');
101
+ tokName = cropNodeName(tokName, openSuffix, closeSuffix);
81
102
  let tokenSpec;
82
- if (tokName in this.tokens)
103
+ if (tokName in this.tokens) {
83
104
  tokenSpec = this.tokens[tokName];
84
- if (!tokenSpec)
105
+ }
106
+ if (!tokenSpec) {
85
107
  throw new RangeError(`No token spec for token: ${JSON.stringify(token)}`);
108
+ }
86
109
  return tokenSpec;
87
110
  }
88
111
  // Getting token type from its name
@@ -136,14 +159,18 @@ export class MarkdownParser {
136
159
  }
137
160
  }
138
161
  }
162
+ getNodeSchema(tokenSpec) {
163
+ const spec = this.schema.nodes[tokenSpec.name];
164
+ return spec;
165
+ }
139
166
  handleNode(_token, tokenSpec, attrs) {
140
- const schemaSpec = this.schema.nodes[tokenSpec.name];
167
+ const schemaSpec = this.getNodeSchema(tokenSpec);
141
168
  // Adding node as is, becasuse it doesn't contain content.
142
169
  this.addNode(schemaSpec, attrs);
143
170
  }
144
171
  handleBlock(token, tokenSpec, attrs) {
145
172
  var _a;
146
- const schemaSpec = this.schema.nodes[tokenSpec.name];
173
+ const schemaSpec = this.getNodeSchema(tokenSpec);
147
174
  if (tokenSpec.noCloseToken) {
148
175
  this.openNode(schemaSpec, attrs);
149
176
  if (tokenSpec.contentField === 'children' && ((_a = token.children) === null || _a === void 0 ? void 0 : _a.length)) {
@@ -186,9 +213,13 @@ export class MarkdownParser {
186
213
  //#endregion
187
214
  //#region state methods
188
215
  addNode(type, attrs, content) {
189
- const node = type.createAndFill(attrs, content, this.marks);
190
- if (!node)
216
+ let node = type.createAndFill(attrs, content, this.marks);
217
+ if (!node) {
191
218
  return null;
219
+ }
220
+ if (this.dynamicModifier) {
221
+ node = this.dynamicModifier.processNodes(node);
222
+ }
192
223
  this.push(node);
193
224
  return node;
194
225
  }
@@ -197,11 +228,13 @@ export class MarkdownParser {
197
228
  }
198
229
  closeNode() {
199
230
  // Marks operate within a node. Therefore, when we close the node, we reset the existing marks.
200
- if (this.marks.length)
231
+ if (this.marks.length) {
201
232
  this.marks = Mark.none;
233
+ }
202
234
  const info = this.stack.pop();
203
- if (info)
235
+ if (info) {
204
236
  return this.addNode(info.type, info.attrs, info.content);
237
+ }
205
238
  return null;
206
239
  }
207
240
  addText(text) {
@@ -248,3 +281,38 @@ function maybeMerge(a, b) {
248
281
  function withoutTrailingNewline(str) {
249
282
  return str[str.length - 1] === '\n' || str.endsWith('\\n') ? str.slice(0, str.length - 1) : str;
250
283
  }
284
+ /** @internal */
285
+ export class MarkdownParserDynamicModifier {
286
+ constructor(config) {
287
+ this.elementProcessors = new Map(Object.entries(config));
288
+ }
289
+ processTokens(tokens, rawMarkup) {
290
+ return tokens.map((token, index) => {
291
+ const processor = this.elementProcessors.get(cropNodeName(token.type, openSuffix, ''));
292
+ if (!processor || !processor.processToken || processor.processToken.length === 0) {
293
+ return token;
294
+ }
295
+ return processor.processToken.reduce((currentToken, process) => {
296
+ return process(currentToken, index, rawMarkup);
297
+ }, token);
298
+ });
299
+ }
300
+ processAttrs(token, attrs) {
301
+ const processor = this.elementProcessors.get(cropNodeName(token.type, openSuffix, ''));
302
+ if (!processor || !processor.processNodeAttrs || processor.processNodeAttrs.length === 0) {
303
+ return attrs;
304
+ }
305
+ return processor.processNodeAttrs.reduce((currentAttrs, process) => {
306
+ return process(token, currentAttrs);
307
+ }, attrs);
308
+ }
309
+ processNodes(node) {
310
+ const processor = this.elementProcessors.get(node.type.name);
311
+ if (!processor || !processor.processNode || processor.processNode.length === 0) {
312
+ return node;
313
+ }
314
+ return processor.processNode.reduce((currentNode, process) => {
315
+ return process(currentNode);
316
+ }, node);
317
+ }
318
+ }