@gravity-ui/markdown-editor 15.37.0 → 15.38.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 (129) hide show
  1. package/build/cjs/core/ExtensionBuilder.d.ts +21 -0
  2. package/build/cjs/core/ExtensionBuilder.js +306 -4
  3. package/build/cjs/core/ExtensionBuilder.js.map +1 -1
  4. package/build/cjs/core/markdown/MarkdownSerializer.d.ts +4 -1
  5. package/build/cjs/core/markdown/MarkdownSerializer.js +86 -23
  6. package/build/cjs/core/markdown/MarkdownSerializer.js.map +1 -1
  7. package/build/cjs/extensions/behavior/SelectionContext/TextSelectionTooltip.d.ts +13 -0
  8. package/build/cjs/extensions/behavior/SelectionContext/TextSelectionTooltip.js +42 -0
  9. package/build/cjs/extensions/behavior/SelectionContext/TextSelectionTooltip.js.map +1 -0
  10. package/build/cjs/extensions/behavior/SelectionContext/index.js +10 -7
  11. package/build/cjs/extensions/behavior/SelectionContext/index.js.map +1 -1
  12. package/build/cjs/extensions/behavior/SelectionContext/tooltip.d.ts +11 -15
  13. package/build/cjs/extensions/behavior/SelectionContext/tooltip.js +24 -56
  14. package/build/cjs/extensions/behavior/SelectionContext/tooltip.js.map +1 -1
  15. package/build/cjs/extensions/behavior/SelectionContext/types.d.ts +10 -0
  16. package/build/cjs/extensions/behavior/SelectionContext/types.js +3 -0
  17. package/build/cjs/extensions/behavior/SelectionContext/types.js.map +1 -0
  18. package/build/cjs/extensions/markdown/CodeBlock/CodeBlockSpecs/index.js +24 -34
  19. package/build/cjs/extensions/markdown/CodeBlock/CodeBlockSpecs/index.js.map +1 -1
  20. package/build/cjs/extensions/markdown/Heading/HeadingSpecs/const.d.ts +4 -0
  21. package/build/cjs/extensions/markdown/Heading/HeadingSpecs/const.js +9 -0
  22. package/build/cjs/extensions/markdown/Heading/HeadingSpecs/const.js.map +1 -0
  23. package/build/cjs/extensions/markdown/Heading/HeadingSpecs/index.d.ts +3 -5
  24. package/build/cjs/extensions/markdown/Heading/HeadingSpecs/index.js +22 -25
  25. package/build/cjs/extensions/markdown/Heading/HeadingSpecs/index.js.map +1 -1
  26. package/build/cjs/extensions/markdown/Heading/HeadingSpecs/utils.d.ts +7 -0
  27. package/build/cjs/extensions/markdown/Heading/HeadingSpecs/utils.js +15 -0
  28. package/build/cjs/extensions/markdown/Heading/HeadingSpecs/utils.js.map +1 -0
  29. package/build/cjs/extensions/markdown/Heading/actions.d.ts +2 -2
  30. package/build/cjs/extensions/markdown/Heading/actions.js +3 -4
  31. package/build/cjs/extensions/markdown/Heading/actions.js.map +1 -1
  32. package/build/cjs/extensions/markdown/Heading/commands.d.ts +3 -1
  33. package/build/cjs/extensions/markdown/Heading/commands.js +16 -1
  34. package/build/cjs/extensions/markdown/Heading/commands.js.map +1 -1
  35. package/build/cjs/extensions/markdown/Heading/index.js +7 -9
  36. package/build/cjs/extensions/markdown/Heading/index.js.map +1 -1
  37. package/build/cjs/extensions/markdown/Lists/index.js +1 -0
  38. package/build/cjs/extensions/markdown/Lists/index.js.map +1 -1
  39. package/build/cjs/extensions/markdown/Lists/plugins/CollapseListsPlugin.d.ts +14 -2
  40. package/build/cjs/extensions/markdown/Lists/plugins/CollapseListsPlugin.js +97 -51
  41. package/build/cjs/extensions/markdown/Lists/plugins/CollapseListsPlugin.js.map +1 -1
  42. package/build/cjs/extensions/yfm/YfmHeading/YfmHeadingSpecs/const.d.ts +1 -1
  43. package/build/cjs/extensions/yfm/YfmHeading/YfmHeadingSpecs/const.js +2 -2
  44. package/build/cjs/extensions/yfm/YfmHeading/YfmHeadingSpecs/const.js.map +1 -1
  45. package/build/cjs/extensions/yfm/YfmHeading/YfmHeadingSpecs/index.d.ts +3 -7
  46. package/build/cjs/extensions/yfm/YfmHeading/YfmHeadingSpecs/index.js +72 -90
  47. package/build/cjs/extensions/yfm/YfmHeading/YfmHeadingSpecs/index.js.map +1 -1
  48. package/build/cjs/extensions/yfm/YfmHeading/YfmHeadingSpecs/utils.d.ts +3 -0
  49. package/build/cjs/extensions/yfm/YfmHeading/YfmHeadingSpecs/utils.js +14 -1
  50. package/build/cjs/extensions/yfm/YfmHeading/YfmHeadingSpecs/utils.js.map +1 -1
  51. package/build/cjs/extensions/yfm/YfmHeading/actions.js +2 -10
  52. package/build/cjs/extensions/yfm/YfmHeading/actions.js.map +1 -1
  53. package/build/cjs/extensions/yfm/YfmHeading/commands.d.ts +1 -4
  54. package/build/cjs/extensions/yfm/YfmHeading/commands.js +3 -21
  55. package/build/cjs/extensions/yfm/YfmHeading/commands.js.map +1 -1
  56. package/build/cjs/extensions/yfm/YfmHeading/index.d.ts +3 -22
  57. package/build/cjs/extensions/yfm/YfmHeading/index.js +2 -33
  58. package/build/cjs/extensions/yfm/YfmHeading/index.js.map +1 -1
  59. package/build/cjs/presets/yfm-specs.js +5 -1
  60. package/build/cjs/presets/yfm-specs.js.map +1 -1
  61. package/build/cjs/presets/yfm.js +5 -1
  62. package/build/cjs/presets/yfm.js.map +1 -1
  63. package/build/cjs/version.js +1 -1
  64. package/build/cjs/version.js.map +1 -1
  65. package/build/esm/core/ExtensionBuilder.d.ts +21 -0
  66. package/build/esm/core/ExtensionBuilder.js +306 -4
  67. package/build/esm/core/ExtensionBuilder.js.map +1 -1
  68. package/build/esm/core/markdown/MarkdownSerializer.d.ts +4 -1
  69. package/build/esm/core/markdown/MarkdownSerializer.js +86 -23
  70. package/build/esm/core/markdown/MarkdownSerializer.js.map +1 -1
  71. package/build/esm/extensions/behavior/SelectionContext/TextSelectionTooltip.d.ts +13 -0
  72. package/build/esm/extensions/behavior/SelectionContext/TextSelectionTooltip.js +38 -0
  73. package/build/esm/extensions/behavior/SelectionContext/TextSelectionTooltip.js.map +1 -0
  74. package/build/esm/extensions/behavior/SelectionContext/index.js +10 -7
  75. package/build/esm/extensions/behavior/SelectionContext/index.js.map +1 -1
  76. package/build/esm/extensions/behavior/SelectionContext/tooltip.d.ts +11 -15
  77. package/build/esm/extensions/behavior/SelectionContext/tooltip.js +24 -56
  78. package/build/esm/extensions/behavior/SelectionContext/tooltip.js.map +1 -1
  79. package/build/esm/extensions/behavior/SelectionContext/types.d.ts +10 -0
  80. package/build/esm/extensions/behavior/SelectionContext/types.js +2 -0
  81. package/build/esm/extensions/behavior/SelectionContext/types.js.map +1 -0
  82. package/build/esm/extensions/markdown/CodeBlock/CodeBlockSpecs/index.js +24 -34
  83. package/build/esm/extensions/markdown/CodeBlock/CodeBlockSpecs/index.js.map +1 -1
  84. package/build/esm/extensions/markdown/Heading/HeadingSpecs/const.d.ts +4 -0
  85. package/build/esm/extensions/markdown/Heading/HeadingSpecs/const.js +6 -0
  86. package/build/esm/extensions/markdown/Heading/HeadingSpecs/const.js.map +1 -0
  87. package/build/esm/extensions/markdown/Heading/HeadingSpecs/index.d.ts +3 -5
  88. package/build/esm/extensions/markdown/Heading/HeadingSpecs/index.js +5 -10
  89. package/build/esm/extensions/markdown/Heading/HeadingSpecs/index.js.map +1 -1
  90. package/build/esm/extensions/markdown/Heading/HeadingSpecs/utils.d.ts +7 -0
  91. package/build/esm/extensions/markdown/Heading/HeadingSpecs/utils.js +12 -0
  92. package/build/esm/extensions/markdown/Heading/HeadingSpecs/utils.js.map +1 -0
  93. package/build/esm/extensions/markdown/Heading/actions.d.ts +2 -2
  94. package/build/esm/extensions/markdown/Heading/actions.js +3 -4
  95. package/build/esm/extensions/markdown/Heading/actions.js.map +1 -1
  96. package/build/esm/extensions/markdown/Heading/commands.d.ts +3 -1
  97. package/build/esm/extensions/markdown/Heading/commands.js +15 -1
  98. package/build/esm/extensions/markdown/Heading/commands.js.map +1 -1
  99. package/build/esm/extensions/markdown/Heading/index.js +9 -11
  100. package/build/esm/extensions/markdown/Heading/index.js.map +1 -1
  101. package/build/esm/extensions/markdown/Lists/index.js +1 -0
  102. package/build/esm/extensions/markdown/Lists/index.js.map +1 -1
  103. package/build/esm/extensions/markdown/Lists/plugins/CollapseListsPlugin.d.ts +14 -2
  104. package/build/esm/extensions/markdown/Lists/plugins/CollapseListsPlugin.js +95 -49
  105. package/build/esm/extensions/markdown/Lists/plugins/CollapseListsPlugin.js.map +1 -1
  106. package/build/esm/extensions/yfm/YfmHeading/YfmHeadingSpecs/const.d.ts +1 -1
  107. package/build/esm/extensions/yfm/YfmHeading/YfmHeadingSpecs/const.js +3 -3
  108. package/build/esm/extensions/yfm/YfmHeading/YfmHeadingSpecs/const.js.map +1 -1
  109. package/build/esm/extensions/yfm/YfmHeading/YfmHeadingSpecs/index.d.ts +3 -7
  110. package/build/esm/extensions/yfm/YfmHeading/YfmHeadingSpecs/index.js +70 -90
  111. package/build/esm/extensions/yfm/YfmHeading/YfmHeadingSpecs/index.js.map +1 -1
  112. package/build/esm/extensions/yfm/YfmHeading/YfmHeadingSpecs/utils.d.ts +3 -0
  113. package/build/esm/extensions/yfm/YfmHeading/YfmHeadingSpecs/utils.js +11 -0
  114. package/build/esm/extensions/yfm/YfmHeading/YfmHeadingSpecs/utils.js.map +1 -1
  115. package/build/esm/extensions/yfm/YfmHeading/actions.js +2 -10
  116. package/build/esm/extensions/yfm/YfmHeading/actions.js.map +1 -1
  117. package/build/esm/extensions/yfm/YfmHeading/commands.d.ts +1 -4
  118. package/build/esm/extensions/yfm/YfmHeading/commands.js +3 -21
  119. package/build/esm/extensions/yfm/YfmHeading/commands.js.map +1 -1
  120. package/build/esm/extensions/yfm/YfmHeading/index.d.ts +3 -22
  121. package/build/esm/extensions/yfm/YfmHeading/index.js +0 -31
  122. package/build/esm/extensions/yfm/YfmHeading/index.js.map +1 -1
  123. package/build/esm/presets/yfm-specs.js +5 -1
  124. package/build/esm/presets/yfm-specs.js.map +1 -1
  125. package/build/esm/presets/yfm.js +5 -1
  126. package/build/esm/presets/yfm.js.map +1 -1
  127. package/build/esm/version.js +1 -1
  128. package/build/esm/version.js.map +1 -1
  129. package/package.json +2 -2
