@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.js CHANGED
@@ -1,4 +1,4 @@
1
- import { EditorState, Text, RangeSet, MapMode, RangeValue, Facet, StateEffect, ChangeSet, findClusterBreak, EditorSelection, findColumn, CharCategory, Annotation, Prec, Transaction, codePointAt, codePointSize, combineConfig, StateField, RangeSetBuilder, countColumn } from '@codemirror/state';
1
+ import { EditorState, Text, RangeSet, MapMode, RangeValue, Facet, StateEffect, ChangeSet, findClusterBreak, EditorSelection, findColumn, CharCategory, Annotation, Transaction, Prec, codePointAt, codePointSize, combineConfig, StateField, RangeSetBuilder, countColumn } from '@codemirror/state';
2
2
  import { StyleModule } from 'style-mod';
3
3
  import { keyName, base, shift } from 'w3c-keyname';
4
4
 
@@ -336,7 +336,7 @@ class ContentView {
336
336
  constructor() {
337
337
  this.parent = null;
338
338
  this.dom = null;
339
- this.flags = 2 /* NodeDirty */;
339
+ this.flags = 2 /* ViewFlag.NodeDirty */;
340
340
  }
341
341
  get overrideDOMText() { return null; }
342
342
  get posAtStart() {
@@ -358,18 +358,18 @@ class ContentView {
358
358
  return this.posBefore(view) + view.length;
359
359
  }
360
360
  sync(view, track) {
361
- if (this.flags & 2 /* NodeDirty */) {
361
+ if (this.flags & 2 /* ViewFlag.NodeDirty */) {
362
362
  let parent = this.dom;
363
363
  let prev = null, next;
364
364
  for (let child of this.children) {
365
- if (child.flags & 7 /* Dirty */) {
365
+ if (child.flags & 7 /* ViewFlag.Dirty */) {
366
366
  if (!child.dom && (next = prev ? prev.nextSibling : parent.firstChild)) {
367
367
  let contentView = ContentView.get(next);
368
368
  if (!contentView || !contentView.parent && contentView.canReuseDOM(child))
369
369
  child.reuseDOM(next);
370
370
  }
371
371
  child.sync(view, track);
372
- child.flags &= ~7 /* Dirty */;
372
+ child.flags &= ~7 /* ViewFlag.Dirty */;
373
373
  }
374
374
  next = prev ? prev.nextSibling : parent.firstChild;
375
375
  if (track && !track.written && track.node == parent && next != child.dom)
@@ -389,11 +389,11 @@ class ContentView {
389
389
  while (next)
390
390
  next = rm$1(next);
391
391
  }
392
- else if (this.flags & 1 /* ChildDirty */) {
392
+ else if (this.flags & 1 /* ViewFlag.ChildDirty */) {
393
393
  for (let child of this.children)
394
- if (child.flags & 7 /* Dirty */) {
394
+ if (child.flags & 7 /* ViewFlag.Dirty */) {
395
395
  child.sync(view, track);
396
- child.flags &= ~7 /* Dirty */;
396
+ child.flags &= ~7 /* ViewFlag.Dirty */;
397
397
  }
398
398
  }
399
399
  }
@@ -458,23 +458,23 @@ class ContentView {
458
458
  endDOM: toI < this.children.length && toI >= 0 ? this.children[toI].dom : null };
459
459
  }
460
460
  markDirty(andParent = false) {
461
- this.flags |= 2 /* NodeDirty */;
461
+ this.flags |= 2 /* ViewFlag.NodeDirty */;
462
462
  this.markParentsDirty(andParent);
463
463
  }
464
464
  markParentsDirty(childList) {
465
465
  for (let parent = this.parent; parent; parent = parent.parent) {
466
466
  if (childList)
467
- parent.flags |= 2 /* NodeDirty */;
468
- if (parent.flags & 1 /* ChildDirty */)
467
+ parent.flags |= 2 /* ViewFlag.NodeDirty */;
468
+ if (parent.flags & 1 /* ViewFlag.ChildDirty */)
469
469
  return;
470
- parent.flags |= 1 /* ChildDirty */;
470
+ parent.flags |= 1 /* ViewFlag.ChildDirty */;
471
471
  childList = false;
472
472
  }
473
473
  }
474
474
  setParent(parent) {
475
475
  if (this.parent != parent) {
476
476
  this.parent = parent;
477
- if (this.flags & 7 /* Dirty */)
477
+ if (this.flags & 7 /* ViewFlag.Dirty */)
478
478
  this.markParentsDirty(true);
479
479
  }
480
480
  }
@@ -526,7 +526,7 @@ class ContentView {
526
526
  }
527
527
  become(other) { return false; }
528
528
  canReuseDOM(other) {
529
- return other.constructor == this.constructor && !((this.flags | other.flags) & 8 /* Composition */);
529
+ return other.constructor == this.constructor && !((this.flags | other.flags) & 8 /* ViewFlag.Composition */);
530
530
  }
531
531
  // When this is a zero-length view with a side, this should return a
532
532
  // number <= 0 to indicate it is before its position, or a
@@ -811,10 +811,10 @@ class TextView extends ContentView {
811
811
  this.createDOM(dom);
812
812
  }
813
813
  merge(from, to, source) {
814
- if ((this.flags & 8 /* Composition */) ||
814
+ if ((this.flags & 8 /* ViewFlag.Composition */) ||
815
815
  source && (!(source instanceof TextView) ||
816
816
  this.length - (to - from) + source.length > MaxJoinLen ||
817
- (source.flags & 8 /* Composition */)))
817
+ (source.flags & 8 /* ViewFlag.Composition */)))
818
818
  return false;
819
819
  this.text = this.text.slice(0, from) + (source ? source.text : "") + this.text.slice(to);
820
820
  this.markDirty();
@@ -824,7 +824,7 @@ class TextView extends ContentView {
824
824
  let result = new TextView(this.text.slice(from));
825
825
  this.text = this.text.slice(0, from);
826
826
  this.markDirty();
827
- result.flags |= this.flags & 8 /* Composition */;
827
+ result.flags |= this.flags & 8 /* ViewFlag.Composition */;
828
828
  return result;
829
829
  }
830
830
  localPosFromDOM(node, offset) {
@@ -857,18 +857,18 @@ class MarkView extends ContentView {
857
857
  return dom;
858
858
  }
859
859
  canReuseDOM(other) {
860
- return super.canReuseDOM(other) && !((this.flags | other.flags) & 8 /* Composition */);
860
+ return super.canReuseDOM(other) && !((this.flags | other.flags) & 8 /* ViewFlag.Composition */);
861
861
  }
862
862
  reuseDOM(node) {
863
863
  if (node.nodeName == this.mark.tagName.toUpperCase()) {
864
864
  this.setDOM(node);
865
- this.flags |= 4 /* AttrsDirty */ | 2 /* NodeDirty */;
865
+ this.flags |= 4 /* ViewFlag.AttrsDirty */ | 2 /* ViewFlag.NodeDirty */;
866
866
  }
867
867
  }
868
868
  sync(view, track) {
869
869
  if (!this.dom)
870
870
  this.setDOM(this.setAttrs(document.createElement(this.mark.tagName)));
871
- else if (this.flags & 4 /* AttrsDirty */)
871
+ else if (this.flags & 4 /* ViewFlag.AttrsDirty */)
872
872
  this.setAttrs(this.dom);
873
873
  super.sync(view, track);
874
874
  }
@@ -939,6 +939,9 @@ function textCoords(text, pos, side) {
939
939
  }
940
940
  // Also used for collapsed ranges that don't have a placeholder widget!
941
941
  class WidgetView extends ContentView {
942
+ static create(widget, length, side) {
943
+ return new WidgetView(widget, length, side);
944
+ }
942
945
  constructor(widget, length, side) {
943
946
  super();
944
947
  this.widget = widget;
@@ -946,9 +949,6 @@ class WidgetView extends ContentView {
946
949
  this.side = side;
947
950
  this.prevWidget = null;
948
951
  }
949
- static create(widget, length, side) {
950
- return new WidgetView(widget, length, side);
951
- }
952
952
  split(from) {
953
953
  let result = WidgetView.create(this.widget, this.length - from, this.side);
954
954
  this.length -= from;
@@ -1163,16 +1163,26 @@ function attrsEq(a, b, ignore) {
1163
1163
  return true;
1164
1164
  }
1165
1165
  function updateAttrs(dom, prev, attrs) {
1166
- let changed = null;
1166
+ let changed = false;
1167
1167
  if (prev)
1168
1168
  for (let name in prev)
1169
- if (!(attrs && name in attrs))
1170
- dom.removeAttribute(changed = name);
1169
+ if (!(attrs && name in attrs)) {
1170
+ changed = true;
1171
+ if (name == "style")
1172
+ dom.style.cssText = "";
1173
+ else
1174
+ dom.removeAttribute(name);
1175
+ }
1171
1176
  if (attrs)
1172
1177
  for (let name in attrs)
1173
- if (!(prev && prev[name] == attrs[name]))
1174
- dom.setAttribute(changed = name, attrs[name]);
1175
- return !!changed;
1178
+ if (!(prev && prev[name] == attrs[name])) {
1179
+ changed = true;
1180
+ if (name == "style")
1181
+ dom.style.cssText = attrs[name];
1182
+ else
1183
+ dom.setAttribute(name, attrs[name]);
1184
+ }
1185
+ return changed;
1176
1186
  }
1177
1187
  function getAttrs(dom) {
1178
1188
  let attrs = Object.create(null);
@@ -1329,8 +1339,8 @@ class Decoration extends RangeValue {
1329
1339
  static widget(spec) {
1330
1340
  let side = Math.max(-10000, Math.min(10000, spec.side || 0)), block = !!spec.block;
1331
1341
  side += (block && !spec.inlineOrder)
1332
- ? (side > 0 ? 300000000 /* BlockAfter */ : -400000000 /* BlockBefore */)
1333
- : (side > 0 ? 100000000 /* InlineAfter */ : -100000000 /* InlineBefore */);
1342
+ ? (side > 0 ? 300000000 /* Side.BlockAfter */ : -400000000 /* Side.BlockBefore */)
1343
+ : (side > 0 ? 100000000 /* Side.InlineAfter */ : -100000000 /* Side.InlineBefore */);
1334
1344
  return new PointDecoration(spec, side, side, block, spec.widget || null, false);
1335
1345
  }
1336
1346
  /**
@@ -1340,13 +1350,13 @@ class Decoration extends RangeValue {
1340
1350
  static replace(spec) {
1341
1351
  let block = !!spec.block, startSide, endSide;
1342
1352
  if (spec.isBlockGap) {
1343
- startSide = -500000000 /* GapStart */;
1344
- endSide = 400000000 /* GapEnd */;
1353
+ startSide = -500000000 /* Side.GapStart */;
1354
+ endSide = 400000000 /* Side.GapEnd */;
1345
1355
  }
1346
1356
  else {
1347
1357
  let { start, end } = getInclusive(spec, block);
1348
- startSide = (start ? (block ? -300000000 /* BlockIncStart */ : -1 /* InlineIncStart */) : 500000000 /* NonIncStart */) - 1;
1349
- endSide = (end ? (block ? 200000000 /* BlockIncEnd */ : 1 /* InlineIncEnd */) : -600000000 /* NonIncEnd */) + 1;
1358
+ startSide = (start ? (block ? -300000000 /* Side.BlockIncStart */ : -1 /* Side.InlineIncStart */) : 500000000 /* Side.NonIncStart */) - 1;
1359
+ endSide = (end ? (block ? 200000000 /* Side.BlockIncEnd */ : 1 /* Side.InlineIncEnd */) : -600000000 /* Side.NonIncEnd */) + 1;
1350
1360
  }
1351
1361
  return new PointDecoration(spec, startSide, endSide, block, spec.widget || null, true);
1352
1362
  }
@@ -1377,7 +1387,7 @@ Decoration.none = RangeSet.empty;
1377
1387
  class MarkDecoration extends Decoration {
1378
1388
  constructor(spec) {
1379
1389
  let { start, end } = getInclusive(spec);
1380
- super(start ? -1 /* InlineIncStart */ : 500000000 /* NonIncStart */, end ? 1 /* InlineIncEnd */ : -600000000 /* NonIncEnd */, null, spec);
1390
+ super(start ? -1 /* Side.InlineIncStart */ : 500000000 /* Side.NonIncStart */, end ? 1 /* Side.InlineIncEnd */ : -600000000 /* Side.NonIncEnd */, null, spec);
1381
1391
  this.tagName = spec.tagName || "span";
1382
1392
  this.class = spec.class || "";
1383
1393
  this.attrs = spec.attributes || null;
@@ -1399,7 +1409,7 @@ class MarkDecoration extends Decoration {
1399
1409
  MarkDecoration.prototype.point = false;
1400
1410
  class LineDecoration extends Decoration {
1401
1411
  constructor(spec) {
1402
- super(-200000000 /* Line */, -200000000 /* Line */, null, spec);
1412
+ super(-200000000 /* Side.Line */, -200000000 /* Side.Line */, null, spec);
1403
1413
  }
1404
1414
  eq(other) {
1405
1415
  return other instanceof LineDecoration &&
@@ -1540,7 +1550,7 @@ class LineView extends ContentView {
1540
1550
  reuseDOM(node) {
1541
1551
  if (node.nodeName == "DIV") {
1542
1552
  this.setDOM(node);
1543
- this.flags |= 4 /* AttrsDirty */ | 2 /* NodeDirty */;
1553
+ this.flags |= 4 /* ViewFlag.AttrsDirty */ | 2 /* ViewFlag.NodeDirty */;
1544
1554
  }
1545
1555
  }
1546
1556
  sync(view, track) {
@@ -1550,7 +1560,7 @@ class LineView extends ContentView {
1550
1560
  this.dom.className = "cm-line";
1551
1561
  this.prevAttrs = this.attrs ? null : undefined;
1552
1562
  }
1553
- else if (this.flags & 4 /* AttrsDirty */) {
1563
+ else if (this.flags & 4 /* ViewFlag.AttrsDirty */) {
1554
1564
  clearAttributes(this.dom);
1555
1565
  this.dom.className = "cm-line";
1556
1566
  this.prevAttrs = this.attrs ? null : undefined;
@@ -1698,7 +1708,7 @@ class ContentBuilder {
1698
1708
  this.content = [];
1699
1709
  this.curLine = null;
1700
1710
  this.breakAtStart = 0;
1701
- this.pendingBuffer = 0 /* No */;
1711
+ this.pendingBuffer = 0 /* Buf.No */;
1702
1712
  this.bufferMarks = [];
1703
1713
  // Set to false directly after a widget that covers the position after it
1704
1714
  this.atCursorPos = true;
@@ -1725,7 +1735,7 @@ class ContentBuilder {
1725
1735
  flushBuffer(active = this.bufferMarks) {
1726
1736
  if (this.pendingBuffer) {
1727
1737
  this.curLine.append(wrapMarks(new WidgetBufferView(-1), active), active.length);
1728
- this.pendingBuffer = 0 /* No */;
1738
+ this.pendingBuffer = 0 /* Buf.No */;
1729
1739
  }
1730
1740
  }
1731
1741
  addBlockWidget(view) {
@@ -1737,7 +1747,7 @@ class ContentBuilder {
1737
1747
  if (this.pendingBuffer && openEnd <= this.bufferMarks.length)
1738
1748
  this.flushBuffer();
1739
1749
  else
1740
- this.pendingBuffer = 0 /* No */;
1750
+ this.pendingBuffer = 0 /* Buf.No */;
1741
1751
  if (!this.posCovered())
1742
1752
  this.getLine();
1743
1753
  }
@@ -1766,7 +1776,7 @@ class ContentBuilder {
1766
1776
  this.textOff = 0;
1767
1777
  }
1768
1778
  }
1769
- let take = Math.min(this.text.length - this.textOff, length, 512 /* Chunk */);
1779
+ let take = Math.min(this.text.length - this.textOff, length, 512 /* T.Chunk */);
1770
1780
  this.flushBuffer(active.slice(active.length - openStart));
1771
1781
  this.getLine().append(wrapMarks(new TextView(this.text.slice(this.textOff, this.textOff + take)), active), openStart);
1772
1782
  this.atCursorPos = true;
@@ -1802,8 +1812,8 @@ class ContentBuilder {
1802
1812
  (from < to || deco.startSide > 0);
1803
1813
  let cursorAfter = !view.isEditable && (from < to || openStart > active.length || deco.startSide <= 0);
1804
1814
  let line = this.getLine();
1805
- if (this.pendingBuffer == 2 /* IfCursor */ && !cursorBefore && !view.isEditable)
1806
- this.pendingBuffer = 0 /* No */;
1815
+ if (this.pendingBuffer == 2 /* Buf.IfCursor */ && !cursorBefore && !view.isEditable)
1816
+ this.pendingBuffer = 0 /* Buf.No */;
1807
1817
  this.flushBuffer(active);
1808
1818
  if (cursorBefore) {
1809
1819
  line.append(wrapMarks(new WidgetBufferView(1), active), openStart);
@@ -1811,7 +1821,7 @@ class ContentBuilder {
1811
1821
  }
1812
1822
  line.append(wrapMarks(view, active), openStart);
1813
1823
  this.atCursorPos = cursorAfter;
1814
- this.pendingBuffer = !cursorAfter ? 0 /* No */ : from < to || openStart > active.length ? 1 /* Yes */ : 2 /* IfCursor */;
1824
+ this.pendingBuffer = !cursorAfter ? 0 /* Buf.No */ : from < to || openStart > active.length ? 1 /* Buf.Yes */ : 2 /* Buf.IfCursor */;
1815
1825
  if (this.pendingBuffer)
1816
1826
  this.bufferMarks = active.slice();
1817
1827
  }
@@ -2025,6 +2035,36 @@ const contentAttributes = /*@__PURE__*/Facet.define();
2025
2035
  // Provide decorations
2026
2036
  const decorations = /*@__PURE__*/Facet.define();
2027
2037
  const atomicRanges = /*@__PURE__*/Facet.define();
2038
+ const bidiIsolatedRanges = /*@__PURE__*/Facet.define();
2039
+ function getIsolatedRanges(view, from, to) {
2040
+ let isolates = view.state.facet(bidiIsolatedRanges);
2041
+ if (!isolates.length)
2042
+ return isolates;
2043
+ let sets = isolates.map(i => i instanceof Function ? i(view) : i);
2044
+ let result = [];
2045
+ RangeSet.spans(sets, from, to, {
2046
+ point() { },
2047
+ span(from, to, active, open) {
2048
+ let level = result;
2049
+ for (let i = active.length - 1; i >= 0; i--, open--) {
2050
+ let iso = active[i].spec.bidiIsolate, update;
2051
+ if (iso == null)
2052
+ continue;
2053
+ if (open > 0 && level.length &&
2054
+ (update = level[level.length - 1]).to == from && update.direction == iso) {
2055
+ update.to = to;
2056
+ level = update.inner;
2057
+ }
2058
+ else {
2059
+ let add = { from, to, direction: iso, inner: [] };
2060
+ level.push(add);
2061
+ level = add.inner;
2062
+ }
2063
+ }
2064
+ }
2065
+ });
2066
+ return result;
2067
+ }
2028
2068
  const scrollMargins = /*@__PURE__*/Facet.define();
2029
2069
  function getScrollMargins(view) {
2030
2070
  let left = 0, right = 0, top = 0, bottom = 0;
@@ -2138,27 +2178,27 @@ class ViewUpdate {
2138
2178
  update.
2139
2179
  */
2140
2180
  get viewportChanged() {
2141
- return (this.flags & 4 /* Viewport */) > 0;
2181
+ return (this.flags & 4 /* UpdateFlag.Viewport */) > 0;
2142
2182
  }
2143
2183
  /**
2144
2184
  Indicates whether the height of a block element in the editor
2145
2185
  changed in this update.
2146
2186
  */
2147
2187
  get heightChanged() {
2148
- return (this.flags & 2 /* Height */) > 0;
2188
+ return (this.flags & 2 /* UpdateFlag.Height */) > 0;
2149
2189
  }
2150
2190
  /**
2151
2191
  Returns true when the document was modified or the size of the
2152
2192
  editor, or elements within the editor, changed.
2153
2193
  */
2154
2194
  get geometryChanged() {
2155
- return this.docChanged || (this.flags & (8 /* Geometry */ | 2 /* Height */)) > 0;
2195
+ return this.docChanged || (this.flags & (8 /* UpdateFlag.Geometry */ | 2 /* UpdateFlag.Height */)) > 0;
2156
2196
  }
2157
2197
  /**
2158
2198
  True when this update indicates a focus change.
2159
2199
  */
2160
2200
  get focusChanged() {
2161
- return (this.flags & 1 /* Focus */) > 0;
2201
+ return (this.flags & 1 /* UpdateFlag.Focus */) > 0;
2162
2202
  }
2163
2203
  /**
2164
2204
  Whether the document changed in this update.
@@ -2216,12 +2256,12 @@ for (let p of ["()", "[]", "{}"]) {
2216
2256
  }
2217
2257
  function charType(ch) {
2218
2258
  return ch <= 0xf7 ? LowTypes[ch] :
2219
- 0x590 <= ch && ch <= 0x5f4 ? 2 /* R */ :
2259
+ 0x590 <= ch && ch <= 0x5f4 ? 2 /* T.R */ :
2220
2260
  0x600 <= ch && ch <= 0x6f9 ? ArabicTypes[ch - 0x600] :
2221
- 0x6ee <= ch && ch <= 0x8ac ? 4 /* AL */ :
2222
- 0x2000 <= ch && ch <= 0x200b ? 256 /* NI */ :
2223
- 0xfb50 <= ch && ch <= 0xfdff ? 4 /* AL */ :
2224
- ch == 0x200c ? 256 /* NI */ : 1 /* L */;
2261
+ 0x6ee <= ch && ch <= 0x8ac ? 4 /* T.AL */ :
2262
+ 0x2000 <= ch && ch <= 0x200b ? 256 /* T.NI */ :
2263
+ 0xfb50 <= ch && ch <= 0xfdff ? 4 /* T.AL */ :
2264
+ ch == 0x200c ? 256 /* T.NI */ : 1 /* T.L */;
2225
2265
  }
2226
2266
  const BidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac\ufb50-\ufdff]/;
2227
2267
  /**
@@ -2229,6 +2269,10 @@ Represents a contiguous range of text that has a single direction
2229
2269
  (as in left-to-right or right-to-left).
2230
2270
  */
2231
2271
  class BidiSpan {
2272
+ /**
2273
+ The direction of this span.
2274
+ */
2275
+ get dir() { return this.level % 2 ? RTL : LTR; }
2232
2276
  /**
2233
2277
  @internal
2234
2278
  */
@@ -2254,10 +2298,6 @@ class BidiSpan {
2254
2298
  this.level = level;
2255
2299
  }
2256
2300
  /**
2257
- The direction of this span.
2258
- */
2259
- get dir() { return this.level % 2 ? RTL : LTR; }
2260
- /**
2261
2301
  @internal
2262
2302
  */
2263
2303
  side(end, dir) { return (this.dir == dir) == end ? this.to : this.from; }
@@ -2283,166 +2323,328 @@ class BidiSpan {
2283
2323
  return maybe;
2284
2324
  }
2285
2325
  }
2326
+ function isolatesEq(a, b) {
2327
+ if (a.length != b.length)
2328
+ return false;
2329
+ for (let i = 0; i < a.length; i++) {
2330
+ let iA = a[i], iB = b[i];
2331
+ if (iA.from != iB.from || iA.to != iB.to || iA.direction != iB.direction || !isolatesEq(iA.inner, iB.inner))
2332
+ return false;
2333
+ }
2334
+ return true;
2335
+ }
2286
2336
  // Reused array of character types
2287
2337
  const types = [];
2288
- function computeOrder(line, direction) {
2289
- let len = line.length, outerType = direction == LTR ? 1 /* L */ : 2 /* R */, oppositeType = direction == LTR ? 2 /* R */ : 1 /* L */;
2290
- if (!line || outerType == 1 /* L */ && !BidiRE.test(line))
2291
- return trivialOrder(len);
2292
- // W1. Examine each non-spacing mark (NSM) in the level run, and
2293
- // change the type of the NSM to the type of the previous
2294
- // character. If the NSM is at the start of the level run, it will
2295
- // get the type of sor.
2296
- // W2. Search backwards from each instance of a European number
2297
- // until the first strong type (R, L, AL, or sor) is found. If an
2298
- // AL is found, change the type of the European number to Arabic
2299
- // number.
2300
- // W3. Change all ALs to R.
2301
- // (Left after this: L, R, EN, AN, ET, CS, NI)
2302
- for (let i = 0, prev = outerType, prevStrong = outerType; i < len; i++) {
2303
- let type = charType(line.charCodeAt(i));
2304
- if (type == 512 /* NSM */)
2305
- type = prev;
2306
- else if (type == 8 /* EN */ && prevStrong == 4 /* AL */)
2307
- type = 16 /* AN */;
2308
- types[i] = type == 4 /* AL */ ? 2 /* R */ : type;
2309
- if (type & 7 /* Strong */)
2310
- prevStrong = type;
2311
- prev = type;
2312
- }
2313
- // W5. A sequence of European terminators adjacent to European
2314
- // numbers changes to all European numbers.
2315
- // W6. Otherwise, separators and terminators change to Other
2316
- // Neutral.
2317
- // W7. Search backwards from each instance of a European number
2318
- // until the first strong type (R, L, or sor) is found. If an L is
2319
- // found, then change the type of the European number to L.
2320
- // (Left after this: L, R, EN+AN, NI)
2321
- for (let i = 0, prev = outerType, prevStrong = outerType; i < len; i++) {
2322
- let type = types[i];
2323
- if (type == 128 /* CS */) {
2324
- if (i < len - 1 && prev == types[i + 1] && (prev & 24 /* Num */))
2325
- type = types[i] = prev;
2326
- else
2327
- types[i] = 256 /* NI */;
2328
- }
2329
- else if (type == 64 /* ET */) {
2330
- let end = i + 1;
2331
- while (end < len && types[end] == 64 /* ET */)
2332
- end++;
2333
- let replace = (i && prev == 8 /* EN */) || (end < len && types[end] == 8 /* EN */) ? (prevStrong == 1 /* L */ ? 1 /* L */ : 8 /* EN */) : 256 /* NI */;
2334
- for (let j = i; j < end; j++)
2335
- types[j] = replace;
2336
- i = end - 1;
2337
- }
2338
- else if (type == 8 /* EN */ && prevStrong == 1 /* L */) {
2339
- types[i] = 1 /* L */;
2340
- }
2341
- prev = type;
2342
- if (type & 7 /* Strong */)
2343
- prevStrong = type;
2344
- }
2345
- // N0. Process bracket pairs in an isolating run sequence
2346
- // sequentially in the logical order of the text positions of the
2347
- // opening paired brackets using the logic given below. Within this
2348
- // scope, bidirectional types EN and AN are treated as R.
2349
- for (let i = 0, sI = 0, context = 0, ch, br, type; i < len; i++) {
2350
- // Keeps [startIndex, type, strongSeen] triples for each open
2351
- // bracket on BracketStack.
2352
- if (br = Brackets[ch = line.charCodeAt(i)]) {
2353
- if (br < 0) { // Closing bracket
2338
+ // Fill in the character types (in `types`) from `from` to `to` and
2339
+ // apply W normalization rules.
2340
+ function computeCharTypes(line, rFrom, rTo, isolates, outerType) {
2341
+ for (let iI = 0; iI <= isolates.length; iI++) {
2342
+ let from = iI ? isolates[iI - 1].to : rFrom, to = iI < isolates.length ? isolates[iI].from : rTo;
2343
+ let prevType = iI ? 256 /* T.NI */ : outerType;
2344
+ // W1. Examine each non-spacing mark (NSM) in the level run, and
2345
+ // change the type of the NSM to the type of the previous
2346
+ // character. If the NSM is at the start of the level run, it will
2347
+ // get the type of sor.
2348
+ // W2. Search backwards from each instance of a European number
2349
+ // until the first strong type (R, L, AL, or sor) is found. If an
2350
+ // AL is found, change the type of the European number to Arabic
2351
+ // number.
2352
+ // W3. Change all ALs to R.
2353
+ // (Left after this: L, R, EN, AN, ET, CS, NI)
2354
+ for (let i = from, prev = prevType, prevStrong = prevType; i < to; i++) {
2355
+ let type = charType(line.charCodeAt(i));
2356
+ if (type == 512 /* T.NSM */)
2357
+ type = prev;
2358
+ else if (type == 8 /* T.EN */ && prevStrong == 4 /* T.AL */)
2359
+ type = 16 /* T.AN */;
2360
+ types[i] = type == 4 /* T.AL */ ? 2 /* T.R */ : type;
2361
+ if (type & 7 /* T.Strong */)
2362
+ prevStrong = type;
2363
+ prev = type;
2364
+ }
2365
+ // W5. A sequence of European terminators adjacent to European
2366
+ // numbers changes to all European numbers.
2367
+ // W6. Otherwise, separators and terminators change to Other
2368
+ // Neutral.
2369
+ // W7. Search backwards from each instance of a European number
2370
+ // until the first strong type (R, L, or sor) is found. If an L is
2371
+ // found, then change the type of the European number to L.
2372
+ // (Left after this: L, R, EN+AN, NI)
2373
+ for (let i = from, prev = prevType, prevStrong = prevType; i < to; i++) {
2374
+ let type = types[i];
2375
+ if (type == 128 /* T.CS */) {
2376
+ if (i < to - 1 && prev == types[i + 1] && (prev & 24 /* T.Num */))
2377
+ type = types[i] = prev;
2378
+ else
2379
+ types[i] = 256 /* T.NI */;
2380
+ }
2381
+ else if (type == 64 /* T.ET */) {
2382
+ let end = i + 1;
2383
+ while (end < to && types[end] == 64 /* T.ET */)
2384
+ end++;
2385
+ 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 */;
2386
+ for (let j = i; j < end; j++)
2387
+ types[j] = replace;
2388
+ i = end - 1;
2389
+ }
2390
+ else if (type == 8 /* T.EN */ && prevStrong == 1 /* T.L */) {
2391
+ types[i] = 1 /* T.L */;
2392
+ }
2393
+ prev = type;
2394
+ if (type & 7 /* T.Strong */)
2395
+ prevStrong = type;
2396
+ }
2397
+ }
2398
+ }
2399
+ // Process brackets throughout a run sequence.
2400
+ function processBracketPairs(line, rFrom, rTo, isolates, outerType) {
2401
+ let oppositeType = outerType == 1 /* T.L */ ? 2 /* T.R */ : 1 /* T.L */;
2402
+ for (let iI = 0, sI = 0, context = 0; iI <= isolates.length; iI++) {
2403
+ let from = iI ? isolates[iI - 1].to : rFrom, to = iI < isolates.length ? isolates[iI].from : rTo;
2404
+ // N0. Process bracket pairs in an isolating run sequence
2405
+ // sequentially in the logical order of the text positions of the
2406
+ // opening paired brackets using the logic given below. Within this
2407
+ // scope, bidirectional types EN and AN are treated as R.
2408
+ for (let i = from, ch, br, type; i < to; i++) {
2409
+ // Keeps [startIndex, type, strongSeen] triples for each open
2410
+ // bracket on BracketStack.
2411
+ if (br = Brackets[ch = line.charCodeAt(i)]) {
2412
+ if (br < 0) { // Closing bracket
2413
+ for (let sJ = sI - 3; sJ >= 0; sJ -= 3) {
2414
+ if (BracketStack[sJ + 1] == -br) {
2415
+ let flags = BracketStack[sJ + 2];
2416
+ let type = (flags & 2 /* Bracketed.EmbedInside */) ? outerType :
2417
+ !(flags & 4 /* Bracketed.OppositeInside */) ? 0 :
2418
+ (flags & 1 /* Bracketed.OppositeBefore */) ? oppositeType : outerType;
2419
+ if (type)
2420
+ types[i] = types[BracketStack[sJ]] = type;
2421
+ sI = sJ;
2422
+ break;
2423
+ }
2424
+ }
2425
+ }
2426
+ else if (BracketStack.length == 189 /* Bracketed.MaxDepth */) {
2427
+ break;
2428
+ }
2429
+ else {
2430
+ BracketStack[sI++] = i;
2431
+ BracketStack[sI++] = ch;
2432
+ BracketStack[sI++] = context;
2433
+ }
2434
+ }
2435
+ else if ((type = types[i]) == 2 /* T.R */ || type == 1 /* T.L */) {
2436
+ let embed = type == outerType;
2437
+ context = embed ? 0 : 1 /* Bracketed.OppositeBefore */;
2354
2438
  for (let sJ = sI - 3; sJ >= 0; sJ -= 3) {
2355
- if (BracketStack[sJ + 1] == -br) {
2356
- let flags = BracketStack[sJ + 2];
2357
- let type = (flags & 2 /* EmbedInside */) ? outerType :
2358
- !(flags & 4 /* OppositeInside */) ? 0 :
2359
- (flags & 1 /* OppositeBefore */) ? oppositeType : outerType;
2360
- if (type)
2361
- types[i] = types[BracketStack[sJ]] = type;
2362
- sI = sJ;
2439
+ let cur = BracketStack[sJ + 2];
2440
+ if (cur & 2 /* Bracketed.EmbedInside */)
2363
2441
  break;
2442
+ if (embed) {
2443
+ BracketStack[sJ + 2] |= 2 /* Bracketed.EmbedInside */;
2444
+ }
2445
+ else {
2446
+ if (cur & 4 /* Bracketed.OppositeInside */)
2447
+ break;
2448
+ BracketStack[sJ + 2] |= 4 /* Bracketed.OppositeInside */;
2364
2449
  }
2365
2450
  }
2366
2451
  }
2367
- else if (BracketStack.length == 189 /* MaxDepth */) {
2368
- break;
2452
+ }
2453
+ }
2454
+ }
2455
+ function processNeutrals(rFrom, rTo, isolates, outerType) {
2456
+ for (let iI = 0, prev = outerType; iI <= isolates.length; iI++) {
2457
+ let from = iI ? isolates[iI - 1].to : rFrom, to = iI < isolates.length ? isolates[iI].from : rTo;
2458
+ // N1. A sequence of neutrals takes the direction of the
2459
+ // surrounding strong text if the text on both sides has the same
2460
+ // direction. European and Arabic numbers act as if they were R in
2461
+ // terms of their influence on neutrals. Start-of-level-run (sor)
2462
+ // and end-of-level-run (eor) are used at level run boundaries.
2463
+ // N2. Any remaining neutrals take the embedding direction.
2464
+ // (Left after this: L, R, EN+AN)
2465
+ for (let i = from; i < to;) {
2466
+ let type = types[i];
2467
+ if (type == 256 /* T.NI */) {
2468
+ let end = i + 1;
2469
+ for (;;) {
2470
+ if (end == to) {
2471
+ if (iI == isolates.length)
2472
+ break;
2473
+ end = isolates[iI++].to;
2474
+ to = iI < isolates.length ? isolates[iI].from : rTo;
2475
+ }
2476
+ else if (types[end] == 256 /* T.NI */) {
2477
+ end++;
2478
+ }
2479
+ else {
2480
+ break;
2481
+ }
2482
+ }
2483
+ let beforeL = prev == 1 /* T.L */;
2484
+ let afterL = (end < rTo ? types[end] : outerType) == 1 /* T.L */;
2485
+ let replace = beforeL == afterL ? (beforeL ? 1 /* T.L */ : 2 /* T.R */) : outerType;
2486
+ for (let j = end, jI = iI, fromJ = jI ? isolates[jI - 1].to : rFrom; j > i;) {
2487
+ if (j == fromJ) {
2488
+ j = isolates[--jI].from;
2489
+ fromJ = jI ? isolates[jI - 1].to : rFrom;
2490
+ }
2491
+ types[--j] = replace;
2492
+ }
2493
+ i = end;
2369
2494
  }
2370
2495
  else {
2371
- BracketStack[sI++] = i;
2372
- BracketStack[sI++] = ch;
2373
- BracketStack[sI++] = context;
2496
+ prev = type;
2497
+ i++;
2374
2498
  }
2375
2499
  }
2376
- else if ((type = types[i]) == 2 /* R */ || type == 1 /* L */) {
2377
- let embed = type == outerType;
2378
- context = embed ? 0 : 1 /* OppositeBefore */;
2379
- for (let sJ = sI - 3; sJ >= 0; sJ -= 3) {
2380
- let cur = BracketStack[sJ + 2];
2381
- if (cur & 2 /* EmbedInside */)
2500
+ }
2501
+ }
2502
+ // Find the contiguous ranges of character types in a given range, and
2503
+ // emit spans for them. Flip the order of the spans as appropriate
2504
+ // based on the level, and call through to compute the spans for
2505
+ // isolates at the proper point.
2506
+ function emitSpans(line, from, to, level, baseLevel, isolates, order) {
2507
+ let ourType = level % 2 ? 2 /* T.R */ : 1 /* T.L */;
2508
+ if ((level % 2) == (baseLevel % 2)) { // Same dir as base direction, don't flip
2509
+ for (let iCh = from, iI = 0; iCh < to;) {
2510
+ // Scan a section of characters in direction ourType, unless
2511
+ // there's another type of char right after iCh, in which case
2512
+ // we scan a section of other characters (which, if ourType ==
2513
+ // T.L, may contain both T.R and T.AN chars).
2514
+ let sameDir = true, isNum = false;
2515
+ if (iI == isolates.length || iCh < isolates[iI].from) {
2516
+ let next = types[iCh];
2517
+ if (next != ourType) {
2518
+ sameDir = false;
2519
+ isNum = next == 16 /* T.AN */;
2520
+ }
2521
+ }
2522
+ // Holds an array of isolates to pass to a recursive call if we
2523
+ // must recurse (to distinguish T.AN inside an RTL section in
2524
+ // LTR text), null if we can emit directly
2525
+ let recurse = !sameDir && ourType == 1 /* T.L */ ? [] : null;
2526
+ let localLevel = sameDir ? level : level + 1;
2527
+ let iScan = iCh;
2528
+ run: for (;;) {
2529
+ if (iI < isolates.length && iScan == isolates[iI].from) {
2530
+ if (isNum)
2531
+ break run;
2532
+ let iso = isolates[iI];
2533
+ // Scan ahead to verify that there is another char in this dir after the isolate(s)
2534
+ if (!sameDir)
2535
+ for (let upto = iso.to, jI = iI + 1;;) {
2536
+ if (upto == to)
2537
+ break run;
2538
+ if (jI < isolates.length && isolates[jI].from == upto)
2539
+ upto = isolates[jI++].to;
2540
+ else if (types[upto] == ourType)
2541
+ break run;
2542
+ else
2543
+ break;
2544
+ }
2545
+ iI++;
2546
+ if (recurse) {
2547
+ recurse.push(iso);
2548
+ }
2549
+ else {
2550
+ if (iso.from > iCh)
2551
+ order.push(new BidiSpan(iCh, iso.from, localLevel));
2552
+ let dirSwap = (iso.direction == LTR) != !(localLevel % 2);
2553
+ computeSectionOrder(line, dirSwap ? level + 1 : level, baseLevel, iso.inner, iso.from, iso.to, order);
2554
+ iCh = iso.to;
2555
+ }
2556
+ iScan = iso.to;
2557
+ }
2558
+ else if (iScan == to || (sameDir ? types[iScan] != ourType : types[iScan] == ourType)) {
2382
2559
  break;
2383
- if (embed) {
2384
- BracketStack[sJ + 2] |= 2 /* EmbedInside */;
2385
2560
  }
2386
2561
  else {
2387
- if (cur & 4 /* OppositeInside */)
2388
- break;
2389
- BracketStack[sJ + 2] |= 4 /* OppositeInside */;
2562
+ iScan++;
2390
2563
  }
2391
2564
  }
2565
+ if (recurse)
2566
+ emitSpans(line, iCh, iScan, level + 1, baseLevel, recurse, order);
2567
+ else if (iCh < iScan)
2568
+ order.push(new BidiSpan(iCh, iScan, localLevel));
2569
+ iCh = iScan;
2392
2570
  }
2393
2571
  }
2394
- // N1. A sequence of neutrals takes the direction of the
2395
- // surrounding strong text if the text on both sides has the same
2396
- // direction. European and Arabic numbers act as if they were R in
2397
- // terms of their influence on neutrals. Start-of-level-run (sor)
2398
- // and end-of-level-run (eor) are used at level run boundaries.
2399
- // N2. Any remaining neutrals take the embedding direction.
2400
- // (Left after this: L, R, EN+AN)
2401
- for (let i = 0; i < len; i++) {
2402
- if (types[i] == 256 /* NI */) {
2403
- let end = i + 1;
2404
- while (end < len && types[end] == 256 /* NI */)
2405
- end++;
2406
- let beforeL = (i ? types[i - 1] : outerType) == 1 /* L */;
2407
- let afterL = (end < len ? types[end] : outerType) == 1 /* L */;
2408
- let replace = beforeL == afterL ? (beforeL ? 1 /* L */ : 2 /* R */) : outerType;
2409
- for (let j = i; j < end; j++)
2410
- types[j] = replace;
2411
- i = end - 1;
2412
- }
2413
- }
2414
- // Here we depart from the documented algorithm, in order to avoid
2415
- // building up an actual levels array. Since there are only three
2416
- // levels (0, 1, 2) in an implementation that doesn't take
2417
- // explicit embedding into account, we can build up the order on
2418
- // the fly, without following the level-based algorithm.
2419
- let order = [];
2420
- if (outerType == 1 /* L */) {
2421
- for (let i = 0; i < len;) {
2422
- let start = i, rtl = types[i++] != 1 /* L */;
2423
- while (i < len && rtl == (types[i] != 1 /* L */))
2424
- i++;
2425
- if (rtl) {
2426
- for (let j = i; j > start;) {
2427
- let end = j, l = types[--j] != 2 /* R */;
2428
- while (j > start && l == (types[j - 1] != 2 /* R */))
2429
- j--;
2430
- order.push(new BidiSpan(j, end, l ? 2 : 1));
2572
+ else {
2573
+ // Iterate in reverse to flip the span order. Same code again, but
2574
+ // going from the back of the section to the front
2575
+ for (let iCh = to, iI = isolates.length; iCh > from;) {
2576
+ let sameDir = true, isNum = false;
2577
+ if (!iI || iCh > isolates[iI - 1].to) {
2578
+ let next = types[iCh - 1];
2579
+ if (next != ourType) {
2580
+ sameDir = false;
2581
+ isNum = next == 16 /* T.AN */;
2431
2582
  }
2432
2583
  }
2433
- else {
2434
- order.push(new BidiSpan(start, i, 0));
2584
+ let recurse = !sameDir && ourType == 1 /* T.L */ ? [] : null;
2585
+ let localLevel = sameDir ? level : level + 1;
2586
+ let iScan = iCh;
2587
+ run: for (;;) {
2588
+ if (iI && iScan == isolates[iI - 1].to) {
2589
+ if (isNum)
2590
+ break run;
2591
+ let iso = isolates[--iI];
2592
+ // Scan ahead to verify that there is another char in this dir after the isolate(s)
2593
+ if (!sameDir)
2594
+ for (let upto = iso.from, jI = iI;;) {
2595
+ if (upto == from)
2596
+ break run;
2597
+ if (jI && isolates[jI - 1].to == upto)
2598
+ upto = isolates[--jI].from;
2599
+ else if (types[upto - 1] == ourType)
2600
+ break run;
2601
+ else
2602
+ break;
2603
+ }
2604
+ if (recurse) {
2605
+ recurse.push(iso);
2606
+ }
2607
+ else {
2608
+ if (iso.to < iCh)
2609
+ order.push(new BidiSpan(iso.to, iCh, localLevel));
2610
+ let dirSwap = (iso.direction == LTR) != !(localLevel % 2);
2611
+ computeSectionOrder(line, dirSwap ? level + 1 : level, baseLevel, iso.inner, iso.from, iso.to, order);
2612
+ iCh = iso.from;
2613
+ }
2614
+ iScan = iso.from;
2615
+ }
2616
+ else if (iScan == from || (sameDir ? types[iScan - 1] != ourType : types[iScan - 1] == ourType)) {
2617
+ break;
2618
+ }
2619
+ else {
2620
+ iScan--;
2621
+ }
2435
2622
  }
2623
+ if (recurse)
2624
+ emitSpans(line, iScan, iCh, level + 1, baseLevel, recurse, order);
2625
+ else if (iScan < iCh)
2626
+ order.push(new BidiSpan(iScan, iCh, localLevel));
2627
+ iCh = iScan;
2436
2628
  }
2437
2629
  }
2438
- else {
2439
- for (let i = 0; i < len;) {
2440
- let start = i, rtl = types[i++] == 2 /* R */;
2441
- while (i < len && rtl == (types[i] == 2 /* R */))
2442
- i++;
2443
- order.push(new BidiSpan(start, i, rtl ? 1 : 2));
2444
- }
2445
- }
2630
+ }
2631
+ function computeSectionOrder(line, level, baseLevel, isolates, from, to, order) {
2632
+ let outerType = (level % 2 ? 2 /* T.R */ : 1 /* T.L */);
2633
+ computeCharTypes(line, from, to, isolates, outerType);
2634
+ processBracketPairs(line, from, to, isolates, outerType);
2635
+ processNeutrals(from, to, isolates, outerType);
2636
+ emitSpans(line, from, to, level, baseLevel, isolates, order);
2637
+ }
2638
+ function computeOrder(line, direction, isolates) {
2639
+ if (!line)
2640
+ return [new BidiSpan(0, 0, direction == RTL ? 1 : 0)];
2641
+ if (direction == LTR && !isolates.length && !BidiRE.test(line))
2642
+ return trivialOrder(line.length);
2643
+ if (isolates.length)
2644
+ while (line.length > types.length)
2645
+ types[types.length] = 256 /* T.NI */; // Make sure types array has no gaps
2646
+ let order = [], level = direction == LTR ? 0 : 1;
2647
+ computeSectionOrder(line, level, level, isolates, 0, line.length, order);
2446
2648
  return order;
2447
2649
  }
2448
2650
  function trivialOrder(length) {
@@ -2491,6 +2693,7 @@ function moveVisually(line, order, dir, start, forward) {
2491
2693
  }
2492
2694
 
2493
2695
  class DocView extends ContentView {
2696
+ get length() { return this.view.state.doc.length; }
2494
2697
  constructor(view) {
2495
2698
  super();
2496
2699
  this.view = view;
@@ -2522,7 +2725,6 @@ class DocView extends ContentView {
2522
2725
  this.updateDeco();
2523
2726
  this.updateInner([new ChangedRange(0, 0, 0, view.state.doc.length)], 0, null);
2524
2727
  }
2525
- get length() { return this.view.state.doc.length; }
2526
2728
  // Update the document view to a given state.
2527
2729
  update(update) {
2528
2730
  let changedRanges = update.changedRanges;
@@ -2554,7 +2756,7 @@ class DocView extends ContentView {
2554
2756
  let prevDeco = this.decorations, deco = this.updateDeco();
2555
2757
  let decoDiff = findChangedDeco(prevDeco, deco, update.changes);
2556
2758
  changedRanges = ChangedRange.extendWithRanges(changedRanges, decoDiff);
2557
- if (!(this.flags & 7 /* Dirty */) && changedRanges.length == 0) {
2759
+ if (!(this.flags & 7 /* ViewFlag.Dirty */) && changedRanges.length == 0) {
2558
2760
  return false;
2559
2761
  }
2560
2762
  else {
@@ -2583,12 +2785,12 @@ class DocView extends ContentView {
2583
2785
  // to detect that situation.
2584
2786
  let track = browser.chrome || browser.ios ? { node: observer.selectionRange.focusNode, written: false } : undefined;
2585
2787
  this.sync(this.view, track);
2586
- this.flags &= ~7 /* Dirty */;
2788
+ this.flags &= ~7 /* ViewFlag.Dirty */;
2587
2789
  if (track && (track.written || observer.selectionRange.focusNode != track.node))
2588
2790
  this.forceSelection = true;
2589
2791
  this.dom.style.height = "";
2590
2792
  });
2591
- this.markedForComposition.forEach(cView => cView.flags &= ~8 /* Composition */);
2793
+ this.markedForComposition.forEach(cView => cView.flags &= ~8 /* ViewFlag.Composition */);
2592
2794
  let gaps = [];
2593
2795
  if (this.view.viewport.from || this.view.viewport.to < this.view.state.doc.length)
2594
2796
  for (let child of this.children)
@@ -2638,7 +2840,7 @@ class DocView extends ContentView {
2638
2840
  }
2639
2841
  compositionView(composition) {
2640
2842
  let cur = new TextView(composition.text.nodeValue);
2641
- cur.flags |= 8 /* Composition */;
2843
+ cur.flags |= 8 /* ViewFlag.Composition */;
2642
2844
  for (let { deco } of composition.marks)
2643
2845
  cur = new MarkView(deco, [cur], cur.length);
2644
2846
  let line = new LineView;
@@ -2647,7 +2849,7 @@ class DocView extends ContentView {
2647
2849
  }
2648
2850
  fixCompositionDOM(composition) {
2649
2851
  let fix = (dom, cView) => {
2650
- cView.flags |= 8 /* Composition */;
2852
+ cView.flags |= 8 /* ViewFlag.Composition */;
2651
2853
  this.markedForComposition.add(cView);
2652
2854
  let prev = ContentView.get(dom);
2653
2855
  if (prev != cView) {
@@ -2709,15 +2911,15 @@ class DocView extends ContentView {
2709
2911
  // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=1612076
2710
2912
  if (browser.gecko) {
2711
2913
  let nextTo = nextToUneditable(anchor.node, anchor.offset);
2712
- if (nextTo && nextTo != (1 /* Before */ | 2 /* After */)) {
2713
- let text = nearbyTextNode(anchor.node, anchor.offset, nextTo == 1 /* Before */ ? 1 : -1);
2914
+ if (nextTo && nextTo != (1 /* NextTo.Before */ | 2 /* NextTo.After */)) {
2915
+ let text = nearbyTextNode(anchor.node, anchor.offset, nextTo == 1 /* NextTo.Before */ ? 1 : -1);
2714
2916
  if (text)
2715
- anchor = new DOMPos(text, nextTo == 1 /* Before */ ? 0 : text.nodeValue.length);
2917
+ anchor = new DOMPos(text, nextTo == 1 /* NextTo.Before */ ? 0 : text.nodeValue.length);
2716
2918
  }
2717
2919
  }
2718
2920
  rawSel.collapse(anchor.node, anchor.offset);
2719
- if (main.bidiLevel != null && domSel.cursorBidiLevel != null)
2720
- domSel.cursorBidiLevel = main.bidiLevel;
2921
+ if (main.bidiLevel != null && domSel.caretBidiLevel != null)
2922
+ domSel.caretBidiLevel = main.bidiLevel;
2721
2923
  }
2722
2924
  else if (rawSel.extend) {
2723
2925
  // Selection.extend can be used to create an 'inverted' selection
@@ -2817,6 +3019,28 @@ class DocView extends ContentView {
2817
3019
  off = start;
2818
3020
  }
2819
3021
  }
3022
+ coordsForChar(pos) {
3023
+ let { i, off } = this.childPos(pos, 1), child = this.children[i];
3024
+ if (!(child instanceof LineView))
3025
+ return null;
3026
+ while (child.children.length) {
3027
+ let { i, off: childOff } = child.childPos(off, 1);
3028
+ for (;; i++) {
3029
+ if (i == child.children.length)
3030
+ return null;
3031
+ if ((child = child.children[i]).length)
3032
+ break;
3033
+ }
3034
+ off = childOff;
3035
+ }
3036
+ if (!(child instanceof TextView))
3037
+ return null;
3038
+ let end = findClusterBreak(child.text, off);
3039
+ if (end == off)
3040
+ return null;
3041
+ let rects = textRange(child.dom, off, end).getClientRects();
3042
+ return !rects.length || rects[0].top >= rects[0].bottom ? null : rects[0];
3043
+ }
2820
3044
  measureVisibleLineHeights(viewport) {
2821
3045
  let result = [], { from, to } = viewport;
2822
3046
  let contentWidth = this.view.contentDOM.clientWidth;
@@ -3067,16 +3291,16 @@ function nearbyTextNode(startNode, startOffset, side) {
3067
3291
  function nextToUneditable(node, offset) {
3068
3292
  if (node.nodeType != 1)
3069
3293
  return 0;
3070
- return (offset && node.childNodes[offset - 1].contentEditable == "false" ? 1 /* Before */ : 0) |
3071
- (offset < node.childNodes.length && node.childNodes[offset].contentEditable == "false" ? 2 /* After */ : 0);
3294
+ return (offset && node.childNodes[offset - 1].contentEditable == "false" ? 1 /* NextTo.Before */ : 0) |
3295
+ (offset < node.childNodes.length && node.childNodes[offset].contentEditable == "false" ? 2 /* NextTo.After */ : 0);
3072
3296
  }
3073
- class DecorationComparator$1 {
3297
+ let DecorationComparator$1 = class DecorationComparator {
3074
3298
  constructor() {
3075
3299
  this.changes = [];
3076
3300
  }
3077
3301
  compareRange(from, to) { addRange(from, to, this.changes); }
3078
3302
  comparePoint(from, to) { addRange(from, to, this.changes); }
3079
- }
3303
+ };
3080
3304
  function findChangedDeco(a, b, diff) {
3081
3305
  let comp = new DecorationComparator$1;
3082
3306
  RangeSet.compare(a, b, diff, comp);
@@ -3458,6 +3682,10 @@ function skipAtoms(view, oldPos, pos) {
3458
3682
 
3459
3683
  // This will also be where dragging info and such goes
3460
3684
  class InputState {
3685
+ setSelectionOrigin(origin) {
3686
+ this.lastSelectionOrigin = origin;
3687
+ this.lastSelectionTime = Date.now();
3688
+ }
3461
3689
  constructor(view) {
3462
3690
  this.lastKeyCode = 0;
3463
3691
  this.lastKeyTime = 0;
@@ -3554,10 +3782,6 @@ class InputState {
3554
3782
  if (browser.safari)
3555
3783
  view.contentDOM.addEventListener("input", () => null);
3556
3784
  }
3557
- setSelectionOrigin(origin) {
3558
- this.lastSelectionOrigin = origin;
3559
- this.lastSelectionTime = Date.now();
3560
- }
3561
3785
  ensureHandlers(view, plugins) {
3562
3786
  var _a;
3563
3787
  let handlers;
@@ -4425,13 +4649,13 @@ const Epsilon = 1e-3;
4425
4649
  class HeightMap {
4426
4650
  constructor(length, // The number of characters covered
4427
4651
  height, // Height of this part of the document
4428
- flags = 2 /* Outdated */) {
4652
+ flags = 2 /* Flag.Outdated */) {
4429
4653
  this.length = length;
4430
4654
  this.height = height;
4431
4655
  this.flags = flags;
4432
4656
  }
4433
- get outdated() { return (this.flags & 2 /* Outdated */) > 0; }
4434
- set outdated(value) { this.flags = (value ? 2 /* Outdated */ : 0) | (this.flags & ~2 /* Outdated */); }
4657
+ get outdated() { return (this.flags & 2 /* Flag.Outdated */) > 0; }
4658
+ set outdated(value) { this.flags = (value ? 2 /* Flag.Outdated */ : 0) | (this.flags & ~2 /* Flag.Outdated */); }
4435
4659
  setHeight(oracle, height) {
4436
4660
  if (this.height != height) {
4437
4661
  if (Math.abs(this.height - height) > Epsilon)
@@ -4562,7 +4786,7 @@ class HeightMapText extends HeightMapBlock {
4562
4786
  }
4563
4787
  replace(_from, _to, nodes) {
4564
4788
  let node = nodes[0];
4565
- if (nodes.length == 1 && (node instanceof HeightMapText || node instanceof HeightMapGap && (node.flags & 4 /* SingleLine */)) &&
4789
+ if (nodes.length == 1 && (node instanceof HeightMapText || node instanceof HeightMapGap && (node.flags & 4 /* Flag.SingleLine */)) &&
4566
4790
  Math.abs(this.length - node.length) < 10) {
4567
4791
  if (node instanceof HeightMapGap)
4568
4792
  node = new HeightMapText(node.length, this.height);
@@ -4715,12 +4939,12 @@ class HeightMapGap extends HeightMap {
4715
4939
  }
4716
4940
  class HeightMapBranch extends HeightMap {
4717
4941
  constructor(left, brk, right) {
4718
- super(left.length + brk + right.length, left.height + right.height, brk | (left.outdated || right.outdated ? 2 /* Outdated */ : 0));
4942
+ super(left.length + brk + right.length, left.height + right.height, brk | (left.outdated || right.outdated ? 2 /* Flag.Outdated */ : 0));
4719
4943
  this.left = left;
4720
4944
  this.right = right;
4721
4945
  this.size = left.size + right.size;
4722
4946
  }
4723
- get break() { return this.flags & 1 /* Break */; }
4947
+ get break() { return this.flags & 1 /* Flag.Break */; }
4724
4948
  blockAt(height, oracle, top, offset) {
4725
4949
  let mid = top + this.left.height;
4726
4950
  return height < mid ? this.left.blockAt(height, oracle, top, offset)
@@ -4905,7 +5129,7 @@ class NodeBuilder {
4905
5129
  blankContent(from, to) {
4906
5130
  let gap = new HeightMapGap(to - from);
4907
5131
  if (this.oracle.doc.lineAt(from).to == to)
4908
- gap.flags |= 4 /* SingleLine */;
5132
+ gap.flags |= 4 /* Flag.SingleLine */;
4909
5133
  return gap;
4910
5134
  }
4911
5135
  ensureLine() {
@@ -5115,7 +5339,7 @@ class ViewState {
5115
5339
  }
5116
5340
  }
5117
5341
  this.viewports = viewports.sort((a, b) => a.from - b.from);
5118
- this.scaler = this.heightMap.height <= 7000000 /* MaxDOMHeight */ ? IdScaler :
5342
+ this.scaler = this.heightMap.height <= 7000000 /* VP.MaxDOMHeight */ ? IdScaler :
5119
5343
  new BigScaler(this.heightOracle, this.heightMap, this.viewports);
5120
5344
  }
5121
5345
  updateViewportLines() {
@@ -5134,7 +5358,7 @@ class ViewState {
5134
5358
  let scrollAnchor = this.scrolledToBottom ? null : this.scrollAnchorAt(this.scrollTop);
5135
5359
  this.heightMap = this.heightMap.applyChanges(this.stateDeco, update.startState.doc, this.heightOracle.setDoc(this.state.doc), heightChanges);
5136
5360
  if (this.heightMap.height != prevHeight)
5137
- update.flags |= 2 /* Height */;
5361
+ update.flags |= 2 /* UpdateFlag.Height */;
5138
5362
  if (scrollAnchor) {
5139
5363
  this.scrollAnchorPos = update.changes.mapPos(scrollAnchor.from, -1);
5140
5364
  this.scrollAnchorHeight = scrollAnchor.top;
@@ -5147,13 +5371,13 @@ class ViewState {
5147
5371
  if (scrollTarget && (scrollTarget.range.head < viewport.from || scrollTarget.range.head > viewport.to) ||
5148
5372
  !this.viewportIsAppropriate(viewport))
5149
5373
  viewport = this.getViewport(0, scrollTarget);
5150
- let updateLines = !update.changes.empty || (update.flags & 2 /* Height */) ||
5374
+ let updateLines = !update.changes.empty || (update.flags & 2 /* UpdateFlag.Height */) ||
5151
5375
  viewport.from != this.viewport.from || viewport.to != this.viewport.to;
5152
5376
  this.viewport = viewport;
5153
5377
  this.updateForViewport();
5154
5378
  if (updateLines)
5155
5379
  this.updateViewportLines();
5156
- if (this.lineGaps.length || this.viewport.to - this.viewport.from > (2000 /* Margin */ << 1))
5380
+ if (this.lineGaps.length || this.viewport.to - this.viewport.from > (2000 /* LG.Margin */ << 1))
5157
5381
  this.updateLineGaps(this.ensureLineGaps(this.mapLineGaps(this.lineGaps, update.changes)));
5158
5382
  update.flags |= this.computeVisibleRanges();
5159
5383
  if (scrollTarget)
@@ -5179,13 +5403,13 @@ class ViewState {
5179
5403
  if (this.paddingTop != paddingTop || this.paddingBottom != paddingBottom) {
5180
5404
  this.paddingTop = paddingTop;
5181
5405
  this.paddingBottom = paddingBottom;
5182
- result |= 8 /* Geometry */ | 2 /* Height */;
5406
+ result |= 8 /* UpdateFlag.Geometry */ | 2 /* UpdateFlag.Height */;
5183
5407
  }
5184
5408
  if (this.editorWidth != view.scrollDOM.clientWidth) {
5185
5409
  if (oracle.lineWrapping)
5186
5410
  measureContent = true;
5187
5411
  this.editorWidth = view.scrollDOM.clientWidth;
5188
- result |= 8 /* Geometry */;
5412
+ result |= 8 /* UpdateFlag.Geometry */;
5189
5413
  }
5190
5414
  if (this.scrollTop != view.scrollDOM.scrollTop) {
5191
5415
  this.scrollAnchorHeight = -1;
@@ -5208,7 +5432,7 @@ class ViewState {
5208
5432
  if (this.contentDOMWidth != contentWidth || this.editorHeight != view.scrollDOM.clientHeight) {
5209
5433
  this.contentDOMWidth = domRect.width;
5210
5434
  this.editorHeight = view.scrollDOM.clientHeight;
5211
- result |= 8 /* Geometry */;
5435
+ result |= 8 /* UpdateFlag.Geometry */;
5212
5436
  }
5213
5437
  if (measureContent) {
5214
5438
  let lineHeights = view.docView.measureVisibleLineHeights(this.viewport);
@@ -5219,7 +5443,7 @@ class ViewState {
5219
5443
  refresh = lineHeight > 0 && oracle.refresh(whiteSpace, lineHeight, charWidth, textHeight, contentWidth / charWidth, lineHeights);
5220
5444
  if (refresh) {
5221
5445
  view.docView.minWidth = 0;
5222
- result |= 8 /* Geometry */;
5446
+ result |= 8 /* UpdateFlag.Geometry */;
5223
5447
  }
5224
5448
  }
5225
5449
  if (dTop > 0 && dBottom > 0)
@@ -5232,7 +5456,7 @@ class ViewState {
5232
5456
  this.heightMap = (refresh ? HeightMap.empty().applyChanges(this.stateDeco, Text.empty, this.heightOracle, [new ChangedRange(0, 0, 0, view.state.doc.length)]) : this.heightMap).updateHeight(oracle, 0, refresh, new MeasuredHeights(vp.from, heights));
5233
5457
  }
5234
5458
  if (oracle.heightChanged)
5235
- result |= 2 /* Height */;
5459
+ result |= 2 /* UpdateFlag.Height */;
5236
5460
  }
5237
5461
  let viewportChange = !this.viewportIsAppropriate(this.viewport, bias) ||
5238
5462
  this.scrollTarget && (this.scrollTarget.range.head < this.viewport.from ||
@@ -5240,9 +5464,9 @@ class ViewState {
5240
5464
  if (viewportChange)
5241
5465
  this.viewport = this.getViewport(bias, this.scrollTarget);
5242
5466
  this.updateForViewport();
5243
- if ((result & 2 /* Height */) || viewportChange)
5467
+ if ((result & 2 /* UpdateFlag.Height */) || viewportChange)
5244
5468
  this.updateViewportLines();
5245
- if (this.lineGaps.length || this.viewport.to - this.viewport.from > (2000 /* Margin */ << 1))
5469
+ if (this.lineGaps.length || this.viewport.to - this.viewport.from > (2000 /* LG.Margin */ << 1))
5246
5470
  this.updateLineGaps(this.ensureLineGaps(refresh ? [] : this.lineGaps, view));
5247
5471
  result |= this.computeVisibleRanges();
5248
5472
  if (this.mustEnforceCursorAssoc) {
@@ -5261,10 +5485,10 @@ class ViewState {
5261
5485
  // This will divide VP.Margin between the top and the
5262
5486
  // bottom, depending on the bias (the change in viewport position
5263
5487
  // since the last update). It'll hold a number between 0 and 1
5264
- let marginTop = 0.5 - Math.max(-0.5, Math.min(0.5, bias / 1000 /* Margin */ / 2));
5488
+ let marginTop = 0.5 - Math.max(-0.5, Math.min(0.5, bias / 1000 /* VP.Margin */ / 2));
5265
5489
  let map = this.heightMap, oracle = this.heightOracle;
5266
5490
  let { visibleTop, visibleBottom } = this;
5267
- 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);
5491
+ 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);
5268
5492
  // If scrollTarget is given, make sure the viewport includes that position
5269
5493
  if (scrollTarget) {
5270
5494
  let { head } = scrollTarget.range;
@@ -5277,7 +5501,7 @@ class ViewState {
5277
5501
  topPos = block.top;
5278
5502
  else
5279
5503
  topPos = block.bottom - viewHeight;
5280
- 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);
5504
+ 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);
5281
5505
  }
5282
5506
  }
5283
5507
  return viewport;
@@ -5294,10 +5518,10 @@ class ViewState {
5294
5518
  let { top } = this.heightMap.lineAt(from, QueryType.ByPos, this.heightOracle, 0, 0);
5295
5519
  let { bottom } = this.heightMap.lineAt(to, QueryType.ByPos, this.heightOracle, 0, 0);
5296
5520
  let { visibleTop, visibleBottom } = this;
5297
- return (from == 0 || top <= visibleTop - Math.max(10 /* MinCoverMargin */, Math.min(-bias, 250 /* MaxCoverMargin */))) &&
5521
+ return (from == 0 || top <= visibleTop - Math.max(10 /* VP.MinCoverMargin */, Math.min(-bias, 250 /* VP.MaxCoverMargin */))) &&
5298
5522
  (to == this.state.doc.length ||
5299
- bottom >= visibleBottom + Math.max(10 /* MinCoverMargin */, Math.min(bias, 250 /* MaxCoverMargin */))) &&
5300
- (top > visibleTop - 2 * 1000 /* Margin */ && bottom < visibleBottom + 2 * 1000 /* Margin */);
5523
+ bottom >= visibleBottom + Math.max(10 /* VP.MinCoverMargin */, Math.min(bias, 250 /* VP.MaxCoverMargin */))) &&
5524
+ (top > visibleTop - 2 * 1000 /* VP.Margin */ && bottom < visibleBottom + 2 * 1000 /* VP.Margin */);
5301
5525
  }
5302
5526
  mapLineGaps(gaps, changes) {
5303
5527
  if (!gaps.length || changes.empty)
@@ -5317,7 +5541,7 @@ class ViewState {
5317
5541
  // the artifacts this might produce from the user.
5318
5542
  ensureLineGaps(current, mayMeasure) {
5319
5543
  let wrapping = this.heightOracle.lineWrapping;
5320
- let margin = wrapping ? 10000 /* MarginWrap */ : 2000 /* Margin */, halfMargin = margin >> 1, doubleMargin = margin << 1;
5544
+ let margin = wrapping ? 10000 /* LG.MarginWrap */ : 2000 /* LG.Margin */, halfMargin = margin >> 1, doubleMargin = margin << 1;
5321
5545
  // The non-wrapping logic won't work at all in predominantly right-to-left text.
5322
5546
  if (this.defaultTextDirection != Direction.LTR && !wrapping)
5323
5547
  return [];
@@ -5330,8 +5554,8 @@ class ViewState {
5330
5554
  avoid.push(sel.to);
5331
5555
  for (let pos of avoid) {
5332
5556
  if (pos > from && pos < to) {
5333
- addGap(from, pos - 10 /* SelectionMargin */, line, structure);
5334
- addGap(pos + 10 /* SelectionMargin */, to, line, structure);
5557
+ addGap(from, pos - 10 /* LG.SelectionMargin */, line, structure);
5558
+ addGap(pos + 10 /* LG.SelectionMargin */, to, line, structure);
5335
5559
  return;
5336
5560
  }
5337
5561
  }
@@ -5425,7 +5649,7 @@ class ViewState {
5425
5649
  let changed = ranges.length != this.visibleRanges.length ||
5426
5650
  this.visibleRanges.some((r, i) => r.from != ranges[i].from || r.to != ranges[i].to);
5427
5651
  this.visibleRanges = ranges;
5428
- return changed ? 4 /* Viewport */ : 0;
5652
+ return changed ? 4 /* UpdateFlag.Viewport */ : 0;
5429
5653
  }
5430
5654
  lineBlockAt(pos) {
5431
5655
  return (pos >= this.viewport.from && pos <= this.viewport.to && this.viewportLines.find(b => b.from <= pos && b.to >= pos)) ||
@@ -5521,7 +5745,7 @@ class BigScaler {
5521
5745
  vpHeight += bottom - top;
5522
5746
  return { from, to, top, bottom, domTop: 0, domBottom: 0 };
5523
5747
  });
5524
- this.scale = (7000000 /* MaxDOMHeight */ - vpHeight) / (heightMap.height - vpHeight);
5748
+ this.scale = (7000000 /* VP.MaxDOMHeight */ - vpHeight) / (heightMap.height - vpHeight);
5525
5749
  for (let obj of this.viewports) {
5526
5750
  obj.domTop = domBase + (obj.top - base) * this.scale;
5527
5751
  domBase = obj.domBottom = obj.domTop + (obj.bottom - obj.top);
@@ -5688,7 +5912,7 @@ const baseTheme$1 = /*@__PURE__*/buildTheme("." + baseThemeID, {
5688
5912
  display: "flex",
5689
5913
  height: "100%",
5690
5914
  boxSizing: "border-box",
5691
- left: 0,
5915
+ insetInlineStart: 0,
5692
5916
  zIndex: 200
5693
5917
  },
5694
5918
  "&light .cm-gutters": {
@@ -5904,7 +6128,6 @@ function applyDOMChange(view, domChange) {
5904
6128
  change = { from: sel.from, to: sel.to, insert: Text.of([" "]) };
5905
6129
  }
5906
6130
  if (change) {
5907
- let startState = view.state;
5908
6131
  if (browser.ios && view.inputState.flushIOSKey(view))
5909
6132
  return true;
5910
6133
  // Android browsers don't fire reasonable key events for enter,
@@ -5924,64 +6147,12 @@ function applyDOMChange(view, domChange) {
5924
6147
  dispatchKey(view.contentDOM, "Delete", 46))))
5925
6148
  return true;
5926
6149
  let text = change.insert.toString();
5927
- if (view.state.facet(inputHandler).some(h => h(view, change.from, change.to, text)))
5928
- return true;
5929
6150
  if (view.inputState.composing >= 0)
5930
6151
  view.inputState.composing++;
5931
- let tr;
5932
- if (change.from >= sel.from && change.to <= sel.to && change.to - change.from >= (sel.to - sel.from) / 3 &&
5933
- (!newSel || newSel.main.empty && newSel.main.from == change.from + change.insert.length) &&
5934
- view.inputState.composing < 0) {
5935
- let before = sel.from < change.from ? startState.sliceDoc(sel.from, change.from) : "";
5936
- let after = sel.to > change.to ? startState.sliceDoc(change.to, sel.to) : "";
5937
- tr = startState.replaceSelection(view.state.toText(before + change.insert.sliceString(0, undefined, view.state.lineBreak) + after));
5938
- }
5939
- else {
5940
- let changes = startState.changes(change);
5941
- let mainSel = newSel && newSel.main.to <= changes.newLength ? newSel.main : undefined;
5942
- // Try to apply a composition change to all cursors
5943
- if (startState.selection.ranges.length > 1 && view.inputState.composing >= 0 &&
5944
- change.to <= sel.to && change.to >= sel.to - 10) {
5945
- let replaced = view.state.sliceDoc(change.from, change.to);
5946
- let composition = findCompositionNode(view) || view.state.doc.lineAt(sel.head);
5947
- let offset = sel.to - change.to, size = sel.to - sel.from;
5948
- tr = startState.changeByRange(range => {
5949
- if (range.from == sel.from && range.to == sel.to)
5950
- return { changes, range: mainSel || range.map(changes) };
5951
- let to = range.to - offset, from = to - replaced.length;
5952
- if (range.to - range.from != size || view.state.sliceDoc(from, to) != replaced ||
5953
- // Unfortunately, there's no way to make multiple
5954
- // changes in the same node work without aborting
5955
- // composition, so cursors in the composition range are
5956
- // ignored.
5957
- composition && range.to >= composition.from && range.from <= composition.to)
5958
- return { range };
5959
- let rangeChanges = startState.changes({ from, to, insert: change.insert }), selOff = range.to - sel.to;
5960
- return {
5961
- changes: rangeChanges,
5962
- range: !mainSel ? range.map(rangeChanges) :
5963
- EditorSelection.range(Math.max(0, mainSel.anchor + selOff), Math.max(0, mainSel.head + selOff))
5964
- };
5965
- });
5966
- }
5967
- else {
5968
- tr = {
5969
- changes,
5970
- selection: mainSel && startState.selection.replaceRange(mainSel)
5971
- };
5972
- }
5973
- }
5974
- let userEvent = "input.type";
5975
- if (view.composing ||
5976
- view.inputState.compositionPendingChange && view.inputState.compositionEndedAt > Date.now() - 50) {
5977
- view.inputState.compositionPendingChange = false;
5978
- userEvent += ".compose";
5979
- if (view.inputState.compositionFirstChange) {
5980
- userEvent += ".start";
5981
- view.inputState.compositionFirstChange = false;
5982
- }
5983
- }
5984
- view.dispatch(tr, { scrollIntoView: true, userEvent });
6152
+ let defaultTr;
6153
+ let defaultInsert = () => defaultTr || (defaultTr = applyDefaultInsert(view, change, newSel));
6154
+ if (!view.state.facet(inputHandler).some(h => h(view, change.from, change.to, text, defaultInsert)))
6155
+ view.dispatch(defaultInsert());
5985
6156
  return true;
5986
6157
  }
5987
6158
  else if (newSel && !newSel.main.eq(sel)) {
@@ -5998,6 +6169,62 @@ function applyDOMChange(view, domChange) {
5998
6169
  return false;
5999
6170
  }
6000
6171
  }
6172
+ function applyDefaultInsert(view, change, newSel) {
6173
+ let tr, startState = view.state, sel = startState.selection.main;
6174
+ if (change.from >= sel.from && change.to <= sel.to && change.to - change.from >= (sel.to - sel.from) / 3 &&
6175
+ (!newSel || newSel.main.empty && newSel.main.from == change.from + change.insert.length) &&
6176
+ view.inputState.composing < 0) {
6177
+ let before = sel.from < change.from ? startState.sliceDoc(sel.from, change.from) : "";
6178
+ let after = sel.to > change.to ? startState.sliceDoc(change.to, sel.to) : "";
6179
+ tr = startState.replaceSelection(view.state.toText(before + change.insert.sliceString(0, undefined, view.state.lineBreak) + after));
6180
+ }
6181
+ else {
6182
+ let changes = startState.changes(change);
6183
+ let mainSel = newSel && newSel.main.to <= changes.newLength ? newSel.main : undefined;
6184
+ // Try to apply a composition change to all cursors
6185
+ if (startState.selection.ranges.length > 1 && view.inputState.composing >= 0 &&
6186
+ change.to <= sel.to && change.to >= sel.to - 10) {
6187
+ let replaced = view.state.sliceDoc(change.from, change.to);
6188
+ let composition = findCompositionNode(view) || view.state.doc.lineAt(sel.head);
6189
+ let offset = sel.to - change.to, size = sel.to - sel.from;
6190
+ tr = startState.changeByRange(range => {
6191
+ if (range.from == sel.from && range.to == sel.to)
6192
+ return { changes, range: mainSel || range.map(changes) };
6193
+ let to = range.to - offset, from = to - replaced.length;
6194
+ if (range.to - range.from != size || view.state.sliceDoc(from, to) != replaced ||
6195
+ // Unfortunately, there's no way to make multiple
6196
+ // changes in the same node work without aborting
6197
+ // composition, so cursors in the composition range are
6198
+ // ignored.
6199
+ composition && range.to >= composition.from && range.from <= composition.to)
6200
+ return { range };
6201
+ let rangeChanges = startState.changes({ from, to, insert: change.insert }), selOff = range.to - sel.to;
6202
+ return {
6203
+ changes: rangeChanges,
6204
+ range: !mainSel ? range.map(rangeChanges) :
6205
+ EditorSelection.range(Math.max(0, mainSel.anchor + selOff), Math.max(0, mainSel.head + selOff))
6206
+ };
6207
+ });
6208
+ }
6209
+ else {
6210
+ tr = {
6211
+ changes,
6212
+ selection: mainSel && startState.selection.replaceRange(mainSel)
6213
+ };
6214
+ }
6215
+ }
6216
+ let userEvent = "input.type";
6217
+ if (view.composing ||
6218
+ view.inputState.compositionPendingChange && view.inputState.compositionEndedAt > Date.now() - 50) {
6219
+ view.inputState.compositionPendingChange = false;
6220
+ userEvent += ".compose";
6221
+ if (view.inputState.compositionFirstChange) {
6222
+ userEvent += ".start";
6223
+ view.inputState.compositionFirstChange = false;
6224
+ }
6225
+ }
6226
+ return startState.update(tr, { userEvent, scrollIntoView: true });
6227
+ }
6001
6228
  function findDiff(a, b, preferredPos, preferredSide) {
6002
6229
  let minLen = Math.min(a.length, b.length);
6003
6230
  let from = 0;
@@ -6415,7 +6642,7 @@ class DOMObserver {
6415
6642
  return null;
6416
6643
  cView.markDirty(rec.type == "attributes");
6417
6644
  if (rec.type == "attributes")
6418
- cView.flags |= 4 /* AttrsDirty */;
6645
+ cView.flags |= 4 /* ViewFlag.AttrsDirty */;
6419
6646
  if (rec.type == "childList") {
6420
6647
  let childBefore = findChild(cView, rec.previousSibling || rec.target.previousSibling, -1);
6421
6648
  let childAfter = findChild(cView, rec.nextSibling || rec.target.nextSibling, 1);
@@ -6523,6 +6750,53 @@ line number gutter. It handles events and dispatches state
6523
6750
  transactions for editing actions.
6524
6751
  */
6525
6752
  class EditorView {
6753
+ /**
6754
+ The current editor state.
6755
+ */
6756
+ get state() { return this.viewState.state; }
6757
+ /**
6758
+ To be able to display large documents without consuming too much
6759
+ memory or overloading the browser, CodeMirror only draws the
6760
+ code that is visible (plus a margin around it) to the DOM. This
6761
+ property tells you the extent of the current drawn viewport, in
6762
+ document positions.
6763
+ */
6764
+ get viewport() { return this.viewState.viewport; }
6765
+ /**
6766
+ When there are, for example, large collapsed ranges in the
6767
+ viewport, its size can be a lot bigger than the actual visible
6768
+ content. Thus, if you are doing something like styling the
6769
+ content in the viewport, it is preferable to only do so for
6770
+ these ranges, which are the subset of the viewport that is
6771
+ actually drawn.
6772
+ */
6773
+ get visibleRanges() { return this.viewState.visibleRanges; }
6774
+ /**
6775
+ Returns false when the editor is entirely scrolled out of view
6776
+ or otherwise hidden.
6777
+ */
6778
+ get inView() { return this.viewState.inView; }
6779
+ /**
6780
+ Indicates whether the user is currently composing text via
6781
+ [IME](https://en.wikipedia.org/wiki/Input_method), and at least
6782
+ one change has been made in the current composition.
6783
+ */
6784
+ get composing() { return this.inputState.composing > 0; }
6785
+ /**
6786
+ Indicates whether the user is currently in composing state. Note
6787
+ that on some platforms, like Android, this will be the case a
6788
+ lot, since just putting the cursor on a word starts a
6789
+ composition there.
6790
+ */
6791
+ get compositionStarted() { return this.inputState.composing >= 0; }
6792
+ /**
6793
+ The document or shadow root that the view lives in.
6794
+ */
6795
+ get root() { return this._root; }
6796
+ /**
6797
+ @internal
6798
+ */
6799
+ get win() { return this.dom.ownerDocument.defaultView || window; }
6526
6800
  /**
6527
6801
  Construct a new view. You'll want to either provide a `parent`
6528
6802
  option, or put `view.dom` into your document after creating a
@@ -6538,7 +6812,7 @@ class EditorView {
6538
6812
  /**
6539
6813
  @internal
6540
6814
  */
6541
- this.updateState = 2 /* Updating */;
6815
+ this.updateState = 2 /* UpdateState.Updating */;
6542
6816
  /**
6543
6817
  @internal
6544
6818
  */
@@ -6558,7 +6832,10 @@ class EditorView {
6558
6832
  this.dom = document.createElement("div");
6559
6833
  this.dom.appendChild(this.announceDOM);
6560
6834
  this.dom.appendChild(this.scrollDOM);
6561
- this._dispatch = config.dispatch || ((tr) => this.update([tr]));
6835
+ let { dispatch } = config;
6836
+ this.dispatchTransactions = config.dispatchTransactions ||
6837
+ (dispatch && ((trs) => trs.forEach(tr => dispatch(tr, this)))) ||
6838
+ ((trs) => this.update(trs));
6562
6839
  this.dispatch = this.dispatch.bind(this);
6563
6840
  this._root = (config.root || getRoot(config.parent) || document);
6564
6841
  this.viewState = new ViewState(config.state || EditorState.create(config));
@@ -6571,62 +6848,16 @@ class EditorView {
6571
6848
  this.docView = new DocView(this);
6572
6849
  this.mountStyles();
6573
6850
  this.updateAttrs();
6574
- this.updateState = 0 /* Idle */;
6851
+ this.updateState = 0 /* UpdateState.Idle */;
6575
6852
  this.requestMeasure();
6576
6853
  if (config.parent)
6577
6854
  config.parent.appendChild(this.dom);
6578
6855
  }
6579
- /**
6580
- The current editor state.
6581
- */
6582
- get state() { return this.viewState.state; }
6583
- /**
6584
- To be able to display large documents without consuming too much
6585
- memory or overloading the browser, CodeMirror only draws the
6586
- code that is visible (plus a margin around it) to the DOM. This
6587
- property tells you the extent of the current drawn viewport, in
6588
- document positions.
6589
- */
6590
- get viewport() { return this.viewState.viewport; }
6591
- /**
6592
- When there are, for example, large collapsed ranges in the
6593
- viewport, its size can be a lot bigger than the actual visible
6594
- content. Thus, if you are doing something like styling the
6595
- content in the viewport, it is preferable to only do so for
6596
- these ranges, which are the subset of the viewport that is
6597
- actually drawn.
6598
- */
6599
- get visibleRanges() { return this.viewState.visibleRanges; }
6600
- /**
6601
- Returns false when the editor is entirely scrolled out of view
6602
- or otherwise hidden.
6603
- */
6604
- get inView() { return this.viewState.inView; }
6605
- /**
6606
- Indicates whether the user is currently composing text via
6607
- [IME](https://en.wikipedia.org/wiki/Input_method), and at least
6608
- one change has been made in the current composition.
6609
- */
6610
- get composing() { return this.inputState.composing > 0; }
6611
- /**
6612
- Indicates whether the user is currently in composing state. Note
6613
- that on some platforms, like Android, this will be the case a
6614
- lot, since just putting the cursor on a word starts a
6615
- composition there.
6616
- */
6617
- get compositionStarted() { return this.inputState.composing >= 0; }
6618
- /**
6619
- The document or shadow root that the view lives in.
6620
- */
6621
- get root() { return this._root; }
6622
- /**
6623
- @internal
6624
- */
6625
- get win() { return this.dom.ownerDocument.defaultView || window; }
6626
6856
  dispatch(...input) {
6627
- let tr = input.length == 1 && input[0] instanceof Transaction ? input[0]
6628
- : this.state.update(...input);
6629
- this._dispatch(tr, this);
6857
+ let trs = input.length == 1 && input[0] instanceof Transaction ? input
6858
+ : input.length == 1 && Array.isArray(input[0]) ? input[0]
6859
+ : [this.state.update(...input)];
6860
+ this.dispatchTransactions(trs, this);
6630
6861
  }
6631
6862
  /**
6632
6863
  Update the view for the given array of transactions. This will
@@ -6637,7 +6868,7 @@ class EditorView {
6637
6868
  as a primitive.
6638
6869
  */
6639
6870
  update(transactions) {
6640
- if (this.updateState != 0 /* Idle */)
6871
+ if (this.updateState != 0 /* UpdateState.Idle */)
6641
6872
  throw new Error("Calls to EditorView.update are not allowed while an update is in progress");
6642
6873
  let redrawn = false, attrsChanged = false, update;
6643
6874
  let state = this.state;
@@ -6654,7 +6885,7 @@ class EditorView {
6654
6885
  if (transactions.some(tr => tr.annotation(isFocusChange))) {
6655
6886
  this.inputState.notifiedFocused = focus;
6656
6887
  // If a focus-change transaction is being dispatched, set this update flag.
6657
- focusFlag = 1 /* Focus */;
6888
+ focusFlag = 1 /* UpdateFlag.Focus */;
6658
6889
  }
6659
6890
  else if (focus != this.inputState.notifiedFocused) {
6660
6891
  this.inputState.notifiedFocused = focus;
@@ -6662,7 +6893,7 @@ class EditorView {
6662
6893
  // add a flag to this update
6663
6894
  dispatchFocus = focusChangeTransaction(state, focus);
6664
6895
  if (!dispatchFocus)
6665
- focusFlag = 1 /* Focus */;
6896
+ focusFlag = 1 /* UpdateFlag.Focus */;
6666
6897
  }
6667
6898
  // If there was a pending DOM change, eagerly read it and try to
6668
6899
  // apply it after the given transactions.
@@ -6685,7 +6916,7 @@ class EditorView {
6685
6916
  update.flags |= focusFlag;
6686
6917
  let scrollTarget = this.viewState.scrollTarget;
6687
6918
  try {
6688
- this.updateState = 2 /* Updating */;
6919
+ this.updateState = 2 /* UpdateState.Updating */;
6689
6920
  for (let tr of transactions) {
6690
6921
  if (scrollTarget)
6691
6922
  scrollTarget = scrollTarget.map(tr.changes);
@@ -6711,7 +6942,7 @@ class EditorView {
6711
6942
  this.docView.updateSelection(redrawn, transactions.some(tr => tr.isUserEvent("select.pointer")));
6712
6943
  }
6713
6944
  finally {
6714
- this.updateState = 0 /* Idle */;
6945
+ this.updateState = 0 /* UpdateState.Idle */;
6715
6946
  }
6716
6947
  if (update.startState.facet(theme) != update.state.facet(theme))
6717
6948
  this.viewState.mustMeasureContent = true;
@@ -6738,13 +6969,13 @@ class EditorView {
6738
6969
  [`dispatch`](https://codemirror.net/6/docs/ref/#view.EditorView.dispatch) instead.)
6739
6970
  */
6740
6971
  setState(newState) {
6741
- if (this.updateState != 0 /* Idle */)
6972
+ if (this.updateState != 0 /* UpdateState.Idle */)
6742
6973
  throw new Error("Calls to EditorView.setState are not allowed while an update is in progress");
6743
6974
  if (this.destroyed) {
6744
6975
  this.viewState.state = newState;
6745
6976
  return;
6746
6977
  }
6747
- this.updateState = 2 /* Updating */;
6978
+ this.updateState = 2 /* UpdateState.Updating */;
6748
6979
  let hadFocus = this.hasFocus;
6749
6980
  try {
6750
6981
  for (let plugin of this.plugins)
@@ -6761,7 +6992,7 @@ class EditorView {
6761
6992
  this.bidiCache = [];
6762
6993
  }
6763
6994
  finally {
6764
- this.updateState = 0 /* Idle */;
6995
+ this.updateState = 0 /* UpdateState.Idle */;
6765
6996
  }
6766
6997
  if (hadFocus)
6767
6998
  this.focus();
@@ -6826,7 +7057,7 @@ class EditorView {
6826
7057
  scrollAnchorHeight = block.top;
6827
7058
  }
6828
7059
  }
6829
- this.updateState = 1 /* Measuring */;
7060
+ this.updateState = 1 /* UpdateState.Measuring */;
6830
7061
  let changed = this.viewState.measure(this);
6831
7062
  if (!changed && !this.measureRequests.length && this.viewState.scrollTarget == null)
6832
7063
  break;
@@ -6838,7 +7069,7 @@ class EditorView {
6838
7069
  }
6839
7070
  let measuring = [];
6840
7071
  // Only run measure requests in this cycle when the viewport didn't change
6841
- if (!(changed & 4 /* Viewport */))
7072
+ if (!(changed & 4 /* UpdateFlag.Viewport */))
6842
7073
  [this.measureRequests, measuring] = [measuring, this.measureRequests];
6843
7074
  let measured = measuring.map(m => {
6844
7075
  try {
@@ -6855,7 +7086,7 @@ class EditorView {
6855
7086
  updated = update;
6856
7087
  else
6857
7088
  updated.flags |= changed;
6858
- this.updateState = 2 /* Updating */;
7089
+ this.updateState = 2 /* UpdateState.Updating */;
6859
7090
  if (!update.empty) {
6860
7091
  this.updatePlugins(update);
6861
7092
  this.inputState.update(update);
@@ -6898,7 +7129,7 @@ class EditorView {
6898
7129
  }
6899
7130
  }
6900
7131
  finally {
6901
- this.updateState = 0 /* Idle */;
7132
+ this.updateState = 0 /* UpdateState.Idle */;
6902
7133
  this.measureScheduled = -1;
6903
7134
  }
6904
7135
  if (updated && !updated.empty)
@@ -6954,12 +7185,13 @@ class EditorView {
6954
7185
  }
6955
7186
  mountStyles() {
6956
7187
  this.styleModules = this.state.facet(styleModule);
6957
- StyleModule.mount(this.root, this.styleModules.concat(baseTheme$1).reverse());
7188
+ let nonce = this.state.facet(EditorView.cspNonce);
7189
+ StyleModule.mount(this.root, this.styleModules.concat(baseTheme$1).reverse(), nonce ? { nonce } : undefined);
6958
7190
  }
6959
7191
  readMeasured() {
6960
- if (this.updateState == 2 /* Updating */)
7192
+ if (this.updateState == 2 /* UpdateState.Updating */)
6961
7193
  throw new Error("Reading the editor layout isn't allowed during an update");
6962
- if (this.updateState == 0 /* Idle */ && this.measureScheduled > -1)
7194
+ if (this.updateState == 0 /* UpdateState.Idle */ && this.measureScheduled > -1)
6963
7195
  this.measure(false);
6964
7196
  }
6965
7197
  /**
@@ -7152,6 +7384,17 @@ class EditorView {
7152
7384
  return flattenRect(rect, (span.dir == Direction.LTR) == (side > 0));
7153
7385
  }
7154
7386
  /**
7387
+ Return the rectangle around a given character. If `pos` does not
7388
+ point in front of a character that is in the viewport and
7389
+ rendered (i.e. not replaced, not a line break), this will return
7390
+ null. For space characters that are a line wrap point, this will
7391
+ return the position before the line break.
7392
+ */
7393
+ coordsForChar(pos) {
7394
+ this.readMeasured();
7395
+ return this.docView.coordsForChar(pos);
7396
+ }
7397
+ /**
7155
7398
  The default width of a character in the editor. May not
7156
7399
  accurately reflect the width of all characters (given variable
7157
7400
  width fonts or styling of invididual ranges).
@@ -7202,12 +7445,16 @@ class EditorView {
7202
7445
  bidiSpans(line) {
7203
7446
  if (line.length > MaxBidiLine)
7204
7447
  return trivialOrder(line.length);
7205
- let dir = this.textDirectionAt(line.from);
7206
- for (let entry of this.bidiCache)
7207
- if (entry.from == line.from && entry.dir == dir)
7448
+ let dir = this.textDirectionAt(line.from), isolates;
7449
+ for (let entry of this.bidiCache) {
7450
+ if (entry.from == line.from && entry.dir == dir &&
7451
+ (entry.fresh || isolatesEq(entry.isolates, isolates = getIsolatedRanges(this, line.from, line.to))))
7208
7452
  return entry.order;
7209
- let order = computeOrder(line.text, dir);
7210
- this.bidiCache.push(new CachedOrder(line.from, line.to, dir, order));
7453
+ }
7454
+ if (!isolates)
7455
+ isolates = getIsolatedRanges(this, line.from, line.to);
7456
+ let order = computeOrder(line.text, dir, isolates);
7457
+ this.bidiCache.push(new CachedOrder(line.from, line.to, dir, isolates, true, order));
7211
7458
  return order;
7212
7459
  }
7213
7460
  /**
@@ -7342,6 +7589,10 @@ DOM content are handled. Handlers are passed the document
7342
7589
  positions between which the change was found, and the new
7343
7590
  content. When one returns true, no further input handlers are
7344
7591
  called and the default behavior is prevented.
7592
+
7593
+ The `insert` argument can be used to get the default transaction
7594
+ that would be applied for this input. This can be useful when
7595
+ dispatching the custom behavior as a separate transaction.
7345
7596
  */
7346
7597
  EditorView.inputHandler = inputHandler;
7347
7598
  /**
@@ -7429,6 +7680,16 @@ regions.
7429
7680
  */
7430
7681
  EditorView.atomicRanges = atomicRanges;
7431
7682
  /**
7683
+ When range decorations add a `unicode-bidi: isolate` style, they
7684
+ should also include a
7685
+ [`bidiIsolate`](https://codemirror.net/6/docs/ref/#view.MarkDecorationSpec.bidiIsolate) property
7686
+ in their decoration spec, and be exposed through this facet, so
7687
+ that the editor can compute the proper text order. (Other values
7688
+ for `unicode-bidi`, except of course `normal`, are not
7689
+ supported.)
7690
+ */
7691
+ EditorView.bidiIsolatedRanges = bidiIsolatedRanges;
7692
+ /**
7432
7693
  Facet that allows extensions to provide additional scroll
7433
7694
  margins (space around the sides of the scrolling element that
7434
7695
  should be considered invisible). This can be useful when the
@@ -7444,6 +7705,12 @@ true.
7444
7705
  */
7445
7706
  EditorView.darkTheme = darkTheme;
7446
7707
  /**
7708
+ Provides a Content Security Policy nonce to use when creating
7709
+ the style sheets for the editor. Holds the empty string when no
7710
+ nonce has been provided.
7711
+ */
7712
+ EditorView.cspNonce = /*@__PURE__*/Facet.define({ combine: values => values.length ? values[0] : "" });
7713
+ /**
7447
7714
  Facet that provides additional DOM attributes for the editor's
7448
7715
  editable DOM element.
7449
7716
  */
@@ -7471,20 +7738,22 @@ EditorView.announce = /*@__PURE__*/StateEffect.define();
7471
7738
  const MaxBidiLine = 4096;
7472
7739
  const BadMeasure = {};
7473
7740
  class CachedOrder {
7474
- constructor(from, to, dir, order) {
7741
+ constructor(from, to, dir, isolates, fresh, order) {
7475
7742
  this.from = from;
7476
7743
  this.to = to;
7477
7744
  this.dir = dir;
7745
+ this.isolates = isolates;
7746
+ this.fresh = fresh;
7478
7747
  this.order = order;
7479
7748
  }
7480
7749
  static update(cache, changes) {
7481
- if (changes.empty)
7750
+ if (changes.empty && !cache.some(c => c.fresh))
7482
7751
  return cache;
7483
7752
  let result = [], lastDir = cache.length ? cache[cache.length - 1].dir : Direction.LTR;
7484
7753
  for (let i = Math.max(0, cache.length - 10); i < cache.length; i++) {
7485
7754
  let entry = cache[i];
7486
7755
  if (entry.dir == lastDir && !changes.touchesRange(entry.from, entry.to))
7487
- result.push(new CachedOrder(changes.mapPos(entry.from, 1), changes.mapPos(entry.to, -1), entry.dir, entry.order));
7756
+ result.push(new CachedOrder(changes.mapPos(entry.from, 1), changes.mapPos(entry.to, -1), entry.dir, entry.isolates, false, entry.order));
7488
7757
  }
7489
7758
  return result;
7490
7759
  }
@@ -7807,7 +8076,7 @@ function rectanglesForRange(view, className, range) {
7807
8076
  return pieces(top).concat(between).concat(pieces(bottom));
7808
8077
  }
7809
8078
  function piece(left, top, right, bottom) {
7810
- return new RectangleMarker(className, left - base.left, top - base.top - 0.01 /* Epsilon */, right - left, bottom - top + 0.01 /* Epsilon */);
8079
+ return new RectangleMarker(className, left - base.left, top - base.top - 0.01 /* C.Epsilon */, right - left, bottom - top + 0.01 /* C.Epsilon */);
7811
8080
  }
7812
8081
  function pieces({ top, bottom, horizontal }) {
7813
8082
  let pieces = [];
@@ -8824,12 +9093,12 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
8824
9093
  continue;
8825
9094
  }
8826
9095
  let arrow = tooltip.arrow ? tView.dom.querySelector(".cm-tooltip-arrow") : null;
8827
- let arrowHeight = arrow ? 7 /* Size */ : 0;
9096
+ let arrowHeight = arrow ? 7 /* Arrow.Size */ : 0;
8828
9097
  let width = size.right - size.left, height = (_a = knownHeight.get(tView)) !== null && _a !== void 0 ? _a : size.bottom - size.top;
8829
9098
  let offset = tView.offset || noOffset, ltr = this.view.textDirection == Direction.LTR;
8830
9099
  let left = size.width > space.right - space.left ? (ltr ? space.left : space.right - size.width)
8831
- : ltr ? Math.min(pos.left - (arrow ? 14 /* Offset */ : 0) + offset.x, space.right - width)
8832
- : Math.max(space.left, pos.left - width + (arrow ? 14 /* Offset */ : 0) - offset.x);
9100
+ : ltr ? Math.min(pos.left - (arrow ? 14 /* Arrow.Offset */ : 0) + offset.x, space.right - width)
9101
+ : Math.max(space.left, pos.left - width + (arrow ? 14 /* Arrow.Offset */ : 0) - offset.x);
8833
9102
  let above = !!tooltip.above;
8834
9103
  if (!tooltip.strictSide && (above
8835
9104
  ? pos.top - (size.bottom - size.top) - offset.y < space.top
@@ -8863,7 +9132,7 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
8863
9132
  dom.style.left = left + "px";
8864
9133
  }
8865
9134
  if (arrow)
8866
- arrow.style.left = `${pos.left + (ltr ? offset.x : -offset.x) - (left + 14 /* Offset */ - 7 /* Size */)}px`;
9135
+ arrow.style.left = `${pos.left + (ltr ? offset.x : -offset.x) - (left + 14 /* Arrow.Offset */ - 7 /* Arrow.Size */)}px`;
8867
9136
  if (tView.overlap !== true)
8868
9137
  others.push({ left, top, right, bottom: top + height });
8869
9138
  dom.classList.toggle("cm-tooltip-above", above);
@@ -8906,8 +9175,8 @@ const baseTheme = /*@__PURE__*/EditorView.baseTheme({
8906
9175
  color: "white"
8907
9176
  },
8908
9177
  ".cm-tooltip-arrow": {
8909
- height: `${7 /* Size */}px`,
8910
- width: `${7 /* Size */ * 2}px`,
9178
+ height: `${7 /* Arrow.Size */}px`,
9179
+ width: `${7 /* Arrow.Size */ * 2}px`,
8911
9180
  position: "absolute",
8912
9181
  zIndex: -1,
8913
9182
  overflow: "hidden",
@@ -8916,26 +9185,26 @@ const baseTheme = /*@__PURE__*/EditorView.baseTheme({
8916
9185
  position: "absolute",
8917
9186
  width: 0,
8918
9187
  height: 0,
8919
- borderLeft: `${7 /* Size */}px solid transparent`,
8920
- borderRight: `${7 /* Size */}px solid transparent`,
9188
+ borderLeft: `${7 /* Arrow.Size */}px solid transparent`,
9189
+ borderRight: `${7 /* Arrow.Size */}px solid transparent`,
8921
9190
  },
8922
9191
  ".cm-tooltip-above &": {
8923
- bottom: `-${7 /* Size */}px`,
9192
+ bottom: `-${7 /* Arrow.Size */}px`,
8924
9193
  "&:before": {
8925
- borderTop: `${7 /* Size */}px solid #bbb`,
9194
+ borderTop: `${7 /* Arrow.Size */}px solid #bbb`,
8926
9195
  },
8927
9196
  "&:after": {
8928
- borderTop: `${7 /* Size */}px solid #f5f5f5`,
9197
+ borderTop: `${7 /* Arrow.Size */}px solid #f5f5f5`,
8929
9198
  bottom: "1px"
8930
9199
  }
8931
9200
  },
8932
9201
  ".cm-tooltip-below &": {
8933
- top: `-${7 /* Size */}px`,
9202
+ top: `-${7 /* Arrow.Size */}px`,
8934
9203
  "&:before": {
8935
- borderBottom: `${7 /* Size */}px solid #bbb`,
9204
+ borderBottom: `${7 /* Arrow.Size */}px solid #bbb`,
8936
9205
  },
8937
9206
  "&:after": {
8938
- borderBottom: `${7 /* Size */}px solid #f5f5f5`,
9207
+ borderBottom: `${7 /* Arrow.Size */}px solid #f5f5f5`,
8939
9208
  top: "1px"
8940
9209
  }
8941
9210
  },
@@ -8960,6 +9229,10 @@ const showTooltip = /*@__PURE__*/Facet.define({
8960
9229
  });
8961
9230
  const showHoverTooltip = /*@__PURE__*/Facet.define();
8962
9231
  class HoverTooltipHost {
9232
+ // Needs to be static so that host tooltip instances always match
9233
+ static create(view) {
9234
+ return new HoverTooltipHost(view);
9235
+ }
8963
9236
  constructor(view) {
8964
9237
  this.view = view;
8965
9238
  this.mounted = false;
@@ -8967,10 +9240,6 @@ class HoverTooltipHost {
8967
9240
  this.dom.classList.add("cm-tooltip-hover");
8968
9241
  this.manager = new TooltipViewManager(view, showHoverTooltip, t => this.createHostedView(t));
8969
9242
  }
8970
- // Needs to be static so that host tooltip instances always match
8971
- static create(view) {
8972
- return new HoverTooltipHost(view);
8973
- }
8974
9243
  createHostedView(tooltip) {
8975
9244
  let hostedView = tooltip.create(this.view);
8976
9245
  hostedView.dom.classList.add("cm-tooltip-section");
@@ -9050,30 +9319,41 @@ class HoverPlugin {
9050
9319
  }
9051
9320
  startHover() {
9052
9321
  clearTimeout(this.restartTimeout);
9053
- let { lastMove } = this;
9054
- let pos = this.view.contentDOM.contains(lastMove.target) ? this.view.posAtCoords(lastMove) : null;
9055
- if (pos == null)
9056
- return;
9057
- let posCoords = this.view.coordsAtPos(pos);
9058
- if (posCoords == null || lastMove.y < posCoords.top || lastMove.y > posCoords.bottom ||
9059
- lastMove.x < posCoords.left - this.view.defaultCharacterWidth ||
9060
- lastMove.x > posCoords.right + this.view.defaultCharacterWidth)
9322
+ let { view, lastMove } = this;
9323
+ let desc = view.docView.nearest(lastMove.target);
9324
+ if (!desc)
9061
9325
  return;
9062
- let bidi = this.view.bidiSpans(this.view.state.doc.lineAt(pos)).find(s => s.from <= pos && s.to >= pos);
9063
- let rtl = bidi && bidi.dir == Direction.RTL ? -1 : 1;
9064
- let open = this.source(this.view, pos, (lastMove.x < posCoords.left ? -rtl : rtl));
9326
+ let pos, side = 1;
9327
+ if (desc instanceof WidgetView) {
9328
+ pos = desc.posAtStart;
9329
+ }
9330
+ else {
9331
+ pos = view.posAtCoords(lastMove);
9332
+ if (pos == null)
9333
+ return;
9334
+ let posCoords = view.coordsAtPos(pos);
9335
+ if (!posCoords ||
9336
+ lastMove.y < posCoords.top || lastMove.y > posCoords.bottom ||
9337
+ lastMove.x < posCoords.left - view.defaultCharacterWidth ||
9338
+ lastMove.x > posCoords.right + view.defaultCharacterWidth)
9339
+ return;
9340
+ let bidi = view.bidiSpans(view.state.doc.lineAt(pos)).find(s => s.from <= pos && s.to >= pos);
9341
+ let rtl = bidi && bidi.dir == Direction.RTL ? -1 : 1;
9342
+ side = (lastMove.x < posCoords.left ? -rtl : rtl);
9343
+ }
9344
+ let open = this.source(view, pos, side);
9065
9345
  if (open === null || open === void 0 ? void 0 : open.then) {
9066
9346
  let pending = this.pending = { pos };
9067
9347
  open.then(result => {
9068
9348
  if (this.pending == pending) {
9069
9349
  this.pending = null;
9070
9350
  if (result)
9071
- this.view.dispatch({ effects: this.setHover.of(result) });
9351
+ view.dispatch({ effects: this.setHover.of(result) });
9072
9352
  }
9073
- }, e => logException(this.view.state, e, "hover tooltip"));
9353
+ }, e => logException(view.state, e, "hover tooltip"));
9074
9354
  }
9075
9355
  else if (open) {
9076
- this.view.dispatch({ effects: this.setHover.of(open) });
9356
+ view.dispatch({ effects: this.setHover.of(open) });
9077
9357
  }
9078
9358
  }
9079
9359
  mousemove(event) {
@@ -9085,7 +9365,7 @@ class HoverPlugin {
9085
9365
  if (tooltip && !isInTooltip(this.lastMove.target) || this.pending) {
9086
9366
  let { pos } = tooltip || this.pending, end = (_a = tooltip === null || tooltip === void 0 ? void 0 : tooltip.end) !== null && _a !== void 0 ? _a : pos;
9087
9367
  if ((pos == end ? this.view.posAtCoords(this.lastMove) != pos
9088
- : !isOverRange(this.view, pos, end, event.clientX, event.clientY, 6 /* MaxDist */))) {
9368
+ : !isOverRange(this.view, pos, end, event.clientX, event.clientY, 6 /* Hover.MaxDist */))) {
9089
9369
  this.view.dispatch({ effects: this.setHover.of(null) });
9090
9370
  this.pending = null;
9091
9371
  }
@@ -9167,7 +9447,7 @@ function hoverTooltip(source, options = {}) {
9167
9447
  });
9168
9448
  return [
9169
9449
  hoverState,
9170
- ViewPlugin.define(view => new HoverPlugin(view, source, hoverState, setHover, options.hoverTime || 300 /* Time */)),
9450
+ ViewPlugin.define(view => new HoverPlugin(view, source, hoverState, setHover, options.hoverTime || 300 /* Hover.Time */)),
9171
9451
  showHoverTooltipHost
9172
9452
  ];
9173
9453
  }