@gravity-ui/markdown-editor 14.8.0 → 14.10.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 (166) hide show
  1. package/README.md +16 -14
  2. package/build/cjs/bundle/Editor.d.ts +2 -0
  3. package/build/cjs/bundle/Editor.js +15 -4
  4. package/build/cjs/bundle/MarkdownEditorView.d.ts +27 -0
  5. package/build/cjs/bundle/MarkdownEditorView.js +19 -2
  6. package/build/cjs/bundle/config/action-names.d.ts +1 -1
  7. package/build/cjs/bundle/config/action-names.js +51 -27
  8. package/build/cjs/bundle/config/index.d.ts +3 -0
  9. package/build/cjs/bundle/config/index.js +3 -0
  10. package/build/cjs/bundle/config/markup.js +3 -0
  11. package/build/cjs/bundle/config/wysiwyg.d.ts +3 -0
  12. package/build/cjs/bundle/toolbar/utils/flattenPreset.d.ts +2 -0
  13. package/build/cjs/bundle/toolbar/utils/flattenPreset.js +14 -0
  14. package/build/cjs/bundle/toolbar/utils/toolbarsConfigs.d.ts +17 -0
  15. package/build/cjs/bundle/toolbar/utils/toolbarsConfigs.js +60 -0
  16. package/build/cjs/bundle/types.d.ts +6 -0
  17. package/build/cjs/bundle/useMarkdownEditor.js +8 -2
  18. package/build/cjs/bundle/wysiwyg-preset.d.ts +1 -0
  19. package/build/cjs/bundle/wysiwyg-preset.js +1 -1
  20. package/build/cjs/core/Editor.d.ts +3 -1
  21. package/build/cjs/core/Editor.js +2 -1
  22. package/build/cjs/core/ExtensionsManager.d.ts +2 -0
  23. package/build/cjs/core/ExtensionsManager.js +8 -4
  24. package/build/cjs/core/ParserTokensRegistry.d.ts +2 -1
  25. package/build/cjs/core/ParserTokensRegistry.js +2 -2
  26. package/build/cjs/core/markdown/MarkdownParser.d.ts +3 -1
  27. package/build/cjs/core/markdown/MarkdownParser.js +5 -2
  28. package/build/cjs/core/markdown/MarkdownSerializer.js +1 -1
  29. package/build/cjs/core/markdown/ProseMirrorTransformer/emptyRowTransformer.d.ts +2 -0
  30. package/build/cjs/core/markdown/ProseMirrorTransformer/emptyRowTransformer.js +15 -0
  31. package/build/cjs/core/markdown/ProseMirrorTransformer/getTransformers.d.ts +7 -0
  32. package/build/cjs/core/markdown/ProseMirrorTransformer/getTransformers.js +13 -0
  33. package/build/cjs/core/markdown/ProseMirrorTransformer/index.d.ts +15 -0
  34. package/build/cjs/core/markdown/ProseMirrorTransformer/index.js +25 -0
  35. package/build/cjs/extensions/additional/Math/MathSpecs/index.js +1 -0
  36. package/build/cjs/extensions/base/BaseSchema/BaseSchemaSpecs/index.d.ts +1 -0
  37. package/build/cjs/extensions/base/BaseSchema/BaseSchemaSpecs/index.js +23 -3
  38. package/build/cjs/extensions/behavior/Selection/selection.js +1 -5
  39. package/build/cjs/extensions/markdown/Blockquote/BlockquoteSpecs/index.js +1 -0
  40. package/build/cjs/extensions/markdown/CodeBlock/commands.js +1 -1
  41. package/build/cjs/extensions/markdown/HorizontalRule/HorizontalRuleSpecs/index.js +1 -0
  42. package/build/cjs/extensions/markdown/Link/paste-plugin.js +21 -5
  43. package/build/cjs/extensions/yfm/YfmTabs/YfmTabsSpecs/schema.js +1 -0
  44. package/build/cjs/i18n/empty-row/en.json +3 -0
  45. package/build/cjs/i18n/empty-row/index.d.ts +5 -0
  46. package/build/cjs/i18n/empty-row/index.js +9 -0
  47. package/build/cjs/i18n/empty-row/ru.json +3 -0
  48. package/build/cjs/i18n/menubar/en.json +1 -0
  49. package/build/cjs/i18n/menubar/index.d.ts +2 -1
  50. package/build/cjs/i18n/menubar/ru.json +1 -0
  51. package/build/cjs/i18n/yfm-note/index.d.ts +1 -1
  52. package/build/cjs/index.d.ts +1 -0
  53. package/build/cjs/index.js +1 -0
  54. package/build/cjs/markup/codemirror/autocomplete/emptyRow.d.ts +9 -0
  55. package/build/cjs/markup/codemirror/autocomplete/emptyRow.js +26 -0
  56. package/build/cjs/markup/codemirror/autocomplete/index.d.ts +5 -0
  57. package/build/cjs/markup/codemirror/autocomplete/index.js +14 -0
  58. package/build/cjs/markup/codemirror/create.d.ts +1 -0
  59. package/build/cjs/markup/codemirror/create.js +30 -12
  60. package/build/cjs/markup/codemirror/smart-reindent/index.d.ts +4 -0
  61. package/build/cjs/markup/codemirror/smart-reindent/index.js +42 -0
  62. package/build/cjs/markup/codemirror/smart-reindent/utils.d.ts +15 -0
  63. package/build/cjs/markup/codemirror/smart-reindent/utils.js +59 -0
  64. package/build/cjs/markup/codemirror/yfm.d.ts +2 -1
  65. package/build/cjs/markup/codemirror/yfm.js +3 -3
  66. package/build/cjs/markup/commands/emptyRow.d.ts +2 -0
  67. package/build/cjs/markup/commands/emptyRow.js +43 -0
  68. package/build/cjs/markup/commands/index.d.ts +1 -0
  69. package/build/cjs/markup/commands/index.js +1 -0
  70. package/build/cjs/modules/toolbars/constants.d.ts +13 -0
  71. package/build/cjs/modules/toolbars/constants.js +18 -0
  72. package/build/cjs/modules/toolbars/items.d.ts +127 -0
  73. package/build/cjs/modules/toolbars/items.js +736 -0
  74. package/build/cjs/modules/toolbars/presets.d.ts +6 -0
  75. package/build/cjs/modules/toolbars/presets.js +465 -0
  76. package/build/cjs/modules/toolbars/types.d.ts +62 -0
  77. package/build/cjs/modules/toolbars/types.js +2 -0
  78. package/build/cjs/shortcuts/const.d.ts +1 -0
  79. package/build/cjs/shortcuts/const.js +1 -0
  80. package/build/cjs/shortcuts/default.js +1 -0
  81. package/build/cjs/toolbar/types.d.ts +8 -0
  82. package/build/cjs/toolbar/types.js +2 -0
  83. package/build/cjs/version.js +1 -1
  84. package/build/esm/bundle/Editor.d.ts +2 -0
  85. package/build/esm/bundle/Editor.js +15 -4
  86. package/build/esm/bundle/MarkdownEditorView.d.ts +27 -0
  87. package/build/esm/bundle/MarkdownEditorView.js +19 -2
  88. package/build/esm/bundle/config/action-names.d.ts +1 -1
  89. package/build/esm/bundle/config/action-names.js +51 -27
  90. package/build/esm/bundle/config/index.d.ts +3 -0
  91. package/build/esm/bundle/config/index.js +3 -0
  92. package/build/esm/bundle/config/markup.js +3 -0
  93. package/build/esm/bundle/config/wysiwyg.d.ts +3 -0
  94. package/build/esm/bundle/toolbar/utils/flattenPreset.d.ts +2 -0
  95. package/build/esm/bundle/toolbar/utils/flattenPreset.js +10 -0
  96. package/build/esm/bundle/toolbar/utils/toolbarsConfigs.d.ts +17 -0
  97. package/build/esm/bundle/toolbar/utils/toolbarsConfigs.js +55 -0
  98. package/build/esm/bundle/types.d.ts +6 -0
  99. package/build/esm/bundle/useMarkdownEditor.js +8 -2
  100. package/build/esm/bundle/wysiwyg-preset.d.ts +1 -0
  101. package/build/esm/bundle/wysiwyg-preset.js +1 -1
  102. package/build/esm/core/Editor.d.ts +3 -1
  103. package/build/esm/core/Editor.js +2 -1
  104. package/build/esm/core/ExtensionsManager.d.ts +2 -0
  105. package/build/esm/core/ExtensionsManager.js +8 -4
  106. package/build/esm/core/ParserTokensRegistry.d.ts +2 -1
  107. package/build/esm/core/ParserTokensRegistry.js +2 -2
  108. package/build/esm/core/markdown/MarkdownParser.d.ts +3 -1
  109. package/build/esm/core/markdown/MarkdownParser.js +5 -2
  110. package/build/esm/core/markdown/MarkdownSerializer.js +1 -1
  111. package/build/esm/core/markdown/ProseMirrorTransformer/emptyRowTransformer.d.ts +2 -0
  112. package/build/esm/core/markdown/ProseMirrorTransformer/emptyRowTransformer.js +11 -0
  113. package/build/esm/core/markdown/ProseMirrorTransformer/getTransformers.d.ts +7 -0
  114. package/build/esm/core/markdown/ProseMirrorTransformer/getTransformers.js +9 -0
  115. package/build/esm/core/markdown/ProseMirrorTransformer/index.d.ts +15 -0
  116. package/build/esm/core/markdown/ProseMirrorTransformer/index.js +21 -0
  117. package/build/esm/extensions/additional/Math/MathSpecs/index.js +1 -0
  118. package/build/esm/extensions/base/BaseSchema/BaseSchemaSpecs/index.d.ts +1 -0
  119. package/build/esm/extensions/base/BaseSchema/BaseSchemaSpecs/index.js +23 -3
  120. package/build/esm/extensions/behavior/Selection/selection.js +1 -5
  121. package/build/esm/extensions/markdown/Blockquote/BlockquoteSpecs/index.js +1 -0
  122. package/build/esm/extensions/markdown/CodeBlock/commands.js +1 -1
  123. package/build/esm/extensions/markdown/HorizontalRule/HorizontalRuleSpecs/index.js +1 -0
  124. package/build/esm/extensions/markdown/Link/paste-plugin.js +21 -5
  125. package/build/esm/extensions/yfm/YfmTabs/YfmTabsSpecs/schema.js +1 -0
  126. package/build/esm/i18n/empty-row/en.json +3 -0
  127. package/build/esm/i18n/empty-row/index.d.ts +5 -0
  128. package/build/esm/i18n/empty-row/index.js +5 -0
  129. package/build/esm/i18n/empty-row/ru.json +3 -0
  130. package/build/esm/i18n/menubar/en.json +1 -0
  131. package/build/esm/i18n/menubar/index.d.ts +2 -1
  132. package/build/esm/i18n/menubar/ru.json +1 -0
  133. package/build/esm/i18n/yfm-note/index.d.ts +1 -1
  134. package/build/esm/index.d.ts +1 -0
  135. package/build/esm/index.js +1 -0
  136. package/build/esm/markup/codemirror/autocomplete/emptyRow.d.ts +9 -0
  137. package/build/esm/markup/codemirror/autocomplete/emptyRow.js +23 -0
  138. package/build/esm/markup/codemirror/autocomplete/index.d.ts +5 -0
  139. package/build/esm/markup/codemirror/autocomplete/index.js +10 -0
  140. package/build/esm/markup/codemirror/create.d.ts +1 -0
  141. package/build/esm/markup/codemirror/create.js +31 -13
  142. package/build/esm/markup/codemirror/smart-reindent/index.d.ts +4 -0
  143. package/build/esm/markup/codemirror/smart-reindent/index.js +38 -0
  144. package/build/esm/markup/codemirror/smart-reindent/utils.d.ts +15 -0
  145. package/build/esm/markup/codemirror/smart-reindent/utils.js +55 -0
  146. package/build/esm/markup/codemirror/yfm.d.ts +2 -1
  147. package/build/esm/markup/codemirror/yfm.js +1 -1
  148. package/build/esm/markup/commands/emptyRow.d.ts +2 -0
  149. package/build/esm/markup/commands/emptyRow.js +39 -0
  150. package/build/esm/markup/commands/index.d.ts +1 -0
  151. package/build/esm/markup/commands/index.js +1 -0
  152. package/build/esm/modules/toolbars/constants.d.ts +13 -0
  153. package/build/esm/modules/toolbars/constants.js +15 -0
  154. package/build/esm/modules/toolbars/items.d.ts +127 -0
  155. package/build/esm/modules/toolbars/items.js +730 -0
  156. package/build/esm/modules/toolbars/presets.d.ts +6 -0
  157. package/build/esm/modules/toolbars/presets.js +462 -0
  158. package/build/esm/modules/toolbars/types.d.ts +62 -0
  159. package/build/esm/modules/toolbars/types.js +1 -0
  160. package/build/esm/shortcuts/const.d.ts +1 -0
  161. package/build/esm/shortcuts/const.js +1 -0
  162. package/build/esm/shortcuts/default.js +1 -0
  163. package/build/esm/toolbar/types.d.ts +8 -0
  164. package/build/esm/toolbar/types.js +2 -0
  165. package/build/esm/version.js +1 -1
  166. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- var _ExtensionsManager_schemaRegistry, _ExtensionsManager_parserRegistry, _ExtensionsManager_serializerRegistry, _ExtensionsManager_nodeViewCreators, _ExtensionsManager_markViewCreators, _ExtensionsManager_mdForMarkup, _ExtensionsManager_mdForText, _ExtensionsManager_extensions, _ExtensionsManager_builder, _ExtensionsManager_spec, _ExtensionsManager_deps, _ExtensionsManager_plugins, _ExtensionsManager_actions, _ExtensionsManager_nodeViews, _ExtensionsManager_markViews;
