@ni/ok-components 1.12.3 → 1.12.4

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.
@@ -10160,7 +10160,7 @@
10160
10160
  }
10161
10161
 
10162
10162
  /*!
10163
- * tabbable 6.5.0
10163
+ * tabbable 6.5.1
10164
10164
  * @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
10165
10165
  */
10166
10166
  // NOTE: separate `:not()` selectors has broader browser support than the newer
@@ -10169,10 +10169,9 @@
10169
10169
  var NoElement = typeof Element === 'undefined';
10170
10170
  var matches$1 = NoElement ? function () {} : Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
10171
10171
  var getRootNode = !NoElement && Element.prototype.getRootNode ? function (element) {
10172
- var _element$getRootNode;
10173
- return element === null || element === void 0 ? void 0 : (_element$getRootNode = element.getRootNode) === null || _element$getRootNode === void 0 ? void 0 : _element$getRootNode.call(element);
10172
+ return element == null || element.getRootNode == null ? void 0 : element.getRootNode();
10174
10173
  } : function (element) {
10175
- return element === null || element === void 0 ? void 0 : element.ownerDocument;
10174
+ return element == null ? void 0 : element.ownerDocument;
10176
10175
  };
10177
10176
  var isInput = function isInput(node) {
10178
10177
  return node.tagName === 'INPUT';
@@ -10214,22 +10213,22 @@
10214
10213
  // from the DOM as in https://github.com/focus-trap/focus-trap-react/issues/905), then
10215
10214
  // `ownerDocument` will be `null`, hence the optional chaining on it.
10216
10215
  var nodeRoot = node && getRootNode(node);
10217
- var nodeRootHost = (_nodeRoot = nodeRoot) === null || _nodeRoot === void 0 ? void 0 : _nodeRoot.host;
10216
+ var nodeRootHost = (_nodeRoot = nodeRoot) == null ? void 0 : _nodeRoot.host;
10218
10217
 
10219
10218
  // in some cases, a detached node will return itself as the root instead of a document or
10220
10219
  // shadow root object, in which case, we shouldn't try to look further up the host chain
10221
10220
  var attached = false;
10222
10221
  if (nodeRoot && nodeRoot !== node) {
10223
- var _nodeRootHost, _nodeRootHost$ownerDo, _node$ownerDocument;
10224
- attached = !!((_nodeRootHost = nodeRootHost) !== null && _nodeRootHost !== void 0 && (_nodeRootHost$ownerDo = _nodeRootHost.ownerDocument) !== null && _nodeRootHost$ownerDo !== void 0 && _nodeRootHost$ownerDo.contains(nodeRootHost) || node !== null && node !== void 0 && (_node$ownerDocument = node.ownerDocument) !== null && _node$ownerDocument !== void 0 && _node$ownerDocument.contains(node));
10222
+ var _nodeRootHost, _node$ownerDocument;
10223
+ attached = !!((_nodeRootHost = nodeRootHost) != null && (_nodeRootHost = _nodeRootHost.ownerDocument) != null && _nodeRootHost.contains(nodeRootHost) || node != null && (_node$ownerDocument = node.ownerDocument) != null && _node$ownerDocument.contains(node));
10225
10224
  while (!attached && nodeRootHost) {
10226
- var _nodeRoot2, _nodeRootHost2, _nodeRootHost2$ownerD;
10225
+ var _nodeRoot2, _nodeRootHost2;
10227
10226
  // since it's not attached and we have a root host, the node MUST be in a nested shadow DOM,
10228
10227
  // which means we need to get the host's host and check if that parent host is contained
10229
10228
  // in (i.e. attached to) the document
10230
10229
  nodeRoot = getRootNode(nodeRootHost);
10231
- nodeRootHost = (_nodeRoot2 = nodeRoot) === null || _nodeRoot2 === void 0 ? void 0 : _nodeRoot2.host;
10232
- attached = !!((_nodeRootHost2 = nodeRootHost) !== null && _nodeRootHost2 !== void 0 && (_nodeRootHost2$ownerD = _nodeRootHost2.ownerDocument) !== null && _nodeRootHost2$ownerD !== void 0 && _nodeRootHost2$ownerD.contains(nodeRootHost));
10230
+ nodeRootHost = (_nodeRoot2 = nodeRoot) == null ? void 0 : _nodeRoot2.host;
10231
+ attached = !!((_nodeRootHost2 = nodeRootHost) != null && (_nodeRootHost2 = _nodeRootHost2.ownerDocument) != null && _nodeRootHost2.contains(nodeRootHost));
10233
10232
  }
10234
10233
  }
10235
10234
  return attached;
@@ -22771,8 +22770,8 @@ so this becomes the fallback color for the slot */ ''}
22771
22770
  </template>