@@ -2,102 +2,74 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TooltipView = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
- const uikit_1 = require("@gravity-ui/uikit");
6
- const lodash_1 = require("../../../lodash.js");
7
5
  const logger_1 = require("../../../logger.js");
8
6
  const ErrorBoundary_1 = require("../../../react-utils/ErrorBoundary.js");
9
- const toolbar_1 = require("../../../toolbar/index.js");
10
7
  const ReactRenderer_1 = require("../ReactRenderer/index.js");
11
- const SelectionTooltip = ({ show, poppupProps, ...toolbarProps }) => {
12
- if (!show)
13
- return null;
14
- return ((0, jsx_runtime_1.jsx)(uikit_1.Popup, { open: true, ...poppupProps, style: { padding: '4px 8px' }, children: (0, jsx_runtime_1.jsx)(toolbar_1.Toolbar, { ...toolbarProps }) }));
15
- };
8
+ const TextSelectionTooltip_1 = require("./TextSelectionTooltip.js");
16
9
  class TooltipView {
17
10
  #isTooltipOpen = false;
18
11
  logger;
19
12
  actions;
20
13
  menuConfig;
21
14
  placement;
15
+ onPopupOpenChange;
22
16
  view;
23
- baseProps = { show: false, poppupProps: {} };
17
+ visible = false;
18
+ anchor = undefined;
24
19
  _tooltipRenderItem = null;
25
20
  constructor(actions, menuConfig, logger, params) {
26
21
  this.logger = logger;
27
22
  this.actions = actions;
28
23
  this.menuConfig = menuConfig;
29
- const { flip, placement = 'bottom' } = params;
24
+ const { flip, placement = 'bottom', onPopupOpenChange } = params;
30
25
  this.placement = flip ? placement : [placement];
26
+ this.onPopupOpenChange = onPopupOpenChange;
31
27
  }
32
28
  get isTooltipOpen() {
33
29
  return this.#isTooltipOpen;
34
30
  }
35
- show(view, popupProps) {
31
+ show(view) {
36
32
  this.view = view;
37
33
  this.#isTooltipOpen = true;
38
- this.baseProps = {
39
- show: true,
40
- poppupProps: {
41
- ...popupProps,
42
- ...this.calcPosition(view),
43
- },
44
- };
34
+ this.visible = true;
35
+ this.anchor ??= this.createVirtualElement(view);
45
36
  this.renderPopup();
46
37
  }
47
38
  hide(view) {
48
39
  this.view = view;
49
40
  // do not rerender popup if it is already hidden
50
- if (!this.#isTooltipOpen && !this.baseProps.show)
41
+ if (!this.#isTooltipOpen && !this.visible)
51
42
  return;
52
43
  this.#isTooltipOpen = false;
53
- this.baseProps = { show: false, poppupProps: {} };
44
+ this.visible = false;
45
+ this.anchor = undefined;
54
46
  this.renderPopup();
55
47
  }
56
48
  destroy() {
57
49
  this._tooltipRenderItem?.remove();
58
50
  this._tooltipRenderItem = null;
59
51
  }
60
- getSelectionTooltipProps() {
61
- return {
62
- ...this.baseProps,
63
- qa: 'g-md-toolbar-selection',
64
- focus: () => this.view.focus(),
65
- data: this.getFilteredConfig(),
66
- editor: this.actions,
67
- onClick: (id) => {
68
- logger_1.globalLogger.action({ mode: 'wysiwyg', source: 'context-menu', action: id });
69
- this.logger.action({ source: 'context-menu', action: id });
70
- },
71
- };
72
- }
73
- getFilteredConfig() {
74
- return this.baseProps.show
75
- ? this.menuConfig
76
- .map((groupData) => groupData.filter((item) => {
77
- const { condition } = item;
78
- if (condition === 'enabled') {
79
- return item.isEnable(this.actions);
80
- }
81
- if ((0, lodash_1.isFunction)(condition)) {
82
- return condition(this.view.state);
83
- }
84
- return true;
85
- }))
86
- .filter((groupData) => Boolean(groupData.length))
87
- : [];
88
- }
52
+ handleFocus = () => this.view.focus();
53
+ handleClick = (id) => {
54
+ logger_1.globalLogger.action({ mode: 'wysiwyg', source: 'context-menu', action: id });
55
+ this.logger.action({ source: 'context-menu', action: id });
56
+ };
89
57
  renderPopup() {
90
58
  this.tooltipRenderItem.rerender();
91
59
  }
92
60
  get tooltipRenderItem() {
93
61
  if (!this._tooltipRenderItem) {
94
62
  const reactRenderer = (0, ReactRenderer_1.getReactRendererFromState)(this.view.state);
95
- this._tooltipRenderItem = reactRenderer.createItem('selection_context', () => ((0, jsx_runtime_1.jsx)(ErrorBoundary_1.ErrorLoggerBoundary, { children: (0, jsx_runtime_1.jsx)(SelectionTooltip, { ...this.getSelectionTooltipProps() }) })));
63
+ this._tooltipRenderItem = reactRenderer.createItem('selection_context', () => {
64
+ if (!this.visible)
65
+ return null;
66
+ return ((0, jsx_runtime_1.jsx)(ErrorBoundary_1.ErrorLoggerBoundary, { children: (0, jsx_runtime_1.jsx)(TextSelectionTooltip_1.TextSelectionTooltip, { config: this.menuConfig, editor: this.actions, editorView: this.view, focus: this.handleFocus, onClick: this.handleClick, popupPlacement: this.placement, popupAnchor: this.anchor, popupOnOpenChange: this.onPopupOpenChange }) }));
67
+ });
96
68
  }
97
69
  return this._tooltipRenderItem;
98
70
  }
99
- calcPosition(view) {
100
- const virtualElem = {
71
+ createVirtualElement(view) {
72
+ return {
101
73
  getBoundingClientRect() {
102
74
  // These are in screen coordinates
103
75
  const start = view.coordsAtPos(view.state.selection.from);
@@ -121,10 +93,6 @@ class TooltipView {
121
93
  };
122
94
  },
123
95
  };
124
- return {
125
- placement: this.placement,
126
- anchorElement: virtualElem,
127
- };
128
96
  }
129
97
  }
130
98
  exports.TooltipView = TooltipView;
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/SelectionContext/tooltip.tsx"],"names":[],"mappings":"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","sourcesContent":["import type {VirtualElement} from '@floating-ui/react';\nimport {Popup, type PopupPlacement, type PopupProps} from '@gravity-ui/uikit';\nimport type {EditorState} from 'prosemirror-state';\nimport type {EditorView} from 'prosemirror-view';\n\nimport type {ActionStorage} from '../../../core';\nimport {isFunction} from '../../../lodash';\nimport {type Logger2, globalLogger} from '../../../logger';\nimport {ErrorLoggerBoundary} from '../../../react-utils/ErrorBoundary';\nimport {Toolbar} from '../../../toolbar';\nimport type {\n ToolbarButtonPopupData,\n ToolbarGroupItemData,\n ToolbarProps,\n ToolbarSingleItemData,\n} from '../../../toolbar';\nimport {type RendererItem, getReactRendererFromState} from '../ReactRenderer';\n\ntype SelectionTooltipBaseProps = {\n show?: boolean;\n poppupProps: PopupProps;\n};\ntype SelectionTooltipProps = SelectionTooltipBaseProps & ToolbarProps<ActionStorage>;\n\nconst SelectionTooltip: React.FC<SelectionTooltipProps> = ({\n show,\n poppupProps,\n ...toolbarProps\n}) => {\n if (!show) return null;\n return (\n <Popup open {...poppupProps} style={{padding: '4px 8px'}}>\n <Toolbar {...toolbarProps} />\n </Popup>\n );\n};\n\nexport type ContextGroupItemData =\n | (ToolbarGroupItemData<ActionStorage> & {\n condition?: (state: EditorState) => void;\n })\n | ((ToolbarSingleItemData<ActionStorage> | ToolbarButtonPopupData<ActionStorage>) & {\n condition?: 'enabled';\n });\n\nexport type ContextGroupData = ContextGroupItemData[];\nexport type ContextConfig = ContextGroupData[];\n\nexport type TooltipViewParams = {\n /** @default 'bottom' */\n placement?: 'top' | 'bottom';\n /** @default false */\n flip?: boolean;\n};\n\nexport class TooltipView {\n #isTooltipOpen = false;\n\n private readonly logger: Logger2.ILogger;\n private readonly actions: ActionStorage;\n private readonly menuConfig: ContextConfig;\n private readonly placement: PopupPlacement;\n\n private view!: EditorView;\n private baseProps: SelectionTooltipBaseProps = {show: false, poppupProps: {}};\n private _tooltipRenderItem: RendererItem | null = null;\n\n constructor(\n actions: ActionStorage,\n menuConfig: ContextConfig,\n logger: Logger2.ILogger,\n params: TooltipViewParams,\n ) {\n this.logger = logger;\n this.actions = actions;\n this.menuConfig = menuConfig;\n\n const {flip, placement = 'bottom'} = params;\n this.placement = flip ? placement : [placement];\n }\n\n get isTooltipOpen(): boolean {\n return this.#isTooltipOpen;\n }\n\n show(view: EditorView, popupProps?: PopupProps) {\n this.view = view;\n this.#isTooltipOpen = true;\n this.baseProps = {\n show: true,\n poppupProps: {\n ...popupProps,\n ...this.calcPosition(view),\n },\n };\n this.renderPopup();\n }\n\n hide(view: EditorView) {\n this.view = view;\n\n // do not rerender popup if it is already hidden\n if (!this.#isTooltipOpen && !this.baseProps.show) return;\n\n this.#isTooltipOpen = false;\n this.baseProps = {show: false, poppupProps: {}};\n this.renderPopup();\n }\n\n destroy() {\n this._tooltipRenderItem?.remove();\n this._tooltipRenderItem = null;\n }\n\n private getSelectionTooltipProps(): SelectionTooltipProps {\n return {\n ...this.baseProps,\n qa: 'g-md-toolbar-selection',\n focus: () => this.view.focus(),\n data: this.getFilteredConfig(),\n editor: this.actions,\n onClick: (id) => {\n globalLogger.action({mode: 'wysiwyg', source: 'context-menu', action: id});\n this.logger.action({source: 'context-menu', action: id});\n },\n };\n }\n\n private getFilteredConfig(): ContextConfig {\n return this.baseProps.show\n ? this.menuConfig\n .map((groupData) =>\n groupData.filter((item) => {\n const {condition} = item;\n if (condition === 'enabled') {\n return item.isEnable(this.actions);\n }\n if (isFunction(condition)) {\n return condition(this.view.state);\n }\n return true;\n }),\n )\n .filter((groupData) => Boolean(groupData.length))\n : [];\n }\n\n private renderPopup() {\n this.tooltipRenderItem.rerender();\n }\n\n private get tooltipRenderItem() {\n if (!this._tooltipRenderItem) {\n const reactRenderer = getReactRendererFromState(this.view.state);\n this._tooltipRenderItem = reactRenderer.createItem('selection_context', () => (\n <ErrorLoggerBoundary>\n <SelectionTooltip {...this.getSelectionTooltipProps()} />\n </ErrorLoggerBoundary>\n ));\n }\n return this._tooltipRenderItem;\n }\n\n private calcPosition(view: EditorView): PopupProps {\n const virtualElem: VirtualElement = {\n getBoundingClientRect() {\n // These are in screen coordinates\n const start = view.coordsAtPos(view.state.selection.from);\n const end = view.coordsAtPos(view.state.selection.to);\n // Find a center-ish x position from the selection endpoints (when\n // crossing lines, end may be more to the left)\n const yCenter = Math.max((start.left + end.left) / 2, start.left + 3);\n\n const top = start.top;\n const left = yCenter - 1;\n const width = 2;\n const height = end.bottom - start.top;\n\n return {\n top,\n left,\n right: left + width,\n bottom: top + height,\n y: top,\n x: left,\n height,\n width,\n };\n },\n };\n\n return {\n placement: this.placement,\n anchorElement: virtualElem,\n };\n }\n}\n"]}
1
+ {"version":3,"file":"tooltip.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/SelectionContext/tooltip.tsx"],"names":[],"mappings":"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","sourcesContent":["import type {VirtualElement} from '@floating-ui/react';\nimport type {PopupPlacement, PopupProps} from '@gravity-ui/uikit';\nimport type {EditorView} from 'prosemirror-view';\n\nimport type {ActionStorage} from '../../../core';\nimport {type Logger2, globalLogger} from '../../../logger';\nimport {ErrorLoggerBoundary} from '../../../react-utils/ErrorBoundary';\nimport {type RendererItem, getReactRendererFromState} from '../ReactRenderer';\n\nimport {TextSelectionTooltip} from './TextSelectionTooltip';\nimport type {ContextConfig} from './types';\n\nexport type {ContextGroupItemData, ContextGroupData, ContextConfig} from './types';\n\nexport type TooltipViewParams = {\n /** @default 'bottom' */\n placement?: 'top' | 'bottom';\n /** @default false */\n flip?: boolean;\n onPopupOpenChange: PopupProps['onOpenChange'];\n};\n\nexport class TooltipView {\n #isTooltipOpen = false;\n\n private readonly logger: Logger2.ILogger;\n private readonly actions: ActionStorage;\n private readonly menuConfig: ContextConfig;\n private readonly placement: PopupPlacement;\n private readonly onPopupOpenChange: PopupProps['onOpenChange'];\n\n private view!: EditorView;\n private visible = false;\n private anchor: PopupProps['anchorElement'] = undefined;\n private _tooltipRenderItem: RendererItem | null = null;\n\n constructor(\n actions: ActionStorage,\n menuConfig: ContextConfig,\n logger: Logger2.ILogger,\n params: TooltipViewParams,\n ) {\n this.logger = logger;\n this.actions = actions;\n this.menuConfig = menuConfig;\n\n const {flip, placement = 'bottom', onPopupOpenChange} = params;\n this.placement = flip ? placement : [placement];\n this.onPopupOpenChange = onPopupOpenChange;\n }\n\n get isTooltipOpen(): boolean {\n return this.#isTooltipOpen;\n }\n\n show(view: EditorView) {\n this.view = view;\n this.#isTooltipOpen = true;\n this.visible = true;\n this.anchor ??= this.createVirtualElement(view);\n this.renderPopup();\n }\n\n hide(view: EditorView) {\n this.view = view;\n\n // do not rerender popup if it is already hidden\n if (!this.#isTooltipOpen && !this.visible) return;\n\n this.#isTooltipOpen = false;\n this.visible = false;\n this.anchor = undefined;\n this.renderPopup();\n }\n\n destroy() {\n this._tooltipRenderItem?.remove();\n this._tooltipRenderItem = null;\n }\n\n private readonly handleFocus = () => this.view.focus();\n private readonly handleClick = (id: string) => {\n globalLogger.action({mode: 'wysiwyg', source: 'context-menu', action: id});\n this.logger.action({source: 'context-menu', action: id});\n };\n\n private renderPopup() {\n this.tooltipRenderItem.rerender();\n }\n\n private get tooltipRenderItem() {\n if (!this._tooltipRenderItem) {\n const reactRenderer = getReactRendererFromState(this.view.state);\n this._tooltipRenderItem = reactRenderer.createItem('selection_context', () => {\n if (!this.visible) return null;\n return (\n <ErrorLoggerBoundary>\n <TextSelectionTooltip\n config={this.menuConfig}\n editor={this.actions}\n editorView={this.view}\n focus={this.handleFocus}\n onClick={this.handleClick}\n popupPlacement={this.placement}\n popupAnchor={this.anchor}\n popupOnOpenChange={this.onPopupOpenChange}\n />\n </ErrorLoggerBoundary>\n );\n });\n }\n return this._tooltipRenderItem;\n }\n\n private createVirtualElement(view: EditorView): VirtualElement {\n return {\n getBoundingClientRect() {\n // These are in screen coordinates\n const start = view.coordsAtPos(view.state.selection.from);\n const end = view.coordsAtPos(view.state.selection.to);\n // Find a center-ish x position from the selection endpoints (when\n // crossing lines, end may be more to the left)\n const yCenter = Math.max((start.left + end.left) / 2, start.left + 3);\n\n const top = start.top;\n const left = yCenter - 1;\n const width = 2;\n const height = end.bottom - start.top;\n\n return {\n top,\n left,\n right: left + width,\n bottom: top + height,\n y: top,\n x: left,\n height,\n width,\n };\n },\n };\n }\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import type { ActionStorage } from "../../../core/index.js";
2
+ import type { EditorState } from "../../../pm/state.js";
3
+ import type { ToolbarButtonPopupData, ToolbarGroupItemData, ToolbarSingleItemData } from "../../../toolbar/index.js";
4
+ export type ContextGroupItemData = (ToolbarGroupItemData<ActionStorage> & {
5
+ condition?: (state: EditorState) => void;
6
+ }) | ((ToolbarSingleItemData<ActionStorage> | ToolbarButtonPopupData<ActionStorage>) & {
7
+ condition?: 'enabled';
8
+ });
9
+ export type ContextGroupData = ContextGroupItemData[];
10
+ export type ContextConfig = ContextGroupData[];
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/SelectionContext/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {ActionStorage} from '#core';\nimport type {EditorState} from '#pm/state';\nimport type {\n ToolbarButtonPopupData,\n ToolbarGroupItemData,\n ToolbarSingleItemData,\n} from 'src/toolbar';\n\nexport type ContextGroupItemData =\n | (ToolbarGroupItemData<ActionStorage> & {\n condition?: (state: EditorState) => void;\n })\n | ((ToolbarSingleItemData<ActionStorage> | ToolbarButtonPopupData<ActionStorage>) & {\n condition?: 'enabled';\n });\n\nexport type ContextGroupData = ContextGroupItemData[];\nexport type ContextConfig = ContextGroupData[];\n"]}
@@ -93,41 +93,31 @@ const CodeBlockSpecs = (builder, opts) => {
93
93
  state.closeBlock(node);
94
94
  },
95
95
  }));
96
- builder.addNode('fence', () => ({
97
- // we adding this node only for define specific 'fence' parser token,
98
- // which parse fence md token to code_block node
99
- spec: {},
100
- fromMd: {
101
- tokenSpec: {
102
- name: exports.codeBlockNodeName,
103
- type: 'block',
104
- noCloseToken: true,
105
- getAttrs: (tok) => {
106
- const attrs = {
107
- [exports.CodeBlockNodeAttr.Markup]: tok.markup,
108
- [exports.CodeBlockNodeAttr.Line]: tok.attrGet('data-line'),
109
- };
110
- if (tok.info) {
111
- // like in markdown-it
112
- // https://github.com/markdown-it/markdown-it/blob/d07d585b6b15aaee2bc8f7a54b994526dad4dbc5/lib/renderer.mjs#L36-L37
113
- const parts = tok.info.split(/\s+/);
114
- const isFirstPartForLineNumbers = opts.lineNumbers?.enabled && parts[0] === 'showLineNumbers';
115
- attrs[exports.CodeBlockNodeAttr.Lang] = isFirstPartForLineNumbers ? '' : parts[0];
116
- }
117
- if (opts.lineNumbers?.enabled && tok.info?.includes('showLineNumbers')) {
118
- attrs[exports.CodeBlockNodeAttr.ShowLineNumbers] = 'true';
119
- }
120
- else {
121
- attrs[exports.CodeBlockNodeAttr.ShowLineNumbers] = '';
122
- }
123
- return attrs;
124
- },
125
- prepareContent: removeNewLineAtEnd, // content of fence blocks contains extra \n at the end
126
- },
127
- },
128
- toMd: () => {
129
- throw new Error('Unexpected toMd() call on fence node');
96
+ builder.addMarkdownTokenParserSpec('fence', () => ({
97
+ name: exports.codeBlockNodeName,
98
+ type: 'block',
99
+ noCloseToken: true,
100
+ getAttrs: (tok) => {
101
+ const attrs = {
102
+ [exports.CodeBlockNodeAttr.Markup]: tok.markup,
103
+ [exports.CodeBlockNodeAttr.Line]: tok.attrGet('data-line'),
104
+ };
105
+ if (tok.info) {
106
+ // like in markdown-it
107
+ // https://github.com/markdown-it/markdown-it/blob/d07d585b6b15aaee2bc8f7a54b994526dad4dbc5/lib/renderer.mjs#L36-L37
108
+ const parts = tok.info.split(/\s+/);
109
+ const isFirstPartForLineNumbers = opts.lineNumbers?.enabled && parts[0] === 'showLineNumbers';
110
+ attrs[exports.CodeBlockNodeAttr.Lang] = isFirstPartForLineNumbers ? '' : parts[0];
111
+ }
112
+ if (opts.lineNumbers?.enabled && tok.info?.includes('showLineNumbers')) {
113
+ attrs[exports.CodeBlockNodeAttr.ShowLineNumbers] = 'true';
114
+ }
115
+ else {
116
+ attrs[exports.CodeBlockNodeAttr.ShowLineNumbers] = '';
117
+ }
118
+ return attrs;
130
119
  },
120
+ prepareContent: removeNewLineAtEnd, // content of fence blocks contains extra \n at the end
131
121
  }));
132
122
  builder.addKeymap(() => ({
133
123
  Tab: (state, dispatch) => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"../../../../../../src","sources":["extensions/markdown/CodeBlock/CodeBlockSpecs/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type {ExtensionAuto, ExtensionNodeSpec} from '#core';\nimport {nodeTypeFactory} from 'src/utils/schema';\n\nexport const CodeBlockNodeAttr = {\n Lang: 'data-language',\n Markup: 'data-markup',\n Line: 'data-line',\n ShowLineNumbers: 'data-show-line-numbers',\n} as const;\n\nexport const codeBlockNodeName = 'code_block';\nexport const codeBlockType = nodeTypeFactory(codeBlockNodeName);\n\nexport type LineNumbersOptions = {\n /**\n * Allow line numbers in codeblock.\n * Available with @diplodoc/transform v4.55.0 or higher.\n * @default true\n */\n // TODO [MAJOR]: enable by default and remove option\n enabled?: boolean;\n /**\n * By default, new code blocks are added with line numbers.\n * @default false\n */\n showByDefault?: boolean;\n};\n\nexport type CodeBlockSpecsOptions = {\n nodeview?: ExtensionNodeSpec['view'];\n /** Configure line numbers in code block */\n lineNumbers?: LineNumbersOptions;\n};\n\nconst getLangOfNode = (node: Element) => {\n let result = node.getAttribute(CodeBlockNodeAttr.Lang) || '';\n\n if (!result) {\n const firstElementChild = node.firstElementChild;\n\n if (\n firstElementChild &&\n firstElementChild.nodeName.toLowerCase() === 'code' &&\n firstElementChild.classList.contains('hljs')\n ) {\n result = firstElementChild.getAttribute('class')?.split(' ')?.[1] || '';\n }\n }\n\n return result;\n};\n\nexport const CodeBlockSpecs: ExtensionAuto<CodeBlockSpecsOptions> = (builder, opts) => {\n builder.addNode(codeBlockNodeName, () => ({\n view: opts.nodeview,\n spec: {\n attrs: {\n [CodeBlockNodeAttr.Lang]: {default: ''},\n [CodeBlockNodeAttr.Markup]: {default: '```'},\n [CodeBlockNodeAttr.Line]: {default: null},\n ...(opts.lineNumbers?.enabled\n ? {\n [CodeBlockNodeAttr.ShowLineNumbers]: {\n default: opts.lineNumbers.showByDefault ? 'true' : '',\n },\n }\n : {}),\n },\n content: 'text*',\n group: 'block',\n code: true,\n marks: '',\n selectable: true,\n allowSelection: false,\n parseDOM: [\n {\n tag: 'pre',\n preserveWhitespace: 'full',\n getAttrs: (node) => {\n return {\n [CodeBlockNodeAttr.Lang]: getLangOfNode(node as Element),\n };\n },\n },\n ],\n toDOM({attrs}) {\n return ['pre', attrs, ['code', 0]];\n },\n },\n fromMd: {\n tokenSpec: {\n name: codeBlockNodeName,\n type: 'block',\n noCloseToken: true,\n getAttrs: (tok) => {\n return {\n [CodeBlockNodeAttr.Line]: tok.attrGet('data-line'),\n [CodeBlockNodeAttr.ShowLineNumbers]: tok.info.includes('showLineNumbers')\n ? 'true'\n : '',\n };\n },\n prepareContent: removeNewLineAtEnd, // content of code blocks contains extra \\n at the end\n },\n },\n toMd: (state, node) => {\n const lang: string = node.attrs[CodeBlockNodeAttr.Lang];\n const markup: string = node.attrs[CodeBlockNodeAttr.Markup];\n const showLineNumbers: string = opts.lineNumbers?.enabled\n ? node.attrs[CodeBlockNodeAttr.ShowLineNumbers]\n : '';\n\n let info = lang;\n\n if (showLineNumbers === 'true') {\n info += ' showLineNumbers';\n }\n\n state.write(markup + info + '\\n');\n state.text(node.textContent, false);\n // Add a newline to the current content before adding closing marker\n state.write('\\n');\n state.write(markup);\n state.closeBlock(node);\n },\n }));\n builder.addNode('fence', () => ({\n // we adding this node only for define specific 'fence' parser token,\n // which parse fence md token to code_block node\n spec: {},\n fromMd: {\n tokenSpec: {\n name: codeBlockNodeName,\n type: 'block',\n noCloseToken: true,\n getAttrs: (tok) => {\n const attrs: Record<string, string | null> = {\n [CodeBlockNodeAttr.Markup]: tok.markup,\n [CodeBlockNodeAttr.Line]: tok.attrGet('data-line'),\n };\n if (tok.info) {\n // like in markdown-it\n // https://github.com/markdown-it/markdown-it/blob/d07d585b6b15aaee2bc8f7a54b994526dad4dbc5/lib/renderer.mjs#L36-L37\n const parts = tok.info.split(/\\s+/);\n\n const isFirstPartForLineNumbers =\n opts.lineNumbers?.enabled && parts[0] === 'showLineNumbers';\n\n attrs[CodeBlockNodeAttr.Lang] = isFirstPartForLineNumbers ? '' : parts[0];\n }\n if (opts.lineNumbers?.enabled && tok.info?.includes('showLineNumbers')) {\n attrs[CodeBlockNodeAttr.ShowLineNumbers] = 'true';\n } else {\n attrs[CodeBlockNodeAttr.ShowLineNumbers] = '';\n }\n\n return attrs;\n },\n prepareContent: removeNewLineAtEnd, // content of fence blocks contains extra \\n at the end\n },\n },\n toMd: () => {\n throw new Error('Unexpected toMd() call on fence node');\n },\n }));\n builder.addKeymap(() => ({\n Tab: (state, dispatch) => {\n const {$anchor, $head} = state.selection;\n if ($anchor.sameParent($head) && $anchor.parent.type.name === codeBlockNodeName) {\n dispatch?.(state.tr.replaceSelectionWith(state.schema.text('\\t')).scrollIntoView());\n return true;\n }\n return false;\n },\n }));\n};\n\nfunction removeNewLineAtEnd(content: string): string {\n return content.endsWith('\\n') ? content.slice(0, content.length - 1) : content;\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"../../../../../../src","sources":["extensions/markdown/CodeBlock/CodeBlockSpecs/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type {ExtensionAuto, ExtensionNodeSpec} from '#core';\nimport {nodeTypeFactory} from 'src/utils/schema';\n\nexport const CodeBlockNodeAttr = {\n Lang: 'data-language',\n Markup: 'data-markup',\n Line: 'data-line',\n ShowLineNumbers: 'data-show-line-numbers',\n} as const;\n\nexport const codeBlockNodeName = 'code_block';\nexport const codeBlockType = nodeTypeFactory(codeBlockNodeName);\n\nexport type LineNumbersOptions = {\n /**\n * Allow line numbers in codeblock.\n * Available with @diplodoc/transform v4.55.0 or higher.\n * @default true\n */\n // TODO [MAJOR]: enable by default and remove option\n enabled?: boolean;\n /**\n * By default, new code blocks are added with line numbers.\n * @default false\n */\n showByDefault?: boolean;\n};\n\nexport type CodeBlockSpecsOptions = {\n nodeview?: ExtensionNodeSpec['view'];\n /** Configure line numbers in code block */\n lineNumbers?: LineNumbersOptions;\n};\n\nconst getLangOfNode = (node: Element) => {\n let result = node.getAttribute(CodeBlockNodeAttr.Lang) || '';\n\n if (!result) {\n const firstElementChild = node.firstElementChild;\n\n if (\n firstElementChild &&\n firstElementChild.nodeName.toLowerCase() === 'code' &&\n firstElementChild.classList.contains('hljs')\n ) {\n result = firstElementChild.getAttribute('class')?.split(' ')?.[1] || '';\n }\n }\n\n return result;\n};\n\nexport const CodeBlockSpecs: ExtensionAuto<CodeBlockSpecsOptions> = (builder, opts) => {\n builder.addNode(codeBlockNodeName, () => ({\n view: opts.nodeview,\n spec: {\n attrs: {\n [CodeBlockNodeAttr.Lang]: {default: ''},\n [CodeBlockNodeAttr.Markup]: {default: '```'},\n [CodeBlockNodeAttr.Line]: {default: null},\n ...(opts.lineNumbers?.enabled\n ? {\n [CodeBlockNodeAttr.ShowLineNumbers]: {\n default: opts.lineNumbers.showByDefault ? 'true' : '',\n },\n }\n : {}),\n },\n content: 'text*',\n group: 'block',\n code: true,\n marks: '',\n selectable: true,\n allowSelection: false,\n parseDOM: [\n {\n tag: 'pre',\n preserveWhitespace: 'full',\n getAttrs: (node) => {\n return {\n [CodeBlockNodeAttr.Lang]: getLangOfNode(node as Element),\n };\n },\n },\n ],\n toDOM({attrs}) {\n return ['pre', attrs, ['code', 0]];\n },\n },\n fromMd: {\n tokenSpec: {\n name: codeBlockNodeName,\n type: 'block',\n noCloseToken: true,\n getAttrs: (tok) => {\n return {\n [CodeBlockNodeAttr.Line]: tok.attrGet('data-line'),\n [CodeBlockNodeAttr.ShowLineNumbers]: tok.info.includes('showLineNumbers')\n ? 'true'\n : '',\n };\n },\n prepareContent: removeNewLineAtEnd, // content of code blocks contains extra \\n at the end\n },\n },\n toMd: (state, node) => {\n const lang: string = node.attrs[CodeBlockNodeAttr.Lang];\n const markup: string = node.attrs[CodeBlockNodeAttr.Markup];\n const showLineNumbers: string = opts.lineNumbers?.enabled\n ? node.attrs[CodeBlockNodeAttr.ShowLineNumbers]\n : '';\n\n let info = lang;\n\n if (showLineNumbers === 'true') {\n info += ' showLineNumbers';\n }\n\n state.write(markup + info + '\\n');\n state.text(node.textContent, false);\n // Add a newline to the current content before adding closing marker\n state.write('\\n');\n state.write(markup);\n state.closeBlock(node);\n },\n }));\n builder.addMarkdownTokenParserSpec('fence', () => ({\n name: codeBlockNodeName,\n type: 'block',\n noCloseToken: true,\n getAttrs: (tok) => {\n const attrs: Record<string, string | null> = {\n [CodeBlockNodeAttr.Markup]: tok.markup,\n [CodeBlockNodeAttr.Line]: tok.attrGet('data-line'),\n };\n if (tok.info) {\n // like in markdown-it\n // https://github.com/markdown-it/markdown-it/blob/d07d585b6b15aaee2bc8f7a54b994526dad4dbc5/lib/renderer.mjs#L36-L37\n const parts = tok.info.split(/\\s+/);\n\n const isFirstPartForLineNumbers =\n opts.lineNumbers?.enabled && parts[0] === 'showLineNumbers';\n\n attrs[CodeBlockNodeAttr.Lang] = isFirstPartForLineNumbers ? '' : parts[0];\n }\n if (opts.lineNumbers?.enabled && tok.info?.includes('showLineNumbers')) {\n attrs[CodeBlockNodeAttr.ShowLineNumbers] = 'true';\n } else {\n attrs[CodeBlockNodeAttr.ShowLineNumbers] = '';\n }\n\n return attrs;\n },\n prepareContent: removeNewLineAtEnd, // content of fence blocks contains extra \\n at the end\n }));\n builder.addKeymap(() => ({\n Tab: (state, dispatch) => {\n const {$anchor, $head} = state.selection;\n if ($anchor.sameParent($head) && $anchor.parent.type.name === codeBlockNodeName) {\n dispatch?.(state.tr.replaceSelectionWith(state.schema.text('\\t')).scrollIntoView());\n return true;\n }\n return false;\n },\n }));\n};\n\nfunction removeNewLineAtEnd(content: string): string {\n return content.endsWith('\\n') ? content.slice(0, content.length - 1) : content;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ export declare const headingNodeName = "heading";
2
+ export declare const headingLevelAttr = "level";
3
+ export declare const headingLineNumberAttr = "data-line";
4
+ export declare const headingType: (schema: import("prosemirror-model").Schema) => import("prosemirror-model").NodeType;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.headingType = exports.headingLineNumberAttr = exports.headingLevelAttr = exports.headingNodeName = void 0;
4
+ const schema_1 = require("../../../../utils/schema.js");
5
+ exports.headingNodeName = 'heading';
6
+ exports.headingLevelAttr = 'level';
7
+ exports.headingLineNumberAttr = 'data-line';
8
+ exports.headingType = (0, schema_1.nodeTypeFactory)(exports.headingNodeName);
9
+ //# sourceMappingURL=const.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"const.js","sourceRoot":"../../../../../../src","sources":["extensions/markdown/Heading/HeadingSpecs/const.ts"],"names":[],"mappings":";;;AAAA,wDAAiD;AAEpC,QAAA,eAAe,GAAG,SAAS,CAAC;AAC5B,QAAA,gBAAgB,GAAG,OAAO,CAAC;AAC3B,QAAA,qBAAqB,GAAG,WAAW,CAAC;AACpC,QAAA,WAAW,GAAG,IAAA,wBAAe,EAAC,uBAAe,CAAC,CAAC","sourcesContent":["import {nodeTypeFactory} from 'src/utils/schema';\n\nexport const headingNodeName = 'heading';\nexport const headingLevelAttr = 'level';\nexport const headingLineNumberAttr = 'data-line';\nexport const headingType = nodeTypeFactory(headingNodeName);\n"]}
@@ -1,9 +1,7 @@
1
- import type { NodeSpec } from 'prosemirror-model';
2
1
  import type { ExtensionAuto } from "../../../../core/index.js";
3
- export declare const headingNodeName = "heading";
4
- export declare const headingLevelAttr = "level";
5
- export declare const headingLineNumberAttr = "data-line";
6
- export declare const headingType: (schema: import("prosemirror-model").Schema) => import("prosemirror-model").NodeType;
2
+ import type { NodeSpec } from "../../../../pm/model.js";
3
+ export * from "./const.js";
4
+ export { headingToMarkdown } from "./utils.js";
7
5
  export type HeadingSpecsOptions = {
8
6
  /**
9
7
  * @deprecated use placeholder option in BehaviorPreset instead.
@@ -1,32 +1,33 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HeadingSpecs = exports.headingType = exports.headingLineNumberAttr = exports.headingLevelAttr = exports.headingNodeName = void 0;
4
- const schema_1 = require("../../../../utils/schema.js");
5
- exports.headingNodeName = 'heading';
6
- exports.headingLevelAttr = 'level';
7
- exports.headingLineNumberAttr = 'data-line';
8
- exports.headingType = (0, schema_1.nodeTypeFactory)(exports.headingNodeName);
9
- const DEFAULT_PLACEHOLDER = (node) => 'Heading ' + node.attrs[exports.headingLevelAttr];
3
+ exports.HeadingSpecs = exports.headingToMarkdown = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const const_1 = require("./const.js");
6
+ const utils_1 = require("./utils.js");
7
+ tslib_1.__exportStar(require("./const.js"), exports);
8
+ var utils_2 = require("./utils.js");
9
+ Object.defineProperty(exports, "headingToMarkdown", { enumerable: true, get: function () { return utils_2.headingToMarkdown; } });
10
+ const DEFAULT_PLACEHOLDER = (node) => 'Heading ' + node.attrs[const_1.headingLevelAttr];
10
11
  const HeadingSpecs = (builder, opts) => {
11
- builder.addNode(exports.headingNodeName, () => ({
12
+ builder.addNode(const_1.headingNodeName, () => ({
12
13
  spec: {
13
- attrs: { [exports.headingLevelAttr]: { default: 1 }, [exports.headingLineNumberAttr]: { default: null } },
14
+ attrs: { [const_1.headingLevelAttr]: { default: 1 }, [const_1.headingLineNumberAttr]: { default: null } },
14
15
  content: '(text | inline)*',
15
16
  group: 'block',
16
17
  defining: true,
17
18
  parseDOM: [
18
- { tag: 'h1', attrs: { [exports.headingLevelAttr]: 1 } },
19
- { tag: 'h2', attrs: { [exports.headingLevelAttr]: 2 } },
20
- { tag: 'h3', attrs: { [exports.headingLevelAttr]: 3 } },
21
- { tag: 'h4', attrs: { [exports.headingLevelAttr]: 4 } },
22
- { tag: 'h5', attrs: { [exports.headingLevelAttr]: 5 } },
23
- { tag: 'h6', attrs: { [exports.headingLevelAttr]: 6 } },
19
+ { tag: 'h1', attrs: { [const_1.headingLevelAttr]: 1 } },
20
+ { tag: 'h2', attrs: { [const_1.headingLevelAttr]: 2 } },
21
+ { tag: 'h3', attrs: { [const_1.headingLevelAttr]: 3 } },
22
+ { tag: 'h4', attrs: { [const_1.headingLevelAttr]: 4 } },
23
+ { tag: 'h5', attrs: { [const_1.headingLevelAttr]: 5 } },
24
+ { tag: 'h6', attrs: { [const_1.headingLevelAttr]: 6 } },
24
25
  ],
25
26
  toDOM(node) {
26
- const lineNumber = node.attrs[exports.headingLineNumberAttr];
27
+ const lineNumber = node.attrs[const_1.headingLineNumberAttr];
27
28
  return [
28
- 'h' + node.attrs[exports.headingLevelAttr],
29
- lineNumber === null ? {} : { [exports.headingLineNumberAttr]: lineNumber },
29
+ 'h' + node.attrs[const_1.headingLevelAttr],
30
+ lineNumber === null ? {} : { [const_1.headingLineNumberAttr]: lineNumber },
30
31
  0,
31
32
  ];
32
33
  },
@@ -39,16 +40,12 @@ const HeadingSpecs = (builder, opts) => {
39
40
  },
40
41
  fromMd: {
41
42
  tokenSpec: {
42
- name: exports.headingNodeName,
43
+ name: const_1.headingNodeName,
43
44
  type: 'block',
44
- getAttrs: (tok) => ({ [exports.headingLevelAttr]: Number(tok.tag.slice(1)) }),
45
+ getAttrs: (tok) => ({ [const_1.headingLevelAttr]: Number(tok.tag.slice(1)) }),
45
46
  },
46
47
  },
47
- toMd: (state, node) => {
48
- state.write(state.repeat('#', node.attrs[exports.headingLevelAttr]) + ' ');
49
- state.renderInline(node);
50
- state.closeBlock(node);
51
- },
48
+ toMd: (0, utils_1.headingToMarkdown)(),
52
49
  }));
53
50
  };
54
51
  exports.HeadingSpecs = HeadingSpecs;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"../../../../../../src","sources":["extensions/markdown/Heading/HeadingSpecs/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type {Node, NodeSpec} from 'prosemirror-model';\n\nimport type {ExtensionAuto} from '../../../../core';\nimport {nodeTypeFactory} from '../../../../utils/schema';\n\nexport const headingNodeName = 'heading';\nexport const headingLevelAttr = 'level';\nexport const headingLineNumberAttr = 'data-line';\nexport const headingType = nodeTypeFactory(headingNodeName);\n\nconst DEFAULT_PLACEHOLDER = (node: Node) => 'Heading ' + node.attrs[headingLevelAttr];\n\nexport type HeadingSpecsOptions = {\n /**\n * @deprecated use placeholder option in BehaviorPreset instead.\n */\n headingPlaceholder?: NonNullable<NodeSpec['placeholder']>['content'];\n};\n\nexport const HeadingSpecs: ExtensionAuto<HeadingSpecsOptions> = (builder, opts) => {\n builder.addNode(headingNodeName, () => ({\n spec: {\n attrs: {[headingLevelAttr]: {default: 1}, [headingLineNumberAttr]: {default: null}},\n content: '(text | inline)*',\n group: 'block',\n defining: true,\n parseDOM: [\n {tag: 'h1', attrs: {[headingLevelAttr]: 1}},\n {tag: 'h2', attrs: {[headingLevelAttr]: 2}},\n {tag: 'h3', attrs: {[headingLevelAttr]: 3}},\n {tag: 'h4', attrs: {[headingLevelAttr]: 4}},\n {tag: 'h5', attrs: {[headingLevelAttr]: 5}},\n {tag: 'h6', attrs: {[headingLevelAttr]: 6}},\n ],\n toDOM(node) {\n const lineNumber = node.attrs[headingLineNumberAttr];\n\n return [\n 'h' + node.attrs[headingLevelAttr],\n lineNumber === null ? {} : {[headingLineNumberAttr]: lineNumber},\n 0,\n ];\n },\n placeholder: {\n content:\n builder.context.get('placeholder')?.heading ??\n opts.headingPlaceholder ??\n DEFAULT_PLACEHOLDER,\n alwaysVisible: true,\n },\n },\n fromMd: {\n tokenSpec: {\n name: headingNodeName,\n type: 'block',\n getAttrs: (tok) => ({[headingLevelAttr]: Number(tok.tag.slice(1))}),\n },\n },\n toMd: (state, node) => {\n state.write(state.repeat('#', node.attrs[headingLevelAttr]) + ' ');\n state.renderInline(node);\n state.closeBlock(node);\n },\n }));\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"../../../../../../src","sources":["extensions/markdown/Heading/HeadingSpecs/index.ts"],"names":[],"mappings":";;;;AAGA,sCAAiF;AACjF,sCAA0C;AAE1C,qDAAwB;AACxB,oCAA0C;AAAlC,0GAAA,iBAAiB,OAAA;AAEzB,MAAM,mBAAmB,GAAG,CAAC,IAAU,EAAE,EAAE,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,wBAAgB,CAAC,CAAC;AAS/E,MAAM,YAAY,GAAuC,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;IAC9E,OAAO,CAAC,OAAO,CAAC,uBAAe,EAAE,GAAG,EAAE,CAAC,CAAC;QACpC,IAAI,EAAE;YACF,KAAK,EAAE,EAAC,CAAC,wBAAgB,CAAC,EAAE,EAAC,OAAO,EAAE,CAAC,EAAC,EAAE,CAAC,6BAAqB,CAAC,EAAE,EAAC,OAAO,EAAE,IAAI,EAAC,EAAC;YACnF,OAAO,EAAE,kBAAkB;YAC3B,KAAK,EAAE,OAAO;YACd,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE;gBACN,EAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,EAAC,CAAC,wBAAgB,CAAC,EAAE,CAAC,EAAC,EAAC;gBAC3C,EAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,EAAC,CAAC,wBAAgB,CAAC,EAAE,CAAC,EAAC,EAAC;gBAC3C,EAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,EAAC,CAAC,wBAAgB,CAAC,EAAE,CAAC,EAAC,EAAC;gBAC3C,EAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,EAAC,CAAC,wBAAgB,CAAC,EAAE,CAAC,EAAC,EAAC;gBAC3C,EAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,EAAC,CAAC,wBAAgB,CAAC,EAAE,CAAC,EAAC,EAAC;gBAC3C,EAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,EAAC,CAAC,wBAAgB,CAAC,EAAE,CAAC,EAAC,EAAC;aAC9C;YACD,KAAK,CAAC,IAAI;gBACN,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,6BAAqB,CAAC,CAAC;gBAErD,OAAO;oBACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,wBAAgB,CAAC;oBAClC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAC,CAAC,6BAAqB,CAAC,EAAE,UAAU,EAAC;oBAChE,CAAC;iBACJ,CAAC;YACN,CAAC;YACD,WAAW,EAAE;gBACT,OAAO,EACH,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,OAAO;oBAC3C,IAAI,CAAC,kBAAkB;oBACvB,mBAAmB;gBACvB,aAAa,EAAE,IAAI;aACtB;SACJ;QACD,MAAM,EAAE;YACJ,SAAS,EAAE;gBACP,IAAI,EAAE,uBAAe;gBACrB,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAC,CAAC,wBAAgB,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC;aACtE;SACJ;QACD,IAAI,EAAE,IAAA,yBAAiB,GAAE;KAC5B,CAAC,CAAC,CAAC;AACR,CAAC,CAAC;AAzCW,QAAA,YAAY,gBAyCvB","sourcesContent":["import type {ExtensionAuto} from '#core';\nimport type {Node, NodeSpec} from '#pm/model';\n\nimport {headingLevelAttr, headingLineNumberAttr, headingNodeName} from './const';\nimport {headingToMarkdown} from './utils';\n\nexport * from './const';\nexport {headingToMarkdown} from './utils';\n\nconst DEFAULT_PLACEHOLDER = (node: Node) => 'Heading ' + node.attrs[headingLevelAttr];\n\nexport type HeadingSpecsOptions = {\n /**\n * @deprecated use placeholder option in BehaviorPreset instead.\n */\n headingPlaceholder?: NonNullable<NodeSpec['placeholder']>['content'];\n};\n\nexport const HeadingSpecs: ExtensionAuto<HeadingSpecsOptions> = (builder, opts) => {\n builder.addNode(headingNodeName, () => ({\n spec: {\n attrs: {[headingLevelAttr]: {default: 1}, [headingLineNumberAttr]: {default: null}},\n content: '(text | inline)*',\n group: 'block',\n defining: true,\n parseDOM: [\n {tag: 'h1', attrs: {[headingLevelAttr]: 1}},\n {tag: 'h2', attrs: {[headingLevelAttr]: 2}},\n {tag: 'h3', attrs: {[headingLevelAttr]: 3}},\n {tag: 'h4', attrs: {[headingLevelAttr]: 4}},\n {tag: 'h5', attrs: {[headingLevelAttr]: 5}},\n {tag: 'h6', attrs: {[headingLevelAttr]: 6}},\n ],\n toDOM(node) {\n const lineNumber = node.attrs[headingLineNumberAttr];\n\n return [\n 'h' + node.attrs[headingLevelAttr],\n lineNumber === null ? {} : {[headingLineNumberAttr]: lineNumber},\n 0,\n ];\n },\n placeholder: {\n content:\n builder.context.get('placeholder')?.heading ??\n opts.headingPlaceholder ??\n DEFAULT_PLACEHOLDER,\n alwaysVisible: true,\n },\n },\n fromMd: {\n tokenSpec: {\n name: headingNodeName,\n type: 'block',\n getAttrs: (tok) => ({[headingLevelAttr]: Number(tok.tag.slice(1))}),\n },\n },\n toMd: headingToMarkdown(),\n }));\n};\n"]}
@@ -0,0 +1,7 @@
1
+ import type { SerializerNodeToken } from "../../../../core/index.js";
2
+ type HeadingToMarkdownParams = {
3
+ renderMarkup?: SerializerNodeToken;
4
+ renderAttributes?: SerializerNodeToken;
5
+ };
6
+ export declare function headingToMarkdown({ renderMarkup, renderAttributes, }?: HeadingToMarkdownParams): SerializerNodeToken;
7
+ export {};
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.headingToMarkdown = headingToMarkdown;
4
+ const const_1 = require("./const.js");
5
+ const defaultMarkupRender = (state, node) => state.write(state.repeat('#', node.attrs[const_1.headingLevelAttr]) + ' ');
6
+ function headingToMarkdown({ renderMarkup = defaultMarkupRender, renderAttributes, } = {}) {
7
+ return (...args) => {
8
+ const [state, node] = args;
9
+ renderMarkup(...args);
10
+ state.renderInline(node);
11
+ renderAttributes?.(...args);
12
+ state.closeBlock(node);
13
+ };
14
+ }
15
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"../../../../../../src","sources":["extensions/markdown/Heading/HeadingSpecs/utils.ts"],"names":[],"mappings":";;AAYA,8CAWC;AArBD,sCAAyC;AAOzC,MAAM,mBAAmB,GAAwB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAC7D,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,wBAAgB,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;AAEvE,SAAgB,iBAAiB,CAAC,EAC9B,YAAY,GAAG,mBAAmB,EAClC,gBAAgB,MACS,EAAE;IAC3B,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE;QACf,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC;QAC3B,YAAY,CAAC,GAAG,IAAI,CAAC,CAAC;QACtB,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACzB,gBAAgB,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QAC5B,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC,CAAC;AACN,CAAC","sourcesContent":["import type {SerializerNodeToken} from '#core';\n\nimport {headingLevelAttr} from './const';\n\ntype HeadingToMarkdownParams = {\n renderMarkup?: SerializerNodeToken;\n renderAttributes?: SerializerNodeToken;\n};\n\nconst defaultMarkupRender: SerializerNodeToken = (state, node) =>\n state.write(state.repeat('#', node.attrs[headingLevelAttr]) + ' ');\n\nexport function headingToMarkdown({\n renderMarkup = defaultMarkupRender,\n renderAttributes,\n}: HeadingToMarkdownParams = {}): SerializerNodeToken {\n return (...args) => {\n const [state, node] = args;\n renderMarkup(...args);\n state.renderInline(node);\n renderAttributes?.(...args);\n state.closeBlock(node);\n };\n}\n"]}
@@ -1,4 +1,4 @@
1
1
  import type { NodeType } from 'prosemirror-model';
2
2
  import type { ActionSpec } from "../../../core/index.js";
3
- import { type HeadingLevel } from "./const.js";
4
- export declare const headingAction: (nodeType: NodeType, level: HeadingLevel) => ActionSpec;
3
+ import type { HeadingLevel } from "./const.js";
4
+ export declare const headingAction: (_nodeType: NodeType, level: HeadingLevel) => ActionSpec;
@@ -1,11 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.headingAction = void 0;
4
- const prosemirror_commands_1 = require("prosemirror-commands");
5
- const const_1 = require("./const.js");
4
+ const commands_1 = require("./commands.js");
6
5
  const utils_1 = require("./utils.js");
7
- const headingAction = (nodeType, level) => {
8
- const cmd = (0, prosemirror_commands_1.setBlockType)(nodeType, { [const_1.headingLevelAttr]: level });
6
+ const headingAction = (_nodeType, level) => {
7
+ const cmd = (0, commands_1.toHeading)(level);
9
8
  return {
10
9
  isActive: (0, utils_1.hasParentHeading)(level),
11
10
  isEnable: cmd,
@@ -1 +1 @@
1
- {"version":3,"file":"actions.js","sourceRoot":"../../../../../src","sources":["extensions/markdown/Heading/actions.ts"],"names":[],"mappings":";;;AAAA,+DAAkD;AAKlD,sCAA4D;AAC5D,sCAAyC;AAElC,MAAM,aAAa,GAAG,CAAC,QAAkB,EAAE,KAAmB,EAAc,EAAE;IACjF,MAAM,GAAG,GAAG,IAAA,mCAAY,EAAC,QAAQ,EAAE,EAAC,CAAC,wBAAgB,CAAC,EAAE,KAAK,EAAC,CAAC,CAAC;IAChE,OAAO;QACH,QAAQ,EAAE,IAAA,wBAAgB,EAAC,KAAK,CAAC;QACjC,QAAQ,EAAE,GAAG;QACb,GAAG,EAAE,GAAG;KACX,CAAC;AACN,CAAC,CAAC;AAPW,QAAA,aAAa,iBAOxB","sourcesContent":["import {setBlockType} from 'prosemirror-commands';\nimport type {NodeType} from 'prosemirror-model';\n\nimport type {ActionSpec} from '../../../core';\n\nimport {type HeadingLevel, headingLevelAttr} from './const';\nimport {hasParentHeading} from './utils';\n\nexport const headingAction = (nodeType: NodeType, level: HeadingLevel): ActionSpec => {\n const cmd = setBlockType(nodeType, {[headingLevelAttr]: level});\n return {\n isActive: hasParentHeading(level),\n isEnable: cmd,\n run: cmd,\n };\n};\n"]}
1
+ {"version":3,"file":"actions.js","sourceRoot":"../../../../../src","sources":["extensions/markdown/Heading/actions.ts"],"names":[],"mappings":";;;AAIA,4CAAqC;AAErC,sCAAyC;AAElC,MAAM,aAAa,GAAG,CAAC,SAAmB,EAAE,KAAmB,EAAc,EAAE;IAClF,MAAM,GAAG,GAAG,IAAA,oBAAS,EAAC,KAAK,CAAC,CAAC;IAC7B,OAAO;QACH,QAAQ,EAAE,IAAA,wBAAgB,EAAC,KAAK,CAAC;QACjC,QAAQ,EAAE,GAAG;QACb,GAAG,EAAE,GAAG;KACX,CAAC;AACN,CAAC,CAAC;AAPW,QAAA,aAAa,iBAOxB","sourcesContent":["import type {NodeType} from 'prosemirror-model';\n\nimport type {ActionSpec} from '../../../core';\n\nimport {toHeading} from './commands';\nimport type {HeadingLevel} from './const';\nimport {hasParentHeading} from './utils';\n\nexport const headingAction = (_nodeType: NodeType, level: HeadingLevel): ActionSpec => {\n const cmd = toHeading(level);\n return {\n isActive: hasParentHeading(level),\n isEnable: cmd,\n run: cmd,\n };\n};\n"]}
@@ -1,2 +1,4 @@
1
- import type { Command } from 'prosemirror-state';
1
+ import type { Command } from "../../../pm/state.js";
2
+ import type { HeadingLevel } from "./const.js";
2
3
  export declare const resetHeading: Command;
4
+ export declare const toHeading: (level: HeadingLevel) => Command;
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resetHeading = void 0;
3
+ exports.toHeading = exports.resetHeading = void 0;
4
+ const commands_1 = require("../../../pm/commands.js");
5
+ const utils_1 = require("../../../pm/utils.js");
4
6
  const BaseSchema_1 = require("../../base/BaseSchema/index.js");
5
7
  const HeadingSpecs_1 = require("./HeadingSpecs/index.js");
6
8
  const resetHeading = (state, dispatch, view) => {
@@ -13,4 +15,17 @@ const resetHeading = (state, dispatch, view) => {
13
15
  return false;
14
16
  };
15
17
  exports.resetHeading = resetHeading;
18
+ const toHeading = (level) => (state, dispatch, view) => {
19
+ const attrs = {};
20
+ const parentHeading = (0, utils_1.findParentNodeOfType)((0, HeadingSpecs_1.headingType)(state.schema))(state.selection);
21
+ if (parentHeading) {
22
+ if (parentHeading.node.attrs[HeadingSpecs_1.headingLevelAttr] === level) {
23
+ return (0, BaseSchema_1.toParagraph)(state, dispatch, view);
24
+ }
25
+ Object.assign(attrs, parentHeading.node.attrs);
26
+ }
27
+ attrs[HeadingSpecs_1.headingLevelAttr] = level;
28
+ return (0, commands_1.setBlockType)((0, HeadingSpecs_1.headingType)(state.schema), attrs)(state, dispatch);
29
+ };
30
+ exports.toHeading = toHeading;
16
31
  //# sourceMappingURL=commands.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"commands.js","sourceRoot":"../../../../../src","sources":["extensions/markdown/Heading/commands.ts"],"names":[],"mappings":";;;AAEA,+DAAkD;AAClD,0DAAoD;AAE7C,MAAM,YAAY,GAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;IAC3D,MAAM,EAAC,SAAS,EAAC,GAAG,KAAK,CAAC;IAC1B,IACI,SAAS,CAAC,KAAK;QACf,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,IAAA,0BAAW,EAAC,KAAK,CAAC,MAAM,CAAC;QACzD,IAAI,EAAE,cAAc,CAAC,UAAU,EAAE,KAAK,CAAC,EACzC,CAAC;QACC,OAAO,IAAA,wBAAW,EAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC,CAAC;AAVW,QAAA,YAAY,gBAUvB","sourcesContent":["import type {Command} from 'prosemirror-state';\n\nimport {toParagraph} from '../../base/BaseSchema';\nimport {headingType} from '../Heading/HeadingSpecs';\n\nexport const resetHeading: Command = (state, dispatch, view) => {\n const {selection} = state;\n if (\n selection.empty &&\n selection.$from.parent.type === headingType(state.schema) &&\n view?.endOfTextblock('backward', state)\n ) {\n return toParagraph(state, dispatch, view);\n }\n return false;\n};\n"]}
1
+ {"version":3,"file":"commands.js","sourceRoot":"../../../../../src","sources":["extensions/markdown/Heading/commands.ts"],"names":[],"mappings":";;;AAAA,sDAA0C;AAE1C,gDAA+C;AAE/C,+DAAkD;AAClD,0DAAsE;AAI/D,MAAM,YAAY,GAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;IAC3D,MAAM,EAAC,SAAS,EAAC,GAAG,KAAK,CAAC;IAC1B,IACI,SAAS,CAAC,KAAK;QACf,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,IAAA,0BAAW,EAAC,KAAK,CAAC,MAAM,CAAC;QACzD,IAAI,EAAE,cAAc,CAAC,UAAU,EAAE,KAAK,CAAC,EACzC,CAAC;QACC,OAAO,IAAA,wBAAW,EAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC,CAAC;AAVW,QAAA,YAAY,gBAUvB;AAEK,MAAM,SAAS,GAClB,CAAC,KAAmB,EAAW,EAAE,CACjC,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;IACtB,MAAM,KAAK,GAAwB,EAAE,CAAC;IAEtC,MAAM,aAAa,GAAG,IAAA,4BAAoB,EAAC,IAAA,0BAAW,EAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACvF,IAAI,aAAa,EAAE,CAAC;QAChB,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,+BAAgB,CAAC,KAAK,KAAK,EAAE,CAAC;YACvD,OAAO,IAAA,wBAAW,EAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC9C,CAAC;QAED,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,+BAAgB,CAAC,GAAG,KAAK,CAAC;IAEhC,OAAO,IAAA,uBAAY,EAAC,IAAA,0BAAW,EAAC,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AAC3E,CAAC,CAAC;AAjBO,QAAA,SAAS,aAiBhB","sourcesContent":["import {setBlockType} from '#pm/commands';\nimport type {Command} from '#pm/state';\nimport {findParentNodeOfType} from '#pm/utils';\n\nimport {toParagraph} from '../../base/BaseSchema';\nimport {headingLevelAttr, headingType} from '../Heading/HeadingSpecs';\n\nimport type {HeadingLevel} from './const';\n\nexport const resetHeading: Command = (state, dispatch, view) => {\n const {selection} = state;\n if (\n selection.empty &&\n selection.$from.parent.type === headingType(state.schema) &&\n view?.endOfTextblock('backward', state)\n ) {\n return toParagraph(state, dispatch, view);\n }\n return false;\n};\n\nexport const toHeading =\n (level: HeadingLevel): Command =>\n (state, dispatch, view) => {\n const attrs: Record<string, any> = {};\n\n const parentHeading = findParentNodeOfType(headingType(state.schema))(state.selection);\n if (parentHeading) {\n if (parentHeading.node.attrs[headingLevelAttr] === level) {\n return toParagraph(state, dispatch, view);\n }\n\n Object.assign(attrs, parentHeading.node.attrs);\n }\n\n attrs[headingLevelAttr] = level;\n\n return setBlockType(headingType(state.schema), attrs)(state, dispatch);\n };\n"]}