sqlui 0.1.76 → 0.1.77

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,10 +5,6 @@
5
5
  The data structure for documents. @nonabstract
6
6
  */
7
7
  class Text {
8
- /**
9
- @internal
10
- */
11
- constructor() { }
12
8
  /**
13
9
  Get the line description around the given position.
14
10
  */
@@ -103,7 +99,8 @@
103
99
  return new LineCursor(inner);
104
100
  }
105
101
  /**
106
- @internal
102
+ Return the document as a string, using newline characters to
103
+ separate lines.
107
104
  */
108
105
  toString() { return this.sliceString(0); }
109
106
  /**
@@ -116,6 +113,10 @@
116
113
  return lines;
117
114
  }
118
115
  /**
116
+ @internal
117
+ */
118
+ constructor() { }
119
+ /**
119
120
  Create a `Text` instance for the given array of lines.
120
121
  */
121
122
  static of(text) {
@@ -2159,7 +2160,10 @@
2159
2160
  is(type) { return this.type == type; }
2160
2161
  /**
2161
2162
  Define a new effect type. The type parameter indicates the type
2162
- of values that his effect holds.
2163
+ of values that his effect holds. It should be a type that
2164
+ doesn't include `undefined`, since that is used in
2165
+ [mapping](https://codemirror.net/6/docs/ref/#state.StateEffect.map) to indicate that an effect is
2166
+ removed.
2163
2167
  */
2164
2168
  static define(spec = {}) {
2165
2169
  return new StateEffectType(spec.map || (v => v));
@@ -3302,8 +3306,7 @@
3302
3306
  static compare(oldSets, newSets,
3303
3307
  /**
3304
3308
  This indicates how the underlying data changed between these
3305
- ranges, and is needed to synchronize the iteration. `from` and
3306
- `to` are coordinates in the _new_ space, after these changes.
3309
+ ranges, and is needed to synchronize the iteration.
3307
3310
  */
3308
3311
  textDiff, comparator,
3309
3312
  /**
@@ -3414,6 +3417,18 @@
3414
3417
  an array of [`Range`](https://codemirror.net/6/docs/ref/#state.Range) objects.
3415
3418
  */
3416
3419
  class RangeSetBuilder {
3420
+ finishChunk(newArrays) {
3421
+ this.chunks.push(new Chunk(this.from, this.to, this.value, this.maxPoint));
3422
+ this.chunkPos.push(this.chunkStart);
3423
+ this.chunkStart = -1;
3424
+ this.setMaxPoint = Math.max(this.setMaxPoint, this.maxPoint);
3425
+ this.maxPoint = -1;
3426
+ if (newArrays) {
3427
+ this.from = [];
3428
+ this.to = [];
3429
+ this.value = [];
3430
+ }
3431
+ }
3417
3432
  /**
3418
3433
  Create an empty builder.
3419
3434
  */
@@ -3431,18 +3446,6 @@
3431
3446
  this.setMaxPoint = -1;
3432
3447
  this.nextLayer = null;
3433
3448
  }
3434
- finishChunk(newArrays) {
3435
- this.chunks.push(new Chunk(this.from, this.to, this.value, this.maxPoint));
3436
- this.chunkPos.push(this.chunkStart);
3437
- this.chunkStart = -1;
3438
- this.setMaxPoint = Math.max(this.setMaxPoint, this.maxPoint);
3439
- this.maxPoint = -1;
3440
- if (newArrays) {
3441
- this.from = [];
3442
- this.to = [];
3443
- this.value = [];
3444
- }
3445
- }
3446
3449
  /**
3447
3450
  Add a range. Ranges should be added in sorted (by `from` and
3448
3451
  `value.startSide`) order.
@@ -3802,7 +3805,7 @@
3802
3805
  let end = diff < 0 ? a.to + dPos : b.to, clipEnd = Math.min(end, endB);
3803
3806
  if (a.point || b.point) {
3804
3807
  if (!(a.point && b.point && (a.point == b.point || a.point.eq(b.point)) &&
3805
- sameValues(a.activeForPoint(a.to + dPos), b.activeForPoint(b.to))))
3808
+ sameValues(a.activeForPoint(a.to), b.activeForPoint(b.to))))
3806
3809
  comparator.comparePoint(pos, clipEnd, a.point, b.point);
3807
3810
  }
3808
3811
  else {
@@ -3965,20 +3968,22 @@
3965
3968
  }
3966
3969
  }
3967
3970
 
3968
- let adoptedSet = null;
3971
+ let adoptedSet = new Map; //<Document, StyleSet>
3969
3972
 
3970
3973
  class StyleSet {
3971
3974
  constructor(root) {
3972
- if (!root.head && root.adoptedStyleSheets && typeof CSSStyleSheet != "undefined") {
3973
- if (adoptedSet) {
3974
- root.adoptedStyleSheets = [adoptedSet.sheet, ...root.adoptedStyleSheets];
3975
- return root[SET] = adoptedSet
3975
+ let doc = root.ownerDocument || root, win = doc.defaultView;
3976
+ if (!root.head && root.adoptedStyleSheets && win.CSSStyleSheet) {
3977
+ let adopted = adoptedSet.get(doc);
3978
+ if (adopted) {
3979
+ root.adoptedStyleSheets = [adopted.sheet, ...root.adoptedStyleSheets];
3980
+ return root[SET] = adopted
3976
3981
  }
3977
- this.sheet = new CSSStyleSheet;
3982
+ this.sheet = new win.CSSStyleSheet;
3978
3983
  root.adoptedStyleSheets = [this.sheet, ...root.adoptedStyleSheets];
3979
- adoptedSet = this;
3984
+ adoptedSet.set(doc, this);
3980
3985
  } else {
3981
- this.styleTag = (root.ownerDocument || root).createElement("style");
3986
+ this.styleTag = doc.createElement("style");
3982
3987
  let target = root.head || root;
3983
3988
  target.insertBefore(this.styleTag, target.firstChild);
3984
3989
  }
@@ -4124,10 +4129,8 @@
4124
4129
  222: "\""
4125
4130
  };
4126
4131
 
4127
- var chrome$1 = typeof navigator != "undefined" && /Chrome\/(\d+)/.exec(navigator.userAgent);
4128
4132
  var mac = typeof navigator != "undefined" && /Mac/.test(navigator.platform);
4129
4133
  var ie$1 = typeof navigator != "undefined" && /MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);
4130
- var brokenModifierNames = mac || chrome$1 && +chrome$1[1] < 57;
4131
4134
 
4132
4135
  // Fill in the digit keys
4133
4136
  for (var i = 0; i < 10; i++) base[48 + i] = base[96 + i] = String(i);
@@ -4145,9 +4148,11 @@
4145
4148
  for (var code in base) if (!shift.hasOwnProperty(code)) shift[code] = base[code];
4146
4149
 
4147
4150
  function keyName(event) {
4148
- var ignoreKey = brokenModifierNames && (event.ctrlKey || event.altKey || event.metaKey) ||
4149
- ie$1 && event.shiftKey && event.key && event.key.length == 1 ||
4150
- event.key == "Unidentified";
4151
+ // On macOS, keys held with Shift and Cmd don't reflect the effect of Shift in `.key`.
4152
+ // On IE, shift effect is never included in `.key`.
4153
+ var ignoreKey = mac && event.metaKey && event.shiftKey && !event.ctrlKey && !event.altKey ||
4154
+ ie$1 && event.shiftKey && event.key && event.key.length == 1 ||
4155
+ event.key == "Unidentified";
4151
4156
  var name = (!ignoreKey && event.key) ||
4152
4157
  (event.shiftKey ? shift : base)[event.keyCode] ||
4153
4158
  event.key || "Unidentified";
@@ -4246,7 +4251,6 @@
4246
4251
  function maxOffset(node) {
4247
4252
  return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length;
4248
4253
  }
4249
- const Rect0 = { left: 0, right: 0, top: 0, bottom: 0 };
4250
4254
  function flattenRect(rect, left) {
4251
4255
  let x = left ? rect.left : rect.right;
4252
4256
  return { left: x, right: x, top: rect.top, bottom: rect.bottom };
@@ -4379,7 +4383,9 @@
4379
4383
  this.focusNode == domSel.focusNode && this.focusOffset == domSel.focusOffset;
4380
4384
  }
4381
4385
  setRange(range) {
4382
- this.set(range.anchorNode, range.anchorOffset, range.focusNode, range.focusOffset);
4386
+ let { anchorNode, focusNode } = range;
4387
+ // Clip offsets to node size to avoid crashes when Safari reports bogus offsets (#1152)
4388
+ this.set(anchorNode, Math.min(range.anchorOffset, anchorNode ? maxOffset(anchorNode) : 0), focusNode, Math.min(range.focusOffset, focusNode ? maxOffset(focusNode) : 0));
4383
4389
  }
4384
4390
  set(anchorNode, anchorOffset, focusNode, focusOffset) {
4385
4391
  this.anchorNode = anchorNode;
@@ -4452,6 +4458,8 @@
4452
4458
  let node = selection.focusNode, offset = selection.focusOffset;
4453
4459
  if (!node || selection.anchorNode != node || selection.anchorOffset != offset)
4454
4460
  return false;
4461
+ // Safari can report bogus offsets (#1152)
4462
+ offset = Math.min(offset, maxOffset(node));
4455
4463
  for (;;) {
4456
4464
  if (offset) {
4457
4465
  if (node.nodeType != 1)
@@ -4473,6 +4481,9 @@
4473
4481
  }
4474
4482
  }
4475
4483
  }
4484
+ function isScrolledToBottom(elt) {
4485
+ return elt.scrollTop > Math.max(1, elt.scrollHeight - elt.clientHeight - 4);
4486
+ }
4476
4487
 
4477
4488
  class DOMPos {
4478
4489
  constructor(node, offset, precise = true) {
@@ -4488,7 +4499,7 @@
4488
4499
  constructor() {
4489
4500
  this.parent = null;
4490
4501
  this.dom = null;
4491
- this.dirty = 2 /* Dirty.Node */;
4502
+ this.dirty = 2 /* Node */;
4492
4503
  }
4493
4504
  get overrideDOMText() { return null; }
4494
4505
  get posAtStart() {
@@ -4509,23 +4520,19 @@
4509
4520
  posAfter(view) {
4510
4521
  return this.posBefore(view) + view.length;
4511
4522
  }
4512
- // Will return a rectangle directly before (when side < 0), after
4513
- // (side > 0) or directly on (when the browser supports it) the
4514
- // given position.
4515
- coordsAt(_pos, _side) { return null; }
4516
4523
  sync(view, track) {
4517
- if (this.dirty & 2 /* Dirty.Node */) {
4524
+ if (this.dirty & 2 /* Node */) {
4518
4525
  let parent = this.dom;
4519
4526
  let prev = null, next;
4520
4527
  for (let child of this.children) {
4521
4528
  if (child.dirty) {
4522
- if (!child.dom && (next = prev ? prev.nextSibling : parent.firstChild)) {
4529
+ if (!child.dom && (next = prev ? prev.nextSibling : parent.firstChild) && next != view.docView.compositionNode) {
4523
4530
  let contentView = ContentView.get(next);
4524
4531
  if (!contentView || !contentView.parent && contentView.canReuseDOM(child))
4525
4532
  child.reuseDOM(next);
4526
4533
  }
4527
4534
  child.sync(view, track);
4528
- child.dirty = 0 /* Dirty.Not */;
4535
+ child.dirty = 0 /* Not */;
4529
4536
  }
4530
4537
  next = prev ? prev.nextSibling : parent.firstChild;
4531
4538
  if (track && !track.written && track.node == parent && next != child.dom)
@@ -4545,11 +4552,11 @@
4545
4552
  while (next)
4546
4553
  next = rm$1(next);
4547
4554
  }
4548
- else if (this.dirty & 1 /* Dirty.Child */) {
4555
+ else if (this.dirty & 1 /* Child */) {
4549
4556
  for (let child of this.children)
4550
4557
  if (child.dirty) {
4551
4558
  child.sync(view, track);
4552
- child.dirty = 0 /* Dirty.Not */;
4559
+ child.dirty = 0 /* Not */;
4553
4560
  }
4554
4561
  }
4555
4562
  }
@@ -4614,16 +4621,16 @@
4614
4621
  endDOM: toI < this.children.length && toI >= 0 ? this.children[toI].dom : null };
4615
4622
  }
4616
4623
  markDirty(andParent = false) {
4617
- this.dirty |= 2 /* Dirty.Node */;
4624
+ this.dirty |= 2 /* Node */;
4618
4625
  this.markParentsDirty(andParent);
4619
4626
  }
4620
4627
  markParentsDirty(childList) {
4621
4628
  for (let parent = this.parent; parent; parent = parent.parent) {
4622
4629
  if (childList)
4623
- parent.dirty |= 2 /* Dirty.Node */;
4624
- if (parent.dirty & 1 /* Dirty.Child */)
4630
+ parent.dirty |= 2 /* Node */;
4631
+ if (parent.dirty & 1 /* Child */)
4625
4632
  return;
4626
- parent.dirty |= 1 /* Dirty.Child */;
4633
+ parent.dirty |= 1 /* Child */;
4627
4634
  childList = false;
4628
4635
  }
4629
4636
  }
@@ -4676,6 +4683,7 @@
4676
4683
  static get(node) { return node.cmView; }
4677
4684
  get isEditable() { return true; }
4678
4685
  get isWidget() { return false; }
4686
+ get isHidden() { return false; }
4679
4687
  merge(from, to, source, hasStart, openStart, openEnd) {
4680
4688
  return false;
4681
4689
  }
@@ -4901,13 +4909,13 @@
4901
4909
  reuseDOM(node) {
4902
4910
  if (node.nodeName == this.mark.tagName.toUpperCase()) {
4903
4911
  this.setDOM(node);
4904
- this.dirty |= 4 /* Dirty.Attrs */ | 2 /* Dirty.Node */;
4912
+ this.dirty |= 4 /* Attrs */ | 2 /* Node */;
4905
4913
  }
4906
4914
  }
4907
4915
  sync(view, track) {
4908
4916
  if (!this.dom)
4909
4917
  this.setDOM(this.setAttrs(document.createElement(this.mark.tagName)));
4910
- else if (this.dirty & 4 /* Dirty.Attrs */)
4918
+ else if (this.dirty & 4 /* Attrs */)
4911
4919
  this.setAttrs(this.dom);
4912
4920
  super.sync(view, track);
4913
4921
  }
@@ -4970,7 +4978,7 @@
4970
4978
  }
4971
4979
  let rects = textRange(text, from, to).getClientRects();
4972
4980
  if (!rects.length)
4973
- return Rect0;
4981
+ return null;
4974
4982
  let rect = rects[(flatten ? flatten < 0 : side >= 0) ? 0 : rects.length - 1];
4975
4983
  if (browser.safari && !flatten && rect.width == 0)
4976
4984
  rect = Array.prototype.find.call(rects, r => r.width) || rect;
@@ -5011,15 +5019,15 @@
5011
5019
  return true;
5012
5020
  }
5013
5021
  become(other) {
5014
- if (other.length == this.length && other instanceof WidgetView && other.side == this.side) {
5015
- if (this.widget.constructor == other.widget.constructor) {
5016
- if (!this.widget.eq(other.widget))
5017
- this.markDirty(true);
5018
- if (this.dom && !this.prevWidget)
5019
- this.prevWidget = this.widget;
5020
- this.widget = other.widget;
5021
- return true;
5022
- }
5022
+ if (other instanceof WidgetView && other.side == this.side &&
5023
+ this.widget.constructor == other.widget.constructor) {
5024
+ if (!this.widget.compare(other.widget))
5025
+ this.markDirty(true);
5026
+ if (this.dom && !this.prevWidget)
5027
+ this.prevWidget = this.widget;
5028
+ this.widget = other.widget;
5029
+ this.length = other.length;
5030
+ return true;
5023
5031
  }
5024
5032
  return false;
5025
5033
  }
@@ -5035,22 +5043,29 @@
5035
5043
  return text ? text.slice(start, start + this.length) : Text.empty;
5036
5044
  }
5037
5045
  domAtPos(pos) {
5038
- return pos == 0 ? DOMPos.before(this.dom) : DOMPos.after(this.dom, pos == this.length);
5046
+ return (this.length ? pos == 0 : this.side > 0)
5047
+ ? DOMPos.before(this.dom)
5048
+ : DOMPos.after(this.dom, pos == this.length);
5039
5049
  }
5040
5050
  domBoundsAround() { return null; }
5041
5051
  coordsAt(pos, side) {
5052
+ let custom = this.widget.coordsAt(this.dom, pos, side);
5053
+ if (custom)
5054
+ return custom;
5042
5055
  let rects = this.dom.getClientRects(), rect = null;
5043
5056
  if (!rects.length)
5044
- return Rect0;
5045
- for (let i = pos > 0 ? rects.length - 1 : 0;; i += (pos > 0 ? -1 : 1)) {
5057
+ return null;
5058
+ let fromBack = this.side ? this.side < 0 : pos > 0;
5059
+ for (let i = fromBack ? rects.length - 1 : 0;; i += (fromBack ? -1 : 1)) {
5046
5060
  rect = rects[i];
5047
5061
  if (pos > 0 ? i == 0 : i == rects.length - 1 || rect.top < rect.bottom)
5048
5062
  break;
5049
5063
  }
5050
- return this.length ? rect : flattenRect(rect, this.side > 0);
5064
+ return flattenRect(rect, !fromBack);
5051
5065
  }
5052
5066
  get isEditable() { return false; }
5053
5067
  get isWidget() { return true; }
5068
+ get isHidden() { return this.widget.isHidden; }
5054
5069
  destroy() {
5055
5070
  super.destroy();
5056
5071
  if (this.dom)
@@ -5062,14 +5077,14 @@
5062
5077
  let { topView, text } = this.widget;
5063
5078
  if (!topView)
5064
5079
  return new DOMPos(text, Math.min(pos, text.nodeValue.length));
5065
- return scanCompositionTree(pos, 0, topView, text, (v, p) => v.domAtPos(p), p => new DOMPos(text, Math.min(p, text.nodeValue.length)));
5080
+ return scanCompositionTree(pos, 0, topView, text, this.length - topView.length, (v, p) => v.domAtPos(p), (text, p) => new DOMPos(text, Math.min(p, text.nodeValue.length)));
5066
5081
  }
5067
5082
  sync() { this.setDOM(this.widget.toDOM()); }
5068
5083
  localPosFromDOM(node, offset) {
5069
5084
  let { topView, text } = this.widget;
5070
5085
  if (!topView)
5071
5086
  return Math.min(offset, this.length);
5072
- return posFromDOMInCompositionTree(node, offset, topView, text);
5087
+ return posFromDOMInCompositionTree(node, offset, topView, text, this.length - topView.length);
5073
5088
  }
5074
5089
  ignoreMutation() { return false; }
5075
5090
  get overrideDOMText() { return null; }
@@ -5077,7 +5092,7 @@
5077
5092
  let { topView, text } = this.widget;
5078
5093
  if (!topView)
5079
5094
  return textCoords(text, pos, side);
5080
- return scanCompositionTree(pos, side, topView, text, (v, pos, side) => v.coordsAt(pos, side), (pos, side) => textCoords(text, pos, side));
5095
+ return scanCompositionTree(pos, side, topView, text, this.length - topView.length, (v, pos, side) => v.coordsAt(pos, side), (text, pos, side) => textCoords(text, pos, side));
5081
5096
  }
5082
5097
  destroy() {
5083
5098
  var _a;
@@ -5090,35 +5105,68 @@
5090
5105
  // Uses the old structure of a chunk of content view frozen for
5091
5106
  // composition to try and find a reasonable DOM location for the given
5092
5107
  // offset.
5093
- function scanCompositionTree(pos, side, view, text, enterView, fromText) {
5108
+ function scanCompositionTree(pos, side, view, text, dLen, enterView, fromText) {
5094
5109
  if (view instanceof MarkView) {
5095
5110
  for (let child = view.dom.firstChild; child; child = child.nextSibling) {
5096
5111
  let desc = ContentView.get(child);
5097
- if (!desc)
5098
- return fromText(pos, side);
5099
- let hasComp = contains(child, text);
5100
- let len = desc.length + (hasComp ? text.nodeValue.length : 0);
5101
- if (pos < len || pos == len && desc.getSide() <= 0)
5102
- return hasComp ? scanCompositionTree(pos, side, desc, text, enterView, fromText) : enterView(desc, pos, side);
5103
- pos -= len;
5112
+ if (!desc) {
5113
+ let inner = scanCompositionNode(pos, side, child, fromText);
5114
+ if (typeof inner != "number")
5115
+ return inner;
5116
+ pos = inner;
5117
+ }
5118
+ else {
5119
+ let hasComp = contains(child, text);
5120
+ let len = desc.length + (hasComp ? dLen : 0);
5121
+ if (pos < len || pos == len && desc.getSide() <= 0)
5122
+ return hasComp ? scanCompositionTree(pos, side, desc, text, dLen, enterView, fromText) : enterView(desc, pos, side);
5123
+ pos -= len;
5124
+ }
5104
5125
  }
5105
5126
  return enterView(view, view.length, -1);
5106
5127
  }
5107
5128
  else if (view.dom == text) {
5108
- return fromText(pos, side);
5129
+ return fromText(text, pos, side);
5109
5130
  }
5110
5131
  else {
5111
5132
  return enterView(view, pos, side);
5112
5133
  }
5113
5134
  }
5114
- function posFromDOMInCompositionTree(node, offset, view, text) {
5135
+ function scanCompositionNode(pos, side, node, fromText) {
5136
+ if (node.nodeType == 3) {
5137
+ let len = node.nodeValue.length;
5138
+ if (pos <= len)
5139
+ return fromText(node, pos, side);
5140
+ pos -= len;
5141
+ }
5142
+ else if (node.nodeType == 1 && node.contentEditable != "false") {
5143
+ for (let child = node.firstChild; child; child = child.nextSibling) {
5144
+ let inner = scanCompositionNode(pos, side, child, fromText);
5145
+ if (typeof inner != "number")
5146
+ return inner;
5147
+ pos = inner;
5148
+ }
5149
+ }
5150
+ return pos;
5151
+ }
5152
+ function posFromDOMInCompositionTree(node, offset, view, text, dLen) {
5115
5153
  if (view instanceof MarkView) {
5116
5154
  let pos = 0;
5117
- for (let child of view.children) {
5118
- let hasComp = contains(child.dom, text);
5119
- if (contains(child.dom, node))
5120
- return pos + (hasComp ? posFromDOMInCompositionTree(node, offset, child, text) : child.localPosFromDOM(node, offset));
5121
- pos += hasComp ? text.nodeValue.length : child.length;
5155
+ for (let child = view.dom.firstChild; child; child = child.nextSibling) {
5156
+ let childView = ContentView.get(child);
5157
+ if (childView) {
5158
+ let hasComp = contains(child, text);
5159
+ if (contains(child, node))
5160
+ return pos + (hasComp ? posFromDOMInCompositionTree(node, offset, childView, text, dLen)
5161
+ : childView.localPosFromDOM(node, offset));
5162
+ pos += childView.length + (hasComp ? dLen : 0);
5163
+ }
5164
+ else {
5165
+ let inner = posFromDOMInOpaqueNode(node, offset, child);
5166
+ if (inner.result != null)
5167
+ return pos + inner.result;
5168
+ pos += inner.size;
5169
+ }
5122
5170
  }
5123
5171
  }
5124
5172
  else if (view.dom == text) {
@@ -5126,6 +5174,27 @@
5126
5174
  }
5127
5175
  return view.localPosFromDOM(node, offset);
5128
5176
  }
5177
+ function posFromDOMInOpaqueNode(node, offset, target) {
5178
+ if (target.nodeType == 3) {
5179
+ return node == target ? { result: offset } : { size: target.nodeValue.length };
5180
+ }
5181
+ else if (target.nodeType == 1 && target.contentEditable != "false") {
5182
+ let pos = 0;
5183
+ for (let child = target.firstChild, i = 0;; child = child.nextSibling, i++) {
5184
+ if (node == target && i == offset)
5185
+ return { result: pos };
5186
+ if (!child)
5187
+ return { size: pos };
5188
+ let inner = posFromDOMInOpaqueNode(node, offset, child);
5189
+ if (inner.result != null)
5190
+ return { result: offset + inner.result };
5191
+ pos += inner.size;
5192
+ }
5193
+ }
5194
+ else {
5195
+ return target.contains(node) ? { result: 0 } : { size: 0 };
5196
+ }
5197
+ }
5129
5198
  // These are drawn around uneditable widgets to avoid a number of
5130
5199
  // browser bugs that show up when the cursor is directly next to
5131
5200
  // uneditable inline content.
@@ -5153,43 +5222,14 @@
5153
5222
  localPosFromDOM() { return 0; }
5154
5223
  domBoundsAround() { return null; }
5155
5224
  coordsAt(pos) {
5156
- let imgRect = this.dom.getBoundingClientRect();
5157
- // Since the <img> height doesn't correspond to text height, try
5158
- // to borrow the height from some sibling node.
5159
- let siblingRect = inlineSiblingRect(this, this.side > 0 ? -1 : 1);
5160
- return siblingRect && siblingRect.top < imgRect.bottom && siblingRect.bottom > imgRect.top
5161
- ? { left: imgRect.left, right: imgRect.right, top: siblingRect.top, bottom: siblingRect.bottom } : imgRect;
5225
+ return this.dom.getBoundingClientRect();
5162
5226
  }
5163
5227
  get overrideDOMText() {
5164
5228
  return Text.empty;
5165
5229
  }
5230
+ get isHidden() { return true; }
5166
5231
  }
5167
5232
  TextView.prototype.children = WidgetView.prototype.children = WidgetBufferView.prototype.children = noChildren;
5168
- function inlineSiblingRect(view, side) {
5169
- let parent = view.parent, index = parent ? parent.children.indexOf(view) : -1;
5170
- while (parent && index >= 0) {
5171
- if (side < 0 ? index > 0 : index < parent.children.length) {
5172
- let next = parent.children[index + side];
5173
- if (next instanceof TextView) {
5174
- let nextRect = next.coordsAt(side < 0 ? next.length : 0, side);
5175
- if (nextRect)
5176
- return nextRect;
5177
- }
5178
- index += side;
5179
- }
5180
- else if (parent instanceof MarkView && parent.parent) {
5181
- index = parent.parent.children.indexOf(parent) + (side < 0 ? 0 : 1);
5182
- parent = parent.parent;
5183
- }
5184
- else {
5185
- let last = parent.dom.lastChild;
5186
- if (last && last.nodeName == "BR")
5187
- return last.getClientRects()[0];
5188
- break;
5189
- }
5190
- }
5191
- return undefined;
5192
- }
5193
5233
  function inlineDOMAtPos(parent, pos) {
5194
5234
  let dom = parent.dom, { children } = parent, i = 0;
5195
5235
  for (let off = 0; i < children.length; i++) {
@@ -5236,11 +5276,12 @@
5236
5276
  if (child.children.length) {
5237
5277
  scan(child, pos - off);
5238
5278
  }
5239
- else if (!after && (end > pos || off == end && child.getSide() > 0)) {
5279
+ else if ((!after || after.isHidden && side > 0) &&
5280
+ (end > pos || off == end && child.getSide() > 0)) {
5240
5281
  after = child;
5241
5282
  afterPos = pos - off;
5242
5283
  }
5243
- else if (off < pos || (off == end && child.getSide() < 0)) {
5284
+ else if (off < pos || (off == end && child.getSide() < 0) && !child.isHidden) {
5244
5285
  before = child;
5245
5286
  beforePos = pos - off;
5246
5287
  }
@@ -5340,16 +5381,35 @@
5340
5381
  */
5341
5382
  get estimatedHeight() { return -1; }
5342
5383
  /**
5384
+ For inline widgets that are displayed inline (as opposed to
5385
+ `inline-block`) and introduce line breaks (through `<br>` tags
5386
+ or textual newlines), this must indicate the amount of line
5387
+ breaks they introduce. Defaults to 0.
5388
+ */
5389
+ get lineBreaks() { return 0; }
5390
+ /**
5343
5391
  Can be used to configure which kinds of events inside the widget
5344
5392
  should be ignored by the editor. The default is to ignore all
5345
5393
  events.
5346
5394
  */
5347
5395
  ignoreEvent(event) { return true; }
5348
5396
  /**
5397
+ Override the way screen coordinates for positions at/in the
5398
+ widget are found. `pos` will be the offset into the widget, and
5399
+ `side` the side of the position that is being queried—less than
5400
+ zero for before, greater than zero for after, and zero for
5401
+ directly at that position.
5402
+ */
5403
+ coordsAt(dom, pos, side) { return null; }
5404
+ /**
5349
5405
  @internal
5350
5406
  */
5351
5407
  get customView() { return null; }
5352
5408
  /**
5409
+ @internal
5410
+ */
5411
+ get isHidden() { return false; }
5412
+ /**
5353
5413
  This is called when the an instance of the widget is removed
5354
5414
  from the editor view.
5355
5415
  */
@@ -5429,8 +5489,10 @@
5429
5489
  given position.
5430
5490
  */
5431
5491
  static widget(spec) {
5432
- let side = spec.side || 0, block = !!spec.block;
5433
- side += block ? (side > 0 ? 300000000 /* Side.BlockAfter */ : -400000000 /* Side.BlockBefore */) : (side > 0 ? 100000000 /* Side.InlineAfter */ : -100000000 /* Side.InlineBefore */);
5492
+ let side = Math.max(-10000, Math.min(10000, spec.side || 0)), block = !!spec.block;
5493
+ side += (block && !spec.inlineOrder)
5494
+ ? (side > 0 ? 300000000 /* BlockAfter */ : -400000000 /* BlockBefore */)
5495
+ : (side > 0 ? 100000000 /* InlineAfter */ : -100000000 /* InlineBefore */);
5434
5496
  return new PointDecoration(spec, side, side, block, spec.widget || null, false);
5435
5497
  }
5436
5498
  /**
@@ -5440,13 +5502,13 @@
5440
5502
  static replace(spec) {
5441
5503
  let block = !!spec.block, startSide, endSide;
5442
5504
  if (spec.isBlockGap) {
5443
- startSide = -500000000 /* Side.GapStart */;
5444
- endSide = 400000000 /* Side.GapEnd */;
5505
+ startSide = -500000000 /* GapStart */;
5506
+ endSide = 400000000 /* GapEnd */;
5445
5507
  }
5446
5508
  else {
5447
5509
  let { start, end } = getInclusive(spec, block);
5448
- startSide = (start ? (block ? -300000000 /* Side.BlockIncStart */ : -1 /* Side.InlineIncStart */) : 500000000 /* Side.NonIncStart */) - 1;
5449
- endSide = (end ? (block ? 200000000 /* Side.BlockIncEnd */ : 1 /* Side.InlineIncEnd */) : -600000000 /* Side.NonIncEnd */) + 1;
5510
+ startSide = (start ? (block ? -300000000 /* BlockIncStart */ : -1 /* InlineIncStart */) : 500000000 /* NonIncStart */) - 1;
5511
+ endSide = (end ? (block ? 200000000 /* BlockIncEnd */ : 1 /* InlineIncEnd */) : -600000000 /* NonIncEnd */) + 1;
5450
5512
  }
5451
5513
  return new PointDecoration(spec, startSide, endSide, block, spec.widget || null, true);
5452
5514
  }
@@ -5477,7 +5539,7 @@
5477
5539
  class MarkDecoration extends Decoration {
5478
5540
  constructor(spec) {
5479
5541
  let { start, end } = getInclusive(spec);
5480
- super(start ? -1 /* Side.InlineIncStart */ : 500000000 /* Side.NonIncStart */, end ? 1 /* Side.InlineIncEnd */ : -600000000 /* Side.NonIncEnd */, null, spec);
5542
+ super(start ? -1 /* InlineIncStart */ : 500000000 /* NonIncStart */, end ? 1 /* InlineIncEnd */ : -600000000 /* NonIncEnd */, null, spec);
5481
5543
  this.tagName = spec.tagName || "span";
5482
5544
  this.class = spec.class || "";
5483
5545
  this.attrs = spec.attributes || null;
@@ -5498,7 +5560,7 @@
5498
5560
  MarkDecoration.prototype.point = false;
5499
5561
  class LineDecoration extends Decoration {
5500
5562
  constructor(spec) {
5501
- super(-200000000 /* Side.Line */, -200000000 /* Side.Line */, null, spec);
5563
+ super(-200000000 /* Line */, -200000000 /* Line */, null, spec);
5502
5564
  }
5503
5565
  eq(other) {
5504
5566
  return other instanceof LineDecoration &&
@@ -5525,7 +5587,9 @@
5525
5587
  return this.startSide < this.endSide ? BlockType.WidgetRange
5526
5588
  : this.startSide <= 0 ? BlockType.WidgetBefore : BlockType.WidgetAfter;
5527
5589
  }
5528
- get heightRelevant() { return this.block || !!this.widget && this.widget.estimatedHeight >= 5; }
5590
+ get heightRelevant() {
5591
+ return this.block || !!this.widget && (this.widget.estimatedHeight >= 5 || this.widget.lineBreaks > 0);
5592
+ }
5529
5593
  eq(other) {
5530
5594
  return other instanceof PointDecoration &&
5531
5595
  widgetsEq(this.widget, other.widget) &&
@@ -5637,7 +5701,7 @@
5637
5701
  reuseDOM(node) {
5638
5702
  if (node.nodeName == "DIV") {
5639
5703
  this.setDOM(node);
5640
- this.dirty |= 4 /* Dirty.Attrs */ | 2 /* Dirty.Node */;
5704
+ this.dirty |= 4 /* Attrs */ | 2 /* Node */;
5641
5705
  }
5642
5706
  }
5643
5707
  sync(view, track) {
@@ -5647,7 +5711,7 @@
5647
5711
  this.dom.className = "cm-line";
5648
5712
  this.prevAttrs = this.attrs ? null : undefined;
5649
5713
  }
5650
- else if (this.dirty & 4 /* Dirty.Attrs */) {
5714
+ else if (this.dirty & 4 /* Attrs */) {
5651
5715
  clearAttributes(this.dom);
5652
5716
  this.dom.className = "cm-line";
5653
5717
  this.prevAttrs = this.attrs ? null : undefined;
@@ -5758,14 +5822,15 @@
5758
5822
  }
5759
5823
  domBoundsAround() { return null; }
5760
5824
  become(other) {
5761
- if (other instanceof BlockWidgetView && other.type == this.type &&
5825
+ if (other instanceof BlockWidgetView &&
5762
5826
  other.widget.constructor == this.widget.constructor) {
5763
- if (!other.widget.eq(this.widget))
5827
+ if (!other.widget.compare(this.widget))
5764
5828
  this.markDirty(true);
5765
5829
  if (this.dom && !this.prevWidget)
5766
5830
  this.prevWidget = this.widget;
5767
5831
  this.widget = other.widget;
5768
5832
  this.length = other.length;
5833
+ this.type = other.type;
5769
5834
  this.breakAfter = other.breakAfter;
5770
5835
  return true;
5771
5836
  }
@@ -5775,6 +5840,9 @@
5775
5840
  ignoreEvent(event) { return this.widget.ignoreEvent(event); }
5776
5841
  get isEditable() { return false; }
5777
5842
  get isWidget() { return true; }
5843
+ coordsAt(pos, side) {
5844
+ return this.widget.coordsAt(this.dom, pos, side);
5845
+ }
5778
5846
  destroy() {
5779
5847
  super.destroy();
5780
5848
  if (this.dom)
@@ -5791,7 +5859,7 @@
5791
5859
  this.content = [];
5792
5860
  this.curLine = null;
5793
5861
  this.breakAtStart = 0;
5794
- this.pendingBuffer = 0 /* Buf.No */;
5862
+ this.pendingBuffer = 0 /* No */;
5795
5863
  this.bufferMarks = [];
5796
5864
  // Set to false directly after a widget that covers the position after it
5797
5865
  this.atCursorPos = true;
@@ -5818,7 +5886,7 @@
5818
5886
  flushBuffer(active = this.bufferMarks) {
5819
5887
  if (this.pendingBuffer) {
5820
5888
  this.curLine.append(wrapMarks(new WidgetBufferView(-1), active), active.length);
5821
- this.pendingBuffer = 0 /* Buf.No */;
5889
+ this.pendingBuffer = 0 /* No */;
5822
5890
  }
5823
5891
  }
5824
5892
  addBlockWidget(view) {
@@ -5830,7 +5898,7 @@
5830
5898
  if (this.pendingBuffer && openEnd <= this.bufferMarks.length)
5831
5899
  this.flushBuffer();
5832
5900
  else
5833
- this.pendingBuffer = 0 /* Buf.No */;
5901
+ this.pendingBuffer = 0 /* No */;
5834
5902
  if (!this.posCovered())
5835
5903
  this.getLine();
5836
5904
  }
@@ -5859,7 +5927,7 @@
5859
5927
  this.textOff = 0;
5860
5928
  }
5861
5929
  }
5862
- let take = Math.min(this.text.length - this.textOff, length, 512 /* T.Chunk */);
5930
+ let take = Math.min(this.text.length - this.textOff, length, 512 /* Chunk */);
5863
5931
  this.flushBuffer(active.slice(active.length - openStart));
5864
5932
  this.getLine().append(wrapMarks(new TextView(this.text.slice(this.textOff, this.textOff + take)), active), openStart);
5865
5933
  this.atCursorPos = true;
@@ -5891,11 +5959,12 @@
5891
5959
  }
5892
5960
  else {
5893
5961
  let view = WidgetView.create(deco.widget || new NullWidget("span"), len, len ? 0 : deco.startSide);
5894
- let cursorBefore = this.atCursorPos && !view.isEditable && openStart <= active.length && (from < to || deco.startSide > 0);
5962
+ let cursorBefore = this.atCursorPos && !view.isEditable && openStart <= active.length &&
5963
+ (from < to || deco.startSide > 0);
5895
5964
  let cursorAfter = !view.isEditable && (from < to || openStart > active.length || deco.startSide <= 0);
5896
5965
  let line = this.getLine();
5897
- if (this.pendingBuffer == 2 /* Buf.IfCursor */ && !cursorBefore)
5898
- this.pendingBuffer = 0 /* Buf.No */;
5966
+ if (this.pendingBuffer == 2 /* IfCursor */ && !cursorBefore && !view.isEditable)
5967
+ this.pendingBuffer = 0 /* No */;
5899
5968
  this.flushBuffer(active);
5900
5969
  if (cursorBefore) {
5901
5970
  line.append(wrapMarks(new WidgetBufferView(1), active), openStart);
@@ -5903,7 +5972,7 @@
5903
5972
  }
5904
5973
  line.append(wrapMarks(view, active), openStart);
5905
5974
  this.atCursorPos = cursorAfter;
5906
- this.pendingBuffer = !cursorAfter ? 0 /* Buf.No */ : from < to || openStart > active.length ? 1 /* Buf.Yes */ : 2 /* Buf.IfCursor */;
5975
+ this.pendingBuffer = !cursorAfter ? 0 /* No */ : from < to || openStart > active.length ? 1 /* Yes */ : 2 /* IfCursor */;
5907
5976
  if (this.pendingBuffer)
5908
5977
  this.bufferMarks = active.slice();
5909
5978
  }
@@ -5948,6 +6017,7 @@
5948
6017
  eq(other) { return other.tag == this.tag; }
5949
6018
  toDOM() { return document.createElement(this.tag); }
5950
6019
  updateDOM(elt) { return elt.nodeName.toLowerCase() == this.tag; }
6020
+ get isHidden() { return true; }
5951
6021
  }
5952
6022
 
5953
6023
  const clickAddsSelectionRange = /*@__PURE__*/Facet.define();
@@ -6117,6 +6187,23 @@
6117
6187
  const decorations = /*@__PURE__*/Facet.define();
6118
6188
  const atomicRanges = /*@__PURE__*/Facet.define();
6119
6189
  const scrollMargins = /*@__PURE__*/Facet.define();
6190
+ function getScrollMargins(view) {
6191
+ let left = 0, right = 0, top = 0, bottom = 0;
6192
+ for (let source of view.state.facet(scrollMargins)) {
6193
+ let m = source(view);
6194
+ if (m) {
6195
+ if (m.left != null)
6196
+ left = Math.max(left, m.left);
6197
+ if (m.right != null)
6198
+ right = Math.max(right, m.right);
6199
+ if (m.top != null)
6200
+ top = Math.max(top, m.top);
6201
+ if (m.bottom != null)
6202
+ bottom = Math.max(bottom, m.bottom);
6203
+ }
6204
+ }
6205
+ return { left, right, top, bottom };
6206
+ }
6120
6207
  const styleModule = /*@__PURE__*/Facet.define();
6121
6208
  class ChangedRange {
6122
6209
  constructor(fromA, toA, fromB, toB) {
@@ -6212,27 +6299,27 @@
6212
6299
  update.
6213
6300
  */
6214
6301
  get viewportChanged() {
6215
- return (this.flags & 4 /* UpdateFlag.Viewport */) > 0;
6302
+ return (this.flags & 4 /* Viewport */) > 0;
6216
6303
  }
6217
6304
  /**
6218
6305
  Indicates whether the height of a block element in the editor
6219
6306
  changed in this update.
6220
6307
  */
6221
6308
  get heightChanged() {
6222
- return (this.flags & 2 /* UpdateFlag.Height */) > 0;
6309
+ return (this.flags & 2 /* Height */) > 0;
6223
6310
  }
6224
6311
  /**
6225
6312
  Returns true when the document was modified or the size of the
6226
6313
  editor, or elements within the editor, changed.
6227
6314
  */
6228
6315
  get geometryChanged() {
6229
- return this.docChanged || (this.flags & (8 /* UpdateFlag.Geometry */ | 2 /* UpdateFlag.Height */)) > 0;
6316
+ return this.docChanged || (this.flags & (8 /* Geometry */ | 2 /* Height */)) > 0;
6230
6317
  }
6231
6318
  /**
6232
6319
  True when this update indicates a focus change.
6233
6320
  */
6234
6321
  get focusChanged() {
6235
- return (this.flags & 1 /* UpdateFlag.Focus */) > 0;
6322
+ return (this.flags & 1 /* Focus */) > 0;
6236
6323
  }
6237
6324
  /**
6238
6325
  Whether the document changed in this update.
@@ -6290,12 +6377,12 @@
6290
6377
  }
6291
6378
  function charType(ch) {
6292
6379
  return ch <= 0xf7 ? LowTypes[ch] :
6293
- 0x590 <= ch && ch <= 0x5f4 ? 2 /* T.R */ :
6380
+ 0x590 <= ch && ch <= 0x5f4 ? 2 /* R */ :
6294
6381
  0x600 <= ch && ch <= 0x6f9 ? ArabicTypes[ch - 0x600] :
6295
- 0x6ee <= ch && ch <= 0x8ac ? 4 /* T.AL */ :
6296
- 0x2000 <= ch && ch <= 0x200b ? 256 /* T.NI */ :
6297
- 0xfb50 <= ch && ch <= 0xfdff ? 4 /* T.AL */ :
6298
- ch == 0x200c ? 256 /* T.NI */ : 1 /* T.L */;
6382
+ 0x6ee <= ch && ch <= 0x8ac ? 4 /* AL */ :
6383
+ 0x2000 <= ch && ch <= 0x200b ? 256 /* NI */ :
6384
+ 0xfb50 <= ch && ch <= 0xfdff ? 4 /* AL */ :
6385
+ ch == 0x200c ? 256 /* NI */ : 1 /* L */;
6299
6386
  }
6300
6387
  const BidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac\ufb50-\ufdff]/;
6301
6388
  /**
@@ -6360,8 +6447,8 @@
6360
6447
  // Reused array of character types
6361
6448
  const types = [];
6362
6449
  function computeOrder(line, direction) {
6363
- let len = line.length, outerType = direction == LTR ? 1 /* T.L */ : 2 /* T.R */, oppositeType = direction == LTR ? 2 /* T.R */ : 1 /* T.L */;
6364
- if (!line || outerType == 1 /* T.L */ && !BidiRE.test(line))
6450
+ let len = line.length, outerType = direction == LTR ? 1 /* L */ : 2 /* R */, oppositeType = direction == LTR ? 2 /* R */ : 1 /* L */;
6451
+ if (!line || outerType == 1 /* L */ && !BidiRE.test(line))
6365
6452
  return trivialOrder(len);
6366
6453
  // W1. Examine each non-spacing mark (NSM) in the level run, and
6367
6454
  // change the type of the NSM to the type of the previous
@@ -6375,12 +6462,12 @@
6375
6462
  // (Left after this: L, R, EN, AN, ET, CS, NI)
6376
6463
  for (let i = 0, prev = outerType, prevStrong = outerType; i < len; i++) {
6377
6464
  let type = charType(line.charCodeAt(i));
6378
- if (type == 512 /* T.NSM */)
6465
+ if (type == 512 /* NSM */)
6379
6466
  type = prev;
6380
- else if (type == 8 /* T.EN */ && prevStrong == 4 /* T.AL */)
6381
- type = 16 /* T.AN */;
6382
- types[i] = type == 4 /* T.AL */ ? 2 /* T.R */ : type;
6383
- if (type & 7 /* T.Strong */)
6467
+ else if (type == 8 /* EN */ && prevStrong == 4 /* AL */)
6468
+ type = 16 /* AN */;
6469
+ types[i] = type == 4 /* AL */ ? 2 /* R */ : type;
6470
+ if (type & 7 /* Strong */)
6384
6471
  prevStrong = type;
6385
6472
  prev = type;
6386
6473
  }
@@ -6394,26 +6481,26 @@
6394
6481
  // (Left after this: L, R, EN+AN, NI)
6395
6482
  for (let i = 0, prev = outerType, prevStrong = outerType; i < len; i++) {
6396
6483
  let type = types[i];
6397
- if (type == 128 /* T.CS */) {
6398
- if (i < len - 1 && prev == types[i + 1] && (prev & 24 /* T.Num */))
6484
+ if (type == 128 /* CS */) {
6485
+ if (i < len - 1 && prev == types[i + 1] && (prev & 24 /* Num */))
6399
6486
  type = types[i] = prev;
6400
6487
  else
6401
- types[i] = 256 /* T.NI */;
6488
+ types[i] = 256 /* NI */;
6402
6489
  }
6403
- else if (type == 64 /* T.ET */) {
6490
+ else if (type == 64 /* ET */) {
6404
6491
  let end = i + 1;
6405
- while (end < len && types[end] == 64 /* T.ET */)
6492
+ while (end < len && types[end] == 64 /* ET */)
6406
6493
  end++;
6407
- let replace = (i && prev == 8 /* T.EN */) || (end < len && types[end] == 8 /* T.EN */) ? (prevStrong == 1 /* T.L */ ? 1 /* T.L */ : 8 /* T.EN */) : 256 /* T.NI */;
6494
+ let replace = (i && prev == 8 /* EN */) || (end < len && types[end] == 8 /* EN */) ? (prevStrong == 1 /* L */ ? 1 /* L */ : 8 /* EN */) : 256 /* NI */;
6408
6495
  for (let j = i; j < end; j++)
6409
6496
  types[j] = replace;
6410
6497
  i = end - 1;
6411
6498
  }
6412
- else if (type == 8 /* T.EN */ && prevStrong == 1 /* T.L */) {
6413
- types[i] = 1 /* T.L */;
6499
+ else if (type == 8 /* EN */ && prevStrong == 1 /* L */) {
6500
+ types[i] = 1 /* L */;
6414
6501
  }
6415
6502
  prev = type;
6416
- if (type & 7 /* T.Strong */)
6503
+ if (type & 7 /* Strong */)
6417
6504
  prevStrong = type;
6418
6505
  }
6419
6506
  // N0. Process bracket pairs in an isolating run sequence
@@ -6428,9 +6515,9 @@
6428
6515
  for (let sJ = sI - 3; sJ >= 0; sJ -= 3) {
6429
6516
  if (BracketStack[sJ + 1] == -br) {
6430
6517
  let flags = BracketStack[sJ + 2];
6431
- let type = (flags & 2 /* Bracketed.EmbedInside */) ? outerType :
6432
- !(flags & 4 /* Bracketed.OppositeInside */) ? 0 :
6433
- (flags & 1 /* Bracketed.OppositeBefore */) ? oppositeType : outerType;
6518
+ let type = (flags & 2 /* EmbedInside */) ? outerType :
6519
+ !(flags & 4 /* OppositeInside */) ? 0 :
6520
+ (flags & 1 /* OppositeBefore */) ? oppositeType : outerType;
6434
6521
  if (type)
6435
6522
  types[i] = types[BracketStack[sJ]] = type;
6436
6523
  sI = sJ;
@@ -6438,7 +6525,7 @@
6438
6525
  }
6439
6526
  }
6440
6527
  }
6441
- else if (BracketStack.length == 189 /* Bracketed.MaxDepth */) {
6528
+ else if (BracketStack.length == 189 /* MaxDepth */) {
6442
6529
  break;
6443
6530
  }
6444
6531
  else {
@@ -6447,20 +6534,20 @@
6447
6534
  BracketStack[sI++] = context;
6448
6535
  }
6449
6536
  }
6450
- else if ((type = types[i]) == 2 /* T.R */ || type == 1 /* T.L */) {
6537
+ else if ((type = types[i]) == 2 /* R */ || type == 1 /* L */) {
6451
6538
  let embed = type == outerType;
6452
- context = embed ? 0 : 1 /* Bracketed.OppositeBefore */;
6539
+ context = embed ? 0 : 1 /* OppositeBefore */;
6453
6540
  for (let sJ = sI - 3; sJ >= 0; sJ -= 3) {
6454
6541
  let cur = BracketStack[sJ + 2];
6455
- if (cur & 2 /* Bracketed.EmbedInside */)
6542
+ if (cur & 2 /* EmbedInside */)
6456
6543
  break;
6457
6544
  if (embed) {
6458
- BracketStack[sJ + 2] |= 2 /* Bracketed.EmbedInside */;
6545
+ BracketStack[sJ + 2] |= 2 /* EmbedInside */;
6459
6546
  }
6460
6547
  else {
6461
- if (cur & 4 /* Bracketed.OppositeInside */)
6548
+ if (cur & 4 /* OppositeInside */)
6462
6549
  break;
6463
- BracketStack[sJ + 2] |= 4 /* Bracketed.OppositeInside */;
6550
+ BracketStack[sJ + 2] |= 4 /* OppositeInside */;
6464
6551
  }
6465
6552
  }
6466
6553
  }
@@ -6473,13 +6560,13 @@
6473
6560
  // N2. Any remaining neutrals take the embedding direction.
6474
6561
  // (Left after this: L, R, EN+AN)
6475
6562
  for (let i = 0; i < len; i++) {
6476
- if (types[i] == 256 /* T.NI */) {
6563
+ if (types[i] == 256 /* NI */) {
6477
6564
  let end = i + 1;
6478
- while (end < len && types[end] == 256 /* T.NI */)
6565
+ while (end < len && types[end] == 256 /* NI */)
6479
6566
  end++;
6480
- let beforeL = (i ? types[i - 1] : outerType) == 1 /* T.L */;
6481
- let afterL = (end < len ? types[end] : outerType) == 1 /* T.L */;
6482
- let replace = beforeL == afterL ? (beforeL ? 1 /* T.L */ : 2 /* T.R */) : outerType;
6567
+ let beforeL = (i ? types[i - 1] : outerType) == 1 /* L */;
6568
+ let afterL = (end < len ? types[end] : outerType) == 1 /* L */;
6569
+ let replace = beforeL == afterL ? (beforeL ? 1 /* L */ : 2 /* R */) : outerType;
6483
6570
  for (let j = i; j < end; j++)
6484
6571
  types[j] = replace;
6485
6572
  i = end - 1;
@@ -6491,15 +6578,15 @@
6491
6578
  // explicit embedding into account, we can build up the order on
6492
6579
  // the fly, without following the level-based algorithm.
6493
6580
  let order = [];
6494
- if (outerType == 1 /* T.L */) {
6581
+ if (outerType == 1 /* L */) {
6495
6582
  for (let i = 0; i < len;) {
6496
- let start = i, rtl = types[i++] != 1 /* T.L */;
6497
- while (i < len && rtl == (types[i] != 1 /* T.L */))
6583
+ let start = i, rtl = types[i++] != 1 /* L */;
6584
+ while (i < len && rtl == (types[i] != 1 /* L */))
6498
6585
  i++;
6499
6586
  if (rtl) {
6500
6587
  for (let j = i; j > start;) {
6501
- let end = j, l = types[--j] != 2 /* T.R */;
6502
- while (j > start && l == (types[j - 1] != 2 /* T.R */))
6588
+ let end = j, l = types[--j] != 2 /* R */;
6589
+ while (j > start && l == (types[j - 1] != 2 /* R */))
6503
6590
  j--;
6504
6591
  order.push(new BidiSpan(j, end, l ? 2 : 1));
6505
6592
  }
@@ -6511,8 +6598,8 @@
6511
6598
  }
6512
6599
  else {
6513
6600
  for (let i = 0; i < len;) {
6514
- let start = i, rtl = types[i++] == 2 /* T.R */;
6515
- while (i < len && rtl == (types[i] == 2 /* T.R */))
6601
+ let start = i, rtl = types[i++] == 2 /* R */;
6602
+ while (i < len && rtl == (types[i] == 2 /* R */))
6516
6603
  i++;
6517
6604
  order.push(new BidiSpan(start, i, rtl ? 1 : 2));
6518
6605
  }
@@ -6583,6 +6670,7 @@
6583
6670
  let parent = start.parentNode;
6584
6671
  for (let cur = start;;) {
6585
6672
  this.findPointBefore(parent, cur);
6673
+ let oldLen = this.text.length;
6586
6674
  this.readNode(cur);
6587
6675
  let next = cur.nextSibling;
6588
6676
  if (next == end)
@@ -6590,7 +6678,7 @@
6590
6678
  let view = ContentView.get(cur), nextView = ContentView.get(next);
6591
6679
  if (view && nextView ? view.breakAfter :
6592
6680
  (view ? view.breakAfter : isBlockElement(cur)) ||
6593
- (isBlockElement(next) && (cur.nodeName != "BR" || cur.cmIgnore)))
6681
+ (isBlockElement(next) && (cur.nodeName != "BR" || cur.cmIgnore) && this.text.length > oldLen))
6594
6682
  this.lineBreak();
6595
6683
  cur = next;
6596
6684
  }
@@ -6675,6 +6763,7 @@
6675
6763
  super();
6676
6764
  this.view = view;
6677
6765
  this.compositionDeco = Decoration.none;
6766
+ this.compositionNode = null;
6678
6767
  this.decorations = [];
6679
6768
  this.dynamicDecorationMap = [];
6680
6769
  // Track a minimum width for the editor. When measuring sizes in
@@ -6702,10 +6791,7 @@
6702
6791
  this.updateInner([new ChangedRange(0, 0, 0, view.state.doc.length)], 0);
6703
6792
  }
6704
6793
  get length() { return this.view.state.doc.length; }
6705
- // Update the document view to a given state. scrollIntoView can be
6706
- // used as a hint to compute a new viewport that includes that
6707
- // position, if we know the editor is going to scroll that position
6708
- // into view.
6794
+ // Update the document view to a given state.
6709
6795
  update(update) {
6710
6796
  let changedRanges = update.changedRanges;
6711
6797
  if (this.minWidth > 0 && changedRanges.length) {
@@ -6717,10 +6803,8 @@
6717
6803
  this.minWidthTo = update.changes.mapPos(this.minWidthTo, 1);
6718
6804
  }
6719
6805
  }
6720
- if (this.view.inputState.composing < 0)
6721
- this.compositionDeco = Decoration.none;
6722
- else if (update.transactions.length || this.dirty)
6723
- this.compositionDeco = computeCompositionDeco(this.view, update.changes);
6806
+ ({ deco: this.compositionDeco, node: this.compositionNode } =
6807
+ this.view.inputState.composing < 0 ? noComp : computeCompositionDeco(this.view, update.changes));
6724
6808
  // When the DOM nodes around the selection are moved to another
6725
6809
  // parent, Chrome sometimes reports a different selection through
6726
6810
  // getSelection than the one that it actually shows to the user.
@@ -6732,7 +6816,7 @@
6732
6816
  let prevDeco = this.decorations, deco = this.updateDeco();
6733
6817
  let decoDiff = findChangedDeco(prevDeco, deco, update.changes);
6734
6818
  changedRanges = ChangedRange.extendWithRanges(changedRanges, decoDiff);
6735
- if (this.dirty == 0 /* Dirty.Not */ && changedRanges.length == 0) {
6819
+ if (this.dirty == 0 /* Not */ && changedRanges.length == 0) {
6736
6820
  return false;
6737
6821
  }
6738
6822
  else {
@@ -6761,7 +6845,7 @@
6761
6845
  // to detect that situation.
6762
6846
  let track = browser.chrome || browser.ios ? { node: observer.selectionRange.focusNode, written: false } : undefined;
6763
6847
  this.sync(this.view, track);
6764
- this.dirty = 0 /* Dirty.Not */;
6848
+ this.dirty = 0 /* Not */;
6765
6849
  if (track && (track.written || observer.selectionRange.focusNode != track.node))
6766
6850
  this.forceSelection = true;
6767
6851
  this.dom.style.height = "";
@@ -6790,7 +6874,10 @@
6790
6874
  updateSelection(mustRead = false, fromPointer = false) {
6791
6875
  if (mustRead || !this.view.observer.selectionRange.focusNode)
6792
6876
  this.view.observer.readSelectionRange();
6793
- if (!(fromPointer || this.mayControlSelection()))
6877
+ let activeElt = this.view.root.activeElement, focused = activeElt == this.dom;
6878
+ let selectionNotFocus = !focused &&
6879
+ hasSelection(this.dom, this.view.observer.selectionRange) && !(activeElt && this.dom.contains(activeElt));
6880
+ if (!(focused || fromPointer || selectionNotFocus))
6794
6881
  return;
6795
6882
  let force = this.forceSelection;
6796
6883
  this.forceSelection = false;
@@ -6800,7 +6887,7 @@
6800
6887
  let head = main.empty ? anchor : this.domAtPos(main.head);
6801
6888
  // Always reset on Firefox when next to an uneditable node to
6802
6889
  // avoid invisible cursor bugs (#111)
6803
- if (browser.gecko && main.empty && betweenUneditable(anchor)) {
6890
+ if (browser.gecko && main.empty && !this.compositionDeco.size && betweenUneditable(anchor)) {
6804
6891
  let dummy = document.createTextNode("");
6805
6892
  this.view.observer.ignore(() => anchor.node.insertBefore(dummy, anchor.node.childNodes[anchor.offset] || null));
6806
6893
  anchor = head = new DOMPos(dummy, 0);
@@ -6827,10 +6914,10 @@
6827
6914
  // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=1612076
6828
6915
  if (browser.gecko) {
6829
6916
  let nextTo = nextToUneditable(anchor.node, anchor.offset);
6830
- if (nextTo && nextTo != (1 /* NextTo.Before */ | 2 /* NextTo.After */)) {
6831
- let text = nearbyTextNode(anchor.node, anchor.offset, nextTo == 1 /* NextTo.Before */ ? 1 : -1);
6917
+ if (nextTo && nextTo != (1 /* Before */ | 2 /* After */)) {
6918
+ let text = nearbyTextNode(anchor.node, anchor.offset, nextTo == 1 /* Before */ ? 1 : -1);
6832
6919
  if (text)
6833
- anchor = new DOMPos(text, nextTo == 1 /* NextTo.Before */ ? 0 : text.nodeValue.length);
6920
+ anchor = new DOMPos(text, nextTo == 1 /* Before */ ? 0 : text.nodeValue.length);
6834
6921
  }
6835
6922
  }
6836
6923
  rawSel.collapse(anchor.node, anchor.offset);
@@ -6860,6 +6947,11 @@
6860
6947
  rawSel.removeAllRanges();
6861
6948
  rawSel.addRange(range);
6862
6949
  }
6950
+ if (selectionNotFocus && this.view.root.activeElement == this.dom) {
6951
+ this.dom.blur();
6952
+ if (activeElt)
6953
+ activeElt.focus();
6954
+ }
6863
6955
  });
6864
6956
  this.view.observer.setSelectionRange(anchor, head);
6865
6957
  }
@@ -6893,11 +6985,6 @@
6893
6985
  if (view.docView.posFromDOM(newRange.anchorNode, newRange.anchorOffset) != cursor.from)
6894
6986
  sel.collapse(anchorNode, anchorOffset);
6895
6987
  }
6896
- mayControlSelection() {
6897
- let active = this.view.root.activeElement;
6898
- return active == this.dom ||
6899
- hasSelection(this.dom, this.view.observer.selectionRange) && !(active && this.dom.contains(active));
6900
- }
6901
6988
  nearest(dom) {
6902
6989
  for (let cur = dom; cur;) {
6903
6990
  let domView = ContentView.get(cur);
@@ -7044,22 +7131,10 @@
7044
7131
  if (!range.empty && (other = this.coordsAt(range.anchor, range.anchor > range.head ? -1 : 1)))
7045
7132
  rect = { left: Math.min(rect.left, other.left), top: Math.min(rect.top, other.top),
7046
7133
  right: Math.max(rect.right, other.right), bottom: Math.max(rect.bottom, other.bottom) };
7047
- let mLeft = 0, mRight = 0, mTop = 0, mBottom = 0;
7048
- for (let margins of this.view.state.facet(scrollMargins).map(f => f(this.view)))
7049
- if (margins) {
7050
- let { left, right, top, bottom } = margins;
7051
- if (left != null)
7052
- mLeft = Math.max(mLeft, left);
7053
- if (right != null)
7054
- mRight = Math.max(mRight, right);
7055
- if (top != null)
7056
- mTop = Math.max(mTop, top);
7057
- if (bottom != null)
7058
- mBottom = Math.max(mBottom, bottom);
7059
- }
7134
+ let margins = getScrollMargins(this.view);
7060
7135
  let targetRect = {
7061
- left: rect.left - mLeft, top: rect.top - mTop,
7062
- right: rect.right + mRight, bottom: rect.bottom + mBottom
7136
+ left: rect.left - margins.left, top: rect.top - margins.top,
7137
+ right: rect.right + margins.right, bottom: rect.bottom + margins.bottom
7063
7138
  };
7064
7139
  scrollRectIntoView(this.view.scrollDOM, targetRect, range.head < range.anchor ? -1 : 1, target.x, target.y, target.xMargin, target.yMargin, this.view.textDirection == Direction.LTR);
7065
7140
  }
@@ -7117,32 +7192,40 @@
7117
7192
  return { from, to: from + cView.length, node: cView.dom, text: textNode };
7118
7193
  }
7119
7194
  }
7195
+ const noComp = { deco: Decoration.none, node: null };
7120
7196
  function computeCompositionDeco(view, changes) {
7121
7197
  let surrounding = compositionSurroundingNode(view);
7122
7198
  if (!surrounding)
7123
- return Decoration.none;
7199
+ return noComp;
7124
7200
  let { from, to, node, text: textNode } = surrounding;
7125
7201
  let newFrom = changes.mapPos(from, 1), newTo = Math.max(newFrom, changes.mapPos(to, -1));
7126
- let { state } = view, text = node.nodeType == 3 ? node.nodeValue :
7127
- new DOMReader([], state).readRange(node.firstChild, null).text;
7202
+ let { state } = view, reader = new DOMReader([], state);
7203
+ if (node.nodeType == 3)
7204
+ reader.readTextNode(node);
7205
+ else
7206
+ reader.readRange(node.firstChild, null);
7207
+ let { text } = reader;
7208
+ if (text.indexOf(LineBreakPlaceholder) > -1)
7209
+ return noComp; // Don't try to preserve multi-line compositions
7128
7210
  if (newTo - newFrom < text.length) {
7129
- if (state.doc.sliceString(newFrom, Math.min(state.doc.length, newFrom + text.length), LineBreakPlaceholder) == text)
7211
+ if (state.doc.sliceString(newFrom, Math.min(state.doc.length, newFrom + text.length)) == text)
7130
7212
  newTo = newFrom + text.length;
7131
- else if (state.doc.sliceString(Math.max(0, newTo - text.length), newTo, LineBreakPlaceholder) == text)
7213
+ else if (state.doc.sliceString(Math.max(0, newTo - text.length), newTo) == text)
7132
7214
  newFrom = newTo - text.length;
7133
7215
  else
7134
- return Decoration.none;
7216
+ return noComp;
7135
7217
  }
7136
- else if (state.doc.sliceString(newFrom, newTo, LineBreakPlaceholder) != text) {
7137
- return Decoration.none;
7218
+ else if (state.doc.sliceString(newFrom, newTo) != text) {
7219
+ return noComp;
7138
7220
  }
7139
7221
  let topView = ContentView.get(node);
7140
7222
  if (topView instanceof CompositionView)
7141
7223
  topView = topView.widget.topView;
7142
7224
  else if (topView)
7143
7225
  topView.parent = null;
7144
- return Decoration.set(Decoration.replace({ widget: new CompositionWidget(node, textNode, topView), inclusive: true })
7226
+ let deco = Decoration.set(Decoration.replace({ widget: new CompositionWidget(node, textNode, topView), inclusive: true })
7145
7227
  .range(newFrom, newTo));
7228
+ return { deco, node };
7146
7229
  }
7147
7230
  class CompositionWidget extends WidgetType {
7148
7231
  constructor(top, text, topView) {
@@ -7186,8 +7269,8 @@
7186
7269
  function nextToUneditable(node, offset) {
7187
7270
  if (node.nodeType != 1)
7188
7271
  return 0;
7189
- return (offset && node.childNodes[offset - 1].contentEditable == "false" ? 1 /* NextTo.Before */ : 0) |
7190
- (offset < node.childNodes.length && node.childNodes[offset].contentEditable == "false" ? 2 /* NextTo.After */ : 0);
7272
+ return (offset && node.childNodes[offset - 1].contentEditable == "false" ? 1 /* Before */ : 0) |
7273
+ (offset < node.childNodes.length && node.childNodes[offset].contentEditable == "false" ? 2 /* After */ : 0);
7191
7274
  }
7192
7275
  class DecorationComparator$1 {
7193
7276
  constructor() {
@@ -7354,7 +7437,7 @@
7354
7437
  if (yOffset > docHeight)
7355
7438
  return view.state.doc.length;
7356
7439
  // Scan for a text block near the queried y position
7357
- for (let halfLine = view.defaultLineHeight / 2, bounced = false;;) {
7440
+ for (let halfLine = view.viewState.heightOracle.textHeight / 2, bounced = false;;) {
7358
7441
  block = view.elementAtHeight(yOffset);
7359
7442
  if (block.type == BlockType.Text)
7360
7443
  break;
@@ -7434,7 +7517,8 @@
7434
7517
  function posAtCoordsImprecise(view, contentRect, block, x, y) {
7435
7518
  let into = Math.round((x - contentRect.left) * view.defaultCharacterWidth);
7436
7519
  if (view.lineWrapping && block.height > view.defaultLineHeight * 1.5) {
7437
- let line = Math.floor((y - block.top) / view.defaultLineHeight);
7520
+ let textHeight = view.viewState.heightOracle.textHeight;
7521
+ let line = Math.floor((y - block.top - (view.defaultLineHeight - textHeight) * 0.5) / textHeight);
7438
7522
  into += line * view.viewState.heightOracle.lineLength;
7439
7523
  }
7440
7524
  let content = view.state.sliceDoc(block.from, block.to);
@@ -7469,9 +7553,18 @@
7469
7553
  : textRange(node, 0, Math.max(node.nodeValue.length, 1)).getBoundingClientRect();
7470
7554
  return x - rect.left > 5;
7471
7555
  }
7556
+ function blockAt(view, pos) {
7557
+ let line = view.lineBlockAt(pos);
7558
+ if (Array.isArray(line.type))
7559
+ for (let l of line.type) {
7560
+ if (l.to > pos || l.to == pos && (l.to == line.to || l.type == BlockType.Text))
7561
+ return l;
7562
+ }
7563
+ return line;
7564
+ }
7472
7565
  function moveToLineBoundary(view, start, forward, includeWrap) {
7473
- let line = view.state.doc.lineAt(start.head);
7474
- let coords = !includeWrap || !view.lineWrapping ? null
7566
+ let line = blockAt(view, start.head);
7567
+ let coords = !includeWrap || line.type != BlockType.Text || !(view.lineWrapping || line.widgetLineBreaks) ? null
7475
7568
  : view.coordsAtPos(start.assoc < 0 && start.head > line.from ? start.head - 1 : start.head);
7476
7569
  if (coords) {
7477
7570
  let editorRect = view.dom.getBoundingClientRect();
@@ -7481,9 +7574,7 @@
7481
7574
  if (pos != null)
7482
7575
  return EditorSelection.cursor(pos, forward ? -1 : 1);
7483
7576
  }
7484
- let lineView = LineView.find(view.docView, start.head);
7485
- let end = lineView ? (forward ? lineView.posAtEnd : lineView.posAtStart) : (forward ? line.to : line.from);
7486
- return EditorSelection.cursor(end, forward ? -1 : 1);
7577
+ return EditorSelection.cursor(forward ? line.to : line.from, forward ? -1 : 1);
7487
7578
  }
7488
7579
  function moveByChar(view, start, forward, by) {
7489
7580
  let line = view.state.doc.lineAt(start.head), spans = view.bidiSpans(line);
@@ -7538,7 +7629,7 @@
7538
7629
  startY = (dir < 0 ? line.top : line.bottom) + docTop;
7539
7630
  }
7540
7631
  let resolvedGoal = rect.left + goal;
7541
- let dist = distance !== null && distance !== void 0 ? distance : (view.defaultLineHeight >> 1);
7632
+ let dist = distance !== null && distance !== void 0 ? distance : (view.viewState.heightOracle.textHeight >> 1);
7542
7633
  for (let extra = 0;; extra += 10) {
7543
7634
  let curY = startY + (dist + extra) * dir;
7544
7635
  let pos = posAtCoords(view, { x: resolvedGoal, y: curY }, false, dir);
@@ -7546,15 +7637,15 @@
7546
7637
  return EditorSelection.cursor(pos, start.assoc, undefined, goal);
7547
7638
  }
7548
7639
  }
7549
- function skipAtoms(view, oldPos, pos) {
7550
- let atoms = view.state.facet(atomicRanges).map(f => f(view));
7640
+ function skipAtomicRanges(atoms, pos, bias) {
7551
7641
  for (;;) {
7552
- let moved = false;
7642
+ let moved = 0;
7553
7643
  for (let set of atoms) {
7554
- set.between(pos.from - 1, pos.from + 1, (from, to, value) => {
7555
- if (pos.from > from && pos.from < to) {
7556
- pos = oldPos.head > pos.from ? EditorSelection.cursor(from, 1) : EditorSelection.cursor(to, -1);
7557
- moved = true;
7644
+ set.between(pos - 1, pos + 1, (from, to, value) => {
7645
+ if (pos > from && pos < to) {
7646
+ let side = moved || bias || (pos - from < to - pos ? -1 : 1);
7647
+ pos = side < 0 ? from : to;
7648
+ moved = side;
7558
7649
  }
7559
7650
  });
7560
7651
  }
@@ -7562,6 +7653,10 @@
7562
7653
  return pos;
7563
7654
  }
7564
7655
  }
7656
+ function skipAtoms(view, oldPos, pos) {
7657
+ let newPos = skipAtomicRanges(view.state.facet(atomicRanges).map(f => f(view)), pos.from, oldPos.head > pos.from ? -1 : 1);
7658
+ return newPos == pos.from ? pos : EditorSelection.cursor(newPos, newPos < pos.from ? 1 : -1);
7659
+ }
7565
7660
 
7566
7661
  // This will also be where dragging info and such goes
7567
7662
  class InputState {
@@ -7594,7 +7689,15 @@
7594
7689
  // first, false means first has already been marked for this
7595
7690
  // composition)
7596
7691
  this.compositionFirstChange = null;
7692
+ // End time of the previous composition
7597
7693
  this.compositionEndedAt = 0;
7694
+ // Used in a kludge to detect when an Enter keypress should be
7695
+ // considered part of the composition on Safari, which fires events
7696
+ // in the wrong order
7697
+ this.compositionPendingKey = false;
7698
+ // Used to categorize changes as part of a composition, even when
7699
+ // the mutation events fire shortly after the compositionend event
7700
+ this.compositionPendingChange = false;
7598
7701
  this.mouseSelection = null;
7599
7702
  let handleEvent = (handler, event) => {
7600
7703
  if (this.ignoreDuringComposition(event))
@@ -7628,6 +7731,10 @@
7628
7731
  }
7629
7732
  }
7630
7733
  });
7734
+ view.scrollDOM.addEventListener("drop", (event) => {
7735
+ if (event.target == view.scrollDOM && event.clientY > view.contentDOM.getBoundingClientRect().bottom)
7736
+ handleEvent(handlers.drop, event);
7737
+ });
7631
7738
  if (browser.chrome && browser.chrome_version == 102) { // FIXME remove at some point
7632
7739
  // On Chrome 102, viewport updates somehow stop wheel-based
7633
7740
  // scrolling. Turning off pointer events during the scroll seems
@@ -7708,6 +7815,8 @@
7708
7815
  this.lastKeyTime = Date.now();
7709
7816
  if (event.keyCode == 9 && Date.now() < this.lastEscPress + 2000)
7710
7817
  return true;
7818
+ if (event.keyCode != 27 && modifierCodes.indexOf(event.keyCode) < 0)
7819
+ view.inputState.lastEscPress = 0;
7711
7820
  // Chrome for Android usually doesn't fire proper key events, but
7712
7821
  // occasionally does, usually surrounded by a bunch of complicated
7713
7822
  // composition changes. When an enter or backspace key event is
@@ -7751,8 +7860,8 @@
7751
7860
  // compositionend and keydown events are sometimes emitted in the
7752
7861
  // wrong order. The key event should still be ignored, even when
7753
7862
  // it happens after the compositionend event.
7754
- if (browser.safari && !browser.ios && Date.now() - this.compositionEndedAt < 100) {
7755
- this.compositionEndedAt = 0;
7863
+ if (browser.safari && !browser.ios && this.compositionPendingKey && Date.now() - this.compositionEndedAt < 100) {
7864
+ this.compositionPendingKey = false;
7756
7865
  return true;
7757
7866
  }
7758
7867
  return false;
@@ -7779,13 +7888,15 @@
7779
7888
  const PendingKeys = [
7780
7889
  { key: "Backspace", keyCode: 8, inputType: "deleteContentBackward" },
7781
7890
  { key: "Enter", keyCode: 13, inputType: "insertParagraph" },
7891
+ { key: "Enter", keyCode: 13, inputType: "insertLineBreak" },
7782
7892
  { key: "Delete", keyCode: 46, inputType: "deleteContentForward" }
7783
7893
  ];
7784
7894
  const EmacsyPendingKeys = "dthko";
7785
7895
  // Key codes for modifier keys
7786
7896
  const modifierCodes = [16, 17, 18, 20, 91, 92, 224, 225];
7897
+ const dragScrollMargin = 6;
7787
7898
  function dragScrollSpeed(dist) {
7788
- return dist * 0.7 + 8;
7899
+ return Math.max(0, dist) * 0.7 + 8;
7789
7900
  }
7790
7901
  class MouseSelection {
7791
7902
  constructor(view, startEvent, style, mustSelect) {
@@ -7796,12 +7907,12 @@
7796
7907
  this.scrolling = -1;
7797
7908
  this.lastEvent = startEvent;
7798
7909
  this.scrollParent = scrollableParent(view.contentDOM);
7910
+ this.atoms = view.state.facet(atomicRanges).map(f => f(view));
7799
7911
  let doc = view.contentDOM.ownerDocument;
7800
7912
  doc.addEventListener("mousemove", this.move = this.move.bind(this));
7801
7913
  doc.addEventListener("mouseup", this.up = this.up.bind(this));
7802
7914
  this.extend = startEvent.shiftKey;
7803
7915
  this.multiple = view.state.facet(EditorState.allowMultipleSelections) && addsSelectionRange(view, startEvent);
7804
- this.dragMove = dragMovesSelection(view, startEvent);
7805
7916
  this.dragging = isInPrimarySelection(view, startEvent) && getClickType(startEvent) == 1 ? null : false;
7806
7917
  }
7807
7918
  start(event) {
@@ -7822,13 +7933,14 @@
7822
7933
  let sx = 0, sy = 0;
7823
7934
  let rect = ((_a = this.scrollParent) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect())
7824
7935
  || { left: 0, top: 0, right: this.view.win.innerWidth, bottom: this.view.win.innerHeight };
7825
- if (event.clientX <= rect.left)
7936
+ let margins = getScrollMargins(this.view);
7937
+ if (event.clientX - margins.left <= rect.left + dragScrollMargin)
7826
7938
  sx = -dragScrollSpeed(rect.left - event.clientX);
7827
- else if (event.clientX >= rect.right)
7939
+ else if (event.clientX + margins.right >= rect.right - dragScrollMargin)
7828
7940
  sx = dragScrollSpeed(event.clientX - rect.right);
7829
- if (event.clientY <= rect.top)
7941
+ if (event.clientY - margins.top <= rect.top + dragScrollMargin)
7830
7942
  sy = -dragScrollSpeed(rect.top - event.clientY);
7831
- else if (event.clientY >= rect.bottom)
7943
+ else if (event.clientY + margins.bottom >= rect.bottom - dragScrollMargin)
7832
7944
  sy = dragScrollSpeed(event.clientY - rect.bottom);
7833
7945
  this.setScrollSpeed(sx, sy);
7834
7946
  }
@@ -7868,10 +7980,33 @@
7868
7980
  if (this.dragging === false)
7869
7981
  this.select(this.lastEvent);
7870
7982
  }
7983
+ skipAtoms(sel) {
7984
+ let ranges = null;
7985
+ for (let i = 0; i < sel.ranges.length; i++) {
7986
+ let range = sel.ranges[i], updated = null;
7987
+ if (range.empty) {
7988
+ let pos = skipAtomicRanges(this.atoms, range.from, 0);
7989
+ if (pos != range.from)
7990
+ updated = EditorSelection.cursor(pos, -1);
7991
+ }
7992
+ else {
7993
+ let from = skipAtomicRanges(this.atoms, range.from, -1);
7994
+ let to = skipAtomicRanges(this.atoms, range.to, 1);
7995
+ if (from != range.from || to != range.to)
7996
+ updated = EditorSelection.range(range.from == range.anchor ? from : to, range.from == range.head ? from : to);
7997
+ }
7998
+ if (updated) {
7999
+ if (!ranges)
8000
+ ranges = sel.ranges.slice();
8001
+ ranges[i] = updated;
8002
+ }
8003
+ }
8004
+ return ranges ? EditorSelection.create(ranges, sel.mainIndex) : sel;
8005
+ }
7871
8006
  select(event) {
7872
- let selection = this.style.get(event, this.extend, this.multiple);
7873
- if (this.mustSelect || !selection.eq(this.view.state.selection) ||
7874
- selection.main.assoc != this.view.state.selection.main.assoc)
8007
+ let { view } = this, selection = this.skipAtoms(this.style.get(event, this.extend, this.multiple));
8008
+ if (this.mustSelect || !selection.eq(view.state.selection) ||
8009
+ selection.main.assoc != view.state.selection.main.assoc)
7875
8010
  this.view.dispatch({
7876
8011
  selection,
7877
8012
  userEvent: "select.pointer"
@@ -7976,8 +8111,6 @@
7976
8111
  view.inputState.setSelectionOrigin("select");
7977
8112
  if (event.keyCode == 27)
7978
8113
  view.inputState.lastEscPress = Date.now();
7979
- else if (modifierCodes.indexOf(event.keyCode) < 0)
7980
- view.inputState.lastEscPress = 0;
7981
8114
  };
7982
8115
  handlers.touchstart = (view, e) => {
7983
8116
  view.inputState.lastTouchTime = Date.now();
@@ -8000,7 +8133,7 @@
8000
8133
  if (!style && event.button == 0)
8001
8134
  style = basicMouseSelection(view, event);
8002
8135
  if (style) {
8003
- let mustFocus = view.root.activeElement != view.contentDOM;
8136
+ let mustFocus = !view.hasFocus;
8004
8137
  view.inputState.startMouseSelection(new MouseSelection(view, event, style, mustFocus));
8005
8138
  if (mustFocus)
8006
8139
  view.observer.ignore(() => focusPreventScroll(view.contentDOM));
@@ -8075,7 +8208,7 @@
8075
8208
  }
8076
8209
  },
8077
8210
  get(event, extend, multiple) {
8078
- let cur = queryPos(view, event);
8211
+ let cur = queryPos(view, event), removed;
8079
8212
  let range = rangeForClick(view, cur.pos, cur.bias, type);
8080
8213
  if (start.pos != cur.pos && !extend) {
8081
8214
  let startRange = rangeForClick(view, start.pos, start.bias, type);
@@ -8084,8 +8217,8 @@
8084
8217
  }
8085
8218
  if (extend)
8086
8219
  return startSel.replaceRange(startSel.main.extend(range.from, range.to));
8087
- else if (multiple && startSel.ranges.length > 1 && startSel.ranges.some(r => r.eq(range)))
8088
- return removeRange(startSel, range);
8220
+ else if (multiple && type == 1 && startSel.ranges.length > 1 && (removed = removeRangeAround(startSel, cur.pos)))
8221
+ return removed;
8089
8222
  else if (multiple)
8090
8223
  return startSel.addRange(range);
8091
8224
  else
@@ -8093,11 +8226,13 @@
8093
8226
  }
8094
8227
  };
8095
8228
  }
8096
- function removeRange(sel, range) {
8097
- for (let i = 0;; i++) {
8098
- if (sel.ranges[i].eq(range))
8229
+ function removeRangeAround(sel, pos) {
8230
+ for (let i = 0; i < sel.ranges.length; i++) {
8231
+ let { from, to } = sel.ranges[i];
8232
+ if (from <= pos && to >= pos)
8099
8233
  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));
8100
8234
  }
8235
+ return null;
8101
8236
  }
8102
8237
  handlers.dragstart = (view, event) => {
8103
8238
  let { selection: { main } } = view.state;
@@ -8115,7 +8250,7 @@
8115
8250
  let dropPos = view.posAtCoords({ x: event.clientX, y: event.clientY }, false);
8116
8251
  event.preventDefault();
8117
8252
  let { mouseSelection } = view.inputState;
8118
- let del = direct && mouseSelection && mouseSelection.dragging && mouseSelection.dragMove ?
8253
+ let del = direct && mouseSelection && mouseSelection.dragging && dragMovesSelection(view, event) ?
8119
8254
  { from: mouseSelection.dragging.from, to: mouseSelection.dragging.to } : null;
8120
8255
  let ins = { from: dropPos, insert: text };
8121
8256
  let changes = view.state.changes(del ? [del, ins] : ins);
@@ -8274,14 +8409,26 @@
8274
8409
  handlers.compositionend = view => {
8275
8410
  view.inputState.composing = -1;
8276
8411
  view.inputState.compositionEndedAt = Date.now();
8412
+ view.inputState.compositionPendingKey = true;
8413
+ view.inputState.compositionPendingChange = view.observer.pendingRecords().length > 0;
8277
8414
  view.inputState.compositionFirstChange = null;
8278
- if (browser.chrome && browser.android)
8415
+ if (browser.chrome && browser.android) {
8416
+ // Delay flushing for a bit on Android because it'll often fire a
8417
+ // bunch of contradictory changes in a row at end of compositon
8279
8418
  view.observer.flushSoon();
8280
- setTimeout(() => {
8281
- // Force the composition state to be cleared if it hasn't already been
8282
- if (view.inputState.composing < 0 && view.docView.compositionDeco.size)
8283
- view.update([]);
8284
- }, 50);
8419
+ }
8420
+ else if (view.inputState.compositionPendingChange) {
8421
+ // If we found pending records, schedule a flush.
8422
+ Promise.resolve().then(() => view.observer.flush());
8423
+ }
8424
+ else {
8425
+ // Otherwise, make sure that, if no changes come in soon, the
8426
+ // composition view is cleared.
8427
+ setTimeout(() => {
8428
+ if (view.inputState.composing < 0 && view.docView.compositionDeco.size)
8429
+ view.update([]);
8430
+ }, 50);
8431
+ }
8285
8432
  };
8286
8433
  handlers.contextmenu = view => {
8287
8434
  view.inputState.lastContextMenu = Date.now();
@@ -8416,15 +8563,25 @@
8416
8563
  */
8417
8564
  height,
8418
8565
  /**
8419
- The type of element this is. When querying lines, this may be
8420
- an array of all the blocks that make up the line.
8566
+ @internal Weird packed field that holds an array of children
8567
+ for composite blocks, a decoration for block widgets, and a
8568
+ number indicating the amount of widget-create line breaks for
8569
+ text blocks.
8421
8570
  */
8422
- type) {
8571
+ _content) {
8423
8572
  this.from = from;
8424
8573
  this.length = length;
8425
8574
  this.top = top;
8426
8575
  this.height = height;
8427
- this.type = type;
8576
+ this._content = _content;
8577
+ }
8578
+ /**
8579
+ The type of element this is. When querying lines, this may be
8580
+ an array of all the blocks that make up the line.
8581
+ */
8582
+ get type() {
8583
+ return typeof this._content == "number" ? BlockType.Text :
8584
+ Array.isArray(this._content) ? this._content : this._content.type;
8428
8585
  }
8429
8586
  /**
8430
8587
  The end of the element as a document position.
@@ -8435,12 +8592,26 @@
8435
8592
  */
8436
8593
  get bottom() { return this.top + this.height; }
8437
8594
  /**
8595
+ If this is a widget block, this will return the widget
8596
+ associated with it.
8597
+ */
8598
+ get widget() {
8599
+ return this._content instanceof PointDecoration ? this._content.widget : null;
8600
+ }
8601
+ /**
8602
+ If this is a textblock, this holds the number of line breaks
8603
+ that appear in widgets inside the block.
8604
+ */
8605
+ get widgetLineBreaks() {
8606
+ return typeof this._content == "number" ? this._content : 0;
8607
+ }
8608
+ /**
8438
8609
  @internal
8439
8610
  */
8440
8611
  join(other) {
8441
- let detail = (Array.isArray(this.type) ? this.type : [this])
8442
- .concat(Array.isArray(other.type) ? other.type : [other]);
8443
- return new BlockInfo(this.from, this.length + other.length, this.top, this.height + other.height, detail);
8612
+ let content = (Array.isArray(this._content) ? this._content : [this])
8613
+ .concat(Array.isArray(other._content) ? other._content : [other]);
8614
+ return new BlockInfo(this.from, this.length + other.length, this.top, this.height + other.height, content);
8444
8615
  }
8445
8616
  }
8446
8617
  var QueryType$1 = /*@__PURE__*/(function (QueryType) {
@@ -8452,13 +8623,13 @@
8452
8623
  class HeightMap {
8453
8624
  constructor(length, // The number of characters covered
8454
8625
  height, // Height of this part of the document
8455
- flags = 2 /* Flag.Outdated */) {
8626
+ flags = 2 /* Outdated */) {
8456
8627
  this.length = length;
8457
8628
  this.height = height;
8458
8629
  this.flags = flags;
8459
8630
  }
8460
- get outdated() { return (this.flags & 2 /* Flag.Outdated */) > 0; }
8461
- set outdated(value) { this.flags = (value ? 2 /* Flag.Outdated */ : 0) | (this.flags & ~2 /* Flag.Outdated */); }
8631
+ get outdated() { return (this.flags & 2 /* Outdated */) > 0; }
8632
+ set outdated(value) { this.flags = (value ? 2 /* Outdated */ : 0) | (this.flags & ~2 /* Outdated */); }
8462
8633
  setHeight(oracle, height) {
8463
8634
  if (this.height != height) {
8464
8635
  if (Math.abs(this.height - height) > Epsilon)
@@ -8555,12 +8726,12 @@
8555
8726
  }
8556
8727
  HeightMap.prototype.size = 1;
8557
8728
  class HeightMapBlock extends HeightMap {
8558
- constructor(length, height, type) {
8729
+ constructor(length, height, deco) {
8559
8730
  super(length, height);
8560
- this.type = type;
8731
+ this.deco = deco;
8561
8732
  }
8562
8733
  blockAt(_height, _oracle, top, offset) {
8563
- return new BlockInfo(offset, this.length, top, this.height, this.type);
8734
+ return new BlockInfo(offset, this.length, top, this.height, this.deco || 0);
8564
8735
  }
8565
8736
  lineAt(_value, _type, oracle, top, offset) {
8566
8737
  return this.blockAt(0, oracle, top, offset);
@@ -8579,13 +8750,17 @@
8579
8750
  }
8580
8751
  class HeightMapText extends HeightMapBlock {
8581
8752
  constructor(length, height) {
8582
- super(length, height, BlockType.Text);
8753
+ super(length, height, null);
8583
8754
  this.collapsed = 0; // Amount of collapsed content in the line
8584
8755
  this.widgetHeight = 0; // Maximum inline widget height
8756
+ this.breaks = 0; // Number of widget-introduced line breaks on the line
8757
+ }
8758
+ blockAt(_height, _oracle, top, offset) {
8759
+ return new BlockInfo(offset, this.length, top, this.height, this.breaks);
8585
8760
  }
8586
8761
  replace(_from, _to, nodes) {
8587
8762
  let node = nodes[0];
8588
- if (nodes.length == 1 && (node instanceof HeightMapText || node instanceof HeightMapGap && (node.flags & 4 /* Flag.SingleLine */)) &&
8763
+ if (nodes.length == 1 && (node instanceof HeightMapText || node instanceof HeightMapGap && (node.flags & 4 /* SingleLine */)) &&
8589
8764
  Math.abs(this.length - node.length) < 10) {
8590
8765
  if (node instanceof HeightMapGap)
8591
8766
  node = new HeightMapText(node.length, this.height);
@@ -8603,7 +8778,8 @@
8603
8778
  if (measured && measured.from <= offset && measured.more)
8604
8779
  this.setHeight(oracle, measured.heights[measured.index++]);
8605
8780
  else if (force || this.outdated)
8606
- this.setHeight(oracle, Math.max(this.widgetHeight, oracle.heightForLine(this.length - this.collapsed)));
8781
+ this.setHeight(oracle, Math.max(this.widgetHeight, oracle.heightForLine(this.length - this.collapsed)) +
8782
+ this.breaks * oracle.lineHeight);
8607
8783
  this.outdated = false;
8608
8784
  return this;
8609
8785
  }
@@ -8620,7 +8796,8 @@
8620
8796
  if (oracle.lineWrapping) {
8621
8797
  let totalPerLine = Math.min(this.height, oracle.lineHeight * lines);
8622
8798
  perLine = totalPerLine / lines;
8623
- perChar = (this.height - totalPerLine) / (this.length - lines - 1);
8799
+ if (this.length > lines + 1)
8800
+ perChar = (this.height - totalPerLine) / (this.length - lines - 1);
8624
8801
  }
8625
8802
  else {
8626
8803
  perLine = this.height / lines;
@@ -8633,12 +8810,12 @@
8633
8810
  let guess = offset + Math.round(Math.max(0, Math.min(1, (height - top) / this.height)) * this.length);
8634
8811
  let line = oracle.doc.lineAt(guess), lineHeight = perLine + line.length * perChar;
8635
8812
  let lineTop = Math.max(top, height - lineHeight / 2);
8636
- return new BlockInfo(line.from, line.length, lineTop, lineHeight, BlockType.Text);
8813
+ return new BlockInfo(line.from, line.length, lineTop, lineHeight, 0);
8637
8814
  }
8638
8815
  else {
8639
8816
  let line = Math.max(0, Math.min(lastLine - firstLine, Math.floor((height - top) / perLine)));
8640
8817
  let { from, length } = oracle.doc.line(firstLine + line);
8641
- return new BlockInfo(from, length, top + perLine * line, perLine, BlockType.Text);
8818
+ return new BlockInfo(from, length, top + perLine * line, perLine, 0);
8642
8819
  }
8643
8820
  }
8644
8821
  lineAt(value, type, oracle, top, offset) {
@@ -8646,13 +8823,13 @@
8646
8823
  return this.blockAt(value, oracle, top, offset);
8647
8824
  if (type == QueryType$1.ByPosNoHeight) {
8648
8825
  let { from, to } = oracle.doc.lineAt(value);
8649
- return new BlockInfo(from, to - from, 0, 0, BlockType.Text);
8826
+ return new BlockInfo(from, to - from, 0, 0, 0);
8650
8827
  }
8651
8828
  let { firstLine, perLine, perChar } = this.heightMetrics(oracle, offset);
8652
8829
  let line = oracle.doc.lineAt(value), lineHeight = perLine + line.length * perChar;
8653
8830
  let linesAbove = line.number - firstLine;
8654
8831
  let lineTop = top + perLine * linesAbove + perChar * (line.from - offset - linesAbove);
8655
- return new BlockInfo(line.from, line.length, Math.max(top, Math.min(lineTop, top + this.height - lineHeight)), lineHeight, BlockType.Text);
8832
+ return new BlockInfo(line.from, line.length, Math.max(top, Math.min(lineTop, top + this.height - lineHeight)), lineHeight, 0);
8656
8833
  }
8657
8834
  forEachLine(from, to, oracle, top, offset, f) {
8658
8835
  from = Math.max(from, offset);
@@ -8665,7 +8842,7 @@
8665
8842
  lineTop += perLine * linesAbove + perChar * (from - offset - linesAbove);
8666
8843
  }
8667
8844
  let lineHeight = perLine + perChar * line.length;
8668
- f(new BlockInfo(line.from, line.length, lineTop, lineHeight, BlockType.Text));
8845
+ f(new BlockInfo(line.from, line.length, lineTop, lineHeight, 0));
8669
8846
  lineTop += lineHeight;
8670
8847
  pos = line.to + 1;
8671
8848
  }
@@ -8736,12 +8913,12 @@
8736
8913
  }
8737
8914
  class HeightMapBranch extends HeightMap {
8738
8915
  constructor(left, brk, right) {
8739
- super(left.length + brk + right.length, left.height + right.height, brk | (left.outdated || right.outdated ? 2 /* Flag.Outdated */ : 0));
8916
+ super(left.length + brk + right.length, left.height + right.height, brk | (left.outdated || right.outdated ? 2 /* Outdated */ : 0));
8740
8917
  this.left = left;
8741
8918
  this.right = right;
8742
8919
  this.size = left.size + right.size;
8743
8920
  }
8744
- get break() { return this.flags & 1 /* Flag.Break */; }
8921
+ get break() { return this.flags & 1 /* Break */; }
8745
8922
  blockAt(height, oracle, top, offset) {
8746
8923
  let mid = top + this.left.height;
8747
8924
  return height < mid ? this.left.blockAt(height, oracle, top, offset)
@@ -8891,14 +9068,15 @@
8891
9068
  point(from, to, deco) {
8892
9069
  if (from < to || deco.heightRelevant) {
8893
9070
  let height = deco.widget ? deco.widget.estimatedHeight : 0;
9071
+ let breaks = deco.widget ? deco.widget.lineBreaks : 0;
8894
9072
  if (height < 0)
8895
9073
  height = this.oracle.lineHeight;
8896
9074
  let len = to - from;
8897
9075
  if (deco.block) {
8898
- this.addBlock(new HeightMapBlock(len, height, deco.type));
9076
+ this.addBlock(new HeightMapBlock(len, height, deco));
8899
9077
  }
8900
- else if (len || height >= relevantWidgetHeight) {
8901
- this.addLineDeco(height, len);
9078
+ else if (len || breaks || height >= relevantWidgetHeight) {
9079
+ this.addLineDeco(height, breaks, len);
8902
9080
  }
8903
9081
  }
8904
9082
  else if (to > from) {
@@ -8925,7 +9103,7 @@
8925
9103
  blankContent(from, to) {
8926
9104
  let gap = new HeightMapGap(to - from);
8927
9105
  if (this.oracle.doc.lineAt(from).to == to)
8928
- gap.flags |= 4 /* Flag.SingleLine */;
9106
+ gap.flags |= 4 /* SingleLine */;
8929
9107
  return gap;
8930
9108
  }
8931
9109
  ensureLine() {
@@ -8938,19 +9116,22 @@
8938
9116
  return line;
8939
9117
  }
8940
9118
  addBlock(block) {
9119
+ var _a;
8941
9120
  this.enterLine();
8942
- if (block.type == BlockType.WidgetAfter && !this.isCovered)
9121
+ let type = (_a = block.deco) === null || _a === void 0 ? void 0 : _a.type;
9122
+ if (type == BlockType.WidgetAfter && !this.isCovered)
8943
9123
  this.ensureLine();
8944
9124
  this.nodes.push(block);
8945
9125
  this.writtenTo = this.pos = this.pos + block.length;
8946
- if (block.type != BlockType.WidgetBefore)
9126
+ if (type != BlockType.WidgetBefore)
8947
9127
  this.covering = block;
8948
9128
  }
8949
- addLineDeco(height, length) {
9129
+ addLineDeco(height, breaks, length) {
8950
9130
  let line = this.ensureLine();
8951
9131
  line.length += length;
8952
9132
  line.collapsed += length;
8953
9133
  line.widgetHeight = Math.max(line.widgetHeight, height);
9134
+ line.breaks += breaks;
8954
9135
  this.writtenTo = this.pos = this.pos + length;
8955
9136
  }
8956
9137
  finish(from) {
@@ -9084,6 +9265,14 @@
9084
9265
  this.contentDOMHeight = 0;
9085
9266
  this.editorHeight = 0;
9086
9267
  this.editorWidth = 0;
9268
+ this.scrollTop = 0;
9269
+ this.scrolledToBottom = true;
9270
+ // The vertical position (document-relative) to which to anchor the
9271
+ // scroll position. -1 means anchor to the end of the document.
9272
+ this.scrollAnchorPos = 0;
9273
+ // The height at the anchor position. Set by the DOM update phase.
9274
+ // -1 means no height available.
9275
+ this.scrollAnchorHeight = -1;
9087
9276
  // See VP.MaxDOMHeight
9088
9277
  this.scaler = IdScaler;
9089
9278
  this.scrollTarget = null;
@@ -9124,7 +9313,7 @@
9124
9313
  }
9125
9314
  }
9126
9315
  this.viewports = viewports.sort((a, b) => a.from - b.from);
9127
- this.scaler = this.heightMap.height <= 7000000 /* VP.MaxDOMHeight */ ? IdScaler :
9316
+ this.scaler = this.heightMap.height <= 7000000 /* MaxDOMHeight */ ? IdScaler :
9128
9317
  new BigScaler(this.heightOracle, this.heightMap, this.viewports);
9129
9318
  }
9130
9319
  updateViewportLines() {
@@ -9140,20 +9329,29 @@
9140
9329
  let contentChanges = update.changedRanges;
9141
9330
  let heightChanges = ChangedRange.extendWithRanges(contentChanges, heightRelevantDecoChanges(prevDeco, this.stateDeco, update ? update.changes : ChangeSet.empty(this.state.doc.length)));
9142
9331
  let prevHeight = this.heightMap.height;
9332
+ let scrollAnchor = this.scrolledToBottom ? null : this.scrollAnchorAt(this.scrollTop);
9143
9333
  this.heightMap = this.heightMap.applyChanges(this.stateDeco, update.startState.doc, this.heightOracle.setDoc(this.state.doc), heightChanges);
9144
9334
  if (this.heightMap.height != prevHeight)
9145
- update.flags |= 2 /* UpdateFlag.Height */;
9335
+ update.flags |= 2 /* Height */;
9336
+ if (scrollAnchor) {
9337
+ this.scrollAnchorPos = update.changes.mapPos(scrollAnchor.from, -1);
9338
+ this.scrollAnchorHeight = scrollAnchor.top;
9339
+ }
9340
+ else {
9341
+ this.scrollAnchorPos = -1;
9342
+ this.scrollAnchorHeight = this.heightMap.height;
9343
+ }
9146
9344
  let viewport = heightChanges.length ? this.mapViewport(this.viewport, update.changes) : this.viewport;
9147
9345
  if (scrollTarget && (scrollTarget.range.head < viewport.from || scrollTarget.range.head > viewport.to) ||
9148
9346
  !this.viewportIsAppropriate(viewport))
9149
9347
  viewport = this.getViewport(0, scrollTarget);
9150
- let updateLines = !update.changes.empty || (update.flags & 2 /* UpdateFlag.Height */) ||
9348
+ let updateLines = !update.changes.empty || (update.flags & 2 /* Height */) ||
9151
9349
  viewport.from != this.viewport.from || viewport.to != this.viewport.to;
9152
9350
  this.viewport = viewport;
9153
9351
  this.updateForViewport();
9154
9352
  if (updateLines)
9155
9353
  this.updateViewportLines();
9156
- if (this.lineGaps.length || this.viewport.to - this.viewport.from > (2000 /* LG.Margin */ << 1))
9354
+ if (this.lineGaps.length || this.viewport.to - this.viewport.from > (2000 /* Margin */ << 1))
9157
9355
  this.updateLineGaps(this.ensureLineGaps(this.mapLineGaps(this.lineGaps, update.changes)));
9158
9356
  update.flags |= this.computeVisibleRanges();
9159
9357
  if (scrollTarget)
@@ -9179,14 +9377,19 @@
9179
9377
  if (this.paddingTop != paddingTop || this.paddingBottom != paddingBottom) {
9180
9378
  this.paddingTop = paddingTop;
9181
9379
  this.paddingBottom = paddingBottom;
9182
- result |= 8 /* UpdateFlag.Geometry */ | 2 /* UpdateFlag.Height */;
9380
+ result |= 8 /* Geometry */ | 2 /* Height */;
9183
9381
  }
9184
9382
  if (this.editorWidth != view.scrollDOM.clientWidth) {
9185
9383
  if (oracle.lineWrapping)
9186
9384
  measureContent = true;
9187
9385
  this.editorWidth = view.scrollDOM.clientWidth;
9188
- result |= 8 /* UpdateFlag.Geometry */;
9386
+ result |= 8 /* Geometry */;
9387
+ }
9388
+ if (this.scrollTop != view.scrollDOM.scrollTop) {
9389
+ this.scrollAnchorHeight = -1;
9390
+ this.scrollTop = view.scrollDOM.scrollTop;
9189
9391
  }
9392
+ this.scrolledToBottom = isScrolledToBottom(view.scrollDOM);
9190
9393
  // Pixel viewport
9191
9394
  let pixelViewport = (this.printing ? fullPixelRange : visiblePixelRange)(dom, this.paddingTop);
9192
9395
  let dTop = pixelViewport.top - this.pixelViewport.top, dBottom = pixelViewport.bottom - this.pixelViewport.bottom;
@@ -9203,7 +9406,7 @@
9203
9406
  if (this.contentDOMWidth != contentWidth || this.editorHeight != view.scrollDOM.clientHeight) {
9204
9407
  this.contentDOMWidth = domRect.width;
9205
9408
  this.editorHeight = view.scrollDOM.clientHeight;
9206
- result |= 8 /* UpdateFlag.Geometry */;
9409
+ result |= 8 /* Geometry */;
9207
9410
  }
9208
9411
  if (measureContent) {
9209
9412
  let lineHeights = view.docView.measureVisibleLineHeights(this.viewport);
@@ -9214,7 +9417,7 @@
9214
9417
  refresh = lineHeight > 0 && oracle.refresh(whiteSpace, lineHeight, charWidth, textHeight, contentWidth / charWidth, lineHeights);
9215
9418
  if (refresh) {
9216
9419
  view.docView.minWidth = 0;
9217
- result |= 8 /* UpdateFlag.Geometry */;
9420
+ result |= 8 /* Geometry */;
9218
9421
  }
9219
9422
  }
9220
9423
  if (dTop > 0 && dBottom > 0)
@@ -9227,7 +9430,7 @@
9227
9430
  this.heightMap = (refresh ? HeightMap.empty().applyChanges(this.stateDeco, Text.empty, this.heightOracle, [new ChangedRange(0, 0, 0, view.state.doc.length)]) : this.heightMap).updateHeight(oracle, 0, refresh, new MeasuredHeights(vp.from, heights));
9228
9431
  }
9229
9432
  if (oracle.heightChanged)
9230
- result |= 2 /* UpdateFlag.Height */;
9433
+ result |= 2 /* Height */;
9231
9434
  }
9232
9435
  let viewportChange = !this.viewportIsAppropriate(this.viewport, bias) ||
9233
9436
  this.scrollTarget && (this.scrollTarget.range.head < this.viewport.from ||
@@ -9235,9 +9438,9 @@
9235
9438
  if (viewportChange)
9236
9439
  this.viewport = this.getViewport(bias, this.scrollTarget);
9237
9440
  this.updateForViewport();
9238
- if ((result & 2 /* UpdateFlag.Height */) || viewportChange)
9441
+ if ((result & 2 /* Height */) || viewportChange)
9239
9442
  this.updateViewportLines();
9240
- if (this.lineGaps.length || this.viewport.to - this.viewport.from > (2000 /* LG.Margin */ << 1))
9443
+ if (this.lineGaps.length || this.viewport.to - this.viewport.from > (2000 /* Margin */ << 1))
9241
9444
  this.updateLineGaps(this.ensureLineGaps(refresh ? [] : this.lineGaps, view));
9242
9445
  result |= this.computeVisibleRanges();
9243
9446
  if (this.mustEnforceCursorAssoc) {
@@ -9256,10 +9459,10 @@
9256
9459
  // This will divide VP.Margin between the top and the
9257
9460
  // bottom, depending on the bias (the change in viewport position
9258
9461
  // since the last update). It'll hold a number between 0 and 1
9259
- let marginTop = 0.5 - Math.max(-0.5, Math.min(0.5, bias / 1000 /* VP.Margin */ / 2));
9462
+ let marginTop = 0.5 - Math.max(-0.5, Math.min(0.5, bias / 1000 /* Margin */ / 2));
9260
9463
  let map = this.heightMap, oracle = this.heightOracle;
9261
9464
  let { visibleTop, visibleBottom } = this;
9262
- let viewport = new Viewport(map.lineAt(visibleTop - marginTop * 1000 /* VP.Margin */, QueryType$1.ByHeight, oracle, 0, 0).from, map.lineAt(visibleBottom + (1 - marginTop) * 1000 /* VP.Margin */, QueryType$1.ByHeight, oracle, 0, 0).to);
9465
+ let viewport = new Viewport(map.lineAt(visibleTop - marginTop * 1000 /* Margin */, QueryType$1.ByHeight, oracle, 0, 0).from, map.lineAt(visibleBottom + (1 - marginTop) * 1000 /* Margin */, QueryType$1.ByHeight, oracle, 0, 0).to);
9263
9466
  // If scrollTarget is given, make sure the viewport includes that position
9264
9467
  if (scrollTarget) {
9265
9468
  let { head } = scrollTarget.range;
@@ -9272,7 +9475,7 @@
9272
9475
  topPos = block.top;
9273
9476
  else
9274
9477
  topPos = block.bottom - viewHeight;
9275
- viewport = new Viewport(map.lineAt(topPos - 1000 /* VP.Margin */ / 2, QueryType$1.ByHeight, oracle, 0, 0).from, map.lineAt(topPos + viewHeight + 1000 /* VP.Margin */ / 2, QueryType$1.ByHeight, oracle, 0, 0).to);
9478
+ viewport = new Viewport(map.lineAt(topPos - 1000 /* Margin */ / 2, QueryType$1.ByHeight, oracle, 0, 0).from, map.lineAt(topPos + viewHeight + 1000 /* Margin */ / 2, QueryType$1.ByHeight, oracle, 0, 0).to);
9276
9479
  }
9277
9480
  }
9278
9481
  return viewport;
@@ -9289,10 +9492,10 @@
9289
9492
  let { top } = this.heightMap.lineAt(from, QueryType$1.ByPos, this.heightOracle, 0, 0);
9290
9493
  let { bottom } = this.heightMap.lineAt(to, QueryType$1.ByPos, this.heightOracle, 0, 0);
9291
9494
  let { visibleTop, visibleBottom } = this;
9292
- return (from == 0 || top <= visibleTop - Math.max(10 /* VP.MinCoverMargin */, Math.min(-bias, 250 /* VP.MaxCoverMargin */))) &&
9495
+ return (from == 0 || top <= visibleTop - Math.max(10 /* MinCoverMargin */, Math.min(-bias, 250 /* MaxCoverMargin */))) &&
9293
9496
  (to == this.state.doc.length ||
9294
- bottom >= visibleBottom + Math.max(10 /* VP.MinCoverMargin */, Math.min(bias, 250 /* VP.MaxCoverMargin */))) &&
9295
- (top > visibleTop - 2 * 1000 /* VP.Margin */ && bottom < visibleBottom + 2 * 1000 /* VP.Margin */);
9497
+ bottom >= visibleBottom + Math.max(10 /* MinCoverMargin */, Math.min(bias, 250 /* MaxCoverMargin */))) &&
9498
+ (top > visibleTop - 2 * 1000 /* Margin */ && bottom < visibleBottom + 2 * 1000 /* Margin */);
9296
9499
  }
9297
9500
  mapLineGaps(gaps, changes) {
9298
9501
  if (!gaps.length || changes.empty)
@@ -9312,7 +9515,7 @@
9312
9515
  // the artifacts this might produce from the user.
9313
9516
  ensureLineGaps(current, mayMeasure) {
9314
9517
  let wrapping = this.heightOracle.lineWrapping;
9315
- let margin = wrapping ? 10000 /* LG.MarginWrap */ : 2000 /* LG.Margin */, halfMargin = margin >> 1, doubleMargin = margin << 1;
9518
+ let margin = wrapping ? 10000 /* MarginWrap */ : 2000 /* Margin */, halfMargin = margin >> 1, doubleMargin = margin << 1;
9316
9519
  // The non-wrapping logic won't work at all in predominantly right-to-left text.
9317
9520
  if (this.defaultTextDirection != Direction.LTR && !wrapping)
9318
9521
  return [];
@@ -9325,8 +9528,8 @@
9325
9528
  avoid.push(sel.to);
9326
9529
  for (let pos of avoid) {
9327
9530
  if (pos > from && pos < to) {
9328
- addGap(from, pos - 10 /* LG.SelectionMargin */, line, structure);
9329
- addGap(pos + 10 /* LG.SelectionMargin */, to, line, structure);
9531
+ addGap(from, pos - 10 /* SelectionMargin */, line, structure);
9532
+ addGap(pos + 10 /* SelectionMargin */, to, line, structure);
9330
9533
  return;
9331
9534
  }
9332
9535
  }
@@ -9420,7 +9623,7 @@
9420
9623
  let changed = ranges.length != this.visibleRanges.length ||
9421
9624
  this.visibleRanges.some((r, i) => r.from != ranges[i].from || r.to != ranges[i].to);
9422
9625
  this.visibleRanges = ranges;
9423
- return changed ? 4 /* UpdateFlag.Viewport */ : 0;
9626
+ return changed ? 4 /* Viewport */ : 0;
9424
9627
  }
9425
9628
  lineBlockAt(pos) {
9426
9629
  return (pos >= this.viewport.from && pos <= this.viewport.to && this.viewportLines.find(b => b.from <= pos && b.to >= pos)) ||
@@ -9429,6 +9632,10 @@
9429
9632
  lineBlockAtHeight(height) {
9430
9633
  return scaleBlock(this.heightMap.lineAt(this.scaler.fromDOM(height), QueryType$1.ByHeight, this.heightOracle, 0, 0), this.scaler);
9431
9634
  }
9635
+ scrollAnchorAt(scrollTop) {
9636
+ let block = this.lineBlockAtHeight(scrollTop + 8);
9637
+ return block.from >= this.viewport.from || this.viewportLines[0].top - scrollTop > 200 ? block : this.viewportLines[0];
9638
+ }
9432
9639
  elementAtHeight(height) {
9433
9640
  return scaleBlock(this.heightMap.blockAt(this.scaler.fromDOM(height), this.heightOracle, 0, 0), this.scaler);
9434
9641
  }
@@ -9512,7 +9719,7 @@
9512
9719
  vpHeight += bottom - top;
9513
9720
  return { from, to, top, bottom, domTop: 0, domBottom: 0 };
9514
9721
  });
9515
- this.scale = (7000000 /* VP.MaxDOMHeight */ - vpHeight) / (heightMap.height - vpHeight);
9722
+ this.scale = (7000000 /* MaxDOMHeight */ - vpHeight) / (heightMap.height - vpHeight);
9516
9723
  for (let obj of this.viewports) {
9517
9724
  obj.domTop = domBase + (obj.top - base) * this.scale;
9518
9725
  domBase = obj.domBottom = obj.domTop + (obj.bottom - obj.top);
@@ -9546,7 +9753,7 @@
9546
9753
  if (scaler.scale == 1)
9547
9754
  return block;
9548
9755
  let bTop = scaler.toDOM(block.top), bBottom = scaler.toDOM(block.bottom);
9549
- return new BlockInfo(block.from, block.length, bTop, bBottom - bTop, Array.isArray(block.type) ? block.type.map(b => scaleBlock(b, scaler)) : block.type);
9756
+ return new BlockInfo(block.from, block.length, bTop, bBottom - bTop, Array.isArray(block._content) ? block._content.map(b => scaleBlock(b, scaler)) : block._content);
9550
9757
  }
9551
9758
 
9552
9759
  const theme = /*@__PURE__*/Facet.define({ combine: strs => strs.join(" ") });
@@ -9636,16 +9843,16 @@
9636
9843
  "&dark .cm-selectionBackground": {
9637
9844
  background: "#222"
9638
9845
  },
9639
- "&light.cm-focused .cm-selectionBackground": {
9846
+ "&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
9640
9847
  background: "#d7d4f0"
9641
9848
  },
9642
- "&dark.cm-focused .cm-selectionBackground": {
9849
+ "&dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
9643
9850
  background: "#233"
9644
9851
  },
9645
9852
  ".cm-cursorLayer": {
9646
9853
  pointerEvents: "none"
9647
9854
  },
9648
- "&.cm-focused .cm-cursorLayer": {
9855
+ "&.cm-focused > .cm-scroller > .cm-cursorLayer": {
9649
9856
  animation: "steps(1) cm-blink 1.2s infinite"
9650
9857
  },
9651
9858
  // Two animations defined so that we can switch between them to
@@ -9667,7 +9874,7 @@
9667
9874
  ".cm-dropCursor": {
9668
9875
  position: "absolute"
9669
9876
  },
9670
- "&.cm-focused .cm-cursor": {
9877
+ "&.cm-focused > .cm-scroller > .cm-cursorLayer .cm-cursor": {
9671
9878
  display: "block"
9672
9879
  },
9673
9880
  "&light .cm-activeLine": { backgroundColor: "#cceeff44" },
@@ -9836,13 +10043,13 @@
9836
10043
  function applyDOMChange(view, domChange) {
9837
10044
  let change;
9838
10045
  let { newSel } = domChange, sel = view.state.selection.main;
10046
+ let lastKey = view.inputState.lastKeyTime > Date.now() - 100 ? view.inputState.lastKeyCode : -1;
9839
10047
  if (domChange.bounds) {
9840
10048
  let { from, to } = domChange.bounds;
9841
10049
  let preferredPos = sel.from, preferredSide = null;
9842
10050
  // Prefer anchoring to end when Backspace is pressed (or, on
9843
10051
  // Android, when something was deleted)
9844
- if (view.inputState.lastKeyCode === 8 && view.inputState.lastKeyTime > Date.now() - 100 ||
9845
- browser.android && domChange.text.length < to - from) {
10052
+ if (lastKey === 8 || browser.android && domChange.text.length < to - from) {
9846
10053
  preferredPos = sel.to;
9847
10054
  preferredSide = "end";
9848
10055
  }
@@ -9850,7 +10057,7 @@
9850
10057
  if (diff) {
9851
10058
  // Chrome inserts two newlines when pressing shift-enter at the
9852
10059
  // end of a line. DomChange drops one of those.
9853
- if (browser.chrome && view.inputState.lastKeyCode == 13 &&
10060
+ if (browser.chrome && lastKey == 13 &&
9854
10061
  diff.toB == diff.from + 2 && domChange.text.slice(diff.from, diff.toB) == LineBreakPlaceholder + LineBreakPlaceholder)
9855
10062
  diff.toB--;
9856
10063
  change = { from: from + diff.from, to: from + diff.toA,
@@ -9908,7 +10115,8 @@
9908
10115
  ((change.from == sel.from && change.to == sel.to &&
9909
10116
  change.insert.length == 1 && change.insert.lines == 2 &&
9910
10117
  dispatchKey(view.contentDOM, "Enter", 13)) ||
9911
- (change.from == sel.from - 1 && change.to == sel.to && change.insert.length == 0 &&
10118
+ ((change.from == sel.from - 1 && change.to == sel.to && change.insert.length == 0 ||
10119
+ lastKey == 8 && change.insert.length < change.to - change.from) &&
9912
10120
  dispatchKey(view.contentDOM, "Backspace", 8)) ||
9913
10121
  (change.from == sel.from && change.to == sel.to + 1 && change.insert.length == 0 &&
9914
10122
  dispatchKey(view.contentDOM, "Delete", 46))))
@@ -9928,8 +10136,7 @@
9928
10136
  }
9929
10137
  else {
9930
10138
  let changes = startState.changes(change);
9931
- let mainSel = newSel && !startState.selection.main.eq(newSel.main) && newSel.main.to <= changes.newLength
9932
- ? newSel.main : undefined;
10139
+ let mainSel = newSel && newSel.main.to <= changes.newLength ? newSel.main : undefined;
9933
10140
  // Try to apply a composition change to all cursors
9934
10141
  if (startState.selection.ranges.length > 1 && view.inputState.composing >= 0 &&
9935
10142
  change.to <= sel.to && change.to >= sel.to - 10) {
@@ -9963,7 +10170,9 @@
9963
10170
  }
9964
10171
  }
9965
10172
  let userEvent = "input.type";
9966
- if (view.composing) {
10173
+ if (view.composing ||
10174
+ view.inputState.compositionPendingChange && view.inputState.compositionEndedAt > Date.now() - 50) {
10175
+ view.inputState.compositionPendingChange = false;
9967
10176
  userEvent += ".compose";
9968
10177
  if (view.inputState.compositionFirstChange) {
9969
10178
  userEvent += ".start";
@@ -10126,7 +10335,7 @@
10126
10335
  if (this.intersecting != this.view.inView)
10127
10336
  this.onScrollChanged(document.createEvent("Event"));
10128
10337
  }
10129
- }, {});
10338
+ }, { threshold: [0, .001] });
10130
10339
  this.intersection.observe(this.dom);
10131
10340
  this.gapIntersection = new IntersectionObserver(entries => {
10132
10341
  if (entries.length > 0 && entries[entries.length - 1].intersectionRatio > 0)
@@ -10305,7 +10514,10 @@
10305
10514
  let key = this.delayedAndroidKey;
10306
10515
  if (key) {
10307
10516
  this.clearDelayedAndroidKey();
10308
- if (!this.flush() && key.force)
10517
+ this.view.inputState.lastKeyCode = key.keyCode;
10518
+ this.view.inputState.lastKeyTime = Date.now();
10519
+ let flushed = this.flush();
10520
+ if (!flushed && key.force)
10309
10521
  dispatchKey(this.dom, key.key, key.keyCode);
10310
10522
  }
10311
10523
  };
@@ -10339,10 +10551,13 @@
10339
10551
  }
10340
10552
  this.flush();
10341
10553
  }
10342
- processRecords() {
10343
- let records = this.queue;
10554
+ pendingRecords() {
10344
10555
  for (let mut of this.observer.takeRecords())
10345
- records.push(mut);
10556
+ this.queue.push(mut);
10557
+ return this.queue;
10558
+ }
10559
+ processRecords() {
10560
+ let records = this.pendingRecords();
10346
10561
  if (records.length)
10347
10562
  this.queue = [];
10348
10563
  let from = -1, to = -1, typeOver = false;
@@ -10398,7 +10613,7 @@
10398
10613
  return null;
10399
10614
  cView.markDirty(rec.type == "attributes");
10400
10615
  if (rec.type == "attributes")
10401
- cView.dirty |= 4 /* Dirty.Attrs */;
10616
+ cView.dirty |= 4 /* Attrs */;
10402
10617
  if (rec.type == "childList") {
10403
10618
  let childBefore = findChild(cView, rec.previousSibling || rec.target.previousSibling, -1);
10404
10619
  let childAfter = findChild(cView, rec.nextSibling || rec.target.nextSibling, 1);
@@ -10521,7 +10736,7 @@
10521
10736
  /**
10522
10737
  @internal
10523
10738
  */
10524
- this.updateState = 2 /* UpdateState.Updating */;
10739
+ this.updateState = 2 /* Updating */;
10525
10740
  /**
10526
10741
  @internal
10527
10742
  */
@@ -10554,7 +10769,7 @@
10554
10769
  this.docView = new DocView(this);
10555
10770
  this.mountStyles();
10556
10771
  this.updateAttrs();
10557
- this.updateState = 0 /* UpdateState.Idle */;
10772
+ this.updateState = 0 /* Idle */;
10558
10773
  this.requestMeasure();
10559
10774
  if (config.parent)
10560
10775
  config.parent.appendChild(this.dom);
@@ -10607,8 +10822,9 @@
10607
10822
  */
10608
10823
  get win() { return this.dom.ownerDocument.defaultView || window; }
10609
10824
  dispatch(...input) {
10610
- this._dispatch(input.length == 1 && input[0] instanceof Transaction ? input[0]
10611
- : this.state.update(...input));
10825
+ let tr = input.length == 1 && input[0] instanceof Transaction ? input[0]
10826
+ : this.state.update(...input);
10827
+ this._dispatch(tr, this);
10612
10828
  }
10613
10829
  /**
10614
10830
  Update the view for the given array of transactions. This will
@@ -10619,7 +10835,7 @@
10619
10835
  as a primitive.
10620
10836
  */
10621
10837
  update(transactions) {
10622
- if (this.updateState != 0 /* UpdateState.Idle */)
10838
+ if (this.updateState != 0 /* Idle */)
10623
10839
  throw new Error("Calls to EditorView.update are not allowed while an update is in progress");
10624
10840
  let redrawn = false, attrsChanged = false, update;
10625
10841
  let state = this.state;
@@ -10636,7 +10852,7 @@
10636
10852
  if (transactions.some(tr => tr.annotation(isFocusChange))) {
10637
10853
  this.inputState.notifiedFocused = focus;
10638
10854
  // If a focus-change transaction is being dispatched, set this update flag.
10639
- focusFlag = 1 /* UpdateFlag.Focus */;
10855
+ focusFlag = 1 /* Focus */;
10640
10856
  }
10641
10857
  else if (focus != this.inputState.notifiedFocused) {
10642
10858
  this.inputState.notifiedFocused = focus;
@@ -10644,7 +10860,7 @@
10644
10860
  // add a flag to this update
10645
10861
  dispatchFocus = focusChangeTransaction(state, focus);
10646
10862
  if (!dispatchFocus)
10647
- focusFlag = 1 /* UpdateFlag.Focus */;
10863
+ focusFlag = 1 /* Focus */;
10648
10864
  }
10649
10865
  // If there was a pending DOM change, eagerly read it and try to
10650
10866
  // apply it after the given transactions.
@@ -10667,7 +10883,7 @@
10667
10883
  update.flags |= focusFlag;
10668
10884
  let scrollTarget = this.viewState.scrollTarget;
10669
10885
  try {
10670
- this.updateState = 2 /* UpdateState.Updating */;
10886
+ this.updateState = 2 /* Updating */;
10671
10887
  for (let tr of transactions) {
10672
10888
  if (scrollTarget)
10673
10889
  scrollTarget = scrollTarget.map(tr.changes);
@@ -10693,7 +10909,7 @@
10693
10909
  this.docView.updateSelection(redrawn, transactions.some(tr => tr.isUserEvent("select.pointer")));
10694
10910
  }
10695
10911
  finally {
10696
- this.updateState = 0 /* UpdateState.Idle */;
10912
+ this.updateState = 0 /* Idle */;
10697
10913
  }
10698
10914
  if (update.startState.facet(theme) != update.state.facet(theme))
10699
10915
  this.viewState.mustMeasureContent = true;
@@ -10720,13 +10936,13 @@
10720
10936
  [`dispatch`](https://codemirror.net/6/docs/ref/#view.EditorView.dispatch) instead.)
10721
10937
  */
10722
10938
  setState(newState) {
10723
- if (this.updateState != 0 /* UpdateState.Idle */)
10939
+ if (this.updateState != 0 /* Idle */)
10724
10940
  throw new Error("Calls to EditorView.setState are not allowed while an update is in progress");
10725
10941
  if (this.destroyed) {
10726
10942
  this.viewState.state = newState;
10727
10943
  return;
10728
10944
  }
10729
- this.updateState = 2 /* UpdateState.Updating */;
10945
+ this.updateState = 2 /* Updating */;
10730
10946
  let hadFocus = this.hasFocus;
10731
10947
  try {
10732
10948
  for (let plugin of this.plugins)
@@ -10743,7 +10959,7 @@
10743
10959
  this.bidiCache = [];
10744
10960
  }
10745
10961
  finally {
10746
- this.updateState = 0 /* UpdateState.Idle */;
10962
+ this.updateState = 0 /* Idle */;
10747
10963
  }
10748
10964
  if (hadFocus)
10749
10965
  this.focus();
@@ -10790,13 +11006,25 @@
10790
11006
  if (flush)
10791
11007
  this.observer.forceFlush();
10792
11008
  let updated = null;
10793
- let { scrollHeight, scrollTop, clientHeight } = this.scrollDOM;
10794
- let refHeight = scrollTop > scrollHeight - clientHeight - 4 ? scrollHeight : scrollTop;
11009
+ let sDOM = this.scrollDOM, { scrollTop } = sDOM;
11010
+ let { scrollAnchorPos, scrollAnchorHeight } = this.viewState;
11011
+ if (scrollTop != this.viewState.scrollTop)
11012
+ scrollAnchorHeight = -1;
11013
+ this.viewState.scrollAnchorHeight = -1;
10795
11014
  try {
10796
11015
  for (let i = 0;; i++) {
10797
- this.updateState = 1 /* UpdateState.Measuring */;
10798
- let oldViewport = this.viewport;
10799
- let refBlock = this.viewState.lineBlockAtHeight(refHeight);
11016
+ if (scrollAnchorHeight < 0) {
11017
+ if (isScrolledToBottom(sDOM)) {
11018
+ scrollAnchorPos = -1;
11019
+ scrollAnchorHeight = this.viewState.heightMap.height;
11020
+ }
11021
+ else {
11022
+ let block = this.viewState.scrollAnchorAt(scrollTop);
11023
+ scrollAnchorPos = block.from;
11024
+ scrollAnchorHeight = block.top;
11025
+ }
11026
+ }
11027
+ this.updateState = 1 /* Measuring */;
10800
11028
  let changed = this.viewState.measure(this);
10801
11029
  if (!changed && !this.measureRequests.length && this.viewState.scrollTarget == null)
10802
11030
  break;
@@ -10808,7 +11036,7 @@
10808
11036
  }
10809
11037
  let measuring = [];
10810
11038
  // Only run measure requests in this cycle when the viewport didn't change
10811
- if (!(changed & 4 /* UpdateFlag.Viewport */))
11039
+ if (!(changed & 4 /* Viewport */))
10812
11040
  [this.measureRequests, measuring] = [measuring, this.measureRequests];
10813
11041
  let measured = measuring.map(m => {
10814
11042
  try {
@@ -10819,13 +11047,13 @@
10819
11047
  return BadMeasure;
10820
11048
  }
10821
11049
  });
10822
- let update = ViewUpdate.create(this, this.state, []), redrawn = false, scrolled = false;
11050
+ let update = ViewUpdate.create(this, this.state, []), redrawn = false;
10823
11051
  update.flags |= changed;
10824
11052
  if (!updated)
10825
11053
  updated = update;
10826
11054
  else
10827
11055
  updated.flags |= changed;
10828
- this.updateState = 2 /* UpdateState.Updating */;
11056
+ this.updateState = 2 /* Updating */;
10829
11057
  if (!update.empty) {
10830
11058
  this.updatePlugins(update);
10831
11059
  this.inputState.update(update);
@@ -10843,29 +11071,32 @@
10843
11071
  logException(this.state, e);
10844
11072
  }
10845
11073
  }
10846
- if (this.viewState.editorHeight) {
10847
- if (this.viewState.scrollTarget) {
10848
- this.docView.scrollIntoView(this.viewState.scrollTarget);
10849
- this.viewState.scrollTarget = null;
10850
- scrolled = true;
10851
- }
10852
- else {
10853
- let diff = this.viewState.lineBlockAt(refBlock.from).top - refBlock.top;
10854
- if (diff > 1 || diff < -1) {
10855
- this.scrollDOM.scrollTop += diff;
10856
- scrolled = true;
10857
- }
10858
- }
10859
- }
10860
11074
  if (redrawn)
10861
11075
  this.docView.updateSelection(true);
10862
- if (this.viewport.from == oldViewport.from && this.viewport.to == oldViewport.to &&
10863
- !scrolled && this.measureRequests.length == 0)
11076
+ if (!update.viewportChanged && this.measureRequests.length == 0) {
11077
+ if (this.viewState.editorHeight) {
11078
+ if (this.viewState.scrollTarget) {
11079
+ this.docView.scrollIntoView(this.viewState.scrollTarget);
11080
+ this.viewState.scrollTarget = null;
11081
+ continue;
11082
+ }
11083
+ else {
11084
+ let newAnchorHeight = scrollAnchorPos < 0 ? this.viewState.heightMap.height :
11085
+ this.viewState.lineBlockAt(scrollAnchorPos).top;
11086
+ let diff = newAnchorHeight - scrollAnchorHeight;
11087
+ if (diff > 1 || diff < -1) {
11088
+ scrollTop = sDOM.scrollTop = scrollTop + diff;
11089
+ scrollAnchorHeight = -1;
11090
+ continue;
11091
+ }
11092
+ }
11093
+ }
10864
11094
  break;
11095
+ }
10865
11096
  }
10866
11097
  }
10867
11098
  finally {
10868
- this.updateState = 0 /* UpdateState.Idle */;
11099
+ this.updateState = 0 /* Idle */;
10869
11100
  this.measureScheduled = -1;
10870
11101
  }
10871
11102
  if (updated && !updated.empty)
@@ -10924,9 +11155,9 @@
10924
11155
  StyleModule.mount(this.root, this.styleModules.concat(baseTheme$1$2).reverse());
10925
11156
  }
10926
11157
  readMeasured() {
10927
- if (this.updateState == 2 /* UpdateState.Updating */)
11158
+ if (this.updateState == 2 /* Updating */)
10928
11159
  throw new Error("Reading the editor layout isn't allowed during an update");
10929
- if (this.updateState == 0 /* UpdateState.Idle */ && this.measureScheduled > -1)
11160
+ if (this.updateState == 0 /* Idle */ && this.measureScheduled > -1)
10930
11161
  this.measure(false);
10931
11162
  }
10932
11163
  /**
@@ -11720,15 +11951,6 @@
11720
11951
  to: Math.min(inside.to, view.moveToLineBoundary(range, true, true).from),
11721
11952
  type: BlockType.Text };
11722
11953
  }
11723
- function blockAt(view, pos) {
11724
- let line = view.lineBlockAt(pos);
11725
- if (Array.isArray(line.type))
11726
- for (let l of line.type) {
11727
- if (l.to > pos || l.to == pos && (l.to == line.to || l.type == BlockType.Text))
11728
- return l;
11729
- }
11730
- return line;
11731
- }
11732
11954
  function rectanglesForRange(view, className, range) {
11733
11955
  if (range.to <= view.viewport.from || range.from >= view.viewport.to)
11734
11956
  return [];
@@ -11742,12 +11964,10 @@
11742
11964
  let startBlock = blockAt(view, from), endBlock = blockAt(view, to);
11743
11965
  let visualStart = startBlock.type == BlockType.Text ? startBlock : null;
11744
11966
  let visualEnd = endBlock.type == BlockType.Text ? endBlock : null;
11745
- if (view.lineWrapping) {
11746
- if (visualStart)
11747
- visualStart = wrappedLine(view, from, visualStart);
11748
- if (visualEnd)
11749
- visualEnd = wrappedLine(view, to, visualEnd);
11750
- }
11967
+ if (visualStart && (view.lineWrapping || startBlock.widgetLineBreaks))
11968
+ visualStart = wrappedLine(view, from, visualStart);
11969
+ if (visualEnd && (view.lineWrapping || endBlock.widgetLineBreaks))
11970
+ visualEnd = wrappedLine(view, to, visualEnd);
11751
11971
  if (visualStart && visualEnd && visualStart.from == visualEnd.from) {
11752
11972
  return pieces(drawForLine(range.from, range.to, visualStart));
11753
11973
  }
@@ -11755,14 +11975,15 @@
11755
11975
  let top = visualStart ? drawForLine(range.from, null, visualStart) : drawForWidget(startBlock, false);
11756
11976
  let bottom = visualEnd ? drawForLine(null, range.to, visualEnd) : drawForWidget(endBlock, true);
11757
11977
  let between = [];
11758
- if ((visualStart || startBlock).to < (visualEnd || endBlock).from - 1)
11978
+ if ((visualStart || startBlock).to < (visualEnd || endBlock).from - (visualStart && visualEnd ? 1 : 0) ||
11979
+ startBlock.widgetLineBreaks > 1 && top.bottom + view.defaultLineHeight / 2 < bottom.top)
11759
11980
  between.push(piece(leftSide, top.bottom, rightSide, bottom.top));
11760
11981
  else if (top.bottom < bottom.top && view.elementAtHeight((top.bottom + bottom.top) / 2).type == BlockType.Text)
11761
11982
  top.bottom = bottom.top = (top.bottom + bottom.top) / 2;
11762
11983
  return pieces(top).concat(between).concat(pieces(bottom));
11763
11984
  }
11764
11985
  function piece(left, top, right, bottom) {
11765
- return new RectangleMarker(className, left - base.left, top - base.top - 0.01 /* C.Epsilon */, right - left, bottom - top + 0.01 /* C.Epsilon */);
11986
+ return new RectangleMarker(className, left - base.left, top - base.top - 0.01 /* Epsilon */, right - left, bottom - top + 0.01 /* Epsilon */);
11766
11987
  }
11767
11988
  function pieces({ top, bottom, horizontal }) {
11768
11989
  let pieces = [];
@@ -11780,6 +12001,8 @@
11780
12001
  // coordsAtPos queries, would break selection drawing.
11781
12002
  let fromCoords = view.coordsAtPos(from, (from == line.to ? -2 : 2));
11782
12003
  let toCoords = view.coordsAtPos(to, (to == line.from ? 2 : -2));
12004
+ if (!fromCoords || !toCoords)
12005
+ return;
11783
12006
  top = Math.min(fromCoords.top, toCoords.top, top);
11784
12007
  bottom = Math.max(fromCoords.bottom, toCoords.bottom, bottom);
11785
12008
  if (dir == Direction.LTR)
@@ -12394,6 +12617,17 @@
12394
12617
  wrap.setAttribute("aria-hidden", "true");
12395
12618
  return wrap;
12396
12619
  }
12620
+ coordsAt(dom) {
12621
+ let rects = dom.firstChild ? clientRectsFor(dom.firstChild) : [];
12622
+ if (!rects.length)
12623
+ return null;
12624
+ let style = window.getComputedStyle(dom.parentNode);
12625
+ let rect = flattenRect(rects[0], style.direction != "rtl");
12626
+ let lineHeight = parseInt(style.lineHeight);
12627
+ if (rect.bottom - rect.top > lineHeight * 1.5)
12628
+ return { left: rect.left, right: rect.right, top: rect.top, bottom: rect.top + lineHeight };
12629
+ return rect;
12630
+ }
12397
12631
  ignoreEvent() { return false; }
12398
12632
  }
12399
12633
  /**
@@ -12491,10 +12725,10 @@
12491
12725
  return EditorView.mouseSelectionStyle.of((view, event) => filter(event) ? rectangleSelectionStyle(view, event) : null);
12492
12726
  }
12493
12727
  const keys = {
12494
- Alt: [18, e => e.altKey],
12495
- Control: [17, e => e.ctrlKey],
12496
- Shift: [16, e => e.shiftKey],
12497
- Meta: [91, e => e.metaKey]
12728
+ Alt: [18, e => !!e.altKey],
12729
+ Control: [17, e => !!e.ctrlKey],
12730
+ Shift: [16, e => !!e.shiftKey],
12731
+ Meta: [91, e => !!e.metaKey]
12498
12732
  };
12499
12733
  const showCrosshair = { style: "cursor: crosshair" };
12500
12734
  /**
@@ -12731,12 +12965,12 @@
12731
12965
  continue;
12732
12966
  }
12733
12967
  let arrow = tooltip.arrow ? tView.dom.querySelector(".cm-tooltip-arrow") : null;
12734
- let arrowHeight = arrow ? 7 /* Arrow.Size */ : 0;
12968
+ let arrowHeight = arrow ? 7 /* Size */ : 0;
12735
12969
  let width = size.right - size.left, height = (_a = knownHeight.get(tView)) !== null && _a !== void 0 ? _a : size.bottom - size.top;
12736
12970
  let offset = tView.offset || noOffset, ltr = this.view.textDirection == Direction.LTR;
12737
12971
  let left = size.width > space.right - space.left ? (ltr ? space.left : space.right - size.width)
12738
- : ltr ? Math.min(pos.left - (arrow ? 14 /* Arrow.Offset */ : 0) + offset.x, space.right - width)
12739
- : Math.max(space.left, pos.left - width + (arrow ? 14 /* Arrow.Offset */ : 0) - offset.x);
12972
+ : ltr ? Math.min(pos.left - (arrow ? 14 /* Offset */ : 0) + offset.x, space.right - width)
12973
+ : Math.max(space.left, pos.left - width + (arrow ? 14 /* Offset */ : 0) - offset.x);
12740
12974
  let above = !!tooltip.above;
12741
12975
  if (!tooltip.strictSide && (above
12742
12976
  ? pos.top - (size.bottom - size.top) - offset.y < space.top
@@ -12770,7 +13004,7 @@
12770
13004
  dom.style.left = left + "px";
12771
13005
  }
12772
13006
  if (arrow)
12773
- arrow.style.left = `${pos.left + (ltr ? offset.x : -offset.x) - (left + 14 /* Arrow.Offset */ - 7 /* Arrow.Size */)}px`;
13007
+ arrow.style.left = `${pos.left + (ltr ? offset.x : -offset.x) - (left + 14 /* Offset */ - 7 /* Size */)}px`;
12774
13008
  if (tView.overlap !== true)
12775
13009
  others.push({ left, top, right, bottom: top + height });
12776
13010
  dom.classList.toggle("cm-tooltip-above", above);
@@ -12813,8 +13047,8 @@
12813
13047
  color: "white"
12814
13048
  },
12815
13049
  ".cm-tooltip-arrow": {
12816
- height: `${7 /* Arrow.Size */}px`,
12817
- width: `${7 /* Arrow.Size */ * 2}px`,
13050
+ height: `${7 /* Size */}px`,
13051
+ width: `${7 /* Size */ * 2}px`,
12818
13052
  position: "absolute",
12819
13053
  zIndex: -1,
12820
13054
  overflow: "hidden",
@@ -12823,26 +13057,26 @@
12823
13057
  position: "absolute",
12824
13058
  width: 0,
12825
13059
  height: 0,
12826
- borderLeft: `${7 /* Arrow.Size */}px solid transparent`,
12827
- borderRight: `${7 /* Arrow.Size */}px solid transparent`,
13060
+ borderLeft: `${7 /* Size */}px solid transparent`,
13061
+ borderRight: `${7 /* Size */}px solid transparent`,
12828
13062
  },
12829
13063
  ".cm-tooltip-above &": {
12830
- bottom: `-${7 /* Arrow.Size */}px`,
13064
+ bottom: `-${7 /* Size */}px`,
12831
13065
  "&:before": {
12832
- borderTop: `${7 /* Arrow.Size */}px solid #bbb`,
13066
+ borderTop: `${7 /* Size */}px solid #bbb`,
12833
13067
  },
12834
13068
  "&:after": {
12835
- borderTop: `${7 /* Arrow.Size */}px solid #f5f5f5`,
13069
+ borderTop: `${7 /* Size */}px solid #f5f5f5`,
12836
13070
  bottom: "1px"
12837
13071
  }
12838
13072
  },
12839
13073
  ".cm-tooltip-below &": {
12840
- top: `-${7 /* Arrow.Size */}px`,
13074
+ top: `-${7 /* Size */}px`,
12841
13075
  "&:before": {
12842
- borderBottom: `${7 /* Arrow.Size */}px solid #bbb`,
13076
+ borderBottom: `${7 /* Size */}px solid #bbb`,
12843
13077
  },
12844
13078
  "&:after": {
12845
- borderBottom: `${7 /* Arrow.Size */}px solid #f5f5f5`,
13079
+ borderBottom: `${7 /* Size */}px solid #f5f5f5`,
12846
13080
  top: "1px"
12847
13081
  }
12848
13082
  },
@@ -13086,6 +13320,7 @@
13086
13320
  elementStyle: "",
13087
13321
  markers: () => RangeSet.empty,
13088
13322
  lineMarker: () => null,
13323
+ widgetMarker: () => null,
13089
13324
  lineMarkerChange: null,
13090
13325
  initialSpacer: null,
13091
13326
  updateSpacer: null,
@@ -13166,24 +13401,28 @@
13166
13401
  let classSet = [];
13167
13402
  let contexts = this.gutters.map(gutter => new UpdateContext(gutter, this.view.viewport, -this.view.documentPadding.top));
13168
13403
  for (let line of this.view.viewportLineBlocks) {
13169
- let text;
13404
+ if (classSet.length)
13405
+ classSet = [];
13170
13406
  if (Array.isArray(line.type)) {
13171
- for (let b of line.type)
13172
- if (b.type == BlockType.Text) {
13173
- text = b;
13174
- break;
13407
+ let first = true;
13408
+ for (let b of line.type) {
13409
+ if (b.type == BlockType.Text && first) {
13410
+ advanceCursor(lineClasses, classSet, b.from);
13411
+ for (let cx of contexts)
13412
+ cx.line(this.view, b, classSet);
13413
+ first = false;
13175
13414
  }
13415
+ else if (b.widget) {
13416
+ for (let cx of contexts)
13417
+ cx.widget(this.view, b);
13418
+ }
13419
+ }
13176
13420
  }
13177
- else {
13178
- text = line.type == BlockType.Text ? line : undefined;
13421
+ else if (line.type == BlockType.Text) {
13422
+ advanceCursor(lineClasses, classSet, line.from);
13423
+ for (let cx of contexts)
13424
+ cx.line(this.view, line, classSet);
13179
13425
  }
13180
- if (!text)
13181
- continue;
13182
- if (classSet.length)
13183
- classSet = [];
13184
- advanceCursor(lineClasses, classSet, line.from);
13185
- for (let cx of contexts)
13186
- cx.line(this.view, text, classSet);
13187
13426
  }
13188
13427
  for (let cx of contexts)
13189
13428
  cx.finish();
@@ -13251,6 +13490,19 @@
13251
13490
  this.i = 0;
13252
13491
  this.cursor = RangeSet.iter(gutter.markers, viewport.from);
13253
13492
  }
13493
+ addElement(view, block, markers) {
13494
+ let { gutter } = this, above = block.top - this.height;
13495
+ if (this.i == gutter.elements.length) {
13496
+ let newElt = new GutterElement(view, block.height, above, markers);
13497
+ gutter.elements.push(newElt);
13498
+ gutter.dom.appendChild(newElt.dom);
13499
+ }
13500
+ else {
13501
+ gutter.elements[this.i].update(view, block.height, above, markers);
13502
+ }
13503
+ this.height = block.bottom;
13504
+ this.i++;
13505
+ }
13254
13506
  line(view, line, extraMarkers) {
13255
13507
  let localMarkers = [];
13256
13508
  advanceCursor(this.cursor, localMarkers, line.from);
@@ -13262,17 +13514,12 @@
13262
13514
  let gutter = this.gutter;
13263
13515
  if (localMarkers.length == 0 && !gutter.config.renderEmptyElements)
13264
13516
  return;
13265
- let above = line.top - this.height;
13266
- if (this.i == gutter.elements.length) {
13267
- let newElt = new GutterElement(view, line.height, above, localMarkers);
13268
- gutter.elements.push(newElt);
13269
- gutter.dom.appendChild(newElt.dom);
13270
- }
13271
- else {
13272
- gutter.elements[this.i].update(view, line.height, above, localMarkers);
13273
- }
13274
- this.height = line.bottom;
13275
- this.i++;
13517
+ this.addElement(view, line, localMarkers);
13518
+ }
13519
+ widget(view, block) {
13520
+ let marker = this.gutter.config.widgetMarker(view, block.widget, block);
13521
+ if (marker)
13522
+ this.addElement(view, block, [marker]);
13276
13523
  }
13277
13524
  finish() {
13278
13525
  let gutter = this.gutter;
@@ -13440,6 +13687,7 @@
13440
13687
  return null;
13441
13688
  return new NumberMarker(formatNumber(view, view.state.doc.lineAt(line.from).number));
13442
13689
  },
13690
+ widgetMarker: () => null,
13443
13691
  lineMarkerChange: update => update.startState.facet(lineNumberConfig) != update.state.facet(lineNumberConfig),
13444
13692
  initialSpacer(view) {
13445
13693
  return new NumberMarker(formatNumber(view, maxLineNumber(view.state.doc.lines)));
@@ -13815,15 +14063,16 @@
13815
14063
  /// not have its children iterated over (or `leave` called).
13816
14064
  iterate(spec) {
13817
14065
  let { enter, leave, from = 0, to = this.length } = spec;
13818
- for (let c = this.cursor((spec.mode || 0) | IterMode.IncludeAnonymous);;) {
14066
+ let mode = spec.mode || 0, anon = (mode & IterMode.IncludeAnonymous) > 0;
14067
+ for (let c = this.cursor(mode | IterMode.IncludeAnonymous);;) {
13819
14068
  let entered = false;
13820
- if (c.from <= to && c.to >= from && (c.type.isAnonymous || enter(c) !== false)) {
14069
+ if (c.from <= to && c.to >= from && (!anon && c.type.isAnonymous || enter(c) !== false)) {
13821
14070
  if (c.firstChild())
13822
14071
  continue;
13823
14072
  entered = true;
13824
14073
  }
13825
14074
  for (;;) {
13826
- if (entered && leave && !c.type.isAnonymous)
14075
+ if (entered && leave && (anon || !c.type.isAnonymous))
13827
14076
  leave(c);
13828
14077
  if (c.nextSibling())
13829
14078
  break;
@@ -15184,7 +15433,7 @@
15184
15433
  if (rule.mode == 1 /* Inherit */)
15185
15434
  inheritedClass += (inheritedClass ? " " : "") + tagCls;
15186
15435
  }
15187
- this.startSpan(cursor.from, cls);
15436
+ this.startSpan(Math.max(from, start), cls);
15188
15437
  if (rule.opaque)
15189
15438
  return;
15190
15439
  let mounted = cursor.tree && cursor.tree.prop(NodeProp.mounted);
@@ -15208,14 +15457,16 @@
15208
15457
  break;
15209
15458
  pos = next.to + start;
15210
15459
  if (pos > from) {
15211
- this.highlightRange(inner.cursor(), Math.max(from, next.from + start), Math.min(to, pos), inheritedClass, innerHighlighters);
15212
- this.startSpan(pos, cls);
15460
+ this.highlightRange(inner.cursor(), Math.max(from, next.from + start), Math.min(to, pos), "", innerHighlighters);
15461
+ this.startSpan(Math.min(to, pos), cls);
15213
15462
  }
15214
15463
  }
15215
15464
  if (hasChild)
15216
15465
  cursor.parent();
15217
15466
  }
15218
15467
  else if (cursor.firstChild()) {
15468
+ if (mounted)
15469
+ inheritedClass = "";
15219
15470
  do {
15220
15471
  if (cursor.to <= from)
15221
15472
  continue;
@@ -15728,7 +15979,7 @@
15728
15979
  });
15729
15980
  }
15730
15981
  /**
15731
- Syntax node prop used to register sublangauges. Should be added to
15982
+ Syntax node prop used to register sublanguages. Should be added to
15732
15983
  the top level node type for the language.
15733
15984
  */
15734
15985
  const sublanguageProp = /*@__PURE__*/new NodeProp();
@@ -15892,8 +16143,15 @@
15892
16143
  let field = state.field(Language.state, false);
15893
16144
  return field ? field.tree : Tree.empty;
15894
16145
  }
15895
- // Lezer-style Input object for a Text document.
16146
+ /**
16147
+ Lezer-style
16148
+ [`Input`](https://lezer.codemirror.net/docs/ref#common.Input)
16149
+ object for a [`Text`](https://codemirror.net/6/docs/ref/#state.Text) object.
16150
+ */
15896
16151
  class DocInput {
16152
+ /**
16153
+ Create an input object for the given document.
16154
+ */
15897
16155
  constructor(doc) {
15898
16156
  this.doc = doc;
15899
16157
  this.cursorPos = 0;
@@ -16179,14 +16437,14 @@
16179
16437
  // state updates with parse work beyond the viewport.
16180
16438
  let upto = this.context.treeLen == tr.startState.doc.length ? undefined
16181
16439
  : Math.max(tr.changes.mapPos(this.context.treeLen), newCx.viewport.to);
16182
- if (!newCx.work(20 /* Work.Apply */, upto))
16440
+ if (!newCx.work(20 /* Apply */, upto))
16183
16441
  newCx.takeTree();
16184
16442
  return new LanguageState(newCx);
16185
16443
  }
16186
16444
  static init(state) {
16187
- let vpTo = Math.min(3000 /* Work.InitViewport */, state.doc.length);
16445
+ let vpTo = Math.min(3000 /* InitViewport */, state.doc.length);
16188
16446
  let parseState = ParseContext.create(state.facet(language).parser, state, { from: 0, to: vpTo });
16189
- if (!parseState.work(20 /* Work.Apply */, vpTo))
16447
+ if (!parseState.work(20 /* Apply */, vpTo))
16190
16448
  parseState.takeTree();
16191
16449
  return new LanguageState(parseState);
16192
16450
  }
@@ -16203,14 +16461,14 @@
16203
16461
  }
16204
16462
  });
16205
16463
  let requestIdle = (callback) => {
16206
- let timeout = setTimeout(() => callback(), 500 /* Work.MaxPause */);
16464
+ let timeout = setTimeout(() => callback(), 500 /* MaxPause */);
16207
16465
  return () => clearTimeout(timeout);
16208
16466
  };
16209
16467
  if (typeof requestIdleCallback != "undefined")
16210
16468
  requestIdle = (callback) => {
16211
16469
  let idle = -1, timeout = setTimeout(() => {
16212
- idle = requestIdleCallback(callback, { timeout: 500 /* Work.MaxPause */ - 100 /* Work.MinPause */ });
16213
- }, 100 /* Work.MinPause */);
16470
+ idle = requestIdleCallback(callback, { timeout: 500 /* MaxPause */ - 100 /* MinPause */ });
16471
+ }, 100 /* MinPause */);
16214
16472
  return () => idle < 0 ? clearTimeout(timeout) : cancelIdleCallback(idle);
16215
16473
  };
16216
16474
  const isInputPending = typeof navigator != "undefined" && ((_a = navigator.scheduling) === null || _a === void 0 ? void 0 : _a.isInputPending)
@@ -16233,7 +16491,7 @@
16233
16491
  this.scheduleWork();
16234
16492
  if (update.docChanged) {
16235
16493
  if (this.view.hasFocus)
16236
- this.chunkBudget += 50 /* Work.ChangeBonus */;
16494
+ this.chunkBudget += 50 /* ChangeBonus */;
16237
16495
  this.scheduleWork();
16238
16496
  }
16239
16497
  this.checkAsyncSchedule(cx);
@@ -16249,19 +16507,19 @@
16249
16507
  this.working = null;
16250
16508
  let now = Date.now();
16251
16509
  if (this.chunkEnd < now && (this.chunkEnd < 0 || this.view.hasFocus)) { // Start a new chunk
16252
- this.chunkEnd = now + 30000 /* Work.ChunkTime */;
16253
- this.chunkBudget = 3000 /* Work.ChunkBudget */;
16510
+ this.chunkEnd = now + 30000 /* ChunkTime */;
16511
+ this.chunkBudget = 3000 /* ChunkBudget */;
16254
16512
  }
16255
16513
  if (this.chunkBudget <= 0)
16256
16514
  return; // No more budget
16257
16515
  let { state, viewport: { to: vpTo } } = this.view, field = state.field(Language.state);
16258
- if (field.tree == field.context.tree && field.context.isDone(vpTo + 100000 /* Work.MaxParseAhead */))
16516
+ if (field.tree == field.context.tree && field.context.isDone(vpTo + 100000 /* MaxParseAhead */))
16259
16517
  return;
16260
- let endTime = Date.now() + Math.min(this.chunkBudget, 100 /* Work.Slice */, deadline && !isInputPending ? Math.max(25 /* Work.MinSlice */, deadline.timeRemaining() - 5) : 1e9);
16518
+ let endTime = Date.now() + Math.min(this.chunkBudget, 100 /* Slice */, deadline && !isInputPending ? Math.max(25 /* MinSlice */, deadline.timeRemaining() - 5) : 1e9);
16261
16519
  let viewportFirst = field.context.treeLen < vpTo && state.doc.length > vpTo + 1000;
16262
16520
  let done = field.context.work(() => {
16263
16521
  return isInputPending && isInputPending() || Date.now() > endTime;
16264
- }, vpTo + (viewportFirst ? 0 : 100000 /* Work.MaxParseAhead */));
16522
+ }, vpTo + (viewportFirst ? 0 : 100000 /* MaxParseAhead */));
16265
16523
  this.chunkBudget -= Date.now() - now;
16266
16524
  if (done || this.chunkBudget <= 0) {
16267
16525
  field.context.takeTree();
@@ -16581,13 +16839,20 @@
16581
16839
  on if it is covered by another such node.
16582
16840
  */
16583
16841
  get baseIndent() {
16584
- let line = this.state.doc.lineAt(this.node.from);
16842
+ return this.baseIndentFor(this.node);
16843
+ }
16844
+ /**
16845
+ Get the indentation for the reference line of the given node
16846
+ (see [`baseIndent`](https://codemirror.net/6/docs/ref/#language.TreeIndentContext.baseIndent)).
16847
+ */
16848
+ baseIndentFor(node) {
16849
+ let line = this.state.doc.lineAt(node.from);
16585
16850
  // Skip line starts that are covered by a sibling (or cousin, etc)
16586
16851
  for (;;) {
16587
- let atBreak = this.node.resolve(line.from);
16852
+ let atBreak = node.resolve(line.from);
16588
16853
  while (atBreak.parent && atBreak.parent.from == atBreak.from)
16589
16854
  atBreak = atBreak.parent;
16590
- if (isParent(atBreak, this.node))
16855
+ if (isParent(atBreak, node))
16591
16856
  break;
16592
16857
  line = this.state.doc.lineAt(atBreak.from);
16593
16858
  }
@@ -17521,7 +17786,7 @@
17521
17786
  if (last >= 0 && ranges[last].to > fromLine.from)
17522
17787
  ranges[last].to = toLine.to;
17523
17788
  else
17524
- ranges.push({ from: fromLine.from, to: toLine.to });
17789
+ ranges.push({ from: fromLine.from + /^\s*/.exec(fromLine.text)[0].length, to: toLine.to });
17525
17790
  }
17526
17791
  return ranges;
17527
17792
  }
@@ -18799,7 +19064,7 @@
18799
19064
  - Shift-Alt-ArrowUp: [`copyLineUp`](https://codemirror.net/6/docs/ref/#commands.copyLineUp)
18800
19065
  - Shift-Alt-ArrowDown: [`copyLineDown`](https://codemirror.net/6/docs/ref/#commands.copyLineDown)
18801
19066
  - Escape: [`simplifySelection`](https://codemirror.net/6/docs/ref/#commands.simplifySelection)
18802
- - Ctrl-Enter (Comd-Enter on macOS): [`insertBlankLine`](https://codemirror.net/6/docs/ref/#commands.insertBlankLine)
19067
+ - Ctrl-Enter (Cmd-Enter on macOS): [`insertBlankLine`](https://codemirror.net/6/docs/ref/#commands.insertBlankLine)
18803
19068
  - Alt-l (Ctrl-l on macOS): [`selectLine`](https://codemirror.net/6/docs/ref/#commands.selectLine)
18804
19069
  - Ctrl-i (Cmd-i on macOS): [`selectParentSyntax`](https://codemirror.net/6/docs/ref/#commands.selectParentSyntax)
18805
19070
  - Ctrl-[ (Cmd-[ on macOS): [`indentLess`](https://codemirror.net/6/docs/ref/#commands.indentLess)
@@ -19104,7 +19369,7 @@
19104
19369
  this.matchPos = toCharEnd(text, from);
19105
19370
  this.re = new RegExp(query, baseFlags + ((options === null || options === void 0 ? void 0 : options.ignoreCase) ? "i" : ""));
19106
19371
  this.test = options === null || options === void 0 ? void 0 : options.test;
19107
- this.flat = FlattenedDoc.get(text, from, this.chunkEnd(from + 5000 /* Chunk.Base */));
19372
+ this.flat = FlattenedDoc.get(text, from, this.chunkEnd(from + 5000 /* Base */));
19108
19373
  }
19109
19374
  chunkEnd(pos) {
19110
19375
  return pos >= this.to ? this.to : this.text.lineAt(pos).to;
@@ -19411,6 +19676,7 @@
19411
19676
  top: false,
19412
19677
  caseSensitive: false,
19413
19678
  literal: false,
19679
+ regexp: false,
19414
19680
  wholeWord: false,
19415
19681
  createPanel: view => new SearchPanel(view),
19416
19682
  scrollToMatch: range => EditorView.scrollIntoView(range)
@@ -19496,11 +19762,11 @@
19496
19762
  cursor = stringCursor(this.spec, state, 0, curFrom).nextOverlapping();
19497
19763
  return cursor.done ? null : cursor.value;
19498
19764
  }
19499
- // Searching in reverse is, rather than implementing inverted search
19765
+ // Searching in reverse is, rather than implementing an inverted search
19500
19766
  // cursor, done by scanning chunk after chunk forward.
19501
19767
  prevMatchInRange(state, from, to) {
19502
19768
  for (let pos = to;;) {
19503
- let start = Math.max(from, pos - 10000 /* FindPrev.ChunkSize */ - this.spec.unquoted.length);
19769
+ let start = Math.max(from, pos - 10000 /* ChunkSize */ - this.spec.unquoted.length);
19504
19770
  let cursor = stringCursor(this.spec, state, start, pos), range = null;
19505
19771
  while (!cursor.nextOverlapping().done)
19506
19772
  range = cursor.value;
@@ -19508,7 +19774,7 @@
19508
19774
  return range;
19509
19775
  if (start == from)
19510
19776
  return null;
19511
- pos -= 10000 /* FindPrev.ChunkSize */;
19777
+ pos -= 10000 /* ChunkSize */;
19512
19778
  }
19513
19779
  }
19514
19780
  prevMatch(state, curFrom, curTo) {
@@ -19559,7 +19825,7 @@
19559
19825
  }
19560
19826
  prevMatchInRange(state, from, to) {
19561
19827
  for (let size = 1;; size++) {
19562
- let start = Math.max(from, to - size * 10000 /* FindPrev.ChunkSize */);
19828
+ let start = Math.max(from, to - size * 10000 /* ChunkSize */);
19563
19829
  let cursor = regexpCursor(this.spec, state, start, to), range = null;
19564
19830
  while (!cursor.next().done)
19565
19831
  range = cursor.value;
@@ -19589,7 +19855,7 @@
19589
19855
  return ranges;
19590
19856
  }
19591
19857
  highlight(state, from, to, add) {
19592
- let cursor = regexpCursor(this.spec, state, Math.max(0, from - 250 /* RegExp.HighlightMargin */), Math.min(to + 250 /* RegExp.HighlightMargin */, state.doc.length));
19858
+ let cursor = regexpCursor(this.spec, state, Math.max(0, from - 250 /* HighlightMargin */), Math.min(to + 250 /* HighlightMargin */, state.doc.length));
19593
19859
  while (!cursor.next().done)
19594
19860
  add(cursor.value.from, cursor.value.to);
19595
19861
  }
@@ -19642,7 +19908,7 @@
19642
19908
  let builder = new RangeSetBuilder();
19643
19909
  for (let i = 0, ranges = view.visibleRanges, l = ranges.length; i < l; i++) {
19644
19910
  let { from, to } = ranges[i];
19645
- while (i < l - 1 && to > ranges[i + 1].from - 2 * 250 /* RegExp.HighlightMargin */)
19911
+ while (i < l - 1 && to > ranges[i + 1].from - 2 * 250 /* HighlightMargin */)
19646
19912
  to = ranges[++i].to;
19647
19913
  query.highlight(view.state, from, to, (from, to) => {
19648
19914
  let selected = view.state.selection.ranges.some(r => r.from == from && r.to == to);
@@ -19675,9 +19941,10 @@
19675
19941
  let config = view.state.facet(searchConfigFacet);
19676
19942
  view.dispatch({
19677
19943
  selection,
19678
- effects: [announceMatch(view, next), config.scrollToMatch(selection.main)],
19944
+ effects: [announceMatch(view, next), config.scrollToMatch(selection.main, view)],
19679
19945
  userEvent: "select.search"
19680
19946
  });
19947
+ selectSearchInput(view);
19681
19948
  return true;
19682
19949
  });
19683
19950
  /**
@@ -19694,9 +19961,10 @@
19694
19961
  let config = view.state.facet(searchConfigFacet);
19695
19962
  view.dispatch({
19696
19963
  selection,
19697
- effects: [announceMatch(view, prev), config.scrollToMatch(selection.main)],
19964
+ effects: [announceMatch(view, prev), config.scrollToMatch(selection.main, view)],
19698
19965
  userEvent: "select.search"
19699
19966
  });
19967
+ selectSearchInput(view);
19700
19968
  return true;
19701
19969
  });
19702
19970
  /**
@@ -19756,7 +20024,7 @@
19756
20024
  let off = changes.length == 0 || changes[0].from >= next.to ? 0 : next.to - next.from - replacement.length;
19757
20025
  selection = EditorSelection.single(next.from - off, next.to - off);
19758
20026
  effects.push(announceMatch(view, next));
19759
- effects.push(state.facet(searchConfigFacet).scrollToMatch(selection.main));
20027
+ effects.push(state.facet(searchConfigFacet).scrollToMatch(selection.main, view));
19760
20028
  }
19761
20029
  view.dispatch({
19762
20030
  changes, selection, effects,
@@ -19789,7 +20057,7 @@
19789
20057
  return view.state.facet(searchConfigFacet).createPanel(view);
19790
20058
  }
19791
20059
  function defaultQuery(state, fallback) {
19792
- var _a, _b, _c, _d;
20060
+ var _a, _b, _c, _d, _e;
19793
20061
  let sel = state.selection.main;
19794
20062
  let selText = sel.empty || sel.to > sel.from + 100 ? "" : state.sliceDoc(sel.from, sel.to);
19795
20063
  if (fallback && !selText)
@@ -19799,19 +20067,26 @@
19799
20067
  search: ((_a = fallback === null || fallback === void 0 ? void 0 : fallback.literal) !== null && _a !== void 0 ? _a : config.literal) ? selText : selText.replace(/\n/g, "\\n"),
19800
20068
  caseSensitive: (_b = fallback === null || fallback === void 0 ? void 0 : fallback.caseSensitive) !== null && _b !== void 0 ? _b : config.caseSensitive,
19801
20069
  literal: (_c = fallback === null || fallback === void 0 ? void 0 : fallback.literal) !== null && _c !== void 0 ? _c : config.literal,
19802
- wholeWord: (_d = fallback === null || fallback === void 0 ? void 0 : fallback.wholeWord) !== null && _d !== void 0 ? _d : config.wholeWord
20070
+ regexp: (_d = fallback === null || fallback === void 0 ? void 0 : fallback.regexp) !== null && _d !== void 0 ? _d : config.regexp,
20071
+ wholeWord: (_e = fallback === null || fallback === void 0 ? void 0 : fallback.wholeWord) !== null && _e !== void 0 ? _e : config.wholeWord
19803
20072
  });
19804
20073
  }
20074
+ function getSearchInput(view) {
20075
+ let panel = getPanel(view, createSearchPanel);
20076
+ return panel && panel.dom.querySelector("[main-field]");
20077
+ }
20078
+ function selectSearchInput(view) {
20079
+ let input = getSearchInput(view);
20080
+ if (input && input == view.root.activeElement)
20081
+ input.select();
20082
+ }
19805
20083
  /**
19806
20084
  Make sure the search panel is open and focused.
19807
20085
  */
19808
20086
  const openSearchPanel = view => {
19809
20087
  let state = view.state.field(searchState, false);
19810
20088
  if (state && state.panel) {
19811
- let panel = getPanel(view, createSearchPanel);
19812
- if (!panel)
19813
- return false;
19814
- let searchInput = panel.dom.querySelector("[main-field]");
20089
+ let searchInput = getSearchInput(view);
19815
20090
  if (searchInput && searchInput != view.root.activeElement) {
19816
20091
  let query = defaultQuery(view.state, state.query.spec);
19817
20092
  if (query.valid)
@@ -20153,13 +20428,14 @@
20153
20428
  };
20154
20429
  }
20155
20430
  class Option {
20156
- constructor(completion, source, match) {
20431
+ constructor(completion, source, match, score) {
20157
20432
  this.completion = completion;
20158
20433
  this.source = source;
20159
20434
  this.match = match;
20435
+ this.score = score;
20160
20436
  }
20161
20437
  }
20162
- function cur(state) { return state.selection.main.head; }
20438
+ function cur(state) { return state.selection.main.from; }
20163
20439
  // Make sure the given regexp has a $ at its end and, if `start` is
20164
20440
  // true, a ^ at its start.
20165
20441
  function ensureAnchor(expr, start) {
@@ -20181,30 +20457,17 @@
20181
20457
  selection range that has the same text in front of it.
20182
20458
  */
20183
20459
  function insertCompletionText(state, text, from, to) {
20460
+ let { main } = state.selection, fromOff = from - main.from, toOff = to - main.from;
20184
20461
  return Object.assign(Object.assign({}, state.changeByRange(range => {
20185
- if (range == state.selection.main)
20186
- return {
20187
- changes: { from: from, to: to, insert: text },
20188
- range: EditorSelection.cursor(from + text.length)
20189
- };
20190
- let len = to - from;
20191
- if (!range.empty ||
20192
- len && state.sliceDoc(range.from - len, range.from) != state.sliceDoc(from, to))
20462
+ if (range != main && from != to &&
20463
+ state.sliceDoc(range.from + fromOff, range.from + toOff) != state.sliceDoc(from, to))
20193
20464
  return { range };
20194
20465
  return {
20195
- changes: { from: range.from - len, to: range.from, insert: text },
20196
- range: EditorSelection.cursor(range.from - len + text.length)
20466
+ changes: { from: range.from + fromOff, to: to == main.from ? range.to : range.from + toOff, insert: text },
20467
+ range: EditorSelection.cursor(range.from + fromOff + text.length)
20197
20468
  };
20198
20469
  })), { userEvent: "input.complete" });
20199
20470
  }
20200
- function applyCompletion(view, option) {
20201
- const apply = option.completion.apply || option.completion.label;
20202
- let result = option.source;
20203
- if (typeof apply == "string")
20204
- view.dispatch(Object.assign(Object.assign({}, insertCompletionText(view.state, apply, result.from, result.to)), { annotations: pickedCompletion.of(option.completion) }));
20205
- else
20206
- apply(view, option.completion, result.from, result.to);
20207
- }
20208
20471
  const SourceCache = /*@__PURE__*/new WeakMap();
20209
20472
  function asSource(source) {
20210
20473
  if (!Array.isArray(source))
@@ -20214,6 +20477,8 @@
20214
20477
  SourceCache.set(source, known = completeFromList(source));
20215
20478
  return known;
20216
20479
  }
20480
+ const startCompletionEffect = /*@__PURE__*/StateEffect.define();
20481
+ const closeCompletionEffect = /*@__PURE__*/StateEffect.define();
20217
20482
 
20218
20483
  // A pattern matcher for fuzzy completion matching. Create an instance
20219
20484
  // once for a pattern, and then use that to match any number of
@@ -20246,7 +20511,7 @@
20246
20511
  // is. See `Penalty` above.
20247
20512
  match(word) {
20248
20513
  if (this.pattern.length == 0)
20249
- return [0];
20514
+ return [-100 /* NotFull */];
20250
20515
  if (word.length < this.pattern.length)
20251
20516
  return null;
20252
20517
  let { chars, folded, any, precise, byWord } = this;
@@ -20254,17 +20519,17 @@
20254
20519
  // at the start
20255
20520
  if (chars.length == 1) {
20256
20521
  let first = codePointAt(word, 0), firstSize = codePointSize(first);
20257
- let score = firstSize == word.length ? 0 : -100 /* Penalty.NotFull */;
20522
+ let score = firstSize == word.length ? 0 : -100 /* NotFull */;
20258
20523
  if (first == chars[0]) ;
20259
20524
  else if (first == folded[0])
20260
- score += -200 /* Penalty.CaseFold */;
20525
+ score += -200 /* CaseFold */;
20261
20526
  else
20262
20527
  return null;
20263
20528
  return [score, 0, firstSize];
20264
20529
  }
20265
20530
  let direct = word.indexOf(this.pattern);
20266
20531
  if (direct == 0)
20267
- return [word.length == this.pattern.length ? 0 : -100 /* Penalty.NotFull */, 0, this.pattern.length];
20532
+ return [word.length == this.pattern.length ? 0 : -100 /* NotFull */, 0, this.pattern.length];
20268
20533
  let len = chars.length, anyTo = 0;
20269
20534
  if (direct < 0) {
20270
20535
  for (let i = 0, e = Math.min(word.length, 200); i < e && anyTo < len;) {
@@ -20288,7 +20553,7 @@
20288
20553
  let adjacentTo = 0, adjacentStart = -1, adjacentEnd = -1;
20289
20554
  let hasLower = /[a-z]/.test(word), wordAdjacent = true;
20290
20555
  // Go over the option's text, scanning for the various kinds of matches
20291
- for (let i = 0, e = Math.min(word.length, 200), prevType = 0 /* Tp.NonWord */; i < e && byWordTo < len;) {
20556
+ for (let i = 0, e = Math.min(word.length, 200), prevType = 0 /* NonWord */; i < e && byWordTo < len;) {
20292
20557
  let next = codePointAt(word, i);
20293
20558
  if (direct < 0) {
20294
20559
  if (preciseTo < len && next == chars[preciseTo])
@@ -20306,9 +20571,9 @@
20306
20571
  }
20307
20572
  }
20308
20573
  let ch, type = next < 0xff
20309
- ? (next >= 48 && next <= 57 || next >= 97 && next <= 122 ? 2 /* Tp.Lower */ : next >= 65 && next <= 90 ? 1 /* Tp.Upper */ : 0 /* Tp.NonWord */)
20310
- : ((ch = fromCodePoint(next)) != ch.toLowerCase() ? 1 /* Tp.Upper */ : ch != ch.toUpperCase() ? 2 /* Tp.Lower */ : 0 /* Tp.NonWord */);
20311
- if (!i || type == 1 /* Tp.Upper */ && hasLower || prevType == 0 /* Tp.NonWord */ && type != 0 /* Tp.NonWord */) {
20574
+ ? (next >= 48 && next <= 57 || next >= 97 && next <= 122 ? 2 /* Lower */ : next >= 65 && next <= 90 ? 1 /* Upper */ : 0 /* NonWord */)
20575
+ : ((ch = fromCodePoint(next)) != ch.toLowerCase() ? 1 /* Upper */ : ch != ch.toUpperCase() ? 2 /* Lower */ : 0 /* NonWord */);
20576
+ if (!i || type == 1 /* Upper */ && hasLower || prevType == 0 /* NonWord */ && type != 0 /* NonWord */) {
20312
20577
  if (chars[byWordTo] == next || (folded[byWordTo] == next && (byWordFolded = true)))
20313
20578
  byWord[byWordTo++] = i;
20314
20579
  else if (byWord.length)
@@ -20318,17 +20583,17 @@
20318
20583
  i += codePointSize(next);
20319
20584
  }
20320
20585
  if (byWordTo == len && byWord[0] == 0 && wordAdjacent)
20321
- return this.result(-100 /* Penalty.ByWord */ + (byWordFolded ? -200 /* Penalty.CaseFold */ : 0), byWord, word);
20586
+ return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0), byWord, word);
20322
20587
  if (adjacentTo == len && adjacentStart == 0)
20323
- return [-200 /* Penalty.CaseFold */ - word.length + (adjacentEnd == word.length ? 0 : -100 /* Penalty.NotFull */), 0, adjacentEnd];
20588
+ return [-200 /* CaseFold */ - word.length + (adjacentEnd == word.length ? 0 : -100 /* NotFull */), 0, adjacentEnd];
20324
20589
  if (direct > -1)
20325
- return [-700 /* Penalty.NotStart */ - word.length, direct, direct + this.pattern.length];
20590
+ return [-700 /* NotStart */ - word.length, direct, direct + this.pattern.length];
20326
20591
  if (adjacentTo == len)
20327
- return [-200 /* Penalty.CaseFold */ + -700 /* Penalty.NotStart */ - word.length, adjacentStart, adjacentEnd];
20592
+ return [-200 /* CaseFold */ + -700 /* NotStart */ - word.length, adjacentStart, adjacentEnd];
20328
20593
  if (byWordTo == len)
20329
- return this.result(-100 /* Penalty.ByWord */ + (byWordFolded ? -200 /* Penalty.CaseFold */ : 0) + -700 /* Penalty.NotStart */ +
20330
- (wordAdjacent ? 0 : -1100 /* Penalty.Gap */), byWord, word);
20331
- return chars.length == 2 ? null : this.result((any[0] ? -700 /* Penalty.NotStart */ : 0) + -200 /* Penalty.CaseFold */ + -1100 /* Penalty.Gap */, any, word);
20594
+ return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0) + -700 /* NotStart */ +
20595
+ (wordAdjacent ? 0 : -1100 /* Gap */), byWord, word);
20596
+ return chars.length == 2 ? null : this.result((any[0] ? -700 /* NotStart */ : 0) + -200 /* CaseFold */ + -1100 /* Gap */, any, word);
20332
20597
  }
20333
20598
  result(score, positions, word) {
20334
20599
  let result = [score - word.length], i = 1;
@@ -20359,6 +20624,7 @@
20359
20624
  aboveCursor: false,
20360
20625
  icons: true,
20361
20626
  addToOptions: [],
20627
+ positionInfo: defaultPositionInfo,
20362
20628
  compareCompletions: (a, b) => a.label.localeCompare(b.label),
20363
20629
  interactionDelay: 75
20364
20630
  }, {
@@ -20374,6 +20640,36 @@
20374
20640
  function joinClass(a, b) {
20375
20641
  return a ? b ? a + " " + b : a : b;
20376
20642
  }
20643
+ function defaultPositionInfo(view, list, option, info, space) {
20644
+ let rtl = view.textDirection == Direction.RTL, left = rtl, narrow = false;
20645
+ let side = "top", offset, maxWidth;
20646
+ let spaceLeft = list.left - space.left, spaceRight = space.right - list.right;
20647
+ let infoWidth = info.right - info.left, infoHeight = info.bottom - info.top;
20648
+ if (left && spaceLeft < Math.min(infoWidth, spaceRight))
20649
+ left = false;
20650
+ else if (!left && spaceRight < Math.min(infoWidth, spaceLeft))
20651
+ left = true;
20652
+ if (infoWidth <= (left ? spaceLeft : spaceRight)) {
20653
+ offset = Math.max(space.top, Math.min(option.top, space.bottom - infoHeight)) - list.top;
20654
+ maxWidth = Math.min(400 /* Width */, left ? spaceLeft : spaceRight);
20655
+ }
20656
+ else {
20657
+ narrow = true;
20658
+ maxWidth = Math.min(400 /* Width */, (rtl ? list.right : space.right - list.left) - 30 /* Margin */);
20659
+ let spaceBelow = space.bottom - list.bottom;
20660
+ if (spaceBelow >= infoHeight || spaceBelow > list.top) { // Below the completion
20661
+ offset = option.bottom - list.top;
20662
+ }
20663
+ else { // Above it
20664
+ side = "bottom";
20665
+ offset = list.bottom - option.top;
20666
+ }
20667
+ }
20668
+ return {
20669
+ style: `${side}: ${offset}px; max-width: ${maxWidth}px`,
20670
+ class: "cm-completionInfo-" + (narrow ? (rtl ? "left-narrow" : "right-narrow") : left ? "left" : "right")
20671
+ };
20672
+ }
20377
20673
 
20378
20674
  function optionContent(config) {
20379
20675
  let content = config.addToOptions.slice();
@@ -20434,13 +20730,15 @@
20434
20730
  return { from: total - (off + 1) * max, to: total - off * max };
20435
20731
  }
20436
20732
  class CompletionTooltip {
20437
- constructor(view, stateField) {
20733
+ constructor(view, stateField, applyCompletion) {
20438
20734
  this.view = view;
20439
20735
  this.stateField = stateField;
20736
+ this.applyCompletion = applyCompletion;
20440
20737
  this.info = null;
20441
- this.placeInfo = {
20738
+ this.infoDestroy = null;
20739
+ this.placeInfoReq = {
20442
20740
  read: () => this.measureInfo(),
20443
- write: (pos) => this.positionInfo(pos),
20741
+ write: (pos) => this.placeInfo(pos),
20444
20742
  key: this
20445
20743
  };
20446
20744
  this.space = null;
@@ -20458,16 +20756,22 @@
20458
20756
  this.dom.addEventListener("mousedown", (e) => {
20459
20757
  for (let dom = e.target, match; dom && dom != this.dom; dom = dom.parentNode) {
20460
20758
  if (dom.nodeName == "LI" && (match = /-(\d+)$/.exec(dom.id)) && +match[1] < options.length) {
20461
- applyCompletion(view, options[+match[1]]);
20759
+ this.applyCompletion(view, options[+match[1]]);
20462
20760
  e.preventDefault();
20463
20761
  return;
20464
20762
  }
20465
20763
  }
20466
20764
  });
20765
+ this.dom.addEventListener("focusout", (e) => {
20766
+ let state = view.state.field(this.stateField, false);
20767
+ if (state && state.tooltip && view.state.facet(completionConfig).closeOnBlur &&
20768
+ e.relatedTarget != view.contentDOM)
20769
+ view.dispatch({ effects: closeCompletionEffect.of(null) });
20770
+ });
20467
20771
  this.list = this.dom.appendChild(this.createListBox(options, cState.id, this.range));
20468
20772
  this.list.addEventListener("scroll", () => {
20469
20773
  if (this.info)
20470
- this.view.requestMeasure(this.placeInfo);
20774
+ this.view.requestMeasure(this.placeInfoReq);
20471
20775
  });
20472
20776
  }
20473
20777
  mount() { this.updateSel(); }
@@ -20497,7 +20801,7 @@
20497
20801
  positioned(space) {
20498
20802
  this.space = space;
20499
20803
  if (this.info)
20500
- this.view.requestMeasure(this.placeInfo);
20804
+ this.view.requestMeasure(this.placeInfoReq);
20501
20805
  }
20502
20806
  updateSel() {
20503
20807
  let cState = this.view.state.field(this.stateField), open = cState.open;
@@ -20507,43 +20811,52 @@
20507
20811
  this.list = this.dom.appendChild(this.createListBox(open.options, cState.id, this.range));
20508
20812
  this.list.addEventListener("scroll", () => {
20509
20813
  if (this.info)
20510
- this.view.requestMeasure(this.placeInfo);
20814
+ this.view.requestMeasure(this.placeInfoReq);
20511
20815
  });
20512
20816
  }
20513
20817
  if (this.updateSelectedOption(open.selected)) {
20514
- if (this.info) {
20515
- this.info.remove();
20516
- this.info = null;
20517
- }
20818
+ this.destroyInfo();
20518
20819
  let { completion } = open.options[open.selected];
20519
20820
  let { info } = completion;
20520
20821
  if (!info)
20521
20822
  return;
20522
- let infoResult = typeof info === 'string' ? document.createTextNode(info) : info(completion);
20823
+ let infoResult = typeof info === "string" ? document.createTextNode(info) : info(completion);
20523
20824
  if (!infoResult)
20524
20825
  return;
20525
- if ('then' in infoResult) {
20526
- infoResult.then(node => {
20527
- if (node && this.view.state.field(this.stateField, false) == cState)
20528
- this.addInfoPane(node);
20826
+ if ("then" in infoResult) {
20827
+ infoResult.then(obj => {
20828
+ if (obj && this.view.state.field(this.stateField, false) == cState)
20829
+ this.addInfoPane(obj, completion);
20529
20830
  }).catch(e => logException(this.view.state, e, "completion info"));
20530
20831
  }
20531
20832
  else {
20532
- this.addInfoPane(infoResult);
20833
+ this.addInfoPane(infoResult, completion);
20533
20834
  }
20534
20835
  }
20535
20836
  }
20536
- addInfoPane(content) {
20537
- let dom = this.info = document.createElement("div");
20538
- dom.className = "cm-tooltip cm-completionInfo";
20539
- dom.appendChild(content);
20540
- this.dom.appendChild(dom);
20541
- this.view.requestMeasure(this.placeInfo);
20837
+ addInfoPane(content, completion) {
20838
+ this.destroyInfo();
20839
+ let wrap = this.info = document.createElement("div");
20840
+ wrap.className = "cm-tooltip cm-completionInfo";
20841
+ if (content.nodeType != null) {
20842
+ wrap.appendChild(content);
20843
+ this.infoDestroy = null;
20844
+ }
20845
+ else {
20846
+ let { dom, destroy } = content;
20847
+ wrap.appendChild(dom);
20848
+ this.infoDestroy = destroy || null;
20849
+ }
20850
+ this.dom.appendChild(wrap);
20851
+ this.view.requestMeasure(this.placeInfoReq);
20542
20852
  }
20543
20853
  updateSelectedOption(selected) {
20544
20854
  let set = null;
20545
20855
  for (let opt = this.list.firstChild, i = this.range.from; opt; opt = opt.nextSibling, i++) {
20546
- if (i == selected) {
20856
+ if (opt.nodeName != "LI" || !opt.id) {
20857
+ i--; // A section header
20858
+ }
20859
+ else if (i == selected) {
20547
20860
  if (!opt.hasAttribute("aria-selected")) {
20548
20861
  opt.setAttribute("aria-selected", "true");
20549
20862
  set = opt;
@@ -20573,41 +20886,17 @@
20573
20886
  if (selRect.top > Math.min(space.bottom, listRect.bottom) - 10 ||
20574
20887
  selRect.bottom < Math.max(space.top, listRect.top) + 10)
20575
20888
  return null;
20576
- let rtl = this.view.textDirection == Direction.RTL, left = rtl, narrow = false, maxWidth;
20577
- let top = "", bottom = "";
20578
- let spaceLeft = listRect.left - space.left, spaceRight = space.right - listRect.right;
20579
- if (left && spaceLeft < Math.min(infoRect.width, spaceRight))
20580
- left = false;
20581
- else if (!left && spaceRight < Math.min(infoRect.width, spaceLeft))
20582
- left = true;
20583
- if (infoRect.width <= (left ? spaceLeft : spaceRight)) {
20584
- top = (Math.max(space.top, Math.min(selRect.top, space.bottom - infoRect.height)) - listRect.top) + "px";
20585
- maxWidth = Math.min(400 /* Info.Width */, left ? spaceLeft : spaceRight) + "px";
20586
- }
20587
- else {
20588
- narrow = true;
20589
- maxWidth = Math.min(400 /* Info.Width */, (rtl ? listRect.right : space.right - listRect.left) - 30 /* Info.Margin */) + "px";
20590
- let spaceBelow = space.bottom - listRect.bottom;
20591
- if (spaceBelow >= infoRect.height || spaceBelow > listRect.top) // Below the completion
20592
- top = (selRect.bottom - listRect.top) + "px";
20593
- else // Above it
20594
- bottom = (listRect.bottom - selRect.top) + "px";
20595
- }
20596
- return {
20597
- top, bottom, maxWidth,
20598
- class: narrow ? (rtl ? "left-narrow" : "right-narrow") : left ? "left" : "right",
20599
- };
20889
+ return this.view.state.facet(completionConfig).positionInfo(this.view, listRect, selRect, infoRect, space);
20600
20890
  }
20601
- positionInfo(pos) {
20891
+ placeInfo(pos) {
20602
20892
  if (this.info) {
20603
20893
  if (pos) {
20604
- this.info.style.top = pos.top;
20605
- this.info.style.bottom = pos.bottom;
20606
- this.info.style.maxWidth = pos.maxWidth;
20607
- this.info.className = "cm-tooltip cm-completionInfo cm-completionInfo-" + pos.class;
20894
+ if (pos.style)
20895
+ this.info.style.cssText = pos.style;
20896
+ this.info.className = "cm-tooltip cm-completionInfo " + (pos.class || "");
20608
20897
  }
20609
20898
  else {
20610
- this.info.style.top = "-1e6px";
20899
+ this.info.style.cssText = "top: -1e6px";
20611
20900
  }
20612
20901
  }
20613
20902
  }
@@ -20617,8 +20906,22 @@
20617
20906
  ul.setAttribute("role", "listbox");
20618
20907
  ul.setAttribute("aria-expanded", "true");
20619
20908
  ul.setAttribute("aria-label", this.view.state.phrase("Completions"));
20909
+ let curSection = null;
20620
20910
  for (let i = range.from; i < range.to; i++) {
20621
- let { completion, match } = options[i];
20911
+ let { completion, match } = options[i], { section } = completion;
20912
+ if (section) {
20913
+ let name = typeof section == "string" ? section : section.name;
20914
+ if (name != curSection && (i > range.from || range.from == 0)) {
20915
+ curSection = name;
20916
+ if (typeof section != "string" && section.header) {
20917
+ ul.appendChild(section.header(section));
20918
+ }
20919
+ else {
20920
+ let header = ul.appendChild(document.createElement("completion-section"));
20921
+ header.textContent = name;
20922
+ }
20923
+ }
20924
+ }
20622
20925
  const li = ul.appendChild(document.createElement("li"));
20623
20926
  li.id = id + "-" + i;
20624
20927
  li.setAttribute("role", "option");
@@ -20637,11 +20940,22 @@
20637
20940
  ul.classList.add("cm-completionListIncompleteBottom");
20638
20941
  return ul;
20639
20942
  }
20943
+ destroyInfo() {
20944
+ if (this.info) {
20945
+ if (this.infoDestroy)
20946
+ this.infoDestroy();
20947
+ this.info.remove();
20948
+ this.info = null;
20949
+ }
20950
+ }
20951
+ destroy() {
20952
+ this.destroyInfo();
20953
+ }
20640
20954
  }
20641
20955
  // We allocate a new function instance every time the completion
20642
20956
  // changes to force redrawing/repositioning of the tooltip
20643
- function completionTooltip(stateField) {
20644
- return (view) => new CompletionTooltip(view, stateField);
20957
+ function completionTooltip(stateField, applyCompletion) {
20958
+ return (view) => new CompletionTooltip(view, stateField, applyCompletion);
20645
20959
  }
20646
20960
  function scrollIntoView(container, element) {
20647
20961
  let parent = container.getBoundingClientRect();
@@ -20659,35 +20973,59 @@
20659
20973
  (option.type ? 1 : 0);
20660
20974
  }
20661
20975
  function sortOptions(active, state) {
20662
- let options = [], i = 0;
20976
+ let options = [];
20977
+ let sections = null;
20978
+ let addOption = (option) => {
20979
+ options.push(option);
20980
+ let { section } = option.completion;
20981
+ if (section) {
20982
+ if (!sections)
20983
+ sections = [];
20984
+ let name = typeof section == "string" ? section : section.name;
20985
+ if (!sections.some(s => s.name == name))
20986
+ sections.push(typeof section == "string" ? { name } : section);
20987
+ }
20988
+ };
20663
20989
  for (let a of active)
20664
20990
  if (a.hasResult()) {
20665
20991
  if (a.result.filter === false) {
20666
20992
  let getMatch = a.result.getMatch;
20667
20993
  for (let option of a.result.options) {
20668
- let match = [1e9 - i++];
20994
+ let match = [1e9 - options.length];
20669
20995
  if (getMatch)
20670
20996
  for (let n of getMatch(option))
20671
20997
  match.push(n);
20672
- options.push(new Option(option, a, match));
20998
+ addOption(new Option(option, a.source, match, match[0]));
20673
20999
  }
20674
21000
  }
20675
21001
  else {
20676
21002
  let matcher = new FuzzyMatcher(state.sliceDoc(a.from, a.to)), match;
20677
21003
  for (let option of a.result.options)
20678
21004
  if (match = matcher.match(option.label)) {
20679
- if (option.boost != null)
20680
- match[0] += option.boost;
20681
- options.push(new Option(option, a, match));
21005
+ addOption(new Option(option, a.source, match, match[0] + (option.boost || 0)));
20682
21006
  }
20683
21007
  }
20684
21008
  }
21009
+ if (sections) {
21010
+ let sectionOrder = Object.create(null), pos = 0;
21011
+ let cmp = (a, b) => { var _a, _b; return ((_a = a.rank) !== null && _a !== void 0 ? _a : 1e9) - ((_b = b.rank) !== null && _b !== void 0 ? _b : 1e9) || (a.name < b.name ? -1 : 1); };
21012
+ for (let s of sections.sort(cmp)) {
21013
+ pos -= 1e5;
21014
+ sectionOrder[s.name] = pos;
21015
+ }
21016
+ for (let option of options) {
21017
+ let { section } = option.completion;
21018
+ if (section)
21019
+ option.score += sectionOrder[typeof section == "string" ? section : section.name];
21020
+ }
21021
+ }
20685
21022
  let result = [], prev = null;
20686
21023
  let compare = state.facet(completionConfig).compareCompletions;
20687
- for (let opt of options.sort((a, b) => (b.match[0] - a.match[0]) || compare(a.completion, b.completion))) {
20688
- if (!prev || prev.label != opt.completion.label || prev.detail != opt.completion.detail ||
20689
- (prev.type != null && opt.completion.type != null && prev.type != opt.completion.type) ||
20690
- prev.apply != opt.completion.apply)
21024
+ for (let opt of options.sort((a, b) => (b.score - a.score) || compare(a.completion, b.completion))) {
21025
+ let cur = opt.completion;
21026
+ if (!prev || prev.label != cur.label || prev.detail != cur.detail ||
21027
+ (prev.type != null && cur.type != null && prev.type != cur.type) ||
21028
+ prev.apply != cur.apply || prev.boost != cur.boost)
20691
21029
  result.push(opt);
20692
21030
  else if (score(opt.completion) > score(prev))
20693
21031
  result[result.length - 1] = opt;
@@ -20711,7 +21049,7 @@
20711
21049
  static build(active, state, id, prev, conf) {
20712
21050
  let options = sortOptions(active, state);
20713
21051
  if (!options.length) {
20714
- return prev && active.some(a => a.state == 1 /* State.Pending */) ?
21052
+ return prev && active.some(a => a.state == 1 /* Pending */) ?
20715
21053
  new CompletionDialog(prev.options, prev.attrs, prev.tooltip, prev.timestamp, prev.selected, true) : null;
20716
21054
  }
20717
21055
  let selected = state.facet(completionConfig).selectOnOpen ? 0 : -1;
@@ -20725,7 +21063,7 @@
20725
21063
  }
20726
21064
  return new CompletionDialog(options, makeAttrs(id, selected), {
20727
21065
  pos: active.reduce((a, b) => b.hasResult() ? Math.min(a, b.from) : a, 1e8),
20728
- create: completionTooltip(completionState),
21066
+ create: completionTooltip(completionState, applyCompletion),
20729
21067
  above: conf.aboveCursor,
20730
21068
  }, prev ? prev.timestamp : Date.now(), selected, false);
20731
21069
  }
@@ -20748,7 +21086,7 @@
20748
21086
  state.languageDataAt("autocomplete", cur(state)).map(asSource);
20749
21087
  let active = sources.map(source => {
20750
21088
  let value = this.active.find(s => s.source == source) ||
20751
- new ActiveSource(source, this.active.some(a => a.state != 0 /* State.Inactive */) ? 1 /* State.Pending */ : 0 /* State.Inactive */);
21089
+ new ActiveSource(source, this.active.some(a => a.state != 0 /* Inactive */) ? 1 /* Pending */ : 0 /* Inactive */);
20752
21090
  return value.update(tr, conf);
20753
21091
  });
20754
21092
  if (active.length == this.active.length && active.every((a, i) => a == this.active[i]))
@@ -20759,10 +21097,10 @@
20759
21097
  if (tr.selection || active.some(a => a.hasResult() && tr.changes.touchesRange(a.from, a.to)) ||
20760
21098
  !sameResults(active, this.active))
20761
21099
  open = CompletionDialog.build(active, state, this.id, open, conf);
20762
- else if (open && open.disabled && !active.some(a => a.state == 1 /* State.Pending */))
21100
+ else if (open && open.disabled && !active.some(a => a.state == 1 /* Pending */))
20763
21101
  open = null;
20764
- if (!open && active.every(a => a.state != 1 /* State.Pending */) && active.some(a => a.hasResult()))
20765
- active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* State.Inactive */) : a);
21102
+ if (!open && active.every(a => a.state != 1 /* Pending */) && active.some(a => a.hasResult()))
21103
+ active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* Inactive */) : a);
20766
21104
  for (let effect of tr.effects)
20767
21105
  if (effect.is(setSelectedEffect))
20768
21106
  open = open && open.setSelected(effect.value, this.id);
@@ -20816,13 +21154,13 @@
20816
21154
  value = value.handleUserEvent(tr, event, conf);
20817
21155
  else if (tr.docChanged)
20818
21156
  value = value.handleChange(tr);
20819
- else if (tr.selection && value.state != 0 /* State.Inactive */)
20820
- value = new ActiveSource(value.source, 0 /* State.Inactive */);
21157
+ else if (tr.selection && value.state != 0 /* Inactive */)
21158
+ value = new ActiveSource(value.source, 0 /* Inactive */);
20821
21159
  for (let effect of tr.effects) {
20822
21160
  if (effect.is(startCompletionEffect))
20823
- value = new ActiveSource(value.source, 1 /* State.Pending */, effect.value ? cur(tr.state) : -1);
21161
+ value = new ActiveSource(value.source, 1 /* Pending */, effect.value ? cur(tr.state) : -1);
20824
21162
  else if (effect.is(closeCompletionEffect))
20825
- value = new ActiveSource(value.source, 0 /* State.Inactive */);
21163
+ value = new ActiveSource(value.source, 0 /* Inactive */);
20826
21164
  else if (effect.is(setActiveEffect))
20827
21165
  for (let active of effect.value)
20828
21166
  if (active.source == value.source)
@@ -20831,10 +21169,10 @@
20831
21169
  return value;
20832
21170
  }
20833
21171
  handleUserEvent(tr, type, conf) {
20834
- return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /* State.Pending */);
21172
+ return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /* Pending */);
20835
21173
  }
20836
21174
  handleChange(tr) {
20837
- return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes);
21175
+ return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes);
20838
21176
  }
20839
21177
  map(changes) {
20840
21178
  return changes.empty || this.explicitPos < 0 ? this : new ActiveSource(this.source, this.state, changes.mapPos(this.explicitPos));
@@ -20842,7 +21180,7 @@
20842
21180
  }
20843
21181
  class ActiveResult extends ActiveSource {
20844
21182
  constructor(source, explicitPos, result, from, to) {
20845
- super(source, 2 /* State.Result */, explicitPos);
21183
+ super(source, 2 /* Result */, explicitPos);
20846
21184
  this.result = result;
20847
21185
  this.from = from;
20848
21186
  this.to = to;
@@ -20855,17 +21193,17 @@
20855
21193
  if ((this.explicitPos < 0 ? pos <= from : pos < this.from) ||
20856
21194
  pos > to ||
20857
21195
  type == "delete" && cur(tr.startState) == this.from)
20858
- return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* State.Pending */ : 0 /* State.Inactive */);
21196
+ return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* Pending */ : 0 /* Inactive */);
20859
21197
  let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos), updated;
20860
21198
  if (checkValid(this.result.validFor, tr.state, from, to))
20861
21199
  return new ActiveResult(this.source, explicitPos, this.result, from, to);
20862
21200
  if (this.result.update &&
20863
21201
  (updated = this.result.update(this.result, from, to, new CompletionContext(tr.state, pos, explicitPos >= 0))))
20864
21202
  return new ActiveResult(this.source, explicitPos, updated, updated.from, (_a = updated.to) !== null && _a !== void 0 ? _a : cur(tr.state));
20865
- return new ActiveSource(this.source, 1 /* State.Pending */, explicitPos);
21203
+ return new ActiveSource(this.source, 1 /* Pending */, explicitPos);
20866
21204
  }
20867
21205
  handleChange(tr) {
20868
- return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes);
21206
+ return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes);
20869
21207
  }
20870
21208
  map(mapping) {
20871
21209
  return mapping.empty ? this :
@@ -20878,8 +21216,6 @@
20878
21216
  let text = state.sliceDoc(from, to);
20879
21217
  return typeof validFor == "function" ? validFor(text, from, to, state) : ensureAnchor(validFor, true).test(text);
20880
21218
  }
20881
- const startCompletionEffect = /*@__PURE__*/StateEffect.define();
20882
- const closeCompletionEffect = /*@__PURE__*/StateEffect.define();
20883
21219
  const setActiveEffect = /*@__PURE__*/StateEffect.define({
20884
21220
  map(sources, mapping) { return sources.map(s => s.map(mapping)); }
20885
21221
  });
@@ -20892,6 +21228,17 @@
20892
21228
  EditorView.contentAttributes.from(f, state => state.attrs)
20893
21229
  ]
20894
21230
  });
21231
+ function applyCompletion(view, option) {
21232
+ const apply = option.completion.apply || option.completion.label;
21233
+ let result = view.state.field(completionState).active.find(a => a.source == option.source);
21234
+ if (!(result instanceof ActiveResult))
21235
+ return false;
21236
+ if (typeof apply == "string")
21237
+ view.dispatch(Object.assign(Object.assign({}, insertCompletionText(view.state, apply, result.from, result.to)), { annotations: pickedCompletion.of(option.completion) }));
21238
+ else
21239
+ apply(view, option.completion, result.from, result.to);
21240
+ return true;
21241
+ }
20895
21242
 
20896
21243
  /**
20897
21244
  Returns a command that moves the completion selection forward or
@@ -20922,12 +21269,10 @@
20922
21269
  */
20923
21270
  const acceptCompletion = (view) => {
20924
21271
  let cState = view.state.field(completionState, false);
20925
- if (view.state.readOnly || !cState || !cState.open || cState.open.selected < 0 ||
21272
+ if (view.state.readOnly || !cState || !cState.open || cState.open.selected < 0 || cState.open.disabled ||
20926
21273
  Date.now() - cState.open.timestamp < view.state.facet(completionConfig).interactionDelay)
20927
21274
  return false;
20928
- if (!cState.open.disabled)
20929
- applyCompletion(view, cState.open.options[cState.open.selected]);
20930
- return true;
21275
+ return applyCompletion(view, cState.open.options[cState.open.selected]);
20931
21276
  };
20932
21277
  /**
20933
21278
  Explicitly start autocompletion.
@@ -20944,7 +21289,7 @@
20944
21289
  */
20945
21290
  const closeCompletion = (view) => {
20946
21291
  let cState = view.state.field(completionState, false);
20947
- if (!cState || !cState.active.some(a => a.state != 0 /* State.Inactive */))
21292
+ if (!cState || !cState.active.some(a => a.state != 0 /* Inactive */))
20948
21293
  return false;
20949
21294
  view.dispatch({ effects: closeCompletionEffect.of(null) });
20950
21295
  return true;
@@ -20967,9 +21312,9 @@
20967
21312
  this.debounceUpdate = -1;
20968
21313
  this.running = [];
20969
21314
  this.debounceAccept = -1;
20970
- this.composing = 0 /* CompositionState.None */;
21315
+ this.composing = 0 /* None */;
20971
21316
  for (let active of view.state.field(completionState).active)
20972
- if (active.state == 1 /* State.Pending */)
21317
+ if (active.state == 1 /* Pending */)
20973
21318
  this.startQuery(active);
20974
21319
  }
20975
21320
  update(update) {
@@ -21000,21 +21345,21 @@
21000
21345
  }
21001
21346
  if (this.debounceUpdate > -1)
21002
21347
  clearTimeout(this.debounceUpdate);
21003
- this.debounceUpdate = cState.active.some(a => a.state == 1 /* State.Pending */ && !this.running.some(q => q.active.source == a.source))
21348
+ this.debounceUpdate = cState.active.some(a => a.state == 1 /* Pending */ && !this.running.some(q => q.active.source == a.source))
21004
21349
  ? setTimeout(() => this.startUpdate(), DebounceTime) : -1;
21005
- if (this.composing != 0 /* CompositionState.None */)
21350
+ if (this.composing != 0 /* None */)
21006
21351
  for (let tr of update.transactions) {
21007
21352
  if (getUserEvent(tr) == "input")
21008
- this.composing = 2 /* CompositionState.Changed */;
21009
- else if (this.composing == 2 /* CompositionState.Changed */ && tr.selection)
21010
- this.composing = 3 /* CompositionState.ChangedAndMoved */;
21353
+ this.composing = 2 /* Changed */;
21354
+ else if (this.composing == 2 /* Changed */ && tr.selection)
21355
+ this.composing = 3 /* ChangedAndMoved */;
21011
21356
  }
21012
21357
  }
21013
21358
  startUpdate() {
21014
21359
  this.debounceUpdate = -1;
21015
21360
  let { state } = this.view, cState = state.field(completionState);
21016
21361
  for (let active of cState.active) {
21017
- if (active.state == 1 /* State.Pending */ && !this.running.some(r => r.active.source == active.source))
21362
+ if (active.state == 1 /* Pending */ && !this.running.some(r => r.active.source == active.source))
21018
21363
  this.startQuery(active);
21019
21364
  }
21020
21365
  }
@@ -21065,14 +21410,14 @@
21065
21410
  }
21066
21411
  }
21067
21412
  let current = this.view.state.field(completionState).active.find(a => a.source == query.active.source);
21068
- if (current && current.state == 1 /* State.Pending */) {
21413
+ if (current && current.state == 1 /* Pending */) {
21069
21414
  if (query.done == null) {
21070
21415
  // Explicitly failed. Should clear the pending status if it
21071
21416
  // hasn't been re-set in the meantime.
21072
- let active = new ActiveSource(query.active.source, 0 /* State.Inactive */);
21417
+ let active = new ActiveSource(query.active.source, 0 /* Inactive */);
21073
21418
  for (let tr of query.updates)
21074
21419
  active = active.update(tr, conf);
21075
- if (active.state != 1 /* State.Pending */)
21420
+ if (active.state != 1 /* Pending */)
21076
21421
  updated.push(active);
21077
21422
  }
21078
21423
  else {
@@ -21086,21 +21431,24 @@
21086
21431
  }
21087
21432
  }, {
21088
21433
  eventHandlers: {
21089
- blur() {
21434
+ blur(event) {
21090
21435
  let state = this.view.state.field(completionState, false);
21091
- if (state && state.tooltip && this.view.state.facet(completionConfig).closeOnBlur)
21092
- this.view.dispatch({ effects: closeCompletionEffect.of(null) });
21436
+ if (state && state.tooltip && this.view.state.facet(completionConfig).closeOnBlur) {
21437
+ let dialog = state.open && getTooltip(this.view, state.open.tooltip);
21438
+ if (!dialog || !dialog.dom.contains(event.relatedTarget))
21439
+ this.view.dispatch({ effects: closeCompletionEffect.of(null) });
21440
+ }
21093
21441
  },
21094
21442
  compositionstart() {
21095
- this.composing = 1 /* CompositionState.Started */;
21443
+ this.composing = 1 /* Started */;
21096
21444
  },
21097
21445
  compositionend() {
21098
- if (this.composing == 3 /* CompositionState.ChangedAndMoved */) {
21446
+ if (this.composing == 3 /* ChangedAndMoved */) {
21099
21447
  // Safari fires compositionend events synchronously, possibly
21100
21448
  // from inside an update, so dispatch asynchronously to avoid reentrancy
21101
21449
  setTimeout(() => this.view.dispatch({ effects: startCompletionEffect.of(false) }), 20);
21102
21450
  }
21103
- this.composing = 0 /* CompositionState.None */;
21451
+ this.composing = 0 /* None */;
21104
21452
  }
21105
21453
  }
21106
21454
  });
@@ -21119,13 +21467,21 @@
21119
21467
  listStyle: "none",
21120
21468
  margin: 0,
21121
21469
  padding: 0,
21470
+ "& > li, & > completion-section": {
21471
+ padding: "1px 3px",
21472
+ lineHeight: 1.2
21473
+ },
21122
21474
  "& > li": {
21123
21475
  overflowX: "hidden",
21124
21476
  textOverflow: "ellipsis",
21125
- cursor: "pointer",
21126
- padding: "1px 3px",
21127
- lineHeight: 1.2
21477
+ cursor: "pointer"
21128
21478
  },
21479
+ "& > completion-section": {
21480
+ display: "list-item",
21481
+ borderBottom: "1px solid silver",
21482
+ paddingLeft: "0.5em",
21483
+ opacity: 0.7
21484
+ }
21129
21485
  }
21130
21486
  },
21131
21487
  "&light .cm-tooltip-autocomplete ul li[aria-selected]": {
@@ -21152,13 +21508,13 @@
21152
21508
  position: "absolute",
21153
21509
  padding: "3px 9px",
21154
21510
  width: "max-content",
21155
- maxWidth: `${400 /* Info.Width */}px`,
21511
+ maxWidth: `${400 /* Width */}px`,
21156
21512
  boxSizing: "border-box"
21157
21513
  },
21158
21514
  ".cm-completionInfo.cm-completionInfo-left": { right: "100%" },
21159
21515
  ".cm-completionInfo.cm-completionInfo-right": { left: "100%" },
21160
- ".cm-completionInfo.cm-completionInfo-left-narrow": { right: `${30 /* Info.Margin */}px` },
21161
- ".cm-completionInfo.cm-completionInfo-right-narrow": { left: `${30 /* Info.Margin */}px` },
21516
+ ".cm-completionInfo.cm-completionInfo-left-narrow": { right: `${30 /* Margin */}px` },
21517
+ ".cm-completionInfo.cm-completionInfo-right-narrow": { left: `${30 /* Margin */}px` },
21162
21518
  "&light .cm-snippetField": { backgroundColor: "#00000022" },
21163
21519
  "&dark .cm-snippetField": { backgroundColor: "#ffffff22" },
21164
21520
  ".cm-snippetFieldPosition": {
@@ -21231,9 +21587,6 @@
21231
21587
  return mapped == null ? undefined : mapped;
21232
21588
  }
21233
21589
  });
21234
- const skipBracketEffect = /*@__PURE__*/StateEffect.define({
21235
- map(value, mapping) { return mapping.mapPos(value); }
21236
- });
21237
21590
  const closedBracket = /*@__PURE__*/new class extends RangeValue {
21238
21591
  };
21239
21592
  closedBracket.startSide = 1;
@@ -21248,12 +21601,9 @@
21248
21601
  value = RangeSet.empty;
21249
21602
  }
21250
21603
  value = value.map(tr.changes);
21251
- for (let effect of tr.effects) {
21604
+ for (let effect of tr.effects)
21252
21605
  if (effect.is(closeBracketEffect))
21253
21606
  value = value.update({ add: [closedBracket.range(effect.value, effect.value + 1)] });
21254
- else if (effect.is(skipBracketEffect))
21255
- value = value.update({ filter: from => from != effect.value });
21256
- }
21257
21607
  return value;
21258
21608
  }
21259
21609
  });
@@ -21381,15 +21731,15 @@
21381
21731
  });
21382
21732
  }
21383
21733
  function handleClose(state, _open, close) {
21384
- let dont = null, moved = state.selection.ranges.map(range => {
21734
+ let dont = null, changes = state.changeByRange(range => {
21385
21735
  if (range.empty && nextChar(state.doc, range.head) == close)
21386
- return EditorSelection.cursor(range.head + close.length);
21387
- return dont = range;
21736
+ return { changes: { from: range.head, to: range.head + close.length, insert: close },
21737
+ range: EditorSelection.cursor(range.head + close.length) };
21738
+ return dont = { range };
21388
21739
  });
21389
- return dont ? null : state.update({
21390
- selection: EditorSelection.create(moved, state.selection.mainIndex),
21740
+ return dont ? null : state.update(changes, {
21391
21741
  scrollIntoView: true,
21392
- effects: state.selection.ranges.map(({ from }) => skipBracketEffect.of(from))
21742
+ userEvent: "input.type"
21393
21743
  });
21394
21744
  }
21395
21745
  // Handles cases where the open and close token are the same, and
@@ -21410,8 +21760,9 @@
21410
21760
  }
21411
21761
  else if (closedBracketAt(state, pos)) {
21412
21762
  let isTriple = allowTriple && state.sliceDoc(pos, pos + token.length * 3) == token + token + token;
21413
- return { range: EditorSelection.cursor(pos + token.length * (isTriple ? 3 : 1)),
21414
- effects: skipBracketEffect.of(pos) };
21763
+ let content = isTriple ? token + token + token : token;
21764
+ return { changes: { from: pos, to: pos + content.length, insert: content },
21765
+ range: EditorSelection.cursor(pos + content.length) };
21415
21766
  }
21416
21767
  }
21417
21768
  else if (allowTriple && state.sliceDoc(pos - 2 * token.length, pos) == token + token &&
@@ -21869,22 +22220,54 @@
21869
22220
  // be done.
21870
22221
  /// @internal
21871
22222
  forceReduce() {
21872
- let reduce = this.p.parser.stateSlot(this.state, 5 /* ParseState.ForcedReduce */);
22223
+ let { parser } = this.p;
22224
+ let reduce = parser.stateSlot(this.state, 5 /* ParseState.ForcedReduce */);
21873
22225
  if ((reduce & 65536 /* Action.ReduceFlag */) == 0)
21874
22226
  return false;
21875
- let { parser } = this.p;
21876
22227
  if (!parser.validAction(this.state, reduce)) {
21877
22228
  let depth = reduce >> 19 /* Action.ReduceDepthShift */, term = reduce & 65535 /* Action.ValueMask */;
21878
22229
  let target = this.stack.length - depth * 3;
21879
- if (target < 0 || parser.getGoto(this.stack[target], term, false) < 0)
21880
- return false;
21881
- this.storeNode(0 /* Term.Err */, this.reducePos, this.reducePos, 4, true);
22230
+ if (target < 0 || parser.getGoto(this.stack[target], term, false) < 0) {
22231
+ let backup = this.findForcedReduction();
22232
+ if (backup == null)
22233
+ return false;
22234
+ reduce = backup;
22235
+ }
22236
+ this.storeNode(0 /* Term.Err */, this.pos, this.pos, 4, true);
21882
22237
  this.score -= 100 /* Recover.Reduce */;
21883
22238
  }
21884
22239
  this.reducePos = this.pos;
21885
22240
  this.reduce(reduce);
21886
22241
  return true;
21887
22242
  }
22243
+ /// Try to scan through the automaton to find some kind of reduction
22244
+ /// that can be applied. Used when the regular ForcedReduce field
22245
+ /// isn't a valid action. @internal
22246
+ findForcedReduction() {
22247
+ let { parser } = this.p, seen = [];
22248
+ let explore = (state, depth) => {
22249
+ if (seen.includes(state))
22250
+ return;
22251
+ seen.push(state);
22252
+ return parser.allActions(state, (action) => {
22253
+ if (action & (262144 /* Action.StayFlag */ | 131072 /* Action.GotoFlag */)) ;
22254
+ else if (action & 65536 /* Action.ReduceFlag */) {
22255
+ let rDepth = (action >> 19 /* Action.ReduceDepthShift */) - depth;
22256
+ if (rDepth > 1) {
22257
+ let term = action & 65535 /* Action.ValueMask */, target = this.stack.length - rDepth * 3;
22258
+ if (target >= 0 && parser.getGoto(this.stack[target], term, false) >= 0)
22259
+ return (rDepth << 19 /* Action.ReduceDepthShift */) | 65536 /* Action.ReduceFlag */ | term;
22260
+ }
22261
+ }
22262
+ else {
22263
+ let found = explore(action, depth + 1);
22264
+ if (found != null)
22265
+ return found;
22266
+ }
22267
+ });
22268
+ };
22269
+ return explore(this.state, 0);
22270
+ }
21888
22271
  /// @internal
21889
22272
  forceAll() {
21890
22273
  while (!this.p.parser.stateFlag(this.state, 2 /* StateFlag.Accepting */)) {
@@ -21938,13 +22321,13 @@
21938
22321
  emitContext() {
21939
22322
  let last = this.buffer.length - 1;
21940
22323
  if (last < 0 || this.buffer[last] != -3)
21941
- this.buffer.push(this.curContext.hash, this.reducePos, this.reducePos, -3);
22324
+ this.buffer.push(this.curContext.hash, this.pos, this.pos, -3);
21942
22325
  }
21943
22326
  /// @internal
21944
22327
  emitLookAhead() {
21945
22328
  let last = this.buffer.length - 1;
21946
22329
  if (last < 0 || this.buffer[last] != -4)
21947
- this.buffer.push(this.lookAhead, this.reducePos, this.reducePos, -4);
22330
+ this.buffer.push(this.lookAhead, this.pos, this.pos, -4);
21948
22331
  }
21949
22332
  updateContext(context) {
21950
22333
  if (context != this.curContext.context) {
@@ -23060,18 +23443,22 @@
23060
23443
  }
23061
23444
  /// @internal
23062
23445
  validAction(state, action) {
23063
- if (action == this.stateSlot(state, 4 /* ParseState.DefaultReduce */))
23064
- return true;
23065
- for (let i = this.stateSlot(state, 1 /* ParseState.Actions */);; i += 3) {
23446
+ return !!this.allActions(state, a => a == action ? true : null);
23447
+ }
23448
+ /// @internal
23449
+ allActions(state, action) {
23450
+ let deflt = this.stateSlot(state, 4 /* ParseState.DefaultReduce */);
23451
+ let result = deflt ? action(deflt) : undefined;
23452
+ for (let i = this.stateSlot(state, 1 /* ParseState.Actions */); result == null; i += 3) {
23066
23453
  if (this.data[i] == 65535 /* Seq.End */) {
23067
23454
  if (this.data[i + 1] == 1 /* Seq.Next */)
23068
23455
  i = pair(this.data, i + 2);
23069
23456
  else
23070
- return false;
23457
+ break;
23071
23458
  }
23072
- if (action == pair(this.data, i + 1))
23073
- return true;
23459
+ result = action(pair(this.data, i + 1));
23074
23460
  }
23461
+ return result;
23075
23462
  }
23076
23463
  /// Get the states that can follow this one through shift actions or
23077
23464
  /// goto jumps. @internal
@@ -23228,10 +23615,10 @@
23228
23615
  Builtin = 24;
23229
23616
 
23230
23617
  function isAlpha(ch) {
23231
- return ch >= 65 /* Ch.A */ && ch <= 90 /* Ch.Z */ || ch >= 97 /* Ch.a */ && ch <= 122 /* Ch.z */ || ch >= 48 /* Ch._0 */ && ch <= 57 /* Ch._9 */;
23618
+ return ch >= 65 /* A */ && ch <= 90 /* Z */ || ch >= 97 /* a */ && ch <= 122 /* z */ || ch >= 48 /* _0 */ && ch <= 57 /* _9 */;
23232
23619
  }
23233
23620
  function isHexDigit(ch) {
23234
- return ch >= 48 /* Ch._0 */ && ch <= 57 /* Ch._9 */ || ch >= 97 /* Ch.a */ && ch <= 102 /* Ch.f */ || ch >= 65 /* Ch.A */ && ch <= 70 /* Ch.F */;
23621
+ return ch >= 48 /* _0 */ && ch <= 57 /* _9 */ || ch >= 97 /* a */ && ch <= 102 /* f */ || ch >= 65 /* A */ && ch <= 70 /* F */;
23235
23622
  }
23236
23623
  function readLiteral(input, endQuote, backslashEscapes) {
23237
23624
  for (let escaped = false;;) {
@@ -23241,7 +23628,7 @@
23241
23628
  input.advance();
23242
23629
  return;
23243
23630
  }
23244
- escaped = backslashEscapes && !escaped && input.next == 92 /* Ch.Backslash */;
23631
+ escaped = backslashEscapes && !escaped && input.next == 92 /* Backslash */;
23245
23632
  input.advance();
23246
23633
  }
23247
23634
  }
@@ -23249,7 +23636,7 @@
23249
23636
  for (;;) {
23250
23637
  if (input.next < 0 || input.peek(1) < 0)
23251
23638
  return;
23252
- if (input.next == 36 /* Ch.Dollar */ && input.peek(1) == 36 /* Ch.Dollar */) {
23639
+ if (input.next == 36 /* Dollar */ && input.peek(1) == 36 /* Dollar */) {
23253
23640
  input.advance(2);
23254
23641
  return;
23255
23642
  }
@@ -23258,7 +23645,7 @@
23258
23645
  }
23259
23646
  function readWord(input, result) {
23260
23647
  for (;;) {
23261
- if (input.next != 95 /* Ch.Underscore */ && !isAlpha(input.next))
23648
+ if (input.next != 95 /* Underscore */ && !isAlpha(input.next))
23262
23649
  break;
23263
23650
  if (result != null)
23264
23651
  result += String.fromCharCode(input.next);
@@ -23267,7 +23654,7 @@
23267
23654
  return result;
23268
23655
  }
23269
23656
  function readWordOrQuoted(input) {
23270
- if (input.next == 39 /* Ch.SingleQuote */ || input.next == 34 /* Ch.DoubleQuote */ || input.next == 96 /* Ch.Backtick */) {
23657
+ if (input.next == 39 /* SingleQuote */ || input.next == 34 /* DoubleQuote */ || input.next == 96 /* Backtick */) {
23271
23658
  let quote = input.next;
23272
23659
  input.advance();
23273
23660
  readLiteral(input, quote, false);
@@ -23277,33 +23664,33 @@
23277
23664
  }
23278
23665
  }
23279
23666
  function readBits(input, endQuote) {
23280
- while (input.next == 48 /* Ch._0 */ || input.next == 49 /* Ch._1 */)
23667
+ while (input.next == 48 /* _0 */ || input.next == 49 /* _1 */)
23281
23668
  input.advance();
23282
23669
  if (endQuote && input.next == endQuote)
23283
23670
  input.advance();
23284
23671
  }
23285
23672
  function readNumber(input, sawDot) {
23286
23673
  for (;;) {
23287
- if (input.next == 46 /* Ch.Dot */) {
23674
+ if (input.next == 46 /* Dot */) {
23288
23675
  if (sawDot)
23289
23676
  break;
23290
23677
  sawDot = true;
23291
23678
  }
23292
- else if (input.next < 48 /* Ch._0 */ || input.next > 57 /* Ch._9 */) {
23679
+ else if (input.next < 48 /* _0 */ || input.next > 57 /* _9 */) {
23293
23680
  break;
23294
23681
  }
23295
23682
  input.advance();
23296
23683
  }
23297
- if (input.next == 69 /* Ch.E */ || input.next == 101 /* Ch.e */) {
23684
+ if (input.next == 69 /* E */ || input.next == 101 /* e */) {
23298
23685
  input.advance();
23299
- if (input.next == 43 /* Ch.Plus */ || input.next == 45 /* Ch.Dash */)
23686
+ if (input.next == 43 /* Plus */ || input.next == 45 /* Dash */)
23300
23687
  input.advance();
23301
- while (input.next >= 48 /* Ch._0 */ && input.next <= 57 /* Ch._9 */)
23688
+ while (input.next >= 48 /* _0 */ && input.next <= 57 /* _9 */)
23302
23689
  input.advance();
23303
23690
  }
23304
23691
  }
23305
23692
  function eol(input) {
23306
- while (!(input.next < 0 || input.next == 10 /* Ch.Newline */))
23693
+ while (!(input.next < 0 || input.next == 10 /* Newline */))
23307
23694
  input.advance();
23308
23695
  }
23309
23696
  function inString(ch, str) {
@@ -23363,63 +23750,59 @@
23363
23750
  input.advance();
23364
23751
  input.acceptToken(whitespace);
23365
23752
  }
23366
- else if (next == 36 /* Ch.Dollar */ && input.next == 36 /* Ch.Dollar */ && d.doubleDollarQuotedStrings) {
23753
+ else if (next == 36 /* Dollar */ && input.next == 36 /* Dollar */ && d.doubleDollarQuotedStrings) {
23367
23754
  readDoubleDollarLiteral(input);
23368
23755
  input.acceptToken(String$1);
23369
23756
  }
23370
- else if (next == 39 /* Ch.SingleQuote */ || next == 34 /* Ch.DoubleQuote */ && d.doubleQuotedStrings) {
23757
+ else if (next == 39 /* SingleQuote */ || next == 34 /* DoubleQuote */ && d.doubleQuotedStrings) {
23371
23758
  readLiteral(input, next, d.backslashEscapes);
23372
23759
  input.acceptToken(String$1);
23373
23760
  }
23374
- else if (next == 35 /* Ch.Hash */ && d.hashComments ||
23375
- next == 47 /* Ch.Slash */ && input.next == 47 /* Ch.Slash */ && d.slashComments) {
23761
+ else if (next == 35 /* Hash */ && d.hashComments ||
23762
+ next == 47 /* Slash */ && input.next == 47 /* Slash */ && d.slashComments) {
23376
23763
  eol(input);
23377
23764
  input.acceptToken(LineComment);
23378
23765
  }
23379
- else if (next == 45 /* Ch.Dash */ && input.next == 45 /* Ch.Dash */ &&
23380
- (!d.spaceAfterDashes || input.peek(1) == 32 /* Ch.Space */)) {
23766
+ else if (next == 45 /* Dash */ && input.next == 45 /* Dash */ &&
23767
+ (!d.spaceAfterDashes || input.peek(1) == 32 /* Space */)) {
23381
23768
  eol(input);
23382
23769
  input.acceptToken(LineComment);
23383
23770
  }
23384
- else if (next == 47 /* Ch.Slash */ && input.next == 42 /* Ch.Star */) {
23771
+ else if (next == 47 /* Slash */ && input.next == 42 /* Star */) {
23385
23772
  input.advance();
23386
- for (let prev = -1, depth = 1;;) {
23773
+ for (let depth = 1;;) {
23774
+ let cur = input.next;
23387
23775
  if (input.next < 0)
23388
23776
  break;
23389
23777
  input.advance();
23390
- if (prev == 42 /* Ch.Star */ && input.next == 47 /* Ch.Slash */) {
23778
+ if (cur == 42 /* Star */ && input.next == 47 /* Slash */) {
23391
23779
  depth--;
23392
- if (!depth) {
23393
- input.advance();
23780
+ input.advance();
23781
+ if (!depth)
23394
23782
  break;
23395
- }
23396
- prev = -1;
23397
23783
  }
23398
- else if (prev == 47 /* Ch.Slash */ && input.next == 42 /* Ch.Star */) {
23784
+ else if (cur == 47 /* Slash */ && input.next == 42 /* Star */) {
23399
23785
  depth++;
23400
- prev = -1;
23401
- }
23402
- else {
23403
- prev = input.next;
23786
+ input.advance();
23404
23787
  }
23405
23788
  }
23406
23789
  input.acceptToken(BlockComment);
23407
23790
  }
23408
- else if ((next == 101 /* Ch.e */ || next == 69 /* Ch.E */) && input.next == 39 /* Ch.SingleQuote */) {
23791
+ else if ((next == 101 /* e */ || next == 69 /* E */) && input.next == 39 /* SingleQuote */) {
23409
23792
  input.advance();
23410
- readLiteral(input, 39 /* Ch.SingleQuote */, true);
23793
+ readLiteral(input, 39 /* SingleQuote */, true);
23411
23794
  }
23412
- else if ((next == 110 /* Ch.n */ || next == 78 /* Ch.N */) && input.next == 39 /* Ch.SingleQuote */ &&
23795
+ else if ((next == 110 /* n */ || next == 78 /* N */) && input.next == 39 /* SingleQuote */ &&
23413
23796
  d.charSetCasts) {
23414
23797
  input.advance();
23415
- readLiteral(input, 39 /* Ch.SingleQuote */, d.backslashEscapes);
23798
+ readLiteral(input, 39 /* SingleQuote */, d.backslashEscapes);
23416
23799
  input.acceptToken(String$1);
23417
23800
  }
23418
- else if (next == 95 /* Ch.Underscore */ && d.charSetCasts) {
23801
+ else if (next == 95 /* Underscore */ && d.charSetCasts) {
23419
23802
  for (let i = 0;; i++) {
23420
- if (input.next == 39 /* Ch.SingleQuote */ && i > 1) {
23803
+ if (input.next == 39 /* SingleQuote */ && i > 1) {
23421
23804
  input.advance();
23422
- readLiteral(input, 39 /* Ch.SingleQuote */, d.backslashEscapes);
23805
+ readLiteral(input, 39 /* SingleQuote */, d.backslashEscapes);
23423
23806
  input.acceptToken(String$1);
23424
23807
  break;
23425
23808
  }
@@ -23428,33 +23811,33 @@
23428
23811
  input.advance();
23429
23812
  }
23430
23813
  }
23431
- else if (next == 40 /* Ch.ParenL */) {
23814
+ else if (next == 40 /* ParenL */) {
23432
23815
  input.acceptToken(ParenL);
23433
23816
  }
23434
- else if (next == 41 /* Ch.ParenR */) {
23817
+ else if (next == 41 /* ParenR */) {
23435
23818
  input.acceptToken(ParenR);
23436
23819
  }
23437
- else if (next == 123 /* Ch.BraceL */) {
23820
+ else if (next == 123 /* BraceL */) {
23438
23821
  input.acceptToken(BraceL);
23439
23822
  }
23440
- else if (next == 125 /* Ch.BraceR */) {
23823
+ else if (next == 125 /* BraceR */) {
23441
23824
  input.acceptToken(BraceR);
23442
23825
  }
23443
- else if (next == 91 /* Ch.BracketL */) {
23826
+ else if (next == 91 /* BracketL */) {
23444
23827
  input.acceptToken(BracketL);
23445
23828
  }
23446
- else if (next == 93 /* Ch.BracketR */) {
23829
+ else if (next == 93 /* BracketR */) {
23447
23830
  input.acceptToken(BracketR);
23448
23831
  }
23449
- else if (next == 59 /* Ch.Semi */) {
23832
+ else if (next == 59 /* Semi */) {
23450
23833
  input.acceptToken(Semi);
23451
23834
  }
23452
- else if (d.unquotedBitLiterals && next == 48 /* Ch._0 */ && input.next == 98 /* Ch.b */) {
23835
+ else if (d.unquotedBitLiterals && next == 48 /* _0 */ && input.next == 98 /* b */) {
23453
23836
  input.advance();
23454
23837
  readBits(input);
23455
23838
  input.acceptToken(Bits);
23456
23839
  }
23457
- else if ((next == 98 /* Ch.b */ || next == 66 /* Ch.B */) && (input.next == 39 /* Ch.SingleQuote */ || input.next == 34 /* Ch.DoubleQuote */)) {
23840
+ else if ((next == 98 /* b */ || next == 66 /* B */) && (input.next == 39 /* SingleQuote */ || input.next == 34 /* DoubleQuote */)) {
23458
23841
  const quoteStyle = input.next;
23459
23842
  input.advance();
23460
23843
  if (d.treatBitsAsBytes) {
@@ -23466,24 +23849,24 @@
23466
23849
  input.acceptToken(Bits);
23467
23850
  }
23468
23851
  }
23469
- else if (next == 48 /* Ch._0 */ && (input.next == 120 /* Ch.x */ || input.next == 88 /* Ch.X */) ||
23470
- (next == 120 /* Ch.x */ || next == 88 /* Ch.X */) && input.next == 39 /* Ch.SingleQuote */) {
23471
- let quoted = input.next == 39 /* Ch.SingleQuote */;
23852
+ else if (next == 48 /* _0 */ && (input.next == 120 /* x */ || input.next == 88 /* X */) ||
23853
+ (next == 120 /* x */ || next == 88 /* X */) && input.next == 39 /* SingleQuote */) {
23854
+ let quoted = input.next == 39 /* SingleQuote */;
23472
23855
  input.advance();
23473
23856
  while (isHexDigit(input.next))
23474
23857
  input.advance();
23475
- if (quoted && input.next == 39 /* Ch.SingleQuote */)
23858
+ if (quoted && input.next == 39 /* SingleQuote */)
23476
23859
  input.advance();
23477
23860
  input.acceptToken(Number$1);
23478
23861
  }
23479
- else if (next == 46 /* Ch.Dot */ && input.next >= 48 /* Ch._0 */ && input.next <= 57 /* Ch._9 */) {
23862
+ else if (next == 46 /* Dot */ && input.next >= 48 /* _0 */ && input.next <= 57 /* _9 */) {
23480
23863
  readNumber(input, true);
23481
23864
  input.acceptToken(Number$1);
23482
23865
  }
23483
- else if (next == 46 /* Ch.Dot */) {
23866
+ else if (next == 46 /* Dot */) {
23484
23867
  input.acceptToken(Dot);
23485
23868
  }
23486
- else if (next >= 48 /* Ch._0 */ && next <= 57 /* Ch._9 */) {
23869
+ else if (next >= 48 /* _0 */ && next <= 57 /* _9 */) {
23487
23870
  readNumber(input, false);
23488
23871
  input.acceptToken(Number$1);
23489
23872
  }
@@ -23502,12 +23885,12 @@
23502
23885
  readLiteral(input, next, false);
23503
23886
  input.acceptToken(QuotedIdentifier);
23504
23887
  }
23505
- else if (next == 58 /* Ch.Colon */ || next == 44 /* Ch.Comma */) {
23888
+ else if (next == 58 /* Colon */ || next == 44 /* Comma */) {
23506
23889
  input.acceptToken(Punctuation);
23507
23890
  }
23508
23891
  else if (isAlpha(next)) {
23509
23892
  let word = readWord(input, String.fromCharCode(next));
23510
- input.acceptToken(input.next == 46 /* Ch.Dot */ ? Identifier : (_a = d.words[word.toLowerCase()]) !== null && _a !== void 0 ? _a : Identifier);
23893
+ input.acceptToken(input.next == 46 /* Dot */ ? Identifier : (_a = d.words[word.toLowerCase()]) !== null && _a !== void 0 ? _a : Identifier);
23511
23894
  }
23512
23895
  });
23513
23896
  }
@@ -23625,31 +24008,50 @@
23625
24008
  this.list = [];
23626
24009
  this.children = undefined;
23627
24010
  }
23628
- child(name) {
24011
+ child(name, idQuote) {
23629
24012
  let children = this.children || (this.children = Object.create(null));
23630
- return children[name] || (children[name] = new CompletionLevel);
24013
+ let found = children[name];
24014
+ if (found)
24015
+ return found;
24016
+ if (name)
24017
+ this.list.push(nameCompletion(name, "type", idQuote));
24018
+ return (children[name] = new CompletionLevel);
23631
24019
  }
23632
- childCompletions(type) {
23633
- return this.children ? Object.keys(this.children).filter(x => x).map(name => ({ label: name, type })) : [];
24020
+ addCompletions(list) {
24021
+ for (let option of list) {
24022
+ let found = this.list.findIndex(o => o.label == option.label);
24023
+ if (found > -1)
24024
+ this.list[found] = option;
24025
+ else
24026
+ this.list.push(option);
24027
+ }
23634
24028
  }
23635
24029
  }
23636
- function completeFromSchema(schema, tables, schemas, defaultTableName, defaultSchemaName) {
24030
+ function nameCompletion(label, type, idQuote) {
24031
+ if (!/[^\w\xb5-\uffff]/.test(label))
24032
+ return { label, type };
24033
+ return { label, type, apply: idQuote + label + idQuote };
24034
+ }
24035
+ function completeFromSchema(schema, tables, schemas, defaultTableName, defaultSchemaName, dialect) {
24036
+ var _a;
23637
24037
  let top = new CompletionLevel;
23638
- let defaultSchema = top.child(defaultSchemaName || "");
24038
+ let idQuote = ((_a = dialect === null || dialect === void 0 ? void 0 : dialect.spec.identifierQuotes) === null || _a === void 0 ? void 0 : _a[0]) || '"';
24039
+ let defaultSchema = top.child(defaultSchemaName || "", idQuote);
23639
24040
  for (let table in schema) {
23640
- let dot = table.indexOf(".");
23641
- let schemaCompletions = dot > -1 ? top.child(table.slice(0, dot)) : defaultSchema;
23642
- let tableCompletions = schemaCompletions.child(dot > -1 ? table.slice(dot + 1) : table);
23643
- tableCompletions.list = schema[table].map(val => typeof val == "string" ? { label: val, type: "property" } : val);
23644
- }
23645
- defaultSchema.list = (tables || defaultSchema.childCompletions("type"))
23646
- .concat(defaultTableName ? defaultSchema.child(defaultTableName).list : []);
23647
- for (let sName in top.children) {
23648
- let schema = top.child(sName);
23649
- if (!schema.list.length)
23650
- schema.list = schema.childCompletions("type");
23651
- }
23652
- top.list = defaultSchema.list.concat(schemas || top.childCompletions("type"));
24041
+ let parts = table.split("."), base = parts.length == 1 ? defaultSchema : top;
24042
+ for (let part of parts)
24043
+ base = base.child(part, idQuote);
24044
+ for (let option of schema[table])
24045
+ if (option)
24046
+ base.list.push(typeof option == "string" ? nameCompletion(option, "property", idQuote) : option);
24047
+ }
24048
+ if (tables)
24049
+ defaultSchema.addCompletions(tables);
24050
+ if (schemas)
24051
+ top.addCompletions(schemas);
24052
+ top.addCompletions(defaultSchema.list);
24053
+ if (defaultTableName)
24054
+ top.addCompletions(defaultSchema.child(defaultTableName, idQuote).list);
23653
24055
  return (context) => {
23654
24056
  let { parents, from, quoted, empty, aliases } = sourceContext(context.state, context.pos);
23655
24057
  if (empty && !context.explicit)
@@ -23662,11 +24064,11 @@
23662
24064
  if (level == top)
23663
24065
  level = defaultSchema;
23664
24066
  else if (level == defaultSchema && defaultTableName)
23665
- level = level.child(defaultTableName);
24067
+ level = level.child(defaultTableName, idQuote);
23666
24068
  else
23667
24069
  return null;
23668
24070
  }
23669
- level = level.child(name);
24071
+ level = level.child(name, idQuote);
23670
24072
  }
23671
24073
  let quoteAfter = quoted && context.state.sliceDoc(context.pos, context.pos + 1) == quoted;
23672
24074
  let options = level.list;
@@ -23733,9 +24135,14 @@
23733
24135
  /**
23734
24136
  The language for this dialect.
23735
24137
  */
23736
- language) {
24138
+ language,
24139
+ /**
24140
+ The spec used to define this dialect.
24141
+ */
24142
+ spec) {
23737
24143
  this.dialect = dialect;
23738
24144
  this.language = language;
24145
+ this.spec = spec;
23739
24146
  }
23740
24147
  /**
23741
24148
  Returns the language for this dialect as an extension.
@@ -23756,7 +24163,7 @@
23756
24163
  closeBrackets: { brackets: ["(", "[", "{", "'", '"', "`"] }
23757
24164
  }
23758
24165
  });
23759
- return new SQLDialect(d, language);
24166
+ return new SQLDialect(d, language, spec);
23760
24167
  }
23761
24168
  }
23762
24169
  /**
@@ -23771,9 +24178,13 @@
23771
24178
  for the given configuration.
23772
24179
  */
23773
24180
  function schemaCompletionSource(config) {
23774
- return config.schema ? completeFromSchema(config.schema, config.tables, config.schemas, config.defaultTable, config.defaultSchema)
24181
+ return config.schema ? completeFromSchema(config.schema, config.tables, config.schemas, config.defaultTable, config.defaultSchema, config.dialect || StandardSQL)
23775
24182
  : () => null;
23776
24183
  }
24184
+ /**
24185
+ The standard SQL dialect.
24186
+ */
24187
+ const StandardSQL = /*@__PURE__*/SQLDialect.define({});
23777
24188
  const MySQLKeywords = "accessible algorithm analyze asensitive authors auto_increment autocommit avg avg_row_length binlog btree cache catalog_name chain change changed checkpoint checksum class_origin client_statistics coalesce code collations columns comment committed completion concurrent consistent contains contributors convert database databases day_hour day_microsecond day_minute day_second delay_key_write delayed delimiter des_key_file dev_pop dev_samp deviance directory disable discard distinctrow div dual dumpfile enable enclosed ends engine engines enum errors escaped even event events every explain extended fast field fields flush force found_rows fulltext grants handler hash high_priority hosts hour_microsecond hour_minute hour_second ignore ignore_server_ids import index index_statistics infile innodb insensitive insert_method install invoker iterate keys kill linear lines list load lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modify mutex mysql_errno no_write_to_binlog offline offset one online optimize optionally outfile pack_keys parser partition partitions password phase plugin plugins prev processlist profile profiles purge query quick range read_write rebuild recover regexp relaylog remove rename reorganize repair repeatable replace require resume rlike row_format rtree schedule schema_name schemas second_microsecond security sensitive separator serializable server share show slave slow snapshot soname spatial sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result ssl starting starts std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace terminated triggers truncate uncommitted uninstall unlock upgrade use use_frm user_resources user_statistics utc_date utc_time utc_timestamp variables views warnings xa xor year_month zerofill";
23778
24189
  const MySQLTypes = SQLTypes + "bool blob long longblob longtext medium mediumblob mediumint mediumtext tinyblob tinyint tinytext text bigint int1 int2 int3 int4 int8 float4 float8 varbinary varcharacter precision datetime unsigned signed";
23779
24190
  const MySQLBuiltin = "charset clear edit ego help nopager notee nowarning pager print prompt quit rehash source status system tee";