@gravity-ui/markdown-editor 14.11.2 → 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 +3 -2
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- var _EditorImpl_markup, _EditorImpl_editorMode, _EditorImpl_toolbarVisible, _EditorImpl_splitModeEnabled, _EditorImpl_splitMode, _EditorImpl_renderPreview, _EditorImpl_wysiwygEditor, _EditorImpl_markupEditor, _EditorImpl_markupConfig, _EditorImpl_escapeConfig, _EditorImpl_mdOptions, _EditorImpl_pmTransformers, _EditorImpl_preserveEmptyRows, _EditorImpl_preset, _EditorImpl_extensions, _EditorImpl_renderStorage, _EditorImpl_fileUploadHandler, _EditorImpl_parseInsertedUrlAsImage, _EditorImpl_needToSetDimensionsForUploadedImages, _EditorImpl_enableNewImageSizeCalculation, _EditorImpl_directiveSyntax, _EditorImpl_prepareRawMarkup, _EditorImpl_beforeEditorModeChange;
2
+ var _EditorImpl_markup, _EditorImpl_editorMode, _EditorImpl_toolbarVisible, _EditorImpl_splitModeEnabled, _EditorImpl_splitMode, _EditorImpl_renderPreview, _EditorImpl_wysiwygEditor, _EditorImpl_markupEditor, _EditorImpl_markupConfig, _EditorImpl_escapeConfig, _EditorImpl_mdOptions, _EditorImpl_pmTransformers, _EditorImpl_preserveEmptyRows, _EditorImpl_modifiers, _EditorImpl_preset, _EditorImpl_extensions, _EditorImpl_renderStorage, _EditorImpl_fileUploadHandler, _EditorImpl_parseInsertedUrlAsImage, _EditorImpl_needToSetDimensionsForUploadedImages, _EditorImpl_enableNewImageSizeCalculation, _EditorImpl_directiveSyntax, _EditorImpl_prepareRawMarkup, _EditorImpl_beforeEditorModeChange;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.EditorImpl = void 0;
5
5
  const tslib_1 = require("tslib");
@@ -12,6 +12,8 @@ const markup_1 = require("../markup");
12
12
  const autocomplete_1 = require("../markup/codemirror/autocomplete");
13
13
  const editor_1 = require("../markup/editor");
14
14
  const utils_1 = require("../utils");
15
+ const MarkupManager_1 = require("./MarkupManager");
16
+ const dynamicModifiers_1 = require("./config/dynamicModifiers");
15
17
  /** @internal */
