@limetech/lime-elements 37.56.0 → 37.56.1

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 (30) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js +315 -247
  3. package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js.map +1 -1
  4. package/dist/cjs/limel-snackbar.cjs.entry.js +1 -0
  5. package/dist/cjs/limel-snackbar.cjs.entry.js.map +1 -1
  6. package/dist/cjs/limel-text-editor.cjs.entry.js +2 -2
  7. package/dist/cjs/limel-text-editor.cjs.entry.js.map +1 -1
  8. package/dist/collection/components/snackbar/snackbar.js +1 -0
  9. package/dist/collection/components/snackbar/snackbar.js.map +1 -1
  10. package/dist/collection/components/text-editor/text-editor.css +6 -13
  11. package/dist/collection/components/text-editor/text-editor.js +1 -1
  12. package/dist/collection/components/text-editor/text-editor.js.map +1 -1
  13. package/dist/esm/limel-prosemirror-adapter.entry.js +315 -247
  14. package/dist/esm/limel-prosemirror-adapter.entry.js.map +1 -1
  15. package/dist/esm/limel-snackbar.entry.js +1 -0
  16. package/dist/esm/limel-snackbar.entry.js.map +1 -1
  17. package/dist/esm/limel-text-editor.entry.js +2 -2
  18. package/dist/esm/limel-text-editor.entry.js.map +1 -1
  19. package/dist/lime-elements/lime-elements.esm.js +1 -1
  20. package/dist/lime-elements/p-232dd438.entry.js +2 -0
  21. package/dist/lime-elements/p-232dd438.entry.js.map +1 -0
  22. package/dist/lime-elements/p-4ae6f448.entry.js +2 -0
  23. package/dist/lime-elements/p-4ae6f448.entry.js.map +1 -0
  24. package/dist/lime-elements/{p-385f680b.entry.js → p-84c9482c.entry.js} +2 -2
  25. package/dist/lime-elements/{p-385f680b.entry.js.map → p-84c9482c.entry.js.map} +1 -1
  26. package/package.json +2 -2
  27. package/dist/lime-elements/p-200b7739.entry.js +0 -2
  28. package/dist/lime-elements/p-200b7739.entry.js.map +0 -1
  29. package/dist/lime-elements/p-a82054c2.entry.js +0 -2
  30. package/dist/lime-elements/p-a82054c2.entry.js.map +0 -1
