@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/CHANGELOG.md +28 -0
- package/dist/index.cjs +693 -415
- package/dist/index.d.cts +108 -64
- package/dist/index.d.ts +108 -64
- package/dist/index.js +694 -414
- package/package.json +2 -2
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 =
|
|
1168
|
+
let changed = false;
|
|
1171
1169
|
if (prev)
|
|
1172
1170
|
for (let name in prev)
|
|
1173
|
-
if (!(attrs && name in attrs))
|
|
1174
|
-
|
|
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
|
-
|
|
1179
|
-
|
|
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
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
type =
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
end
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
types[
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
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
|
-
|
|
2362
|
-
|
|
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
|
-
|
|
2374
|
-
|
|
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
|
-
|
|
2378
|
-
|
|
2379
|
-
BracketStack[sI++] = context;
|
|
2500
|
+
prev = type;
|
|
2501
|
+
i++;
|
|
2380
2502
|
}
|
|
2381
2503
|
}
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
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
|
-
|
|
2440
|
-
|
|
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
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
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.
|
|
2726
|
-
domSel.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
view.
|
|
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
|
-
|
|
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
|
|
6635
|
-
:
|
|
6636
|
-
|
|
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
|
-
|
|
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
|
-
|
|
7217
|
-
|
|
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
|
|
9062
|
-
if (
|
|
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
|
|
9070
|
-
|
|
9071
|
-
|
|
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
|
-
|
|
9356
|
+
view.dispatch({ effects: this.setHover.of(result) });
|
|
9079
9357
|
}
|
|
9080
|
-
}, e => logException(
|
|
9358
|
+
}, e => logException(view.state, e, "hover tooltip"));
|
|
9081
9359
|
}
|
|
9082
9360
|
else if (open) {
|
|
9083
|
-
|
|
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
|
}
|