@gravity-ui/markdown-editor 15.3.0 → 15.4.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 (189) hide show
  1. package/build/cjs/extensions/additional/GPT/MarkupGpt/plugin.js +4 -1
  2. package/build/cjs/extensions/additional/GPT/MarkupGpt/plugin.js.map +1 -1
  3. package/build/cjs/extensions/additional/Mermaid/MermaidNodeView/MermaidView.js +7 -3
  4. package/build/cjs/extensions/additional/Mermaid/MermaidNodeView/MermaidView.js.map +1 -1
  5. package/build/cjs/extensions/additional/Mermaid/MermaidNodeView/NodeView.d.ts +1 -0
  6. package/build/cjs/extensions/additional/Mermaid/MermaidNodeView/NodeView.js +19 -2
  7. package/build/cjs/extensions/additional/Mermaid/MermaidNodeView/NodeView.js.map +1 -1
  8. package/build/cjs/extensions/additional/Mermaid/MermaidSpecs/const.d.ts +3 -0
  9. package/build/cjs/extensions/additional/Mermaid/MermaidSpecs/const.js +7 -1
  10. package/build/cjs/extensions/additional/Mermaid/MermaidSpecs/const.js.map +1 -1
  11. package/build/cjs/extensions/additional/Mermaid/MermaidSpecs/index.d.ts +1 -1
  12. package/build/cjs/extensions/additional/Mermaid/MermaidSpecs/index.js +8 -2
  13. package/build/cjs/extensions/additional/Mermaid/MermaidSpecs/index.js.map +1 -1
  14. package/build/cjs/extensions/additional/Mermaid/actions.js +12 -5
  15. package/build/cjs/extensions/additional/Mermaid/actions.js.map +1 -1
  16. package/build/cjs/extensions/additional/Mermaid/types.d.ts +3 -0
  17. package/build/cjs/extensions/additional/Mermaid/types.js +3 -0
  18. package/build/cjs/extensions/additional/Mermaid/types.js.map +1 -0
  19. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/NodeView.d.ts +1 -0
  20. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/NodeView.js +14 -5
  21. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/NodeView.js.map +1 -1
  22. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/YfmHtmlBlockView.js +13 -12
  23. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/YfmHtmlBlockView.js.map +1 -1
  24. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/const.d.ts +3 -0
  25. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/const.js +7 -1
  26. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/const.js.map +1 -1
  27. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/index.d.ts +1 -1
  28. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/index.js +8 -2
  29. package/build/cjs/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/index.js.map +1 -1
  30. package/build/cjs/extensions/additional/YfmHtmlBlock/actions.js +9 -2
  31. package/build/cjs/extensions/additional/YfmHtmlBlock/actions.js.map +1 -1
  32. package/build/cjs/extensions/additional/YfmHtmlBlock/types.d.ts +3 -0
  33. package/build/cjs/extensions/additional/YfmHtmlBlock/types.js +3 -0
  34. package/build/cjs/extensions/additional/YfmHtmlBlock/types.js.map +1 -0
  35. package/build/cjs/extensions/behavior/Autocomplete/index.d.ts +1 -0
  36. package/build/cjs/extensions/behavior/Autocomplete/index.js +5 -3
  37. package/build/cjs/extensions/behavior/Autocomplete/index.js.map +1 -1
  38. package/build/cjs/extensions/behavior/Autocomplete/types.d.ts +1 -1
  39. package/build/cjs/extensions/behavior/Autocomplete/types.js.map +1 -1
  40. package/build/cjs/extensions/behavior/Autocomplete/utils.d.ts +3 -0
  41. package/build/cjs/extensions/behavior/Autocomplete/utils.js +8 -0
  42. package/build/cjs/extensions/behavior/Autocomplete/utils.js.map +1 -0
  43. package/build/cjs/extensions/behavior/Clipboard/code.d.ts +7 -1
  44. package/build/cjs/extensions/behavior/Clipboard/code.js +60 -0
  45. package/build/cjs/extensions/behavior/Clipboard/code.js.map +1 -1
  46. package/build/cjs/extensions/behavior/Clipboard/index.js +2 -0
  47. package/build/cjs/extensions/behavior/Clipboard/index.js.map +1 -1
  48. package/build/cjs/extensions/behavior/CommandMenu/handler.js +6 -6
  49. package/build/cjs/extensions/behavior/CommandMenu/handler.js.map +1 -1
  50. package/build/cjs/extensions/behavior/SharedState/SharedState.d.ts +7 -0
  51. package/build/cjs/extensions/behavior/SharedState/SharedState.js +16 -0
  52. package/build/cjs/extensions/behavior/SharedState/SharedState.js.map +1 -0
  53. package/build/cjs/extensions/behavior/SharedState/index.d.ts +1 -0
  54. package/build/cjs/extensions/behavior/SharedState/index.js +5 -0
  55. package/build/cjs/extensions/behavior/SharedState/index.js.map +1 -0
  56. package/build/cjs/extensions/behavior/SharedState/plugin.d.ts +3 -0
  57. package/build/cjs/extensions/behavior/SharedState/plugin.js +62 -0
  58. package/build/cjs/extensions/behavior/SharedState/plugin.js.map +1 -0
  59. package/build/cjs/extensions/behavior/SharedState/types.d.ts +1 -0
  60. package/build/cjs/extensions/behavior/SharedState/types.js +3 -0
  61. package/build/cjs/extensions/behavior/SharedState/types.js.map +1 -0
  62. package/build/cjs/extensions/behavior/SharedState/utils.d.ts +29 -0
  63. package/build/cjs/extensions/behavior/SharedState/utils.js +60 -0
  64. package/build/cjs/extensions/behavior/SharedState/utils.js.map +1 -0
  65. package/build/cjs/extensions/behavior/index.d.ts +2 -0
  66. package/build/cjs/extensions/behavior/index.js +4 -0
  67. package/build/cjs/extensions/behavior/index.js.map +1 -1
  68. package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.js +41 -26
  69. package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.js.map +1 -1
  70. package/build/cjs/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.d.ts +0 -1
  71. package/build/cjs/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.js +7 -6
  72. package/build/cjs/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.js.map +1 -1
  73. package/build/cjs/react-utils/index.d.ts +1 -0
  74. package/build/cjs/react-utils/index.js +1 -0
  75. package/build/cjs/react-utils/index.js.map +1 -1
  76. package/build/cjs/react-utils/useSharedEditingState.d.ts +5 -0
  77. package/build/cjs/react-utils/useSharedEditingState.js +25 -0
  78. package/build/cjs/react-utils/useSharedEditingState.js.map +1 -0
  79. package/build/cjs/utils/descedants.d.ts +8 -0
  80. package/build/cjs/utils/descedants.js +15 -0
  81. package/build/cjs/utils/descedants.js.map +1 -0
  82. package/build/cjs/utils/entity-id.d.ts +11 -0
  83. package/build/cjs/utils/entity-id.js +21 -0
  84. package/build/cjs/utils/entity-id.js.map +1 -0
  85. package/build/cjs/utils/index.d.ts +2 -0
  86. package/build/cjs/utils/index.js +2 -0
  87. package/build/cjs/utils/index.js.map +1 -1
  88. package/build/cjs/version.js +1 -1
  89. package/build/cjs/version.js.map +1 -1
  90. package/build/cjs/view/hocs/withYfmHtml/index.d.ts +2 -0
  91. package/build/cjs/view/hocs/withYfmHtml/index.js +2 -2
  92. package/build/cjs/view/hocs/withYfmHtml/index.js.map +1 -1
  93. package/build/cjs/view/hocs/withYfmHtml/useYfmHtmlBlockRuntime.js +3 -1
  94. package/build/cjs/view/hocs/withYfmHtml/useYfmHtmlBlockRuntime.js.map +1 -1
  95. package/build/esm/extensions/additional/GPT/MarkupGpt/plugin.js +4 -1
  96. package/build/esm/extensions/additional/GPT/MarkupGpt/plugin.js.map +1 -1
  97. package/build/esm/extensions/additional/Mermaid/MermaidNodeView/MermaidView.js +8 -4
  98. package/build/esm/extensions/additional/Mermaid/MermaidNodeView/MermaidView.js.map +1 -1
  99. package/build/esm/extensions/additional/Mermaid/MermaidNodeView/NodeView.d.ts +1 -0
  100. package/build/esm/extensions/additional/Mermaid/MermaidNodeView/NodeView.js +18 -1
  101. package/build/esm/extensions/additional/Mermaid/MermaidNodeView/NodeView.js.map +1 -1
  102. package/build/esm/extensions/additional/Mermaid/MermaidSpecs/const.d.ts +3 -0
  103. package/build/esm/extensions/additional/Mermaid/MermaidSpecs/const.js +6 -0
  104. package/build/esm/extensions/additional/Mermaid/MermaidSpecs/const.js.map +1 -1
  105. package/build/esm/extensions/additional/Mermaid/MermaidSpecs/index.d.ts +2 -2
  106. package/build/esm/extensions/additional/Mermaid/MermaidSpecs/index.js +8 -3
  107. package/build/esm/extensions/additional/Mermaid/MermaidSpecs/index.js.map +1 -1
  108. package/build/esm/extensions/additional/Mermaid/actions.js +12 -5
  109. package/build/esm/extensions/additional/Mermaid/actions.js.map +1 -1
  110. package/build/esm/extensions/additional/Mermaid/types.d.ts +3 -0
  111. package/build/esm/extensions/additional/Mermaid/types.js +2 -0
  112. package/build/esm/extensions/additional/Mermaid/types.js.map +1 -0
  113. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/NodeView.d.ts +1 -0
  114. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/NodeView.js +14 -5
  115. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/NodeView.js.map +1 -1
  116. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/YfmHtmlBlockView.js +13 -11
  117. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockNodeView/YfmHtmlBlockView.js.map +1 -1
  118. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/const.d.ts +3 -0
  119. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/const.js +6 -0
  120. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/const.js.map +1 -1
  121. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/index.d.ts +2 -2
  122. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/index.js +8 -3
  123. package/build/esm/extensions/additional/YfmHtmlBlock/YfmHtmlBlockSpecs/index.js.map +1 -1
  124. package/build/esm/extensions/additional/YfmHtmlBlock/actions.js +9 -2
  125. package/build/esm/extensions/additional/YfmHtmlBlock/actions.js.map +1 -1
  126. package/build/esm/extensions/additional/YfmHtmlBlock/types.d.ts +3 -0
  127. package/build/esm/extensions/additional/YfmHtmlBlock/types.js +2 -0
  128. package/build/esm/extensions/additional/YfmHtmlBlock/types.js.map +1 -0
  129. package/build/esm/extensions/behavior/Autocomplete/index.d.ts +1 -0
  130. package/build/esm/extensions/behavior/Autocomplete/index.js +2 -1
  131. package/build/esm/extensions/behavior/Autocomplete/index.js.map +1 -1
  132. package/build/esm/extensions/behavior/Autocomplete/types.d.ts +1 -1
  133. package/build/esm/extensions/behavior/Autocomplete/types.js.map +1 -1
  134. package/build/esm/extensions/behavior/Autocomplete/utils.d.ts +3 -0
  135. package/build/esm/extensions/behavior/Autocomplete/utils.js +5 -0
  136. package/build/esm/extensions/behavior/Autocomplete/utils.js.map +1 -0
  137. package/build/esm/extensions/behavior/Clipboard/code.d.ts +7 -1
  138. package/build/esm/extensions/behavior/Clipboard/code.js +57 -0
  139. package/build/esm/extensions/behavior/Clipboard/code.js.map +1 -1
  140. package/build/esm/extensions/behavior/Clipboard/index.js +2 -0
  141. package/build/esm/extensions/behavior/Clipboard/index.js.map +1 -1
  142. package/build/esm/extensions/behavior/CommandMenu/handler.js +7 -7
  143. package/build/esm/extensions/behavior/CommandMenu/handler.js.map +1 -1
  144. package/build/esm/extensions/behavior/SharedState/SharedState.d.ts +7 -0
  145. package/build/esm/extensions/behavior/SharedState/SharedState.js +11 -0
  146. package/build/esm/extensions/behavior/SharedState/SharedState.js.map +1 -0
  147. package/build/esm/extensions/behavior/SharedState/index.d.ts +1 -0
  148. package/build/esm/extensions/behavior/SharedState/index.js +2 -0
  149. package/build/esm/extensions/behavior/SharedState/index.js.map +1 -0
  150. package/build/esm/extensions/behavior/SharedState/plugin.d.ts +3 -0
  151. package/build/esm/extensions/behavior/SharedState/plugin.js +59 -0
  152. package/build/esm/extensions/behavior/SharedState/plugin.js.map +1 -0
  153. package/build/esm/extensions/behavior/SharedState/types.d.ts +1 -0
  154. package/build/esm/extensions/behavior/SharedState/types.js +2 -0
  155. package/build/esm/extensions/behavior/SharedState/types.js.map +1 -0
  156. package/build/esm/extensions/behavior/SharedState/utils.d.ts +29 -0
  157. package/build/esm/extensions/behavior/SharedState/utils.js +56 -0
  158. package/build/esm/extensions/behavior/SharedState/utils.js.map +1 -0
  159. package/build/esm/extensions/behavior/index.d.ts +2 -0
  160. package/build/esm/extensions/behavior/index.js +4 -0
  161. package/build/esm/extensions/behavior/index.js.map +1 -1
  162. package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.js +41 -26
  163. package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.js.map +1 -1
  164. package/build/esm/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.d.ts +0 -1
  165. package/build/esm/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.js +8 -7
  166. package/build/esm/extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.js.map +1 -1
  167. package/build/esm/react-utils/index.d.ts +1 -0
  168. package/build/esm/react-utils/index.js +1 -0
  169. package/build/esm/react-utils/index.js.map +1 -1
  170. package/build/esm/react-utils/useSharedEditingState.d.ts +5 -0
  171. package/build/esm/react-utils/useSharedEditingState.js +22 -0
  172. package/build/esm/react-utils/useSharedEditingState.js.map +1 -0
  173. package/build/esm/utils/descedants.d.ts +8 -0
  174. package/build/esm/utils/descedants.js +12 -0
  175. package/build/esm/utils/descedants.js.map +1 -0
  176. package/build/esm/utils/entity-id.d.ts +11 -0
  177. package/build/esm/utils/entity-id.js +16 -0
  178. package/build/esm/utils/entity-id.js.map +1 -0
  179. package/build/esm/utils/index.d.ts +2 -0
  180. package/build/esm/utils/index.js +2 -0
  181. package/build/esm/utils/index.js.map +1 -1
  182. package/build/esm/version.js +1 -1
  183. package/build/esm/version.js.map +1 -1
  184. package/build/esm/view/hocs/withYfmHtml/index.d.ts +2 -0
  185. package/build/esm/view/hocs/withYfmHtml/index.js +2 -2
  186. package/build/esm/view/hocs/withYfmHtml/index.js.map +1 -1
  187. package/build/esm/view/hocs/withYfmHtml/useYfmHtmlBlockRuntime.js +3 -1
  188. package/build/esm/view/hocs/withYfmHtml/useYfmHtmlBlockRuntime.js.map +1 -1
  189. package/package.json +3 -3
