@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,10 +1,13 @@
1
1
  import type MarkdownIt from 'markdown-it';
2
2
  import { inputRules } from 'prosemirror-inputrules';
3
+ import type { MarkSpec, NodeSpec } from 'prosemirror-model';
3
4
  import type { Plugin } from 'prosemirror-state';
4
5
  import type { Logger2 } from "../logger.js";
5
6
  import type { ActionSpec } from "./types/actions.js";
6
7
  import type { Extension, ExtensionDeps, ExtensionMarkSpec, ExtensionNodeSpec, ExtensionSpec, ExtensionWithOptions } from "./types/extension.js";
7
8
  import type { Keymap } from "./types/keymap.js";
9
+ import type { ParserToken } from "./types/parser.js";
10
+ import type { SerializerMarkToken, SerializerNodeToken } from "./types/serializer.js";
8
11
  type InputRulesConfig = Parameters<typeof inputRules>[0];
9
12
  type ConfigureMdParams = {
10
13
  /**
@@ -56,12 +59,30 @@ export declare class ExtensionBuilder {
56
59
  use(extension: Extension): this;
57
60
  use<T>(extension: ExtensionWithOptions<T>, options: T): this;
58
61
  configureMd(cb: ConfigureMdCallback, params?: ConfigureMdParams): this;
62
+ /**
63
+ * @deprecated Will be removed in the next major version.
64
+ * Use addNodeSpec() + addMarkdownTokenParserSpec() + addNodeSerializerSpec() instead.
65
+ */
59
66
  addNode(name: string, cb: AddPmNodeCallback): this;
67
+ /**
68
+ * @deprecated Will be removed in the next major version.
69
+ * Use addMarkSpec() + addMarkdownTokenParserSpec() + addMarkSerializerSpec() instead.
70
+ */
60
71
  addMark(name: string, cb: AddPmMarkCallback, priority?: Priority): this;
61
72
  addPlugin(cb: AddPmPluginCallback, priority?: Priority): this;
62
73
  addKeymap(cb: AddPmKeymapCallback, priority?: Priority): this;
63
74
  addInputRules(cb: AddPmInputRulesCallback, priority?: Priority): this;
64
75
  addAction(name: string, cb: AddActionCallback): this;
76
+ addNodeSpec(name: string, cb: () => NodeSpec): this;
77
+ addMarkSpec(name: string, cb: () => MarkSpec, priority?: Priority): this;
78
+ addMarkdownTokenParserSpec(tokenName: string, cb: () => ParserToken): this;
79
+ addNodeSerializerSpec(name: string, cb: () => SerializerNodeToken): this;
80
+ addMarkSerializerSpec(name: string, cb: () => SerializerMarkToken): this;
81
+ overrideNodeSpec(name: string, cb: (prev: NodeSpec) => NodeSpec): this;
82
+ overrideMarkSpec(name: string, cb: (prev: MarkSpec) => MarkSpec): this;
83
+ overrideMarkdownTokenParserSpec(tokenName: string, cb: (prev: ParserToken) => ParserToken): this;
84
+ overrideNodeSerializerSpec(name: string, cb: (prev: SerializerNodeToken) => SerializerNodeToken): this;
85
+ overrideMarkSerializerSpec(name: string, cb: (prev: SerializerMarkToken) => SerializerMarkToken): this;
65
86
  build(): ExtensionSpec;
66
87
  }
67
88
  export {};
@@ -16,6 +16,43 @@ var Priority;
16
16
  Priority[Priority["Lowest"] = 0] = "Lowest";
17
17
  })(Priority || (Priority = {}));
18
18
  const DEFAULT_PRIORITY = Priority.Medium;
