@sanity/runtime-cli 11.2.0 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +36 -38
  2. package/dist/actions/blueprints/blueprint.d.ts +3 -0
  3. package/dist/actions/blueprints/blueprint.js +26 -14
  4. package/dist/actions/blueprints/config.d.ts +34 -3
  5. package/dist/actions/blueprints/config.js +67 -14
  6. package/dist/actions/blueprints/stacks.d.ts +1 -2
  7. package/dist/actions/blueprints/stacks.js +2 -3
  8. package/dist/commands/blueprints/config.d.ts +0 -1
  9. package/dist/commands/blueprints/config.js +4 -12
  10. package/dist/commands/blueprints/deploy.js +1 -1
  11. package/dist/commands/blueprints/destroy.js +3 -3
  12. package/dist/commands/blueprints/info.js +2 -2
  13. package/dist/commands/blueprints/init.d.ts +1 -0
  14. package/dist/commands/blueprints/init.js +4 -0
  15. package/dist/commands/blueprints/logs.js +2 -2
  16. package/dist/commands/blueprints/plan.js +1 -0
  17. package/dist/config.d.ts +2 -1
  18. package/dist/config.js +8 -1
  19. package/dist/cores/blueprints/config.d.ts +1 -1
  20. package/dist/cores/blueprints/config.js +92 -78
  21. package/dist/cores/blueprints/deploy.js +8 -8
  22. package/dist/cores/blueprints/destroy.d.ts +1 -0
  23. package/dist/cores/blueprints/destroy.js +22 -26
  24. package/dist/cores/blueprints/doctor.js +24 -72
  25. package/dist/cores/blueprints/info.d.ts +1 -0
  26. package/dist/cores/blueprints/info.js +5 -4
  27. package/dist/cores/blueprints/init.d.ts +1 -1
  28. package/dist/cores/blueprints/init.js +50 -78
  29. package/dist/cores/blueprints/logs.d.ts +1 -0
  30. package/dist/cores/blueprints/logs.js +7 -7
  31. package/dist/cores/blueprints/plan.d.ts +3 -0
  32. package/dist/cores/blueprints/plan.js +5 -4
  33. package/dist/cores/blueprints/stacks.d.ts +1 -0
  34. package/dist/cores/blueprints/stacks.js +1 -2
  35. package/dist/cores/functions/add.js +58 -70
  36. package/dist/cores/functions/logs.js +2 -4
  37. package/dist/cores/index.js +3 -3
  38. package/dist/server/static/vendor/vendor.bundle.js +515 -234
  39. package/dist/utils/display/blueprints-formatting.js +8 -3
  40. package/dist/utils/display/errors.js +2 -2
  41. package/dist/utils/display/presenters.d.ts +2 -0
  42. package/dist/utils/display/presenters.js +7 -0
  43. package/dist/utils/display/prompt.d.ts +14 -2
  44. package/dist/utils/display/prompt.js +60 -41
  45. package/dist/utils/types.d.ts +0 -1
  46. package/oclif.manifest.json +19 -26
  47. package/package.json +6 -5
