@vuu-ui/vuu-codemirror 0.7.5-debug → 0.7.6-debug

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.
package/cjs/index.js CHANGED
@@ -74,11 +74,6 @@ module.exports = __toCommonJS(src_exports);
74
74
 
75
75
  // ../../node_modules/@codemirror/state/dist/index.js
76
76
  var Text = class {
77
- /**
78
- @internal
79
- */
80
- constructor() {
81
- }
82
77
  /**
83
78
  Get the line description around the given position.
84
79
  */
@@ -194,7 +189,8 @@ var Text = class {
194
189
  return new LineCursor(inner);
195
190
  }
196
191
  /**
197
- @internal
192
+ Return the document as a string, using newline characters to
193
+ separate lines.
198
194
  */
199
195
  toString() {
200
196
  return this.sliceString(0);
@@ -209,6 +205,11 @@ var Text = class {
209
205
  return lines;
210
206
  }
211
207
  /**
208
+ @internal
209
+ */
210
+ constructor() {
211
+ }
212
+ /**
212
213
  Create a `Text` instance for the given array of lines.
213
214
  */
214
215
  static of(text) {
@@ -2026,7 +2027,10 @@ var StateEffect = class {
2026
2027
  }
2027
2028
  /**
2028
2029
  Define a new effect type. The type parameter indicates the type
2029
- of values that his effect holds.
2030
+ of values that his effect holds. It should be a type that
2031
+ doesn't include `undefined`, since that is used in
2032
+ [mapping](https://codemirror.net/6/docs/ref/#state.StateEffect.map) to indicate that an effect is
2033
+ removed.
2030
2034
  */
2031
2035
  static define(spec = {}) {
2032
2036
  return new StateEffectType(spec.map || ((v) => v));
@@ -2970,6 +2974,18 @@ function lazySort(ranges) {
2970
2974
  }
2971
2975
  RangeSet.empty.nextLayer = RangeSet.empty;
2972
2976
  var RangeSetBuilder = class {
2977
+ finishChunk(newArrays) {
2978
+ this.chunks.push(new Chunk(this.from, this.to, this.value, this.maxPoint));
2979
+ this.chunkPos.push(this.chunkStart);
2980
+ this.chunkStart = -1;
2981
+ this.setMaxPoint = Math.max(this.setMaxPoint, this.maxPoint);
2982
+ this.maxPoint = -1;
2983
+ if (newArrays) {
2984
+ this.from = [];
2985
+ this.to = [];
2986
+ this.value = [];
2987
+ }
2988
+ }
2973
2989
  /**
2974
2990
  Create an empty builder.
2975
2991
  */
@@ -2987,18 +3003,6 @@ var RangeSetBuilder = class {
2987
3003
  this.setMaxPoint = -1;
2988
3004
  this.nextLayer = null;
2989
3005
  }
2990
- finishChunk(newArrays) {
2991
- this.chunks.push(new Chunk(this.from, this.to, this.value, this.maxPoint));
2992
- this.chunkPos.push(this.chunkStart);
2993
- this.chunkStart = -1;
2994
- this.setMaxPoint = Math.max(this.setMaxPoint, this.maxPoint);
2995
- this.maxPoint = -1;
2996
- if (newArrays) {
2997
- this.from = [];
2998
- this.to = [];
2999
- this.value = [];
3000
- }
3001
- }
3002
3006
  /**
3003
3007
  Add a range. Ranges should be added in sorted (by `from` and
3004
3008
  `value.startSide`) order.
@@ -3349,7 +3353,7 @@ function compare(a, startA, b, startB, length2, comparator) {
3349
3353
  let diff = a.to + dPos - b.to || a.endSide - b.endSide;
3350
3354
  let end = diff < 0 ? a.to + dPos : b.to, clipEnd = Math.min(end, endB);
3351
3355
  if (a.point || b.point) {
3352
- if (!(a.point && b.point && (a.point == b.point || a.point.eq(b.point)) && sameValues(a.activeForPoint(a.to + dPos), b.activeForPoint(b.to))))
3356
+ if (!(a.point && b.point && (a.point == b.point || a.point.eq(b.point)) && sameValues(a.activeForPoint(a.to), b.activeForPoint(b.to))))
3353
3357
  comparator.comparePoint(pos, clipEnd, a.point, b.point);
3354
3358
  } else {
3355
3359
  if (clipEnd > pos && !sameValues(a.active, b.active))
@@ -3489,19 +3493,21 @@ var StyleModule = class {
3489
3493
  (root[SET] || new StyleSet(root)).mount(Array.isArray(modules) ? modules : [modules]);
3490
3494
  }
3491
3495
  };
3492
- var adoptedSet = null;
3496
+ var adoptedSet = /* @__PURE__ */ new Map();
3493
3497
  var StyleSet = class {
3494
3498
  constructor(root) {
3495
- if (!root.head && root.adoptedStyleSheets && typeof CSSStyleSheet != "undefined") {
3496
- if (adoptedSet) {
3497
- root.adoptedStyleSheets = [adoptedSet.sheet, ...root.adoptedStyleSheets];
3498
- return root[SET] = adoptedSet;
3499
- }
3500
- this.sheet = new CSSStyleSheet();
3499
+ let doc2 = root.ownerDocument || root, win = doc2.defaultView;
3500
+ if (!root.head && root.adoptedStyleSheets && win.CSSStyleSheet) {
3501
+ let adopted = adoptedSet.get(doc2);
3502
+ if (adopted) {
3503
+ root.adoptedStyleSheets = [adopted.sheet, ...root.adoptedStyleSheets];
3504
+ return root[SET] = adopted;
3505
+ }
3506
+ this.sheet = new win.CSSStyleSheet();
3501
3507
  root.adoptedStyleSheets = [this.sheet, ...root.adoptedStyleSheets];
3502
- adoptedSet = this;
3508
+ adoptedSet.set(doc2, this);
3503
3509
  } else {
3504
- this.styleTag = (root.ownerDocument || root).createElement("style");
3510
+ this.styleTag = doc2.createElement("style");
3505
3511
  let target = root.head || root;
3506
3512
  target.insertBefore(this.styleTag, target.firstChild);
3507
3513
  }
@@ -3539,7 +3545,7 @@ var StyleSet = class {
3539
3545
  }
3540
3546
  };
3541
3547
 
3542
- // ../../node_modules/w3c-keyname/index.es.js
3548
+ // ../../node_modules/w3c-keyname/index.js
3543
3549
  var base = {
3544
3550
  8: "Backspace",
3545
3551
  9: "Tab",
@@ -3620,11 +3626,8 @@ var shift = {
3620
3626
  221: "}",
3621
3627
  222: '"'
3622
3628
  };
3623
- var chrome = typeof navigator != "undefined" && /Chrome\/(\d+)/.exec(navigator.userAgent);
3624
- var gecko = typeof navigator != "undefined" && /Gecko\/\d+/.test(navigator.userAgent);
3625
3629
  var mac = typeof navigator != "undefined" && /Mac/.test(navigator.platform);
3626
3630
  var ie = typeof navigator != "undefined" && /MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);
3627
- var brokenModifierNames = mac || chrome && +chrome[1] < 57;
3628
3631
  for (i = 0; i < 10; i++)
3629
3632
  base[48 + i] = base[96 + i] = String(i);
3630
3633
  var i;
@@ -3641,7 +3644,7 @@ for (code in base)
3641
3644
  shift[code] = base[code];
3642
3645
  var code;
3643
3646
  function keyName(event) {
3644
- var ignoreKey = brokenModifierNames && (event.ctrlKey || event.altKey || event.metaKey) || ie && event.shiftKey && event.key && event.key.length == 1 || event.key == "Unidentified";
3647
+ var ignoreKey = mac && event.metaKey && event.shiftKey && !event.ctrlKey && !event.altKey || ie && event.shiftKey && event.key && event.key.length == 1 || event.key == "Unidentified";
3645
3648
  var name = !ignoreKey && event.key || (event.shiftKey ? shift : base)[event.keyCode] || event.key || "Unidentified";
3646
3649
  if (name == "Esc")
3647
3650
  name = "Escape";
@@ -3729,7 +3732,6 @@ function scanFor(node, off, targetNode, targetOff, dir) {
3729
3732
  function maxOffset(node) {
3730
3733
  return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length;
3731
3734
  }
3732
- var Rect0 = { left: 0, right: 0, top: 0, bottom: 0 };
3733
3735
  function flattenRect(rect, left) {
3734
3736
  let x = left ? rect.left : rect.right;
3735
3737
  return { left: x, right: x, top: rect.top, bottom: rect.bottom };
@@ -3857,7 +3859,8 @@ var DOMSelectionState = class {
3857
3859
  return this.anchorNode == domSel.anchorNode && this.anchorOffset == domSel.anchorOffset && this.focusNode == domSel.focusNode && this.focusOffset == domSel.focusOffset;
3858
3860
  }
3859
3861
  setRange(range) {
3860
- this.set(range.anchorNode, range.anchorOffset, range.focusNode, range.focusOffset);
3862
+ let { anchorNode, focusNode } = range;
3863
+ this.set(anchorNode, Math.min(range.anchorOffset, anchorNode ? maxOffset(anchorNode) : 0), focusNode, Math.min(range.focusOffset, focusNode ? maxOffset(focusNode) : 0));
3861
3864
  }
3862
3865
  set(anchorNode, anchorOffset, focusNode, focusOffset) {
3863
3866
  this.anchorNode = anchorNode;
@@ -3928,6 +3931,7 @@ function atElementStart(doc2, selection) {
3928
3931
  let node = selection.focusNode, offset = selection.focusOffset;
3929
3932
  if (!node || selection.anchorNode != node || selection.anchorOffset != offset)
3930
3933
  return false;
3934
+ offset = Math.min(offset, maxOffset(node));
3931
3935
  for (; ; ) {
3932
3936
  if (offset) {
3933
3937
  if (node.nodeType != 1)
@@ -3988,12 +3992,6 @@ var ContentView = class {
3988
3992
  posAfter(view) {
3989
3993
  return this.posBefore(view) + view.length;
3990
3994
  }
3991
- // Will return a rectangle directly before (when side < 0), after
3992
- // (side > 0) or directly on (when the browser supports it) the
3993
- // given position.
3994
- coordsAt(_pos, _side) {
3995
- return null;
3996
- }
3997
3995
  sync(view, track) {
3998
3996
  if (this.dirty & 2) {
3999
3997
  let parent = this.dom;
@@ -4166,6 +4164,9 @@ var ContentView = class {
4166
4164
  get isWidget() {
4167
4165
  return false;
4168
4166
  }
4167
+ get isHidden() {
4168
+ return false;
4169
+ }
4169
4170
  merge(from, to, source, hasStart, openStart, openEnd) {
4170
4171
  return false;
4171
4172
  }
@@ -4283,8 +4284,8 @@ var ie_edge = /* @__PURE__ */ /Edge\/(\d+)/.exec(nav.userAgent);
4283
4284
  var ie_upto10 = /* @__PURE__ */ /MSIE \d/.test(nav.userAgent);
4284
4285
  var ie_11up = /* @__PURE__ */ /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(nav.userAgent);
4285
4286
  var ie2 = !!(ie_upto10 || ie_11up || ie_edge);
4286
- var gecko2 = !ie2 && /* @__PURE__ */ /gecko\/(\d+)/i.test(nav.userAgent);
4287
- var chrome2 = !ie2 && /* @__PURE__ */ /Chrome\/(\d+)/.exec(nav.userAgent);
4287
+ var gecko = !ie2 && /* @__PURE__ */ /gecko\/(\d+)/i.test(nav.userAgent);
4288
+ var chrome = !ie2 && /* @__PURE__ */ /Chrome\/(\d+)/.exec(nav.userAgent);
4288
4289
  var webkit = "webkitFontSmoothing" in doc.documentElement.style;
4289
4290
  var safari = !ie2 && /* @__PURE__ */ /Apple Computer/.test(nav.vendor);
4290
4291
  var ios = safari && (/* @__PURE__ */ /Mobile\/\w+/.test(nav.userAgent) || nav.maxTouchPoints > 2);
@@ -4294,10 +4295,10 @@ var browser = {
4294
4295
  linux: /* @__PURE__ */ /Linux|X11/.test(nav.platform),
4295
4296
  ie: ie2,
4296
4297
  ie_version: ie_upto10 ? doc.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0,
4297
- gecko: gecko2,
4298
- gecko_version: gecko2 ? +(/* @__PURE__ */ /Firefox\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
4299
- chrome: !!chrome2,
4300
- chrome_version: chrome2 ? +chrome2[1] : 0,
4298
+ gecko,
4299
+ gecko_version: gecko ? +(/* @__PURE__ */ /Firefox\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
4300
+ chrome: !!chrome,
4301
+ chrome_version: chrome ? +chrome[1] : 0,
4301
4302
  ios,
4302
4303
  android: /* @__PURE__ */ /Android\b/.test(nav.userAgent),
4303
4304
  webkit,
@@ -4443,7 +4444,7 @@ function textCoords(text, pos, side) {
4443
4444
  }
4444
4445
  let rects = textRange(text, from, to).getClientRects();
4445
4446
  if (!rects.length)
4446
- return Rect0;
4447
+ return null;
4447
4448
  let rect = rects[(flatten2 ? flatten2 < 0 : side >= 0) ? 0 : rects.length - 1];
4448
4449
  if (browser.safari && !flatten2 && rect.width == 0)
4449
4450
  rect = Array.prototype.find.call(rects, (r) => r.width) || rect;
@@ -4484,15 +4485,14 @@ var WidgetView = class extends ContentView {
4484
4485
  return true;
4485
4486
  }
4486
4487
  become(other) {
4487
- if (other.length == this.length && other instanceof WidgetView && other.side == this.side) {
4488
- if (this.widget.constructor == other.widget.constructor) {
4489
- if (!this.widget.eq(other.widget))
4490
- this.markDirty(true);
4491
- if (this.dom && !this.prevWidget)
4492
- this.prevWidget = this.widget;
4493
- this.widget = other.widget;
4494
- return true;
4495
- }
4488
+ if (other instanceof WidgetView && other.side == this.side && this.widget.constructor == other.widget.constructor) {
4489
+ if (!this.widget.compare(other.widget))
4490
+ this.markDirty(true);
4491
+ if (this.dom && !this.prevWidget)
4492
+ this.prevWidget = this.widget;
4493
+ this.widget = other.widget;
4494
+ this.length = other.length;
4495
+ return true;
4496
4496
  }
4497
4497
  return false;
4498
4498
  }
@@ -4512,21 +4512,25 @@ var WidgetView = class extends ContentView {
4512
4512
  return text ? text.slice(start, start + this.length) : Text.empty;
4513
4513
  }
4514
4514
  domAtPos(pos) {
4515
- return pos == 0 ? DOMPos.before(this.dom) : DOMPos.after(this.dom, pos == this.length);
4515
+ return (this.length ? pos == 0 : this.side > 0) ? DOMPos.before(this.dom) : DOMPos.after(this.dom, pos == this.length);
4516
4516
  }
4517
4517
  domBoundsAround() {
4518
4518
  return null;
4519
4519
  }
4520
4520
  coordsAt(pos, side) {
4521
+ let custom = this.widget.coordsAt(this.dom, pos, side);
4522
+ if (custom)
4523
+ return custom;
4521
4524
  let rects = this.dom.getClientRects(), rect = null;
4522
4525
  if (!rects.length)
4523
- return Rect0;
4524
- for (let i = pos > 0 ? rects.length - 1 : 0; ; i += pos > 0 ? -1 : 1) {
4526
+ return null;
4527
+ let fromBack = this.side ? this.side < 0 : pos > 0;
4528
+ for (let i = fromBack ? rects.length - 1 : 0; ; i += fromBack ? -1 : 1) {
4525
4529
  rect = rects[i];
4526
4530
  if (pos > 0 ? i == 0 : i == rects.length - 1 || rect.top < rect.bottom)
4527
4531
  break;
4528
4532
  }
4529
- return this.length ? rect : flattenRect(rect, this.side > 0);
4533
+ return this.length ? rect : flattenRect(rect, !fromBack);
4530
4534
  }
4531
4535
  get isEditable() {
4532
4536
  return false;
@@ -4534,6 +4538,9 @@ var WidgetView = class extends ContentView {
4534
4538
  get isWidget() {
4535
4539
  return true;
4536
4540
  }
4541
+ get isHidden() {
4542
+ return this.widget.isHidden;
4543
+ }
4537
4544
  destroy() {
4538
4545
  super.destroy();
4539
4546
  if (this.dom)
@@ -4545,7 +4552,7 @@ var CompositionView = class extends WidgetView {
4545
4552
  let { topView, text } = this.widget;
4546
4553
  if (!topView)
4547
4554
  return new DOMPos(text, Math.min(pos, text.nodeValue.length));
4548
- return scanCompositionTree(pos, 0, topView, text, (v, p) => v.domAtPos(p), (p) => new DOMPos(text, Math.min(p, text.nodeValue.length)));
4555
+ return scanCompositionTree(pos, 0, topView, text, this.length - topView.length, (v, p) => v.domAtPos(p), (text2, p) => new DOMPos(text2, Math.min(p, text2.nodeValue.length)));
4549
4556
  }
4550
4557
  sync() {
4551
4558
  this.setDOM(this.widget.toDOM());
@@ -4554,7 +4561,7 @@ var CompositionView = class extends WidgetView {
4554
4561
  let { topView, text } = this.widget;
4555
4562
  if (!topView)
4556
4563
  return Math.min(offset, this.length);
4557
- return posFromDOMInCompositionTree(node, offset, topView, text);
4564
+ return posFromDOMInCompositionTree(node, offset, topView, text, this.length - topView.length);
4558
4565
  }
4559
4566
  ignoreMutation() {
4560
4567
  return false;
@@ -4566,7 +4573,7 @@ var CompositionView = class extends WidgetView {
4566
4573
  let { topView, text } = this.widget;
4567
4574
  if (!topView)
4568
4575
  return textCoords(text, pos, side);
4569
- return scanCompositionTree(pos, side, topView, text, (v, pos2, side2) => v.coordsAt(pos2, side2), (pos2, side2) => textCoords(text, pos2, side2));
4576
+ return scanCompositionTree(pos, side, topView, text, this.length - topView.length, (v, pos2, side2) => v.coordsAt(pos2, side2), (text2, pos2, side2) => textCoords(text2, pos2, side2));
4570
4577
  }
4571
4578
  destroy() {
4572
4579
  var _a2;
@@ -4580,39 +4587,87 @@ var CompositionView = class extends WidgetView {
4580
4587
  return true;
4581
4588
  }
4582
4589
  };
4583
- function scanCompositionTree(pos, side, view, text, enterView, fromText) {
4590
+ function scanCompositionTree(pos, side, view, text, dLen, enterView, fromText) {
4584
4591
  if (view instanceof MarkView) {
4585
4592
  for (let child = view.dom.firstChild; child; child = child.nextSibling) {
4586
4593
  let desc = ContentView.get(child);
4587
- if (!desc)
4588
- return fromText(pos, side);
4589
- let hasComp = contains(child, text);
4590
- let len = desc.length + (hasComp ? text.nodeValue.length : 0);
4591
- if (pos < len || pos == len && desc.getSide() <= 0)
4592
- return hasComp ? scanCompositionTree(pos, side, desc, text, enterView, fromText) : enterView(desc, pos, side);
4593
- pos -= len;
4594
+ if (!desc) {
4595
+ let inner = scanCompositionNode(pos, side, child, fromText);
4596
+ if (typeof inner != "number")
4597
+ return inner;
4598
+ pos = inner;
4599
+ } else {
4600
+ let hasComp = contains(child, text);
4601
+ let len = desc.length + (hasComp ? dLen : 0);
4602
+ if (pos < len || pos == len && desc.getSide() <= 0)
4603
+ return hasComp ? scanCompositionTree(pos, side, desc, text, dLen, enterView, fromText) : enterView(desc, pos, side);
4604
+ pos -= len;
4605
+ }
4594
4606
  }
4595
4607
  return enterView(view, view.length, -1);
4596
4608
  } else if (view.dom == text) {
4597
- return fromText(pos, side);
4609
+ return fromText(text, pos, side);
4598
4610
  } else {
4599
4611
  return enterView(view, pos, side);
4600
4612
  }
4601
4613
  }
4602
- function posFromDOMInCompositionTree(node, offset, view, text) {
4614
+ function scanCompositionNode(pos, side, node, fromText) {
4615
+ if (node.nodeType == 3) {
4616
+ let len = node.nodeValue.length;
4617
+ if (pos <= len)
4618
+ return fromText(node, pos, side);
4619
+ pos -= len;
4620
+ } else if (node.nodeType == 1 && node.contentEditable != "false") {
4621
+ for (let child = node.firstChild; child; child = child.nextSibling) {
4622
+ let inner = scanCompositionNode(pos, side, child, fromText);
4623
+ if (typeof inner != "number")
4624
+ return inner;
4625
+ pos = inner;
4626
+ }
4627
+ }
4628
+ return pos;
4629
+ }
4630
+ function posFromDOMInCompositionTree(node, offset, view, text, dLen) {
4603
4631
  if (view instanceof MarkView) {
4604
4632
  let pos = 0;
4605
- for (let child of view.children) {
4606
- let hasComp = contains(child.dom, text);
4607
- if (contains(child.dom, node))
4608
- return pos + (hasComp ? posFromDOMInCompositionTree(node, offset, child, text) : child.localPosFromDOM(node, offset));
4609
- pos += hasComp ? text.nodeValue.length : child.length;
4633
+ for (let child = view.dom.firstChild; child; child = child.nextSibling) {
4634
+ let childView = ContentView.get(child);
4635
+ if (childView) {
4636
+ let hasComp = contains(child, text);
4637
+ if (contains(child, node))
4638
+ return pos + (hasComp ? posFromDOMInCompositionTree(node, offset, childView, text, dLen) : childView.localPosFromDOM(node, offset));
4639
+ pos += childView.length + (hasComp ? dLen : 0);
4640
+ } else {
4641
+ let inner = posFromDOMInOpaqueNode(node, offset, child);
4642
+ if (inner.result != null)
4643
+ return pos + inner.result;
4644
+ pos += inner.size;
4645
+ }
4610
4646
  }
4611
4647
  } else if (view.dom == text) {
4612
4648
  return Math.min(offset, text.nodeValue.length);
4613
4649
  }
4614
4650
  return view.localPosFromDOM(node, offset);
4615
4651
  }
4652
+ function posFromDOMInOpaqueNode(node, offset, target) {
4653
+ if (target.nodeType == 3) {
4654
+ return node == target ? { result: offset } : { size: target.nodeValue.length };
4655
+ } else if (target.nodeType == 1 && target.contentEditable != "false") {
4656
+ let pos = 0;
4657
+ for (let child = target.firstChild, i = 0; ; child = child.nextSibling, i++) {
4658
+ if (node == target && i == offset)
4659
+ return { result: pos };
4660
+ if (!child)
4661
+ return { size: pos };
4662
+ let inner = posFromDOMInOpaqueNode(node, offset, child);
4663
+ if (inner.result != null)
4664
+ return { result: offset + inner.result };
4665
+ pos += inner.size;
4666
+ }
4667
+ } else {
4668
+ return target.contains(node) ? { result: 0 } : { size: 0 };
4669
+ }
4670
+ }
4616
4671
  var WidgetBufferView = class extends ContentView {
4617
4672
  constructor(side) {
4618
4673
  super();
@@ -4651,38 +4706,16 @@ var WidgetBufferView = class extends ContentView {
4651
4706
  return null;
4652
4707
  }
4653
4708
  coordsAt(pos) {
4654
- let imgRect = this.dom.getBoundingClientRect();
4655
- let siblingRect = inlineSiblingRect(this, this.side > 0 ? -1 : 1);
4656
- return siblingRect && siblingRect.top < imgRect.bottom && siblingRect.bottom > imgRect.top ? { left: imgRect.left, right: imgRect.right, top: siblingRect.top, bottom: siblingRect.bottom } : imgRect;
4709
+ return this.dom.getBoundingClientRect();
4657
4710
  }
4658
4711
  get overrideDOMText() {
4659
4712
  return Text.empty;
4660
4713
  }
4714
+ get isHidden() {
4715
+ return true;
4716
+ }
4661
4717
  };
4662
4718
  TextView.prototype.children = WidgetView.prototype.children = WidgetBufferView.prototype.children = noChildren;
4663
- function inlineSiblingRect(view, side) {
4664
- let parent = view.parent, index = parent ? parent.children.indexOf(view) : -1;
4665
- while (parent && index >= 0) {
4666
- if (side < 0 ? index > 0 : index < parent.children.length) {
4667
- let next = parent.children[index + side];
4668
- if (next instanceof TextView) {
4669
- let nextRect = next.coordsAt(side < 0 ? next.length : 0, side);
4670
- if (nextRect)
4671
- return nextRect;
4672
- }
4673
- index += side;
4674
- } else if (parent instanceof MarkView && parent.parent) {
4675
- index = parent.parent.children.indexOf(parent) + (side < 0 ? 0 : 1);
4676
- parent = parent.parent;
4677
- } else {
4678
- let last = parent.dom.lastChild;
4679
- if (last && last.nodeName == "BR")
4680
- return last.getClientRects()[0];
4681
- break;
4682
- }
4683
- }
4684
- return void 0;
4685
- }
4686
4719
  function inlineDOMAtPos(parent, pos) {
4687
4720
  let dom = parent.dom, { children } = parent, i = 0;
4688
4721
  for (let off = 0; i < children.length; i++) {
@@ -4725,10 +4758,10 @@ function coordsInChildren(view, pos, side) {
4725
4758
  if (end >= pos2) {
4726
4759
  if (child.children.length) {
4727
4760
  scan(child, pos2 - off);
4728
- } else if (!after && (end > pos2 || off == end && child.getSide() > 0)) {
4761
+ } else if ((!after || after.isHidden && side > 0) && (end > pos2 || off == end && child.getSide() > 0)) {
4729
4762
  after = child;
4730
4763
  afterPos = pos2 - off;
4731
- } else if (off < pos2 || off == end && child.getSide() < 0) {
4764
+ } else if (off < pos2 || off == end && child.getSide() < 0 && !child.isHidden) {
4732
4765
  before = child;
4733
4766
  beforePos = pos2 - off;
4734
4767
  }
@@ -4827,6 +4860,15 @@ var WidgetType = class {
4827
4860
  return -1;
4828
4861
  }
4829
4862
  /**
4863
+ For inline widgets that are displayed inline (as opposed to
4864
+ `inline-block`) and introduce line breaks (through `<br>` tags
4865
+ or textual newlines), this must indicate the amount of line
4866
+ breaks they introduce. Defaults to 0.
4867
+ */
4868
+ get lineBreaks() {
4869
+ return 0;
4870
+ }
4871
+ /**
4830
4872
  Can be used to configure which kinds of events inside the widget
4831
4873
  should be ignored by the editor. The default is to ignore all
4832
4874
  events.
@@ -4835,12 +4877,28 @@ var WidgetType = class {
4835
4877
  return true;
4836
4878
  }
4837
4879
  /**
4880
+ Override the way screen coordinates for positions at/in the
4881
+ widget are found. `pos` will be the offset into the widget, and
4882
+ `side` the side of the position that is being queried—less than
4883
+ zero for before, greater than zero for after, and zero for
4884
+ directly at that position.
4885
+ */
4886
+ coordsAt(dom, pos, side) {
4887
+ return null;
4888
+ }
4889
+ /**
4838
4890
  @internal
4839
4891
  */
4840
4892
  get customView() {
4841
4893
  return null;
4842
4894
  }
4843
4895
  /**
4896
+ @internal
4897
+ */
4898
+ get isHidden() {
4899
+ return false;
4900
+ }
4901
+ /**
4844
4902
  This is called when the an instance of the widget is removed
4845
4903
  from the editor view.
4846
4904
  */
@@ -4885,7 +4943,7 @@ var Decoration = class extends RangeValue {
4885
4943
  given position.
4886
4944
  */
4887
4945
  static widget(spec) {
4888
- let side = spec.side || 0, block = !!spec.block;
4946
+ let side = Math.max(-1e4, Math.min(1e4, spec.side || 0)), block = !!spec.block;
4889
4947
  side += block ? side > 0 ? 3e8 : -4e8 : side > 0 ? 1e8 : -1e8;
4890
4948
  return new PointDecoration(spec, side, side, block, spec.widget || null, false);
4891
4949
  }
@@ -4973,7 +5031,7 @@ var PointDecoration = class extends Decoration {
4973
5031
  return this.startSide < this.endSide ? BlockType.WidgetRange : this.startSide <= 0 ? BlockType.WidgetBefore : BlockType.WidgetAfter;
4974
5032
  }
4975
5033
  get heightRelevant() {
4976
- return this.block || !!this.widget && this.widget.estimatedHeight >= 5;
5034
+ return this.block || !!this.widget && (this.widget.estimatedHeight >= 5 || this.widget.lineBreaks > 0);
4977
5035
  }
4978
5036
  eq(other) {
4979
5037
  return other instanceof PointDecoration && widgetsEq(this.widget, other.widget) && this.block == other.block && this.startSide == other.startSide && this.endSide == other.endSide;
@@ -5205,13 +5263,14 @@ var BlockWidgetView = class extends ContentView {
5205
5263
  return null;
5206
5264
  }
5207
5265
  become(other) {
5208
- if (other instanceof BlockWidgetView && other.type == this.type && other.widget.constructor == this.widget.constructor) {
5209
- if (!other.widget.eq(this.widget))
5266
+ if (other instanceof BlockWidgetView && other.widget.constructor == this.widget.constructor) {
5267
+ if (!other.widget.compare(this.widget))
5210
5268
  this.markDirty(true);
5211
5269
  if (this.dom && !this.prevWidget)
5212
5270
  this.prevWidget = this.widget;
5213
5271
  this.widget = other.widget;
5214
5272
  this.length = other.length;
5273
+ this.type = other.type;
5215
5274
  this.breakAfter = other.breakAfter;
5216
5275
  return true;
5217
5276
  }
@@ -5229,6 +5288,9 @@ var BlockWidgetView = class extends ContentView {
5229
5288
  get isWidget() {
5230
5289
  return true;
5231
5290
  }
5291
+ coordsAt(pos, side) {
5292
+ return this.widget.coordsAt(this.dom, pos, side);
5293
+ }
5232
5294
  destroy() {
5233
5295
  super.destroy();
5234
5296
  if (this.dom)
@@ -5314,7 +5376,7 @@ var ContentBuilder = class {
5314
5376
  this.text.length - this.textOff,
5315
5377
  length2,
5316
5378
  512
5317
- /* T.Chunk */
5379
+ /* Chunk */
5318
5380
  );
5319
5381
  this.flushBuffer(active.slice(active.length - openStart));
5320
5382
  this.getLine().append(wrapMarks(new TextView(this.text.slice(this.textOff, this.textOff + take)), active), openStart);
@@ -5349,7 +5411,7 @@ var ContentBuilder = class {
5349
5411
  let cursorBefore = this.atCursorPos && !view.isEditable && openStart <= active.length && (from < to || deco.startSide > 0);
5350
5412
  let cursorAfter = !view.isEditable && (from < to || openStart > active.length || deco.startSide <= 0);
5351
5413
  let line = this.getLine();
5352
- if (this.pendingBuffer == 2 && !cursorBefore)
5414
+ if (this.pendingBuffer == 2 && !cursorBefore && !view.isEditable)
5353
5415
  this.pendingBuffer = 0;
5354
5416
  this.flushBuffer(active);
5355
5417
  if (cursorBefore) {
@@ -5406,6 +5468,9 @@ var NullWidget = class extends WidgetType {
5406
5468
  updateDOM(elt) {
5407
5469
  return elt.nodeName.toLowerCase() == this.tag;
5408
5470
  }
5471
+ get isHidden() {
5472
+ return true;
5473
+ }
5409
5474
  };
5410
5475
  var clickAddsSelectionRange = /* @__PURE__ */ Facet.define();
5411
5476
  var dragMovesSelection$1 = /* @__PURE__ */ Facet.define();
@@ -5534,6 +5599,23 @@ var contentAttributes = /* @__PURE__ */ Facet.define();
5534
5599
  var decorations = /* @__PURE__ */ Facet.define();
5535
5600
  var atomicRanges = /* @__PURE__ */ Facet.define();
5536
5601
  var scrollMargins = /* @__PURE__ */ Facet.define();
5602
+ function getScrollMargins(view) {
5603
+ let left = 0, right = 0, top2 = 0, bottom = 0;
5604
+ for (let source of view.state.facet(scrollMargins)) {
5605
+ let m = source(view);
5606
+ if (m) {
5607
+ if (m.left != null)
5608
+ left = Math.max(left, m.left);
5609
+ if (m.right != null)
5610
+ right = Math.max(right, m.right);
5611
+ if (m.top != null)
5612
+ top2 = Math.max(top2, m.top);
5613
+ if (m.bottom != null)
5614
+ bottom = Math.max(bottom, m.bottom);
5615
+ }
5616
+ }
5617
+ return { left, right, top: top2, bottom };
5618
+ }
5537
5619
  var styleModule = /* @__PURE__ */ Facet.define();
5538
5620
  var ChangedRange = class {
5539
5621
  constructor(fromA, toA, fromB, toB) {
@@ -5893,12 +5975,13 @@ var DOMReader = class {
5893
5975
  let parent = start.parentNode;
5894
5976
  for (let cur2 = start; ; ) {
5895
5977
  this.findPointBefore(parent, cur2);
5978
+ let oldLen = this.text.length;
5896
5979
  this.readNode(cur2);
5897
5980
  let next = cur2.nextSibling;
5898
5981
  if (next == end)
5899
5982
  break;
5900
5983
  let view = ContentView.get(cur2), nextView = ContentView.get(next);
5901
- if (view && nextView ? view.breakAfter : (view ? view.breakAfter : isBlockElement(cur2)) || isBlockElement(next) && (cur2.nodeName != "BR" || cur2.cmIgnore))
5984
+ if (view && nextView ? view.breakAfter : (view ? view.breakAfter : isBlockElement(cur2)) || isBlockElement(next) && (cur2.nodeName != "BR" || cur2.cmIgnore) && this.text.length > oldLen)
5902
5985
  this.lineBreak();
5903
5986
  cur2 = next;
5904
5987
  }
@@ -5997,10 +6080,7 @@ var DocView = class extends ContentView {
5997
6080
  get length() {
5998
6081
  return this.view.state.doc.length;
5999
6082
  }
6000
- // Update the document view to a given state. scrollIntoView can be
6001
- // used as a hint to compute a new viewport that includes that
6002
- // position, if we know the editor is going to scroll that position
6003
- // into view.
6083
+ // Update the document view to a given state.
6004
6084
  update(update) {
6005
6085
  let changedRanges = update.changedRanges;
6006
6086
  if (this.minWidth > 0 && changedRanges.length) {
@@ -6070,14 +6150,16 @@ var DocView = class extends ContentView {
6070
6150
  updateSelection(mustRead = false, fromPointer = false) {
6071
6151
  if (mustRead || !this.view.observer.selectionRange.focusNode)
6072
6152
  this.view.observer.readSelectionRange();
6073
- if (!(fromPointer || this.mayControlSelection()))
6153
+ let activeElt = this.view.root.activeElement, focused = activeElt == this.dom;
6154
+ let selectionNotFocus = !focused && hasSelection(this.dom, this.view.observer.selectionRange) && !(activeElt && this.dom.contains(activeElt));
6155
+ if (!(focused || fromPointer || selectionNotFocus))
6074
6156
  return;
6075
6157
  let force = this.forceSelection;
6076
6158
  this.forceSelection = false;
6077
6159
  let main = this.view.state.selection.main;
6078
6160
  let anchor = this.domAtPos(main.anchor);
6079
6161
  let head = main.empty ? anchor : this.domAtPos(main.head);
6080
- if (browser.gecko && main.empty && betweenUneditable(anchor)) {
6162
+ if (browser.gecko && main.empty && !this.compositionDeco.size && betweenUneditable(anchor)) {
6081
6163
  let dummy = document.createTextNode("");
6082
6164
  this.view.observer.ignore(() => anchor.node.insertBefore(dummy, anchor.node.childNodes[anchor.offset] || null));
6083
6165
  anchor = head = new DOMPos(dummy, 0);
@@ -6120,6 +6202,11 @@ var DocView = class extends ContentView {
6120
6202
  rawSel.removeAllRanges();
6121
6203
  rawSel.addRange(range);
6122
6204
  }
6205
+ if (selectionNotFocus && this.view.root.activeElement == this.dom) {
6206
+ this.dom.blur();
6207
+ if (activeElt)
6208
+ activeElt.focus();
6209
+ }
6123
6210
  });
6124
6211
  this.view.observer.setSelectionRange(anchor, head);
6125
6212
  }
@@ -6151,10 +6238,6 @@ var DocView = class extends ContentView {
6151
6238
  if (view.docView.posFromDOM(newRange.anchorNode, newRange.anchorOffset) != cursor.from)
6152
6239
  sel.collapse(anchorNode, anchorOffset);
6153
6240
  }
6154
- mayControlSelection() {
6155
- let active = this.view.root.activeElement;
6156
- return active == this.dom || hasSelection(this.dom, this.view.observer.selectionRange) && !(active && this.dom.contains(active));
6157
- }
6158
6241
  nearest(dom) {
6159
6242
  for (let cur2 = dom; cur2; ) {
6160
6243
  let domView = ContentView.get(cur2);
@@ -6298,24 +6381,12 @@ var DocView = class extends ContentView {
6298
6381
  right: Math.max(rect.right, other.right),
6299
6382
  bottom: Math.max(rect.bottom, other.bottom)
6300
6383
  };
6301
- let mLeft = 0, mRight = 0, mTop = 0, mBottom = 0;
6302
- for (let margins of this.view.state.facet(scrollMargins).map((f) => f(this.view)))
6303
- if (margins) {
6304
- let { left, right, top: top2, bottom } = margins;
6305
- if (left != null)
6306
- mLeft = Math.max(mLeft, left);
6307
- if (right != null)
6308
- mRight = Math.max(mRight, right);
6309
- if (top2 != null)
6310
- mTop = Math.max(mTop, top2);
6311
- if (bottom != null)
6312
- mBottom = Math.max(mBottom, bottom);
6313
- }
6384
+ let margins = getScrollMargins(this.view);
6314
6385
  let targetRect = {
6315
- left: rect.left - mLeft,
6316
- top: rect.top - mTop,
6317
- right: rect.right + mRight,
6318
- bottom: rect.bottom + mBottom
6386
+ left: rect.left - margins.left,
6387
+ top: rect.top - margins.top,
6388
+ right: rect.right + margins.right,
6389
+ bottom: rect.bottom + margins.bottom
6319
6390
  };
6320
6391
  scrollRectIntoView(this.view.scrollDOM, targetRect, range.head < range.anchor ? -1 : 1, target.x, target.y, target.xMargin, target.yMargin, this.view.textDirection == Direction.LTR);
6321
6392
  }
@@ -6380,15 +6451,22 @@ function computeCompositionDeco(view, changes) {
6380
6451
  return Decoration.none;
6381
6452
  let { from, to, node, text: textNode } = surrounding;
6382
6453
  let newFrom = changes.mapPos(from, 1), newTo = Math.max(newFrom, changes.mapPos(to, -1));
6383
- let { state } = view, text = node.nodeType == 3 ? node.nodeValue : new DOMReader([], state).readRange(node.firstChild, null).text;
6454
+ let { state } = view, reader = new DOMReader([], state);
6455
+ if (node.nodeType == 3)
6456
+ reader.readTextNode(node);
6457
+ else
6458
+ reader.readRange(node.firstChild, null);
6459
+ let { text } = reader;
6460
+ if (text.indexOf(LineBreakPlaceholder) > -1)
6461
+ return Decoration.none;
6384
6462
  if (newTo - newFrom < text.length) {
6385
- if (state.doc.sliceString(newFrom, Math.min(state.doc.length, newFrom + text.length), LineBreakPlaceholder) == text)
6463
+ if (state.doc.sliceString(newFrom, Math.min(state.doc.length, newFrom + text.length)) == text)
6386
6464
  newTo = newFrom + text.length;
6387
- else if (state.doc.sliceString(Math.max(0, newTo - text.length), newTo, LineBreakPlaceholder) == text)
6465
+ else if (state.doc.sliceString(Math.max(0, newTo - text.length), newTo) == text)
6388
6466
  newFrom = newTo - text.length;
6389
6467
  else
6390
6468
  return Decoration.none;
6391
- } else if (state.doc.sliceString(newFrom, newTo, LineBreakPlaceholder) != text) {
6469
+ } else if (state.doc.sliceString(newFrom, newTo) != text) {
6392
6470
  return Decoration.none;
6393
6471
  }
6394
6472
  let topView = ContentView.get(node);
@@ -6699,9 +6777,18 @@ function isSuspiciousChromeCaretResult(node, offset, x) {
6699
6777
  let rect = node.nodeType == 1 ? node.getBoundingClientRect() : textRange(node, 0, Math.max(node.nodeValue.length, 1)).getBoundingClientRect();
6700
6778
  return x - rect.left > 5;
6701
6779
  }
6780
+ function blockAt(view, pos) {
6781
+ let line = view.lineBlockAt(pos);
6782
+ if (Array.isArray(line.type))
6783
+ for (let l of line.type) {
6784
+ if (l.to > pos || l.to == pos && (l.to == line.to || l.type == BlockType.Text))
6785
+ return l;
6786
+ }
6787
+ return line;
6788
+ }
6702
6789
  function moveToLineBoundary(view, start, forward, includeWrap) {
6703
- let line = view.state.doc.lineAt(start.head);
6704
- let coords = !includeWrap || !view.lineWrapping ? null : view.coordsAtPos(start.assoc < 0 && start.head > line.from ? start.head - 1 : start.head);
6790
+ let line = blockAt(view, start.head);
6791
+ let coords = !includeWrap || line.type != BlockType.Text || !(view.lineWrapping || line.widgetLineBreaks) ? null : view.coordsAtPos(start.assoc < 0 && start.head > line.from ? start.head - 1 : start.head);
6705
6792
  if (coords) {
6706
6793
  let editorRect = view.dom.getBoundingClientRect();
6707
6794
  let direction = view.textDirectionAt(line.from);
@@ -6712,9 +6799,7 @@ function moveToLineBoundary(view, start, forward, includeWrap) {
6712
6799
  if (pos != null)
6713
6800
  return EditorSelection.cursor(pos, forward ? -1 : 1);
6714
6801
  }
6715
- let lineView = LineView.find(view.docView, start.head);
6716
- let end = lineView ? forward ? lineView.posAtEnd : lineView.posAtStart : forward ? line.to : line.from;
6717
- return EditorSelection.cursor(end, forward ? -1 : 1);
6802
+ return EditorSelection.cursor(forward ? line.to : line.from, forward ? -1 : 1);
6718
6803
  }
6719
6804
  function moveByChar(view, start, forward, by) {
6720
6805
  let line = view.state.doc.lineAt(start.head), spans = view.bidiSpans(line);
@@ -6775,15 +6860,15 @@ function moveVertically(view, start, forward, distance) {
6775
6860
  return EditorSelection.cursor(pos, start.assoc, void 0, goal);
6776
6861
  }
6777
6862
  }
6778
- function skipAtoms(view, oldPos, pos) {
6779
- let atoms = view.state.facet(atomicRanges).map((f) => f(view));
6863
+ function skipAtomicRanges(atoms, pos, bias) {
6780
6864
  for (; ; ) {
6781
- let moved = false;
6865
+ let moved = 0;
6782
6866
  for (let set of atoms) {
6783
- set.between(pos.from - 1, pos.from + 1, (from, to, value) => {
6784
- if (pos.from > from && pos.from < to) {
6785
- pos = oldPos.head > pos.from ? EditorSelection.cursor(from, 1) : EditorSelection.cursor(to, -1);
6786
- moved = true;
6867
+ set.between(pos - 1, pos + 1, (from, to, value) => {
6868
+ if (pos > from && pos < to) {
6869
+ let side = moved || bias || (pos - from < to - pos ? -1 : 1);
6870
+ pos = side < 0 ? from : to;
6871
+ moved = side;
6787
6872
  }
6788
6873
  });
6789
6874
  }
@@ -6791,6 +6876,10 @@ function skipAtoms(view, oldPos, pos) {
6791
6876
  return pos;
6792
6877
  }
6793
6878
  }
6879
+ function skipAtoms(view, oldPos, pos) {
6880
+ let newPos = skipAtomicRanges(view.state.facet(atomicRanges).map((f) => f(view)), pos.from, oldPos.head > pos.from ? -1 : 1);
6881
+ return newPos == pos.from ? pos : EditorSelection.cursor(newPos, newPos < pos.from ? 1 : -1);
6882
+ }
6794
6883
  var InputState = class {
6795
6884
  constructor(view) {
6796
6885
  this.lastKeyCode = 0;
@@ -6811,6 +6900,8 @@ var InputState = class {
6811
6900
  this.composing = -1;
6812
6901
  this.compositionFirstChange = null;
6813
6902
  this.compositionEndedAt = 0;
6903
+ this.compositionPendingKey = false;
6904
+ this.compositionPendingChange = false;
6814
6905
  this.mouseSelection = null;
6815
6906
  let handleEvent = (handler, event) => {
6816
6907
  if (this.ignoreDuringComposition(event))
@@ -6842,6 +6933,10 @@ var InputState = class {
6842
6933
  }
6843
6934
  }
6844
6935
  });
6936
+ view.scrollDOM.addEventListener("drop", (event) => {
6937
+ if (event.target == view.scrollDOM && event.clientY > view.contentDOM.getBoundingClientRect().bottom)
6938
+ handleEvent(handlers.drop, event);
6939
+ });
6845
6940
  if (browser.chrome && browser.chrome_version == 102) {
6846
6941
  view.scrollDOM.addEventListener("wheel", () => {
6847
6942
  if (this.chromeScrollHack < 0)
@@ -6914,6 +7009,8 @@ var InputState = class {
6914
7009
  this.lastKeyTime = Date.now();
6915
7010
  if (event.keyCode == 9 && Date.now() < this.lastEscPress + 2e3)
6916
7011
  return true;
7012
+ if (event.keyCode != 27 && modifierCodes.indexOf(event.keyCode) < 0)
7013
+ view.inputState.lastEscPress = 0;
6917
7014
  if (browser.android && browser.chrome && !event.synthetic && (event.keyCode == 13 || event.keyCode == 8)) {
6918
7015
  view.observer.delayAndroidKey(event.key, event.keyCode);
6919
7016
  return true;
@@ -6938,8 +7035,8 @@ var InputState = class {
6938
7035
  return false;
6939
7036
  if (this.composing > 0)
6940
7037
  return true;
6941
- if (browser.safari && !browser.ios && Date.now() - this.compositionEndedAt < 100) {
6942
- this.compositionEndedAt = 0;
7038
+ if (browser.safari && !browser.ios && this.compositionPendingKey && Date.now() - this.compositionEndedAt < 100) {
7039
+ this.compositionPendingKey = false;
6943
7040
  return true;
6944
7041
  }
6945
7042
  return false;
@@ -6970,8 +7067,9 @@ var PendingKeys = [
6970
7067
  ];
6971
7068
  var EmacsyPendingKeys = "dthko";
6972
7069
  var modifierCodes = [16, 17, 18, 20, 91, 92, 224, 225];
7070
+ var dragScrollMargin = 6;
6973
7071
  function dragScrollSpeed(dist) {
6974
- return dist * 0.7 + 8;
7072
+ return Math.max(0, dist) * 0.7 + 8;
6975
7073
  }
6976
7074
  var MouseSelection = class {
6977
7075
  constructor(view, startEvent, style, mustSelect) {
@@ -6982,6 +7080,7 @@ var MouseSelection = class {
6982
7080
  this.scrolling = -1;
6983
7081
  this.lastEvent = startEvent;
6984
7082
  this.scrollParent = scrollableParent(view.contentDOM);
7083
+ this.atoms = view.state.facet(atomicRanges).map((f) => f(view));
6985
7084
  let doc2 = view.contentDOM.ownerDocument;
6986
7085
  doc2.addEventListener("mousemove", this.move = this.move.bind(this));
6987
7086
  doc2.addEventListener("mouseup", this.up = this.up.bind(this));
@@ -7005,13 +7104,14 @@ var MouseSelection = class {
7005
7104
  this.select(this.lastEvent = event);
7006
7105
  let sx = 0, sy = 0;
7007
7106
  let rect = ((_a2 = this.scrollParent) === null || _a2 === void 0 ? void 0 : _a2.getBoundingClientRect()) || { left: 0, top: 0, right: this.view.win.innerWidth, bottom: this.view.win.innerHeight };
7008
- if (event.clientX <= rect.left)
7107
+ let margins = getScrollMargins(this.view);
7108
+ if (event.clientX - margins.left <= rect.left + dragScrollMargin)
7009
7109
  sx = -dragScrollSpeed(rect.left - event.clientX);
7010
- else if (event.clientX >= rect.right)
7110
+ else if (event.clientX + margins.right >= rect.right - dragScrollMargin)
7011
7111
  sx = dragScrollSpeed(event.clientX - rect.right);
7012
- if (event.clientY <= rect.top)
7112
+ if (event.clientY - margins.top <= rect.top + dragScrollMargin)
7013
7113
  sy = -dragScrollSpeed(rect.top - event.clientY);
7014
- else if (event.clientY >= rect.bottom)
7114
+ else if (event.clientY + margins.bottom >= rect.bottom - dragScrollMargin)
7015
7115
  sy = dragScrollSpeed(event.clientY - rect.bottom);
7016
7116
  this.setScrollSpeed(sx, sy);
7017
7117
  }
@@ -7049,9 +7149,31 @@ var MouseSelection = class {
7049
7149
  if (this.dragging === false)
7050
7150
  this.select(this.lastEvent);
7051
7151
  }
7152
+ skipAtoms(sel) {
7153
+ let ranges = null;
7154
+ for (let i = 0; i < sel.ranges.length; i++) {
7155
+ let range = sel.ranges[i], updated = null;
7156
+ if (range.empty) {
7157
+ let pos = skipAtomicRanges(this.atoms, range.from, 0);
7158
+ if (pos != range.from)
7159
+ updated = EditorSelection.cursor(pos, -1);
7160
+ } else {
7161
+ let from = skipAtomicRanges(this.atoms, range.from, -1);
7162
+ let to = skipAtomicRanges(this.atoms, range.to, 1);
7163
+ if (from != range.from || to != range.to)
7164
+ updated = EditorSelection.range(range.from == range.anchor ? from : to, range.from == range.head ? from : to);
7165
+ }
7166
+ if (updated) {
7167
+ if (!ranges)
7168
+ ranges = sel.ranges.slice();
7169
+ ranges[i] = updated;
7170
+ }
7171
+ }
7172
+ return ranges ? EditorSelection.create(ranges, sel.mainIndex) : sel;
7173
+ }
7052
7174
  select(event) {
7053
- let selection = this.style.get(event, this.extend, this.multiple);
7054
- if (this.mustSelect || !selection.eq(this.view.state.selection) || selection.main.assoc != this.view.state.selection.main.assoc)
7175
+ let { view } = this, selection = this.skipAtoms(this.style.get(event, this.extend, this.multiple));
7176
+ if (this.mustSelect || !selection.eq(view.state.selection) || selection.main.assoc != view.state.selection.main.assoc)
7055
7177
  this.view.dispatch({
7056
7178
  selection,
7057
7179
  userEvent: "select.pointer"
@@ -7151,8 +7273,6 @@ handlers.keydown = (view, event) => {
7151
7273
  view.inputState.setSelectionOrigin("select");
7152
7274
  if (event.keyCode == 27)
7153
7275
  view.inputState.lastEscPress = Date.now();
7154
- else if (modifierCodes.indexOf(event.keyCode) < 0)
7155
- view.inputState.lastEscPress = 0;
7156
7276
  };
7157
7277
  handlers.touchstart = (view, e) => {
7158
7278
  view.inputState.lastTouchTime = Date.now();
@@ -7242,7 +7362,7 @@ function basicMouseSelection(view, event) {
7242
7362
  }
7243
7363
  },
7244
7364
  get(event2, extend2, multiple) {
7245
- let cur2 = queryPos(view, event2);
7365
+ let cur2 = queryPos(view, event2), removed;
7246
7366
  let range = rangeForClick(view, cur2.pos, cur2.bias, type);
7247
7367
  if (start.pos != cur2.pos && !extend2) {
7248
7368
  let startRange = rangeForClick(view, start.pos, start.bias, type);
@@ -7251,8 +7371,8 @@ function basicMouseSelection(view, event) {
7251
7371
  }
7252
7372
  if (extend2)
7253
7373
  return startSel.replaceRange(startSel.main.extend(range.from, range.to));
7254
- else if (multiple && startSel.ranges.length > 1 && startSel.ranges.some((r) => r.eq(range)))
7255
- return removeRange(startSel, range);
7374
+ else if (multiple && type == 1 && startSel.ranges.length > 1 && (removed = removeRangeAround(startSel, cur2.pos)))
7375
+ return removed;
7256
7376
  else if (multiple)
7257
7377
  return startSel.addRange(range);
7258
7378
  else
@@ -7260,11 +7380,13 @@ function basicMouseSelection(view, event) {
7260
7380
  }
7261
7381
  };
7262
7382
  }
7263
- function removeRange(sel, range) {
7264
- for (let i = 0; ; i++) {
7265
- if (sel.ranges[i].eq(range))
7383
+ function removeRangeAround(sel, pos) {
7384
+ for (let i = 0; i < sel.ranges.length; i++) {
7385
+ let { from, to } = sel.ranges[i];
7386
+ if (from <= pos && to >= pos)
7266
7387
  return EditorSelection.create(sel.ranges.slice(0, i).concat(sel.ranges.slice(i + 1)), sel.mainIndex == i ? 0 : sel.mainIndex - (sel.mainIndex > i ? 1 : 0));
7267
7388
  }
7389
+ return null;
7268
7390
  }
7269
7391
  handlers.dragstart = (view, event) => {
7270
7392
  let { selection: { main } } = view.state;
@@ -7432,13 +7554,19 @@ handlers.compositionstart = handlers.compositionupdate = (view) => {
7432
7554
  handlers.compositionend = (view) => {
7433
7555
  view.inputState.composing = -1;
7434
7556
  view.inputState.compositionEndedAt = Date.now();
7557
+ view.inputState.compositionPendingKey = true;
7558
+ view.inputState.compositionPendingChange = view.observer.pendingRecords().length > 0;
7435
7559
  view.inputState.compositionFirstChange = null;
7436
- if (browser.chrome && browser.android)
7560
+ if (browser.chrome && browser.android) {
7437
7561
  view.observer.flushSoon();
7438
- setTimeout(() => {
7439
- if (view.inputState.composing < 0 && view.docView.compositionDeco.size)
7440
- view.update([]);
7441
- }, 50);
7562
+ } else if (view.inputState.compositionPendingChange) {
7563
+ Promise.resolve().then(() => view.observer.flush());
7564
+ } else {
7565
+ setTimeout(() => {
7566
+ if (view.inputState.composing < 0 && view.docView.compositionDeco.size)
7567
+ view.update([]);
7568
+ }, 50);
7569
+ }
7442
7570
  };
7443
7571
  handlers.contextmenu = (view) => {
7444
7572
  view.inputState.lastContextMenu = Date.now();
@@ -7539,12 +7667,19 @@ var BlockInfo = class {
7539
7667
  /**
7540
7668
  @internal
7541
7669
  */
7542
- constructor(from, length2, top2, height, type) {
7670
+ constructor(from, length2, top2, height, _content) {
7543
7671
  this.from = from;
7544
7672
  this.length = length2;
7545
7673
  this.top = top2;
7546
7674
  this.height = height;
7547
- this.type = type;
7675
+ this._content = _content;
7676
+ }
7677
+ /**
7678
+ The type of element this is. When querying lines, this may be
7679
+ an array of all the blocks that make up the line.
7680
+ */
7681
+ get type() {
7682
+ return typeof this._content == "number" ? BlockType.Text : Array.isArray(this._content) ? this._content : this._content.type;
7548
7683
  }
7549
7684
  /**
7550
7685
  The end of the element as a document position.
@@ -7559,11 +7694,25 @@ var BlockInfo = class {
7559
7694
  return this.top + this.height;
7560
7695
  }
7561
7696
  /**
7697
+ If this is a widget block, this will return the widget
7698
+ associated with it.
7699
+ */
7700
+ get widget() {
7701
+ return this._content instanceof PointDecoration ? this._content.widget : null;
7702
+ }
7703
+ /**
7704
+ If this is a textblock, this holds the number of line breaks
7705
+ that appear in widgets inside the block.
7706
+ */
7707
+ get widgetLineBreaks() {
7708
+ return typeof this._content == "number" ? this._content : 0;
7709
+ }
7710
+ /**
7562
7711
  @internal
7563
7712
  */
7564
7713
  join(other) {
7565
- let detail = (Array.isArray(this.type) ? this.type : [this]).concat(Array.isArray(other.type) ? other.type : [other]);
7566
- return new BlockInfo(this.from, this.length + other.length, this.top, this.height + other.height, detail);
7714
+ let content = (Array.isArray(this._content) ? this._content : [this]).concat(Array.isArray(other._content) ? other._content : [other]);
7715
+ return new BlockInfo(this.from, this.length + other.length, this.top, this.height + other.height, content);
7567
7716
  }
7568
7717
  };
7569
7718
  var QueryType = /* @__PURE__ */ function(QueryType2) {
@@ -7682,12 +7831,12 @@ var HeightMap = class {
7682
7831
  };
7683
7832
  HeightMap.prototype.size = 1;
7684
7833
  var HeightMapBlock = class extends HeightMap {
7685
- constructor(length2, height, type) {
7834
+ constructor(length2, height, deco) {
7686
7835
  super(length2, height);
7687
- this.type = type;
7836
+ this.deco = deco;
7688
7837
  }
7689
7838
  blockAt(_height, _oracle, top2, offset) {
7690
- return new BlockInfo(offset, this.length, top2, this.height, this.type);
7839
+ return new BlockInfo(offset, this.length, top2, this.height, this.deco || 0);
7691
7840
  }
7692
7841
  lineAt(_value, _type, oracle, top2, offset) {
7693
7842
  return this.blockAt(0, oracle, top2, offset);
@@ -7708,9 +7857,13 @@ var HeightMapBlock = class extends HeightMap {
7708
7857
  };
7709
7858
  var HeightMapText = class extends HeightMapBlock {
7710
7859
  constructor(length2, height) {
7711
- super(length2, height, BlockType.Text);
7860
+ super(length2, height, null);
7712
7861
  this.collapsed = 0;
7713
7862
  this.widgetHeight = 0;
7863
+ this.breaks = 0;
7864
+ }
7865
+ blockAt(_height, _oracle, top2, offset) {
7866
+ return new BlockInfo(offset, this.length, top2, this.height, this.breaks);
7714
7867
  }
7715
7868
  replace(_from, _to, nodes) {
7716
7869
  let node = nodes[0];
@@ -7730,7 +7883,7 @@ var HeightMapText = class extends HeightMapBlock {
7730
7883
  if (measured && measured.from <= offset && measured.more)
7731
7884
  this.setHeight(oracle, measured.heights[measured.index++]);
7732
7885
  else if (force || this.outdated)
7733
- this.setHeight(oracle, Math.max(this.widgetHeight, oracle.heightForLine(this.length - this.collapsed)));
7886
+ this.setHeight(oracle, Math.max(this.widgetHeight, oracle.heightForLine(this.length - this.collapsed)) + this.breaks * oracle.lineHeight);
7734
7887
  this.outdated = false;
7735
7888
  return this;
7736
7889
  }
@@ -7749,7 +7902,8 @@ var HeightMapGap = class extends HeightMap {
7749
7902
  if (oracle.lineWrapping) {
7750
7903
  let totalPerLine = Math.min(this.height, oracle.lineHeight * lines);
7751
7904
  perLine = totalPerLine / lines;
7752
- perChar = (this.height - totalPerLine) / (this.length - lines - 1);
7905
+ if (this.length > lines + 1)
7906
+ perChar = (this.height - totalPerLine) / (this.length - lines - 1);
7753
7907
  } else {
7754
7908
  perLine = this.height / lines;
7755
7909
  }
@@ -7761,11 +7915,11 @@ var HeightMapGap = class extends HeightMap {
7761
7915
  let guess = offset + Math.round(Math.max(0, Math.min(1, (height - top2) / this.height)) * this.length);
7762
7916
  let line = oracle.doc.lineAt(guess), lineHeight = perLine + line.length * perChar;
7763
7917
  let lineTop = Math.max(top2, height - lineHeight / 2);
7764
- return new BlockInfo(line.from, line.length, lineTop, lineHeight, BlockType.Text);
7918
+ return new BlockInfo(line.from, line.length, lineTop, lineHeight, 0);
7765
7919
  } else {
7766
7920
  let line = Math.max(0, Math.min(lastLine - firstLine, Math.floor((height - top2) / perLine)));
7767
7921
  let { from, length: length2 } = oracle.doc.line(firstLine + line);
7768
- return new BlockInfo(from, length2, top2 + perLine * line, perLine, BlockType.Text);
7922
+ return new BlockInfo(from, length2, top2 + perLine * line, perLine, 0);
7769
7923
  }
7770
7924
  }
7771
7925
  lineAt(value, type, oracle, top2, offset) {
@@ -7773,13 +7927,13 @@ var HeightMapGap = class extends HeightMap {
7773
7927
  return this.blockAt(value, oracle, top2, offset);
7774
7928
  if (type == QueryType.ByPosNoHeight) {
7775
7929
  let { from, to } = oracle.doc.lineAt(value);
7776
- return new BlockInfo(from, to - from, 0, 0, BlockType.Text);
7930
+ return new BlockInfo(from, to - from, 0, 0, 0);
7777
7931
  }
7778
7932
  let { firstLine, perLine, perChar } = this.heightMetrics(oracle, offset);
7779
7933
  let line = oracle.doc.lineAt(value), lineHeight = perLine + line.length * perChar;
7780
7934
  let linesAbove = line.number - firstLine;
7781
7935
  let lineTop = top2 + perLine * linesAbove + perChar * (line.from - offset - linesAbove);
7782
- return new BlockInfo(line.from, line.length, Math.max(top2, Math.min(lineTop, top2 + this.height - lineHeight)), lineHeight, BlockType.Text);
7936
+ return new BlockInfo(line.from, line.length, Math.max(top2, Math.min(lineTop, top2 + this.height - lineHeight)), lineHeight, 0);
7783
7937
  }
7784
7938
  forEachLine(from, to, oracle, top2, offset, f) {
7785
7939
  from = Math.max(from, offset);
@@ -7792,7 +7946,7 @@ var HeightMapGap = class extends HeightMap {
7792
7946
  lineTop += perLine * linesAbove + perChar * (from - offset - linesAbove);
7793
7947
  }
7794
7948
  let lineHeight = perLine + perChar * line.length;
7795
- f(new BlockInfo(line.from, line.length, lineTop, lineHeight, BlockType.Text));
7949
+ f(new BlockInfo(line.from, line.length, lineTop, lineHeight, 0));
7796
7950
  lineTop += lineHeight;
7797
7951
  pos = line.to + 1;
7798
7952
  }
@@ -8013,13 +8167,14 @@ var NodeBuilder = class {
8013
8167
  point(from, to, deco) {
8014
8168
  if (from < to || deco.heightRelevant) {
8015
8169
  let height = deco.widget ? deco.widget.estimatedHeight : 0;
8170
+ let breaks = deco.widget ? deco.widget.lineBreaks : 0;
8016
8171
  if (height < 0)
8017
8172
  height = this.oracle.lineHeight;
8018
8173
  let len = to - from;
8019
8174
  if (deco.block) {
8020
- this.addBlock(new HeightMapBlock(len, height, deco.type));
8021
- } else if (len || height >= relevantWidgetHeight) {
8022
- this.addLineDeco(height, len);
8175
+ this.addBlock(new HeightMapBlock(len, height, deco));
8176
+ } else if (len || breaks || height >= relevantWidgetHeight) {
8177
+ this.addLineDeco(height, breaks, len);
8023
8178
  }
8024
8179
  } else if (to > from) {
8025
8180
  this.span(from, to);
@@ -8058,19 +8213,22 @@ var NodeBuilder = class {
8058
8213
  return line;
8059
8214
  }
8060
8215
  addBlock(block) {
8216
+ var _a2;
8061
8217
  this.enterLine();
8062
- if (block.type == BlockType.WidgetAfter && !this.isCovered)
8218
+ let type = (_a2 = block.deco) === null || _a2 === void 0 ? void 0 : _a2.type;
8219
+ if (type == BlockType.WidgetAfter && !this.isCovered)
8063
8220
  this.ensureLine();
8064
8221
  this.nodes.push(block);
8065
8222
  this.writtenTo = this.pos = this.pos + block.length;
8066
- if (block.type != BlockType.WidgetBefore)
8223
+ if (type != BlockType.WidgetBefore)
8067
8224
  this.covering = block;
8068
8225
  }
8069
- addLineDeco(height, length2) {
8226
+ addLineDeco(height, breaks, length2) {
8070
8227
  let line = this.ensureLine();
8071
8228
  line.length += length2;
8072
8229
  line.collapsed += length2;
8073
8230
  line.widgetHeight = Math.max(line.widgetHeight, height);
8231
+ line.breaks += breaks;
8074
8232
  this.writtenTo = this.pos = this.pos + length2;
8075
8233
  }
8076
8234
  finish(from) {
@@ -8208,6 +8366,10 @@ var ViewState = class {
8208
8366
  this.contentDOMHeight = 0;
8209
8367
  this.editorHeight = 0;
8210
8368
  this.editorWidth = 0;
8369
+ this.scrollTop = 0;
8370
+ this.scrolledToBottom = true;
8371
+ this.scrollAnchorPos = 0;
8372
+ this.scrollAnchorHeight = -1;
8211
8373
  this.scaler = IdScaler;
8212
8374
  this.scrollTarget = null;
8213
8375
  this.printing = false;
@@ -8251,9 +8413,17 @@ var ViewState = class {
8251
8413
  let contentChanges = update.changedRanges;
8252
8414
  let heightChanges = ChangedRange.extendWithRanges(contentChanges, heightRelevantDecoChanges(prevDeco, this.stateDeco, update ? update.changes : ChangeSet.empty(this.state.doc.length)));
8253
8415
  let prevHeight = this.heightMap.height;
8416
+ let scrollAnchor = this.scrolledToBottom ? null : this.lineBlockAtHeight(this.scrollTop);
8254
8417
  this.heightMap = this.heightMap.applyChanges(this.stateDeco, update.startState.doc, this.heightOracle.setDoc(this.state.doc), heightChanges);
8255
8418
  if (this.heightMap.height != prevHeight)
8256
8419
  update.flags |= 2;
8420
+ if (scrollAnchor) {
8421
+ this.scrollAnchorPos = update.changes.mapPos(scrollAnchor.from, -1);
8422
+ this.scrollAnchorHeight = scrollAnchor.top;
8423
+ } else {
8424
+ this.scrollAnchorPos = -1;
8425
+ this.scrollAnchorHeight = this.heightMap.height;
8426
+ }
8257
8427
  let viewport = heightChanges.length ? this.mapViewport(this.viewport, update.changes) : this.viewport;
8258
8428
  if (scrollTarget && (scrollTarget.range.head < viewport.from || scrollTarget.range.head > viewport.to) || !this.viewportIsAppropriate(viewport))
8259
8429
  viewport = this.getViewport(0, scrollTarget);
@@ -8293,6 +8463,11 @@ var ViewState = class {
8293
8463
  this.editorWidth = view.scrollDOM.clientWidth;
8294
8464
  result |= 8;
8295
8465
  }
8466
+ if (this.scrollTop != view.scrollDOM.scrollTop) {
8467
+ this.scrollAnchorHeight = -1;
8468
+ this.scrollTop = view.scrollDOM.scrollTop;
8469
+ }
8470
+ this.scrolledToBottom = this.scrollTop > view.scrollDOM.scrollHeight - view.scrollDOM.clientHeight - 4;
8296
8471
  let pixelViewport = (this.printing ? fullPixelRange : visiblePixelRange)(dom, this.paddingTop);
8297
8472
  let dTop = pixelViewport.top - this.pixelViewport.top, dBottom = pixelViewport.bottom - this.pixelViewport.bottom;
8298
8473
  this.pixelViewport = pixelViewport;
@@ -8391,11 +8566,11 @@ var ViewState = class {
8391
8566
  return (from == 0 || top2 <= visibleTop - Math.max(10, Math.min(
8392
8567
  -bias,
8393
8568
  250
8394
- /* VP.MaxCoverMargin */
8569
+ /* MaxCoverMargin */
8395
8570
  ))) && (to == this.state.doc.length || bottom >= visibleBottom + Math.max(10, Math.min(
8396
8571
  bias,
8397
8572
  250
8398
- /* VP.MaxCoverMargin */
8573
+ /* MaxCoverMargin */
8399
8574
  ))) && (top2 > visibleTop - 2 * 1e3 && bottom < visibleBottom + 2 * 1e3);
8400
8575
  }
8401
8576
  mapLineGaps(gaps, changes) {
@@ -8642,7 +8817,7 @@ function scaleBlock(block, scaler) {
8642
8817
  if (scaler.scale == 1)
8643
8818
  return block;
8644
8819
  let bTop = scaler.toDOM(block.top), bBottom = scaler.toDOM(block.bottom);
8645
- return new BlockInfo(block.from, block.length, bTop, bBottom - bTop, Array.isArray(block.type) ? block.type.map((b) => scaleBlock(b, scaler)) : block.type);
8820
+ return new BlockInfo(block.from, block.length, bTop, bBottom - bTop, Array.isArray(block._content) ? block._content.map((b) => scaleBlock(b, scaler)) : block._content);
8646
8821
  }
8647
8822
  var theme = /* @__PURE__ */ Facet.define({ combine: (strs) => strs.join(" ") });
8648
8823
  var darkTheme = /* @__PURE__ */ Facet.define({ combine: (values) => values.indexOf(true) > -1 });
@@ -8733,16 +8908,16 @@ var baseTheme$1 = /* @__PURE__ */ buildTheme("." + baseThemeID, {
8733
8908
  "&dark .cm-selectionBackground": {
8734
8909
  background: "#222"
8735
8910
  },
8736
- "&light.cm-focused .cm-selectionBackground": {
8911
+ "&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
8737
8912
  background: "#d7d4f0"
8738
8913
  },
8739
- "&dark.cm-focused .cm-selectionBackground": {
8914
+ "&dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
8740
8915
  background: "#233"
8741
8916
  },
8742
8917
  ".cm-cursorLayer": {
8743
8918
  pointerEvents: "none"
8744
8919
  },
8745
- "&.cm-focused .cm-cursorLayer": {
8920
+ "&.cm-focused > .cm-scroller > .cm-cursorLayer": {
8746
8921
  animation: "steps(1) cm-blink 1.2s infinite"
8747
8922
  },
8748
8923
  // Two animations defined so that we can switch between them to
@@ -8764,7 +8939,7 @@ var baseTheme$1 = /* @__PURE__ */ buildTheme("." + baseThemeID, {
8764
8939
  ".cm-dropCursor": {
8765
8940
  position: "absolute"
8766
8941
  },
8767
- "&.cm-focused .cm-cursor": {
8942
+ "&.cm-focused > .cm-scroller > .cm-cursorLayer .cm-cursor": {
8768
8943
  display: "block"
8769
8944
  },
8770
8945
  "&light .cm-activeLine": { backgroundColor: "#cceeff44" },
@@ -8923,16 +9098,17 @@ var DOMChange = class {
8923
9098
  function applyDOMChange(view, domChange) {
8924
9099
  let change;
8925
9100
  let { newSel } = domChange, sel = view.state.selection.main;
9101
+ let lastKey = view.inputState.lastKeyTime > Date.now() - 100 ? view.inputState.lastKeyCode : -1;
8926
9102
  if (domChange.bounds) {
8927
9103
  let { from, to } = domChange.bounds;
8928
9104
  let preferredPos = sel.from, preferredSide = null;
8929
- if (view.inputState.lastKeyCode === 8 && view.inputState.lastKeyTime > Date.now() - 100 || browser.android && domChange.text.length < to - from) {
9105
+ if (lastKey === 8 || browser.android && domChange.text.length < to - from) {
8930
9106
  preferredPos = sel.to;
8931
9107
  preferredSide = "end";
8932
9108
  }
8933
9109
  let diff = findDiff(view.state.doc.sliceString(from, to, LineBreakPlaceholder), domChange.text, preferredPos - from, preferredSide);
8934
9110
  if (diff) {
8935
- if (browser.chrome && view.inputState.lastKeyCode == 13 && diff.toB == diff.from + 2 && domChange.text.slice(diff.from, diff.toB) == LineBreakPlaceholder + LineBreakPlaceholder)
9111
+ if (browser.chrome && lastKey == 13 && diff.toB == diff.from + 2 && domChange.text.slice(diff.from, diff.toB) == LineBreakPlaceholder + LineBreakPlaceholder)
8936
9112
  diff.toB--;
8937
9113
  change = {
8938
9114
  from: from + diff.from,
@@ -8966,7 +9142,7 @@ function applyDOMChange(view, domChange) {
8966
9142
  let startState = view.state;
8967
9143
  if (browser.ios && view.inputState.flushIOSKey(view))
8968
9144
  return true;
8969
- if (browser.android && (change.from == sel.from && change.to == sel.to && change.insert.length == 1 && change.insert.lines == 2 && dispatchKey(view.contentDOM, "Enter", 13) || change.from == sel.from - 1 && change.to == sel.to && change.insert.length == 0 && dispatchKey(view.contentDOM, "Backspace", 8) || change.from == sel.from && change.to == sel.to + 1 && change.insert.length == 0 && dispatchKey(view.contentDOM, "Delete", 46)))
9145
+ if (browser.android && (change.from == sel.from && change.to == sel.to && change.insert.length == 1 && change.insert.lines == 2 && dispatchKey(view.contentDOM, "Enter", 13) || (change.from == sel.from - 1 && change.to == sel.to && change.insert.length == 0 || lastKey == 8 && change.insert.length < change.to - change.from) && dispatchKey(view.contentDOM, "Backspace", 8) || change.from == sel.from && change.to == sel.to + 1 && change.insert.length == 0 && dispatchKey(view.contentDOM, "Delete", 46)))
8970
9146
  return true;
8971
9147
  let text = change.insert.toString();
8972
9148
  if (view.state.facet(inputHandler).some((h) => h(view, change.from, change.to, text)))
@@ -8980,7 +9156,7 @@ function applyDOMChange(view, domChange) {
8980
9156
  tr = startState.replaceSelection(view.state.toText(before + change.insert.sliceString(0, void 0, view.state.lineBreak) + after));
8981
9157
  } else {
8982
9158
  let changes = startState.changes(change);
8983
- let mainSel = newSel && !startState.selection.main.eq(newSel.main) && newSel.main.to <= changes.newLength ? newSel.main : void 0;
9159
+ let mainSel = newSel && newSel.main.to <= changes.newLength ? newSel.main : void 0;
8984
9160
  if (startState.selection.ranges.length > 1 && view.inputState.composing >= 0 && change.to <= sel.to && change.to >= sel.to - 10) {
8985
9161
  let replaced = view.state.sliceDoc(change.from, change.to);
8986
9162
  let compositionRange = compositionSurroundingNode(view) || view.state.doc.lineAt(sel.head);
@@ -9009,7 +9185,8 @@ function applyDOMChange(view, domChange) {
9009
9185
  }
9010
9186
  }
9011
9187
  let userEvent = "input.type";
9012
- if (view.composing) {
9188
+ if (view.composing || view.inputState.compositionPendingChange && view.inputState.compositionEndedAt > Date.now() - 50) {
9189
+ view.inputState.compositionPendingChange = false;
9013
9190
  userEvent += ".compose";
9014
9191
  if (view.inputState.compositionFirstChange) {
9015
9192
  userEvent += ".start";
@@ -9149,7 +9326,7 @@ var DOMObserver = class {
9149
9326
  if (this.intersecting != this.view.inView)
9150
9327
  this.onScrollChanged(document.createEvent("Event"));
9151
9328
  }
9152
- }, {});
9329
+ }, { threshold: [0, 1e-3] });
9153
9330
  this.intersection.observe(this.dom);
9154
9331
  this.gapIntersection = new IntersectionObserver((entries) => {
9155
9332
  if (entries.length > 0 && entries[entries.length - 1].intersectionRatio > 0)
@@ -9309,7 +9486,10 @@ var DOMObserver = class {
9309
9486
  let key2 = this.delayedAndroidKey;
9310
9487
  if (key2) {
9311
9488
  this.clearDelayedAndroidKey();
9312
- if (!this.flush() && key2.force)
9489
+ this.view.inputState.lastKeyCode = key2.keyCode;
9490
+ this.view.inputState.lastKeyTime = Date.now();
9491
+ let flushed = this.flush();
9492
+ if (!flushed && key2.force)
9313
9493
  dispatchKey(this.dom, key2.key, key2.keyCode);
9314
9494
  }
9315
9495
  };
@@ -9345,10 +9525,13 @@ var DOMObserver = class {
9345
9525
  }
9346
9526
  this.flush();
9347
9527
  }
9348
- processRecords() {
9349
- let records = this.queue;
9528
+ pendingRecords() {
9350
9529
  for (let mut of this.observer.takeRecords())
9351
- records.push(mut);
9530
+ this.queue.push(mut);
9531
+ return this.queue;
9532
+ }
9533
+ processRecords() {
9534
+ let records = this.pendingRecords();
9352
9535
  if (records.length)
9353
9536
  this.queue = [];
9354
9537
  let from = -1, to = -1, typeOver = false;
@@ -9587,7 +9770,8 @@ var EditorView = class {
9587
9770
  return this.dom.ownerDocument.defaultView || window;
9588
9771
  }
9589
9772
  dispatch(...input) {
9590
- this._dispatch(input.length == 1 && input[0] instanceof Transaction ? input[0] : this.state.update(...input));
9773
+ let tr = input.length == 1 && input[0] instanceof Transaction ? input[0] : this.state.update(...input);
9774
+ this._dispatch(tr, this);
9591
9775
  }
9592
9776
  /**
9593
9777
  Update the view for the given array of transactions. This will
@@ -9755,13 +9939,22 @@ var EditorView = class {
9755
9939
  if (flush)
9756
9940
  this.observer.forceFlush();
9757
9941
  let updated = null;
9758
- let { scrollHeight, scrollTop, clientHeight } = this.scrollDOM;
9759
- let refHeight = scrollTop > scrollHeight - clientHeight - 4 ? scrollHeight : scrollTop;
9942
+ let sDOM = this.scrollDOM, { scrollAnchorPos, scrollAnchorHeight } = this.viewState;
9943
+ this.viewState.scrollAnchorHeight = -1;
9944
+ if (scrollAnchorHeight < 0 || sDOM.scrollTop != this.viewState.scrollTop) {
9945
+ if (sDOM.scrollTop > sDOM.scrollHeight - sDOM.clientHeight - 4) {
9946
+ scrollAnchorPos = -1;
9947
+ scrollAnchorHeight = this.viewState.heightMap.height;
9948
+ } else {
9949
+ let block = this.viewState.lineBlockAtHeight(sDOM.scrollTop);
9950
+ scrollAnchorPos = block.from;
9951
+ scrollAnchorHeight = block.top;
9952
+ }
9953
+ }
9760
9954
  try {
9761
9955
  for (let i = 0; ; i++) {
9762
9956
  this.updateState = 1;
9763
9957
  let oldViewport = this.viewport;
9764
- let refBlock = this.viewState.lineBlockAtHeight(refHeight);
9765
9958
  let changed = this.viewState.measure(this);
9766
9959
  if (!changed && !this.measureRequests.length && this.viewState.scrollTarget == null)
9767
9960
  break;
@@ -9808,10 +10001,11 @@ var EditorView = class {
9808
10001
  this.docView.scrollIntoView(this.viewState.scrollTarget);
9809
10002
  this.viewState.scrollTarget = null;
9810
10003
  scrolled = true;
9811
- } else {
9812
- let diff = this.viewState.lineBlockAt(refBlock.from).top - refBlock.top;
10004
+ } else if (scrollAnchorHeight > -1) {
10005
+ let newAnchorHeight = scrollAnchorPos < 0 ? this.viewState.heightMap.height : this.viewState.lineBlockAt(scrollAnchorPos).top;
10006
+ let diff = newAnchorHeight - scrollAnchorHeight;
9813
10007
  if (diff > 1 || diff < -1) {
9814
- this.scrollDOM.scrollTop += diff;
10008
+ sDOM.scrollTop += diff;
9815
10009
  scrolled = true;
9816
10010
  }
9817
10011
  }
@@ -9820,6 +10014,7 @@ var EditorView = class {
9820
10014
  this.docView.updateSelection(true);
9821
10015
  if (this.viewport.from == oldViewport.from && this.viewport.to == oldViewport.to && !scrolled && this.measureRequests.length == 0)
9822
10016
  break;
10017
+ scrollAnchorHeight = -1;
9823
10018
  }
9824
10019
  } finally {
9825
10020
  this.updateState = 0;
@@ -10529,15 +10724,6 @@ function wrappedLine(view, pos, inside2) {
10529
10724
  type: BlockType.Text
10530
10725
  };
10531
10726
  }
10532
- function blockAt(view, pos) {
10533
- let line = view.lineBlockAt(pos);
10534
- if (Array.isArray(line.type))
10535
- for (let l of line.type) {
10536
- if (l.to > pos || l.to == pos && (l.to == line.to || l.type == BlockType.Text))
10537
- return l;
10538
- }
10539
- return line;
10540
- }
10541
10727
  function rectanglesForRange(view, className, range) {
10542
10728
  if (range.to <= view.viewport.from || range.from >= view.viewport.to)
10543
10729
  return [];
@@ -10550,19 +10736,17 @@ function rectanglesForRange(view, className, range) {
10550
10736
  let startBlock = blockAt(view, from), endBlock = blockAt(view, to);
10551
10737
  let visualStart = startBlock.type == BlockType.Text ? startBlock : null;
10552
10738
  let visualEnd = endBlock.type == BlockType.Text ? endBlock : null;
10553
- if (view.lineWrapping) {
10554
- if (visualStart)
10555
- visualStart = wrappedLine(view, from, visualStart);
10556
- if (visualEnd)
10557
- visualEnd = wrappedLine(view, to, visualEnd);
10558
- }
10739
+ if (visualStart && (view.lineWrapping || startBlock.widgetLineBreaks))
10740
+ visualStart = wrappedLine(view, from, visualStart);
10741
+ if (visualEnd && (view.lineWrapping || endBlock.widgetLineBreaks))
10742
+ visualEnd = wrappedLine(view, to, visualEnd);
10559
10743
  if (visualStart && visualEnd && visualStart.from == visualEnd.from) {
10560
10744
  return pieces(drawForLine(range.from, range.to, visualStart));
10561
10745
  } else {
10562
10746
  let top2 = visualStart ? drawForLine(range.from, null, visualStart) : drawForWidget(startBlock, false);
10563
10747
  let bottom = visualEnd ? drawForLine(null, range.to, visualEnd) : drawForWidget(endBlock, true);
10564
10748
  let between = [];
10565
- if ((visualStart || startBlock).to < (visualEnd || endBlock).from - 1)
10749
+ if ((visualStart || startBlock).to < (visualEnd || endBlock).from - (visualStart && visualEnd ? 1 : 0) || startBlock.widgetLineBreaks > 1 && top2.bottom + view.defaultLineHeight / 2 < bottom.top)
10566
10750
  between.push(piece(leftSide, top2.bottom, rightSide, bottom.top));
10567
10751
  else if (top2.bottom < bottom.top && view.elementAtHeight((top2.bottom + bottom.top) / 2).type == BlockType.Text)
10568
10752
  top2.bottom = bottom.top = (top2.bottom + bottom.top) / 2;
@@ -10575,7 +10759,7 @@ function rectanglesForRange(view, className, range) {
10575
10759
  top2 - base2.top - 0.01,
10576
10760
  right - left,
10577
10761
  bottom - top2 + 0.01
10578
- /* C.Epsilon */
10762
+ /* Epsilon */
10579
10763
  );
10580
10764
  }
10581
10765
  function pieces({ top: top2, bottom, horizontal }) {
@@ -10589,6 +10773,8 @@ function rectanglesForRange(view, className, range) {
10589
10773
  function addSpan(from3, fromOpen, to3, toOpen, dir) {
10590
10774
  let fromCoords = view.coordsAtPos(from3, from3 == line.to ? -2 : 2);
10591
10775
  let toCoords = view.coordsAtPos(to3, to3 == line.from ? 2 : -2);
10776
+ if (!fromCoords || !toCoords)
10777
+ return;
10592
10778
  top2 = Math.min(fromCoords.top, toCoords.top, top2);
10593
10779
  bottom = Math.max(fromCoords.bottom, toCoords.bottom, bottom);
10594
10780
  if (dir == Direction.LTR)
@@ -11519,6 +11705,9 @@ function ensureSyntaxTree(state, upto, timeout = 50) {
11519
11705
  return result;
11520
11706
  }
11521
11707
  var DocInput = class {
11708
+ /**
11709
+ Create an input object for the given document.
11710
+ */
11522
11711
  constructor(doc2) {
11523
11712
  this.doc = doc2;
11524
11713
  this.cursorPos = 0;
@@ -12535,14 +12724,15 @@ function completeFromList(list) {
12535
12724
  };
12536
12725
  }
12537
12726
  var Option = class {
12538
- constructor(completion, source, match) {
12727
+ constructor(completion, source, match, score2) {
12539
12728
  this.completion = completion;
12540
12729
  this.source = source;
12541
12730
  this.match = match;
12731
+ this.score = score2;
12542
12732
  }
12543
12733
  };
12544
12734
  function cur(state) {
12545
- return state.selection.main.head;
12735
+ return state.selection.main.from;
12546
12736
  }
12547
12737
  function ensureAnchor(expr, start) {
12548
12738
  var _a2;
@@ -12554,29 +12744,16 @@ function ensureAnchor(expr, start) {
12554
12744
  }
12555
12745
  var pickedCompletion = /* @__PURE__ */ Annotation.define();
12556
12746
  function insertCompletionText(state, text, from, to) {
12747
+ let { main } = state.selection, fromOff = from - main.from, toOff = to - main.from;
12557
12748
  return Object.assign(Object.assign({}, state.changeByRange((range) => {
12558
- if (range == state.selection.main)
12559
- return {
12560
- changes: { from, to, insert: text },
12561
- range: EditorSelection.cursor(from + text.length)
12562
- };
12563
- let len = to - from;
12564
- if (!range.empty || len && state.sliceDoc(range.from - len, range.from) != state.sliceDoc(from, to))
12749
+ if (range != main && from != to && state.sliceDoc(range.from + fromOff, range.from + toOff) != state.sliceDoc(from, to))
12565
12750
  return { range };
12566
12751
  return {
12567
- changes: { from: range.from - len, to: range.from, insert: text },
12568
- range: EditorSelection.cursor(range.from - len + text.length)
12752
+ changes: { from: range.from + fromOff, to: to == main.from ? range.to : range.from + toOff, insert: text },
12753
+ range: EditorSelection.cursor(range.from + fromOff + text.length)
12569
12754
  };
12570
12755
  })), { userEvent: "input.complete" });
12571
12756
  }
12572
- function applyCompletion(view, option) {
12573
- const apply = option.completion.apply || option.completion.label;
12574
- let result = option.source;
12575
- if (typeof apply == "string")
12576
- view.dispatch(Object.assign(Object.assign({}, insertCompletionText(view.state, apply, result.from, result.to)), { annotations: pickedCompletion.of(option.completion) }));
12577
- else
12578
- apply(view, option.completion, result.from, result.to);
12579
- }
12580
12757
  var SourceCache = /* @__PURE__ */ new WeakMap();
12581
12758
  function asSource(source) {
12582
12759
  if (!Array.isArray(source))
@@ -12586,6 +12763,8 @@ function asSource(source) {
12586
12763
  SourceCache.set(source, known = completeFromList(source));
12587
12764
  return known;
12588
12765
  }
12766
+ var startCompletionEffect = /* @__PURE__ */ StateEffect.define();
12767
+ var closeCompletionEffect = /* @__PURE__ */ StateEffect.define();
12589
12768
  var FuzzyMatcher = class {
12590
12769
  constructor(pattern) {
12591
12770
  this.pattern = pattern;
@@ -12612,7 +12791,10 @@ var FuzzyMatcher = class {
12612
12791
  // is. See `Penalty` above.
12613
12792
  match(word) {
12614
12793
  if (this.pattern.length == 0)
12615
- return [0];
12794
+ return [
12795
+ -100
12796
+ /* Penalty.NotFull */
12797
+ ];
12616
12798
  if (word.length < this.pattern.length)
12617
12799
  return null;
12618
12800
  let { chars, folded, any, precise, byWord } = this;
@@ -12711,6 +12893,7 @@ var completionConfig = /* @__PURE__ */ Facet.define({
12711
12893
  aboveCursor: false,
12712
12894
  icons: true,
12713
12895
  addToOptions: [],
12896
+ positionInfo: defaultPositionInfo,
12714
12897
  compareCompletions: (a, b) => a.label.localeCompare(b.label),
12715
12898
  interactionDelay: 75
12716
12899
  }, {
@@ -12726,82 +12909,318 @@ var completionConfig = /* @__PURE__ */ Facet.define({
12726
12909
  function joinClass(a, b) {
12727
12910
  return a ? b ? a + " " + b : a : b;
12728
12911
  }
12729
- function optionContent(config2) {
12730
- let content = config2.addToOptions.slice();
12731
- if (config2.icons)
12732
- content.push({
12733
- render(completion) {
12734
- let icon = document.createElement("div");
12735
- icon.classList.add("cm-completionIcon");
12736
- if (completion.type)
12737
- icon.classList.add(...completion.type.split(/\s+/g).map((cls) => "cm-completionIcon-" + cls));
12738
- icon.setAttribute("aria-hidden", "true");
12739
- return icon;
12740
- },
12741
- position: 20
12742
- });
12743
- content.push({
12744
- render(completion, _s, match) {
12745
- let labelElt = document.createElement("span");
12746
- labelElt.className = "cm-completionLabel";
12747
- let { label } = completion, off = 0;
12748
- for (let j = 1; j < match.length; ) {
12749
- let from = match[j++], to = match[j++];
12750
- if (from > off)
12751
- labelElt.appendChild(document.createTextNode(label.slice(off, from)));
12752
- let span = labelElt.appendChild(document.createElement("span"));
12753
- span.appendChild(document.createTextNode(label.slice(from, to)));
12754
- span.className = "cm-completionMatchedText";
12755
- off = to;
12756
- }
12757
- if (off < label.length)
12758
- labelElt.appendChild(document.createTextNode(label.slice(off)));
12759
- return labelElt;
12760
- },
12761
- position: 50
12762
- }, {
12763
- render(completion) {
12764
- if (!completion.detail)
12765
- return null;
12766
- let detailElt = document.createElement("span");
12767
- detailElt.className = "cm-completionDetail";
12768
- detailElt.textContent = completion.detail;
12769
- return detailElt;
12770
- },
12771
- position: 80
12772
- });
12773
- return content.sort((a, b) => a.position - b.position).map((a) => a.render);
12774
- }
12775
- function rangeAroundSelected(total, selected, max) {
12776
- if (total <= max)
12777
- return { from: 0, to: total };
12778
- if (selected < 0)
12779
- selected = 0;
12780
- if (selected <= total >> 1) {
12781
- let off2 = Math.floor(selected / max);
12782
- return { from: off2 * max, to: (off2 + 1) * max };
12912
+ function defaultPositionInfo(view, list, option, info, space) {
12913
+ let rtl = view.textDirection == Direction.RTL, left = rtl, narrow = false;
12914
+ let side = "top", offset, maxWidth;
12915
+ let spaceLeft = list.left - space.left, spaceRight = space.right - list.right;
12916
+ let infoWidth = info.right - info.left, infoHeight = info.bottom - info.top;
12917
+ if (left && spaceLeft < Math.min(infoWidth, spaceRight))
12918
+ left = false;
12919
+ else if (!left && spaceRight < Math.min(infoWidth, spaceLeft))
12920
+ left = true;
12921
+ if (infoWidth <= (left ? spaceLeft : spaceRight)) {
12922
+ offset = Math.max(space.top, Math.min(option.top, space.bottom - infoHeight)) - list.top;
12923
+ maxWidth = Math.min(400, left ? spaceLeft : spaceRight);
12924
+ } else {
12925
+ narrow = true;
12926
+ maxWidth = Math.min(
12927
+ 400,
12928
+ (rtl ? list.right : space.right - list.left) - 30
12929
+ /* Info.Margin */
12930
+ );
12931
+ let spaceBelow = space.bottom - list.bottom;
12932
+ if (spaceBelow >= infoHeight || spaceBelow > list.top) {
12933
+ offset = option.bottom - list.top;
12934
+ } else {
12935
+ side = "bottom";
12936
+ offset = list.bottom - option.top;
12937
+ }
12783
12938
  }
12784
- let off = Math.floor((total - selected) / max);
12785
- return { from: total - (off + 1) * max, to: total - off * max };
12939
+ return {
12940
+ style: `${side}: ${offset}px; max-width: ${maxWidth}px`,
12941
+ class: "cm-completionInfo-" + (narrow ? rtl ? "left-narrow" : "right-narrow" : left ? "left" : "right")
12942
+ };
12786
12943
  }
12787
- var CompletionTooltip = class {
12788
- constructor(view, stateField) {
12789
- this.view = view;
12790
- this.stateField = stateField;
12791
- this.info = null;
12792
- this.placeInfo = {
12793
- read: () => this.measureInfo(),
12794
- write: (pos) => this.positionInfo(pos),
12795
- key: this
12796
- };
12797
- this.space = null;
12798
- this.currentClass = "";
12799
- let cState = view.state.field(stateField);
12800
- let { options, selected } = cState.open;
12801
- let config2 = view.state.facet(completionConfig);
12802
- this.optionContent = optionContent(config2);
12803
- this.optionClass = config2.optionClass;
12804
- this.tooltipClass = config2.tooltipClass;
12944
+ function moveCompletionSelection(forward, by = "option") {
12945
+ return (view) => {
12946
+ let cState = view.state.field(completionState, false);
12947
+ if (!cState || !cState.open || cState.open.disabled || Date.now() - cState.open.timestamp < view.state.facet(completionConfig).interactionDelay)
12948
+ return false;
12949
+ let step = 1, tooltip;
12950
+ if (by == "page" && (tooltip = getTooltip(view, cState.open.tooltip)))
12951
+ step = Math.max(2, Math.floor(tooltip.dom.offsetHeight / tooltip.dom.querySelector("li").offsetHeight) - 1);
12952
+ let { length: length2 } = cState.open.options;
12953
+ let selected = cState.open.selected > -1 ? cState.open.selected + step * (forward ? 1 : -1) : forward ? 0 : length2 - 1;
12954
+ if (selected < 0)
12955
+ selected = by == "page" ? 0 : length2 - 1;
12956
+ else if (selected >= length2)
12957
+ selected = by == "page" ? length2 - 1 : 0;
12958
+ view.dispatch({ effects: setSelectedEffect.of(selected) });
12959
+ return true;
12960
+ };
12961
+ }
12962
+ var acceptCompletion = (view) => {
12963
+ let cState = view.state.field(completionState, false);
12964
+ if (view.state.readOnly || !cState || !cState.open || cState.open.selected < 0 || Date.now() - cState.open.timestamp < view.state.facet(completionConfig).interactionDelay)
12965
+ return false;
12966
+ if (!cState.open.disabled)
12967
+ return applyCompletion(view, cState.open.options[cState.open.selected]);
12968
+ return true;
12969
+ };
12970
+ var startCompletion = (view) => {
12971
+ let cState = view.state.field(completionState, false);
12972
+ if (!cState)
12973
+ return false;
12974
+ view.dispatch({ effects: startCompletionEffect.of(true) });
12975
+ return true;
12976
+ };
12977
+ var closeCompletion = (view) => {
12978
+ let cState = view.state.field(completionState, false);
12979
+ if (!cState || !cState.active.some(
12980
+ (a) => a.state != 0
12981
+ /* State.Inactive */
12982
+ ))
12983
+ return false;
12984
+ view.dispatch({ effects: closeCompletionEffect.of(null) });
12985
+ return true;
12986
+ };
12987
+ var RunningQuery = class {
12988
+ constructor(active, context) {
12989
+ this.active = active;
12990
+ this.context = context;
12991
+ this.time = Date.now();
12992
+ this.updates = [];
12993
+ this.done = void 0;
12994
+ }
12995
+ };
12996
+ var DebounceTime = 50;
12997
+ var MaxUpdateCount = 50;
12998
+ var MinAbortTime = 1e3;
12999
+ var completionPlugin = /* @__PURE__ */ ViewPlugin.fromClass(class {
13000
+ constructor(view) {
13001
+ this.view = view;
13002
+ this.debounceUpdate = -1;
13003
+ this.running = [];
13004
+ this.debounceAccept = -1;
13005
+ this.composing = 0;
13006
+ for (let active of view.state.field(completionState).active)
13007
+ if (active.state == 1)
13008
+ this.startQuery(active);
13009
+ }
13010
+ update(update) {
13011
+ let cState = update.state.field(completionState);
13012
+ if (!update.selectionSet && !update.docChanged && update.startState.field(completionState) == cState)
13013
+ return;
13014
+ let doesReset = update.transactions.some((tr) => {
13015
+ return (tr.selection || tr.docChanged) && !getUserEvent(tr);
13016
+ });
13017
+ for (let i = 0; i < this.running.length; i++) {
13018
+ let query = this.running[i];
13019
+ if (doesReset || query.updates.length + update.transactions.length > MaxUpdateCount && Date.now() - query.time > MinAbortTime) {
13020
+ for (let handler of query.context.abortListeners) {
13021
+ try {
13022
+ handler();
13023
+ } catch (e) {
13024
+ logException(this.view.state, e);
13025
+ }
13026
+ }
13027
+ query.context.abortListeners = null;
13028
+ this.running.splice(i--, 1);
13029
+ } else {
13030
+ query.updates.push(...update.transactions);
13031
+ }
13032
+ }
13033
+ if (this.debounceUpdate > -1)
13034
+ clearTimeout(this.debounceUpdate);
13035
+ this.debounceUpdate = cState.active.some((a) => a.state == 1 && !this.running.some((q) => q.active.source == a.source)) ? setTimeout(() => this.startUpdate(), DebounceTime) : -1;
13036
+ if (this.composing != 0)
13037
+ for (let tr of update.transactions) {
13038
+ if (getUserEvent(tr) == "input")
13039
+ this.composing = 2;
13040
+ else if (this.composing == 2 && tr.selection)
13041
+ this.composing = 3;
13042
+ }
13043
+ }
13044
+ startUpdate() {
13045
+ this.debounceUpdate = -1;
13046
+ let { state } = this.view, cState = state.field(completionState);
13047
+ for (let active of cState.active) {
13048
+ if (active.state == 1 && !this.running.some((r) => r.active.source == active.source))
13049
+ this.startQuery(active);
13050
+ }
13051
+ }
13052
+ startQuery(active) {
13053
+ let { state } = this.view, pos = cur(state);
13054
+ let context = new CompletionContext(state, pos, active.explicitPos == pos);
13055
+ let pending = new RunningQuery(active, context);
13056
+ this.running.push(pending);
13057
+ Promise.resolve(active.source(context)).then((result) => {
13058
+ if (!pending.context.aborted) {
13059
+ pending.done = result || null;
13060
+ this.scheduleAccept();
13061
+ }
13062
+ }, (err) => {
13063
+ this.view.dispatch({ effects: closeCompletionEffect.of(null) });
13064
+ logException(this.view.state, err);
13065
+ });
13066
+ }
13067
+ scheduleAccept() {
13068
+ if (this.running.every((q) => q.done !== void 0))
13069
+ this.accept();
13070
+ else if (this.debounceAccept < 0)
13071
+ this.debounceAccept = setTimeout(() => this.accept(), DebounceTime);
13072
+ }
13073
+ // For each finished query in this.running, try to create a result
13074
+ // or, if appropriate, restart the query.
13075
+ accept() {
13076
+ var _a2;
13077
+ if (this.debounceAccept > -1)
13078
+ clearTimeout(this.debounceAccept);
13079
+ this.debounceAccept = -1;
13080
+ let updated = [];
13081
+ let conf = this.view.state.facet(completionConfig);
13082
+ for (let i = 0; i < this.running.length; i++) {
13083
+ let query = this.running[i];
13084
+ if (query.done === void 0)
13085
+ continue;
13086
+ this.running.splice(i--, 1);
13087
+ if (query.done) {
13088
+ let active = new ActiveResult(query.active.source, query.active.explicitPos, query.done, query.done.from, (_a2 = query.done.to) !== null && _a2 !== void 0 ? _a2 : cur(query.updates.length ? query.updates[0].startState : this.view.state));
13089
+ for (let tr of query.updates)
13090
+ active = active.update(tr, conf);
13091
+ if (active.hasResult()) {
13092
+ updated.push(active);
13093
+ continue;
13094
+ }
13095
+ }
13096
+ let current = this.view.state.field(completionState).active.find((a) => a.source == query.active.source);
13097
+ if (current && current.state == 1) {
13098
+ if (query.done == null) {
13099
+ let active = new ActiveSource(
13100
+ query.active.source,
13101
+ 0
13102
+ /* State.Inactive */
13103
+ );
13104
+ for (let tr of query.updates)
13105
+ active = active.update(tr, conf);
13106
+ if (active.state != 1)
13107
+ updated.push(active);
13108
+ } else {
13109
+ this.startQuery(current);
13110
+ }
13111
+ }
13112
+ }
13113
+ if (updated.length)
13114
+ this.view.dispatch({ effects: setActiveEffect.of(updated) });
13115
+ }
13116
+ }, {
13117
+ eventHandlers: {
13118
+ blur(event) {
13119
+ let state = this.view.state.field(completionState, false);
13120
+ if (state && state.tooltip && this.view.state.facet(completionConfig).closeOnBlur) {
13121
+ let dialog = state.open && getTooltip(this.view, state.open.tooltip);
13122
+ if (!dialog || !dialog.dom.contains(event.relatedTarget))
13123
+ this.view.dispatch({ effects: closeCompletionEffect.of(null) });
13124
+ }
13125
+ },
13126
+ compositionstart() {
13127
+ this.composing = 1;
13128
+ },
13129
+ compositionend() {
13130
+ if (this.composing == 3) {
13131
+ setTimeout(() => this.view.dispatch({ effects: startCompletionEffect.of(false) }), 20);
13132
+ }
13133
+ this.composing = 0;
13134
+ }
13135
+ }
13136
+ });
13137
+ function applyCompletion(view, option) {
13138
+ const apply = option.completion.apply || option.completion.label;
13139
+ let result = view.state.field(completionState).active.find((a) => a.source == option.source);
13140
+ if (!(result instanceof ActiveResult))
13141
+ return false;
13142
+ if (typeof apply == "string")
13143
+ view.dispatch(Object.assign(Object.assign({}, insertCompletionText(view.state, apply, result.from, result.to)), { annotations: pickedCompletion.of(option.completion) }));
13144
+ else
13145
+ apply(view, option.completion, result.from, result.to);
13146
+ return true;
13147
+ }
13148
+ function optionContent(config2) {
13149
+ let content = config2.addToOptions.slice();
13150
+ if (config2.icons)
13151
+ content.push({
13152
+ render(completion) {
13153
+ let icon = document.createElement("div");
13154
+ icon.classList.add("cm-completionIcon");
13155
+ if (completion.type)
13156
+ icon.classList.add(...completion.type.split(/\s+/g).map((cls) => "cm-completionIcon-" + cls));
13157
+ icon.setAttribute("aria-hidden", "true");
13158
+ return icon;
13159
+ },
13160
+ position: 20
13161
+ });
13162
+ content.push({
13163
+ render(completion, _s, match) {
13164
+ let labelElt = document.createElement("span");
13165
+ labelElt.className = "cm-completionLabel";
13166
+ let { label } = completion, off = 0;
13167
+ for (let j = 1; j < match.length; ) {
13168
+ let from = match[j++], to = match[j++];
13169
+ if (from > off)
13170
+ labelElt.appendChild(document.createTextNode(label.slice(off, from)));
13171
+ let span = labelElt.appendChild(document.createElement("span"));
13172
+ span.appendChild(document.createTextNode(label.slice(from, to)));
13173
+ span.className = "cm-completionMatchedText";
13174
+ off = to;
13175
+ }
13176
+ if (off < label.length)
13177
+ labelElt.appendChild(document.createTextNode(label.slice(off)));
13178
+ return labelElt;
13179
+ },
13180
+ position: 50
13181
+ }, {
13182
+ render(completion) {
13183
+ if (!completion.detail)
13184
+ return null;
13185
+ let detailElt = document.createElement("span");
13186
+ detailElt.className = "cm-completionDetail";
13187
+ detailElt.textContent = completion.detail;
13188
+ return detailElt;
13189
+ },
13190
+ position: 80
13191
+ });
13192
+ return content.sort((a, b) => a.position - b.position).map((a) => a.render);
13193
+ }
13194
+ function rangeAroundSelected(total, selected, max) {
13195
+ if (total <= max)
13196
+ return { from: 0, to: total };
13197
+ if (selected < 0)
13198
+ selected = 0;
13199
+ if (selected <= total >> 1) {
13200
+ let off2 = Math.floor(selected / max);
13201
+ return { from: off2 * max, to: (off2 + 1) * max };
13202
+ }
13203
+ let off = Math.floor((total - selected) / max);
13204
+ return { from: total - (off + 1) * max, to: total - off * max };
13205
+ }
13206
+ var CompletionTooltip = class {
13207
+ constructor(view, stateField) {
13208
+ this.view = view;
13209
+ this.stateField = stateField;
13210
+ this.info = null;
13211
+ this.placeInfoReq = {
13212
+ read: () => this.measureInfo(),
13213
+ write: (pos) => this.placeInfo(pos),
13214
+ key: this
13215
+ };
13216
+ this.space = null;
13217
+ this.currentClass = "";
13218
+ let cState = view.state.field(stateField);
13219
+ let { options, selected } = cState.open;
13220
+ let config2 = view.state.facet(completionConfig);
13221
+ this.optionContent = optionContent(config2);
13222
+ this.optionClass = config2.optionClass;
13223
+ this.tooltipClass = config2.tooltipClass;
12805
13224
  this.range = rangeAroundSelected(options.length, selected, config2.maxRenderedOptions);
12806
13225
  this.dom = document.createElement("div");
12807
13226
  this.dom.className = "cm-tooltip-autocomplete";
@@ -12815,10 +13234,15 @@ var CompletionTooltip = class {
12815
13234
  }
12816
13235
  }
12817
13236
  });
13237
+ this.dom.addEventListener("focusout", (e) => {
13238
+ let state = view.state.field(this.stateField, false);
13239
+ if (state && state.tooltip && view.state.facet(completionConfig).closeOnBlur && e.relatedTarget != view.contentDOM)
13240
+ view.dispatch({ effects: closeCompletionEffect.of(null) });
13241
+ });
12818
13242
  this.list = this.dom.appendChild(this.createListBox(options, cState.id, this.range));
12819
13243
  this.list.addEventListener("scroll", () => {
12820
13244
  if (this.info)
12821
- this.view.requestMeasure(this.placeInfo);
13245
+ this.view.requestMeasure(this.placeInfoReq);
12822
13246
  });
12823
13247
  }
12824
13248
  mount() {
@@ -12850,7 +13274,7 @@ var CompletionTooltip = class {
12850
13274
  positioned(space) {
12851
13275
  this.space = space;
12852
13276
  if (this.info)
12853
- this.view.requestMeasure(this.placeInfo);
13277
+ this.view.requestMeasure(this.placeInfoReq);
12854
13278
  }
12855
13279
  updateSel() {
12856
13280
  let cState = this.view.state.field(this.stateField), open = cState.open;
@@ -12860,7 +13284,7 @@ var CompletionTooltip = class {
12860
13284
  this.list = this.dom.appendChild(this.createListBox(open.options, cState.id, this.range));
12861
13285
  this.list.addEventListener("scroll", () => {
12862
13286
  if (this.info)
12863
- this.view.requestMeasure(this.placeInfo);
13287
+ this.view.requestMeasure(this.placeInfoReq);
12864
13288
  });
12865
13289
  }
12866
13290
  if (this.updateSelectedOption(open.selected)) {
@@ -12890,12 +13314,14 @@ var CompletionTooltip = class {
12890
13314
  dom.className = "cm-tooltip cm-completionInfo";
12891
13315
  dom.appendChild(content);
12892
13316
  this.dom.appendChild(dom);
12893
- this.view.requestMeasure(this.placeInfo);
13317
+ this.view.requestMeasure(this.placeInfoReq);
12894
13318
  }
12895
13319
  updateSelectedOption(selected) {
12896
13320
  let set = null;
12897
13321
  for (let opt = this.list.firstChild, i = this.range.from; opt; opt = opt.nextSibling, i++) {
12898
- if (i == selected) {
13322
+ if (opt.nodeName != "LI" || !opt.id) {
13323
+ i--;
13324
+ } else if (i == selected) {
12899
13325
  if (!opt.hasAttribute("aria-selected")) {
12900
13326
  opt.setAttribute("aria-selected", "true");
12901
13327
  set = opt;
@@ -12923,45 +13349,16 @@ var CompletionTooltip = class {
12923
13349
  }
12924
13350
  if (selRect.top > Math.min(space.bottom, listRect.bottom) - 10 || selRect.bottom < Math.max(space.top, listRect.top) + 10)
12925
13351
  return null;
12926
- let rtl = this.view.textDirection == Direction.RTL, left = rtl, narrow = false, maxWidth;
12927
- let top2 = "", bottom = "";
12928
- let spaceLeft = listRect.left - space.left, spaceRight = space.right - listRect.right;
12929
- if (left && spaceLeft < Math.min(infoRect.width, spaceRight))
12930
- left = false;
12931
- else if (!left && spaceRight < Math.min(infoRect.width, spaceLeft))
12932
- left = true;
12933
- if (infoRect.width <= (left ? spaceLeft : spaceRight)) {
12934
- top2 = Math.max(space.top, Math.min(selRect.top, space.bottom - infoRect.height)) - listRect.top + "px";
12935
- maxWidth = Math.min(400, left ? spaceLeft : spaceRight) + "px";
12936
- } else {
12937
- narrow = true;
12938
- maxWidth = Math.min(
12939
- 400,
12940
- (rtl ? listRect.right : space.right - listRect.left) - 30
12941
- /* Info.Margin */
12942
- ) + "px";
12943
- let spaceBelow = space.bottom - listRect.bottom;
12944
- if (spaceBelow >= infoRect.height || spaceBelow > listRect.top)
12945
- top2 = selRect.bottom - listRect.top + "px";
12946
- else
12947
- bottom = listRect.bottom - selRect.top + "px";
12948
- }
12949
- return {
12950
- top: top2,
12951
- bottom,
12952
- maxWidth,
12953
- class: narrow ? rtl ? "left-narrow" : "right-narrow" : left ? "left" : "right"
12954
- };
13352
+ return this.view.state.facet(completionConfig).positionInfo(this.view, listRect, selRect, infoRect, space);
12955
13353
  }
12956
- positionInfo(pos) {
13354
+ placeInfo(pos) {
12957
13355
  if (this.info) {
12958
13356
  if (pos) {
12959
- this.info.style.top = pos.top;
12960
- this.info.style.bottom = pos.bottom;
12961
- this.info.style.maxWidth = pos.maxWidth;
12962
- this.info.className = "cm-tooltip cm-completionInfo cm-completionInfo-" + pos.class;
13357
+ if (pos.style)
13358
+ this.info.style.cssText = pos.style;
13359
+ this.info.className = "cm-tooltip cm-completionInfo " + (pos.class || "");
12963
13360
  } else {
12964
- this.info.style.top = "-1e6px";
13361
+ this.info.style.cssText = "top: -1e6px";
12965
13362
  }
12966
13363
  }
12967
13364
  }
@@ -12971,8 +13368,21 @@ var CompletionTooltip = class {
12971
13368
  ul.setAttribute("role", "listbox");
12972
13369
  ul.setAttribute("aria-expanded", "true");
12973
13370
  ul.setAttribute("aria-label", this.view.state.phrase("Completions"));
13371
+ let curSection = null;
12974
13372
  for (let i = range.from; i < range.to; i++) {
12975
- let { completion, match } = options[i];
13373
+ let { completion, match } = options[i], { section } = completion;
13374
+ if (section) {
13375
+ let name = typeof section == "string" ? section : section.name;
13376
+ if (name != curSection && (i > range.from || range.from == 0)) {
13377
+ curSection = name;
13378
+ if (typeof section != "string" && section.header) {
13379
+ ul.appendChild(section.header(section));
13380
+ } else {
13381
+ let header = ul.appendChild(document.createElement("completion-section"));
13382
+ header.textContent = name;
13383
+ }
13384
+ }
13385
+ }
12976
13386
  const li = ul.appendChild(document.createElement("li"));
12977
13387
  li.id = id + "-" + i;
12978
13388
  li.setAttribute("role", "option");
@@ -13007,31 +13417,57 @@ function score(option) {
13007
13417
  return (option.boost || 0) * 100 + (option.apply ? 10 : 0) + (option.info ? 5 : 0) + (option.type ? 1 : 0);
13008
13418
  }
13009
13419
  function sortOptions(active, state) {
13010
- let options = [], i = 0;
13420
+ let options = [];
13421
+ let sections = null;
13422
+ let addOption = (option) => {
13423
+ options.push(option);
13424
+ let { section } = option.completion;
13425
+ if (section) {
13426
+ if (!sections)
13427
+ sections = [];
13428
+ let name = typeof section == "string" ? section : section.name;
13429
+ if (!sections.some((s) => s.name == name))
13430
+ sections.push(typeof section == "string" ? { name } : section);
13431
+ }
13432
+ };
13011
13433
  for (let a of active)
13012
13434
  if (a.hasResult()) {
13013
13435
  if (a.result.filter === false) {
13014
13436
  let getMatch = a.result.getMatch;
13015
13437
  for (let option of a.result.options) {
13016
- let match = [1e9 - i++];
13438
+ let match = [1e9 - options.length];
13017
13439
  if (getMatch)
13018
13440
  for (let n of getMatch(option))
13019
13441
  match.push(n);
13020
- options.push(new Option(option, a, match));
13442
+ addOption(new Option(option, a.source, match, match[0]));
13021
13443
  }
13022
13444
  } else {
13023
13445
  let matcher = new FuzzyMatcher(state.sliceDoc(a.from, a.to)), match;
13024
13446
  for (let option of a.result.options)
13025
13447
  if (match = matcher.match(option.label)) {
13026
- if (option.boost != null)
13027
- match[0] += option.boost;
13028
- options.push(new Option(option, a, match));
13448
+ addOption(new Option(option, a.source, match, match[0] + (option.boost || 0)));
13029
13449
  }
13030
13450
  }
13031
13451
  }
13452
+ if (sections) {
13453
+ let sectionOrder = /* @__PURE__ */ Object.create(null), pos = 0;
13454
+ let cmp = (a, b) => {
13455
+ var _a2, _b;
13456
+ return ((_a2 = a.rank) !== null && _a2 !== void 0 ? _a2 : 1e9) - ((_b = b.rank) !== null && _b !== void 0 ? _b : 1e9) || (a.name < b.name ? -1 : 1);
13457
+ };
13458
+ for (let s of sections.sort(cmp)) {
13459
+ pos -= 1e5;
13460
+ sectionOrder[s.name] = pos;
13461
+ }
13462
+ for (let option of options) {
13463
+ let { section } = option.completion;
13464
+ if (section)
13465
+ option.score += sectionOrder[typeof section == "string" ? section : section.name];
13466
+ }
13467
+ }
13032
13468
  let result = [], prev = null;
13033
13469
  let compare2 = state.facet(completionConfig).compareCompletions;
13034
- for (let opt of options.sort((a, b) => b.match[0] - a.match[0] || compare2(a.completion, b.completion))) {
13470
+ for (let opt of options.sort((a, b) => b.score - a.score || compare2(a.completion, b.completion))) {
13035
13471
  if (!prev || prev.label != opt.completion.label || prev.detail != opt.completion.detail || prev.type != null && opt.completion.type != null && prev.type != opt.completion.type || prev.apply != opt.completion.apply)
13036
13472
  result.push(opt);
13037
13473
  else if (score(opt.completion) > score(prev))
@@ -13267,8 +13703,6 @@ function checkValid(validFor, state, from, to) {
13267
13703
  let text = state.sliceDoc(from, to);
13268
13704
  return typeof validFor == "function" ? validFor(text, from, to, state) : ensureAnchor(validFor, true).test(text);
13269
13705
  }
13270
- var startCompletionEffect = /* @__PURE__ */ StateEffect.define();
13271
- var closeCompletionEffect = /* @__PURE__ */ StateEffect.define();
13272
13706
  var setActiveEffect = /* @__PURE__ */ StateEffect.define({
13273
13707
  map(sources, mapping) {
13274
13708
  return sources.map((s) => s.map(mapping));
@@ -13287,196 +13721,6 @@ var completionState = /* @__PURE__ */ StateField.define({
13287
13721
  EditorView.contentAttributes.from(f, (state) => state.attrs)
13288
13722
  ]
13289
13723
  });
13290
- function moveCompletionSelection(forward, by = "option") {
13291
- return (view) => {
13292
- let cState = view.state.field(completionState, false);
13293
- if (!cState || !cState.open || cState.open.disabled || Date.now() - cState.open.timestamp < view.state.facet(completionConfig).interactionDelay)
13294
- return false;
13295
- let step = 1, tooltip;
13296
- if (by == "page" && (tooltip = getTooltip(view, cState.open.tooltip)))
13297
- step = Math.max(2, Math.floor(tooltip.dom.offsetHeight / tooltip.dom.querySelector("li").offsetHeight) - 1);
13298
- let { length: length2 } = cState.open.options;
13299
- let selected = cState.open.selected > -1 ? cState.open.selected + step * (forward ? 1 : -1) : forward ? 0 : length2 - 1;
13300
- if (selected < 0)
13301
- selected = by == "page" ? 0 : length2 - 1;
13302
- else if (selected >= length2)
13303
- selected = by == "page" ? length2 - 1 : 0;
13304
- view.dispatch({ effects: setSelectedEffect.of(selected) });
13305
- return true;
13306
- };
13307
- }
13308
- var acceptCompletion = (view) => {
13309
- let cState = view.state.field(completionState, false);
13310
- if (view.state.readOnly || !cState || !cState.open || cState.open.selected < 0 || Date.now() - cState.open.timestamp < view.state.facet(completionConfig).interactionDelay)
13311
- return false;
13312
- if (!cState.open.disabled)
13313
- applyCompletion(view, cState.open.options[cState.open.selected]);
13314
- return true;
13315
- };
13316
- var startCompletion = (view) => {
13317
- let cState = view.state.field(completionState, false);
13318
- if (!cState)
13319
- return false;
13320
- view.dispatch({ effects: startCompletionEffect.of(true) });
13321
- return true;
13322
- };
13323
- var closeCompletion = (view) => {
13324
- let cState = view.state.field(completionState, false);
13325
- if (!cState || !cState.active.some(
13326
- (a) => a.state != 0
13327
- /* State.Inactive */
13328
- ))
13329
- return false;
13330
- view.dispatch({ effects: closeCompletionEffect.of(null) });
13331
- return true;
13332
- };
13333
- var RunningQuery = class {
13334
- constructor(active, context) {
13335
- this.active = active;
13336
- this.context = context;
13337
- this.time = Date.now();
13338
- this.updates = [];
13339
- this.done = void 0;
13340
- }
13341
- };
13342
- var DebounceTime = 50;
13343
- var MaxUpdateCount = 50;
13344
- var MinAbortTime = 1e3;
13345
- var completionPlugin = /* @__PURE__ */ ViewPlugin.fromClass(class {
13346
- constructor(view) {
13347
- this.view = view;
13348
- this.debounceUpdate = -1;
13349
- this.running = [];
13350
- this.debounceAccept = -1;
13351
- this.composing = 0;
13352
- for (let active of view.state.field(completionState).active)
13353
- if (active.state == 1)
13354
- this.startQuery(active);
13355
- }
13356
- update(update) {
13357
- let cState = update.state.field(completionState);
13358
- if (!update.selectionSet && !update.docChanged && update.startState.field(completionState) == cState)
13359
- return;
13360
- let doesReset = update.transactions.some((tr) => {
13361
- return (tr.selection || tr.docChanged) && !getUserEvent(tr);
13362
- });
13363
- for (let i = 0; i < this.running.length; i++) {
13364
- let query = this.running[i];
13365
- if (doesReset || query.updates.length + update.transactions.length > MaxUpdateCount && Date.now() - query.time > MinAbortTime) {
13366
- for (let handler of query.context.abortListeners) {
13367
- try {
13368
- handler();
13369
- } catch (e) {
13370
- logException(this.view.state, e);
13371
- }
13372
- }
13373
- query.context.abortListeners = null;
13374
- this.running.splice(i--, 1);
13375
- } else {
13376
- query.updates.push(...update.transactions);
13377
- }
13378
- }
13379
- if (this.debounceUpdate > -1)
13380
- clearTimeout(this.debounceUpdate);
13381
- this.debounceUpdate = cState.active.some((a) => a.state == 1 && !this.running.some((q) => q.active.source == a.source)) ? setTimeout(() => this.startUpdate(), DebounceTime) : -1;
13382
- if (this.composing != 0)
13383
- for (let tr of update.transactions) {
13384
- if (getUserEvent(tr) == "input")
13385
- this.composing = 2;
13386
- else if (this.composing == 2 && tr.selection)
13387
- this.composing = 3;
13388
- }
13389
- }
13390
- startUpdate() {
13391
- this.debounceUpdate = -1;
13392
- let { state } = this.view, cState = state.field(completionState);
13393
- for (let active of cState.active) {
13394
- if (active.state == 1 && !this.running.some((r) => r.active.source == active.source))
13395
- this.startQuery(active);
13396
- }
13397
- }
13398
- startQuery(active) {
13399
- let { state } = this.view, pos = cur(state);
13400
- let context = new CompletionContext(state, pos, active.explicitPos == pos);
13401
- let pending = new RunningQuery(active, context);
13402
- this.running.push(pending);
13403
- Promise.resolve(active.source(context)).then((result) => {
13404
- if (!pending.context.aborted) {
13405
- pending.done = result || null;
13406
- this.scheduleAccept();
13407
- }
13408
- }, (err) => {
13409
- this.view.dispatch({ effects: closeCompletionEffect.of(null) });
13410
- logException(this.view.state, err);
13411
- });
13412
- }
13413
- scheduleAccept() {
13414
- if (this.running.every((q) => q.done !== void 0))
13415
- this.accept();
13416
- else if (this.debounceAccept < 0)
13417
- this.debounceAccept = setTimeout(() => this.accept(), DebounceTime);
13418
- }
13419
- // For each finished query in this.running, try to create a result
13420
- // or, if appropriate, restart the query.
13421
- accept() {
13422
- var _a2;
13423
- if (this.debounceAccept > -1)
13424
- clearTimeout(this.debounceAccept);
13425
- this.debounceAccept = -1;
13426
- let updated = [];
13427
- let conf = this.view.state.facet(completionConfig);
13428
- for (let i = 0; i < this.running.length; i++) {
13429
- let query = this.running[i];
13430
- if (query.done === void 0)
13431
- continue;
13432
- this.running.splice(i--, 1);
13433
- if (query.done) {
13434
- let active = new ActiveResult(query.active.source, query.active.explicitPos, query.done, query.done.from, (_a2 = query.done.to) !== null && _a2 !== void 0 ? _a2 : cur(query.updates.length ? query.updates[0].startState : this.view.state));
13435
- for (let tr of query.updates)
13436
- active = active.update(tr, conf);
13437
- if (active.hasResult()) {
13438
- updated.push(active);
13439
- continue;
13440
- }
13441
- }
13442
- let current = this.view.state.field(completionState).active.find((a) => a.source == query.active.source);
13443
- if (current && current.state == 1) {
13444
- if (query.done == null) {
13445
- let active = new ActiveSource(
13446
- query.active.source,
13447
- 0
13448
- /* State.Inactive */
13449
- );
13450
- for (let tr of query.updates)
13451
- active = active.update(tr, conf);
13452
- if (active.state != 1)
13453
- updated.push(active);
13454
- } else {
13455
- this.startQuery(current);
13456
- }
13457
- }
13458
- }
13459
- if (updated.length)
13460
- this.view.dispatch({ effects: setActiveEffect.of(updated) });
13461
- }
13462
- }, {
13463
- eventHandlers: {
13464
- blur() {
13465
- let state = this.view.state.field(completionState, false);
13466
- if (state && state.tooltip && this.view.state.facet(completionConfig).closeOnBlur)
13467
- this.view.dispatch({ effects: closeCompletionEffect.of(null) });
13468
- },
13469
- compositionstart() {
13470
- this.composing = 1;
13471
- },
13472
- compositionend() {
13473
- if (this.composing == 3) {
13474
- setTimeout(() => this.view.dispatch({ effects: startCompletionEffect.of(false) }), 20);
13475
- }
13476
- this.composing = 0;
13477
- }
13478
- }
13479
- });
13480
13724
  var baseTheme2 = /* @__PURE__ */ EditorView.baseTheme({
13481
13725
  ".cm-tooltip.cm-tooltip-autocomplete": {
13482
13726
  "& > ul": {
@@ -13491,12 +13735,20 @@ var baseTheme2 = /* @__PURE__ */ EditorView.baseTheme({
13491
13735
  listStyle: "none",
13492
13736
  margin: 0,
13493
13737
  padding: 0,
13738
+ "& > li, & > completion-section": {
13739
+ padding: "1px 3px",
13740
+ lineHeight: 1.2
13741
+ },
13494
13742
  "& > li": {
13495
13743
  overflowX: "hidden",
13496
13744
  textOverflow: "ellipsis",
13497
- cursor: "pointer",
13498
- padding: "1px 3px",
13499
- lineHeight: 1.2
13745
+ cursor: "pointer"
13746
+ },
13747
+ "& > completion-section": {
13748
+ display: "list-item",
13749
+ borderBottom: "1px solid silver",
13750
+ paddingLeft: "0.5em",
13751
+ opacity: 0.7
13500
13752
  }
13501
13753
  }
13502
13754
  },
@@ -13603,11 +13855,6 @@ var closeBracketEffect = /* @__PURE__ */ StateEffect.define({
13603
13855
  return mapped == null ? void 0 : mapped;
13604
13856
  }
13605
13857
  });
13606
- var skipBracketEffect = /* @__PURE__ */ StateEffect.define({
13607
- map(value, mapping) {
13608
- return mapping.mapPos(value);
13609
- }
13610
- });
13611
13858
  var closedBracket = /* @__PURE__ */ new class extends RangeValue {
13612
13859
  }();
13613
13860
  closedBracket.startSide = 1;
@@ -13624,12 +13871,9 @@ var bracketState = /* @__PURE__ */ StateField.define({
13624
13871
  value = RangeSet.empty;
13625
13872
  }
13626
13873
  value = value.map(tr.changes);
13627
- for (let effect of tr.effects) {
13874
+ for (let effect of tr.effects)
13628
13875
  if (effect.is(closeBracketEffect))
13629
13876
  value = value.update({ add: [closedBracket.range(effect.value, effect.value + 1)] });
13630
- else if (effect.is(skipBracketEffect))
13631
- value = value.update({ filter: (from) => from != effect.value });
13632
- }
13633
13877
  return value;
13634
13878
  }
13635
13879
  });
@@ -13706,15 +13950,17 @@ function handleOpen(state, open, close, closeBefore) {
13706
13950
  });
13707
13951
  }
13708
13952
  function handleClose(state, _open, close) {
13709
- let dont = null, moved = state.selection.ranges.map((range) => {
13953
+ let dont = null, changes = state.changeByRange((range) => {
13710
13954
  if (range.empty && nextChar(state.doc, range.head) == close)
13711
- return EditorSelection.cursor(range.head + close.length);
13712
- return dont = range;
13955
+ return {
13956
+ changes: { from: range.head, to: range.head + close.length, insert: close },
13957
+ range: EditorSelection.cursor(range.head + close.length)
13958
+ };
13959
+ return dont = { range };
13713
13960
  });
13714
- return dont ? null : state.update({
13715
- selection: EditorSelection.create(moved, state.selection.mainIndex),
13961
+ return dont ? null : state.update(changes, {
13716
13962
  scrollIntoView: true,
13717
- effects: state.selection.ranges.map(({ from }) => skipBracketEffect.of(from))
13963
+ userEvent: "input.type"
13718
13964
  });
13719
13965
  }
13720
13966
  function handleSame(state, token, allowTriple, config2) {
@@ -13736,9 +13982,10 @@ function handleSame(state, token, allowTriple, config2) {
13736
13982
  };
13737
13983
  } else if (closedBracketAt(state, pos)) {
13738
13984
  let isTriple = allowTriple && state.sliceDoc(pos, pos + token.length * 3) == token + token + token;
13985
+ let content = isTriple ? token + token + token : token;
13739
13986
  return {
13740
- range: EditorSelection.cursor(pos + token.length * (isTriple ? 3 : 1)),
13741
- effects: skipBracketEffect.of(pos)
13987
+ changes: { from: pos, to: pos + content.length, insert: content },
13988
+ range: EditorSelection.cursor(pos + content.length)
13742
13989
  };
13743
13990
  }
13744
13991
  } else if (allowTriple && state.sliceDoc(pos - 2 * token.length, pos) == token + token && (start = canStartStringAt(state, pos - 2 * token.length, stringPrefixes)) > -1 && nodeStart(state, start)) {
@@ -13822,7 +14069,7 @@ var completionKeymapExt = /* @__PURE__ */ Prec.highest(/* @__PURE__ */ keymap.co
13822
14069
  // ../../node_modules/@codemirror/commands/dist/index.js
13823
14070
  var import_common2 = require("@lezer/common");
13824
14071
  var toggleComment = (target) => {
13825
- let { state } = target, line = state.doc.lineAt(state.selection.main.head), config2 = getConfig(target.state, line.from);
14072
+ let { state } = target, line = state.doc.lineAt(state.selection.main.from), config2 = getConfig(target.state, line.from);
13826
14073
  return config2.line ? toggleLineComment(target) : config2.block ? toggleBlockCommentByLine(target) : false;
13827
14074
  };
13828
14075
  function command(f, option) {
@@ -13899,7 +14146,7 @@ function selectedLineRanges(state) {
13899
14146
  if (last >= 0 && ranges[last].to > fromLine.from)
13900
14147
  ranges[last].to = toLine.to;
13901
14148
  else
13902
- ranges.push({ from: fromLine.from, to: toLine.to });
14149
+ ranges.push({ from: fromLine.from + /^\s*/.exec(fromLine.text)[0].length, to: toLine.to });
13903
14150
  }
13904
14151
  return ranges;
13905
14152
  }
@@ -13930,13 +14177,13 @@ function changeLineComment(option, state, ranges = state.selection.ranges) {
13930
14177
  let prevLine = -1;
13931
14178
  for (let { from, to } of ranges) {
13932
14179
  let startI = lines.length, minIndent = 1e9;
14180
+ let token = getConfig(state, from).line;
14181
+ if (!token)
14182
+ continue;
13933
14183
  for (let pos = from; pos <= to; ) {
13934
14184
  let line = state.doc.lineAt(pos);
13935
14185
  if (line.from > prevLine && (from == to || to > line.from)) {
13936
14186
  prevLine = line.from;
13937
- let token = getConfig(state, line.from).line;
13938
- if (!token)
13939
- continue;
13940
14187
  let indent = /^\s*/.exec(line.text)[0].length;
13941
14188
  let empty = indent == line.length;
13942
14189
  let comment = line.text.slice(indent, indent + token.length) == token ? indent : -1;