@@ -1029,7 +1029,7 @@ class Fragment {
1029
1029
  /**
1030
1030
  Find the index and inner offset corresponding to a given relative
1031
1031
  position in this fragment. The result object will be reused
1032
- (overwritten) the next time the function is called. (Not public.)
1032
+ (overwritten) the next time the function is called. @internal
1033
1033
  */
1034
1034
  findIndex(pos, round = -1) {
1035
1035
  if (pos == 0)
@@ -1262,7 +1262,9 @@ class Mark {
1262
1262
  let type = schema.marks[json.type];
1263
1263
  if (!type)
1264
1264
  throw new RangeError(`There is no mark type ${json.type} in this schema`);
1265
- return type.create(json.attrs);
1265
+ let mark = type.create(json.attrs);
1266
+ type.checkAttrs(mark.attrs);
1267
+ return mark;
1266
1268
  }
1267
1269
  /**
1268
1270
  Test whether two sets of marks are identical.
@@ -1820,17 +1822,29 @@ class ResolvedPos {
1820
1822
  @internal
1821
1823
  */
1822
1824
  static resolveCached(doc, pos) {
1823
- for (let i = 0; i < resolveCache.length; i++) {
1824
- let cached = resolveCache[i];
1825
- if (cached.pos == pos && cached.doc == doc)
1826
- return cached;
1825
+ let cache = resolveCache.get(doc);
1826
+ if (cache) {
1827
+ for (let i = 0; i < cache.elts.length; i++) {
1828
+ let elt = cache.elts[i];
1829
+ if (elt.pos == pos)
1830
+ return elt;
1831
+ }
1832
+ }
1833
+ else {
1834
+ resolveCache.set(doc, cache = new ResolveCache);
1827
1835
  }
1828
- let result = resolveCache[resolveCachePos] = ResolvedPos.resolve(doc, pos);
1829
- resolveCachePos = (resolveCachePos + 1) % resolveCacheSize;
1836
+ let result = cache.elts[cache.i] = ResolvedPos.resolve(doc, pos);
1837
+ cache.i = (cache.i + 1) % resolveCacheSize;
1830
1838
  return result;
1831
1839
  }
1832
1840
  }
1833
- let resolveCache = [], resolveCachePos = 0, resolveCacheSize = 12;
1841
+ class ResolveCache {
1842
+ constructor() {
1843
+ this.elts = [];
1844
+ this.i = 0;
1845
+ }
1846
+ }
1847
+ const resolveCacheSize = 12, resolveCache = new WeakMap();
1834
1848
  /**
1835
1849
  Represents a flat range of content, i.e. one that starts and
1836
1850
  ends in the same node.
@@ -2230,13 +2244,17 @@ class Node$1 {
2230
2244
  }
2231
2245
  /**
2232
2246
  Check whether this node and its descendants conform to the
2233
- schema, and raise error when they do not.
2247
+ schema, and raise an exception when they do not.
2234
2248
  */
2235
2249
  check() {
2236
2250
  this.type.checkContent(this.content);
2251
+ this.type.checkAttrs(this.attrs);
2237
2252
  let copy = Mark.none;
2238
- for (let i = 0; i < this.marks.length; i++)
2239
- copy = this.marks[i].addToSet(copy);
2253
+ for (let i = 0; i < this.marks.length; i++) {
2254
+ let mark = this.marks[i];
2255
+ mark.type.checkAttrs(mark.attrs);
2256
+ copy = mark.addToSet(copy);
2257
+ }
2240
2258
  if (!Mark.sameSet(copy, this.marks))
2241
2259
  throw new RangeError(`Invalid collection of marks for node ${this.type.name}: ${this.marks.map(m => m.type.name)}`);
2242
2260
  this.content.forEach(node => node.check());
@@ -2262,7 +2280,7 @@ class Node$1 {
2262
2280
  static fromJSON(schema, json) {
2263
2281
  if (!json)
2264
2282
  throw new RangeError("Invalid input for Node.fromJSON");
2265
- let marks = null;
2283
+ let marks = undefined;
2266
2284
  if (json.marks) {
2267
2285
  if (!Array.isArray(json.marks))
2268
2286
  throw new RangeError("Invalid mark data for Node.fromJSON");
@@ -2274,7 +2292,9 @@ class Node$1 {
2274
2292
  return schema.text(json.text, marks);
2275
2293
  }
2276
2294
  let content = Fragment.fromJSON(schema, json.content);
2277
- return schema.nodeType(json.type).create(json.attrs, content, marks);
2295
+ let node = schema.nodeType(json.type).create(json.attrs, content, marks);
2296
+ node.type.checkAttrs(node.attrs);
2297
+ return node;
2278
2298
  }
2279
2299
  }
2280
2300
  Node$1.prototype.text = undefined;
@@ -2791,11 +2811,21 @@ function computeAttrs(attrs, value) {
2791
2811
  }
2792
2812
  return built;
2793
2813
  }
2794
- function initAttrs(attrs) {
2814
+ function checkAttrs(attrs, values, type, name) {
2815
+ for (let name in values)
2816
+ if (!(name in attrs))
2817
+ throw new RangeError(`Unsupported attribute ${name} for ${type} of type ${name}`);
2818
+ for (let name in attrs) {
2819
+ let attr = attrs[name];
2820
+ if (attr.validate)
2821
+ attr.validate(values[name]);
2822
+ }
2823
+ }
2824
+ function initAttrs(typeName, attrs) {
2795
2825
  let result = Object.create(null);
2796
2826
  if (attrs)
2797
2827
  for (let name in attrs)
2798
- result[name] = new Attribute(attrs[name]);
2828
+ result[name] = new Attribute(typeName, name, attrs[name]);
2799
2829
  return result;
2800
2830
  }
2801
2831
  /**
@@ -2830,7 +2860,7 @@ class NodeType$1 {
2830
2860
  */
2831
2861
  this.markSet = null;
2832
2862
  this.groups = spec.group ? spec.group.split(" ") : [];
2833
- this.attrs = initAttrs(spec.attrs);
2863
+ this.attrs = initAttrs(name, spec.attrs);
2834
2864
  this.defaultAttrs = defaultAttrs(this.attrs);
2835
2865
  this.contentMatch = null;
2836
2866
  this.inlineContent = null;
@@ -2934,7 +2964,7 @@ class NodeType$1 {
2934
2964
  }
2935
2965
  /**
2936
2966
  Returns true if the given fragment is valid content for this node
2937
- type with the given attributes.
2967
+ type.
2938
2968
  */
2939
2969
  validContent(content) {
2940
2970
  let result = this.contentMatch.matchFragment(content);
@@ -2955,6 +2985,12 @@ class NodeType$1 {
2955
2985
  throw new RangeError(`Invalid content for node ${this.name}: ${content.toString().slice(0, 50)}`);
2956
2986
  }
2957
2987
  /**
2988
+ @internal
2989
+ */
2990
+ checkAttrs(attrs) {
2991
+ checkAttrs(this.attrs, attrs, "node");
2992
+ }
2993
+ /**
2958
2994
  Check whether the given mark type is allowed in this node.
2959
2995
  */
2960
2996
  allowsMarkType(markType) {
@@ -3005,11 +3041,20 @@ class NodeType$1 {
3005
3041
  return result;
3006
3042
  }
3007
3043
  }
3044
+ function validateType(typeName, attrName, type) {
3045
+ let types = type.split("|");
3046
+ return (value) => {
3047
+ let name = value === null ? "null" : typeof value;
3048
+ if (types.indexOf(name) < 0)
3049
+ throw new RangeError(`Expected value of type ${types} for attribute ${attrName} on type ${typeName}, got ${name}`);
3050
+ };
3051
+ }
3008
3052
  // Attribute descriptors
3009
3053
  class Attribute {
3010
- constructor(options) {
3054
+ constructor(typeName, attrName, options) {
3011
3055
  this.hasDefault = Object.prototype.hasOwnProperty.call(options, "default");
3012
3056
  this.default = options.default;
3057
+ this.validate = typeof options.validate == "string" ? validateType(typeName, attrName, options.validate) : options.validate;
3013
3058
  }
3014
3059
  get isRequired() {
3015
3060
  return !this.hasDefault;
@@ -3047,7 +3092,7 @@ class MarkType {
3047
3092
  this.rank = rank;
3048
3093
  this.schema = schema;
3049
3094
  this.spec = spec;
3050
- this.attrs = initAttrs(spec.attrs);
3095
+ this.attrs = initAttrs(name, spec.attrs);
3051
3096
  this.excluded = null;
3052
3097
  let defaults = defaultAttrs(this.attrs);
3053
3098
  this.instance = defaults ? new Mark(this, defaults) : null;
@@ -3091,6 +3136,12 @@ class MarkType {
3091
3136
  return set[i];
3092
3137
  }
3093
3138
  /**
3139
+ @internal
3140
+ */
3141
+ checkAttrs(attrs) {
3142
+ checkAttrs(this.attrs, attrs, "mark");
3143
+ }
3144
+ /**
3094
3145
  Queries whether a given mark type is
3095
3146
  [excluded](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) by this one.
3096
3147
  */
@@ -3112,6 +3163,12 @@ class Schema {
3112
3163
  Construct a schema from a schema [specification](https://prosemirror.net/docs/ref/#model.SchemaSpec).
3113
3164
  */
3114
3165
  constructor(spec) {
3166
+ /**
3167
+ The [linebreak
3168
+ replacement](https://prosemirror.net/docs/ref/#model.NodeSpec.linebreakReplacement) node defined
3169
+ in this schema, if any.
3170
+ */
3171
+ this.linebreakReplacement = null;
3115
3172
  /**
3116
3173
  An object for storing whatever values modules may want to
3117
3174
  compute and cache per schema. (If you want to store something
@@ -3133,6 +3190,13 @@ class Schema {
3133
3190
  type.contentMatch = contentExprCache[contentExpr] ||
3134
3191
  (contentExprCache[contentExpr] = ContentMatch.parse(contentExpr, this.nodes));
3135
3192
  type.inlineContent = type.contentMatch.inlineContent;
3193
+ if (type.spec.linebreakReplacement) {
3194
+ if (this.linebreakReplacement)
3195
+ throw new RangeError("Multiple linebreak nodes defined");
3196
+ if (!type.isInline || !type.isLeaf)
3197
+ throw new RangeError("Linebreak replacement nodes must be inline leaf nodes");
3198
+ this.linebreakReplacement = type;
3199
+ }
3136
3200
  type.markSet = markExpr == "_" ? null :
3137
3201
  markExpr ? gatherMarks(this, markExpr.split(" ")) :
3138
3202
  markExpr == "" || !type.inlineContent ? [] : null;
@@ -3221,6 +3285,8 @@ function gatherMarks(schema, marks) {
3221
3285
  return found;
3222
3286
  }
3223
3287
 
3288
+ function isTagRule(rule) { return rule.tag != null; }
3289
+ function isStyleRule(rule) { return rule.style != null; }
3224
3290
  /**
3225
3291
  A DOM parser represents a strategy for parsing DOM content into a
3226
3292
  ProseMirror document conforming to a given schema. Its behavior is
@@ -3251,11 +3317,17 @@ class DOMParser {
3251
3317
  @internal
3252
3318
  */
3253
3319
  this.styles = [];
3320
+ let matchedStyles = this.matchedStyles = [];
3254
3321
  rules.forEach(rule => {
3255
- if (rule.tag)
3322
+ if (isTagRule(rule)) {
3256
3323
  this.tags.push(rule);
3257
- else if (rule.style)
3324
+ }
3325
+ else if (isStyleRule(rule)) {
3326
+ let prop = /[^=]*/.exec(rule.style)[0];
3327
+ if (matchedStyles.indexOf(prop) < 0)
3328
+ matchedStyles.push(prop);
3258
3329
  this.styles.push(rule);
3330
+ }
3259
3331
  });
3260
3332
  // Only normalize list elements when lists in the schema can't directly contain themselves
3261
3333
  this.normalizeLists = !this.tags.some(r => {
@@ -3270,7 +3342,7 @@ class DOMParser {
3270
3342
  */
3271
3343
  parse(dom, options = {}) {
3272
3344
  let context = new ParseContext(this, options, false);
3273
- context.addAll(dom, options.from, options.to);
3345
+ context.addAll(dom, Mark.none, options.from, options.to);
3274
3346
  return context.finish();
3275
3347
  }
3276
3348
  /**
@@ -3283,7 +3355,7 @@ class DOMParser {
3283
3355
  */
3284
3356
  parseSlice(dom, options = {}) {
3285
3357
  let context = new ParseContext(this, options, true);
3286
- context.addAll(dom, options.from, options.to);
3358
+ context.addAll(dom, Mark.none, options.from, options.to);
3287
3359
  return Slice.maxOpen(context.finish());
3288
3360
  }
3289
3361
  /**
@@ -3392,22 +3464,15 @@ function wsOptionsFor(type, preserveWhitespace, base) {
3392
3464
  return type && type.whitespace == "pre" ? OPT_PRESERVE_WS | OPT_PRESERVE_WS_FULL : base & ~OPT_OPEN_LEFT;
3393
3465
  }
3394
3466
  class NodeContext {
3395
- constructor(type, attrs,
3396
- // Marks applied to this node itself
3397
- marks,
3398
- // Marks that can't apply here, but will be used in children if possible
3399
- pendingMarks, solid, match, options) {
3467
+ constructor(type, attrs, marks, solid, match, options) {
3400
3468
  this.type = type;
3401
3469
  this.attrs = attrs;
3402
3470
  this.marks = marks;
3403
- this.pendingMarks = pendingMarks;
3404
3471
  this.solid = solid;
3405
3472
  this.options = options;
3406
3473
  this.content = [];
3407
3474
  // Marks applied to the node's children
3408
3475
  this.activeMarks = Mark.none;
3409
- // Nested Marks with same type
3410
- this.stashMarks = [];
3411
3476
  this.match = match || (options & OPT_OPEN_LEFT ? null : type.contentMatch);
3412
3477
  }
3413
3478
  findWrapping(node) {
@@ -3447,21 +3512,6 @@ class NodeContext {
3447
3512
  content = content.append(this.match.fillBefore(Fragment.empty, true));
3448
3513
  return this.type ? this.type.create(this.attrs, content, this.marks) : content;
3449
3514
  }
3450
- popFromStashMark(mark) {
3451
- for (let i = this.stashMarks.length - 1; i >= 0; i--)
3452
- if (mark.eq(this.stashMarks[i]))
3453
- return this.stashMarks.splice(i, 1)[0];
3454
- }
3455
- applyPending(nextType) {
3456
- for (let i = 0, pending = this.pendingMarks; i < pending.length; i++) {
3457
- let mark = pending[i];
3458
- if ((this.type ? this.type.allowsMarkType(mark.type) : markMayApply(mark.type, nextType)) &&
3459
- !mark.isInSet(this.activeMarks)) {
3460
- this.activeMarks = mark.addToSet(this.activeMarks);
3461
- this.pendingMarks = mark.removeFromSet(this.pendingMarks);
3462
- }
3463
- }
3464
- }
3465
3515
  inlineContext(node) {
3466
3516
  if (this.type)
3467
3517
  return this.type.inlineContent;
@@ -3483,11 +3533,11 @@ class ParseContext {
3483
3533
  let topNode = options.topNode, topContext;
3484
3534
  let topOptions = wsOptionsFor(null, options.preserveWhitespace, 0) | (isOpen ? OPT_OPEN_LEFT : 0);
3485
3535
  if (topNode)
3486
- topContext = new NodeContext(topNode.type, topNode.attrs, Mark.none, Mark.none, true, options.topMatch || topNode.type.contentMatch, topOptions);
3536
+ topContext = new NodeContext(topNode.type, topNode.attrs, Mark.none, true, options.topMatch || topNode.type.contentMatch, topOptions);
3487
3537
  else if (isOpen)
3488
- topContext = new NodeContext(null, null, Mark.none, Mark.none, true, null, topOptions);
3538
+ topContext = new NodeContext(null, null, Mark.none, true, null, topOptions);
3489
3539
  else
3490
- topContext = new NodeContext(parser.schema.topNodeType, null, Mark.none, Mark.none, true, null, topOptions);
3540
+ topContext = new NodeContext(parser.schema.topNodeType, null, Mark.none, true, null, topOptions);
3491
3541
  this.nodes = [topContext];
3492
3542
  this.find = options.findPositions;
3493
3543
  this.needsBlock = false;
@@ -3498,31 +3548,13 @@ class ParseContext {
3498
3548
  // Add a DOM node to the content. Text is inserted as text node,
3499
3549
  // otherwise, the node is passed to `addElement` or, if it has a
3500
3550
  // `style` attribute, `addElementWithStyles`.
3501
- addDOM(dom) {
3551
+ addDOM(dom, marks) {
3502
3552
  if (dom.nodeType == 3)
3503
- this.addTextNode(dom);
3553
+ this.addTextNode(dom, marks);
3504
3554
  else if (dom.nodeType == 1)
3505
- this.addElement(dom);
3506
- }
3507
- withStyleRules(dom, f) {
3508
- let style = dom.getAttribute("style");
3509
- if (!style)
3510
- return f();
3511
- let marks = this.readStyles(parseStyles(style));
3512
- if (!marks)
3513
- return; // A style with ignore: true
3514
- let [addMarks, removeMarks] = marks, top = this.top;
3515
- for (let i = 0; i < removeMarks.length; i++)
3516
- this.removePendingMark(removeMarks[i], top);
3517
- for (let i = 0; i < addMarks.length; i++)
3518
- this.addPendingMark(addMarks[i]);
3519
- f();
3520
- for (let i = 0; i < addMarks.length; i++)
3521
- this.removePendingMark(addMarks[i], top);
3522
- for (let i = 0; i < removeMarks.length; i++)
3523
- this.addPendingMark(removeMarks[i]);
3555
+ this.addElement(dom, marks);
3524
3556
  }
3525
- addTextNode(dom) {
3557
+ addTextNode(dom, marks) {
3526
3558
  let value = dom.nodeValue;
3527
3559
  let top = this.top;
3528
3560
  if (top.options & OPT_PRESERVE_WS_FULL ||
@@ -3549,7 +3581,7 @@ class ParseContext {
3549
3581
  value = value.replace(/\r\n?/g, "\n");
3550
3582
  }
3551
3583
  if (value)
3552
- this.insertNode(this.parser.schema.text(value));
3584
+ this.insertNode(this.parser.schema.text(value), marks);
3553
3585
  this.findInText(dom);
3554
3586
  }
3555
3587
  else {
@@ -3558,7 +3590,7 @@ class ParseContext {
3558
3590
  }
3559
3591
  // Try to find a handler for the given tag and use that to parse. If
3560
3592
  // none is found, the element's content nodes are added directly.
3561
- addElement(dom, matchAfter) {
3593
+ addElement(dom, marks, matchAfter) {
3562
3594
  let name = dom.nodeName.toLowerCase(), ruleID;
3563
3595
  if (listTags.hasOwnProperty(name) && this.parser.normalizeLists)
3564
3596
  normalizeList(dom);
@@ -3566,7 +3598,7 @@ class ParseContext {
3566
3598
  (ruleID = this.parser.matchTag(dom, this, matchAfter));
3567
3599
  if (rule ? rule.ignore : ignoreTags.hasOwnProperty(name)) {
3568
3600
  this.findInside(dom);
3569
- this.ignoreFallback(dom);
3601
+ this.ignoreFallback(dom, marks);
3570
3602
  }
3571
3603
  else if (!rule || rule.skip || rule.closeParent) {
3572
3604
  if (rule && rule.closeParent)
@@ -3584,92 +3616,97 @@ class ParseContext {
3584
3616
  this.needsBlock = true;
3585
3617
  }
3586
3618
  else if (!dom.firstChild) {
3587
- this.leafFallback(dom);
3619
+ this.leafFallback(dom, marks);
3588
3620
  return;
3589
3621
  }
3590
- if (rule && rule.skip)
3591
- this.addAll(dom);
3592
- else
3593
- this.withStyleRules(dom, () => this.addAll(dom));
3622
+ let innerMarks = rule && rule.skip ? marks : this.readStyles(dom, marks);
3623
+ if (innerMarks)
3624
+ this.addAll(dom, innerMarks);
3594
3625
  if (sync)
3595
3626
  this.sync(top);
3596
3627
  this.needsBlock = oldNeedsBlock;
3597
3628
  }
3598
3629
  else {
3599
- this.withStyleRules(dom, () => {
3600
- this.addElementByRule(dom, rule, rule.consuming === false ? ruleID : undefined);
3601
- });
3630
+ let innerMarks = this.readStyles(dom, marks);
3631
+ if (innerMarks)
3632
+ this.addElementByRule(dom, rule, innerMarks, rule.consuming === false ? ruleID : undefined);
3602
3633
  }
3603
3634
  }
3604
3635
  // Called for leaf DOM nodes that would otherwise be ignored
3605
- leafFallback(dom) {
3636
+ leafFallback(dom, marks) {
3606
3637
  if (dom.nodeName == "BR" && this.top.type && this.top.type.inlineContent)
3607
- this.addTextNode(dom.ownerDocument.createTextNode("\n"));
3638
+ this.addTextNode(dom.ownerDocument.createTextNode("\n"), marks);
3608
3639
  }
3609
3640
  // Called for ignored nodes
3610
- ignoreFallback(dom) {
3641
+ ignoreFallback(dom, marks) {
3611
3642
  // Ignored BR nodes should at least create an inline context
3612
3643
  if (dom.nodeName == "BR" && (!this.top.type || !this.top.type.inlineContent))
3613
- this.findPlace(this.parser.schema.text("-"));
3644
+ this.findPlace(this.parser.schema.text("-"), marks);
3614
3645
  }
3615
3646
  // Run any style parser associated with the node's styles. Either
3616
- // return an array of marks, or null to indicate some of the styles
3617
- // had a rule with `ignore` set.
3618
- readStyles(styles) {
3619
- let add = Mark.none, remove = Mark.none;
3620
- for (let i = 0; i < styles.length; i += 2) {
3621
- for (let after = undefined;;) {
3622
- let rule = this.parser.matchStyle(styles[i], styles[i + 1], this, after);
3623
- if (!rule)
3624
- break;
3625
- if (rule.ignore)
3626
- return null;
3627
- if (rule.clearMark) {
3628
- this.top.pendingMarks.concat(this.top.activeMarks).forEach(m => {
3629
- if (rule.clearMark(m))
3630
- remove = m.addToSet(remove);
3631
- });
3632
- }
3633
- else {
3634
- add = this.parser.schema.marks[rule.mark].create(rule.attrs).addToSet(add);
3635
- }
3636
- if (rule.consuming === false)
3637
- after = rule;
3638
- else
3639
- break;
3647
+ // return an updated array of marks, or null to indicate some of the
3648
+ // styles had a rule with `ignore` set.
3649
+ readStyles(dom, marks) {
3650
+ let styles = dom.style;
3651
+ // Because many properties will only show up in 'normalized' form
3652
+ // in `style.item` (i.e. text-decoration becomes
3653
+ // text-decoration-line, text-decoration-color, etc), we directly
3654
+ // query the styles mentioned in our rules instead of iterating
3655
+ // over the items.
3656
+ if (styles && styles.length)
3657
+ for (let i = 0; i < this.parser.matchedStyles.length; i++) {
3658
+ let name = this.parser.matchedStyles[i], value = styles.getPropertyValue(name);
3659
+ if (value)
3660
+ for (let after = undefined;;) {
3661
+ let rule = this.parser.matchStyle(name, value, this, after);
3662
+ if (!rule)
3663
+ break;
3664
+ if (rule.ignore)
3665
+ return null;
3666
+ if (rule.clearMark)
3667
+ marks = marks.filter(m => !rule.clearMark(m));
3668
+ else
3669
+ marks = marks.concat(this.parser.schema.marks[rule.mark].create(rule.attrs));
3670
+ if (rule.consuming === false)
3671
+ after = rule;
3672
+ else
3673
+ break;
3674
+ }
3640
3675
  }
3641
- }
3642
- return [add, remove];
3676
+ return marks;
3643
3677
  }
3644
3678
  // Look up a handler for the given node. If none are found, return
3645
3679
  // false. Otherwise, apply it, use its return value to drive the way
3646
3680
  // the node's content is wrapped, and return true.
3647
- addElementByRule(dom, rule, continueAfter) {
3648
- let sync, nodeType, mark;
3681
+ addElementByRule(dom, rule, marks, continueAfter) {
3682
+ let sync, nodeType;
3649
3683
  if (rule.node) {
3650
3684
  nodeType = this.parser.schema.nodes[rule.node];
3651
3685
  if (!nodeType.isLeaf) {
3652
- sync = this.enter(nodeType, rule.attrs || null, rule.preserveWhitespace);
3686
+ let inner = this.enter(nodeType, rule.attrs || null, marks, rule.preserveWhitespace);
3687
+ if (inner) {
3688
+ sync = true;
3689
+ marks = inner;
3690
+ }
3653
3691
  }
3654
- else if (!this.insertNode(nodeType.create(rule.attrs))) {
3655
- this.leafFallback(dom);
3692
+ else if (!this.insertNode(nodeType.create(rule.attrs), marks)) {
3693
+ this.leafFallback(dom, marks);
3656
3694
  }
3657
3695
  }
3658
3696
  else {
3659
3697
  let markType = this.parser.schema.marks[rule.mark];
3660
- mark = markType.create(rule.attrs);
3661
- this.addPendingMark(mark);
3698
+ marks = marks.concat(markType.create(rule.attrs));
3662
3699
  }
3663
3700
  let startIn = this.top;
3664
3701
  if (nodeType && nodeType.isLeaf) {
3665
3702
  this.findInside(dom);
3666
3703
  }
3667
3704
  else if (continueAfter) {
3668
- this.addElement(dom, continueAfter);
3705
+ this.addElement(dom, marks, continueAfter);
3669
3706
  }
3670
3707
  else if (rule.getContent) {
3671
3708
  this.findInside(dom);
3672
- rule.getContent(dom, this.parser.schema).forEach(node => this.insertNode(node));
3709
+ rule.getContent(dom, this.parser.schema).forEach(node => this.insertNode(node, marks));
3673
3710
  }
3674
3711
  else {
3675
3712
  let contentDOM = dom;
@@ -3680,28 +3717,26 @@ class ParseContext {
3680
3717
  else if (rule.contentElement)
3681
3718
  contentDOM = rule.contentElement;
3682
3719
  this.findAround(dom, contentDOM, true);
3683
- this.addAll(contentDOM);
3720
+ this.addAll(contentDOM, marks);
3684
3721
  }
3685
3722
  if (sync && this.sync(startIn))
3686
3723
  this.open--;
3687
- if (mark)
3688
- this.removePendingMark(mark, startIn);
3689
3724
  }
3690
3725
  // Add all child nodes between `startIndex` and `endIndex` (or the
3691
3726
  // whole node, if not given). If `sync` is passed, use it to
3692
3727
  // synchronize after every block element.
3693
- addAll(parent, startIndex, endIndex) {
3728
+ addAll(parent, marks, startIndex, endIndex) {
3694
3729
  let index = startIndex || 0;
3695
3730
  for (let dom = startIndex ? parent.childNodes[startIndex] : parent.firstChild, end = endIndex == null ? null : parent.childNodes[endIndex]; dom != end; dom = dom.nextSibling, ++index) {
3696
3731
  this.findAtPoint(parent, index);
3697
- this.addDOM(dom);
3732
+ this.addDOM(dom, marks);
3698
3733
  }
3699
3734
  this.findAtPoint(parent, index);
3700
3735
  }
3701
3736
  // Try to find a way to fit the given node type into the current
3702
3737
  // context. May add intermediate wrappers and/or leave non-solid
3703
3738
  // nodes that we're in.
3704
- findPlace(node) {
3739
+ findPlace(node, marks) {
3705
3740
  let route, sync;
3706
3741
  for (let depth = this.open; depth >= 0; depth--) {
3707
3742
  let cx = this.nodes[depth];
@@ -3716,53 +3751,61 @@ class ParseContext {
3716
3751
  break;
3717
3752
  }
3718
3753
  if (!route)
3719
- return false;
3754
+ return null;
3720
3755
  this.sync(sync);
3721
3756
  for (let i = 0; i < route.length; i++)
3722
- this.enterInner(route[i], null, false);
3723
- return true;
3757
+ marks = this.enterInner(route[i], null, marks, false);
3758
+ return marks;
3724
3759
  }
3725
3760
  // Try to insert the given node, adjusting the context when needed.
3726
- insertNode(node) {
3761
+ insertNode(node, marks) {
3727
3762
  if (node.isInline && this.needsBlock && !this.top.type) {
3728
3763
  let block = this.textblockFromContext();
3729
3764
  if (block)
3730
- this.enterInner(block);
3765
+ marks = this.enterInner(block, null, marks);
3731
3766
  }
3732
- if (this.findPlace(node)) {
3767
+ let innerMarks = this.findPlace(node, marks);
3768
+ if (innerMarks) {
3733
3769
  this.closeExtra();
3734
3770
  let top = this.top;
3735
- top.applyPending(node.type);
3736
3771
  if (top.match)
3737
3772
  top.match = top.match.matchType(node.type);
3738
- let marks = top.activeMarks;
3739
- for (let i = 0; i < node.marks.length; i++)
3740
- if (!top.type || top.type.allowsMarkType(node.marks[i].type))
3741
- marks = node.marks[i].addToSet(marks);
3742
- top.content.push(node.mark(marks));
3773
+ let nodeMarks = Mark.none;
3774
+ for (let m of innerMarks.concat(node.marks))
3775
+ if (top.type ? top.type.allowsMarkType(m.type) : markMayApply(m.type, node.type))
3776
+ nodeMarks = m.addToSet(nodeMarks);
3777
+ top.content.push(node.mark(nodeMarks));
3743
3778
  return true;
3744
3779
  }
3745
3780
  return false;
3746
3781
  }
3747
3782
  // Try to start a node of the given type, adjusting the context when
3748
3783
  // necessary.
3749
- enter(type, attrs, preserveWS) {
3750
- let ok = this.findPlace(type.create(attrs));
3751
- if (ok)
3752
- this.enterInner(type, attrs, true, preserveWS);
3753
- return ok;
3784
+ enter(type, attrs, marks, preserveWS) {
3785
+ let innerMarks = this.findPlace(type.create(attrs), marks);
3786
+ if (innerMarks)
3787
+ innerMarks = this.enterInner(type, attrs, marks, true, preserveWS);
3788
+ return innerMarks;
3754
3789
  }
3755
3790
  // Open a node of the given type
3756
- enterInner(type, attrs = null, solid = false, preserveWS) {
3791
+ enterInner(type, attrs, marks, solid = false, preserveWS) {
3757
3792
  this.closeExtra();
3758
3793
  let top = this.top;
3759
- top.applyPending(type);
3760
3794
  top.match = top.match && top.match.matchType(type);
3761
3795
  let options = wsOptionsFor(type, preserveWS, top.options);
3762
3796
  if ((top.options & OPT_OPEN_LEFT) && top.content.length == 0)
3763
3797
  options |= OPT_OPEN_LEFT;
3764
- this.nodes.push(new NodeContext(type, attrs, top.activeMarks, top.pendingMarks, solid, null, options));
3798
+ let applyMarks = Mark.none;
3799
+ marks = marks.filter(m => {
3800
+ if (top.type ? top.type.allowsMarkType(m.type) : markMayApply(m.type, type)) {
3801
+ applyMarks = m.addToSet(applyMarks);
3802
+ return false;
3803
+ }
3804
+ return true;
3805
+ });
3806
+ this.nodes.push(new NodeContext(type, attrs, applyMarks, solid, null, options));
3765
3807
  this.open++;
3808
+ return marks;
3766
3809
  }
3767
3810
  // Make sure all nodes above this.open are finished and added to
3768
3811
  // their parents
@@ -3876,29 +3919,6 @@ class ParseContext {
3876
3919
  return type;
3877
3920
  }
3878
3921
  }
3879
- addPendingMark(mark) {
3880
- let found = findSameMarkInSet(mark, this.top.pendingMarks);
3881
- if (found)
3882
- this.top.stashMarks.push(found);
3883
- this.top.pendingMarks = mark.addToSet(this.top.pendingMarks);
3884
- }
3885
- removePendingMark(mark, upto) {
3886
- for (let depth = this.open; depth >= 0; depth--) {
3887
- let level = this.nodes[depth];
3888
- let found = level.pendingMarks.lastIndexOf(mark);
3889
- if (found > -1) {
3890
- level.pendingMarks = mark.removeFromSet(level.pendingMarks);
3891
- }
3892
- else {
3893
- level.activeMarks = mark.removeFromSet(level.activeMarks);
3894
- let stashMark = level.popFromStashMark(mark);
3895
- if (stashMark && level.type && level.type.allowsMarkType(stashMark.type))
3896
- level.activeMarks = stashMark.addToSet(level.activeMarks);
3897
- }
3898
- if (level == upto)
3899
- break;
3900
- }
3901
- }
3902
3922
  }
3903
3923
  // Kludge to work around directly nested list nodes produced by some
3904
3924
  // tools and allowed by browsers to mean that the nested list is
@@ -3922,13 +3942,6 @@ function normalizeList(dom) {
3922
3942
  function matches(dom, selector) {
3923
3943
  return (dom.matches || dom.msMatchesSelector || dom.webkitMatchesSelector || dom.mozMatchesSelector).call(dom, selector);
3924
3944
  }
3925
- // Tokenize a style attribute into property/value pairs.
3926
- function parseStyles(style) {
3927
- let re = /\s*([\w-]+)\s*:\s*([^;]+)/g, m, result = [];
3928
- while (m = re.exec(style))
3929
- result.push(m[1], m[2].trim());
3930
- return result;
3931
- }
3932
3945
  function copy(obj) {
3933
3946
  let copy = {};
3934
3947
  for (let prop in obj)
@@ -3958,12 +3971,6 @@ function markMayApply(markType, nodeType) {
3958
3971
  return true;
3959
3972
  }
3960
3973
  }
3961
- function findSameMarkInSet(mark, set) {
3962
- for (let i = 0; i < set.length; i++) {
3963
- if (mark.eq(set[i]))
3964
- return set[i];
3965
- }
3966
- }
3967
3974
 
3968
3975
  /**
3969
3976
  A DOM serializer knows how to convert ProseMirror nodes and
@@ -4035,7 +4042,7 @@ class DOMSerializer {
4035
4042
  @internal
4036
4043
  */
4037
4044
  serializeNodeInner(node, options) {
4038
- let { dom, contentDOM } = DOMSerializer.renderSpec(doc$1(options), this.nodes[node.type.name](node));
4045
+ let { dom, contentDOM } = renderSpec(doc$1(options), this.nodes[node.type.name](node), null, node.attrs);
4039
4046
  if (contentDOM) {
4040
4047
  if (node.isLeaf)
4041
4048
  throw new RangeError("Content hole not allowed in a leaf node spec");
@@ -4066,57 +4073,10 @@ class DOMSerializer {
4066
4073
  */
4067
4074
  serializeMark(mark, inline, options = {}) {
4068
4075
  let toDOM = this.marks[mark.type.name];
4069
- return toDOM && DOMSerializer.renderSpec(doc$1(options), toDOM(mark, inline));
4070
- }
4071
- /**
4072
- Render an [output spec](https://prosemirror.net/docs/ref/#model.DOMOutputSpec) to a DOM node. If
4073
- the spec has a hole (zero) in it, `contentDOM` will point at the
4074
- node with the hole.
4075
- */
4076
- static renderSpec(doc, structure, xmlNS = null) {
4077
- if (typeof structure == "string")
4078
- return { dom: doc.createTextNode(structure) };
4079
- if (structure.nodeType != null)
4080
- return { dom: structure };
4081
- if (structure.dom && structure.dom.nodeType != null)
4082
- return structure;
4083
- let tagName = structure[0], space = tagName.indexOf(" ");
4084
- if (space > 0) {
4085
- xmlNS = tagName.slice(0, space);
4086
- tagName = tagName.slice(space + 1);
4087
- }
4088
- let contentDOM;
4089
- let dom = (xmlNS ? doc.createElementNS(xmlNS, tagName) : doc.createElement(tagName));
4090
- let attrs = structure[1], start = 1;
4091
- if (attrs && typeof attrs == "object" && attrs.nodeType == null && !Array.isArray(attrs)) {
4092
- start = 2;
4093
- for (let name in attrs)
4094
- if (attrs[name] != null) {
4095
- let space = name.indexOf(" ");
4096
- if (space > 0)
4097
- dom.setAttributeNS(name.slice(0, space), name.slice(space + 1), attrs[name]);
4098
- else
4099
- dom.setAttribute(name, attrs[name]);
4100
- }
4101
- }
4102
- for (let i = start; i < structure.length; i++) {
4103
- let child = structure[i];
4104
- if (child === 0) {
4105
- if (i < structure.length - 1 || i > start)
4106
- throw new RangeError("Content hole must be the only child of its parent node");
4107
- return { dom, contentDOM: dom };
4108
- }
4109
- else {
4110
- let { dom: inner, contentDOM: innerContent } = DOMSerializer.renderSpec(doc, child, xmlNS);
4111
- dom.appendChild(inner);
4112
- if (innerContent) {
4113
- if (contentDOM)
4114
- throw new RangeError("Multiple content holes");
4115
- contentDOM = innerContent;
4116
- }
4117
- }
4118
- }
4119
- return { dom, contentDOM };
4076
+ return toDOM && renderSpec(doc$1(options), toDOM(mark, inline), null, mark.attrs);
4077
+ }
4078
+ static renderSpec(doc, structure, xmlNS = null, blockArraysIn) {
4079
+ return renderSpec(doc, structure, xmlNS, blockArraysIn);
4120
4080
  }
4121
4081
  /**
4122
4082
  Build a serializer using the [`toDOM`](https://prosemirror.net/docs/ref/#model.NodeSpec.toDOM)
@@ -4155,6 +4115,88 @@ function gatherToDOM(obj) {
4155
4115
  function doc$1(options) {
4156
4116
  return options.document || window.document;
4157
4117
  }
4118
+ const suspiciousAttributeCache = new WeakMap();
4119
+ function suspiciousAttributes(attrs) {
4120
+ let value = suspiciousAttributeCache.get(attrs);
4121
+ if (value === undefined)
4122
+ suspiciousAttributeCache.set(attrs, value = suspiciousAttributesInner(attrs));
4123
+ return value;
4124
+ }
4125
+ function suspiciousAttributesInner(attrs) {
4126
+ let result = null;
4127
+ function scan(value) {
4128
+ if (value && typeof value == "object") {
4129
+ if (Array.isArray(value)) {
4130
+ if (typeof value[0] == "string") {
4131
+ if (!result)
4132
+ result = [];
4133
+ result.push(value);
4134
+ }
4135
+ else {
4136
+ for (let i = 0; i < value.length; i++)
4137
+ scan(value[i]);
4138
+ }
4139
+ }
4140
+ else {
4141
+ for (let prop in value)
4142
+ scan(value[prop]);
4143
+ }
4144
+ }
4145
+ }
4146
+ scan(attrs);
4147
+ return result;
4148
+ }
4149
+ function renderSpec(doc, structure, xmlNS, blockArraysIn) {
4150
+ if (typeof structure == "string")
4151
+ return { dom: doc.createTextNode(structure) };
4152
+ if (structure.nodeType != null)
4153
+ return { dom: structure };
4154
+ if (structure.dom && structure.dom.nodeType != null)
4155
+ return structure;
4156
+ let tagName = structure[0], suspicious;
4157
+ if (typeof tagName != "string")
4158
+ throw new RangeError("Invalid array passed to renderSpec");
4159
+ if (blockArraysIn && (suspicious = suspiciousAttributes(blockArraysIn)) &&
4160
+ suspicious.indexOf(structure) > -1)
4161
+ throw new RangeError("Using an array from an attribute object as a DOM spec. This may be an attempted cross site scripting attack.");
4162
+ let space = tagName.indexOf(" ");
4163
+ if (space > 0) {
4164
+ xmlNS = tagName.slice(0, space);
4165
+ tagName = tagName.slice(space + 1);
4166
+ }
4167
+ let contentDOM;
4168
+ let dom = (xmlNS ? doc.createElementNS(xmlNS, tagName) : doc.createElement(tagName));
4169
+ let attrs = structure[1], start = 1;
4170
+ if (attrs && typeof attrs == "object" && attrs.nodeType == null && !Array.isArray(attrs)) {
4171
+ start = 2;
4172
+ for (let name in attrs)
4173
+ if (attrs[name] != null) {
4174
+ let space = name.indexOf(" ");
4175
+ if (space > 0)
4176
+ dom.setAttributeNS(name.slice(0, space), name.slice(space + 1), attrs[name]);
4177
+ else
4178
+ dom.setAttribute(name, attrs[name]);
4179
+ }
4180
+ }
4181
+ for (let i = start; i < structure.length; i++) {
4182
+ let child = structure[i];
4183
+ if (child === 0) {
4184
+ if (i < structure.length - 1 || i > start)
4185
+ throw new RangeError("Content hole must be the only child of its parent node");
4186
+ return { dom, contentDOM: dom };
4187
+ }
4188
+ else {
4189
+ let { dom: inner, contentDOM: innerContent } = renderSpec(doc, child, xmlNS, blockArraysIn);
4190
+ dom.appendChild(inner);
4191
+ if (innerContent) {
4192
+ if (contentDOM)
4193
+ throw new RangeError("Multiple content holes");
4194
+ contentDOM = innerContent;
4195
+ }
4196
+ }
4197
+ }
4198
+ return { dom, contentDOM };
4199
+ }
4158
4200
 
4159
4201
  // Recovery values encode a range index and an offset. They are
4160
4202
  // represented as numbers, because tons of them will be created when
@@ -24875,9 +24917,9 @@ const schema = new Schema({
24875
24917
  strong: {
24876
24918
  parseDOM: [
24877
24919
  { tag: "strong" },
24878
- { tag: "b", getAttrs: (node) => node.style.fontWeight != "normal" && null },
24920
+ { tag: "b", getAttrs: node => node.style.fontWeight != "normal" && null },
24879
24921
  { style: "font-weight=400", clearMark: m => m.type.name == "strong" },
24880
- { style: "font-weight", getAttrs: (value) => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null }
24922
+ { style: "font-weight", getAttrs: value => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null }
24881
24923
  ],
24882
24924
  toDOM() { return ["strong"]; }
24883
24925
  },
@@ -25131,6 +25173,7 @@ new MarkdownParser(schema, MarkdownIt("commonmark", { html: false }), {
25131
25173
  code_inline: { mark: "code", noCloseToken: true }
25132
25174
  });
25133
25175
 
25176
+ const blankMark = { open: "", close: "", mixable: true };
25134
25177
  /**
25135
25178
  A specification for serializing a ProseMirror document as
25136
25179
  Markdown/CommonMark text.
@@ -25338,6 +25381,18 @@ class MarkdownSerializerState {
25338
25381
  }
25339
25382
  }
25340
25383
  /**
25384
+ @internal
25385
+ */
25386
+ getMark(name) {
25387
+ let info = this.marks[name];
25388
+ if (!info) {
25389
+ if (this.options.strict !== false)
25390
+ throw new Error(`Mark type \`${name}\` not supported by Markdown renderer`);
25391
+ info = blankMark;
25392
+ }
25393
+ return info;
25394
+ }
25395
+ /**
25341
25396
  Render a block, prefixing each line with `delim`, and the first
25342
25397
  line in `firstDelim`. `node` should be the node that is closed at
25343
25398
  the end of the block, and `f` is a function that renders the
@@ -25402,9 +25457,22 @@ class MarkdownSerializerState {
25402
25457
  Render the given node as a block.
25403
25458
  */
25404
25459
  render(node, parent, index) {
25405
- if (!this.nodes[node.type.name])
25406
- throw new Error("Token type `" + node.type.name + "` not supported by Markdown renderer");
25407
- this.nodes[node.type.name](this, node, parent, index);
25460
+ if (this.nodes[node.type.name]) {
25461
+ this.nodes[node.type.name](this, node, parent, index);
25462
+ }
25463
+ else {
25464
+ if (this.options.strict !== false) {
25465
+ throw new Error("Token type `" + node.type.name + "` not supported by Markdown renderer");
25466
+ }
25467
+ else if (!node.type.isLeaf) {
25468
+ if (node.type.inlineContent)
25469
+ this.renderInline(node);
25470
+ else
25471
+ this.renderContent(node);
25472
+ if (node.isBlock)
25473
+ this.closeBlock(node);
25474
+ }
25475
+ }
25408
25476
  }
25409
25477
  /**
25410
25478
  Render the contents of `parent` as block nodes.
@@ -25435,7 +25503,7 @@ class MarkdownSerializerState {
25435
25503
  // If whitespace has to be expelled from the node, adjust
25436
25504
  // leading and trailing accordingly.
25437
25505
  if (node && node.isText && marks.some(mark => {
25438
- let info = this.marks[mark.type.name];
25506
+ let info = this.getMark(mark.type.name);
25439
25507
  return info && info.expelEnclosingWhitespace && !mark.isInSet(active);
25440
25508
  })) {
25441
25509
  let [_, lead, rest] = /^(\s*)(.*)$/m.exec(node.text);
@@ -25447,7 +25515,7 @@ class MarkdownSerializerState {
25447
25515
  }
25448
25516
  }
25449
25517
  if (node && node.isText && marks.some(mark => {
25450
- let info = this.marks[mark.type.name];
25518
+ let info = this.getMark(mark.type.name);
25451
25519
  return info && info.expelEnclosingWhitespace &&
25452
25520
  (index == parent.childCount - 1 || !mark.isInSet(parent.child(index + 1).marks));
25453
25521
  })) {
@@ -25460,7 +25528,7 @@ class MarkdownSerializerState {
25460
25528
  }
25461
25529
  }
25462
25530
  let inner = marks.length ? marks[marks.length - 1] : null;
25463
- let noEsc = inner && this.marks[inner.type.name].escape === false;
25531
+ let noEsc = inner && this.getMark(inner.type.name).escape === false;
25464
25532
  let len = marks.length - (noEsc ? 1 : 0);
25465
25533
  // Try to reorder 'mixable' marks, such as em and strong, which
25466
25534
  // in Markdown may be opened and closed in different order, so
@@ -25468,11 +25536,11 @@ class MarkdownSerializerState {
25468
25536
  // active.
25469
25537
  outer: for (let i = 0; i < len; i++) {
25470
25538
  let mark = marks[i];
25471
- if (!this.marks[mark.type.name].mixable)
25539
+ if (!this.getMark(mark.type.name).mixable)
25472
25540
  break;
25473
25541
  for (let j = 0; j < active.length; j++) {
25474
25542
  let other = active[j];
25475
- if (!this.marks[other.type.name].mixable)
25543
+ if (!this.getMark(other.type.name).mixable)
25476
25544
  break;
25477
25545
  if (mark.eq(other)) {
25478
25546
  if (i > j)
@@ -25578,7 +25646,7 @@ class MarkdownSerializerState {
25578
25646
  Get the markdown string for a given opening or closing mark.
25579
25647
  */
25580
25648
  markString(mark, open, parent, index) {
25581
- let info = this.marks[mark.type.name];
25649
+ let info = this.getMark(mark.type.name);
25582
25650
  let value = open ? info.open : info.close;
25583
25651
  return typeof value == "string" ? value : value(this, mark, parent, index);
25584
25652
  }