@@ -11,41 +11,53 @@ export const CodeBlockHighlight = (builder, opts) => {
11
11
  let langs;
12
12
  let lowlight;
13
13
  let hljs;
14
- try {
15
- hljs = require('highlight.js/lib/core');
16
- const low = require('lowlight');
17
- const all = low.all;
18
- const create = low.createLowlight;
19
- langs = { ...all, ...opts.langs };
20
- lowlight = create(langs);
21
- }
22
- catch (e) {
23
- globalLogger.info('Skip code_block highlighting');
24
- builder.logger.log('Skip code_block highlighting');
25
- return;
26
- }
14
+ const loadModules = async () => {
15
+ try {
16
+ hljs = (await import('highlight.js/lib/core')).default;
17
+ const low = await import('lowlight');
18
+ const all = low.all;
19
+ const create = low.createLowlight;
20
+ langs = { ...all, ...opts.langs };
21
+ lowlight = create(langs);
22
+ return true;
23
+ }
24
+ catch (e) {
25
+ globalLogger.info('Skip code_block highlighting');
26
+ builder.logger.log('Skip code_block highlighting');
27
+ return false;
28
+ }
29
+ };
27
30
  builder.addPlugin(() => {
31
+ let modulesLoaded = false;
28
32
  const selectItems = [];
29
33
  const mapping = {};
30
- for (const lang of Object.keys(langs)) {
31
- const defs = langs[lang](hljs);
32
- selectItems.push({
33
- value: lang,
34
- content: defs.name || capitalize(lang),
35
- });
36
- if (defs.aliases) {
37
- for (const alias of defs.aliases) {
38
- mapping[alias] = lang;
39
- }
40
- }
41
- }
42
34
  // TODO: add TAB key handler
43
35
  // TODO: Remove constant selection of block
44
36
  return new Plugin({
45
37
  key,
46
38
  state: {
47
- init: (_, state) => getDecorations(state.doc),
39
+ init: (_, state) => {
40
+ loadModules().then(() => {
41
+ modulesLoaded = true;
42
+ for (const lang of Object.keys(langs)) {
43
+ const defs = langs[lang](hljs);
44
+ selectItems.push({
45
+ value: lang,
46
+ content: defs.name || capitalize(lang),
47
+ });
48
+ if (defs.aliases) {
49
+ for (const alias of defs.aliases) {
50
+ mapping[alias] = lang;
51
+ }
52
+ }
53
+ }
54
+ });
55
+ return getDecorations(state.doc);
56
+ },
48
57
  apply: (tr, decos, oldState, newState) => {
58
+ if (!modulesLoaded) {
59
+ return DecorationSet.empty;
60
+ }
49
61
  if (tr.docChanged) {
50
62
  const oldNodeName = oldState.selection.$head.parent.type.name;
51
63
  const newNodeName = newState.selection.$head.parent.type.name;
@@ -120,6 +132,9 @@ export const CodeBlockHighlight = (builder, opts) => {
120
132
  });
121
133
  function getDecorations(doc) {
122
134
  const decos = [];
135
+ if (!lowlight) {
136
+ return DecorationSet.empty;
137
+ }
123
138
  for (const { node, pos } of findChildrenByType(doc, codeBlockType(doc.type.schema), true)) {
124
139
  let from = pos + 1;
125
140
  let nodes;
@@ -1 +1 @@
1
- {"version":3,"file":"CodeBlockHighlight.js","sourceRoot":"../../../../../../src","sources":["extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.ts"],"names":[],"mappings":"AAKA,OAAO,EAAC,MAAM,EAAE,SAAS,EAAC,MAAM,mBAAmB,CAAC;AAEpD,oCAAoC;AACpC,OAAO,EAAC,kBAAkB,EAAC,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAC,UAAU,EAAE,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAG3D,OAAO,EAAC,UAAU,EAAC,8BAA2B;AAC9C,OAAO,EAAC,YAAY,EAAC,8BAA2B;AAChD,OAAO,EAAC,iBAAiB,EAAE,iBAAiB,EAAE,aAAa,EAAC,mCAA0B;AAEtF,OAAO,EAAC,gCAAgC,EAAC,iCAAwB;AAYjE,MAAM,GAAG,GAAG,IAAI,SAAS,CAAgB,sBAAsB,CAAC,CAAC;AAMjE,MAAM,CAAC,MAAM,kBAAkB,GAA6C,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;IAC1F,IAAI,KAAoC,CAAC;IACzC,IAAI,QAAkB,CAAC;IACvB,IAAI,IAAiB,CAAC;IAEtB,IAAI,CAAC;QACD,IAAI,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;QACxC,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QAChC,MAAM,GAAG,GAAqB,GAAG,CAAC,GAAG,CAAC;QACtC,MAAM,MAAM,GAA0B,GAAG,CAAC,cAAc,CAAC;QACzD,KAAK,GAAG,EAAC,GAAG,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAC,CAAC;QAChC,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,YAAY,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;QAClD,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;QACnD,OAAO;IACX,CAAC;IAED,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,WAAW,GAAqB,EAAE,CAAC;QACzC,MAAM,OAAO,GAA2B,EAAE,CAAC;QAC3C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;YAC/B,WAAW,CAAC,IAAI,CAAC;gBACb,KAAK,EAAE,IAAI;gBACX,OAAO,EAAE,IAAI,CAAC,IAAI,IAAI,UAAU,CAAC,IAAI,CAAC;aACzC,CAAC,CAAC;YACH,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;oBAC/B,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;gBAC1B,CAAC;YACL,CAAC;QACL,CAAC;QAED,4BAA4B;QAC5B,2CAA2C;QAC3C,OAAO,IAAI,MAAM,CAAgB;YAC7B,GAAG;YACH,KAAK,EAAE;gBACH,IAAI,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC;gBAC7C,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE;oBACrC,IAAI,EAAE,CAAC,UAAU,EAAE,CAAC;wBAChB,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;wBAC9D,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;wBAE9D,wBAAwB;wBACxB,IACI,WAAW,KAAK,iBAAiB;4BACjC,WAAW,KAAK,iBAAiB,EACnC,CAAC;4BACC,qCAAqC;4BACrC,OAAO,cAAc,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;wBAClC,CAAC;6BAAM,CAAC;4BACJ,MAAM,QAAQ,GAAG,kBAAkB,CAC/B,QAAQ,CAAC,GAAG,EACZ,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,CACjC,CAAC;4BACF,MAAM,QAAQ,GAAG,kBAAkB,CAC/B,QAAQ,CAAC,GAAG,EACZ,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,CACjC,CAAC;4BACF;4BACI,+CAA+C;4BAC/C,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM;gCACnC,gEAAgE;gCAChE,iEAAiE;gCACjE,qFAAqF;gCACrF,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;oCACnB,OAAO,CACH,aAAa,CAAC,IAAI,CAAC;wCACnB,QAAQ,CAAC,IAAI,CACT,CAAC,IAA+B,EAAE,EAAE,CAChC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI;4CACrB,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,EAAE,CAC/C,CACJ,CAAC;gCACN,CAAC,CAAC,EACJ,CAAC;gCACC,OAAO,cAAc,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;4BAClC,CAAC;wBACL,CAAC;oBACL,CAAC;oBACD,OAAO,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;gBACzC,CAAC;aACJ;YACD,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,gCAAgC,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC;YAC5E,KAAK,EAAE;gBACH,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE;oBACnB,OAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAC/B,CAAC;gBACD,SAAS,EAAE;oBACP,CAAC,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE;wBAC1B,IAAI,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;wBAElD,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;wBAE1C,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;wBAClD,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;wBAEjC,IAAI,QAAQ,EAAE,CAAC;4BACX,GAAG,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;4BACnD,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;wBACvC,CAAC;wBAED,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;wBAEvB,OAAO;4BACH,GAAG;4BACH,UAAU;4BACV,MAAM,CAAC,OAAO;gCACV,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI;oCAAE,OAAO,KAAK,CAAC;gCAE7C,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;gCACtD,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;oCACvB,UAAU,CAAC,SAAS,GAAG,MAAM,CAAC;oCAC9B,IAAI,OAAO,EAAE,CAAC;wCACV,GAAG,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;wCAClD,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oCACtC,CAAC;yCAAM,CAAC;wCACJ,GAAG,CAAC,eAAe,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;oCAChD,CAAC;oCACD,QAAQ,GAAG,OAAO,CAAC;gCACvB,CAAC;gCAED,OAAO,IAAI,CAAC;4BAChB,CAAC;yBACJ,CAAC;oBACN,CAAC;iBACJ;aACJ;SACJ,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,SAAS,cAAc,CAAC,GAAS;QAC7B,MAAM,KAAK,GAAiB,EAAE,CAAC;QAE/B,KAAK,MAAM,EAAC,IAAI,EAAE,GAAG,EAAC,IAAI,kBAAkB,CAAC,GAAG,EAAE,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC;YACtF,IAAI,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC;YACnB,IAAI,KAAuB,CAAC;YAE5B,MAAM,IAAI,GAAuB,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACpE,IAAI,IAAI,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACpC,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC;YAChE,CAAC;iBAAM,CAAC;gBACJ,SAAS;YACb,CAAC;YAED,KAAK,MAAM,EAAC,IAAI,EAAE,OAAO,EAAC,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9C,MAAM,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC;gBAC9B,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;oBACjB,KAAK,CAAC,IAAI,CACN,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE;wBACxB,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;qBAC3B,CAAC,CACL,CAAC;gBACN,CAAC;gBACD,IAAI,GAAG,EAAE,CAAC;YACd,CAAC;QACL,CAAC;QAED,OAAO,aAAa,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC5C,CAAC;AACL,CAAC,CAAC;AAEF,SAAS,UAAU,CACf,KAAuB,EACvB,YAA+B,EAAE;IAEjC,OAAO,KAAK;SACP,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACV,IAAI,OAAO,GAAG,SAAS,CAAC;QACxB,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,GAAG,OAAO,CAAC,MAAM,CAAE,IAAI,CAAC,UAAU,CAAC,SAAsB,IAAI,EAAE,CAAC,CAAC;YACxE,OAAO,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC9C,CAAC;QAED,OAAO;YACH,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;YACvE,OAAO;SACV,CAAC;IACN,CAAC,CAAC;SACD,IAAI,EAAE,CAAC;AAChB,CAAC;AAED,SAAS,aAAa,CAAC,IAAU;IAC7B,mBAAmB;IACnB,OAAO,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,CAAC;AACxE,CAAC","sourcesContent":["import type {Options} from '@diplodoc/transform';\n// importing only type, because lowlight and highlight.js is optional deps\nimport type HLJS from 'highlight.js/lib/core';\nimport type {createLowlight} from 'lowlight' with {'resolution-mode': 'import'};\nimport type {Node} from 'prosemirror-model';\nimport {Plugin, PluginKey} from 'prosemirror-state';\nimport type {Step} from 'prosemirror-transform';\n// @ts-ignore // TODO: fix cjs build\nimport {findChildrenByType} from 'prosemirror-utils';\nimport {Decoration, DecorationSet} from 'prosemirror-view';\n\nimport type {ExtensionAuto} from '../../../../core';\nimport {capitalize} from '../../../../lodash';\nimport {globalLogger} from '../../../../logger';\nimport {CodeBlockNodeAttr, codeBlockNodeName, codeBlockType} from '../CodeBlockSpecs';\n\nimport {codeLangSelectTooltipViewCreator} from './TooltipPlugin';\n\nexport type HighlightLangMap = Options['highlightLangs'];\n\ntype Lowlight = ReturnType<typeof createLowlight>;\ntype Root = ReturnType<Lowlight['highlight']>;\n\ntype LangSelectItem = {\n value: string;\n content: string;\n};\n\nconst key = new PluginKey<DecorationSet>('code_block_highlight');\n\nexport type CodeBlockHighlightOptions = {\n langs?: HighlightLangMap;\n};\n\nexport const CodeBlockHighlight: ExtensionAuto<CodeBlockHighlightOptions> = (builder, opts) => {\n let langs: NonNullable<HighlightLangMap>;\n let lowlight: Lowlight;\n let hljs: typeof HLJS;\n\n try {\n hljs = require('highlight.js/lib/core');\n const low = require('lowlight');\n const all: HighlightLangMap = low.all;\n const create: typeof createLowlight = low.createLowlight;\n langs = {...all, ...opts.langs};\n lowlight = create(langs);\n } catch (e) {\n globalLogger.info('Skip code_block highlighting');\n builder.logger.log('Skip code_block highlighting');\n return;\n }\n\n builder.addPlugin(() => {\n const selectItems: LangSelectItem[] = [];\n const mapping: Record<string, string> = {};\n for (const lang of Object.keys(langs)) {\n const defs = langs[lang](hljs);\n selectItems.push({\n value: lang,\n content: defs.name || capitalize(lang),\n });\n if (defs.aliases) {\n for (const alias of defs.aliases) {\n mapping[alias] = lang;\n }\n }\n }\n\n // TODO: add TAB key handler\n // TODO: Remove constant selection of block\n return new Plugin<DecorationSet>({\n key,\n state: {\n init: (_, state) => getDecorations(state.doc),\n apply: (tr, decos, oldState, newState) => {\n if (tr.docChanged) {\n const oldNodeName = oldState.selection.$head.parent.type.name;\n const newNodeName = newState.selection.$head.parent.type.name;\n\n // Apply decorations if:\n if (\n oldNodeName === codeBlockNodeName ||\n newNodeName === codeBlockNodeName\n ) {\n // selection includes codeblock node,\n return getDecorations(tr.doc);\n } else {\n const oldNodes = findChildrenByType(\n oldState.doc,\n codeBlockType(oldState.schema),\n );\n const newNodes = findChildrenByType(\n newState.doc,\n codeBlockType(newState.schema),\n );\n if (\n // OR transaction adds/removes codeblock nodes,\n newNodes.length !== oldNodes.length ||\n // OR transaction has changes that completely encapsulate a node\n // (for example, a transaction that affects the entire document).\n // Such transactions can happen during collab syncing via y-prosemirror, for example.\n tr.steps.some((step) => {\n return (\n stepHasFromTo(step) &&\n oldNodes.some(\n (node: {node: Node; pos: number}) =>\n node.pos >= step.from &&\n node.pos + node.node.nodeSize <= step.to,\n )\n );\n })\n ) {\n return getDecorations(tr.doc);\n }\n }\n }\n return decos.map(tr.mapping, tr.doc);\n },\n },\n view: (view) => codeLangSelectTooltipViewCreator(view, selectItems, mapping),\n props: {\n decorations: (state) => {\n return key.getState(state);\n },\n nodeViews: {\n [codeBlockNodeName]: (node) => {\n let prevLang = node.attrs[CodeBlockNodeAttr.Lang];\n\n const dom = document.createElement('pre');\n\n const contentDOM = document.createElement('code');\n contentDOM.classList.add('hljs');\n\n if (prevLang) {\n dom.setAttribute(CodeBlockNodeAttr.Lang, prevLang);\n contentDOM.classList.add(prevLang);\n }\n\n dom.append(contentDOM);\n\n return {\n dom,\n contentDOM,\n update(newNode) {\n if (node.type !== newNode.type) return false;\n\n const newLang = newNode.attrs[CodeBlockNodeAttr.Lang];\n if (prevLang !== newLang) {\n contentDOM.className = 'hljs';\n if (newLang) {\n dom.setAttribute(CodeBlockNodeAttr.Lang, newLang);\n contentDOM.classList.add(newLang);\n } else {\n dom.removeAttribute(CodeBlockNodeAttr.Lang);\n }\n prevLang = newLang;\n }\n\n return true;\n },\n };\n },\n },\n },\n });\n });\n\n function getDecorations(doc: Node) {\n const decos: Decoration[] = [];\n\n for (const {node, pos} of findChildrenByType(doc, codeBlockType(doc.type.schema), true)) {\n let from = pos + 1;\n let nodes: Root['children'];\n\n const lang: string | undefined = node.attrs[CodeBlockNodeAttr.Lang];\n if (lang && lowlight.registered(lang)) {\n nodes = lowlight.highlight(lang, node.textContent).children;\n } else {\n continue;\n }\n\n for (const {text, classes} of parseNodes(nodes)) {\n const to = from + text.length;\n if (classes.length) {\n decos.push(\n Decoration.inline(from, to, {\n class: classes.join(' '),\n }),\n );\n }\n from = to;\n }\n }\n\n return DecorationSet.create(doc, decos);\n }\n};\n\nfunction parseNodes(\n nodes: Root['children'],\n className: readonly string[] = [],\n): {text: string; classes: readonly string[]}[] {\n return nodes\n .map((node) => {\n let classes = className;\n if (node.type === 'element') {\n classes = classes.concat((node.properties.className as string[]) ?? []);\n return parseNodes(node.children, classes);\n }\n\n return {\n text: node.type === 'comment' || node.type === 'text' ? node.value : '',\n classes,\n };\n })\n .flat();\n}\n\nfunction stepHasFromTo(step: Step): step is Step & {from: number; to: number} {\n // @ts-expect-error\n return typeof step.from === 'number' && typeof step.to === 'number';\n}\n"]}
1
+ {"version":3,"file":"CodeBlockHighlight.js","sourceRoot":"../../../../../../src","sources":["extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.ts"],"names":[],"mappings":"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","sourcesContent":["import type {Options} from '@diplodoc/transform';\n// importing only type, because lowlight and highlight.js is optional deps\nimport type HLJS from 'highlight.js/lib/core';\nimport type {createLowlight} from 'lowlight' with {'resolution-mode': 'import'};\nimport type {Node} from 'prosemirror-model';\nimport {Plugin, PluginKey} from 'prosemirror-state';\nimport type {Step} from 'prosemirror-transform';\n// @ts-ignore // TODO: fix cjs build\nimport {findChildrenByType} from 'prosemirror-utils';\nimport {Decoration, DecorationSet} from 'prosemirror-view';\n\nimport type {ExtensionAuto} from '../../../../core';\nimport {capitalize} from '../../../../lodash';\nimport {globalLogger} from '../../../../logger';\nimport {CodeBlockNodeAttr, codeBlockNodeName, codeBlockType} from '../CodeBlockSpecs';\n\nimport {codeLangSelectTooltipViewCreator} from './TooltipPlugin';\n\nexport type HighlightLangMap = Options['highlightLangs'];\n\ntype Lowlight = ReturnType<typeof createLowlight>;\ntype Root = ReturnType<Lowlight['highlight']>;\n\ntype LangSelectItem = {\n value: string;\n content: string;\n};\n\nconst key = new PluginKey<DecorationSet>('code_block_highlight');\n\nexport type CodeBlockHighlightOptions = {\n langs?: HighlightLangMap;\n};\n\nexport const CodeBlockHighlight: ExtensionAuto<CodeBlockHighlightOptions> = (builder, opts) => {\n let langs: NonNullable<HighlightLangMap>;\n let lowlight: Lowlight;\n let hljs: typeof HLJS;\n\n const loadModules = async () => {\n try {\n hljs = (await import('highlight.js/lib/core')).default;\n const low = await import('lowlight');\n\n const all: HighlightLangMap = low.all;\n const create: typeof createLowlight = low.createLowlight;\n langs = {...all, ...opts.langs};\n lowlight = create(langs);\n return true;\n } catch (e) {\n globalLogger.info('Skip code_block highlighting');\n builder.logger.log('Skip code_block highlighting');\n return false;\n }\n };\n\n builder.addPlugin(() => {\n let modulesLoaded = false;\n\n const selectItems: LangSelectItem[] = [];\n const mapping: Record<string, string> = {};\n\n // TODO: add TAB key handler\n // TODO: Remove constant selection of block\n return new Plugin<DecorationSet>({\n key,\n state: {\n init: (_, state) => {\n loadModules().then(() => {\n modulesLoaded = true;\n\n for (const lang of Object.keys(langs)) {\n const defs = langs[lang](hljs);\n selectItems.push({\n value: lang,\n content: defs.name || capitalize(lang),\n });\n if (defs.aliases) {\n for (const alias of defs.aliases) {\n mapping[alias] = lang;\n }\n }\n }\n });\n return getDecorations(state.doc);\n },\n apply: (tr, decos, oldState, newState) => {\n if (!modulesLoaded) {\n return DecorationSet.empty;\n }\n\n if (tr.docChanged) {\n const oldNodeName = oldState.selection.$head.parent.type.name;\n const newNodeName = newState.selection.$head.parent.type.name;\n\n // Apply decorations if:\n if (\n oldNodeName === codeBlockNodeName ||\n newNodeName === codeBlockNodeName\n ) {\n // selection includes codeblock node,\n return getDecorations(tr.doc);\n } else {\n const oldNodes = findChildrenByType(\n oldState.doc,\n codeBlockType(oldState.schema),\n );\n const newNodes = findChildrenByType(\n newState.doc,\n codeBlockType(newState.schema),\n );\n if (\n // OR transaction adds/removes codeblock nodes,\n newNodes.length !== oldNodes.length ||\n // OR transaction has changes that completely encapsulate a node\n // (for example, a transaction that affects the entire document).\n // Such transactions can happen during collab syncing via y-prosemirror, for example.\n tr.steps.some((step) => {\n return (\n stepHasFromTo(step) &&\n oldNodes.some(\n (node: {node: Node; pos: number}) =>\n node.pos >= step.from &&\n node.pos + node.node.nodeSize <= step.to,\n )\n );\n })\n ) {\n return getDecorations(tr.doc);\n }\n }\n }\n return decos.map(tr.mapping, tr.doc);\n },\n },\n view: (view) => codeLangSelectTooltipViewCreator(view, selectItems, mapping),\n props: {\n decorations: (state) => {\n return key.getState(state);\n },\n nodeViews: {\n [codeBlockNodeName]: (node) => {\n let prevLang = node.attrs[CodeBlockNodeAttr.Lang];\n\n const dom = document.createElement('pre');\n\n const contentDOM = document.createElement('code');\n contentDOM.classList.add('hljs');\n\n if (prevLang) {\n dom.setAttribute(CodeBlockNodeAttr.Lang, prevLang);\n contentDOM.classList.add(prevLang);\n }\n\n dom.append(contentDOM);\n\n return {\n dom,\n contentDOM,\n update(newNode) {\n if (node.type !== newNode.type) return false;\n\n const newLang = newNode.attrs[CodeBlockNodeAttr.Lang];\n if (prevLang !== newLang) {\n contentDOM.className = 'hljs';\n if (newLang) {\n dom.setAttribute(CodeBlockNodeAttr.Lang, newLang);\n contentDOM.classList.add(newLang);\n } else {\n dom.removeAttribute(CodeBlockNodeAttr.Lang);\n }\n prevLang = newLang;\n }\n\n return true;\n },\n };\n },\n },\n },\n });\n });\n\n function getDecorations(doc: Node) {\n const decos: Decoration[] = [];\n\n if (!lowlight) {\n return DecorationSet.empty;\n }\n\n for (const {node, pos} of findChildrenByType(doc, codeBlockType(doc.type.schema), true)) {\n let from = pos + 1;\n let nodes: Root['children'];\n\n const lang: string | undefined = node.attrs[CodeBlockNodeAttr.Lang];\n if (lang && lowlight.registered(lang)) {\n nodes = lowlight.highlight(lang, node.textContent).children;\n } else {\n continue;\n }\n\n for (const {text, classes} of parseNodes(nodes)) {\n const to = from + text.length;\n if (classes.length) {\n decos.push(\n Decoration.inline(from, to, {\n class: classes.join(' '),\n }),\n );\n }\n from = to;\n }\n }\n\n return DecorationSet.create(doc, decos);\n }\n};\n\nfunction parseNodes(\n nodes: Root['children'],\n className: readonly string[] = [],\n): {text: string; classes: readonly string[]}[] {\n return nodes\n .map((node) => {\n let classes = className;\n if (node.type === 'element') {\n classes = classes.concat((node.properties.className as string[]) ?? []);\n return parseNodes(node.children, classes);\n }\n\n return {\n text: node.type === 'comment' || node.type === 'text' ? node.value : '',\n classes,\n };\n })\n .flat();\n}\n\nfunction stepHasFromTo(step: Step): step is Step & {from: number; to: number} {\n // @ts-expect-error\n return typeof step.from === 'number' && typeof step.to === 'number';\n}\n"]}
@@ -8,7 +8,6 @@ export declare class EmojiHandler implements AutocompleteHandler {
8
8
  private _emojiCarousel?;
9
9
  private _view?;
10
10
  private _anchor;
11
- private _range?;
12
11
  private _popupCloser?;
13
12
  private _suggestProps?;
14
13
  private _suggestRenderItem?;
@@ -1,7 +1,7 @@
1
1
  import { AutocompletePopupCloser } from "../../../../utils/autocomplete-popup.js";
2
2
  import { ArrayCarousel } from "../../../../utils/carousel/index.js";
3
3
  import { getReactRendererFromState } from "../../../behavior/index.js";
4
- import { AutocompleteActionKind, closeAutocomplete, } from "../../../behavior/Autocomplete/index.js";
4
+ import { AutocompleteActionKind, closeAutocomplete, getAutocompleteState, } from "../../../behavior/Autocomplete/index.js";
5
5
  import { EmojiConsts } from "../EmojiSpecs/index.js";
6
6
  import { render } from "./EmojiSuggestComponent.js";
7
7
  import { findDecoElem } from "./utils.js";
@@ -11,7 +11,6 @@ export class EmojiHandler {
11
11
  _emojiCarousel;
12
12
  _view;
13
13
  _anchor = null;
14
- _range;
15
14
  _popupCloser;
16
15
  _suggestProps;
17
16
  _suggestRenderItem;
@@ -89,12 +88,16 @@ export class EmojiHandler {
89
88
  });
90
89
  }
91
90
  select() {
92
- const { _view: view, _range: range } = this;
93
- if (!view || !range)
91
+ const { _view: view } = this;
92
+ if (!view)
94
93
  return;
95
94
  const emojiDef = this._emojiCarousel?.currentItem;
96
95
  if (!emojiDef)
97
96
  return;
97
+ const autocompleteState = getAutocompleteState(view.state);
98
+ if (!autocompleteState || !autocompleteState.active)
99
+ return;
100
+ const { range } = autocompleteState;
98
101
  const { tr, schema } = view.state;
99
102
  view.dispatch(tr.replaceWith(range.from, range.to, createEmoji(schema, emojiDef)).scrollIntoView());
100
103
  view.focus();
@@ -136,13 +139,11 @@ export class EmojiHandler {
136
139
  }
137
140
  this._view?.focus();
138
141
  };
139
- updateState({ view, range }) {
142
+ updateState({ view }) {
140
143
  this._view = view;
141
- this._range = range;
142
144
  }
143
145
  clear() {
144
146
  this._view = undefined;
145
- this._range = undefined;
146
147
  this._anchor = null;
147
148
  this._emojiCarousel = undefined;
148
149
  this._popupCloser?.cancelTimer();
@@ -1 +1 @@
1
- {"version":3,"file":"EmojiHandler.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import type {Schema} from 'prosemirror-model';\nimport type {EditorView} from 'prosemirror-view';\n\nimport {AutocompletePopupCloser} from '../../../../utils/autocomplete-popup';\nimport {ArrayCarousel} from '../../../../utils/carousel';\nimport {type RendererItem, getReactRendererFromState} from '../../../behavior';\nimport {\n type AutocompleteAction,\n AutocompleteActionKind,\n type AutocompleteHandler,\n type FromTo,\n closeAutocomplete,\n} from '../../../behavior/Autocomplete';\nimport {EmojiConsts} from '../EmojiSpecs';\n\nimport {type EmojiSuggestComponentProps, render} from './EmojiSuggestComponent';\nimport type {EmojiDef} from './types';\nimport {findDecoElem} from './utils';\n\nconst emptyArray = new Array<string>(0);\n\nexport type EmojiHandlerParams = {\n defs: Record<string, string>;\n shortcuts?: Partial<Record<string, string | string[]>>;\n};\n\nexport class EmojiHandler implements AutocompleteHandler {\n private readonly _emojis: readonly EmojiDef[];\n private _emojiCarousel?: ArrayCarousel<EmojiDef>;\n\n private _view?: EditorView;\n private _anchor: Element | null = null;\n private _range?: FromTo;\n private _popupCloser?: AutocompletePopupCloser;\n\n private _suggestProps?: EmojiSuggestComponentProps;\n private _suggestRenderItem?: RendererItem;\n\n constructor({defs, shortcuts = {}}: EmojiHandlerParams) {\n this._emojis = Object.entries(defs).map(([name, symbol]) => {\n const def: EmojiDef = {symbol, origName: name, name: name.toLowerCase()};\n const short = shortcuts[name];\n if (short) {\n def.origShortcuts = emptyArray.concat(short);\n def.shortcuts = def.origShortcuts.map((val) =>\n val.startsWith(':') ? val.slice(1) : val,\n );\n }\n return def;\n });\n }\n\n onOpen(action: AutocompleteAction): boolean {\n this.findAnchor();\n if (!this._anchor) {\n this.closeAutocomplete(action.view);\n return true;\n }\n\n this._popupCloser = new AutocompletePopupCloser(action.view);\n this.updateState(action);\n this.filterActions();\n this.render();\n\n return true;\n }\n\n onFilter(action: AutocompleteAction): boolean {\n if (action.filter?.endsWith(' ')) {\n this.closeAutocomplete(action.view);\n return true;\n }\n\n this.updateState(action);\n\n const needToClose = this.filterActions(action.filter?.trim());\n this.render();\n\n if (needToClose) {\n this.closeAutocomplete(action.view);\n }\n\n return true;\n }\n\n onArrow(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n if (!this._emojiCarousel) return false;\n\n switch (action.kind) {\n case AutocompleteActionKind.up: {\n this._emojiCarousel.prev();\n break;\n }\n case AutocompleteActionKind.down: {\n this._emojiCarousel.next();\n break;\n }\n default:\n return false;\n }\n\n this.render();\n\n return true;\n }\n\n onEnter(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n this.select();\n\n return true;\n }\n\n onClose(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n this.clear();\n\n return true;\n }\n\n onDestroy(): void {\n this.clear();\n }\n\n private closeAutocomplete(view: EditorView) {\n setTimeout(() => {\n closeAutocomplete(view);\n });\n }\n\n private select() {\n const {_view: view, _range: range} = this;\n if (!view || !range) return;\n\n const emojiDef = this._emojiCarousel?.currentItem;\n if (!emojiDef) return;\n\n const {tr, schema} = view.state;\n view.dispatch(\n tr.replaceWith(range.from, range.to, createEmoji(schema, emojiDef)).scrollIntoView(),\n );\n view.focus();\n }\n\n private filterActions(inputText?: string): boolean {\n const currentItem = this._emojiCarousel?.currentItem;\n\n let filteredEmojis = this._emojis;\n let needToClose = false;\n\n if (inputText) {\n filteredEmojis = filterEmojis(filteredEmojis, inputText);\n needToClose = !filteredEmojis.length && needToHide(this._emojis, inputText);\n }\n\n this._emojiCarousel = new ArrayCarousel(filteredEmojis);\n\n if (currentItem) {\n const newIndex = this._emojiCarousel.array.findIndex((item) => item === currentItem);\n if (newIndex !== -1) {\n this._emojiCarousel.currentIndex = newIndex;\n }\n }\n\n return needToClose;\n }\n\n private render() {\n this.findAnchor();\n const viewItems = this._emojiCarousel?.array ?? [];\n this._suggestProps = {\n anchorElement: this._anchor,\n currentIndex: this._emojiCarousel?.currentIndex,\n items: viewItems,\n onClick: this.onItemClick,\n onOpenChange: this._popupCloser?.popupOpenChangeHandler,\n };\n this._suggestRenderItem = this._suggestRenderItem ?? this.createMenuRenderItem();\n this._suggestRenderItem.rerender();\n }\n\n private onItemClick = (index: number) => {\n if (this._emojiCarousel) {\n this._emojiCarousel.currentIndex = index;\n this.select();\n }\n this._view?.focus();\n };\n\n private updateState({view, range}: AutocompleteAction) {\n this._view = view;\n this._range = range;\n }\n\n private clear() {\n this._view = undefined;\n this._range = undefined;\n this._anchor = null;\n this._emojiCarousel = undefined;\n this._popupCloser?.cancelTimer();\n this._popupCloser = undefined;\n this._suggestProps = undefined;\n this._suggestRenderItem?.remove();\n this._suggestRenderItem = undefined;\n }\n\n private createMenuRenderItem(): RendererItem {\n return getReactRendererFromState(this._view!.state).createItem('emoji_suggest', () =>\n this._suggestProps ? render(this._suggestProps) : null,\n );\n }\n\n private findAnchor() {\n this._anchor = findDecoElem(this._view?.dom);\n }\n}\n\nfunction createEmoji(schema: Schema, def: EmojiDef) {\n return EmojiConsts.nodeType(schema).create(\n {[EmojiConsts.NodeAttrs.Markup]: def.name},\n schema.text(def.symbol),\n );\n}\n\nfunction filterEmojis(defs: readonly EmojiDef[], text: string): readonly EmojiDef[] {\n if (!text) return defs;\n const textLowerCase = text.toLowerCase();\n\n const byShortcuts: EmojiDef[] = [];\n const byName: EmojiDef[] = [];\n for (const emoji of defs) {\n if (emoji.shortcuts?.some((val) => val.startsWith(text))) {\n byShortcuts.push(emoji);\n } else if (emoji.name.startsWith(textLowerCase)) {\n byName.push(emoji);\n }\n }\n return byShortcuts.concat(byName);\n}\n\nconst CHARS_TO_HIDE = 4;\nfunction needToHide(defs: readonly EmojiDef[], text: string): boolean {\n let iter = 1;\n do {\n const prevInput = text.slice(0, text.length - iter);\n const prevActions = filterEmojis(defs, prevInput);\n if (prevActions.length) break;\n iter++;\n } while (iter < text.length && iter < CHARS_TO_HIDE);\n return iter >= CHARS_TO_HIDE;\n}\n"]}
1
+ {"version":3,"file":"EmojiHandler.js","sourceRoot":"../../../../../../src","sources":["extensions/yfm/Emoji/EmojiSuggest/EmojiHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import type {Schema} from 'prosemirror-model';\nimport type {EditorView} from 'prosemirror-view';\n\nimport {AutocompletePopupCloser} from '../../../../utils/autocomplete-popup';\nimport {ArrayCarousel} from '../../../../utils/carousel';\nimport {type RendererItem, getReactRendererFromState} from '../../../behavior';\nimport {\n type AutocompleteAction,\n AutocompleteActionKind,\n type AutocompleteHandler,\n closeAutocomplete,\n getAutocompleteState,\n} from '../../../behavior/Autocomplete';\nimport {EmojiConsts} from '../EmojiSpecs';\n\nimport {type EmojiSuggestComponentProps, render} from './EmojiSuggestComponent';\nimport type {EmojiDef} from './types';\nimport {findDecoElem} from './utils';\n\nconst emptyArray = new Array<string>(0);\n\nexport type EmojiHandlerParams = {\n defs: Record<string, string>;\n shortcuts?: Partial<Record<string, string | string[]>>;\n};\n\nexport class EmojiHandler implements AutocompleteHandler {\n private readonly _emojis: readonly EmojiDef[];\n private _emojiCarousel?: ArrayCarousel<EmojiDef>;\n\n private _view?: EditorView;\n private _anchor: Element | null = null;\n private _popupCloser?: AutocompletePopupCloser;\n\n private _suggestProps?: EmojiSuggestComponentProps;\n private _suggestRenderItem?: RendererItem;\n\n constructor({defs, shortcuts = {}}: EmojiHandlerParams) {\n this._emojis = Object.entries(defs).map(([name, symbol]) => {\n const def: EmojiDef = {symbol, origName: name, name: name.toLowerCase()};\n const short = shortcuts[name];\n if (short) {\n def.origShortcuts = emptyArray.concat(short);\n def.shortcuts = def.origShortcuts.map((val) =>\n val.startsWith(':') ? val.slice(1) : val,\n );\n }\n return def;\n });\n }\n\n onOpen(action: AutocompleteAction): boolean {\n this.findAnchor();\n if (!this._anchor) {\n this.closeAutocomplete(action.view);\n return true;\n }\n\n this._popupCloser = new AutocompletePopupCloser(action.view);\n this.updateState(action);\n this.filterActions();\n this.render();\n\n return true;\n }\n\n onFilter(action: AutocompleteAction): boolean {\n if (action.filter?.endsWith(' ')) {\n this.closeAutocomplete(action.view);\n return true;\n }\n\n this.updateState(action);\n\n const needToClose = this.filterActions(action.filter?.trim());\n this.render();\n\n if (needToClose) {\n this.closeAutocomplete(action.view);\n }\n\n return true;\n }\n\n onArrow(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n if (!this._emojiCarousel) return false;\n\n switch (action.kind) {\n case AutocompleteActionKind.up: {\n this._emojiCarousel.prev();\n break;\n }\n case AutocompleteActionKind.down: {\n this._emojiCarousel.next();\n break;\n }\n default:\n return false;\n }\n\n this.render();\n\n return true;\n }\n\n onEnter(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n this.select();\n\n return true;\n }\n\n onClose(action: AutocompleteAction): boolean {\n this.updateState(action);\n\n this.clear();\n\n return true;\n }\n\n onDestroy(): void {\n this.clear();\n }\n\n private closeAutocomplete(view: EditorView) {\n setTimeout(() => {\n closeAutocomplete(view);\n });\n }\n\n private select() {\n const {_view: view} = this;\n if (!view) return;\n\n const emojiDef = this._emojiCarousel?.currentItem;\n if (!emojiDef) return;\n\n const autocompleteState = getAutocompleteState(view.state);\n if (!autocompleteState || !autocompleteState.active) return;\n\n const {range} = autocompleteState;\n const {tr, schema} = view.state;\n view.dispatch(\n tr.replaceWith(range.from, range.to, createEmoji(schema, emojiDef)).scrollIntoView(),\n );\n view.focus();\n }\n\n private filterActions(inputText?: string): boolean {\n const currentItem = this._emojiCarousel?.currentItem;\n\n let filteredEmojis = this._emojis;\n let needToClose = false;\n\n if (inputText) {\n filteredEmojis = filterEmojis(filteredEmojis, inputText);\n needToClose = !filteredEmojis.length && needToHide(this._emojis, inputText);\n }\n\n this._emojiCarousel = new ArrayCarousel(filteredEmojis);\n\n if (currentItem) {\n const newIndex = this._emojiCarousel.array.findIndex((item) => item === currentItem);\n if (newIndex !== -1) {\n this._emojiCarousel.currentIndex = newIndex;\n }\n }\n\n return needToClose;\n }\n\n private render() {\n this.findAnchor();\n const viewItems = this._emojiCarousel?.array ?? [];\n this._suggestProps = {\n anchorElement: this._anchor,\n currentIndex: this._emojiCarousel?.currentIndex,\n items: viewItems,\n onClick: this.onItemClick,\n onOpenChange: this._popupCloser?.popupOpenChangeHandler,\n };\n this._suggestRenderItem = this._suggestRenderItem ?? this.createMenuRenderItem();\n this._suggestRenderItem.rerender();\n }\n\n private onItemClick = (index: number) => {\n if (this._emojiCarousel) {\n this._emojiCarousel.currentIndex = index;\n this.select();\n }\n this._view?.focus();\n };\n\n private updateState({view}: AutocompleteAction) {\n this._view = view;\n }\n\n private clear() {\n this._view = undefined;\n this._anchor = null;\n this._emojiCarousel = undefined;\n this._popupCloser?.cancelTimer();\n this._popupCloser = undefined;\n this._suggestProps = undefined;\n this._suggestRenderItem?.remove();\n this._suggestRenderItem = undefined;\n }\n\n private createMenuRenderItem(): RendererItem {\n return getReactRendererFromState(this._view!.state).createItem('emoji_suggest', () =>\n this._suggestProps ? render(this._suggestProps) : null,\n );\n }\n\n private findAnchor() {\n this._anchor = findDecoElem(this._view?.dom);\n }\n}\n\nfunction createEmoji(schema: Schema, def: EmojiDef) {\n return EmojiConsts.nodeType(schema).create(\n {[EmojiConsts.NodeAttrs.Markup]: def.name},\n schema.text(def.symbol),\n );\n}\n\nfunction filterEmojis(defs: readonly EmojiDef[], text: string): readonly EmojiDef[] {\n if (!text) return defs;\n const textLowerCase = text.toLowerCase();\n\n const byShortcuts: EmojiDef[] = [];\n const byName: EmojiDef[] = [];\n for (const emoji of defs) {\n if (emoji.shortcuts?.some((val) => val.startsWith(text))) {\n byShortcuts.push(emoji);\n } else if (emoji.name.startsWith(textLowerCase)) {\n byName.push(emoji);\n }\n }\n return byShortcuts.concat(byName);\n}\n\nconst CHARS_TO_HIDE = 4;\nfunction needToHide(defs: readonly EmojiDef[], text: string): boolean {\n let iter = 1;\n do {\n const prevInput = text.slice(0, text.length - iter);\n const prevActions = filterEmojis(defs, prevInput);\n if (prevActions.length) break;\n iter++;\n } while (iter < text.length && iter < CHARS_TO_HIDE);\n return iter >= CHARS_TO_HIDE;\n}\n"]}
@@ -3,4 +3,5 @@ export * from "./hooks.js";
3
3
  export * from "./react-node-view.js";
4
4
  export * from "./useNodeEditing.js";
5
5
  export * from "./useNodeHovered.js";
6
+ export * from "./useSharedEditingState.js";
6
7
  export * from "./useSticky.js";
@@ -3,5 +3,6 @@ export * from "./hooks.js";
3
3
  export * from "./react-node-view.js";
4
4
  export * from "./useNodeEditing.js";
5
5
  export * from "./useNodeHovered.js";
6
+ export * from "./useSharedEditingState.js";
6
7
  export * from "./useSticky.js";
7
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"../../../src","sources":["react-utils/index.ts"],"names":[],"mappings":"AAAA,mCAAgC;AAChC,2BAAwB;AACxB,qCAAkC;AAClC,oCAAiC;AACjC,oCAAiC;AACjC,+BAA4B","sourcesContent":["export * from './ErrorBoundary';\nexport * from './hooks';\nexport * from './react-node-view';\nexport * from './useNodeEditing';\nexport * from './useNodeHovered';\nexport * from './useSticky';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"../../../src","sources":["react-utils/index.ts"],"names":[],"mappings":"AAAA,mCAAgC;AAChC,2BAAwB;AACxB,qCAAkC;AAClC,oCAAiC;AACjC,oCAAiC;AACjC,2CAAwC;AACxC,+BAA4B","sourcesContent":["export * from './ErrorBoundary';\nexport * from './hooks';\nexport * from './react-node-view';\nexport * from './useNodeEditing';\nexport * from './useNodeHovered';\nexport * from './useSharedEditingState';\nexport * from './useSticky';\n"]}
@@ -0,0 +1,5 @@
1
+ import type { EditorView } from "../pm/view.js";
2
+ import type { SharedStateKey } from "../extensions/behavior/SharedState/index.js";
3
+ export declare function useSharedEditingState(view: EditorView, key: SharedStateKey<{
4
+ editing: boolean;
5
+ }>): readonly [Boolean, () => void, () => void, () => void];
@@ -0,0 +1,22 @@
1
+ import { useLayoutEffect, useMemo, useState } from 'react';
2
+ import { useLatest } from 'react-use';
3
+ export function useSharedEditingState(view, key) {
4
+ const [value, setValue] = useState(false);
5
+ const valueRef = useLatest(value);
6
+ useLayoutEffect(() => {
7
+ setValue(key.getValue(view.state)?.editing || false);
8
+ return key.getNotifier(view.state).subscribe((data) => setValue(data?.editing || false));
9
+ }, [key, view]);
10
+ const { set, unset, toggle } = useMemo(() => {
11
+ const dispatch = (value) => {
12
+ view.dispatch(key.appendTransaction.update(view.state.tr, { editing: value }));
13
+ };
14
+ return {
15
+ set: () => dispatch(true),
16
+ unset: () => dispatch(false),
17
+ toggle: () => dispatch(!valueRef.current),
18
+ };
19
+ }, [key, view, valueRef]);
20
+ return [value, set, unset, toggle];
21
+ }
22
+ //# sourceMappingURL=useSharedEditingState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSharedEditingState.js","sourceRoot":"../../../src","sources":["react-utils/useSharedEditingState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAE,OAAO,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAC,SAAS,EAAC,MAAM,WAAW,CAAC;AAKpC,MAAM,UAAU,qBAAqB,CAAC,IAAgB,EAAE,GAAuC;IAC3F,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAElC,eAAe,CAAC,GAAG,EAAE;QACjB,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,OAAO,IAAI,KAAK,CAAC,CAAC;QACrD,OAAO,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC;IAC7F,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;IAEhB,MAAM,EAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAC,GAAG,OAAO,CAAC,GAAG,EAAE;QACtC,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAE,EAAE;YAChC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAC,OAAO,EAAE,KAAK,EAAC,CAAC,CAAC,CAAC;QACjF,CAAC,CAAC;QACF,OAAO;YACH,GAAG,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;YACzB,KAAK,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;YAC5B,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;SAC5C,CAAC;IACN,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IAE1B,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAU,CAAC;AAChD,CAAC","sourcesContent":["import {useLayoutEffect, useMemo, useState} from 'react';\n\nimport {useLatest} from 'react-use';\n\nimport type {EditorView} from '#pm/view';\nimport type {SharedStateKey} from 'src/extensions/behavior/SharedState';\n\nexport function useSharedEditingState(view: EditorView, key: SharedStateKey<{editing: boolean}>) {\n const [value, setValue] = useState<Boolean>(false);\n const valueRef = useLatest(value);\n\n useLayoutEffect(() => {\n setValue(key.getValue(view.state)?.editing || false);\n return key.getNotifier(view.state).subscribe((data) => setValue(data?.editing || false));\n }, [key, view]);\n\n const {set, unset, toggle} = useMemo(() => {\n const dispatch = (value: boolean) => {\n view.dispatch(key.appendTransaction.update(view.state.tr, {editing: value}));\n };\n return {\n set: () => dispatch(true),\n unset: () => dispatch(false),\n toggle: () => dispatch(!valueRef.current),\n };\n }, [key, view, valueRef]);\n\n return [value, set, unset, toggle] as const;\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import type { Node } from "../pm/model.js";
2
+ export type FindDescedantItem = {
3
+ node: Node;
4
+ pos: number;
5
+ index: number;
6
+ parent: Node | null;
7
+ };
8
+ export declare function findFirstDescedantNode(doc: Node, predicate: (node: Node) => boolean): FindDescedantItem | null;
@@ -0,0 +1,12 @@
1
+ export function findFirstDescedantNode(doc, predicate) {
2
+ let found = null;
3
+ doc.descendants((node, pos, parent, index) => {
4
+ if (found)
5
+ return false;
6
+ if (predicate(node))
7
+ found = { node, pos, parent, index };
8
+ return true;
9
+ });
10
+ return found;
11
+ }
12
+ //# sourceMappingURL=descedants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"descedants.js","sourceRoot":"../../../src","sources":["utils/descedants.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,sBAAsB,CAClC,GAAS,EACT,SAAkC;IAElC,IAAI,KAAK,GAA6B,IAAI,CAAC;IAE3C,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;QACzC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QAExB,IAAI,SAAS,CAAC,IAAI,CAAC;YAAE,KAAK,GAAG,EAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAC,CAAC;QAExD,OAAO,IAAI,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACjB,CAAC","sourcesContent":["import type {Node} from '#pm/model';\n\nexport type FindDescedantItem = {\n node: Node;\n pos: number;\n index: number;\n parent: Node | null;\n};\n\nexport function findFirstDescedantNode(\n doc: Node,\n predicate: (node: Node) => boolean,\n): FindDescedantItem | null {\n let found: FindDescedantItem | null = null;\n\n doc.descendants((node, pos, parent, index) => {\n if (found) return false;\n\n if (predicate(node)) found = {node, pos, parent, index};\n\n return true;\n });\n\n return found;\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import type { Node } from "../pm/model.js";
2
+ export declare const entityIdAttr = "data-entity-id";
3
+ export declare function generateEntityId(name?: string): string;
4
+ /**
5
+ * Returns true when entityId is not set, is set to default value, or is duplicated (other node already has this entityId)
6
+ */
7
+ export declare function isInvalidEntityId({ doc, node, defaultId, }: {
8
+ doc: Node;
9
+ node: Node;
10
+ defaultId: string;
11
+ }): boolean;
@@ -0,0 +1,16 @@
1
+ import { v4 as uuidv4 } from 'uuid';
2
+ import { findFirstDescedantNode } from "./descedants.js";
3
+ export const entityIdAttr = 'data-entity-id';
4
+ export function generateEntityId(name = 'entity') {
5
+ return name + '-' + uuidv4();
6
+ }
7
+ /**
8
+ * Returns true when entityId is not set, is set to default value, or is duplicated (other node already has this entityId)
9
+ */
10
+ export function isInvalidEntityId({ doc, node, defaultId, }) {
11
+ const entityId = node.attrs[entityIdAttr];
12
+ if (!entityId || entityId === defaultId)
13
+ return true;
14
+ return Boolean(findFirstDescedantNode(doc, (dNode) => node !== dNode && dNode.attrs[entityIdAttr] === entityId));
15
+ }
16
+ //# sourceMappingURL=entity-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-id.js","sourceRoot":"../../../src","sources":["utils/entity-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,EAAE,IAAI,MAAM,EAAC,MAAM,MAAM,CAAC;AAIlC,OAAO,EAAC,sBAAsB,EAAC,wBAAqB;AAEpD,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAC;AAE7C,MAAM,UAAU,gBAAgB,CAAC,IAAI,GAAG,QAAQ;IAC5C,OAAO,IAAI,GAAG,GAAG,GAAG,MAAM,EAAE,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAC9B,GAAG,EACH,IAAI,EACJ,SAAS,GAKZ;IACG,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAE1C,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAErD,OAAO,OAAO,CACV,sBAAsB,CAClB,GAAG,EACH,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,KAAK,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,QAAQ,CACtE,CACJ,CAAC;AACN,CAAC","sourcesContent":["import {v4 as uuidv4} from 'uuid';\n\nimport type {Node} from '#pm/model';\n\nimport {findFirstDescedantNode} from './descedants';\n\nexport const entityIdAttr = 'data-entity-id';\n\nexport function generateEntityId(name = 'entity'): string {\n return name + '-' + uuidv4();\n}\n\n/**\n * Returns true when entityId is not set, is set to default value, or is duplicated (other node already has this entityId)\n */\nexport function isInvalidEntityId({\n doc,\n node,\n defaultId,\n}: {\n doc: Node;\n node: Node;\n defaultId: string;\n}): boolean {\n const entityId = node.attrs[entityIdAttr];\n\n if (!entityId || entityId === defaultId) return true;\n\n return Boolean(\n findFirstDescedantNode(\n doc,\n (dNode) => node !== dNode && dNode.attrs[entityIdAttr] === entityId,\n ),\n );\n}\n"]}
@@ -2,7 +2,9 @@ export * from "./actions.js";
2
2
  export * from "./autocomplete-popup.js";
3
3
  export * from "./carousel/index.js";
4
4
  export * from "./clipboard.js";
5
+ export * from "./descedants.js";
5
6
  export * from "./ecapeRegexp.js";
7
+ export * from "./entity-id.js";
6
8
  export * from "./event-emitter.js";
7
9
  export * from "./helpers.js";
8
10
  export * from "./inputrules.js";
@@ -2,7 +2,9 @@ export * from "./actions.js";
2
2
  export * from "./autocomplete-popup.js";
3
3
  export * from "./carousel/index.js";
4
4
  export * from "./clipboard.js";
5
+ export * from "./descedants.js";
5
6
  export * from "./ecapeRegexp.js";
7
+ export * from "./entity-id.js";
6
8
  export * from "./event-emitter.js";
7
9
  export * from "./helpers.js";
8
10
  export * from "./inputrules.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"../../../src","sources":["utils/index.ts"],"names":[],"mappings":"AAAA,6BAA0B;AAC1B,wCAAqC;AACrC,oCAA2B;AAC3B,+BAA4B;AAC5B,iCAA8B;AAC9B,mCAAgC;AAChC,6BAA0B;AAC1B,gCAA6B;AAC7B,4BAAyB;AACzB,2BAAwB;AACxB,mCAAgC;AAChC,2BAAwB;AACxB,iCAA8B;AAC9B,8BAA2B;AAC3B,iCAA8B;AAC9B,4BAAyB;AACzB,+BAA4B;AAC5B,6CAA0C;AAC1C,iCAA8B;AAC9B,4BAAyB;AACzB,2CAAwC","sourcesContent":["export * from './actions';\nexport * from './autocomplete-popup';\nexport * from './carousel';\nexport * from './clipboard';\nexport * from './ecapeRegexp';\nexport * from './event-emitter';\nexport * from './helpers';\nexport * from './inputrules';\nexport * from './keymap';\nexport * from './marks';\nexport * from './node-children';\nexport * from './nodes';\nexport * from './placeholder';\nexport * from './platform';\nexport * from './remove-node';\nexport * from './schema';\nexport * from './selection';\nexport * from './serialize-for-clipboard';\nexport * from './sync-scroll';\nexport * from './upload';\nexport * from './get-proportional-size';\nexport type {DirectiveSyntaxValue, DirectiveSyntaxOption} from './directive';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"../../../src","sources":["utils/index.ts"],"names":[],"mappings":"AAAA,6BAA0B;AAC1B,wCAAqC;AACrC,oCAA2B;AAC3B,+BAA4B;AAC5B,gCAA6B;AAC7B,iCAA8B;AAC9B,+BAA4B;AAC5B,mCAAgC;AAChC,6BAA0B;AAC1B,gCAA6B;AAC7B,4BAAyB;AACzB,2BAAwB;AACxB,mCAAgC;AAChC,2BAAwB;AACxB,iCAA8B;AAC9B,8BAA2B;AAC3B,iCAA8B;AAC9B,4BAAyB;AACzB,+BAA4B;AAC5B,6CAA0C;AAC1C,iCAA8B;AAC9B,4BAAyB;AACzB,2CAAwC","sourcesContent":["export * from './actions';\nexport * from './autocomplete-popup';\nexport * from './carousel';\nexport * from './clipboard';\nexport * from './descedants';\nexport * from './ecapeRegexp';\nexport * from './entity-id';\nexport * from './event-emitter';\nexport * from './helpers';\nexport * from './inputrules';\nexport * from './keymap';\nexport * from './marks';\nexport * from './node-children';\nexport * from './nodes';\nexport * from './placeholder';\nexport * from './platform';\nexport * from './remove-node';\nexport * from './schema';\nexport * from './selection';\nexport * from './serialize-for-clipboard';\nexport * from './sync-scroll';\nexport * from './upload';\nexport * from './get-proportional-size';\nexport type {DirectiveSyntaxValue, DirectiveSyntaxOption} from './directive';\n"]}
@@ -1,3 +1,3 @@
1
1
  /** During build process, the current version will be injected here */
2
- export const VERSION = typeof '15.3.0' !== 'undefined' ? '15.3.0' : 'unknown';
2
+ export const VERSION = typeof '15.4.0' !== 'undefined' ? '15.4.0' : 'unknown';
3
3
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"../../src","sources":["version.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,WAAW,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC","sourcesContent":["/** During build process, the current version will be injected here */\nexport const VERSION = typeof '15.3.0' !== 'undefined' ? '15.3.0' : 'unknown';\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"../../src","sources":["version.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,WAAW,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC","sourcesContent":["/** During build process, the current version will be injected here */\nexport const VERSION = typeof '15.4.0' !== 'undefined' ? '15.4.0' : 'unknown';\n"]}
@@ -1,4 +1,5 @@
1
1
  import { type ComponentType, type RefAttributes } from 'react';
2
+ import type { HTMLRuntimeConfig } from '@diplodoc/html-extension';
2
3
  import type { IHTMLIFrameElementConfig } from '@diplodoc/html-extension/runtime';
3
4
  import type { PluginRuntime, TransformMeta } from "../withMermaid/types.js";
4
5
  export type WithYfmHtmlBlockOptions = {
@@ -7,6 +8,7 @@ export type WithYfmHtmlBlockOptions = {
7
8
  export type WithYfmHtmlBlockProps = {
8
9
  meta: TransformMeta;
9
10
  yfmHtmlBlockConfig?: IHTMLIFrameElementConfig;
11
+ htmlRuntimeConfig?: HTMLRuntimeConfig;
10
12
  };
11
13
  export declare function withYfmHtmlBlock(opts: WithYfmHtmlBlockOptions): <T extends {
12
14
  html: string;
@@ -4,8 +4,8 @@ import { useDiplodocEmbeddedContentController } from '@diplodoc/html-extension/r
4
4
  import { useYfmHtmlBlockRuntime } from "./useYfmHtmlBlockRuntime.js";
5
5
  export function withYfmHtmlBlock(opts) {
6
6
  return (Component) => forwardRef(function WithYfmHtml(props, ref) {
7
- const { meta, html, yfmHtmlBlockConfig } = props;
8
- useYfmHtmlBlockRuntime(meta, opts.runtime);
7
+ const { meta, html, yfmHtmlBlockConfig, htmlRuntimeConfig } = props;
8
+ useYfmHtmlBlockRuntime(meta, opts.runtime, htmlRuntimeConfig);
9
9
  const yfmHtmlBlock = useDiplodocEmbeddedContentController();
10
10
  useEffect(() => {
11
11
  if (yfmHtmlBlock) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["view/hocs/withYfmHtml/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAyC,UAAU,EAAE,SAAS,EAAC,MAAM,OAAO,CAAC;AAEpF,OAAO,EAAC,oCAAoC,EAAC,MAAM,gCAAgC,CAAC;AAKpF,OAAO,EAAC,sBAAsB,EAAC,oCAAiC;AAWhE,MAAM,UAAU,gBAAgB,CAAC,IAA6B;IAC1D,OAAO,CACH,SAA2D,EAC7D,EAAE,CACA,UAAU,CAA4C,SAAS,WAAW,CAAC,KAAK,EAAE,GAAG;QACjF,MAAM,EAAC,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAC,GAAG,KAAK,CAAC;QAE/C,sBAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAE3C,MAAM,YAAY,GAAG,oCAAoC,EAAE,CAAC;QAE5D,SAAS,CAAC,GAAG,EAAE;YACX,IAAI,YAAY,EAAE,CAAC;gBACf,IAAI,kBAAkB,EAAE,CAAC;oBACrB,YAAY,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;gBAC/C,CAAC;gBACD,YAAY,CAAC,UAAU,EAAE,CAAC;YAC9B,CAAC;QACL,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC;QAE7C,OAAO,KAAC,SAAS,OAAK,KAAK,EAAE,GAAG,EAAE,GAAG,GAAI,CAAC;IAC9C,CAAC,CAAC,CAAC;AACX,CAAC","sourcesContent":["import {type ComponentType, type RefAttributes, forwardRef, useEffect} from 'react';\n\nimport {useDiplodocEmbeddedContentController} from '@diplodoc/html-extension/react';\nimport type {IHTMLIFrameElementConfig} from '@diplodoc/html-extension/runtime';\n\nimport type {PluginRuntime, TransformMeta} from '../withMermaid/types';\n\nimport {useYfmHtmlBlockRuntime} from './useYfmHtmlBlockRuntime';\n\nexport type WithYfmHtmlBlockOptions = {\n runtime: PluginRuntime;\n};\n\nexport type WithYfmHtmlBlockProps = {\n meta: TransformMeta;\n yfmHtmlBlockConfig?: IHTMLIFrameElementConfig;\n};\n\nexport function withYfmHtmlBlock(opts: WithYfmHtmlBlockOptions) {\n return <T extends {html: string}>(\n Component: ComponentType<T & RefAttributes<HTMLDivElement>>,\n ) =>\n forwardRef<HTMLDivElement, T & WithYfmHtmlBlockProps>(function WithYfmHtml(props, ref) {\n const {meta, html, yfmHtmlBlockConfig} = props;\n\n useYfmHtmlBlockRuntime(meta, opts.runtime);\n\n const yfmHtmlBlock = useDiplodocEmbeddedContentController();\n\n useEffect(() => {\n if (yfmHtmlBlock) {\n if (yfmHtmlBlockConfig) {\n yfmHtmlBlock.setConfig(yfmHtmlBlockConfig);\n }\n yfmHtmlBlock.initialize();\n }\n }, [yfmHtmlBlock, html, yfmHtmlBlockConfig]);\n\n return <Component {...props} ref={ref} />;\n });\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["view/hocs/withYfmHtml/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAyC,UAAU,EAAE,SAAS,EAAC,MAAM,OAAO,CAAC;AAGpF,OAAO,EAAC,oCAAoC,EAAC,MAAM,gCAAgC,CAAC;AAKpF,OAAO,EAAC,sBAAsB,EAAC,oCAAiC;AAYhE,MAAM,UAAU,gBAAgB,CAAC,IAA6B;IAC1D,OAAO,CACH,SAA2D,EAC7D,EAAE,CACA,UAAU,CAA4C,SAAS,WAAW,CAAC,KAAK,EAAE,GAAG;QACjF,MAAM,EAAC,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,iBAAiB,EAAC,GAAG,KAAK,CAAC;QAElE,sBAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;QAE9D,MAAM,YAAY,GAAG,oCAAoC,EAAE,CAAC;QAE5D,SAAS,CAAC,GAAG,EAAE;YACX,IAAI,YAAY,EAAE,CAAC;gBACf,IAAI,kBAAkB,EAAE,CAAC;oBACrB,YAAY,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;gBAC/C,CAAC;gBACD,YAAY,CAAC,UAAU,EAAE,CAAC;YAC9B,CAAC;QACL,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC;QAE7C,OAAO,KAAC,SAAS,OAAK,KAAK,EAAE,GAAG,EAAE,GAAG,GAAI,CAAC;IAC9C,CAAC,CAAC,CAAC;AACX,CAAC","sourcesContent":["import {type ComponentType, type RefAttributes, forwardRef, useEffect} from 'react';\n\nimport type {HTMLRuntimeConfig} from '@diplodoc/html-extension';\nimport {useDiplodocEmbeddedContentController} from '@diplodoc/html-extension/react';\nimport type {IHTMLIFrameElementConfig} from '@diplodoc/html-extension/runtime';\n\nimport type {PluginRuntime, TransformMeta} from '../withMermaid/types';\n\nimport {useYfmHtmlBlockRuntime} from './useYfmHtmlBlockRuntime';\n\nexport type WithYfmHtmlBlockOptions = {\n runtime: PluginRuntime;\n};\n\nexport type WithYfmHtmlBlockProps = {\n meta: TransformMeta;\n yfmHtmlBlockConfig?: IHTMLIFrameElementConfig;\n htmlRuntimeConfig?: HTMLRuntimeConfig;\n};\n\nexport function withYfmHtmlBlock(opts: WithYfmHtmlBlockOptions) {\n return <T extends {html: string}>(\n Component: ComponentType<T & RefAttributes<HTMLDivElement>>,\n ) =>\n forwardRef<HTMLDivElement, T & WithYfmHtmlBlockProps>(function WithYfmHtml(props, ref) {\n const {meta, html, yfmHtmlBlockConfig, htmlRuntimeConfig} = props;\n\n useYfmHtmlBlockRuntime(meta, opts.runtime, htmlRuntimeConfig);\n\n const yfmHtmlBlock = useDiplodocEmbeddedContentController();\n\n useEffect(() => {\n if (yfmHtmlBlock) {\n if (yfmHtmlBlockConfig) {\n yfmHtmlBlock.setConfig(yfmHtmlBlockConfig);\n }\n yfmHtmlBlock.initialize();\n }\n }, [yfmHtmlBlock, html, yfmHtmlBlockConfig]);\n\n return <Component {...props} ref={ref} />;\n });\n}\n"]}
@@ -1,6 +1,8 @@
1
+ import { setupRuntimeConfig } from '@diplodoc/html-extension/utils';
1
2
  /** @internal */
2
- export function useYfmHtmlBlockRuntime(meta, runtime = '_assets/html-extension.js') {
3
+ export function useYfmHtmlBlockRuntime(meta, runtime = '_assets/html-extension.js', htmlRuntimeConfig = {}) {
3
4
  if (meta?.script?.includes(runtime)) {
5
+ setupRuntimeConfig(htmlRuntimeConfig);
4
6
  import(/* webpackChunkName: "yfm-html-runtime" */ '@diplodoc/html-extension/runtime');
5
7
  }
6
8
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useYfmHtmlBlockRuntime.js","sourceRoot":"../../../../../src","sources":["view/hocs/withYfmHtml/useYfmHtmlBlockRuntime.ts"],"names":[],"mappings":"AAEA,gBAAgB;AAChB,MAAM,UAAU,sBAAsB,CAClC,IAAmB,EACnB,UAAyB,2BAA2B;IAEpD,IAAI,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAClC,MAAM,CAAC,0CAA0C,CAAC,kCAAkC,CAAC,CAAC;IAC1F,CAAC;AACL,CAAC","sourcesContent":["import type {PluginRuntime, TransformMeta} from './types';\n\n/** @internal */\nexport function useYfmHtmlBlockRuntime(\n meta: TransformMeta,\n runtime: PluginRuntime = '_assets/html-extension.js',\n) {\n if (meta?.script?.includes(runtime)) {\n import(/* webpackChunkName: \"yfm-html-runtime\" */ '@diplodoc/html-extension/runtime');\n }\n}\n"]}
1
+ {"version":3,"file":"useYfmHtmlBlockRuntime.js","sourceRoot":"../../../../../src","sources":["view/hocs/withYfmHtml/useYfmHtmlBlockRuntime.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,kBAAkB,EAAC,MAAM,gCAAgC,CAAC;AAIlE,gBAAgB;AAChB,MAAM,UAAU,sBAAsB,CAClC,IAAmB,EACnB,UAAyB,2BAA2B,EACpD,oBAAuC,EAAE;IAEzC,IAAI,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAClC,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;QACtC,MAAM,CAAC,0CAA0C,CAAC,kCAAkC,CAAC,CAAC;IAC1F,CAAC;AACL,CAAC","sourcesContent":["import type {HTMLRuntimeConfig} from '@diplodoc/html-extension';\nimport {setupRuntimeConfig} from '@diplodoc/html-extension/utils';\n\nimport type {PluginRuntime, TransformMeta} from './types';\n\n/** @internal */\nexport function useYfmHtmlBlockRuntime(\n meta: TransformMeta,\n runtime: PluginRuntime = '_assets/html-extension.js',\n htmlRuntimeConfig: HTMLRuntimeConfig = {},\n) {\n if (meta?.script?.includes(runtime)) {\n setupRuntimeConfig(htmlRuntimeConfig);\n import(/* webpackChunkName: \"yfm-html-runtime\" */ '@diplodoc/html-extension/runtime');\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/markdown-editor",
3
- "version": "15.3.0",
3
+ "version": "15.4.0",
4
4
  "description": "Markdown wysiwyg and markup editor",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -210,7 +210,7 @@
210
210
  "devDependencies": {
211
211
  "@diplodoc/cut-extension": "^0.6.1",
212
212
  "@diplodoc/folding-headings-extension": "0.1.0",
213
- "@diplodoc/html-extension": "^2.5.0",
213
+ "@diplodoc/html-extension": "2.7.1",
214
214
  "@diplodoc/latex-extension": "1.0.3",
215
215
  "@diplodoc/mermaid-extension": "1.2.1",
216
216
  "@diplodoc/tabs-extension": "^3.5.1",
@@ -295,8 +295,8 @@
295
295
  },
296
296
  "peerDependencies": {
297
297
  "@diplodoc/cut-extension": "^0.5.0 || ^0.6.1 || ^0.7.1",
298
- "@diplodoc/folding-headings-extension": "^0.1.0",
299
298
  "@diplodoc/file-extension": "^0.2.1",
299
+ "@diplodoc/folding-headings-extension": "^0.1.0",
300
300
  "@diplodoc/html-extension": "^2.3.2",
301
301
  "@diplodoc/latex-extension": "^1.0.3",
302
302
  "@diplodoc/mermaid-extension": "^1.0.0",