22772
22771
  `;
22773
22772
 
22774
- // Based on: https://github.com/microsoft/fast/blob/%40microsoft/fast-foundation_v2.49.5/packages/web-components/fast-foundation/src/combobox/combobox.form-associated.ts
22775
22773
  /* eslint-disable max-classes-per-file */
22774
+ // Based on: https://github.com/microsoft/fast/blob/%40microsoft/fast-foundation_v2.49.5/packages/web-components/fast-foundation/src/combobox/combobox.form-associated.ts
22776
22775
  // eslint-disable-next-line jsdoc/require-jsdoc
22777
22776
  let Combobox$1 = class Combobox extends ListboxElement {
22778
22777
  };
@@ -33305,14 +33304,27 @@ so this becomes the fallback color for the slot */ ''}
33305
33304
  }, parent), oldSlice.openStart, oldSlice.openEnd);
33306
33305
  return StepResult.fromReplace(doc, this.from, this.to, slice);
33307
33306
  }
33308
- invert() {
33309
- return new RemoveMarkStep(this.from, this.to, this.mark);
33307
+ invert(doc) {
33308
+ let steps = [];
33309
+ doc.nodesBetween(this.from, this.to, (node, pos) => {
33310
+ if (node.isInline && node.isAtom) {
33311
+ let added = this.mark.addToSet(node.marks);
33312
+ if (!Mark$1.sameSet(added, node.marks)) {
33313
+ let from = Math.max(this.from, pos), to = Math.min(this.to, pos + node.nodeSize);
33314
+ pushMarkStep(RemoveMarkStep, from, to, this.mark, steps);
33315
+ for (let mark of node.marks)
33316
+ if (!mark.isInSet(added))
33317
+ pushMarkStep(AddMarkStep, from, to, mark, steps);
33318
+ }
33319
+ }
33320
+ });
33321
+ return steps.length == 1 ? steps[0] : new MarkSetStep(steps);
33310
33322
  }
33311
33323
  map(mapping) {
33312
- let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
33313
- if (from.deleted && to.deleted || from.pos >= to.pos)
33324
+ let from = mapping.map(this.from, 1), to = mapping.map(this.to, -1);
33325
+ if (from >= to)
33314
33326
  return null;
33315
- return new AddMarkStep(from.pos, to.pos, this.mark);
33327
+ return new AddMarkStep(from, to, this.mark);
33316
33328
  }
33317
33329
  merge(other) {
33318
33330
  if (other instanceof AddMarkStep &&
@@ -33367,14 +33379,19 @@ so this becomes the fallback color for the slot */ ''}
33367
33379
  }, doc), oldSlice.openStart, oldSlice.openEnd);
33368
33380
  return StepResult.fromReplace(doc, this.from, this.to, slice);
33369
33381
  }
33370
- invert() {
33371
- return new AddMarkStep(this.from, this.to, this.mark);
33382
+ invert(doc) {
33383
+ let steps = [];
33384
+ doc.nodesBetween(this.from, this.to, (node, pos) => {
33385
+ if (node.isInline && node.isAtom && this.mark.isInSet(node.marks))
33386
+ pushMarkStep(AddMarkStep, Math.max(this.from, pos), Math.min(this.to, pos + node.nodeSize), this.mark, steps);
33387
+ });
33388
+ return steps.length == 1 ? steps[0] : new MarkSetStep(steps);
33372
33389
  }
33373
33390
  map(mapping) {
33374
- let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
33375
- if (from.deleted && to.deleted || from.pos >= to.pos)
33391
+ let from = mapping.map(this.from, 1), to = mapping.map(this.to, -1);
33392
+ if (from >= to)
33376
33393
  return null;
33377
- return new RemoveMarkStep(from.pos, to.pos, this.mark);
33394
+ return new RemoveMarkStep(from, to, this.mark);
33378
33395
  }
33379
33396
  merge(other) {
33380
33397
  if (other instanceof RemoveMarkStep &&
@@ -33397,6 +33414,51 @@ so this becomes the fallback color for the slot */ ''}
33397
33414
  }
33398
33415
  }
33399
33416
  Step$1.jsonID("removeMark", RemoveMarkStep);
33417
+ function pushMarkStep(cls, from, to, mark, target) {
33418
+ let last = target.length ? target[target.length - 1] : null;
33419
+ if (last && last instanceof cls && last.to == from && last.mark.eq(mark)) {
33420
+ target[target.length - 1] = new cls(last.from, to, mark);
33421
+ }
33422
+ else {
33423
+ target.push(new cls(from, to, mark));
33424
+ }
33425
+ }
33426
+ class MarkSetStep extends Step$1 {
33427
+ constructor(steps) {
33428
+ super();
33429
+ this.steps = steps;
33430
+ }
33431
+ apply(doc) {
33432
+ for (let step of this.steps) {
33433
+ let result = step.apply(doc);
33434
+ if (!result.doc)
33435
+ return result;
33436
+ doc = result.doc;
33437
+ }
33438
+ return new StepResult(doc, null);
33439
+ }
33440
+ invert(doc) {
33441
+ return new MarkSetStep(this.steps.map(s => s.invert(doc)));
33442
+ }
33443
+ map(mapping) {
33444
+ let result = [];
33445
+ for (let step of this.steps) {
33446
+ let mapped = step.map(mapping);
33447
+ if (mapped)
33448
+ result.push(mapped);
33449
+ }
33450
+ return result.length ? new MarkSetStep(result) : null;
33451
+ }
33452
+ toJSON() {
33453
+ return { stepType: "markSet", steps: this.steps.map(s => s.toJSON()) };
33454
+ }
33455
+ static fromJSON(schema, json) {
33456
+ if (!Array.isArray(json.steps) || !json.steps.every((s) => s.stepType == "addMark" || s.stepType == "removeMark"))
33457
+ throw new RangeError("Invalid JSON for MarkSetStep");
33458
+ return new MarkSetStep(json.steps.map((s) => Step$1.fromJSON(schema, s)));
33459
+ }
33460
+ }
33461
+ Step$1.jsonID("markSet", MarkSetStep);
33400
33462
  /**
33401
33463
  Add a mark to a specific node.
33402
33464
  */
@@ -33721,36 +33783,22 @@ so this becomes the fallback color for the slot */ ''}
33721
33783
  }
33722
33784
 
33723
33785
  function addMark(tr, from, to, mark) {
33724
- let removed = [], added = [];
33725
- let removing, adding;
33786
+ let added = [];
33726
33787
  tr.doc.nodesBetween(from, to, (node, pos, parent) => {
33727
33788
  if (!node.isInline)
33728
33789
  return;
33729
33790
  let marks = node.marks;
33730
33791
  if (!mark.isInSet(marks) && parent.type.allowsMarkType(mark.type)) {
33731
33792
  let start = Math.max(pos, from), end = Math.min(pos + node.nodeSize, to);
33732
- let newSet = mark.addToSet(marks);
33733
- for (let i = 0; i < marks.length; i++) {
33734
- if (!marks[i].isInSet(newSet)) {
33735
- if (removing && removing.to == start && removing.mark.eq(marks[i]))
33736
- removing.to = end;
33737
- else
33738
- removed.push(removing = new RemoveMarkStep(start, end, marks[i]));
33739
- }
33740
- }
33741
- if (adding && adding.to == start)
33742
- adding.to = end;
33743
- else
33744
- added.push(adding = new AddMarkStep(start, end, mark));
33793
+ pushMarkStep(AddMarkStep, start, end, mark, added);
33745
33794
  }
33746
33795
  });
33747
- removed.forEach(s => tr.step(s));
33748
33796
  added.forEach(s => tr.step(s));
33749
33797
  }
33750
33798
  function removeMark(tr, from, to, mark) {
33751
33799
  let matched = [], step = 0;
33752
33800
  tr.doc.nodesBetween(from, to, (node, pos) => {
33753
- if (!node.isInline)
33801
+ if (!node.isInline || !node.isAtom)
33754
33802
  return;
33755
33803
  step++;
33756
33804
  let toRemove = null;
@@ -36763,7 +36811,7 @@ so this becomes the fallback color for the slot */ ''}
36763
36811
  let splitDepth = wrappers.length - found;
36764
36812
  let splitPos = range.start + wrappers.length - (joinBefore ? 2 : 0), parent = range.parent;
36765
36813
  for (let i = range.startIndex, e = range.endIndex, first = true; i < e; i++, first = false) {
36766
- if (!first && canSplit(tr.doc, splitPos, splitDepth)) {
36814
+ if (!first && splitDepth && canSplit(tr.doc, splitPos, splitDepth)) {
36767
36815
  tr.split(splitPos, splitDepth);
36768
36816
  splitPos += 2 * splitDepth;
36769
36817
  }
@@ -36771,26 +36819,30 @@ so this becomes the fallback color for the slot */ ''}
36771
36819
  }
36772
36820
  return tr;
36773
36821
  }
36822
+ function isItem(itemType, type) {
36823
+ return itemType instanceof NodeType$1 ? type == itemType : itemType.indexOf(type) > -1;
36824
+ }
36774
36825
  /**
36775
36826
  Create a command to lift the list item around the selection up into
36776
- a wrapping list.
36827
+ a wrapping list. `itemType` may be an array of list item types.
36777
36828
  */
36778
36829
  function liftListItem(itemType) {
36779
36830
  return function (state, dispatch) {
36780
36831
  let { $from, $to } = state.selection;
36781
- let range = $from.blockRange($to, node => node.childCount > 0 && node.firstChild.type == itemType);
36832
+ let range = $from.blockRange($to, node => node.childCount > 0 && isItem(itemType, node.firstChild.type));
36782
36833
  if (!range)
36783
36834
  return false;
36784
36835
  if (!dispatch)
36785
36836
  return true;
36786
- if ($from.node(range.depth - 1).type == itemType) // Inside a parent list
36787
- return liftToOuterList(state, dispatch, itemType, range);
36837
+ if (isItem(itemType, $from.node(range.depth - 1).type)) // Inside a parent list
36838
+ return liftToOuterList(state, dispatch, range);
36788
36839
  else // Outer list node
36789
36840
  return liftOutOfList(state, dispatch, range);
36790
36841
  };
36791
36842
  }
36792
- function liftToOuterList(state, dispatch, itemType, range) {
36843
+ function liftToOuterList(state, dispatch, range) {
36793
36844
  let tr = state.tr, end = range.end, endOfList = range.$to.end(range.depth);
36845
+ let itemType = range.parent.child(range.endIndex - 1).type;
36794
36846
  if (end < endOfList) {
36795
36847
  // There are siblings after the lifted items, which must become
36796
36848
  // children of the last item
@@ -36832,24 +36884,24 @@ so this becomes the fallback color for the slot */ ''}
36832
36884
  }
36833
36885
  /**
36834
36886
  Create a command to sink the list item around the selection down
36835
- into an inner list.
36887
+ into an inner list. `itemType` may be an array of list item types.
36836
36888
  */
36837
36889
  function sinkListItem(itemType) {
36838
36890
  return function (state, dispatch) {
36839
36891
  let { $from, $to } = state.selection;
36840
- let range = $from.blockRange($to, node => node.childCount > 0 && node.firstChild.type == itemType);
36892
+ let range = $from.blockRange($to, node => node.childCount > 0 && isItem(itemType, node.firstChild.type));
36841
36893
  if (!range)
36842
36894
  return false;
36843
36895
  let startIndex = range.startIndex;
36844
36896
  if (startIndex == 0)
36845
36897
  return false;
36846
36898
  let parent = range.parent, nodeBefore = parent.child(startIndex - 1);
36847
- if (nodeBefore.type != itemType)
36899
+ if (!isItem(itemType, nodeBefore.type))
36848
36900
  return false;
36849
36901
  if (dispatch) {
36850
36902
  let nestedBefore = nodeBefore.lastChild && nodeBefore.lastChild.type == parent.type;
36851
- let inner = Fragment.from(nestedBefore ? itemType.create() : null);
36852
- let slice = new Slice(Fragment.from(itemType.create(null, Fragment.from(parent.type.create(null, inner)))), nestedBefore ? 3 : 1, 0);
36903
+ let inner = Fragment.from(nestedBefore ? nodeBefore.lastChild.lastChild.type.create() : null);
36904
+ let slice = new Slice(Fragment.from(nodeBefore.type.create(null, Fragment.from(parent.type.create(null, inner)))), nestedBefore ? 3 : 1, 0);
36853
36905
  let before = range.start, after = range.end;
36854
36906
  dispatch(state.tr.step(new ReplaceAroundStep(before - (nestedBefore ? 3 : 1), after, before, after, slice, 1, true))
36855
36907
  .scrollIntoView());
@@ -37706,7 +37758,13 @@ so this becomes the fallback color for the slot */ ''}
37706
37758
  atEnd = offset > domIndex(this.contentDOM);
37707
37759
  }
37708
37760
  else if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) {
37709
- atEnd = !!(dom.compareDocumentPosition(this.contentDOM) & 4);
37761
+ let rel = dom.compareDocumentPosition(this.contentDOM);
37762
+ if (rel & 16) { // this.contentDOM is inside dom
37763
+ atEnd = offset > Array.from(dom.childNodes).findIndex(n => n.contains(this.contentDOM));
37764
+ }
37765
+ else { // Check if after or before
37766
+ atEnd = !(rel & 4);
37767
+ }
37710
37768
  }
37711
37769
  else if (this.dom.firstChild) {
37712
37770
  if (offset == 0)
@@ -38029,8 +38087,10 @@ so this becomes the fallback color for the slot */ ''}
38029
38087
  });
38030
38088
  if (!widget.type.spec.raw) {
38031
38089
  let elt = isElt(dom) ? dom : document.createElement("span");
38032
- if (elt != dom)
38090
+ if (elt != dom) {
38033
38091
  elt.appendChild(dom);
38092
+ dom = elt;
38093
+ }
38034
38094
  if (!elt.hasAttribute("contenteditable"))
38035
38095
  elt.contentEditable = "false";
38036
38096
  elt.classList.add("ProseMirror-widget");
@@ -39339,7 +39399,7 @@ so this becomes the fallback color for the slot */ ''}
39339
39399
  return apply(view, next);
39340
39400
  return false;
39341
39401
  }
39342
- else if (!(mac$2 && mods.indexOf("m") > -1)) {
39402
+ else if (!mac$2 || mods.indexOf("m") < 0) {
39343
39403
  let $head = sel.$head, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter, desc;
39344
39404
  if (!node || node.isText)
39345
39405
  return false;
@@ -39528,17 +39588,14 @@ so this becomes the fallback color for the slot */ ''}
39528
39588
  offset = before.nodeValue.length;
39529
39589
  }
39530
39590
  }
39531
- let sel = view.domSelection();
39591
+ let sel = view.domSelection(), range = view.domSelectionRange();
39532
39592
  if (!sel)
39533
39593
  return;
39534
- if (selectionCollapsed(sel)) {
39535
- let range = document.createRange();
39536
- range.setEnd(node, offset);
39537
- range.setStart(node, offset);
39538
- sel.removeAllRanges();
39539
- sel.addRange(range);
39594
+ if (selectionCollapsed(range)) {
39595
+ sel.collapse(node, offset);
39540
39596
  }
39541
39597
  else if (sel.extend) {
39598
+ sel.collapse(range.anchorNode, range.anchorOffset);
39542
39599
  sel.extend(node, offset);
39543
39600
  }
39544
39601
  view.domObserver.setCurSelection();
@@ -39566,7 +39623,13 @@ so this becomes the fallback color for the slot */ ''}
39566
39623
  return after.left > coords.left ? "ltr" : "rtl";
39567
39624
  }
39568
39625
  }
39569
- let computed = getComputedStyle(view.dom).direction;
39626
+ let block = view.dom;
39627
+ for (let d = $pos.depth; d > 0; d--)
39628
+ if ($pos.node(d).isBlock) {
39629
+ block = view.nodeDOM($pos.before(d)) || block;
39630
+ break;
39631
+ }
39632
+ let computed = getComputedStyle(block).direction;
39570
39633
  return computed == "rtl" ? "rtl" : "ltr";
39571
39634
  }
39572
39635
  // Check whether vertical selection motion would involve node
@@ -40839,6 +40902,23 @@ so this becomes the fallback color for the slot */ ''}
40839
40902
  return false;
40840
40903
  return true;
40841
40904
  }
40905
+ class FragmentCursor {
40906
+ constructor(frag) {
40907
+ this.frag = frag;
40908
+ this.index = 0;
40909
+ this.off = 0;
40910
+ }
40911
+ nodeAt(off) {
40912
+ while (this.off <= off && this.index < this.frag.childCount) {
40913
+ let next = this.frag.child(this.index);
40914
+ if (this.off == off)
40915
+ return next;
40916
+ this.off += next.nodeSize;
40917
+ this.index++;
40918
+ }
40919
+ return null;
40920
+ }
40921
+ }
40842
40922
  class WidgetType {
40843
40923
  constructor(toDOM, spec) {
40844
40924
  this.toDOM = toDOM;
@@ -40894,9 +40974,9 @@ so this becomes the fallback color for the slot */ ''}
40894
40974
  return null;
40895
40975
  return new Decoration(from.pos - offset, to.pos - offset, this);
40896
40976
  }
40897
- valid(node, span) {
40898
- let { index, offset } = node.content.findIndex(span.from), child;
40899
- return offset == span.from && !(child = node.child(index)).isText && offset + child.nodeSize == span.to;
40977
+ valid(node, span, cursor) {
40978
+ let found = cursor.nodeAt(span.from);
40979
+ return !!found && !found.isText && span.from + found.nodeSize == span.to;
40900
40980
  }
40901
40981
  eq(other) {
40902
40982
  return this == other ||
@@ -41053,12 +41133,15 @@ so this becomes the fallback color for the slot */ ''}
41053
41133
  */
41054
41134
  mapInner(mapping, node, offset, oldOffset, options) {
41055
41135
  let newLocal;
41056
- for (let i = 0; i < this.local.length; i++) {
41057
- let mapped = this.local[i].map(mapping, offset, oldOffset);
41058
- if (mapped && mapped.type.valid(node, mapped))
41059
- (newLocal || (newLocal = [])).push(mapped);
41060
- else if (options.onRemove)
41061
- options.onRemove(this.local[i].spec);
41136
+ if (this.local.length) {
41137
+ let cur = new FragmentCursor(node.content);
41138
+ for (let i = 0; i < this.local.length; i++) {
41139
+ let mapped = this.local[i].map(mapping, offset, oldOffset);
41140
+ if (mapped && mapped.type.valid(node, mapped, cur))
41141
+ (newLocal || (newLocal = [])).push(mapped);
41142
+ else if (options.onRemove)
41143
+ options.onRemove(this.local[i].spec);
41144
+ }
41062
41145
  }
41063
41146
  if (this.children.length)
41064
41147
  return mapChildren(this.children, newLocal || [], mapping, node, offset, oldOffset, options);
@@ -41095,9 +41178,12 @@ so this becomes the fallback color for the slot */ ''}
41095
41178
  childIndex += 3;
41096
41179
  });
41097
41180
  let local = moveSpans(childIndex ? withoutNulls(decorations) : decorations, -offset);
41098
- for (let i = 0; i < local.length; i++)
41099
- if (!local[i].type.valid(doc, local[i]))
41100
- local.splice(i--, 1);
41181
+ if (local.length) {
41182
+ let cur = new FragmentCursor(doc.content);
41183
+ for (let i = 0; i < local.length; i++)
41184
+ if (!local[i].type.valid(doc, local[i], cur))
41185
+ local.splice(i--, 1);
41186
+ }
41101
41187
  return new DecorationSet(local.length ? this.local.concat(local).sort(byPos) : this.local, children || this.children);
41102
41188
  }
41103
41189
  /**
@@ -41440,12 +41526,15 @@ so this becomes the fallback color for the slot */ ''}
41440
41526
  }
41441
41527
  });
41442
41528
  let locals = moveSpans(hasNulls ? withoutNulls(spans) : spans, -offset).sort(byPos);
41443
- for (let i = 0; i < locals.length; i++)
41444
- if (!locals[i].type.valid(node, locals[i])) {
41445
- if (options.onRemove)
41446
- options.onRemove(locals[i].spec);
41447
- locals.splice(i--, 1);
41448
- }
41529
+ if (locals.length) {
41530
+ let cur = new FragmentCursor(node.content);
41531
+ for (let i = 0; i < locals.length; i++)
41532
+ if (!locals[i].type.valid(node, locals[i], cur)) {
41533
+ if (options.onRemove)
41534
+ options.onRemove(locals[i].spec);
41535
+ locals.splice(i--, 1);
41536
+ }
41537
+ }
41449
41538
  return locals.length || children.length ? new DecorationSet(locals, children) : empty$1;
41450
41539
  }
41451
41540
  // Used to sort decorations so that ones with a low start position
@@ -41678,8 +41767,11 @@ so this becomes the fallback color for the slot */ ''}
41678
41767
  let mutations = this.pendingRecords();
41679
41768
  if (mutations.length)
41680
41769
  this.queue = [];
41681
- let sel = view.domSelectionRange();
41682
- let newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(view) && !this.ignoreSelectionChange(sel);
41770
+ let selRange, newSel = false;
41771
+ if (!this.suppressingSelectionUpdates && hasFocusAndSelection(view)) {
41772
+ selRange = view.domSelectionRange();
41773
+ newSel = !this.currentSelection.eq(selRange) && !this.ignoreSelectionChange(selRange);
41774
+ }
41683
41775
  let from = -1, to = -1, typeOver = false, added = [];
41684
41776
  if (view.editable) {
41685
41777
  for (let i = 0; i < mutations.length; i++) {
@@ -41734,11 +41826,11 @@ so this becomes the fallback color for the slot */ ''}
41734
41826
  // the state
41735
41827
  if (from < 0 && newSel && view.input.lastFocus > Date.now() - 200 &&
41736
41828
  Math.max(view.input.lastTouch, view.input.lastClick.time) < Date.now() - 300 &&
41737
- selectionCollapsed(sel) && (readSel = selectionFromDOM(view)) &&
41829
+ selectionCollapsed(selRange) && (readSel = selectionFromDOM(view)) &&
41738
41830
  readSel.eq(Selection$2.near(view.state.doc.resolve(0), 1))) {
41739
41831
  view.input.lastFocus = 0;
41740
41832
  selectionToDOM(view);
41741
- this.currentSelection.set(sel);
41833
+ this.currentSelection.set(selRange);
41742
41834
  view.scrollToSelection();
41743
41835
  }
41744
41836
  else if (from > -1 || newSel) {
@@ -41753,9 +41845,10 @@ so this becomes the fallback color for the slot */ ''}
41753
41845
  this.handleDOMChange(from, to, typeOver, added);
41754
41846
  if (view.docView && view.docView.dirty)
41755
41847
  view.updateState(view.state);
41756
- else if (!this.currentSelection.eq(sel))
41848
+ else if (selRange && !this.currentSelection.eq(selRange))
41757
41849
  selectionToDOM(view);
41758
- this.currentSelection.set(sel);
41850
+ if (selRange)
41851
+ this.currentSelection.set(selRange);
41759
41852
  }
41760
41853
  }
41761
41854
  registerMutation(mut, added) {
@@ -42087,7 +42180,8 @@ so this becomes the fallback color for the slot */ ''}
42087
42180
  }
42088
42181
  // Same for backspace
42089
42182
  if (view.state.selection.anchor > change.start &&
42090
- looksLikeBackspace(doc, change.start, change.endA, $from, $to) &&
42183
+ (inlineChange ? change.endA > change.start && change.endB == change.start
42184
+ : looksLikeBlockJoin(doc, change.start, change.endA, $from, $to)) &&
42091
42185
  view.someProp("handleKeyDown", f => f(view, keyEvent(8, "Backspace")))) {
42092
42186
  if (android && chrome)
42093
42187
  view.domObserver.suppressSelectionUpdates(); // #820
@@ -42208,7 +42302,7 @@ so this becomes the fallback color for the slot */ ''}
42208
42302
  if (Fragment.from(updated).eq(cur))
42209
42303
  return { mark, type };
42210
42304
  }
42211
- function looksLikeBackspace(old, start, end, $newStart, $newEnd) {
42305
+ function looksLikeBlockJoin(old, start, end, $newStart, $newEnd) {
42212
42306
  if ( // The content must have shrunk
42213
42307
  end - start <= $newEnd.pos - $newStart.pos ||
42214
42308
  // newEnd must point directly at or after the end of the block that newStart points into
@@ -42216,7 +42310,7 @@ so this becomes the fallback color for the slot */ ''}
42216
42310
  return false;
42217
42311
  let $start = old.resolve(start);
42218
42312
  // Handle the case where, rather than joining blocks, the change just removed an entire block
42219
- if (!$newStart.parent.isTextblock) {
42313
+ if (!$newStart.parent.inlineContent) {
42220
42314
  let after = $start.nodeAfter;
42221
42315
  return after != null && end == start + after.nodeSize;
42222
42316
  }
@@ -44047,6 +44141,7 @@ so this becomes the fallback color for the slot */ ''}
44047
44141
  if (dispatch) {
44048
44142
  const tr = state.tr;
44049
44143
  const { ranges } = state.selection;
44144
+ const marks = state.selection instanceof TextSelection ? state.selection.$from.marksAcross(state.selection.$to) : null;
44050
44145
  const mapFrom = tr.steps.length;
44051
44146
  ranges.forEach((range) => {
44052
44147
  const mapping = tr.mapping.slice(mapFrom);
@@ -44056,6 +44151,7 @@ so this becomes the fallback color for the slot */ ''}
44056
44151
  tr.deleteRange(from, to);
44057
44152
  });
44058
44153
  if (!tr.selection.empty) tr.setSelection(TextSelection.near(tr.doc.resolve(tr.selection.from)));
44154
+ if (marks) tr.ensureMarks(marks);
44059
44155
  tr.scrollIntoView();
44060
44156
  dispatch(tr);
44061
44157
  }
@@ -44945,30 +45041,121 @@ so this becomes the fallback color for the slot */ ''}
44945
45041
  return container.innerHTML;
44946
45042
  }
44947
45043
  //#endregion
44948
- //#region src/utilities/isFunction.ts
44949
- function isFunction$3(value) {
44950
- return typeof value === "function";
45044
+ //#region src/schema/getSchemaAttributes.ts
45045
+ /**
45046
+ * Combines external attribute structure with local attribute behavior.
45047
+ * @param attributes The attributes from resolved local extensions
45048
+ * @param schema The schema that defines the allowed attributes
45049
+ * @returns Only attributes present in the schema
45050
+ */
45051
+ function getSchemaAttributes(attributes, schema) {
45052
+ const attributesByType = /* @__PURE__ */ new Map();
45053
+ for (const attribute of attributes) {
45054
+ var _attributesByType$get;
45055
+ const typeAttributes = (_attributesByType$get = attributesByType.get(attribute.type)) !== null && _attributesByType$get !== void 0 ? _attributesByType$get : /* @__PURE__ */ new Map();
45056
+ typeAttributes.set(attribute.name, attribute);
45057
+ attributesByType.set(attribute.type, typeAttributes);
45058
+ }
45059
+ return [...Object.values(schema.nodes), ...Object.values(schema.marks)].flatMap((type) => {
45060
+ var _type$spec$attrs;
45061
+ return Object.entries((_type$spec$attrs = type.spec.attrs) !== null && _type$spec$attrs !== void 0 ? _type$spec$attrs : {}).map(([name, spec]) => {
45062
+ var _attributesByType$get2;
45063
+ const local = (_attributesByType$get2 = attributesByType.get(type.name)) === null || _attributesByType$get2 === void 0 ? void 0 : _attributesByType$get2.get(name);
45064
+ const hasDefault = Object.hasOwn(spec, "default");
45065
+ return {
45066
+ type: type.name,
45067
+ name,
45068
+ attribute: {
45069
+ rendered: true,
45070
+ renderHTML: null,
45071
+ parseHTML: null,
45072
+ keepOnSplit: true,
45073
+ ...local === null || local === void 0 ? void 0 : local.attribute,
45074
+ default: spec.default,
45075
+ isRequired: !hasDefault,
45076
+ validate: spec.validate
45077
+ }
45078
+ };
45079
+ });
45080
+ });
44951
45081
  }
44952
45082
  //#endregion
44953
- //#region src/utilities/callOrReturn.ts
45083
+ //#region src/schema/schemaSpecFields.ts
45084
+ const nodeSchemaFields = {
45085
+ content: "string",
45086
+ marks: "string",
45087
+ group: "string",
45088
+ inline: "boolean",
45089
+ atom: "boolean",
45090
+ selectable: "boolean",
45091
+ draggable: "boolean",
45092
+ code: "boolean",
45093
+ whitespace: ["pre", "normal"],
45094
+ definingAsContext: "boolean",
45095
+ definingForContent: "boolean",
45096
+ defining: "boolean",
45097
+ isolating: "boolean",
45098
+ linebreakReplacement: "boolean"
45099
+ };
45100
+ const markSchemaFields = {
45101
+ inclusive: "boolean",
45102
+ excludes: "string",
45103
+ group: "string",
45104
+ spanning: "boolean",
45105
+ code: "boolean"
45106
+ };
45107
+ //#endregion
45108
+ //#region src/schema/mergeSchemaSpec.ts
45109
+ function structuralFields(spec, fields, path) {
45110
+ return Object.fromEntries(Object.entries(fields).flatMap(([name, expected]) => {
45111
+ const value = spec[name];
45112
+ if (value === void 0) return [];
45113
+ if (!(typeof expected === "string" ? typeof value === expected : typeof value === "string" && expected.includes(value))) throw new RangeError(`Invalid schemaSpec field '${path}.${name}'`);
45114
+ return [[name, value]];
45115
+ }));
45116
+ }
45117
+ function mergeType(name, local, external, fields) {
45118
+ return {
45119
+ ...Object.fromEntries(Object.entries(local).filter(([key]) => key !== "attrs" && !Object.hasOwn(fields, key))),
45120
+ ...structuralFields(external, fields, name),
45121
+ attrs: external.attrs
45122
+ };
45123
+ }
45124
+ function checkTypes(local, external, kind) {
45125
+ for (const name of Object.keys(external)) if (!Object.hasOwn(local, name)) throw new RangeError(`schemaSpec requires a local ${kind} extension named '${name}'`);
45126
+ for (const name of Object.keys(local)) if (!Object.hasOwn(external, name)) throw new RangeError(`Local ${kind} extension '${name}' is not in schemaSpec`);
45127
+ }
44954
45128
  /**
44955
- * Optionally calls `value` as a function.
44956
- * Otherwise it is returned directly.
44957
- * @param value Function or any value.
44958
- * @param context Optional context to bind to function.
44959
- * @param props Optional props to pass to function.
45129
+ * Combines external structure with local DOM behavior and extension metadata.
45130
+ * @param local The specifications generated by resolved local extensions
45131
+ * @param external The schema compiled from the provided specification
45132
+ * @returns A specification in the external schema's node and mark order
44960
45133
  */
44961
- function callOrReturn(value, context = void 0, ...props) {
44962
- if (isFunction$3(value)) {
44963
- if (context) return value.bind(context)(...props);
44964
- return value(...props);
44965
- }
44966
- return value;
45134
+ function mergeSchemaSpec(local, external) {
45135
+ checkTypes(local.nodes, external.nodes, "node");
45136
+ checkTypes(local.marks, external.marks, "mark");
45137
+ let nodes = external.spec.nodes;
45138
+ let marks = external.spec.marks;
45139
+ external.spec.nodes.forEach((name, spec) => {
45140
+ nodes = nodes.update(name, mergeType(name, local.nodes[name], spec, nodeSchemaFields));
45141
+ });
45142
+ external.spec.marks.forEach((name, spec) => {
45143
+ marks = marks.update(name, mergeType(name, local.marks[name], spec, markSchemaFields));
45144
+ });
45145
+ return {
45146
+ topNode: external.topNodeType.name,
45147
+ nodes,
45148
+ marks
45149
+ };
44967
45150
  }
44968
45151
  //#endregion
44969
- //#region src/utilities/isEmptyObject.ts
44970
- function isEmptyObject(value = {}) {
44971
- return Object.keys(value).length === 0 && value.constructor === Object;
45152
+ //#region src/utilities/findDuplicates.ts
45153
+ /**
45154
+ * Find duplicates in an array.
45155
+ */
45156
+ function findDuplicates(items) {
45157
+ const filtered = items.filter((el, index) => items.indexOf(el) !== index);
45158
+ return Array.from(new Set(filtered));
44972
45159
  }
44973
45160
  //#endregion
44974
45161
  //#region src/helpers/splitExtensions.ts
@@ -45055,6 +45242,32 @@ so this becomes the fallback color for the slot */ ''}
45055
45242
  return extensionAttributes;
45056
45243
  }
45057
45244
  //#endregion
45245
+ //#region src/utilities/isFunction.ts
45246
+ function isFunction$3(value) {
45247
+ return typeof value === "function";
45248
+ }
45249
+ //#endregion
45250
+ //#region src/utilities/callOrReturn.ts
45251
+ /**
45252
+ * Optionally calls `value` as a function.
45253
+ * Otherwise it is returned directly.
45254
+ * @param value Function or any value.
45255
+ * @param context Optional context to bind to function.
45256
+ * @param props Optional props to pass to function.
45257
+ */
45258
+ function callOrReturn(value, context = void 0, ...props) {
45259
+ if (isFunction$3(value)) {
45260
+ if (context) return value.bind(context)(...props);
45261
+ return value(...props);
45262
+ }
45263
+ return value;
45264
+ }
45265
+ //#endregion
45266
+ //#region src/utilities/isEmptyObject.ts
45267
+ function isEmptyObject(value = {}) {
45268
+ return Object.keys(value).length === 0 && value.constructor === Object;
45269
+ }
45270
+ //#endregion
45058
45271
  //#region src/utilities/mergeAttributes.ts
45059
45272
  /** Splits a CSS style string into declarations, ignoring semicolons inside quotes/parentheses. */
45060
45273
  function splitStyleDeclarations(styles) {
@@ -45191,7 +45404,7 @@ so this becomes the fallback color for the slot */ ''}
45191
45404
  };
45192
45405
  }
45193
45406
  //#endregion
45194
- //#region src/helpers/getSchemaByResolvedExtensions.ts
45407
+ //#region src/helpers/getSchemaSpecByResolvedExtensions.ts
45195
45408
  function cleanUpSchemaItem(data) {
45196
45409
  return Object.fromEntries(Object.entries(data).filter(([key, value]) => {
45197
45410
  if (key === "attrs" && isEmptyObject(value)) return false;
@@ -45211,103 +45424,108 @@ so this becomes the fallback color for the slot */ ''}
45211
45424
  return [extensionAttribute.name, spec];
45212
45425
  }
45213
45426
  /**
45214
- * Creates a new Prosemirror schema based on the given extensions.
45427
+ * Builds schema specifications without compiling content expressions.
45215
45428
  * @param extensions An array of Tiptap extensions
45216
45429
  * @param editor The editor instance
45217
- * @returns A Prosemirror schema
45430
+ * @param allAttributes The effective attributes used for schema and DOM behavior
45431
+ * @returns The node and mark specifications
45218
45432
  */
45219
- function getSchemaByResolvedExtensions(extensions, editor) {
45433
+ function getSchemaSpecByResolvedExtensions(extensions, editor, allAttributes = getAttributesFromExtensions(extensions)) {
45220
45434
  var _nodeExtensions$find;
45221
- const allAttributes = getAttributesFromExtensions(extensions);
45222
45435
  const { nodeExtensions, markExtensions } = splitExtensions(extensions);
45223
- const topNode = (_nodeExtensions$find = nodeExtensions.find((extension) => getExtensionField(extension, "topNode"))) === null || _nodeExtensions$find === void 0 ? void 0 : _nodeExtensions$find.name;
45224
- const nodes = Object.fromEntries(nodeExtensions.map((extension) => {
45225
- const extensionAttributes = allAttributes.filter((attribute) => attribute.type === extension.name);
45226
- const context = {
45227
- name: extension.name,
45228
- options: extension.options,
45229
- storage: extension.storage,
45230
- editor
45231
- };
45232
- const schema = cleanUpSchemaItem({
45233
- ...extensions.reduce((fields, e) => {
45234
- const extendNodeSchema = getExtensionField(e, "extendNodeSchema", context);
45235
- return {
45236
- ...fields,
45237
- ...extendNodeSchema ? extendNodeSchema(extension) : {}
45238
- };
45239
- }, {}),
45240
- content: callOrReturn(getExtensionField(extension, "content", context)),
45241
- marks: callOrReturn(getExtensionField(extension, "marks", context)),
45242
- group: callOrReturn(getExtensionField(extension, "group", context)),
45243
- inline: callOrReturn(getExtensionField(extension, "inline", context)),
45244
- atom: callOrReturn(getExtensionField(extension, "atom", context)),
45245
- selectable: callOrReturn(getExtensionField(extension, "selectable", context)),
45246
- draggable: callOrReturn(getExtensionField(extension, "draggable", context)),
45247
- code: callOrReturn(getExtensionField(extension, "code", context)),
45248
- whitespace: callOrReturn(getExtensionField(extension, "whitespace", context)),
45249
- linebreakReplacement: callOrReturn(getExtensionField(extension, "linebreakReplacement", context)),
45250
- defining: callOrReturn(getExtensionField(extension, "defining", context)),
45251
- isolating: callOrReturn(getExtensionField(extension, "isolating", context)),
45252
- attrs: Object.fromEntries(extensionAttributes.map(buildAttributeSpec))
45253
- });
45254
- const parseHTML = callOrReturn(getExtensionField(extension, "parseHTML", context));
45255
- if (parseHTML) schema.parseDOM = parseHTML.map((parseRule) => injectExtensionAttributesToParseRule(parseRule, extensionAttributes));
45256
- const renderHTML = getExtensionField(extension, "renderHTML", context);
45257
- if (renderHTML) schema.toDOM = (node) => renderHTML({
45258
- node,
45259
- HTMLAttributes: getRenderedAttributes(node, extensionAttributes)
45260
- });
45261
- const renderText = getExtensionField(extension, "renderText", context);
45262
- if (renderText) schema.toText = renderText;
45263
- return [extension.name, schema];
45264
- }));
45265
- const marks = Object.fromEntries(markExtensions.map((extension) => {
45266
- const extensionAttributes = allAttributes.filter((attribute) => attribute.type === extension.name);
45267
- const context = {
45268
- name: extension.name,
45269
- options: extension.options,
45270
- storage: extension.storage,
45271
- editor
45272
- };
45273
- const schema = cleanUpSchemaItem({
45274
- ...extensions.reduce((fields, e) => {
45275
- const extendMarkSchema = getExtensionField(e, "extendMarkSchema", context);
45276
- return {
45277
- ...fields,
45278
- ...extendMarkSchema ? extendMarkSchema(extension) : {}
45279
- };
45280
- }, {}),
45281
- inclusive: callOrReturn(getExtensionField(extension, "inclusive", context)),
45282
- excludes: callOrReturn(getExtensionField(extension, "excludes", context)),
45283
- group: callOrReturn(getExtensionField(extension, "group", context)),
45284
- spanning: callOrReturn(getExtensionField(extension, "spanning", context)),
45285
- code: callOrReturn(getExtensionField(extension, "code", context)),
45286
- attrs: Object.fromEntries(extensionAttributes.map(buildAttributeSpec))
45287
- });
45288
- const parseHTML = callOrReturn(getExtensionField(extension, "parseHTML", context));
45289
- if (parseHTML) schema.parseDOM = parseHTML.map((parseRule) => injectExtensionAttributesToParseRule(parseRule, extensionAttributes));
45290
- const renderHTML = getExtensionField(extension, "renderHTML", context);
45291
- if (renderHTML) schema.toDOM = (mark) => renderHTML({
45292
- mark,
45293
- HTMLAttributes: getRenderedAttributes(mark, extensionAttributes)
45294
- });
45295
- return [extension.name, schema];
45296
- }));
45297
- return new Schema$2({
45298
- topNode,
45299
- nodes,
45300
- marks
45301
- });
45436
+ return {
45437
+ topNode: (_nodeExtensions$find = nodeExtensions.find((extension) => getExtensionField(extension, "topNode"))) === null || _nodeExtensions$find === void 0 ? void 0 : _nodeExtensions$find.name,
45438
+ nodes: Object.fromEntries(nodeExtensions.map((extension) => {
45439
+ const extensionAttributes = allAttributes.filter((attribute) => attribute.type === extension.name);
45440
+ const context = {
45441
+ name: extension.name,
45442
+ options: extension.options,
45443
+ storage: extension.storage,
45444
+ editor
45445
+ };
45446
+ const schema = cleanUpSchemaItem({
45447
+ ...extensions.reduce((fields, e) => {
45448
+ const extendNodeSchema = getExtensionField(e, "extendNodeSchema", context);
45449
+ return {
45450
+ ...fields,
45451
+ ...extendNodeSchema ? extendNodeSchema(extension) : {}
45452
+ };
45453
+ }, {}),
45454
+ content: callOrReturn(getExtensionField(extension, "content", context)),
45455
+ marks: callOrReturn(getExtensionField(extension, "marks", context)),
45456
+ group: callOrReturn(getExtensionField(extension, "group", context)),
45457
+ inline: callOrReturn(getExtensionField(extension, "inline", context)),
45458
+ atom: callOrReturn(getExtensionField(extension, "atom", context)),
45459
+ selectable: callOrReturn(getExtensionField(extension, "selectable", context)),
45460
+ draggable: callOrReturn(getExtensionField(extension, "draggable", context)),
45461
+ code: callOrReturn(getExtensionField(extension, "code", context)),
45462
+ whitespace: callOrReturn(getExtensionField(extension, "whitespace", context)),
45463
+ linebreakReplacement: callOrReturn(getExtensionField(extension, "linebreakReplacement", context)),
45464
+ defining: callOrReturn(getExtensionField(extension, "defining", context)),
45465
+ isolating: callOrReturn(getExtensionField(extension, "isolating", context)),
45466
+ attrs: Object.fromEntries(extensionAttributes.map(buildAttributeSpec))
45467
+ });
45468
+ const parseHTML = callOrReturn(getExtensionField(extension, "parseHTML", context));
45469
+ if (parseHTML) schema.parseDOM = parseHTML.map((parseRule) => injectExtensionAttributesToParseRule(parseRule, extensionAttributes));
45470
+ const renderHTML = getExtensionField(extension, "renderHTML", context);
45471
+ if (renderHTML) schema.toDOM = (node) => renderHTML({
45472
+ node,
45473
+ HTMLAttributes: getRenderedAttributes(node, extensionAttributes)
45474
+ });
45475
+ const renderText = getExtensionField(extension, "renderText", context);
45476
+ if (renderText) schema.toText = renderText;
45477
+ return [extension.name, schema];
45478
+ })),
45479
+ marks: Object.fromEntries(markExtensions.map((extension) => {
45480
+ const extensionAttributes = allAttributes.filter((attribute) => attribute.type === extension.name);
45481
+ const context = {
45482
+ name: extension.name,
45483
+ options: extension.options,
45484
+ storage: extension.storage,
45485
+ editor
45486
+ };
45487
+ const schema = cleanUpSchemaItem({
45488
+ ...extensions.reduce((fields, e) => {
45489
+ const extendMarkSchema = getExtensionField(e, "extendMarkSchema", context);
45490
+ return {
45491
+ ...fields,
45492
+ ...extendMarkSchema ? extendMarkSchema(extension) : {}
45493
+ };
45494
+ }, {}),
45495
+ inclusive: callOrReturn(getExtensionField(extension, "inclusive", context)),
45496
+ excludes: callOrReturn(getExtensionField(extension, "excludes", context)),
45497
+ group: callOrReturn(getExtensionField(extension, "group", context)),
45498
+ spanning: callOrReturn(getExtensionField(extension, "spanning", context)),
45499
+ code: callOrReturn(getExtensionField(extension, "code", context)),
45500
+ attrs: Object.fromEntries(extensionAttributes.map(buildAttributeSpec))
45501
+ });
45502
+ const parseHTML = callOrReturn(getExtensionField(extension, "parseHTML", context));
45503
+ if (parseHTML) schema.parseDOM = parseHTML.map((parseRule) => injectExtensionAttributesToParseRule(parseRule, extensionAttributes));
45504
+ const renderHTML = getExtensionField(extension, "renderHTML", context);
45505
+ if (renderHTML) schema.toDOM = (mark) => renderHTML({
45506
+ mark,
45507
+ HTMLAttributes: getRenderedAttributes(mark, extensionAttributes)
45508
+ });
45509
+ return [extension.name, schema];
45510
+ }))
45511
+ };
45302
45512
  }
45303
45513
  //#endregion
45304
- //#region src/utilities/findDuplicates.ts
45514
+ //#region src/helpers/getSchemaByResolvedExtensions.ts
45305
45515
  /**
45306
- * Find duplicates in an array.
45516
+ * Creates a ProseMirror schema from resolved extensions.
45517
+ * @param extensions The flattened and sorted extensions
45518
+ * @param editor The editor instance
45519
+ * @param schemaSpec The external structure to use with local extension behavior
45520
+ * @returns A ProseMirror schema
45307
45521
  */
45308
- function findDuplicates(items) {
45309
- const filtered = items.filter((el, index) => items.indexOf(el) !== index);
45310
- return Array.from(new Set(filtered));
45522
+ function getSchemaByResolvedExtensions(extensions, editor, schemaSpec) {
45523
+ if (schemaSpec === void 0) return new Schema$2(getSchemaSpecByResolvedExtensions(extensions, editor));
45524
+ const duplicates = findDuplicates(extensions.filter((extension) => extension.type !== "extension").map((extension) => extension.name));
45525
+ if (duplicates.length) throw new RangeError(`Duplicate local schema types: ${duplicates.join(", ")}`);
45526
+ const external = new Schema$2(schemaSpec);
45527
+ const local = getSchemaSpecByResolvedExtensions(extensions, editor, getSchemaAttributes(getAttributesFromExtensions(extensions), external));
45528
+ return new Schema$2(mergeSchemaSpec(local, external));
45311
45529
  }
45312
45530
  //#endregion
45313
45531
  //#region src/helpers/sortExtensions.ts
@@ -45462,6 +45680,7 @@ so this becomes the fallback color for the slot */ ''}
45462
45680
  function getChangedRanges(transform) {
45463
45681
  const { mapping, steps } = transform;
45464
45682
  const changes = [];
45683
+ const inverted = mapping.invert();
45465
45684
  mapping.maps.forEach((stepMap, index) => {
45466
45685
  const ranges = [];
45467
45686
  if (!stepMap.ranges.length) {
@@ -45477,11 +45696,12 @@ so this becomes the fallback color for the slot */ ''}
45477
45696
  to
45478
45697
  });
45479
45698
  });
45699
+ const rest = mapping.slice(index);
45480
45700
  ranges.forEach(({ from, to }) => {
45481
- const newStart = mapping.slice(index).map(from, -1);
45482
- const newEnd = mapping.slice(index).map(to);
45483
- const oldStart = mapping.invert().map(newStart, -1);
45484
- const oldEnd = mapping.invert().map(newEnd);
45701
+ const newStart = rest.map(from, -1);
45702
+ const newEnd = rest.map(to);
45703
+ const oldStart = inverted.map(newStart, -1);
45704
+ const oldEnd = inverted.map(newEnd);
45485
45705
  changes.push({
45486
45706
  oldRange: {
45487
45707
  from: oldStart,
@@ -45751,6 +45971,40 @@ so this becomes the fallback color for the slot */ ''}
45751
45971
  return value instanceof NodeSelection;
45752
45972
  }
45753
45973
  //#endregion
45974
+ //#region src/helpers/isProseMirrorStep.ts
45975
+ /**
45976
+ * Checks if a value is a ProseMirror step
45977
+ * @param value The value to check
45978
+ * @returns - A boolean, if the boolean is true the value is a ProseMirror Step
45979
+ * @example ```js
45980
+ * isProseMirrorStep(transaction.steps[0])
45981
+ * ```
45982
+ */
45983
+ function isProseMirrorStep(value) {
45984
+ if (value === null || typeof value !== "object") return false;
45985
+ const step = value;
45986
+ if (typeof step.apply !== "function" || typeof step.getMap !== "function" || typeof step.invert !== "function" || typeof step.map !== "function" || typeof step.merge !== "function" || typeof step.toJSON !== "function") return false;
45987
+ return true;
45988
+ }
45989
+ //#endregion
45990
+ //#region src/helpers/isProseMirrorReplaceStep.ts
45991
+ /**
45992
+ * Checks if a value is a ProseMirror replace step result
45993
+ * @param value The value to check
45994
+ * @returns - A boolean, if the boolean is true the value is a ProseMirror ReplaceStep
45995
+ * @example ```js
45996
+ * isProseMirrorReplaceStep(transaction.steps[0])
45997
+ * ```
45998
+ */
45999
+ function isProseMirrorReplaceStep(value) {
46000
+ if (value === null || typeof value !== "object") return false;
46001
+ const step = value;
46002
+ if (!isProseMirrorStep(step)) return false;
46003
+ const json = step.toJSON();
46004
+ if (json === null || typeof json !== "object" || json.stepType !== "replace") return false;
46005
+ return true;
46006
+ }
46007
+ //#endregion
45754
46008
  //#region src/helpers/MappablePosition.ts
45755
46009
  /**
45756
46010
  * A class that represents a mappable position in the editor. It can be extended
@@ -46072,6 +46326,94 @@ so this becomes the fallback color for the slot */ ''}
46072
46326
  return true;
46073
46327
  };
46074
46328
  //#endregion
46329
+ //#region src/commands/utils/createNode.ts
46330
+ /** Creates a node when its content and required attributes are valid. */
46331
+ function createNode(type, content, attrs) {
46332
+ if (!type.validContent(content)) return null;
46333
+ try {
46334
+ return type.create(attrs, content);
46335
+ } catch {
46336
+ return null;
46337
+ }
46338
+ }
46339
+ //#endregion
46340
+ //#region src/commands/utils/flushPendingContent.ts
46341
+ /** Converts and appends the content accumulated for the current list item. */
46342
+ function flushPendingContent(state, itemType) {
46343
+ if (state.pendingContent.length === 0) return true;
46344
+ const item = createNode(itemType, Fragment.from(state.pendingContent));
46345
+ if (!item) return false;
46346
+ state.items.push(item);
46347
+ state.pendingContent = [];
46348
+ return true;
46349
+ }
46350
+ //#endregion
46351
+ //#region src/commands/utils/appendContentNode.ts
46352
+ /** Appends a content node to the current item or starts a new item when needed. */
46353
+ function appendContentNode(node, state, itemType) {
46354
+ if (itemType.validContent(Fragment.from([...state.pendingContent, node]))) {
46355
+ state.pendingContent.push(node);
46356
+ return true;
46357
+ }
46358
+ if (!flushPendingContent(state, itemType) || !itemType.validContent(Fragment.from(node))) return false;
46359
+ state.pendingContent.push(node);
46360
+ return true;
46361
+ }
46362
+ //#endregion
46363
+ //#region src/commands/utils/appendNestedList.ts
46364
+ /** Preserves a nested list when supported or flattens its converted items. */
46365
+ function appendNestedList(sourceList, state, context, convertListItems) {
46366
+ const nestedItems = convertListItems(sourceList, context);
46367
+ if (!nestedItems) return false;
46368
+ const nestedList = createNode(context.listType, Fragment.from(nestedItems), sourceList.attrs);
46369
+ if (!nestedList) return false;
46370
+ if (context.itemType.validContent(Fragment.from([...state.pendingContent, nestedList]))) {
46371
+ state.pendingContent.push(nestedList);
46372
+ return true;
46373
+ }
46374
+ if (!flushPendingContent(state, context.itemType)) return false;
46375
+ state.items.push(...nestedItems);
46376
+ return true;
46377
+ }
46378
+ //#endregion
46379
+ //#region src/commands/utils/convertListItem.ts
46380
+ /** Converts one source list item into one or more target list items. */
46381
+ function convertListItem(sourceItem, context, convertListItems) {
46382
+ const state = {
46383
+ items: [],
46384
+ pendingContent: []
46385
+ };
46386
+ for (let index = 0; index < sourceItem.childCount; index += 1) {
46387
+ const child = sourceItem.child(index);
46388
+ if (!(context.isListNode(child) ? appendNestedList(child, state, context, convertListItems) : appendContentNode(child, state, context.itemType))) return null;
46389
+ }
46390
+ return flushPendingContent(state, context.itemType) ? state.items : null;
46391
+ }
46392
+ //#endregion
46393
+ //#region src/commands/utils/convertListItems.ts
46394
+ /** Recursively converts all items in a source list to the target list schema. */
46395
+ function convertListItems(sourceList, context) {
46396
+ const convertedItems = [];
46397
+ for (let index = 0; index < sourceList.childCount; index += 1) {
46398
+ const items = convertListItem(sourceList.child(index), context, convertListItems);
46399
+ if (!items) return null;
46400
+ convertedItems.push(...items);
46401
+ }
46402
+ return convertedItems;
46403
+ }
46404
+ //#endregion
46405
+ //#region src/commands/utils/findNodePosition.ts
46406
+ /** Finds a descendant node's position relative to its root node. */
46407
+ function findNodePosition(root, target) {
46408
+ let targetPos = null;
46409
+ root.descendants((node, pos) => {
46410
+ if (node !== target) return true;
46411
+ targetPos = pos;
46412
+ return false;
46413
+ });
46414
+ return targetPos;
46415
+ }
46416
+ //#endregion
46075
46417
  //#region src/commands/toggleList.ts
46076
46418
  /**
46077
46419
  * Normalise a list type attribute for comparison.
@@ -46151,6 +46493,43 @@ so this becomes the fallback color for the slot */ ''}
46151
46493
  tr.setNodeMarkup(currentList.pos, listType);
46152
46494
  return true;
46153
46495
  }).command(() => joinListBackwards(tr, listType)).command(() => joinListForwards(tr, listType)).run();
46496
+ if (isList(currentList.node.type.name, extensions)) {
46497
+ var _currentList$node$fir;
46498
+ const currentItemType = (_currentList$node$fir = currentList.node.firstChild) === null || _currentList$node$fir === void 0 ? void 0 : _currentList$node$fir.type;
46499
+ if (currentItemType && currentItemType !== itemType) {
46500
+ const convertedItems = convertListItems(currentList.node, {
46501
+ listType,
46502
+ itemType,
46503
+ isListNode: (node) => isList(node.type.name, extensions)
46504
+ });
46505
+ const convertedContent = convertedItems ? Fragment.from(convertedItems) : null;
46506
+ if (!convertedContent || !listType.validContent(convertedContent)) return false;
46507
+ return chain().command(() => {
46508
+ const { $anchor, $head } = tr.selection;
46509
+ const anchorParent = $anchor.parent;
46510
+ const headParent = $head.parent;
46511
+ const anchorOffset = $anchor.parentOffset;
46512
+ const headOffset = $head.parentOffset;
46513
+ let newList;
46514
+ try {
46515
+ newList = listType.create(attributes, convertedContent);
46516
+ } catch {
46517
+ return false;
46518
+ }
46519
+ tr.replaceWith(currentList.pos, currentList.pos + currentList.node.nodeSize, newList);
46520
+ if (anchorParent.inlineContent && headParent.inlineContent) {
46521
+ const anchorParentPos = findNodePosition(newList, anchorParent);
46522
+ const headParentPos = findNodePosition(newList, headParent);
46523
+ if (anchorParentPos !== null && headParentPos !== null) {
46524
+ const anchor = currentList.pos + anchorParentPos + 2 + anchorOffset;
46525
+ const head = currentList.pos + headParentPos + 2 + headOffset;
46526
+ tr.setSelection(TextSelection.create(tr.doc, anchor, head));
46527
+ }
46528
+ }
46529
+ return true;
46530
+ }).command(() => joinListBackwards(tr, listType)).command(() => joinListForwards(tr, listType)).run();
46531
+ }
46532
+ }
46154
46533
  }
46155
46534
  if (!keepMarks || !marks || !dispatch) return chain().command(() => {
46156
46535
  if (can().wrapInList(listType, attributes)) return true;
@@ -47348,6 +47727,34 @@ so this becomes the fallback color for the slot */ ''}
47348
47727
  }
47349
47728
  //#endregion
47350
47729
  //#region src/utilities/markdown/parseIndentedBlocks.ts
47730
+ function dedentLine(line, indentSize) {
47731
+ return line.replace(/^[ \t]*/, (whitespace) => {
47732
+ const tabSize = 4;
47733
+ let columns = 0;
47734
+ for (const character of whitespace) columns += character === " " ? tabSize - columns % tabSize : 1;
47735
+ return " ".repeat(Math.max(0, columns - indentSize));
47736
+ });
47737
+ }
47738
+ function continuesParagraph(line, blockTokens) {
47739
+ const source = `text\n${line}\n`;
47740
+ const token = blockTokens(source)[0];
47741
+ return ((token === null || token === void 0 ? void 0 : token.type) === "paragraph" || (token === null || token === void 0 ? void 0 : token.type) === "text") && token.raw === source;
47742
+ }
47743
+ /** Joins paragraph continuation lines and leaves nested blocks for separate parsing. */
47744
+ function parseContinuation(mainContent, nestedContent, lexer) {
47745
+ var _lexer$isParagraphCon;
47746
+ const lines = nestedContent.split("\n");
47747
+ const isContinuation = (_lexer$isParagraphCon = lexer.isParagraphContinuation) !== null && _lexer$isParagraphCon !== void 0 ? _lexer$isParagraphCon : ((line) => continuesParagraph(line, lexer.blockTokens));
47748
+ let continuationLength = 0;
47749
+ for (const line of lines) {
47750
+ if (!line.trim() || !isContinuation(line)) break;
47751
+ continuationLength += 1;
47752
+ }
47753
+ return {
47754
+ mainContent: [mainContent, ...lines.slice(0, continuationLength).map((line) => line.trimStart())].join("\n"),
47755
+ nestedContent: lines.slice(continuationLength).join("\n")
47756
+ };
47757
+ }
47351
47758
  /**
47352
47759
  * Parses markdown text into hierarchical indented blocks with proper nesting.
47353
47760
  *
@@ -47430,7 +47837,9 @@ so this becomes the fallback color for the slot */ ''}
47430
47837
  let nestedTokens;
47431
47838
  const nestedContent = itemContent.slice(1);
47432
47839
  if (nestedContent.length > 0) {
47433
- const dedentedNested = nestedContent.map((nestedLine) => nestedLine.slice(indentLevel + baseIndentSize)).join("\n");
47840
+ const continuation = parseContinuation(mainContent, nestedContent.map((nestedLine) => dedentLine(nestedLine, indentLevel + baseIndentSize)).join("\n"), lexer);
47841
+ itemData.mainContent = continuation.mainContent;
47842
+ const dedentedNested = continuation.nestedContent;
47434
47843
  if (dedentedNested.trim()) {
47435
47844
  if (config.customNestedParser) nestedTokens = config.customNestedParser(dedentedNested);
47436
47845
  else nestedTokens = lexer.blockTokens(dedentedNested);
@@ -47442,7 +47851,7 @@ so this becomes the fallback color for the slot */ ''}
47442
47851
  if (items.length === 0) return;
47443
47852
  return {
47444
47853
  items,
47445
- raw: totalRaw
47854
+ raw: totalRaw.slice(0, src.length)
47446
47855
  };
47447
47856
  }
47448
47857
  //#endregion
@@ -47467,6 +47876,7 @@ so this becomes the fallback color for the slot */ ''}
47467
47876
  * @param options - Optional rendering options
47468
47877
  * @param options.alignNestedToPrefix - Indent nested content to the width of the prefix
47469
47878
  * instead of the configured indent size, when the configured one is narrower
47879
+ * @param options.indentMainContent - Indent continuation lines in the opening paragraph
47470
47880
  * @returns The rendered markdown string
47471
47881
  *
47472
47882
  * @example
@@ -47516,7 +47926,8 @@ so this becomes the fallback color for the slot */ ''}
47516
47926
  if (!node || !Array.isArray(node.content)) return "";
47517
47927
  const prefix = typeof prefixOrGenerator === "function" ? prefixOrGenerator(ctx) : prefixOrGenerator;
47518
47928
  const [content, ...children] = node.content;
47519
- let output = `${prefix}${h.renderChildren([content])}`;
47929
+ const mainContent = h.renderChildren([content]);
47930
+ let output = `${prefix}${(options === null || options === void 0 ? void 0 : options.indentMainContent) ? mainContent.split("\n").map((line, index) => index === 0 ? line : h.indent(line)).join("\n") : mainContent}`;
47520
47931
  if (children && children.length > 0) children.forEach((child, index) => {
47521
47932
  var _h$renderChild, _h$renderChild2;
47522
47933
  const childContent = (_h$renderChild = (_h$renderChild2 = h.renderChild) === null || _h$renderChild2 === void 0 ? void 0 : _h$renderChild2.call(h, child, index + 1)) !== null && _h$renderChild !== void 0 ? _h$renderChild : h.renderChildren([child]);
@@ -48069,7 +48480,8 @@ so this becomes the fallback color for the slot */ ''}
48069
48480
  this.editor = editor;
48070
48481
  this.baseExtensions = extensions;
48071
48482
  this.extensions = resolveExtensions(extensions);
48072
- this.schema = getSchemaByResolvedExtensions(this.extensions, editor);
48483
+ this.hasSchemaSpec = editor.options.schemaSpec !== void 0;
48484
+ this.schema = getSchemaByResolvedExtensions(this.extensions, editor, editor.options.schemaSpec);
48073
48485
  this.setupExtensions();
48074
48486
  }
48075
48487
  /**
@@ -48195,7 +48607,8 @@ so this becomes the fallback color for the slot */ ''}
48195
48607
  * @returns An array of attributes
48196
48608
  */
48197
48609
  get attributes() {
48198
- return getAttributesFromExtensions(this.extensions);
48610
+ const attributes = getAttributesFromExtensions(this.extensions);
48611
+ return this.hasSchemaSpec ? getSchemaAttributes(attributes, this.schema) : attributes;
48199
48612
  }
48200
48613
  /**
48201
48614
  * Get all node views from the extensions.
@@ -48771,10 +49184,12 @@ so this becomes the fallback color for the slot */ ''}
48771
49184
  hasChecked = true;
48772
49185
  let content;
48773
49186
  try {
48774
- content = ReplaceStep.fromJSON(schema, {
49187
+ const step = ReplaceStep.fromJSON(schema, {
48775
49188
  from: 0,
48776
49189
  to: 0
48777
- }).slice.content;
49190
+ });
49191
+ if (!isProseMirrorReplaceStep(step)) return;
49192
+ content = step.slice.content;
48778
49193
  } catch {
48779
49194
  return;
48780
49195
  }
@@ -54773,114 +55188,141 @@ img.ProseMirror-separator {
54773
55188
  return true
54774
55189
  }
54775
55190
 
54776
- function reference (state, startLine, _endLine, silent) {
54777
- let pos = state.bMarks[startLine] + state.tShift[startLine];
54778
- let max = state.eMarks[startLine];
54779
- let nextLine = startLine + 1;
55191
+ // CommonMark limits reference labels to 999 Unicode code points.
55192
+ const MAX_LABEL_LENGTH = 999;
54780
55193
 
54781
- // if it's indented more than 3 spaces, it should be a code block
54782
- if (state.sCount[startLine] - state.blkIndent >= 4) { return false }
55194
+ function countCodePoints (str) {
55195
+ let length = str.length;
54783
55196
 
54784
- if (state.src.charCodeAt(pos) !== 0x5B/* [ */) { return false }
55197
+ for (let i = 0; i < str.length - 1; i++) {
55198
+ const high = str.charCodeAt(i);
55199
+ if (high < 0xD800 || high > 0xDBFF) { continue }
54785
55200
 
54786
- function getNextLine (nextLine) {
54787
- const endLine = state.lineMax;
54788
-
54789
- if (nextLine >= endLine || state.isEmpty(nextLine)) {
54790
- // empty line or end of input
54791
- return null
55201
+ const low = str.charCodeAt(i + 1);
55202
+ if (low >= 0xDC00 && low <= 0xDFFF) {
55203
+ length--;
55204
+ i++;
54792
55205
  }
55206
+ }
54793
55207
 
54794
- let isContinuation = false;
55208
+ return length
55209
+ }
54795
55210
 
54796
- // this would be a code block normally, but after paragraph
54797
- // it's considered a lazy continuation regardless of what's there
54798
- if (state.sCount[nextLine] - state.blkIndent > 3) { isContinuation = true; }
55211
+ // Exclusive end offset of the line, after its newline if present
55212
+ function lineEnd (state, line) {
55213
+ return Math.min(state.eMarks[line] + 1, state.src.length)
55214
+ }
54799
55215
 
54800
- // quirk for blockquotes, this line should already be checked by that rule
54801
- if (state.sCount[nextLine] < 0) { isContinuation = true; }
54802
-
54803
- if (!isContinuation) {
54804
- const terminatorRules = state.md.block.ruler.getRules('reference');
54805
- const oldParentType = state.parentType;
54806
- state.parentType = 'reference';
54807
-
54808
- // Some tags can terminate paragraph without empty line.
54809
- let terminate = false;
54810
- for (let i = 0, l = terminatorRules.length; i < l; i++) {
54811
- if (terminatorRules[i](state, nextLine, endLine, true)) {
54812
- terminate = true;
54813
- break
54814
- }
54815
- }
55216
+ // Returns -1 if the reference can't continue on this line
55217
+ function getNextLinePos (state, nextLine) {
55218
+ const endLine = state.lineMax;
55219
+
55220
+ if (nextLine >= endLine || state.isEmpty(nextLine)) {
55221
+ // empty line or end of input
55222
+ return -1
55223
+ }
55224
+
55225
+ let isContinuation = false;
54816
55226
 
54817
- state.parentType = oldParentType;
54818
- if (terminate) {
54819
- // terminated by another block
54820
- return null
55227
+ // this would be a code block normally, but after paragraph
55228
+ // it's considered a lazy continuation regardless of what's there
55229
+ if (state.sCount[nextLine] - state.blkIndent > 3) { isContinuation = true; }
55230
+
55231
+ // quirk for blockquotes, this line should already be checked by that rule
55232
+ if (state.sCount[nextLine] < 0) { isContinuation = true; }
55233
+
55234
+ if (!isContinuation) {
55235
+ const terminatorRules = state.md.block.ruler.getRules('reference');
55236
+ const oldParentType = state.parentType;
55237
+ state.parentType = 'reference';
55238
+
55239
+ // Some tags can terminate paragraph without empty line.
55240
+ let terminate = false;
55241
+ for (let i = 0, l = terminatorRules.length; i < l; i++) {
55242
+ if (terminatorRules[i](state, nextLine, endLine, true)) {
55243
+ terminate = true;
55244
+ break
54821
55245
  }
54822
55246
  }
54823
55247
 
54824
- const pos = state.bMarks[nextLine] + state.tShift[nextLine];
54825
- const max = state.eMarks[nextLine];
54826
-
54827
- // max + 1 explicitly includes the newline
54828
- return state.src.slice(pos, max + 1)
55248
+ state.parentType = oldParentType;
55249
+ if (terminate) {
55250
+ // terminated by another block
55251
+ return -1
55252
+ }
54829
55253
  }
54830
55254
 
54831
- let str = state.src.slice(pos, max + 1);
55255
+ return state.bMarks[nextLine] + state.tShift[nextLine]
55256
+ }
55257
+
55258
+ function reference (state, startLine, _endLine, silent) {
55259
+ const src = state.src;
55260
+ let pos = state.bMarks[startLine] + state.tShift[startLine];
55261
+ let nextLine = startLine + 1;
54832
55262
 
54833
- max = str.length;
55263
+ // if it's indented more than 3 spaces, it should be a code block
55264
+ if (state.sCount[startLine] - state.blkIndent >= 4) { return false }
55265
+
55266
+ if (src.charCodeAt(pos) !== 0x5B/* [ */) { return false }
55267
+
55268
+ // Scan the source directly: indexing a string after each appended line
55269
+ // can make V8 copy the accumulated prefix on every continuation.
55270
+ let max = lineEnd(state, startLine);
55271
+
55272
+ let rawLabel = '';
54834
55273
  let labelEnd = -1;
55274
+ let segmentStart = ++pos;
54835
55275
 
54836
- for (pos = 1; pos < max; pos++) {
54837
- const ch = str.charCodeAt(pos);
54838
- if (ch === 0x5B /* [ */) {
54839
- return false
54840
- } else if (ch === 0x5D /* ] */) {
55276
+ while (pos < max) {
55277
+ if (rawLabel.length + pos - segmentStart > MAX_LABEL_LENGTH * 2) { return false }
55278
+
55279
+ let ch = src.charCodeAt(pos);
55280
+ if (ch === 0x5B /* [ */) { return false }
55281
+ if (ch === 0x5D /* ] */) {
54841
55282
  labelEnd = pos;
54842
55283
  break
54843
- } else if (ch === 0x0A /* \n */) {
54844
- const lineContent = getNextLine(nextLine);
54845
- if (lineContent !== null) {
54846
- str += lineContent;
54847
- max = str.length;
54848
- nextLine++;
54849
- }
54850
- } else if (ch === 0x5C /* \ */) {
54851
- pos++;
54852
- if (pos < max && str.charCodeAt(pos) === 0x0A) {
54853
- const lineContent = getNextLine(nextLine);
54854
- if (lineContent !== null) {
54855
- str += lineContent;
54856
- max = str.length;
54857
- nextLine++;
54858
- }
54859
- }
54860
55284
  }
55285
+ if (ch === 0x5C /* \ */) { ch = src.charCodeAt(++pos); }
55286
+
55287
+ if (ch === 0x0A /* \n */ && pos < max) {
55288
+ const nextPos = getNextLinePos(state, nextLine);
55289
+ if (nextPos < 0) { return false }
55290
+ rawLabel += src.slice(segmentStart, max);
55291
+ pos = segmentStart = nextPos;
55292
+ max = lineEnd(state, nextLine++);
55293
+ continue
55294
+ }
55295
+ pos++;
54861
55296
  }
54862
55297
 
54863
- if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 0x3A/* : */) { return false }
55298
+ if (labelEnd < 0 || src.charCodeAt(labelEnd + 1) !== 0x3A/* : */) { return false }
55299
+
55300
+ rawLabel += src.slice(segmentStart, labelEnd);
55301
+
55302
+ if (rawLabel.length > MAX_LABEL_LENGTH && countCodePoints(rawLabel) > MAX_LABEL_LENGTH) {
55303
+ return false
55304
+ }
54864
55305
 
54865
55306
  // [label]: destination 'title'
54866
55307
  // ^^^ skip optional whitespace here
54867
- for (pos = labelEnd + 2; pos < max; pos++) {
54868
- const ch = str.charCodeAt(pos);
55308
+ pos = labelEnd + 2;
55309
+ while (pos < max) {
55310
+ const ch = src.charCodeAt(pos);
54869
55311
  if (ch === 0x0A) {
54870
- const lineContent = getNextLine(nextLine);
54871
- if (lineContent !== null) {
54872
- str += lineContent;
54873
- max = str.length;
54874
- nextLine++;
54875
- }
54876
- } else if (isSpace(ch)) ; else {
55312
+ const nextPos = getNextLinePos(state, nextLine);
55313
+ if (nextPos < 0) { break }
55314
+ pos = nextPos;
55315
+ max = lineEnd(state, nextLine++);
55316
+ } else if (isSpace(ch)) {
55317
+ pos++;
55318
+ } else {
54877
55319
  break
54878
55320
  }
54879
55321
  }
54880
55322
 
54881
55323
  // [label]: destination 'title'
54882
55324
  // ^^^^^^^^^^^ parse this
54883
- const destRes = state.md.helpers.parseLinkDestination(str, pos, max);
55325
+ const destRes = state.md.helpers.parseLinkDestination(src, pos, max);
54884
55326
  if (!destRes.ok) { return false }
54885
55327
 
54886
55328
  const href = state.md.normalizeLink(destRes.str);
@@ -54890,76 +55332,77 @@ img.ProseMirror-separator {
54890
55332
 
54891
55333
  // save cursor state, we could require to rollback later
54892
55334
  const destEndPos = pos;
55335
+ const destEndMax = max;
54893
55336
  const destEndLineNo = nextLine;
54894
55337
 
54895
55338
  // [label]: destination 'title'
54896
55339
  // ^^^ skipping those spaces
54897
- const start = pos;
54898
- for (; pos < max; pos++) {
54899
- const ch = str.charCodeAt(pos);
55340
+ while (pos < max) {
55341
+ const ch = src.charCodeAt(pos);
54900
55342
  if (ch === 0x0A) {
54901
- const lineContent = getNextLine(nextLine);
54902
- if (lineContent !== null) {
54903
- str += lineContent;
54904
- max = str.length;
54905
- nextLine++;
54906
- }
54907
- } else if (isSpace(ch)) ; else {
55343
+ const nextPos = getNextLinePos(state, nextLine);
55344
+ if (nextPos < 0) { break }
55345
+ pos = nextPos;
55346
+ max = lineEnd(state, nextLine++);
55347
+ } else if (isSpace(ch)) {
55348
+ pos++;
55349
+ } else {
54908
55350
  break
54909
55351
  }
54910
55352
  }
54911
55353
 
54912
55354
  // [label]: destination 'title'
54913
55355
  // ^^^^^^^ parse this
54914
- let titleRes = state.md.helpers.parseLinkTitle(str, pos, max);
55356
+ const titleStart = pos;
55357
+ let titleRes = state.md.helpers.parseLinkTitle(src, pos, max);
54915
55358
  while (titleRes.can_continue) {
54916
- const lineContent = getNextLine(nextLine);
54917
- if (lineContent === null) break
54918
- str += lineContent;
54919
- pos = max;
54920
- max = str.length;
54921
- nextLine++;
54922
- titleRes = state.md.helpers.parseLinkTitle(str, pos, max, titleRes);
55359
+ const nextPos = getNextLinePos(state, nextLine);
55360
+ if (nextPos < 0) break
55361
+ pos = nextPos;
55362
+ max = lineEnd(state, nextLine++);
55363
+ titleRes = state.md.helpers.parseLinkTitle(src, pos, max, titleRes);
54923
55364
  }
54924
55365
  let title;
54925
55366
 
54926
- if (pos < max && start !== pos && titleRes.ok) {
55367
+ if (titleStart !== destEndPos && titleRes.ok) {
54927
55368
  title = titleRes.str;
54928
55369
  pos = titleRes.pos;
54929
55370
  } else {
54930
55371
  title = '';
54931
55372
  pos = destEndPos;
55373
+ max = destEndMax;
54932
55374
  nextLine = destEndLineNo;
54933
55375
  }
54934
55376
 
54935
55377
  // skip trailing spaces until the rest of the line
54936
55378
  while (pos < max) {
54937
- const ch = str.charCodeAt(pos);
55379
+ const ch = src.charCodeAt(pos);
54938
55380
  if (!isSpace(ch)) { break }
54939
55381
  pos++;
54940
55382
  }
54941
55383
 
54942
- if (pos < max && str.charCodeAt(pos) !== 0x0A) {
55384
+ if (pos < max && src.charCodeAt(pos) !== 0x0A) {
54943
55385
  if (title) {
54944
55386
  // garbage at the end of the line after title,
54945
55387
  // but it could still be a valid reference if we roll back
54946
55388
  title = '';
54947
55389
  pos = destEndPos;
55390
+ max = destEndMax;
54948
55391
  nextLine = destEndLineNo;
54949
55392
  while (pos < max) {
54950
- const ch = str.charCodeAt(pos);
55393
+ const ch = src.charCodeAt(pos);
54951
55394
  if (!isSpace(ch)) { break }
54952
55395
  pos++;
54953
55396
  }
54954
55397
  }
54955
55398
  }
54956
55399
 
54957
- if (pos < max && str.charCodeAt(pos) !== 0x0A) {
55400
+ if (pos < max && src.charCodeAt(pos) !== 0x0A) {
54958
55401
  // garbage at the end of the line
54959
55402
  return false
54960
55403
  }
54961
55404
 
54962
- const label = normalizeReference(str.slice(1, labelEnd));
55405
+ const label = normalizeReference(rawLabel);
54963
55406
  if (!label) {
54964
55407
  // CommonMark 0.20 disallows empty labels
54965
55408
  return false
@@ -55063,13 +55506,6 @@ img.ProseMirror-separator {
55063
55506
  const open_tag = '<[A-Za-z][A-Za-z0-9\\-]*' + attribute + '*\\s*\\/?>';
55064
55507
 
55065
55508
  const close_tag = '<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>';
55066
- const comment = '<!---?>|<!--(?:[^-]|-[^-]|--[^>])*-->';
55067
- const processing = '<[?][\\s\\S]*?[?]>';
55068
- const declaration = '<![A-Za-z][^>]*>';
55069
- const cdata = '<!\\[CDATA\\[[\\s\\S]*?\\]\\]>';
55070
-
55071
- const HTML_TAG_RE = new RegExp('^(?:' + open_tag + '|' + close_tag + '|' + comment +
55072
- '|' + processing + '|' + declaration + '|' + cdata + ')');
55073
55509
  const HTML_OPEN_CLOSE_TAG_RE = new RegExp('^(?:' + open_tag + '|' + close_tag + ')');
55074
55510
 
55075
55511
  // HTML block
@@ -55484,6 +55920,10 @@ img.ProseMirror-separator {
55484
55920
  this.backticks = {};
55485
55921
  this.backticksScanned = false;
55486
55922
 
55923
+ // Set when html comment / PI / declaration / CDATA has no terminator,
55924
+ // to skip further scans of these constructs
55925
+ this.skipHtmlSpecial = false;
55926
+
55487
55927
  // Counter used to disable inline linkify-it execution
55488
55928
  // inside <a> and markdown links
55489
55929
  this.linkLevel = 0;
@@ -56578,6 +57018,43 @@ img.ProseMirror-separator {
56578
57018
  return (lc >= 0x61/* a */) && (lc <= 0x7a/* z */)
56579
57019
  }
56580
57020
 
57021
+ // Comment, processing instruction, declaration or CDATA: fixed opener,
57022
+ // then everything up to the first terminator. Returns end position or -1.
57023
+ function scanSpecial (state, pos) {
57024
+ const src = state.src;
57025
+ let start;
57026
+ let terminator;
57027
+
57028
+ if (src.startsWith('<!--', pos)) {
57029
+ if (src.startsWith('>', pos + 4)) { return pos + 5 }
57030
+ if (src.startsWith('->', pos + 4)) { return pos + 6 }
57031
+ start = pos + 4;
57032
+ terminator = '-->';
57033
+ } else if (src.startsWith('<![CDATA[', pos)) {
57034
+ start = pos + 9;
57035
+ terminator = ']]>';
57036
+ } else if (src.charCodeAt(pos + 1) === 0x3F/* ? */) {
57037
+ start = pos + 2;
57038
+ terminator = '?>';
57039
+ } else if (isLetter(src.charCodeAt(pos + 2))) {
57040
+ start = pos + 3;
57041
+ terminator = '>';
57042
+ } else {
57043
+ return -1
57044
+ }
57045
+
57046
+ if (state.skipHtmlSpecial) { return -1 }
57047
+
57048
+ const end = src.indexOf(terminator, start);
57049
+ if (end < 0) {
57050
+ // One flag for all constructs to keep code simple. Valid constructs after
57051
+ // an unclosed one in the same paragraph become text, that's acceptable.
57052
+ state.skipHtmlSpecial = true;
57053
+ return -1
57054
+ }
57055
+ return end + terminator.length
57056
+ }
57057
+
56581
57058
  function html_inline (state, silent) {
56582
57059
  if (!state.md.options.html) { return false }
56583
57060
 
@@ -56589,26 +57066,28 @@ img.ProseMirror-separator {
56589
57066
  return false
56590
57067
  }
56591
57068
 
56592
- // Quick fail on second char
57069
+ let end;
56593
57070
  const ch = state.src.charCodeAt(pos + 1);
56594
- if (ch !== 0x21/* ! */ &&
56595
- ch !== 0x3F/* ? */ &&
56596
- ch !== 0x2F/* / */ &&
56597
- !isLetter(ch)) {
57071
+
57072
+ if (ch === 0x21/* ! */ || ch === 0x3F/* ? */) {
57073
+ end = scanSpecial(state, pos);
57074
+ } else if (ch === 0x2F/* / */ || isLetter(ch)) {
57075
+ const match = state.src.slice(pos).match(HTML_OPEN_CLOSE_TAG_RE);
57076
+ end = match ? pos + match[0].length : -1;
57077
+ } else {
56598
57078
  return false
56599
57079
  }
56600
57080
 
56601
- const match = state.src.slice(pos).match(HTML_TAG_RE);
56602
- if (!match) { return false }
57081
+ if (end < 0) { return false }
56603
57082
 
56604
57083
  if (!silent) {
56605
57084
  const token = state.push('html_inline', '', 0);
56606
- token.content = match[0];
57085
+ token.content = state.src.slice(pos, end);
56607
57086
 
56608
57087
  if (isLinkOpen(token.content)) state.linkLevel++;
56609
57088
  if (isLinkClose(token.content)) state.linkLevel--;
56610
57089
  }
56611
- state.pos += match[0].length;
57090
+ state.pos = end;
56612
57091
  return true
56613
57092
  }
56614
57093
 
@@ -59648,7 +60127,7 @@ img.ProseMirror-separator {
59648
60127
  @internal
59649
60128
  */
59650
60129
  atBlank() {
59651
- return /(^|\n)$/.test(this.out);
60130
+ return !this.out || this.out[this.out.length - 1] == "\n";
59652
60131
  }
59653
60132
  /**
59654
60133
  Ensure the current content ends with a newline.
@@ -59684,7 +60163,7 @@ img.ProseMirror-separator {
59684
60163
  for (let i = 0; i < lines.length; i++) {
59685
60164
  this.write();
59686
60165
  // Escape exclamation marks in front of links
59687
- if (!escape && lines[i][0] == "[" && /(^|[^\\])\!$/.test(this.out))
60166
+ if (!escape && lines[i][0] == "[" && /(^|[^\\])\!$/.test(this.out.slice(-2)))
59688
60167
  this.out = this.out.slice(0, this.out.length - 1) + "\\!";
59689
60168
  this.out += escape ? this.esc(lines[i], this.atBlockStart) : lines[i];
59690
60169
  if (i != lines.length - 1)
@@ -60832,7 +61311,7 @@ img.ProseMirror-separator {
60832
61311
  // THIS FILE IS AUTOMATICALLY GENERATED DO NOT EDIT DIRECTLY
60833
61312
  // See update-tlds.js for encoding/decoding format
60834
61313
  // https://data.iana.org/TLD/tlds-alpha-by-domain.txt
60835
- const encodedTlds = 'aaa1rp3bb0ott3vie4c1le2ogado5udhabi7c0ademy5centure6ountant0s9o1tor4d0s1ult4e0g1ro2tna4f0l1rica5g0akhan5ency5i0g1rbus3force5tel5kdn3l0ibaba4pay4lfinanz6state5y2sace3tom5m0azon4ericanexpress7family11x2fam3ica3sterdam8nalytics7droid5quan4z2o0l2partments8p0le4q0uarelle8r0ab1mco4chi3my2pa2t0e3s0da2ia2sociates9t0hleta5torney7u0ction5di0ble3o3spost5thor3o0s4w0s2x0a2z0ure5ba0by2idu3namex4d1k2r0celona5laycard4s5efoot5gains6seball5ketball8uhaus5yern5b0c1t1va3cg1n2d1e0ats2uty4er2rlin4st0buy5t2f1g1h0arti5i0ble3d1ke2ng0o3o1z2j1lack0friday9ockbuster8g1omberg7ue3m0s1w2n0pparibas9o0ats3ehringer8fa2m1nd2o0k0ing5sch2tik2on4t1utique6x2r0adesco6idgestone9oadway5ker3ther5ussels7s1t1uild0ers6siness6y1zz3v1w1y1z0h3ca0b1fe2l0l1vinklein9m0era3p2non3petown5ital0one8r0avan4ds2e0er0s4s2sa1e1h1ino4t0ering5holic7ba1n1re3c1d1enter4o1rn3f0a1d2g1h0anel2nel4rity4se2t2eap3intai5ristmas6ome4urch5i0priani6rcle4sco3tadel4i0c2y3k1l0aims4eaning6ick2nic1que6othing5ud3ub0med6m1n1o0ach3des3ffee4llege4ogne5m0mbank4unity6pany2re3uter5sec4ndos3struction8ulting7tact3ractors9oking4l1p2rsica5untry4pon0s4rses6pa2r0edit0card4union9icket5own3s1uise0s6u0isinella9v1w1x1y0mru3ou3z2dad1nce3ta1e1ing3sun4y2clk3ds2e0al0er2s3gree4livery5l1oitte5ta3mocrat6ntal2ist5si0gn4v2hl2iamonds6et2gital5rect0ory7scount3ver5h2y2j1k1m1np2o0cs1tor4g1mains5t1wnload7rive4tv2ubai3pont4rban5vag2r2z2earth3t2c0o2deka3u0cation8e1g1mail3erck5nergy4gineer0ing9terprises10pson4quipment8r0icsson6ni3s0q1tate5t1u0rovision8s2vents5xchange6pert3osed4ress5traspace10fage2il1rwinds6th3mily4n0s2rm0ers5shion4t3edex3edback6rrari3ero6i0delity5o2lm2nal1nce1ial7re0stone6mdale6sh0ing5t0ness6j1k1lickr3ghts4r2orist4wers5y2m1o0o0d1tball6rd1ex2sale4um3undation8x2r0ee1senius7l1ogans4ntier7tr2ujitsu5n0d2rniture7tbol5yi3ga0l0lery3o1up4me0s3p1rden4y2b0iz3d0n2e0a1nt0ing5orge5f1g0ee3h1i0ft0s3ves2ing5l0ass3e1obal2o4m0ail3bh2o1x2n1odaddy5ld0point6f2odyear5g0le4p1t1v2p1q1r0ainger5phics5tis4een3ipe3ocery4up4s1t1u0cci3ge2ide2tars5ru3w1y2hair2mburg5ngout5us3bo2dfc0bank7ealth0care8lp1sinki6re1mes5iphop4samitsu7tachi5v2k0t2m1n1ockey4ldings5iday5medepot5goods5s0ense7nda3rse3spital5t0ing5t0els3mail5use3w2r1sbc3t1u0ghes5yatt3undai7ibm2cbc2e1u2d1e0ee3fm2kano4l1m0amat4db2mo0bilien9n0c1dustries8finiti5o2g1k1stitute6urance4e4t0ernational10uit4vestments10o1piranga7q1r0ish4s0maili5t0anbul7t0au2v3jaguar4va3cb2e0ep2tzt3welry6io2ll2m0p2nj2o0bs1urg4t1y2p0morgan6rs3uegos4niper7kaufen5ddi3e0rryhotels6properties14fh2g1h1i0a1ds2m1ndle4tchen5wi3m1n1oeln3matsu5sher5p0mg2n2r0d1ed3uokgroup8w1y0oto4z2la0caixa5mborghini8er3nd0rover6xess5salle5t0ino3robe5w0yer5b1c1ds2ease3clerc5frak4gal2o2xus4gbt3i0dl2fe0insurance9style7ghting6ke2lly3mited4o2ncoln4k2ve1ing5k1lc1p2oan0s3cker3us3l1ndon4tte1o3ve3pl0financial11r1s1t0d0a3u0ndbeck6xe1ury5v1y2ma0drid4if1son4keup4n0agement7go3p1rket0ing3s4riott5shalls7ttel5ba2c0kinsey7d1e0d0ia3et2lbourne7me1orial6n0u2rck0msd7g1h1iami3crosoft7l1ni1t2t0subishi9k1l0b1s2m0a2n1o0bi0le4da2e1i1m1nash3ey2ster5rmon3tgage6scow4to0rcycles9v0ie4p1q1r1s0d2t0n1r2u0seum3ic4v1w1x1y1z2na0b1goya4me2vy3ba2c1e0c1t0bank4flix4work5ustar5w0s2xt0direct7us4f0l2g0o2hk2i0co2ke1on3nja3ssan1y5l1o0kia3rton4w0ruz3tv4p1r0a1w2tt2u1yc2z2obi1server7ffice5kinawa6layan0group9lo3m0ega4ne1g1l0ine5oo2pen3racle3nge4g0anic5igins6saka4tsuka4t2vh3pa0ge2nasonic7ris2s1tners4s1y3y2ccw3e0t2f0izer5g1h0armacy6d1ilips5one2to0graphy6s4ysio5ics1tet2ures6d1n0g1k2oneer5zza4k1l0ace2y0station9umbing5s3m1n0c2ohl2ker3litie5rn2st3r0axi3ess3ime3o0d0uctions8f1gressive8mo2perties3y5tection8u0dential9s1t1ub2w0c2y2qa1pon3uebec3st5racing4dio4e0ad1lestate6tor2y4cipes5d0umbrella9hab3ise0n3t2liance6n0t0als5pair3ort3ublican8st0aurant8view0s5xroth6ich0ardli6oh3l1o1p2o0cks3deo3gers4om3s0vp3u0gby3hr2n2w0e2yukyu6sa0arland6fe0ty4kura4le1on3msclub4ung5ndvik0coromant12ofi4p1rl2s1ve2xo3b0i1s2c0b1haeffler7midt4olarships8ol3ule3warz5ience5ot3d1e0arch3t2cure1ity6ek2lect4ner3rvices6ven3w1x0y3fr2g1h0angrila6rp3ell3ia1ksha5oes2p0ping5uji3w3i0lk2na1gles5te3j1k0i0n2y0pe4l0ing4m0art3ile4n0cf3o0ccer3ial4ftbank4ware6hu2lar2utions7ng1y2y2pa0ce3ort2t3r0l2s1t0ada2ples4r1tebank4farm7c0group6ockholm6rage3e3ream4udio2y3yle4u0cks3pplies3y2ort5rf1gery5zuki5v1watch4iss4x1y0dney4stems6z2tab1ipei4lk2obao4rget4tamotors6r2too4x0i3c0i2d0k2eam2ch0nology8l1masek5nnis4va3f1g1h0d1eater2re6iaa2ckets5enda4ps2res2ol4j0maxx4x2k0maxx5l1m0all4n1o0day3kyo3ols3p1ray3shiba5tal3urs3wn2yota3s3r0ade1ing4ining5vel0ers0insurance16ust3v2t1ube2i1nes3shu4v0s2w1z2ua1bank3s2g1k1nicom3versity8o2ol2ps2s1y1z2va0cations7na1guard7c1e0gas3ntures6risign5mögensberater2ung14sicherung10t2g1i0ajes4deo3g1king4llas4n1p1rgin4sa1ion4va1o3laanderen9n1odka3lvo3te1ing3o2yage5u2wales2mart4ter4ng0gou5tch0es6eather0channel12bcam3er2site5d0ding5ibo2r3f1hoswho6ien2ki2lliamhill9n0dows4e1ners6me2oodside6rk0s2ld3w2s1tc1f3xbox3erox4ihuan4n2xx2yz3yachts4hoo3maxun5ndex5e1odobashi7ga2kohama6u0tube6t1un3za0ppos4ra3ero3ip2m1one3uerich6w2';
61314
+ const encodedTlds = 'aaa1rp3bb0ott3vie4c1le2ogado5udhabi7c0ademy5centure6ountant0s9o1tor4d0s1ult4e0g1ro2tna4f0l1rica5g0akhan5ency5i0g1rbus3force5tel5kdn3l0ibaba4pay4lfinanz6state5y2sace3tom5m0azon4ericanexpress7family11x2fam3ica3sterdam8nalytics7droid5quan4z2o0l2partments8p0le4q0uarelle8r0ab1mco4chi3my2pa2t0e3s0da2ia2sociates9t0hleta5torney7u0ction5di0ble3o3spost5thor3o0s4w0s2x0a2z0ure5ba0by2idu3namex4d1k2r0celona5laycard4s5efoot5gains6seball5ketball8uhaus5yern5b0c1t1va3cg1n2d1e0ats2uty4er2rlin4st0buy5t2f1g1h0arti5i0ble3d1ke2ng0o3o1z2j1lack0friday9ockbuster8g1omberg7ue3m0s1w2n0pparibas9o0ats3ehringer8fa2m1nd2o0k0ing5sch2tik2on4t1utique6x2r0adesco6idgestone9oadway5ker3ther5ussels7s1t1uild0ers6siness6y1zz3v1w1y1z0h3ca0b1fe2l0l1vinklein9m0era3p2non3petown5ital0one8r0avan4ds2e0er0s4s2sa1e1h1ino4t0ering5holic7ba1n1re3c1d1enter4o1rn3f0a1d2g1h0anel2nel4rity4se2t2eap3intai5ristmas6ome4urch5i0priani6rcle4sco3tadel4i0c2y3k1l0aims4eaning6ick2nic1que6othing5ud3ub0med6m1n1o0ach3des3ffee4llege4ogne5m0mbank4unity6pany2re3uter5sec4ndos3struction8ulting7tact3ractors9oking4l1p2rsica5untry4pon0s4rses6pa2r0edit0card4union9icket5own3s1uise0s6u0isinella9v1w1x1y0mru3ou3z2dad1nce3ta1e1ing3sun4y2clk3ds2e0al0er2s3gree4livery5l1oitte5ta3mocrat6ntal2ist5si0gn4v2hl2iamonds6et2gital5rect0ory7scount3ver5h2y2j1k1m1np2o0cs1tor4g1mains5t1wnload7rive4tv2ubai3pont4rban5vag2r2z2earth3t2c0o2deka3u0cation8e1g1mail3erck5nergy4gineer0ing9terprises10pson4quipment8r0icsson6ni3s0q1tate5t1u0rovision8s2vents5xchange6pert3osed4ress5traspace10fage2il1rwinds6th3mily4n0s2rm0ers5shion4t3edex3edback6rrari3ero6i0delity5o2lm2nal1nce1ial7re0stone6mdale6sh0ing5t0ness6j1k1lickr3ghts4r2orist4wers5y2m1o0o0d1tball6rd1ex2sale4um3undation8x2r0ee1senius7l1ogans4ntier7tr2ujitsu5n0d2rniture7tbol5yi3ga0l0lery3o1up4me0s3p1rden4y2b0iz3d0n2e0a1nt0ing5orge5f1g0ee3h1i0ft0s3ves2ing5l0ass3e1obal2o4m0ail3bh2o1x2n1odaddy5ld0point6f2odyear5g0le4p1t1v2p1q1r0ainger5phics5tis4een3ipe3ocery4up4s1t1u0cci3ge2ide2tars5ru3w1y2hair2mburg5ngout5us3bo2dfc0bank7ealth0care8lp1sinki6re1mes5iphop4samitsu7tachi5v2k0t2m1n1ockey4ldings5iday5medepot5goods5s0ense7nda3rse3spital5t0ing5t0els3mail5use3w2r1sbc3t1u0ghes5yatt3undai7ibm2cbc2e1u2d1e0ee3fm2kano4l1m0amat4db2mo0bilien9n0c1dustries8finiti5o2g1k1stitute6urance4e4t0ernational10uit4vestments10o1piranga7q1r0ish4s0maili5t0anbul7t0au2v3jaguar4va3cb2e0ep2tzt3welry6io2ll2m0p2nj2o0bs1urg4t1y2p0morgan6rs3uegos6kaufen5ddi3e0rryhotels6properties14fh2g1h1i0a1ds2m1ndle4tchen5wi3m1n1oeln3matsu5sher5p0mg2n2r0d1ed3uokgroup8w1y0oto4z2la0caixa5mborghini8er3nd0rover6xess5salle5t0ino3robe5w0yer5b1c1ds2ease3clerc5frak4gal2o2xus4gbt3i0dl2fe0insurance9style7ghting6ke2lly3mited4o2ncoln4k2ve1ing5k1lc1p2oan0s3cker3us3l1ndon4tte1o3ve3pl0financial11r1s1t0d0a3u0ndbeck6xe1ury5v1y2ma0drid4if1son4keup4n0agement7go3p1rket0ing3s4riott5shalls7ttel5ba2c0kinsey7d1e0d0ia3et2lbourne7me1orial6n0u2rck0msd7g1h1iami3crosoft7l1ni1t2t0subishi9k1l0b1s2m0a2n1o0bi0le4da2e1i1m1nash3ey2ster5rmon3tgage6scow4to0rcycles9v0ie4p1q1r1s0d2t0n1r2u0seum3ic4v1w1x1y1z2na0b1goya4me2vy3ba2c1e0c1t0bank4flix4work5ustar5w0s2xt0direct7us4f0l2g0o2hk2i0co2ke1on3nja3ssan1y5l1o0kia3rton4w0ruz3tv4p1r0a1w2tt2u1yc2z2obi1server7ffice5kinawa6layan0group9lo3m0ega4ne1g1l0ine5oo2pen3racle3nge4g0anic5igins6saka4tsuka4t2vh3pa0ge2nasonic7ris2s1tners4s1y3y2ccw3e0t2f0izer5g1h0armacy6d1ilips5one2to0graphy6s4ysio5ics1tet2ures6d1n0g1k2oneer5zza4k1l0ace2y0station9umbing5s3m1n0c2ohl2ker3litie5rn2st3r0axi3ess3ime3o0d0uctions8f1gressive8mo2perties3y5tection8u0dential9s1t1ub2w0c2y2qa1pon3uebec3st5racing4dio4e0ad1lestate6tor2y4cipes5d0umbrella9hab3ise0n3t2liance6n0t0als5pair3ort3ublican8st0aurant8view0s5xroth6ich0ardli6oh3l1o1p2o0cks3deo3gers4om3s0vp3u0gby3hr2n2w0e2yukyu6sa0arland6fe0ty4kura4le1on3msclub4ung5ndvik0coromant12ofi4p1rl2s1ve2xo3b0i1s2c0b1haeffler7midt4olarships8ol3ule3warz5ience5ot3d1e0arch3t2cure1ity6ek2lect4ner3rvices6ven3w1x0y3fr2g1h0angrila6rp3ell3ia1ksha5oes2p0ping5uji3w3i0lk2na1gles5te3j1k0i0n2y0pe4l0ing4m0art3ile4n0cf3o0ccer3ial4ftbank4ware6hu2lar2utions7ng1y2y2pa0ce3ort2t3r0l2s1t0ada2ples4r1tebank4farm7c0group6ockholm6rage3e3ream4udio2y3yle4u0cks3pplies3y2ort5rf1gery5zuki5v1watch4iss4x1y0dney4stems6z2tab1ipei4lk2obao4rget4tamotors6r2too4x0i3c0i2d0k2eam2ch0nology8l1masek5nnis4va3f1g1h0d1eater2re6iaa2ckets5enda4ps2res2ol4j0maxx4x2k0maxx5l1m0all4n1o0day3kyo3ols3p1ray3shiba5tal3urs3wn2yota3s3r0ade1ing4ining5vel0ers0insurance16ust3v2t1ube2i1nes3shu4v0s2w1z2ua1bank3s2g1k1nicom3versity8o2ol2ps2s1y1z2va0cations7na1guard7c1e0gas3ntures6risign5mögensberater2ung14sicherung10t2g1i0ajes4deo3g1king4llas4n1p1rgin4sa1ion4va1o3laanderen9n1odka3lvo3te1ing3o2yage5u2wales2mart4ter4ng0gou5tch0es6eather0channel12b0cam3er2site5d0ding5ibo2r3f1hoswho6ien2ki2lliamhill9n0dows4e1ners6me2oodside6rk0s2ld3w2s1tc1f3xbox3erox4ihuan4n2xx2yz3yachts4hoo3maxun5ndex5e1odobashi7ga2kohama6u0tube6t1un3za0ppos4ra3ero3ip2m1one3uerich6w2';
60836
61315
  // Internationalized domain names containing non-ASCII
60837
61316
  const encodedUtlds = 'ελ1υ2бг1ел3дети4ею2католик6ом3мкд2он1сква6онлайн5рг3рус2ф2сайт3рб3укр3қаз3հայ3ישראל5קום3ابوظبي5رامكو5لاردن4بحرين5جزائر5سعودية6عليان5مغرب5مارات5یران5بارت2زار4يتك3ھارت5تونس4سودان3رية5شبكة4عراق2ب2مان4فلسطين6قطر3كاثوليك6وم3مصر2ليسيا5وريتانيا7قع4همراه5پاکستان7ڀارت4कॉम3नेट3भारत0म्3ोत5संगठन5বাংলা5ভারত2ৰত4ਭਾਰਤ4ભારત4ଭାରତ4இந்தியா6லங்கை6சிங்கப்பூர்11భారత్5ಭಾರತ4ഭാരതം5ලංකා4คอม3ไทย3ລາວ3გე2みんな3アマゾン4クラウド4グーグル4コム2ストア3セール3ファッション6ポイント4世界2中信1国1國1文网3亚马逊3企业2佛山2信息2健康2八卦2公司1益2台湾1灣2商城1店1标2嘉里0大酒店5在线2大拿2天主教3娱乐2家電2广东2微博2慈善2我爱你3手机2招聘2政务1府2新加坡2闻2时尚2書籍2机构2淡马锡3游戏2澳門2点看2移动2组织机构4网址1店1站1络2联通2谷歌2购物2通販2集团2電訊盈科4飞利浦3食品2餐厅2香格里拉3港2닷넷1컴2삼성2한국2';
60838
61317
 
@@ -61317,8 +61796,20 @@ img.ProseMirror-separator {
61317
61796
 
61318
61797
  // Note that these two Unicode ones expand into a really big one with Babel
61319
61798
  const ASCII_LETTER = /[a-z]/;
61320
- const LETTER = /\p{L}/u; // Any Unicode character with letter data type
61321
- const EMOJI = /\p{Emoji}/u; // Any Unicode emoji character
61799
+ // `\p{}` property escapes need ICU, which some embedded JS runtimes ship
61800
+ // without (e.g. NativeScript's V8). The literal form throws a SyntaxError
61801
+ // at parse time — before any user code can catch it — so build them
61802
+ // dynamically and keep ASCII-range fallbacks for engines without Unicode
61803
+ // property escapes.
61804
+ let LETTER = /[a-z]/i; // Any Unicode character with letter data type
61805
+ let EMOJI = /[\u{1F000}-\u{1FAFF}\u{2600}-\u{27BF}]|\u{FE0F}/u; // Any Unicode emoji character
61806
+
61807
+ try {
61808
+ LETTER = new RegExp('\\p{L}', 'u');
61809
+ EMOJI = new RegExp('\\p{Emoji}', 'u');
61810
+ } catch {
61811
+ // use ASCII fallbacks
61812
+ }
61322
61813
  const DIGIT = /\d/;
61323
61814
  const SPACE = /\s/;
61324
61815
 
@@ -61782,6 +62273,7 @@ img.ProseMirror-separator {
61782
62273
  * className?: Opt<string>,
61783
62274
  * attributes?: OptObj<({ [attr: string]: any })>,
61784
62275
  * ignoreTags?: string[],
62276
+ * ignoreClasses?: string[],
61785
62277
  * render?: OptFn<((ir: IntermediateRepresentation) => any)>
61786
62278
  * }} Opts
61787
62279
  */
@@ -61803,6 +62295,7 @@ img.ProseMirror-separator {
61803
62295
  className: null,
61804
62296
  attributes: null,
61805
62297
  ignoreTags: [],
62298
+ ignoreClasses: [],
61806
62299
  render: null
61807
62300
  };
61808
62301
 
@@ -61834,6 +62327,7 @@ img.ProseMirror-separator {
61834
62327
  this.defaultRender = defaultRender;
61835
62328
  }
61836
62329
  this.ignoreTags = uppercaseIgnoredTags;
62330
+ this.ignoreClasses = o.ignoreClasses.slice();
61837
62331
  }
61838
62332
  Options.prototype = {
61839
62333
  o: defaults,
@@ -61841,6 +62335,28 @@ img.ProseMirror-separator {
61841
62335
  * @type string[]
61842
62336
  */
61843
62337
  ignoreTags: [],
62338
+ /**
62339
+ * @type string[]
62340
+ */
62341
+ ignoreClasses: [],
62342
+ /**
62343
+ * Returns whether a whitespace-separated class attribute contains an
62344
+ * ignored class name.
62345
+ * @param {unknown} classNames
62346
+ * @returns {boolean}
62347
+ */
62348
+ isIgnoredClass(classNames) {
62349
+ if (typeof classNames !== 'string' || this.ignoreClasses.length === 0) {
62350
+ return false;
62351
+ }
62352
+ const classes = classNames.split(/\s+/);
62353
+ for (let i = 0; i < classes.length; i++) {
62354
+ if (this.ignoreClasses.indexOf(classes[i]) >= 0) {
62355
+ return true;
62356
+ }
62357
+ }
62358
+ return false;
62359
+ },
61844
62360
  /**
61845
62361
  * @param {IntermediateRepresentation} ir
61846
62362
  * @returns {any}
@@ -62261,6 +62777,15 @@ img.ProseMirror-separator {
62261
62777
  tt(DomainDotTld, SLASH, Url$1);
62262
62778
  tt(DomainDotTldColonPort, SLASH, Url$1);
62263
62779
 
62780
+ // A query string or fragment may also follow the domain (or port) directly,
62781
+ // without a path slash (e.g. `example.com?q=1`, `example.com#frag`). Mirror
62782
+ // how the `Url` state treats these tokens: `?` is non-accepting (a trailing
62783
+ // `?` is trimmed), `#` is accepting.
62784
+ tt(DomainDotTld, QUERY, UrlNonaccept);
62785
+ tt(DomainDotTld, POUND, Url$1);
62786
+ tt(DomainDotTldColonPort, QUERY, UrlNonaccept);
62787
+ tt(DomainDotTldColonPort, POUND, Url$1);
62788
+
62264
62789
  // Note that domains that begin with schemes are treated slighly differently