2
+ var _ExtensionsManager_schemaRegistry, _ExtensionsManager_parserRegistry, _ExtensionsManager_serializerRegistry, _ExtensionsManager_nodeViewCreators, _ExtensionsManager_markViewCreators, _ExtensionsManager_pmTransformers, _ExtensionsManager_mdForMarkup, _ExtensionsManager_mdForText, _ExtensionsManager_extensions, _ExtensionsManager_builder, _ExtensionsManager_spec, _ExtensionsManager_deps, _ExtensionsManager_plugins, _ExtensionsManager_actions, _ExtensionsManager_nodeViews, _ExtensionsManager_markViews;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.ExtensionsManager = void 0;
5
5
  const tslib_1 = require("tslib");
@@ -17,6 +17,7 @@ class ExtensionsManager {
17
17
  _ExtensionsManager_serializerRegistry.set(this, new SerializerTokensRegistry_1.SerializerTokensRegistry());
18
18
  _ExtensionsManager_nodeViewCreators.set(this, new Map());
19
19
  _ExtensionsManager_markViewCreators.set(this, new Map());
20
+ _ExtensionsManager_pmTransformers.set(this, []);
20
21
  _ExtensionsManager_mdForMarkup.set(this, void 0);
21
22
  _ExtensionsManager_mdForText.set(this, void 0);
22
23
  _ExtensionsManager_extensions.set(this, void 0);
@@ -51,6 +52,9 @@ class ExtensionsManager {
51
52
  tslib_1.__classPrivateFieldGet(this, _ExtensionsManager_mdForMarkup, "f").linkify.tlds(options.linkifyTlds, true);
52
53
  tslib_1.__classPrivateFieldGet(this, _ExtensionsManager_mdForText, "f").linkify.tlds(options.linkifyTlds, true);
53
54
  }
55
+ if (options.pmTransformers) {
56
+ tslib_1.__classPrivateFieldSet(this, _ExtensionsManager_pmTransformers, options.pmTransformers, "f");
57
+ }
54
58
  // TODO: add prefilled context
55
59
  tslib_1.__classPrivateFieldSet(this, _ExtensionsManager_builder, new ExtensionBuilder_1.ExtensionBuilder(), "f");
56
60
  }