@@ -765,6 +765,7 @@ class TreeNode extends BaseNode {
765
765
  get lastChild() { return this.nextChild(this._tree.children.length - 1, -1, 0, 4 /* Side.DontCare */); }
766
766
  childAfter(pos) { return this.nextChild(0, 1, pos, 2 /* Side.After */); }
767
767
  childBefore(pos) { return this.nextChild(this._tree.children.length - 1, -1, pos, -2 /* Side.Before */); }
768
+ prop(prop) { return this._tree.prop(prop); }
768
769
  enter(pos, side, mode = 0) {
769
770
  let mounted;
770
771
  if (!(mode & IterMode.IgnoreOverlays) && (mounted = MountedTree.get(this._tree)) && mounted.overlay) {
@@ -858,6 +859,7 @@ class BufferNode extends BaseNode {
858
859
  get lastChild() { return this.child(-1, 0, 4 /* Side.DontCare */); }
859
860
  childAfter(pos) { return this.child(1, pos, 2 /* Side.After */); }
860
861
  childBefore(pos) { return this.child(-1, pos, -2 /* Side.Before */); }
862
+ prop(prop) { return this.type.prop(prop); }
861
863
  enter(pos, side, mode = 0) {
862
864
  if (mode & IterMode.ExcludeBuffers)
863
865
  return null;
@@ -1439,7 +1441,7 @@ function buildTree(data) {
1439
1441
  fork.next();
1440
1442
  while (fork.pos > startPos) {
1441
1443
  if (fork.size < 0) {
1442
- if (fork.size == -3 /* SpecialRecord.ContextChange */)
1444
+ if (fork.size == -3 /* SpecialRecord.ContextChange */ || fork.size == -4 /* SpecialRecord.LookAhead */)
1443
1445
  localSkipped += 4;
1444
1446
  else
1445
1447
  break scan;
@@ -1828,9 +1830,7 @@ class Stack {
1828
1830
  var _a;
1829
1831
  let depth = action >> 19 /* Action.ReduceDepthShift */, type = action & 65535 /* Action.ValueMask */;
1830
1832
  let { parser } = this.p;
1831
- let lookaheadRecord = this.reducePos < this.pos - 25 /* Lookahead.Margin */;
1832
- if (lookaheadRecord)
1833
- this.setLookAhead(this.pos);
1833
+ let lookaheadRecord = this.reducePos < this.pos - 25 /* Lookahead.Margin */ && this.setLookAhead(this.pos);
1834
1834
  let dPrec = parser.dynamicPrecedence(type);
1835
1835
  if (dPrec)
1836
1836
  this.score += dPrec;
@@ -1908,7 +1908,7 @@ class Stack {
1908
1908
  }
1909
1909
  else { // There may be skipped nodes that have to be moved forward
1910
1910
  let index = this.buffer.length;
1911
- if (index > 0 && this.buffer[index - 4] != 0 /* Term.Err */) {
1911
+ if (index > 0 && (this.buffer[index - 4] != 0 /* Term.Err */ || this.buffer[index - 1] < 0)) {
1912
1912
  let mustMove = false;
1913
1913
  for (let scan = index; scan > 0 && this.buffer[scan - 2] > end; scan -= 4) {
1914
1914
  if (this.buffer[scan - 1] >= 0) {
@@ -2221,10 +2221,11 @@ class Stack {
2221
2221
  @internal
2222
2222
  */
2223
2223
  setLookAhead(lookAhead) {
2224
- if (lookAhead > this.lookAhead) {
2225
- this.emitLookAhead();
2226
- this.lookAhead = lookAhead;
2227
- }
2224
+ if (lookAhead <= this.lookAhead)
2225
+ return false;
2226
+ this.emitLookAhead();
2227
+ this.lookAhead = lookAhead;
2228
+ return true;
2228
2229
  }
2229
2230
  /**
2230
2231
  @internal
@@ -3132,7 +3133,7 @@ class Parse {
3132
3133
  continue;
3133
3134
  }
3134
3135
  let force = stack.split(), forceBase = base;
3135
- for (let j = 0; force.forceReduce() && j < 10 /* Rec.ForceReduceLimit */; j++) {
3136
+ for (let j = 0; j < 10 /* Rec.ForceReduceLimit */ && force.forceReduce(); j++) {
3136
3137
  if (verbose)
3137
3138
  console.log(forceBase + this.stackID(force) + " (via force-reduce)");
3138
3139
  let done = this.advanceFully(force, newStacks);
@@ -8685,6 +8686,63 @@ function keyName(event) {
8685
8686
  return name
8686
8687
  }
8687
8688
 
8689
+ function crelt() {
8690
+ var elt = arguments[0];
8691
+ if (typeof elt == "string") elt = document.createElement(elt);
8692
+ var i = 1, next = arguments[1];
8693
+ if (next && typeof next == "object" && next.nodeType == null && !Array.isArray(next)) {
8694
+ for (var name in next) if (Object.prototype.hasOwnProperty.call(next, name)) {
8695
+ var value = next[name];
8696
+ if (typeof value == "string") elt.setAttribute(name, value);
8697
+ else if (value != null) elt[name] = value;
8698
+ }
8699
+ i++;
8700
+ }
8701
+ for (; i < arguments.length; i++) add(elt, arguments[i]);
8702
+ return elt
8703
+ }
8704
+
8705
+ function add(elt, child) {
8706
+ if (typeof child == "string") {
8707
+ elt.appendChild(document.createTextNode(child));
8708
+ } else if (child == null) ; else if (child.nodeType != null) {
8709
+ elt.appendChild(child);
8710
+ } else if (Array.isArray(child)) {
8711
+ for (var i = 0; i < child.length; i++) add(elt, child[i]);
8712
+ } else {
8713
+ throw new RangeError("Unsupported child node: " + child)
8714
+ }
8715
+ }
8716
+
8717
+ let nav = typeof navigator != "undefined" ? navigator : { userAgent: "", vendor: "", platform: "" };
8718
+ let doc = typeof document != "undefined" ? document : { documentElement: { style: {} } };
8719
+ const ie_edge = /*@__PURE__*//Edge\/(\d+)/.exec(nav.userAgent);
8720
+ const ie_upto10 = /*@__PURE__*//MSIE \d/.test(nav.userAgent);
8721
+ const ie_11up = /*@__PURE__*//Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(nav.userAgent);
8722
+ const ie = !!(ie_upto10 || ie_11up || ie_edge);
8723
+ const gecko = !ie && /*@__PURE__*//gecko\/(\d+)/i.test(nav.userAgent);
8724
+ const chrome = !ie && /*@__PURE__*//Chrome\/(\d+)/.exec(nav.userAgent);
8725
+ const webkit = "webkitFontSmoothing" in doc.documentElement.style;
8726
+ const safari = !ie && /*@__PURE__*//Apple Computer/.test(nav.vendor);
8727
+ const ios = safari && (/*@__PURE__*//Mobile\/\w+/.test(nav.userAgent) || nav.maxTouchPoints > 2);
8728
+ var browser = {
8729
+ mac: ios || /*@__PURE__*//Mac/.test(nav.platform),
8730
+ windows: /*@__PURE__*//Win/.test(nav.platform),
8731
+ linux: /*@__PURE__*//Linux|X11/.test(nav.platform),
8732
+ ie,
8733
+ ie_version: ie_upto10 ? doc.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0,
8734
+ gecko,
8735
+ gecko_version: gecko ? +(/*@__PURE__*//Firefox\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
8736
+ chrome: !!chrome,
8737
+ chrome_version: chrome ? +chrome[1] : 0,
8738
+ ios,
8739
+ android: /*@__PURE__*//Android\b/.test(nav.userAgent),
8740
+ webkit_version: webkit ? +(/*@__PURE__*//\bAppleWebKit\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
8741
+ safari,
8742
+ safari_version: safari ? +(/*@__PURE__*//\bVersion\/(\d+(\.\d+)?)/.exec(nav.userAgent) || [0, 0])[1] : 0,
8743
+ tabSize: doc.documentElement.style.tabSize != null ? "tab-size" : "-moz-tab-size"
8744
+ };
8745
+
8688
8746
  function getSelection(root) {
8689
8747
  let target;
8690
8748
  // Browsers differ on whether shadow roots have a getSelection
@@ -8935,6 +8993,9 @@ class DOMSelectionState {
8935
8993
  }
8936
8994
  }
8937
8995
  let preventScrollSupported = null;
8996
+ // Safari 26 breaks preventScroll support
8997
+ if (browser.safari && browser.safari_version >= 26)
8998
+ preventScrollSupported = false;
8938
8999
  // Feature-detects support for .focus({preventScroll: true}), and uses
8939
9000
  // a fallback kludge when not supported.
8940
9001
  function focusPreventScroll(dom) {
@@ -9404,34 +9465,6 @@ function mergeChildrenInto(parent, from, to, insert, openStart, openEnd) {
9404
9465
  replaceRange(parent, fromI, fromOff, toI, toOff, insert, 0, openStart, openEnd);
9405
9466
  }
9406
9467
 
9407
- let nav = typeof navigator != "undefined" ? navigator : { userAgent: "", vendor: "", platform: "" };
9408
- let doc = typeof document != "undefined" ? document : { documentElement: { style: {} } };
9409
- const ie_edge = /*@__PURE__*//Edge\/(\d+)/.exec(nav.userAgent);
9410
- const ie_upto10 = /*@__PURE__*//MSIE \d/.test(nav.userAgent);
9411
- const ie_11up = /*@__PURE__*//Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(nav.userAgent);
9412
- const ie = !!(ie_upto10 || ie_11up || ie_edge);
9413
- const gecko = !ie && /*@__PURE__*//gecko\/(\d+)/i.test(nav.userAgent);
9414
- const chrome = !ie && /*@__PURE__*//Chrome\/(\d+)/.exec(nav.userAgent);
9415
- const webkit = "webkitFontSmoothing" in doc.documentElement.style;
9416
- const safari = !ie && /*@__PURE__*//Apple Computer/.test(nav.vendor);
9417
- const ios = safari && (/*@__PURE__*//Mobile\/\w+/.test(nav.userAgent) || nav.maxTouchPoints > 2);
9418
- var browser = {
9419
- mac: ios || /*@__PURE__*//Mac/.test(nav.platform),
9420
- windows: /*@__PURE__*//Win/.test(nav.platform),
9421
- linux: /*@__PURE__*//Linux|X11/.test(nav.platform),
9422
- ie,
9423
- ie_version: ie_upto10 ? doc.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0,
9424
- gecko,
9425
- gecko_version: gecko ? +(/*@__PURE__*//Firefox\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
9426
- chrome: !!chrome,
9427
- chrome_version: chrome ? +chrome[1] : 0,
9428
- ios,
9429
- android: /*@__PURE__*//Android\b/.test(nav.userAgent),
9430
- safari,
9431
- webkit_version: webkit ? +(/*@__PURE__*//\bAppleWebKit\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
9432
- tabSize: doc.documentElement.style.tabSize != null ? "tab-size" : "-moz-tab-size"
9433
- };
9434
-
9435
9468
  const MaxJoinLen = 256;
9436
9469
  class TextView extends ContentView {
9437
9470
  constructor(text) {
@@ -10464,13 +10497,14 @@ class ContentBuilder {
10464
10497
  this.textOff = 0;
10465
10498
  }
10466
10499
  }
10467
- let take = Math.min(this.text.length - this.textOff, length, 512 /* T.Chunk */);
10500
+ let remaining = Math.min(this.text.length - this.textOff, length);
10501
+ let take = Math.min(remaining, 512 /* T.Chunk */);
10468
10502
  this.flushBuffer(active.slice(active.length - openStart));
10469
10503
  this.getLine().append(wrapMarks(new TextView(this.text.slice(this.textOff, this.textOff + take)), active), openStart);
10470
10504
  this.atCursorPos = true;
10471
10505
  this.textOff += take;
10472
10506
  length -= take;
10473
- openStart = 0;
10507
+ openStart = remaining <= take ? 0 : active.length;
10474
10508
  }
10475
10509
  }
10476
10510
  span(from, to, active, openStart) {
@@ -11100,8 +11134,7 @@ function logException(state, exception, context) {
11100
11134
  let handler = state.facet(exceptionSink);
11101
11135
  if (handler.length)
11102
11136
  handler[0](exception);
11103
- else if (window.onerror)
11104
- window.onerror(String(exception), context, undefined, undefined, exception);
11137
+ else if (window.onerror && window.onerror(String(exception), context, undefined, undefined, exception)) ;
11105
11138
  else if (context)
11106
11139
  console.error(context + ":", exception);
11107
11140
  else
@@ -11109,11 +11142,23 @@ function logException(state, exception, context) {
11109
11142
  }
11110
11143
  const editable = /*@__PURE__*/Facet.define({ combine: values => values.length ? values[0] : true });
11111
11144
  let nextPluginID = 0;
11112
- const viewPlugin = /*@__PURE__*/Facet.define();
11145
+ const viewPlugin = /*@__PURE__*/Facet.define({
11146
+ combine(plugins) {
11147
+ return plugins.filter((p, i) => {
11148
+ for (let j = 0; j < i; j++)
11149
+ if (plugins[j].plugin == p.plugin)
11150
+ return false;
11151
+ return true;
11152
+ });
11153
+ }
11154
+ });
11113
11155
  /**
11114
11156
  View plugins associate stateful values with a view. They can
11115
11157
  influence the way the content is drawn, and are notified of things
11116
- that happen in the view.
11158
+ that happen in the view. They optionally take an argument, in
11159
+ which case you need to call [`of`](https://codemirror.net/6/docs/ref/#view.ViewPlugin.of) to create
11160
+ an extension for the plugin. When the argument type is undefined,
11161
+ you can use the plugin instance as an extension directly.
11117
11162
  */
11118
11163
  class ViewPlugin {
11119
11164
  constructor(
@@ -11137,7 +11182,14 @@ class ViewPlugin {
11137
11182
  this.create = create;
11138
11183
  this.domEventHandlers = domEventHandlers;
11139
11184
  this.domEventObservers = domEventObservers;
11140
- this.extension = buildExtensions(this);
11185
+ this.baseExtensions = buildExtensions(this);
11186
+ this.extension = this.baseExtensions.concat(viewPlugin.of({ plugin: this, arg: undefined }));
11187
+ }
11188
+ /**
11189
+ Create an extension for this plugin with the given argument.
11190
+ */
11191
+ of(arg) {
11192
+ return this.baseExtensions.concat(viewPlugin.of({ plugin: this, arg }));
11141
11193
  }
11142
11194
  /**
11143
11195
  Define a plugin from a constructor function that creates the
@@ -11146,7 +11198,7 @@ class ViewPlugin {
11146
11198
  static define(create, spec) {
11147
11199
  const { eventHandlers, eventObservers, provide, decorations: deco } = spec || {};
11148
11200
  return new ViewPlugin(nextPluginID++, create, eventHandlers, eventObservers, plugin => {
11149
- let ext = [viewPlugin.of(plugin)];
11201
+ let ext = [];
11150
11202
  if (deco)
11151
11203
  ext.push(decorations.of(view => {
11152
11204
  let pluginInst = view.plugin(plugin);
@@ -11162,7 +11214,7 @@ class ViewPlugin {
11162
11214
  editor view as argument.
11163
11215
  */
11164
11216
  static fromClass(cls, spec) {
11165
- return ViewPlugin.define(view => new cls(view), spec);
11217
+ return ViewPlugin.define((view, arg) => new cls(view, arg), spec);
11166
11218
  }
11167
11219
  }
11168
11220
  class PluginInstance {
@@ -11170,18 +11222,19 @@ class PluginInstance {
11170
11222
  this.spec = spec;
11171
11223
  // When starting an update, all plugins have this field set to the
11172
11224
  // update object, indicating they need to be updated. When finished
11173
- // updating, it is set to `false`. Retrieving a plugin that needs to
11225
+ // updating, it is set to `null`. Retrieving a plugin that needs to
11174
11226
  // be updated with `view.plugin` forces an eager update.
11175
11227
  this.mustUpdate = null;
11176
11228
  // This is null when the plugin is initially created, but
11177
11229
  // initialized on the first update.
11178
11230
  this.value = null;
11179
11231
  }
11232
+ get plugin() { return this.spec && this.spec.plugin; }
11180
11233
  update(view) {
11181
11234
  if (!this.value) {
11182
11235
  if (this.spec) {
11183
11236
  try {
11184
- this.value = this.spec.create(view);
11237
+ this.value = this.spec.plugin.create(view, this.spec.arg);
11185
11238
  }
11186
11239
  catch (e) {
11187
11240
  logException(view.state, e, "CodeMirror plugin crashed");
@@ -11977,6 +12030,13 @@ class DocView extends ContentView {
11977
12030
  let { offsetWidth, offsetHeight } = this.view.scrollDOM;
11978
12031
  scrollRectIntoView(this.view.scrollDOM, targetRect, range.head < range.anchor ? -1 : 1, target.x, target.y, Math.max(Math.min(target.xMargin, offsetWidth), -offsetWidth), Math.max(Math.min(target.yMargin, offsetHeight), -offsetHeight), this.view.textDirection == Direction.LTR);
11979
12032
  }
12033
+ lineHasWidget(pos) {
12034
+ let { i } = this.childCursor().findPos(pos);
12035
+ if (i == this.children.length)
12036
+ return false;
12037
+ let scan = (child) => child instanceof WidgetView || child.children.some(scan);
12038
+ return scan(this.children[i]);
12039
+ }
11980
12040
  }
11981
12041
  function betweenUneditable(pos) {
11982
12042
  return pos.node.nodeType == 1 && pos.node.firstChild &&
@@ -12137,8 +12197,7 @@ function domPosAtCoords(parent, x, y) {
12137
12197
  closestRect = rect;
12138
12198
  closestX = dx;
12139
12199
  closestY = dy;
12140
- let side = dy ? (y < rect.top ? -1 : 1) : dx ? (x < rect.left ? -1 : 1) : 0;
12141
- closestOverlap = !side || (side > 0 ? i < rects.length - 1 : i > 0);
12200
+ closestOverlap = !dx ? true : x < rect.left ? i > 0 : i < rects.length - 1;
12142
12201
  }
12143
12202
  if (dx == 0) {
12144
12203
  if (y > rect.bottom && (!aboveRect || aboveRect.bottom < rect.bottom)) {
@@ -12195,7 +12254,7 @@ function domPosInText(node, x, y) {
12195
12254
  // Check for RTL on browsers that support getting client
12196
12255
  // rects for empty ranges.
12197
12256
  let rectBefore = textRange(node, i).getBoundingClientRect();
12198
- if (rectBefore.left == rect.right)
12257
+ if (Math.abs(rectBefore.left - rect.right) < 0.1)
12199
12258
  after = !right;
12200
12259
  }
12201
12260
  if (dy <= 0)
@@ -12266,14 +12325,13 @@ function posAtCoords(view, coords, precise, bias = -1) {
12266
12325
  }
12267
12326
  else if (doc.caretRangeFromPoint) {
12268
12327
  let range = doc.caretRangeFromPoint(x, y);
12269
- if (range) {
12328
+ if (range)
12270
12329
  ({ startContainer: node, startOffset: offset } = range);
12271
- if (!view.contentDOM.contains(node) ||
12272
- browser.safari && isSuspiciousSafariCaretResult(node, offset, x) ||
12273
- browser.chrome && isSuspiciousChromeCaretResult(node, offset, x))
12274
- node = undefined;
12275
- }
12276
12330
  }
12331
+ if (node && (!view.contentDOM.contains(node) ||
12332
+ browser.safari && isSuspiciousSafariCaretResult(node, offset, x) ||
12333
+ browser.chrome && isSuspiciousChromeCaretResult(node, offset, x)))
12334
+ node = undefined;
12277
12335
  // Chrome will return offsets into <input> elements without child
12278
12336
  // nodes, which will lead to a null deref below, so clip the
12279
12337
  // offset to the node size.
@@ -12309,23 +12367,37 @@ function posAtCoordsImprecise(view, contentRect, block, x, y) {
12309
12367
  let content = view.state.sliceDoc(block.from, block.to);
12310
12368
  return block.from + findColumn(content, into, view.state.tabSize);
12311
12369
  }
12370
+ function isEndOfLineBefore(node, offset, x) {
12371
+ let len, scan = node;
12372
+ if (node.nodeType != 3 || offset != (len = node.nodeValue.length))
12373
+ return false;
12374
+ for (;;) { // Check that there is no content after this node
12375
+ let next = scan.nextSibling;
12376
+ if (next) {
12377
+ if (next.nodeName == "BR")
12378
+ break;
12379
+ return false;
12380
+ }
12381
+ else {
12382
+ let parent = scan.parentNode;
12383
+ if (!parent || parent.nodeName == "DIV")
12384
+ break;
12385
+ scan = parent;
12386
+ }
12387
+ }
12388
+ return textRange(node, len - 1, len).getBoundingClientRect().right > x;
12389
+ }
12312
12390
  // In case of a high line height, Safari's caretRangeFromPoint treats
12313
12391
  // the space between lines as belonging to the last character of the
12314
12392
  // line before. This is used to detect such a result so that it can be
12315
12393
  // ignored (issue #401).
12316
12394
  function isSuspiciousSafariCaretResult(node, offset, x) {
12317
- let len;
12318
- if (node.nodeType != 3 || offset != (len = node.nodeValue.length))
12319
- return false;
12320
- for (let next = node.nextSibling; next; next = next.nextSibling)
12321
- if (next.nodeType != 1 || next.nodeName != "BR")
12322
- return false;
12323
- return textRange(node, len - 1, len).getBoundingClientRect().left > x;
12395
+ return isEndOfLineBefore(node, offset, x);
12324
12396
  }
12325
12397
  // Chrome will move positions between lines to the start of the next line
12326
12398
  function isSuspiciousChromeCaretResult(node, offset, x) {
12327
12399
  if (offset != 0)
12328
- return false;
12400
+ return isEndOfLineBefore(node, offset, x);
12329
12401
  for (let cur = node;;) {
12330
12402
  let parent = cur.parentNode;
12331
12403
  if (!parent || parent.nodeType != 1 || parent.firstChild != cur)
@@ -12450,6 +12522,29 @@ function skipAtomicRanges(atoms, pos, bias) {
12450
12522
  return pos;
12451
12523
  }
12452
12524
  }
12525
+ function skipAtomsForSelection(atoms, sel) {
12526
+ let ranges = null;
12527
+ for (let i = 0; i < sel.ranges.length; i++) {
12528
+ let range = sel.ranges[i], updated = null;
12529
+ if (range.empty) {
12530
+ let pos = skipAtomicRanges(atoms, range.from, 0);
12531
+ if (pos != range.from)
12532
+ updated = EditorSelection.cursor(pos, -1);
12533
+ }
12534
+ else {
12535
+ let from = skipAtomicRanges(atoms, range.from, -1);
12536
+ let to = skipAtomicRanges(atoms, range.to, 1);
12537
+ if (from != range.from || to != range.to)
12538
+ updated = EditorSelection.range(range.from == range.anchor ? from : to, range.from == range.head ? from : to);
12539
+ }
12540
+ if (updated) {
12541
+ if (!ranges)
12542
+ ranges = sel.ranges.slice();
12543
+ ranges[i] = updated;
12544
+ }
12545
+ }
12546
+ return ranges ? EditorSelection.create(ranges, sel.mainIndex) : sel;
12547
+ }
12453
12548
  function skipAtoms(view, oldPos, pos) {
12454
12549
  let newPos = skipAtomicRanges(view.state.facet(atomicRanges).map(f => f(view)), pos.from, oldPos.head > pos.from ? -1 : 1);
12455
12550
  return newPos == pos.from ? pos : EditorSelection.cursor(newPos, newPos < pos.from ? 1 : -1);
@@ -12480,9 +12575,10 @@ class DOMReader {
12480
12575
  if (next == end)
12481
12576
  break;
12482
12577
  let view = ContentView.get(cur), nextView = ContentView.get(next);
12483
- if (view && nextView ? view.breakAfter :
12578
+ if ((view && nextView ? view.breakAfter :
12484
12579
  (view ? view.breakAfter : isBlockElement(cur)) ||
12485
- (isBlockElement(next) && (cur.nodeName != "BR" || cur.cmIgnore) && this.text.length > oldLen))
12580
+ (isBlockElement(next) && (cur.nodeName != "BR" || cur.cmIgnore) && this.text.length > oldLen)) &&
12581
+ !isEmptyToEnd(next, end))
12486
12582
  this.lineBreak();
12487
12583
  cur = next;
12488
12584
  }
@@ -12561,6 +12657,25 @@ function isAtEnd(parent, node, offset) {
12561
12657
  node = node.parentNode;
12562
12658
  }
12563
12659
  }
12660
+ function isEmptyToEnd(node, end) {
12661
+ let widgets;
12662
+ for (;; node = node.nextSibling) {
12663
+ if (node == end || !node)
12664
+ break;
12665
+ let view = ContentView.get(node);
12666
+ if (!((view === null || view === void 0 ? void 0 : view.isWidget) || node.cmIgnore))
12667
+ return false;
12668
+ if (view)
12669
+ (widgets || (widgets = [])).push(view);
12670
+ }
12671
+ if (widgets)
12672
+ for (let w of widgets) {
12673
+ let override = w.overrideDOMText;
12674
+ if (override === null || override === void 0 ? void 0 : override.length)
12675
+ return false;
12676
+ }
12677
+ return true;
12678
+ }
12564
12679
  class DOMPoint {
12565
12680
  constructor(node, offset) {
12566
12681
  this.node = node;
@@ -12611,7 +12726,10 @@ class DOMChange {
12611
12726
  anchor = view.state.doc.length;
12612
12727
  }
12613
12728
  }
12614
- this.newSel = EditorSelection.single(anchor, head);
12729
+ if (view.inputState.composing > -1 && view.state.selection.ranges.length > 1)
12730
+ this.newSel = view.state.selection.replaceRange(EditorSelection.range(anchor, head));
12731
+ else
12732
+ this.newSel = EditorSelection.single(anchor, head);
12615
12733
  }
12616
12734
  }
12617
12735
  }
@@ -12667,6 +12785,18 @@ function applyDOMChange(view, domChange) {
12667
12785
  insert: view.state.doc.slice(sel.from, change.from).append(change.insert).append(view.state.doc.slice(change.to, sel.to))
12668
12786
  };
12669
12787
  }
12788
+ else if (view.state.doc.lineAt(sel.from).to < sel.to && view.docView.lineHasWidget(sel.to) &&
12789
+ view.inputState.insertingTextAt > Date.now() - 50) {
12790
+ // For a cross-line insertion, Chrome and Safari will crudely take
12791
+ // the text of the line after the selection, flattening any
12792
+ // widgets, and move it into the joined line. This tries to detect
12793
+ // such a situation, and replaces the change with a selection
12794
+ // replace of the text provided by the beforeinput event.
12795
+ change = {
12796
+ from: sel.from, to: sel.to,
12797
+ insert: view.state.toText(view.inputState.insertingText)
12798
+ };
12799
+ }
12670
12800
  else if (browser.chrome && change && change.from == change.to && change.from == sel.head &&
12671
12801
  change.insert.toString() == "\n " && view.lineWrapping) {
12672
12802
  // In Chrome, if you insert a space at the start of a wrapped
@@ -12685,6 +12815,8 @@ function applyDOMChange(view, domChange) {
12685
12815
  if (view.inputState.lastSelectionOrigin == "select")
12686
12816
  scrollIntoView = true;
12687
12817
  userEvent = view.inputState.lastSelectionOrigin;
12818
+ if (userEvent == "select.pointer")
12819
+ newSel = skipAtomsForSelection(view.state.facet(atomicRanges).map(f => f(view)), newSel);
12688
12820
  }
12689
12821
  view.dispatch({ selection: newSel, scrollIntoView, userEvent });
12690
12822
  return true;
@@ -12726,8 +12858,20 @@ function applyDOMChangeInner(view, change, newSel, lastKey = -1) {
12726
12858
  return true;
12727
12859
  }
12728
12860
  function applyDefaultInsert(view, change, newSel) {
12729
- let tr, startState = view.state, sel = startState.selection.main;
12730
- if (change.from >= sel.from && change.to <= sel.to && change.to - change.from >= (sel.to - sel.from) / 3 &&
12861
+ let tr, startState = view.state, sel = startState.selection.main, inAtomic = -1;
12862
+ if (change.from == change.to && change.from < sel.from || change.from > sel.to) {
12863
+ let side = change.from < sel.from ? -1 : 1, pos = side < 0 ? sel.from : sel.to;
12864
+ let moved = skipAtomicRanges(startState.facet(atomicRanges).map(f => f(view)), pos, side);
12865
+ if (change.from == moved)
12866
+ inAtomic = moved;
12867
+ }
12868
+ if (inAtomic > -1) {
12869
+ tr = {
12870
+ changes: change,
12871
+ selection: EditorSelection.cursor(change.from + change.insert.length, -1)
12872
+ };
12873
+ }
12874
+ else if (change.from >= sel.from && change.to <= sel.to && change.to - change.from >= (sel.to - sel.from) / 3 &&
12731
12875
  (!newSel || newSel.main.empty && newSel.main.from == change.from + change.insert.length) &&
12732
12876
  view.inputState.composing < 0) {
12733
12877
  let before = sel.from < change.from ? startState.sliceDoc(sel.from, change.from) : "";
@@ -12738,8 +12882,8 @@ function applyDefaultInsert(view, change, newSel) {
12738
12882
  let changes = startState.changes(change);
12739
12883
  let mainSel = newSel && newSel.main.to <= changes.newLength ? newSel.main : undefined;
12740
12884
  // Try to apply a composition change to all cursors
12741
- if (startState.selection.ranges.length > 1 && view.inputState.composing >= 0 &&
12742
- change.to <= sel.to && change.to >= sel.to - 10) {
12885
+ if (startState.selection.ranges.length > 1 && (view.inputState.composing >= 0 || view.inputState.compositionPendingChange) &&
12886
+ change.to <= sel.to + 10 && change.to >= sel.to - 10) {
12743
12887
  let replaced = view.state.sliceDoc(change.from, change.to);
12744
12888
  let compositionRange, composition = newSel && findCompositionNode(view, newSel.main.head);
12745
12889
  if (composition) {
@@ -12749,17 +12893,17 @@ function applyDefaultInsert(view, change, newSel) {
12749
12893
  else {
12750
12894
  compositionRange = view.state.doc.lineAt(sel.head);
12751
12895
  }
12752
- let offset = sel.to - change.to, size = sel.to - sel.from;
12896
+ let offset = sel.to - change.to;
12753
12897
  tr = startState.changeByRange(range => {
12754
12898
  if (range.from == sel.from && range.to == sel.to)
12755
12899
  return { changes, range: mainSel || range.map(changes) };
12756
12900
  let to = range.to - offset, from = to - replaced.length;
12757
- if (range.to - range.from != size || view.state.sliceDoc(from, to) != replaced ||
12901
+ if (view.state.sliceDoc(from, to) != replaced ||
12758
12902
  // Unfortunately, there's no way to make multiple
12759
12903
  // changes in the same node work without aborting
12760
12904
  // composition, so cursors in the composition range are
12761
12905
  // ignored.
12762
- range.to >= compositionRange.from && range.from <= compositionRange.to)
12906
+ to >= compositionRange.from && from <= compositionRange.to)
12763
12907
  return { range };
12764
12908
  let rangeChanges = startState.changes({ from, to, insert: change.insert }), selOff = range.to - sel.to;
12765
12909
  return {
@@ -12886,6 +13030,9 @@ class InputState {
12886
13030
  // Used to categorize changes as part of a composition, even when
12887
13031
  // the mutation events fire shortly after the compositionend event
12888
13032
  this.compositionPendingChange = false;
13033
+ // Set by beforeinput, used in DOM change reader
13034
+ this.insertingText = "";
13035
+ this.insertingTextAt = 0;
12889
13036
  this.mouseSelection = null;
12890
13037
  // When a drag from the editor is active, this points at the range
12891
13038
  // being dragged.
@@ -12988,7 +13135,7 @@ class InputState {
12988
13135
  return dispatchKey(this.view.contentDOM, key.key, key.keyCode, key instanceof KeyboardEvent ? key : undefined);
12989
13136
  }
12990
13137
  ignoreDuringComposition(event) {
12991
- if (!/^key/.test(event.type))
13138
+ if (!/^key/.test(event.type) || event.synthetic)
12992
13139
  return false;
12993
13140
  if (this.composing > 0)
12994
13141
  return true;
@@ -13039,16 +13186,16 @@ function computeHandlers(plugins) {
13039
13186
  return result[type] || (result[type] = { observers: [], handlers: [] });
13040
13187
  }
13041
13188
  for (let plugin of plugins) {
13042
- let spec = plugin.spec;
13043
- if (spec && spec.domEventHandlers)
13044
- for (let type in spec.domEventHandlers) {
13045
- let f = spec.domEventHandlers[type];
13189
+ let spec = plugin.spec, handlers = spec && spec.plugin.domEventHandlers, observers = spec && spec.plugin.domEventObservers;
13190
+ if (handlers)
13191
+ for (let type in handlers) {
13192
+ let f = handlers[type];
13046
13193
  if (f)
13047
13194
  record(type).handlers.push(bindHandler(plugin.value, f));
13048
13195
  }
13049
- if (spec && spec.domEventObservers)
13050
- for (let type in spec.domEventObservers) {
13051
- let f = spec.domEventObservers[type];
13196
+ if (observers)
13197
+ for (let type in observers) {
13198
+ let f = observers[type];
13052
13199
  if (f)
13053
13200
  record(type).observers.push(bindHandler(plugin.value, f));
13054
13201
  }
@@ -13162,31 +13309,8 @@ class MouseSelection {
13162
13309
  if (this.dragging === false)
13163
13310
  this.select(this.lastEvent);
13164
13311
  }
13165
- skipAtoms(sel) {
13166
- let ranges = null;
13167
- for (let i = 0; i < sel.ranges.length; i++) {
13168
- let range = sel.ranges[i], updated = null;
13169
- if (range.empty) {
13170
- let pos = skipAtomicRanges(this.atoms, range.from, 0);
13171
- if (pos != range.from)
13172
- updated = EditorSelection.cursor(pos, -1);
13173
- }
13174
- else {
13175
- let from = skipAtomicRanges(this.atoms, range.from, -1);
13176
- let to = skipAtomicRanges(this.atoms, range.to, 1);
13177
- if (from != range.from || to != range.to)
13178
- updated = EditorSelection.range(range.from == range.anchor ? from : to, range.from == range.head ? from : to);
13179
- }
13180
- if (updated) {
13181
- if (!ranges)
13182
- ranges = sel.ranges.slice();
13183
- ranges[i] = updated;
13184
- }
13185
- }
13186
- return ranges ? EditorSelection.create(ranges, sel.mainIndex) : sel;
13187
- }
13188
13312
  select(event) {
13189
- let { view } = this, selection = this.skipAtoms(this.style.get(event, this.extend, this.multiple));
13313
+ let { view } = this, selection = skipAtomsForSelection(this.atoms, this.style.get(event, this.extend, this.multiple));
13190
13314
  if (this.mustSelect || !selection.eq(view.state.selection, this.dragging === false))
13191
13315
  this.view.dispatch({
13192
13316
  selection,
@@ -13339,6 +13463,9 @@ handlers.mousedown = (view, event) => {
13339
13463
  return mouseSel.dragging === false;
13340
13464
  }
13341
13465
  }
13466
+ else {
13467
+ view.inputState.setSelectionOrigin("select.pointer");
13468
+ }
13342
13469
  return false;
13343
13470
  };
13344
13471
  function rangeForClick(view, pos, bias, type) {
@@ -13660,6 +13787,10 @@ observers.contextmenu = view => {
13660
13787
  };
13661
13788
  handlers.beforeinput = (view, event) => {
13662
13789
  var _a, _b;
13790
+ if (event.inputType == "insertText" || event.inputType == "insertCompositionText") {
13791
+ view.inputState.insertingText = event.data;
13792
+ view.inputState.insertingTextAt = Date.now();
13793
+ }
13663
13794
  // In EditContext mode, we must handle insertReplacementText events
13664
13795
  // directly, to make spell checking corrections work
13665
13796
  if (event.inputType == "insertReplacementText" && view.observer.editContext) {
@@ -13743,7 +13874,7 @@ class HeightOracle {
13743
13874
  heightForLine(length) {
13744
13875
  if (!this.lineWrapping)
13745
13876
  return this.lineHeight;
13746
- let lines = 1 + Math.max(0, Math.ceil((length - this.lineLength) / (this.lineLength - 5)));
13877
+ let lines = 1 + Math.max(0, Math.ceil((length - this.lineLength) / Math.max(1, this.lineLength - 5)));
13747
13878
  return lines * this.lineHeight;
13748
13879
  }
13749
13880
  setDoc(doc) { this.doc = doc; return this; }
@@ -14713,7 +14844,7 @@ class ViewState {
14713
14844
  refresh = true;
14714
14845
  if (refresh || oracle.lineWrapping && Math.abs(contentWidth - this.contentDOMWidth) > oracle.charWidth) {
14715
14846
  let { lineHeight, charWidth, textHeight } = view.docView.measureTextSize();
14716
- refresh = lineHeight > 0 && oracle.refresh(whiteSpace, lineHeight, charWidth, textHeight, contentWidth / charWidth, lineHeights);
14847
+ refresh = lineHeight > 0 && oracle.refresh(whiteSpace, lineHeight, charWidth, textHeight, Math.max(5, contentWidth / charWidth), lineHeights);
14717
14848
  if (refresh) {
14718
14849
  view.docView.minWidth = 0;
14719
14850
  result |= 16 /* UpdateFlag.Geometry */;
@@ -15238,13 +15369,16 @@ const baseTheme$1$3 = /*@__PURE__*/buildTheme("." + baseThemeID, {
15238
15369
  display: "flex",
15239
15370
  height: "100%",
15240
15371
  boxSizing: "border-box",
15241
- insetInlineStart: 0,
15242
- zIndex: 200
15372
+ zIndex: 200,
15243
15373
  },
15374
+ ".cm-gutters-before": { insetInlineStart: 0 },
15375
+ ".cm-gutters-after": { insetInlineEnd: 0 },
15244
15376
  "&light .cm-gutters": {
15245
15377
  backgroundColor: "#f5f5f5",
15246
15378
  color: "#6c6c6c",
15247
- borderRight: "1px solid #ddd"
15379
+ border: "0px solid #ddd",
15380
+ "&.cm-gutters-before": { borderRightWidth: "1px" },
15381
+ "&.cm-gutters-after": { borderLeftWidth: "1px" },
15248
15382
  },
15249
15383
  "&dark .cm-gutters": {
15250
15384
  backgroundColor: "#333338",
@@ -15294,6 +15428,21 @@ const baseTheme$1$3 = /*@__PURE__*/buildTheme("." + baseThemeID, {
15294
15428
  backgroundColor: "#333338",
15295
15429
  color: "white"
15296
15430
  },
15431
+ ".cm-dialog": {
15432
+ padding: "2px 19px 4px 6px",
15433
+ position: "relative",
15434
+ "& label": { fontSize: "80%" },
15435
+ },
15436
+ ".cm-dialog-close": {
15437
+ position: "absolute",
15438
+ top: "3px",
15439
+ right: "4px",
15440
+ backgroundColor: "inherit",
15441
+ border: "none",
15442
+ font: "inherit",
15443
+ fontSize: "14px",
15444
+ padding: "0"
15445
+ },
15297
15446
  ".cm-tab": {
15298
15447
  display: "inline-block",
15299
15448
  overflow: "hidden",
@@ -15420,7 +15569,7 @@ class DOMObserver {
15420
15569
  else
15421
15570
  this.flush();
15422
15571
  });
15423
- if (window.EditContext && view.constructor.EDIT_CONTEXT !== false &&
15572
+ if (window.EditContext && browser.android && view.constructor.EDIT_CONTEXT !== false &&
15424
15573
  // Chrome <126 doesn't support inverted selections in edit context (#1392)
15425
15574
  !(browser.chrome && browser.chrome_version < 126)) {
15426
15575
  this.editContext = new EditContextManager(view);
@@ -15894,20 +16043,23 @@ class EditContextManager {
15894
16043
  let from = this.toEditorPos(e.updateRangeStart), to = this.toEditorPos(e.updateRangeEnd);
15895
16044
  if (view.inputState.composing >= 0 && !this.composing)
15896
16045
  this.composing = { contextBase: e.updateRangeStart, editorBase: from, drifted: false };
15897
- let change = { from, to, insert: Text.of(e.text.split("\n")) };
16046
+ let deletes = to - from > e.text.length;
15898
16047
  // If the window doesn't include the anchor, assume changes
15899
16048
  // adjacent to a side go up to the anchor.
15900
- if (change.from == this.from && anchor < this.from)
15901
- change.from = anchor;
15902
- else if (change.to == this.to && anchor > this.to)
15903
- change.to = anchor;
16049
+ if (from == this.from && anchor < this.from)
16050
+ from = anchor;
16051
+ else if (to == this.to && anchor > this.to)
16052
+ to = anchor;
16053
+ let diff = findDiff(view.state.sliceDoc(from, to), e.text, (deletes ? main.from : main.to) - from, deletes ? "end" : null);
15904
16054
  // Edit contexts sometimes fire empty changes
15905
- if (change.from == change.to && !change.insert.length) {
16055
+ if (!diff) {
15906
16056
  let newSel = EditorSelection.single(this.toEditorPos(e.selectionStart), this.toEditorPos(e.selectionEnd));
15907
16057
  if (!newSel.main.eq(main))
15908
16058
  view.dispatch({ selection: newSel, userEvent: "select" });
15909
16059
  return;
15910
16060
  }
16061
+ let change = { from: diff.from + from, to: diff.toA + from,
16062
+ insert: Text.of(e.text.slice(diff.from, diff.toB).split("\n")) };
15911
16063
  if ((browser.mac || browser.android) && change.from == head - 1 &&
15912
16064
  /^\. ?$/.test(e.text) && view.contentDOM.getAttribute("autocorrect") == "off")
15913
16065
  change = { from, to, insert: Text.of([e.text.replace(".", " ")]) };
@@ -15922,6 +16074,10 @@ class EditContextManager {
15922
16074
  this.revertPending(view.state);
15923
16075
  this.setSelection(view.state);
15924
16076
  }
16077
+ // Work around missed compositionend events. See https://discuss.codemirror.net/t/a/9514
16078
+ if (change.from < change.to && !change.insert.length && view.inputState.composing >= 0 &&
16079
+ !/[\\p{Alphabetic}\\p{Number}_]/.test(context.text.slice(Math.max(0, e.updateRangeStart - 1), Math.min(context.text.length, e.updateRangeStart + 1))))
16080
+ this.handlers.compositionend(e);
15925
16081
  };
15926
16082
  this.handlers.characterboundsupdate = e => {
15927
16083
  let rects = [], prev = null;
@@ -15937,10 +16093,11 @@ class EditContextManager {
15937
16093
  let deco = [];
15938
16094
  for (let format of e.getTextFormats()) {
15939
16095
  let lineStyle = format.underlineStyle, thickness = format.underlineThickness;
15940
- if (lineStyle != "None" && thickness != "None") {
16096
+ if (!/none/i.test(lineStyle) && !/none/i.test(thickness)) {
15941
16097
  let from = this.toEditorPos(format.rangeStart), to = this.toEditorPos(format.rangeEnd);
15942
16098
  if (from < to) {
15943
- let style = `text-decoration: underline ${lineStyle == "Dashed" ? "dashed " : lineStyle == "Squiggle" ? "wavy " : ""}${thickness == "Thin" ? 1 : 2}px`;
16099
+ // These values changed from capitalized custom strings to lower-case CSS keywords in 2025
16100
+ let style = `text-decoration: underline ${/^[a-z]/.test(lineStyle) ? lineStyle + " " : lineStyle == "Dashed" ? "dashed " : lineStyle == "Squiggle" ? "wavy " : ""}${/thin/i.test(thickness) ? 1 : 2}px`;
15944
16101
  deco.push(Decoration.mark({ attributes: { style } }).range(from, to));
15945
16102
  }
15946
16103
  }
@@ -16606,8 +16763,8 @@ class EditorView {
16606
16763
  */
16607
16764
  plugin(plugin) {
16608
16765
  let known = this.pluginMap.get(plugin);
16609
- if (known === undefined || known && known.spec != plugin)
16610
- this.pluginMap.set(plugin, known = this.plugins.find(p => p.spec == plugin) || null);
16766
+ if (known === undefined || known && known.plugin != plugin)
16767
+ this.pluginMap.set(plugin, known = this.plugins.find(p => p.plugin == plugin) || null);
16611
16768
  return known && known.update(this).value;
16612
16769
  }
16613
16770
  /**
@@ -16645,7 +16802,7 @@ class EditorView {
16645
16802
  }
16646
16803
  /**
16647
16804
  Find the line block (see
16648
- [`lineBlockAt`](https://codemirror.net/6/docs/ref/#view.EditorView.lineBlockAt) at the given
16805
+ [`lineBlockAt`](https://codemirror.net/6/docs/ref/#view.EditorView.lineBlockAt)) at the given
16649
16806
  height, again interpreted relative to the [top of the
16650
16807
  document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop).
16651
16808
  */
@@ -17139,7 +17296,7 @@ Facet that works much like
17139
17296
  [`decorations`](https://codemirror.net/6/docs/ref/#view.EditorView^decorations), but puts its
17140
17297
  inputs at the very bottom of the precedence stack, meaning mark
17141
17298
  decorations provided here will only be split by other, partially
17142
- overlapping \`outerDecorations\` ranges, and wrap around all
17299
+ overlapping `outerDecorations` ranges, and wrap around all
17143
17300
  regular decorations. Use this for mark elements that should, as
17144
17301
  much as possible, remain in one piece.
17145
17302
  */
@@ -17431,6 +17588,8 @@ function runHandlers(map, event, view, scope) {
17431
17588
  else if (isChar && (event.altKey || event.metaKey || event.ctrlKey) &&
17432
17589
  // Ctrl-Alt may be used for AltGr on Windows
17433
17590
  !(browser.windows && event.ctrlKey && event.altKey) &&
17591
+ // Alt-combinations on macOS tend to be typed characters
17592
+ !(browser.mac && event.altKey && !(event.ctrlKey || event.metaKey)) &&
17434
17593
  (baseName = base[event.keyCode]) && baseName != name) {
17435
17594
  if (runFor(scopeObj[prefix + modifiers(baseName, event, true)])) {
17436
17595
  handled = true;
@@ -17705,6 +17864,8 @@ class LayerView {
17705
17864
  old = next;
17706
17865
  }
17707
17866
  this.drawn = markers;
17867
+ if (browser.safari && browser.safari_version >= 26) // Issue #1600, 1627
17868
+ this.dom.style.display = this.dom.firstChild ? "" : "none";
17708
17869
  }
17709
17870
  }
17710
17871
  destroy() {
@@ -18010,7 +18171,7 @@ class MatchDecorator {
18010
18171
  updateRange(view, deco, updateFrom, updateTo) {
18011
18172
  for (let r of view.visibleRanges) {
18012
18173
  let from = Math.max(r.from, updateFrom), to = Math.min(r.to, updateTo);
18013
- if (to > from) {
18174
+ if (to >= from) {
18014
18175
  let fromLine = view.state.doc.lineAt(from), toLine = fromLine.to < to ? view.state.doc.lineAt(to) : fromLine;
18015
18176
  let start = Math.max(r.from, fromLine.from), end = Math.min(r.to, toLine.to);
18016
18177
  if (this.boundary) {
@@ -18544,18 +18705,18 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
18544
18705
  let scaleX = 1, scaleY = 1, makeAbsolute = false;
18545
18706
  if (this.position == "fixed" && this.manager.tooltipViews.length) {
18546
18707
  let { dom } = this.manager.tooltipViews[0];
18547
- if (browser.gecko) {
18548
- // Firefox sets the element's `offsetParent` to the
18549
- // transformed element when a transform interferes with fixed
18550
- // positioning.
18551
- makeAbsolute = dom.offsetParent != this.container.ownerDocument.body;
18552
- }
18553
- else if (dom.style.top == Outside && dom.style.left == "0px") {
18554
- // On other browsers, we have to awkwardly try and use other
18555
- // information to detect a transform.
18708
+ if (browser.safari) {
18709
+ // Safari always sets offsetParent to null, even if a fixed
18710
+ // element is positioned relative to a transformed parent. So
18711
+ // we use this kludge to try and detect this.
18556
18712
  let rect = dom.getBoundingClientRect();
18557
18713
  makeAbsolute = Math.abs(rect.top + 10000) > 1 || Math.abs(rect.left) > 1;
18558
18714
  }
18715
+ else {
18716
+ // More conforming browsers will set offsetParent to the
18717
+ // transformed element.
18718
+ makeAbsolute = !!dom.offsetParent && dom.offsetParent != this.container.ownerDocument.body;
18719
+ }
18559
18720
  }
18560
18721
  if (makeAbsolute || this.position == "absolute") {
18561
18722
  if (this.parent) {
@@ -19256,7 +19417,8 @@ const defaults$1 = {
19256
19417
  lineMarkerChange: null,
19257
19418
  initialSpacer: null,
19258
19419
  updateSpacer: null,
19259
- domEventHandlers: {}
19420
+ domEventHandlers: {},
19421
+ side: "before"
19260
19422
  };
19261
19423
  const activeGutters = /*@__PURE__*/Facet.define();
19262
19424
  /**
@@ -19264,7 +19426,7 @@ Define an editor gutter. The order in which the gutters appear is
19264
19426
  determined by their extension priority.
19265
19427
  */
19266
19428
  function gutter(config) {
19267
- return [gutters(), activeGutters.of(Object.assign(Object.assign({}, defaults$1), config))];
19429
+ return [gutters(), activeGutters.of({ ...defaults$1, ...config })];
19268
19430
  }
19269
19431
  const unfixGutters = /*@__PURE__*/Facet.define({
19270
19432
  combine: values => values.some(x => x)
@@ -19288,15 +19450,20 @@ function gutters(config) {
19288
19450
  const gutterView = /*@__PURE__*/ViewPlugin.fromClass(class {
19289
19451
  constructor(view) {
19290
19452
  this.view = view;
19453
+ this.domAfter = null;
19291
19454
  this.prevViewport = view.viewport;
19292
19455
  this.dom = document.createElement("div");
19293
- this.dom.className = "cm-gutters";
19456
+ this.dom.className = "cm-gutters cm-gutters-before";
19294
19457
  this.dom.setAttribute("aria-hidden", "true");
19295
19458
  this.dom.style.minHeight = (this.view.contentHeight / this.view.scaleY) + "px";
19296
19459
  this.gutters = view.state.facet(activeGutters).map(conf => new SingleGutterView(view, conf));
19297
- for (let gutter of this.gutters)
19298
- this.dom.appendChild(gutter.dom);
19299
19460
  this.fixed = !view.state.facet(unfixGutters);
19461
+ for (let gutter of this.gutters) {
19462
+ if (gutter.config.side == "after")
19463
+ this.getDOMAfter().appendChild(gutter.dom);
19464
+ else
19465
+ this.dom.appendChild(gutter.dom);
19466
+ }
19300
19467
  if (this.fixed) {
19301
19468
  // FIXME IE11 fallback, which doesn't support position: sticky,
19302
19469
  // by using position: relative + event handlers that realign the
@@ -19306,6 +19473,17 @@ const gutterView = /*@__PURE__*/ViewPlugin.fromClass(class {
19306
19473
  this.syncGutters(false);
19307
19474
  view.scrollDOM.insertBefore(this.dom, view.contentDOM);
19308
19475
  }
19476
+ getDOMAfter() {
19477
+ if (!this.domAfter) {
19478
+ this.domAfter = document.createElement("div");
19479
+ this.domAfter.className = "cm-gutters cm-gutters-after";
19480
+ this.domAfter.setAttribute("aria-hidden", "true");
19481
+ this.domAfter.style.minHeight = (this.view.contentHeight / this.view.scaleY) + "px";
19482
+ this.domAfter.style.position = this.fixed ? "sticky" : "";
19483
+ this.view.scrollDOM.appendChild(this.domAfter);
19484
+ }
19485
+ return this.domAfter;
19486
+ }
19309
19487
  update(update) {
19310
19488
  if (this.updateGutters(update)) {
19311
19489
  // Detach during sync when the viewport changed significantly
@@ -19316,18 +19494,26 @@ const gutterView = /*@__PURE__*/ViewPlugin.fromClass(class {
19316
19494
  this.syncGutters(vpOverlap < (vpB.to - vpB.from) * 0.8);
19317
19495
  }
19318
19496
  if (update.geometryChanged) {
19319
- this.dom.style.minHeight = (this.view.contentHeight / this.view.scaleY) + "px";
19497
+ let min = (this.view.contentHeight / this.view.scaleY) + "px";
19498
+ this.dom.style.minHeight = min;
19499
+ if (this.domAfter)
19500
+ this.domAfter.style.minHeight = min;
19320
19501
  }
19321
19502
  if (this.view.state.facet(unfixGutters) != !this.fixed) {
19322
19503
  this.fixed = !this.fixed;
19323
19504
  this.dom.style.position = this.fixed ? "sticky" : "";
19505
+ if (this.domAfter)
19506
+ this.domAfter.style.position = this.fixed ? "sticky" : "";
19324
19507
  }
19325
19508
  this.prevViewport = update.view.viewport;
19326
19509
  }
19327
19510
  syncGutters(detach) {
19328
19511
  let after = this.dom.nextSibling;
19329
- if (detach)
19512
+ if (detach) {
19330
19513
  this.dom.remove();
19514
+ if (this.domAfter)
19515
+ this.domAfter.remove();
19516
+ }
19331
19517
  let lineClasses = RangeSet.iter(this.view.state.facet(gutterLineClass), this.view.viewport.from);
19332
19518
  let classSet = [];
19333
19519
  let contexts = this.gutters.map(gutter => new UpdateContext(gutter, this.view.viewport, -this.view.documentPadding.top));
@@ -19361,8 +19547,11 @@ const gutterView = /*@__PURE__*/ViewPlugin.fromClass(class {
19361
19547
  }
19362
19548
  for (let cx of contexts)
19363
19549
  cx.finish();
19364
- if (detach)
19550
+ if (detach) {
19365
19551
  this.view.scrollDOM.insertBefore(this.dom, after);
19552
+ if (this.domAfter)
19553
+ this.view.scrollDOM.appendChild(this.domAfter);
19554
+ }
19366
19555
  }
19367
19556
  updateGutters(update) {
19368
19557
  let prev = update.startState.facet(activeGutters), cur = update.state.facet(activeGutters);
@@ -19391,8 +19580,12 @@ const gutterView = /*@__PURE__*/ViewPlugin.fromClass(class {
19391
19580
  if (gutters.indexOf(g) < 0)
19392
19581
  g.destroy();
19393
19582
  }
19394
- for (let g of gutters)
19395
- this.dom.appendChild(g.dom);
19583
+ for (let g of gutters) {
19584
+ if (g.config.side == "after")
19585
+ this.getDOMAfter().appendChild(g.dom);
19586
+ else
19587
+ this.dom.appendChild(g.dom);
19588
+ }
19396
19589
  this.gutters = gutters;
19397
19590
  }
19398
19591
  return change;
@@ -19401,15 +19594,18 @@ const gutterView = /*@__PURE__*/ViewPlugin.fromClass(class {
19401
19594
  for (let view of this.gutters)
19402
19595
  view.destroy();
19403
19596
  this.dom.remove();
19597
+ if (this.domAfter)
19598
+ this.domAfter.remove();
19404
19599
  }
19405
19600
  }, {
19406
19601
  provide: plugin => EditorView.scrollMargins.of(view => {
19407
19602
  let value = view.plugin(plugin);
19408
19603
  if (!value || value.gutters.length == 0 || !value.fixed)
19409
19604
  return null;
19605
+ let before = value.dom.offsetWidth * view.scaleX, after = value.domAfter ? value.domAfter.offsetWidth * view.scaleX : 0;
19410
19606
  return view.textDirection == Direction.LTR
19411
- ? { left: value.dom.offsetWidth * view.scaleX }
19412
- : { right: value.dom.offsetWidth * view.scaleX };
19607
+ ? { left: before, right: after }
19608
+ : { right: before, left: after };
19413
19609
  })
19414
19610
  });
19415
19611
  function asArray(val) { return (Array.isArray(val) ? val : [val]); }
@@ -19651,7 +19847,8 @@ const lineNumberGutter = /*@__PURE__*/activeGutters.compute([lineNumberConfig],
19651
19847
  let max = formatNumber(update.view, maxLineNumber(update.view.state.doc.lines));
19652
19848
  return max == spacer.number ? spacer : new NumberMarker(max);
19653
19849
  },
19654
- domEventHandlers: state.facet(lineNumberConfig).domEventHandlers
19850
+ domEventHandlers: state.facet(lineNumberConfig).domEventHandlers,
19851
+ side: "before"
19655
19852
  }));
19656
19853
  /**
19657
19854
  Create a line number gutter extension.
@@ -20343,8 +20540,8 @@ service.
20343
20540
  const indentService = /*@__PURE__*/Facet.define();
20344
20541
  /**
20345
20542
  Facet for overriding the unit by which indentation happens. Should
20346
- be a string consisting either entirely of the same whitespace
20347
- character. When not set, this defaults to 2 spaces.
20543
+ be a string consisting entirely of the same whitespace character.
20544
+ When not set, this defaults to 2 spaces.
20348
20545
  */
20349
20546
  const indentUnit = /*@__PURE__*/Facet.define({
20350
20547
  combine: values => {
@@ -20513,7 +20710,8 @@ function syntaxIndentation(cx, ast, pos) {
20513
20710
  let inner = ast.resolveInner(pos, -1).resolve(pos, 0).enterUnfinishedNodesBefore(pos);
20514
20711
  if (inner != stack.node) {
20515
20712
  let add = [];
20516
- for (let cur = inner; cur && !(cur.from == stack.node.from && cur.type == stack.node.type); cur = cur.parent)
20713
+ for (let cur = inner; cur && !(cur.from < stack.node.from || cur.to > stack.node.to ||
20714
+ cur.from == stack.node.from && cur.type == stack.node.type); cur = cur.parent)
20517
20715
  add.push(cur);
20518
20716
  for (let i = add.length - 1; i >= 0; i--)
20519
20717
  stack = { node: add[i], next: stack };
@@ -20813,6 +21011,8 @@ const foldState = /*@__PURE__*/StateField.define({
20813
21011
  return Decoration.none;
20814
21012
  },
20815
21013
  update(folded, tr) {
21014
+ if (tr.isUserEvent("delete"))
21015
+ tr.changes.iterChangedRanges((fromA, toA) => folded = clearTouchedFolds(folded, fromA, toA));
20816
21016
  folded = folded.map(tr.changes);
20817
21017
  for (let e of tr.effects) {
20818
21018
  if (e.is(foldEffect) && !foldExists(folded, e.value.from, e.value.to)) {
@@ -20827,17 +21027,8 @@ const foldState = /*@__PURE__*/StateField.define({
20827
21027
  }
20828
21028
  }
20829
21029
  // Clear folded ranges that cover the selection head
20830
- if (tr.selection) {
20831
- let onSelection = false, { head } = tr.selection.main;
20832
- folded.between(head, head, (a, b) => { if (a < head && b > head)
20833
- onSelection = true; });
20834
- if (onSelection)
20835
- folded = folded.update({
20836
- filterFrom: head,
20837
- filterTo: head,
20838
- filter: (a, b) => b <= head || a >= head
20839
- });
20840
- }
21030
+ if (tr.selection)
21031
+ folded = clearTouchedFolds(folded, tr.selection.main.head);
20841
21032
  return folded;
20842
21033
  },
20843
21034
  provide: f => EditorView.decorations.from(f),
@@ -20859,6 +21050,16 @@ const foldState = /*@__PURE__*/StateField.define({
20859
21050
  return Decoration.set(ranges, true);
20860
21051
  }
20861
21052
  });
21053
+ function clearTouchedFolds(folded, from, to = from) {
21054
+ let touched = false;
21055
+ folded.between(from, to, (a, b) => { if (a < to && b > from)
21056
+ touched = true; });
21057
+ return !touched ? folded : folded.update({
21058
+ filterFrom: from,
21059
+ filterTo: to,
21060
+ filter: (a, b) => a >= to || b <= from
21061
+ });
21062
+ }
20862
21063
  function findFold(state, from, to) {
20863
21064
  var _a;
20864
21065
  let found = null;
@@ -21031,7 +21232,7 @@ fold status indicator before foldable lines (which can be clicked
21031
21232
  to fold or unfold the line).
21032
21233
  */
21033
21234
  function foldGutter(config = {}) {
21034
- let fullConfig = Object.assign(Object.assign({}, foldGutterDefaults), config);
21235
+ let fullConfig = { ...foldGutterDefaults, ...config };
21035
21236
  let canFold = new FoldMarker(fullConfig, true), canUnfold = new FoldMarker(fullConfig, false);
21036
21237
  let markers = ViewPlugin.fromClass(class {
21037
21238
  constructor(view) {
@@ -21066,7 +21267,9 @@ function foldGutter(config = {}) {
21066
21267
  initialSpacer() {
21067
21268
  return new FoldMarker(fullConfig, false);
21068
21269
  },
21069
- domEventHandlers: Object.assign(Object.assign({}, domEventHandlers), { click: (view, line, event) => {
21270
+ domEventHandlers: {
21271
+ ...domEventHandlers,
21272
+ click: (view, line, event) => {
21070
21273
  if (domEventHandlers.click && domEventHandlers.click(view, line, event))
21071
21274
  return true;
21072
21275
  let folded = findFold(view.state, line.from, line.to);
@@ -21080,7 +21283,8 @@ function foldGutter(config = {}) {
21080
21283
  return true;
21081
21284
  }
21082
21285
  return false;
21083
- } })
21286
+ }
21287
+ }
21084
21288
  }),
21085
21289
  codeFolding()
21086
21290
  ];
@@ -22490,6 +22694,41 @@ const selectParentSyntax = ({ state, dispatch }) => {
22490
22694
  dispatch(setSel(state, selection));
22491
22695
  return true;
22492
22696
  };
22697
+ function addCursorVertically(view, forward) {
22698
+ let { state } = view, sel = state.selection, ranges = state.selection.ranges.slice();
22699
+ for (let range of state.selection.ranges) {
22700
+ let line = state.doc.lineAt(range.head);
22701
+ if (forward ? line.to < view.state.doc.length : line.from > 0)
22702
+ for (let cur = range;;) {
22703
+ let next = view.moveVertically(cur, forward);
22704
+ if (next.head < line.from || next.head > line.to) {
22705
+ if (!ranges.some(r => r.head == next.head))
22706
+ ranges.push(next);
22707
+ break;
22708
+ }
22709
+ else if (next.head == cur.head) {
22710
+ break;
22711
+ }
22712
+ else {
22713
+ cur = next;
22714
+ }
22715
+ }
22716
+ }
22717
+ if (ranges.length == sel.ranges.length)
22718
+ return false;
22719
+ view.dispatch(setSel(state, EditorSelection.create(ranges, ranges.length - 1)));
22720
+ return true;
22721
+ }
22722
+ /**
22723
+ Expand the selection by adding a cursor above the heads of
22724
+ currently selected ranges.
22725
+ */
22726
+ const addCursorAbove = view => addCursorVertically(view, false);
22727
+ /**
22728
+ Expand the selection by adding a cursor below the heads of
22729
+ currently selected ranges.
22730
+ */
22731
+ const addCursorBelow = view => addCursorVertically(view, true);
22493
22732
  /**
22494
22733
  Simplify the current selection. When multiple ranges are selected,
22495
22734
  reduce it to its main range. Otherwise, if the selection is
@@ -22999,12 +23238,12 @@ const standardKeymap = /*@__PURE__*/[
22999
23238
  { key: "Mod-End", run: cursorDocEnd, shift: selectDocEnd },
23000
23239
  { key: "Enter", run: insertNewlineAndIndent, shift: insertNewlineAndIndent },
23001
23240
  { key: "Mod-a", run: selectAll },
23002
- { key: "Backspace", run: deleteCharBackward, shift: deleteCharBackward },
23003
- { key: "Delete", run: deleteCharForward },
23004
- { key: "Mod-Backspace", mac: "Alt-Backspace", run: deleteGroupBackward },
23005
- { key: "Mod-Delete", mac: "Alt-Delete", run: deleteGroupForward },
23006
- { mac: "Mod-Backspace", run: deleteLineBoundaryBackward },
23007
- { mac: "Mod-Delete", run: deleteLineBoundaryForward }
23241
+ { key: "Backspace", run: deleteCharBackward, shift: deleteCharBackward, preventDefault: true },
23242
+ { key: "Delete", run: deleteCharForward, preventDefault: true },
23243
+ { key: "Mod-Backspace", mac: "Alt-Backspace", run: deleteGroupBackward, preventDefault: true },
23244
+ { key: "Mod-Delete", mac: "Alt-Delete", run: deleteGroupForward, preventDefault: true },
23245
+ { mac: "Mod-Backspace", run: deleteLineBoundaryBackward, preventDefault: true },
23246
+ { mac: "Mod-Delete", run: deleteLineBoundaryForward, preventDefault: true }
23008
23247
  ].concat(/*@__PURE__*/emacsStyleKeymap.map(b => ({ mac: b.key, run: b.run, shift: b.shift })));
23009
23248
  /**
23010
23249
  The default keymap. Includes all bindings from
@@ -23016,6 +23255,8 @@ The default keymap. Includes all bindings from
23016
23255
  - Alt-ArrowDown: [`moveLineDown`](https://codemirror.net/6/docs/ref/#commands.moveLineDown)
23017
23256
  - Shift-Alt-ArrowUp: [`copyLineUp`](https://codemirror.net/6/docs/ref/#commands.copyLineUp)
23018
23257
  - Shift-Alt-ArrowDown: [`copyLineDown`](https://codemirror.net/6/docs/ref/#commands.copyLineDown)
23258
+ - Ctrl-Alt-ArrowUp (Cmd-Alt-ArrowUp on macOS): [`addCursorAbove`](https://codemirror.net/6/docs/ref/#commands.addCursorAbove).
23259
+ - Ctrl-Alt-ArrowDown (Cmd-Alt-ArrowDown on macOS): [`addCursorBelow`](https://codemirror.net/6/docs/ref/#commands.addCursorBelow).
23019
23260
  - Escape: [`simplifySelection`](https://codemirror.net/6/docs/ref/#commands.simplifySelection)
23020
23261
  - Ctrl-Enter (Cmd-Enter on macOS): [`insertBlankLine`](https://codemirror.net/6/docs/ref/#commands.insertBlankLine)
23021
23262
  - Alt-l (Ctrl-l on macOS): [`selectLine`](https://codemirror.net/6/docs/ref/#commands.selectLine)
@@ -23036,6 +23277,8 @@ const defaultKeymap = /*@__PURE__*/[
23036
23277
  { key: "Shift-Alt-ArrowUp", run: copyLineUp },
23037
23278
  { key: "Alt-ArrowDown", run: moveLineDown },
23038
23279
  { key: "Shift-Alt-ArrowDown", run: copyLineDown },
23280
+ { key: "Mod-Alt-ArrowUp", run: addCursorAbove },
23281
+ { key: "Mod-Alt-ArrowDown", run: addCursorBelow },
23039
23282
  { key: "Escape", run: simplifySelection },
23040
23283
  { key: "Mod-Enter", run: insertBlankLine },
23041
23284
  { key: "Alt-l", mac: "Ctrl-l", run: selectLine },
@@ -23050,34 +23293,6 @@ const defaultKeymap = /*@__PURE__*/[
23050
23293
  { key: "Ctrl-m", mac: "Shift-Alt-m", run: toggleTabFocusMode },
23051
23294
  ].concat(standardKeymap);
23052
23295
 
23053
- function crelt() {
23054
- var elt = arguments[0];
23055
- if (typeof elt == "string") elt = document.createElement(elt);
23056
- var i = 1, next = arguments[1];
23057
- if (next && typeof next == "object" && next.nodeType == null && !Array.isArray(next)) {
23058
- for (var name in next) if (Object.prototype.hasOwnProperty.call(next, name)) {
23059
- var value = next[name];
23060
- if (typeof value == "string") elt.setAttribute(name, value);
23061
- else if (value != null) elt[name] = value;
23062
- }
23063
- i++;
23064
- }
23065
- for (; i < arguments.length; i++) add(elt, arguments[i]);
23066
- return elt
23067
- }
23068
-
23069
- function add(elt, child) {
23070
- if (typeof child == "string") {
23071
- elt.appendChild(document.createTextNode(child));
23072
- } else if (child == null) ; else if (child.nodeType != null) {
23073
- elt.appendChild(child);
23074
- } else if (Array.isArray(child)) {
23075
- for (var i = 0; i < child.length; i++) add(elt, child[i]);
23076
- } else {
23077
- throw new RangeError("Unsupported child node: " + child)
23078
- }
23079
- }
23080
-
23081
23296
  const basicNormalize = typeof String.prototype.normalize == "function"
23082
23297
  ? x => x.normalize("NFKD") : x => x;
23083
23298
  /**
@@ -24007,14 +24222,16 @@ const replaceNext = /*@__PURE__*/searchCommand((view, { query }) => {
24007
24222
  next = query.nextMatch(state, next.from, next.to);
24008
24223
  effects.push(EditorView.announce.of(state.phrase("replaced match on line $", state.doc.lineAt(from).number) + "."));
24009
24224
  }
24225
+ let changeSet = view.state.changes(changes);
24010
24226
  if (next) {
24011
- let off = changes.length == 0 || changes[0].from >= match.to ? 0 : match.to - match.from - replacement.length;
24012
- selection = EditorSelection.single(next.from - off, next.to - off);
24227
+ selection = EditorSelection.single(next.from, next.to).map(changeSet);
24013
24228
  effects.push(announceMatch(view, next));
24014
24229
  effects.push(state.facet(searchConfigFacet).scrollToMatch(selection.main, view));
24015
24230
  }
24016
24231
  view.dispatch({
24017
- changes, selection, effects,
24232
+ changes: changeSet,
24233
+ selection,
24234
+ effects,
24018
24235
  userEvent: "input.replace"
24019
24236
  });
24020
24237
  return true;
@@ -24454,16 +24671,20 @@ selection range that has the same text in front of it.
24454
24671
  */
24455
24672
  function insertCompletionText(state, text, from, to) {
24456
24673
  let { main } = state.selection, fromOff = from - main.from, toOff = to - main.from;
24457
- return Object.assign(Object.assign({}, state.changeByRange(range => {
24458
- if (range != main && from != to &&
24459
- state.sliceDoc(range.from + fromOff, range.from + toOff) != state.sliceDoc(from, to))
24460
- return { range };
24461
- let lines = state.toText(text);
24462
- return {
24463
- changes: { from: range.from + fromOff, to: to == main.from ? range.to : range.from + toOff, insert: lines },
24464
- range: EditorSelection.cursor(range.from + fromOff + lines.length)
24465
- };
24466
- })), { scrollIntoView: true, userEvent: "input.complete" });
24674
+ return {
24675
+ ...state.changeByRange(range => {
24676
+ if (range != main && from != to &&
24677
+ state.sliceDoc(range.from + fromOff, range.from + toOff) != state.sliceDoc(from, to))
24678
+ return { range };
24679
+ let lines = state.toText(text);
24680
+ return {
24681
+ changes: { from: range.from + fromOff, to: to == main.from ? range.to : range.from + toOff, insert: lines },
24682
+ range: EditorSelection.cursor(range.from + fromOff + lines.length)
24683
+ };
24684
+ }),
24685
+ scrollIntoView: true,
24686
+ userEvent: "input.complete"
24687
+ };
24467
24688
  }
24468
24689
  const SourceCache = /*@__PURE__*/new WeakMap();
24469
24690
  function asSource(source) {
@@ -24652,7 +24873,7 @@ const completionConfig = /*@__PURE__*/Facet.define({
24652
24873
  addToOptions: [],
24653
24874
  positionInfo: defaultPositionInfo,
24654
24875
  filterStrict: false,
24655
- compareCompletions: (a, b) => a.label.localeCompare(b.label),
24876
+ compareCompletions: (a, b) => (a.sortText || a.label).localeCompare(b.sortText || b.label),
24656
24877
  interactionDelay: 75,
24657
24878
  updateSyncTime: 100
24658
24879
  }, {
@@ -24851,7 +25072,8 @@ class CompletionTooltip {
24851
25072
  this.range = rangeAroundSelected(open.options.length, open.selected, this.view.state.facet(completionConfig).maxRenderedOptions);
24852
25073
  this.showOptions(open.options, cState.id);
24853
25074
  }
24854
- if (this.updateSelectedOption(open.selected)) {
25075
+ let newSel = this.updateSelectedOption(open.selected);
25076
+ if (newSel) {
24855
25077
  this.destroyInfo();
24856
25078
  let { completion } = open.options[open.selected];
24857
25079
  let { info } = completion;
@@ -24868,6 +25090,7 @@ class CompletionTooltip {
24868
25090
  }
24869
25091
  else {
24870
25092
  this.addInfoPane(infoResult, completion);
25093
+ newSel.setAttribute("aria-describedby", this.info.id);
24871
25094
  }
24872
25095
  }
24873
25096
  }
@@ -24875,6 +25098,7 @@ class CompletionTooltip {
24875
25098
  this.destroyInfo();
24876
25099
  let wrap = this.info = document.createElement("div");
24877
25100
  wrap.className = "cm-tooltip cm-completionInfo";
25101
+ wrap.id = "cm-completionInfo-" + Math.floor(Math.random() * 0xffff).toString(16);
24878
25102
  if (content.nodeType != null) {
24879
25103
  wrap.appendChild(content);
24880
25104
  this.infoDestroy = null;
@@ -24900,8 +25124,10 @@ class CompletionTooltip {
24900
25124
  }
24901
25125
  }
24902
25126
  else {
24903
- if (opt.hasAttribute("aria-selected"))
25127
+ if (opt.hasAttribute("aria-selected")) {
24904
25128
  opt.removeAttribute("aria-selected");
25129
+ opt.removeAttribute("aria-describedby");
25130
+ }
24905
25131
  }
24906
25132
  }
24907
25133
  if (set)
@@ -25015,7 +25241,7 @@ function score(option) {
25015
25241
  }
25016
25242
  function sortOptions(active, state) {
25017
25243
  let options = [];
25018
- let sections = null;
25244
+ let sections = null, dynamicSectionScore = null;
25019
25245
  let addOption = (option) => {
25020
25246
  options.push(option);
25021
25247
  let { section } = option.completion;
@@ -25042,13 +25268,24 @@ function sortOptions(active, state) {
25042
25268
  for (let option of a.result.options)
25043
25269
  if (match = matcher.match(option.label)) {
25044
25270
  let matched = !option.displayLabel ? match.matched : getMatch ? getMatch(option, match.matched) : [];
25045
- addOption(new Option(option, a.source, matched, match.score + (option.boost || 0)));
25271
+ let score = match.score + (option.boost || 0);
25272
+ addOption(new Option(option, a.source, matched, score));
25273
+ if (typeof option.section == "object" && option.section.rank === "dynamic") {
25274
+ let { name } = option.section;
25275
+ if (!dynamicSectionScore)
25276
+ dynamicSectionScore = Object.create(null);
25277
+ dynamicSectionScore[name] = Math.max(score, dynamicSectionScore[name] || -1e9);
25278
+ }
25046
25279
  }
25047
25280
  }
25048
25281
  }
25049
25282
  if (sections) {
25050
25283
  let sectionOrder = Object.create(null), pos = 0;
25051
- 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); };
25284
+ let cmp = (a, b) => {
25285
+ return (a.rank === "dynamic" && b.rank === "dynamic" ? dynamicSectionScore[b.name] - dynamicSectionScore[a.name] : 0) ||
25286
+ (typeof a.rank == "number" ? a.rank : 1e9) - (typeof b.rank == "number" ? b.rank : 1e9) ||
25287
+ (a.name < b.name ? -1 : 1);
25288
+ };
25052
25289
  for (let s of sections.sort(cmp)) {
25053
25290
  pos -= 1e5;
25054
25291
  sectionOrder[s.name] = pos;
@@ -25108,7 +25345,7 @@ class CompletionDialog {
25108
25345
  }, prev ? prev.timestamp : Date.now(), selected, false);
25109
25346
  }
25110
25347
  map(changes) {
25111
- return new CompletionDialog(this.options, this.attrs, Object.assign(Object.assign({}, this.tooltip), { pos: changes.mapPos(this.tooltip.pos) }), this.timestamp, this.selected, this.disabled);
25348
+ return new CompletionDialog(this.options, this.attrs, { ...this.tooltip, pos: changes.mapPos(this.tooltip.pos) }, this.timestamp, this.selected, this.disabled);
25112
25349
  }
25113
25350
  setDisabled() {
25114
25351
  return new CompletionDialog(this.options, this.attrs, this.tooltip, this.timestamp, this.selected, true);
@@ -25293,7 +25530,10 @@ function applyCompletion(view, option) {
25293
25530
  if (!(result instanceof ActiveResult))
25294
25531
  return false;
25295
25532
  if (typeof apply == "string")
25296
- view.dispatch(Object.assign(Object.assign({}, insertCompletionText(view.state, apply, result.from, result.to)), { annotations: pickedCompletion.of(option.completion) }));
25533
+ view.dispatch({
25534
+ ...insertCompletionText(view.state, apply, result.from, result.to),
25535
+ annotations: pickedCompletion.of(option.completion)
25536
+ });
25297
25537
  else
25298
25538
  apply(view, option.completion, result.from, result.to);
25299
25539
  return true;
@@ -25925,17 +26165,18 @@ function autocompletion(config = {}) {
25925
26165
  /**
25926
26166
  Basic keybindings for autocompletion.
25927
26167
 
25928
- - Ctrl-Space (and Alt-\` on macOS): [`startCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.startCompletion)
26168
+ - Ctrl-Space (and Alt-\` or Alt-i on macOS): [`startCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.startCompletion)
25929
26169
  - Escape: [`closeCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.closeCompletion)
25930
26170
  - ArrowDown: [`moveCompletionSelection`](https://codemirror.net/6/docs/ref/#autocomplete.moveCompletionSelection)`(true)`
25931
26171
  - ArrowUp: [`moveCompletionSelection`](https://codemirror.net/6/docs/ref/#autocomplete.moveCompletionSelection)`(false)`
25932
26172
  - PageDown: [`moveCompletionSelection`](https://codemirror.net/6/docs/ref/#autocomplete.moveCompletionSelection)`(true, "page")`
25933
- - PageDown: [`moveCompletionSelection`](https://codemirror.net/6/docs/ref/#autocomplete.moveCompletionSelection)`(true, "page")`
26173
+ - PageUp: [`moveCompletionSelection`](https://codemirror.net/6/docs/ref/#autocomplete.moveCompletionSelection)`(false, "page")`
25934
26174
  - Enter: [`acceptCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.acceptCompletion)
25935
26175
  */
25936
26176
  const completionKeymap = [
25937
26177
  { key: "Ctrl-Space", run: startCompletion },
25938
26178
  { mac: "Alt-`", run: startCompletion },
26179
+ { mac: "Alt-i", run: startCompletion },
25939
26180
  { key: "Escape", run: closeCompletion },
25940
26181
  { key: "ArrowDown", run: /*@__PURE__*/moveCompletionSelection(true) },
25941
26182
  { key: "ArrowUp", run: /*@__PURE__*/moveCompletionSelection(false) },
@@ -25965,6 +26206,7 @@ class LintState {
25965
26206
  diagnostics = diagnosticFilter(diagnostics, state);
25966
26207
  let sorted = diagnostics.slice().sort((a, b) => a.from - b.from || a.to - b.to);
25967
26208
  let deco = new RangeSetBuilder(), active = [], pos = 0;
26209
+ let scan = state.doc.iter(), scanPos = 0, docLen = state.doc.length;
25968
26210
  for (let i = 0;;) {
25969
26211
  let next = i == sorted.length ? null : sorted[i];
25970
26212
  if (!next && !active.length)
@@ -25976,6 +26218,8 @@ class LintState {
25976
26218
  }
25977
26219
  else {
25978
26220
  from = next.from;
26221
+ if (from > docLen)
26222
+ break;
25979
26223
  to = next.to;
25980
26224
  active.push(next);
25981
26225
  i++;
@@ -25992,8 +26236,31 @@ class LintState {
25992
26236
  break;
25993
26237
  }
25994
26238
  }
26239
+ to = Math.min(to, docLen);
26240
+ let widget = false;
26241
+ if (active.some(d => d.from == from && (d.to == to || to == docLen))) {
26242
+ widget = from == to;
26243
+ if (!widget && to - from < 10) {
26244
+ let behind = from - (scanPos + scan.value.length);
26245
+ if (behind > 0) {
26246
+ scan.next(behind);
26247
+ scanPos = from;
26248
+ }
26249
+ for (let check = from;;) {
26250
+ if (check >= to) {
26251
+ widget = true;
26252
+ break;
26253
+ }
26254
+ if (!scan.lineBreak && scanPos + scan.value.length > check)
26255
+ break;
26256
+ check = scanPos + scan.value.length;
26257
+ scanPos += scan.value.length;
26258
+ scan.next();
26259
+ }
26260
+ }
26261
+ }
25995
26262
  let sev = maxSeverity(active);
25996
- if (active.some(d => d.from == d.to || (d.from == d.to - 1 && state.doc.lineAt(d.from).to == d.from))) {
26263
+ if (widget) {
25997
26264
  deco.add(from, from, Decoration.widget({
25998
26265
  widget: new DiagnosticWidget(sev),
25999
26266
  diagnostics: active.slice()
@@ -26008,6 +26275,8 @@ class LintState {
26008
26275
  }));
26009
26276
  }
26010
26277
  pos = to;
26278
+ if (pos == docLen)
26279
+ break;
26011
26280
  for (let i = 0; i < active.length; i++)
26012
26281
  if (active[i].to <= pos)
26013
26282
  active.splice(i--, 1);
@@ -26160,17 +26429,28 @@ const lintKeymap = [
26160
26429
  ];
26161
26430
  const lintConfig = /*@__PURE__*/Facet.define({
26162
26431
  combine(input) {
26163
- return Object.assign({ sources: input.map(i => i.source).filter(x => x != null) }, combineConfig(input.map(i => i.config), {
26164
- delay: 750,
26165
- markerFilter: null,
26166
- tooltipFilter: null,
26167
- needsRefresh: null,
26168
- hideOn: () => null,
26169
- }, {
26170
- needsRefresh: (a, b) => !a ? b : !b ? a : u => a(u) || b(u)
26171
- }));
26432
+ return {
26433
+ sources: input.map(i => i.source).filter(x => x != null),
26434
+ ...combineConfig(input.map(i => i.config), {
26435
+ delay: 750,
26436
+ markerFilter: null,
26437
+ tooltipFilter: null,
26438
+ needsRefresh: null,
26439
+ hideOn: () => null,
26440
+ }, {
26441
+ delay: Math.max,
26442
+ markerFilter: combineFilter,
26443
+ tooltipFilter: combineFilter,
26444
+ needsRefresh: (a, b) => !a ? b : !b ? a : u => a(u) || b(u),
26445
+ hideOn: (a, b) => !a ? b : !b ? a : (t, x, y) => a(t, x, y) || b(t, x, y),
26446
+ autoPanel: (a, b) => a || b
26447
+ })
26448
+ };
26172
26449
  }
26173
26450
  });
26451
+ function combineFilter(a, b) {
26452
+ return !a ? b : !b ? a : (d, s) => b(a(d, s), s);
26453
+ }
26174
26454
  function assignKeys(actions) {
26175
26455
  let assigned = [];
26176
26456
  if (actions)
@@ -26203,9 +26483,10 @@ function renderDiagnostic(view, diagnostic, inPanel) {
26203
26483
  let nameElt = keyIndex < 0 ? name : [name.slice(0, keyIndex),
26204
26484
  crelt("u", name.slice(keyIndex, keyIndex + 1)),
26205
26485
  name.slice(keyIndex + 1)];
26486
+ let markClass = action.markClass ? " " + action.markClass : "";
26206
26487
  return crelt("button", {
26207
26488
  type: "button",
26208
- class: "cm-diagnosticAction",
26489
+ class: "cm-diagnosticAction" + markClass,
26209
26490
  onclick: click,
26210
26491
  onmousedown: click,
26211
26492
  "aria-label": ` Action: ${name}${keyIndex < 0 ? "" : ` (access key "${keys[i]})"`}.`