@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
@@ -9,6 +9,7 @@ const classname_1 = require("../../../classname");
9
9
  const suggest_1 = require("../../../i18n/suggest");
10
10
  const lodash_1 = require("../../../lodash");
11
11
  const ErrorBoundary_1 = require("../../../react-utils/ErrorBoundary");
12
+ const PreviewTooltip_1 = require("../../../toolbar/PreviewTooltip");
12
13
  const b = (0, classname_1.cn)('command-menu');
13
14
  const placement = ['bottom-start', 'top-start', 'bottom-end', 'top-end'];
14
15
  const ITEM_HEIGHT = 28; // px
@@ -27,16 +28,17 @@ const CommandMenuComponent = ({ anchor, currentIndex, items, onClick, onEnterKey
27
28
  react_1.default.createElement(uikit_1.List, { virtualized: true, items: items, sortable: false, filterable: false, emptyPlaceholder: (0, suggest_1.i18n)('empty-msg'), itemHeight: ITEM_HEIGHT, itemsHeight: calcListHeight(items.length), renderItem: renderItem, deactivateOnLeave: false, activeItemIndex: currentIndex, onItemClick: (_item, index) => onClick(index), className: b('list'), itemClassName: b('list-item') }))));
28
29
  };
29
30
  exports.CommandMenuComponent = CommandMenuComponent;
