@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
@@ -12,6 +12,43 @@ var Priority;
12
12
  Priority[Priority["Lowest"] = 0] = "Lowest";
13
13
  })(Priority || (Priority = {}));
14
14
  const DEFAULT_PRIORITY = Priority.Medium;
15
+ function applyOverrides(initial, overrides) {
16
+ return overrides ? overrides.reduce((acc, fn) => fn(acc), initial) : initial;
17
+ }
18
+ function resolveParserEntry(entry, overrides) {
19
+ return {
20
+ tokenName: entry.tokenName,
21
+ tokenSpec: applyOverrides(entry.tokenSpec, overrides[entry.tokenName]),
22
+ };
23
+ }
24
+ function resolveGranularParserEntries(entityName, entityType, parserSpecsByEntity, overrides) {
25
+ const entries = parserSpecsByEntity[entityName];
26
+ if (!entries || entries.length === 0) {
27
+ throw new Error(`Incomplete ${entityType} spec for "${entityName}": missing parser spec. ` +
28
+ `Use addMarkdownTokenParserSpec() to register a parser for this ${entityType}.`);
29
+ }
30
+ const [primaryRaw, ...extraRaw] = entries;
31
+ return {
32
+ primary: resolveParserEntry(primaryRaw, overrides),
33
+ extra: extraRaw.map((e) => resolveParserEntry(e, overrides)),
34
+ };
35
+ }
36
+ function buildParserOnlyNodeEntry(resolved) {
37
+ return {
38
+ spec: {},
39
+ fromMd: { tokenName: resolved.tokenName, tokenSpec: resolved.tokenSpec },
40
+ toMd: () => {
41
+ throw new Error(`Unexpected toMd() call on parser-only node "${resolved.tokenName}"`);
42
+ },
43
+ };
44
+ }
45
+ function buildParserOnlyMarkEntry(resolved) {
46
+ return {
47
+ spec: {},
48
+ fromMd: { tokenName: resolved.tokenName, tokenSpec: resolved.tokenSpec },
49
+ toMd: { open: '', close: '' },
50
+ };
51
+ }
15
52
  export class ExtensionBuilder {
16
53
  static createContext() {
17
54
  return new Map();
@@ -26,6 +63,18 @@ export class ExtensionBuilder {
26
63
  #markSpecs = {};
27
64
  #plugins = [];
28
65
  #actions = [];
66
+ // Granular add storage
67
+ #rawNodeSpecs = {};
68
+ #rawMarkSpecs = {};
69
+ #rawParserSpecs = {};
70
+ #rawNodeSerializers = {};
71
+ #rawMarkSerializers = {};
72
+ // Override chains
73
+ #nodeSpecOverrides = {};
74
+ #markSpecOverrides = {};
75
+ #parserSpecOverrides = {};
76
+ #nodeSerializerOverrides = {};
77
+ #markSerializerOverrides = {};
29
78
  context;
30
79
  constructor(logger, context) {
31
80
  this.#logger = logger;
@@ -48,17 +97,41 @@ export class ExtensionBuilder {
48
97
  });
49
98
  return this;
50
99
  }
100
+ /**
101
+ * @deprecated Will be removed in the next major version.
102
+ * Use addNodeSpec() + addMarkdownTokenParserSpec() + addNodeSerializerSpec() instead.
103
+ */
51
104
  addNode(name, cb) {
52
105
  if (this.#nodeSpecs[name]) {
53
106
  throw new Error(`ProseMirror node with this name "${name}" already exist`);
54
107
  }
108
+ if (this.#rawNodeSpecs[name]) {
109
+ throw new Error(`Node with name "${name}" already registered via addNodeSpec. ` +
110
+ `Cannot use addNode for a node that already has granular registrations.`);
111
+ }
112
+ if (this.#rawNodeSerializers[name]) {
113
+ throw new Error(`Node serializer for "${name}" already registered via addNodeSerializerSpec. ` +
114
+ `Cannot use addNode for a node that already has granular registrations.`);
115
+ }
55
116
  this.#nodeSpecs[name] = { name, cb };
56
117
  return this;
57
118
  }
119
+ /**
120
+ * @deprecated Will be removed in the next major version.
121
+ * Use addMarkSpec() + addMarkdownTokenParserSpec() + addMarkSerializerSpec() instead.
122
+ */
58
123
  addMark(name, cb, priority = DEFAULT_PRIORITY) {
59
124
  if (this.#markSpecs[name]) {
60
125
  throw new Error(`ProseMirror mark with this name "${name}" already exist`);
61
126
  }
127
+ if (this.#rawMarkSpecs[name]) {
128
+ throw new Error(`Mark with name "${name}" already registered via addMarkSpec. ` +
129
+ `Cannot use addMark for a mark that already has granular registrations.`);
130
+ }
131
+ if (this.#rawMarkSerializers[name]) {
132
+ throw new Error(`Mark serializer for "${name}" already registered via addMarkSerializerSpec. ` +
133
+ `Cannot use addMark for a mark that already has granular registrations.`);
134
+ }
62
135
  this.#markSpecs[name] = { name, cb, priority };
63
136
  return this;
64
137
  }
@@ -81,12 +154,115 @@ export class ExtensionBuilder {
81
154
  this.#actions.push([name, cb]);
82
155
  return this;
83
156
  }
157
+ addNodeSpec(name, cb) {
158
+ if (this.#rawNodeSpecs[name]) {
159
+ throw new Error(`Node spec with name "${name}" already registered via addNodeSpec`);
160
+ }
161
+ if (this.#nodeSpecs[name]) {
162
+ throw new Error(`Node with name "${name}" already registered via addNode. Use overrideNodeSpec to modify it.`);
163
+ }
164
+ this.#rawNodeSpecs[name] = cb;
165
+ return this;
166
+ }
167
+ addMarkSpec(name, cb, priority = DEFAULT_PRIORITY) {
168
+ if (this.#rawMarkSpecs[name]) {
169
+ throw new Error(`Mark spec with name "${name}" already registered via addMarkSpec`);
170
+ }
171
+ if (this.#markSpecs[name]) {
172
+ throw new Error(`Mark with name "${name}" already registered via addMark. Use overrideMarkSpec to modify it.`);
173
+ }
174
+ this.#rawMarkSpecs[name] = { cb, priority };
175
+ return this;
176
+ }
177
+ addMarkdownTokenParserSpec(tokenName, cb) {
178
+ if (this.#rawParserSpecs[tokenName]) {
179
+ throw new Error(`Parser spec for token "${tokenName}" already registered via addMarkdownTokenParserSpec`);
180
+ }
181
+ this.#rawParserSpecs[tokenName] = { tokenName, cb };
182
+ return this;
183
+ }
184
+ addNodeSerializerSpec(name, cb) {
185
+ if (this.#rawNodeSerializers[name]) {
186
+ throw new Error(`Node serializer for "${name}" already registered via addNodeSerializerSpec`);
187
+ }
188
+ if (this.#nodeSpecs[name]) {
189
+ throw new Error(`Node with name "${name}" already registered via addNode. Use overrideNodeSerializerSpec to modify it.`);
190
+ }
191
+ this.#rawNodeSerializers[name] = cb;
192
+ return this;
193
+ }
194
+ addMarkSerializerSpec(name, cb) {
195
+ if (this.#rawMarkSerializers[name]) {
196
+ throw new Error(`Mark serializer for "${name}" already registered via addMarkSerializerSpec`);
197
+ }
198
+ if (this.#markSpecs[name]) {
199
+ throw new Error(`Mark with name "${name}" already registered via addMark. Use overrideMarkSerializerSpec to modify it.`);
200
+ }
201
+ this.#rawMarkSerializers[name] = cb;
202
+ return this;
203
+ }
204
+ overrideNodeSpec(name, cb) {
205
+ if (!this.#nodeSpecs[name] && !this.#rawNodeSpecs[name]) {
206
+ throw new Error(`Cannot override node spec "${name}": not registered. Use addNode() or addNodeSpec() first.`);
207
+ }
208
+ (this.#nodeSpecOverrides[name] ??= []).push(cb);
209
+ return this;
210
+ }
211
+ overrideMarkSpec(name, cb) {
212
+ if (!this.#markSpecs[name] && !this.#rawMarkSpecs[name]) {
213
+ throw new Error(`Cannot override mark spec "${name}": not registered. Use addMark() or addMarkSpec() first.`);
214
+ }
215
+ (this.#markSpecOverrides[name] ??= []).push(cb);
216
+ return this;
217
+ }
218
+ overrideMarkdownTokenParserSpec(tokenName, cb) {
219
+ if (!this.#rawParserSpecs[tokenName] &&
220
+ !this.#nodeSpecs[tokenName] &&
221
+ !this.#markSpecs[tokenName]) {
222
+ throw new Error(`Cannot override parser spec for token "${tokenName}": not registered. ` +
223
+ `Use addMarkdownTokenParserSpec(), addNode(), or addMark() first.`);
224
+ }
225
+ (this.#parserSpecOverrides[tokenName] ??= []).push(cb);
226
+ return this;
227
+ }
228
+ overrideNodeSerializerSpec(name, cb) {
229
+ if (!this.#nodeSpecs[name] && !this.#rawNodeSerializers[name]) {
230
+ throw new Error(`Cannot override node serializer "${name}": not registered. Use addNode() or addNodeSerializerSpec() first.`);
231
+ }
232
+ (this.#nodeSerializerOverrides[name] ??= []).push(cb);
233
+ return this;
234
+ }
235
+ overrideMarkSerializerSpec(name, cb) {
236
+ if (!this.#markSpecs[name] && !this.#rawMarkSerializers[name]) {
237
+ throw new Error(`Cannot override mark serializer "${name}": not registered. Use addMark() or addMarkSerializerSpec() first.`);
238
+ }
239
+ (this.#markSerializerOverrides[name] ??= []).push(cb);
240
+ return this;
241
+ }
84
242
  build() {
85
243
  const confMd = this.#confMdCbs.slice();
86
244
  const nodes = { ...this.#nodeSpecs };
87
245
  const marks = { ...this.#markSpecs };
88
246
  const plugins = this.#plugins.slice();
89
247
  const actions = this.#actions.slice();
248
+ const rawNodeSpecs = { ...this.#rawNodeSpecs };
249
+ const rawMarkSpecs = { ...this.#rawMarkSpecs };
250
+ const rawParserSpecs = { ...this.#rawParserSpecs };
251
+ const rawNodeSerializers = { ...this.#rawNodeSerializers };
252
+ const rawMarkSerializers = { ...this.#rawMarkSerializers };
253
+ const nodeSpecOverrides = { ...this.#nodeSpecOverrides };
254
+ const markSpecOverrides = { ...this.#markSpecOverrides };
255
+ const parserSpecOverrides = { ...this.#parserSpecOverrides };
256
+ const nodeSerializerOverrides = { ...this.#nodeSerializerOverrides };
257
+ const markSerializerOverrides = { ...this.#markSerializerOverrides };
258
+ // Pre-build entity name → parser specs lookup for O(1) access
259
+ // Multiple markdown-it tokens can map to the same ProseMirror entity
260
+ // (e.g. both 'fence' and 'code_block' tokens → 'code_block' node)
261
+ const parserSpecsByEntity = {};
262
+ for (const { tokenName, cb } of Object.values(rawParserSpecs)) {
263
+ const tokenSpec = cb();
264
+ (parserSpecsByEntity[tokenSpec.name] ??= []).push({ tokenName, tokenSpec });
265
+ }
90
266
  return {
91
267
  configureMd: (md, parserType) => confMd.reduce((pMd, { cb, params }) => {
92
268
  if (parserType === 'text' && params.text) {
@@ -99,18 +275,144 @@ export class ExtensionBuilder {
99
275
  }, md),
100
276
  nodes: () => {
101
277
  let map = OrderedMap.from({});
278
+ // 1. Process addNode entries with overrides
102
279
  for (const { name, cb } of Object.values(nodes)) {
103
- map = map.addToEnd(name, cb());
280
+ const base = cb();
281
+ const tokenName = base.fromMd.tokenName ?? name;
282
+ const hasOverrides = nodeSpecOverrides[name] ||
283
+ parserSpecOverrides[tokenName] ||
284
+ nodeSerializerOverrides[name];
285
+ if (hasOverrides) {
286
+ map = map.addToEnd(name, {
287
+ spec: applyOverrides(base.spec, nodeSpecOverrides[name]),
288
+ fromMd: {
289
+ tokenName: base.fromMd.tokenName,
290
+ tokenSpec: applyOverrides(base.fromMd.tokenSpec, parserSpecOverrides[tokenName]),
291
+ },
292
+ toMd: applyOverrides(base.toMd, nodeSerializerOverrides[name]),
293
+ view: base.view,
294
+ });
295
+ }
296
+ else {
297
+ map = map.addToEnd(name, base);
298
+ }
299
+ }
300
+ // 1b. Add parser-only entries for rawParserSpecs tokens targeting addNode entities
301
+ for (const { name } of Object.values(nodes)) {
302
+ const entries = parserSpecsByEntity[name];
303
+ if (entries) {
304
+ for (const entry of entries) {
305
+ // Skip when tokenName matches the entity name —
306
+ // the full spec was already added in step 1
307
+ if (entry.tokenName === name)
308
+ continue;
309
+ map = map.addToEnd(entry.tokenName, buildParserOnlyNodeEntry(resolveParserEntry(entry, parserSpecOverrides)));
310
+ }
311
+ }
312
+ }
313
+ // 2. Process granular-only nodes
314
+ for (const name of Object.keys(rawNodeSpecs)) {
315
+ const spec = applyOverrides(rawNodeSpecs[name](), nodeSpecOverrides[name]);
316
+ const { primary, extra } = resolveGranularParserEntries(name, 'node', parserSpecsByEntity, parserSpecOverrides);
317
+ if (!rawNodeSerializers[name]) {
318
+ throw new Error(`Incomplete node spec for "${name}": missing serializer. ` +
319
+ `Use addNodeSerializerSpec() to register a serializer for this node.`);
320
+ }
321
+ const toMd = applyOverrides(rawNodeSerializers[name](), nodeSerializerOverrides[name]);
322
+ map = map.addToEnd(name, {
323
+ spec,
324
+ fromMd: { tokenName: primary.tokenName, tokenSpec: primary.tokenSpec },
325
+ toMd,
326
+ });
327
+ for (const entry of extra) {
328
+ map = map.addToEnd(entry.tokenName, buildParserOnlyNodeEntry(entry));
329
+ }
104
330
  }
105
331
  return map;
106
332
  },
107
333
  marks: () => {
108
334
  // The order of marks in schema is important when serializing pm-document to DOM or markup
109
335
  // https://discuss.prosemirror.net/t/marks-priority/4463
110
- const sortedMarks = Object.values(marks).sort((a, b) => b.priority - a.priority);
336
+ // 1. Process addMark entries with overrides
337
+ const allMarks = [];
338
+ for (const { name, cb, priority } of Object.values(marks)) {
339
+ allMarks.push({
340
+ name,
341
+ priority,
342
+ buildSpec: () => {
343
+ const base = cb();
344
+ const tokenName = base.fromMd.tokenName ?? name;
345
+ const hasOverrides = markSpecOverrides[name] ||
346
+ parserSpecOverrides[tokenName] ||
347
+ markSerializerOverrides[name];
348
+ if (hasOverrides) {
349
+ return {
350
+ spec: applyOverrides(base.spec, markSpecOverrides[name]),
351
+ fromMd: {
352
+ tokenName: base.fromMd.tokenName,
353
+ tokenSpec: applyOverrides(base.fromMd.tokenSpec, parserSpecOverrides[tokenName]),
354
+ },
355
+ toMd: applyOverrides(base.toMd, markSerializerOverrides[name]),
356
+ view: base.view,
357
+ };
358
+ }
359
+ return base;
360
+ },
361
+ });
362
+ }
363
+ // 1b. Add parser-only entries for rawParserSpecs tokens targeting addMark entities
364
+ for (const { name, priority } of Object.values(marks)) {
365
+ const entries = parserSpecsByEntity[name];
366
+ if (entries) {
367
+ for (const entry of entries) {
368
+ // Skip when tokenName matches the entity name —
369
+ // the full spec was already added in step 1
370
+ if (entry.tokenName === name)
371
+ continue;
372
+ allMarks.push({
373
+ name: entry.tokenName,
374
+ priority,
375
+ buildSpec: () => buildParserOnlyMarkEntry(resolveParserEntry(entry, parserSpecOverrides)),
376
+ });
377
+ }
378
+ }
379
+ }
380
+ // 2. Process granular-only marks
381
+ for (const name of Object.keys(rawMarkSpecs)) {
382
+ const { cb: specCb, priority } = rawMarkSpecs[name];
383
+ const { primary, extra } = resolveGranularParserEntries(name, 'mark', parserSpecsByEntity, parserSpecOverrides);
384
+ if (!rawMarkSerializers[name]) {
385
+ throw new Error(`Incomplete mark spec for "${name}": missing serializer. ` +
386
+ `Use addMarkSerializerSpec() to register a serializer for this mark.`);
387
+ }
388
+ allMarks.push({
389
+ name,
390
+ priority,
391
+ buildSpec: () => {
392
+ const spec = applyOverrides(specCb(), markSpecOverrides[name]);
393
+ const toMd = applyOverrides(rawMarkSerializers[name](), markSerializerOverrides[name]);
394
+ return {
395
+ spec,
396
+ fromMd: {
397
+ tokenName: primary.tokenName,
398
+ tokenSpec: primary.tokenSpec,
399
+ },
400
+ toMd,
401
+ };
402
+ },
403
+ });
404
+ for (const entry of extra) {
405
+ allMarks.push({
406
+ name: entry.tokenName,
407
+ priority,
408
+ buildSpec: () => buildParserOnlyMarkEntry(entry),
409
+ });
410
+ }
411
+ }
412
+ allMarks.sort((a, b) => b.priority - a.priority);
111
413
  let map = OrderedMap.from({});
112
- for (const { name, cb } of sortedMarks) {
113
- map = map.addToEnd(name, cb());
414
+ for (const { name, buildSpec } of allMarks) {
415
+ map = map.addToEnd(name, buildSpec());
114
416
  }
115
417
  return map;
116
418
  },
@@ -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 {};