@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
@@ -1025,7 +1025,7 @@ class Fragment {
1025
1025
  /**
1026
1026
  Find the index and inner offset corresponding to a given relative
1027
1027
  position in this fragment. The result object will be reused
1028
- (overwritten) the next time the function is called. (Not public.)
1028
+ (overwritten) the next time the function is called. @internal
1029
1029
  */
1030
1030
  findIndex(pos, round = -1) {
1031
1031
  if (pos == 0)
@@ -1258,7 +1258,9 @@ class Mark {
1258
1258
  let type = schema.marks[json.type];
1259
1259
  if (!type)
1260
1260
  throw new RangeError(`There is no mark type ${json.type} in this schema`);
1261
- return type.create(json.attrs);
1261
+ let mark = type.create(json.attrs);
1262
+ type.checkAttrs(mark.attrs);
1263
+ return mark;
1262
1264
  }
1263
1265
  /**
1264
1266
  Test whether two sets of marks are identical.
@@ -1816,17 +1818,29 @@ class ResolvedPos {
1816
1818
  @internal
1817
1819
  */
1818
1820
  static resolveCached(doc, pos) {
1819
- for (let i = 0; i < resolveCache.length; i++) {
1820
- let cached = resolveCache[i];
1821
- if (cached.pos == pos && cached.doc == doc)
1822
- return cached;
1821
+ let cache = resolveCache.get(doc);
1822
+ if (cache) {
1823
+ for (let i = 0; i < cache.elts.length; i++) {
1824
+ let elt = cache.elts[i];
1825
+ if (elt.pos == pos)
1826
+ return elt;
1827
+ }
1828
+ }
1829
+ else {
1830
+ resolveCache.set(doc, cache = new ResolveCache);
1823
1831
  }
1824
- let result = resolveCache[resolveCachePos] = ResolvedPos.resolve(doc, pos);
1825
- resolveCachePos = (resolveCachePos + 1) % resolveCacheSize;
1832
+ let result = cache.elts[cache.i] = ResolvedPos.resolve(doc, pos);
1833
+ cache.i = (cache.i + 1) % resolveCacheSize;
1826
1834
  return result;
1827
1835
  }
1828
1836
  }
1829
- let resolveCache = [], resolveCachePos = 0, resolveCacheSize = 12;
1837
+ class ResolveCache {
1838
+ constructor() {
1839
+ this.elts = [];
1840
+ this.i = 0;
1841
+ }
1842
+ }
1843
+ const resolveCacheSize = 12, resolveCache = new WeakMap();
1830
1844
  /**
1831
1845
  Represents a flat range of content, i.e. one that starts and
1832
1846
  ends in the same node.
@@ -2226,13 +2240,17 @@ class Node$1 {
2226
2240
  }
2227
2241
  /**
2228
2242
  Check whether this node and its descendants conform to the
2229
- schema, and raise error when they do not.
2243
+ schema, and raise an exception when they do not.
2230
2244
  */
2231
2245
  check() {
2232
2246
  this.type.checkContent(this.content);
2247
+ this.type.checkAttrs(this.attrs);
2233
2248
  let copy = Mark.none;
2234
- for (let i = 0; i < this.marks.length; i++)
2235
- copy = this.marks[i].addToSet(copy);
2249
+ for (let i = 0; i < this.marks.length; i++) {
2250
+ let mark = this.marks[i];
2251
+ mark.type.checkAttrs(mark.attrs);
2252
+ copy = mark.addToSet(copy);
2253
+ }
2236
2254
  if (!Mark.sameSet(copy, this.marks))
2237
2255
  throw new RangeError(`Invalid collection of marks for node ${this.type.name}: ${this.marks.map(m => m.type.name)}`);
2238
2256
  this.content.forEach(node => node.check());
@@ -2258,7 +2276,7 @@ class Node$1 {
2258
2276
  static fromJSON(schema, json) {
2259
2277
  if (!json)
2260
2278
  throw new RangeError("Invalid input for Node.fromJSON");
2261
- let marks = null;
2279
+ let marks = undefined;
2262
2280
  if (json.marks) {
2263
2281
  if (!Array.isArray(json.marks))
2264
2282
  throw new RangeError("Invalid mark data for Node.fromJSON");
@@ -2270,7 +2288,9 @@ class Node$1 {
2270
2288
  return schema.text(json.text, marks);
2271
2289
  }
2272
2290
  let content = Fragment.fromJSON(schema, json.content);
2273
- return schema.nodeType(json.type).create(json.attrs, content, marks);
2291
+ let node = schema.nodeType(json.type).create(json.attrs, content, marks);
2292
+ node.type.checkAttrs(node.attrs);
2293
+ return node;
2274
2294
  }
2275
2295
  }
2276
2296
  Node$1.prototype.text = undefined;
@@ -2787,11 +2807,21 @@ function computeAttrs(attrs, value) {
2787
2807
  }
2788
2808
  return built;
2789
2809
  }
2790
- function initAttrs(attrs) {
2810
+ function checkAttrs(attrs, values, type, name) {
2811
+ for (let name in values)
2812
+ if (!(name in attrs))
2813
+ throw new RangeError(`Unsupported attribute ${name} for ${type} of type ${name}`);
2814
+ for (let name in attrs) {
2815
+ let attr = attrs[name];
2816
+ if (attr.validate)
2817
+ attr.validate(values[name]);
2818
+ }
2819
+ }
2820
+ function initAttrs(typeName, attrs) {
2791
2821
  let result = Object.create(null);
2792
2822
  if (attrs)
2793
2823
  for (let name in attrs)
2794
- result[name] = new Attribute(attrs[name]);
2824
+ result[name] = new Attribute(typeName, name, attrs[name]);
2795
2825
  return result;
2796
2826
  }
2797
2827
  /**
@@ -2826,7 +2856,7 @@ class NodeType$1 {
2826
2856
  */
2827
2857
  this.markSet = null;
2828
2858
  this.groups = spec.group ? spec.group.split(" ") : [];
2829
- this.attrs = initAttrs(spec.attrs);
2859
+ this.attrs = initAttrs(name, spec.attrs);
2830
2860
  this.defaultAttrs = defaultAttrs(this.attrs);
2831
2861
  this.contentMatch = null;
2832
2862
  this.inlineContent = null;
@@ -2930,7 +2960,7 @@ class NodeType$1 {
2930
2960
  }
2931
2961
  /**
2932
2962
  Returns true if the given fragment is valid content for this node
2933
- type with the given attributes.
2963
+ type.
2934
2964
  */
2935
2965
  validContent(content) {
2936
2966
  let result = this.contentMatch.matchFragment(content);
@@ -2951,6 +2981,12 @@ class NodeType$1 {
2951
2981
  throw new RangeError(`Invalid content for node ${this.name}: ${content.toString().slice(0, 50)}`);
2952
2982
  }
2953
2983
  /**
2984
+ @internal
2985
+ */
2986
+ checkAttrs(attrs) {
2987
+ checkAttrs(this.attrs, attrs, "node");
2988
+ }
2989
+ /**
2954
2990
  Check whether the given mark type is allowed in this node.
2955
2991
  */
2956
2992
  allowsMarkType(markType) {
@@ -3001,11 +3037,20 @@ class NodeType$1 {
3001
3037
  return result;
3002
3038
  }
3003
3039
  }
3040
+ function validateType(typeName, attrName, type) {
3041
+ let types = type.split("|");
3042
+ return (value) => {
3043
+ let name = value === null ? "null" : typeof value;
3044
+ if (types.indexOf(name) < 0)
3045
+ throw new RangeError(`Expected value of type ${types} for attribute ${attrName} on type ${typeName}, got ${name}`);
3046
+ };
3047
+ }
3004
3048
  // Attribute descriptors
3005
3049
  class Attribute {
3006
- constructor(options) {
3050
+ constructor(typeName, attrName, options) {
3007
3051
  this.hasDefault = Object.prototype.hasOwnProperty.call(options, "default");
3008
3052
  this.default = options.default;
3053
+ this.validate = typeof options.validate == "string" ? validateType(typeName, attrName, options.validate) : options.validate;
3009
3054
  }
3010
3055
  get isRequired() {
3011
3056
  return !this.hasDefault;
@@ -3043,7 +3088,7 @@ class MarkType {
3043
3088
  this.rank = rank;
3044
3089
  this.schema = schema;
3045
3090
  this.spec = spec;
3046
- this.attrs = initAttrs(spec.attrs);
3091
+ this.attrs = initAttrs(name, spec.attrs);
3047
3092
  this.excluded = null;
3048
3093
  let defaults = defaultAttrs(this.attrs);
3049
3094
  this.instance = defaults ? new Mark(this, defaults) : null;
@@ -3087,6 +3132,12 @@ class MarkType {
3087
3132
  return set[i];
3088
3133
  }
3089
3134
  /**
3135
+ @internal
3136
+ */
3137
+ checkAttrs(attrs) {
3138
+ checkAttrs(this.attrs, attrs, "mark");
3139
+ }
3140
+ /**
3090
3141
  Queries whether a given mark type is
3091
3142
  [excluded](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) by this one.
3092
3143
  */
@@ -3108,6 +3159,12 @@ class Schema {
3108
3159
  Construct a schema from a schema [specification](https://prosemirror.net/docs/ref/#model.SchemaSpec).
3109
3160
  */
3110
3161
  constructor(spec) {
3162
+ /**
3163
+ The [linebreak
3164
+ replacement](https://prosemirror.net/docs/ref/#model.NodeSpec.linebreakReplacement) node defined
3165
+ in this schema, if any.
3166
+ */
3167
+ this.linebreakReplacement = null;
3111
3168
  /**
3112
3169
  An object for storing whatever values modules may want to
3113
3170
  compute and cache per schema. (If you want to store something
@@ -3129,6 +3186,13 @@ class Schema {
3129
3186
  type.contentMatch = contentExprCache[contentExpr] ||
3130
3187
  (contentExprCache[contentExpr] = ContentMatch.parse(contentExpr, this.nodes));
3131
3188
  type.inlineContent = type.contentMatch.inlineContent;
3189
+ if (type.spec.linebreakReplacement) {
3190
+ if (this.linebreakReplacement)
3191
+ throw new RangeError("Multiple linebreak nodes defined");
3192
+ if (!type.isInline || !type.isLeaf)
3193
+ throw new RangeError("Linebreak replacement nodes must be inline leaf nodes");
3194
+ this.linebreakReplacement = type;
3195
+ }
3132
3196
  type.markSet = markExpr == "_" ? null :
3133
3197
  markExpr ? gatherMarks(this, markExpr.split(" ")) :
3134
3198
  markExpr == "" || !type.inlineContent ? [] : null;
@@ -3217,6 +3281,8 @@ function gatherMarks(schema, marks) {
3217
3281
  return found;
3218
3282
  }
3219
3283
 
3284
+ function isTagRule(rule) { return rule.tag != null; }
3285
+ function isStyleRule(rule) { return rule.style != null; }
3220
3286
  /**
3221
3287
  A DOM parser represents a strategy for parsing DOM content into a
3222
3288
  ProseMirror document conforming to a given schema. Its behavior is
@@ -3247,11 +3313,17 @@ class DOMParser {
3247
3313
  @internal
3248
3314
  */
3249
3315
  this.styles = [];
3316
+ let matchedStyles = this.matchedStyles = [];
3250
3317
  rules.forEach(rule => {
3251
- if (rule.tag)
3318
+ if (isTagRule(rule)) {
3252
3319
  this.tags.push(rule);
3253
- else if (rule.style)
3320
+ }
3321
+ else if (isStyleRule(rule)) {
3322
+ let prop = /[^=]*/.exec(rule.style)[0];
3323
+ if (matchedStyles.indexOf(prop) < 0)
3324
+ matchedStyles.push(prop);
3254
3325
  this.styles.push(rule);
3326
+ }
3255
3327
  });
3256
3328
  // Only normalize list elements when lists in the schema can't directly contain themselves
3257
3329
  this.normalizeLists = !this.tags.some(r => {
@@ -3266,7 +3338,7 @@ class DOMParser {
3266
3338
  */
3267
3339
  parse(dom, options = {}) {
3268
3340
  let context = new ParseContext(this, options, false);
3269
- context.addAll(dom, options.from, options.to);
3341
+ context.addAll(dom, Mark.none, options.from, options.to);
3270
3342
  return context.finish();
3271
3343
  }
3272
3344
  /**
@@ -3279,7 +3351,7 @@ class DOMParser {
3279
3351
  */
3280
3352
  parseSlice(dom, options = {}) {
3281
3353
  let context = new ParseContext(this, options, true);
3282
- context.addAll(dom, options.from, options.to);
3354
+ context.addAll(dom, Mark.none, options.from, options.to);
3283
3355
  return Slice.maxOpen(context.finish());
3284
3356
  }
3285
3357
  /**
@@ -3388,22 +3460,15 @@ function wsOptionsFor(type, preserveWhitespace, base) {
3388
3460
  return type && type.whitespace == "pre" ? OPT_PRESERVE_WS | OPT_PRESERVE_WS_FULL : base & ~OPT_OPEN_LEFT;
3389
3461
  }
3390
3462
  class NodeContext {
3391
- constructor(type, attrs,
3392
- // Marks applied to this node itself
3393
- marks,
3394
- // Marks that can't apply here, but will be used in children if possible
3395
- pendingMarks, solid, match, options) {
3463
+ constructor(type, attrs, marks, solid, match, options) {
3396
3464
  this.type = type;
3397
3465
  this.attrs = attrs;
3398
3466
  this.marks = marks;
3399
- this.pendingMarks = pendingMarks;
3400
3467
  this.solid = solid;
3401
3468
  this.options = options;
3402
3469
  this.content = [];
3403
3470
  // Marks applied to the node's children
3404
3471
  this.activeMarks = Mark.none;
3405
- // Nested Marks with same type
3406
- this.stashMarks = [];
3407
3472
  this.match = match || (options & OPT_OPEN_LEFT ? null : type.contentMatch);
3408
3473
  }
3409
3474
  findWrapping(node) {
@@ -3443,21 +3508,6 @@ class NodeContext {
3443
3508
  content = content.append(this.match.fillBefore(Fragment.empty, true));
3444
3509
  return this.type ? this.type.create(this.attrs, content, this.marks) : content;
3445
3510
  }
3446
- popFromStashMark(mark) {
3447
- for (let i = this.stashMarks.length - 1; i >= 0; i--)
3448
- if (mark.eq(this.stashMarks[i]))
3449
- return this.stashMarks.splice(i, 1)[0];
3450
- }
3451
- applyPending(nextType) {
3452
- for (let i = 0, pending = this.pendingMarks; i < pending.length; i++) {
3453
- let mark = pending[i];
3454
- if ((this.type ? this.type.allowsMarkType(mark.type) : markMayApply(mark.type, nextType)) &&
3455
- !mark.isInSet(this.activeMarks)) {
3456
- this.activeMarks = mark.addToSet(this.activeMarks);
3457
- this.pendingMarks = mark.removeFromSet(this.pendingMarks);
3458
- }
3459
- }
3460
- }
3461
3511
  inlineContext(node) {
3462
3512
  if (this.type)
3463
3513
  return this.type.inlineContent;
@@ -3479,11 +3529,11 @@ class ParseContext {
3479
3529
  let topNode = options.topNode, topContext;
3480
3530
  let topOptions = wsOptionsFor(null, options.preserveWhitespace, 0) | (isOpen ? OPT_OPEN_LEFT : 0);
3481
3531
  if (topNode)
3482
- topContext = new NodeContext(topNode.type, topNode.attrs, Mark.none, Mark.none, true, options.topMatch || topNode.type.contentMatch, topOptions);
3532
+ topContext = new NodeContext(topNode.type, topNode.attrs, Mark.none, true, options.topMatch || topNode.type.contentMatch, topOptions);
3483
3533
  else if (isOpen)
3484
- topContext = new NodeContext(null, null, Mark.none, Mark.none, true, null, topOptions);
3534
+ topContext = new NodeContext(null, null, Mark.none, true, null, topOptions);
3485
3535
  else
3486
- topContext = new NodeContext(parser.schema.topNodeType, null, Mark.none, Mark.none, true, null, topOptions);
3536
+ topContext = new NodeContext(parser.schema.topNodeType, null, Mark.none, true, null, topOptions);
3487
3537
  this.nodes = [topContext];
3488
3538
  this.find = options.findPositions;
3489
3539
  this.needsBlock = false;
@@ -3494,31 +3544,13 @@ class ParseContext {
3494
3544
  // Add a DOM node to the content. Text is inserted as text node,
3495
3545
  // otherwise, the node is passed to `addElement` or, if it has a
3496
3546
  // `style` attribute, `addElementWithStyles`.
3497
- addDOM(dom) {
3547
+ addDOM(dom, marks) {
3498
3548
  if (dom.nodeType == 3)
3499
- this.addTextNode(dom);
3549
+ this.addTextNode(dom, marks);
3500
3550
  else if (dom.nodeType == 1)
3501
- this.addElement(dom);
3502
- }
3503
- withStyleRules(dom, f) {
3504
- let style = dom.getAttribute("style");
3505
- if (!style)
3506
- return f();
3507
- let marks = this.readStyles(parseStyles(style));
3508
- if (!marks)
3509
- return; // A style with ignore: true
3510
- let [addMarks, removeMarks] = marks, top = this.top;
3511
- for (let i = 0; i < removeMarks.length; i++)
3512
- this.removePendingMark(removeMarks[i], top);
3513
- for (let i = 0; i < addMarks.length; i++)
3514
- this.addPendingMark(addMarks[i]);
3515
- f();
3516
- for (let i = 0; i < addMarks.length; i++)
3517
- this.removePendingMark(addMarks[i], top);
3518
- for (let i = 0; i < removeMarks.length; i++)
3519
- this.addPendingMark(removeMarks[i]);
3551
+ this.addElement(dom, marks);
3520
3552
  }
3521
- addTextNode(dom) {
3553
+ addTextNode(dom, marks) {
3522
3554
  let value = dom.nodeValue;
3523
3555
  let top = this.top;
3524
3556
  if (top.options & OPT_PRESERVE_WS_FULL ||
@@ -3545,7 +3577,7 @@ class ParseContext {
3545
3577
  value = value.replace(/\r\n?/g, "\n");
3546
3578
  }
3547
3579
  if (value)
3548
- this.insertNode(this.parser.schema.text(value));
3580
+ this.insertNode(this.parser.schema.text(value), marks);
3549
3581
  this.findInText(dom);
3550
3582
  }
3551
3583
  else {
@@ -3554,7 +3586,7 @@ class ParseContext {
3554
3586
  }
3555
3587
  // Try to find a handler for the given tag and use that to parse. If
3556
3588
  // none is found, the element's content nodes are added directly.
3557
- addElement(dom, matchAfter) {
3589
+ addElement(dom, marks, matchAfter) {
3558
3590
  let name = dom.nodeName.toLowerCase(), ruleID;
3559
3591
  if (listTags.hasOwnProperty(name) && this.parser.normalizeLists)
3560
3592
  normalizeList(dom);
@@ -3562,7 +3594,7 @@ class ParseContext {
3562
3594
  (ruleID = this.parser.matchTag(dom, this, matchAfter));
3563
3595
  if (rule ? rule.ignore : ignoreTags.hasOwnProperty(name)) {
3564
3596
  this.findInside(dom);
3565
- this.ignoreFallback(dom);
3597
+ this.ignoreFallback(dom, marks);
3566
3598
  }
3567
3599
  else if (!rule || rule.skip || rule.closeParent) {
3568
3600
  if (rule && rule.closeParent)
@@ -3580,92 +3612,97 @@ class ParseContext {
3580
3612
  this.needsBlock = true;
3581
3613
  }
3582
3614
  else if (!dom.firstChild) {
3583
- this.leafFallback(dom);
3615
+ this.leafFallback(dom, marks);
3584
3616
  return;
3585
3617
  }
3586
- if (rule && rule.skip)
3587
- this.addAll(dom);
3588
- else
3589
- this.withStyleRules(dom, () => this.addAll(dom));
3618
+ let innerMarks = rule && rule.skip ? marks : this.readStyles(dom, marks);
3619
+ if (innerMarks)
3620
+ this.addAll(dom, innerMarks);
3590
3621
  if (sync)
3591
3622
  this.sync(top);
3592
3623
  this.needsBlock = oldNeedsBlock;
3593
3624
  }
3594
3625
  else {
3595
- this.withStyleRules(dom, () => {
3596
- this.addElementByRule(dom, rule, rule.consuming === false ? ruleID : undefined);
3597
- });
3626
+ let innerMarks = this.readStyles(dom, marks);
3627
+ if (innerMarks)
3628
+ this.addElementByRule(dom, rule, innerMarks, rule.consuming === false ? ruleID : undefined);
3598
3629
  }
3599
3630
  }
3600
3631
  // Called for leaf DOM nodes that would otherwise be ignored
3601
- leafFallback(dom) {
3632
+ leafFallback(dom, marks) {
3602
3633
  if (dom.nodeName == "BR" && this.top.type && this.top.type.inlineContent)
3603
- this.addTextNode(dom.ownerDocument.createTextNode("\n"));
3634
+ this.addTextNode(dom.ownerDocument.createTextNode("\n"), marks);
3604
3635
  }
3605
3636
  // Called for ignored nodes
3606
- ignoreFallback(dom) {
3637
+ ignoreFallback(dom, marks) {
3607
3638
  // Ignored BR nodes should at least create an inline context
3608
3639
  if (dom.nodeName == "BR" && (!this.top.type || !this.top.type.inlineContent))
3609
- this.findPlace(this.parser.schema.text("-"));
3640
+ this.findPlace(this.parser.schema.text("-"), marks);
3610
3641
  }
3611
3642
  // Run any style parser associated with the node's styles. Either
3612
- // return an array of marks, or null to indicate some of the styles
3613
- // had a rule with `ignore` set.
3614
- readStyles(styles) {
3615
- let add = Mark.none, remove = Mark.none;
3616
- for (let i = 0; i < styles.length; i += 2) {
3617
- for (let after = undefined;;) {
3618
- let rule = this.parser.matchStyle(styles[i], styles[i + 1], this, after);
3619
- if (!rule)
3620
- break;
3621
- if (rule.ignore)
3622
- return null;
3623
- if (rule.clearMark) {
3624
- this.top.pendingMarks.concat(this.top.activeMarks).forEach(m => {
3625
- if (rule.clearMark(m))
3626
- remove = m.addToSet(remove);
3627
- });
3628
- }
3629
- else {
3630
- add = this.parser.schema.marks[rule.mark].create(rule.attrs).addToSet(add);
3631
- }
3632
- if (rule.consuming === false)
3633
- after = rule;
3634
- else
3635
- break;
3643
+ // return an updated array of marks, or null to indicate some of the
3644
+ // styles had a rule with `ignore` set.
3645
+ readStyles(dom, marks) {
3646
+ let styles = dom.style;
3647
+ // Because many properties will only show up in 'normalized' form
3648
+ // in `style.item` (i.e. text-decoration becomes
3649
+ // text-decoration-line, text-decoration-color, etc), we directly
3650
+ // query the styles mentioned in our rules instead of iterating
3651
+ // over the items.
3652
+ if (styles && styles.length)
3653
+ for (let i = 0; i < this.parser.matchedStyles.length; i++) {
3654
+ let name = this.parser.matchedStyles[i], value = styles.getPropertyValue(name);
3655
+ if (value)
3656
+ for (let after = undefined;;) {
3657
+ let rule = this.parser.matchStyle(name, value, this, after);
3658
+ if (!rule)
3659
+ break;
3660
+ if (rule.ignore)
3661
+ return null;
3662
+ if (rule.clearMark)
3663
+ marks = marks.filter(m => !rule.clearMark(m));
3664
+ else
3665
+ marks = marks.concat(this.parser.schema.marks[rule.mark].create(rule.attrs));
3666
+ if (rule.consuming === false)
3667
+ after = rule;
3668
+ else
3669
+ break;
3670
+ }
3636
3671
  }
3637
- }
3638
- return [add, remove];
3672
+ return marks;
3639
3673
  }
3640
3674
  // Look up a handler for the given node. If none are found, return
3641
3675
  // false. Otherwise, apply it, use its return value to drive the way
3642
3676
  // the node's content is wrapped, and return true.
3643
- addElementByRule(dom, rule, continueAfter) {
3644
- let sync, nodeType, mark;
3677
+ addElementByRule(dom, rule, marks, continueAfter) {
3678
+ let sync, nodeType;
3645
3679
  if (rule.node) {
3646
3680
  nodeType = this.parser.schema.nodes[rule.node];
3647
3681
  if (!nodeType.isLeaf) {
3648
- sync = this.enter(nodeType, rule.attrs || null, rule.preserveWhitespace);
3682
+ let inner = this.enter(nodeType, rule.attrs || null, marks, rule.preserveWhitespace);
3683
+ if (inner) {
3684
+ sync = true;
3685
+ marks = inner;
3686
+ }
3649
3687
  }
3650
- else if (!this.insertNode(nodeType.create(rule.attrs))) {
3651
- this.leafFallback(dom);
3688
+ else if (!this.insertNode(nodeType.create(rule.attrs), marks)) {
3689
+ this.leafFallback(dom, marks);
3652
3690
  }
3653
3691
  }
3654
3692
  else {
3655
3693
  let markType = this.parser.schema.marks[rule.mark];
3656
- mark = markType.create(rule.attrs);
3657
- this.addPendingMark(mark);
3694
+ marks = marks.concat(markType.create(rule.attrs));
3658
3695
  }
3659
3696
  let startIn = this.top;
3660
3697
  if (nodeType && nodeType.isLeaf) {
3661
3698
  this.findInside(dom);
3662
3699
  }
3663
3700
  else if (continueAfter) {
3664
- this.addElement(dom, continueAfter);
3701
+ this.addElement(dom, marks, continueAfter);
3665
3702
  }
3666
3703
  else if (rule.getContent) {
3667
3704
  this.findInside(dom);
3668
- rule.getContent(dom, this.parser.schema).forEach(node => this.insertNode(node));
3705
+ rule.getContent(dom, this.parser.schema).forEach(node => this.insertNode(node, marks));
3669
3706
  }
3670
3707
  else {
3671
3708
  let contentDOM = dom;
@@ -3676,28 +3713,26 @@ class ParseContext {
3676
3713
  else if (rule.contentElement)
3677
3714
  contentDOM = rule.contentElement;
3678
3715
  this.findAround(dom, contentDOM, true);
3679
- this.addAll(contentDOM);
3716
+ this.addAll(contentDOM, marks);
3680
3717
  }
3681
3718
  if (sync && this.sync(startIn))
3682
3719
  this.open--;
3683
- if (mark)
3684
- this.removePendingMark(mark, startIn);
3685
3720
  }
3686
3721
  // Add all child nodes between `startIndex` and `endIndex` (or the
3687
3722
  // whole node, if not given). If `sync` is passed, use it to
3688
3723
  // synchronize after every block element.
3689
- addAll(parent, startIndex, endIndex) {
3724
+ addAll(parent, marks, startIndex, endIndex) {
3690
3725
  let index = startIndex || 0;
3691
3726
  for (let dom = startIndex ? parent.childNodes[startIndex] : parent.firstChild, end = endIndex == null ? null : parent.childNodes[endIndex]; dom != end; dom = dom.nextSibling, ++index) {
3692
3727
  this.findAtPoint(parent, index);
3693
- this.addDOM(dom);
3728
+ this.addDOM(dom, marks);
3694
3729
  }
3695
3730
  this.findAtPoint(parent, index);
3696
3731
  }
3697
3732
  // Try to find a way to fit the given node type into the current
3698
3733
  // context. May add intermediate wrappers and/or leave non-solid
3699
3734
  // nodes that we're in.
3700
- findPlace(node) {
3735
+ findPlace(node, marks) {
3701
3736
  let route, sync;
3702
3737
  for (let depth = this.open; depth >= 0; depth--) {
3703
3738
  let cx = this.nodes[depth];
@@ -3712,53 +3747,61 @@ class ParseContext {
3712
3747
  break;
3713
3748
  }
3714
3749
  if (!route)
3715
- return false;
3750
+ return null;
3716
3751
  this.sync(sync);
3717
3752
  for (let i = 0; i < route.length; i++)
3718
- this.enterInner(route[i], null, false);
3719
- return true;
3753
+ marks = this.enterInner(route[i], null, marks, false);
3754
+ return marks;
3720
3755
  }
3721
3756
  // Try to insert the given node, adjusting the context when needed.
3722
- insertNode(node) {
3757
+ insertNode(node, marks) {
3723
3758
  if (node.isInline && this.needsBlock && !this.top.type) {
3724
3759
  let block = this.textblockFromContext();
3725
3760
  if (block)
3726
- this.enterInner(block);
3761
+ marks = this.enterInner(block, null, marks);
3727
3762
  }
3728
- if (this.findPlace(node)) {
3763
+ let innerMarks = this.findPlace(node, marks);
3764
+ if (innerMarks) {
3729
3765
  this.closeExtra();
3730
3766
  let top = this.top;
3731
- top.applyPending(node.type);
3732
3767
  if (top.match)
3733
3768
  top.match = top.match.matchType(node.type);
3734
- let marks = top.activeMarks;
3735
- for (let i = 0; i < node.marks.length; i++)
3736
- if (!top.type || top.type.allowsMarkType(node.marks[i].type))
3737
- marks = node.marks[i].addToSet(marks);
3738
- top.content.push(node.mark(marks));
3769
+ let nodeMarks = Mark.none;
3770
+ for (let m of innerMarks.concat(node.marks))
3771
+ if (top.type ? top.type.allowsMarkType(m.type) : markMayApply(m.type, node.type))
3772
+ nodeMarks = m.addToSet(nodeMarks);
3773
+ top.content.push(node.mark(nodeMarks));
3739
3774
  return true;
3740
3775
  }
3741
3776
  return false;
3742
3777
  }
3743
3778
  // Try to start a node of the given type, adjusting the context when
3744
3779
  // necessary.
3745
- enter(type, attrs, preserveWS) {
3746
- let ok = this.findPlace(type.create(attrs));
3747
- if (ok)
3748
- this.enterInner(type, attrs, true, preserveWS);
3749
- return ok;
3780
+ enter(type, attrs, marks, preserveWS) {
3781
+ let innerMarks = this.findPlace(type.create(attrs), marks);
3782
+ if (innerMarks)
3783
+ innerMarks = this.enterInner(type, attrs, marks, true, preserveWS);
3784
+ return innerMarks;
3750
3785
  }
3751
3786
  // Open a node of the given type
3752
- enterInner(type, attrs = null, solid = false, preserveWS) {
3787
+ enterInner(type, attrs, marks, solid = false, preserveWS) {
3753
3788
  this.closeExtra();
3754
3789
  let top = this.top;
3755
- top.applyPending(type);
3756
3790
  top.match = top.match && top.match.matchType(type);
3757
3791
  let options = wsOptionsFor(type, preserveWS, top.options);
3758
3792
  if ((top.options & OPT_OPEN_LEFT) && top.content.length == 0)
3759
3793
  options |= OPT_OPEN_LEFT;
3760
- this.nodes.push(new NodeContext(type, attrs, top.activeMarks, top.pendingMarks, solid, null, options));
3794
+ let applyMarks = Mark.none;
3795
+ marks = marks.filter(m => {
3796
+ if (top.type ? top.type.allowsMarkType(m.type) : markMayApply(m.type, type)) {
3797
+ applyMarks = m.addToSet(applyMarks);
3798
+ return false;
3799
+ }
3800
+ return true;
3801
+ });
3802
+ this.nodes.push(new NodeContext(type, attrs, applyMarks, solid, null, options));
3761
3803
  this.open++;
3804
+ return marks;
3762
3805
  }
3763
3806
  // Make sure all nodes above this.open are finished and added to
3764
3807
  // their parents
@@ -3872,29 +3915,6 @@ class ParseContext {
3872
3915
  return type;
3873
3916
  }
3874
3917
  }
3875
- addPendingMark(mark) {
3876
- let found = findSameMarkInSet(mark, this.top.pendingMarks);
3877
- if (found)
3878
- this.top.stashMarks.push(found);
3879
- this.top.pendingMarks = mark.addToSet(this.top.pendingMarks);
3880
- }
3881
- removePendingMark(mark, upto) {
3882
- for (let depth = this.open; depth >= 0; depth--) {
3883
- let level = this.nodes[depth];
3884
- let found = level.pendingMarks.lastIndexOf(mark);
3885
- if (found > -1) {
3886
- level.pendingMarks = mark.removeFromSet(level.pendingMarks);
3887
- }
3888
- else {
3889
- level.activeMarks = mark.removeFromSet(level.activeMarks);
3890
- let stashMark = level.popFromStashMark(mark);
3891
- if (stashMark && level.type && level.type.allowsMarkType(stashMark.type))
3892
- level.activeMarks = stashMark.addToSet(level.activeMarks);
3893
- }
3894
- if (level == upto)
3895
- break;
3896
- }
3897
- }
3898
3918
  }
3899
3919
  // Kludge to work around directly nested list nodes produced by some
3900
3920
  // tools and allowed by browsers to mean that the nested list is
@@ -3918,13 +3938,6 @@ function normalizeList(dom) {
3918
3938
  function matches(dom, selector) {
3919
3939
  return (dom.matches || dom.msMatchesSelector || dom.webkitMatchesSelector || dom.mozMatchesSelector).call(dom, selector);
3920
3940
  }
3921
- // Tokenize a style attribute into property/value pairs.
3922
- function parseStyles(style) {
3923
- let re = /\s*([\w-]+)\s*:\s*([^;]+)/g, m, result = [];
3924
- while (m = re.exec(style))
3925
- result.push(m[1], m[2].trim());
3926
- return result;
3927
- }
3928
3941
  function copy(obj) {
3929
3942
  let copy = {};
3930
3943
  for (let prop in obj)
@@ -3954,12 +3967,6 @@ function markMayApply(markType, nodeType) {
3954
3967
  return true;
3955
3968
  }
3956
3969
  }
3957
- function findSameMarkInSet(mark, set) {
3958
- for (let i = 0; i < set.length; i++) {
3959
- if (mark.eq(set[i]))
3960
- return set[i];
3961
- }
3962
- }
3963
3970
 
3964
3971
  /**
3965
3972
  A DOM serializer knows how to convert ProseMirror nodes and
@@ -4031,7 +4038,7 @@ class DOMSerializer {
4031
4038
  @internal
4032
4039
  */
4033
4040
  serializeNodeInner(node, options) {
4034
- let { dom, contentDOM } = DOMSerializer.renderSpec(doc$1(options), this.nodes[node.type.name](node));
4041
+ let { dom, contentDOM } = renderSpec(doc$1(options), this.nodes[node.type.name](node), null, node.attrs);
4035
4042
  if (contentDOM) {
4036
4043
  if (node.isLeaf)
4037
4044
  throw new RangeError("Content hole not allowed in a leaf node spec");
@@ -4062,57 +4069,10 @@ class DOMSerializer {
4062
4069
  */
4063
4070
  serializeMark(mark, inline, options = {}) {
4064
4071
  let toDOM = this.marks[mark.type.name];
4065
- return toDOM && DOMSerializer.renderSpec(doc$1(options), toDOM(mark, inline));
4066
- }
4067
- /**
4068
- Render an [output spec](https://prosemirror.net/docs/ref/#model.DOMOutputSpec) to a DOM node. If
4069
- the spec has a hole (zero) in it, `contentDOM` will point at the
4070
- node with the hole.
4071
- */
4072
- static renderSpec(doc, structure, xmlNS = null) {
4073
- if (typeof structure == "string")
4074
- return { dom: doc.createTextNode(structure) };
4075
- if (structure.nodeType != null)
4076
- return { dom: structure };
4077
- if (structure.dom && structure.dom.nodeType != null)
4078
- return structure;
4079
- let tagName = structure[0], space = tagName.indexOf(" ");
4080
- if (space > 0) {
4081
- xmlNS = tagName.slice(0, space);
4082
- tagName = tagName.slice(space + 1);
4083
- }
4084
- let contentDOM;
4085
- let dom = (xmlNS ? doc.createElementNS(xmlNS, tagName) : doc.createElement(tagName));
4086
- let attrs = structure[1], start = 1;
4087
- if (attrs && typeof attrs == "object" && attrs.nodeType == null && !Array.isArray(attrs)) {
4088
- start = 2;
4089
- for (let name in attrs)
4090
- if (attrs[name] != null) {
4091
- let space = name.indexOf(" ");
4092
- if (space > 0)
4093
- dom.setAttributeNS(name.slice(0, space), name.slice(space + 1), attrs[name]);
4094
- else
4095
- dom.setAttribute(name, attrs[name]);
4096
- }
4097
- }
4098
- for (let i = start; i < structure.length; i++) {
4099
- let child = structure[i];
4100
- if (child === 0) {
4101
- if (i < structure.length - 1 || i > start)
4102
- throw new RangeError("Content hole must be the only child of its parent node");
4103
- return { dom, contentDOM: dom };
4104
- }
4105
- else {
4106
- let { dom: inner, contentDOM: innerContent } = DOMSerializer.renderSpec(doc, child, xmlNS);
4107
- dom.appendChild(inner);
4108
- if (innerContent) {
4109
- if (contentDOM)
4110
- throw new RangeError("Multiple content holes");
4111
- contentDOM = innerContent;
4112
- }
4113
- }
4114
- }
4115
- return { dom, contentDOM };
4072
+ return toDOM && renderSpec(doc$1(options), toDOM(mark, inline), null, mark.attrs);
4073
+ }
4074
+ static renderSpec(doc, structure, xmlNS = null, blockArraysIn) {
4075
+ return renderSpec(doc, structure, xmlNS, blockArraysIn);
4116
4076
  }
4117
4077
  /**
4118
4078
  Build a serializer using the [`toDOM`](https://prosemirror.net/docs/ref/#model.NodeSpec.toDOM)
@@ -4151,6 +4111,88 @@ function gatherToDOM(obj) {
4151
4111
  function doc$1(options) {
4152
4112
  return options.document || window.document;
4153
4113
  }
4114
+ const suspiciousAttributeCache = new WeakMap();
4115
+ function suspiciousAttributes(attrs) {
4116
+ let value = suspiciousAttributeCache.get(attrs);
4117
+ if (value === undefined)
4118
+ suspiciousAttributeCache.set(attrs, value = suspiciousAttributesInner(attrs));
4119
+ return value;
4120
+ }
4121
+ function suspiciousAttributesInner(attrs) {
4122
+ let result = null;
4123
+ function scan(value) {
4124
+ if (value && typeof value == "object") {
4125
+ if (Array.isArray(value)) {
4126
+ if (typeof value[0] == "string") {
4127
+ if (!result)
4128
+ result = [];
4129
+ result.push(value);
4130
+ }
4131
+ else {
4132
+ for (let i = 0; i < value.length; i++)
4133
+ scan(value[i]);
4134
+ }
4135
+ }
4136
+ else {
4137
+ for (let prop in value)
4138
+ scan(value[prop]);
4139
+ }
4140
+ }
4141
+ }
4142
+ scan(attrs);
4143
+ return result;
4144
+ }
4145
+ function renderSpec(doc, structure, xmlNS, blockArraysIn) {
4146
+ if (typeof structure == "string")
4147
+ return { dom: doc.createTextNode(structure) };
4148
+ if (structure.nodeType != null)
4149
+ return { dom: structure };
4150
+ if (structure.dom && structure.dom.nodeType != null)
4151
+ return structure;
4152
+ let tagName = structure[0], suspicious;
4153
+ if (typeof tagName != "string")
4154
+ throw new RangeError("Invalid array passed to renderSpec");
4155
+ if (blockArraysIn && (suspicious = suspiciousAttributes(blockArraysIn)) &&
4156
+ suspicious.indexOf(structure) > -1)
4157
+ throw new RangeError("Using an array from an attribute object as a DOM spec. This may be an attempted cross site scripting attack.");
4158
+ let space = tagName.indexOf(" ");
4159
+ if (space > 0) {
4160
+ xmlNS = tagName.slice(0, space);
4161
+ tagName = tagName.slice(space + 1);
4162
+ }
4163
+ let contentDOM;
4164
+ let dom = (xmlNS ? doc.createElementNS(xmlNS, tagName) : doc.createElement(tagName));
4165
+ let attrs = structure[1], start = 1;
4166
+ if (attrs && typeof attrs == "object" && attrs.nodeType == null && !Array.isArray(attrs)) {
4167
+ start = 2;
4168
+ for (let name in attrs)
4169
+ if (attrs[name] != null) {
4170
+ let space = name.indexOf(" ");
4171
+ if (space > 0)
4172
+ dom.setAttributeNS(name.slice(0, space), name.slice(space + 1), attrs[name]);
4173
+ else
4174
+ dom.setAttribute(name, attrs[name]);
4175
+ }
4176
+ }
4177
+ for (let i = start; i < structure.length; i++) {
4178
+ let child = structure[i];
4179
+ if (child === 0) {
4180
+ if (i < structure.length - 1 || i > start)
4181
+ throw new RangeError("Content hole must be the only child of its parent node");
4182
+ return { dom, contentDOM: dom };
4183
+ }
4184
+ else {
4185
+ let { dom: inner, contentDOM: innerContent } = renderSpec(doc, child, xmlNS, blockArraysIn);
4186
+ dom.appendChild(inner);
4187
+ if (innerContent) {
4188
+ if (contentDOM)
4189
+ throw new RangeError("Multiple content holes");
4190
+ contentDOM = innerContent;
4191
+ }
4192
+ }
4193
+ }
4194
+ return { dom, contentDOM };
4195
+ }
4154
4196
 
4155
4197
  // Recovery values encode a range index and an offset. They are
4156
4198
  // represented as numbers, because tons of them will be created when
@@ -24871,9 +24913,9 @@ const schema = new Schema({
24871
24913
  strong: {
24872
24914
  parseDOM: [
24873
24915
  { tag: "strong" },
24874
- { tag: "b", getAttrs: (node) => node.style.fontWeight != "normal" && null },
24916
+ { tag: "b", getAttrs: node => node.style.fontWeight != "normal" && null },
24875
24917
  { style: "font-weight=400", clearMark: m => m.type.name == "strong" },
24876
- { style: "font-weight", getAttrs: (value) => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null }
24918
+ { style: "font-weight", getAttrs: value => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null }
24877
24919
  ],
24878
24920
  toDOM() { return ["strong"]; }
24879
24921
  },
@@ -25127,6 +25169,7 @@ new MarkdownParser(schema, MarkdownIt("commonmark", { html: false }), {
25127
25169
  code_inline: { mark: "code", noCloseToken: true }
25128
25170
  });
25129
25171
 
25172
+ const blankMark = { open: "", close: "", mixable: true };
25130
25173
  /**
25131
25174
  A specification for serializing a ProseMirror document as
25132
25175
  Markdown/CommonMark text.
@@ -25334,6 +25377,18 @@ class MarkdownSerializerState {
25334
25377
  }
25335
25378
  }
25336
25379
  /**
25380
+ @internal
25381
+ */
25382
+ getMark(name) {
25383
+ let info = this.marks[name];
25384
+ if (!info) {
25385
+ if (this.options.strict !== false)
25386
+ throw new Error(`Mark type \`${name}\` not supported by Markdown renderer`);
25387
+ info = blankMark;
25388
+ }
25389
+ return info;
25390
+ }
25391
+ /**
25337
25392
  Render a block, prefixing each line with `delim`, and the first
25338
25393
  line in `firstDelim`. `node` should be the node that is closed at
25339
25394
  the end of the block, and `f` is a function that renders the
@@ -25398,9 +25453,22 @@ class MarkdownSerializerState {
25398
25453
  Render the given node as a block.
25399
25454
  */
25400
25455
  render(node, parent, index) {
25401
- if (!this.nodes[node.type.name])
25402
- throw new Error("Token type `" + node.type.name + "` not supported by Markdown renderer");
25403
- this.nodes[node.type.name](this, node, parent, index);
25456
+ if (this.nodes[node.type.name]) {
25457
+ this.nodes[node.type.name](this, node, parent, index);
25458
+ }
25459
+ else {
25460
+ if (this.options.strict !== false) {
25461
+ throw new Error("Token type `" + node.type.name + "` not supported by Markdown renderer");
25462
+ }
25463
+ else if (!node.type.isLeaf) {
25464
+ if (node.type.inlineContent)
25465
+ this.renderInline(node);
25466
+ else
25467
+ this.renderContent(node);
25468
+ if (node.isBlock)
25469
+ this.closeBlock(node);
25470
+ }
25471
+ }
25404
25472
  }
25405
25473
  /**
25406
25474
  Render the contents of `parent` as block nodes.
@@ -25431,7 +25499,7 @@ class MarkdownSerializerState {
25431
25499
  // If whitespace has to be expelled from the node, adjust
25432
25500
  // leading and trailing accordingly.
25433
25501
  if (node && node.isText && marks.some(mark => {
25434
- let info = this.marks[mark.type.name];
25502
+ let info = this.getMark(mark.type.name);
25435
25503
  return info && info.expelEnclosingWhitespace && !mark.isInSet(active);
25436
25504
  })) {
25437
25505
  let [_, lead, rest] = /^(\s*)(.*)$/m.exec(node.text);
@@ -25443,7 +25511,7 @@ class MarkdownSerializerState {
25443
25511
  }
25444
25512
  }
25445
25513
  if (node && node.isText && marks.some(mark => {
25446
- let info = this.marks[mark.type.name];
25514
+ let info = this.getMark(mark.type.name);
25447
25515
  return info && info.expelEnclosingWhitespace &&
25448
25516
  (index == parent.childCount - 1 || !mark.isInSet(parent.child(index + 1).marks));
25449
25517
  })) {
@@ -25456,7 +25524,7 @@ class MarkdownSerializerState {
25456
25524
  }
25457
25525
  }
25458
25526
  let inner = marks.length ? marks[marks.length - 1] : null;
25459
- let noEsc = inner && this.marks[inner.type.name].escape === false;
25527
+ let noEsc = inner && this.getMark(inner.type.name).escape === false;
25460
25528
  let len = marks.length - (noEsc ? 1 : 0);
25461
25529
  // Try to reorder 'mixable' marks, such as em and strong, which
25462
25530
  // in Markdown may be opened and closed in different order, so
@@ -25464,11 +25532,11 @@ class MarkdownSerializerState {
25464
25532
  // active.
25465
25533
  outer: for (let i = 0; i < len; i++) {
25466
25534
  let mark = marks[i];
25467
- if (!this.marks[mark.type.name].mixable)
25535
+ if (!this.getMark(mark.type.name).mixable)
25468
25536
  break;
25469
25537
  for (let j = 0; j < active.length; j++) {
25470
25538
  let other = active[j];
25471
- if (!this.marks[other.type.name].mixable)
25539
+ if (!this.getMark(other.type.name).mixable)
25472
25540
  break;
25473
25541
  if (mark.eq(other)) {
25474
25542
  if (i > j)
@@ -25574,7 +25642,7 @@ class MarkdownSerializerState {
25574
25642
  Get the markdown string for a given opening or closing mark.
25575
25643
  */
25576
25644
  markString(mark, open, parent, index) {
25577
- let info = this.marks[mark.type.name];
25645
+ let info = this.getMark(mark.type.name);
25578
25646
  let value = open ? info.open : info.close;
25579
25647
  return typeof value == "string" ? value : value(this, mark, parent, index);
25580
25648
  }