@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
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MarkdownSerializerState = exports.MarkdownSerializer = void 0;
4
+ const blankMark = { open: '', close: '', mixable: false };
4
5
  class MarkdownSerializer {
5
6
  nodes;
6
7
  marks;
@@ -73,6 +74,7 @@ class MarkdownSerializerState {
73
74
  inTightList;
74
75
  noAutoBlank;
75
76
  isAutolink;
77
+ atBlockStart;
76
78
  escapeWhitespace;
77
79
  escapeCharacters;
78
80
  nodes;
@@ -89,6 +91,7 @@ class MarkdownSerializerState {
89
91
  this.inTightList = false;
90
92
  this.noAutoBlank = false;
91
93
  this.isAutolink = undefined;
94
+ this.atBlockStart = false;
92
95
  this.escapeWhitespace = false;
93
96
  // :: Object
94
97
  // The options passed to the serializer.
@@ -173,11 +176,13 @@ class MarkdownSerializerState {
173
176
  text(text, escape) {
174
177
  const lines = text.split('\n');
175
178
  for (let i = 0; i < lines.length; i++) {
176
- const startOfLine = this.atBlank() || this.closed;
177
179
  this.write();
180
+ // Escape ! before [ to prevent being parsed as image syntax
181
+ if (escape === false && lines[i][0] === '[' && /(^|[^\\])!$/.test(this.out))
182
+ this.out = this.out.slice(0, this.out.length - 1) + '\\!';
178
183
  let text = lines[i];
179
184
  if (escape !== false && this.options.escape !== false)
180
- text = this.esc(text, startOfLine);
185
+ text = this.esc(text, this.atBlockStart);
181
186
  if (this.escapeWhitespace)
182
187
  text = this.escWhitespace(text);
183
188
  this.out += text;
@@ -191,15 +196,27 @@ class MarkdownSerializerState {
191
196
  if (typeof parent === 'number') {
192
197
  throw new Error('!');
193
198
  }
194
- if (!this.nodes[node.type.name]) {
195
- throw new Error('Token type `' + node.type.name + '` not supported by Markdown renderer');
196
- }
197
199
  const callback = this.nodes[node.type.name];
198
- if (this.dynamicModifier) {
199
- this.dynamicModifier.processNode(this, node, parent, index, callback);
200
+ if (callback) {
201
+ if (this.dynamicModifier) {
202
+ this.dynamicModifier.processNode(this, node, parent, index, callback);
203
+ }
204
+ else {
205
+ callback(this, node, parent, index);
206
+ }
200
207
  }
201
208
  else {
202
- callback(this, node, parent, index);
209
+ if (this.options.strict !== false) {
210
+ throw new Error('Token type `' + node.type.name + '` not supported by Markdown renderer');
211
+ }
212
+ else if (!node.type.isLeaf) {
213
+ if (node.type.inlineContent)
214
+ this.renderInline(node);
215
+ else
216
+ this.renderContent(node);
217
+ if (node.isBlock)
218
+ this.closeBlock(node);
219
+ }
203
220
  }
204
221
  }
205
222
  // :: (Node)
@@ -207,9 +224,9 @@ class MarkdownSerializerState {
207
224
  renderContent(parent) {
208
225
  parent.forEach((node, _, i) => this.render(node, parent, i));
209
226
  }
210
- // :: (Node)
211
227
  // Render the contents of `parent` as inline content.
212
- renderInline(parent) {
228
+ renderInline(parent, fromBlockStart = true) {
229
+ this.atBlockStart = fromBlockStart;
213
230
  const active = [];
214
231
  let trailing = '';
215
232
  const progress = (node, _, index) => {
@@ -221,7 +238,7 @@ class MarkdownSerializerState {
221
238
  marks = marks.filter((m) => {
222
239
  if (index === 0)
223
240
  return false;
224
- if (index + 1 == parent.childCount)
241
+ if (index + 1 === parent.childCount)
225
242
  return false;
226
243
  const prev = parent.child(index - 1);
227
244
  const next = parent.child(index + 1);
@@ -234,20 +251,31 @@ class MarkdownSerializerState {
234
251
  // If whitespace has to be expelled from the node, adjust
235
252
  // leading and trailing accordingly.
236
253
  if (node && node.isText && marks.some((mark) => {
237
- const info = this.marks[mark.type.name];
238
- return info && info.expelEnclosingWhitespace;
254
+ const info = this.getMark(mark.type.name);
255
+ return info && info.expelEnclosingWhitespace && !mark.isInSet(active);
239
256
  })) {
240
- const [_, lead, inner, trail] = /^(\s*)(.*?)(\s*)$/m.exec(node.text ?? '');
241
- leading += lead;
242
- trailing = trail;
243
- if (lead || trail) {
244
- node = inner ? node.withText(inner) : null;
257
+ const [_, lead, rest] = /^(\s*)(.*)$/m.exec(node.text);
258
+ if (lead) {
259
+ leading += lead;
260
+ node = rest ? node.withText(rest) : null;
261
+ if (!node)
262
+ marks = active;
263
+ }
264
+ }
265
+ if (node && node.isText && marks.some((mark) => {
266
+ const info = this.getMark(mark.type.name);
267
+ return info && info.expelEnclosingWhitespace && !this.isMarkAhead(parent, index + 1, mark);
268
+ })) {
269
+ const [_, rest, trail] = /^(.*?)(\s*)$/m.exec(node.text);
270
+ if (trail) {
271
+ trailing = trail;
272
+ node = rest ? node.withText(rest) : null;
245
273
  if (!node)
246
274
  marks = active;
247
275
  }
248
276
  }
249
277
  const inner = marks.length && marks[marks.length - 1];
250
- const noEsc = inner && this.marks[inner.type.name].escape === false;
278
+ const noEsc = inner && this.getMark(inner.type.name).escape === false;
251
279
  const len = marks.length - (noEsc ? 1 : 0);
252
280
  // Try to reorder 'mixable' marks, such as em and strong, which
253
281
  // in Markdown may be opened and closed in different order, so
@@ -256,11 +284,11 @@ class MarkdownSerializerState {
256
284
  // eslint-disable-next-line no-labels
257
285
  outer: for (let i = 0; i < len; i++) {
258
286
  const mark = marks[i];
259
- if (!this.marks[mark.type.name].mixable)
287
+ if (!this.getMark(mark.type.name).mixable)
260
288
  break;
261
289
  for (let j = 0; j < active.length; j++) {
262
290
  const other = active[j];
263
- if (!this.marks[other.type.name].mixable)
291
+ if (!this.getMark(other.type.name).mixable)
264
292
  break;
265
293
  if (mark.eq(other)) {
266
294
  if (i > j) {
@@ -291,6 +319,7 @@ class MarkdownSerializerState {
291
319
  const add = marks[active.length];
292
320
  active.push(add);
293
321
  this.text(this.markString(add, true, parent, index), false);
322
+ this.atBlockStart = false;
294
323
  }
295
324
  // Render the node. Special case code marks, since their content
296
325
  // may not be escaped.
@@ -301,10 +330,21 @@ class MarkdownSerializerState {
301
330
  else {
302
331
  this.render(node, parent, index);
303
332
  }
333
+ this.atBlockStart = false;
334
+ }
335
+ // After the first non-empty text node is rendered, the end of output
336
+ // is no longer at block start.
337
+ //
338
+ // FIXME: If a non-text node writes something to the output for this
339
+ // block, the end of output is also no longer at block start. But how
340
+ // can we detect that?
341
+ if (node?.isText && node.nodeSize > 0) {
342
+ this.atBlockStart = false;
304
343
  }
305
344
  };
306
345
  parent.forEach(progress);
307
346
  progress(null, null, parent.childCount);
347
+ this.atBlockStart = false;
308
348
  }
309
349
  // :: (Node, string, (number) → string)
310
350
  // Render a node's content as a list. `delim` should be the extra
@@ -334,13 +374,17 @@ class MarkdownSerializerState {
334
374
  // have special meaning only at the start of the line.
335
375
  esc(str, startOfLine = false) {
336
376
  // eslint-disable-next-line no-useless-escape
337
- const defaultEsc = /[`\^+*\\\|~\[\]\{\}<>\$_]/g;
377
+ const defaultEsc = /[`\^+*\\\|~\[\]\{\}<>\$]/g;
338
378
  const extraChars = this.escapeCharacters?.length ? this.escapeCharacters.map(c => '\\' + c).join('') : '';
339
379
  const escRegexp = this.options?.commonEscape ||
340
380
  // Compose the escape regexp from default, options, and extra characters
341
381
  new RegExp(defaultEsc.source + (extraChars ? `|[${extraChars}]` : ''), 'g');
342
382
  const startOfLineEscRegexp = this.options?.startOfLineEscape || /^[:#\-*+>]/;
343
383
  str = str.replace(escRegexp, '\\$&');
384
+ // Smart underscore: don't escape _ between word characters (e.g. foo_bar)
385
+ str = str.replace(/_/g, (m, i) => i > 0 && i + 1 < str.length && /\w/.test(str[i - 1]) && /\w/.test(str[i + 1])
386
+ ? m
387
+ : '\\' + m);
344
388
  if (startOfLine)
345
389
  str = str.replace(startOfLineEscRegexp, '\\$&').replace(/^(\s*\d+)\./, '$1\\.');
346
390
  return str;
@@ -364,7 +408,7 @@ class MarkdownSerializerState {
364
408
  // :: (Mark, bool, string?) → string
365
409
  // Get the markdown string for a given opening or closing mark.
366
410
  markString(mark, open, parent, index) {
367
- const info = this.marks[mark.type.name];
411
+ const info = this.getMark(mark.type.name);
368
412
  const value = open ? info.open : info.close;
369
413
  return typeof value === 'string' ? value : value(this, mark, parent, index);
370
414
  }
@@ -378,6 +422,25 @@ class MarkdownSerializerState {
378
422
  trailing: (text.match(/(\s+)$/) || [])[0],
379
423
  };
380
424
  }
425
+ isMarkAhead(parent, index, mark) {
426
+ for (;; index++) {
427
+ if (index >= parent.childCount)
428
+ return false;
429
+ const next = parent.child(index);
430
+ if (!next.type.spec.isBreak)
431
+ return !!mark.isInSet(next.marks);
432
+ }
433
+ }
434
+ // Get mark info by name, with fallback to blankMark when strict mode is off.
435
+ getMark(name) {
436
+ const info = this.marks[name];
437
+ if (!info) {
438
+ if (this.options.strict !== false)
439
+ throw new Error(`Mark type \`${name}\` not supported by Markdown renderer`);
440
+ return blankMark;
441
+ }
442
+ return info;
443
+ }
381
444
  }
382
445
  exports.MarkdownSerializerState = MarkdownSerializerState;
383
446
  //# sourceMappingURL=MarkdownSerializer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownSerializer.js","sourceRoot":"../../../../src","sources":["core/markdown/MarkdownSerializer.ts"],"names":[],"mappings":";;;AAyCA,MAAa,kBAAkB;IACV,KAAK,CAAU;IACf,KAAK,CAAU;IACf,eAAe,CAAqC;IAErE,iGAAiG;IACjG,mEAAmE;IACnE,kEAAkE;IAClE,mEAAmE;IACnE,EAAE;IACF,iEAAiE;IACjE,mEAAmE;IACnE,iEAAiE;IACjE,mEAAmE;IACnE,kEAAkE;IAClE,YAAY;IACZ,EAAE;IACF,mDAAmD;IACnD,iDAAiD;IACjD,EAAE;IACF,6DAA6D;IAC7D,4CAA4C;IAC5C,EAAE;IACF,8DAA8D;IAC9D,mEAAmE;IACnE,+DAA+D;IAC/D,iEAAiE;IACjE,uCAAuC;IACvC,EAAE;IACF,8DAA8D;IAC9D,oEAAoE;IACpE,kDAAkD;IAClD,EAAE;IACF,0DAA0D;IAC1D,mEAAmE;IACnE,6DAA6D;IAC7D,kEAAkE;IAClE,2DAA2D;IAC3D,YACI,KAAc,EACd,KAAc,EACd,eAAmD;QAEnD,iEAAiE;QACjE,iCAAiC;QACjC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,sCAAsC;QACtC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QAEnB,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;IAC3C,CAAC;IAED,8BAA8B;IAC9B,6CAA6C;IAC7C,wCAAwC;IACxC,SAAS,CAAC,OAAa,EAAE,UAAsC,EAAE;QAC7D,MAAM,KAAK,GAAG,IAAI,uBAAuB,CACrC,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,KAAK,EACV,OAAO,EACP,IAAI,CAAC,eAAe,CACvB,CAAC;QACF,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC7B,OAAO,KAAK,CAAC,GAAG,CAAC;IACrB,CAAC;IAED,mDAAmD;IACnD,YAAY,CAAC,QAAgB;QACzB,OAAO,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC;IAClC,CAAC;IAED,mDAAmD;IACnD,YAAY,CAAC,QAAgB;QACzB,OAAO,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC;IAClC,CAAC;CACJ;AA3ED,gDA2EC;AAED,uDAAuD;AACvD,qEAAqE;AACrE,0DAA0D;AAC1D,kBAAkB;AAClB,MAAa,uBAAuB;IAChC,GAAG,CAAS;IACZ,WAAW,CAAU;IACrB,WAAW,CAAU;IACrB,UAAU,CAAsB;IAChC,gBAAgB,CAAU;IAC1B,gBAAgB,CAAY;IAEX,KAAK,CAAU;IACf,KAAK,CAAU;IACf,OAAO,CAAoB;IACpC,KAAK,CAAS;IACd,MAAM,CAAe;IACZ,eAAe,CAAqC;IAErE,YAAY,KAAc,EAAE,KAAc,EAAE,UAAsC,EAAE,EAAE,eAAmD;QACrI,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAC9B,YAAY;QACZ,wCAAwC;QACxC,uBAAuB;QACvB,qEAAqE;QACrE,iEAAiE;QACjE,uBAAuB;QACvB,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,KAAK,WAAW,EAAE,CAAC;YAAC,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,KAAK,CAAA;QAAC,CAAC;IAC3F,CAAC;IAED,cAAc;QACV,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED,gBAAgB;QACZ,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC7B,CAAC;IAED,UAAU,CAAC,IAAoB;QAC3B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW;gBAAE,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC;YAC3D,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS;gBAAE,IAAI,GAAG,CAAC,CAAC;YAClD,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;gBACX,IAAI,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC;gBAC1B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACnC,IAAI,IAAI;oBAAE,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;gBAEzE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;oBACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;wBAAC,IAAI,CAAC,GAAG,IAAI,QAAQ,GAAG,IAAI,CAAA;oBAAC,CAAC;gBAClE,CAAC;YACL,CAAC;YACD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACxB,CAAC;IACL,CAAC;IAED,iCAAiC;IACjC,kEAAkE;IAClE,oEAAoE;IACpE,+DAA+D;IAC/D,wBAAwB;IACxB,SAAS,CAAC,KAAa,EAAE,UAAyB,EAAE,IAAU,EAAE,CAAa;QACzE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC;QACvB,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,CAAC;QAChC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC;QACpB,CAAC,EAAE,CAAC;QACJ,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC;QACjB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO;QACH,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IAED,QAAQ;IACR,kDAAkD;IAClD,aAAa;QACT,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAAE,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC;IAC1C,CAAC;IAED,eAAe;IACf,mEAAmE;IACnE,iEAAiE;IACjE,6BAA6B;IAC7B,KAAK,CAAC,OAAuB;QACzB,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YAAC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAA;QAAC,CAAC;QAC5D,IAAI,OAAO;YAAE,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC;IACrC,CAAC;IAED,YAAY;IACZ,sCAAsC;IACtC,UAAU,CAAC,IAAW;QAClB,IAAI,CAAC,MAAM,GAAG,IAAI,IAAI,KAAK,CAAC;IAChC,CAAC;IAED,qBAAqB;IACrB,kEAAkE;IAClE,sBAAsB;IACtB,IAAI,CAAC,IAAY,EAAE,MAAgB;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC;YAClD,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,IAAI,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,MAAM,KAAK,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,KAAK;gBAAE,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,WAAkB,CAAC,CAAA;YAChG,IAAI,IAAI,CAAC,gBAAgB;gBAAE,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAC3D,IAAI,CAAC,GAAG,IAAI,IAAI,CAAA;YAChB,IAAI,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC;QAChD,CAAC;IACL,CAAC;IAED,YAAY;IACZ,oCAAoC;IACpC,MAAM,CAAC,IAAU,EAAE,MAAY,EAAE,KAAa;QAC1C,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,sCAAsC,CAAC,CAAC;QAC9F,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC1E,CAAC;aAAM,CAAC;YACJ,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QACxC,CAAC;IACL,CAAC;IAED,YAAY;IACZ,kDAAkD;IAClD,aAAa,CAAC,MAAY;QACtB,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,YAAY;IACZ,qDAAqD;IACrD,YAAY,CAAC,MAAY;QACrB,MAAM,MAAM,GAAW,EAAE,CAAC;QAAC,IACvB,QAAQ,GAAG,EAAE,CAAC;QAClB,MAAM,QAAQ,GAAG,CAAC,IAAiB,EAAE,CAAM,EAAE,KAAa,EAAE,EAAE;YAC1D,IAAI,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YAEnC,oFAAoF;YACpF,6DAA6D;YAC7D,yCAAyC;YACzC,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE;oBAC5B,IAAI,KAAK,KAAK,CAAC;wBAAE,OAAO,KAAK,CAAC;oBAC9B,IAAI,KAAK,GAAG,CAAC,IAAI,MAAM,CAAC,UAAU;wBAAE,OAAO,KAAK,CAAC;oBACjD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;oBACrC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;oBACrC,OAAO,CACH,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;wBACvE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CAC1E,CAAC;gBACN,CAAC,CAAC,CAAC;YACP,CAAC;YAED,IAAI,OAAO,GAAG,QAAQ,CAAC;YACvB,QAAQ,GAAG,EAAE,CAAC;YACd,yDAAyD;YACzD,oCAAoC;YACpC,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAS,EAAE,EAAE;gBAChD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACxC,OAAO,IAAI,IAAI,IAAI,CAAC,wBAAwB,CAAC;YACjD,CAAC,CAAC,EAAE,CAAC;gBACD,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAE,CAAC;gBAC5E,OAAO,IAAI,IAAI,CAAC;gBAChB,QAAQ,GAAG,KAAK,CAAC;gBACjB,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;oBAChB,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,IAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;oBACpD,IAAI,CAAC,IAAI;wBAAE,KAAK,GAAG,MAAM,CAAC;gBAC9B,CAAC;YACL,CAAC;YAED,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACtD,MAAM,KAAK,GAAG,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC;YACpE,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAE3C,+DAA+D;YAC/D,8DAA8D;YAC9D,6DAA6D;YAC7D,UAAU;YACV,sCAAsC;YACtC,KAAK,EAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;gBAClC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACtB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO;oBAAE,MAAM;gBAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACrC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;oBACxB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO;wBAAE,MAAM;oBAChD,IAAI,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;wBACjB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;4BAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;wBAAC,CAAC;6BAAM,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;4BAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;wBAAC,CAAC;wBACpO,qCAAqC;wBACrC,SAAS,KAAK,CAAC;oBACnB,CAAC;gBACL,CAAC;YACL,CAAC;YAED,qDAAqD;YACrD,IAAI,IAAI,GAAG,CAAC,CAAC;YACb,OAAO,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAAE,EAAE,IAAI,CAAC;YAEnF,yCAAyC;YACzC,OAAO,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;gBAC1B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,EAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAA;YAC1E,CAAC;YAED,uEAAuE;YACvE,IAAI,OAAO;gBAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAE/B,wCAAwC;YACxC,IAAI,IAAI,EAAE,CAAC;gBACP,OAAO,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;oBACzB,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;oBACjC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACjB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;gBAChE,CAAC;gBAED,gEAAgE;gBAChE,sBAAsB;gBACtB,IAAI,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;oBACvB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI;wBAC/D,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;gBAC/D,CAAC;qBAAM,CAAC;oBAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;gBAAC,CAAC;YAC/C,CAAC;QACL,CAAC,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACzB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IAC5C,CAAC;IAED,uCAAuC;IACvC,iEAAiE;IACjE,8DAA8D;IAC9D,2DAA2D;IAC3D,4CAA4C;IAC5C,UAAU,CAAC,IAAU,EAAE,KAAa,EAAE,UAA2D;QAC7F,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;QAAC,CAAC;aAAM,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;QAAC,CAAC;QAE1H,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;QACrG,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC;QACnC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC;QAC3B,IAAI,CAAC,OAAO,CAAC,CAAC,KAAU,EAAE,CAAM,EAAE,CAAM,EAAE,EAAE;YACxC,IAAI,CAAC,IAAI,OAAO;gBAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACrC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;QACxF,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;IACjC,CAAC;IAED,8BAA8B;IAC9B,mEAAmE;IACnE,iEAAiE;IACjE,sDAAsD;IACtD,GAAG,CAAC,GAAW,EAAE,WAAW,GAAG,KAAK;QAChC,6CAA6C;QAC7C,MAAM,UAAU,GAAG,4BAA4B,CAAC;QAChD,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1G,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,YAAY;YACxC,wEAAwE;YACxE,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QAEhF,MAAM,oBAAoB,GAAG,IAAI,CAAC,OAAO,EAAE,iBAAiB,IAAI,YAAY,CAAC;QAE7E,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACrC,IAAI,WAAW;YAAE,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QACjG,OAAO,GAAG,CAAC;IACf,CAAC;IAED,aAAa,CAAC,GAAW;QACrB,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,aAAa;IACb,KAAK,CAAC,GAAW;QACb,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QAClF,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC;IAED,+BAA+B;IAC/B,qCAAqC;IACrC,MAAM,CAAC,GAAW,EAAE,CAAS;QACzB,IAAI,GAAG,GAAG,EAAE,CAAC;QACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAAE,GAAG,IAAI,GAAG,CAAC;QACvC,OAAO,GAAG,CAAC;IACf,CAAC;IAED,oCAAoC;IACpC,+DAA+D;IAC/D,UAAU,CAAC,IAAU,EAAE,IAAa,EAAE,MAAY,EAAE,KAAa;QAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QAC5C,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IAChF,CAAC;IAED,wDAAwD;IACxD,+DAA+D;IAC/D,sEAAsE;IACtE,wBAAwB;IACxB,sBAAsB,CAAC,IAAY;QAC/B,OAAO;YACH,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACxC,QAAQ,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;SAC5C,CAAC;IACN,CAAC;CACJ;AArTD,0DAqTC","sourcesContent":["// ::- A specification for serializing a ProseMirror document as\n// Markdown/CommonMark text.\n// prettier-ignore\nimport type {Mark, Node} from \"prosemirror-model\";\n\nimport type {MarkdownSerializerDynamicModifier} from './MarkdownSerializerDynamicModifier';\n\nexport interface SerializerNodeToken {\n (state: MarkdownSerializerState, node: Node, parent: Node, index: number): void;\n}\n\nexport interface SerializerMarkToken {\n open:\n | string\n | ((state: MarkdownSerializerState, mark: Mark, parent: Node, index: number) => string);\n close:\n | string\n | ((state: MarkdownSerializerState, mark: Mark, parent: Node, index: number) => string);\n mixable?: boolean;\n expelEnclosingWhitespace?: boolean;\n escape?: boolean;\n}\n\ninterface SerializerOptions {\n tightLists?: boolean;\n escapeExtraCharacters?: RegExp;\n hardBreakNodeName?: string;\n strict?: boolean;\n commonEscape?: RegExp;\n startOfLineEscape?: RegExp;\n escape?: boolean; // Added to fix types\n}\n\ninterface MarkMap {\n [markName: string]: SerializerMarkToken;\n}\n\ninterface NodeMap {\n [nodeName: string]: SerializerNodeToken;\n}\n\nexport class MarkdownSerializer {\n private readonly nodes: NodeMap;\n private readonly marks: MarkMap;\n private readonly dynamicModifier?: MarkdownSerializerDynamicModifier;\n\n // :: (Object<(state: MarkdownSerializerState, node: Node, parent: Node, index: number)>, Object)\n // Construct a serializer with the given configuration. The `nodes`\n // object should map node names in a given schema to function that\n // take a serializer state and such a node, and serialize the node.\n //\n // The `marks` object should hold objects with `open` and `close`\n // properties, which hold the strings that should appear before and\n // after a piece of text marked that way, either directly or as a\n // function that takes a serializer state and a mark, and returns a\n // string. `open` and `close` can also be functions, which will be\n // called as\n //\n // (state: MarkdownSerializerState, mark: Mark,\n // parent: Fragment, index: number) → string\n //\n // Where `parent` and `index` allow you to inspect the mark's\n // context to see which nodes it applies to.\n //\n // Mark information objects can also have a `mixable` property\n // which, when `true`, indicates that the order in which the mark's\n // opening and closing syntax appears relative to other mixable\n // marks can be varied. (For example, you can say `**a *b***` and\n // `*a **b***`, but not `` `a *b*` ``.)\n //\n // To disable character escaping in a mark, you can give it an\n // `escape` property of `false`. Such a mark has to have the highest\n // precedence (must always be the innermost mark).\n //\n // The `expelEnclosingWhitespace` mark property causes the\n // serializer to move enclosing whitespace from inside the marks to\n // outside the marks. This is necessary for emphasis marks as\n // CommonMark does not permit enclosing whitespace inside emphasis\n // marks, see: http://spec.commonmark.org/0.26/#example-330\n constructor(\n nodes: NodeMap,\n marks: MarkMap,\n dynamicModifier?: MarkdownSerializerDynamicModifier,\n ) {\n // :: Object<(MarkdownSerializerState, Node)> The node serializer\n // functions for this serializer.\n this.nodes = nodes;\n // :: Object The mark serializer info.\n this.marks = marks;\n\n this.dynamicModifier = dynamicModifier;\n }\n\n // :: (Node, ?Object) → string\n // Serialize the content of the given node to\n // [CommonMark](http://commonmark.org/).\n serialize(content: Node, options: Partial<SerializerOptions> = {}): string {\n const state = new MarkdownSerializerState(\n this.nodes,\n this.marks,\n options,\n this.dynamicModifier,\n );\n state.renderContent(content);\n return state.out;\n }\n\n // for tests (implements SerializerTests interface)\n containsNode(nodeName: string): boolean {\n return nodeName in this.nodes;\n }\n\n // for tests (implements SerializerTests interface)\n containsMark(markName: string): boolean {\n return markName in this.marks;\n }\n}\n\n// ::- This is an object used to track state and expose\n// methods related to markdown serialization. Instances are passed to\n// node and mark serialization methods (see `toMarkdown`).\n// prettier-ignore\nexport class MarkdownSerializerState {\n out: string;\n inTightList: boolean;\n noAutoBlank: boolean;\n isAutolink: boolean | undefined;\n escapeWhitespace: boolean;\n escapeCharacters?: string[];\n\n private readonly nodes: NodeMap;\n private readonly marks: MarkMap;\n private readonly options: SerializerOptions;\n private delim: string;\n private closed: Node | false;\n private readonly dynamicModifier?: MarkdownSerializerDynamicModifier;\n\n constructor(nodes: NodeMap, marks: MarkMap, options: Partial<SerializerOptions> = {}, dynamicModifier?: MarkdownSerializerDynamicModifier) {\n this.nodes = nodes;\n this.marks = marks;\n this.delim = this.out = '';\n this.closed = false;\n this.inTightList = false;\n this.noAutoBlank = false;\n this.isAutolink = undefined;\n this.escapeWhitespace = false;\n // :: Object\n // The options passed to the serializer.\n // tightLists:: ?bool\n // Whether to render lists in a tight style. This can be overridden\n // on a node level by specifying a tight attribute on the node.\n // Defaults to false.\n this.options = options || {};\n this.dynamicModifier = dynamicModifier;\n if (typeof this.options.tightLists === 'undefined') { this.options.tightLists = false }\n }\n\n setNoAutoBlank() {\n this.noAutoBlank = true;\n }\n\n unsetNoAutoBlank() {\n this.noAutoBlank = false;\n }\n\n flushClose(size?: number | null) {\n if (this.closed) {\n if (!this.atBlank() && !this.noAutoBlank) this.out += '\\n';\n if (size === null || size === undefined) size = 2;\n if (size > 1) {\n let delimMin = this.delim;\n const trim = /\\s+$/.exec(delimMin);\n if (trim) delimMin = delimMin.slice(0, delimMin.length - trim[0].length);\n\n if (!this.noAutoBlank) {\n for (let i = 1; i < size; i++) { this.out += delimMin + '\\n' }\n }\n }\n this.closed = false;\n }\n }\n\n // :: (string, ?string, Node, ())\n // Render a block, prefixing each line with `delim`, and the first\n // line in `firstDelim`. `node` should be the node that is closed at\n // the end of the block, and `f` is a function that renders the\n // content of the block.\n wrapBlock(delim: string, firstDelim: string | null, node: Node, f: () => void) {\n const old = this.delim;\n this.write(firstDelim || delim);\n this.delim += delim;\n f();\n this.delim = old;\n this.closeBlock(node);\n }\n\n atBlank(): boolean {\n return /(^|\\n)$/.test(this.out);\n }\n\n // :: ()\n // Ensure the current content ends with a newline.\n ensureNewLine() {\n if (!this.atBlank()) this.out += '\\n';\n }\n\n // :: (?string)\n // Prepare the state for writing output (closing closed paragraphs,\n // adding delimiters, and so on), and then optionally add content\n // (unescaped) to the output.\n write(content?: string | null): void {\n this.flushClose();\n if (this.delim && this.atBlank()) { this.out += this.delim }\n if (content) this.out += content;\n }\n\n // :: (Node)\n // Close the block for the given node.\n closeBlock(node?: Node) {\n this.closed = node ?? false;\n }\n\n // :: (string, ?bool)\n // Add the given text to the document. When escape is not `false`,\n // it will be escaped.\n text(text: string, escape?: boolean) {\n const lines = text.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n const startOfLine = this.atBlank() || this.closed;\n this.write();\n let text = lines[i];\n if (escape !== false && this.options.escape !== false) text = this.esc(text, startOfLine as any)\n if (this.escapeWhitespace) text = this.escWhitespace(text);\n this.out += text\n if (i != lines.length - 1) this.out += '\\n';\n }\n }\n\n // :: (Node)\n // Render the given node as a block.\n render(node: Node, parent: Node, index: number) {\n if (typeof parent === 'number') {\n throw new Error('!');\n }\n if (!this.nodes[node.type.name]) {\n throw new Error('Token type `' + node.type.name + '` not supported by Markdown renderer');\n }\n\n const callback = this.nodes[node.type.name];\n if (this.dynamicModifier) {\n this.dynamicModifier.processNode(this, node, parent, index, callback);\n } else {\n callback(this, node, parent, index);\n }\n }\n\n // :: (Node)\n // Render the contents of `parent` as block nodes.\n renderContent(parent: Node) {\n parent.forEach((node, _, i) => this.render(node, parent, i));\n }\n\n // :: (Node)\n // Render the contents of `parent` as inline content.\n renderInline(parent: Node) {\n const active: Mark[] = []; let\n trailing = '';\n const progress = (node: Node | null, _: any, index: number) => {\n let marks = node ? node.marks : [];\n\n // Remove marks from breaks (hard_break or soft_break) that are the edge node inside\n // that mark to prevent parser edge cases with new lines just\n // before closing or after opening marks.\n if (node && node.type.spec.isBreak) {\n marks = marks.filter((m: any) => {\n if (index === 0) return false;\n if (index + 1 == parent.childCount) return false;\n const prev = parent.child(index - 1);\n const next = parent.child(index + 1);\n return (\n (m.isInSet(prev.marks) && (!prev.isText || /\\S/.test(prev.text ?? ''))) &&\n (m.isInSet(next.marks) && (!next.isText || /\\S/.test(next.text ?? '')))\n );\n });\n }\n\n let leading = trailing;\n trailing = '';\n // If whitespace has to be expelled from the node, adjust\n // leading and trailing accordingly.\n if (node && node.isText && marks.some((mark: any) => {\n const info = this.marks[mark.type.name];\n return info && info.expelEnclosingWhitespace;\n })) {\n const [_, lead, inner, trail] = /^(\\s*)(.*?)(\\s*)$/m.exec(node.text ?? '')!;\n leading += lead;\n trailing = trail;\n if (lead || trail) {\n node = inner ? (node as any).withText(inner) : null;\n if (!node) marks = active;\n }\n }\n\n const inner = marks.length && marks[marks.length - 1];\n const noEsc = inner && this.marks[inner.type.name].escape === false;\n const len = marks.length - (noEsc ? 1 : 0);\n\n // Try to reorder 'mixable' marks, such as em and strong, which\n // in Markdown may be opened and closed in different order, so\n // that order of the marks for the token matches the order in\n // active.\n // eslint-disable-next-line no-labels\n outer: for (let i = 0; i < len; i++) {\n const mark = marks[i];\n if (!this.marks[mark.type.name].mixable) break;\n for (let j = 0; j < active.length; j++) {\n const other = active[j];\n if (!this.marks[other.type.name].mixable) break;\n if (mark.eq(other)) {\n if (i > j) { marks = marks.slice(0, j).concat(mark).concat(marks.slice(j, i)).concat(marks.slice(i + 1, len)) } else if (j > i) { marks = marks.slice(0, i).concat(marks.slice(i + 1, j)).concat(mark).concat(marks.slice(j, len)) }\n // eslint-disable-next-line no-labels\n continue outer;\n }\n }\n }\n\n // Find the prefix of the mark set that didn't change\n let keep = 0;\n while (keep < Math.min(active.length, len) && marks[keep].eq(active[keep])) ++keep;\n\n // Close the marks that need to be closed\n while (keep < active.length) {\n this.text(this.markString(active.pop()!, false, parent, index), false)\n }\n\n // Output any previously expelled trailing whitespace outside the marks\n if (leading) this.text(leading)\n\n // Open the marks that need to be opened\n if (node) {\n while (active.length < len) {\n const add = marks[active.length];\n active.push(add);\n this.text(this.markString(add, true, parent, index), false);\n }\n\n // Render the node. Special case code marks, since their content\n // may not be escaped.\n if (noEsc && node.isText) {\n this.text(this.markString(inner, true, parent, index) + node.text +\n this.markString(inner, false, parent, index + 1), false);\n } else { this.render(node, parent, index) }\n }\n };\n parent.forEach(progress);\n progress(null, null, parent.childCount);\n }\n\n // :: (Node, string, (number) → string)\n // Render a node's content as a list. `delim` should be the extra\n // indentation added to all lines except the first in an item,\n // `firstDelim` is a function going from an item index to a\n // delimiter for the first line of the item.\n renderList(node: Node, delim: string, firstDelim: (index: number, firstDelimNode: Node) => string): void {\n if (this.closed && this.closed.type == node.type) { this.flushClose(3) } else if (this.inTightList) { this.flushClose(1) }\n\n const isTight = typeof node.attrs.tight !== 'undefined' ? node.attrs.tight : this.options.tightLists;\n const prevTight = this.inTightList;\n this.inTightList = isTight;\n node.forEach((child: any, _: any, i: any) => {\n if (i && isTight) this.flushClose(1);\n this.wrapBlock(delim, firstDelim(i, child), node, () => this.render(child, node, i))\n });\n this.inTightList = prevTight;\n }\n\n // :: (string, ?bool) → string\n // Escape the given string so that it can safely appear in Markdown\n // content. If `startOfLine` is true, also escape characters that\n // have special meaning only at the start of the line.\n esc(str: string, startOfLine = false) {\n // eslint-disable-next-line no-useless-escape\n const defaultEsc = /[`\\^+*\\\\\\|~\\[\\]\\{\\}<>\\$_]/g;\n const extraChars = this.escapeCharacters?.length ? this.escapeCharacters.map(c => '\\\\' + c).join('') : '';\n const escRegexp = this.options?.commonEscape ||\n // Compose the escape regexp from default, options, and extra characters\n new RegExp(defaultEsc.source + (extraChars ? `|[${extraChars}]` : ''), 'g');\n\n const startOfLineEscRegexp = this.options?.startOfLineEscape || /^[:#\\-*+>]/;\n\n str = str.replace(escRegexp, '\\\\$&');\n if (startOfLine) str = str.replace(startOfLineEscRegexp, '\\\\$&').replace(/^(\\s*\\d+)\\./, '$1\\\\.');\n return str;\n }\n\n escWhitespace(str: string): string {\n return str.replace(/ /g, '\\\\ ');\n }\n\n /// @internal\n quote(str: string): string {\n const wrap = str.indexOf('\"') == -1 ? '\"\"' : str.indexOf(\"'\") == -1 ? \"''\" : '()';\n return wrap[0] + str + wrap[1];\n }\n\n // :: (string, number) → string\n // Repeat the given string `n` times.\n repeat(str: string, n: number) {\n let out = '';\n for (let i = 0; i < n; i++) out += str;\n return out;\n }\n\n // :: (Mark, bool, string?) → string\n // Get the markdown string for a given opening or closing mark.\n markString(mark: Mark, open: boolean, parent: Node, index: number): string {\n const info = this.marks[mark.type.name];\n const value = open ? info.open : info.close;\n return typeof value === 'string' ? value : value(this, mark, parent, index);\n }\n\n // :: (string) → { leading: ?string, trailing: ?string }\n // Get leading and trailing whitespace from a string. Values of\n // leading or trailing property of the return object will be undefined\n // if there is no match.\n getEnclosingWhitespace(text: string) {\n return {\n leading: (text.match(/^(\\s+)/) || [])[0],\n trailing: (text.match(/(\\s+)$/) || [])[0],\n };\n }\n}\n"]}
1
+ {"version":3,"file":"MarkdownSerializer.js","sourceRoot":"../../../../src","sources":["core/markdown/MarkdownSerializer.ts"],"names":[],"mappings":"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","sourcesContent":["// ::- A specification for serializing a ProseMirror document as\n// Markdown/CommonMark text.\n// prettier-ignore\nimport type {Mark, Node} from \"prosemirror-model\";\n\nimport type {MarkdownSerializerDynamicModifier} from './MarkdownSerializerDynamicModifier';\n\nexport interface SerializerNodeToken {\n (state: MarkdownSerializerState, node: Node, parent: Node, index: number): void;\n}\n\nexport interface SerializerMarkToken {\n open:\n | string\n | ((state: MarkdownSerializerState, mark: Mark, parent: Node, index: number) => string);\n close:\n | string\n | ((state: MarkdownSerializerState, mark: Mark, parent: Node, index: number) => string);\n mixable?: boolean;\n expelEnclosingWhitespace?: boolean;\n escape?: boolean;\n}\n\ninterface SerializerOptions {\n tightLists?: boolean;\n escapeExtraCharacters?: RegExp;\n hardBreakNodeName?: string;\n strict?: boolean;\n commonEscape?: RegExp;\n startOfLineEscape?: RegExp;\n escape?: boolean; // Added to fix types\n}\n\nconst blankMark: SerializerMarkToken = {open: '', close: '', mixable: false};\n\ninterface MarkMap {\n [markName: string]: SerializerMarkToken;\n}\n\ninterface NodeMap {\n [nodeName: string]: SerializerNodeToken;\n}\n\nexport class MarkdownSerializer {\n private readonly nodes: NodeMap;\n private readonly marks: MarkMap;\n private readonly dynamicModifier?: MarkdownSerializerDynamicModifier;\n\n // :: (Object<(state: MarkdownSerializerState, node: Node, parent: Node, index: number)>, Object)\n // Construct a serializer with the given configuration. The `nodes`\n // object should map node names in a given schema to function that\n // take a serializer state and such a node, and serialize the node.\n //\n // The `marks` object should hold objects with `open` and `close`\n // properties, which hold the strings that should appear before and\n // after a piece of text marked that way, either directly or as a\n // function that takes a serializer state and a mark, and returns a\n // string. `open` and `close` can also be functions, which will be\n // called as\n //\n // (state: MarkdownSerializerState, mark: Mark,\n // parent: Fragment, index: number) → string\n //\n // Where `parent` and `index` allow you to inspect the mark's\n // context to see which nodes it applies to.\n //\n // Mark information objects can also have a `mixable` property\n // which, when `true`, indicates that the order in which the mark's\n // opening and closing syntax appears relative to other mixable\n // marks can be varied. (For example, you can say `**a *b***` and\n // `*a **b***`, but not `` `a *b*` ``.)\n //\n // To disable character escaping in a mark, you can give it an\n // `escape` property of `false`. Such a mark has to have the highest\n // precedence (must always be the innermost mark).\n //\n // The `expelEnclosingWhitespace` mark property causes the\n // serializer to move enclosing whitespace from inside the marks to\n // outside the marks. This is necessary for emphasis marks as\n // CommonMark does not permit enclosing whitespace inside emphasis\n // marks, see: http://spec.commonmark.org/0.26/#example-330\n constructor(\n nodes: NodeMap,\n marks: MarkMap,\n dynamicModifier?: MarkdownSerializerDynamicModifier,\n ) {\n // :: Object<(MarkdownSerializerState, Node)> The node serializer\n // functions for this serializer.\n this.nodes = nodes;\n // :: Object The mark serializer info.\n this.marks = marks;\n\n this.dynamicModifier = dynamicModifier;\n }\n\n // :: (Node, ?Object) → string\n // Serialize the content of the given node to\n // [CommonMark](http://commonmark.org/).\n serialize(content: Node, options: Partial<SerializerOptions> = {}): string {\n const state = new MarkdownSerializerState(\n this.nodes,\n this.marks,\n options,\n this.dynamicModifier,\n );\n state.renderContent(content);\n return state.out;\n }\n\n // for tests (implements SerializerTests interface)\n containsNode(nodeName: string): boolean {\n return nodeName in this.nodes;\n }\n\n // for tests (implements SerializerTests interface)\n containsMark(markName: string): boolean {\n return markName in this.marks;\n }\n}\n\n// ::- This is an object used to track state and expose\n// methods related to markdown serialization. Instances are passed to\n// node and mark serialization methods (see `toMarkdown`).\n// prettier-ignore\nexport class MarkdownSerializerState {\n out: string;\n inTightList: boolean;\n noAutoBlank: boolean;\n isAutolink: boolean | undefined;\n atBlockStart: boolean;\n escapeWhitespace: boolean;\n escapeCharacters?: string[];\n\n private readonly nodes: NodeMap;\n private readonly marks: MarkMap;\n private readonly options: SerializerOptions;\n private delim: string;\n private closed: Node | false;\n private readonly dynamicModifier?: MarkdownSerializerDynamicModifier;\n\n constructor(nodes: NodeMap, marks: MarkMap, options: Partial<SerializerOptions> = {}, dynamicModifier?: MarkdownSerializerDynamicModifier) {\n this.nodes = nodes;\n this.marks = marks;\n this.delim = this.out = '';\n this.closed = false;\n this.inTightList = false;\n this.noAutoBlank = false;\n this.isAutolink = undefined;\n this.atBlockStart = false;\n this.escapeWhitespace = false;\n // :: Object\n // The options passed to the serializer.\n // tightLists:: ?bool\n // Whether to render lists in a tight style. This can be overridden\n // on a node level by specifying a tight attribute on the node.\n // Defaults to false.\n this.options = options || {};\n this.dynamicModifier = dynamicModifier;\n if (typeof this.options.tightLists === 'undefined') { this.options.tightLists = false }\n }\n\n setNoAutoBlank() {\n this.noAutoBlank = true;\n }\n\n unsetNoAutoBlank() {\n this.noAutoBlank = false;\n }\n\n flushClose(size?: number | null) {\n if (this.closed) {\n if (!this.atBlank() && !this.noAutoBlank) this.out += '\\n';\n if (size === null || size === undefined) size = 2;\n if (size > 1) {\n let delimMin = this.delim;\n const trim = /\\s+$/.exec(delimMin);\n if (trim) delimMin = delimMin.slice(0, delimMin.length - trim[0].length);\n\n if (!this.noAutoBlank) {\n for (let i = 1; i < size; i++) { this.out += delimMin + '\\n' }\n }\n }\n this.closed = false;\n }\n }\n\n // :: (string, ?string, Node, ())\n // Render a block, prefixing each line with `delim`, and the first\n // line in `firstDelim`. `node` should be the node that is closed at\n // the end of the block, and `f` is a function that renders the\n // content of the block.\n wrapBlock(delim: string, firstDelim: string | null, node: Node, f: () => void) {\n const old = this.delim;\n this.write(firstDelim || delim);\n this.delim += delim;\n f();\n this.delim = old;\n this.closeBlock(node);\n }\n\n atBlank(): boolean {\n return /(^|\\n)$/.test(this.out);\n }\n\n // :: ()\n // Ensure the current content ends with a newline.\n ensureNewLine() {\n if (!this.atBlank()) this.out += '\\n';\n }\n\n // :: (?string)\n // Prepare the state for writing output (closing closed paragraphs,\n // adding delimiters, and so on), and then optionally add content\n // (unescaped) to the output.\n write(content?: string | null): void {\n this.flushClose();\n if (this.delim && this.atBlank()) { this.out += this.delim }\n if (content) this.out += content;\n }\n\n // :: (Node)\n // Close the block for the given node.\n closeBlock(node?: Node) {\n this.closed = node ?? false;\n }\n\n // :: (string, ?bool)\n // Add the given text to the document. When escape is not `false`,\n // it will be escaped.\n text(text: string, escape?: boolean) {\n const lines = text.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n this.write();\n // Escape ! before [ to prevent being parsed as image syntax\n if (escape === false && lines[i][0] === '[' && /(^|[^\\\\])!$/.test(this.out))\n this.out = this.out.slice(0, this.out.length - 1) + '\\\\!';\n let text = lines[i];\n if (escape !== false && this.options.escape !== false) text = this.esc(text, this.atBlockStart)\n if (this.escapeWhitespace) text = this.escWhitespace(text);\n this.out += text\n if (i != lines.length - 1) this.out += '\\n';\n }\n }\n\n // :: (Node)\n // Render the given node as a block.\n render(node: Node, parent: Node, index: number) {\n if (typeof parent === 'number') {\n throw new Error('!');\n }\n\n const callback = this.nodes[node.type.name];\n if (callback) {\n if (this.dynamicModifier) {\n this.dynamicModifier.processNode(this, node, parent, index, callback);\n } else {\n callback(this, node, parent, index);\n }\n } else {\n if (this.options.strict !== false) {\n throw new Error('Token type `' + node.type.name + '` not supported by Markdown renderer');\n } else if (!node.type.isLeaf) {\n if (node.type.inlineContent) this.renderInline(node);\n else this.renderContent(node);\n if (node.isBlock) this.closeBlock(node);\n }\n }\n }\n\n // :: (Node)\n // Render the contents of `parent` as block nodes.\n renderContent(parent: Node) {\n parent.forEach((node, _, i) => this.render(node, parent, i));\n }\n\n // Render the contents of `parent` as inline content.\n renderInline(parent: Node, fromBlockStart = true) {\n this.atBlockStart = fromBlockStart;\n const active: Mark[] = [];\n let trailing = '';\n const progress = (node: Node | null, _: any, index: number) => {\n let marks = node ? node.marks : [];\n\n // Remove marks from breaks (hard_break or soft_break) that are the edge node inside\n // that mark to prevent parser edge cases with new lines just\n // before closing or after opening marks.\n if (node && node.type.spec.isBreak) {\n marks = marks.filter((m) => {\n if (index === 0) return false;\n if (index + 1 === parent.childCount) return false;\n const prev = parent.child(index - 1);\n const next = parent.child(index + 1);\n return (\n (m.isInSet(prev.marks) && (!prev.isText || /\\S/.test(prev.text ?? ''))) &&\n (m.isInSet(next.marks) && (!next.isText || /\\S/.test(next.text ?? '')))\n );\n });\n }\n\n let leading = trailing;\n trailing = '';\n // If whitespace has to be expelled from the node, adjust\n // leading and trailing accordingly.\n if (node && node.isText && marks.some((mark) => {\n const info = this.getMark(mark.type.name);\n return info && info.expelEnclosingWhitespace && !mark.isInSet(active);\n })) {\n const [_, lead, rest] = /^(\\s*)(.*)$/m.exec(node.text!)!;\n if (lead) {\n leading += lead;\n node = rest ? (node as any).withText(rest) : null;\n if (!node) marks = active;\n }\n }\n if (node && node.isText && marks.some((mark) => {\n const info = this.getMark(mark.type.name);\n return info && info.expelEnclosingWhitespace && !this.isMarkAhead(parent, index + 1, mark);\n })) {\n const [_, rest, trail] = /^(.*?)(\\s*)$/m.exec(node.text!)!;\n if (trail) {\n trailing = trail;\n node = rest ? (node as any).withText(rest) : null;\n if (!node) marks = active;\n }\n }\n\n const inner = marks.length && marks[marks.length - 1];\n const noEsc = inner && this.getMark(inner.type.name).escape === false;\n const len = marks.length - (noEsc ? 1 : 0);\n\n // Try to reorder 'mixable' marks, such as em and strong, which\n // in Markdown may be opened and closed in different order, so\n // that order of the marks for the token matches the order in\n // active.\n // eslint-disable-next-line no-labels\n outer: for (let i = 0; i < len; i++) {\n const mark = marks[i];\n if (!this.getMark(mark.type.name).mixable) break;\n for (let j = 0; j < active.length; j++) {\n const other = active[j];\n if (!this.getMark(other.type.name).mixable) break;\n if (mark.eq(other)) {\n if (i > j) {\n marks = marks.slice(0, j).concat(mark).concat(marks.slice(j, i)).concat(marks.slice(i + 1, len))\n }\n else if (j > i) {\n marks = marks.slice(0, i).concat(marks.slice(i + 1, j)).concat(mark).concat(marks.slice(j, len))\n }\n // eslint-disable-next-line no-labels\n continue outer;\n }\n }\n }\n\n // Find the prefix of the mark set that didn't change\n let keep = 0;\n while (keep < Math.min(active.length, len) && marks[keep].eq(active[keep])) ++keep;\n\n // Close the marks that need to be closed\n while (keep < active.length) {\n this.text(this.markString(active.pop()!, false, parent, index), false)\n }\n\n // Output any previously expelled trailing whitespace outside the marks\n if (leading) this.text(leading)\n\n // Open the marks that need to be opened\n if (node) {\n while (active.length < len) {\n const add = marks[active.length];\n active.push(add);\n this.text(this.markString(add, true, parent, index), false);\n this.atBlockStart = false;\n }\n\n // Render the node. Special case code marks, since their content\n // may not be escaped.\n if (noEsc && node.isText) {\n this.text(this.markString(inner, true, parent, index) + node.text +\n this.markString(inner, false, parent, index + 1), false);\n } else {\n this.render(node, parent, index)\n }\n this.atBlockStart = false;\n }\n\n // After the first non-empty text node is rendered, the end of output\n // is no longer at block start.\n //\n // FIXME: If a non-text node writes something to the output for this\n // block, the end of output is also no longer at block start. But how\n // can we detect that?\n if (node?.isText && node.nodeSize > 0) {\n this.atBlockStart = false;\n }\n };\n parent.forEach(progress);\n progress(null, null, parent.childCount);\n this.atBlockStart = false;\n }\n\n // :: (Node, string, (number) → string)\n // Render a node's content as a list. `delim` should be the extra\n // indentation added to all lines except the first in an item,\n // `firstDelim` is a function going from an item index to a\n // delimiter for the first line of the item.\n renderList(node: Node, delim: string, firstDelim: (index: number, firstDelimNode: Node) => string): void {\n if (this.closed && this.closed.type == node.type) { this.flushClose(3) } else if (this.inTightList) { this.flushClose(1) }\n\n const isTight = typeof node.attrs.tight !== 'undefined' ? node.attrs.tight : this.options.tightLists;\n const prevTight = this.inTightList;\n this.inTightList = isTight;\n node.forEach((child: any, _: any, i: any) => {\n if (i && isTight) this.flushClose(1);\n this.wrapBlock(delim, firstDelim(i, child), node, () => this.render(child, node, i))\n });\n this.inTightList = prevTight;\n }\n\n // :: (string, ?bool) → string\n // Escape the given string so that it can safely appear in Markdown\n // content. If `startOfLine` is true, also escape characters that\n // have special meaning only at the start of the line.\n esc(str: string, startOfLine = false) {\n // eslint-disable-next-line no-useless-escape\n const defaultEsc = /[`\\^+*\\\\\\|~\\[\\]\\{\\}<>\\$]/g;\n const extraChars = this.escapeCharacters?.length ? this.escapeCharacters.map(c => '\\\\' + c).join('') : '';\n const escRegexp = this.options?.commonEscape ||\n // Compose the escape regexp from default, options, and extra characters\n new RegExp(defaultEsc.source + (extraChars ? `|[${extraChars}]` : ''), 'g');\n\n const startOfLineEscRegexp = this.options?.startOfLineEscape || /^[:#\\-*+>]/;\n\n str = str.replace(escRegexp, '\\\\$&');\n // Smart underscore: don't escape _ between word characters (e.g. foo_bar)\n str = str.replace(/_/g, (m, i) =>\n i > 0 && i + 1 < str.length && /\\w/.test(str[i - 1]) && /\\w/.test(str[i + 1])\n ? m\n : '\\\\' + m\n );\n if (startOfLine) str = str.replace(startOfLineEscRegexp, '\\\\$&').replace(/^(\\s*\\d+)\\./, '$1\\\\.');\n return str;\n }\n\n escWhitespace(str: string): string {\n return str.replace(/ /g, '\\\\ ');\n }\n\n /// @internal\n quote(str: string): string {\n const wrap = str.indexOf('\"') == -1 ? '\"\"' : str.indexOf(\"'\") == -1 ? \"''\" : '()';\n return wrap[0] + str + wrap[1];\n }\n\n // :: (string, number) → string\n // Repeat the given string `n` times.\n repeat(str: string, n: number) {\n let out = '';\n for (let i = 0; i < n; i++) out += str;\n return out;\n }\n\n // :: (Mark, bool, string?) → string\n // Get the markdown string for a given opening or closing mark.\n markString(mark: Mark, open: boolean, parent: Node, index: number): string {\n const info = this.getMark(mark.type.name);\n const value = open ? info.open : info.close;\n return typeof value === 'string' ? value : value(this, mark, parent, index);\n }\n\n // :: (string) → { leading: ?string, trailing: ?string }\n // Get leading and trailing whitespace from a string. Values of\n // leading or trailing property of the return object will be undefined\n // if there is no match.\n getEnclosingWhitespace(text: string) {\n return {\n leading: (text.match(/^(\\s+)/) || [])[0],\n trailing: (text.match(/(\\s+)$/) || [])[0],\n };\n }\n\n private isMarkAhead(parent: Node, index: number, mark: Mark): boolean {\n for (;; index++) {\n if (index >= parent.childCount) return false;\n const next = parent.child(index);\n if (!next.type.spec.isBreak) return !!mark.isInSet(next.marks);\n }\n }\n\n // Get mark info by name, with fallback to blankMark when strict mode is off.\n private getMark(name: string): SerializerMarkToken {\n const info = this.marks[name];\n if (!info) {\n if (this.options.strict !== false)\n throw new Error(`Mark type \\`${name}\\` not supported by Markdown renderer`);\n return blankMark;\n }\n return info;\n }\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import { type PopupPlacement, type PopupProps } from '@gravity-ui/uikit';
2
+ import type { ActionStorage } from "../../../core/index.js";
3
+ import type { EditorView } from "../../../pm/view.js";
4
+ import { type ToolbarProps } from "../../../toolbar/index.js";
5
+ import type { ContextConfig } from "./types.js";
6
+ export type TextSelectionTooltipProps = Pick<ToolbarProps<ActionStorage>, 'onClick' | 'editor' | 'focus'> & {
7
+ config: ContextConfig;
8
+ editorView: EditorView;
9
+ popupPlacement: PopupPlacement;
10
+ popupAnchor: PopupProps['anchorElement'];
11
+ popupOnOpenChange: PopupProps['onOpenChange'];
12
+ };
13
+ export declare const TextSelectionTooltip: React.FC<TextSelectionTooltipProps>;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TextSelectionTooltip = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const uikit_1 = require("@gravity-ui/uikit");
7
+ const lodash_1 = require("../../../lodash.js");
8
+ const memo_1 = require("../../../react-utils/memo.js");
9
+ const toolbar_1 = require("../../../toolbar/index.js");
10
+ const ToolbarRerender_1 = require("../../../toolbar/ToolbarRerender.js");
11
+ const ToolbarMemoized = (0, memo_1.typedMemo)(toolbar_1.Toolbar);
12
+ const KEY_SEP = '|||';
13
+ const TextSelectionTooltip = function TextSelectionTooltip({ popupAnchor, popupPlacement, popupOnOpenChange, config, focus, editor, onClick, editorView, }) {
14
+ const [conditionKey, setConditionKey] = (0, react_1.useState)(() => calcConditionKey(config, editor, editorView));
15
+ (0, react_1.useEffect)(() => {
16
+ const newKey = calcConditionKey(config, editor, editorView);
17
+ if (conditionKey !== newKey)
18
+ setConditionKey(newKey);
19
+ });
20
+ const toolbarData = (0, react_1.useMemo)(() => {
21
+ const results = conditionKey.split(KEY_SEP);
22
+ let idx = 0;
23
+ return config
24
+ .map((groupData) => groupData.filter(() => results[idx++] === 'true'))
25
+ .filter((groupData) => Boolean(groupData.length));
26
+ }, [config, conditionKey]);
27
+ return ((0, jsx_runtime_1.jsx)(uikit_1.Popup, { open: true, className: (0, uikit_1.sp)({ p: '0.5' }), placement: popupPlacement, anchorElement: popupAnchor, onOpenChange: popupOnOpenChange, children: (0, jsx_runtime_1.jsx)(ToolbarRerender_1.ToolbarWrapToContext, { editor: editor, children: (0, jsx_runtime_1.jsx)(ToolbarMemoized, { focus: focus, editor: editor, onClick: onClick, data: toolbarData, qa: "g-md-toolbar-selection" }) }) }));
28
+ };
29
+ exports.TextSelectionTooltip = TextSelectionTooltip;
30
+ function calcConditionKey(config, editor, editorView) {
31
+ return config
32
+ .flatMap((groupData) => groupData.map((item) => {
33
+ const { condition } = item;
34
+ if (condition === 'enabled')
35
+ return item.isEnable(editor);
36
+ if ((0, lodash_1.isFunction)(condition))
37
+ return condition(editorView.state);
38
+ return true;
39
+ }))
40
+ .join(KEY_SEP);
41
+ }
42
+ //# sourceMappingURL=TextSelectionTooltip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextSelectionTooltip.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/SelectionContext/TextSelectionTooltip.tsx"],"names":[],"mappings":";;;;AAAA,iCAAmD;AAEnD,6CAAkF;AAIlF,+CAAsC;AACtC,uDAA+C;AAC/C,uDAAyE;AACzE,yEAAiE;AAIjE,MAAM,eAAe,GAAG,IAAA,gBAAS,EAAC,iBAAO,CAAC,CAAC;AAC3C,MAAM,OAAO,GAAG,KAAK,CAAC;AAaf,MAAM,oBAAoB,GAC7B,SAAS,oBAAoB,CAAC,EAC1B,WAAW,EACX,cAAc,EACd,iBAAiB,EAEjB,MAAM,EACN,KAAK,EACL,MAAM,EACN,OAAO,EACP,UAAU,GACb;IACG,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,IAAA,gBAAQ,EAAC,GAAG,EAAE,CAClD,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAC/C,CAAC;IAEF,IAAA,iBAAS,EAAC,GAAG,EAAE;QACX,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QAC5D,IAAI,YAAY,KAAK,MAAM;YAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,IAAA,eAAO,EAA6B,GAAG,EAAE;QACzD,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,OAAO,MAAM;aACR,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC,CAAC;aACrE,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1D,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;IAE3B,OAAO,CACH,uBAAC,aAAK,IACF,IAAI,QACJ,SAAS,EAAE,IAAA,UAAE,EAAC,EAAC,CAAC,EAAE,KAAK,EAAC,CAAC,EACzB,SAAS,EAAE,cAAc,EACzB,aAAa,EAAE,WAAW,EAC1B,YAAY,EAAE,iBAAiB,YAE/B,uBAAC,sCAAoB,IAAC,MAAM,EAAE,MAAM,YAChC,uBAAC,eAAe,IACZ,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,WAAW,EACjB,EAAE,EAAC,wBAAwB,GAC7B,GACiB,GACnB,CACX,CAAC;AACN,CAAC,CAAC;AAhDO,QAAA,oBAAoB,wBAgD3B;AAEN,SAAS,gBAAgB,CACrB,MAAqB,EACrB,MAAqB,EACrB,UAAsB;IAEtB,OAAO,MAAM;SACR,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CACnB,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACnB,MAAM,EAAC,SAAS,EAAC,GAAG,IAAI,CAAC;QACzB,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC1D,IAAI,IAAA,mBAAU,EAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC;IAChB,CAAC,CAAC,CACL;SACA,IAAI,CAAC,OAAO,CAAC,CAAC;AACvB,CAAC","sourcesContent":["import {useEffect, useMemo, useState} from 'react';\n\nimport {Popup, type PopupPlacement, type PopupProps, sp} from '@gravity-ui/uikit';\n\nimport type {ActionStorage} from '#core';\nimport type {EditorView} from '#pm/view';\nimport {isFunction} from 'src/lodash';\nimport {typedMemo} from 'src/react-utils/memo';\nimport {Toolbar, type ToolbarData, type ToolbarProps} from 'src/toolbar';\nimport {ToolbarWrapToContext} from 'src/toolbar/ToolbarRerender';\n\nimport type {ContextConfig} from './types';\n\nconst ToolbarMemoized = typedMemo(Toolbar);\nconst KEY_SEP = '|||';\n\nexport type TextSelectionTooltipProps = Pick<\n ToolbarProps<ActionStorage>,\n 'onClick' | 'editor' | 'focus'\n> & {\n config: ContextConfig;\n editorView: EditorView;\n popupPlacement: PopupPlacement;\n popupAnchor: PopupProps['anchorElement'];\n popupOnOpenChange: PopupProps['onOpenChange'];\n};\n\nexport const TextSelectionTooltip: React.FC<TextSelectionTooltipProps> =\n function TextSelectionTooltip({\n popupAnchor,\n popupPlacement,\n popupOnOpenChange,\n\n config,\n focus,\n editor,\n onClick,\n editorView,\n }) {\n const [conditionKey, setConditionKey] = useState(() =>\n calcConditionKey(config, editor, editorView),\n );\n\n useEffect(() => {\n const newKey = calcConditionKey(config, editor, editorView);\n if (conditionKey !== newKey) setConditionKey(newKey);\n });\n\n const toolbarData = useMemo<ToolbarData<ActionStorage>>(() => {\n const results = conditionKey.split(KEY_SEP);\n let idx = 0;\n return config\n .map((groupData) => groupData.filter(() => results[idx++] === 'true'))\n .filter((groupData) => Boolean(groupData.length));\n }, [config, conditionKey]);\n\n return (\n <Popup\n open\n className={sp({p: '0.5'})}\n placement={popupPlacement}\n anchorElement={popupAnchor}\n onOpenChange={popupOnOpenChange}\n >\n <ToolbarWrapToContext editor={editor}>\n <ToolbarMemoized\n focus={focus}\n editor={editor}\n onClick={onClick}\n data={toolbarData}\n qa=\"g-md-toolbar-selection\"\n />\n </ToolbarWrapToContext>\n </Popup>\n );\n };\n\nfunction calcConditionKey(\n config: ContextConfig,\n editor: ActionStorage,\n editorView: EditorView,\n): string {\n return config\n .flatMap((groupData) =>\n groupData.map((item) => {\n const {condition} = item;\n if (condition === 'enabled') return item.isEnable(editor);\n if (isFunction(condition)) return condition(editorView.state);\n return true;\n }),\n )\n .join(KEY_SEP);\n}\n"]}
@@ -23,10 +23,17 @@ const pluginKey = new prosemirror_state_1.PluginKey('selection-context');
23
23
  class SelectionTooltip {
24
24
  destroyed = false;
25
25
  tooltip;
26
+ editorView = null;
26
27
  hideTimeoutRef = null;
27
28
  _isMousePressed = false;
28
29
  constructor(actions, menuConfig, logger, options) {
29
- this.tooltip = new tooltip_1.TooltipView(actions, menuConfig, logger, options);
30
+ this.tooltip = new tooltip_1.TooltipView(actions, menuConfig, logger, {
31
+ ...options,
32
+ onPopupOpenChange: (_open, _event, reason) => {
33
+ if (reason !== 'escape-key' && this.editorView)
34
+ this.scheduleTooltipHiding(this.editorView);
35
+ },
36
+ });
30
37
  }
31
38
  get key() {
32
39
  return pluginKey;
@@ -84,6 +91,7 @@ class SelectionTooltip {
84
91
  };
85
92
  }
86
93
  update(view, prevState) {
94
+ this.editorView = view;
87
95
  if (this._isMousePressed)
88
96
  return;
89
97
  this.cancelTooltipHiding();
@@ -119,12 +127,7 @@ class SelectionTooltip {
119
127
  this.tooltip.hide(view);
120
128
  return;
121
129
  }
122
- this.tooltip.show(view, {
123
- onOpenChange: (_open, _event, reason) => {
124
- if (reason !== 'escape-key')
125
- this.scheduleTooltipHiding(view);
126
- },
127
- });
130
+ this.tooltip.show(view);
128
131
  }
129
132
  scheduleTooltipHiding(view) {
130
133
  this.hideTimeoutRef = setTimeout(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/SelectionContext/index.ts"],"names":[],"mappings":";;;AAAA,2DAAkD;AAElD,yDAS2B;AAC3B,oCAAoC;AACpC,yDAAgD;AAKhD,mDAAiD;AAEjD,0CAA0D;AAqBnD,MAAM,gBAAgB,GAA2C,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;IACtF,MAAM,EAAC,MAAM,EAAC,GAAG,IAAI,CAAC;IACtB,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7C,OAAO,CAAC,SAAS,CACb,CAAC,EAAC,OAAO,EAAC,EAAE,EAAE,CAAC,IAAI,0BAAM,CAAC,IAAI,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CACzF,CAAC;IACN,CAAC;AACL,CAAC,CAAC;AAPW,QAAA,gBAAgB,oBAO3B;AAEF,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAEnC,MAAM,iBAAiB,GAAG,CAAC,EAAe,EAAE,EAAE;IACjD,OAAO,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC,CAAC;AAFW,QAAA,iBAAiB,qBAE5B;AAEF,MAAM,SAAS,GAAG,IAAI,6BAAS,CAAc,mBAAmB,CAAC,CAAC;AAQlE,MAAM,gBAAgB;IACV,SAAS,GAAG,KAAK,CAAC;IAElB,OAAO,CAAc;IACrB,cAAc,GAAyC,IAAI,CAAC;IAE5D,eAAe,GAAG,KAAK,CAAC;IAEhC,YACI,OAAsB,EACtB,UAAyB,EACzB,MAAuB,EACvB,OAAgC;QAEhC,IAAI,CAAC,OAAO,GAAG,IAAI,qBAAW,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACzE,CAAC;IAED,IAAI,GAAG;QACH,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,IAAI,KAAK;QACL,OAAO;YACH,qBAAqB;YACrB,aAAa,EAAE,IAAA,mCAAc,EAAC;gBAC1B,yCAAyC;gBACzC,MAAM,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE;oBAChC,IAAI,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;wBAC7B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAK,CAAC,CAAC;wBACzB,OAAO,IAAI,CAAC;oBAChB,CAAC;oBACD,OAAO,KAAK,CAAC;gBACjB,CAAC;aACJ,CAAC;YACF,eAAe,EAAE;gBACb,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE;oBAChB,MAAM,UAAU,GAAc;wBAC1B,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG;wBACnB,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS;qBAClC,CAAC;oBACF,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;oBAC5B,IAAI,CAAC,mBAAmB,EAAE,CAAC;oBAC3B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAExB,MAAM,SAAS,GAAG,GAAG,EAAE;wBACnB,IAAI,IAAI,CAAC,SAAS;4BAAE,OAAO;wBAC3B,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;wBAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;oBAClC,CAAC,CAAC;oBAEF,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,EAAE,EAAC,IAAI,EAAE,IAAI,EAAC,CAAC,CAAC;gBAClE,CAAC;aACJ;SACJ,CAAC;IACN,CAAC;IAED,IAAI,KAAK;QACL,OAAO;YACH,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,EAAC,QAAQ,EAAE,KAAK,EAAC,CAAC;YAC/B,KAAK,CAAC,EAAE;gBACJ,OAAO,EAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,EAAC,CAAC;YACxD,CAAC;SACJ,CAAC;IACN,CAAC;IAED,IAAI,CAAC,IAAgB;QACjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAClB,OAAO;YACH,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;YAC9B,OAAO,EAAE,GAAG,EAAE;gBACV,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;gBACtB,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC3B,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAC3B,CAAC;SACJ,CAAC;IACN,CAAC;IAEO,MAAM,CAAC,IAAgB,EAAE,SAAqB;QAClD,IAAI,IAAI,CAAC,eAAe;YAAE,OAAO;QAEjC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAE3B,MAAM,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC;QAE5D,sDAAsD;QACtD,IAAI,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;YACrC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxB,OAAO;QACX,CAAC;QAED,MAAM,EAAC,KAAK,EAAC,GAAG,IAAI,CAAC;QACrB,4DAA4D;QAC5D,IAAI,SAAS,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;YACtF,OAAO;QACX,CAAC;QAED,4CAA4C;QAC5C,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;YACnB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxB,OAAO;QACX,CAAC;QAED,MAAM,EAAC,SAAS,EAAC,GAAG,KAAK,CAAC;QAC1B,6CAA6C;QAC7C,IACI,SAAS,CAAC,KAAK;YACf,CAAC,CAAC,SAAS,YAAY,iCAAa,IAAI,SAAS,YAAY,gCAAY,CAAC,EAC5E,CAAC;YACC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxB,OAAO;QACX,CAAC;QAED;QACI,gEAAgE;QAChE,IAAA,mBAAW,EAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC;YACnC,IAAA,mBAAW,EAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC;YACjC,kEAAkE;YAClE,IAAA,iCAAa,EAAC,CAAC,IAAU,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,KAAK,KAAK,CAAC,CAAC,SAAS,CAAC,EACrF,CAAC;YACC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxB,OAAO;QACX,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE;YACpB,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;gBACpC,IAAI,MAAM,KAAK,YAAY;oBAAE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;YAClE,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;IAEO,qBAAqB,CAAC,IAAgB;QAC1C,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE;YAClC,mDAAmD;YACnD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;gBACnB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5B,CAAC;QACL,CAAC,EAAE,EAAE,CAAC,CAAC;IACX,CAAC;IAEO,mBAAmB;QACvB,IAAI,IAAI,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;YAC/B,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC/B,CAAC;IACL,CAAC;CACJ","sourcesContent":["import {keydownHandler} from 'prosemirror-keymap';\nimport type {Node} from 'prosemirror-model';\nimport {\n AllSelection,\n type EditorState,\n Plugin,\n PluginKey,\n type PluginSpec,\n type StateField,\n TextSelection,\n type Transaction,\n} from 'prosemirror-state';\n// @ts-ignore // TODO: fix cjs build\nimport {hasParentNode} from 'prosemirror-utils';\nimport type {EditorProps, EditorView} from 'prosemirror-view';\n\nimport type {ActionStorage, ExtensionAuto} from '../../../core';\nimport type {Logger2} from '../../../logger';\nimport {isCodeBlock} from '../../../utils/nodes';\n\nimport {type ContextConfig, TooltipView} from './tooltip';\n\nexport type {\n ContextConfig as SelectionContextConfig,\n ContextGroupItemData as SelectionContextItemData,\n} from './tooltip';\n\nexport type SelectionContextOptions = {\n config?: ContextConfig;\n /**\n * Placement of context popup\n * @default 'bottom'\n */\n placement?: 'top' | 'bottom';\n /**\n * Prevents context popup from overflowing\n * @default false\n */\n flip?: boolean;\n};\n\nexport const SelectionContext: ExtensionAuto<SelectionContextOptions> = (builder, opts) => {\n const {config} = opts;\n if (Array.isArray(config) && config.length > 0) {\n builder.addPlugin(\n ({actions}) => new Plugin(new SelectionTooltip(actions, config, builder.logger, opts)),\n );\n }\n};\n\nconst HideMetaKey = 'hide-selection-menu';\n\nexport const hideSelectionMenu = (tr: Transaction) => {\n return tr.setMeta(HideMetaKey, true);\n};\n\nconst pluginKey = new PluginKey<PluginState>('selection-context');\n\ntype PluginState = {\n disabled: boolean;\n};\n\ntype TinyState = Pick<EditorState, 'doc' | 'selection'>;\n\nclass SelectionTooltip implements PluginSpec<PluginState> {\n private destroyed = false;\n\n private tooltip: TooltipView;\n private hideTimeoutRef: ReturnType<typeof setTimeout> | null = null;\n\n private _isMousePressed = false;\n\n constructor(\n actions: ActionStorage,\n menuConfig: ContextConfig,\n logger: Logger2.ILogger,\n options: SelectionContextOptions,\n ) {\n this.tooltip = new TooltipView(actions, menuConfig, logger, options);\n }\n\n get key(): PluginKey<PluginState> {\n return pluginKey;\n }\n\n get props(): EditorProps {\n return {\n // same as keymap({})\n handleKeyDown: keydownHandler({\n // hide context menu when Esc was pressed\n Escape: (_state, _dispatch, view) => {\n if (this.tooltip.isTooltipOpen) {\n this.tooltip.hide(view!);\n return true;\n }\n return false;\n },\n }),\n handleDOMEvents: {\n mousedown: (view) => {\n const startState: TinyState = {\n doc: view.state.doc,\n selection: view.state.selection,\n };\n this._isMousePressed = true;\n this.cancelTooltipHiding();\n this.tooltip.hide(view);\n\n const onMouseUp = () => {\n if (this.destroyed) return;\n this._isMousePressed = false;\n this.update(view, startState);\n };\n\n document.addEventListener('mouseup', onMouseUp, {once: true});\n },\n },\n };\n }\n\n get state(): StateField<PluginState> {\n return {\n init: () => ({disabled: false}),\n apply(tr) {\n return {disabled: Boolean(tr.getMeta(HideMetaKey))};\n },\n };\n }\n\n view(view: EditorView) {\n this.update(view);\n return {\n update: this.update.bind(this),\n destroy: () => {\n this.destroyed = true;\n this.cancelTooltipHiding();\n this.tooltip.destroy();\n },\n };\n }\n\n private update(view: EditorView, prevState?: TinyState) {\n if (this._isMousePressed) return;\n\n this.cancelTooltipHiding();\n\n const hideFromTr = pluginKey.getState(view.state)?.disabled;\n\n // Don't show tooltip if editor not mounted to the DOM\n if (hideFromTr || !view.dom.parentNode) {\n this.tooltip.hide(view);\n return;\n }\n\n const {state} = view;\n // Don't do anything if the document/selection didn't change\n if (prevState && prevState.doc.eq(state.doc) && prevState.selection.eq(state.selection)) {\n return;\n }\n\n // Don't show tooltip if editor out of focus\n if (!view.hasFocus()) {\n this.tooltip.hide(view);\n return;\n }\n\n const {selection} = state;\n // Hide the tooltip if the selection is empty\n if (\n selection.empty ||\n !(selection instanceof TextSelection || selection instanceof AllSelection)\n ) {\n this.tooltip.hide(view);\n return;\n }\n\n if (\n // Hide tooltip when one side of selection is inside a codeblock\n isCodeBlock(selection.$from.parent) ||\n isCodeBlock(selection.$to.parent) ||\n // or when selection is inside node where context menu is disabled\n hasParentNode((node: Node) => node.type.spec.selectionContext === false)(selection)\n ) {\n this.tooltip.hide(view);\n return;\n }\n\n this.tooltip.show(view, {\n onOpenChange: (_open, _event, reason) => {\n if (reason !== 'escape-key') this.scheduleTooltipHiding(view);\n },\n });\n }\n\n private scheduleTooltipHiding(view: EditorView) {\n this.hideTimeoutRef = setTimeout(() => {\n // hide tooltip if view is out of focus after 30 ms\n if (!view.hasFocus()) {\n this.tooltip.hide(view);\n }\n }, 30);\n }\n\n private cancelTooltipHiding() {\n if (this.hideTimeoutRef !== null) {\n clearTimeout(this.hideTimeoutRef);\n this.hideTimeoutRef = null;\n }\n }\n}\n\ndeclare module 'prosemirror-model' {\n interface NodeSpec {\n /** Set false to disable the selection-context menu within this node */\n selectionContext?: boolean | undefined;\n }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/SelectionContext/index.ts"],"names":[],"mappings":";;;AAAA,2DAAkD;AAElD,yDAS2B;AAC3B,oCAAoC;AACpC,yDAAgD;AAKhD,mDAAiD;AAEjD,0CAA0D;AAqBnD,MAAM,gBAAgB,GAA2C,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;IACtF,MAAM,EAAC,MAAM,EAAC,GAAG,IAAI,CAAC;IACtB,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7C,OAAO,CAAC,SAAS,CACb,CAAC,EAAC,OAAO,EAAC,EAAE,EAAE,CAAC,IAAI,0BAAM,CAAC,IAAI,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CACzF,CAAC;IACN,CAAC;AACL,CAAC,CAAC;AAPW,QAAA,gBAAgB,oBAO3B;AAEF,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAEnC,MAAM,iBAAiB,GAAG,CAAC,EAAe,EAAE,EAAE;IACjD,OAAO,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC,CAAC;AAFW,QAAA,iBAAiB,qBAE5B;AAEF,MAAM,SAAS,GAAG,IAAI,6BAAS,CAAc,mBAAmB,CAAC,CAAC;AAQlE,MAAM,gBAAgB;IACV,SAAS,GAAG,KAAK,CAAC;IAElB,OAAO,CAAc;IACrB,UAAU,GAAsB,IAAI,CAAC;IACrC,cAAc,GAAyC,IAAI,CAAC;IAE5D,eAAe,GAAG,KAAK,CAAC;IAEhC,YACI,OAAsB,EACtB,UAAyB,EACzB,MAAuB,EACvB,OAAgC;QAEhC,IAAI,CAAC,OAAO,GAAG,IAAI,qBAAW,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE;YACxD,GAAG,OAAO;YACV,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;gBACzC,IAAI,MAAM,KAAK,YAAY,IAAI,IAAI,CAAC,UAAU;oBAC1C,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACpD,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;IAED,IAAI,GAAG;QACH,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,IAAI,KAAK;QACL,OAAO;YACH,qBAAqB;YACrB,aAAa,EAAE,IAAA,mCAAc,EAAC;gBAC1B,yCAAyC;gBACzC,MAAM,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE;oBAChC,IAAI,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;wBAC7B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAK,CAAC,CAAC;wBACzB,OAAO,IAAI,CAAC;oBAChB,CAAC;oBACD,OAAO,KAAK,CAAC;gBACjB,CAAC;aACJ,CAAC;YACF,eAAe,EAAE;gBACb,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE;oBAChB,MAAM,UAAU,GAAc;wBAC1B,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG;wBACnB,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS;qBAClC,CAAC;oBACF,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;oBAC5B,IAAI,CAAC,mBAAmB,EAAE,CAAC;oBAC3B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAExB,MAAM,SAAS,GAAG,GAAG,EAAE;wBACnB,IAAI,IAAI,CAAC,SAAS;4BAAE,OAAO;wBAC3B,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;wBAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;oBAClC,CAAC,CAAC;oBAEF,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,EAAE,EAAC,IAAI,EAAE,IAAI,EAAC,CAAC,CAAC;gBAClE,CAAC;aACJ;SACJ,CAAC;IACN,CAAC;IAED,IAAI,KAAK;QACL,OAAO;YACH,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,EAAC,QAAQ,EAAE,KAAK,EAAC,CAAC;YAC/B,KAAK,CAAC,EAAE;gBACJ,OAAO,EAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,EAAC,CAAC;YACxD,CAAC;SACJ,CAAC;IACN,CAAC;IAED,IAAI,CAAC,IAAgB;QACjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAClB,OAAO;YACH,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;YAC9B,OAAO,EAAE,GAAG,EAAE;gBACV,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;gBACtB,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC3B,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAC3B,CAAC;SACJ,CAAC;IACN,CAAC;IAEO,MAAM,CAAC,IAAgB,EAAE,SAAqB;QAClD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QAEvB,IAAI,IAAI,CAAC,eAAe;YAAE,OAAO;QAEjC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAE3B,MAAM,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC;QAE5D,sDAAsD;QACtD,IAAI,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;YACrC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxB,OAAO;QACX,CAAC;QAED,MAAM,EAAC,KAAK,EAAC,GAAG,IAAI,CAAC;QACrB,4DAA4D;QAC5D,IAAI,SAAS,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;YACtF,OAAO;QACX,CAAC;QAED,4CAA4C;QAC5C,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;YACnB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxB,OAAO;QACX,CAAC;QAED,MAAM,EAAC,SAAS,EAAC,GAAG,KAAK,CAAC;QAC1B,6CAA6C;QAC7C,IACI,SAAS,CAAC,KAAK;YACf,CAAC,CAAC,SAAS,YAAY,iCAAa,IAAI,SAAS,YAAY,gCAAY,CAAC,EAC5E,CAAC;YACC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxB,OAAO;QACX,CAAC;QAED;QACI,gEAAgE;QAChE,IAAA,mBAAW,EAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC;YACnC,IAAA,mBAAW,EAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC;YACjC,kEAAkE;YAClE,IAAA,iCAAa,EAAC,CAAC,IAAU,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,KAAK,KAAK,CAAC,CAAC,SAAS,CAAC,EACrF,CAAC;YACC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxB,OAAO;QACX,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAEO,qBAAqB,CAAC,IAAgB;QAC1C,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE;YAClC,mDAAmD;YACnD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;gBACnB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5B,CAAC;QACL,CAAC,EAAE,EAAE,CAAC,CAAC;IACX,CAAC;IAEO,mBAAmB;QACvB,IAAI,IAAI,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;YAC/B,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC/B,CAAC;IACL,CAAC;CACJ","sourcesContent":["import {keydownHandler} from 'prosemirror-keymap';\nimport type {Node} from 'prosemirror-model';\nimport {\n AllSelection,\n type EditorState,\n Plugin,\n PluginKey,\n type PluginSpec,\n type StateField,\n TextSelection,\n type Transaction,\n} from 'prosemirror-state';\n// @ts-ignore // TODO: fix cjs build\nimport {hasParentNode} from 'prosemirror-utils';\nimport type {EditorProps, EditorView} from 'prosemirror-view';\n\nimport type {ActionStorage, ExtensionAuto} from '../../../core';\nimport type {Logger2} from '../../../logger';\nimport {isCodeBlock} from '../../../utils/nodes';\n\nimport {type ContextConfig, TooltipView} from './tooltip';\n\nexport type {\n ContextConfig as SelectionContextConfig,\n ContextGroupItemData as SelectionContextItemData,\n} from './tooltip';\n\nexport type SelectionContextOptions = {\n config?: ContextConfig;\n /**\n * Placement of context popup\n * @default 'bottom'\n */\n placement?: 'top' | 'bottom';\n /**\n * Prevents context popup from overflowing\n * @default false\n */\n flip?: boolean;\n};\n\nexport const SelectionContext: ExtensionAuto<SelectionContextOptions> = (builder, opts) => {\n const {config} = opts;\n if (Array.isArray(config) && config.length > 0) {\n builder.addPlugin(\n ({actions}) => new Plugin(new SelectionTooltip(actions, config, builder.logger, opts)),\n );\n }\n};\n\nconst HideMetaKey = 'hide-selection-menu';\n\nexport const hideSelectionMenu = (tr: Transaction) => {\n return tr.setMeta(HideMetaKey, true);\n};\n\nconst pluginKey = new PluginKey<PluginState>('selection-context');\n\ntype PluginState = {\n disabled: boolean;\n};\n\ntype TinyState = Pick<EditorState, 'doc' | 'selection'>;\n\nclass SelectionTooltip implements PluginSpec<PluginState> {\n private destroyed = false;\n\n private tooltip: TooltipView;\n private editorView: EditorView | null = null;\n private hideTimeoutRef: ReturnType<typeof setTimeout> | null = null;\n\n private _isMousePressed = false;\n\n constructor(\n actions: ActionStorage,\n menuConfig: ContextConfig,\n logger: Logger2.ILogger,\n options: SelectionContextOptions,\n ) {\n this.tooltip = new TooltipView(actions, menuConfig, logger, {\n ...options,\n onPopupOpenChange: (_open, _event, reason) => {\n if (reason !== 'escape-key' && this.editorView)\n this.scheduleTooltipHiding(this.editorView);\n },\n });\n }\n\n get key(): PluginKey<PluginState> {\n return pluginKey;\n }\n\n get props(): EditorProps {\n return {\n // same as keymap({})\n handleKeyDown: keydownHandler({\n // hide context menu when Esc was pressed\n Escape: (_state, _dispatch, view) => {\n if (this.tooltip.isTooltipOpen) {\n this.tooltip.hide(view!);\n return true;\n }\n return false;\n },\n }),\n handleDOMEvents: {\n mousedown: (view) => {\n const startState: TinyState = {\n doc: view.state.doc,\n selection: view.state.selection,\n };\n this._isMousePressed = true;\n this.cancelTooltipHiding();\n this.tooltip.hide(view);\n\n const onMouseUp = () => {\n if (this.destroyed) return;\n this._isMousePressed = false;\n this.update(view, startState);\n };\n\n document.addEventListener('mouseup', onMouseUp, {once: true});\n },\n },\n };\n }\n\n get state(): StateField<PluginState> {\n return {\n init: () => ({disabled: false}),\n apply(tr) {\n return {disabled: Boolean(tr.getMeta(HideMetaKey))};\n },\n };\n }\n\n view(view: EditorView) {\n this.update(view);\n return {\n update: this.update.bind(this),\n destroy: () => {\n this.destroyed = true;\n this.cancelTooltipHiding();\n this.tooltip.destroy();\n },\n };\n }\n\n private update(view: EditorView, prevState?: TinyState) {\n this.editorView = view;\n\n if (this._isMousePressed) return;\n\n this.cancelTooltipHiding();\n\n const hideFromTr = pluginKey.getState(view.state)?.disabled;\n\n // Don't show tooltip if editor not mounted to the DOM\n if (hideFromTr || !view.dom.parentNode) {\n this.tooltip.hide(view);\n return;\n }\n\n const {state} = view;\n // Don't do anything if the document/selection didn't change\n if (prevState && prevState.doc.eq(state.doc) && prevState.selection.eq(state.selection)) {\n return;\n }\n\n // Don't show tooltip if editor out of focus\n if (!view.hasFocus()) {\n this.tooltip.hide(view);\n return;\n }\n\n const {selection} = state;\n // Hide the tooltip if the selection is empty\n if (\n selection.empty ||\n !(selection instanceof TextSelection || selection instanceof AllSelection)\n ) {\n this.tooltip.hide(view);\n return;\n }\n\n if (\n // Hide tooltip when one side of selection is inside a codeblock\n isCodeBlock(selection.$from.parent) ||\n isCodeBlock(selection.$to.parent) ||\n // or when selection is inside node where context menu is disabled\n hasParentNode((node: Node) => node.type.spec.selectionContext === false)(selection)\n ) {\n this.tooltip.hide(view);\n return;\n }\n\n this.tooltip.show(view);\n }\n\n private scheduleTooltipHiding(view: EditorView) {\n this.hideTimeoutRef = setTimeout(() => {\n // hide tooltip if view is out of focus after 30 ms\n if (!view.hasFocus()) {\n this.tooltip.hide(view);\n }\n }, 30);\n }\n\n private cancelTooltipHiding() {\n if (this.hideTimeoutRef !== null) {\n clearTimeout(this.hideTimeoutRef);\n this.hideTimeoutRef = null;\n }\n }\n}\n\ndeclare module 'prosemirror-model' {\n interface NodeSpec {\n /** Set false to disable the selection-context menu within this node */\n selectionContext?: boolean | undefined;\n }\n}\n"]}
@@ -1,21 +1,15 @@
1
- import { type PopupProps } from '@gravity-ui/uikit';
2
- import type { EditorState } from 'prosemirror-state';
1
+ import type { PopupProps } from '@gravity-ui/uikit';
3
2
  import type { EditorView } from 'prosemirror-view';
4
3
  import type { ActionStorage } from "../../../core/index.js";
5
4
  import { type Logger2 } from "../../../logger.js";
6
- import type { ToolbarButtonPopupData, ToolbarGroupItemData, ToolbarSingleItemData } from "../../../toolbar/index.js";
7
- export type ContextGroupItemData = (ToolbarGroupItemData<ActionStorage> & {
8
- condition?: (state: EditorState) => void;
9
- }) | ((ToolbarSingleItemData<ActionStorage> | ToolbarButtonPopupData<ActionStorage>) & {
10
- condition?: 'enabled';
11
- });
12
- export type ContextGroupData = ContextGroupItemData[];
13
- export type ContextConfig = ContextGroupData[];
5
+ import type { ContextConfig } from "./types.js";
6
+ export type { ContextGroupItemData, ContextGroupData, ContextConfig } from "./types.js";
14
7
  export type TooltipViewParams = {
15
8
  /** @default 'bottom' */
16
9
  placement?: 'top' | 'bottom';
17
10
  /** @default false */
18
11
  flip?: boolean;
12
+ onPopupOpenChange: PopupProps['onOpenChange'];
19
13
  };
20
14
  export declare class TooltipView {
21
15
  #private;
@@ -23,17 +17,19 @@ export declare class TooltipView {
23
17
  private readonly actions;
24
18
  private readonly menuConfig;
25
19
  private readonly placement;
20
+ private readonly onPopupOpenChange;
26
21
  private view;
27
- private baseProps;
22
+ private visible;
23
+ private anchor;
28
24
  private _tooltipRenderItem;
29
25
  constructor(actions: ActionStorage, menuConfig: ContextConfig, logger: Logger2.ILogger, params: TooltipViewParams);
30
26
  get isTooltipOpen(): boolean;
31
- show(view: EditorView, popupProps?: PopupProps): void;
27
+ show(view: EditorView): void;
32
28
  hide(view: EditorView): void;
33
29
  destroy(): void;
34
- private getSelectionTooltipProps;
35
- private getFilteredConfig;
30
+ private readonly handleFocus;
31
+ private readonly handleClick;
36
32
  private renderPopup;
37
33
  private get tooltipRenderItem();
38
- private calcPosition;
34
+ private createVirtualElement;
39
35
  }