@@ -80,8 +84,8 @@ class ExtensionsManager {
80
84
  tslib_1.__classPrivateFieldSet(this, _ExtensionsManager_deps, {
81
85
  schema,
82
86
  actions: new ActionsManager_1.ActionsManager(),
83
- markupParser: tslib_1.__classPrivateFieldGet(this, _ExtensionsManager_parserRegistry, "f").createParser(schema, tslib_1.__classPrivateFieldGet(this, _ExtensionsManager_mdForMarkup, "f")),
84
- textParser: tslib_1.__classPrivateFieldGet(this, _ExtensionsManager_parserRegistry, "f").createParser(schema, tslib_1.__classPrivateFieldGet(this, _ExtensionsManager_mdForText, "f")),
87
+ markupParser: tslib_1.__classPrivateFieldGet(this, _ExtensionsManager_parserRegistry, "f").createParser(schema, tslib_1.__classPrivateFieldGet(this, _ExtensionsManager_mdForMarkup, "f"), tslib_1.__classPrivateFieldGet(this, _ExtensionsManager_pmTransformers, "f")),
88
+ textParser: tslib_1.__classPrivateFieldGet(this, _ExtensionsManager_parserRegistry, "f").createParser(schema, tslib_1.__classPrivateFieldGet(this, _ExtensionsManager_mdForText, "f"), tslib_1.__classPrivateFieldGet(this, _ExtensionsManager_pmTransformers, "f")),
85
89
  serializer: tslib_1.__classPrivateFieldGet(this, _ExtensionsManager_serializerRegistry, "f").createSerializer(),
86
90
  }, "f");
87
91
  }
@@ -97,4 +101,4 @@ class ExtensionsManager {
97
101
  }
98
102
  }
99
103
  exports.ExtensionsManager = ExtensionsManager;