62265
62790
  const SchemeColon = tt(Scheme, COLON); // e.g., 'mailto:'
62266
62791
  const SlashSchemeColon = tt(SlashScheme, COLON); // e.g., 'http:'
@@ -62353,6 +62878,18 @@ img.ProseMirror-separator {
62353
62878
  let cursor = 0;
62354
62879
  let multis = [];
62355
62880
  let textTokens = [];
62881
+
62882
+ // Memo of parser states that are known not to lead to any accepting state
62883
+ // when reached at a given cursor position. dead[i] is a Set of states that,
62884
+ // once reached right before tokens[i], can never reach another accepting
62885
+ // state. Because the parser is deterministic, a run that reaches one of
62886
+ // these (state, cursor) pairs can stop there with the same result as
62887
+ // continuing. Without this, inputs where every token can extend a
62888
+ // potential link that never completes (e.g., 'a.a.a.a.…') make each
62889
+ // failed attempt rescan to the end of the input, which is quadratic.
62890
+ // See https://github.com/Hypercontext/linkifyjs/issues/568
62891
+ /** @type {Array<Set<State<MultiToken>> | undefined>} */
62892
+ const dead = [];
62356
62893
  while (cursor < len) {
62357
62894
  let state = start;
62358
62895
  let secondState = null;
@@ -62360,6 +62897,10 @@ img.ProseMirror-separator {
62360
62897
  let multiLength = 0;
62361
62898
  let latestAccepting = null;
62362
62899
  let sinceAccepts = -1;
62900
+ // States reached since the latest accepting state (or since the start
62901
+ // of this attempt), in order. visited[k] is the state reached right
62902
+ // before tokens[cursor - visited.length + k + 1]
62903
+ let visited = [];
62363
62904
  while (cursor < len && !(secondState = state.go(tokens[cursor].t))) {
62364
62905
  // Starting tokens with nowhere to jump to.
62365
62906
  // Consider these to be just plain text
@@ -62369,16 +62910,31 @@ img.ProseMirror-separator {
62369
62910
  // Get the next state
62370
62911
  secondState = null;
62371
62912
  state = nextState;
62913
+ cursor++;
62914
+ multiLength++;
62372
62915
 
62373
62916
  // Keep track of the latest accepting state
62374
62917
  if (state.accepts()) {
62375
62918
  sinceAccepts = 0;
62376
62919
  latestAccepting = state;
62377
- } else if (sinceAccepts >= 0) {
62378
- sinceAccepts++;
62920
+ visited = [];
62921
+ } else {
62922
+ if (sinceAccepts >= 0) {
62923
+ sinceAccepts++;
62924
+ }
62925
+ visited.push(state);
62926
+ if (dead[cursor] && dead[cursor].has(state)) {
62927
+ // Already known that no accepting state is reachable from here
62928
+ break;
62929
+ }
62379
62930
  }
62380
- cursor++;
62381
- multiLength++;
62931
+ }
62932
+
62933
+ // None of the states visited since the latest accepting state lead to
62934
+ // another accepting state; remember them so later attempts that reach
62935
+ // the same state at the same position can stop early.
62936
+ for (let k = 0, pos = cursor - visited.length + 1; k < visited.length; k++, pos++) {
62937
+ (dead[pos] || (dead[pos] = new Set())).add(visited[k]);
62382
62938
  }
62383
62939
  if (sinceAccepts < 0) {
62384
62940
  // No accepting state was found, part of a regular text token add
@@ -63501,7 +64057,29 @@ img.ProseMirror-separator {
63501
64057
  }
63502
64058
  }
63503
64059
  //#endregion
64060
+ //#region src/item/ensureLeadingParagraph.ts
64061
+ function ensureLeadingParagraph(content) {
64062
+ if (!content[0] || content[0].type === "paragraph") return content;
64063
+ return [{
64064
+ type: "paragraph",
64065
+ content: []
64066
+ }, ...content];
64067
+ }
64068
+ //#endregion
64069
+ //#region src/item/hasEmptyLeadingParagraph.ts
64070
+ function hasEmptyLeadingParagraph(node) {
64071
+ var _node$content, _first$content;
64072
+ const first = (_node$content = node.content) === null || _node$content === void 0 ? void 0 : _node$content[0];
64073
+ return (first === null || first === void 0 ? void 0 : first.type) === "paragraph" && !((_first$content = first.content) === null || _first$content === void 0 ? void 0 : _first$content.length);
64074
+ }
64075
+ //#endregion
63504
64076
  //#region src/item/list-item.ts
64077
+ const EMPTY_ITEM_TEXT = "&nbsp;";
64078
+ const TOP_LEVEL = 1;
64079
+ const isNested = (ctx) => {
64080
+ var _ctx$level;
64081
+ return ((_ctx$level = ctx === null || ctx === void 0 ? void 0 : ctx.level) !== null && _ctx$level !== void 0 ? _ctx$level : TOP_LEVEL) > TOP_LEVEL;
64082
+ };
63505
64083
  function isSameLineOrderedListToken(token) {
63506
64084
  var _token$tokens, _token$tokens2;
63507
64085
  const nestedToken = (_token$tokens = token.tokens) === null || _token$tokens === void 0 ? void 0 : _token$tokens[0];
@@ -63554,20 +64132,28 @@ img.ProseMirror-separator {
63554
64132
  content: parseSameLineOrderedListText(token.text || "", helpers)
63555
64133
  }]
63556
64134
  };
63557
- if (token.tokens.some((t) => t.type === "paragraph")) content = parseBlockChildren(token.tokens);
63558
- else {
63559
- const firstToken = token.tokens[0];
63560
- if (firstToken && firstToken.type === "text" && firstToken.tokens && firstToken.tokens.length > 0) {
63561
- content = [{
64135
+ const [firstToken, ...remainingTokens] = token.tokens;
64136
+ if (firstToken.type === "heading") {
64137
+ var _firstToken$tokens;
64138
+ return {
64139
+ type: "listItem",
64140
+ content: [{
63562
64141
  type: "paragraph",
63563
- content: helpers.parseInline(firstToken.tokens)
63564
- }];
63565
- if (token.tokens.length > 1) {
63566
- const additionalContent = parseBlockChildren(token.tokens.slice(1));
63567
- content.push(...additionalContent);
63568
- }
63569
- } else content = parseBlockChildren(token.tokens);
64142
+ content: helpers.parseInline((_firstToken$tokens = firstToken.tokens) !== null && _firstToken$tokens !== void 0 ? _firstToken$tokens : [])
64143
+ }, ...remainingTokens.length > 0 ? parseBlockChildren(remainingTokens) : []]
64144
+ };
63570
64145
  }
64146
+ if (token.tokens.some((t) => t.type === "paragraph")) content = parseBlockChildren(token.tokens);
64147
+ else if (firstToken.type === "text" && firstToken.tokens && firstToken.tokens.length > 0) {
64148
+ content = [{
64149
+ type: "paragraph",
64150
+ content: helpers.parseInline(firstToken.tokens)
64151
+ }];
64152
+ if (token.tokens.length > 1) {
64153
+ const additionalContent = parseBlockChildren(token.tokens.slice(1));
64154
+ content.push(...additionalContent);
64155
+ }
64156
+ } else content = parseBlockChildren(token.tokens);
63571
64157
  }
63572
64158
  if (content.length === 0) content = [{
63573
64159
  type: "paragraph",
@@ -63575,11 +64161,11 @@ img.ProseMirror-separator {
63575
64161
  }];
63576
64162
  return {
63577
64163
  type: "listItem",
63578
- content
64164
+ content: ensureLeadingParagraph(content)
63579
64165
  };
63580
64166
  },
63581
64167
  renderMarkdown: (node, h, ctx) => {
63582
- return renderNestedMarkdownContent(node, h, (context) => {
64168
+ const getPrefix = (context) => {
63583
64169
  if (context.parentType === "bulletList") return "- ";
63584
64170
  if (context.parentType === "orderedList") {
63585
64171
  var _context$meta, _context$meta2;
@@ -63587,7 +64173,11 @@ img.ProseMirror-separator {
63587
64173
  return getListMarker((_context$meta2 = context.meta) === null || _context$meta2 === void 0 || (_context$meta2 = _context$meta2.parentAttrs) === null || _context$meta2 === void 0 ? void 0 : _context$meta2.type, start - 1 + (context.index || 0), ". ");
63588
64174
  }
63589
64175
  return "- ";
63590
- }, ctx, { alignNestedToPrefix: (ctx === null || ctx === void 0 ? void 0 : ctx.parentType) === "orderedList" });
64176
+ };
64177
+ const output = renderNestedMarkdownContent(node, h, getPrefix, ctx, { alignNestedToPrefix: (ctx === null || ctx === void 0 ? void 0 : ctx.parentType) === "orderedList" });
64178
+ if (!hasEmptyLeadingParagraph(node) || !isNested(ctx)) return output;
64179
+ const prefix = getPrefix(ctx);
64180
+ return `${prefix}${EMPTY_ITEM_TEXT}${output.slice(prefix.length)}`;
63591
64181
  },
63592
64182
  addExtensions() {
63593
64183
  return [createBranchingListDeleteKeymap(this.name, [this.options.bulletListTypeName, this.options.orderedListTypeName])];
@@ -63658,10 +64248,15 @@ img.ProseMirror-separator {
63658
64248
  const lastItem = listDescendants.at(-1);
63659
64249
  if (!lastItem) return false;
63660
64250
  const $lastItemPos = editor.state.doc.resolve($listPos.start() + lastItem.pos + 1);
63661
- return editor.chain().cut({
63662
- from: $anchor.start() - 1,
63663
- to: $anchor.end() + 1
63664
- }, $lastItemPos.end()).joinForward().run();
64251
+ return editor.chain().command(({ tr }) => {
64252
+ const target = $lastItemPos.end();
64253
+ tr.delete($anchor.before(), $anchor.after()).insert(target, $anchor.parent);
64254
+ tr.setSelection(TextSelection.create(tr.doc, target + 1));
64255
+ return true;
64256
+ }).command(({ state, dispatch }) => {
64257
+ joinTextblockBackward(state, dispatch);
64258
+ return true;
64259
+ }).run();
63665
64260
  }
63666
64261
  if (!isNodeActive(editor.state, name)) return false;
63667
64262
  if (!isAtStartOfNode(editor.state)) return false;
@@ -63693,11 +64288,9 @@ img.ProseMirror-separator {
63693
64288
  const handleDelete = (editor, name) => {
63694
64289
  if (!isNodeActive(editor.state, name)) return false;
63695
64290
  if (!isAtEndOfNode(editor.state, name)) return false;
63696
- const { selection } = editor.state;
63697
- const { $from, $to } = selection;
63698
- if (!selection.empty && $from.sameParent($to)) return false;
64291
+ if (!editor.state.selection.empty) return false;
63699
64292
  if (nextListIsDeeper(name, editor.state)) return editor.chain().focus(editor.state.selection.from + 4).lift(name).joinBackward().run();
63700
- if (nextListIsHigher(name, editor.state)) return editor.chain().joinForward().joinBackward().run();
64293
+ if (nextListIsHigher(name, editor.state)) return editor.commands.command(({ state, dispatch }) => joinTextblockForward(state, dispatch));
63701
64294
  return editor.commands.joinItemForward();
63702
64295
  };
63703
64296
  //#endregion
@@ -64349,7 +64942,7 @@ img.ProseMirror-separator {
64349
64942
  renderMarkdown: (node, h) => {
64350
64943
  var _node$attrs;
64351
64944
  const prefix = `- [${((_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.checked) ? "x" : " "}] `;
64352
- return renderNestedMarkdownContent(node, h, prefix);
64945
+ return renderNestedMarkdownContent(node, h, prefix, void 0, { indentMainContent: true });
64353
64946
  },
64354
64947
  addExtensions() {
64355
64948
  if (!this.options.nested) return [];
@@ -66052,7 +66645,7 @@ img.ProseMirror-separator {
66052
66645
  const match = Array.from(text.matchAll(regexp)).pop();
66053
66646
  if (!match || match.input === void 0 || match.index === void 0) return null;
66054
66647
  const matchPrefix = match.input.slice(Math.max(0, match.index - 1), match.index);
66055
- const matchPrefixIsAllowed = new RegExp(`^[${allowedPrefixes === null || allowedPrefixes === void 0 ? void 0 : allowedPrefixes.join("")}\0]?$`).test(matchPrefix);
66648
+ const matchPrefixIsAllowed = new RegExp(`^[${allowedPrefixes === null || allowedPrefixes === void 0 ? void 0 : allowedPrefixes.map(escapeForRegEx).join("")}\0]?$`).test(matchPrefix);
66056
66649
  if (allowedPrefixes !== null && !matchPrefixIsAllowed) return null;
66057
66650
  const from = textFrom + match.index;
66058
66651
  let to = from + match[0].length;
@@ -69584,8 +70177,8 @@ img.ProseMirror-separator {
69584
70177
  </template>
69585
70178
  `;
69586
70179
 
69587
- // Based on: https://github.com/microsoft/fast/blob/%40microsoft/fast-foundation_v2.49.5/packages/web-components/fast-foundation/src/select/select.form-associated.ts
69588
70180
  /* eslint-disable max-classes-per-file */
70181
+ // Based on: https://github.com/microsoft/fast/blob/%40microsoft/fast-foundation_v2.49.5/packages/web-components/fast-foundation/src/select/select.form-associated.ts
69589
70182
  // eslint-disable-next-line jsdoc/require-jsdoc
69590
70183
  let Select$1 = class Select extends ListboxElement {
69591
70184
  };
@@ -77047,6 +77640,84 @@ focus outline in that case.
77047
77640
  );
77048
77641
  };
77049
77642
 
77643
+ function classifyScrollEvent({
77644
+ offset,
77645
+ isScrolling,
77646
+ elementMax,
77647
+ holdOffset,
77648
+ scrollOffset,
77649
+ pendingWrite,
77650
+ clampedMaxAtWrite
77651
+ }) {
77652
+ var _a;
77653
+ if (isScrolling && pendingWrite === null && offset === scrollOffset) {
77654
+ return "spurious";
77655
+ }
77656
+ if (pendingWrite !== null && Math.abs(offset - pendingWrite.target) < 1.5) {
77657
+ return "readBack";
77658
+ }
77659
+ if (pendingWrite !== null && !pendingWrite.smooth && elementMax !== null && pendingWrite.target > elementMax + holdOffset + 0.5 && Math.abs(offset - (elementMax + holdOffset)) < 1.5) {
77660
+ return "clampedReadBack";
77661
+ }
77662
+ if (pendingWrite !== null && !pendingWrite.smooth && ((_a = pendingWrite.lowMaxes) == null ? void 0 : _a.some((max) => Math.abs(offset - max) < 1.5))) {
77663
+ return "clampedReadBack";
77664
+ }
77665
+ if (clampedMaxAtWrite !== null && Math.abs(offset - clampedMaxAtWrite) < 1.5) {
77666
+ return "clampedEcho";
77667
+ }
77668
+ return "external";
77669
+ }
77670
+ const isAnimating = (phase) => phase === "smooth" || phase === "smoothFinishing";
77671
+ function externalRetiresCommand({
77672
+ kind,
77673
+ offset,
77674
+ command,
77675
+ target
77676
+ }) {
77677
+ return kind !== "spurious" && kind !== "readBack" && // Our own write, clamped (`clampedReadBack`, #1310): the command is not
77678
+ // retired by it, and reconcile retargets below the new max.
77679
+ kind !== "clampedReadBack" && (command == null ? void 0 : command.index) != null && // Nothing has been written for a command waiting for the tail; these
77680
+ // are the fling's events.
77681
+ command.phase !== "queued" && // A non-smooth write lands at once, so any other scroll event is the
77682
+ // user's, even before reconcile saw the target reached (the target may
77683
+ // keep moving, or iOS ignored the write under a finger). A write the
77684
+ // browser clamped because the sizer hasn't grown yet reads back at the
77685
+ // max, which is also where the fresh target clamps, so the check below
77686
+ // keeps it reconciling (#1294). While a smooth scroll's animation may
77687
+ // still report, its events look like a user's, so it yields only once it
77688
+ // has landed.
77689
+ !isAnimating(command.phase) && !approxEqual(offset, command.lastTargetOffset) && !approxEqual(offset, target()) && // A compensation write's clamped echo (#1258) keeps the command. The
77690
+ // order is deliberate, not tidiness: this clause stays after `target()`
77691
+ // (and `clampedReadBack` before it) because `target()` can rebuild the
77692
+ // measurements, so it must run for exactly the events it always did.
77693
+ kind !== "clampedEcho";
77694
+ }
77695
+ const FLING_WINDOW_MS = 40;
77696
+ function flingSpedUp(samples) {
77697
+ const last = samples[samples.length - 1];
77698
+ if (last === void 0) return false;
77699
+ let j = samples.length - 2;
77700
+ while (j >= 0 && last.t - samples[j].t < FLING_WINDOW_MS) j--;
77701
+ if (j < 0) return false;
77702
+ const mid = samples[j];
77703
+ let k = j - 1;
77704
+ while (k >= 0 && mid.t - samples[k].t < FLING_WINDOW_MS) k--;
77705
+ if (k < 0) return false;
77706
+ const first = samples[k];
77707
+ const recent = (last.offset - mid.offset) / (last.t - mid.t);
77708
+ const before = (mid.offset - first.offset) / (mid.t - first.t);
77709
+ return recent * before >= 0 && Math.abs(recent) >= 2 * Math.abs(before) && Math.abs(recent) - Math.abs(before) >= 0.8;
77710
+ }
77711
+ function flingCaught(samples) {
77712
+ const last = samples[samples.length - 1];
77713
+ if (last === void 0) return false;
77714
+ let j = samples.length - 2;
77715
+ while (j >= 0 && last.t - samples[j].t < FLING_WINDOW_MS) j--;
77716
+ if (j < 0) return false;
77717
+ const from = samples[j];
77718
+ return Math.abs(last.offset - from.offset) / (last.t - from.t) >= 0.05;
77719
+ }
77720
+
77050
77721
  let _isIOSResult;
77051
77722
  const isIOSWebKit = () => {
77052
77723
  if (_isIOSResult !== void 0) return _isIOSResult;
@@ -77055,14 +77726,143 @@ focus outline in that case.
77055
77726
  const mtp = navigator.maxTouchPoints;
77056
77727
  return _isIOSResult = navigator.platform === "MacIntel" && mtp !== void 0 && mtp > 0;
77057
77728
  };
77729
+ let _iosMomentumOverridesWritesResult;
77730
+ const iosMomentumOverridesWrites = () => {
77731
+ if (_iosMomentumOverridesWritesResult !== void 0) {
77732
+ return _iosMomentumOverridesWritesResult;
77733
+ }
77734
+ return _iosMomentumOverridesWritesResult = isIOSWebKit() && typeof CSS !== "undefined" && typeof CSS.supports === "function" && CSS.supports("overflow-anchor: auto");
77735
+ };
77736
+ const momentumOverridesWrites = () => !isIOSWebKit() || iosMomentumOverridesWrites();
77737
+ const touchListenerOptions = {
77738
+ capture: true,
77739
+ passive: true
77740
+ };
77741
+ class IosGesture {
77742
+ constructor(host) {
77743
+ this.host = host;
77744
+ this._touch = null;
77745
+ this.inMotion = () => this._touch !== null && this._touch.phase !== "lateFling";
77746
+ this.dragging = () => {
77747
+ var _a;
77748
+ return ((_a = this._touch) == null ? void 0 : _a.phase) === "down" && this._touch.moved;
77749
+ };
77750
+ this.tail = () => {
77751
+ var _a;
77752
+ return ((_a = this._touch) == null ? void 0 : _a.phase) === "tail" ? this._touch.moved ? "fling" : "tap" : null;
77753
+ };
77754
+ this.onScroll = ({
77755
+ isScrolling,
77756
+ ownReadBack,
77757
+ moved,
77758
+ external
77759
+ }) => {
77760
+ var _a, _b, _c;
77761
+ if (isScrolling && ((_a = this._touch) == null ? void 0 : _a.phase) === "tail") {
77762
+ this._openTail(this._touch.moved || !ownReadBack, false);
77763
+ } else if (((_b = this._touch) == null ? void 0 : _b.phase) === "lateFling") {
77764
+ if (this.host.now() > this._touch.until) {
77765
+ this._touch = null;
77766
+ } else if (external && isScrolling && moved) {
77767
+ this._openTail(true, false);
77768
+ }
77769
+ }
77770
+ if (!ownReadBack && isScrolling && moved && ((_c = this._touch) == null ? void 0 : _c.phase) === "down") {
77771
+ this._touch.moved = true;
77772
+ return true;
77773
+ }
77774
+ return false;
77775
+ };
77776
+ this.touchStart = () => {
77777
+ this.end();
77778
+ this._touch = { phase: "down", moved: false };
77779
+ };
77780
+ this.touchEnd = () => {
77781
+ var _a;
77782
+ const moved = ((_a = this._touch) == null ? void 0 : _a.phase) === "down" && this._touch.moved;
77783
+ this.end();
77784
+ this._openTail(moved, moved);
77785
+ };
77786
+ this.end = () => {
77787
+ var _a;
77788
+ const win = this.host.getWindow();
77789
+ if (((_a = this._touch) == null ? void 0 : _a.phase) === "tail" && win != null) {
77790
+ win.clearTimeout(this._touch.timerId);
77791
+ }
77792
+ this._touch = null;
77793
+ };
77794
+ this.listen = (target) => {
77795
+ const onTouchStart = () => this.touchStart();
77796
+ const onTouchEnd = () => this.touchEnd();
77797
+ target.addEventListener("touchstart", onTouchStart, touchListenerOptions);
77798
+ target.addEventListener("touchend", onTouchEnd, touchListenerOptions);
77799
+ target.addEventListener("touchcancel", onTouchEnd, touchListenerOptions);
77800
+ return () => {
77801
+ target.removeEventListener(
77802
+ "touchstart",
77803
+ onTouchStart,
77804
+ touchListenerOptions
77805
+ );
77806
+ target.removeEventListener("touchend", onTouchEnd, touchListenerOptions);
77807
+ target.removeEventListener(
77808
+ "touchcancel",
77809
+ onTouchEnd,
77810
+ touchListenerOptions
77811
+ );
77812
+ this.end();
77813
+ };
77814
+ };
77815
+ this._openTail = (moved, awaitingFling) => {
77816
+ const win = this.host.getWindow();
77817
+ if (win == null) return;
77818
+ this.end();
77819
+ const tail = {
77820
+ phase: "tail",
77821
+ moved,
77822
+ awaitingFling,
77823
+ // Only fires while this tail is current: `end` clears it otherwise.
77824
+ timerId: win.setTimeout(() => {
77825
+ if (this.host.tailStillMoving()) {
77826
+ this._openTail(tail.moved, tail.awaitingFling);
77827
+ return;
77828
+ }
77829
+ this._touch = tail.awaitingFling ? { phase: "lateFling", until: this.host.now() + 1e3 } : null;
77830
+ this.host.onTailClosed();
77831
+ }, 150)
77832
+ };
77833
+ this._touch = tail;
77834
+ };
77835
+ }
77836
+ get touch() {
77837
+ return this._touch;
77838
+ }
77839
+ }
77840
+
77058
77841
  const getRect = (element) => {
77059
- const { offsetWidth, offsetHeight } = element;
77060
- return { width: offsetWidth, height: offsetHeight };
77842
+ const { clientWidth, clientHeight } = element;
77843
+ return { width: clientWidth, height: clientHeight };
77844
+ };
77845
+ const createFrameQueue = (targetWindow) => {
77846
+ const ids = /* @__PURE__ */ new Set();
77847
+ return {
77848
+ schedule: (fn) => {
77849
+ const id = targetWindow.requestAnimationFrame(() => {
77850
+ ids.delete(id);
77851
+ fn();
77852
+ });
77853
+ ids.add(id);
77854
+ },
77855
+ cancel: () => {
77856
+ ids.forEach((id) => targetWindow.cancelAnimationFrame(id));
77857
+ ids.clear();
77858
+ }
77859
+ };
77061
77860
  };
77062
77861
  const defaultKeyExtractor = (index) => index;
77063
77862
  const defaultRangeExtractor = (range) => {
77064
- const start = Math.max(range.startIndex - range.overscan, 0);
77065
- const end = Math.min(range.endIndex + range.overscan, range.count - 1);
77863
+ const overscan = range.overscan * Math.max(range.lanes ?? 1, 1);
77864
+ const start = Math.max(range.startIndex - overscan, 0);
77865
+ const end = Math.min(range.endIndex + overscan, range.count - 1);
77066
77866
  const len = end - start + 1;
77067
77867
  const arr = new Array(len);
77068
77868
  for (let i = 0; i < len; i++) {
@@ -77088,23 +77888,17 @@ focus outline in that case.
77088
77888
  return () => {
77089
77889
  };
77090
77890
  }
77091
- const observer = new targetWindow.ResizeObserver((entries) => {
77891
+ const frames = createFrameQueue(targetWindow);
77892
+ const observer = new targetWindow.ResizeObserver(() => {
77092
77893
  const run = () => {
77093
- const entry = entries[0];
77094
- if (entry == null ? void 0 : entry.borderBoxSize) {
77095
- const box = entry.borderBoxSize[0];
77096
- if (box) {
77097
- handler({ width: box.inlineSize, height: box.blockSize });
77098
- return;
77099
- }
77100
- }
77101
77894
  handler(getRect(element));
77102
77895
  };
77103
- instance.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();
77896
+ instance.options.useAnimationFrameWithResizeObserver ? frames.schedule(run) : run();
77104
77897
  });
77105
- observer.observe(element, { box: "border-box" });
77898
+ observer.observe(element, { box: "content-box" });
77106
77899
  return () => {
77107
77900
  observer.unobserve(element);
77901
+ frames.cancel();
77108
77902
  };
77109
77903
  };
77110
77904
  const addEventListenerOptions = {
@@ -77186,6 +77980,8 @@ focus outline in that case.
77186
77980
  });
77187
77981
  };
77188
77982
  const elementScroll = scrollWithAdjustments;
77983
+ const initialScrollPhase = (behavior, atTarget) => behavior === "smooth" ? atTarget ? "smoothLanded" : "smooth" : "instant";
77984
+ const isSmoothScroll = (state) => (state == null ? void 0 : state.phase) === "smooth" || (state == null ? void 0 : state.phase) === "smoothLanded";
77189
77985
  function isAppendWithTrim(prevCount, nextCount, getPreviousKey, getNextKey) {
77190
77986
  if (nextCount === 0) return false;
77191
77987
  const firstKey = getNextKey(0);
@@ -77227,67 +78023,144 @@ focus outline in that case.
77227
78023
  this.scrollRect = null;
77228
78024
  this.scrollOffset = null;
77229
78025
  this.scrollDirection = null;
77230
- this.scrollAdjustments = 0;
77231
- this._iosDeferredAdjustment = 0;
77232
- this._iosTouching = false;
77233
- this._iosJustTouchEnded = false;
77234
- this._iosTouchEndTimerId = null;
77235
- this._intendedScrollOffset = null;
78026
+ this._holdOffset = 0;
78027
+ this._reportedOverscroll = false;
78028
+ this._iosGesture = new IosGesture({
78029
+ getWindow: () => this.targetWindow,
78030
+ now: () => this.now(),
78031
+ // The end of a fling can move less than a pixel per scroll event, so
78032
+ // events can stop for 150ms while the fling is still running (seen on
78033
+ // an iPhone, 27.0.1). A command waiting for it would then be written
78034
+ // into the fling and overridden. The element having moved since the
78035
+ // last event means it has not ended: wait again. Not while our own
78036
+ // write has yet to report: that moved it.
78037
+ tailStillMoving: () => {
78038
+ const state = this.scrollState;
78039
+ if ((state == null ? void 0 : state.phase) !== "queued" || this.pendingWrite !== null) {
78040
+ return false;
78041
+ }
78042
+ const now = this._readElementOffset();
78043
+ if (now === null || this._lastElementOffset === null || Math.abs(now - this._lastElementOffset) < 1) {
78044
+ return false;
78045
+ }
78046
+ this._lastElementOffset = now;
78047
+ state.samples = [...state.samples ?? [], { t: this.now(), offset: now }];
78048
+ return true;
78049
+ },
78050
+ onTailClosed: () => {
78051
+ const state = this.scrollState;
78052
+ if ((state == null ? void 0 : state.phase) === "queued" && flingCaught(state.samples ?? [])) {
78053
+ this.scrollState = null;
78054
+ }
78055
+ this._flushHoldIfReady(true);
78056
+ this._writeAwaitingCommand();
78057
+ this._retryClampedAdjustment();
78058
+ }
78059
+ });
78060
+ this._lastElementOffset = null;
78061
+ this.pendingWrite = null;
77236
78062
  this._clampedAdjustment = null;
77237
78063
  this.elementsCache = /* @__PURE__ */ new Map();
78064
+ this._resizeBatch = null;
77238
78065
  this.now = () => {
77239
78066
  var _a, _b, _c;
77240
78067
  return ((_c = (_b = (_a = this.targetWindow) == null ? void 0 : _a.performance) == null ? void 0 : _b.now) == null ? void 0 : _c.call(_b)) ?? Date.now();
77241
78068
  };
77242
78069
  this.observer = /* @__PURE__ */ (() => {
77243
78070
  let _ro = null;
78071
+ let _frames = null;
78072
+ let delivering = false;
78073
+ let observeQueued = false;
78074
+ const pendingObservations = /* @__PURE__ */ new Set();
77244
78075
  const get = () => {
77245
78076
  if (_ro) {
77246
78077
  return _ro;
77247
78078
  }
77248
- if (!this.targetWindow || !this.targetWindow.ResizeObserver) {
78079
+ const targetWindow = this.targetWindow;
78080
+ if (!targetWindow || !targetWindow.ResizeObserver) {
77249
78081
  return null;
77250
78082
  }
77251
- return _ro = new this.targetWindow.ResizeObserver((entries) => {
77252
- entries.forEach((entry) => {
77253
- const run = () => {
77254
- const node = entry.target;
77255
- const index = this.indexFromElement(node);
77256
- if (!node.isConnected) {
77257
- this.observer.unobserve(node);
77258
- for (const [cacheKey, cachedNode] of this.elementsCache) {
77259
- if (cachedNode === node) {
77260
- this.elementsCache.delete(cacheKey);
77261
- break;
77262
- }
77263
- }
77264
- return;
77265
- }
77266
- if (!this.isIndexInRange(index)) return;
77267
- if (this.shouldMeasureDuringScroll(index)) {
77268
- this.resizeItem(
77269
- index,
77270
- this.options.measureElement(node, entry, this)
77271
- );
78083
+ const frames = _frames = createFrameQueue(targetWindow);
78084
+ return _ro = new targetWindow.ResizeObserver((entries) => {
78085
+ const run = () => {
78086
+ const batch = { sync: false };
78087
+ this._resizeBatch = batch;
78088
+ try {
78089
+ entries.forEach(measureEntry);
78090
+ } finally {
78091
+ this._resizeBatch = null;
78092
+ if (batch.notify) {
78093
+ this.notify(batch.sync);
78094
+ this._noteClampMax();
78095
+ this._flushHoldIfReady(true);
78096
+ this._retryClampedAdjustment();
78097
+ this.measureElement(null);
77272
78098
  }
77273
- };
77274
- this.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();
77275
- });
78099
+ }
78100
+ };
78101
+ if (this.options.useAnimationFrameWithResizeObserver) {
78102
+ frames.schedule(run);
78103
+ } else {
78104
+ delivering = true;
78105
+ try {
78106
+ run();
78107
+ } finally {
78108
+ delivering = false;
78109
+ }
78110
+ }
77276
78111
  });
77277
78112
  };
78113
+ const measureEntry = (entry) => {
78114
+ const node = entry.target;
78115
+ const index = this.indexFromElement(node);
78116
+ if (!node.isConnected) {
78117
+ this.observer.unobserve(node);
78118
+ for (const [cacheKey, cachedNode] of this.elementsCache) {
78119
+ if (cachedNode === node) {
78120
+ this.elementsCache.delete(cacheKey);
78121
+ break;
78122
+ }
78123
+ }
78124
+ return;
78125
+ }
78126
+ if (!this.isIndexInRange(index)) return;
78127
+ if (this.shouldMeasureDuringScroll(index)) {
78128
+ this.resizeItem(index, this.options.measureElement(node, entry, this));
78129
+ }
78130
+ };
77278
78131
  return {
77279
78132
  disconnect: () => {
77280
78133
  var _a;
77281
78134
  (_a = get()) == null ? void 0 : _a.disconnect();
78135
+ _frames == null ? void 0 : _frames.cancel();
78136
+ pendingObservations.clear();
78137
+ observeQueued = false;
77282
78138
  _ro = null;
78139
+ _frames = null;
77283
78140
  },
77284
78141
  observe: (target) => {
77285
- var _a;
77286
- return (_a = get()) == null ? void 0 : _a.observe(target, { box: "border-box" });
78142
+ const observer = get();
78143
+ if (!observer) return;
78144
+ if (!delivering) {
78145
+ observer.observe(target, { box: "border-box" });
78146
+ return;
78147
+ }
78148
+ pendingObservations.add(target);
78149
+ if (!observeQueued) {
78150
+ observeQueued = true;
78151
+ _frames == null ? void 0 : _frames.schedule(() => {
78152
+ observeQueued = false;
78153
+ pendingObservations.forEach((node) => {
78154
+ if (node.isConnected) _ro == null ? void 0 : _ro.observe(node, { box: "border-box" });
78155
+ });
78156
+ pendingObservations.clear();
78157
+ });
78158
+ }
77287
78159
  },
77288
78160
  unobserve: (target) => {
77289
78161
  var _a;
77290
- return (_a = get()) == null ? void 0 : _a.unobserve(target);
78162
+ pendingObservations.delete(target);
78163
+ (_a = get()) == null ? void 0 : _a.unobserve(target);
77291
78164
  }
77292
78165
  };
77293
78166
  })();
@@ -77367,9 +78240,8 @@ focus outline in that case.
77367
78240
  this.pendingMin = 0;
77368
78241
  this.itemSizeCacheVersion++;
77369
78242
  }
77370
- let anchorResolved = false;
77371
- let anchorDelta = 0;
77372
- if (anchor && this.scrollOffset !== null) {
78243
+ let anchorDelta = null;
78244
+ if (anchor && this.scrollOffset !== null && !this._awaitingCommandReadBack()) {
77373
78245
  const [anchorKey, anchorOffset] = anchor;
77374
78246
  const newMeasurements = this.getMeasurements();
77375
78247
  const { count, getItemKey } = this.options;
@@ -77384,18 +78256,19 @@ focus outline in that case.
77384
78256
  if (!followOnAppend && newOffset !== this.scrollOffset) {
77385
78257
  anchorDelta = newOffset - this.scrollOffset;
77386
78258
  this.scrollOffset = newOffset;
77387
- anchorResolved = true;
77388
78259
  }
77389
78260
  }
77390
78261
  }
77391
78262
  }
77392
- if (anchorResolved || followOnAppend) {
77393
- this.pendingScrollAnchor = [
77394
- anchorResolved ? anchor[0] : null,
77395
- anchorResolved ? anchor[1] : 0,
77396
- followOnAppend,
77397
- anchorDelta
77398
- ];
78263
+ if (followOnAppend) {
78264
+ this.pendingScrollAnchor = { kind: "follow", behavior: followOnAppend };
78265
+ } else if (anchorDelta !== null) {
78266
+ if (this._canWriteScroll()) {
78267
+ this.pendingScrollAnchor = { kind: "anchor", delta: anchorDelta };
78268
+ } else {
78269
+ this._holdOffset += anchorDelta;
78270
+ this._followOffsetTarget(anchorDelta);
78271
+ }
77399
78272
  }
77400
78273
  };
77401
78274
  this.notify = (sync) => {
@@ -77425,6 +78298,7 @@ focus outline in that case.
77425
78298
  }
77426
78299
  );
77427
78300
  this.cleanup = () => {
78301
+ var _a;
77428
78302
  this.unsubs.filter(Boolean).forEach((d) => d());
77429
78303
  this.unsubs = [];
77430
78304
  this.observer.disconnect();
@@ -77433,12 +78307,14 @@ focus outline in that case.
77433
78307
  this.rafId = null;
77434
78308
  }
77435
78309
  this.scrollState = null;
78310
+ (_a = this._momentumStop) == null ? void 0 : _a.restore();
78311
+ this._momentumStop = null;
77436
78312
  this.isScrolling = false;
77437
78313
  this.scrollDirection = null;
77438
- this._iosDeferredAdjustment = 0;
77439
- this._iosTouching = false;
77440
- this._iosJustTouchEnded = false;
78314
+ this._holdOffset = 0;
78315
+ this._reportedOverscroll = false;
77441
78316
  this._clampedAdjustment = null;
78317
+ this.pendingWrite = null;
77442
78318
  this.scrollElement = null;
77443
78319
  this.targetWindow = null;
77444
78320
  };
@@ -77448,7 +78324,7 @@ focus outline in that case.
77448
78324
  };
77449
78325
  };
77450
78326
  this._willUpdate = () => {
77451
- var _a, _b;
78327
+ var _a;
77452
78328
  const scrollElement = this.options.enabled ? this.options.getScrollElement() : null;
77453
78329
  if (this.scrollElement !== scrollElement) {
77454
78330
  this.cleanup();
@@ -77473,22 +78349,71 @@ focus outline in that case.
77473
78349
  );
77474
78350
  this.unsubs.push(
77475
78351
  this.options.observeElementOffset(this, (offset, isScrolling) => {
77476
- if (isScrolling && this._intendedScrollOffset === null && offset === this.scrollOffset) {
77477
- return;
77478
- }
77479
- if (this._intendedScrollOffset !== null && Math.abs(offset - this._intendedScrollOffset) < 1.5) {
77480
- offset = this._intendedScrollOffset;
78352
+ var _a2, _b, _c, _d;
78353
+ const elementMax = isScrolling ? this._elementMaxScrollOffset() : null;
78354
+ const wasOverscrolled = this._reportedOverscroll;
78355
+ this._reportedOverscroll = offset < 0 || elementMax !== null && offset > elementMax + 1;
78356
+ const elementOffset = offset;
78357
+ this._lastElementOffset = elementOffset;
78358
+ offset = this._toLayoutOffset(offset);
78359
+ const kind = this._classifyScrollEvent(
78360
+ offset,
78361
+ isScrolling,
78362
+ elementMax
78363
+ );
78364
+ if (kind === "spurious") return;
78365
+ if (kind === "readBack") {
78366
+ offset = this.pendingWrite.target;
78367
+ } else if (kind === "clampedReadBack" && ((_a2 = this.scrollState) == null ? void 0 : _a2.index) != null && // Not `elementMax`: an adapter can report the read-back at rest.
78368
+ offset < this.getMaxScrollOffset() - 1.5) {
78369
+ this.scrollState.lastTargetOffset = offset;
78370
+ } else if (externalRetiresCommand({
78371
+ kind,
78372
+ offset,
78373
+ command: this.scrollState,
78374
+ target: () => this.getScrollStateTarget(this.scrollState)
78375
+ })) {
78376
+ this.scrollState = null;
77481
78377
  }
77482
- this._intendedScrollOffset = null;
78378
+ this.pendingWrite = null;
77483
78379
  if (this._clampedAdjustment !== null && Math.abs(offset - this._clampedAdjustment.maxAtWrite) >= 1.5) {
77484
78380
  this._clampedAdjustment = null;
77485
78381
  }
77486
- this.scrollAdjustments = 0;
77487
78382
  const prevOffset = this.getScrollOffset();
78383
+ const prevDirection = this.scrollDirection;
77488
78384
  this.scrollDirection = isScrolling ? prevOffset === offset ? this.scrollDirection : prevOffset < offset ? "forward" : "backward" : null;
77489
78385
  this.scrollOffset = offset;
77490
78386
  this.isScrolling = isScrolling;
77491
- this._flushIosDeferredIfReady();
78387
+ const queued = this.scrollState;
78388
+ if ((queued == null ? void 0 : queued.phase) === "queued" && kind === "external" && isScrolling) {
78389
+ if (wasOverscrolled || this._reportedOverscroll) {
78390
+ queued.samples = [];
78391
+ } else {
78392
+ const t = this.now();
78393
+ queued.samples = [
78394
+ ...(queued.samples ?? []).filter(
78395
+ (sample) => t - sample.t <= 200
78396
+ ),
78397
+ { t, offset: elementOffset }
78398
+ ];
78399
+ if (prevDirection !== null && this.scrollDirection !== prevDirection || flingSpedUp(queued.samples)) {
78400
+ this.scrollState = null;
78401
+ }
78402
+ }
78403
+ }
78404
+ if (this._iosGesture.onScroll({
78405
+ isScrolling,
78406
+ ownReadBack: kind === "readBack",
78407
+ moved: offset !== prevOffset,
78408
+ // Neither our write's read-back nor a frame of our smooth
78409
+ // animation: the user or a fling moved it.
78410
+ external: kind === "external" && ((_b = this.scrollState) == null ? void 0 : _b.phase) !== "smooth" && ((_c = this.scrollState) == null ? void 0 : _c.phase) !== "smoothFinishing"
78411
+ }) && // The user scrolls: a command still waiting for the tail is
78412
+ // theirs to override, like a written one would be.
78413
+ ((_d = this.scrollState) == null ? void 0 : _d.phase) === "queued") {
78414
+ this.scrollState = null;
78415
+ }
78416
+ this._flushHoldIfReady(true);
77492
78417
  if (this.scrollState) {
77493
78418
  this.scheduleScrollReconcile();
77494
78419
  }
@@ -77496,109 +78421,101 @@ focus outline in that case.
77496
78421
  })
77497
78422
  );
77498
78423
  if ("addEventListener" in this.scrollElement) {
77499
- const scrollEl = this.scrollElement;
77500
- const onTouchStart = () => {
77501
- this._iosTouching = true;
77502
- this._iosJustTouchEnded = false;
77503
- if (this._iosTouchEndTimerId !== null && this.targetWindow != null) {
77504
- this.targetWindow.clearTimeout(this._iosTouchEndTimerId);
77505
- this._iosTouchEndTimerId = null;
77506
- }
77507
- };
77508
- const onTouchEnd = () => {
77509
- this._iosTouching = false;
77510
- if (!isIOSWebKit() || this.targetWindow == null) {
77511
- return;
77512
- }
77513
- this._iosJustTouchEnded = true;
77514
- this._iosTouchEndTimerId = this.targetWindow.setTimeout(() => {
77515
- this._iosJustTouchEnded = false;
77516
- this._iosTouchEndTimerId = null;
77517
- this._flushIosDeferredIfReady();
77518
- }, 150);
77519
- };
77520
- scrollEl.addEventListener(
77521
- "touchstart",
77522
- onTouchStart,
77523
- addEventListenerOptions
78424
+ this.unsubs.push(
78425
+ this._iosGesture.listen(this.scrollElement)
77524
78426
  );
77525
- scrollEl.addEventListener(
77526
- "touchend",
77527
- onTouchEnd,
77528
- addEventListenerOptions
77529
- );
77530
- this.unsubs.push(() => {
77531
- scrollEl.removeEventListener("touchstart", onTouchStart);
77532
- scrollEl.removeEventListener("touchend", onTouchEnd);
77533
- if (this._iosTouchEndTimerId !== null && this.targetWindow != null) {
77534
- this.targetWindow.clearTimeout(this._iosTouchEndTimerId);
77535
- this._iosTouchEndTimerId = null;
77536
- }
77537
- });
77538
78427
  }
77539
- this._scrollToOffset(this.getScrollOffset(), {
77540
- adjustments: void 0,
77541
- behavior: void 0
77542
- });
78428
+ this._scrollToOffset(this.getScrollOffset());
77543
78429
  }
78430
+ this._noteClampMax();
77544
78431
  const anchor = this.pendingScrollAnchor;
77545
78432
  this.pendingScrollAnchor = null;
77546
78433
  if (anchor && this.scrollElement && this.options.enabled) {
77547
- const [key, _offset, followOnAppend, anchorDelta] = anchor;
77548
- if (key !== null && !followOnAppend) {
77549
- if (isIOSWebKit() && (this.isScrolling || this._iosTouching || this._iosJustTouchEnded)) {
77550
- if (anchorDelta !== 0) {
77551
- this._iosDeferredAdjustment += anchorDelta;
77552
- }
77553
- } else if (((_b = this.scrollState) == null ? void 0 : _b.behavior) === "smooth" && !approxEqual(
77554
- this.getScrollOffset() - anchorDelta,
78434
+ if (anchor.kind === "anchor") {
78435
+ if (!this._canWriteScroll()) {
78436
+ this._holdOffset += anchor.delta;
78437
+ this._followOffsetTarget(anchor.delta);
78438
+ this.notify(false);
78439
+ } else if (isSmoothScroll(this.scrollState) && !approxEqual(
78440
+ this.getScrollOffset() - anchor.delta,
77555
78441
  this.scrollState.lastTargetOffset
77556
78442
  )) ;
77557
78443
  else {
77558
- this._scrollToOffset(this.getScrollOffset(), {
77559
- adjustments: void 0,
77560
- behavior: void 0
77561
- });
78444
+ this._followOffsetTarget(anchor.delta);
78445
+ this._scrollToOffset(this.getScrollOffset());
77562
78446
  }
77563
- }
77564
- if (followOnAppend) {
77565
- this.scrollToEnd({ behavior: followOnAppend });
78447
+ } else {
78448
+ this.scrollToEnd({ behavior: anchor.behavior });
77566
78449
  }
77567
78450
  }
78451
+ this._flushHoldIfReady(false);
77568
78452
  this._retryClampedAdjustment();
77569
78453
  };
78454
+ this._classifyScrollEvent = (offset, isScrolling, elementMax) => {
78455
+ var _a;
78456
+ return classifyScrollEvent({
78457
+ offset,
78458
+ isScrolling,
78459
+ elementMax,
78460
+ holdOffset: this._holdOffset,
78461
+ scrollOffset: this.scrollOffset,
78462
+ pendingWrite: this.pendingWrite,
78463
+ clampedMaxAtWrite: ((_a = this._clampedAdjustment) == null ? void 0 : _a.maxAtWrite) ?? null
78464
+ });
78465
+ };
77570
78466
  this._retryClampedAdjustment = () => {
77571
- if (this._clampedAdjustment === null || !this.scrollElement || !this.options.enabled) {
78467
+ if (this._clampedAdjustment === null || !this.scrollElement || !this.options.enabled || !this._canWriteScroll()) {
77572
78468
  return;
77573
78469
  }
77574
78470
  const { target, maxAtWrite } = this._clampedAdjustment;
77575
78471
  const max = this.getMaxScrollOffset();
77576
78472
  if (max > maxAtWrite + 0.5) {
77577
78473
  this._clampedAdjustment = target > max + 0.5 ? { target, maxAtWrite: max } : null;
77578
- this._scrollToOffset(target, {
77579
- adjustments: void 0,
77580
- behavior: void 0
77581
- });
78474
+ this._scrollToOffset(target);
77582
78475
  }
77583
78476
  };
77584
- this._flushIosDeferredIfReady = () => {
77585
- if (this._iosDeferredAdjustment === 0) return;
77586
- if (this.isScrolling) return;
77587
- if (this._iosTouching) return;
77588
- if (this._iosJustTouchEnded) return;
77589
- const cur = this.getScrollOffset();
77590
- const max = this.getMaxScrollOffset();
77591
- if (cur < 0 || cur > max) return;
77592
- if (this._iosDeferredAdjustment < 0 && cur >= max - 1) {
77593
- this._iosDeferredAdjustment = 0;
77594
- return;
78477
+ this._writeAwaitingCommand = () => {
78478
+ const state = this.scrollState;
78479
+ if (state === null || state.phase !== "queued") return;
78480
+ const { behavior } = state;
78481
+ this.getMeasurements();
78482
+ const offset = this.getScrollStateTarget(state);
78483
+ state.lastTargetOffset = offset;
78484
+ this._clampedAdjustment = null;
78485
+ state.phase = initialScrollPhase(
78486
+ behavior,
78487
+ state.index != null && approxEqual(offset, this.getScrollOffset())
78488
+ );
78489
+ this._scrollToOffset(offset, { behavior });
78490
+ this.scheduleScrollReconcile();
78491
+ };
78492
+ this._readElementOffset = () => {
78493
+ const el = this.scrollElement;
78494
+ if (el == null) return null;
78495
+ const { horizontal, isRtl } = this.options;
78496
+ if (typeof el.scrollTop === "number") {
78497
+ return horizontal ? el.scrollLeft * (isRtl && -1 || 1) : el.scrollTop;
77595
78498
  }
77596
- const delta = this._iosDeferredAdjustment;
77597
- this._iosDeferredAdjustment = 0;
77598
- this._scrollToOffset(cur, {
77599
- adjustments: this.scrollAdjustments += delta,
77600
- behavior: void 0
77601
- });
78499
+ if (typeof el.scrollY === "number") {
78500
+ return horizontal ? el.scrollX : el.scrollY;
78501
+ }
78502
+ return null;
78503
+ };
78504
+ this._canWriteScroll = () => !(isIOSWebKit() && this._iosGesture.inMotion()) && !this._reportedOverscroll;
78505
+ this._flushHoldIfReady = (sync) => {
78506
+ var _a;
78507
+ if (this._holdOffset === 0) return;
78508
+ if (!this.scrollElement || !this.options.enabled) return;
78509
+ if (!this._canWriteScroll()) return;
78510
+ if (((_a = this.scrollState) == null ? void 0 : _a.phase) === "smooth") return;
78511
+ this._holdOffset = 0;
78512
+ if (this.scrollOffset !== null && this.scrollOffset < 0) {
78513
+ this.scrollOffset = 0;
78514
+ }
78515
+ this.notify(sync);
78516
+ const target = this.getCommandWrittenOffset() ?? this.getScrollOffset();
78517
+ this._clampedAdjustment = this._clampedBy(target);
78518
+ this._scrollToOffset(target);
77602
78519
  };
77603
78520
  this.rafId = null;
77604
78521
  this.getSize = () => {
@@ -77844,15 +78761,17 @@ focus outline in that case.
77844
78761
  this.options.overscan,
77845
78762
  this.options.count,
77846
78763
  startIndex,
77847
- endIndex
78764
+ endIndex,
78765
+ this.options.lanes
77848
78766
  ];
77849
78767
  },
77850
- (rangeExtractor, overscan, count, startIndex, endIndex) => {
78768
+ (rangeExtractor, overscan, count, startIndex, endIndex, lanes) => {
77851
78769
  return startIndex === null || endIndex === null ? [] : rangeExtractor({
77852
78770
  startIndex,
77853
78771
  endIndex,
77854
78772
  overscan,
77855
- count
78773
+ count,
78774
+ lanes
77856
78775
  });
77857
78776
  },
77858
78777
  {
@@ -77873,7 +78792,7 @@ focus outline in that case.
77873
78792
  };
77874
78793
  this.shouldMeasureDuringScroll = (index) => {
77875
78794
  var _a;
77876
- if (!this.scrollState || this.scrollState.behavior !== "smooth") {
78795
+ if (!isSmoothScroll(this.scrollState)) {
77877
78796
  return true;
77878
78797
  }
77879
78798
  const scrollIndex = this.scrollState.index ?? ((_a = this.getVirtualItemForOffset(this.scrollState.lastTargetOffset)) == null ? void 0 : _a.index);
@@ -77912,17 +78831,18 @@ focus outline in that case.
77912
78831
  this.observer.observe(node);
77913
78832
  this.elementsCache.set(key, node);
77914
78833
  }
77915
- if ((!this.isScrolling || this.scrollState) && this.shouldMeasureDuringScroll(index)) {
78834
+ if (node.isConnected && (!this.isScrolling || this.scrollState) && this.shouldMeasureDuringScroll(index)) {
77916
78835
  this.resizeItem(index, this.options.measureElement(node, void 0, this));
77917
78836
  }
77918
78837
  };
77919
78838
  this.resizeItem = (index, size) => {
77920
78839
  var _a, _b, _c;
77921
78840
  if (!this.isIndexInRange(index)) return;
78841
+ if ((_a = this._resizeBatch) == null ? void 0 : _a.sync) this.getMeasurements();
77922
78842
  let cachedSize;
77923
78843
  let itemStart;
77924
78844
  let key;
77925
- const flat = (_a = this._singleLaneMeasurements) == null ? void 0 : _a.flat;
78845
+ const flat = (_b = this._singleLaneMeasurements) == null ? void 0 : _b.flat;
77926
78846
  if (this.options.lanes === 1 && flat != null) {
77927
78847
  key = this.options.getItemKey(index);
77928
78848
  itemStart = flat[index * 2];
@@ -77937,15 +78857,15 @@ focus outline in that case.
77937
78857
  const itemSize = this.itemSizeCache.get(key) ?? cachedSize;
77938
78858
  const delta = size - itemSize;
77939
78859
  if (delta !== 0) {
77940
- const wasAtEnd = this.options.anchorTo === "end" && ((_b = this.scrollState) == null ? void 0 : _b.behavior) !== "smooth" && this.getVirtualDistanceFromEnd() <= this.options.scrollEndThreshold;
77941
- const prevTotalSize = wasAtEnd ? this.getTotalSize() : 0;
77942
- const scrollOffsetWithAdj = this.getScrollOffset() + this.scrollAdjustments;
78860
+ const wasAtEnd = this.options.anchorTo === "end" && !isSmoothScroll(this.scrollState) && this.getVirtualDistanceFromEnd() <= this.options.scrollEndThreshold;
78861
+ const prevTotalSize = wasAtEnd ? this._getLayoutTotalSize() : 0;
78862
+ const scrollOffset = this.getScrollOffset();
77943
78863
  const isFirstMeasure = !this.itemSizeCache.has(key);
77944
78864
  const defaultShouldAdjust = isFirstMeasure ? (
77945
78865
  // First measurement: compensate any item whose top sits above the
77946
78866
  // fold — the estimate→actual delta must be corrected regardless of
77947
78867
  // scroll direction, since the whole estimated block was above it.
77948
- itemStart < scrollOffsetWithAdj
78868
+ itemStart < scrollOffset
77949
78869
  ) : (
77950
78870
  // Re-measurement: only compensate an item that is ENTIRELY above the
77951
78871
  // fold. An item that merely *spans* the fold (top above, bottom
@@ -77954,9 +78874,9 @@ focus outline in that case.
77954
78874
  // delta would drag the viewport downward on every growth (#1218).
77955
78875
  // Also skip during backward scroll to avoid the "items jump while
77956
78876
  // scrolling up" cascade.
77957
- itemStart + itemSize <= scrollOffsetWithAdj && this.scrollDirection !== "backward"
78877
+ itemStart + itemSize <= scrollOffset && this.scrollDirection !== "backward"
77958
78878
  );
77959
- const shouldAdjustScroll = ((_c = this.scrollState) == null ? void 0 : _c.behavior) !== "smooth" && (this.shouldAdjustScrollPositionOnItemSizeChange !== void 0 ? this.shouldAdjustScrollPositionOnItemSizeChange(
78879
+ const shouldAdjustScroll = !isSmoothScroll(this.scrollState) && (this.shouldAdjustScrollPositionOnItemSizeChange !== void 0 ? this.shouldAdjustScrollPositionOnItemSizeChange(
77960
78880
  // The callback expects a VirtualItem; build one lazily only
77961
78881
  // when the consumer actually supplied a custom predicate.
77962
78882
  this.measurementsCache[index] ?? {
@@ -77976,25 +78896,40 @@ focus outline in that case.
77976
78896
  this.itemSizeCache.set(key, size);
77977
78897
  this.itemSizeCacheVersion++;
77978
78898
  let adjustedSync = false;
77979
- if (wasAtEnd) {
77980
- adjustedSync = this.applyScrollAdjustment(
77981
- this.getTotalSize() - prevTotalSize
77982
- );
77983
- } else if (shouldAdjustScroll) {
77984
- adjustedSync = this.applyScrollAdjustment(delta);
78899
+ if (!this._awaitingCommandReadBack()) {
78900
+ if (wasAtEnd) {
78901
+ adjustedSync = this.applyScrollAdjustment(
78902
+ this._getLayoutTotalSize() - prevTotalSize
78903
+ );
78904
+ } else if (shouldAdjustScroll) {
78905
+ adjustedSync = this.applyScrollAdjustment(delta);
78906
+ }
78907
+ }
78908
+ if (this._resizeBatch) {
78909
+ this._resizeBatch.notify = true;
78910
+ (_c = this._resizeBatch).sync || (_c.sync = adjustedSync);
78911
+ return;
77985
78912
  }
77986
78913
  this.notify(adjustedSync);
78914
+ this._noteClampMax();
78915
+ this._flushHoldIfReady(true);
77987
78916
  this._retryClampedAdjustment();
77988
78917
  }
77989
78918
  };
77990
78919
  this.getVirtualItems = memo(
77991
- () => [this.getVirtualIndexes(), this.getMeasurements()],
77992
- (indexes, measurements) => {
78920
+ () => [this.getVirtualIndexes(), this.getMeasurements(), this._holdOffset],
78921
+ (indexes, measurements, hold) => {
77993
78922
  const virtualItems = [];
77994
78923
  for (let k = 0, len = indexes.length; k < len; k++) {
77995
78924
  const i = indexes[k];
77996
78925
  const measurement = measurements[i];
77997
- virtualItems.push(measurement);
78926
+ virtualItems.push(
78927
+ hold === 0 ? measurement : {
78928
+ ...measurement,
78929
+ start: measurement.start - hold,
78930
+ end: measurement.end - hold
78931
+ }
78932
+ );
77998
78933
  }
77999
78934
  return virtualItems;
78000
78935
  },
@@ -78019,18 +78954,89 @@ focus outline in that case.
78019
78954
  );
78020
78955
  return notUndefined(measurements[idx]);
78021
78956
  };
78022
- this.getMaxScrollOffset = () => {
78023
- if (!this.scrollElement) return 0;
78024
- if ("scrollHeight" in this.scrollElement) {
78025
- return this.options.horizontal ? this.scrollElement.scrollWidth - this.scrollElement.clientWidth : this.scrollElement.scrollHeight - this.scrollElement.clientHeight;
78026
- } else {
78027
- const doc = this.scrollElement.document.documentElement;
78028
- return this.options.horizontal ? doc.scrollWidth - this.scrollElement.innerWidth : doc.scrollHeight - this.scrollElement.innerHeight;
78957
+ this._noteClampMax = () => {
78958
+ if (!this._awaitingCommandReadBack()) return;
78959
+ const elementMax = this._elementMaxScrollOffset();
78960
+ if (elementMax === null) return;
78961
+ const write = this.pendingWrite;
78962
+ const max = Math.max(elementMax, 0) + this._holdOffset;
78963
+ if (max >= write.target) return;
78964
+ const lowMaxes = write.lowMaxes ?? (write.lowMaxes = []);
78965
+ if (lowMaxes[lowMaxes.length - 1] !== max) lowMaxes.push(max);
78966
+ };
78967
+ this.getMaxScrollOffset = () => (this._elementMaxScrollOffset() ?? 0) + this._holdOffset;
78968
+ this._toLayoutOffset = (elementOffset) => {
78969
+ var _a;
78970
+ let offset = elementOffset + this._holdOffset;
78971
+ if (((_a = this.pendingScrollAnchor) == null ? void 0 : _a.kind) === "anchor") {
78972
+ offset += this.pendingScrollAnchor.delta;
78973
+ }
78974
+ return offset;
78975
+ };
78976
+ this._elementMaxScrollOffset = () => {
78977
+ const el = this.scrollElement;
78978
+ if (el === null) return null;
78979
+ if ("scrollHeight" in el) {
78980
+ return this.options.horizontal ? el.scrollWidth - el.clientWidth : el.scrollHeight - el.clientHeight;
78981
+ }
78982
+ if ("document" in el) {
78983
+ const doc = el.document.documentElement;
78984
+ return this.options.horizontal ? doc.scrollWidth - el.innerWidth : doc.scrollHeight - el.innerHeight;
78985
+ }
78986
+ return null;
78987
+ };
78988
+ this._momentumStop = null;
78989
+ this._stopMomentum = (done) => {
78990
+ const el = this.scrollElement;
78991
+ const win = this.targetWindow;
78992
+ if (el === null || win === null) return;
78993
+ const scroller = "document" in el ? el.document.scrollingElement : el;
78994
+ if (!(scroller == null ? void 0 : scroller.style)) return;
78995
+ if (this._momentumStop) {
78996
+ this._momentumStop.done = done;
78997
+ return;
78029
78998
  }
78999
+ const { style } = scroller;
79000
+ const property = this.options.horizontal ? "overflow-x" : "overflow-y";
79001
+ const value = style.getPropertyValue(property);
79002
+ const priority = style.getPropertyPriority(property);
79003
+ const crossSize = () => this.options.horizontal ? scroller.clientHeight : scroller.clientWidth;
79004
+ const crossSizeBefore = crossSize();
79005
+ style.setProperty(property, "hidden", "important");
79006
+ if (crossSize() !== crossSizeBefore) {
79007
+ style.setProperty(property, value, priority);
79008
+ return;
79009
+ }
79010
+ const stop = {
79011
+ // False when the app replaced the hidden value: the fling may not
79012
+ // have stopped.
79013
+ restore: () => {
79014
+ if (style.getPropertyValue(property) !== "hidden" || style.getPropertyPriority(property) !== "important") {
79015
+ return false;
79016
+ }
79017
+ style.setProperty(property, value, priority);
79018
+ return true;
79019
+ },
79020
+ done
79021
+ };
79022
+ this._momentumStop = stop;
79023
+ win.requestAnimationFrame(
79024
+ () => win.requestAnimationFrame(() => {
79025
+ if (this._momentumStop !== stop) return;
79026
+ this._momentumStop = null;
79027
+ if (stop.restore()) stop.done();
79028
+ })
79029
+ );
79030
+ };
79031
+ this._clampedBy = (target) => {
79032
+ const elementMax = this._elementMaxScrollOffset();
79033
+ if (elementMax === null) return null;
79034
+ const maxAtWrite = elementMax + this._holdOffset;
79035
+ return target > maxAtWrite + 0.5 ? { target, maxAtWrite } : null;
78030
79036
  };
78031
79037
  this.getVirtualDistanceFromEnd = () => {
78032
79038
  return Math.max(
78033
- this.getTotalSize() - this.getSize() - this.getScrollOffset(),
79039
+ this._getLayoutTotalSize() + this.options.scrollMargin - this.getSize() - this.getScrollOffset(),
78034
79040
  0
78035
79041
  );
78036
79042
  };
@@ -78071,7 +79077,9 @@ focus outline in that case.
78071
79077
  }
78072
79078
  }
78073
79079
  if (align === "end" && index === this.options.count - 1) {
78074
- return [this.getMaxScrollOffset(), align];
79080
+ const maxOffset = this.getMaxScrollOffset();
79081
+ const toOffset2 = maxOffset - this.options.paddingEnd + this.options.scrollPaddingEnd;
79082
+ return [Math.max(Math.min(toOffset2, maxOffset), 0), align];
78075
79083
  }
78076
79084
  const toOffset = align === "end" ? item.end + this.options.scrollPaddingEnd : item.start - this.options.scrollPaddingStart;
78077
79085
  return [
@@ -78080,70 +79088,58 @@ focus outline in that case.
78080
79088
  ];
78081
79089
  };
78082
79090
  this.scrollToOffset = (toOffset, { align = "start", behavior = "auto" } = {}) => {
78083
- this._iosDeferredAdjustment = 0;
78084
- const offset = this.getOffsetForAlignment(toOffset, align);
78085
- const now = this.now();
78086
- this.scrollState = {
78087
- index: null,
78088
- align,
79091
+ this._startScroll(
79092
+ { index: null, align },
79093
+ this.getOffsetForAlignment(toOffset, align),
78089
79094
  behavior,
78090
- startedAt: now,
78091
- lastTargetOffset: offset,
78092
- stableFrames: 0
78093
- };
78094
- this._scrollToOffset(offset, { adjustments: void 0, behavior });
78095
- this.scheduleScrollReconcile();
79095
+ "absolute"
79096
+ );
78096
79097
  };
78097
79098
  this.scrollToIndex = (index, {
78098
79099
  align: initialAlign = "auto",
78099
79100
  behavior = "auto"
78100
79101
  } = {}) => {
78101
- this._iosDeferredAdjustment = 0;
78102
79102
  index = Math.max(0, Math.min(index, this.options.count - 1));
78103
79103
  const offsetInfo = this.getOffsetForIndex(index, initialAlign);
78104
- if (!offsetInfo) {
78105
- return;
78106
- }
79104
+ if (!offsetInfo) return;
78107
79105
  const [offset, align] = offsetInfo;
78108
- const now = this.now();
78109
- this.scrollState = {
78110
- index,
78111
- align,
78112
- behavior,
78113
- startedAt: now,
78114
- lastTargetOffset: offset,
78115
- stableFrames: 0
78116
- };
78117
- this._scrollToOffset(offset, { adjustments: void 0, behavior });
78118
- this.scheduleScrollReconcile();
79106
+ this._startScroll({ index, align }, offset, behavior, "absolute");
78119
79107
  };
78120
79108
  this.scrollBy = (delta, { behavior = "auto" } = {}) => {
78121
- const offset = this.getScrollOffset() + delta;
78122
- const now = this.now();
78123
- this.scrollState = {
78124
- index: null,
78125
- align: "start",
79109
+ const offset = this.getOffsetForAlignment(
79110
+ (this.getCommandWrittenOffset() ?? this.getScrollOffset()) + delta,
79111
+ "start"
79112
+ );
79113
+ this._startScroll(
79114
+ { index: null, align: "start" },
79115
+ offset,
78126
79116
  behavior,
78127
- startedAt: now,
78128
- lastTargetOffset: offset,
78129
- stableFrames: 0
78130
- };
78131
- this._scrollToOffset(offset, { adjustments: void 0, behavior });
78132
- this.scheduleScrollReconcile();
79117
+ "relative"
79118
+ );
78133
79119
  };
78134
79120
  this.scrollToEnd = ({ behavior = "auto" } = {}) => {
78135
79121
  if (this.options.count > 0) {
78136
- this.scrollToIndex(this.options.count - 1, {
78137
- align: "end",
78138
- behavior
78139
- });
79122
+ this._startScroll(
79123
+ { index: this.options.count - 1, align: "end", toEnd: true },
79124
+ Math.max(this.getMaxScrollOffset(), 0),
79125
+ behavior,
79126
+ "absolute"
79127
+ );
78140
79128
  return;
78141
79129
  }
78142
79130
  this.scrollToOffset(Math.max(this.getTotalSize() - this.getSize(), 0), {
78143
79131
  behavior
78144
79132
  });
78145
79133
  };
78146
- this.getTotalSize = () => {
79134
+ this.cancelScroll = () => {
79135
+ if (this.rafId != null && this.targetWindow) {
79136
+ this.targetWindow.cancelAnimationFrame(this.rafId);
79137
+ this.rafId = null;
79138
+ }
79139
+ this.scrollState = null;
79140
+ };
79141
+ this.getTotalSize = () => Math.max(this._getLayoutTotalSize() - this._holdOffset, 0);
79142
+ this._getLayoutTotalSize = () => {
78147
79143
  var _a, _b;
78148
79144
  const measurements = this.getMeasurements();
78149
79145
  let end;
@@ -78195,9 +79191,28 @@ focus outline in that case.
78195
79191
  this._scrollToOffset = (offset, {
78196
79192
  adjustments,
78197
79193
  behavior
78198
- }) => {
78199
- this._intendedScrollOffset = offset + (adjustments ?? 0);
78200
- this.options.scrollToFn(offset, { behavior, adjustments }, this);
79194
+ } = {}) => {
79195
+ const write = {
79196
+ target: offset + (adjustments ?? 0),
79197
+ smooth: behavior === "smooth"
79198
+ };
79199
+ this.pendingWrite = write;
79200
+ this.options.scrollToFn(
79201
+ offset - this._holdOffset,
79202
+ { behavior, adjustments },
79203
+ this
79204
+ );
79205
+ return write;
79206
+ };
79207
+ this.getCommandWrittenOffset = () => this.scrollState !== null && this.pendingWrite !== null && !this.pendingWrite.smooth ? this.pendingWrite.target : null;
79208
+ this._awaitingCommandReadBack = () => {
79209
+ const writtenOffset = this.getCommandWrittenOffset();
79210
+ return !(isIOSWebKit() && this._iosGesture.dragging()) && writtenOffset !== null && !approxEqual(writtenOffset, this.getScrollOffset());
79211
+ };
79212
+ this._followOffsetTarget = (delta) => {
79213
+ if (this.scrollState !== null && this.scrollState.index == null) {
79214
+ this.scrollState.lastTargetOffset += delta;
79215
+ }
78201
79216
  };
78202
79217
  this.measure = () => {
78203
79218
  this.pendingMin = null;
@@ -78208,6 +79223,14 @@ focus outline in that case.
78208
79223
  };
78209
79224
  this.setOptions(opts);
78210
79225
  }
79226
+ /**
79227
+ * @deprecated Always 0: a scroll correction is folded into `scrollOffset`
79228
+ * at once, so there is never an outstanding adjustment to add to it. Read
79229
+ * `scrollOffset` alone.
79230
+ */
79231
+ get scrollAdjustments() {
79232
+ return 0;
79233
+ }
78211
79234
  // Returns `true` when it performed a synchronous `scrollTop` write this
78212
79235
  // tick, `false` when the delta was zero or the write was deferred (iOS).
78213
79236
  // `resizeItem` uses that to decide whether the follow-up `notify` must be
@@ -78217,22 +79240,21 @@ focus outline in that case.
78217
79240
  if (this.options.debug) {
78218
79241
  console.info("correction", delta);
78219
79242
  }
78220
- if (isIOSWebKit() && (this.isScrolling || this._iosTouching || this._iosJustTouchEnded)) {
78221
- this._iosDeferredAdjustment += delta;
78222
- return false;
79243
+ this._followOffsetTarget(delta);
79244
+ if (!this._canWriteScroll()) {
79245
+ this._holdOffset += delta;
79246
+ if (this.scrollOffset !== null) this.scrollOffset += delta;
79247
+ return true;
78223
79248
  } else {
78224
- const target = this.getScrollOffset() + this.scrollAdjustments + delta;
78225
- const el = this.scrollElement;
78226
- const maxAtWrite = el !== null && ("scrollHeight" in el || "document" in el) ? this.getMaxScrollOffset() : null;
78227
- this._clampedAdjustment = maxAtWrite !== null && target > maxAtWrite + 0.5 ? { target, maxAtWrite } : null;
78228
- this._scrollToOffset(this.getScrollOffset(), {
78229
- adjustments: this.scrollAdjustments += delta,
79249
+ const offset = this.getScrollOffset();
79250
+ this._clampedAdjustment = this._clampedBy(offset + delta);
79251
+ const write = this._scrollToOffset(offset, {
79252
+ adjustments: delta,
78230
79253
  behavior
78231
79254
  });
78232
79255
  if (this.scrollOffset !== null) {
78233
- this.scrollOffset += this.scrollAdjustments;
79256
+ if (this.pendingWrite === write) this.scrollOffset += delta;
78234
79257
  if (this.scrollOffset < 0) this.scrollOffset = 0;
78235
- this.scrollAdjustments = 0;
78236
79258
  }
78237
79259
  return true;
78238
79260
  }
@@ -78248,6 +79270,10 @@ focus outline in that case.
78248
79270
  this.reconcileScroll();
78249
79271
  });
78250
79272
  }
79273
+ getScrollStateTarget(state) {
79274
+ const offsetInfo = state.toEnd ? [Math.max(this.getMaxScrollOffset(), 0)] : state.index != null ? this.getOffsetForIndex(state.index, state.align) : void 0;
79275
+ return offsetInfo ? offsetInfo[0] : state.lastTargetOffset;
79276
+ }
78251
79277
  reconcileScroll() {
78252
79278
  if (!this.scrollState) return;
78253
79279
  const el = this.scrollElement;
@@ -78257,18 +79283,24 @@ focus outline in that case.
78257
79283
  this.scrollState = null;
78258
79284
  return;
78259
79285
  }
78260
- const offsetInfo = this.scrollState.index != null ? this.getOffsetForIndex(this.scrollState.index, this.scrollState.align) : void 0;
78261
- const targetOffset = offsetInfo ? offsetInfo[0] : this.scrollState.lastTargetOffset;
78262
- const STABLE_FRAMES = 1;
79286
+ if (this.scrollState.phase === "queued") {
79287
+ this.scheduleScrollReconcile();
79288
+ return;
79289
+ }
79290
+ this.getMeasurements();
79291
+ const targetOffset = this.getScrollStateTarget(this.scrollState);
79292
+ const STABLE_FRAMES = this.scrollState.index == null ? 1 : this.options.useAnimationFrameWithResizeObserver ? 3 : 2;
78263
79293
  const targetChanged = targetOffset !== this.scrollState.lastTargetOffset;
78264
79294
  if (!targetChanged && approxEqual(targetOffset, this.getScrollOffset())) {
79295
+ if (this.scrollState.phase === "smooth") {
79296
+ this.scrollState.phase = "smoothLanded";
79297
+ } else if (this.scrollState.phase === "smoothFinishing") {
79298
+ this.scrollState.phase = "instant";
79299
+ }
78265
79300
  this.scrollState.stableFrames++;
78266
79301
  if (this.scrollState.stableFrames >= STABLE_FRAMES) {
78267
79302
  if (this.getScrollOffset() !== targetOffset) {
78268
- this._scrollToOffset(targetOffset, {
78269
- adjustments: void 0,
78270
- behavior: "auto"
78271
- });
79303
+ this._scrollToOffset(targetOffset, { behavior: "auto" });
78272
79304
  }
78273
79305
  this.scrollState = null;
78274
79306
  return;
@@ -78278,19 +79310,81 @@ focus outline in that case.
78278
79310
  if (targetChanged) {
78279
79311
  const viewport = this.getSize() || 600;
78280
79312
  const distance = Math.abs(targetOffset - this.getScrollOffset());
78281
- const keepSmooth = this.scrollState.behavior === "smooth" && distance > viewport;
79313
+ const keepSmooth = isSmoothScroll(this.scrollState) && distance > viewport;
78282
79314
  this.scrollState.lastTargetOffset = targetOffset;
78283
- if (!keepSmooth) {
78284
- this.scrollState.behavior = "auto";
79315
+ if (keepSmooth) {
79316
+ this.scrollState.phase = "smooth";
79317
+ } else if (this.scrollState.phase === "smooth") {
79318
+ this.scrollState.phase = "smoothFinishing";
79319
+ } else if (this.scrollState.phase === "smoothLanded") {
79320
+ this.scrollState.phase = "instant";
78285
79321
  }
78286
79322
  this._scrollToOffset(targetOffset, {
78287
- adjustments: void 0,
78288
79323
  behavior: keepSmooth ? "smooth" : "auto"
78289
79324
  });
78290
79325
  }
78291
79326
  }
78292
79327
  this.scheduleScrollReconcile();
78293
79328
  }
79329
+ // Every scroll command starts here: it becomes the in-flight command,
79330
+ // writes its first target and leaves reconcile to retarget and retire it.
79331
+ //
79332
+ // Targets are layout offsets. A held correction is not dropped by a
79333
+ // command: the write lands the element `_holdOffset` short of the target,
79334
+ // under the rows exposed shifted by the same amount, and the flush moves
79335
+ // both together once a write is possible.
79336
+ //
79337
+ // An index or end target that is already at its offset starts a smooth
79338
+ // scroll as landed; an offset target never does, so its first scroll
79339
+ // event is read as the user's (see the scroll handler in `_willUpdate`).
79340
+ _startScroll(target, offset, behavior, kind) {
79341
+ this.pendingScrollAnchor = null;
79342
+ this._clampedAdjustment = null;
79343
+ const tail = this._iosGesture.tail();
79344
+ if (kind === "absolute" && tail !== null) {
79345
+ if (tail === "fling" && momentumOverridesWrites()) {
79346
+ this._stopMomentum(() => {
79347
+ const state = this.scrollState;
79348
+ if ((state == null ? void 0 : state.phase) !== "queued" || // A finger came down: it owns the scroll until it lifts.
79349
+ this._iosGesture.tail() !== "fling" || // In a bounce WebKit can drop the write (#1287): the tail
79350
+ // decides, as without the stop. (Not `flingCaught`: our stop
79351
+ // also ends the fling at speed, so a slow frame would read as
79352
+ // a catch and the tail would drop the command.)
79353
+ this._reportedOverscroll) {
79354
+ return;
79355
+ }
79356
+ this._iosGesture.end();
79357
+ this._flushHoldIfReady(true);
79358
+ this._writeAwaitingCommand();
79359
+ });
79360
+ this.scrollState = {
79361
+ ...target,
79362
+ startedAt: this.now(),
79363
+ lastTargetOffset: offset,
79364
+ stableFrames: 0,
79365
+ phase: "queued",
79366
+ behavior,
79367
+ samples: []
79368
+ };
79369
+ this.scheduleScrollReconcile();
79370
+ return;
79371
+ }
79372
+ this._iosGesture.end();
79373
+ }
79374
+ this.scrollState = {
79375
+ ...target,
79376
+ startedAt: this.now(),
79377
+ lastTargetOffset: offset,
79378
+ stableFrames: 0,
79379
+ behavior,
79380
+ phase: initialScrollPhase(
79381
+ behavior,
79382
+ target.index != null && approxEqual(offset, this.getScrollOffset())
79383
+ )
79384
+ };
79385
+ this._scrollToOffset(offset, { behavior });
79386
+ this.scheduleScrollReconcile();
79387
+ }
78294
79388
  };
78295
79389
  const findNearestBinarySearch = (low, high, getCurrentValue, value) => {
78296
79390
  while (low <= high) {