@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/esm/index.js CHANGED
@@ -14,11 +14,6 @@ var __privateAdd = (obj, member, value) => {
14
14
 
15
15
  // ../../node_modules/@codemirror/state/dist/index.js
16
16
  var Text = class {
17
- /**
18
- @internal
19
- */
20
- constructor() {
21
- }
22
17
  /**
23
18
  Get the line description around the given position.
24
19
  */
@@ -134,7 +129,8 @@ var Text = class {
134
129
  return new LineCursor(inner);
135
130
  }
136
131
  /**
137
- @internal
132
+ Return the document as a string, using newline characters to
133
+ separate lines.
138
134
  */
139
135
  toString() {
140
136
  return this.sliceString(0);
@@ -149,6 +145,11 @@ var Text = class {
149
145
  return lines;
150
146
  }
151
147
  /**
148
+ @internal
149
+ */
150
+ constructor() {
151
+ }
152
+ /**
152
153
  Create a `Text` instance for the given array of lines.
153
154
  */
154
155
  static of(text) {
@@ -1966,7 +1967,10 @@ var StateEffect = class {
1966
1967
  }
1967
1968
  /**
1968
1969
  Define a new effect type. The type parameter indicates the type
1969
- of values that his effect holds.
1970
+ of values that his effect holds. It should be a type that
1971
+ doesn't include `undefined`, since that is used in
1972
+ [mapping](https://codemirror.net/6/docs/ref/#state.StateEffect.map) to indicate that an effect is
1973
+ removed.
1970
1974
  */
1971
1975
  static define(spec = {}) {
1972
1976
  return new StateEffectType(spec.map || ((v) => v));
@@ -2910,6 +2914,18 @@ function lazySort(ranges) {
2910
2914
  }
2911
2915
  RangeSet.empty.nextLayer = RangeSet.empty;
2912
2916
  var RangeSetBuilder = class {
2917
+ finishChunk(newArrays) {
2918
+ this.chunks.push(new Chunk(this.from, this.to, this.value, this.maxPoint));
2919
+ this.chunkPos.push(this.chunkStart);
2920
+ this.chunkStart = -1;
2921
+ this.setMaxPoint = Math.max(this.setMaxPoint, this.maxPoint);
2922
+ this.maxPoint = -1;
2923
+ if (newArrays) {
2924
+ this.from = [];
2925
+ this.to = [];
2926
+ this.value = [];
2927
+ }
2928
+ }
2913
2929
  /**
2914
2930
  Create an empty builder.
2915
2931
  */
@@ -2927,18 +2943,6 @@ var RangeSetBuilder = class {
2927
2943
  this.setMaxPoint = -1;
2928
2944
  this.nextLayer = null;
2929
2945
  }
2930
- finishChunk(newArrays) {
2931
- this.chunks.push(new Chunk(this.from, this.to, this.value, this.maxPoint));
2932
- this.chunkPos.push(this.chunkStart);
2933
- this.chunkStart = -1;
2934
- this.setMaxPoint = Math.max(this.setMaxPoint, this.maxPoint);
2935
- this.maxPoint = -1;
2936
- if (newArrays) {
2937
- this.from = [];
2938
- this.to = [];
2939
- this.value = [];
2940
- }
2941
- }
2942
2946
  /**
2943
2947
  Add a range. Ranges should be added in sorted (by `from` and
2944
2948
  `value.startSide`) order.
@@ -3289,7 +3293,7 @@ function compare(a, startA, b, startB, length2, comparator) {
3289
3293
  let diff = a.to + dPos - b.to || a.endSide - b.endSide;
3290
3294
  let end = diff < 0 ? a.to + dPos : b.to, clipEnd = Math.min(end, endB);
3291
3295
  if (a.point || b.point) {
3292
- if (!(a.point && b.point && (a.point == b.point || a.point.eq(b.point)) && sameValues(a.activeForPoint(a.to + dPos), b.activeForPoint(b.to))))
3296
+ if (!(a.point && b.point && (a.point == b.point || a.point.eq(b.point)) && sameValues(a.activeForPoint(a.to), b.activeForPoint(b.to))))
3293
3297
  comparator.comparePoint(pos, clipEnd, a.point, b.point);
3294
3298
  } else {
3295
3299
  if (clipEnd > pos && !sameValues(a.active, b.active))
@@ -3429,19 +3433,21 @@ var StyleModule = class {
3429
3433
  (root[SET] || new StyleSet(root)).mount(Array.isArray(modules) ? modules : [modules]);
3430
3434
  }
3431
3435
  };
3432
- var adoptedSet = null;
3436
+ var adoptedSet = /* @__PURE__ */ new Map();
3433
3437
  var StyleSet = class {
3434
3438
  constructor(root) {
3435
- if (!root.head && root.adoptedStyleSheets && typeof CSSStyleSheet != "undefined") {
3436
- if (adoptedSet) {
3437
- root.adoptedStyleSheets = [adoptedSet.sheet, ...root.adoptedStyleSheets];
3438
- return root[SET] = adoptedSet;
3439
- }
3440
- this.sheet = new CSSStyleSheet();
3439
+ let doc2 = root.ownerDocument || root, win = doc2.defaultView;
3440
+ if (!root.head && root.adoptedStyleSheets && win.CSSStyleSheet) {
3441
+ let adopted = adoptedSet.get(doc2);
3442
+ if (adopted) {
3443
+ root.adoptedStyleSheets = [adopted.sheet, ...root.adoptedStyleSheets];
3444
+ return root[SET] = adopted;
3445
+ }
3446
+ this.sheet = new win.CSSStyleSheet();
3441
3447
  root.adoptedStyleSheets = [this.sheet, ...root.adoptedStyleSheets];
3442
- adoptedSet = this;
3448
+ adoptedSet.set(doc2, this);
3443
3449
  } else {
3444
- this.styleTag = (root.ownerDocument || root).createElement("style");
3450
+ this.styleTag = doc2.createElement("style");
3445
3451
  let target = root.head || root;
3446
3452
  target.insertBefore(this.styleTag, target.firstChild);
3447
3453
  }
@@ -3479,7 +3485,7 @@ var StyleSet = class {
3479
3485
  }
3480
3486
  };
3481
3487
 
3482
- // ../../node_modules/w3c-keyname/index.es.js
3488
+ // ../../node_modules/w3c-keyname/index.js
3483
3489
  var base = {
3484
3490
  8: "Backspace",
3485
3491
  9: "Tab",
@@ -3560,11 +3566,8 @@ var shift = {
3560
3566
  221: "}",
3561
3567
  222: '"'
3562
3568
  };
3563
- var chrome = typeof navigator != "undefined" && /Chrome\/(\d+)/.exec(navigator.userAgent);
3564
- var gecko = typeof navigator != "undefined" && /Gecko\/\d+/.test(navigator.userAgent);
3565
3569
  var mac = typeof navigator != "undefined" && /Mac/.test(navigator.platform);
3566
3570
  var ie = typeof navigator != "undefined" && /MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);
3567
- var brokenModifierNames = mac || chrome && +chrome[1] < 57;
3568
3571
  for (i = 0; i < 10; i++)
3569
3572
  base[48 + i] = base[96 + i] = String(i);
3570
3573
  var i;
@@ -3581,7 +3584,7 @@ for (code in base)
3581
3584
  shift[code] = base[code];
3582
3585
  var code;
3583
3586
  function keyName(event) {
3584
- var ignoreKey = brokenModifierNames && (event.ctrlKey || event.altKey || event.metaKey) || ie && event.shiftKey && event.key && event.key.length == 1 || event.key == "Unidentified";
3587
+ var ignoreKey = mac && event.metaKey && event.shiftKey && !event.ctrlKey && !event.altKey || ie && event.shiftKey && event.key && event.key.length == 1 || event.key == "Unidentified";
3585
3588
  var name = !ignoreKey && event.key || (event.shiftKey ? shift : base)[event.keyCode] || event.key || "Unidentified";
3586
3589
  if (name == "Esc")
3587
3590
  name = "Escape";
@@ -3669,7 +3672,6 @@ function scanFor(node, off, targetNode, targetOff, dir) {
3669
3672
  function maxOffset(node) {
3670
3673
  return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length;
3671
3674
  }
3672
- var Rect0 = { left: 0, right: 0, top: 0, bottom: 0 };
3673
3675
  function flattenRect(rect, left) {
3674
3676
  let x = left ? rect.left : rect.right;
3675
3677
  return { left: x, right: x, top: rect.top, bottom: rect.bottom };
@@ -3797,7 +3799,8 @@ var DOMSelectionState = class {
3797
3799
  return this.anchorNode == domSel.anchorNode && this.anchorOffset == domSel.anchorOffset && this.focusNode == domSel.focusNode && this.focusOffset == domSel.focusOffset;
3798
3800
  }
3799
3801
  setRange(range) {
3800
- this.set(range.anchorNode, range.anchorOffset, range.focusNode, range.focusOffset);
3802
+ let { anchorNode, focusNode } = range;
3803
+ this.set(anchorNode, Math.min(range.anchorOffset, anchorNode ? maxOffset(anchorNode) : 0), focusNode, Math.min(range.focusOffset, focusNode ? maxOffset(focusNode) : 0));
3801
3804
  }
3802
3805
  set(anchorNode, anchorOffset, focusNode, focusOffset) {
3803
3806
  this.anchorNode = anchorNode;
@@ -3868,6 +3871,7 @@ function atElementStart(doc2, selection) {
3868
3871
  let node = selection.focusNode, offset = selection.focusOffset;
3869
3872
  if (!node || selection.anchorNode != node || selection.anchorOffset != offset)
3870
3873
  return false;
3874
+ offset = Math.min(offset, maxOffset(node));
3871
3875
  for (; ; ) {
3872
3876
  if (offset) {
3873
3877
  if (node.nodeType != 1)
@@ -3928,12 +3932,6 @@ var ContentView = class {
3928
3932
  posAfter(view) {
3929
3933
  return this.posBefore(view) + view.length;
3930
3934
  }
3931
- // Will return a rectangle directly before (when side < 0), after
3932
- // (side > 0) or directly on (when the browser supports it) the
3933
- // given position.
3934
- coordsAt(_pos, _side) {
3935
- return null;
3936
- }
3937
3935
  sync(view, track) {
3938
3936
  if (this.dirty & 2) {
3939
3937
  let parent = this.dom;
@@ -4106,6 +4104,9 @@ var ContentView = class {
4106
4104
  get isWidget() {
4107
4105
  return false;
4108
4106
  }
4107
+ get isHidden() {
4108
+ return false;
4109
+ }
4109
4110
  merge(from, to, source, hasStart, openStart, openEnd) {
4110
4111
  return false;
4111
4112
  }
@@ -4223,8 +4224,8 @@ var ie_edge = /* @__PURE__ */ /Edge\/(\d+)/.exec(nav.userAgent);
4223
4224
  var ie_upto10 = /* @__PURE__ */ /MSIE \d/.test(nav.userAgent);
4224
4225
  var ie_11up = /* @__PURE__ */ /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(nav.userAgent);
4225
4226
  var ie2 = !!(ie_upto10 || ie_11up || ie_edge);
4226
- var gecko2 = !ie2 && /* @__PURE__ */ /gecko\/(\d+)/i.test(nav.userAgent);
4227
- var chrome2 = !ie2 && /* @__PURE__ */ /Chrome\/(\d+)/.exec(nav.userAgent);
4227
+ var gecko = !ie2 && /* @__PURE__ */ /gecko\/(\d+)/i.test(nav.userAgent);
4228
+ var chrome = !ie2 && /* @__PURE__ */ /Chrome\/(\d+)/.exec(nav.userAgent);
4228
4229
  var webkit = "webkitFontSmoothing" in doc.documentElement.style;
4229
4230
  var safari = !ie2 && /* @__PURE__ */ /Apple Computer/.test(nav.vendor);
4230
4231
  var ios = safari && (/* @__PURE__ */ /Mobile\/\w+/.test(nav.userAgent) || nav.maxTouchPoints > 2);
@@ -4234,10 +4235,10 @@ var browser = {
4234
4235
  linux: /* @__PURE__ */ /Linux|X11/.test(nav.platform),
4235
4236
  ie: ie2,
4236
4237
  ie_version: ie_upto10 ? doc.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0,
4237
- gecko: gecko2,
4238
- gecko_version: gecko2 ? +(/* @__PURE__ */ /Firefox\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
4239
- chrome: !!chrome2,
4240
- chrome_version: chrome2 ? +chrome2[1] : 0,
4238
+ gecko,
4239
+ gecko_version: gecko ? +(/* @__PURE__ */ /Firefox\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
4240
+ chrome: !!chrome,
4241
+ chrome_version: chrome ? +chrome[1] : 0,
4241
4242
  ios,
4242
4243
  android: /* @__PURE__ */ /Android\b/.test(nav.userAgent),
4243
4244
  webkit,
@@ -4383,7 +4384,7 @@ function textCoords(text, pos, side) {
4383
4384
  }
4384
4385
  let rects = textRange(text, from, to).getClientRects();
4385
4386
  if (!rects.length)
4386
- return Rect0;
4387
+ return null;
4387
4388
  let rect = rects[(flatten2 ? flatten2 < 0 : side >= 0) ? 0 : rects.length - 1];
4388
4389
  if (browser.safari && !flatten2 && rect.width == 0)
4389
4390
  rect = Array.prototype.find.call(rects, (r) => r.width) || rect;
@@ -4424,15 +4425,14 @@ var WidgetView = class extends ContentView {
4424
4425
  return true;
4425
4426
  }
4426
4427
  become(other) {
4427
- if (other.length == this.length && other instanceof WidgetView && other.side == this.side) {
4428
- if (this.widget.constructor == other.widget.constructor) {
4429
- if (!this.widget.eq(other.widget))
4430
- this.markDirty(true);
4431
- if (this.dom && !this.prevWidget)
4432
- this.prevWidget = this.widget;
4433
- this.widget = other.widget;
4434
- return true;
4435
- }
4428
+ if (other instanceof WidgetView && other.side == this.side && this.widget.constructor == other.widget.constructor) {
4429
+ if (!this.widget.compare(other.widget))
4430
+ this.markDirty(true);
4431
+ if (this.dom && !this.prevWidget)
4432
+ this.prevWidget = this.widget;
4433
+ this.widget = other.widget;
4434
+ this.length = other.length;
4435
+ return true;
4436
4436
  }
4437
4437
  return false;
4438
4438
  }
@@ -4452,21 +4452,25 @@ var WidgetView = class extends ContentView {
4452
4452
  return text ? text.slice(start, start + this.length) : Text.empty;
4453
4453
  }
4454
4454
  domAtPos(pos) {
4455
- return pos == 0 ? DOMPos.before(this.dom) : DOMPos.after(this.dom, pos == this.length);
4455
+ return (this.length ? pos == 0 : this.side > 0) ? DOMPos.before(this.dom) : DOMPos.after(this.dom, pos == this.length);
4456
4456
  }
4457
4457
  domBoundsAround() {
4458
4458
  return null;
4459
4459
  }
4460
4460
  coordsAt(pos, side) {
4461
+ let custom = this.widget.coordsAt(this.dom, pos, side);
4462
+ if (custom)
4463
+ return custom;
4461
4464
  let rects = this.dom.getClientRects(), rect = null;
4462
4465
  if (!rects.length)
4463
- return Rect0;
4464
- for (let i = pos > 0 ? rects.length - 1 : 0; ; i += pos > 0 ? -1 : 1) {
4466
+ return null;
4467
+ let fromBack = this.side ? this.side < 0 : pos > 0;
4468
+ for (let i = fromBack ? rects.length - 1 : 0; ; i += fromBack ? -1 : 1) {
4465
4469
  rect = rects[i];
4466
4470
  if (pos > 0 ? i == 0 : i == rects.length - 1 || rect.top < rect.bottom)
4467
4471
  break;
4468
4472
  }
4469
- return this.length ? rect : flattenRect(rect, this.side > 0);
4473
+ return this.length ? rect : flattenRect(rect, !fromBack);
4470
4474
  }
4471
4475
  get isEditable() {
4472
4476
  return false;
@@ -4474,6 +4478,9 @@ var WidgetView = class extends ContentView {
4474
4478
  get isWidget() {
4475
4479
  return true;
4476
4480
  }
4481
+ get isHidden() {
4482
+ return this.widget.isHidden;
4483
+ }
4477
4484
  destroy() {
4478
4485
  super.destroy();
4479
4486
  if (this.dom)
@@ -4485,7 +4492,7 @@ var CompositionView = class extends WidgetView {
4485
4492
  let { topView, text } = this.widget;
4486
4493
  if (!topView)
4487
4494
  return new DOMPos(text, Math.min(pos, text.nodeValue.length));
4488
- return scanCompositionTree(pos, 0, topView, text, (v, p) => v.domAtPos(p), (p) => new DOMPos(text, Math.min(p, text.nodeValue.length)));
4495
+ 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)));
4489
4496
  }
4490
4497
  sync() {
4491
4498
  this.setDOM(this.widget.toDOM());
@@ -4494,7 +4501,7 @@ var CompositionView = class extends WidgetView {
4494
4501
  let { topView, text } = this.widget;
4495
4502
  if (!topView)
4496
4503
  return Math.min(offset, this.length);
4497
- return posFromDOMInCompositionTree(node, offset, topView, text);
4504
+ return posFromDOMInCompositionTree(node, offset, topView, text, this.length - topView.length);
4498
4505
  }
4499
4506
  ignoreMutation() {
4500
4507
  return false;
@@ -4506,7 +4513,7 @@ var CompositionView = class extends WidgetView {
4506
4513
  let { topView, text } = this.widget;
4507
4514
  if (!topView)
4508
4515
  return textCoords(text, pos, side);
4509
- return scanCompositionTree(pos, side, topView, text, (v, pos2, side2) => v.coordsAt(pos2, side2), (pos2, side2) => textCoords(text, pos2, side2));
4516
+ return scanCompositionTree(pos, side, topView, text, this.length - topView.length, (v, pos2, side2) => v.coordsAt(pos2, side2), (text2, pos2, side2) => textCoords(text2, pos2, side2));
4510
4517
  }
4511
4518
  destroy() {
4512
4519
  var _a2;
@@ -4520,39 +4527,87 @@ var CompositionView = class extends WidgetView {
4520
4527
  return true;
4521
4528
  }
4522
4529
  };
4523
- function scanCompositionTree(pos, side, view, text, enterView, fromText) {
4530
+ function scanCompositionTree(pos, side, view, text, dLen, enterView, fromText) {
4524
4531
  if (view instanceof MarkView) {
4525
4532
  for (let child = view.dom.firstChild; child; child = child.nextSibling) {
4526
4533
  let desc = ContentView.get(child);
4527
- if (!desc)
4528
- return fromText(pos, side);
4529
- let hasComp = contains(child, text);
4530
- let len = desc.length + (hasComp ? text.nodeValue.length : 0);
4531
- if (pos < len || pos == len && desc.getSide() <= 0)
4532
- return hasComp ? scanCompositionTree(pos, side, desc, text, enterView, fromText) : enterView(desc, pos, side);
4533
- pos -= len;
4534
+ if (!desc) {
4535
+ let inner = scanCompositionNode(pos, side, child, fromText);
4536
+ if (typeof inner != "number")
4537
+ return inner;
4538
+ pos = inner;
4539
+ } else {
4540
+ let hasComp = contains(child, text);
4541
+ let len = desc.length + (hasComp ? dLen : 0);
4542
+ if (pos < len || pos == len && desc.getSide() <= 0)
4543
+ return hasComp ? scanCompositionTree(pos, side, desc, text, dLen, enterView, fromText) : enterView(desc, pos, side);
4544
+ pos -= len;
4545
+ }
4534
4546
  }
4535
4547
  return enterView(view, view.length, -1);
4536
4548
  } else if (view.dom == text) {
4537
- return fromText(pos, side);
4549
+ return fromText(text, pos, side);
4538
4550
  } else {
4539
4551
  return enterView(view, pos, side);
4540
4552
  }
4541
4553
  }
4542
- function posFromDOMInCompositionTree(node, offset, view, text) {
4554
+ function scanCompositionNode(pos, side, node, fromText) {
4555
+ if (node.nodeType == 3) {
4556
+ let len = node.nodeValue.length;
4557
+ if (pos <= len)
4558
+ return fromText(node, pos, side);
4559
+ pos -= len;
4560
+ } else if (node.nodeType == 1 && node.contentEditable != "false") {
4561
+ for (let child = node.firstChild; child; child = child.nextSibling) {
4562
+ let inner = scanCompositionNode(pos, side, child, fromText);
4563
+ if (typeof inner != "number")
4564
+ return inner;
4565
+ pos = inner;
4566
+ }
4567
+ }
4568
+ return pos;
4569
+ }
4570
+ function posFromDOMInCompositionTree(node, offset, view, text, dLen) {
4543
4571
  if (view instanceof MarkView) {
4544
4572
  let pos = 0;
4545
- for (let child of view.children) {
4546
- let hasComp = contains(child.dom, text);
4547
- if (contains(child.dom, node))
4548
- return pos + (hasComp ? posFromDOMInCompositionTree(node, offset, child, text) : child.localPosFromDOM(node, offset));
4549
- pos += hasComp ? text.nodeValue.length : child.length;
4573
+ for (let child = view.dom.firstChild; child; child = child.nextSibling) {
4574
+ let childView = ContentView.get(child);
4575
+ if (childView) {
4576
+ let hasComp = contains(child, text);
4577
+ if (contains(child, node))
4578
+ return pos + (hasComp ? posFromDOMInCompositionTree(node, offset, childView, text, dLen) : childView.localPosFromDOM(node, offset));
4579
+ pos += childView.length + (hasComp ? dLen : 0);
4580
+ } else {
4581
+ let inner = posFromDOMInOpaqueNode(node, offset, child);
4582
+ if (inner.result != null)
4583
+ return pos + inner.result;
4584
+ pos += inner.size;
4585
+ }
4550
4586
  }
4551
4587
  } else if (view.dom == text) {
4552
4588
  return Math.min(offset, text.nodeValue.length);
4553
4589
  }
4554
4590
  return view.localPosFromDOM(node, offset);
4555
4591
  }
4592
+ function posFromDOMInOpaqueNode(node, offset, target) {
4593
+ if (target.nodeType == 3) {
4594
+ return node == target ? { result: offset } : { size: target.nodeValue.length };
4595
+ } else if (target.nodeType == 1 && target.contentEditable != "false") {
4596
+ let pos = 0;
4597
+ for (let child = target.firstChild, i = 0; ; child = child.nextSibling, i++) {
4598
+ if (node == target && i == offset)
4599
+ return { result: pos };
4600
+ if (!child)
4601
+ return { size: pos };
4602
+ let inner = posFromDOMInOpaqueNode(node, offset, child);
4603
+ if (inner.result != null)
4604
+ return { result: offset + inner.result };
4605
+ pos += inner.size;
4606
+ }
4607
+ } else {
4608
+ return target.contains(node) ? { result: 0 } : { size: 0 };
4609
+ }
4610
+ }
4556
4611
  var WidgetBufferView = class extends ContentView {
4557
4612
  constructor(side) {
4558
4613
  super();
@@ -4591,38 +4646,16 @@ var WidgetBufferView = class extends ContentView {
4591
4646
  return null;
4592
4647
  }
4593
4648
  coordsAt(pos) {
4594
- let imgRect = this.dom.getBoundingClientRect();
4595
- let siblingRect = inlineSiblingRect(this, this.side > 0 ? -1 : 1);
4596
- return siblingRect && siblingRect.top < imgRect.bottom && siblingRect.bottom > imgRect.top ? { left: imgRect.left, right: imgRect.right, top: siblingRect.top, bottom: siblingRect.bottom } : imgRect;
4649
+ return this.dom.getBoundingClientRect();
4597
4650
  }
4598
4651
  get overrideDOMText() {
4599
4652
  return Text.empty;
4600
4653
  }
4654
+ get isHidden() {
4655
+ return true;
4656
+ }
4601
4657
  };
4602
4658
  TextView.prototype.children = WidgetView.prototype.children = WidgetBufferView.prototype.children = noChildren;
4603
- function inlineSiblingRect(view, side) {
4604
- let parent = view.parent, index = parent ? parent.children.indexOf(view) : -1;
4605
- while (parent && index >= 0) {
4606
- if (side < 0 ? index > 0 : index < parent.children.length) {
4607
- let next = parent.children[index + side];
4608
- if (next instanceof TextView) {
4609
- let nextRect = next.coordsAt(side < 0 ? next.length : 0, side);
4610
- if (nextRect)
4611
- return nextRect;
4612
- }
4613
- index += side;
4614
- } else if (parent instanceof MarkView && parent.parent) {
4615
- index = parent.parent.children.indexOf(parent) + (side < 0 ? 0 : 1);
4616
- parent = parent.parent;
4617
- } else {
4618
- let last = parent.dom.lastChild;
4619
- if (last && last.nodeName == "BR")
4620
- return last.getClientRects()[0];
4621
- break;
4622
- }
4623
- }
4624
- return void 0;
4625
- }
4626
4659
  function inlineDOMAtPos(parent, pos) {
4627
4660
  let dom = parent.dom, { children } = parent, i = 0;
4628
4661
  for (let off = 0; i < children.length; i++) {
@@ -4665,10 +4698,10 @@ function coordsInChildren(view, pos, side) {
4665
4698
  if (end >= pos2) {
4666
4699
  if (child.children.length) {
4667
4700
  scan(child, pos2 - off);
4668
- } else if (!after && (end > pos2 || off == end && child.getSide() > 0)) {
4701
+ } else if ((!after || after.isHidden && side > 0) && (end > pos2 || off == end && child.getSide() > 0)) {
4669
4702
  after = child;
4670
4703
  afterPos = pos2 - off;
4671
- } else if (off < pos2 || off == end && child.getSide() < 0) {
4704
+ } else if (off < pos2 || off == end && child.getSide() < 0 && !child.isHidden) {
4672
4705
  before = child;
4673
4706
  beforePos = pos2 - off;
4674
4707
  }
@@ -4767,6 +4800,15 @@ var WidgetType = class {
4767
4800
  return -1;
4768
4801
  }
4769
4802
  /**
4803
+ For inline widgets that are displayed inline (as opposed to
4804
+ `inline-block`) and introduce line breaks (through `<br>` tags
4805
+ or textual newlines), this must indicate the amount of line
4806
+ breaks they introduce. Defaults to 0.
4807
+ */
4808
+ get lineBreaks() {
4809
+ return 0;
4810
+ }
4811
+ /**
4770
4812
  Can be used to configure which kinds of events inside the widget
4771
4813
  should be ignored by the editor. The default is to ignore all
4772
4814
  events.
@@ -4775,12 +4817,28 @@ var WidgetType = class {
4775
4817
  return true;
4776
4818
  }
4777
4819
  /**
4820
+ Override the way screen coordinates for positions at/in the
4821
+ widget are found. `pos` will be the offset into the widget, and
4822
+ `side` the side of the position that is being queried—less than
4823
+ zero for before, greater than zero for after, and zero for
4824
+ directly at that position.
4825
+ */
4826
+ coordsAt(dom, pos, side) {
4827
+ return null;
4828
+ }
4829
+ /**
4778
4830
  @internal
4779
4831
  */
4780
4832
  get customView() {
4781
4833
  return null;
4782
4834
  }
4783
4835
  /**
4836
+ @internal
4837
+ */
4838
+ get isHidden() {
4839
+ return false;
4840
+ }
4841
+ /**
4784
4842
  This is called when the an instance of the widget is removed
4785
4843
  from the editor view.
4786
4844
  */
@@ -4825,7 +4883,7 @@ var Decoration = class extends RangeValue {
4825
4883
  given position.
4826
4884
  */
4827
4885
  static widget(spec) {
4828
- let side = spec.side || 0, block = !!spec.block;
4886
+ let side = Math.max(-1e4, Math.min(1e4, spec.side || 0)), block = !!spec.block;
4829
4887
  side += block ? side > 0 ? 3e8 : -4e8 : side > 0 ? 1e8 : -1e8;
4830
4888
  return new PointDecoration(spec, side, side, block, spec.widget || null, false);
4831
4889
  }
@@ -4913,7 +4971,7 @@ var PointDecoration = class extends Decoration {
4913
4971
  return this.startSide < this.endSide ? BlockType.WidgetRange : this.startSide <= 0 ? BlockType.WidgetBefore : BlockType.WidgetAfter;
4914
4972
  }
4915
4973
  get heightRelevant() {
4916
- return this.block || !!this.widget && this.widget.estimatedHeight >= 5;
4974
+ return this.block || !!this.widget && (this.widget.estimatedHeight >= 5 || this.widget.lineBreaks > 0);
4917
4975
  }
4918
4976
  eq(other) {
4919
4977
  return other instanceof PointDecoration && widgetsEq(this.widget, other.widget) && this.block == other.block && this.startSide == other.startSide && this.endSide == other.endSide;
@@ -5145,13 +5203,14 @@ var BlockWidgetView = class extends ContentView {
5145
5203
  return null;
5146
5204
  }
5147
5205
  become(other) {
5148
- if (other instanceof BlockWidgetView && other.type == this.type && other.widget.constructor == this.widget.constructor) {
5149
- if (!other.widget.eq(this.widget))
5206
+ if (other instanceof BlockWidgetView && other.widget.constructor == this.widget.constructor) {
5207
+ if (!other.widget.compare(this.widget))
5150
5208
  this.markDirty(true);
5151
5209
  if (this.dom && !this.prevWidget)
5152
5210
  this.prevWidget = this.widget;
5153
5211
  this.widget = other.widget;
5154
5212
  this.length = other.length;
5213
+ this.type = other.type;
5155
5214
  this.breakAfter = other.breakAfter;
5156
5215
  return true;
5157
5216
  }
@@ -5169,6 +5228,9 @@ var BlockWidgetView = class extends ContentView {
5169
5228
  get isWidget() {
5170
5229
  return true;
5171
5230
  }
5231
+ coordsAt(pos, side) {
5232
+ return this.widget.coordsAt(this.dom, pos, side);
5233
+ }
5172
5234
  destroy() {
5173
5235
  super.destroy();
5174
5236
  if (this.dom)
@@ -5254,7 +5316,7 @@ var ContentBuilder = class {
5254
5316
  this.text.length - this.textOff,
5255
5317
  length2,
5256
5318
  512
5257
- /* T.Chunk */
5319
+ /* Chunk */
5258
5320
  );
5259
5321
  this.flushBuffer(active.slice(active.length - openStart));
5260
5322
  this.getLine().append(wrapMarks(new TextView(this.text.slice(this.textOff, this.textOff + take)), active), openStart);
@@ -5289,7 +5351,7 @@ var ContentBuilder = class {
5289
5351
  let cursorBefore = this.atCursorPos && !view.isEditable && openStart <= active.length && (from < to || deco.startSide > 0);
5290
5352
  let cursorAfter = !view.isEditable && (from < to || openStart > active.length || deco.startSide <= 0);
5291
5353
  let line = this.getLine();
5292
- if (this.pendingBuffer == 2 && !cursorBefore)
5354
+ if (this.pendingBuffer == 2 && !cursorBefore && !view.isEditable)
5293
5355
  this.pendingBuffer = 0;
5294
5356
  this.flushBuffer(active);
5295
5357
  if (cursorBefore) {
@@ -5346,6 +5408,9 @@ var NullWidget = class extends WidgetType {
5346
5408
  updateDOM(elt) {
5347
5409
  return elt.nodeName.toLowerCase() == this.tag;
5348
5410
  }
5411
+ get isHidden() {
5412
+ return true;
5413
+ }
5349
5414
  };
5350
5415
  var clickAddsSelectionRange = /* @__PURE__ */ Facet.define();
5351
5416
  var dragMovesSelection$1 = /* @__PURE__ */ Facet.define();
@@ -5474,6 +5539,23 @@ var contentAttributes = /* @__PURE__ */ Facet.define();
5474
5539
  var decorations = /* @__PURE__ */ Facet.define();
5475
5540
  var atomicRanges = /* @__PURE__ */ Facet.define();
5476
5541
  var scrollMargins = /* @__PURE__ */ Facet.define();
5542
+ function getScrollMargins(view) {
5543
+ let left = 0, right = 0, top2 = 0, bottom = 0;
5544
+ for (let source of view.state.facet(scrollMargins)) {
5545
+ let m = source(view);
5546
+ if (m) {
5547
+ if (m.left != null)
5548
+ left = Math.max(left, m.left);
5549
+ if (m.right != null)
5550
+ right = Math.max(right, m.right);
5551
+ if (m.top != null)
5552
+ top2 = Math.max(top2, m.top);
5553
+ if (m.bottom != null)
5554
+ bottom = Math.max(bottom, m.bottom);
5555
+ }
5556
+ }
5557
+ return { left, right, top: top2, bottom };
5558
+ }
5477
5559
  var styleModule = /* @__PURE__ */ Facet.define();
5478
5560
  var ChangedRange = class {
5479
5561
  constructor(fromA, toA, fromB, toB) {
@@ -5833,12 +5915,13 @@ var DOMReader = class {
5833
5915
  let parent = start.parentNode;
5834
5916
  for (let cur2 = start; ; ) {
5835
5917
  this.findPointBefore(parent, cur2);
5918
+ let oldLen = this.text.length;
5836
5919
  this.readNode(cur2);
5837
5920
  let next = cur2.nextSibling;
5838
5921
  if (next == end)
5839
5922
  break;
5840
5923
  let view = ContentView.get(cur2), nextView = ContentView.get(next);
5841
- if (view && nextView ? view.breakAfter : (view ? view.breakAfter : isBlockElement(cur2)) || isBlockElement(next) && (cur2.nodeName != "BR" || cur2.cmIgnore))
5924
+ if (view && nextView ? view.breakAfter : (view ? view.breakAfter : isBlockElement(cur2)) || isBlockElement(next) && (cur2.nodeName != "BR" || cur2.cmIgnore) && this.text.length > oldLen)
5842
5925
  this.lineBreak();
5843
5926
  cur2 = next;
5844
5927
  }
@@ -5937,10 +6020,7 @@ var DocView = class extends ContentView {
5937
6020
  get length() {
5938
6021
  return this.view.state.doc.length;
5939
6022
  }
5940
- // Update the document view to a given state. scrollIntoView can be
5941
- // used as a hint to compute a new viewport that includes that
5942
- // position, if we know the editor is going to scroll that position
5943
- // into view.
6023
+ // Update the document view to a given state.
5944
6024
  update(update) {
5945
6025
  let changedRanges = update.changedRanges;
5946
6026
  if (this.minWidth > 0 && changedRanges.length) {
@@ -6010,14 +6090,16 @@ var DocView = class extends ContentView {
6010
6090
  updateSelection(mustRead = false, fromPointer = false) {
6011
6091
  if (mustRead || !this.view.observer.selectionRange.focusNode)
6012
6092
  this.view.observer.readSelectionRange();
6013
- if (!(fromPointer || this.mayControlSelection()))
6093
+ let activeElt = this.view.root.activeElement, focused = activeElt == this.dom;
6094
+ let selectionNotFocus = !focused && hasSelection(this.dom, this.view.observer.selectionRange) && !(activeElt && this.dom.contains(activeElt));
6095
+ if (!(focused || fromPointer || selectionNotFocus))
6014
6096
  return;
6015
6097
  let force = this.forceSelection;
6016
6098
  this.forceSelection = false;
6017
6099
  let main = this.view.state.selection.main;
6018
6100
  let anchor = this.domAtPos(main.anchor);
6019
6101
  let head = main.empty ? anchor : this.domAtPos(main.head);
6020
- if (browser.gecko && main.empty && betweenUneditable(anchor)) {
6102
+ if (browser.gecko && main.empty && !this.compositionDeco.size && betweenUneditable(anchor)) {
6021
6103
  let dummy = document.createTextNode("");
6022
6104
  this.view.observer.ignore(() => anchor.node.insertBefore(dummy, anchor.node.childNodes[anchor.offset] || null));
6023
6105
  anchor = head = new DOMPos(dummy, 0);
@@ -6060,6 +6142,11 @@ var DocView = class extends ContentView {
6060
6142
  rawSel.removeAllRanges();
6061
6143
  rawSel.addRange(range);
6062
6144
  }
6145
+ if (selectionNotFocus && this.view.root.activeElement == this.dom) {
6146
+ this.dom.blur();
6147
+ if (activeElt)
6148
+ activeElt.focus();
6149
+ }
6063
6150
  });
6064
6151
  this.view.observer.setSelectionRange(anchor, head);
6065
6152
  }
@@ -6091,10 +6178,6 @@ var DocView = class extends ContentView {
6091
6178
  if (view.docView.posFromDOM(newRange.anchorNode, newRange.anchorOffset) != cursor.from)
6092
6179
  sel.collapse(anchorNode, anchorOffset);
6093
6180
  }
6094
- mayControlSelection() {
6095
- let active = this.view.root.activeElement;
6096
- return active == this.dom || hasSelection(this.dom, this.view.observer.selectionRange) && !(active && this.dom.contains(active));
6097
- }
6098
6181
  nearest(dom) {
6099
6182
  for (let cur2 = dom; cur2; ) {
6100
6183
  let domView = ContentView.get(cur2);
@@ -6238,24 +6321,12 @@ var DocView = class extends ContentView {
6238
6321
  right: Math.max(rect.right, other.right),
6239
6322
  bottom: Math.max(rect.bottom, other.bottom)
6240
6323
  };
6241
- let mLeft = 0, mRight = 0, mTop = 0, mBottom = 0;
6242
- for (let margins of this.view.state.facet(scrollMargins).map((f) => f(this.view)))
6243
- if (margins) {
6244
- let { left, right, top: top2, bottom } = margins;
6245
- if (left != null)
6246
- mLeft = Math.max(mLeft, left);
6247
- if (right != null)
6248
- mRight = Math.max(mRight, right);
6249
- if (top2 != null)
6250
- mTop = Math.max(mTop, top2);
6251
- if (bottom != null)
6252
- mBottom = Math.max(mBottom, bottom);
6253
- }
6324
+ let margins = getScrollMargins(this.view);
6254
6325
  let targetRect = {
6255
- left: rect.left - mLeft,
6256
- top: rect.top - mTop,
6257
- right: rect.right + mRight,
6258
- bottom: rect.bottom + mBottom
6326
+ left: rect.left - margins.left,
6327
+ top: rect.top - margins.top,
6328
+ right: rect.right + margins.right,
6329
+ bottom: rect.bottom + margins.bottom
6259
6330
  };
6260
6331
  scrollRectIntoView(this.view.scrollDOM, targetRect, range.head < range.anchor ? -1 : 1, target.x, target.y, target.xMargin, target.yMargin, this.view.textDirection == Direction.LTR);
6261
6332
  }
@@ -6320,15 +6391,22 @@ function computeCompositionDeco(view, changes) {
6320
6391
  return Decoration.none;
6321
6392
  let { from, to, node, text: textNode } = surrounding;
6322
6393
  let newFrom = changes.mapPos(from, 1), newTo = Math.max(newFrom, changes.mapPos(to, -1));
6323
- let { state } = view, text = node.nodeType == 3 ? node.nodeValue : new DOMReader([], state).readRange(node.firstChild, null).text;
6394
+ let { state } = view, reader = new DOMReader([], state);
6395
+ if (node.nodeType == 3)
6396
+ reader.readTextNode(node);
6397
+ else
6398
+ reader.readRange(node.firstChild, null);
6399
+ let { text } = reader;
6400
+ if (text.indexOf(LineBreakPlaceholder) > -1)
6401
+ return Decoration.none;
6324
6402
  if (newTo - newFrom < text.length) {
6325
- if (state.doc.sliceString(newFrom, Math.min(state.doc.length, newFrom + text.length), LineBreakPlaceholder) == text)
6403
+ if (state.doc.sliceString(newFrom, Math.min(state.doc.length, newFrom + text.length)) == text)
6326
6404
  newTo = newFrom + text.length;
6327
- else if (state.doc.sliceString(Math.max(0, newTo - text.length), newTo, LineBreakPlaceholder) == text)
6405
+ else if (state.doc.sliceString(Math.max(0, newTo - text.length), newTo) == text)
6328
6406
  newFrom = newTo - text.length;
6329
6407
  else
6330
6408
  return Decoration.none;
6331
- } else if (state.doc.sliceString(newFrom, newTo, LineBreakPlaceholder) != text) {
6409
+ } else if (state.doc.sliceString(newFrom, newTo) != text) {
6332
6410
  return Decoration.none;
6333
6411
  }
6334
6412
  let topView = ContentView.get(node);
@@ -6639,9 +6717,18 @@ function isSuspiciousChromeCaretResult(node, offset, x) {
6639
6717
  let rect = node.nodeType == 1 ? node.getBoundingClientRect() : textRange(node, 0, Math.max(node.nodeValue.length, 1)).getBoundingClientRect();
6640
6718
  return x - rect.left > 5;
6641
6719
  }
6720
+ function blockAt(view, pos) {
6721
+ let line = view.lineBlockAt(pos);
6722
+ if (Array.isArray(line.type))
6723
+ for (let l of line.type) {
6724
+ if (l.to > pos || l.to == pos && (l.to == line.to || l.type == BlockType.Text))
6725
+ return l;
6726
+ }
6727
+ return line;
6728
+ }
6642
6729
  function moveToLineBoundary(view, start, forward, includeWrap) {
6643
- let line = view.state.doc.lineAt(start.head);
6644
- let coords = !includeWrap || !view.lineWrapping ? null : view.coordsAtPos(start.assoc < 0 && start.head > line.from ? start.head - 1 : start.head);
6730
+ let line = blockAt(view, start.head);
6731
+ 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);
6645
6732
  if (coords) {
6646
6733
  let editorRect = view.dom.getBoundingClientRect();
6647
6734
  let direction = view.textDirectionAt(line.from);
@@ -6652,9 +6739,7 @@ function moveToLineBoundary(view, start, forward, includeWrap) {
6652
6739
  if (pos != null)
6653
6740
  return EditorSelection.cursor(pos, forward ? -1 : 1);
6654
6741
  }
6655
- let lineView = LineView.find(view.docView, start.head);
6656
- let end = lineView ? forward ? lineView.posAtEnd : lineView.posAtStart : forward ? line.to : line.from;
6657
- return EditorSelection.cursor(end, forward ? -1 : 1);
6742
+ return EditorSelection.cursor(forward ? line.to : line.from, forward ? -1 : 1);
6658
6743
  }
6659
6744
  function moveByChar(view, start, forward, by) {
6660
6745
  let line = view.state.doc.lineAt(start.head), spans = view.bidiSpans(line);
@@ -6715,15 +6800,15 @@ function moveVertically(view, start, forward, distance) {
6715
6800
  return EditorSelection.cursor(pos, start.assoc, void 0, goal);
6716
6801
  }
6717
6802
  }
6718
- function skipAtoms(view, oldPos, pos) {
6719
- let atoms = view.state.facet(atomicRanges).map((f) => f(view));
6803
+ function skipAtomicRanges(atoms, pos, bias) {
6720
6804
  for (; ; ) {
6721
- let moved = false;
6805
+ let moved = 0;
6722
6806
  for (let set of atoms) {
6723
- set.between(pos.from - 1, pos.from + 1, (from, to, value) => {
6724
- if (pos.from > from && pos.from < to) {
6725
- pos = oldPos.head > pos.from ? EditorSelection.cursor(from, 1) : EditorSelection.cursor(to, -1);
6726
- moved = true;
6807
+ set.between(pos - 1, pos + 1, (from, to, value) => {
6808
+ if (pos > from && pos < to) {
6809
+ let side = moved || bias || (pos - from < to - pos ? -1 : 1);
6810
+ pos = side < 0 ? from : to;
6811
+ moved = side;
6727
6812
  }
6728
6813
  });
6729
6814
  }
@@ -6731,6 +6816,10 @@ function skipAtoms(view, oldPos, pos) {
6731
6816
  return pos;
6732
6817
  }
6733
6818
  }
6819
+ function skipAtoms(view, oldPos, pos) {
6820
+ let newPos = skipAtomicRanges(view.state.facet(atomicRanges).map((f) => f(view)), pos.from, oldPos.head > pos.from ? -1 : 1);
6821
+ return newPos == pos.from ? pos : EditorSelection.cursor(newPos, newPos < pos.from ? 1 : -1);
6822
+ }
6734
6823
  var InputState = class {
6735
6824
  constructor(view) {
6736
6825
  this.lastKeyCode = 0;
@@ -6751,6 +6840,8 @@ var InputState = class {
6751
6840
  this.composing = -1;
6752
6841
  this.compositionFirstChange = null;
6753
6842
  this.compositionEndedAt = 0;
6843
+ this.compositionPendingKey = false;
6844
+ this.compositionPendingChange = false;
6754
6845
  this.mouseSelection = null;
6755
6846
  let handleEvent = (handler, event) => {
6756
6847
  if (this.ignoreDuringComposition(event))
@@ -6782,6 +6873,10 @@ var InputState = class {
6782
6873
  }
6783
6874
  }
6784
6875
  });
6876
+ view.scrollDOM.addEventListener("drop", (event) => {
6877
+ if (event.target == view.scrollDOM && event.clientY > view.contentDOM.getBoundingClientRect().bottom)
6878
+ handleEvent(handlers.drop, event);
6879
+ });
6785
6880
  if (browser.chrome && browser.chrome_version == 102) {
6786
6881
  view.scrollDOM.addEventListener("wheel", () => {
6787
6882
  if (this.chromeScrollHack < 0)
@@ -6854,6 +6949,8 @@ var InputState = class {
6854
6949
  this.lastKeyTime = Date.now();
6855
6950
  if (event.keyCode == 9 && Date.now() < this.lastEscPress + 2e3)
6856
6951
  return true;
6952
+ if (event.keyCode != 27 && modifierCodes.indexOf(event.keyCode) < 0)
6953
+ view.inputState.lastEscPress = 0;
6857
6954
  if (browser.android && browser.chrome && !event.synthetic && (event.keyCode == 13 || event.keyCode == 8)) {
6858
6955
  view.observer.delayAndroidKey(event.key, event.keyCode);
6859
6956
  return true;
@@ -6878,8 +6975,8 @@ var InputState = class {
6878
6975
  return false;
6879
6976
  if (this.composing > 0)
6880
6977
  return true;
6881
- if (browser.safari && !browser.ios && Date.now() - this.compositionEndedAt < 100) {
6882
- this.compositionEndedAt = 0;
6978
+ if (browser.safari && !browser.ios && this.compositionPendingKey && Date.now() - this.compositionEndedAt < 100) {
6979
+ this.compositionPendingKey = false;
6883
6980
  return true;
6884
6981
  }
6885
6982
  return false;
@@ -6910,8 +7007,9 @@ var PendingKeys = [
6910
7007
  ];
6911
7008
  var EmacsyPendingKeys = "dthko";
6912
7009
  var modifierCodes = [16, 17, 18, 20, 91, 92, 224, 225];
7010
+ var dragScrollMargin = 6;
6913
7011
  function dragScrollSpeed(dist) {
6914
- return dist * 0.7 + 8;
7012
+ return Math.max(0, dist) * 0.7 + 8;
6915
7013
  }
6916
7014
  var MouseSelection = class {
6917
7015
  constructor(view, startEvent, style, mustSelect) {
@@ -6922,6 +7020,7 @@ var MouseSelection = class {
6922
7020
  this.scrolling = -1;
6923
7021
  this.lastEvent = startEvent;
6924
7022
  this.scrollParent = scrollableParent(view.contentDOM);
7023
+ this.atoms = view.state.facet(atomicRanges).map((f) => f(view));
6925
7024
  let doc2 = view.contentDOM.ownerDocument;
6926
7025
  doc2.addEventListener("mousemove", this.move = this.move.bind(this));
6927
7026
  doc2.addEventListener("mouseup", this.up = this.up.bind(this));
@@ -6945,13 +7044,14 @@ var MouseSelection = class {
6945
7044
  this.select(this.lastEvent = event);
6946
7045
  let sx = 0, sy = 0;
6947
7046
  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 };
6948
- if (event.clientX <= rect.left)
7047
+ let margins = getScrollMargins(this.view);
7048
+ if (event.clientX - margins.left <= rect.left + dragScrollMargin)
6949
7049
  sx = -dragScrollSpeed(rect.left - event.clientX);
6950
- else if (event.clientX >= rect.right)
7050
+ else if (event.clientX + margins.right >= rect.right - dragScrollMargin)
6951
7051
  sx = dragScrollSpeed(event.clientX - rect.right);
6952
- if (event.clientY <= rect.top)
7052
+ if (event.clientY - margins.top <= rect.top + dragScrollMargin)
6953
7053
  sy = -dragScrollSpeed(rect.top - event.clientY);
6954
- else if (event.clientY >= rect.bottom)
7054
+ else if (event.clientY + margins.bottom >= rect.bottom - dragScrollMargin)
6955
7055
  sy = dragScrollSpeed(event.clientY - rect.bottom);
6956
7056
  this.setScrollSpeed(sx, sy);
6957
7057
  }
@@ -6989,9 +7089,31 @@ var MouseSelection = class {
6989
7089
  if (this.dragging === false)
6990
7090
  this.select(this.lastEvent);
6991
7091
  }
7092
+ skipAtoms(sel) {
7093
+ let ranges = null;
7094
+ for (let i = 0; i < sel.ranges.length; i++) {
7095
+ let range = sel.ranges[i], updated = null;
7096
+ if (range.empty) {
7097
+ let pos = skipAtomicRanges(this.atoms, range.from, 0);
7098
+ if (pos != range.from)
7099
+ updated = EditorSelection.cursor(pos, -1);
7100
+ } else {
7101
+ let from = skipAtomicRanges(this.atoms, range.from, -1);
7102
+ let to = skipAtomicRanges(this.atoms, range.to, 1);
7103
+ if (from != range.from || to != range.to)
7104
+ updated = EditorSelection.range(range.from == range.anchor ? from : to, range.from == range.head ? from : to);
7105
+ }
7106
+ if (updated) {
7107
+ if (!ranges)
7108
+ ranges = sel.ranges.slice();
7109
+ ranges[i] = updated;
7110
+ }
7111
+ }
7112
+ return ranges ? EditorSelection.create(ranges, sel.mainIndex) : sel;
7113
+ }
6992
7114
  select(event) {
6993
- let selection = this.style.get(event, this.extend, this.multiple);
6994
- if (this.mustSelect || !selection.eq(this.view.state.selection) || selection.main.assoc != this.view.state.selection.main.assoc)
7115
+ let { view } = this, selection = this.skipAtoms(this.style.get(event, this.extend, this.multiple));
7116
+ if (this.mustSelect || !selection.eq(view.state.selection) || selection.main.assoc != view.state.selection.main.assoc)
6995
7117
  this.view.dispatch({
6996
7118
  selection,
6997
7119
  userEvent: "select.pointer"
@@ -7091,8 +7213,6 @@ handlers.keydown = (view, event) => {
7091
7213
  view.inputState.setSelectionOrigin("select");
7092
7214
  if (event.keyCode == 27)
7093
7215
  view.inputState.lastEscPress = Date.now();
7094
- else if (modifierCodes.indexOf(event.keyCode) < 0)
7095
- view.inputState.lastEscPress = 0;
7096
7216
  };
7097
7217
  handlers.touchstart = (view, e) => {
7098
7218
  view.inputState.lastTouchTime = Date.now();
@@ -7182,7 +7302,7 @@ function basicMouseSelection(view, event) {
7182
7302
  }
7183
7303
  },
7184
7304
  get(event2, extend2, multiple) {
7185
- let cur2 = queryPos(view, event2);
7305
+ let cur2 = queryPos(view, event2), removed;
7186
7306
  let range = rangeForClick(view, cur2.pos, cur2.bias, type);
7187
7307
  if (start.pos != cur2.pos && !extend2) {
7188
7308
  let startRange = rangeForClick(view, start.pos, start.bias, type);
@@ -7191,8 +7311,8 @@ function basicMouseSelection(view, event) {
7191
7311
  }
7192
7312
  if (extend2)
7193
7313
  return startSel.replaceRange(startSel.main.extend(range.from, range.to));
7194
- else if (multiple && startSel.ranges.length > 1 && startSel.ranges.some((r) => r.eq(range)))
7195
- return removeRange(startSel, range);
7314
+ else if (multiple && type == 1 && startSel.ranges.length > 1 && (removed = removeRangeAround(startSel, cur2.pos)))
7315
+ return removed;
7196
7316
  else if (multiple)
7197
7317
  return startSel.addRange(range);
7198
7318
  else
@@ -7200,11 +7320,13 @@ function basicMouseSelection(view, event) {
7200
7320
  }
7201
7321
  };
7202
7322
  }
7203
- function removeRange(sel, range) {
7204
- for (let i = 0; ; i++) {
7205
- if (sel.ranges[i].eq(range))
7323
+ function removeRangeAround(sel, pos) {
7324
+ for (let i = 0; i < sel.ranges.length; i++) {
7325
+ let { from, to } = sel.ranges[i];
7326
+ if (from <= pos && to >= pos)
7206
7327
  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));
7207
7328
  }
7329
+ return null;
7208
7330
  }
7209
7331
  handlers.dragstart = (view, event) => {
7210
7332
  let { selection: { main } } = view.state;
@@ -7372,13 +7494,19 @@ handlers.compositionstart = handlers.compositionupdate = (view) => {
7372
7494
  handlers.compositionend = (view) => {
7373
7495
  view.inputState.composing = -1;
7374
7496
  view.inputState.compositionEndedAt = Date.now();
7497
+ view.inputState.compositionPendingKey = true;
7498
+ view.inputState.compositionPendingChange = view.observer.pendingRecords().length > 0;
7375
7499
  view.inputState.compositionFirstChange = null;
7376
- if (browser.chrome && browser.android)
7500
+ if (browser.chrome && browser.android) {
7377
7501
  view.observer.flushSoon();
7378
- setTimeout(() => {
7379
- if (view.inputState.composing < 0 && view.docView.compositionDeco.size)
7380
- view.update([]);
7381
- }, 50);
7502
+ } else if (view.inputState.compositionPendingChange) {
7503
+ Promise.resolve().then(() => view.observer.flush());
7504
+ } else {
7505
+ setTimeout(() => {
7506
+ if (view.inputState.composing < 0 && view.docView.compositionDeco.size)
7507
+ view.update([]);
7508
+ }, 50);
7509
+ }
7382
7510
  };
7383
7511
  handlers.contextmenu = (view) => {
7384
7512
  view.inputState.lastContextMenu = Date.now();
@@ -7479,12 +7607,19 @@ var BlockInfo = class {
7479
7607
  /**
7480
7608
  @internal
7481
7609
  */
7482
- constructor(from, length2, top2, height, type) {
7610
+ constructor(from, length2, top2, height, _content) {
7483
7611
  this.from = from;
7484
7612
  this.length = length2;
7485
7613
  this.top = top2;
7486
7614
  this.height = height;
7487
- this.type = type;
7615
+ this._content = _content;
7616
+ }
7617
+ /**
7618
+ The type of element this is. When querying lines, this may be
7619
+ an array of all the blocks that make up the line.
7620
+ */
7621
+ get type() {
7622
+ return typeof this._content == "number" ? BlockType.Text : Array.isArray(this._content) ? this._content : this._content.type;
7488
7623
  }
7489
7624
  /**
7490
7625
  The end of the element as a document position.
@@ -7499,11 +7634,25 @@ var BlockInfo = class {
7499
7634
  return this.top + this.height;
7500
7635
  }
7501
7636
  /**
7637
+ If this is a widget block, this will return the widget
7638
+ associated with it.
7639
+ */
7640
+ get widget() {
7641
+ return this._content instanceof PointDecoration ? this._content.widget : null;
7642
+ }
7643
+ /**
7644
+ If this is a textblock, this holds the number of line breaks
7645
+ that appear in widgets inside the block.
7646
+ */
7647
+ get widgetLineBreaks() {
7648
+ return typeof this._content == "number" ? this._content : 0;
7649
+ }
7650
+ /**
7502
7651
  @internal
7503
7652
  */
7504
7653
  join(other) {
7505
- let detail = (Array.isArray(this.type) ? this.type : [this]).concat(Array.isArray(other.type) ? other.type : [other]);
7506
- return new BlockInfo(this.from, this.length + other.length, this.top, this.height + other.height, detail);
7654
+ let content = (Array.isArray(this._content) ? this._content : [this]).concat(Array.isArray(other._content) ? other._content : [other]);
7655
+ return new BlockInfo(this.from, this.length + other.length, this.top, this.height + other.height, content);
7507
7656
  }
7508
7657
  };
7509
7658
  var QueryType = /* @__PURE__ */ function(QueryType2) {
@@ -7622,12 +7771,12 @@ var HeightMap = class {
7622
7771
  };
7623
7772
  HeightMap.prototype.size = 1;
7624
7773
  var HeightMapBlock = class extends HeightMap {
7625
- constructor(length2, height, type) {
7774
+ constructor(length2, height, deco) {
7626
7775
  super(length2, height);
7627
- this.type = type;
7776
+ this.deco = deco;
7628
7777
  }
7629
7778
  blockAt(_height, _oracle, top2, offset) {
7630
- return new BlockInfo(offset, this.length, top2, this.height, this.type);
7779
+ return new BlockInfo(offset, this.length, top2, this.height, this.deco || 0);
7631
7780
  }
7632
7781
  lineAt(_value, _type, oracle, top2, offset) {
7633
7782
  return this.blockAt(0, oracle, top2, offset);
@@ -7648,9 +7797,13 @@ var HeightMapBlock = class extends HeightMap {
7648
7797
  };
7649
7798
  var HeightMapText = class extends HeightMapBlock {
7650
7799
  constructor(length2, height) {
7651
- super(length2, height, BlockType.Text);
7800
+ super(length2, height, null);
7652
7801
  this.collapsed = 0;
7653
7802
  this.widgetHeight = 0;
7803
+ this.breaks = 0;
7804
+ }
7805
+ blockAt(_height, _oracle, top2, offset) {
7806
+ return new BlockInfo(offset, this.length, top2, this.height, this.breaks);
7654
7807
  }
7655
7808
  replace(_from, _to, nodes) {
7656
7809
  let node = nodes[0];
@@ -7670,7 +7823,7 @@ var HeightMapText = class extends HeightMapBlock {
7670
7823
  if (measured && measured.from <= offset && measured.more)
7671
7824
  this.setHeight(oracle, measured.heights[measured.index++]);
7672
7825
  else if (force || this.outdated)
7673
- this.setHeight(oracle, Math.max(this.widgetHeight, oracle.heightForLine(this.length - this.collapsed)));
7826
+ this.setHeight(oracle, Math.max(this.widgetHeight, oracle.heightForLine(this.length - this.collapsed)) + this.breaks * oracle.lineHeight);
7674
7827
  this.outdated = false;
7675
7828
  return this;
7676
7829
  }
@@ -7689,7 +7842,8 @@ var HeightMapGap = class extends HeightMap {
7689
7842
  if (oracle.lineWrapping) {
7690
7843
  let totalPerLine = Math.min(this.height, oracle.lineHeight * lines);
7691
7844
  perLine = totalPerLine / lines;
7692
- perChar = (this.height - totalPerLine) / (this.length - lines - 1);
7845
+ if (this.length > lines + 1)
7846
+ perChar = (this.height - totalPerLine) / (this.length - lines - 1);
7693
7847
  } else {
7694
7848
  perLine = this.height / lines;
7695
7849
  }
@@ -7701,11 +7855,11 @@ var HeightMapGap = class extends HeightMap {
7701
7855
  let guess = offset + Math.round(Math.max(0, Math.min(1, (height - top2) / this.height)) * this.length);
7702
7856
  let line = oracle.doc.lineAt(guess), lineHeight = perLine + line.length * perChar;
7703
7857
  let lineTop = Math.max(top2, height - lineHeight / 2);
7704
- return new BlockInfo(line.from, line.length, lineTop, lineHeight, BlockType.Text);
7858
+ return new BlockInfo(line.from, line.length, lineTop, lineHeight, 0);
7705
7859
  } else {
7706
7860
  let line = Math.max(0, Math.min(lastLine - firstLine, Math.floor((height - top2) / perLine)));
7707
7861
  let { from, length: length2 } = oracle.doc.line(firstLine + line);
7708
- return new BlockInfo(from, length2, top2 + perLine * line, perLine, BlockType.Text);
7862
+ return new BlockInfo(from, length2, top2 + perLine * line, perLine, 0);
7709
7863
  }
7710
7864
  }
7711
7865
  lineAt(value, type, oracle, top2, offset) {
@@ -7713,13 +7867,13 @@ var HeightMapGap = class extends HeightMap {
7713
7867
  return this.blockAt(value, oracle, top2, offset);
7714
7868
  if (type == QueryType.ByPosNoHeight) {
7715
7869
  let { from, to } = oracle.doc.lineAt(value);
7716
- return new BlockInfo(from, to - from, 0, 0, BlockType.Text);
7870
+ return new BlockInfo(from, to - from, 0, 0, 0);
7717
7871
  }
7718
7872
  let { firstLine, perLine, perChar } = this.heightMetrics(oracle, offset);
7719
7873
  let line = oracle.doc.lineAt(value), lineHeight = perLine + line.length * perChar;
7720
7874
  let linesAbove = line.number - firstLine;
7721
7875
  let lineTop = top2 + perLine * linesAbove + perChar * (line.from - offset - linesAbove);
7722
- return new BlockInfo(line.from, line.length, Math.max(top2, Math.min(lineTop, top2 + this.height - lineHeight)), lineHeight, BlockType.Text);
7876
+ return new BlockInfo(line.from, line.length, Math.max(top2, Math.min(lineTop, top2 + this.height - lineHeight)), lineHeight, 0);
7723
7877
  }
7724
7878
  forEachLine(from, to, oracle, top2, offset, f) {
7725
7879
  from = Math.max(from, offset);
@@ -7732,7 +7886,7 @@ var HeightMapGap = class extends HeightMap {
7732
7886
  lineTop += perLine * linesAbove + perChar * (from - offset - linesAbove);
7733
7887
  }
7734
7888
  let lineHeight = perLine + perChar * line.length;
7735
- f(new BlockInfo(line.from, line.length, lineTop, lineHeight, BlockType.Text));
7889
+ f(new BlockInfo(line.from, line.length, lineTop, lineHeight, 0));
7736
7890
  lineTop += lineHeight;
7737
7891
  pos = line.to + 1;
7738
7892
  }
@@ -7953,13 +8107,14 @@ var NodeBuilder = class {
7953
8107
  point(from, to, deco) {
7954
8108
  if (from < to || deco.heightRelevant) {
7955
8109
  let height = deco.widget ? deco.widget.estimatedHeight : 0;
8110
+ let breaks = deco.widget ? deco.widget.lineBreaks : 0;
7956
8111
  if (height < 0)
7957
8112
  height = this.oracle.lineHeight;
7958
8113
  let len = to - from;
7959
8114
  if (deco.block) {
7960
- this.addBlock(new HeightMapBlock(len, height, deco.type));
7961
- } else if (len || height >= relevantWidgetHeight) {
7962
- this.addLineDeco(height, len);
8115
+ this.addBlock(new HeightMapBlock(len, height, deco));
8116
+ } else if (len || breaks || height >= relevantWidgetHeight) {
8117
+ this.addLineDeco(height, breaks, len);
7963
8118
  }
7964
8119
  } else if (to > from) {
7965
8120
  this.span(from, to);
@@ -7998,19 +8153,22 @@ var NodeBuilder = class {
7998
8153
  return line;
7999
8154
  }
8000
8155
  addBlock(block) {
8156
+ var _a2;
8001
8157
  this.enterLine();
8002
- if (block.type == BlockType.WidgetAfter && !this.isCovered)
8158
+ let type = (_a2 = block.deco) === null || _a2 === void 0 ? void 0 : _a2.type;
8159
+ if (type == BlockType.WidgetAfter && !this.isCovered)
8003
8160
  this.ensureLine();
8004
8161
  this.nodes.push(block);
8005
8162
  this.writtenTo = this.pos = this.pos + block.length;
8006
- if (block.type != BlockType.WidgetBefore)
8163
+ if (type != BlockType.WidgetBefore)
8007
8164
  this.covering = block;
8008
8165
  }
8009
- addLineDeco(height, length2) {
8166
+ addLineDeco(height, breaks, length2) {
8010
8167
  let line = this.ensureLine();
8011
8168
  line.length += length2;
8012
8169
  line.collapsed += length2;
8013
8170
  line.widgetHeight = Math.max(line.widgetHeight, height);
8171
+ line.breaks += breaks;
8014
8172
  this.writtenTo = this.pos = this.pos + length2;
8015
8173
  }
8016
8174
  finish(from) {
@@ -8148,6 +8306,10 @@ var ViewState = class {
8148
8306
  this.contentDOMHeight = 0;
8149
8307
  this.editorHeight = 0;
8150
8308
  this.editorWidth = 0;
8309
+ this.scrollTop = 0;
8310
+ this.scrolledToBottom = true;
8311
+ this.scrollAnchorPos = 0;
8312
+ this.scrollAnchorHeight = -1;
8151
8313
  this.scaler = IdScaler;
8152
8314
  this.scrollTarget = null;
8153
8315
  this.printing = false;
@@ -8191,9 +8353,17 @@ var ViewState = class {
8191
8353
  let contentChanges = update.changedRanges;
8192
8354
  let heightChanges = ChangedRange.extendWithRanges(contentChanges, heightRelevantDecoChanges(prevDeco, this.stateDeco, update ? update.changes : ChangeSet.empty(this.state.doc.length)));
8193
8355
  let prevHeight = this.heightMap.height;
8356
+ let scrollAnchor = this.scrolledToBottom ? null : this.lineBlockAtHeight(this.scrollTop);
8194
8357
  this.heightMap = this.heightMap.applyChanges(this.stateDeco, update.startState.doc, this.heightOracle.setDoc(this.state.doc), heightChanges);
8195
8358
  if (this.heightMap.height != prevHeight)
8196
8359
  update.flags |= 2;
8360
+ if (scrollAnchor) {
8361
+ this.scrollAnchorPos = update.changes.mapPos(scrollAnchor.from, -1);
8362
+ this.scrollAnchorHeight = scrollAnchor.top;
8363
+ } else {
8364
+ this.scrollAnchorPos = -1;
8365
+ this.scrollAnchorHeight = this.heightMap.height;
8366
+ }
8197
8367
  let viewport = heightChanges.length ? this.mapViewport(this.viewport, update.changes) : this.viewport;
8198
8368
  if (scrollTarget && (scrollTarget.range.head < viewport.from || scrollTarget.range.head > viewport.to) || !this.viewportIsAppropriate(viewport))
8199
8369
  viewport = this.getViewport(0, scrollTarget);
@@ -8233,6 +8403,11 @@ var ViewState = class {
8233
8403
  this.editorWidth = view.scrollDOM.clientWidth;
8234
8404
  result |= 8;
8235
8405
  }
8406
+ if (this.scrollTop != view.scrollDOM.scrollTop) {
8407
+ this.scrollAnchorHeight = -1;
8408
+ this.scrollTop = view.scrollDOM.scrollTop;
8409
+ }
8410
+ this.scrolledToBottom = this.scrollTop > view.scrollDOM.scrollHeight - view.scrollDOM.clientHeight - 4;
8236
8411
  let pixelViewport = (this.printing ? fullPixelRange : visiblePixelRange)(dom, this.paddingTop);
8237
8412
  let dTop = pixelViewport.top - this.pixelViewport.top, dBottom = pixelViewport.bottom - this.pixelViewport.bottom;
8238
8413
  this.pixelViewport = pixelViewport;
@@ -8331,11 +8506,11 @@ var ViewState = class {
8331
8506
  return (from == 0 || top2 <= visibleTop - Math.max(10, Math.min(
8332
8507
  -bias,
8333
8508
  250
8334
- /* VP.MaxCoverMargin */
8509
+ /* MaxCoverMargin */
8335
8510
  ))) && (to == this.state.doc.length || bottom >= visibleBottom + Math.max(10, Math.min(
8336
8511
  bias,
8337
8512
  250
8338
- /* VP.MaxCoverMargin */
8513
+ /* MaxCoverMargin */
8339
8514
  ))) && (top2 > visibleTop - 2 * 1e3 && bottom < visibleBottom + 2 * 1e3);
8340
8515
  }
8341
8516
  mapLineGaps(gaps, changes) {
@@ -8582,7 +8757,7 @@ function scaleBlock(block, scaler) {
8582
8757
  if (scaler.scale == 1)
8583
8758
  return block;
8584
8759
  let bTop = scaler.toDOM(block.top), bBottom = scaler.toDOM(block.bottom);
8585
- return new BlockInfo(block.from, block.length, bTop, bBottom - bTop, Array.isArray(block.type) ? block.type.map((b) => scaleBlock(b, scaler)) : block.type);
8760
+ return new BlockInfo(block.from, block.length, bTop, bBottom - bTop, Array.isArray(block._content) ? block._content.map((b) => scaleBlock(b, scaler)) : block._content);
8586
8761
  }
8587
8762
  var theme = /* @__PURE__ */ Facet.define({ combine: (strs) => strs.join(" ") });
8588
8763
  var darkTheme = /* @__PURE__ */ Facet.define({ combine: (values) => values.indexOf(true) > -1 });
@@ -8673,16 +8848,16 @@ var baseTheme$1 = /* @__PURE__ */ buildTheme("." + baseThemeID, {
8673
8848
  "&dark .cm-selectionBackground": {
8674
8849
  background: "#222"
8675
8850
  },
8676
- "&light.cm-focused .cm-selectionBackground": {
8851
+ "&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
8677
8852
  background: "#d7d4f0"
8678
8853
  },
8679
- "&dark.cm-focused .cm-selectionBackground": {
8854
+ "&dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
8680
8855
  background: "#233"
8681
8856
  },
8682
8857
  ".cm-cursorLayer": {
8683
8858
  pointerEvents: "none"
8684
8859
  },
8685
- "&.cm-focused .cm-cursorLayer": {
8860
+ "&.cm-focused > .cm-scroller > .cm-cursorLayer": {
8686
8861
  animation: "steps(1) cm-blink 1.2s infinite"
8687
8862
  },
8688
8863
  // Two animations defined so that we can switch between them to
@@ -8704,7 +8879,7 @@ var baseTheme$1 = /* @__PURE__ */ buildTheme("." + baseThemeID, {
8704
8879
  ".cm-dropCursor": {
8705
8880
  position: "absolute"
8706
8881
  },
8707
- "&.cm-focused .cm-cursor": {
8882
+ "&.cm-focused > .cm-scroller > .cm-cursorLayer .cm-cursor": {
8708
8883
  display: "block"
8709
8884
  },
8710
8885
  "&light .cm-activeLine": { backgroundColor: "#cceeff44" },
@@ -8863,16 +9038,17 @@ var DOMChange = class {
8863
9038
  function applyDOMChange(view, domChange) {
8864
9039
  let change;
8865
9040
  let { newSel } = domChange, sel = view.state.selection.main;
9041
+ let lastKey = view.inputState.lastKeyTime > Date.now() - 100 ? view.inputState.lastKeyCode : -1;
8866
9042
  if (domChange.bounds) {
8867
9043
  let { from, to } = domChange.bounds;
8868
9044
  let preferredPos = sel.from, preferredSide = null;
8869
- if (view.inputState.lastKeyCode === 8 && view.inputState.lastKeyTime > Date.now() - 100 || browser.android && domChange.text.length < to - from) {
9045
+ if (lastKey === 8 || browser.android && domChange.text.length < to - from) {
8870
9046
  preferredPos = sel.to;
8871
9047
  preferredSide = "end";
8872
9048
  }
8873
9049
  let diff = findDiff(view.state.doc.sliceString(from, to, LineBreakPlaceholder), domChange.text, preferredPos - from, preferredSide);
8874
9050
  if (diff) {
8875
- if (browser.chrome && view.inputState.lastKeyCode == 13 && diff.toB == diff.from + 2 && domChange.text.slice(diff.from, diff.toB) == LineBreakPlaceholder + LineBreakPlaceholder)
9051
+ if (browser.chrome && lastKey == 13 && diff.toB == diff.from + 2 && domChange.text.slice(diff.from, diff.toB) == LineBreakPlaceholder + LineBreakPlaceholder)
8876
9052
  diff.toB--;
8877
9053
  change = {
8878
9054
  from: from + diff.from,
@@ -8906,7 +9082,7 @@ function applyDOMChange(view, domChange) {
8906
9082
  let startState = view.state;
8907
9083
  if (browser.ios && view.inputState.flushIOSKey(view))
8908
9084
  return true;
8909
- 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)))
9085
+ 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)))
8910
9086
  return true;
8911
9087
  let text = change.insert.toString();
8912
9088
  if (view.state.facet(inputHandler).some((h) => h(view, change.from, change.to, text)))
@@ -8920,7 +9096,7 @@ function applyDOMChange(view, domChange) {
8920
9096
  tr = startState.replaceSelection(view.state.toText(before + change.insert.sliceString(0, void 0, view.state.lineBreak) + after));
8921
9097
  } else {
8922
9098
  let changes = startState.changes(change);
8923
- let mainSel = newSel && !startState.selection.main.eq(newSel.main) && newSel.main.to <= changes.newLength ? newSel.main : void 0;
9099
+ let mainSel = newSel && newSel.main.to <= changes.newLength ? newSel.main : void 0;
8924
9100
  if (startState.selection.ranges.length > 1 && view.inputState.composing >= 0 && change.to <= sel.to && change.to >= sel.to - 10) {
8925
9101
  let replaced = view.state.sliceDoc(change.from, change.to);
8926
9102
  let compositionRange = compositionSurroundingNode(view) || view.state.doc.lineAt(sel.head);
@@ -8949,7 +9125,8 @@ function applyDOMChange(view, domChange) {
8949
9125
  }
8950
9126
  }
8951
9127
  let userEvent = "input.type";
8952
- if (view.composing) {
9128
+ if (view.composing || view.inputState.compositionPendingChange && view.inputState.compositionEndedAt > Date.now() - 50) {
9129
+ view.inputState.compositionPendingChange = false;
8953
9130
  userEvent += ".compose";
8954
9131
  if (view.inputState.compositionFirstChange) {
8955
9132
  userEvent += ".start";
@@ -9089,7 +9266,7 @@ var DOMObserver = class {
9089
9266
  if (this.intersecting != this.view.inView)
9090
9267
  this.onScrollChanged(document.createEvent("Event"));
9091
9268
  }
9092
- }, {});
9269
+ }, { threshold: [0, 1e-3] });
9093
9270
  this.intersection.observe(this.dom);
9094
9271
  this.gapIntersection = new IntersectionObserver((entries) => {
9095
9272
  if (entries.length > 0 && entries[entries.length - 1].intersectionRatio > 0)
@@ -9249,7 +9426,10 @@ var DOMObserver = class {
9249
9426
  let key2 = this.delayedAndroidKey;
9250
9427
  if (key2) {
9251
9428
  this.clearDelayedAndroidKey();
9252
- if (!this.flush() && key2.force)
9429
+ this.view.inputState.lastKeyCode = key2.keyCode;
9430
+ this.view.inputState.lastKeyTime = Date.now();
9431
+ let flushed = this.flush();
9432
+ if (!flushed && key2.force)
9253
9433
  dispatchKey(this.dom, key2.key, key2.keyCode);
9254
9434
  }
9255
9435
  };
@@ -9285,10 +9465,13 @@ var DOMObserver = class {
9285
9465
  }
9286
9466
  this.flush();
9287
9467
  }
9288
- processRecords() {
9289
- let records = this.queue;
9468
+ pendingRecords() {
9290
9469
  for (let mut of this.observer.takeRecords())
9291
- records.push(mut);
9470
+ this.queue.push(mut);
9471
+ return this.queue;
9472
+ }
9473
+ processRecords() {
9474
+ let records = this.pendingRecords();
9292
9475
  if (records.length)
9293
9476
  this.queue = [];
9294
9477
  let from = -1, to = -1, typeOver = false;
@@ -9527,7 +9710,8 @@ var EditorView = class {
9527
9710
  return this.dom.ownerDocument.defaultView || window;
9528
9711
  }
9529
9712
  dispatch(...input) {
9530
- this._dispatch(input.length == 1 && input[0] instanceof Transaction ? input[0] : this.state.update(...input));
9713
+ let tr = input.length == 1 && input[0] instanceof Transaction ? input[0] : this.state.update(...input);
9714
+ this._dispatch(tr, this);
9531
9715
  }
9532
9716
  /**
9533
9717
  Update the view for the given array of transactions. This will
@@ -9695,13 +9879,22 @@ var EditorView = class {
9695
9879
  if (flush)
9696
9880
  this.observer.forceFlush();
9697
9881
  let updated = null;
9698
- let { scrollHeight, scrollTop, clientHeight } = this.scrollDOM;
9699
- let refHeight = scrollTop > scrollHeight - clientHeight - 4 ? scrollHeight : scrollTop;
9882
+ let sDOM = this.scrollDOM, { scrollAnchorPos, scrollAnchorHeight } = this.viewState;
9883
+ this.viewState.scrollAnchorHeight = -1;
9884
+ if (scrollAnchorHeight < 0 || sDOM.scrollTop != this.viewState.scrollTop) {
9885
+ if (sDOM.scrollTop > sDOM.scrollHeight - sDOM.clientHeight - 4) {
9886
+ scrollAnchorPos = -1;
9887
+ scrollAnchorHeight = this.viewState.heightMap.height;
9888
+ } else {
9889
+ let block = this.viewState.lineBlockAtHeight(sDOM.scrollTop);
9890
+ scrollAnchorPos = block.from;
9891
+ scrollAnchorHeight = block.top;
9892
+ }
9893
+ }
9700
9894
  try {
9701
9895
  for (let i = 0; ; i++) {
9702
9896
  this.updateState = 1;
9703
9897
  let oldViewport = this.viewport;
9704
- let refBlock = this.viewState.lineBlockAtHeight(refHeight);
9705
9898
  let changed = this.viewState.measure(this);
9706
9899
  if (!changed && !this.measureRequests.length && this.viewState.scrollTarget == null)
9707
9900
  break;
@@ -9748,10 +9941,11 @@ var EditorView = class {
9748
9941
  this.docView.scrollIntoView(this.viewState.scrollTarget);
9749
9942
  this.viewState.scrollTarget = null;
9750
9943
  scrolled = true;
9751
- } else {
9752
- let diff = this.viewState.lineBlockAt(refBlock.from).top - refBlock.top;
9944
+ } else if (scrollAnchorHeight > -1) {
9945
+ let newAnchorHeight = scrollAnchorPos < 0 ? this.viewState.heightMap.height : this.viewState.lineBlockAt(scrollAnchorPos).top;
9946
+ let diff = newAnchorHeight - scrollAnchorHeight;
9753
9947
  if (diff > 1 || diff < -1) {
9754
- this.scrollDOM.scrollTop += diff;
9948
+ sDOM.scrollTop += diff;
9755
9949
  scrolled = true;
9756
9950
  }
9757
9951
  }
@@ -9760,6 +9954,7 @@ var EditorView = class {
9760
9954
  this.docView.updateSelection(true);
9761
9955
  if (this.viewport.from == oldViewport.from && this.viewport.to == oldViewport.to && !scrolled && this.measureRequests.length == 0)
9762
9956
  break;
9957
+ scrollAnchorHeight = -1;
9763
9958
  }
9764
9959
  } finally {
9765
9960
  this.updateState = 0;
@@ -10469,15 +10664,6 @@ function wrappedLine(view, pos, inside2) {
10469
10664
  type: BlockType.Text
10470
10665
  };
10471
10666
  }
10472
- function blockAt(view, pos) {
10473
- let line = view.lineBlockAt(pos);
10474
- if (Array.isArray(line.type))
10475
- for (let l of line.type) {
10476
- if (l.to > pos || l.to == pos && (l.to == line.to || l.type == BlockType.Text))
10477
- return l;
10478
- }
10479
- return line;
10480
- }
10481
10667
  function rectanglesForRange(view, className, range) {
10482
10668
  if (range.to <= view.viewport.from || range.from >= view.viewport.to)
10483
10669
  return [];
@@ -10490,19 +10676,17 @@ function rectanglesForRange(view, className, range) {
10490
10676
  let startBlock = blockAt(view, from), endBlock = blockAt(view, to);
10491
10677
  let visualStart = startBlock.type == BlockType.Text ? startBlock : null;
10492
10678
  let visualEnd = endBlock.type == BlockType.Text ? endBlock : null;
10493
- if (view.lineWrapping) {
10494
- if (visualStart)
10495
- visualStart = wrappedLine(view, from, visualStart);
10496
- if (visualEnd)
10497
- visualEnd = wrappedLine(view, to, visualEnd);
10498
- }
10679
+ if (visualStart && (view.lineWrapping || startBlock.widgetLineBreaks))
10680
+ visualStart = wrappedLine(view, from, visualStart);
10681
+ if (visualEnd && (view.lineWrapping || endBlock.widgetLineBreaks))
10682
+ visualEnd = wrappedLine(view, to, visualEnd);
10499
10683
  if (visualStart && visualEnd && visualStart.from == visualEnd.from) {
10500
10684
  return pieces(drawForLine(range.from, range.to, visualStart));
10501
10685
  } else {
10502
10686
  let top2 = visualStart ? drawForLine(range.from, null, visualStart) : drawForWidget(startBlock, false);
10503
10687
  let bottom = visualEnd ? drawForLine(null, range.to, visualEnd) : drawForWidget(endBlock, true);
10504
10688
  let between = [];
10505
- if ((visualStart || startBlock).to < (visualEnd || endBlock).from - 1)
10689
+ if ((visualStart || startBlock).to < (visualEnd || endBlock).from - (visualStart && visualEnd ? 1 : 0) || startBlock.widgetLineBreaks > 1 && top2.bottom + view.defaultLineHeight / 2 < bottom.top)
10506
10690
  between.push(piece(leftSide, top2.bottom, rightSide, bottom.top));
10507
10691
  else if (top2.bottom < bottom.top && view.elementAtHeight((top2.bottom + bottom.top) / 2).type == BlockType.Text)
10508
10692
  top2.bottom = bottom.top = (top2.bottom + bottom.top) / 2;
@@ -10515,7 +10699,7 @@ function rectanglesForRange(view, className, range) {
10515
10699
  top2 - base2.top - 0.01,
10516
10700
  right - left,
10517
10701
  bottom - top2 + 0.01
10518
- /* C.Epsilon */
10702
+ /* Epsilon */
10519
10703
  );
10520
10704
  }
10521
10705
  function pieces({ top: top2, bottom, horizontal }) {
@@ -10529,6 +10713,8 @@ function rectanglesForRange(view, className, range) {
10529
10713
  function addSpan(from3, fromOpen, to3, toOpen, dir) {
10530
10714
  let fromCoords = view.coordsAtPos(from3, from3 == line.to ? -2 : 2);
10531
10715
  let toCoords = view.coordsAtPos(to3, to3 == line.from ? 2 : -2);
10716
+ if (!fromCoords || !toCoords)
10717
+ return;
10532
10718
  top2 = Math.min(fromCoords.top, toCoords.top, top2);
10533
10719
  bottom = Math.max(fromCoords.bottom, toCoords.bottom, bottom);
10534
10720
  if (dir == Direction.LTR)
@@ -11459,6 +11645,9 @@ function ensureSyntaxTree(state, upto, timeout = 50) {
11459
11645
  return result;
11460
11646
  }
11461
11647
  var DocInput = class {
11648
+ /**
11649
+ Create an input object for the given document.
11650
+ */
11462
11651
  constructor(doc2) {
11463
11652
  this.doc = doc2;
11464
11653
  this.cursorPos = 0;
@@ -12475,14 +12664,15 @@ function completeFromList(list) {
12475
12664
  };
12476
12665
  }
12477
12666
  var Option = class {
12478
- constructor(completion, source, match) {
12667
+ constructor(completion, source, match, score2) {
12479
12668
  this.completion = completion;
12480
12669
  this.source = source;
12481
12670
  this.match = match;
12671
+ this.score = score2;
12482
12672
  }
12483
12673
  };
12484
12674
  function cur(state) {
12485
- return state.selection.main.head;
12675
+ return state.selection.main.from;
12486
12676
  }
12487
12677
  function ensureAnchor(expr, start) {
12488
12678
  var _a2;
@@ -12494,29 +12684,16 @@ function ensureAnchor(expr, start) {
12494
12684
  }
12495
12685
  var pickedCompletion = /* @__PURE__ */ Annotation.define();
12496
12686
  function insertCompletionText(state, text, from, to) {
12687
+ let { main } = state.selection, fromOff = from - main.from, toOff = to - main.from;
12497
12688
  return Object.assign(Object.assign({}, state.changeByRange((range) => {
12498
- if (range == state.selection.main)
12499
- return {
12500
- changes: { from, to, insert: text },
12501
- range: EditorSelection.cursor(from + text.length)
12502
- };
12503
- let len = to - from;
12504
- if (!range.empty || len && state.sliceDoc(range.from - len, range.from) != state.sliceDoc(from, to))
12689
+ if (range != main && from != to && state.sliceDoc(range.from + fromOff, range.from + toOff) != state.sliceDoc(from, to))
12505
12690
  return { range };
12506
12691
  return {
12507
- changes: { from: range.from - len, to: range.from, insert: text },
12508
- range: EditorSelection.cursor(range.from - len + text.length)
12692
+ changes: { from: range.from + fromOff, to: to == main.from ? range.to : range.from + toOff, insert: text },
12693
+ range: EditorSelection.cursor(range.from + fromOff + text.length)
12509
12694
  };
12510
12695
  })), { userEvent: "input.complete" });
12511
12696
  }
12512
- function applyCompletion(view, option) {
12513
- const apply = option.completion.apply || option.completion.label;
12514
- let result = option.source;
12515
- if (typeof apply == "string")
12516
- view.dispatch(Object.assign(Object.assign({}, insertCompletionText(view.state, apply, result.from, result.to)), { annotations: pickedCompletion.of(option.completion) }));
12517
- else
12518
- apply(view, option.completion, result.from, result.to);
12519
- }
12520
12697
  var SourceCache = /* @__PURE__ */ new WeakMap();
12521
12698
  function asSource(source) {
12522
12699
  if (!Array.isArray(source))
@@ -12526,6 +12703,8 @@ function asSource(source) {
12526
12703
  SourceCache.set(source, known = completeFromList(source));
12527
12704
  return known;
12528
12705
  }
12706
+ var startCompletionEffect = /* @__PURE__ */ StateEffect.define();
12707
+ var closeCompletionEffect = /* @__PURE__ */ StateEffect.define();
12529
12708
  var FuzzyMatcher = class {
12530
12709
  constructor(pattern) {
12531
12710
  this.pattern = pattern;
@@ -12552,7 +12731,10 @@ var FuzzyMatcher = class {
12552
12731
  // is. See `Penalty` above.
12553
12732
  match(word) {
12554
12733
  if (this.pattern.length == 0)
12555
- return [0];
12734
+ return [
12735
+ -100
12736
+ /* Penalty.NotFull */
12737
+ ];
12556
12738
  if (word.length < this.pattern.length)
12557
12739
  return null;
12558
12740
  let { chars, folded, any, precise, byWord } = this;
@@ -12651,6 +12833,7 @@ var completionConfig = /* @__PURE__ */ Facet.define({
12651
12833
  aboveCursor: false,
12652
12834
  icons: true,
12653
12835
  addToOptions: [],
12836
+ positionInfo: defaultPositionInfo,
12654
12837
  compareCompletions: (a, b) => a.label.localeCompare(b.label),
12655
12838
  interactionDelay: 75
12656
12839
  }, {
@@ -12666,82 +12849,318 @@ var completionConfig = /* @__PURE__ */ Facet.define({
12666
12849
  function joinClass(a, b) {
12667
12850
  return a ? b ? a + " " + b : a : b;
12668
12851
  }
12669
- function optionContent(config2) {
12670
- let content = config2.addToOptions.slice();
12671
- if (config2.icons)
12672
- content.push({
12673
- render(completion) {
12674
- let icon = document.createElement("div");
12675
- icon.classList.add("cm-completionIcon");
12676
- if (completion.type)
12677
- icon.classList.add(...completion.type.split(/\s+/g).map((cls) => "cm-completionIcon-" + cls));
12678
- icon.setAttribute("aria-hidden", "true");
12679
- return icon;
12680
- },
12681
- position: 20
12682
- });
12683
- content.push({
12684
- render(completion, _s, match) {
12685
- let labelElt = document.createElement("span");
12686
- labelElt.className = "cm-completionLabel";
12687
- let { label } = completion, off = 0;
12688
- for (let j = 1; j < match.length; ) {
12689
- let from = match[j++], to = match[j++];
12690
- if (from > off)
12691
- labelElt.appendChild(document.createTextNode(label.slice(off, from)));
12692
- let span = labelElt.appendChild(document.createElement("span"));
12693
- span.appendChild(document.createTextNode(label.slice(from, to)));
12694
- span.className = "cm-completionMatchedText";
12695
- off = to;
12696
- }
12697
- if (off < label.length)
12698
- labelElt.appendChild(document.createTextNode(label.slice(off)));
12699
- return labelElt;
12700
- },
12701
- position: 50
12702
- }, {
12703
- render(completion) {
12704
- if (!completion.detail)
12705
- return null;
12706
- let detailElt = document.createElement("span");
12707
- detailElt.className = "cm-completionDetail";
12708
- detailElt.textContent = completion.detail;
12709
- return detailElt;
12710
- },
12711
- position: 80
12712
- });
12713
- return content.sort((a, b) => a.position - b.position).map((a) => a.render);
12714
- }
12715
- function rangeAroundSelected(total, selected, max) {
12716
- if (total <= max)
12717
- return { from: 0, to: total };
12718
- if (selected < 0)
12719
- selected = 0;
12720
- if (selected <= total >> 1) {
12721
- let off2 = Math.floor(selected / max);
12722
- return { from: off2 * max, to: (off2 + 1) * max };
12852
+ function defaultPositionInfo(view, list, option, info, space) {
12853
+ let rtl = view.textDirection == Direction.RTL, left = rtl, narrow = false;
12854
+ let side = "top", offset, maxWidth;
12855
+ let spaceLeft = list.left - space.left, spaceRight = space.right - list.right;
12856
+ let infoWidth = info.right - info.left, infoHeight = info.bottom - info.top;
12857
+ if (left && spaceLeft < Math.min(infoWidth, spaceRight))
12858
+ left = false;
12859
+ else if (!left && spaceRight < Math.min(infoWidth, spaceLeft))
12860
+ left = true;
12861
+ if (infoWidth <= (left ? spaceLeft : spaceRight)) {
12862
+ offset = Math.max(space.top, Math.min(option.top, space.bottom - infoHeight)) - list.top;
12863
+ maxWidth = Math.min(400, left ? spaceLeft : spaceRight);
12864
+ } else {
12865
+ narrow = true;
12866
+ maxWidth = Math.min(
12867
+ 400,
12868
+ (rtl ? list.right : space.right - list.left) - 30
12869
+ /* Info.Margin */
12870
+ );
12871
+ let spaceBelow = space.bottom - list.bottom;
12872
+ if (spaceBelow >= infoHeight || spaceBelow > list.top) {
12873
+ offset = option.bottom - list.top;
12874
+ } else {
12875
+ side = "bottom";
12876
+ offset = list.bottom - option.top;
12877
+ }
12723
12878
  }
12724
- let off = Math.floor((total - selected) / max);
12725
- return { from: total - (off + 1) * max, to: total - off * max };
12879
+ return {
12880
+ style: `${side}: ${offset}px; max-width: ${maxWidth}px`,
12881
+ class: "cm-completionInfo-" + (narrow ? rtl ? "left-narrow" : "right-narrow" : left ? "left" : "right")
12882
+ };
12726
12883
  }
12727
- var CompletionTooltip = class {
12728
- constructor(view, stateField) {
12729
- this.view = view;
12730
- this.stateField = stateField;
12731
- this.info = null;
12732
- this.placeInfo = {
12733
- read: () => this.measureInfo(),
12734
- write: (pos) => this.positionInfo(pos),
12735
- key: this
12736
- };
12737
- this.space = null;
12738
- this.currentClass = "";
12739
- let cState = view.state.field(stateField);
12740
- let { options, selected } = cState.open;
12741
- let config2 = view.state.facet(completionConfig);
12742
- this.optionContent = optionContent(config2);
12743
- this.optionClass = config2.optionClass;
12744
- this.tooltipClass = config2.tooltipClass;
12884
+ function moveCompletionSelection(forward, by = "option") {
12885
+ return (view) => {
12886
+ let cState = view.state.field(completionState, false);
12887
+ if (!cState || !cState.open || cState.open.disabled || Date.now() - cState.open.timestamp < view.state.facet(completionConfig).interactionDelay)
12888
+ return false;
12889
+ let step = 1, tooltip;
12890
+ if (by == "page" && (tooltip = getTooltip(view, cState.open.tooltip)))
12891
+ step = Math.max(2, Math.floor(tooltip.dom.offsetHeight / tooltip.dom.querySelector("li").offsetHeight) - 1);
12892
+ let { length: length2 } = cState.open.options;
12893
+ let selected = cState.open.selected > -1 ? cState.open.selected + step * (forward ? 1 : -1) : forward ? 0 : length2 - 1;
12894
+ if (selected < 0)
12895
+ selected = by == "page" ? 0 : length2 - 1;
12896
+ else if (selected >= length2)
12897
+ selected = by == "page" ? length2 - 1 : 0;
12898
+ view.dispatch({ effects: setSelectedEffect.of(selected) });
12899
+ return true;
12900
+ };
12901
+ }
12902
+ var acceptCompletion = (view) => {
12903
+ let cState = view.state.field(completionState, false);
12904
+ if (view.state.readOnly || !cState || !cState.open || cState.open.selected < 0 || Date.now() - cState.open.timestamp < view.state.facet(completionConfig).interactionDelay)
12905
+ return false;
12906
+ if (!cState.open.disabled)
12907
+ return applyCompletion(view, cState.open.options[cState.open.selected]);
12908
+ return true;
12909
+ };
12910
+ var startCompletion = (view) => {
12911
+ let cState = view.state.field(completionState, false);
12912
+ if (!cState)
12913
+ return false;
12914
+ view.dispatch({ effects: startCompletionEffect.of(true) });
12915
+ return true;
12916
+ };
12917
+ var closeCompletion = (view) => {
12918
+ let cState = view.state.field(completionState, false);
12919
+ if (!cState || !cState.active.some(
12920
+ (a) => a.state != 0
12921
+ /* State.Inactive */
12922
+ ))
12923
+ return false;
12924
+ view.dispatch({ effects: closeCompletionEffect.of(null) });
12925
+ return true;
12926
+ };
12927
+ var RunningQuery = class {
12928
+ constructor(active, context) {
12929
+ this.active = active;
12930
+ this.context = context;
12931
+ this.time = Date.now();
12932
+ this.updates = [];
12933
+ this.done = void 0;
12934
+ }
12935
+ };
12936
+ var DebounceTime = 50;
12937
+ var MaxUpdateCount = 50;
12938
+ var MinAbortTime = 1e3;
12939
+ var completionPlugin = /* @__PURE__ */ ViewPlugin.fromClass(class {
12940
+ constructor(view) {
12941
+ this.view = view;
12942
+ this.debounceUpdate = -1;
12943
+ this.running = [];
12944
+ this.debounceAccept = -1;
12945
+ this.composing = 0;
12946
+ for (let active of view.state.field(completionState).active)
12947
+ if (active.state == 1)
12948
+ this.startQuery(active);
12949
+ }
12950
+ update(update) {
12951
+ let cState = update.state.field(completionState);
12952
+ if (!update.selectionSet && !update.docChanged && update.startState.field(completionState) == cState)
12953
+ return;
12954
+ let doesReset = update.transactions.some((tr) => {
12955
+ return (tr.selection || tr.docChanged) && !getUserEvent(tr);
12956
+ });
12957
+ for (let i = 0; i < this.running.length; i++) {
12958
+ let query = this.running[i];
12959
+ if (doesReset || query.updates.length + update.transactions.length > MaxUpdateCount && Date.now() - query.time > MinAbortTime) {
12960
+ for (let handler of query.context.abortListeners) {
12961
+ try {
12962
+ handler();
12963
+ } catch (e) {
12964
+ logException(this.view.state, e);
12965
+ }
12966
+ }
12967
+ query.context.abortListeners = null;
12968
+ this.running.splice(i--, 1);
12969
+ } else {
12970
+ query.updates.push(...update.transactions);
12971
+ }
12972
+ }
12973
+ if (this.debounceUpdate > -1)
12974
+ clearTimeout(this.debounceUpdate);
12975
+ this.debounceUpdate = cState.active.some((a) => a.state == 1 && !this.running.some((q) => q.active.source == a.source)) ? setTimeout(() => this.startUpdate(), DebounceTime) : -1;
12976
+ if (this.composing != 0)
12977
+ for (let tr of update.transactions) {
12978
+ if (getUserEvent(tr) == "input")
12979
+ this.composing = 2;
12980
+ else if (this.composing == 2 && tr.selection)
12981
+ this.composing = 3;
12982
+ }
12983
+ }
12984
+ startUpdate() {
12985
+ this.debounceUpdate = -1;
12986
+ let { state } = this.view, cState = state.field(completionState);
12987
+ for (let active of cState.active) {
12988
+ if (active.state == 1 && !this.running.some((r) => r.active.source == active.source))
12989
+ this.startQuery(active);
12990
+ }
12991
+ }
12992
+ startQuery(active) {
12993
+ let { state } = this.view, pos = cur(state);
12994
+ let context = new CompletionContext(state, pos, active.explicitPos == pos);
12995
+ let pending = new RunningQuery(active, context);
12996
+ this.running.push(pending);
12997
+ Promise.resolve(active.source(context)).then((result) => {
12998
+ if (!pending.context.aborted) {
12999
+ pending.done = result || null;
13000
+ this.scheduleAccept();
13001
+ }
13002
+ }, (err) => {
13003
+ this.view.dispatch({ effects: closeCompletionEffect.of(null) });
13004
+ logException(this.view.state, err);
13005
+ });
13006
+ }
13007
+ scheduleAccept() {
13008
+ if (this.running.every((q) => q.done !== void 0))
13009
+ this.accept();
13010
+ else if (this.debounceAccept < 0)
13011
+ this.debounceAccept = setTimeout(() => this.accept(), DebounceTime);
13012
+ }
13013
+ // For each finished query in this.running, try to create a result
13014
+ // or, if appropriate, restart the query.
13015
+ accept() {
13016
+ var _a2;
13017
+ if (this.debounceAccept > -1)
13018
+ clearTimeout(this.debounceAccept);
13019
+ this.debounceAccept = -1;
13020
+ let updated = [];
13021
+ let conf = this.view.state.facet(completionConfig);
13022
+ for (let i = 0; i < this.running.length; i++) {
13023
+ let query = this.running[i];
13024
+ if (query.done === void 0)
13025
+ continue;
13026
+ this.running.splice(i--, 1);
13027
+ if (query.done) {
13028
+ 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));
13029
+ for (let tr of query.updates)
13030
+ active = active.update(tr, conf);
13031
+ if (active.hasResult()) {
13032
+ updated.push(active);
13033
+ continue;
13034
+ }
13035
+ }
13036
+ let current = this.view.state.field(completionState).active.find((a) => a.source == query.active.source);
13037
+ if (current && current.state == 1) {
13038
+ if (query.done == null) {
13039
+ let active = new ActiveSource(
13040
+ query.active.source,
13041
+ 0
13042
+ /* State.Inactive */
13043
+ );
13044
+ for (let tr of query.updates)
13045
+ active = active.update(tr, conf);
13046
+ if (active.state != 1)
13047
+ updated.push(active);
13048
+ } else {
13049
+ this.startQuery(current);
13050
+ }
13051
+ }
13052
+ }
13053
+ if (updated.length)
13054
+ this.view.dispatch({ effects: setActiveEffect.of(updated) });
13055
+ }
13056
+ }, {
13057
+ eventHandlers: {
13058
+ blur(event) {
13059
+ let state = this.view.state.field(completionState, false);
13060
+ if (state && state.tooltip && this.view.state.facet(completionConfig).closeOnBlur) {
13061
+ let dialog = state.open && getTooltip(this.view, state.open.tooltip);
13062
+ if (!dialog || !dialog.dom.contains(event.relatedTarget))
13063
+ this.view.dispatch({ effects: closeCompletionEffect.of(null) });
13064
+ }
13065
+ },
13066
+ compositionstart() {
13067
+ this.composing = 1;
13068
+ },
13069
+ compositionend() {
13070
+ if (this.composing == 3) {
13071
+ setTimeout(() => this.view.dispatch({ effects: startCompletionEffect.of(false) }), 20);
13072
+ }
13073
+ this.composing = 0;
13074
+ }
13075
+ }
13076
+ });
13077
+ function applyCompletion(view, option) {
13078
+ const apply = option.completion.apply || option.completion.label;
13079
+ let result = view.state.field(completionState).active.find((a) => a.source == option.source);
13080
+ if (!(result instanceof ActiveResult))
13081
+ return false;
13082
+ if (typeof apply == "string")
13083
+ view.dispatch(Object.assign(Object.assign({}, insertCompletionText(view.state, apply, result.from, result.to)), { annotations: pickedCompletion.of(option.completion) }));
13084
+ else
13085
+ apply(view, option.completion, result.from, result.to);
13086
+ return true;
13087
+ }
13088
+ function optionContent(config2) {
13089
+ let content = config2.addToOptions.slice();
13090
+ if (config2.icons)
13091
+ content.push({
13092
+ render(completion) {
13093
+ let icon = document.createElement("div");
13094
+ icon.classList.add("cm-completionIcon");
13095
+ if (completion.type)
13096
+ icon.classList.add(...completion.type.split(/\s+/g).map((cls) => "cm-completionIcon-" + cls));
13097
+ icon.setAttribute("aria-hidden", "true");
13098
+ return icon;
13099
+ },
13100
+ position: 20
13101
+ });
13102
+ content.push({
13103
+ render(completion, _s, match) {
13104
+ let labelElt = document.createElement("span");
13105
+ labelElt.className = "cm-completionLabel";
13106
+ let { label } = completion, off = 0;
13107
+ for (let j = 1; j < match.length; ) {
13108
+ let from = match[j++], to = match[j++];
13109
+ if (from > off)
13110
+ labelElt.appendChild(document.createTextNode(label.slice(off, from)));
13111
+ let span = labelElt.appendChild(document.createElement("span"));
13112
+ span.appendChild(document.createTextNode(label.slice(from, to)));
13113
+ span.className = "cm-completionMatchedText";
13114
+ off = to;
13115
+ }
13116
+ if (off < label.length)
13117
+ labelElt.appendChild(document.createTextNode(label.slice(off)));
13118
+ return labelElt;
13119
+ },
13120
+ position: 50
13121
+ }, {
13122
+ render(completion) {
13123
+ if (!completion.detail)
13124
+ return null;
13125
+ let detailElt = document.createElement("span");
13126
+ detailElt.className = "cm-completionDetail";
13127
+ detailElt.textContent = completion.detail;
13128
+ return detailElt;
13129
+ },
13130
+ position: 80
13131
+ });
13132
+ return content.sort((a, b) => a.position - b.position).map((a) => a.render);
13133
+ }
13134
+ function rangeAroundSelected(total, selected, max) {
13135
+ if (total <= max)
13136
+ return { from: 0, to: total };
13137
+ if (selected < 0)
13138
+ selected = 0;
13139
+ if (selected <= total >> 1) {
13140
+ let off2 = Math.floor(selected / max);
13141
+ return { from: off2 * max, to: (off2 + 1) * max };
13142
+ }
13143
+ let off = Math.floor((total - selected) / max);
13144
+ return { from: total - (off + 1) * max, to: total - off * max };
13145
+ }
13146
+ var CompletionTooltip = class {
13147
+ constructor(view, stateField) {
13148
+ this.view = view;
13149
+ this.stateField = stateField;
13150
+ this.info = null;
13151
+ this.placeInfoReq = {
13152
+ read: () => this.measureInfo(),
13153
+ write: (pos) => this.placeInfo(pos),
13154
+ key: this
13155
+ };
13156
+ this.space = null;
13157
+ this.currentClass = "";
13158
+ let cState = view.state.field(stateField);
13159
+ let { options, selected } = cState.open;
13160
+ let config2 = view.state.facet(completionConfig);
13161
+ this.optionContent = optionContent(config2);
13162
+ this.optionClass = config2.optionClass;
13163
+ this.tooltipClass = config2.tooltipClass;
12745
13164
  this.range = rangeAroundSelected(options.length, selected, config2.maxRenderedOptions);
12746
13165
  this.dom = document.createElement("div");
12747
13166
  this.dom.className = "cm-tooltip-autocomplete";
@@ -12755,10 +13174,15 @@ var CompletionTooltip = class {
12755
13174
  }
12756
13175
  }
12757
13176
  });
13177
+ this.dom.addEventListener("focusout", (e) => {
13178
+ let state = view.state.field(this.stateField, false);
13179
+ if (state && state.tooltip && view.state.facet(completionConfig).closeOnBlur && e.relatedTarget != view.contentDOM)
13180
+ view.dispatch({ effects: closeCompletionEffect.of(null) });
13181
+ });
12758
13182
  this.list = this.dom.appendChild(this.createListBox(options, cState.id, this.range));
12759
13183
  this.list.addEventListener("scroll", () => {
12760
13184
  if (this.info)
12761
- this.view.requestMeasure(this.placeInfo);
13185
+ this.view.requestMeasure(this.placeInfoReq);
12762
13186
  });
12763
13187
  }
12764
13188
  mount() {
@@ -12790,7 +13214,7 @@ var CompletionTooltip = class {
12790
13214
  positioned(space) {
12791
13215
  this.space = space;
12792
13216
  if (this.info)
12793
- this.view.requestMeasure(this.placeInfo);
13217
+ this.view.requestMeasure(this.placeInfoReq);
12794
13218
  }
12795
13219
  updateSel() {
12796
13220
  let cState = this.view.state.field(this.stateField), open = cState.open;
@@ -12800,7 +13224,7 @@ var CompletionTooltip = class {
12800
13224
  this.list = this.dom.appendChild(this.createListBox(open.options, cState.id, this.range));
12801
13225
  this.list.addEventListener("scroll", () => {
12802
13226
  if (this.info)
12803
- this.view.requestMeasure(this.placeInfo);
13227
+ this.view.requestMeasure(this.placeInfoReq);
12804
13228
  });
12805
13229
  }
12806
13230
  if (this.updateSelectedOption(open.selected)) {
@@ -12830,12 +13254,14 @@ var CompletionTooltip = class {
12830
13254
  dom.className = "cm-tooltip cm-completionInfo";
12831
13255
  dom.appendChild(content);
12832
13256
  this.dom.appendChild(dom);
12833
- this.view.requestMeasure(this.placeInfo);
13257
+ this.view.requestMeasure(this.placeInfoReq);
12834
13258
  }
12835
13259
  updateSelectedOption(selected) {
12836
13260
  let set = null;
12837
13261
  for (let opt = this.list.firstChild, i = this.range.from; opt; opt = opt.nextSibling, i++) {
12838
- if (i == selected) {
13262
+ if (opt.nodeName != "LI" || !opt.id) {
13263
+ i--;
13264
+ } else if (i == selected) {
12839
13265
  if (!opt.hasAttribute("aria-selected")) {
12840
13266
  opt.setAttribute("aria-selected", "true");
12841
13267
  set = opt;
@@ -12863,45 +13289,16 @@ var CompletionTooltip = class {
12863
13289
  }
12864
13290
  if (selRect.top > Math.min(space.bottom, listRect.bottom) - 10 || selRect.bottom < Math.max(space.top, listRect.top) + 10)
12865
13291
  return null;
12866
- let rtl = this.view.textDirection == Direction.RTL, left = rtl, narrow = false, maxWidth;
12867
- let top2 = "", bottom = "";
12868
- let spaceLeft = listRect.left - space.left, spaceRight = space.right - listRect.right;
12869
- if (left && spaceLeft < Math.min(infoRect.width, spaceRight))
12870
- left = false;
12871
- else if (!left && spaceRight < Math.min(infoRect.width, spaceLeft))
12872
- left = true;
12873
- if (infoRect.width <= (left ? spaceLeft : spaceRight)) {
12874
- top2 = Math.max(space.top, Math.min(selRect.top, space.bottom - infoRect.height)) - listRect.top + "px";
12875
- maxWidth = Math.min(400, left ? spaceLeft : spaceRight) + "px";
12876
- } else {
12877
- narrow = true;
12878
- maxWidth = Math.min(
12879
- 400,
12880
- (rtl ? listRect.right : space.right - listRect.left) - 30
12881
- /* Info.Margin */
12882
- ) + "px";
12883
- let spaceBelow = space.bottom - listRect.bottom;
12884
- if (spaceBelow >= infoRect.height || spaceBelow > listRect.top)
12885
- top2 = selRect.bottom - listRect.top + "px";
12886
- else
12887
- bottom = listRect.bottom - selRect.top + "px";
12888
- }
12889
- return {
12890
- top: top2,
12891
- bottom,
12892
- maxWidth,
12893
- class: narrow ? rtl ? "left-narrow" : "right-narrow" : left ? "left" : "right"
12894
- };
13292
+ return this.view.state.facet(completionConfig).positionInfo(this.view, listRect, selRect, infoRect, space);
12895
13293
  }
12896
- positionInfo(pos) {
13294
+ placeInfo(pos) {
12897
13295
  if (this.info) {
12898
13296
  if (pos) {
12899
- this.info.style.top = pos.top;
12900
- this.info.style.bottom = pos.bottom;
12901
- this.info.style.maxWidth = pos.maxWidth;
12902
- this.info.className = "cm-tooltip cm-completionInfo cm-completionInfo-" + pos.class;
13297
+ if (pos.style)
13298
+ this.info.style.cssText = pos.style;
13299
+ this.info.className = "cm-tooltip cm-completionInfo " + (pos.class || "");
12903
13300
  } else {
12904
- this.info.style.top = "-1e6px";
13301
+ this.info.style.cssText = "top: -1e6px";
12905
13302
  }
12906
13303
  }
12907
13304
  }
@@ -12911,8 +13308,21 @@ var CompletionTooltip = class {
12911
13308
  ul.setAttribute("role", "listbox");
12912
13309
  ul.setAttribute("aria-expanded", "true");
12913
13310
  ul.setAttribute("aria-label", this.view.state.phrase("Completions"));
13311
+ let curSection = null;
12914
13312
  for (let i = range.from; i < range.to; i++) {
12915
- let { completion, match } = options[i];
13313
+ let { completion, match } = options[i], { section } = completion;
13314
+ if (section) {
13315
+ let name = typeof section == "string" ? section : section.name;
13316
+ if (name != curSection && (i > range.from || range.from == 0)) {
13317
+ curSection = name;
13318
+ if (typeof section != "string" && section.header) {
13319
+ ul.appendChild(section.header(section));
13320
+ } else {
13321
+ let header = ul.appendChild(document.createElement("completion-section"));
13322
+ header.textContent = name;
13323
+ }
13324
+ }
13325
+ }
12916
13326
  const li = ul.appendChild(document.createElement("li"));
12917
13327
  li.id = id + "-" + i;
12918
13328
  li.setAttribute("role", "option");
@@ -12947,31 +13357,57 @@ function score(option) {
12947
13357
  return (option.boost || 0) * 100 + (option.apply ? 10 : 0) + (option.info ? 5 : 0) + (option.type ? 1 : 0);
12948
13358
  }
12949
13359
  function sortOptions(active, state) {
12950
- let options = [], i = 0;
13360
+ let options = [];
13361
+ let sections = null;
13362
+ let addOption = (option) => {
13363
+ options.push(option);
13364
+ let { section } = option.completion;
13365
+ if (section) {
13366
+ if (!sections)
13367
+ sections = [];
13368
+ let name = typeof section == "string" ? section : section.name;
13369
+ if (!sections.some((s) => s.name == name))
13370
+ sections.push(typeof section == "string" ? { name } : section);
13371
+ }
13372
+ };
12951
13373
  for (let a of active)
12952
13374
  if (a.hasResult()) {
12953
13375
  if (a.result.filter === false) {
12954
13376
  let getMatch = a.result.getMatch;
12955
13377
  for (let option of a.result.options) {
12956
- let match = [1e9 - i++];
13378
+ let match = [1e9 - options.length];
12957
13379
  if (getMatch)
12958
13380
  for (let n of getMatch(option))
12959
13381
  match.push(n);
12960
- options.push(new Option(option, a, match));
13382
+ addOption(new Option(option, a.source, match, match[0]));
12961
13383
  }
12962
13384
  } else {
12963
13385
  let matcher = new FuzzyMatcher(state.sliceDoc(a.from, a.to)), match;
12964
13386
  for (let option of a.result.options)
12965
13387
  if (match = matcher.match(option.label)) {
12966
- if (option.boost != null)
12967
- match[0] += option.boost;
12968
- options.push(new Option(option, a, match));
13388
+ addOption(new Option(option, a.source, match, match[0] + (option.boost || 0)));
12969
13389
  }
12970
13390
  }
12971
13391
  }
13392
+ if (sections) {
13393
+ let sectionOrder = /* @__PURE__ */ Object.create(null), pos = 0;
13394
+ let cmp = (a, b) => {
13395
+ var _a2, _b;
13396
+ 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);
13397
+ };
13398
+ for (let s of sections.sort(cmp)) {
13399
+ pos -= 1e5;
13400
+ sectionOrder[s.name] = pos;
13401
+ }
13402
+ for (let option of options) {
13403
+ let { section } = option.completion;
13404
+ if (section)
13405
+ option.score += sectionOrder[typeof section == "string" ? section : section.name];
13406
+ }
13407
+ }
12972
13408
  let result = [], prev = null;
12973
13409
  let compare2 = state.facet(completionConfig).compareCompletions;
12974
- for (let opt of options.sort((a, b) => b.match[0] - a.match[0] || compare2(a.completion, b.completion))) {
13410
+ for (let opt of options.sort((a, b) => b.score - a.score || compare2(a.completion, b.completion))) {
12975
13411
  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)
12976
13412
  result.push(opt);
12977
13413
  else if (score(opt.completion) > score(prev))
@@ -13207,8 +13643,6 @@ function checkValid(validFor, state, from, to) {
13207
13643
  let text = state.sliceDoc(from, to);
13208
13644
  return typeof validFor == "function" ? validFor(text, from, to, state) : ensureAnchor(validFor, true).test(text);
13209
13645
  }
13210
- var startCompletionEffect = /* @__PURE__ */ StateEffect.define();
13211
- var closeCompletionEffect = /* @__PURE__ */ StateEffect.define();
13212
13646
  var setActiveEffect = /* @__PURE__ */ StateEffect.define({
13213
13647
  map(sources, mapping) {
13214
13648
  return sources.map((s) => s.map(mapping));
@@ -13227,196 +13661,6 @@ var completionState = /* @__PURE__ */ StateField.define({
13227
13661
  EditorView.contentAttributes.from(f, (state) => state.attrs)
13228
13662
  ]
13229
13663
  });
13230
- function moveCompletionSelection(forward, by = "option") {
13231
- return (view) => {
13232
- let cState = view.state.field(completionState, false);
13233
- if (!cState || !cState.open || cState.open.disabled || Date.now() - cState.open.timestamp < view.state.facet(completionConfig).interactionDelay)
13234
- return false;
13235
- let step = 1, tooltip;
13236
- if (by == "page" && (tooltip = getTooltip(view, cState.open.tooltip)))
13237
- step = Math.max(2, Math.floor(tooltip.dom.offsetHeight / tooltip.dom.querySelector("li").offsetHeight) - 1);
13238
- let { length: length2 } = cState.open.options;
13239
- let selected = cState.open.selected > -1 ? cState.open.selected + step * (forward ? 1 : -1) : forward ? 0 : length2 - 1;
13240
- if (selected < 0)
13241
- selected = by == "page" ? 0 : length2 - 1;
13242
- else if (selected >= length2)
13243
- selected = by == "page" ? length2 - 1 : 0;
13244
- view.dispatch({ effects: setSelectedEffect.of(selected) });
13245
- return true;
13246
- };
13247
- }
13248
- var acceptCompletion = (view) => {
13249
- let cState = view.state.field(completionState, false);
13250
- if (view.state.readOnly || !cState || !cState.open || cState.open.selected < 0 || Date.now() - cState.open.timestamp < view.state.facet(completionConfig).interactionDelay)
13251
- return false;
13252
- if (!cState.open.disabled)
13253
- applyCompletion(view, cState.open.options[cState.open.selected]);
13254
- return true;
13255
- };
13256
- var startCompletion = (view) => {
13257
- let cState = view.state.field(completionState, false);
13258
- if (!cState)
13259
- return false;
13260
- view.dispatch({ effects: startCompletionEffect.of(true) });
13261
- return true;
13262
- };
13263
- var closeCompletion = (view) => {
13264
- let cState = view.state.field(completionState, false);
13265
- if (!cState || !cState.active.some(
13266
- (a) => a.state != 0
13267
- /* State.Inactive */
13268
- ))
13269
- return false;
13270
- view.dispatch({ effects: closeCompletionEffect.of(null) });
13271
- return true;
13272
- };
13273
- var RunningQuery = class {
13274
- constructor(active, context) {
13275
- this.active = active;
13276
- this.context = context;
13277
- this.time = Date.now();
13278
- this.updates = [];
13279
- this.done = void 0;
13280
- }
13281
- };
13282
- var DebounceTime = 50;
13283
- var MaxUpdateCount = 50;
13284
- var MinAbortTime = 1e3;
13285
- var completionPlugin = /* @__PURE__ */ ViewPlugin.fromClass(class {
13286
- constructor(view) {
13287
- this.view = view;
13288
- this.debounceUpdate = -1;
13289
- this.running = [];
13290
- this.debounceAccept = -1;
13291
- this.composing = 0;
13292
- for (let active of view.state.field(completionState).active)
13293
- if (active.state == 1)
13294
- this.startQuery(active);
13295
- }
13296
- update(update) {
13297
- let cState = update.state.field(completionState);
13298
- if (!update.selectionSet && !update.docChanged && update.startState.field(completionState) == cState)
13299
- return;
13300
- let doesReset = update.transactions.some((tr) => {
13301
- return (tr.selection || tr.docChanged) && !getUserEvent(tr);
13302
- });
13303
- for (let i = 0; i < this.running.length; i++) {
13304
- let query = this.running[i];
13305
- if (doesReset || query.updates.length + update.transactions.length > MaxUpdateCount && Date.now() - query.time > MinAbortTime) {
13306
- for (let handler of query.context.abortListeners) {
13307
- try {
13308
- handler();
13309
- } catch (e) {
13310
- logException(this.view.state, e);
13311
- }
13312
- }
13313
- query.context.abortListeners = null;
13314
- this.running.splice(i--, 1);
13315
- } else {
13316
- query.updates.push(...update.transactions);
13317
- }
13318
- }
13319
- if (this.debounceUpdate > -1)
13320
- clearTimeout(this.debounceUpdate);
13321
- this.debounceUpdate = cState.active.some((a) => a.state == 1 && !this.running.some((q) => q.active.source == a.source)) ? setTimeout(() => this.startUpdate(), DebounceTime) : -1;
13322
- if (this.composing != 0)
13323
- for (let tr of update.transactions) {
13324
- if (getUserEvent(tr) == "input")
13325
- this.composing = 2;
13326
- else if (this.composing == 2 && tr.selection)
13327
- this.composing = 3;
13328
- }
13329
- }
13330
- startUpdate() {
13331
- this.debounceUpdate = -1;
13332
- let { state } = this.view, cState = state.field(completionState);
13333
- for (let active of cState.active) {
13334
- if (active.state == 1 && !this.running.some((r) => r.active.source == active.source))
13335
- this.startQuery(active);
13336
- }
13337
- }
13338
- startQuery(active) {
13339
- let { state } = this.view, pos = cur(state);
13340
- let context = new CompletionContext(state, pos, active.explicitPos == pos);
13341
- let pending = new RunningQuery(active, context);
13342
- this.running.push(pending);
13343
- Promise.resolve(active.source(context)).then((result) => {
13344
- if (!pending.context.aborted) {
13345
- pending.done = result || null;
13346
- this.scheduleAccept();
13347
- }
13348
- }, (err) => {
13349
- this.view.dispatch({ effects: closeCompletionEffect.of(null) });
13350
- logException(this.view.state, err);
13351
- });
13352
- }
13353
- scheduleAccept() {
13354
- if (this.running.every((q) => q.done !== void 0))
13355
- this.accept();
13356
- else if (this.debounceAccept < 0)
13357
- this.debounceAccept = setTimeout(() => this.accept(), DebounceTime);
13358
- }
13359
- // For each finished query in this.running, try to create a result
13360
- // or, if appropriate, restart the query.
13361
- accept() {
13362
- var _a2;
13363
- if (this.debounceAccept > -1)
13364
- clearTimeout(this.debounceAccept);
13365
- this.debounceAccept = -1;
13366
- let updated = [];
13367
- let conf = this.view.state.facet(completionConfig);
13368
- for (let i = 0; i < this.running.length; i++) {
13369
- let query = this.running[i];
13370
- if (query.done === void 0)
13371
- continue;
13372
- this.running.splice(i--, 1);
13373
- if (query.done) {
13374
- 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));
13375
- for (let tr of query.updates)
13376
- active = active.update(tr, conf);
13377
- if (active.hasResult()) {
13378
- updated.push(active);
13379
- continue;
13380
- }
13381
- }
13382
- let current = this.view.state.field(completionState).active.find((a) => a.source == query.active.source);
13383
- if (current && current.state == 1) {
13384
- if (query.done == null) {
13385
- let active = new ActiveSource(
13386
- query.active.source,
13387
- 0
13388
- /* State.Inactive */
13389
- );
13390
- for (let tr of query.updates)
13391
- active = active.update(tr, conf);
13392
- if (active.state != 1)
13393
- updated.push(active);
13394
- } else {
13395
- this.startQuery(current);
13396
- }
13397
- }
13398
- }
13399
- if (updated.length)
13400
- this.view.dispatch({ effects: setActiveEffect.of(updated) });
13401
- }
13402
- }, {
13403
- eventHandlers: {
13404
- blur() {
13405
- let state = this.view.state.field(completionState, false);
13406
- if (state && state.tooltip && this.view.state.facet(completionConfig).closeOnBlur)
13407
- this.view.dispatch({ effects: closeCompletionEffect.of(null) });
13408
- },
13409
- compositionstart() {
13410
- this.composing = 1;
13411
- },
13412
- compositionend() {
13413
- if (this.composing == 3) {
13414
- setTimeout(() => this.view.dispatch({ effects: startCompletionEffect.of(false) }), 20);
13415
- }
13416
- this.composing = 0;
13417
- }
13418
- }
13419
- });
13420
13664
  var baseTheme2 = /* @__PURE__ */ EditorView.baseTheme({
13421
13665
  ".cm-tooltip.cm-tooltip-autocomplete": {
13422
13666
  "& > ul": {
@@ -13431,12 +13675,20 @@ var baseTheme2 = /* @__PURE__ */ EditorView.baseTheme({
13431
13675
  listStyle: "none",
13432
13676
  margin: 0,
13433
13677
  padding: 0,
13678
+ "& > li, & > completion-section": {
13679
+ padding: "1px 3px",
13680
+ lineHeight: 1.2
13681
+ },
13434
13682
  "& > li": {
13435
13683
  overflowX: "hidden",
13436
13684
  textOverflow: "ellipsis",
13437
- cursor: "pointer",
13438
- padding: "1px 3px",
13439
- lineHeight: 1.2
13685
+ cursor: "pointer"
13686
+ },
13687
+ "& > completion-section": {
13688
+ display: "list-item",
13689
+ borderBottom: "1px solid silver",
13690
+ paddingLeft: "0.5em",
13691
+ opacity: 0.7
13440
13692
  }
13441
13693
  }
13442
13694
  },
@@ -13543,11 +13795,6 @@ var closeBracketEffect = /* @__PURE__ */ StateEffect.define({
13543
13795
  return mapped == null ? void 0 : mapped;
13544
13796
  }
13545
13797
  });
13546
- var skipBracketEffect = /* @__PURE__ */ StateEffect.define({
13547
- map(value, mapping) {
13548
- return mapping.mapPos(value);
13549
- }
13550
- });
13551
13798
  var closedBracket = /* @__PURE__ */ new class extends RangeValue {
13552
13799
  }();
13553
13800
  closedBracket.startSide = 1;
@@ -13564,12 +13811,9 @@ var bracketState = /* @__PURE__ */ StateField.define({
13564
13811
  value = RangeSet.empty;
13565
13812
  }
13566
13813
  value = value.map(tr.changes);
13567
- for (let effect of tr.effects) {
13814
+ for (let effect of tr.effects)
13568
13815
  if (effect.is(closeBracketEffect))
13569
13816
  value = value.update({ add: [closedBracket.range(effect.value, effect.value + 1)] });
13570
- else if (effect.is(skipBracketEffect))
13571
- value = value.update({ filter: (from) => from != effect.value });
13572
- }
13573
13817
  return value;
13574
13818
  }
13575
13819
  });
@@ -13646,15 +13890,17 @@ function handleOpen(state, open, close, closeBefore) {
13646
13890
  });
13647
13891
  }
13648
13892
  function handleClose(state, _open, close) {
13649
- let dont = null, moved = state.selection.ranges.map((range) => {
13893
+ let dont = null, changes = state.changeByRange((range) => {
13650
13894
  if (range.empty && nextChar(state.doc, range.head) == close)
13651
- return EditorSelection.cursor(range.head + close.length);
13652
- return dont = range;
13895
+ return {
13896
+ changes: { from: range.head, to: range.head + close.length, insert: close },
13897
+ range: EditorSelection.cursor(range.head + close.length)
13898
+ };
13899
+ return dont = { range };
13653
13900
  });
13654
- return dont ? null : state.update({
13655
- selection: EditorSelection.create(moved, state.selection.mainIndex),
13901
+ return dont ? null : state.update(changes, {
13656
13902
  scrollIntoView: true,
13657
- effects: state.selection.ranges.map(({ from }) => skipBracketEffect.of(from))
13903
+ userEvent: "input.type"
13658
13904
  });
13659
13905
  }
13660
13906
  function handleSame(state, token, allowTriple, config2) {
@@ -13676,9 +13922,10 @@ function handleSame(state, token, allowTriple, config2) {
13676
13922
  };
13677
13923
  } else if (closedBracketAt(state, pos)) {
13678
13924
  let isTriple = allowTriple && state.sliceDoc(pos, pos + token.length * 3) == token + token + token;
13925
+ let content = isTriple ? token + token + token : token;
13679
13926
  return {
13680
- range: EditorSelection.cursor(pos + token.length * (isTriple ? 3 : 1)),
13681
- effects: skipBracketEffect.of(pos)
13927
+ changes: { from: pos, to: pos + content.length, insert: content },
13928
+ range: EditorSelection.cursor(pos + content.length)
13682
13929
  };
13683
13930
  }
13684
13931
  } else if (allowTriple && state.sliceDoc(pos - 2 * token.length, pos) == token + token && (start = canStartStringAt(state, pos - 2 * token.length, stringPrefixes)) > -1 && nodeStart(state, start)) {
@@ -13762,7 +14009,7 @@ var completionKeymapExt = /* @__PURE__ */ Prec.highest(/* @__PURE__ */ keymap.co
13762
14009
  // ../../node_modules/@codemirror/commands/dist/index.js
13763
14010
  import { NodeProp as NodeProp2 } from "@lezer/common";
13764
14011
  var toggleComment = (target) => {
13765
- let { state } = target, line = state.doc.lineAt(state.selection.main.head), config2 = getConfig(target.state, line.from);
14012
+ let { state } = target, line = state.doc.lineAt(state.selection.main.from), config2 = getConfig(target.state, line.from);
13766
14013
  return config2.line ? toggleLineComment(target) : config2.block ? toggleBlockCommentByLine(target) : false;
13767
14014
  };
13768
14015
  function command(f, option) {
@@ -13839,7 +14086,7 @@ function selectedLineRanges(state) {
13839
14086
  if (last >= 0 && ranges[last].to > fromLine.from)
13840
14087
  ranges[last].to = toLine.to;
13841
14088
  else
13842
- ranges.push({ from: fromLine.from, to: toLine.to });
14089
+ ranges.push({ from: fromLine.from + /^\s*/.exec(fromLine.text)[0].length, to: toLine.to });
13843
14090
  }
13844
14091
  return ranges;
13845
14092
  }
@@ -13870,13 +14117,13 @@ function changeLineComment(option, state, ranges = state.selection.ranges) {
13870
14117
  let prevLine = -1;
13871
14118
  for (let { from, to } of ranges) {
13872
14119
  let startI = lines.length, minIndent = 1e9;
14120
+ let token = getConfig(state, from).line;
14121
+ if (!token)
14122
+ continue;
13873
14123
  for (let pos = from; pos <= to; ) {
13874
14124
  let line = state.doc.lineAt(pos);
13875
14125
  if (line.from > prevLine && (from == to || to > line.from)) {
13876
14126
  prevLine = line.from;
13877
- let token = getConfig(state, line.from).line;
13878
- if (!token)
13879
- continue;
13880
14127
  let indent = /^\s*/.exec(line.text)[0].length;
13881
14128
  let empty = indent == line.length;
13882
14129
  let comment = line.text.slice(indent, indent + token.length) == token ? indent : -1;