100
- _ExtensionsManager_schemaRegistry = new WeakMap(), _ExtensionsManager_parserRegistry = new WeakMap(), _ExtensionsManager_serializerRegistry = new WeakMap(), _ExtensionsManager_nodeViewCreators = new WeakMap(), _ExtensionsManager_markViewCreators = new WeakMap(), _ExtensionsManager_mdForMarkup = new WeakMap(), _ExtensionsManager_mdForText = new WeakMap(), _ExtensionsManager_extensions = new WeakMap(), _ExtensionsManager_builder = new WeakMap(), _ExtensionsManager_spec = new WeakMap(), _ExtensionsManager_deps = new WeakMap(), _ExtensionsManager_plugins = new WeakMap(), _ExtensionsManager_actions = new WeakMap(), _ExtensionsManager_nodeViews = new WeakMap(), _ExtensionsManager_markViews = new WeakMap();
104
+ _ExtensionsManager_schemaRegistry = new WeakMap(), _ExtensionsManager_parserRegistry = new WeakMap(), _ExtensionsManager_serializerRegistry = new WeakMap(), _ExtensionsManager_nodeViewCreators = new WeakMap(), _ExtensionsManager_markViewCreators = new WeakMap(), _ExtensionsManager_pmTransformers = new WeakMap(), _ExtensionsManager_mdForMarkup = new WeakMap(), _ExtensionsManager_mdForText = new WeakMap(), _ExtensionsManager_extensions = new WeakMap(), _ExtensionsManager_builder = new WeakMap(), _ExtensionsManager_spec = new WeakMap(), _ExtensionsManager_deps = new WeakMap(), _ExtensionsManager_plugins = new WeakMap(), _ExtensionsManager_actions = new WeakMap(), _ExtensionsManager_nodeViews = new WeakMap(), _ExtensionsManager_markViews = new WeakMap();
@@ -1,8 +1,9 @@
1
1
  import type MarkdownIt from 'markdown-it';
2
2
  import type { Schema } from 'prosemirror-model';
3
+ import { TransformFn } from './markdown/ProseMirrorTransformer';
3
4
  import type { Parser, ParserToken } from './types/parser';
4
5
  export declare class ParserTokensRegistry {
5
6
  #private;
6
7
  addToken(name: string, token: ParserToken): this;
7
- createParser(schema: Schema, tokenizer: MarkdownIt): Parser;
8
+ createParser(schema: Schema, tokenizer: MarkdownIt, pmTransformers: TransformFn[]): Parser;
8
9
  }
@@ -12,8 +12,8 @@ class ParserTokensRegistry {
12
12
  tslib_1.__classPrivateFieldGet(this, _ParserTokensRegistry_tokens, "f")[name] = token;
13
13
  return this;
14
14
  }
15
- createParser(schema, tokenizer) {
16
- return new MarkdownParser_1.MarkdownParser(schema, tokenizer, tslib_1.__classPrivateFieldGet(this, _ParserTokensRegistry_tokens, "f"));
15
+ createParser(schema, tokenizer, pmTransformers) {
16
+ return new MarkdownParser_1.MarkdownParser(schema, tokenizer, tslib_1.__classPrivateFieldGet(this, _ParserTokensRegistry_tokens, "f"), pmTransformers);
17
17
  }
18
18
  }
19
19
  exports.ParserTokensRegistry = ParserTokensRegistry;
@@ -2,6 +2,7 @@ import type { Match } from 'linkify-it';
2
2
  import type MarkdownIt from 'markdown-it';
3
3
  import { Mark, Node, NodeType, Schema } from 'prosemirror-model';
4
4
  import type { Parser, ParserToken } from '../types/parser';
5
+ import { TransformFn } from './ProseMirrorTransformer';
5
6
  declare type TokenAttrs = {
6
7
  [name: string]: unknown;
7
8
  };
@@ -15,7 +16,8 @@ export declare class MarkdownParser implements Parser {
15
16
  marks: readonly Mark[];
16
17
  tokens: Record<string, ParserToken>;
17
18
  tokenizer: MarkdownIt;
18
- constructor(schema: Schema, tokenizer: MarkdownIt, tokens: Record<string, ParserToken>);
19
+ pmTransformers: TransformFn[];
20
+ constructor(schema: Schema, tokenizer: MarkdownIt, tokens: Record<string, ParserToken>, pmTransformers: TransformFn[]);
19
21
  validateLink(url: string): boolean;
20
22
  normalizeLink(url: string): string;
21
23
  normalizeLinkText(url: string): string;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MarkdownParser = void 0;
4
4
  const prosemirror_model_1 = require("prosemirror-model");
5
5
  const logger_1 = require("../../logger");
6
+ const ProseMirrorTransformer_1 = require("./ProseMirrorTransformer");
6
7
  const openSuffix = '_open';
7
8
  const closeSuffix = '_close';
8
9
  var TokenType;
@@ -12,12 +13,13 @@ var TokenType;
12
13
  TokenType["default"] = "default";
13
14
  })(TokenType || (TokenType = {}));