19
+ function applyOverrides(initial, overrides) {
20
+ return overrides ? overrides.reduce((acc, fn) => fn(acc), initial) : initial;
21
+ }
22
+ function resolveParserEntry(entry, overrides) {
23
+ return {
24
+ tokenName: entry.tokenName,
25
+ tokenSpec: applyOverrides(entry.tokenSpec, overrides[entry.tokenName]),
26
+ };
27
+ }
28
+ function resolveGranularParserEntries(entityName, entityType, parserSpecsByEntity, overrides) {
29
+ const entries = parserSpecsByEntity[entityName];
30
+ if (!entries || entries.length === 0) {
31
+ throw new Error(`Incomplete ${entityType} spec for "${entityName}": missing parser spec. ` +
32
+ `Use addMarkdownTokenParserSpec() to register a parser for this ${entityType}.`);
33
+ }
34
+ const [primaryRaw, ...extraRaw] = entries;
35
+ return {
36
+ primary: resolveParserEntry(primaryRaw, overrides),
37
+ extra: extraRaw.map((e) => resolveParserEntry(e, overrides)),
38
+ };
39
+ }
40
+ function buildParserOnlyNodeEntry(resolved) {
41
+ return {
42
+ spec: {},
43
+ fromMd: { tokenName: resolved.tokenName, tokenSpec: resolved.tokenSpec },
44
+ toMd: () => {
45
+ throw new Error(`Unexpected toMd() call on parser-only node "${resolved.tokenName}"`);
46
+ },
47
+ };
48
+ }
49
+ function buildParserOnlyMarkEntry(resolved) {
50
+ return {
51
+ spec: {},
52
+ fromMd: { tokenName: resolved.tokenName, tokenSpec: resolved.tokenSpec },
53
+ toMd: { open: '', close: '' },
54
+ };
55
+ }
19
56
  class ExtensionBuilder {
20
57
  static createContext() {
21
58
  return new Map();
@@ -30,6 +67,18 @@ class ExtensionBuilder {
30
67
  #markSpecs = {};
31
68
  #plugins = [];
32
69
  #actions = [];
70
+ // Granular add storage
71
+ #rawNodeSpecs = {};
72
+ #rawMarkSpecs = {};
73
+ #rawParserSpecs = {};
74
+ #rawNodeSerializers = {};
75
+ #rawMarkSerializers = {};
76
+ // Override chains
77
+ #nodeSpecOverrides = {};
78
+ #markSpecOverrides = {};
79
+ #parserSpecOverrides = {};
80
+ #nodeSerializerOverrides = {};
81
+ #markSerializerOverrides = {};
33
82
  context;
34
83
  constructor(logger, context) {
35
84
  this.#logger = logger;
@@ -52,17 +101,41 @@ class ExtensionBuilder {
52
101
  });
53
102
  return this;
54
103
  }
104
+ /**
105
+ * @deprecated Will be removed in the next major version.
106
+ * Use addNodeSpec() + addMarkdownTokenParserSpec() + addNodeSerializerSpec() instead.
107
+ */
55
108
  addNode(name, cb) {
56
109
  if (this.#nodeSpecs[name]) {
57
110
  throw new Error(`ProseMirror node with this name "${name}" already exist`);
58
111
  }
112
+ if (this.#rawNodeSpecs[name]) {
113
+ throw new Error(`Node with name "${name}" already registered via addNodeSpec. ` +
114
+ `Cannot use addNode for a node that already has granular registrations.`);
115
+ }
116
+ if (this.#rawNodeSerializers[name]) {
117
+ throw new Error(`Node serializer for "${name}" already registered via addNodeSerializerSpec. ` +
118
+ `Cannot use addNode for a node that already has granular registrations.`);
119
+ }
59
120
  this.#nodeSpecs[name] = { name, cb };
60
121
  return this;
61
122
  }
123
+ /**
124
+ * @deprecated Will be removed in the next major version.
125
+ * Use addMarkSpec() + addMarkdownTokenParserSpec() + addMarkSerializerSpec() instead.
126
+ */
62
127
  addMark(name, cb, priority = DEFAULT_PRIORITY) {
63
128
  if (this.#markSpecs[name]) {
64
129
  throw new Error(`ProseMirror mark with this name "${name}" already exist`);
65
130
  }
131
+ if (this.#rawMarkSpecs[name]) {
132
+ throw new Error(`Mark with name "${name}" already registered via addMarkSpec. ` +
133
+ `Cannot use addMark for a mark that already has granular registrations.`);
134
+ }
135
+ if (this.#rawMarkSerializers[name]) {
136
+ throw new Error(`Mark serializer for "${name}" already registered via addMarkSerializerSpec. ` +
137
+ `Cannot use addMark for a mark that already has granular registrations.`);
138
+ }
66
139
  this.#markSpecs[name] = { name, cb, priority };
67
140
  return this;
68
141
  }
@@ -85,12 +158,115 @@ class ExtensionBuilder {
85
158
  this.#actions.push([name, cb]);
86
159
  return this;
87
160
  }
161
+ addNodeSpec(name, cb) {
162
+ if (this.#rawNodeSpecs[name]) {
163
+ throw new Error(`Node spec with name "${name}" already registered via addNodeSpec`);
164
+ }
165
+ if (this.#nodeSpecs[name]) {
166
+ throw new Error(`Node with name "${name}" already registered via addNode. Use overrideNodeSpec to modify it.`);
167
+ }
168
+ this.#rawNodeSpecs[name] = cb;
169
+ return this;
170
+ }
171
+ addMarkSpec(name, cb, priority = DEFAULT_PRIORITY) {
172
+ if (this.#rawMarkSpecs[name]) {
173
+ throw new Error(`Mark spec with name "${name}" already registered via addMarkSpec`);
174
+ }
175
+ if (this.#markSpecs[name]) {
176
+ throw new Error(`Mark with name "${name}" already registered via addMark. Use overrideMarkSpec to modify it.`);
177
+ }
178
+ this.#rawMarkSpecs[name] = { cb, priority };
179
+ return this;
180
+ }
181
+ addMarkdownTokenParserSpec(tokenName, cb) {
182
+ if (this.#rawParserSpecs[tokenName]) {
183
+ throw new Error(`Parser spec for token "${tokenName}" already registered via addMarkdownTokenParserSpec`);
184
+ }
185
+ this.#rawParserSpecs[tokenName] = { tokenName, cb };
186
+ return this;
187
+ }
188
+ addNodeSerializerSpec(name, cb) {
189
+ if (this.#rawNodeSerializers[name]) {
190
+ throw new Error(`Node serializer for "${name}" already registered via addNodeSerializerSpec`);
191
+ }
192
+ if (this.#nodeSpecs[name]) {
193
+ throw new Error(`Node with name "${name}" already registered via addNode. Use overrideNodeSerializerSpec to modify it.`);
194
+ }
195
+ this.#rawNodeSerializers[name] = cb;
196
+ return this;
197
+ }
198
+ addMarkSerializerSpec(name, cb) {
199
+ if (this.#rawMarkSerializers[name]) {
200
+ throw new Error(`Mark serializer for "${name}" already registered via addMarkSerializerSpec`);
201
+ }
202
+ if (this.#markSpecs[name]) {
203
+ throw new Error(`Mark with name "${name}" already registered via addMark. Use overrideMarkSerializerSpec to modify it.`);
204
+ }
205
+ this.#rawMarkSerializers[name] = cb;
206
+ return this;
207
+ }
208
+ overrideNodeSpec(name, cb) {
209
+ if (!this.#nodeSpecs[name] && !this.#rawNodeSpecs[name]) {
210
+ throw new Error(`Cannot override node spec "${name}": not registered. Use addNode() or addNodeSpec() first.`);
211
+ }
212
+ (this.#nodeSpecOverrides[name] ??= []).push(cb);
213
+ return this;
214
+ }
215
+ overrideMarkSpec(name, cb) {
216
+ if (!this.#markSpecs[name] && !this.#rawMarkSpecs[name]) {
217
+ throw new Error(`Cannot override mark spec "${name}": not registered. Use addMark() or addMarkSpec() first.`);
218
+ }
219
+ (this.#markSpecOverrides[name] ??= []).push(cb);
220
+ return this;
221
+ }
222
+ overrideMarkdownTokenParserSpec(tokenName, cb) {
223
+ if (!this.#rawParserSpecs[tokenName] &&
224
+ !this.#nodeSpecs[tokenName] &&
225
+ !this.#markSpecs[tokenName]) {
226
+ throw new Error(`Cannot override parser spec for token "${tokenName}": not registered. ` +
227
+ `Use addMarkdownTokenParserSpec(), addNode(), or addMark() first.`);
228
+ }
229
+ (this.#parserSpecOverrides[tokenName] ??= []).push(cb);
230
+ return this;
231
+ }
232
+ overrideNodeSerializerSpec(name, cb) {
233
+ if (!this.#nodeSpecs[name] && !this.#rawNodeSerializers[name]) {
234
+ throw new Error(`Cannot override node serializer "${name}": not registered. Use addNode() or addNodeSerializerSpec() first.`);
235
+ }
236
+ (this.#nodeSerializerOverrides[name] ??= []).push(cb);
237
+ return this;
238
+ }
239
+ overrideMarkSerializerSpec(name, cb) {
240
+ if (!this.#markSpecs[name] && !this.#rawMarkSerializers[name]) {
241
+ throw new Error(`Cannot override mark serializer "${name}": not registered. Use addMark() or addMarkSerializerSpec() first.`);
242
+ }
243
+ (this.#markSerializerOverrides[name] ??= []).push(cb);
244
+ return this;
245
+ }
88
246
  build() {
89
247
  const confMd = this.#confMdCbs.slice();
90
248
  const nodes = { ...this.#nodeSpecs };
91
249
  const marks = { ...this.#markSpecs };
92
250
  const plugins = this.#plugins.slice();
93
251
  const actions = this.#actions.slice();
252
+ const rawNodeSpecs = { ...this.#rawNodeSpecs };
253
+ const rawMarkSpecs = { ...this.#rawMarkSpecs };
254
+ const rawParserSpecs = { ...this.#rawParserSpecs };
255
+ const rawNodeSerializers = { ...this.#rawNodeSerializers };
256
+ const rawMarkSerializers = { ...this.#rawMarkSerializers };
257
+ const nodeSpecOverrides = { ...this.#nodeSpecOverrides };
258
+ const markSpecOverrides = { ...this.#markSpecOverrides };
259
+ const parserSpecOverrides = { ...this.#parserSpecOverrides };
260
+ const nodeSerializerOverrides = { ...this.#nodeSerializerOverrides };
261
+ const markSerializerOverrides = { ...this.#markSerializerOverrides };
262
+ // Pre-build entity name → parser specs lookup for O(1) access
263
+ // Multiple markdown-it tokens can map to the same ProseMirror entity
264
+ // (e.g. both 'fence' and 'code_block' tokens → 'code_block' node)
265
+ const parserSpecsByEntity = {};
266
+ for (const { tokenName, cb } of Object.values(rawParserSpecs)) {
267
+ const tokenSpec = cb();
268
+ (parserSpecsByEntity[tokenSpec.name] ??= []).push({ tokenName, tokenSpec });
269
+ }
94
270
  return {
95
271
  configureMd: (md, parserType) => confMd.reduce((pMd, { cb, params }) => {
96
272
  if (parserType === 'text' && params.text) {
@@ -103,18 +279,144 @@ class ExtensionBuilder {
103
279
  }, md),
104
280
  nodes: () => {
105
281
  let map = orderedmap_1.default.from({});
282
+ // 1. Process addNode entries with overrides
106
283
  for (const { name, cb } of Object.values(nodes)) {
107
- map = map.addToEnd(name, cb());
284
+ const base = cb();
285
+ const tokenName = base.fromMd.tokenName ?? name;
286
+ const hasOverrides = nodeSpecOverrides[name] ||
287
+ parserSpecOverrides[tokenName] ||
288
+ nodeSerializerOverrides[name];
289
+ if (hasOverrides) {
290
+ map = map.addToEnd(name, {
291
+ spec: applyOverrides(base.spec, nodeSpecOverrides[name]),
292
+ fromMd: {
293
+ tokenName: base.fromMd.tokenName,
294
+ tokenSpec: applyOverrides(base.fromMd.tokenSpec, parserSpecOverrides[tokenName]),
295
+ },
296
+ toMd: applyOverrides(base.toMd, nodeSerializerOverrides[name]),
297
+ view: base.view,
298
+ });
299
+ }
300
+ else {
301
+ map = map.addToEnd(name, base);
302
+ }
303
+ }
304
+ // 1b. Add parser-only entries for rawParserSpecs tokens targeting addNode entities
305
+ for (const { name } of Object.values(nodes)) {
306
+ const entries = parserSpecsByEntity[name];
307
+ if (entries) {
308
+ for (const entry of entries) {
309
+ // Skip when tokenName matches the entity name —
310
+ // the full spec was already added in step 1
311
+ if (entry.tokenName === name)
312
+ continue;
313
+ map = map.addToEnd(entry.tokenName, buildParserOnlyNodeEntry(resolveParserEntry(entry, parserSpecOverrides)));
314
+ }
315
+ }
316
+ }
317
+ // 2. Process granular-only nodes
318
+ for (const name of Object.keys(rawNodeSpecs)) {
319
+ const spec = applyOverrides(rawNodeSpecs[name](), nodeSpecOverrides[name]);
320
+ const { primary, extra } = resolveGranularParserEntries(name, 'node', parserSpecsByEntity, parserSpecOverrides);
321
+ if (!rawNodeSerializers[name]) {
322
+ throw new Error(`Incomplete node spec for "${name}": missing serializer. ` +
323
+ `Use addNodeSerializerSpec() to register a serializer for this node.`);
324
+ }
325
+ const toMd = applyOverrides(rawNodeSerializers[name](), nodeSerializerOverrides[name]);
326
+ map = map.addToEnd(name, {
327
+ spec,
328
+ fromMd: { tokenName: primary.tokenName, tokenSpec: primary.tokenSpec },
329
+ toMd,
330
+ });
331
+ for (const entry of extra) {
332
+ map = map.addToEnd(entry.tokenName, buildParserOnlyNodeEntry(entry));
333
+ }
108
334
  }
109
335
  return map;
110
336
  },
111
337
  marks: () => {
112
338
  // The order of marks in schema is important when serializing pm-document to DOM or markup
113
339
  // https://discuss.prosemirror.net/t/marks-priority/4463
114
- const sortedMarks = Object.values(marks).sort((a, b) => b.priority - a.priority);
340
+ // 1. Process addMark entries with overrides
341
+ const allMarks = [];
342
+ for (const { name, cb, priority } of Object.values(marks)) {
343
+ allMarks.push({
344
+ name,
345
+ priority,
346
+ buildSpec: () => {
347
+ const base = cb();
348
+ const tokenName = base.fromMd.tokenName ?? name;
349
+ const hasOverrides = markSpecOverrides[name] ||
350
+ parserSpecOverrides[tokenName] ||
351
+ markSerializerOverrides[name];
352
+ if (hasOverrides) {
353
+ return {
354
+ spec: applyOverrides(base.spec, markSpecOverrides[name]),
355
+ fromMd: {
356
+ tokenName: base.fromMd.tokenName,
357
+ tokenSpec: applyOverrides(base.fromMd.tokenSpec, parserSpecOverrides[tokenName]),
358
+ },
359
+ toMd: applyOverrides(base.toMd, markSerializerOverrides[name]),
360
+ view: base.view,
361
+ };
362
+ }
363
+ return base;
364
+ },
365
+ });
366
+ }
367
+ // 1b. Add parser-only entries for rawParserSpecs tokens targeting addMark entities
368
+ for (const { name, priority } of Object.values(marks)) {
369
+ const entries = parserSpecsByEntity[name];
370
+ if (entries) {
371
+ for (const entry of entries) {
372
+ // Skip when tokenName matches the entity name —
373
+ // the full spec was already added in step 1
374
+ if (entry.tokenName === name)
375
+ continue;
376
+ allMarks.push({
377
+ name: entry.tokenName,
378
+ priority,
379
+ buildSpec: () => buildParserOnlyMarkEntry(resolveParserEntry(entry, parserSpecOverrides)),
380
+ });
381
+ }
382
+ }
383
+ }
384
+ // 2. Process granular-only marks
385
+ for (const name of Object.keys(rawMarkSpecs)) {
386
+ const { cb: specCb, priority } = rawMarkSpecs[name];
387
+ const { primary, extra } = resolveGranularParserEntries(name, 'mark', parserSpecsByEntity, parserSpecOverrides);
388
+ if (!rawMarkSerializers[name]) {
389
+ throw new Error(`Incomplete mark spec for "${name}": missing serializer. ` +
390
+ `Use addMarkSerializerSpec() to register a serializer for this mark.`);
391
+ }
392
+ allMarks.push({
393
+ name,
394
+ priority,
395
+ buildSpec: () => {
396
+ const spec = applyOverrides(specCb(), markSpecOverrides[name]);
397
+ const toMd = applyOverrides(rawMarkSerializers[name](), markSerializerOverrides[name]);
398
+ return {
399
+ spec,
400
+ fromMd: {
401
+ tokenName: primary.tokenName,
402
+ tokenSpec: primary.tokenSpec,
403
+ },
404
+ toMd,
405
+ };
406
+ },
407
+ });
408
+ for (const entry of extra) {
409
+ allMarks.push({
410
+ name: entry.tokenName,
411
+ priority,
412
+ buildSpec: () => buildParserOnlyMarkEntry(entry),
413
+ });
414
+ }
415
+ }
416
+ allMarks.sort((a, b) => b.priority - a.priority);
115
417
  let map = orderedmap_1.default.from({});
116
- for (const { name, cb } of sortedMarks) {
117
- map = map.addToEnd(name, cb());
418
+ for (const { name, buildSpec } of allMarks) {
419
+ map = map.addToEnd(name, buildSpec());
118
420
  }
119
421
  return map;
120
422
  },
@@ -1 +1 @@
1
- {"version":3,"file":"ExtensionBuilder.js","sourceRoot":"../../../src","sources":["core/ExtensionBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["import type MarkdownIt from 'markdown-it';\nimport OrderedMap from 'orderedmap';\nimport {inputRules} from 'prosemirror-inputrules';\nimport {keymap} from 'prosemirror-keymap';\nimport type {Plugin} from 'prosemirror-state';\n\nimport type {Logger2} from '../logger';\n\nimport type {ActionSpec} from './types/actions';\nimport type {\n Extension,\n ExtensionDeps,\n ExtensionMarkSpec,\n ExtensionNodeSpec,\n ExtensionSpec,\n ExtensionWithOptions,\n} from './types/extension';\nimport type {Keymap} from './types/keymap';\n\ntype InputRulesConfig = Parameters<typeof inputRules>[0];\ntype ExtensionWithParams = (builder: ExtensionBuilder, ...params: any[]) => void;\ntype ConfigureMdParams = {\n /**\n * Apply this configurtion to text parser\n * @default true\n */\n text?: boolean;\n /**\n * Apply this configurtion to markup parser\n * @default true\n */\n markup?: boolean;\n};\n\ntype ConfigureMdCallback = (md: MarkdownIt) => MarkdownIt;\ntype AddPmNodeCallback = () => ExtensionNodeSpec;\ntype AddPmMarkCallback = () => ExtensionMarkSpec;\ntype AddPmPluginCallback = (deps: ExtensionDeps) => Plugin | Plugin[];\ntype AddPmKeymapCallback = (deps: ExtensionDeps) => Keymap;\ntype AddPmInputRulesCallback = (deps: ExtensionDeps) => InputRulesConfig;\ntype AddActionCallback = (deps: ExtensionDeps) => ActionSpec;\n\nenum Priority {\n Highest = 1_000_000,\n VeryHigh = 100_000,\n High = 10_000,\n Medium = 1_000,\n Low = 100,\n VeryLow = 10,\n Lowest = 0,\n}\n\nconst DEFAULT_PRIORITY = Priority.Medium;\n\ntype BuilderContext<T extends object> = {\n has(key: keyof T): boolean;\n get<K extends keyof T>(key: K): T[K] | undefined;\n set<K extends keyof T>(key: K, value: T[K]): BuilderContext<T>;\n};\n\ndeclare global {\n namespace WysiwygEditor {\n interface Context {}\n }\n}\n\nexport class ExtensionBuilder {\n static createContext(): BuilderContext<WysiwygEditor.Context> {\n return new Map();\n }\n\n /* eslint-disable @typescript-eslint/member-ordering */\n static readonly Priority = Priority;\n readonly Priority = ExtensionBuilder.Priority;\n /* eslint-enable @typescript-eslint/member-ordering */\n\n readonly #logger: Logger2.ILogger;\n #confMdCbs: {cb: ConfigureMdCallback; params: Required<ConfigureMdParams>}[] = [];\n #nodeSpecs: Record<string, {name: string; cb: AddPmNodeCallback}> = {};\n #markSpecs: Record<string, {name: string; cb: AddPmMarkCallback; priority: number}> = {};\n #plugins: {cb: AddPmPluginCallback; priority: number}[] = [];\n #actions: [string, AddActionCallback][] = [];\n\n readonly context: BuilderContext<WysiwygEditor.Context>;\n\n constructor(logger: Logger2.ILogger, context?: BuilderContext<WysiwygEditor.Context>) {\n this.#logger = logger;\n this.context = context ?? ExtensionBuilder.createContext();\n }\n\n get logger(): Logger2.ILogger {\n return this.#logger;\n }\n\n use(extension: Extension): this;\n use<T>(extension: ExtensionWithOptions<T>, options: T): this;\n use(extension: ExtensionWithParams, ...params: any[]): this {\n extension(this, ...params);\n return this;\n }\n\n configureMd(cb: ConfigureMdCallback, params: ConfigureMdParams = {}): this {\n this.#confMdCbs.push({\n cb,\n params: {\n text: params.text ?? true,\n markup: params.markup ?? true,\n },\n });\n return this;\n }\n\n addNode(name: string, cb: AddPmNodeCallback): this {\n if (this.#nodeSpecs[name]) {\n throw new Error(`ProseMirror node with this name \"${name}\" already exist`);\n }\n this.#nodeSpecs[name] = {name, cb};\n return this;\n }\n\n addMark(name: string, cb: AddPmMarkCallback, priority = DEFAULT_PRIORITY): this {\n if (this.#markSpecs[name]) {\n throw new Error(`ProseMirror mark with this name \"${name}\" already exist`);\n }\n this.#markSpecs[name] = {name, cb, priority};\n return this;\n }\n\n addPlugin(cb: AddPmPluginCallback, priority = DEFAULT_PRIORITY): this {\n this.#plugins.push({cb, priority});\n return this;\n }\n\n addKeymap(cb: AddPmKeymapCallback, priority = DEFAULT_PRIORITY): this {\n this.#plugins.push({cb: (...args) => keymap(cb(...args)), priority});\n return this;\n }\n\n addInputRules(cb: AddPmInputRulesCallback, priority = DEFAULT_PRIORITY): this {\n this.#plugins.push({cb: (...args) => inputRules(cb(...args)), priority});\n return this;\n }\n\n addAction(name: string, cb: AddActionCallback): this {\n if (this.#actions.some(([actionName]) => actionName === name)) {\n throw new Error(\n `[Markdown Wysiwyg Editor] action with this name \"${name}\" already exist`,\n );\n }\n this.#actions.push([name, cb]);\n return this;\n }\n\n build(): ExtensionSpec {\n const confMd = this.#confMdCbs.slice();\n const nodes = {...this.#nodeSpecs};\n const marks = {...this.#markSpecs};\n const plugins = this.#plugins.slice();\n const actions = this.#actions.slice();\n\n return {\n configureMd: (md, parserType) =>\n confMd.reduce((pMd, {cb, params}) => {\n if (parserType === 'text' && params.text) {\n return cb(pMd);\n }\n if (parserType === 'markup' && params.markup) {\n return cb(pMd);\n }\n return pMd;\n }, md),\n nodes: () => {\n let map = OrderedMap.from<ExtensionNodeSpec>({});\n for (const {name, cb} of Object.values(nodes)) {\n map = map.addToEnd(name, cb());\n }\n return map;\n },\n marks: () => {\n // The order of marks in schema is important when serializing pm-document to DOM or markup\n // https://discuss.prosemirror.net/t/marks-priority/4463\n const sortedMarks = Object.values(marks).sort((a, b) => b.priority - a.priority);\n let map = OrderedMap.from<ExtensionMarkSpec>({});\n for (const {name, cb} of sortedMarks) {\n map = map.addToEnd(name, cb());\n }\n return map;\n },\n plugins: (deps) => {\n return plugins\n .sort((a, b) => b.priority - a.priority)\n .reduce<Plugin[]>((acc, {cb}) => {\n const res = cb(deps);\n if (Array.isArray(res)) acc.push(...res);\n else acc.push(res);\n return acc;\n }, []);\n },\n actions: (deps) =>\n actions.reduce(\n (obj, [name, cb]) => {\n obj[name] = cb(deps);\n return obj;\n },\n {} as Record<string, ActionSpec>,\n ),\n };\n }\n}\n"]}
1
+ {"version":3,"file":"ExtensionBuilder.js","sourceRoot":"../../../src","sources":["core/ExtensionBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["import type MarkdownIt from 'markdown-it';\nimport OrderedMap from 'orderedmap';\nimport {inputRules} from 'prosemirror-inputrules';\nimport {keymap} from 'prosemirror-keymap';\nimport type {MarkSpec, NodeSpec} from 'prosemirror-model';\nimport type {Plugin} from 'prosemirror-state';\n\nimport type {Logger2} from '../logger';\n\nimport type {ActionSpec} from './types/actions';\nimport type {\n Extension,\n ExtensionDeps,\n ExtensionMarkSpec,\n ExtensionNodeSpec,\n ExtensionSpec,\n ExtensionWithOptions,\n} from './types/extension';\nimport type {Keymap} from './types/keymap';\nimport type {ParserToken} from './types/parser';\nimport type {SerializerMarkToken, SerializerNodeToken} from './types/serializer';\n\ntype InputRulesConfig = Parameters<typeof inputRules>[0];\ntype ExtensionWithParams = (builder: ExtensionBuilder, ...params: any[]) => void;\ntype ConfigureMdParams = {\n /**\n * Apply this configurtion to text parser\n * @default true\n */\n text?: boolean;\n /**\n * Apply this configurtion to markup parser\n * @default true\n */\n markup?: boolean;\n};\n\ntype ConfigureMdCallback = (md: MarkdownIt) => MarkdownIt;\ntype AddPmNodeCallback = () => ExtensionNodeSpec;\ntype AddPmMarkCallback = () => ExtensionMarkSpec;\ntype AddPmPluginCallback = (deps: ExtensionDeps) => Plugin | Plugin[];\ntype AddPmKeymapCallback = (deps: ExtensionDeps) => Keymap;\ntype AddPmInputRulesCallback = (deps: ExtensionDeps) => InputRulesConfig;\ntype AddActionCallback = (deps: ExtensionDeps) => ActionSpec;\n\nenum Priority {\n Highest = 1_000_000,\n VeryHigh = 100_000,\n High = 10_000,\n Medium = 1_000,\n Low = 100,\n VeryLow = 10,\n Lowest = 0,\n}\n\nconst DEFAULT_PRIORITY = Priority.Medium;\n\ntype BuilderContext<T extends object> = {\n has(key: keyof T): boolean;\n get<K extends keyof T>(key: K): T[K] | undefined;\n set<K extends keyof T>(key: K, value: T[K]): BuilderContext<T>;\n};\n\ndeclare global {\n namespace WysiwygEditor {\n interface Context {}\n }\n}\n\nfunction applyOverrides<T>(initial: T, overrides?: Array<(prev: T) => T>): T {\n return overrides ? overrides.reduce((acc, fn) => fn(acc), initial) : initial;\n}\n\ntype ResolvedParserEntry = {tokenName: string; tokenSpec: ParserToken};\ntype ParserOverridesMap = Record<string, Array<(prev: ParserToken) => ParserToken>>;\n\nfunction resolveParserEntry(\n entry: {tokenName: string; tokenSpec: ParserToken},\n overrides: ParserOverridesMap,\n): ResolvedParserEntry {\n return {\n tokenName: entry.tokenName,\n tokenSpec: applyOverrides(entry.tokenSpec, overrides[entry.tokenName]),\n };\n}\n\nfunction resolveGranularParserEntries(\n entityName: string,\n entityType: 'node' | 'mark',\n parserSpecsByEntity: Record<string, ResolvedParserEntry[]>,\n overrides: ParserOverridesMap,\n): {primary: ResolvedParserEntry; extra: ResolvedParserEntry[]} {\n const entries = parserSpecsByEntity[entityName];\n if (!entries || entries.length === 0) {\n throw new Error(\n `Incomplete ${entityType} spec for \"${entityName}\": missing parser spec. ` +\n `Use addMarkdownTokenParserSpec() to register a parser for this ${entityType}.`,\n );\n }\n\n const [primaryRaw, ...extraRaw] = entries;\n return {\n primary: resolveParserEntry(primaryRaw, overrides),\n extra: extraRaw.map((e) => resolveParserEntry(e, overrides)),\n };\n}\n\nfunction buildParserOnlyNodeEntry(resolved: ResolvedParserEntry): ExtensionNodeSpec {\n return {\n spec: {},\n fromMd: {tokenName: resolved.tokenName, tokenSpec: resolved.tokenSpec},\n toMd: () => {\n throw new Error(`Unexpected toMd() call on parser-only node \"${resolved.tokenName}\"`);\n },\n };\n}\n\nfunction buildParserOnlyMarkEntry(resolved: ResolvedParserEntry): ExtensionMarkSpec {\n return {\n spec: {},\n fromMd: {tokenName: resolved.tokenName, tokenSpec: resolved.tokenSpec},\n toMd: {open: '', close: ''},\n };\n}\n\nexport class ExtensionBuilder {\n static createContext(): BuilderContext<WysiwygEditor.Context> {\n return new Map();\n }\n\n /* eslint-disable @typescript-eslint/member-ordering */\n static readonly Priority = Priority;\n readonly Priority = ExtensionBuilder.Priority;\n /* eslint-enable @typescript-eslint/member-ordering */\n\n readonly #logger: Logger2.ILogger;\n #confMdCbs: {cb: ConfigureMdCallback; params: Required<ConfigureMdParams>}[] = [];\n #nodeSpecs: Record<string, {name: string; cb: AddPmNodeCallback}> = {};\n #markSpecs: Record<string, {name: string; cb: AddPmMarkCallback; priority: number}> = {};\n #plugins: {cb: AddPmPluginCallback; priority: number}[] = [];\n #actions: [string, AddActionCallback][] = [];\n\n // Granular add storage\n #rawNodeSpecs: Record<string, () => NodeSpec> = {};\n #rawMarkSpecs: Record<string, {cb: () => MarkSpec; priority: number}> = {};\n #rawParserSpecs: Record<string, {tokenName: string; cb: () => ParserToken}> = {};\n #rawNodeSerializers: Record<string, () => SerializerNodeToken> = {};\n #rawMarkSerializers: Record<string, () => SerializerMarkToken> = {};\n\n // Override chains\n #nodeSpecOverrides: Record<string, Array<(prev: NodeSpec) => NodeSpec>> = {};\n #markSpecOverrides: Record<string, Array<(prev: MarkSpec) => MarkSpec>> = {};\n #parserSpecOverrides: Record<string, Array<(prev: ParserToken) => ParserToken>> = {};\n #nodeSerializerOverrides: Record<\n string,\n Array<(prev: SerializerNodeToken) => SerializerNodeToken>\n > = {};\n #markSerializerOverrides: Record<\n string,\n Array<(prev: SerializerMarkToken) => SerializerMarkToken>\n > = {};\n\n readonly context: BuilderContext<WysiwygEditor.Context>;\n\n constructor(logger: Logger2.ILogger, context?: BuilderContext<WysiwygEditor.Context>) {\n this.#logger = logger;\n this.context = context ?? ExtensionBuilder.createContext();\n }\n\n get logger(): Logger2.ILogger {\n return this.#logger;\n }\n\n use(extension: Extension): this;\n use<T>(extension: ExtensionWithOptions<T>, options: T): this;\n use(extension: ExtensionWithParams, ...params: any[]): this {\n extension(this, ...params);\n return this;\n }\n\n configureMd(cb: ConfigureMdCallback, params: ConfigureMdParams = {}): this {\n this.#confMdCbs.push({\n cb,\n params: {\n text: params.text ?? true,\n markup: params.markup ?? true,\n },\n });\n return this;\n }\n\n /**\n * @deprecated Will be removed in the next major version.\n * Use addNodeSpec() + addMarkdownTokenParserSpec() + addNodeSerializerSpec() instead.\n */\n addNode(name: string, cb: AddPmNodeCallback): this {\n if (this.#nodeSpecs[name]) {\n throw new Error(`ProseMirror node with this name \"${name}\" already exist`);\n }\n if (this.#rawNodeSpecs[name]) {\n throw new Error(\n `Node with name \"${name}\" already registered via addNodeSpec. ` +\n `Cannot use addNode for a node that already has granular registrations.`,\n );\n }\n if (this.#rawNodeSerializers[name]) {\n throw new Error(\n `Node serializer for \"${name}\" already registered via addNodeSerializerSpec. ` +\n `Cannot use addNode for a node that already has granular registrations.`,\n );\n }\n this.#nodeSpecs[name] = {name, cb};\n return this;\n }\n\n /**\n * @deprecated Will be removed in the next major version.\n * Use addMarkSpec() + addMarkdownTokenParserSpec() + addMarkSerializerSpec() instead.\n */\n addMark(name: string, cb: AddPmMarkCallback, priority = DEFAULT_PRIORITY): this {\n if (this.#markSpecs[name]) {\n throw new Error(`ProseMirror mark with this name \"${name}\" already exist`);\n }\n if (this.#rawMarkSpecs[name]) {\n throw new Error(\n `Mark with name \"${name}\" already registered via addMarkSpec. ` +\n `Cannot use addMark for a mark that already has granular registrations.`,\n );\n }\n if (this.#rawMarkSerializers[name]) {\n throw new Error(\n `Mark serializer for \"${name}\" already registered via addMarkSerializerSpec. ` +\n `Cannot use addMark for a mark that already has granular registrations.`,\n );\n }\n this.#markSpecs[name] = {name, cb, priority};\n return this;\n }\n\n addPlugin(cb: AddPmPluginCallback, priority = DEFAULT_PRIORITY): this {\n this.#plugins.push({cb, priority});\n return this;\n }\n\n addKeymap(cb: AddPmKeymapCallback, priority = DEFAULT_PRIORITY): this {\n this.#plugins.push({cb: (...args) => keymap(cb(...args)), priority});\n return this;\n }\n\n addInputRules(cb: AddPmInputRulesCallback, priority = DEFAULT_PRIORITY): this {\n this.#plugins.push({cb: (...args) => inputRules(cb(...args)), priority});\n return this;\n }\n\n addAction(name: string, cb: AddActionCallback): this {\n if (this.#actions.some(([actionName]) => actionName === name)) {\n throw new Error(\n `[Markdown Wysiwyg Editor] action with this name \"${name}\" already exist`,\n );\n }\n this.#actions.push([name, cb]);\n return this;\n }\n\n addNodeSpec(name: string, cb: () => NodeSpec): this {\n if (this.#rawNodeSpecs[name]) {\n throw new Error(`Node spec with name \"${name}\" already registered via addNodeSpec`);\n }\n if (this.#nodeSpecs[name]) {\n throw new Error(\n `Node with name \"${name}\" already registered via addNode. Use overrideNodeSpec to modify it.`,\n );\n }\n this.#rawNodeSpecs[name] = cb;\n return this;\n }\n\n addMarkSpec(name: string, cb: () => MarkSpec, priority = DEFAULT_PRIORITY): this {\n if (this.#rawMarkSpecs[name]) {\n throw new Error(`Mark spec with name \"${name}\" already registered via addMarkSpec`);\n }\n if (this.#markSpecs[name]) {\n throw new Error(\n `Mark with name \"${name}\" already registered via addMark. Use overrideMarkSpec to modify it.`,\n );\n }\n this.#rawMarkSpecs[name] = {cb, priority};\n return this;\n }\n\n addMarkdownTokenParserSpec(tokenName: string, cb: () => ParserToken): this {\n if (this.#rawParserSpecs[tokenName]) {\n throw new Error(\n `Parser spec for token \"${tokenName}\" already registered via addMarkdownTokenParserSpec`,\n );\n }\n this.#rawParserSpecs[tokenName] = {tokenName, cb};\n return this;\n }\n\n addNodeSerializerSpec(name: string, cb: () => SerializerNodeToken): this {\n if (this.#rawNodeSerializers[name]) {\n throw new Error(\n `Node serializer for \"${name}\" already registered via addNodeSerializerSpec`,\n );\n }\n if (this.#nodeSpecs[name]) {\n throw new Error(\n `Node with name \"${name}\" already registered via addNode. Use overrideNodeSerializerSpec to modify it.`,\n );\n }\n this.#rawNodeSerializers[name] = cb;\n return this;\n }\n\n addMarkSerializerSpec(name: string, cb: () => SerializerMarkToken): this {\n if (this.#rawMarkSerializers[name]) {\n throw new Error(\n `Mark serializer for \"${name}\" already registered via addMarkSerializerSpec`,\n );\n }\n if (this.#markSpecs[name]) {\n throw new Error(\n `Mark with name \"${name}\" already registered via addMark. Use overrideMarkSerializerSpec to modify it.`,\n );\n }\n this.#rawMarkSerializers[name] = cb;\n return this;\n }\n\n overrideNodeSpec(name: string, cb: (prev: NodeSpec) => NodeSpec): this {\n if (!this.#nodeSpecs[name] && !this.#rawNodeSpecs[name]) {\n throw new Error(\n `Cannot override node spec \"${name}\": not registered. Use addNode() or addNodeSpec() first.`,\n );\n }\n (this.#nodeSpecOverrides[name] ??= []).push(cb);\n return this;\n }\n\n overrideMarkSpec(name: string, cb: (prev: MarkSpec) => MarkSpec): this {\n if (!this.#markSpecs[name] && !this.#rawMarkSpecs[name]) {\n throw new Error(\n `Cannot override mark spec \"${name}\": not registered. Use addMark() or addMarkSpec() first.`,\n );\n }\n (this.#markSpecOverrides[name] ??= []).push(cb);\n return this;\n }\n\n overrideMarkdownTokenParserSpec(\n tokenName: string,\n cb: (prev: ParserToken) => ParserToken,\n ): this {\n if (\n !this.#rawParserSpecs[tokenName] &&\n !this.#nodeSpecs[tokenName] &&\n !this.#markSpecs[tokenName]\n ) {\n throw new Error(\n `Cannot override parser spec for token \"${tokenName}\": not registered. ` +\n `Use addMarkdownTokenParserSpec(), addNode(), or addMark() first.`,\n );\n }\n (this.#parserSpecOverrides[tokenName] ??= []).push(cb);\n return this;\n }\n\n overrideNodeSerializerSpec(\n name: string,\n cb: (prev: SerializerNodeToken) => SerializerNodeToken,\n ): this {\n if (!this.#nodeSpecs[name] && !this.#rawNodeSerializers[name]) {\n throw new Error(\n `Cannot override node serializer \"${name}\": not registered. Use addNode() or addNodeSerializerSpec() first.`,\n );\n }\n (this.#nodeSerializerOverrides[name] ??= []).push(cb);\n return this;\n }\n\n overrideMarkSerializerSpec(\n name: string,\n cb: (prev: SerializerMarkToken) => SerializerMarkToken,\n ): this {\n if (!this.#markSpecs[name] && !this.#rawMarkSerializers[name]) {\n throw new Error(\n `Cannot override mark serializer \"${name}\": not registered. Use addMark() or addMarkSerializerSpec() first.`,\n );\n }\n (this.#markSerializerOverrides[name] ??= []).push(cb);\n return this;\n }\n\n build(): ExtensionSpec {\n const confMd = this.#confMdCbs.slice();\n const nodes = {...this.#nodeSpecs};\n const marks = {...this.#markSpecs};\n const plugins = this.#plugins.slice();\n const actions = this.#actions.slice();\n\n const rawNodeSpecs = {...this.#rawNodeSpecs};\n const rawMarkSpecs = {...this.#rawMarkSpecs};\n const rawParserSpecs = {...this.#rawParserSpecs};\n const rawNodeSerializers = {...this.#rawNodeSerializers};\n const rawMarkSerializers = {...this.#rawMarkSerializers};\n\n const nodeSpecOverrides = {...this.#nodeSpecOverrides};\n const markSpecOverrides = {...this.#markSpecOverrides};\n const parserSpecOverrides = {...this.#parserSpecOverrides};\n const nodeSerializerOverrides = {...this.#nodeSerializerOverrides};\n const markSerializerOverrides = {...this.#markSerializerOverrides};\n\n // Pre-build entity name → parser specs lookup for O(1) access\n // Multiple markdown-it tokens can map to the same ProseMirror entity\n // (e.g. both 'fence' and 'code_block' tokens → 'code_block' node)\n const parserSpecsByEntity: Record<\n string,\n Array<{tokenName: string; tokenSpec: ParserToken}>\n > = {};\n for (const {tokenName, cb} of Object.values(rawParserSpecs)) {\n const tokenSpec = cb();\n (parserSpecsByEntity[tokenSpec.name] ??= []).push({tokenName, tokenSpec});\n }\n\n return {\n configureMd: (md, parserType) =>\n confMd.reduce((pMd, {cb, params}) => {\n if (parserType === 'text' && params.text) {\n return cb(pMd);\n }\n if (parserType === 'markup' && params.markup) {\n return cb(pMd);\n }\n return pMd;\n }, md),\n nodes: () => {\n let map = OrderedMap.from<ExtensionNodeSpec>({});\n\n // 1. Process addNode entries with overrides\n for (const {name, cb} of Object.values(nodes)) {\n const base = cb();\n const tokenName = base.fromMd.tokenName ?? name;\n const hasOverrides =\n nodeSpecOverrides[name] ||\n parserSpecOverrides[tokenName] ||\n nodeSerializerOverrides[name];\n\n if (hasOverrides) {\n map = map.addToEnd(name, {\n spec: applyOverrides(base.spec, nodeSpecOverrides[name]),\n fromMd: {\n tokenName: base.fromMd.tokenName,\n tokenSpec: applyOverrides(\n base.fromMd.tokenSpec,\n parserSpecOverrides[tokenName],\n ),\n },\n toMd: applyOverrides(base.toMd, nodeSerializerOverrides[name]),\n view: base.view,\n });\n } else {\n map = map.addToEnd(name, base);\n }\n }\n\n // 1b. Add parser-only entries for rawParserSpecs tokens targeting addNode entities\n for (const {name} of Object.values(nodes)) {\n const entries = parserSpecsByEntity[name];\n if (entries) {\n for (const entry of entries) {\n // Skip when tokenName matches the entity name —\n // the full spec was already added in step 1\n if (entry.tokenName === name) continue;\n map = map.addToEnd(\n entry.tokenName,\n buildParserOnlyNodeEntry(\n resolveParserEntry(entry, parserSpecOverrides),\n ),\n );\n }\n }\n }\n\n // 2. Process granular-only nodes\n for (const name of Object.keys(rawNodeSpecs)) {\n const spec = applyOverrides(rawNodeSpecs[name](), nodeSpecOverrides[name]);\n\n const {primary, extra} = resolveGranularParserEntries(\n name,\n 'node',\n parserSpecsByEntity,\n parserSpecOverrides,\n );\n\n if (!rawNodeSerializers[name]) {\n throw new Error(\n `Incomplete node spec for \"${name}\": missing serializer. ` +\n `Use addNodeSerializerSpec() to register a serializer for this node.`,\n );\n }\n const toMd = applyOverrides(\n rawNodeSerializers[name](),\n nodeSerializerOverrides[name],\n );\n\n map = map.addToEnd(name, {\n spec,\n fromMd: {tokenName: primary.tokenName, tokenSpec: primary.tokenSpec},\n toMd,\n });\n\n for (const entry of extra) {\n map = map.addToEnd(entry.tokenName, buildParserOnlyNodeEntry(entry));\n }\n }\n\n return map;\n },\n marks: () => {\n // The order of marks in schema is important when serializing pm-document to DOM or markup\n // https://discuss.prosemirror.net/t/marks-priority/4463\n\n // 1. Process addMark entries with overrides\n const allMarks: {\n name: string;\n priority: number;\n buildSpec: () => ExtensionMarkSpec;\n }[] = [];\n\n for (const {name, cb, priority} of Object.values(marks)) {\n allMarks.push({\n name,\n priority,\n buildSpec: () => {\n const base = cb();\n const tokenName = base.fromMd.tokenName ?? name;\n const hasOverrides =\n markSpecOverrides[name] ||\n parserSpecOverrides[tokenName] ||\n markSerializerOverrides[name];\n\n if (hasOverrides) {\n return {\n spec: applyOverrides(base.spec, markSpecOverrides[name]),\n fromMd: {\n tokenName: base.fromMd.tokenName,\n tokenSpec: applyOverrides(\n base.fromMd.tokenSpec,\n parserSpecOverrides[tokenName],\n ),\n },\n toMd: applyOverrides(base.toMd, markSerializerOverrides[name]),\n view: base.view,\n };\n }\n return base;\n },\n });\n }\n\n // 1b. Add parser-only entries for rawParserSpecs tokens targeting addMark entities\n for (const {name, priority} of Object.values(marks)) {\n const entries = parserSpecsByEntity[name];\n if (entries) {\n for (const entry of entries) {\n // Skip when tokenName matches the entity name —\n // the full spec was already added in step 1\n if (entry.tokenName === name) continue;\n allMarks.push({\n name: entry.tokenName,\n priority,\n buildSpec: () =>\n buildParserOnlyMarkEntry(\n resolveParserEntry(entry, parserSpecOverrides),\n ),\n });\n }\n }\n }\n\n // 2. Process granular-only marks\n for (const name of Object.keys(rawMarkSpecs)) {\n const {cb: specCb, priority} = rawMarkSpecs[name];\n\n const {primary, extra} = resolveGranularParserEntries(\n name,\n 'mark',\n parserSpecsByEntity,\n parserSpecOverrides,\n );\n\n if (!rawMarkSerializers[name]) {\n throw new Error(\n `Incomplete mark spec for \"${name}\": missing serializer. ` +\n `Use addMarkSerializerSpec() to register a serializer for this mark.`,\n );\n }\n\n allMarks.push({\n name,\n priority,\n buildSpec: () => {\n const spec = applyOverrides(specCb(), markSpecOverrides[name]);\n const toMd = applyOverrides(\n rawMarkSerializers[name](),\n markSerializerOverrides[name],\n );\n return {\n spec,\n fromMd: {\n tokenName: primary.tokenName,\n tokenSpec: primary.tokenSpec,\n },\n toMd,\n };\n },\n });\n\n for (const entry of extra) {\n allMarks.push({\n name: entry.tokenName,\n priority,\n buildSpec: () => buildParserOnlyMarkEntry(entry),\n });\n }\n }\n\n allMarks.sort((a, b) => b.priority - a.priority);\n let map = OrderedMap.from<ExtensionMarkSpec>({});\n for (const {name, buildSpec} of allMarks) {\n map = map.addToEnd(name, buildSpec());\n }\n return map;\n },\n plugins: (deps) => {\n return plugins\n .sort((a, b) => b.priority - a.priority)\n .reduce<Plugin[]>((acc, {cb}) => {\n const res = cb(deps);\n if (Array.isArray(res)) acc.push(...res);\n else acc.push(res);\n return acc;\n }, []);\n },\n actions: (deps) =>\n actions.reduce(\n (obj, [name, cb]) => {\n obj[name] = cb(deps);\n return obj;\n },\n {} as Record<string, ActionSpec>,\n ),\n };\n }\n}\n"]}
@@ -39,6 +39,7 @@ export declare class MarkdownSerializerState {
39
39
  inTightList: boolean;
40
40
  noAutoBlank: boolean;
41
41
  isAutolink: boolean | undefined;
42
+ atBlockStart: boolean;
42
43
  escapeWhitespace: boolean;
43
44
  escapeCharacters?: string[];
44
45
  private readonly nodes;
@@ -59,7 +60,7 @@ export declare class MarkdownSerializerState {
59
60
  text(text: string, escape?: boolean): void;
60
61
  render(node: Node, parent: Node, index: number): void;
61
62
  renderContent(parent: Node): void;
62
- renderInline(parent: Node): void;
63
+ renderInline(parent: Node, fromBlockStart?: boolean): void;
63
64
  renderList(node: Node, delim: string, firstDelim: (index: number, firstDelimNode: Node) => string): void;
64
65
  esc(str: string, startOfLine?: boolean): string;
65
66
  escWhitespace(str: string): string;
@@ -69,5 +70,7 @@ export declare class MarkdownSerializerState {
69
70
  leading: string | undefined;
70
71
  trailing: string | undefined;
71
72
  };
73
+ private isMarkAhead;
74
+ private getMark;
72
75
  }
73
76
  export {};