30
- function renderItem({ id, title, icon, hotkey, hint }) {
31
+ function renderItem({ id, title, icon, hotkey, hint, preview }) {
31
32
  const titleText = (0, lodash_1.isFunction)(title) ? title() : title;
32
33
  const hintText = (0, lodash_1.isFunction)(hint) ? hint() : hint;
33
- return (react_1.default.createElement("div", { key: id, className: b('item', { id }) },
34
- react_1.default.createElement(uikit_1.Icon, { data: icon.data, size: 20, className: b('item-icon') }),
35
- react_1.default.createElement("div", { className: b('item-body') },
36
- react_1.default.createElement("span", { className: b('item-title') }, titleText),
37
- react_1.default.createElement("div", { className: b('item-extra') },
38
- hotkey && react_1.default.createElement(uikit_1.Hotkey, { value: hotkey, className: b('item-hotkey') }),
39
- hintText && react_1.default.createElement(components_1.HelpPopover, { className: b('item- hint'), content: hintText })))));
34
+ return (react_1.default.createElement(PreviewTooltip_1.PreviewTooltip, { preview: preview },
35
+ react_1.default.createElement("div", { key: id, className: b('item', { id }) },
36
+ react_1.default.createElement(uikit_1.Icon, { data: icon.data, size: 20, className: b('item-icon') }),
37
+ react_1.default.createElement("div", { className: b('item-body') },
38
+ react_1.default.createElement("span", { className: b('item-title') }, titleText),
39
+ react_1.default.createElement("div", { className: b('item-extra') },
40
+ hotkey && react_1.default.createElement(uikit_1.Hotkey, { value: hotkey, className: b('item-hotkey') }),
41
+ hintText && react_1.default.createElement(components_1.HelpPopover, { className: b('item-hint'), content: hintText }))))));
40
42
  }
41
43
  function render(props) {
42
44
  return (react_1.default.createElement(ErrorBoundary_1.ErrorLoggerBoundary, null,
@@ -0,0 +1,5 @@
1
+ {
2
+ "text": "This is a text without a title. \nBoth the title and the text \nbelow it can be highlighted in bold, italics, color, \nstrikethrough, and underline. You can also add lists, \ntables, links, formulas, anchors, \nand code blocks.",
3
+ "text-with-head": "This is the text with the title. \nBoth the title and the text \nbelow it can be highlighted in bold, italics, color, \nstrikethrough, and underline. You can also add lists, \ntables, links, formulas, anchors, \nand code blocks.",
4
+ "heading": "Text"
5
+ }
@@ -0,0 +1,7 @@
1
+ export declare const i18n: <G extends "text" | "heading" | "text-with-head", S extends string>(key: G | (string extends S ? S : never), params?: {
2
+ [key: string]: any;
3
+ } | undefined) => S extends G ? {
4
+ text: string;
5
+ "text-with-head": string;
6
+ heading: string;
7
+ }[G] : string;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.i18n = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const i18n_1 = require("../i18n");
6
+ const en_json_1 = tslib_1.__importDefault(require("./en.json"));
7
+ const ru_json_1 = tslib_1.__importDefault(require("./ru.json"));
8
+ const KEYSET = 'action-previews';
9
+ exports.i18n = (0, i18n_1.registerKeyset)(KEYSET, { en: en_json_1.default, ru: ru_json_1.default });
@@ -0,0 +1,5 @@
1
+ {
2
+ "text": "Это текст без заголовка. И заголовок, и \nтекст под ним можно выделять \nполужирным, курсивом, цветом, \nзачёркивать и подчёркивать. А ещё — \nдобавлять списки, таблицы, ссылки, \nформулы, якоря и блоки кода",
3
+ "text-with-head": "Это текст с заголовком. И заголовок, и \nтекст под ним можно выделять \nполужирным, курсивом, цветом, \nзачёркивать и подчёркивать. А ещё — \nдобавлять списки, таблицы, ссылки, \nформулы, якоря и блоки кода.",
4
+ "heading": "О тексте"
5
+ }
@@ -6,6 +6,8 @@ exports.mathListItemView = exports.codeBlocksListItemView = exports.moveListItem
6
6
  const tslib_1 = require("tslib");
7
7
  const react_1 = tslib_1.__importDefault(require("react"));
8
8
  const icons_1 = require("../../bundle/config/icons");
9
+ const HeadingPreview_1 = require("../../bundle/config/previews/HeadingPreview");
10
+ const TextPreview_1 = require("../../bundle/config/previews/TextPreview");
9
11
  const MToolbarColors_1 = require("../../bundle/toolbar/markup/MToolbarColors");
10
12
  const MToolbarFilePopup_1 = require("../../bundle/toolbar/markup/MToolbarFilePopup");
11
13
  const MToolbarImagePopup_1 = require("../../bundle/toolbar/markup/MToolbarImagePopup");
@@ -459,6 +461,7 @@ exports.heading1ItemView = {
459
461
  title: menubar_1.i18n.bind(null, 'heading1'),
460
462
  icon: icons_1.icons.h1,
461
463
  hotkey: shortcuts_1.formatter.toView(shortcuts_1.Action.Heading1),
464
+ preview: react_1.default.createElement(HeadingPreview_1.HeadingPreview, { level: 1 }),
462
465
  };
463
466
  exports.heading1ItemWysiwyg = {
464
467
  exec: (e) => e.actions.toH1.run(),
@@ -476,6 +479,7 @@ exports.heading2ItemView = {
476
479
  title: menubar_1.i18n.bind(null, 'heading2'),
477
480
  icon: icons_1.icons.h2,
478
481
  hotkey: shortcuts_1.formatter.toView(shortcuts_1.Action.Heading2),
482
+ preview: react_1.default.createElement(HeadingPreview_1.HeadingPreview, { level: 2 }),
479
483
  };
480
484
  exports.heading2ItemWysiwyg = {
481
485
  exec: (e) => e.actions.toH2.run(),
@@ -493,6 +497,7 @@ exports.heading3ItemView = {
493
497
  title: menubar_1.i18n.bind(null, 'heading3'),
494
498
  icon: icons_1.icons.h3,
495
499
  hotkey: shortcuts_1.formatter.toView(shortcuts_1.Action.Heading3),
500
+ preview: react_1.default.createElement(HeadingPreview_1.HeadingPreview, { level: 3 }),
496
501
  };
497
502
  exports.heading3ItemWysiwyg = {
498
503
  exec: (e) => e.actions.toH3.run(),
@@ -510,6 +515,7 @@ exports.heading4ItemView = {
510
515
  title: menubar_1.i18n.bind(null, 'heading4'),
511
516
  icon: icons_1.icons.h4,
512
517
  hotkey: shortcuts_1.formatter.toView(shortcuts_1.Action.Heading4),
518
+ preview: react_1.default.createElement(HeadingPreview_1.HeadingPreview, { level: 4 }),
513
519
  };
514
520
  exports.heading4ItemWysiwyg = {
515
521
  exec: (e) => e.actions.toH4.run(),
@@ -527,6 +533,7 @@ exports.heading5ItemView = {
527
533
  title: menubar_1.i18n.bind(null, 'heading5'),
528
534
  icon: icons_1.icons.h5,
529
535
  hotkey: shortcuts_1.formatter.toView(shortcuts_1.Action.Heading5),
536
+ preview: react_1.default.createElement(HeadingPreview_1.HeadingPreview, { level: 5 }),
530
537
  };
531
538
  exports.heading5ItemWysiwyg = {
532
539
  exec: (e) => e.actions.toH5.run(),
@@ -544,6 +551,7 @@ exports.heading6ItemView = {
544
551
  title: menubar_1.i18n.bind(null, 'heading6'),
545
552
  icon: icons_1.icons.h6,
546
553
  hotkey: shortcuts_1.formatter.toView(shortcuts_1.Action.Heading6),
554
+ preview: react_1.default.createElement(HeadingPreview_1.HeadingPreview, { level: 6 }),
547
555
  };
548
556
  exports.heading6ItemWysiwyg = {
549
557
  exec: (e) => e.actions.toH6.run(),
@@ -659,6 +667,7 @@ exports.paragraphItemView = {
659
667
  icon: icons_1.icons.text,
660
668
  hotkey: shortcuts_1.formatter.toView(shortcuts_1.Action.Text),
661
669
  doNotActivateList: true,
670
+ preview: react_1.default.createElement(TextPreview_1.TextPreview, null),
662
671
  };
663
672
  exports.paragraphItemWisywig = {
664
673
  exec: (e) => e.actions.toParagraph.run(),
@@ -22,6 +22,7 @@ export declare type ToolbarItemView<T extends ToolbarDataType = ToolbarDataType.
22
22
  } & (T extends ToolbarDataType.SingleButton ? {
23
23
  icon: ToolbarIconData;
24
24
  title: string | (() => string);
25
+ preview?: React.ReactNode;
25
26
  } : T extends ToolbarDataType.ListButton ? {
26
27
  withArrow?: boolean;
27
28
  icon: ToolbarIconData;
@@ -0,0 +1,8 @@
1
+ .g-md-preview-tooltip {
2
+ padding: var(--g-spacing-3);
3
+ border-radius: var(--g-border-radius-s);
4
+ background-color: var(--g-color-base-float-heavy);
5
+ }
6
+ .g-md-preview-tooltip .g-popup__content:first-child {
7
+ padding: 0 0 0 var(--g-spacing-2);
8
+ }
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ declare type PreviewTooltipProps = {
3
+ preview?: React.ReactNode;
4
+ children: React.ReactElement;
5
+ };
6
+ export declare const PreviewTooltip: React.FC<PreviewTooltipProps>;
7
+ export {};
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PreviewTooltip = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const react_1 = tslib_1.__importDefault(require("react"));
6
+ const uikit_1 = require("@gravity-ui/uikit");
7
+ const classname_1 = require("../classname");
8
+ const const_1 = require("./const");
9
+ const b = (0, classname_1.cn)('preview-tooltip');
10
+ const PreviewTooltip = ({ preview, children }) => {
11
+ return (react_1.default.createElement(uikit_1.Tooltip, { placement: "right", className: b(), contentClassName: b('content'), disabled: !preview, openDelay: const_1.ToolbarTooltipDelay.Open, closeDelay: const_1.ToolbarTooltipDelay.Close, content: preview }, children));
12
+ };
13
+ exports.PreviewTooltip = PreviewTooltip;
@@ -10,6 +10,7 @@ const classname_1 = require("../classname");
10
10
  const common_1 = require("../i18n/common");
11
11
  const lodash_1 = require("../lodash");
12
12
  const hooks_1 = require("../react-utils/hooks");
13
+ const PreviewTooltip_1 = require("./PreviewTooltip");
13
14
  const const_1 = require("./const");
14
15
  const b = (0, classname_1.cn)('toolbar-list-button');
15
16
  function ToolbarListButton({ className, editor, focus, onClick, icon, title, withArrow, data, alwaysActive, }) {
@@ -49,7 +50,7 @@ function ToolbarListButton({ className, editor, focus, onClick, icon, title, wit
49
50
  react_1.default.createElement(uikit_1.Menu, { size: "l", className: b('menu') }, data
50
51
  .map((data) => {
51
52
  var _a;
52
- const { id, title, icon, hotkey, isActive, isEnable, exec, hint, hintWhenDisabled, disabledPopoverVisible = true, } = data;
53
+ const { id, title, icon, hotkey, isActive, isEnable, exec, hint, hintWhenDisabled, disabledPopoverVisible = true, preview, } = data;
53
54
  const titleText = (0, lodash_1.isFunction)(title) ? title() : title;
54
55
  const hintText = (0, lodash_1.isFunction)(hint) ? hint() : hint;
55
56
  const disabled = !isEnable(editor);
@@ -59,24 +60,28 @@ function ToolbarListButton({ className, editor, focus, onClick, icon, title, wit
59
60
  : typeof hintWhenDisabled === 'function'
60
61
  ? hintWhenDisabled()
61
62
  : (0, common_1.i18n)('toolbar_action_disabled');
63
+ const handleClick = () => {
64
+ hide();
65
+ if (isPopupItem(data)) {
66
+ setPopupItem(data);
67
+ }
68
+ else {
69
+ setPopupItem(undefined);
70
+ focus();
71
+ exec(editor);
72
+ onClick === null || onClick === void 0 ? void 0 : onClick(id);
73
+ }
74
+ };
62
75
  return (react_1.default.createElement(uikit_1.Popover, { className: b('action-disabled-popover'), tooltipContentClassName: b('action-disabled-tooltip'), content: hintWhenDisabledText, placement: 'left', disabled: hideHintWhenDisabled, key: id },
63
- react_1.default.createElement(uikit_1.Menu.Item, { key: id, active: isActive(editor), disabled: !isEnable(editor), onClick: () => {
64
- hide();
65
- if (isPopupItem(data)) {
66
- setPopupItem(data);
67
- }
68
- else {
69
- setPopupItem(undefined);
70
- focus();
71
- exec(editor);
72
- onClick === null || onClick === void 0 ? void 0 : onClick(id);
73
- }
74
- }, icon: react_1.default.createElement(uikit_1.Icon, { data: icon.data, size: (_a = icon.size) !== null && _a !== void 0 ? _a : 16 }), extraProps: { 'aria-label': titleText } },
75
- react_1.default.createElement("div", { className: b('item') },
76
- titleText,
77
- react_1.default.createElement("div", { className: b('extra') },
78
- hotkey && react_1.default.createElement(uikit_1.Hotkey, { value: hotkey }),
79
- hintText && (react_1.default.createElement(components_1.HelpPopover, { className: b('hint'), content: hintText })))))));
76
+ react_1.default.createElement(PreviewTooltip_1.PreviewTooltip, { preview: preview },
77
+ react_1.default.createElement(uikit_1.Menu.Item, { key: id, active: isActive(editor), disabled: !isEnable(editor), onClick: handleClick, icon: react_1.default.createElement(uikit_1.Icon, { data: icon.data, size: (_a = icon.size) !== null && _a !== void 0 ? _a : 16 }), extraProps: {
78
+ 'aria-label': titleText,
79
+ } },
80
+ react_1.default.createElement("div", { className: b('item') },
81
+ titleText,
82
+ react_1.default.createElement("div", { className: b('extra') },
83
+ hotkey && react_1.default.createElement(uikit_1.Hotkey, { value: hotkey }),
84
+ hintText && (react_1.default.createElement(components_1.HelpPopover, { className: b('hint'), content: hintText }))))))));
80
85
  })
81
86
  .filter(Boolean))),
82
87
  popupItem
@@ -17,6 +17,7 @@ export declare type ToolbarItemData<E> = {
17
17
  title: string | (() => string);
18
18
  hint?: string | (() => string);
19
19
  hotkey?: HotkeyProps['value'];
20
+ preview?: React.ReactNode;
20
21
  /** @deprecated Use _hintWhenDisabled_ setting instead */
21
22
  disabledPopoverVisible?: boolean;
22
23
  /**
@@ -2,4 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = void 0;
4
4
  /** During build process, the current version will be injected here */
5
- exports.VERSION = typeof '14.11.2' !== 'undefined' ? '14.11.2' : 'unknown';
5
+ exports.VERSION = typeof '14.12.0' !== 'undefined' ? '14.12.0' : 'unknown';
@@ -1,4 +1,4 @@
1
- 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;
1
+ 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;
2
2
  import { __classPrivateFieldGet, __classPrivateFieldSet, __rest } from "tslib";
3
3
  import { EditorView as CMEditorView } from '@codemirror/view';
4
4
  import { TextSelection } from 'prosemirror-state';
@@ -9,6 +9,8 @@ import { createCodemirror } from '../markup';
9
9
  import { getAutocompleteConfig } from '../markup/codemirror/autocomplete';
10
10
  import { Editor as MarkupEditor } from '../markup/editor';
11
11
  import { SafeEventEmitter } from '../utils';
12
+ import { MarkupManager } from './MarkupManager';
13
+ import { createDynamicModifiers } from './config/dynamicModifiers';
12
14
  /** @internal */
13
15
  export class EditorImpl extends SafeEventEmitter {
14
16
  constructor(opts) {
@@ -27,6 +29,7 @@ export class EditorImpl extends SafeEventEmitter {
27
29
  _EditorImpl_mdOptions.set(this, void 0);
28
30
  _EditorImpl_pmTransformers.set(this, []);
29
31
  _EditorImpl_preserveEmptyRows.set(this, void 0);
32
+ _EditorImpl_modifiers.set(this, void 0);
30
33
  _EditorImpl_preset.set(this, void 0);
31
34
  _EditorImpl_extensions.set(this, void 0);
32
35
  _EditorImpl_renderStorage.set(this, void 0);
@@ -39,6 +42,9 @@ export class EditorImpl extends SafeEventEmitter {
39
42
  _EditorImpl_beforeEditorModeChange.set(this, void 0);
40
43
  this.getValue = () => this.currentEditor.getValue();
41
44
  const { md = {}, initial = {}, handlers = {}, experimental = {}, markupConfig = {}, wysiwygConfig = {}, } = opts;
45
+ __classPrivateFieldSet(this, _EditorImpl_modifiers, experimental.preserveMarkupFormatting
46
+ ? createDynamicModifiers(new MarkupManager())
47
+ : undefined, "f");
42
48
  __classPrivateFieldSet(this, _EditorImpl_editorMode, (_a = initial.mode) !== null && _a !== void 0 ? _a : 'wysiwyg', "f");
43
49
  __classPrivateFieldSet(this, _EditorImpl_toolbarVisible, (_b = initial.toolbarVisible) !== null && _b !== void 0 ? _b : true, "f");
44
50
  __classPrivateFieldSet(this, _EditorImpl_splitMode, (_c = (markupConfig.renderPreview && markupConfig.splitMode)) !== null && _c !== void 0 ? _c : false, "f");
@@ -149,6 +155,7 @@ export class EditorImpl extends SafeEventEmitter {
149
155
  initialContent: __classPrivateFieldGet(this, _EditorImpl_markup, "f"),
150
156
  extensions: __classPrivateFieldGet(this, _EditorImpl_extensions, "f"),
151
157
  pmTransformers: __classPrivateFieldGet(this, _EditorImpl_pmTransformers, "f"),
158
+ modifiers: __classPrivateFieldGet(this, _EditorImpl_modifiers, "f"),
152
159
  allowHTML: __classPrivateFieldGet(this, _EditorImpl_mdOptions, "f").html,
153
160
  linkify: __classPrivateFieldGet(this, _EditorImpl_mdOptions, "f").linkify,
154
161
  linkifyTlds: __classPrivateFieldGet(this, _EditorImpl_mdOptions, "f").linkifyTlds,
@@ -326,7 +333,7 @@ export class EditorImpl extends SafeEventEmitter {
326
333
  return (serializedEditorMarkup === null || serializedEditorMarkup === void 0 ? void 0 : serializedEditorMarkup.trim()) !== wysiwygValue.trim();
327
334
  }
328
335
  }
329
- _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();
336
+ _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();
330
337
  function getTopOffset(elem) {
331
338
  const TOOLBAR_HEIGHT = 36; //px
332
339
  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,64 @@
1
+ import { v4 } from 'uuid';
2
+ import { SafeEventEmitter } from '../utils';
3
+ export class MarkupManager extends SafeEventEmitter {
4
+ constructor(logger) {
5
+ super();
6
+ this._markups = new Map();
7
+ this._nodes = new Map();
8
+ this.logger = logger;
9
+ this._namespace = v4();
10
+ }
11
+ /**
12
+ * Set raw markup for a specific id
13
+ */
14
+ setMarkup(id, rawMarkup) {
15
+ var _a, _b;
16
+ if (typeof rawMarkup !== 'string') {
17
+ (_a = this.logger) === null || _a === void 0 ? void 0 : _a.error('[MarkupManager] rawMarkup must be a string');
18
+ return;
19
+ }
20
+ this._markups.set(id, rawMarkup);
21
+ this.emit('markupChanged', { id, rawMarkup });
22
+ (_b = this.logger) === null || _b === void 0 ? void 0 : _b.log(`[MarkupManager] Raw markup for ID ${id} set successfully`);
23
+ }
24
+ /**
25
+ * Set a node for a specific id
26
+ */
27
+ setNode(id, node) {
28
+ var _a, _b;
29
+ if (!node) {
30
+ (_a = this.logger) === null || _a === void 0 ? void 0 : _a.error('[MarkupManager] Node must be a valid ProseMirror Node');
31
+ return;
32
+ }
33
+ this._nodes.set(id, node);
34
+ this.emit('nodeChanged', { id, node });
35
+ (_b = this.logger) === null || _b === void 0 ? void 0 : _b.log(`[MarkupManager] Node for ID ${id} set successfully`);
36
+ }
37
+ /**
38
+ * Get raw markup for a specific id
39
+ */
40
+ getMarkup(id) {
41
+ var _a;
42
+ return (_a = this._markups.get(id)) !== null && _a !== void 0 ? _a : null;
43
+ }
44
+ /**
45
+ * Get a node for a specific id
46
+ */
47
+ getNode(id) {
48
+ var _a;
49
+ return (_a = this._nodes.get(id)) !== null && _a !== void 0 ? _a : null;
50
+ }
51
+ getNamespace() {
52
+ return this._namespace;
53
+ }
54
+ /**
55
+ * Reset the stored markups and nodes
56
+ */
57
+ reset() {
58
+ var _a;
59
+ this._markups.clear();
60
+ this._nodes.clear();
61
+ this.emit('reset', {});
62
+ (_a = this.logger) === null || _a === void 0 ? void 0 : _a.log('[MarkupManager] MarkupManager has been reset');
63
+ }
64
+ }
@@ -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,72 @@
1
+ import { v5 } from 'uuid';
2
+ const YFM_TABLE_TOKEN_ATTR = 'data-token-id';
3
+ const YFM_TABLE_NODE_ATTR = 'data-node-id';
4
+ const PARENTS_WITH_AFFECT = ['blockquote', 'yfm_tabs'];
5
+ export function createDynamicModifiers(markupManager) {
6
+ return [
7
+ {
8
+ type: 'parserToken',
9
+ tokenName: 'yfm_table',
10
+ /**
11
+ * - Assigns a unique `data-token-id` to each token.
12
+ * - Captures and stores the raw Markdown using `MarkupManager`.
13
+ */
14
+ process: (token, _, rawMarkup) => {
15
+ const { map } = token;
16
+ if (map) {
17
+ const content = rawMarkup.split('\n').slice(map[0], map[1]).join('\n');
18
+ const tokenId = v5(content, markupManager.getNamespace());
19
+ token.attrSet(YFM_TABLE_TOKEN_ATTR, tokenId);
20
+ markupManager.setMarkup(tokenId, content);
21
+ }
22
+ return token;
23
+ },
24
+ },
25
+ {
26
+ type: 'parserNodeAttrs',
27
+ tokenName: 'yfm_table',
28
+ /**
29
+ * - Links the token to its corresponding node via `data-node-id`.
30
+ */
31
+ process: (token, attrs) => (Object.assign(Object.assign({}, attrs), { [YFM_TABLE_NODE_ATTR]: token.attrGet(YFM_TABLE_TOKEN_ATTR) })),
32
+ },
33
+ {
34
+ type: 'parserNode',
35
+ nodeName: 'yfm_table',
36
+ process: (node) => {
37
+ const nodeId = node.attrs[YFM_TABLE_NODE_ATTR];
38
+ if (nodeId) {
39
+ markupManager.setNode(nodeId, node);
40
+ }
41
+ return node;
42
+ },
43
+ },
44
+ {
45
+ type: 'serializerNode',
46
+ nodeName: 'yfm_table',
47
+ /**
48
+ * - Retrieves the original Markdown using the `data-node-id` attribute.
49
+ * - Uses the original Markdown if the node matches the saved version.
50
+ * - Falls back to schema-based rendering if the node structure, attributes, or parent elements affect it.
51
+ */
52
+ process: (state, node, parent, index, callback) => {
53
+ var _a;
54
+ const nodeId = node.attrs[YFM_TABLE_NODE_ATTR];
55
+ const savedNode = markupManager.getNode(nodeId);
56
+ 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))) {
57
+ state.write(markupManager.getMarkup(nodeId) + '\n');
58
+ return;
59
+ }
60
+ callback === null || callback === void 0 ? void 0 : callback(state, node, parent, index);
61
+ },
62
+ },
63
+ {
64
+ type: 'schemaNodeSpec',
65
+ nodeName: 'yfm_table',
66
+ /**
67
+ * - Adds the `data-node-id` attribute to the list of allowed attributes.
68
+ */
69
+ allowedAttrs: [YFM_TABLE_NODE_ATTR],
70
+ },
71
+ ];
72
+ }
@@ -2,6 +2,7 @@
2
2
  * @deprecated This file is deprecated. Use ToolbarsPreset instead.
3
3
  */
4
4
  import React from 'react';
5
+ import { HeadingPreview } from '../../bundle/config/previews/HeadingPreview';
5
6
  import { i18n } from '../../i18n/menubar';
6
7
  import { insertHRule, insertLink, insertMermaidDiagram, insertYfmHtmlBlock, insertYfmTable, insertYfmTabs, liftListItem, redo, redoDepth, sinkListItem, toBulletList, toH1, toH2, toH3, toH4, toH5, toH6, toOrderedList, toggleBold, toggleItalic, toggleMarked, toggleMonospace, toggleStrikethrough, toggleUnderline, undo, undoDepth, wrapToBlockquote, wrapToCheckbox, wrapToCodeBlock, wrapToInlineCode, wrapToMathBlock, wrapToMathInline, wrapToYfmCut, wrapToYfmNote, } from '../../markup/commands';
7
8
  import { Action as A, formatter as f } from '../../shortcuts';
@@ -276,6 +277,7 @@ export const mHeading1ItemData = {
276
277
  exec: (e) => toH1(e.cm),
277
278
  isActive: inactive,
278
279
  isEnable: enable,
280
+ preview: React.createElement(HeadingPreview, { level: 1 }),
279
281
  };
280
282
  export const mHeading2ItemData = {
281
283
  id: ActionName.heading2,
@@ -285,6 +287,7 @@ export const mHeading2ItemData = {
285
287
  exec: (e) => toH2(e.cm),
286
288
  isActive: inactive,
287
289
  isEnable: enable,
290
+ preview: React.createElement(HeadingPreview, { level: 2 }),
288
291
  };
289
292
  export const mHeading3ItemData = {
290
293
  id: ActionName.heading3,
@@ -294,6 +297,7 @@ export const mHeading3ItemData = {
294
297
  exec: (e) => toH3(e.cm),
295
298
  isActive: inactive,
296
299
  isEnable: enable,
300
+ preview: React.createElement(HeadingPreview, { level: 3 }),
297
301
  };
298
302
  export const mHeading4ItemData = {
299
303
  id: ActionName.heading4,
@@ -303,6 +307,7 @@ export const mHeading4ItemData = {
303
307
  exec: (e) => toH4(e.cm),
304
308
  isActive: inactive,
305
309
  isEnable: enable,
310
+ preview: React.createElement(HeadingPreview, { level: 4 }),
306
311
  };
307
312
  export const mHeading5ItemData = {
308
313
  id: ActionName.heading5,
@@ -312,6 +317,7 @@ export const mHeading5ItemData = {
312
317
  exec: (e) => toH5(e.cm),
313
318
  isActive: inactive,
314
319
  isEnable: enable,
320
+ preview: React.createElement(HeadingPreview, { level: 5 }),
315
321
  };
316
322
  export const mHeading6ItemData = {
317
323
  id: ActionName.heading6,
@@ -321,6 +327,7 @@ export const mHeading6ItemData = {
321
327
  exec: (e) => toH6(e.cm),
322
328
  isActive: inactive,
323
329
  isEnable: enable,
330
+ preview: React.createElement(HeadingPreview, { level: 6 }),
324
331
  };
325
332
  export const mBulletListItemData = {
326
333
  id: 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,5 @@
1
+ import React from 'react';
2
+ import './ActionPreview.css';
3
+ export declare const ActionPreview: ({ children }: {
4
+ children: React.ReactNode;
5
+ }) => JSX.Element;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { cn } from '../../../classname';
3
+ import './ActionPreview.css';
4
+ const b = cn('action-preview');
5
+ export const ActionPreview = ({ children }) => {
6
+ return React.createElement("div", { className: b(null, ['yfm']) }, children);
7
+ };
@@ -0,0 +1,6 @@
1
+ import './ActionPreview.css';
2
+ declare type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
3
+ export declare const HeadingPreview: ({ level }: {
4
+ level: HeadingLevel;
5
+ }) => JSX.Element;
6
+ export {};
@@ -0,0 +1,12 @@
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 HeadingPreview = ({ level }) => {
8
+ const Heading = `h${level}`;
9
+ return (React.createElement(ActionPreview, null,
10
+ React.createElement(Heading, null, i18n('heading')),
11
+ React.createElement("p", { className: b('text-with-head') }, i18n('text-with-head'))));
12
+ };