14
15
  class MarkdownParser {
15
- constructor(schema, tokenizer, tokens) {
16
+ constructor(schema, tokenizer, tokens, pmTransformers) {
16
17
  this.stack = [];
17
18
  this.schema = schema;
18
19
  this.marks = prosemirror_model_1.Mark.none;
19
20
  this.tokens = tokens;
20
21
  this.tokenizer = tokenizer;
22
+ this.pmTransformers = pmTransformers;
21
23
  }
22
24
  validateLink(url) {
23
25
  return this.tokenizer.validateLink(url);
@@ -50,7 +52,8 @@ class MarkdownParser {
50
52
  do {
51
53
  doc = this.closeNode();
52
54
  } while (this.stack.length);
53
- return (doc || this.schema.topNodeType.createAndFill());
55
+ const pmTransformer = new ProseMirrorTransformer_1.ProseMirrorTransformer(this.pmTransformers);
56
+ return doc ? pmTransformer.transform(doc) : this.schema.topNodeType.createAndFill();
54
57
  }
55
58
  finally {
56
59
  logger_1.logger.metrics({ component: 'parser', event: 'parse', duration: Date.now() - time });
@@ -165,7 +165,7 @@ class MarkdownSerializerState {
165
165
  const startOfLine = this.atBlank() || this.closed;
166
166
  this.write();
167
167
  let text = lines[i];
168
- if (escape !== false)
168
+ if (escape !== false && this.options.escape !== false)
169
169
  text = this.esc(text, startOfLine);
170
170
  if (this.escapeWhitespace)
171
171
  text = this.escWhitespace(text);
@@ -0,0 +1,2 @@
1
+ import { TransformFn } from './index';
2
+ export declare const transformEmptyParagraph: TransformFn;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.transformEmptyParagraph = void 0;
4
+ const transformEmptyParagraph = (node) => {
5
+ var _a, _b;
6
+ if (node.type !== 'paragraph')
7
+ return;
8
+ if (((_a = node.content) === null || _a === void 0 ? void 0 : _a.length) !== 1)
9
+ return;
10
+ if (((_b = node.content[0]) === null || _b === void 0 ? void 0 : _b.type) !== 'text')
11
+ return;
12
+ if (node.content[0].text === String.fromCharCode(160))
13
+ delete node.content;
14
+ };
15
+ exports.transformEmptyParagraph = transformEmptyParagraph;
@@ -0,0 +1,7 @@
1
+ import { TransformFn } from '.';
2
+ declare type GetTransformersProps = {
3
+ emptyRowTransformer?: boolean;
4
+ };
5
+ declare type GetPMTransformersType = (config: GetTransformersProps) => TransformFn[];
6
+ export declare const getPMTransformers: GetPMTransformersType;
7
+ export {};
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPMTransformers = void 0;
4
+ // TODO: add a new method to the ExtensionBuilder
5
+ const emptyRowTransformer_1 = require("./emptyRowTransformer");
6
+ const getPMTransformers = ({ emptyRowTransformer }) => {
7
+ const transformers = [];
8
+ if (emptyRowTransformer) {
9
+ transformers.push(emptyRowTransformer_1.transformEmptyParagraph);
10
+ }
11
+ return transformers;
12
+ };
13
+ exports.getPMTransformers = getPMTransformers;
@@ -0,0 +1,15 @@
1
+ import { Node } from 'prosemirror-model';
2
+ declare type PMNodeJSON = {
3
+ type: string;
4
+ attrs?: Record<string, any>;
5
+ content?: PMNodeJSON[];
6
+ text?: string;
7
+ };
8
+ export declare type TransformFn = (node: PMNodeJSON) => void;
9
+ export declare class ProseMirrorTransformer {
10
+ private readonly _transformers;
11
+ constructor(fns: TransformFn[]);
12
+ transform(doc: Node): Node;
13
+ transformJSON(node: PMNodeJSON): void;
14
+ }
15
+ export {};
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProseMirrorTransformer = void 0;
4
+ const prosemirror_model_1 = require("prosemirror-model");
5
+ class ProseMirrorTransformer {
6
+ constructor(fns) {
7
+ this._transformers = fns;
8
+ }
9
+ transform(doc) {
10
+ const docJSON = doc.toJSON();
11
+ this.transformJSON(docJSON);
12
+ return prosemirror_model_1.Node.fromJSON(doc.type.schema, docJSON);
13
+ }
14
+ transformJSON(node) {
15
+ for (const fn of this._transformers) {
16
+ fn(node);
17
+ }
18
+ if (node.content) {
19
+ for (const child of node.content) {
20
+ this.transformJSON(child);
21
+ }
22
+ }
23
+ }
24
+ }
25
+ exports.ProseMirrorTransformer = ProseMirrorTransformer;
@@ -44,6 +44,7 @@ const MathSpecs = (builder) => {
44
44
  code: true,
45
45
  toDOM: () => ['div', { class: 'math-block' }, 0],
46
46
  parseDOM: [{ tag: 'div.math-block', priority: 200 }],
47
+ selectable: true,
47
48
  },
48
49
  fromMd: {
49
50
  tokenName: 'math_block',
@@ -8,5 +8,6 @@ export declare enum BaseNode {
8
8
  export declare const pType: (schema: import("prosemirror-model").Schema<any, any>) => import("prosemirror-model").NodeType;
9
9
  export declare type BaseSchemaSpecsOptions = {
10
10
  paragraphPlaceholder?: NonNullable<NodeSpec['placeholder']>['content'];
11
+ preserveEmptyRows?: boolean;
11
12
  };
12
13
  export declare const BaseSchemaSpecs: ExtensionAuto<BaseSchemaSpecsOptions>;
@@ -45,6 +45,7 @@ const BaseSchemaSpecs = (builder, opts) => {
45
45
  0,
46
46
  ];
47
47
  },
48
+ selectable: true,
48
49
  placeholder: opts.paragraphPlaceholder
49
50
  ? {
50
51
  content: opts.paragraphPlaceholder,
@@ -53,9 +54,28 @@ const BaseSchemaSpecs = (builder, opts) => {
53
54
  : undefined,
54
55
  },
55
56
  fromMd: { tokenSpec: { name: BaseNode.Paragraph, type: 'block' } },
56
- toMd: (state, node) => {
57
- state.renderInline(node);
58
- state.closeBlock(node);
57
+ toMd: (state, node, parent) => {
58
+ /*
59
+ An empty line is added only if there is some content in the parent element.
60
+ This is necessary in order to prevent an empty document with empty lines
61
+ */
62
+ if (opts.preserveEmptyRows && !node.content.size) {
63
+ let isParentEmpty = true;
64
+ for (let index = 0; index < parent.content.childCount; index++) {
65
+ const parentChild = parent.content.child(index);
66
+ if (parentChild.content.size !== 0 ||
67
+ parentChild.type.name !== 'paragraph') {
68
+ isParentEmpty = false;
69
+ }
70
+ }
71
+ if (!isParentEmpty) {
72
+ state.write('&nbsp;\n\n');
73
+ }
74
+ }
75
+ else {
76
+ state.renderInline(node);
77
+ state.closeBlock(node);
78
+ }
59
79
  },
60
80
  }));
61
81
  };
@@ -74,11 +74,7 @@ const getTopLevelNodesFromSelection = (selection, doc) => {
74
74
  const { from, to } = selection;
75
75
  doc.nodesBetween(from, to, (node, pos) => {
76
76
  const withinSelection = from <= pos && pos + node.nodeSize <= to;
77
- if (node &&
78
- node.type.name !== 'paragraph' &&
79
- !node.isText &&
80
- node.type.spec.selectable &&
81
- withinSelection) {
77
+ if (node && !node.isText && node.type.spec.selectable !== false && withinSelection) {
82
78
  nodes.push({ node, pos });
83
79
  return false;
84
80
  }
@@ -16,6 +16,7 @@ const BlockquoteSpecs = (builder) => {
16
16
  toDOM() {
17
17
  return ['blockquote', 0];
18
18
  },
19
+ selectable: true,
19
20
  },
20
21
  fromMd: { tokenSpec: { name: exports.blockquoteNodeName, type: 'block' } },
21
22
  toMd: (state, node) => {
@@ -20,7 +20,7 @@ const setCodeBlockType = ({ serializer }) => (state, dispatch) => {
20
20
  if (!(0, prosemirror_commands_1.setBlockType)(nodeType)(state))
21
21
  return false;
22
22
  if (dispatch) {
23
- const markup = serializer.serialize(state.selection.content().content);
23
+ const markup = serializer.serialize(state.selection.content().content, { escape: false });
24
24
  dispatch(state.tr.replaceSelectionWith(nodeType.createAndFill({}, markup ? state.schema.text(markup) : null)));
25
25
  }
26
26
  return true;
@@ -14,6 +14,7 @@ const HorizontalRuleSpecs = (builder) => {
14
14
  toDOM() {
15
15
  return ['div', ['hr']];
16
16
  },
17
+ selectable: true,
17
18
  },
18
19
  fromMd: {
19
20
  tokenName: 'hr',
@@ -13,21 +13,37 @@ function linkPasteEnhance({ markupParser: parser }) {
13
13
  paste(view, e) {
14
14
  const { state, dispatch } = view;
15
15
  const sel = state.selection;
16
+ let tr = null;
16
17
  if ((0, selection_1.isTextSelection)(sel) ||
17
18
  ((0, selection_1.isNodeSelection)(sel) && sel.node.type === (0, Image_1.imageType)(state.schema))) {
18
19
  const { $from, $to } = sel;
19
- if ($from.pos !== $to.pos && $from.sameParent($to)) {
20
+ if ($from.pos === $to.pos) {
20
21
  const url = getUrl(e.clipboardData, parser);
21
22
  if (url) {
22
- const tr = state.tr.addMark($from.pos, $to.pos, (0, index_1.linkType)(state.schema).create({
23
+ const linkMarkType = (0, index_1.linkType)(state.schema);
24
+ tr = state.tr.replaceSelectionWith(state.schema.text(url, [
25
+ ...$from
26
+ .marks()
27
+ .filter((mark) => mark.type !== linkMarkType),
28
+ linkMarkType.create({ [index_1.LinkAttr.Href]: url }),
29
+ ]), false);
30
+ }
31
+ }
32
+ else if ($from.sameParent($to)) {
33
+ const url = getUrl(e.clipboardData, parser);
34
+ if (url) {
35
+ tr = state.tr.addMark($from.pos, $to.pos, (0, index_1.linkType)(state.schema).create({
23
36
  [index_1.LinkAttr.Href]: url,
24
37
  }));
25
- dispatch(tr.setSelection(prosemirror_state_1.TextSelection.create(tr.doc, $to.pos)));
26
- e.preventDefault();
27
- return true;
38
+ tr.setSelection(prosemirror_state_1.TextSelection.create(tr.doc, $to.pos));
28
39
  }
29
40
  }
30
41
  }
42
+ if (tr) {
43
+ dispatch(tr.scrollIntoView());
44
+ e.preventDefault();
45
+ return true;
46
+ }
31
47
  return false;
32
48
  },
33
49
  },
@@ -67,6 +67,7 @@ const getSchemaSpecs = (opts, placeholder) => {
67
67
  toDOM(node) {
68
68
  return ['div', node.attrs, 0];
69
69
  },
70
+ selectable: true,
70
71
  complex: 'root',
71
72
  },
72
73
  [const_1.TabsNode.TabsList]: {
@@ -0,0 +1,3 @@
1
+ {
2
+ "snippet.text": "Empty row"
3
+ }
@@ -0,0 +1,5 @@
1
+ export declare const i18n: <G extends "snippet.text", S extends string>(key: G | (string extends S ? S : never), params?: {
2
+ [key: string]: any;
3
+ } | undefined) => S extends G ? {
4
+ "snippet.text": string;
5
+ }[G] : string;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.i18n = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const i18n_1 = require("../i18n");
6
+ const en_json_1 = tslib_1.__importDefault(require("./en.json"));
7
+ const ru_json_1 = tslib_1.__importDefault(require("./ru.json"));
8
+ const KEYSET = 'empty-row';
9
+ exports.i18n = (0, i18n_1.registerKeyset)(KEYSET, { en: en_json_1.default, ru: ru_json_1.default });
@@ -0,0 +1,3 @@
1
+ {
2
+ "snippet.text": "Пустая строка"
3
+ }
@@ -44,6 +44,7 @@
44
44
  "mermaid": "Mermaid",
45
45
  "mono": "Monospace",
46
46
  "more_action": "More action",
47
+ "move_list": "Move list item",
47
48
  "note": "Note",
48
49
  "olist": "Ordered list",
49
50
  "quote": "Quote",
@@ -1,4 +1,4 @@
1
- export declare const i18n: <G extends "bold" | "code" | "colorify" | "mono" | "link" | "italic" | "strike" | "underline" | "mark" | "quote" | "text" | "html" | "cut" | "table" | "image" | "code_inline" | "list" | "heading" | "note" | "file" | "checkbox" | "emoji" | "undo" | "redo" | "heading1" | "heading2" | "heading3" | "heading4" | "heading5" | "heading6" | "math_inline" | "math_block" | "tabs" | "mermaid" | "gpt" | "codeblock" | "math" | "colorify__color_blue" | "colorify__color_default" | "colorify__color_gray" | "colorify__color_green" | "colorify__color_orange" | "colorify__color_red" | "colorify__color_violet" | "colorify__color_yellow" | "colorify__group_text" | "emoji__hint" | "folding-heading" | "folding-heading__hint" | "hrule" | "list__action_lift" | "list__action_sink" | "list_action_disabled" | "more_action" | "olist" | "ulist", S extends string>(key: G | (string extends S ? S : never), params?: {
1
+ export declare const i18n: <G extends "bold" | "code" | "colorify" | "mono" | "link" | "italic" | "strike" | "underline" | "mark" | "quote" | "text" | "html" | "cut" | "table" | "image" | "code_inline" | "list" | "heading" | "note" | "file" | "checkbox" | "emoji" | "gpt" | "heading1" | "heading2" | "heading3" | "heading4" | "heading5" | "heading6" | "math_block" | "math_inline" | "mermaid" | "redo" | "tabs" | "undo" | "codeblock" | "math" | "colorify__color_blue" | "colorify__color_default" | "colorify__color_gray" | "colorify__color_green" | "colorify__color_orange" | "colorify__color_red" | "colorify__color_violet" | "colorify__color_yellow" | "colorify__group_text" | "emoji__hint" | "folding-heading" | "folding-heading__hint" | "hrule" | "list__action_lift" | "list__action_sink" | "list_action_disabled" | "more_action" | "move_list" | "olist" | "ulist", S extends string>(key: G | (string extends S ? S : never), params?: {
2
2
  [key: string]: any;
3
3
  } | undefined) => S extends G ? {
4
4
  bold: string;
@@ -46,6 +46,7 @@ export declare const i18n: <G extends "bold" | "code" | "colorify" | "mono" | "l
46
46
  mermaid: string;
47
47
  mono: string;
48
48
  more_action: string;
49
+ move_list: string;
49
50
  note: string;
50
51
  olist: string;
51
52
  quote: string;
@@ -44,6 +44,7 @@
44
44
  "mermaid": "Mermaid",
45
45
  "mono": "Моноширинный",
46
46
  "more_action": "Другие действия",
47
+ "move_list": "Переместить элемент списка",
47
48
  "note": "Примечание",
48
49
  "olist": "Нумерованный список",
49
50
  "quote": "Цитата",
@@ -1,4 +1,4 @@
1
- export declare const i18n: <G extends "remove" | "info" | "warning" | "tip" | "alert", S extends string>(key: G | (string extends S ? S : never), params?: {
1
+ export declare const i18n: <G extends "remove" | "info" | "tip" | "warning" | "alert", S extends string>(key: G | (string extends S ? S : never), params?: {
2
2
  [key: string]: any;
3
3
  } | undefined) => S extends G ? {
4
4
  info: string;
@@ -1,6 +1,7 @@
1
1
  export * from './common';
2
2
  export * from './core';
3
3
  export * from './toolbar';
4
+ export * from './modules/toolbars/types';
4
5
  export * from './react-utils';
5
6
  export * from './classname';
6
7
  export * from './logger';
@@ -5,6 +5,7 @@ const tslib_1 = require("tslib");
5
5
  tslib_1.__exportStar(require("./common"), exports);
6
6
  tslib_1.__exportStar(require("./core"), exports);
7
7
  tslib_1.__exportStar(require("./toolbar"), exports);
8
+ tslib_1.__exportStar(require("./modules/toolbars/types"), exports);
8
9
  tslib_1.__exportStar(require("./react-utils"), exports);
9
10
  tslib_1.__exportStar(require("./classname"), exports);
10
11
  tslib_1.__exportStar(require("./logger"), exports);
@@ -0,0 +1,9 @@
1
+ import { CompletionContext, CompletionResult } from '@codemirror/autocomplete';
2
+ export declare const emptyRowSnippetTemplate = "&nbsp;\n\n";
3
+ export declare const emptyRowSnippet: (editor: {
4
+ state: import("@codemirror/state").EditorState;
5
+ dispatch: (tr: import("@codemirror/state").Transaction) => void;
6
+ }, completion: import("@codemirror/autocomplete").Completion | null, from: number, to: number) => void;
7
+ export declare const emptyRowAutocomplete: {
8
+ autocomplete: (context: CompletionContext) => CompletionResult | null;
9
+ };
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.emptyRowAutocomplete = exports.emptyRowSnippet = exports.emptyRowSnippetTemplate = void 0;
4
+ const autocomplete_1 = require("@codemirror/autocomplete");
5
+ const empty_row_1 = require("../../../../src/i18n/empty-row");
6
+ exports.emptyRowSnippetTemplate = '&nbsp;\n\n';
7
+ exports.emptyRowSnippet = (0, autocomplete_1.snippet)(exports.emptyRowSnippetTemplate);
8
+ exports.emptyRowAutocomplete = {
9
+ autocomplete: (context) => {
10
+ const word = context.matchBefore(/^.*/);
11
+ if (word === null || word === void 0 ? void 0 : word.text.startsWith('&')) {
12
+ return {
13
+ from: word.from,
14
+ options: [
15
+ {
16
+ label: '&nbsp;',
17
+ displayLabel: (0, empty_row_1.i18n)('snippet.text'),
18
+ type: 'text',
19
+ apply: exports.emptyRowSnippet,
20
+ },
21
+ ],
22
+ };
23
+ }
24
+ return null;
25
+ },
26
+ };
@@ -0,0 +1,5 @@
1
+ declare type GetAutocompleteConfig = {
2
+ preserveEmptyRows?: boolean;
3
+ };
4
+ export declare const getAutocompleteConfig: ({ preserveEmptyRows }: GetAutocompleteConfig) => import("../yfm").LanguageData[];
5
+ export {};
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAutocompleteConfig = void 0;
4
+ const yfm_1 = require("../yfm");
5
+ const emptyRow_1 = require("./emptyRow");
6
+ const getAutocompleteConfig = ({ preserveEmptyRows }) => {
7
+ const autocompleteItems = [];
8
+ if (preserveEmptyRows) {
9
+ autocompleteItems.push(emptyRow_1.emptyRowAutocomplete);
10
+ }
11
+ autocompleteItems.push(yfm_1.mdAutocomplete);
12
+ return autocompleteItems;
13
+ };
14
+ exports.getAutocompleteConfig = getAutocompleteConfig;
@@ -33,6 +33,7 @@ export declare type CreateCodemirrorParams = {
33
33
  yfmLangOptions?: YfmLangOptions;
34
34
  autocompletion?: Autocompletion;
35
35
  directiveSyntax: DirectiveSyntaxContext;
36
+ preserveEmptyRows: boolean;
36
37
  };
37
38
  export declare function createCodemirror(params: CreateCodemirrorParams): EditorView;
38
39
  export declare function withLogger(action: string, command: StateCommand): StateCommand;
@@ -17,9 +17,10 @@ const converters_1 = require("./html-to-markdown/converters");
17
17
  const pairing_chars_1 = require("./pairing-chars");
18
18
  const react_facet_1 = require("./react-facet");
19
19
  const plugin_1 = require("./search-plugin/plugin");
20
+ const smart_reindent_1 = require("./smart-reindent");
20
21
  const yfm_1 = require("./yfm");
21
22
  function createCodemirror(params) {
22
- const { doc, reactRenderer, onCancel, onScroll, onSubmit, onChange, onDocChange, disabledExtensions = {}, keymaps = [], receiver, yfmLangOptions, extensions: extraExtensions, placeholder: placeholderContent, autocompletion: autocompletionConfig, parseHtmlOnPaste, parseInsertedUrlAsImage, directiveSyntax, } = params;
23
+ const { doc, reactRenderer, onCancel, onScroll, onSubmit, onChange, onDocChange, disabledExtensions = {}, keymaps = [], receiver, yfmLangOptions, extensions: extraExtensions, placeholder: placeholderContent, autocompletion: autocompletionConfig, parseHtmlOnPaste, parseInsertedUrlAsImage, directiveSyntax, preserveEmptyRows, } = params;
23
24
  const extensions = [gravity_1.gravityTheme, (0, view_1.placeholder)(placeholderContent)];
24
25
  if (!disabledExtensions.history) {
25
26
  extensions.push((0, commands_1.history)());
@@ -73,12 +74,16 @@ function createCodemirror(params) {
73
74
  var _a;
74
75
  if (!event.clipboardData)
75
76
  return;
77
+ const { from } = editor.state.selection.main;
78
+ const line = editor.state.doc.lineAt(from);
79
+ const currentLine = line.text;
76
80
  // if clipboard contains YFM content - avoid any meddling with pasted content
77
81
  // since text/yfm will contain valid markdown
78
82
  const yfmContent = event.clipboardData.getData(clipboard_1.DataTransferType.Yfm);
79
83
  if (yfmContent) {
80
84
  event.preventDefault();
81
- editor.dispatch(editor.state.replaceSelection(yfmContent));
85
+ const reindentedYfmContent = (0, smart_reindent_1.smartReindent)(yfmContent, currentLine);
86
+ editor.dispatch(editor.state.replaceSelection(reindentedYfmContent));
82
87
  return;
83
88
  }
84
89
  // checking if a copy buffer content is suitable for convertion
@@ -103,29 +108,42 @@ function createCodemirror(params) {
103
108
  }
104
109
  if (parsedMarkdownMarkup !== undefined) {
105
110
  event.preventDefault();
106
- editor.dispatch(editor.state.replaceSelection(parsedMarkdownMarkup));
111
+ const reindentedHtmlContent = (0, smart_reindent_1.smartReindent)(parsedMarkdownMarkup, currentLine);
112
+ editor.dispatch(editor.state.replaceSelection(reindentedHtmlContent));
107
113
  return;
108
114
  }
109
115
  }
110
116
  if (parseInsertedUrlAsImage) {
111
117
  const { imageUrl, title } = parseInsertedUrlAsImage((_a = event.clipboardData.getData(clipboard_1.DataTransferType.Text)) !== null && _a !== void 0 ? _a : '') || {};
112
- if (!imageUrl) {
113
- return;
118
+ if (imageUrl) {
119
+ event.preventDefault();
120
+ (0, commands_2.insertImages)([
121
+ {
122
+ url: imageUrl,
123
+ alt: title,
124
+ title,
125
+ },
126
+ ])(editor);
114
127
  }
128
+ }
129
+ // Reindenting pasted plain text
130
+ const pastedText = event.clipboardData.getData(clipboard_1.DataTransferType.Text);
131
+ const reindentedText = (0, smart_reindent_1.smartReindent)(pastedText, currentLine);
132
+ // but only if there is a need for reindentation
133
+ if (pastedText !== reindentedText) {
134
+ editor.dispatch(editor.state.replaceSelection(reindentedText));
115
135
  event.preventDefault();
116
- (0, commands_2.insertImages)([
117
- {
118
- url: imageUrl,
119
- alt: title,
120
- title,
121
- },
122
- ])(editor);
123
136
  }
124
137
  },
125
138
  }), (0, plugin_1.SearchPanelPlugin)({
126
139
  anchorSelector: '.g-md-search-anchor',
127
140
  receiver,
128
141
  }));
142
+ if (preserveEmptyRows) {
143
+ extensions.push(view_1.keymap.of([
144
+ { key: shortcuts_1.formatter.toCM(shortcuts_1.Action.EmptyRow), run: withLogger(action_names_1.ActionName.emptyRow, commands_2.insertEmptyRow) },
145
+ ]));
146
+ }
129
147
  if (params.uploadHandler) {
130
148
  extensions.push(files_upload_facet_1.FileUploadHandlerFacet.of({
131
149
  fn: params.uploadHandler,
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Reindents pasted text based on the current line's markers
3
+ */
4
+ export declare function smartReindent(pastedText: string, currentLineText: string): string;