@codemirror/view 6.15.3 → 6.17.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.
package/dist/index.cjs CHANGED
@@ -1,7 +1,5 @@
1
1
  'use strict';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
3
  var state = require('@codemirror/state');
6
4
  var styleMod = require('style-mod');
7
5
  var w3cKeyname = require('w3c-keyname');
@@ -340,7 +338,7 @@ class ContentView {
340
338
  constructor() {
341
339
  this.parent = null;
342
340
  this.dom = null;
343
- this.flags = 2 /* NodeDirty */;
341
+ this.flags = 2 /* ViewFlag.NodeDirty */;
344
342
  }
345
343
  get overrideDOMText() { return null; }
346
344
  get posAtStart() {
@@ -362,18 +360,18 @@ class ContentView {
362
360
  return this.posBefore(view) + view.length;
363
361
  }
364
362
  sync(view, track) {
365
- if (this.flags & 2 /* NodeDirty */) {
363
+ if (this.flags & 2 /* ViewFlag.NodeDirty */) {
366
364
  let parent = this.dom;
367
365
  let prev = null, next;
368
366
  for (let child of this.children) {
369
- if (child.flags & 7 /* Dirty */) {
367
+ if (child.flags & 7 /* ViewFlag.Dirty */) {
370
368
  if (!child.dom && (next = prev ? prev.nextSibling : parent.firstChild)) {
371
369
  let contentView = ContentView.get(next);
372
370
  if (!contentView || !contentView.parent && contentView.canReuseDOM(child))
373
371
  child.reuseDOM(next);
374
372
  }
375
373
  child.sync(view, track);
376
- child.flags &= ~7 /* Dirty */;
374
+ child.flags &= ~7 /* ViewFlag.Dirty */;
377
375
  }
378
376
  next = prev ? prev.nextSibling : parent.firstChild;
379
377
  if (track && !track.written && track.node == parent && next != child.dom)
@@ -393,11 +391,11 @@ class ContentView {
393
391
  while (next)
394
392
  next = rm$1(next);
395
393
  }
396
- else if (this.flags & 1 /* ChildDirty */) {
394
+ else if (this.flags & 1 /* ViewFlag.ChildDirty */) {
397
395
  for (let child of this.children)
398
- if (child.flags & 7 /* Dirty */) {
396
+ if (child.flags & 7 /* ViewFlag.Dirty */) {
399
397
  child.sync(view, track);
400
- child.flags &= ~7 /* Dirty */;
398
+ child.flags &= ~7 /* ViewFlag.Dirty */;
401
399
  }
402
400
  }
403
401
  }
@@ -462,23 +460,23 @@ class ContentView {
462
460
  endDOM: toI < this.children.length && toI >= 0 ? this.children[toI].dom : null };
463
461
  }
464
462
  markDirty(andParent = false) {
465
- this.flags |= 2 /* NodeDirty */;
463
+ this.flags |= 2 /* ViewFlag.NodeDirty */;
466
464
  this.markParentsDirty(andParent);
467
465
  }
468
466
  markParentsDirty(childList) {
469
467
  for (let parent = this.parent; parent; parent = parent.parent) {
470
468
  if (childList)
471
- parent.flags |= 2 /* NodeDirty */;
472
- if (parent.flags & 1 /* ChildDirty */)
469
+ parent.flags |= 2 /* ViewFlag.NodeDirty */;
470
+ if (parent.flags & 1 /* ViewFlag.ChildDirty */)
473
471
  return;
474
- parent.flags |= 1 /* ChildDirty */;
472
+ parent.flags |= 1 /* ViewFlag.ChildDirty */;
475
473
  childList = false;
476
474
  }
477
475
  }
478
476
  setParent(parent) {
479
477
  if (this.parent != parent) {
480
478
  this.parent = parent;
481
- if (this.flags & 7 /* Dirty */)
479
+ if (this.flags & 7 /* ViewFlag.Dirty */)
482
480
  this.markParentsDirty(true);
483
481
  }
484
482
  }
@@ -530,7 +528,7 @@ class ContentView {
530
528
  }
531
529
  become(other) { return false; }
532
530
  canReuseDOM(other) {
533
- return other.constructor == this.constructor && !((this.flags | other.flags) & 8 /* Composition */);
531
+ return other.constructor == this.constructor && !((this.flags | other.flags) & 8 /* ViewFlag.Composition */);
534
532
  }
535
533
  // When this is a zero-length view with a side, this should return a
536
534
  // number <= 0 to indicate it is before its position, or a
@@ -815,10 +813,10 @@ class TextView extends ContentView {
815
813
  this.createDOM(dom);
816
814
  }
817
815
  merge(from, to, source) {
818
- if ((this.flags & 8 /* Composition */) ||
816
+ if ((this.flags & 8 /* ViewFlag.Composition */) ||
819
817
  source && (!(source instanceof TextView) ||
820
818
  this.length - (to - from) + source.length > MaxJoinLen ||
821
- (source.flags & 8 /* Composition */)))
819
+ (source.flags & 8 /* ViewFlag.Composition */)))
822
820
  return false;
823
821
  this.text = this.text.slice(0, from) + (source ? source.text : "") + this.text.slice(to);
824
822
  this.markDirty();
@@ -828,7 +826,7 @@ class TextView extends ContentView {
828
826
  let result = new TextView(this.text.slice(from));
829
827
  this.text = this.text.slice(0, from);
830
828
  this.markDirty();
831
- result.flags |= this.flags & 8 /* Composition */;
829
+ result.flags |= this.flags & 8 /* ViewFlag.Composition */;
832
830
  return result;
833
831
  }
834
832
  localPosFromDOM(node, offset) {
@@ -861,18 +859,18 @@ class MarkView extends ContentView {
861
859
  return dom;
862
860
  }
863
861
  canReuseDOM(other) {
864
- return super.canReuseDOM(other) && !((this.flags | other.flags) & 8 /* Composition */);
862
+ return super.canReuseDOM(other) && !((this.flags | other.flags) & 8 /* ViewFlag.Composition */);
865
863
  }
866
864
  reuseDOM(node) {
867
865
  if (node.nodeName == this.mark.tagName.toUpperCase()) {
868
866
  this.setDOM(node);
869
- this.flags |= 4 /* AttrsDirty */ | 2 /* NodeDirty */;
867
+ this.flags |= 4 /* ViewFlag.AttrsDirty */ | 2 /* ViewFlag.NodeDirty */;
870
868
  }
871
869
  }
872
870
  sync(view, track) {
873
871
  if (!this.dom)
874
872
  this.setDOM(this.setAttrs(document.createElement(this.mark.tagName)));
875
- else if (this.flags & 4 /* AttrsDirty */)
873
+ else if (this.flags & 4 /* ViewFlag.AttrsDirty */)
876
874
  this.setAttrs(this.dom);
877
875
  super.sync(view, track);
878
876
  }
@@ -943,6 +941,9 @@ function textCoords(text, pos, side) {
943
941
  }
944
942
  // Also used for collapsed ranges that don't have a placeholder widget!
945
943
  class WidgetView extends ContentView {
944
+ static create(widget, length, side) {
945
+ return new WidgetView(widget, length, side);
946
+ }
946
947
  constructor(widget, length, side) {
947
948
  super();
948
949
  this.widget = widget;
@@ -950,9 +951,6 @@ class WidgetView extends ContentView {
950
951
  this.side = side;
951
952
  this.prevWidget = null;
952
953
  }
953
- static create(widget, length, side) {
954
- return new WidgetView(widget, length, side);
955
- }
956
954
  split(from) {
957
955
  let result = WidgetView.create(this.widget, this.length - from, this.side);
958
956
  this.length -= from;
@@ -1167,16 +1165,26 @@ function attrsEq(a, b, ignore) {
1167
1165
  return true;
1168
1166
  }
1169
1167
  function updateAttrs(dom, prev, attrs) {
1170
- let changed = null;
1168
+ let changed = false;
1171
1169
  if (prev)
1172
1170
  for (let name in prev)
1173
- if (!(attrs && name in attrs))
1174
- dom.removeAttribute(changed = name);
1171
+ if (!(attrs && name in attrs)) {
1172
+ changed = true;
1173
+ if (name == "style")
1174
+ dom.style.cssText = "";
1175
+ else
1176
+ dom.removeAttribute(name);
1177
+ }
1175
1178
  if (attrs)
1176
1179
  for (let name in attrs)
1177
- if (!(prev && prev[name] == attrs[name]))
1178
- dom.setAttribute(changed = name, attrs[name]);
1179
- return !!changed;
1180
+ if (!(prev && prev[name] == attrs[name])) {
1181
+ changed = true;
1182
+ if (name == "style")
1183
+ dom.style.cssText = attrs[name];
1184
+ else
1185
+ dom.setAttribute(name, attrs[name]);
1186
+ }
1187
+ return changed;
1180
1188
  }
1181
1189
  function getAttrs(dom) {
1182
1190
  let attrs = Object.create(null);
@@ -1334,8 +1342,8 @@ class Decoration extends state.RangeValue {
1334
1342
  static widget(spec) {
1335
1343
  let side = Math.max(-10000, Math.min(10000, spec.side || 0)), block = !!spec.block;
1336
1344
  side += (block && !spec.inlineOrder)
1337
- ? (side > 0 ? 300000000 /* BlockAfter */ : -400000000 /* BlockBefore */)
1338
- : (side > 0 ? 100000000 /* InlineAfter */ : -100000000 /* InlineBefore */);
1345
+ ? (side > 0 ? 300000000 /* Side.BlockAfter */ : -400000000 /* Side.BlockBefore */)
1346
+ : (side > 0 ? 100000000 /* Side.InlineAfter */ : -100000000 /* Side.InlineBefore */);
1339
1347
  return new PointDecoration(spec, side, side, block, spec.widget || null, false);
1340
1348
  }
1341
1349
  /**
@@ -1345,13 +1353,13 @@ class Decoration extends state.RangeValue {
1345
1353
  static replace(spec) {
1346
1354
  let block = !!spec.block, startSide, endSide;
1347
1355
  if (spec.isBlockGap) {
1348
- startSide = -500000000 /* GapStart */;
1349
- endSide = 400000000 /* GapEnd */;
1356
+ startSide = -500000000 /* Side.GapStart */;
1357
+ endSide = 400000000 /* Side.GapEnd */;
1350
1358
  }
1351
1359
  else {
1352
1360
  let { start, end } = getInclusive(spec, block);
1353
- startSide = (start ? (block ? -300000000 /* BlockIncStart */ : -1 /* InlineIncStart */) : 500000000 /* NonIncStart */) - 1;
1354
- endSide = (end ? (block ? 200000000 /* BlockIncEnd */ : 1 /* InlineIncEnd */) : -600000000 /* NonIncEnd */) + 1;
1361
+ startSide = (start ? (block ? -300000000 /* Side.BlockIncStart */ : -1 /* Side.InlineIncStart */) : 500000000 /* Side.NonIncStart */) - 1;
1362
+ endSide = (end ? (block ? 200000000 /* Side.BlockIncEnd */ : 1 /* Side.InlineIncEnd */) : -600000000 /* Side.NonIncEnd */) + 1;
1355
1363
  }
1356
1364
  return new PointDecoration(spec, startSide, endSide, block, spec.widget || null, true);
1357
1365
  }
@@ -1382,7 +1390,7 @@ Decoration.none = state.RangeSet.empty;
1382
1390
  class MarkDecoration extends Decoration {
1383
1391
  constructor(spec) {
1384
1392
  let { start, end } = getInclusive(spec);
1385
- super(start ? -1 /* InlineIncStart */ : 500000000 /* NonIncStart */, end ? 1 /* InlineIncEnd */ : -600000000 /* NonIncEnd */, null, spec);
1393
+ super(start ? -1 /* Side.InlineIncStart */ : 500000000 /* Side.NonIncStart */, end ? 1 /* Side.InlineIncEnd */ : -600000000 /* Side.NonIncEnd */, null, spec);
1386
1394
  this.tagName = spec.tagName || "span";
1387
1395
  this.class = spec.class || "";
1388
1396
  this.attrs = spec.attributes || null;
@@ -1404,7 +1412,7 @@ class MarkDecoration extends Decoration {
1404
1412
  MarkDecoration.prototype.point = false;
1405
1413
  class LineDecoration extends Decoration {
1406
1414
  constructor(spec) {
1407
- super(-200000000 /* Line */, -200000000 /* Line */, null, spec);
1415
+ super(-200000000 /* Side.Line */, -200000000 /* Side.Line */, null, spec);
1408
1416
  }
1409
1417
  eq(other) {
1410
1418
  return other instanceof LineDecoration &&
@@ -1545,7 +1553,7 @@ class LineView extends ContentView {
1545
1553
  reuseDOM(node) {
1546
1554
  if (node.nodeName == "DIV") {
1547
1555
  this.setDOM(node);
1548
- this.flags |= 4 /* AttrsDirty */ | 2 /* NodeDirty */;
1556
+ this.flags |= 4 /* ViewFlag.AttrsDirty */ | 2 /* ViewFlag.NodeDirty */;
1549
1557
  }
1550
1558
  }
1551
1559
  sync(view, track) {
@@ -1555,7 +1563,7 @@ class LineView extends ContentView {
1555
1563
  this.dom.className = "cm-line";
1556
1564
  this.prevAttrs = this.attrs ? null : undefined;
1557
1565
  }
1558
- else if (this.flags & 4 /* AttrsDirty */) {
1566
+ else if (this.flags & 4 /* ViewFlag.AttrsDirty */) {
1559
1567
  clearAttributes(this.dom);
1560
1568
  this.dom.className = "cm-line";
1561
1569
  this.prevAttrs = this.attrs ? null : undefined;
@@ -1703,7 +1711,7 @@ class ContentBuilder {
1703
1711
  this.content = [];
1704
1712
  this.curLine = null;
1705
1713
  this.breakAtStart = 0;
1706
- this.pendingBuffer = 0 /* No */;
1714
+ this.pendingBuffer = 0 /* Buf.No */;
1707
1715
  this.bufferMarks = [];
1708
1716
  // Set to false directly after a widget that covers the position after it
1709
1717
  this.atCursorPos = true;
@@ -1730,7 +1738,7 @@ class ContentBuilder {
1730
1738
  flushBuffer(active = this.bufferMarks) {
1731
1739
  if (this.pendingBuffer) {
1732
1740
  this.curLine.append(wrapMarks(new WidgetBufferView(-1), active), active.length);
1733
- this.pendingBuffer = 0 /* No */;
1741
+ this.pendingBuffer = 0 /* Buf.No */;
1734
1742
  }
1735
1743
  }
1736
1744
  addBlockWidget(view) {
@@ -1742,7 +1750,7 @@ class ContentBuilder {
1742
1750
  if (this.pendingBuffer && openEnd <= this.bufferMarks.length)
1743
1751
  this.flushBuffer();
1744
1752
  else
1745
- this.pendingBuffer = 0 /* No */;
1753
+ this.pendingBuffer = 0 /* Buf.No */;
1746
1754
  if (!this.posCovered())
1747
1755
  this.getLine();
1748
1756
  }
@@ -1771,7 +1779,7 @@ class ContentBuilder {
1771
1779
  this.textOff = 0;
1772
1780
  }
1773
1781
  }
1774
- let take = Math.min(this.text.length - this.textOff, length, 512 /* Chunk */);
1782
+ let take = Math.min(this.text.length - this.textOff, length, 512 /* T.Chunk */);
1775
1783
  this.flushBuffer(active.slice(active.length - openStart));
1776
1784
  this.getLine().append(wrapMarks(new TextView(this.text.slice(this.textOff, this.textOff + take)), active), openStart);
1777
1785
  this.atCursorPos = true;
@@ -1807,8 +1815,8 @@ class ContentBuilder {
1807
1815
  (from < to || deco.startSide > 0);
1808
1816
  let cursorAfter = !view.isEditable && (from < to || openStart > active.length || deco.startSide <= 0);
1809
1817
  let line = this.getLine();
1810
- if (this.pendingBuffer == 2 /* IfCursor */ && !cursorBefore && !view.isEditable)
1811
- this.pendingBuffer = 0 /* No */;
1818
+ if (this.pendingBuffer == 2 /* Buf.IfCursor */ && !cursorBefore && !view.isEditable)
1819
+ this.pendingBuffer = 0 /* Buf.No */;
1812
1820
  this.flushBuffer(active);
1813
1821
  if (cursorBefore) {
1814
1822
  line.append(wrapMarks(new WidgetBufferView(1), active), openStart);
@@ -1816,7 +1824,7 @@ class ContentBuilder {
1816
1824
  }
1817
1825
  line.append(wrapMarks(view, active), openStart);
1818
1826
  this.atCursorPos = cursorAfter;
1819
- this.pendingBuffer = !cursorAfter ? 0 /* No */ : from < to || openStart > active.length ? 1 /* Yes */ : 2 /* IfCursor */;
1827
+ this.pendingBuffer = !cursorAfter ? 0 /* Buf.No */ : from < to || openStart > active.length ? 1 /* Buf.Yes */ : 2 /* Buf.IfCursor */;
1820
1828
  if (this.pendingBuffer)
1821
1829
  this.bufferMarks = active.slice();
1822
1830
  }
@@ -2030,6 +2038,36 @@ const contentAttributes = state.Facet.define();
2030
2038
  // Provide decorations
2031
2039
  const decorations = state.Facet.define();
2032
2040
  const atomicRanges = state.Facet.define();
2041
+ const bidiIsolatedRanges = state.Facet.define();
2042
+ function getIsolatedRanges(view, from, to) {
2043
+ let isolates = view.state.facet(bidiIsolatedRanges);
2044
+ if (!isolates.length)
2045
+ return isolates;
2046
+ let sets = isolates.map(i => i instanceof Function ? i(view) : i);
2047
+ let result = [];
2048
+ state.RangeSet.spans(sets, from, to, {
2049
+ point() { },
2050
+ span(from, to, active, open) {
2051
+ let level = result;
2052
+ for (let i = active.length - 1; i >= 0; i--, open--) {
2053
+ let iso = active[i].spec.bidiIsolate, update;
2054
+ if (iso == null)
2055
+ continue;
2056
+ if (open > 0 && level.length &&
2057
+ (update = level[level.length - 1]).to == from && update.direction == iso) {
2058
+ update.to = to;
2059
+ level = update.inner;
2060
+ }
2061
+ else {
2062
+ let add = { from, to, direction: iso, inner: [] };
2063
+ level.push(add);
2064
+ level = add.inner;
2065
+ }
2066
+ }
2067
+ }
2068
+ });
2069
+ return result;
2070
+ }
2033
2071
  const scrollMargins = state.Facet.define();
2034
2072
  function getScrollMargins(view) {
2035
2073
  let left = 0, right = 0, top = 0, bottom = 0;
@@ -2143,27 +2181,27 @@ class ViewUpdate {
2143
2181
  update.
2144
2182
  */
2145
2183
  get viewportChanged() {
2146
- return (this.flags & 4 /* Viewport */) > 0;
2184
+ return (this.flags & 4 /* UpdateFlag.Viewport */) > 0;
2147
2185
  }
2148
2186
  /**
2149
2187
  Indicates whether the height of a block element in the editor
2150
2188
  changed in this update.
2151
2189
  */
2152
2190
  get heightChanged() {
2153
- return (this.flags & 2 /* Height */) > 0;
2191
+ return (this.flags & 2 /* UpdateFlag.Height */) > 0;
2154
2192
  }
2155
2193
  /**
2156
2194
  Returns true when the document was modified or the size of the
2157
2195
  editor, or elements within the editor, changed.
2158
2196
  */
2159
2197
  get geometryChanged() {
2160
- return this.docChanged || (this.flags & (8 /* Geometry */ | 2 /* Height */)) > 0;
2198
+ return this.docChanged || (this.flags & (8 /* UpdateFlag.Geometry */ | 2 /* UpdateFlag.Height */)) > 0;
2161
2199
  }
2162
2200
  /**
2163
2201
  True when this update indicates a focus change.
2164
2202
  */
2165
2203
  get focusChanged() {
2166
- return (this.flags & 1 /* Focus */) > 0;
2204
+ return (this.flags & 1 /* UpdateFlag.Focus */) > 0;
2167
2205
  }
2168
2206
  /**
2169
2207
  Whether the document changed in this update.
@@ -2222,12 +2260,12 @@ for (let p of ["()", "[]", "{}"]) {
2222
2260
  }
2223
2261
  function charType(ch) {
2224
2262
  return ch <= 0xf7 ? LowTypes[ch] :
2225
- 0x590 <= ch && ch <= 0x5f4 ? 2 /* R */ :
2263
+ 0x590 <= ch && ch <= 0x5f4 ? 2 /* T.R */ :
2226
2264
  0x600 <= ch && ch <= 0x6f9 ? ArabicTypes[ch - 0x600] :
2227
- 0x6ee <= ch && ch <= 0x8ac ? 4 /* AL */ :
2228
- 0x2000 <= ch && ch <= 0x200b ? 256 /* NI */ :
2229
- 0xfb50 <= ch && ch <= 0xfdff ? 4 /* AL */ :
2230
- ch == 0x200c ? 256 /* NI */ : 1 /* L */;
2265
+ 0x6ee <= ch && ch <= 0x8ac ? 4 /* T.AL */ :
2266
+ 0x2000 <= ch && ch <= 0x200b ? 256 /* T.NI */ :
2267
+ 0xfb50 <= ch && ch <= 0xfdff ? 4 /* T.AL */ :
2268
+ ch == 0x200c ? 256 /* T.NI */ : 1 /* T.L */;
2231
2269
  }
2232
2270
  const BidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac\ufb50-\ufdff]/;
2233
2271
  /**
@@ -2235,6 +2273,10 @@ Represents a contiguous range of text that has a single direction
2235
2273
  (as in left-to-right or right-to-left).
2236
2274
  */
2237
2275
  class BidiSpan {
2276
+ /**
2277
+ The direction of this span.
2278
+ */
2279
+ get dir() { return this.level % 2 ? RTL : LTR; }
2238
2280
  /**
2239
2281
  @internal
2240
2282
  */
@@ -2260,10 +2302,6 @@ class BidiSpan {
2260
2302
  this.level = level;
2261
2303
  }
2262
2304
  /**
2263
- The direction of this span.
2264
- */
2265
- get dir() { return this.level % 2 ? RTL : LTR; }
2266
- /**
2267
2305
  @internal
2268
2306
  */
2269
2307
  side(end, dir) { return (this.dir == dir) == end ? this.to : this.from; }
@@ -2289,166 +2327,328 @@ class BidiSpan {
2289
2327
  return maybe;
2290
2328
  }
2291
2329
  }
2330
+ function isolatesEq(a, b) {
2331
+ if (a.length != b.length)
2332
+ return false;
2333
+ for (let i = 0; i < a.length; i++) {
2334
+ let iA = a[i], iB = b[i];
2335
+ if (iA.from != iB.from || iA.to != iB.to || iA.direction != iB.direction || !isolatesEq(iA.inner, iB.inner))
2336
+ return false;
2337
+ }
2338
+ return true;
2339
+ }
2292
2340
  // Reused array of character types
2293
2341
  const types = [];
2294
- function computeOrder(line, direction) {
2295
- let len = line.length, outerType = direction == LTR ? 1 /* L */ : 2 /* R */, oppositeType = direction == LTR ? 2 /* R */ : 1 /* L */;
2296
- if (!line || outerType == 1 /* L */ && !BidiRE.test(line))
2297
- return trivialOrder(len);
2298
- // W1. Examine each non-spacing mark (NSM) in the level run, and
2299
- // change the type of the NSM to the type of the previous
2300
- // character. If the NSM is at the start of the level run, it will
2301
- // get the type of sor.
2302
- // W2. Search backwards from each instance of a European number
2303
- // until the first strong type (R, L, AL, or sor) is found. If an
2304
- // AL is found, change the type of the European number to Arabic
2305
- // number.
2306
- // W3. Change all ALs to R.
2307
- // (Left after this: L, R, EN, AN, ET, CS, NI)
2308
- for (let i = 0, prev = outerType, prevStrong = outerType; i < len; i++) {
2309
- let type = charType(line.charCodeAt(i));
2310
- if (type == 512 /* NSM */)
2311
- type = prev;
2312
- else if (type == 8 /* EN */ && prevStrong == 4 /* AL */)
2313
- type = 16 /* AN */;
2314
- types[i] = type == 4 /* AL */ ? 2 /* R */ : type;
2315
- if (type & 7 /* Strong */)
2316
- prevStrong = type;
2317
- prev = type;
2318
- }
2319
- // W5. A sequence of European terminators adjacent to European
2320
- // numbers changes to all European numbers.
2321
- // W6. Otherwise, separators and terminators change to Other
2322
- // Neutral.
2323
- // W7. Search backwards from each instance of a European number
2324
- // until the first strong type (R, L, or sor) is found. If an L is
2325
- // found, then change the type of the European number to L.
2326
- // (Left after this: L, R, EN+AN, NI)
2327
- for (let i = 0, prev = outerType, prevStrong = outerType; i < len; i++) {
2328
- let type = types[i];
2329
- if (type == 128 /* CS */) {
2330
- if (i < len - 1 && prev == types[i + 1] && (prev & 24 /* Num */))
2331
- type = types[i] = prev;
2332
- else
2333
- types[i] = 256 /* NI */;
2334
- }
2335
- else if (type == 64 /* ET */) {
2336
- let end = i + 1;
2337
- while (end < len && types[end] == 64 /* ET */)
2338
- end++;
2339
- let replace = (i && prev == 8 /* EN */) || (end < len && types[end] == 8 /* EN */) ? (prevStrong == 1 /* L */ ? 1 /* L */ : 8 /* EN */) : 256 /* NI */;
2340
- for (let j = i; j < end; j++)
2341
- types[j] = replace;
2342
- i = end - 1;
2343
- }
2344
- else if (type == 8 /* EN */ && prevStrong == 1 /* L */) {
2345
- types[i] = 1 /* L */;
2346
- }
2347
- prev = type;
2348
- if (type & 7 /* Strong */)
2349
- prevStrong = type;
2350
- }
2351
- // N0. Process bracket pairs in an isolating run sequence
2352
- // sequentially in the logical order of the text positions of the
2353
- // opening paired brackets using the logic given below. Within this
2354
- // scope, bidirectional types EN and AN are treated as R.
2355
- for (let i = 0, sI = 0, context = 0, ch, br, type; i < len; i++) {
2356
- // Keeps [startIndex, type, strongSeen] triples for each open
2357
- // bracket on BracketStack.
2358
- if (br = Brackets[ch = line.charCodeAt(i)]) {
2359
- if (br < 0) { // Closing bracket
2342
+ // Fill in the character types (in `types`) from `from` to `to` and
2343
+ // apply W normalization rules.
2344
+ function computeCharTypes(line, rFrom, rTo, isolates, outerType) {
2345
+ for (let iI = 0; iI <= isolates.length; iI++) {
2346
+ let from = iI ? isolates[iI - 1].to : rFrom, to = iI < isolates.length ? isolates[iI].from : rTo;
2347
+ let prevType = iI ? 256 /* T.NI */ : outerType;
2348
+ // W1. Examine each non-spacing mark (NSM) in the level run, and
2349
+ // change the type of the NSM to the type of the previous
2350
+ // character. If the NSM is at the start of the level run, it will
2351
+ // get the type of sor.
2352
+ // W2. Search backwards from each instance of a European number
2353
+ // until the first strong type (R, L, AL, or sor) is found. If an
2354
+ // AL is found, change the type of the European number to Arabic
2355
+ // number.
2356
+ // W3. Change all ALs to R.
2357
+ // (Left after this: L, R, EN, AN, ET, CS, NI)
2358
+ for (let i = from, prev = prevType, prevStrong = prevType; i < to; i++) {
2359
+ let type = charType(line.charCodeAt(i));
2360
+ if (type == 512 /* T.NSM */)
2361
+ type = prev;
2362
+ else if (type == 8 /* T.EN */ && prevStrong == 4 /* T.AL */)
2363
+ type = 16 /* T.AN */;
2364
+ types[i] = type == 4 /* T.AL */ ? 2 /* T.R */ : type;
2365
+ if (type & 7 /* T.Strong */)
2366
+ prevStrong = type;
2367
+ prev = type;
2368
+ }
2369
+ // W5. A sequence of European terminators adjacent to European
2370
+ // numbers changes to all European numbers.
2371
+ // W6. Otherwise, separators and terminators change to Other
2372
+ // Neutral.
2373
+ // W7. Search backwards from each instance of a European number
2374
+ // until the first strong type (R, L, or sor) is found. If an L is
2375
+ // found, then change the type of the European number to L.
2376
+ // (Left after this: L, R, EN+AN, NI)
2377
+ for (let i = from, prev = prevType, prevStrong = prevType; i < to; i++) {
2378
+ let type = types[i];
2379
+ if (type == 128 /* T.CS */) {
2380
+ if (i < to - 1 && prev == types[i + 1] && (prev & 24 /* T.Num */))
2381
+ type = types[i] = prev;
2382
+ else
2383
+ types[i] = 256 /* T.NI */;
2384
+ }
2385
+ else if (type == 64 /* T.ET */) {
2386
+ let end = i + 1;
2387
+ while (end < to && types[end] == 64 /* T.ET */)
2388
+ end++;
2389
+ let replace = (i && prev == 8 /* T.EN */) || (end < rTo && types[end] == 8 /* T.EN */) ? (prevStrong == 1 /* T.L */ ? 1 /* T.L */ : 8 /* T.EN */) : 256 /* T.NI */;
2390
+ for (let j = i; j < end; j++)
2391
+ types[j] = replace;
2392
+ i = end - 1;
2393
+ }
2394
+ else if (type == 8 /* T.EN */ && prevStrong == 1 /* T.L */) {
2395
+ types[i] = 1 /* T.L */;
2396
+ }
2397
+ prev = type;
2398
+ if (type & 7 /* T.Strong */)
2399
+ prevStrong = type;
2400
+ }
2401
+ }
2402
+ }
2403
+ // Process brackets throughout a run sequence.
2404
+ function processBracketPairs(line, rFrom, rTo, isolates, outerType) {
2405
+ let oppositeType = outerType == 1 /* T.L */ ? 2 /* T.R */ : 1 /* T.L */;
2406
+ for (let iI = 0, sI = 0, context = 0; iI <= isolates.length; iI++) {
2407
+ let from = iI ? isolates[iI - 1].to : rFrom, to = iI < isolates.length ? isolates[iI].from : rTo;
2408
+ // N0. Process bracket pairs in an isolating run sequence
2409
+ // sequentially in the logical order of the text positions of the
2410
+ // opening paired brackets using the logic given below. Within this
2411
+ // scope, bidirectional types EN and AN are treated as R.
2412
+ for (let i = from, ch, br, type; i < to; i++) {
2413
+ // Keeps [startIndex, type, strongSeen] triples for each open
2414
+ // bracket on BracketStack.
2415
+ if (br = Brackets[ch = line.charCodeAt(i)]) {
2416
+ if (br < 0) { // Closing bracket
2417
+ for (let sJ = sI - 3; sJ >= 0; sJ -= 3) {
2418
+ if (BracketStack[sJ + 1] == -br) {
2419
+ let flags = BracketStack[sJ + 2];
2420
+ let type = (flags & 2 /* Bracketed.EmbedInside */) ? outerType :
2421
+ !(flags & 4 /* Bracketed.OppositeInside */) ? 0 :
2422
+ (flags & 1 /* Bracketed.OppositeBefore */) ? oppositeType : outerType;
2423
+ if (type)
2424
+ types[i] = types[BracketStack[sJ]] = type;
2425
+ sI = sJ;
2426
+ break;
2427
+ }
2428
+ }
2429
+ }
2430
+ else if (BracketStack.length == 189 /* Bracketed.MaxDepth */) {
2431
+ break;
2432
+ }
2433
+ else {
2434
+ BracketStack[sI++] = i;
2435
+ BracketStack[sI++] = ch;
2436
+ BracketStack[sI++] = context;
2437
+ }
2438
+ }
2439
+ else if ((type = types[i]) == 2 /* T.R */ || type == 1 /* T.L */) {
2440
+ let embed = type == outerType;
2441
+ context = embed ? 0 : 1 /* Bracketed.OppositeBefore */;
2360
2442
  for (let sJ = sI - 3; sJ >= 0; sJ -= 3) {
2361
- if (BracketStack[sJ + 1] == -br) {
2362
- let flags = BracketStack[sJ + 2];
2363
- let type = (flags & 2 /* EmbedInside */) ? outerType :
2364
- !(flags & 4 /* OppositeInside */) ? 0 :
2365
- (flags & 1 /* OppositeBefore */) ? oppositeType : outerType;
2366
- if (type)
2367
- types[i] = types[BracketStack[sJ]] = type;
2368
- sI = sJ;
2443
+ let cur = BracketStack[sJ + 2];
2444
+ if (cur & 2 /* Bracketed.EmbedInside */)
2369
2445
  break;
2446
+ if (embed) {
2447
+ BracketStack[sJ + 2] |= 2 /* Bracketed.EmbedInside */;
2448
+ }
2449
+ else {
2450
+ if (cur & 4 /* Bracketed.OppositeInside */)
2451
+ break;
2452
+ BracketStack[sJ + 2] |= 4 /* Bracketed.OppositeInside */;
2370
2453
  }
2371
2454
  }
2372
2455
  }
2373
- else if (BracketStack.length == 189 /* MaxDepth */) {
2374
- break;
2456
+ }
2457
+ }
2458
+ }
2459
+ function processNeutrals(rFrom, rTo, isolates, outerType) {
2460
+ for (let iI = 0, prev = outerType; iI <= isolates.length; iI++) {
2461
+ let from = iI ? isolates[iI - 1].to : rFrom, to = iI < isolates.length ? isolates[iI].from : rTo;
2462
+ // N1. A sequence of neutrals takes the direction of the
2463
+ // surrounding strong text if the text on both sides has the same
2464
+ // direction. European and Arabic numbers act as if they were R in
2465
+ // terms of their influence on neutrals. Start-of-level-run (sor)
2466
+ // and end-of-level-run (eor) are used at level run boundaries.
2467
+ // N2. Any remaining neutrals take the embedding direction.
2468
+ // (Left after this: L, R, EN+AN)
2469
+ for (let i = from; i < to;) {
2470
+ let type = types[i];
2471
+ if (type == 256 /* T.NI */) {
2472
+ let end = i + 1;
2473
+ for (;;) {
2474
+ if (end == to) {
2475
+ if (iI == isolates.length)
2476
+ break;
2477
+ end = isolates[iI++].to;
2478
+ to = iI < isolates.length ? isolates[iI].from : rTo;
2479
+ }
2480
+ else if (types[end] == 256 /* T.NI */) {
2481
+ end++;
2482
+ }
2483
+ else {
2484
+ break;
2485
+ }
2486
+ }
2487
+ let beforeL = prev == 1 /* T.L */;
2488
+ let afterL = (end < rTo ? types[end] : outerType) == 1 /* T.L */;
2489
+ let replace = beforeL == afterL ? (beforeL ? 1 /* T.L */ : 2 /* T.R */) : outerType;
2490
+ for (let j = end, jI = iI, fromJ = jI ? isolates[jI - 1].to : rFrom; j > i;) {
2491
+ if (j == fromJ) {
2492
+ j = isolates[--jI].from;
2493
+ fromJ = jI ? isolates[jI - 1].to : rFrom;
2494
+ }
2495
+ types[--j] = replace;
2496
+ }
2497
+ i = end;
2375
2498
  }
2376
2499
  else {
2377
- BracketStack[sI++] = i;
2378
- BracketStack[sI++] = ch;
2379
- BracketStack[sI++] = context;
2500
+ prev = type;
2501
+ i++;
2380
2502
  }
2381
2503
  }
2382
- else if ((type = types[i]) == 2 /* R */ || type == 1 /* L */) {
2383
- let embed = type == outerType;
2384
- context = embed ? 0 : 1 /* OppositeBefore */;
2385
- for (let sJ = sI - 3; sJ >= 0; sJ -= 3) {
2386
- let cur = BracketStack[sJ + 2];
2387
- if (cur & 2 /* EmbedInside */)
2504
+ }
2505
+ }
2506
+ // Find the contiguous ranges of character types in a given range, and
2507
+ // emit spans for them. Flip the order of the spans as appropriate
2508
+ // based on the level, and call through to compute the spans for
2509
+ // isolates at the proper point.
2510
+ function emitSpans(line, from, to, level, baseLevel, isolates, order) {
2511
+ let ourType = level % 2 ? 2 /* T.R */ : 1 /* T.L */;
2512
+ if ((level % 2) == (baseLevel % 2)) { // Same dir as base direction, don't flip
2513
+ for (let iCh = from, iI = 0; iCh < to;) {
2514
+ // Scan a section of characters in direction ourType, unless
2515
+ // there's another type of char right after iCh, in which case
2516
+ // we scan a section of other characters (which, if ourType ==
2517
+ // T.L, may contain both T.R and T.AN chars).
2518
+ let sameDir = true, isNum = false;
2519
+ if (iI == isolates.length || iCh < isolates[iI].from) {
2520
+ let next = types[iCh];
2521
+ if (next != ourType) {
2522
+ sameDir = false;
2523
+ isNum = next == 16 /* T.AN */;
2524
+ }
2525
+ }
2526
+ // Holds an array of isolates to pass to a recursive call if we
2527
+ // must recurse (to distinguish T.AN inside an RTL section in
2528
+ // LTR text), null if we can emit directly
2529
+ let recurse = !sameDir && ourType == 1 /* T.L */ ? [] : null;
2530
+ let localLevel = sameDir ? level : level + 1;
2531
+ let iScan = iCh;
2532
+ run: for (;;) {
2533
+ if (iI < isolates.length && iScan == isolates[iI].from) {
2534
+ if (isNum)
2535
+ break run;
2536
+ let iso = isolates[iI];
2537
+ // Scan ahead to verify that there is another char in this dir after the isolate(s)
2538
+ if (!sameDir)
2539
+ for (let upto = iso.to, jI = iI + 1;;) {
2540
+ if (upto == to)
2541
+ break run;
2542
+ if (jI < isolates.length && isolates[jI].from == upto)
2543
+ upto = isolates[jI++].to;
2544
+ else if (types[upto] == ourType)
2545
+ break run;
2546
+ else
2547
+ break;
2548
+ }
2549
+ iI++;
2550
+ if (recurse) {
2551
+ recurse.push(iso);
2552
+ }
2553
+ else {
2554
+ if (iso.from > iCh)
2555
+ order.push(new BidiSpan(iCh, iso.from, localLevel));
2556
+ let dirSwap = (iso.direction == LTR) != !(localLevel % 2);
2557
+ computeSectionOrder(line, dirSwap ? level + 1 : level, baseLevel, iso.inner, iso.from, iso.to, order);
2558
+ iCh = iso.to;
2559
+ }
2560
+ iScan = iso.to;
2561
+ }
2562
+ else if (iScan == to || (sameDir ? types[iScan] != ourType : types[iScan] == ourType)) {
2388
2563
  break;
2389
- if (embed) {
2390
- BracketStack[sJ + 2] |= 2 /* EmbedInside */;
2391
2564
  }
2392
2565
  else {
2393
- if (cur & 4 /* OppositeInside */)
2394
- break;
2395
- BracketStack[sJ + 2] |= 4 /* OppositeInside */;
2566
+ iScan++;
2396
2567
  }
2397
2568
  }
2569
+ if (recurse)
2570
+ emitSpans(line, iCh, iScan, level + 1, baseLevel, recurse, order);
2571
+ else if (iCh < iScan)
2572
+ order.push(new BidiSpan(iCh, iScan, localLevel));
2573
+ iCh = iScan;
2398
2574
  }
2399
2575
  }
2400
- // N1. A sequence of neutrals takes the direction of the
2401
- // surrounding strong text if the text on both sides has the same
2402
- // direction. European and Arabic numbers act as if they were R in
2403
- // terms of their influence on neutrals. Start-of-level-run (sor)
2404
- // and end-of-level-run (eor) are used at level run boundaries.
2405
- // N2. Any remaining neutrals take the embedding direction.
2406
- // (Left after this: L, R, EN+AN)
2407
- for (let i = 0; i < len; i++) {
2408
- if (types[i] == 256 /* NI */) {
2409
- let end = i + 1;
2410
- while (end < len && types[end] == 256 /* NI */)
2411
- end++;
2412
- let beforeL = (i ? types[i - 1] : outerType) == 1 /* L */;
2413
- let afterL = (end < len ? types[end] : outerType) == 1 /* L */;
2414
- let replace = beforeL == afterL ? (beforeL ? 1 /* L */ : 2 /* R */) : outerType;
2415
- for (let j = i; j < end; j++)
2416
- types[j] = replace;
2417
- i = end - 1;
2418
- }
2419
- }
2420
- // Here we depart from the documented algorithm, in order to avoid
2421
- // building up an actual levels array. Since there are only three
2422
- // levels (0, 1, 2) in an implementation that doesn't take
2423
- // explicit embedding into account, we can build up the order on
2424
- // the fly, without following the level-based algorithm.
2425
- let order = [];
2426
- if (outerType == 1 /* L */) {
2427
- for (let i = 0; i < len;) {
2428
- let start = i, rtl = types[i++] != 1 /* L */;
2429
- while (i < len && rtl == (types[i] != 1 /* L */))
2430
- i++;
2431
- if (rtl) {
2432
- for (let j = i; j > start;) {
2433
- let end = j, l = types[--j] != 2 /* R */;
2434
- while (j > start && l == (types[j - 1] != 2 /* R */))
2435
- j--;
2436
- order.push(new BidiSpan(j, end, l ? 2 : 1));
2576
+ else {
2577
+ // Iterate in reverse to flip the span order. Same code again, but
2578
+ // going from the back of the section to the front
2579
+ for (let iCh = to, iI = isolates.length; iCh > from;) {
2580
+ let sameDir = true, isNum = false;
2581
+ if (!iI || iCh > isolates[iI - 1].to) {
2582
+ let next = types[iCh - 1];
2583
+ if (next != ourType) {
2584
+ sameDir = false;
2585
+ isNum = next == 16 /* T.AN */;
2437
2586
  }
2438
2587
  }
2439
- else {
2440
- order.push(new BidiSpan(start, i, 0));
2588
+ let recurse = !sameDir && ourType == 1 /* T.L */ ? [] : null;
2589
+ let localLevel = sameDir ? level : level + 1;
2590
+ let iScan = iCh;
2591
+ run: for (;;) {
2592
+ if (iI && iScan == isolates[iI - 1].to) {
2593
+ if (isNum)
2594
+ break run;
2595
+ let iso = isolates[--iI];
2596
+ // Scan ahead to verify that there is another char in this dir after the isolate(s)
2597
+ if (!sameDir)
2598
+ for (let upto = iso.from, jI = iI;;) {
2599
+ if (upto == from)
2600
+ break run;
2601
+ if (jI && isolates[jI - 1].to == upto)
2602
+ upto = isolates[--jI].from;
2603
+ else if (types[upto - 1] == ourType)
2604
+ break run;
2605
+ else
2606
+ break;
2607
+ }
2608
+ if (recurse) {
2609
+ recurse.push(iso);
2610
+ }
2611
+ else {
2612
+ if (iso.to < iCh)
2613
+ order.push(new BidiSpan(iso.to, iCh, localLevel));
2614
+ let dirSwap = (iso.direction == LTR) != !(localLevel % 2);
2615
+ computeSectionOrder(line, dirSwap ? level + 1 : level, baseLevel, iso.inner, iso.from, iso.to, order);
2616
+ iCh = iso.from;
2617
+ }
2618
+ iScan = iso.from;
2619
+ }
2620
+ else if (iScan == from || (sameDir ? types[iScan - 1] != ourType : types[iScan - 1] == ourType)) {
2621
+ break;
2622
+ }
2623
+ else {
2624
+ iScan--;
2625
+ }
2441
2626
  }
2627
+ if (recurse)
2628
+ emitSpans(line, iScan, iCh, level + 1, baseLevel, recurse, order);
2629
+ else if (iScan < iCh)
2630
+ order.push(new BidiSpan(iScan, iCh, localLevel));
2631
+ iCh = iScan;
2442
2632
  }
2443
2633
  }
2444
- else {
2445
- for (let i = 0; i < len;) {
2446
- let start = i, rtl = types[i++] == 2 /* R */;
2447
- while (i < len && rtl == (types[i] == 2 /* R */))
2448
- i++;
2449
- order.push(new BidiSpan(start, i, rtl ? 1 : 2));
2450
- }
2451
- }
2634
+ }
2635
+ function computeSectionOrder(line, level, baseLevel, isolates, from, to, order) {
2636
+ let outerType = (level % 2 ? 2 /* T.R */ : 1 /* T.L */);
2637
+ computeCharTypes(line, from, to, isolates, outerType);
2638
+ processBracketPairs(line, from, to, isolates, outerType);
2639
+ processNeutrals(from, to, isolates, outerType);
2640
+ emitSpans(line, from, to, level, baseLevel, isolates, order);
2641
+ }
2642
+ function computeOrder(line, direction, isolates) {
2643
+ if (!line)
2644
+ return [new BidiSpan(0, 0, direction == RTL ? 1 : 0)];
2645
+ if (direction == LTR && !isolates.length && !BidiRE.test(line))
2646
+ return trivialOrder(line.length);
2647
+ if (isolates.length)
2648
+ while (line.length > types.length)
2649
+ types[types.length] = 256 /* T.NI */; // Make sure types array has no gaps
2650
+ let order = [], level = direction == LTR ? 0 : 1;
2651
+ computeSectionOrder(line, level, level, isolates, 0, line.length, order);
2452
2652
  return order;
2453
2653
  }
2454
2654
  function trivialOrder(length) {
@@ -2497,6 +2697,7 @@ function moveVisually(line, order, dir, start, forward) {
2497
2697
  }
2498
2698
 
2499
2699
  class DocView extends ContentView {
2700
+ get length() { return this.view.state.doc.length; }
2500
2701
  constructor(view) {
2501
2702
  super();
2502
2703
  this.view = view;
@@ -2528,7 +2729,6 @@ class DocView extends ContentView {
2528
2729
  this.updateDeco();
2529
2730
  this.updateInner([new ChangedRange(0, 0, 0, view.state.doc.length)], 0, null);
2530
2731
  }
2531
- get length() { return this.view.state.doc.length; }
2532
2732
  // Update the document view to a given state.
2533
2733
  update(update) {
2534
2734
  let changedRanges = update.changedRanges;
@@ -2560,7 +2760,7 @@ class DocView extends ContentView {
2560
2760
  let prevDeco = this.decorations, deco = this.updateDeco();
2561
2761
  let decoDiff = findChangedDeco(prevDeco, deco, update.changes);
2562
2762
  changedRanges = ChangedRange.extendWithRanges(changedRanges, decoDiff);
2563
- if (!(this.flags & 7 /* Dirty */) && changedRanges.length == 0) {
2763
+ if (!(this.flags & 7 /* ViewFlag.Dirty */) && changedRanges.length == 0) {
2564
2764
  return false;
2565
2765
  }
2566
2766
  else {
@@ -2589,12 +2789,12 @@ class DocView extends ContentView {
2589
2789
  // to detect that situation.
2590
2790
  let track = browser.chrome || browser.ios ? { node: observer.selectionRange.focusNode, written: false } : undefined;
2591
2791
  this.sync(this.view, track);
2592
- this.flags &= ~7 /* Dirty */;
2792
+ this.flags &= ~7 /* ViewFlag.Dirty */;
2593
2793
  if (track && (track.written || observer.selectionRange.focusNode != track.node))
2594
2794
  this.forceSelection = true;
2595
2795
  this.dom.style.height = "";
2596
2796
  });
2597
- this.markedForComposition.forEach(cView => cView.flags &= ~8 /* Composition */);
2797
+ this.markedForComposition.forEach(cView => cView.flags &= ~8 /* ViewFlag.Composition */);
2598
2798
  let gaps = [];
2599
2799
  if (this.view.viewport.from || this.view.viewport.to < this.view.state.doc.length)
2600
2800
  for (let child of this.children)
@@ -2644,7 +2844,7 @@ class DocView extends ContentView {
2644
2844
  }
2645
2845
  compositionView(composition) {
2646
2846
  let cur = new TextView(composition.text.nodeValue);
2647
- cur.flags |= 8 /* Composition */;
2847
+ cur.flags |= 8 /* ViewFlag.Composition */;
2648
2848
  for (let { deco } of composition.marks)
2649
2849
  cur = new MarkView(deco, [cur], cur.length);
2650
2850
  let line = new LineView;
@@ -2653,7 +2853,7 @@ class DocView extends ContentView {
2653
2853
  }
2654
2854
  fixCompositionDOM(composition) {
2655
2855
  let fix = (dom, cView) => {
2656
- cView.flags |= 8 /* Composition */;
2856
+ cView.flags |= 8 /* ViewFlag.Composition */;
2657
2857
  this.markedForComposition.add(cView);
2658
2858
  let prev = ContentView.get(dom);
2659
2859
  if (prev != cView) {
@@ -2715,15 +2915,15 @@ class DocView extends ContentView {
2715
2915
  // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=1612076
2716
2916
  if (browser.gecko) {
2717
2917
  let nextTo = nextToUneditable(anchor.node, anchor.offset);
2718
- if (nextTo && nextTo != (1 /* Before */ | 2 /* After */)) {
2719
- let text = nearbyTextNode(anchor.node, anchor.offset, nextTo == 1 /* Before */ ? 1 : -1);
2918
+ if (nextTo && nextTo != (1 /* NextTo.Before */ | 2 /* NextTo.After */)) {
2919
+ let text = nearbyTextNode(anchor.node, anchor.offset, nextTo == 1 /* NextTo.Before */ ? 1 : -1);
2720
2920
  if (text)
2721
- anchor = new DOMPos(text, nextTo == 1 /* Before */ ? 0 : text.nodeValue.length);
2921
+ anchor = new DOMPos(text, nextTo == 1 /* NextTo.Before */ ? 0 : text.nodeValue.length);
2722
2922
  }
2723
2923
  }
2724
2924
  rawSel.collapse(anchor.node, anchor.offset);
2725
- if (main.bidiLevel != null && domSel.cursorBidiLevel != null)
2726
- domSel.cursorBidiLevel = main.bidiLevel;
2925
+ if (main.bidiLevel != null && domSel.caretBidiLevel != null)
2926
+ domSel.caretBidiLevel = main.bidiLevel;
2727
2927
  }
2728
2928
  else if (rawSel.extend) {
2729
2929
  // Selection.extend can be used to create an 'inverted' selection
@@ -2823,6 +3023,28 @@ class DocView extends ContentView {
2823
3023
  off = start;
2824
3024
  }
2825
3025
  }
3026
+ coordsForChar(pos) {
3027
+ let { i, off } = this.childPos(pos, 1), child = this.children[i];
3028
+ if (!(child instanceof LineView))
3029
+ return null;
3030
+ while (child.children.length) {
3031
+ let { i, off: childOff } = child.childPos(off, 1);
3032
+ for (;; i++) {
3033
+ if (i == child.children.length)
3034
+ return null;
3035
+ if ((child = child.children[i]).length)
3036
+ break;
3037
+ }
3038
+ off = childOff;
3039
+ }
3040
+ if (!(child instanceof TextView))
3041
+ return null;
3042
+ let end = state.findClusterBreak(child.text, off);
3043
+ if (end == off)
3044
+ return null;
3045
+ let rects = textRange(child.dom, off, end).getClientRects();
3046
+ return !rects.length || rects[0].top >= rects[0].bottom ? null : rects[0];
3047
+ }
2826
3048
  measureVisibleLineHeights(viewport) {
2827
3049
  let result = [], { from, to } = viewport;
2828
3050
  let contentWidth = this.view.contentDOM.clientWidth;
@@ -3073,16 +3295,16 @@ function nearbyTextNode(startNode, startOffset, side) {
3073
3295
  function nextToUneditable(node, offset) {
3074
3296
  if (node.nodeType != 1)
3075
3297
  return 0;
3076
- return (offset && node.childNodes[offset - 1].contentEditable == "false" ? 1 /* Before */ : 0) |
3077
- (offset < node.childNodes.length && node.childNodes[offset].contentEditable == "false" ? 2 /* After */ : 0);
3298
+ return (offset && node.childNodes[offset - 1].contentEditable == "false" ? 1 /* NextTo.Before */ : 0) |
3299
+ (offset < node.childNodes.length && node.childNodes[offset].contentEditable == "false" ? 2 /* NextTo.After */ : 0);
3078
3300
  }
3079
- class DecorationComparator$1 {
3301
+ let DecorationComparator$1 = class DecorationComparator {
3080
3302
  constructor() {
3081
3303
  this.changes = [];
3082
3304
  }
3083
3305
  compareRange(from, to) { addRange(from, to, this.changes); }
3084
3306
  comparePoint(from, to) { addRange(from, to, this.changes); }
3085
- }
3307
+ };
3086
3308
  function findChangedDeco(a, b, diff) {
3087
3309
  let comp = new DecorationComparator$1;
3088
3310
  state.RangeSet.compare(a, b, diff, comp);
@@ -3464,6 +3686,10 @@ function skipAtoms(view, oldPos, pos) {
3464
3686
 
3465
3687
  // This will also be where dragging info and such goes
3466
3688
  class InputState {
3689
+ setSelectionOrigin(origin) {
3690
+ this.lastSelectionOrigin = origin;
3691
+ this.lastSelectionTime = Date.now();
3692
+ }
3467
3693
  constructor(view) {
3468
3694
  this.lastKeyCode = 0;
3469
3695
  this.lastKeyTime = 0;
@@ -3560,10 +3786,6 @@ class InputState {
3560
3786
  if (browser.safari)
3561
3787
  view.contentDOM.addEventListener("input", () => null);
3562
3788
  }
3563
- setSelectionOrigin(origin) {
3564
- this.lastSelectionOrigin = origin;
3565
- this.lastSelectionTime = Date.now();
3566
- }
3567
3789
  ensureHandlers(view, plugins) {
3568
3790
  var _a;
3569
3791
  let handlers;
@@ -4432,13 +4654,13 @@ const Epsilon = 1e-3;
4432
4654
  class HeightMap {
4433
4655
  constructor(length, // The number of characters covered
4434
4656
  height, // Height of this part of the document
4435
- flags = 2 /* Outdated */) {
4657
+ flags = 2 /* Flag.Outdated */) {
4436
4658
  this.length = length;
4437
4659
  this.height = height;
4438
4660
  this.flags = flags;
4439
4661
  }
4440
- get outdated() { return (this.flags & 2 /* Outdated */) > 0; }
4441
- set outdated(value) { this.flags = (value ? 2 /* Outdated */ : 0) | (this.flags & ~2 /* Outdated */); }
4662
+ get outdated() { return (this.flags & 2 /* Flag.Outdated */) > 0; }
4663
+ set outdated(value) { this.flags = (value ? 2 /* Flag.Outdated */ : 0) | (this.flags & ~2 /* Flag.Outdated */); }
4442
4664
  setHeight(oracle, height) {
4443
4665
  if (this.height != height) {
4444
4666
  if (Math.abs(this.height - height) > Epsilon)
@@ -4569,7 +4791,7 @@ class HeightMapText extends HeightMapBlock {
4569
4791
  }
4570
4792
  replace(_from, _to, nodes) {
4571
4793
  let node = nodes[0];
4572
- if (nodes.length == 1 && (node instanceof HeightMapText || node instanceof HeightMapGap && (node.flags & 4 /* SingleLine */)) &&
4794
+ if (nodes.length == 1 && (node instanceof HeightMapText || node instanceof HeightMapGap && (node.flags & 4 /* Flag.SingleLine */)) &&
4573
4795
  Math.abs(this.length - node.length) < 10) {
4574
4796
  if (node instanceof HeightMapGap)
4575
4797
  node = new HeightMapText(node.length, this.height);
@@ -4722,12 +4944,12 @@ class HeightMapGap extends HeightMap {
4722
4944
  }
4723
4945
  class HeightMapBranch extends HeightMap {
4724
4946
  constructor(left, brk, right) {
4725
- super(left.length + brk + right.length, left.height + right.height, brk | (left.outdated || right.outdated ? 2 /* Outdated */ : 0));
4947
+ super(left.length + brk + right.length, left.height + right.height, brk | (left.outdated || right.outdated ? 2 /* Flag.Outdated */ : 0));
4726
4948
  this.left = left;
4727
4949
  this.right = right;
4728
4950
  this.size = left.size + right.size;
4729
4951
  }
4730
- get break() { return this.flags & 1 /* Break */; }
4952
+ get break() { return this.flags & 1 /* Flag.Break */; }
4731
4953
  blockAt(height, oracle, top, offset) {
4732
4954
  let mid = top + this.left.height;
4733
4955
  return height < mid ? this.left.blockAt(height, oracle, top, offset)
@@ -4912,7 +5134,7 @@ class NodeBuilder {
4912
5134
  blankContent(from, to) {
4913
5135
  let gap = new HeightMapGap(to - from);
4914
5136
  if (this.oracle.doc.lineAt(from).to == to)
4915
- gap.flags |= 4 /* SingleLine */;
5137
+ gap.flags |= 4 /* Flag.SingleLine */;
4916
5138
  return gap;
4917
5139
  }
4918
5140
  ensureLine() {
@@ -5122,7 +5344,7 @@ class ViewState {
5122
5344
  }
5123
5345
  }
5124
5346
  this.viewports = viewports.sort((a, b) => a.from - b.from);
5125
- this.scaler = this.heightMap.height <= 7000000 /* MaxDOMHeight */ ? IdScaler :
5347
+ this.scaler = this.heightMap.height <= 7000000 /* VP.MaxDOMHeight */ ? IdScaler :
5126
5348
  new BigScaler(this.heightOracle, this.heightMap, this.viewports);
5127
5349
  }
5128
5350
  updateViewportLines() {
@@ -5141,7 +5363,7 @@ class ViewState {
5141
5363
  let scrollAnchor = this.scrolledToBottom ? null : this.scrollAnchorAt(this.scrollTop);
5142
5364
  this.heightMap = this.heightMap.applyChanges(this.stateDeco, update.startState.doc, this.heightOracle.setDoc(this.state.doc), heightChanges);
5143
5365
  if (this.heightMap.height != prevHeight)
5144
- update.flags |= 2 /* Height */;
5366
+ update.flags |= 2 /* UpdateFlag.Height */;
5145
5367
  if (scrollAnchor) {
5146
5368
  this.scrollAnchorPos = update.changes.mapPos(scrollAnchor.from, -1);
5147
5369
  this.scrollAnchorHeight = scrollAnchor.top;
@@ -5154,13 +5376,13 @@ class ViewState {
5154
5376
  if (scrollTarget && (scrollTarget.range.head < viewport.from || scrollTarget.range.head > viewport.to) ||
5155
5377
  !this.viewportIsAppropriate(viewport))
5156
5378
  viewport = this.getViewport(0, scrollTarget);
5157
- let updateLines = !update.changes.empty || (update.flags & 2 /* Height */) ||
5379
+ let updateLines = !update.changes.empty || (update.flags & 2 /* UpdateFlag.Height */) ||
5158
5380
  viewport.from != this.viewport.from || viewport.to != this.viewport.to;
5159
5381
  this.viewport = viewport;
5160
5382
  this.updateForViewport();
5161
5383
  if (updateLines)
5162
5384
  this.updateViewportLines();
5163
- if (this.lineGaps.length || this.viewport.to - this.viewport.from > (2000 /* Margin */ << 1))
5385
+ if (this.lineGaps.length || this.viewport.to - this.viewport.from > (2000 /* LG.Margin */ << 1))
5164
5386
  this.updateLineGaps(this.ensureLineGaps(this.mapLineGaps(this.lineGaps, update.changes)));
5165
5387
  update.flags |= this.computeVisibleRanges();
5166
5388
  if (scrollTarget)
@@ -5186,13 +5408,13 @@ class ViewState {
5186
5408
  if (this.paddingTop != paddingTop || this.paddingBottom != paddingBottom) {
5187
5409
  this.paddingTop = paddingTop;
5188
5410
  this.paddingBottom = paddingBottom;
5189
- result |= 8 /* Geometry */ | 2 /* Height */;
5411
+ result |= 8 /* UpdateFlag.Geometry */ | 2 /* UpdateFlag.Height */;
5190
5412
  }
5191
5413
  if (this.editorWidth != view.scrollDOM.clientWidth) {
5192
5414
  if (oracle.lineWrapping)
5193
5415
  measureContent = true;
5194
5416
  this.editorWidth = view.scrollDOM.clientWidth;
5195
- result |= 8 /* Geometry */;
5417
+ result |= 8 /* UpdateFlag.Geometry */;
5196
5418
  }
5197
5419
  if (this.scrollTop != view.scrollDOM.scrollTop) {
5198
5420
  this.scrollAnchorHeight = -1;
@@ -5215,7 +5437,7 @@ class ViewState {
5215
5437
  if (this.contentDOMWidth != contentWidth || this.editorHeight != view.scrollDOM.clientHeight) {
5216
5438
  this.contentDOMWidth = domRect.width;
5217
5439
  this.editorHeight = view.scrollDOM.clientHeight;
5218
- result |= 8 /* Geometry */;
5440
+ result |= 8 /* UpdateFlag.Geometry */;
5219
5441
  }
5220
5442
  if (measureContent) {
5221
5443
  let lineHeights = view.docView.measureVisibleLineHeights(this.viewport);
@@ -5226,7 +5448,7 @@ class ViewState {
5226
5448
  refresh = lineHeight > 0 && oracle.refresh(whiteSpace, lineHeight, charWidth, textHeight, contentWidth / charWidth, lineHeights);
5227
5449
  if (refresh) {
5228
5450
  view.docView.minWidth = 0;
5229
- result |= 8 /* Geometry */;
5451
+ result |= 8 /* UpdateFlag.Geometry */;
5230
5452
  }
5231
5453
  }
5232
5454
  if (dTop > 0 && dBottom > 0)
@@ -5239,7 +5461,7 @@ class ViewState {
5239
5461
  this.heightMap = (refresh ? HeightMap.empty().applyChanges(this.stateDeco, state.Text.empty, this.heightOracle, [new ChangedRange(0, 0, 0, view.state.doc.length)]) : this.heightMap).updateHeight(oracle, 0, refresh, new MeasuredHeights(vp.from, heights));
5240
5462
  }
5241
5463
  if (oracle.heightChanged)
5242
- result |= 2 /* Height */;
5464
+ result |= 2 /* UpdateFlag.Height */;
5243
5465
  }
5244
5466
  let viewportChange = !this.viewportIsAppropriate(this.viewport, bias) ||
5245
5467
  this.scrollTarget && (this.scrollTarget.range.head < this.viewport.from ||
@@ -5247,9 +5469,9 @@ class ViewState {
5247
5469
  if (viewportChange)
5248
5470
  this.viewport = this.getViewport(bias, this.scrollTarget);
5249
5471
  this.updateForViewport();
5250
- if ((result & 2 /* Height */) || viewportChange)
5472
+ if ((result & 2 /* UpdateFlag.Height */) || viewportChange)
5251
5473
  this.updateViewportLines();
5252
- if (this.lineGaps.length || this.viewport.to - this.viewport.from > (2000 /* Margin */ << 1))
5474
+ if (this.lineGaps.length || this.viewport.to - this.viewport.from > (2000 /* LG.Margin */ << 1))
5253
5475
  this.updateLineGaps(this.ensureLineGaps(refresh ? [] : this.lineGaps, view));
5254
5476
  result |= this.computeVisibleRanges();
5255
5477
  if (this.mustEnforceCursorAssoc) {
@@ -5268,10 +5490,10 @@ class ViewState {
5268
5490
  // This will divide VP.Margin between the top and the
5269
5491
  // bottom, depending on the bias (the change in viewport position
5270
5492
  // since the last update). It'll hold a number between 0 and 1
5271
- let marginTop = 0.5 - Math.max(-0.5, Math.min(0.5, bias / 1000 /* Margin */ / 2));
5493
+ let marginTop = 0.5 - Math.max(-0.5, Math.min(0.5, bias / 1000 /* VP.Margin */ / 2));
5272
5494
  let map = this.heightMap, oracle = this.heightOracle;
5273
5495
  let { visibleTop, visibleBottom } = this;
5274
- let viewport = new Viewport(map.lineAt(visibleTop - marginTop * 1000 /* Margin */, QueryType.ByHeight, oracle, 0, 0).from, map.lineAt(visibleBottom + (1 - marginTop) * 1000 /* Margin */, QueryType.ByHeight, oracle, 0, 0).to);
5496
+ let viewport = new Viewport(map.lineAt(visibleTop - marginTop * 1000 /* VP.Margin */, QueryType.ByHeight, oracle, 0, 0).from, map.lineAt(visibleBottom + (1 - marginTop) * 1000 /* VP.Margin */, QueryType.ByHeight, oracle, 0, 0).to);
5275
5497
  // If scrollTarget is given, make sure the viewport includes that position
5276
5498
  if (scrollTarget) {
5277
5499
  let { head } = scrollTarget.range;
@@ -5284,7 +5506,7 @@ class ViewState {
5284
5506
  topPos = block.top;
5285
5507
  else
5286
5508
  topPos = block.bottom - viewHeight;
5287
- viewport = new Viewport(map.lineAt(topPos - 1000 /* Margin */ / 2, QueryType.ByHeight, oracle, 0, 0).from, map.lineAt(topPos + viewHeight + 1000 /* Margin */ / 2, QueryType.ByHeight, oracle, 0, 0).to);
5509
+ viewport = new Viewport(map.lineAt(topPos - 1000 /* VP.Margin */ / 2, QueryType.ByHeight, oracle, 0, 0).from, map.lineAt(topPos + viewHeight + 1000 /* VP.Margin */ / 2, QueryType.ByHeight, oracle, 0, 0).to);
5288
5510
  }
5289
5511
  }
5290
5512
  return viewport;
@@ -5301,10 +5523,10 @@ class ViewState {
5301
5523
  let { top } = this.heightMap.lineAt(from, QueryType.ByPos, this.heightOracle, 0, 0);
5302
5524
  let { bottom } = this.heightMap.lineAt(to, QueryType.ByPos, this.heightOracle, 0, 0);
5303
5525
  let { visibleTop, visibleBottom } = this;
5304
- return (from == 0 || top <= visibleTop - Math.max(10 /* MinCoverMargin */, Math.min(-bias, 250 /* MaxCoverMargin */))) &&
5526
+ return (from == 0 || top <= visibleTop - Math.max(10 /* VP.MinCoverMargin */, Math.min(-bias, 250 /* VP.MaxCoverMargin */))) &&
5305
5527
  (to == this.state.doc.length ||
5306
- bottom >= visibleBottom + Math.max(10 /* MinCoverMargin */, Math.min(bias, 250 /* MaxCoverMargin */))) &&
5307
- (top > visibleTop - 2 * 1000 /* Margin */ && bottom < visibleBottom + 2 * 1000 /* Margin */);
5528
+ bottom >= visibleBottom + Math.max(10 /* VP.MinCoverMargin */, Math.min(bias, 250 /* VP.MaxCoverMargin */))) &&
5529
+ (top > visibleTop - 2 * 1000 /* VP.Margin */ && bottom < visibleBottom + 2 * 1000 /* VP.Margin */);
5308
5530
  }
5309
5531
  mapLineGaps(gaps, changes) {
5310
5532
  if (!gaps.length || changes.empty)
@@ -5324,7 +5546,7 @@ class ViewState {
5324
5546
  // the artifacts this might produce from the user.
5325
5547
  ensureLineGaps(current, mayMeasure) {
5326
5548
  let wrapping = this.heightOracle.lineWrapping;
5327
- let margin = wrapping ? 10000 /* MarginWrap */ : 2000 /* Margin */, halfMargin = margin >> 1, doubleMargin = margin << 1;
5549
+ let margin = wrapping ? 10000 /* LG.MarginWrap */ : 2000 /* LG.Margin */, halfMargin = margin >> 1, doubleMargin = margin << 1;
5328
5550
  // The non-wrapping logic won't work at all in predominantly right-to-left text.
5329
5551
  if (this.defaultTextDirection != exports.Direction.LTR && !wrapping)
5330
5552
  return [];
@@ -5337,8 +5559,8 @@ class ViewState {
5337
5559
  avoid.push(sel.to);
5338
5560
  for (let pos of avoid) {
5339
5561
  if (pos > from && pos < to) {
5340
- addGap(from, pos - 10 /* SelectionMargin */, line, structure);
5341
- addGap(pos + 10 /* SelectionMargin */, to, line, structure);
5562
+ addGap(from, pos - 10 /* LG.SelectionMargin */, line, structure);
5563
+ addGap(pos + 10 /* LG.SelectionMargin */, to, line, structure);
5342
5564
  return;
5343
5565
  }
5344
5566
  }
@@ -5432,7 +5654,7 @@ class ViewState {
5432
5654
  let changed = ranges.length != this.visibleRanges.length ||
5433
5655
  this.visibleRanges.some((r, i) => r.from != ranges[i].from || r.to != ranges[i].to);
5434
5656
  this.visibleRanges = ranges;
5435
- return changed ? 4 /* Viewport */ : 0;
5657
+ return changed ? 4 /* UpdateFlag.Viewport */ : 0;
5436
5658
  }
5437
5659
  lineBlockAt(pos) {
5438
5660
  return (pos >= this.viewport.from && pos <= this.viewport.to && this.viewportLines.find(b => b.from <= pos && b.to >= pos)) ||
@@ -5528,7 +5750,7 @@ class BigScaler {
5528
5750
  vpHeight += bottom - top;
5529
5751
  return { from, to, top, bottom, domTop: 0, domBottom: 0 };
5530
5752
  });
5531
- this.scale = (7000000 /* MaxDOMHeight */ - vpHeight) / (heightMap.height - vpHeight);
5753
+ this.scale = (7000000 /* VP.MaxDOMHeight */ - vpHeight) / (heightMap.height - vpHeight);
5532
5754
  for (let obj of this.viewports) {
5533
5755
  obj.domTop = domBase + (obj.top - base) * this.scale;
5534
5756
  domBase = obj.domBottom = obj.domTop + (obj.bottom - obj.top);
@@ -5695,7 +5917,7 @@ const baseTheme$1 = buildTheme("." + baseThemeID, {
5695
5917
  display: "flex",
5696
5918
  height: "100%",
5697
5919
  boxSizing: "border-box",
5698
- left: 0,
5920
+ insetInlineStart: 0,
5699
5921
  zIndex: 200
5700
5922
  },
5701
5923
  "&light .cm-gutters": {
@@ -5911,7 +6133,6 @@ function applyDOMChange(view, domChange) {
5911
6133
  change = { from: sel.from, to: sel.to, insert: state.Text.of([" "]) };
5912
6134
  }
5913
6135
  if (change) {
5914
- let startState = view.state;
5915
6136
  if (browser.ios && view.inputState.flushIOSKey(view))
5916
6137
  return true;
5917
6138
  // Android browsers don't fire reasonable key events for enter,
@@ -5931,64 +6152,12 @@ function applyDOMChange(view, domChange) {
5931
6152
  dispatchKey(view.contentDOM, "Delete", 46))))
5932
6153
  return true;
5933
6154
  let text = change.insert.toString();
5934
- if (view.state.facet(inputHandler).some(h => h(view, change.from, change.to, text)))
5935
- return true;
5936
6155
  if (view.inputState.composing >= 0)
5937
6156
  view.inputState.composing++;
5938
- let tr;
5939
- if (change.from >= sel.from && change.to <= sel.to && change.to - change.from >= (sel.to - sel.from) / 3 &&
5940
- (!newSel || newSel.main.empty && newSel.main.from == change.from + change.insert.length) &&
5941
- view.inputState.composing < 0) {
5942
- let before = sel.from < change.from ? startState.sliceDoc(sel.from, change.from) : "";
5943
- let after = sel.to > change.to ? startState.sliceDoc(change.to, sel.to) : "";
5944
- tr = startState.replaceSelection(view.state.toText(before + change.insert.sliceString(0, undefined, view.state.lineBreak) + after));
5945
- }
5946
- else {
5947
- let changes = startState.changes(change);
5948
- let mainSel = newSel && newSel.main.to <= changes.newLength ? newSel.main : undefined;
5949
- // Try to apply a composition change to all cursors
5950
- if (startState.selection.ranges.length > 1 && view.inputState.composing >= 0 &&
5951
- change.to <= sel.to && change.to >= sel.to - 10) {
5952
- let replaced = view.state.sliceDoc(change.from, change.to);
5953
- let composition = findCompositionNode(view) || view.state.doc.lineAt(sel.head);
5954
- let offset = sel.to - change.to, size = sel.to - sel.from;
5955
- tr = startState.changeByRange(range => {
5956
- if (range.from == sel.from && range.to == sel.to)
5957
- return { changes, range: mainSel || range.map(changes) };
5958
- let to = range.to - offset, from = to - replaced.length;
5959
- if (range.to - range.from != size || view.state.sliceDoc(from, to) != replaced ||
5960
- // Unfortunately, there's no way to make multiple
5961
- // changes in the same node work without aborting
5962
- // composition, so cursors in the composition range are
5963
- // ignored.
5964
- composition && range.to >= composition.from && range.from <= composition.to)
5965
- return { range };
5966
- let rangeChanges = startState.changes({ from, to, insert: change.insert }), selOff = range.to - sel.to;
5967
- return {
5968
- changes: rangeChanges,
5969
- range: !mainSel ? range.map(rangeChanges) :
5970
- state.EditorSelection.range(Math.max(0, mainSel.anchor + selOff), Math.max(0, mainSel.head + selOff))
5971
- };
5972
- });
5973
- }
5974
- else {
5975
- tr = {
5976
- changes,
5977
- selection: mainSel && startState.selection.replaceRange(mainSel)
5978
- };
5979
- }
5980
- }
5981
- let userEvent = "input.type";
5982
- if (view.composing ||
5983
- view.inputState.compositionPendingChange && view.inputState.compositionEndedAt > Date.now() - 50) {
5984
- view.inputState.compositionPendingChange = false;
5985
- userEvent += ".compose";
5986
- if (view.inputState.compositionFirstChange) {
5987
- userEvent += ".start";
5988
- view.inputState.compositionFirstChange = false;
5989
- }
5990
- }
5991
- view.dispatch(tr, { scrollIntoView: true, userEvent });
6157
+ let defaultTr;
6158
+ let defaultInsert = () => defaultTr || (defaultTr = applyDefaultInsert(view, change, newSel));
6159
+ if (!view.state.facet(inputHandler).some(h => h(view, change.from, change.to, text, defaultInsert)))
6160
+ view.dispatch(defaultInsert());
5992
6161
  return true;
5993
6162
  }
5994
6163
  else if (newSel && !newSel.main.eq(sel)) {
@@ -6005,6 +6174,62 @@ function applyDOMChange(view, domChange) {
6005
6174
  return false;
6006
6175
  }
6007
6176
  }
6177
+ function applyDefaultInsert(view, change, newSel) {
6178
+ let tr, startState = view.state, sel = startState.selection.main;
6179
+ if (change.from >= sel.from && change.to <= sel.to && change.to - change.from >= (sel.to - sel.from) / 3 &&
6180
+ (!newSel || newSel.main.empty && newSel.main.from == change.from + change.insert.length) &&
6181
+ view.inputState.composing < 0) {
6182
+ let before = sel.from < change.from ? startState.sliceDoc(sel.from, change.from) : "";
6183
+ let after = sel.to > change.to ? startState.sliceDoc(change.to, sel.to) : "";
6184
+ tr = startState.replaceSelection(view.state.toText(before + change.insert.sliceString(0, undefined, view.state.lineBreak) + after));
6185
+ }
6186
+ else {
6187
+ let changes = startState.changes(change);
6188
+ let mainSel = newSel && newSel.main.to <= changes.newLength ? newSel.main : undefined;
6189
+ // Try to apply a composition change to all cursors
6190
+ if (startState.selection.ranges.length > 1 && view.inputState.composing >= 0 &&
6191
+ change.to <= sel.to && change.to >= sel.to - 10) {
6192
+ let replaced = view.state.sliceDoc(change.from, change.to);
6193
+ let composition = findCompositionNode(view) || view.state.doc.lineAt(sel.head);
6194
+ let offset = sel.to - change.to, size = sel.to - sel.from;
6195
+ tr = startState.changeByRange(range => {
6196
+ if (range.from == sel.from && range.to == sel.to)
6197
+ return { changes, range: mainSel || range.map(changes) };
6198
+ let to = range.to - offset, from = to - replaced.length;
6199
+ if (range.to - range.from != size || view.state.sliceDoc(from, to) != replaced ||
6200
+ // Unfortunately, there's no way to make multiple
6201
+ // changes in the same node work without aborting
6202
+ // composition, so cursors in the composition range are
6203
+ // ignored.
6204
+ composition && range.to >= composition.from && range.from <= composition.to)
6205
+ return { range };
6206
+ let rangeChanges = startState.changes({ from, to, insert: change.insert }), selOff = range.to - sel.to;
6207
+ return {
6208
+ changes: rangeChanges,
6209
+ range: !mainSel ? range.map(rangeChanges) :
6210
+ state.EditorSelection.range(Math.max(0, mainSel.anchor + selOff), Math.max(0, mainSel.head + selOff))
6211
+ };
6212
+ });
6213
+ }
6214
+ else {
6215
+ tr = {
6216
+ changes,
6217
+ selection: mainSel && startState.selection.replaceRange(mainSel)
6218
+ };
6219
+ }
6220
+ }
6221
+ let userEvent = "input.type";
6222
+ if (view.composing ||
6223
+ view.inputState.compositionPendingChange && view.inputState.compositionEndedAt > Date.now() - 50) {
6224
+ view.inputState.compositionPendingChange = false;
6225
+ userEvent += ".compose";
6226
+ if (view.inputState.compositionFirstChange) {
6227
+ userEvent += ".start";
6228
+ view.inputState.compositionFirstChange = false;
6229
+ }
6230
+ }
6231
+ return startState.update(tr, { userEvent, scrollIntoView: true });
6232
+ }
6008
6233
  function findDiff(a, b, preferredPos, preferredSide) {
6009
6234
  let minLen = Math.min(a.length, b.length);
6010
6235
  let from = 0;
@@ -6422,7 +6647,7 @@ class DOMObserver {
6422
6647
  return null;
6423
6648
  cView.markDirty(rec.type == "attributes");
6424
6649
  if (rec.type == "attributes")
6425
- cView.flags |= 4 /* AttrsDirty */;
6650
+ cView.flags |= 4 /* ViewFlag.AttrsDirty */;
6426
6651
  if (rec.type == "childList") {
6427
6652
  let childBefore = findChild(cView, rec.previousSibling || rec.target.previousSibling, -1);
6428
6653
  let childAfter = findChild(cView, rec.nextSibling || rec.target.nextSibling, 1);
@@ -6530,6 +6755,53 @@ line number gutter. It handles events and dispatches state
6530
6755
  transactions for editing actions.
6531
6756
  */
6532
6757
  class EditorView {
6758
+ /**
6759
+ The current editor state.
6760
+ */
6761
+ get state() { return this.viewState.state; }
6762
+ /**
6763
+ To be able to display large documents without consuming too much
6764
+ memory or overloading the browser, CodeMirror only draws the
6765
+ code that is visible (plus a margin around it) to the DOM. This
6766
+ property tells you the extent of the current drawn viewport, in
6767
+ document positions.
6768
+ */
6769
+ get viewport() { return this.viewState.viewport; }
6770
+ /**
6771
+ When there are, for example, large collapsed ranges in the
6772
+ viewport, its size can be a lot bigger than the actual visible
6773
+ content. Thus, if you are doing something like styling the
6774
+ content in the viewport, it is preferable to only do so for
6775
+ these ranges, which are the subset of the viewport that is
6776
+ actually drawn.
6777
+ */
6778
+ get visibleRanges() { return this.viewState.visibleRanges; }
6779
+ /**
6780
+ Returns false when the editor is entirely scrolled out of view
6781
+ or otherwise hidden.
6782
+ */
6783
+ get inView() { return this.viewState.inView; }
6784
+ /**
6785
+ Indicates whether the user is currently composing text via
6786
+ [IME](https://en.wikipedia.org/wiki/Input_method), and at least
6787
+ one change has been made in the current composition.
6788
+ */
6789
+ get composing() { return this.inputState.composing > 0; }
6790
+ /**
6791
+ Indicates whether the user is currently in composing state. Note
6792
+ that on some platforms, like Android, this will be the case a
6793
+ lot, since just putting the cursor on a word starts a
6794
+ composition there.
6795
+ */
6796
+ get compositionStarted() { return this.inputState.composing >= 0; }
6797
+ /**
6798
+ The document or shadow root that the view lives in.
6799
+ */
6800
+ get root() { return this._root; }
6801
+ /**
6802
+ @internal
6803
+ */
6804
+ get win() { return this.dom.ownerDocument.defaultView || window; }
6533
6805
  /**
6534
6806
  Construct a new view. You'll want to either provide a `parent`
6535
6807
  option, or put `view.dom` into your document after creating a
@@ -6545,7 +6817,7 @@ class EditorView {
6545
6817
  /**
6546
6818
  @internal
6547
6819
  */
6548
- this.updateState = 2 /* Updating */;
6820
+ this.updateState = 2 /* UpdateState.Updating */;
6549
6821
  /**
6550
6822
  @internal
6551
6823
  */
@@ -6565,7 +6837,10 @@ class EditorView {
6565
6837
  this.dom = document.createElement("div");
6566
6838
  this.dom.appendChild(this.announceDOM);
6567
6839
  this.dom.appendChild(this.scrollDOM);
6568
- this._dispatch = config.dispatch || ((tr) => this.update([tr]));
6840
+ let { dispatch } = config;
6841
+ this.dispatchTransactions = config.dispatchTransactions ||
6842
+ (dispatch && ((trs) => trs.forEach(tr => dispatch(tr, this)))) ||
6843
+ ((trs) => this.update(trs));
6569
6844
  this.dispatch = this.dispatch.bind(this);
6570
6845
  this._root = (config.root || getRoot(config.parent) || document);
6571
6846
  this.viewState = new ViewState(config.state || state.EditorState.create(config));
@@ -6578,62 +6853,16 @@ class EditorView {
6578
6853
  this.docView = new DocView(this);
6579
6854
  this.mountStyles();
6580
6855
  this.updateAttrs();
6581
- this.updateState = 0 /* Idle */;
6856
+ this.updateState = 0 /* UpdateState.Idle */;
6582
6857
  this.requestMeasure();
6583
6858
  if (config.parent)
6584
6859
  config.parent.appendChild(this.dom);
6585
6860
  }
6586
- /**
6587
- The current editor state.
6588
- */
6589
- get state() { return this.viewState.state; }
6590
- /**
6591
- To be able to display large documents without consuming too much
6592
- memory or overloading the browser, CodeMirror only draws the
6593
- code that is visible (plus a margin around it) to the DOM. This
6594
- property tells you the extent of the current drawn viewport, in
6595
- document positions.
6596
- */
6597
- get viewport() { return this.viewState.viewport; }
6598
- /**
6599
- When there are, for example, large collapsed ranges in the
6600
- viewport, its size can be a lot bigger than the actual visible
6601
- content. Thus, if you are doing something like styling the
6602
- content in the viewport, it is preferable to only do so for
6603
- these ranges, which are the subset of the viewport that is
6604
- actually drawn.
6605
- */
6606
- get visibleRanges() { return this.viewState.visibleRanges; }
6607
- /**
6608
- Returns false when the editor is entirely scrolled out of view
6609
- or otherwise hidden.
6610
- */
6611
- get inView() { return this.viewState.inView; }
6612
- /**
6613
- Indicates whether the user is currently composing text via
6614
- [IME](https://en.wikipedia.org/wiki/Input_method), and at least
6615
- one change has been made in the current composition.
6616
- */
6617
- get composing() { return this.inputState.composing > 0; }
6618
- /**
6619
- Indicates whether the user is currently in composing state. Note
6620
- that on some platforms, like Android, this will be the case a
6621
- lot, since just putting the cursor on a word starts a
6622
- composition there.
6623
- */
6624
- get compositionStarted() { return this.inputState.composing >= 0; }
6625
- /**
6626
- The document or shadow root that the view lives in.
6627
- */
6628
- get root() { return this._root; }
6629
- /**
6630
- @internal
6631
- */
6632
- get win() { return this.dom.ownerDocument.defaultView || window; }
6633
6861
  dispatch(...input) {
6634
- let tr = input.length == 1 && input[0] instanceof state.Transaction ? input[0]
6635
- : this.state.update(...input);
6636
- this._dispatch(tr, this);
6862
+ let trs = input.length == 1 && input[0] instanceof state.Transaction ? input
6863
+ : input.length == 1 && Array.isArray(input[0]) ? input[0]
6864
+ : [this.state.update(...input)];
6865
+ this.dispatchTransactions(trs, this);
6637
6866
  }
6638
6867
  /**
6639
6868
  Update the view for the given array of transactions. This will
@@ -6644,7 +6873,7 @@ class EditorView {
6644
6873
  as a primitive.
6645
6874
  */
6646
6875
  update(transactions) {
6647
- if (this.updateState != 0 /* Idle */)
6876
+ if (this.updateState != 0 /* UpdateState.Idle */)
6648
6877
  throw new Error("Calls to EditorView.update are not allowed while an update is in progress");
6649
6878
  let redrawn = false, attrsChanged = false, update;
6650
6879
  let state$1 = this.state;
@@ -6661,7 +6890,7 @@ class EditorView {
6661
6890
  if (transactions.some(tr => tr.annotation(isFocusChange))) {
6662
6891
  this.inputState.notifiedFocused = focus;
6663
6892
  // If a focus-change transaction is being dispatched, set this update flag.
6664
- focusFlag = 1 /* Focus */;
6893
+ focusFlag = 1 /* UpdateFlag.Focus */;
6665
6894
  }
6666
6895
  else if (focus != this.inputState.notifiedFocused) {
6667
6896
  this.inputState.notifiedFocused = focus;
@@ -6669,7 +6898,7 @@ class EditorView {
6669
6898
  // add a flag to this update
6670
6899
  dispatchFocus = focusChangeTransaction(state$1, focus);
6671
6900
  if (!dispatchFocus)
6672
- focusFlag = 1 /* Focus */;
6901
+ focusFlag = 1 /* UpdateFlag.Focus */;
6673
6902
  }
6674
6903
  // If there was a pending DOM change, eagerly read it and try to
6675
6904
  // apply it after the given transactions.
@@ -6692,7 +6921,7 @@ class EditorView {
6692
6921
  update.flags |= focusFlag;
6693
6922
  let scrollTarget = this.viewState.scrollTarget;
6694
6923
  try {
6695
- this.updateState = 2 /* Updating */;
6924
+ this.updateState = 2 /* UpdateState.Updating */;
6696
6925
  for (let tr of transactions) {
6697
6926
  if (scrollTarget)
6698
6927
  scrollTarget = scrollTarget.map(tr.changes);
@@ -6718,7 +6947,7 @@ class EditorView {
6718
6947
  this.docView.updateSelection(redrawn, transactions.some(tr => tr.isUserEvent("select.pointer")));
6719
6948
  }
6720
6949
  finally {
6721
- this.updateState = 0 /* Idle */;
6950
+ this.updateState = 0 /* UpdateState.Idle */;
6722
6951
  }
6723
6952
  if (update.startState.facet(theme) != update.state.facet(theme))
6724
6953
  this.viewState.mustMeasureContent = true;
@@ -6745,13 +6974,13 @@ class EditorView {
6745
6974
  [`dispatch`](https://codemirror.net/6/docs/ref/#view.EditorView.dispatch) instead.)
6746
6975
  */
6747
6976
  setState(newState) {
6748
- if (this.updateState != 0 /* Idle */)
6977
+ if (this.updateState != 0 /* UpdateState.Idle */)
6749
6978
  throw new Error("Calls to EditorView.setState are not allowed while an update is in progress");
6750
6979
  if (this.destroyed) {
6751
6980
  this.viewState.state = newState;
6752
6981
  return;
6753
6982
  }
6754
- this.updateState = 2 /* Updating */;
6983
+ this.updateState = 2 /* UpdateState.Updating */;
6755
6984
  let hadFocus = this.hasFocus;
6756
6985
  try {
6757
6986
  for (let plugin of this.plugins)
@@ -6768,7 +6997,7 @@ class EditorView {
6768
6997
  this.bidiCache = [];
6769
6998
  }
6770
6999
  finally {
6771
- this.updateState = 0 /* Idle */;
7000
+ this.updateState = 0 /* UpdateState.Idle */;
6772
7001
  }
6773
7002
  if (hadFocus)
6774
7003
  this.focus();
@@ -6833,7 +7062,7 @@ class EditorView {
6833
7062
  scrollAnchorHeight = block.top;
6834
7063
  }
6835
7064
  }
6836
- this.updateState = 1 /* Measuring */;
7065
+ this.updateState = 1 /* UpdateState.Measuring */;
6837
7066
  let changed = this.viewState.measure(this);
6838
7067
  if (!changed && !this.measureRequests.length && this.viewState.scrollTarget == null)
6839
7068
  break;
@@ -6845,7 +7074,7 @@ class EditorView {
6845
7074
  }
6846
7075
  let measuring = [];
6847
7076
  // Only run measure requests in this cycle when the viewport didn't change
6848
- if (!(changed & 4 /* Viewport */))
7077
+ if (!(changed & 4 /* UpdateFlag.Viewport */))
6849
7078
  [this.measureRequests, measuring] = [measuring, this.measureRequests];
6850
7079
  let measured = measuring.map(m => {
6851
7080
  try {
@@ -6862,7 +7091,7 @@ class EditorView {
6862
7091
  updated = update;
6863
7092
  else
6864
7093
  updated.flags |= changed;
6865
- this.updateState = 2 /* Updating */;
7094
+ this.updateState = 2 /* UpdateState.Updating */;
6866
7095
  if (!update.empty) {
6867
7096
  this.updatePlugins(update);
6868
7097
  this.inputState.update(update);
@@ -6905,7 +7134,7 @@ class EditorView {
6905
7134
  }
6906
7135
  }
6907
7136
  finally {
6908
- this.updateState = 0 /* Idle */;
7137
+ this.updateState = 0 /* UpdateState.Idle */;
6909
7138
  this.measureScheduled = -1;
6910
7139
  }
6911
7140
  if (updated && !updated.empty)
@@ -6961,12 +7190,13 @@ class EditorView {
6961
7190
  }
6962
7191
  mountStyles() {
6963
7192
  this.styleModules = this.state.facet(styleModule);
6964
- styleMod.StyleModule.mount(this.root, this.styleModules.concat(baseTheme$1).reverse());
7193
+ let nonce = this.state.facet(EditorView.cspNonce);
7194
+ styleMod.StyleModule.mount(this.root, this.styleModules.concat(baseTheme$1).reverse(), nonce ? { nonce } : undefined);
6965
7195
  }
6966
7196
  readMeasured() {
6967
- if (this.updateState == 2 /* Updating */)
7197
+ if (this.updateState == 2 /* UpdateState.Updating */)
6968
7198
  throw new Error("Reading the editor layout isn't allowed during an update");
6969
- if (this.updateState == 0 /* Idle */ && this.measureScheduled > -1)
7199
+ if (this.updateState == 0 /* UpdateState.Idle */ && this.measureScheduled > -1)
6970
7200
  this.measure(false);
6971
7201
  }
6972
7202
  /**
@@ -7159,6 +7389,17 @@ class EditorView {
7159
7389
  return flattenRect(rect, (span.dir == exports.Direction.LTR) == (side > 0));
7160
7390
  }
7161
7391
  /**
7392
+ Return the rectangle around a given character. If `pos` does not
7393
+ point in front of a character that is in the viewport and
7394
+ rendered (i.e. not replaced, not a line break), this will return
7395
+ null. For space characters that are a line wrap point, this will
7396
+ return the position before the line break.
7397
+ */
7398
+ coordsForChar(pos) {
7399
+ this.readMeasured();
7400
+ return this.docView.coordsForChar(pos);
7401
+ }
7402
+ /**
7162
7403
  The default width of a character in the editor. May not
7163
7404
  accurately reflect the width of all characters (given variable
7164
7405
  width fonts or styling of invididual ranges).
@@ -7209,12 +7450,16 @@ class EditorView {
7209
7450
  bidiSpans(line) {
7210
7451
  if (line.length > MaxBidiLine)
7211
7452
  return trivialOrder(line.length);
7212
- let dir = this.textDirectionAt(line.from);
7213
- for (let entry of this.bidiCache)
7214
- if (entry.from == line.from && entry.dir == dir)
7453
+ let dir = this.textDirectionAt(line.from), isolates;
7454
+ for (let entry of this.bidiCache) {
7455
+ if (entry.from == line.from && entry.dir == dir &&
7456
+ (entry.fresh || isolatesEq(entry.isolates, isolates = getIsolatedRanges(this, line.from, line.to))))
7215
7457
  return entry.order;
7216
- let order = computeOrder(line.text, dir);
7217
- this.bidiCache.push(new CachedOrder(line.from, line.to, dir, order));
7458
+ }
7459
+ if (!isolates)
7460
+ isolates = getIsolatedRanges(this, line.from, line.to);
7461
+ let order = computeOrder(line.text, dir, isolates);
7462
+ this.bidiCache.push(new CachedOrder(line.from, line.to, dir, isolates, true, order));
7218
7463
  return order;
7219
7464
  }
7220
7465
  /**
@@ -7349,6 +7594,10 @@ DOM content are handled. Handlers are passed the document
7349
7594
  positions between which the change was found, and the new
7350
7595
  content. When one returns true, no further input handlers are
7351
7596
  called and the default behavior is prevented.
7597
+
7598
+ The `insert` argument can be used to get the default transaction
7599
+ that would be applied for this input. This can be useful when
7600
+ dispatching the custom behavior as a separate transaction.
7352
7601
  */
7353
7602
  EditorView.inputHandler = inputHandler;
7354
7603
  /**
@@ -7436,6 +7685,16 @@ regions.
7436
7685
  */
7437
7686
  EditorView.atomicRanges = atomicRanges;
7438
7687
  /**
7688
+ When range decorations add a `unicode-bidi: isolate` style, they
7689
+ should also include a
7690
+ [`bidiIsolate`](https://codemirror.net/6/docs/ref/#view.MarkDecorationSpec.bidiIsolate) property
7691
+ in their decoration spec, and be exposed through this facet, so
7692
+ that the editor can compute the proper text order. (Other values
7693
+ for `unicode-bidi`, except of course `normal`, are not
7694
+ supported.)
7695
+ */
7696
+ EditorView.bidiIsolatedRanges = bidiIsolatedRanges;
7697
+ /**
7439
7698
  Facet that allows extensions to provide additional scroll
7440
7699
  margins (space around the sides of the scrolling element that
7441
7700
  should be considered invisible). This can be useful when the
@@ -7451,6 +7710,12 @@ true.
7451
7710
  */
7452
7711
  EditorView.darkTheme = darkTheme;
7453
7712
  /**
7713
+ Provides a Content Security Policy nonce to use when creating
7714
+ the style sheets for the editor. Holds the empty string when no
7715
+ nonce has been provided.
7716
+ */
7717
+ EditorView.cspNonce = state.Facet.define({ combine: values => values.length ? values[0] : "" });
7718
+ /**
7454
7719
  Facet that provides additional DOM attributes for the editor's
7455
7720
  editable DOM element.
7456
7721
  */
@@ -7478,20 +7743,22 @@ EditorView.announce = state.StateEffect.define();
7478
7743
  const MaxBidiLine = 4096;
7479
7744
  const BadMeasure = {};
7480
7745
  class CachedOrder {
7481
- constructor(from, to, dir, order) {
7746
+ constructor(from, to, dir, isolates, fresh, order) {
7482
7747
  this.from = from;
7483
7748
  this.to = to;
7484
7749
  this.dir = dir;
7750
+ this.isolates = isolates;
7751
+ this.fresh = fresh;
7485
7752
  this.order = order;
7486
7753
  }
7487
7754
  static update(cache, changes) {
7488
- if (changes.empty)
7755
+ if (changes.empty && !cache.some(c => c.fresh))
7489
7756
  return cache;
7490
7757
  let result = [], lastDir = cache.length ? cache[cache.length - 1].dir : exports.Direction.LTR;
7491
7758
  for (let i = Math.max(0, cache.length - 10); i < cache.length; i++) {
7492
7759
  let entry = cache[i];
7493
7760
  if (entry.dir == lastDir && !changes.touchesRange(entry.from, entry.to))
7494
- result.push(new CachedOrder(changes.mapPos(entry.from, 1), changes.mapPos(entry.to, -1), entry.dir, entry.order));
7761
+ result.push(new CachedOrder(changes.mapPos(entry.from, 1), changes.mapPos(entry.to, -1), entry.dir, entry.isolates, false, entry.order));
7495
7762
  }
7496
7763
  return result;
7497
7764
  }
@@ -7814,7 +8081,7 @@ function rectanglesForRange(view, className, range) {
7814
8081
  return pieces(top).concat(between).concat(pieces(bottom));
7815
8082
  }
7816
8083
  function piece(left, top, right, bottom) {
7817
- return new RectangleMarker(className, left - base.left, top - base.top - 0.01 /* Epsilon */, right - left, bottom - top + 0.01 /* Epsilon */);
8084
+ return new RectangleMarker(className, left - base.left, top - base.top - 0.01 /* C.Epsilon */, right - left, bottom - top + 0.01 /* C.Epsilon */);
7818
8085
  }
7819
8086
  function pieces({ top, bottom, horizontal }) {
7820
8087
  let pieces = [];
@@ -8831,12 +9098,12 @@ const tooltipPlugin = ViewPlugin.fromClass(class {
8831
9098
  continue;
8832
9099
  }
8833
9100
  let arrow = tooltip.arrow ? tView.dom.querySelector(".cm-tooltip-arrow") : null;
8834
- let arrowHeight = arrow ? 7 /* Size */ : 0;
9101
+ let arrowHeight = arrow ? 7 /* Arrow.Size */ : 0;
8835
9102
  let width = size.right - size.left, height = (_a = knownHeight.get(tView)) !== null && _a !== void 0 ? _a : size.bottom - size.top;
8836
9103
  let offset = tView.offset || noOffset, ltr = this.view.textDirection == exports.Direction.LTR;
8837
9104
  let left = size.width > space.right - space.left ? (ltr ? space.left : space.right - size.width)
8838
- : ltr ? Math.min(pos.left - (arrow ? 14 /* Offset */ : 0) + offset.x, space.right - width)
8839
- : Math.max(space.left, pos.left - width + (arrow ? 14 /* Offset */ : 0) - offset.x);
9105
+ : ltr ? Math.min(pos.left - (arrow ? 14 /* Arrow.Offset */ : 0) + offset.x, space.right - width)
9106
+ : Math.max(space.left, pos.left - width + (arrow ? 14 /* Arrow.Offset */ : 0) - offset.x);
8840
9107
  let above = !!tooltip.above;
8841
9108
  if (!tooltip.strictSide && (above
8842
9109
  ? pos.top - (size.bottom - size.top) - offset.y < space.top
@@ -8870,7 +9137,7 @@ const tooltipPlugin = ViewPlugin.fromClass(class {
8870
9137
  dom.style.left = left + "px";
8871
9138
  }
8872
9139
  if (arrow)
8873
- arrow.style.left = `${pos.left + (ltr ? offset.x : -offset.x) - (left + 14 /* Offset */ - 7 /* Size */)}px`;
9140
+ arrow.style.left = `${pos.left + (ltr ? offset.x : -offset.x) - (left + 14 /* Arrow.Offset */ - 7 /* Arrow.Size */)}px`;
8874
9141
  if (tView.overlap !== true)
8875
9142
  others.push({ left, top, right, bottom: top + height });
8876
9143
  dom.classList.toggle("cm-tooltip-above", above);
@@ -8913,8 +9180,8 @@ const baseTheme = EditorView.baseTheme({
8913
9180
  color: "white"
8914
9181
  },
8915
9182
  ".cm-tooltip-arrow": {
8916
- height: `${7 /* Size */}px`,
8917
- width: `${7 /* Size */ * 2}px`,
9183
+ height: `${7 /* Arrow.Size */}px`,
9184
+ width: `${7 /* Arrow.Size */ * 2}px`,
8918
9185
  position: "absolute",
8919
9186
  zIndex: -1,
8920
9187
  overflow: "hidden",
@@ -8923,26 +9190,26 @@ const baseTheme = EditorView.baseTheme({
8923
9190
  position: "absolute",
8924
9191
  width: 0,
8925
9192
  height: 0,
8926
- borderLeft: `${7 /* Size */}px solid transparent`,
8927
- borderRight: `${7 /* Size */}px solid transparent`,
9193
+ borderLeft: `${7 /* Arrow.Size */}px solid transparent`,
9194
+ borderRight: `${7 /* Arrow.Size */}px solid transparent`,
8928
9195
  },
8929
9196
  ".cm-tooltip-above &": {
8930
- bottom: `-${7 /* Size */}px`,
9197
+ bottom: `-${7 /* Arrow.Size */}px`,
8931
9198
  "&:before": {
8932
- borderTop: `${7 /* Size */}px solid #bbb`,
9199
+ borderTop: `${7 /* Arrow.Size */}px solid #bbb`,
8933
9200
  },
8934
9201
  "&:after": {
8935
- borderTop: `${7 /* Size */}px solid #f5f5f5`,
9202
+ borderTop: `${7 /* Arrow.Size */}px solid #f5f5f5`,
8936
9203
  bottom: "1px"
8937
9204
  }
8938
9205
  },
8939
9206
  ".cm-tooltip-below &": {
8940
- top: `-${7 /* Size */}px`,
9207
+ top: `-${7 /* Arrow.Size */}px`,
8941
9208
  "&:before": {
8942
- borderBottom: `${7 /* Size */}px solid #bbb`,
9209
+ borderBottom: `${7 /* Arrow.Size */}px solid #bbb`,
8943
9210
  },
8944
9211
  "&:after": {
8945
- borderBottom: `${7 /* Size */}px solid #f5f5f5`,
9212
+ borderBottom: `${7 /* Arrow.Size */}px solid #f5f5f5`,
8946
9213
  top: "1px"
8947
9214
  }
8948
9215
  },
@@ -8967,6 +9234,10 @@ const showTooltip = state.Facet.define({
8967
9234
  });
8968
9235
  const showHoverTooltip = state.Facet.define();
8969
9236
  class HoverTooltipHost {
9237
+ // Needs to be static so that host tooltip instances always match
9238
+ static create(view) {
9239
+ return new HoverTooltipHost(view);
9240
+ }
8970
9241
  constructor(view) {
8971
9242
  this.view = view;
8972
9243
  this.mounted = false;
@@ -8974,10 +9245,6 @@ class HoverTooltipHost {
8974
9245
  this.dom.classList.add("cm-tooltip-hover");
8975
9246
  this.manager = new TooltipViewManager(view, showHoverTooltip, t => this.createHostedView(t));
8976
9247
  }
8977
- // Needs to be static so that host tooltip instances always match
8978
- static create(view) {
8979
- return new HoverTooltipHost(view);
8980
- }
8981
9248
  createHostedView(tooltip) {
8982
9249
  let hostedView = tooltip.create(this.view);
8983
9250
  hostedView.dom.classList.add("cm-tooltip-section");
@@ -9057,30 +9324,41 @@ class HoverPlugin {
9057
9324
  }
9058
9325
  startHover() {
9059
9326
  clearTimeout(this.restartTimeout);
9060
- let { lastMove } = this;
9061
- let pos = this.view.contentDOM.contains(lastMove.target) ? this.view.posAtCoords(lastMove) : null;
9062
- if (pos == null)
9063
- return;
9064
- let posCoords = this.view.coordsAtPos(pos);
9065
- if (posCoords == null || lastMove.y < posCoords.top || lastMove.y > posCoords.bottom ||
9066
- lastMove.x < posCoords.left - this.view.defaultCharacterWidth ||
9067
- lastMove.x > posCoords.right + this.view.defaultCharacterWidth)
9327
+ let { view, lastMove } = this;
9328
+ let desc = view.docView.nearest(lastMove.target);
9329
+ if (!desc)
9068
9330
  return;
9069
- let bidi = this.view.bidiSpans(this.view.state.doc.lineAt(pos)).find(s => s.from <= pos && s.to >= pos);
9070
- let rtl = bidi && bidi.dir == exports.Direction.RTL ? -1 : 1;
9071
- let open = this.source(this.view, pos, (lastMove.x < posCoords.left ? -rtl : rtl));
9331
+ let pos, side = 1;
9332
+ if (desc instanceof WidgetView) {
9333
+ pos = desc.posAtStart;
9334
+ }
9335
+ else {
9336
+ pos = view.posAtCoords(lastMove);
9337
+ if (pos == null)
9338
+ return;
9339
+ let posCoords = view.coordsAtPos(pos);
9340
+ if (!posCoords ||
9341
+ lastMove.y < posCoords.top || lastMove.y > posCoords.bottom ||
9342
+ lastMove.x < posCoords.left - view.defaultCharacterWidth ||
9343
+ lastMove.x > posCoords.right + view.defaultCharacterWidth)
9344
+ return;
9345
+ let bidi = view.bidiSpans(view.state.doc.lineAt(pos)).find(s => s.from <= pos && s.to >= pos);
9346
+ let rtl = bidi && bidi.dir == exports.Direction.RTL ? -1 : 1;
9347
+ side = (lastMove.x < posCoords.left ? -rtl : rtl);
9348
+ }
9349
+ let open = this.source(view, pos, side);
9072
9350
  if (open === null || open === void 0 ? void 0 : open.then) {
9073
9351
  let pending = this.pending = { pos };
9074
9352
  open.then(result => {
9075
9353
  if (this.pending == pending) {
9076
9354
  this.pending = null;
9077
9355
  if (result)
9078
- this.view.dispatch({ effects: this.setHover.of(result) });
9356
+ view.dispatch({ effects: this.setHover.of(result) });
9079
9357
  }
9080
- }, e => logException(this.view.state, e, "hover tooltip"));
9358
+ }, e => logException(view.state, e, "hover tooltip"));
9081
9359
  }
9082
9360
  else if (open) {
9083
- this.view.dispatch({ effects: this.setHover.of(open) });
9361
+ view.dispatch({ effects: this.setHover.of(open) });
9084
9362
  }
9085
9363
  }
9086
9364
  mousemove(event) {
@@ -9092,7 +9370,7 @@ class HoverPlugin {
9092
9370
  if (tooltip && !isInTooltip(this.lastMove.target) || this.pending) {
9093
9371
  let { pos } = tooltip || this.pending, end = (_a = tooltip === null || tooltip === void 0 ? void 0 : tooltip.end) !== null && _a !== void 0 ? _a : pos;
9094
9372
  if ((pos == end ? this.view.posAtCoords(this.lastMove) != pos
9095
- : !isOverRange(this.view, pos, end, event.clientX, event.clientY, 6 /* MaxDist */))) {
9373
+ : !isOverRange(this.view, pos, end, event.clientX, event.clientY, 6 /* Hover.MaxDist */))) {
9096
9374
  this.view.dispatch({ effects: this.setHover.of(null) });
9097
9375
  this.pending = null;
9098
9376
  }
@@ -9174,7 +9452,7 @@ function hoverTooltip(source, options = {}) {
9174
9452
  });
9175
9453
  return [
9176
9454
  hoverState,
9177
- ViewPlugin.define(view => new HoverPlugin(view, source, hoverState, setHover, options.hoverTime || 300 /* Time */)),
9455
+ ViewPlugin.define(view => new HoverPlugin(view, source, hoverState, setHover, options.hoverTime || 300 /* Hover.Time */)),
9178
9456
  showHoverTooltipHost
9179
9457
  ];
9180
9458
  }