16
18
  class EditorImpl extends utils_1.SafeEventEmitter {
17
19
  constructor(opts) {
@@ -30,6 +32,7 @@ class EditorImpl extends utils_1.SafeEventEmitter {
30
32
  _EditorImpl_mdOptions.set(this, void 0);
31
33
  _EditorImpl_pmTransformers.set(this, []);
32
34
  _EditorImpl_preserveEmptyRows.set(this, void 0);
35
+ _EditorImpl_modifiers.set(this, void 0);
33
36
  _EditorImpl_preset.set(this, void 0);
34
37
  _EditorImpl_extensions.set(this, void 0);
35
38
  _EditorImpl_renderStorage.set(this, void 0);
@@ -42,6 +45,9 @@ class EditorImpl extends utils_1.SafeEventEmitter {
42
45
  _EditorImpl_beforeEditorModeChange.set(this, void 0);
43
46
  this.getValue = () => this.currentEditor.getValue();
44
47
  const { md = {}, initial = {}, handlers = {}, experimental = {}, markupConfig = {}, wysiwygConfig = {}, } = opts;
48
+ tslib_1.__classPrivateFieldSet(this, _EditorImpl_modifiers, experimental.preserveMarkupFormatting
49
+ ? (0, dynamicModifiers_1.createDynamicModifiers)(new MarkupManager_1.MarkupManager())
50
+ : undefined, "f");
45
51
  tslib_1.__classPrivateFieldSet(this, _EditorImpl_editorMode, (_a = initial.mode) !== null && _a !== void 0 ? _a : 'wysiwyg', "f");
46
52
  tslib_1.__classPrivateFieldSet(this, _EditorImpl_toolbarVisible, (_b = initial.toolbarVisible) !== null && _b !== void 0 ? _b : true, "f");
47
53
  tslib_1.__classPrivateFieldSet(this, _EditorImpl_splitMode, (_c = (markupConfig.renderPreview && markupConfig.splitMode)) !== null && _c !== void 0 ? _c : false, "f");
@@ -152,6 +158,7 @@ class EditorImpl extends utils_1.SafeEventEmitter {
152
158
  initialContent: tslib_1.__classPrivateFieldGet(this, _EditorImpl_markup, "f"),
153
159
  extensions: tslib_1.__classPrivateFieldGet(this, _EditorImpl_extensions, "f"),
154
160
  pmTransformers: tslib_1.__classPrivateFieldGet(this, _EditorImpl_pmTransformers, "f"),
161
+ modifiers: tslib_1.__classPrivateFieldGet(this, _EditorImpl_modifiers, "f"),
155
162
  allowHTML: tslib_1.__classPrivateFieldGet(this, _EditorImpl_mdOptions, "f").html,
156
163
  linkify: tslib_1.__classPrivateFieldGet(this, _EditorImpl_mdOptions, "f").linkify,
157
164
  linkifyTlds: tslib_1.__classPrivateFieldGet(this, _EditorImpl_mdOptions, "f").linkifyTlds,
@@ -330,7 +337,7 @@ class EditorImpl extends utils_1.SafeEventEmitter {
330
337
  }
331
338
  }
332
339
  exports.EditorImpl = EditorImpl;
333
- _EditorImpl_markup = new WeakMap(), _EditorImpl_editorMode = new WeakMap(), _EditorImpl_toolbarVisible = new WeakMap(), _EditorImpl_splitModeEnabled = new WeakMap(), _EditorImpl_splitMode = new WeakMap(), _EditorImpl_renderPreview = new WeakMap(), _EditorImpl_wysiwygEditor = new WeakMap(), _EditorImpl_markupEditor = new WeakMap(), _EditorImpl_markupConfig = new WeakMap(), _EditorImpl_escapeConfig = new WeakMap(), _EditorImpl_mdOptions = new WeakMap(), _EditorImpl_pmTransformers = new WeakMap(), _EditorImpl_preserveEmptyRows = new WeakMap(), _EditorImpl_preset = new WeakMap(), _EditorImpl_extensions = new WeakMap(), _EditorImpl_renderStorage = new WeakMap(), _EditorImpl_fileUploadHandler = new WeakMap(), _EditorImpl_parseInsertedUrlAsImage = new WeakMap(), _EditorImpl_needToSetDimensionsForUploadedImages = new WeakMap(), _EditorImpl_enableNewImageSizeCalculation = new WeakMap(), _EditorImpl_directiveSyntax = new WeakMap(), _EditorImpl_prepareRawMarkup = new WeakMap(), _EditorImpl_beforeEditorModeChange = new WeakMap();
340
+ _EditorImpl_markup = new WeakMap(), _EditorImpl_editorMode = new WeakMap(), _EditorImpl_toolbarVisible = new WeakMap(), _EditorImpl_splitModeEnabled = new WeakMap(), _EditorImpl_splitMode = new WeakMap(), _EditorImpl_renderPreview = new WeakMap(), _EditorImpl_wysiwygEditor = new WeakMap(), _EditorImpl_markupEditor = new WeakMap(), _EditorImpl_markupConfig = new WeakMap(), _EditorImpl_escapeConfig = new WeakMap(), _EditorImpl_mdOptions = new WeakMap(), _EditorImpl_pmTransformers = new WeakMap(), _EditorImpl_preserveEmptyRows = new WeakMap(), _EditorImpl_modifiers = new WeakMap(), _EditorImpl_preset = new WeakMap(), _EditorImpl_extensions = new WeakMap(), _EditorImpl_renderStorage = new WeakMap(), _EditorImpl_fileUploadHandler = new WeakMap(), _EditorImpl_parseInsertedUrlAsImage = new WeakMap(), _EditorImpl_needToSetDimensionsForUploadedImages = new WeakMap(), _EditorImpl_enableNewImageSizeCalculation = new WeakMap(), _EditorImpl_directiveSyntax = new WeakMap(), _EditorImpl_prepareRawMarkup = new WeakMap(), _EditorImpl_beforeEditorModeChange = new WeakMap();
334
341
  function getTopOffset(elem) {
335
342
  const TOOLBAR_HEIGHT = 36; //px
336
343
  const TOOLBAR_BOTTOM_OFFSET = 8; // px
@@ -0,0 +1,54 @@
1
+ import { Node } from 'prosemirror-model';
2
+ import { SafeEventEmitter } from '../utils';
3
+ export interface IMarkupManager {
4
+ setMarkup(id: string, rawMarkup: string): void;
5
+ setNode(id: string, node: Node): void;
6
+ getMarkup(id: string): string | null;
7
+ getNode(id: string): Node | null;
8
+ reset(): void;
9
+ on<K extends keyof Events>(event: K, listener: (value: Events[K]) => void): void;
10
+ }
11
+ export interface Logger {
12
+ log(message: string): void;
13
+ error(message: string): void;
14
+ }
15
+ interface Events {
16
+ markupChanged: {
17
+ id: string;
18
+ rawMarkup: string;
19
+ };
20
+ nodeChanged: {
21
+ id: string;
22
+ node: Node;
23
+ };
24
+ reset: {};
25
+ }
26
+ export declare class MarkupManager extends SafeEventEmitter<Events> implements IMarkupManager {
27
+ private _markups;
28
+ private _nodes;
29
+ private _namespace;
30
+ private readonly logger?;
31
+ constructor(logger?: Logger);
32
+ /**
33
+ * Set raw markup for a specific id
34
+ */
35
+ setMarkup(id: string, rawMarkup: string): void;
36
+ /**
37
+ * Set a node for a specific id
38
+ */
39
+ setNode(id: string, node: Node): void;
40
+ /**
41
+ * Get raw markup for a specific id
42
+ */
43
+ getMarkup(id: string): string | null;
44
+ /**
45
+ * Get a node for a specific id
46
+ */
47
+ getNode(id: string): Node | null;
48
+ getNamespace(): string;
49
+ /**
50
+ * Reset the stored markups and nodes
51
+ */
52
+ reset(): void;
53
+ }
54
+ export {};
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MarkupManager = void 0;
4
+ const uuid_1 = require("uuid");
5
+ const utils_1 = require("../utils");
6
+ class MarkupManager extends utils_1.SafeEventEmitter {
7
+ constructor(logger) {
8
+ super();
9
+ this._markups = new Map();
10
+ this._nodes = new Map();
11
+ this.logger = logger;
12
+ this._namespace = (0, uuid_1.v4)();
13
+ }
14
+ /**
15
+ * Set raw markup for a specific id
16
+ */
17
+ setMarkup(id, rawMarkup) {
18
+ var _a, _b;
19
+ if (typeof rawMarkup !== 'string') {
20
+ (_a = this.logger) === null || _a === void 0 ? void 0 : _a.error('[MarkupManager] rawMarkup must be a string');
21
+ return;
22
+ }
23
+ this._markups.set(id, rawMarkup);
24
+ this.emit('markupChanged', { id, rawMarkup });
25
+ (_b = this.logger) === null || _b === void 0 ? void 0 : _b.log(`[MarkupManager] Raw markup for ID ${id} set successfully`);
26
+ }
27
+ /**
28
+ * Set a node for a specific id
29
+ */
30
+ setNode(id, node) {
31
+ var _a, _b;
32
+ if (!node) {
33
+ (_a = this.logger) === null || _a === void 0 ? void 0 : _a.error('[MarkupManager] Node must be a valid ProseMirror Node');
34
+ return;
35
+ }
36
+ this._nodes.set(id, node);
37
+ this.emit('nodeChanged', { id, node });
38
+ (_b = this.logger) === null || _b === void 0 ? void 0 : _b.log(`[MarkupManager] Node for ID ${id} set successfully`);
39
+ }
40
+ /**
41
+ * Get raw markup for a specific id
42
+ */
43
+ getMarkup(id) {
44
+ var _a;
45
+ return (_a = this._markups.get(id)) !== null && _a !== void 0 ? _a : null;
46
+ }
47
+ /**
48
+ * Get a node for a specific id
49
+ */
50
+ getNode(id) {
51
+ var _a;
52
+ return (_a = this._nodes.get(id)) !== null && _a !== void 0 ? _a : null;
53
+ }
54
+ getNamespace() {
55
+ return this._namespace;
56
+ }
57
+ /**
58
+ * Reset the stored markups and nodes
59
+ */
60
+ reset() {
61
+ var _a;
62
+ this._markups.clear();
63
+ this._nodes.clear();
64
+ this.emit('reset', {});
65
+ (_a = this.logger) === null || _a === void 0 ? void 0 : _a.log('[MarkupManager] MarkupManager has been reset');
66
+ }
67
+ }
68
+ exports.MarkupManager = MarkupManager;
@@ -0,0 +1,3 @@
1
+ import { DynamicModifiers } from '../../core/types/dynamicModifiers';
2
+ import { MarkupManager } from '../MarkupManager';
3
+ export declare function createDynamicModifiers(markupManager: MarkupManager): DynamicModifiers[];
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createDynamicModifiers = void 0;
4
+ const uuid_1 = require("uuid");
5
+ const YFM_TABLE_TOKEN_ATTR = 'data-token-id';
6
+ const YFM_TABLE_NODE_ATTR = 'data-node-id';
7
+ const PARENTS_WITH_AFFECT = ['blockquote', 'yfm_tabs'];
8
+ function createDynamicModifiers(markupManager) {
9
+ return [
10
+ {
11
+ type: 'parserToken',
12
+ tokenName: 'yfm_table',
13
+ /**
14
+ * - Assigns a unique `data-token-id` to each token.
15
+ * - Captures and stores the raw Markdown using `MarkupManager`.
16
+ */
17
+ process: (token, _, rawMarkup) => {
18
+ const { map } = token;
19
+ if (map) {
20
+ const content = rawMarkup.split('\n').slice(map[0], map[1]).join('\n');
21
+ const tokenId = (0, uuid_1.v5)(content, markupManager.getNamespace());
22
+ token.attrSet(YFM_TABLE_TOKEN_ATTR, tokenId);
23
+ markupManager.setMarkup(tokenId, content);
24
+ }
25
+ return token;
26
+ },
27
+ },
28
+ {
29
+ type: 'parserNodeAttrs',
30
+ tokenName: 'yfm_table',
31
+ /**
32
+ * - Links the token to its corresponding node via `data-node-id`.
33
+ */
34
+ process: (token, attrs) => (Object.assign(Object.assign({}, attrs), { [YFM_TABLE_NODE_ATTR]: token.attrGet(YFM_TABLE_TOKEN_ATTR) })),
35
+ },
36
+ {
37
+ type: 'parserNode',
38
+ nodeName: 'yfm_table',
39
+ process: (node) => {
40
+ const nodeId = node.attrs[YFM_TABLE_NODE_ATTR];
41
+ if (nodeId) {
42
+ markupManager.setNode(nodeId, node);
43
+ }
44
+ return node;
45
+ },
46
+ },
47
+ {
48
+ type: 'serializerNode',
49
+ nodeName: 'yfm_table',
50
+ /**
51
+ * - Retrieves the original Markdown using the `data-node-id` attribute.
52
+ * - Uses the original Markdown if the node matches the saved version.
53
+ * - Falls back to schema-based rendering if the node structure, attributes, or parent elements affect it.
54
+ */
55
+ process: (state, node, parent, index, callback) => {
56
+ var _a;
57
+ const nodeId = node.attrs[YFM_TABLE_NODE_ATTR];
58
+ const savedNode = markupManager.getNode(nodeId);
59
+ if (!PARENTS_WITH_AFFECT.includes((_a = parent === null || parent === void 0 ? void 0 : parent.type) === null || _a === void 0 ? void 0 : _a.name) && (savedNode === null || savedNode === void 0 ? void 0 : savedNode.eq(node))) {
60
+ state.write(markupManager.getMarkup(nodeId) + '\n');
61
+ return;
62
+ }
63
+ callback === null || callback === void 0 ? void 0 : callback(state, node, parent, index);
64
+ },
65
+ },
66
+ {
67
+ type: 'schemaNodeSpec',
68
+ nodeName: 'yfm_table',
69
+ /**
70
+ * - Adds the `data-node-id` attribute to the list of allowed attributes.
71
+ */
72
+ allowedAttrs: [YFM_TABLE_NODE_ATTR],
73
+ },
74
+ ];
75
+ }
76
+ exports.createDynamicModifiers = createDynamicModifiers;
@@ -7,6 +7,7 @@ const tslib_1 = require("tslib");
7
7
  * @deprecated This file is deprecated. Use ToolbarsPreset instead.
8
8
  */
9
9
  const react_1 = tslib_1.__importDefault(require("react"));
10
+ const HeadingPreview_1 = require("../../bundle/config/previews/HeadingPreview");
10
11
  const menubar_1 = require("../../i18n/menubar");
11
12
  const commands_1 = require("../../markup/commands");
12
13
  const shortcuts_1 = require("../../shortcuts");
@@ -281,6 +282,7 @@ exports.mHeading1ItemData = {
281
282
  exec: (e) => (0, commands_1.toH1)(e.cm),
282
283
  isActive: inactive,
283
284
  isEnable: enable,
285
+ preview: react_1.default.createElement(HeadingPreview_1.HeadingPreview, { level: 1 }),
284
286
  };
285
287
  exports.mHeading2ItemData = {
286
288
  id: action_names_1.ActionName.heading2,
@@ -290,6 +292,7 @@ exports.mHeading2ItemData = {
290
292
  exec: (e) => (0, commands_1.toH2)(e.cm),
291
293
  isActive: inactive,
292
294
  isEnable: enable,
295
+ preview: react_1.default.createElement(HeadingPreview_1.HeadingPreview, { level: 2 }),
293
296
  };
294
297
  exports.mHeading3ItemData = {
295
298
  id: action_names_1.ActionName.heading3,
@@ -299,6 +302,7 @@ exports.mHeading3ItemData = {
299
302
  exec: (e) => (0, commands_1.toH3)(e.cm),
300
303
  isActive: inactive,
301
304
  isEnable: enable,
305
+ preview: react_1.default.createElement(HeadingPreview_1.HeadingPreview, { level: 3 }),
302
306
  };
303
307
  exports.mHeading4ItemData = {
304
308
  id: action_names_1.ActionName.heading4,
@@ -308,6 +312,7 @@ exports.mHeading4ItemData = {
308
312
  exec: (e) => (0, commands_1.toH4)(e.cm),
309
313
  isActive: inactive,
310
314
  isEnable: enable,
315
+ preview: react_1.default.createElement(HeadingPreview_1.HeadingPreview, { level: 4 }),
311
316
  };
312
317
  exports.mHeading5ItemData = {
313
318
  id: action_names_1.ActionName.heading5,
@@ -317,6 +322,7 @@ exports.mHeading5ItemData = {
317
322
  exec: (e) => (0, commands_1.toH5)(e.cm),
318
323
  isActive: inactive,
319
324
  isEnable: enable,
325
+ preview: react_1.default.createElement(HeadingPreview_1.HeadingPreview, { level: 5 }),
320
326
  };
321
327
  exports.mHeading6ItemData = {
322
328
  id: action_names_1.ActionName.heading6,
@@ -326,6 +332,7 @@ exports.mHeading6ItemData = {
326
332
  exec: (e) => (0, commands_1.toH6)(e.cm),
327
333
  isActive: inactive,
328
334
  isEnable: enable,
335
+ preview: react_1.default.createElement(HeadingPreview_1.HeadingPreview, { level: 6 }),
329
336
  };
330
337
  exports.mBulletListItemData = {
331
338
  id: action_names_1.ActionName.bulletList,
@@ -0,0 +1,45 @@
1
+ :root {
2
+ --toolbar-item-preview-width: 144px;
3
+ --toolbar-item-preview-height: 104px;
4
+ --toolbar-item-preview-h1-margin: 10px 0 2px;
5
+ --toolbar-item-preview-h2-margin: 20px 0 4px;
6
+ --toolbar-item-preview-h3-margin: 24px 0 4px;
7
+ --toolbar-item-preview-h4-margin: 24px 0 4px;
8
+ --toolbar-item-preview-h5-margin: 26px 0 6px;
9
+ --toolbar-item-preview-h6-margin: 28px 0 6px;
10
+ }
11
+
12
+ .g-md-action-preview {
13
+ overflow: hidden;
14
+ width: var(--toolbar-item-preview-width);
15
+ height: var(--toolbar-item-preview-height);
16
+ white-space: pre;
17
+ }
18
+ .g-md-action-preview.yfm > *:not(h2):not(h3):not(h4):not(h5):not(h6):first-child {
19
+ /* stylelint-disable-next-line declaration-no-important */
20
+ margin: var(--toolbar-item-preview-h1-margin) !important;
21
+ }
22
+ .g-md-action-preview.yfm > h2 {
23
+ /* stylelint-disable-next-line declaration-no-important */
24
+ margin: var(--toolbar-item-preview-h2-margin) !important;
25
+ }
26
+ .g-md-action-preview.yfm > h3 {
27
+ /* stylelint-disable-next-line declaration-no-important */
28
+ margin: var(--toolbar-item-preview-h3-margin) !important;
29
+ }
30
+ .g-md-action-preview.yfm > h4 {
31
+ /* stylelint-disable-next-line declaration-no-important */
32
+ margin: var(--toolbar-item-preview-h4-margin) !important;
33
+ }
34
+ .g-md-action-preview.yfm > h5 {
35
+ /* stylelint-disable-next-line declaration-no-important */
36
+ margin: var(--toolbar-item-preview-h5-margin) !important;
37
+ }
38
+ .g-md-action-preview.yfm > h6 {
39
+ /* stylelint-disable-next-line declaration-no-important */
40
+ margin: var(--toolbar-item-preview-h6-margin) !important;
41
+ }
42
+ .g-md-action-preview__text-with-head {
43
+ margin-top: 0;
44
+ color: var(--g-color-text-hint);
45
+ }
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ export declare const ActionPreview: ({ children }: {
3
+ children: React.ReactNode;
4
+ }) => JSX.Element;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ActionPreview = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const react_1 = tslib_1.__importDefault(require("react"));
6
+ const classname_1 = require("../../../classname");
7
+ const b = (0, classname_1.cn)('action-preview');
8
+ const ActionPreview = ({ children }) => {
9
+ return react_1.default.createElement("div", { className: b(null, ['yfm']) }, children);
10
+ };
11
+ exports.ActionPreview = ActionPreview;
@@ -0,0 +1,5 @@
1
+ declare type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
2
+ export declare const HeadingPreview: ({ level }: {
3
+ level: HeadingLevel;
4
+ }) => JSX.Element;
5
+ export {};
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HeadingPreview = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const react_1 = tslib_1.__importDefault(require("react"));
6
+ const classname_1 = require("../../../classname");
7
+ const action_previews_1 = require("../../../i18n/action-previews");
8
+ const ActionPreview_1 = require("./ActionPreview");
9
+ const b = (0, classname_1.cn)('action-preview');
10
+ const HeadingPreview = ({ level }) => {
11
+ const Heading = `h${level}`;
12
+ return (react_1.default.createElement(ActionPreview_1.ActionPreview, null,
13
+ react_1.default.createElement(Heading, null, (0, action_previews_1.i18n)('heading')),
14
+ react_1.default.createElement("p", { className: b('text-with-head') }, (0, action_previews_1.i18n)('text-with-head'))));
15
+ };
16
+ exports.HeadingPreview = HeadingPreview;
@@ -0,0 +1 @@
1
+ export declare const TextPreview: () => JSX.Element;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TextPreview = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const react_1 = tslib_1.__importDefault(require("react"));
6
+ const classname_1 = require("../../../classname");
7
+ const action_previews_1 = require("../../../i18n/action-previews");
8
+ const ActionPreview_1 = require("./ActionPreview");
9
+ const b = (0, classname_1.cn)('action-preview');
10
+ const TextPreview = () => {
11
+ return (react_1.default.createElement(ActionPreview_1.ActionPreview, null,
12
+ react_1.default.createElement("p", { className: b('text') }, (0, action_previews_1.i18n)('text'))));
13
+ };
14
+ exports.TextPreview = TextPreview;
@@ -1,10 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.wHeadingListConfig = exports.wHeading6ItemData = exports.wHeading5ItemData = exports.wHeading4ItemData = exports.wHeading3ItemData = exports.wHeading2ItemData = exports.wHeading1ItemData = exports.wTextItemData = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const react_1 = tslib_1.__importDefault(require("react"));
4
6
  const menubar_1 = require("../../i18n/menubar");
5
7
  const shortcuts_1 = require("../../shortcuts");
6
8
  const action_names_1 = require("./action-names");
7
9
  const icons_1 = require("./icons");
10
+ const HeadingPreview_1 = require("./previews/HeadingPreview");
11
+ const TextPreview_1 = require("./previews/TextPreview");
8
12
  exports.wTextItemData = {
9
13
  id: action_names_1.ActionName.paragraph,
10
14
  title: menubar_1.i18n.bind(null, 'text'),
@@ -14,6 +18,7 @@ exports.wTextItemData = {
14
18
  isActive: (e) => e.actions.toParagraph.isActive(),
15
19
  isEnable: (e) => e.actions.toParagraph.isEnable(),
16
20
  doNotActivateList: true,
21
+ preview: react_1.default.createElement(TextPreview_1.TextPreview, null),
17
22
  };
18
23
  exports.wHeading1ItemData = {
19
24
  id: action_names_1.ActionName.heading1,
@@ -23,6 +28,7 @@ exports.wHeading1ItemData = {
23
28
  exec: (e) => e.actions.toH1.run(),
24
29
  isActive: (e) => e.actions.toH1.isActive(),
25
30
  isEnable: (e) => e.actions.toH1.isEnable(),
31
+ preview: react_1.default.createElement(HeadingPreview_1.HeadingPreview, { level: 1 }),
26
32
  };
27
33
  exports.wHeading2ItemData = {
28
34
  id: action_names_1.ActionName.heading2,
@@ -32,6 +38,7 @@ exports.wHeading2ItemData = {
32
38
  exec: (e) => e.actions.toH2.run(),
33
39
  isActive: (e) => e.actions.toH2.isActive(),
34
40
  isEnable: (e) => e.actions.toH2.isEnable(),
41
+ preview: react_1.default.createElement(HeadingPreview_1.HeadingPreview, { level: 2 }),
35
42
  };
36
43
  exports.wHeading3ItemData = {
37
44
  id: action_names_1.ActionName.heading3,
@@ -41,6 +48,7 @@ exports.wHeading3ItemData = {
41
48
  exec: (e) => e.actions.toH3.run(),
42
49
  isActive: (e) => e.actions.toH3.isActive(),
43
50
  isEnable: (e) => e.actions.toH3.isEnable(),
51
+ preview: react_1.default.createElement(HeadingPreview_1.HeadingPreview, { level: 3 }),
44
52
  };
45
53
  exports.wHeading4ItemData = {
46
54
  id: action_names_1.ActionName.heading4,
@@ -50,6 +58,7 @@ exports.wHeading4ItemData = {
50
58
  exec: (e) => e.actions.toH4.run(),
51
59
  isActive: (e) => e.actions.toH4.isActive(),
52
60
  isEnable: (e) => e.actions.toH4.isEnable(),
61
+ preview: react_1.default.createElement(HeadingPreview_1.HeadingPreview, { level: 4 }),
53
62
  };
54
63
  exports.wHeading5ItemData = {
55
64
  id: action_names_1.ActionName.heading5,
@@ -59,6 +68,7 @@ exports.wHeading5ItemData = {
59
68
  exec: (e) => e.actions.toH5.run(),
60
69
  isActive: (e) => e.actions.toH5.isActive(),
61
70
  isEnable: (e) => e.actions.toH5.isEnable(),
71
+ preview: react_1.default.createElement(HeadingPreview_1.HeadingPreview, { level: 5 }),
62
72
  };
63
73
  exports.wHeading6ItemData = {
64
74
  id: action_names_1.ActionName.heading6,
@@ -68,6 +78,7 @@ exports.wHeading6ItemData = {
68
78
  exec: (e) => e.actions.toH6.run(),
69
79
  isActive: (e) => e.actions.toH6.isActive(),
70
80
  isEnable: (e) => e.actions.toH6.isEnable(),
81
+ preview: react_1.default.createElement(HeadingPreview_1.HeadingPreview, { level: 6 }),
71
82
  };
72
83
  exports.wHeadingListConfig = {
73
84
  icon: icons_1.icons.headline,
@@ -19,7 +19,8 @@ const transformItem = (type, item, id = 'unknown') => {
19
19
  return {};
20
20
  }
21
21
  const isListButton = item.view.type === types_1.ToolbarDataType.ListButton;
22
- return Object.assign(Object.assign(Object.assign({ type: (_a = item.view.type) !== null && _a !== void 0 ? _a : types_1.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)));
22
+ const isSingleButton = item.view.type === types_1.ToolbarDataType.SingleButton;
23
+ return Object.assign(Object.assign(Object.assign(Object.assign({ type: (_a = item.view.type) !== null && _a !== void 0 ? _a : types_1.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)));
23
24
  };
24
25
  const createToolbarConfig = (editorType, toolbarPreset, toolbarName) => {
25
26
  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;
@@ -7,21 +7,36 @@ const prosemirror_state_1 = require("prosemirror-state");
7
7
  const prosemirror_view_1 = require("prosemirror-view");
8
8
  const ContentHandler_1 = require("./ContentHandler");
9
9
  const ExtensionsManager_1 = require("./ExtensionsManager");
10
+ const SchemaDynamicModifier_1 = require("./SchemaDynamicModifier");
11
+ const MarkdownParser_1 = require("./markdown/MarkdownParser");
12
+ const MarkdownSerializerDynamicModifier_1 = require("./markdown/MarkdownSerializerDynamicModifier");
10
13
  const actions_1 = require("./utils/actions");
14
+ const dynamicModifiers_1 = require("./utils/dynamicModifiers");
11
15
  const metrics_1 = require("./utils/metrics");
12
16
  class WysiwygEditor {
13
- constructor({ domElem, initialContent = '', extensions = () => { }, allowHTML, mdPreset, linkify, pmTransformers, linkifyTlds, escapeConfig, onChange, onDocChange, }) {
17
+ constructor({ domElem, initialContent = '', extensions = () => { }, allowHTML, mdPreset, linkify, pmTransformers, linkifyTlds, escapeConfig, onChange, onDocChange, modifiers, }) {
14
18
  _WysiwygEditor_view.set(this, void 0);
15
19
  _WysiwygEditor_serializer.set(this, void 0);
16
20
  _WysiwygEditor_parser.set(this, void 0);
17
21
  _WysiwygEditor_actions.set(this, void 0);
18
22
  _WysiwygEditor_contentHandler.set(this, void 0);
19
23
  _WysiwygEditor_escapeConfig.set(this, void 0);
24
+ const dynamicModifiersConfig = modifiers
25
+ ? (0, dynamicModifiers_1.convertDynamicModifiersConfigs)(modifiers)
26
+ : undefined;
27
+ const dynamicModifiers = dynamicModifiersConfig
28
+ ? {
29
+ schema: new SchemaDynamicModifier_1.SchemaDynamicModifier(dynamicModifiersConfig.schema),
30
+ parser: new MarkdownParser_1.MarkdownParserDynamicModifier(dynamicModifiersConfig.parser),
31
+ serializer: new MarkdownSerializerDynamicModifier_1.MarkdownSerializerDynamicModifier(dynamicModifiersConfig.serializer),
32
+ }
33
+ : undefined;
20
34
  const { schema, markupParser: parser, serializer, nodeViews, markViews, plugins, rawActions, actions, } = ExtensionsManager_1.ExtensionsManager.process(extensions, {
21
35
  // "breaks" option only affects the renderer, but not the parser
22
36
  mdOpts: { html: allowHTML, linkify, breaks: true, preset: mdPreset },
23
37
  linkifyTlds,
24
38
  pmTransformers,
39
+ dynamicModifiers,
25
40
  });
26
41
  const state = prosemirror_state_1.EditorState.create({
27
42
  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
  }