datafolder 1.0.7 → 1.0.9
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/README.md +4 -1
- package/index.js +1 -1
- package/internal.md +5 -3
- package/package.json +7 -5
- package/scripts/airbnb.js +77 -72
- package/scripts/airbnb2.js +78 -73
- package/scripts/airbnb2_queries.js +181 -229
- package/scripts/airbnb_queries.js +214 -265
- package/scripts/convertBinFiles.js +47 -49
- package/scripts/downloadFile.js +41 -40
- package/scripts/express.js +44 -48
- package/scripts/fastify.js +71 -80
- package/scripts/flights.js +71 -75
- package/scripts/flights2.js +78 -81
- package/scripts/flights2_queries.js +417 -455
- package/scripts/flights_queries.js +381 -407
- package/src/QyAcl.d.ts +17 -0
- package/src/QyAcl.js +113 -116
- package/src/QyAclSaver.d.ts +4 -0
- package/src/QyAclSaver.js +3 -3
- package/src/QyAclSaver_Worker.d.ts +9 -0
- package/src/QyAclSaver_Worker.js +2 -4
- package/src/QyAclWriter.d.ts +5 -0
- package/src/QyBatch.d.ts +42 -0
- package/src/QyBatch.js +8 -8
- package/src/QyBinWriter.d.ts +15 -0
- package/src/QyCD.d.ts +37 -0
- package/src/QyCD.js +8 -6
- package/src/QyCache.d.ts +44 -0
- package/src/QyCache.js +65 -59
- package/src/QyCompressor.d.ts +9 -0
- package/src/QyCompressor.js +29 -29
- package/src/QyCompressor_Worker.d.ts +1 -0
- package/src/QyDB.d.ts +42 -0
- package/src/QyDB.js +13 -11
- package/src/QyDefaultOptions.d.ts +1 -0
- package/src/QyDefaultOptions.js +3 -0
- package/src/QyDir.d.ts +48 -0
- package/src/QyDir.js +41 -41
- package/src/QyFetch.d.ts +7 -0
- package/src/QyFetch.js +2 -3
- package/src/QyFile.d.ts +19 -0
- package/src/QyFile.js +35 -34
- package/src/QyFileContentUtils.d.ts +13 -0
- package/src/QyFileContentUtils.js +126 -126
- package/src/QyFileLogger.d.ts +11 -0
- package/src/QyIndex.d.ts +6 -0
- package/src/QyIndex.js +73 -75
- package/src/QyIndexPropTree.d.ts +7 -0
- package/src/QyIndexPropTree.js +24 -24
- package/src/QyIntersectNode.d.ts +7 -0
- package/src/QyIntersectNode.js +15 -15
- package/src/QyItem.d.ts +30 -0
- package/src/QyItem.js +32 -28
- package/src/QyJsonSaver.d.ts +6 -0
- package/src/QyKVData.d.ts +12 -0
- package/src/QyKVData.js +11 -10
- package/src/QyKVDataCleaner.d.ts +4 -0
- package/src/QyKVDataCleaner.js +1 -1
- package/src/QyKVDataCleaner_Worker.d.ts +13 -0
- package/src/QyKVDataCleaner_Worker.js +2 -4
- package/src/QyKVDataLoader.d.ts +9 -0
- package/src/QyKVDataLoader.js +11 -11
- package/src/QyKVDataSaver.d.ts +4 -0
- package/src/QyKVDataSaver.js +6 -6
- package/src/QyKVDataSaver_Worker.d.ts +13 -0
- package/src/QyKVDataSaver_Worker.js +7 -9
- package/src/QyLogFileSaver.d.ts +4 -0
- package/src/QyLogFileSaver.js +1 -1
- package/src/QyLogFileSaver_Worker.d.ts +8 -0
- package/src/QyLogFileSaver_Worker.js +2 -4
- package/src/QyLogger.d.ts +10 -0
- package/src/QyLogger.js +40 -40
- package/src/QyMessageWorker.d.ts +5 -0
- package/src/QyMessageWorker.js +7 -7
- package/src/QyMessager.d.ts +7 -0
- package/src/QyMessager.js +30 -27
- package/src/QyMessager_Run.d.ts +1 -0
- package/src/QyMessager_Run.js +11 -6
- package/src/QyMod.d.ts +1 -0
- package/src/QyMod.js +6 -6
- package/src/QyOpRunner.d.ts +10 -0
- package/src/QyOpRunner.js +39 -39
- package/src/QyQueue.d.ts +11 -0
- package/src/QySaver.d.ts +10 -0
- package/src/QySnapshotCompactor.d.ts +4 -0
- package/src/QySnapshotCompactor.js +1 -1
- package/src/QySnapshotCompactor_Worker.d.ts +11 -0
- package/src/QySnapshotCompactor_Worker.js +2 -4
- package/src/QySnapshotSaver.d.ts +4 -0
- package/src/QySnapshotSaver.js +1 -1
- package/src/QySnapshotSaver_Worker.d.ts +16 -0
- package/src/QySnapshotSaver_Worker.js +17 -16
- package/src/QySnapshots.d.ts +27 -0
- package/src/QySnapshots.js +3 -3
- package/src/QyStructure.d.ts +1 -0
- package/src/QyStructure.js +18 -18
- package/src/QyTrigger.d.ts +9 -0
- package/src/QyTrigger.js +30 -30
- package/src/QyUnionNode.d.ts +17 -0
- package/src/QyUnionNode.js +2 -2
- package/src/QyUtils.d.ts +53 -0
- package/src/QyUtils.js +140 -117
- package/src/QyWorker.d.ts +5 -0
- package/src/QyWorker.js +18 -18
- package/src/hackernews.d.ts +1 -0
- package/src/hackernews.js +59 -47
- package/src/rpc/getRpcFiles.js +1 -0
- package/src/simulate.d.ts +1 -0
- package/src/simulate2.d.ts +1 -0
- package/src/soc_pokec.d.ts +1 -0
- package/static/codemirror.bundle/editor.bundle.js +399 -184
- package/static/datafolderui/QyStyledElement.js +2 -2
- package/static/datafolderui/QyUIFolderViewer.js +97 -77
- package/static/datafolderui/QyUIUtils.js +4 -4
- package/static/datafolderui/code-mirror.js +7 -7
- package/static/datafolderui/display-tree.js +13 -10
- package/static/datafolderui/hscrpt.js +26 -7
- package/static/datafolderui/json-view.js +27 -0
- package/static/datafolderui/main-page.js +65 -37
- package/static/datafolderui/query-editor.js +8 -8
- package/static/datafolderui/rpc-editor.js +31 -0
- package/static/datafolderui/trigger-editor.js +9 -6
- package/static/datafolderui/QyUIFolderTree.js +0 -188
|
@@ -1406,11 +1406,11 @@
|
|
|
1406
1406
|
/**
|
|
1407
1407
|
Extend this range to cover at least `from` to `to`.
|
|
1408
1408
|
*/
|
|
1409
|
-
extend(from, to = from) {
|
|
1409
|
+
extend(from, to = from, assoc = 0) {
|
|
1410
1410
|
if (from <= this.anchor && to >= this.anchor)
|
|
1411
|
-
return EditorSelection.range(from, to);
|
|
1411
|
+
return EditorSelection.range(from, to, undefined, undefined, assoc);
|
|
1412
1412
|
let head = Math.abs(from - this.anchor) > Math.abs(to - this.anchor) ? from : to;
|
|
1413
|
-
return EditorSelection.range(this.anchor, head);
|
|
1413
|
+
return EditorSelection.range(this.anchor, head, undefined, undefined, assoc);
|
|
1414
1414
|
}
|
|
1415
1415
|
/**
|
|
1416
1416
|
Compare this range to another range.
|
|
@@ -1557,11 +1557,13 @@
|
|
|
1557
1557
|
/**
|
|
1558
1558
|
Create a selection range.
|
|
1559
1559
|
*/
|
|
1560
|
-
static range(anchor, head, goalColumn, bidiLevel) {
|
|
1560
|
+
static range(anchor, head, goalColumn, bidiLevel, assoc) {
|
|
1561
1561
|
let flags = ((goalColumn !== null && goalColumn !== void 0 ? goalColumn : 16777215 /* RangeFlag.NoGoalColumn */) << 6 /* RangeFlag.GoalColumnOffset */) |
|
|
1562
1562
|
(bidiLevel == null ? 7 : Math.min(6, bidiLevel));
|
|
1563
|
+
if (!assoc && anchor != head)
|
|
1564
|
+
assoc = head < anchor ? 1 : -1;
|
|
1563
1565
|
return head < anchor ? SelectionRange.create(head, anchor, 32 /* RangeFlag.Inverted */ | 16 /* RangeFlag.AssocAfter */ | flags)
|
|
1564
|
-
: SelectionRange.create(anchor, head, (
|
|
1566
|
+
: SelectionRange.create(anchor, head, (!assoc ? 0 : assoc < 0 ? 8 /* RangeFlag.AssocBefore */ : 16 /* RangeFlag.AssocAfter */) | flags);
|
|
1565
1567
|
}
|
|
1566
1568
|
/**
|
|
1567
1569
|
@internal
|
|
@@ -4418,7 +4420,7 @@
|
|
|
4418
4420
|
couldn't (in which case the widget will be redrawn). The default
|
|
4419
4421
|
implementation just returns false.
|
|
4420
4422
|
*/
|
|
4421
|
-
updateDOM(dom, view) { return false; }
|
|
4423
|
+
updateDOM(dom, view, from) { return false; }
|
|
4422
4424
|
/**
|
|
4423
4425
|
@internal
|
|
4424
4426
|
*/
|
|
@@ -4907,16 +4909,16 @@
|
|
|
4907
4909
|
}
|
|
4908
4910
|
}
|
|
4909
4911
|
}
|
|
4910
|
-
function scrollableParents(dom) {
|
|
4911
|
-
let doc = dom.ownerDocument, x, y;
|
|
4912
|
+
function scrollableParents(dom, getX = true) {
|
|
4913
|
+
let doc = dom.ownerDocument, x = null, y = null;
|
|
4912
4914
|
for (let cur = dom.parentNode; cur;) {
|
|
4913
|
-
if (cur == doc.body || (x && y)) {
|
|
4915
|
+
if (cur == doc.body || ((!getX || x) && y)) {
|
|
4914
4916
|
break;
|
|
4915
4917
|
}
|
|
4916
4918
|
else if (cur.nodeType == 1) {
|
|
4917
4919
|
if (!y && cur.scrollHeight > cur.clientHeight)
|
|
4918
4920
|
y = cur;
|
|
4919
|
-
if (!x && cur.scrollWidth > cur.clientWidth)
|
|
4921
|
+
if (getX && !x && cur.scrollWidth > cur.clientWidth)
|
|
4920
4922
|
x = cur;
|
|
4921
4923
|
cur = cur.assignedSlot || cur.parentNode;
|
|
4922
4924
|
}
|
|
@@ -5041,6 +5043,8 @@
|
|
|
5041
5043
|
}
|
|
5042
5044
|
}
|
|
5043
5045
|
function isScrolledToBottom(elt) {
|
|
5046
|
+
if (elt instanceof Window)
|
|
5047
|
+
return elt.pageYOffset > Math.max(0, elt.document.documentElement.scrollHeight - elt.innerHeight - 4);
|
|
5044
5048
|
return elt.scrollTop > Math.max(1, elt.scrollHeight - elt.clientHeight - 4);
|
|
5045
5049
|
}
|
|
5046
5050
|
function textNodeBefore(startNode, startOffset) {
|
|
@@ -6819,7 +6823,7 @@
|
|
|
6819
6823
|
let tile = widgets[i];
|
|
6820
6824
|
if (!this.reused.has(tile) &&
|
|
6821
6825
|
(pass == 0 ? tile.widget.compare(widget)
|
|
6822
|
-
: tile.widget.constructor == widget.constructor && widget.updateDOM(tile.dom, this.view))) {
|
|
6826
|
+
: tile.widget.constructor == widget.constructor && widget.updateDOM(tile.dom, this.view, tile.widget))) {
|
|
6823
6827
|
widgets.splice(i, 1);
|
|
6824
6828
|
if (i < this.index[0])
|
|
6825
6829
|
this.index[0]--;
|
|
@@ -6938,7 +6942,7 @@
|
|
|
6938
6942
|
}
|
|
6939
6943
|
else if (tile.isText()) {
|
|
6940
6944
|
this.builder.ensureLine(null);
|
|
6941
|
-
if (!from && to == tile.length) {
|
|
6945
|
+
if (!from && to == tile.length && !this.cache.reused.has(tile)) {
|
|
6942
6946
|
this.builder.addText(tile.text, activeMarks, openMarks, this.cache.reuse(tile));
|
|
6943
6947
|
}
|
|
6944
6948
|
else {
|
|
@@ -7073,9 +7077,10 @@
|
|
|
7073
7077
|
marks.push(tile);
|
|
7074
7078
|
else if (tile === null || tile === void 0 ? void 0 : tile.isLine())
|
|
7075
7079
|
line = tile;
|
|
7080
|
+
else if (tile instanceof BlockWrapperTile) ; // Ignore
|
|
7076
7081
|
else if (parent.nodeName == "DIV" && !line && parent != this.view.contentDOM)
|
|
7077
7082
|
line = new LineTile(parent, lineBaseAttrs);
|
|
7078
|
-
else
|
|
7083
|
+
else if (!line)
|
|
7079
7084
|
marks.push(MarkTile.of(new MarkDecoration({ tagName: parent.nodeName.toLowerCase(), attributes: getAttrs(parent) }), parent));
|
|
7080
7085
|
}
|
|
7081
7086
|
return { line: line, marks };
|
|
@@ -7241,6 +7246,8 @@
|
|
|
7241
7246
|
if (composition || changes.length) {
|
|
7242
7247
|
let oldTile = this.tile;
|
|
7243
7248
|
let builder = new TileUpdate(this.view, oldTile, this.blockWrappers, this.decorations, this.dynamicDecorationMap);
|
|
7249
|
+
if (composition && Tile.get(composition.text))
|
|
7250
|
+
builder.cache.reused.set(Tile.get(composition.text), 2 /* Reused.DOM */);
|
|
7244
7251
|
this.tile = builder.run(changes, composition);
|
|
7245
7252
|
destroyDropped(oldTile, builder.cache.reused);
|
|
7246
7253
|
}
|
|
@@ -7672,6 +7679,7 @@
|
|
|
7672
7679
|
this.blockWrappers = this.view.state.facet(blockWrappers).map(v => typeof v == "function" ? v(this.view) : v);
|
|
7673
7680
|
}
|
|
7674
7681
|
scrollIntoView(target) {
|
|
7682
|
+
var _a;
|
|
7675
7683
|
if (target.isSnapshot) {
|
|
7676
7684
|
let ref = this.view.viewState.lineBlockAt(target.range.head);
|
|
7677
7685
|
this.view.scrollDOM.scrollTop = ref.top - target.yMargin;
|
|
@@ -7688,7 +7696,7 @@
|
|
|
7688
7696
|
}
|
|
7689
7697
|
}
|
|
7690
7698
|
let { range } = target;
|
|
7691
|
-
let rect = this.coordsAt(range.head, range.
|
|
7699
|
+
let rect = this.coordsAt(range.head, (_a = range.assoc) !== null && _a !== void 0 ? _a : (range.empty ? 0 : range.head > range.anchor ? -1 : 1)), other;
|
|
7692
7700
|
if (!rect)
|
|
7693
7701
|
return;
|
|
7694
7702
|
if (!range.empty && (other = this.coordsAt(range.anchor, range.anchor > range.head ? -1 : 1)))
|
|
@@ -7701,6 +7709,19 @@
|
|
|
7701
7709
|
};
|
|
7702
7710
|
let { offsetWidth, offsetHeight } = this.view.scrollDOM;
|
|
7703
7711
|
scrollRectIntoView(this.view.scrollDOM, targetRect, range.head < range.anchor ? -1 : 1, target.x, target.y, Math.max(Math.min(target.xMargin, offsetWidth), -offsetWidth), Math.max(Math.min(target.yMargin, offsetHeight), -offsetHeight), this.view.textDirection == Direction.LTR);
|
|
7712
|
+
// On mobile browsers, the visual viewport may be smaller than the
|
|
7713
|
+
// actual reported viewport, causing scrollRectIntoView to fail to
|
|
7714
|
+
// scroll properly. Unfortunately, this visual viewport cannot be
|
|
7715
|
+
// updated directly, and scrollIntoView is the only way a script
|
|
7716
|
+
// can affect it. So this tries to kludge around the problem by
|
|
7717
|
+
// calling scrollIntoView on the scroll target's line.
|
|
7718
|
+
if (window.visualViewport && window.innerHeight - window.visualViewport.height > 1 &&
|
|
7719
|
+
(rect.top > window.pageYOffset + window.visualViewport.offsetTop + window.visualViewport.height ||
|
|
7720
|
+
rect.bottom < window.pageYOffset + window.visualViewport.offsetTop)) {
|
|
7721
|
+
let line = this.view.docView.lineAt(range.head, 1);
|
|
7722
|
+
if (line)
|
|
7723
|
+
line.dom.scrollIntoView({ block: "nearest" });
|
|
7724
|
+
}
|
|
7704
7725
|
}
|
|
7705
7726
|
lineHasWidget(pos) {
|
|
7706
7727
|
let scan = (child) => child.isWidget() || child.children.some(scan);
|
|
@@ -7942,7 +7963,8 @@
|
|
|
7942
7963
|
return EditorSelection.cursor(startPos, start.assoc);
|
|
7943
7964
|
let goal = start.goalColumn, startY;
|
|
7944
7965
|
let rect = view.contentDOM.getBoundingClientRect();
|
|
7945
|
-
let startCoords = view.coordsAtPos(startPos, (start.empty ? start.
|
|
7966
|
+
let startCoords = view.coordsAtPos(startPos, start.assoc || ((start.empty ? forward : start.head == start.from) ? 1 : -1));
|
|
7967
|
+
let docTop = view.documentTop;
|
|
7946
7968
|
if (startCoords) {
|
|
7947
7969
|
if (goal == null)
|
|
7948
7970
|
goal = startCoords.left - rect.left;
|
|
@@ -7955,9 +7977,16 @@
|
|
|
7955
7977
|
startY = (dir < 0 ? line.top : line.bottom) + docTop;
|
|
7956
7978
|
}
|
|
7957
7979
|
let resolvedGoal = rect.left + goal;
|
|
7958
|
-
let dist = distance !== null && distance !== void 0 ? distance :
|
|
7959
|
-
let
|
|
7960
|
-
|
|
7980
|
+
let halfText = view.viewState.heightOracle.textHeight >> 1, dist = distance !== null && distance !== void 0 ? distance : halfText;
|
|
7981
|
+
for (let scan = 0;; scan += halfText) {
|
|
7982
|
+
let y = startY + (dist + scan) * dir;
|
|
7983
|
+
let pos = posAtCoords(view, { x: resolvedGoal, y }, false, dir);
|
|
7984
|
+
if (forward ? y > rect.bottom : y < rect.top)
|
|
7985
|
+
return EditorSelection.cursor(pos.pos, pos.assoc);
|
|
7986
|
+
let posCoords = view.coordsAtPos(pos.pos, pos.assoc), mid = posCoords ? (posCoords.top + posCoords.bottom) / 2 : 0;
|
|
7987
|
+
if (!posCoords || (forward ? mid > startY : mid < startY))
|
|
7988
|
+
return EditorSelection.cursor(pos.pos, pos.assoc, undefined, goal);
|
|
7989
|
+
}
|
|
7961
7990
|
}
|
|
7962
7991
|
function skipAtomicRanges(atoms, pos, bias) {
|
|
7963
7992
|
for (;;) {
|
|
@@ -8049,86 +8078,167 @@
|
|
|
8049
8078
|
let line = view.docView.lineAt(block.from, 2);
|
|
8050
8079
|
if (!line || line.length != block.length)
|
|
8051
8080
|
line = view.docView.lineAt(block.from, -2);
|
|
8052
|
-
return
|
|
8081
|
+
return new InlineCoordsScan(view, x, y, view.textDirectionAt(block.from)).scanTile(line, block.from);
|
|
8053
8082
|
}
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
|
|
8057
|
-
|
|
8058
|
-
|
|
8059
|
-
|
|
8060
|
-
|
|
8061
|
-
|
|
8062
|
-
|
|
8063
|
-
|
|
8064
|
-
|
|
8065
|
-
|
|
8066
|
-
|
|
8067
|
-
|
|
8068
|
-
|
|
8069
|
-
|
|
8070
|
-
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
|
|
8078
|
-
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
8087
|
-
|
|
8088
|
-
|
|
8089
|
-
|
|
8090
|
-
|
|
8091
|
-
|
|
8092
|
-
|
|
8093
|
-
|
|
8083
|
+
class InlineCoordsScan {
|
|
8084
|
+
constructor(view, x, y, baseDir) {
|
|
8085
|
+
this.view = view;
|
|
8086
|
+
this.x = x;
|
|
8087
|
+
this.y = y;
|
|
8088
|
+
this.baseDir = baseDir;
|
|
8089
|
+
// Cached bidi info
|
|
8090
|
+
this.line = null;
|
|
8091
|
+
this.spans = null;
|
|
8092
|
+
}
|
|
8093
|
+
bidiSpansAt(pos) {
|
|
8094
|
+
if (!this.line || this.line.from > pos || this.line.to < pos) {
|
|
8095
|
+
this.line = this.view.state.doc.lineAt(pos);
|
|
8096
|
+
this.spans = this.view.bidiSpans(this.line);
|
|
8097
|
+
}
|
|
8098
|
+
return this;
|
|
8099
|
+
}
|
|
8100
|
+
baseDirAt(pos, side) {
|
|
8101
|
+
let { line, spans } = this.bidiSpansAt(pos);
|
|
8102
|
+
let level = spans[BidiSpan.find(spans, pos - line.from, -1, side)].level;
|
|
8103
|
+
return level == this.baseDir;
|
|
8104
|
+
}
|
|
8105
|
+
dirAt(pos, side) {
|
|
8106
|
+
let { line, spans } = this.bidiSpansAt(pos);
|
|
8107
|
+
return spans[BidiSpan.find(spans, pos - line.from, -1, side)].dir;
|
|
8108
|
+
}
|
|
8109
|
+
// Used to short-circuit bidi tests for content with a uniform direction
|
|
8110
|
+
bidiIn(from, to) {
|
|
8111
|
+
let { spans, line } = this.bidiSpansAt(from);
|
|
8112
|
+
return spans.length > 1 || spans.length && (spans[0].level != this.baseDir || spans[0].to + line.from < to);
|
|
8113
|
+
}
|
|
8114
|
+
// Scan through the rectangles for the content of a tile with inline
|
|
8115
|
+
// content, looking for one that overlaps the queried position
|
|
8116
|
+
// vertically andis
|
|
8117
|
+
// closest horizontally. The caller is responsible for dividing its
|
|
8118
|
+
// content into N pieces, and pass an array with N+1 positions
|
|
8119
|
+
// (including the position after the last piece). For a text tile,
|
|
8120
|
+
// these will be character clusters, for a composite tile, these
|
|
8121
|
+
// will be child tiles.
|
|
8122
|
+
scan(positions, getRects) {
|
|
8123
|
+
let lo = 0, hi = positions.length - 1, seen = new Set();
|
|
8124
|
+
let bidi = this.bidiIn(positions[0], positions[hi]);
|
|
8125
|
+
let above, below;
|
|
8126
|
+
let closestI = -1, closestDx = 1e9, closestRect;
|
|
8127
|
+
// Because, when the content is bidirectional, a regular binary
|
|
8128
|
+
// search is hard to perform (the content order does not
|
|
8129
|
+
// correspond to visual order), this loop does something between a
|
|
8130
|
+
// regular binary search and a full scan, depending on what it can
|
|
8131
|
+
// get away with. The outer hi/lo bounds are only adjusted for
|
|
8132
|
+
// elements that are part of the base order.
|
|
8133
|
+
//
|
|
8134
|
+
// To make sure all elements inside those bounds are visited,
|
|
8135
|
+
// eventually, we keep a set of seen indices, and if the midpoint
|
|
8136
|
+
// has already been handled, we start in a random index within the
|
|
8137
|
+
// current bounds and scan forward until we find an index that
|
|
8138
|
+
// hasn't been seen yet.
|
|
8139
|
+
search: while (lo < hi) {
|
|
8140
|
+
let dist = hi - lo, mid = (lo + hi) >> 1;
|
|
8141
|
+
adjust: if (seen.has(mid)) {
|
|
8142
|
+
let scan = lo + Math.floor(Math.random() * dist);
|
|
8143
|
+
for (let i = 0; i < dist; i++) {
|
|
8144
|
+
if (!seen.has(scan)) {
|
|
8145
|
+
mid = scan;
|
|
8146
|
+
break adjust;
|
|
8147
|
+
}
|
|
8148
|
+
scan++;
|
|
8149
|
+
if (scan == hi)
|
|
8150
|
+
scan = lo; // Wrap around
|
|
8094
8151
|
}
|
|
8152
|
+
break search; // No index found, we're done
|
|
8095
8153
|
}
|
|
8154
|
+
seen.add(mid);
|
|
8155
|
+
let rects = getRects(mid);
|
|
8156
|
+
if (rects)
|
|
8157
|
+
for (let i = 0; i < rects.length; i++) {
|
|
8158
|
+
let rect = rects[i], side = 0;
|
|
8159
|
+
// Ignore empty rectangles when there are other rectangles
|
|
8160
|
+
if (rect.width == 0 && rects.length > 1)
|
|
8161
|
+
continue;
|
|
8162
|
+
if (rect.bottom < this.y) {
|
|
8163
|
+
if (!above || above.bottom < rect.bottom)
|
|
8164
|
+
above = rect;
|
|
8165
|
+
side = 1;
|
|
8166
|
+
}
|
|
8167
|
+
else if (rect.top > this.y) {
|
|
8168
|
+
if (!below || below.top > rect.top)
|
|
8169
|
+
below = rect;
|
|
8170
|
+
side = -1;
|
|
8171
|
+
}
|
|
8172
|
+
else {
|
|
8173
|
+
let off = rect.left > this.x ? this.x - rect.left : rect.right < this.x ? this.x - rect.right : 0;
|
|
8174
|
+
let dx = Math.abs(off);
|
|
8175
|
+
if (dx < closestDx) {
|
|
8176
|
+
closestI = mid;
|
|
8177
|
+
closestDx = dx;
|
|
8178
|
+
closestRect = rect;
|
|
8179
|
+
}
|
|
8180
|
+
if (off)
|
|
8181
|
+
side = (off < 0) == (this.baseDir == Direction.LTR) ? -1 : 1;
|
|
8182
|
+
}
|
|
8183
|
+
// Narrow binary search when it is safe to do so
|
|
8184
|
+
if (side == -1 && (!bidi || this.baseDirAt(positions[mid], 1)))
|
|
8185
|
+
hi = mid;
|
|
8186
|
+
else if (side == 1 && (!bidi || this.baseDirAt(positions[mid + 1], -1)))
|
|
8187
|
+
lo = mid + 1;
|
|
8188
|
+
}
|
|
8096
8189
|
}
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
|
|
8100
|
-
let
|
|
8101
|
-
|
|
8102
|
-
|
|
8103
|
-
break;
|
|
8104
|
-
i = next;
|
|
8190
|
+
// If no element with y overlap is found, find the nearest element
|
|
8191
|
+
// on the y axis, move this.y into it, and retry the scan.
|
|
8192
|
+
if (!closestRect) {
|
|
8193
|
+
let side = above && (!below || (this.y - above.bottom < below.top - this.y)) ? above : below;
|
|
8194
|
+
this.y = (side.top + side.bottom) / 2;
|
|
8195
|
+
return this.scan(positions, getRects);
|
|
8105
8196
|
}
|
|
8106
|
-
let
|
|
8107
|
-
return
|
|
8197
|
+
let ltr = (bidi ? this.dirAt(positions[closestI], 1) : this.baseDir) == Direction.LTR;
|
|
8198
|
+
return {
|
|
8199
|
+
i: closestI,
|
|
8200
|
+
// Test whether x is closes to the start or end of this element
|
|
8201
|
+
after: (this.x > (closestRect.left + closestRect.right) / 2) == ltr
|
|
8202
|
+
};
|
|
8108
8203
|
}
|
|
8109
|
-
|
|
8204
|
+
scanText(tile, offset) {
|
|
8205
|
+
let positions = [];
|
|
8206
|
+
for (let i = 0; i < tile.length; i = findClusterBreak(tile.text, i))
|
|
8207
|
+
positions.push(offset + i);
|
|
8208
|
+
positions.push(offset + tile.length);
|
|
8209
|
+
let scan = this.scan(positions, i => {
|
|
8210
|
+
let off = positions[i] - offset, end = positions[i + 1] - offset;
|
|
8211
|
+
return textRange(tile.dom, off, end).getClientRects();
|
|
8212
|
+
});
|
|
8213
|
+
return scan.after ? new PosAssoc(positions[scan.i + 1], -1) : new PosAssoc(positions[scan.i], 1);
|
|
8214
|
+
}
|
|
8215
|
+
scanTile(tile, offset) {
|
|
8110
8216
|
if (!tile.length)
|
|
8111
8217
|
return new PosAssoc(offset, 1);
|
|
8112
|
-
|
|
8218
|
+
if (tile.children.length == 1) { // Short-circuit single-child tiles
|
|
8219
|
+
let child = tile.children[0];
|
|
8220
|
+
if (child.isText())
|
|
8221
|
+
return this.scanText(child, offset);
|
|
8222
|
+
else if (child.isComposite())
|
|
8223
|
+
return this.scanTile(child, offset);
|
|
8224
|
+
}
|
|
8225
|
+
let positions = [offset];
|
|
8226
|
+
for (let i = 0, pos = offset; i < tile.children.length; i++)
|
|
8227
|
+
positions.push(pos += tile.children[i].length);
|
|
8228
|
+
let scan = this.scan(positions, i => {
|
|
8113
8229
|
let child = tile.children[i];
|
|
8114
8230
|
if (child.flags & 48 /* TileFlag.PointWidget */)
|
|
8115
|
-
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
|
|
8121
|
-
|
|
8122
|
-
|
|
8123
|
-
|
|
8124
|
-
let after = (x > (closestRect.left + closestRect.right) / 2) == (dirAt(view, closest + offset) == Direction.LTR);
|
|
8125
|
-
return after ? new PosAssoc(innerOff + inner.length, -1) : new PosAssoc(innerOff, 1);
|
|
8231
|
+
return null;
|
|
8232
|
+
return (child.dom.nodeType == 1 ? child.dom : textRange(child.dom, 0, child.length)).getClientRects();
|
|
8233
|
+
});
|
|
8234
|
+
let child = tile.children[scan.i], pos = positions[scan.i];
|
|
8235
|
+
if (child.isText())
|
|
8236
|
+
return this.scanText(child, pos);
|
|
8237
|
+
if (child.isComposite())
|
|
8238
|
+
return this.scanTile(child, pos);
|
|
8239
|
+
return scan.after ? new PosAssoc(positions[scan.i + 1], -1) : new PosAssoc(pos, 1);
|
|
8126
8240
|
}
|
|
8127
8241
|
}
|
|
8128
|
-
function dirAt(view, pos) {
|
|
8129
|
-
let line = view.state.doc.lineAt(pos), spans = view.bidiSpans(line);
|
|
8130
|
-
return spans[BidiSpan.find(view.bidiSpans(line), pos - line.from, -1, 1)].dir;
|
|
8131
|
-
}
|
|
8132
8242
|
|
|
8133
8243
|
const LineBreakPlaceholder = "\uffff";
|
|
8134
8244
|
class DOMReader {
|
|
@@ -8272,7 +8382,7 @@
|
|
|
8272
8382
|
this.bounds = null;
|
|
8273
8383
|
this.text = "";
|
|
8274
8384
|
this.domChanged = start > -1;
|
|
8275
|
-
let { impreciseHead: iHead, impreciseAnchor: iAnchor } = view.docView;
|
|
8385
|
+
let { impreciseHead: iHead, impreciseAnchor: iAnchor } = view.docView, curSel = view.state.selection;
|
|
8276
8386
|
if (view.state.readOnly && start > -1) {
|
|
8277
8387
|
// Ignore changes when the editor is read-only
|
|
8278
8388
|
this.newSel = null;
|
|
@@ -8288,18 +8398,18 @@
|
|
|
8288
8398
|
let domSel = view.observer.selectionRange;
|
|
8289
8399
|
let head = iHead && iHead.node == domSel.focusNode && iHead.offset == domSel.focusOffset ||
|
|
8290
8400
|
!contains(view.contentDOM, domSel.focusNode)
|
|
8291
|
-
?
|
|
8401
|
+
? curSel.main.head
|
|
8292
8402
|
: view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset);
|
|
8293
8403
|
let anchor = iAnchor && iAnchor.node == domSel.anchorNode && iAnchor.offset == domSel.anchorOffset ||
|
|
8294
8404
|
!contains(view.contentDOM, domSel.anchorNode)
|
|
8295
|
-
?
|
|
8405
|
+
? curSel.main.anchor
|
|
8296
8406
|
: view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset);
|
|
8297
8407
|
// iOS will refuse to select the block gaps when doing
|
|
8298
8408
|
// select-all.
|
|
8299
8409
|
// Chrome will put the selection *inside* them, confusing
|
|
8300
8410
|
// posFromDOM
|
|
8301
8411
|
let vp = view.viewport;
|
|
8302
|
-
if ((browser.ios || browser.chrome) &&
|
|
8412
|
+
if ((browser.ios || browser.chrome) && curSel.main.empty && head != anchor &&
|
|
8303
8413
|
(vp.from > 0 || vp.to < view.state.doc.length)) {
|
|
8304
8414
|
let from = Math.min(head, anchor), to = Math.max(head, anchor);
|
|
8305
8415
|
let offFrom = vp.from - from, offTo = vp.to - to;
|
|
@@ -8308,10 +8418,22 @@
|
|
|
8308
8418
|
anchor = view.state.doc.length;
|
|
8309
8419
|
}
|
|
8310
8420
|
}
|
|
8311
|
-
if (view.inputState.composing > -1 &&
|
|
8312
|
-
this.newSel =
|
|
8313
|
-
|
|
8421
|
+
if (view.inputState.composing > -1 && curSel.ranges.length > 1) {
|
|
8422
|
+
this.newSel = curSel.replaceRange(EditorSelection.range(anchor, head));
|
|
8423
|
+
}
|
|
8424
|
+
else if (view.lineWrapping && anchor == head && !(curSel.main.empty && curSel.main.head == head) &&
|
|
8425
|
+
view.inputState.lastTouchTime > Date.now() - 100) {
|
|
8426
|
+
// If this is a cursor selection change in a line-wrapping
|
|
8427
|
+
// editor that may have been a touch, use the last touch
|
|
8428
|
+
// position to assign a side to the cursor.
|
|
8429
|
+
let before = view.coordsAtPos(head, -1), assoc = 0;
|
|
8430
|
+
if (before)
|
|
8431
|
+
assoc = view.inputState.lastTouchY <= before.bottom ? -1 : 1;
|
|
8432
|
+
this.newSel = EditorSelection.create([EditorSelection.cursor(head, assoc)]);
|
|
8433
|
+
}
|
|
8434
|
+
else {
|
|
8314
8435
|
this.newSel = EditorSelection.single(anchor, head);
|
|
8436
|
+
}
|
|
8315
8437
|
}
|
|
8316
8438
|
}
|
|
8317
8439
|
}
|
|
@@ -8347,7 +8469,7 @@
|
|
|
8347
8469
|
}
|
|
8348
8470
|
function applyDOMChange(view, domChange) {
|
|
8349
8471
|
let change;
|
|
8350
|
-
let { newSel } = domChange, sel =
|
|
8472
|
+
let { newSel } = domChange, { state } = view, sel = state.selection.main;
|
|
8351
8473
|
let lastKey = view.inputState.lastKeyTime > Date.now() - 100 ? view.inputState.lastKeyCode : -1;
|
|
8352
8474
|
if (domChange.bounds) {
|
|
8353
8475
|
let { from, to } = domChange.bounds;
|
|
@@ -8358,8 +8480,15 @@
|
|
|
8358
8480
|
preferredPos = sel.to;
|
|
8359
8481
|
preferredSide = "end";
|
|
8360
8482
|
}
|
|
8361
|
-
let
|
|
8362
|
-
if (
|
|
8483
|
+
let cmp = state.doc.sliceString(from, to, LineBreakPlaceholder), selEnd, diff;
|
|
8484
|
+
if (!sel.empty && sel.from >= from && sel.to <= to && (domChange.typeOver || cmp != domChange.text) &&
|
|
8485
|
+
cmp.slice(0, sel.from - from) == domChange.text.slice(0, sel.from - from) &&
|
|
8486
|
+
cmp.slice(sel.to - from) == domChange.text.slice(selEnd = domChange.text.length - (cmp.length - (sel.to - from)))) {
|
|
8487
|
+
// This looks like a selection replacement
|
|
8488
|
+
change = { from: sel.from, to: sel.to,
|
|
8489
|
+
insert: Text.of(domChange.text.slice(sel.from - from, selEnd).split(LineBreakPlaceholder)) };
|
|
8490
|
+
}
|
|
8491
|
+
else if (diff = findDiff(cmp, domChange.text, preferredPos - from, preferredSide)) {
|
|
8363
8492
|
// Chrome inserts two newlines when pressing shift-enter at the
|
|
8364
8493
|
// end of a line. DomChange drops one of those.
|
|
8365
8494
|
if (browser.chrome && lastKey == 13 &&
|
|
@@ -8369,16 +8498,12 @@
|
|
|
8369
8498
|
insert: Text.of(domChange.text.slice(diff.from, diff.toB).split(LineBreakPlaceholder)) };
|
|
8370
8499
|
}
|
|
8371
8500
|
}
|
|
8372
|
-
else if (newSel && (!view.hasFocus &&
|
|
8501
|
+
else if (newSel && (!view.hasFocus && state.facet(editable) || sameSelPos(newSel, sel))) {
|
|
8373
8502
|
newSel = null;
|
|
8374
8503
|
}
|
|
8375
8504
|
if (!change && !newSel)
|
|
8376
8505
|
return false;
|
|
8377
|
-
if (
|
|
8378
|
-
// Heuristic to notice typing over a selected character
|
|
8379
|
-
change = { from: sel.from, to: sel.to, insert: view.state.doc.slice(sel.from, sel.to) };
|
|
8380
|
-
}
|
|
8381
|
-
else if ((browser.mac || browser.android) && change && change.from == change.to && change.from == sel.head - 1 &&
|
|
8506
|
+
if ((browser.mac || browser.android) && change && change.from == change.to && change.from == sel.head - 1 &&
|
|
8382
8507
|
/^\. ?$/.test(change.insert.toString()) && view.contentDOM.getAttribute("autocorrect") == "off") {
|
|
8383
8508
|
// Detect insert-period-on-double-space Mac and Android behavior,
|
|
8384
8509
|
// and transform it into a regular space insert.
|
|
@@ -8386,18 +8511,7 @@
|
|
|
8386
8511
|
newSel = EditorSelection.single(newSel.main.anchor - 1, newSel.main.head - 1);
|
|
8387
8512
|
change = { from: change.from, to: change.to, insert: Text.of([change.insert.toString().replace(".", " ")]) };
|
|
8388
8513
|
}
|
|
8389
|
-
else if (
|
|
8390
|
-
(change.from != sel.from || change.to != sel.to) &&
|
|
8391
|
-
(sel.to - sel.from) - (change.to - change.from) <= 4) {
|
|
8392
|
-
// If the change is inside the selection and covers most of it,
|
|
8393
|
-
// assume it is a selection replace (with identical characters at
|
|
8394
|
-
// the start/end not included in the diff)
|
|
8395
|
-
change = {
|
|
8396
|
-
from: sel.from, to: sel.to,
|
|
8397
|
-
insert: view.state.doc.slice(sel.from, change.from).append(change.insert).append(view.state.doc.slice(change.to, sel.to))
|
|
8398
|
-
};
|
|
8399
|
-
}
|
|
8400
|
-
else if (view.state.doc.lineAt(sel.from).to < sel.to && view.docView.lineHasWidget(sel.to) &&
|
|
8514
|
+
else if (state.doc.lineAt(sel.from).to < sel.to && view.docView.lineHasWidget(sel.to) &&
|
|
8401
8515
|
view.inputState.insertingTextAt > Date.now() - 50) {
|
|
8402
8516
|
// For a cross-line insertion, Chrome and Safari will crudely take
|
|
8403
8517
|
// the text of the line after the selection, flattening any
|
|
@@ -8406,7 +8520,7 @@
|
|
|
8406
8520
|
// replace of the text provided by the beforeinput event.
|
|
8407
8521
|
change = {
|
|
8408
8522
|
from: sel.from, to: sel.to,
|
|
8409
|
-
insert:
|
|
8523
|
+
insert: state.toText(view.inputState.insertingText)
|
|
8410
8524
|
};
|
|
8411
8525
|
}
|
|
8412
8526
|
else if (browser.chrome && change && change.from == change.to && change.from == sel.head &&
|
|
@@ -8428,7 +8542,7 @@
|
|
|
8428
8542
|
scrollIntoView = true;
|
|
8429
8543
|
userEvent = view.inputState.lastSelectionOrigin;
|
|
8430
8544
|
if (userEvent == "select.pointer")
|
|
8431
|
-
newSel = skipAtomsForSelection(
|
|
8545
|
+
newSel = skipAtomsForSelection(state.facet(atomicRanges).map(f => f(view)), newSel);
|
|
8432
8546
|
}
|
|
8433
8547
|
view.dispatch({ selection: newSel, scrollIntoView, userEvent });
|
|
8434
8548
|
return true;
|
|
@@ -8606,9 +8720,12 @@
|
|
|
8606
8720
|
this.lastKeyCode = 0;
|
|
8607
8721
|
this.lastKeyTime = 0;
|
|
8608
8722
|
this.lastTouchTime = 0;
|
|
8723
|
+
this.lastTouchX = 0;
|
|
8724
|
+
this.lastTouchY = 0;
|
|
8609
8725
|
this.lastFocusTime = 0;
|
|
8610
8726
|
this.lastScrollTop = 0;
|
|
8611
8727
|
this.lastScrollLeft = 0;
|
|
8728
|
+
this.lastWheelEvent = 0;
|
|
8612
8729
|
// On iOS, some keys need to have their default behavior happen
|
|
8613
8730
|
// (after which we retroactively handle them and reset the DOM) to
|
|
8614
8731
|
// avoid messing up the virtual keyboard state.
|
|
@@ -8728,9 +8845,9 @@
|
|
|
8728
8845
|
// applyDOMChange, notify key handlers of it and reset to
|
|
8729
8846
|
// the state they produce.
|
|
8730
8847
|
let pending;
|
|
8731
|
-
if (browser.ios && !event.synthetic && !event.altKey && !event.metaKey &&
|
|
8848
|
+
if (browser.ios && !event.synthetic && !event.altKey && !event.metaKey && !event.shiftKey &&
|
|
8732
8849
|
((pending = PendingKeys.find(key => key.keyCode == event.keyCode)) && !event.ctrlKey ||
|
|
8733
|
-
EmacsyPendingKeys.indexOf(event.key) > -1 && event.ctrlKey
|
|
8850
|
+
EmacsyPendingKeys.indexOf(event.key) > -1 && event.ctrlKey)) {
|
|
8734
8851
|
this.pendingIOSKey = pending || event;
|
|
8735
8852
|
setTimeout(() => this.flushIOSKey(), 250);
|
|
8736
8853
|
return true;
|
|
@@ -9038,6 +9155,9 @@
|
|
|
9038
9155
|
view.inputState.lastScrollTop = view.scrollDOM.scrollTop;
|
|
9039
9156
|
view.inputState.lastScrollLeft = view.scrollDOM.scrollLeft;
|
|
9040
9157
|
};
|
|
9158
|
+
observers.wheel = observers.mousewheel = view => {
|
|
9159
|
+
view.inputState.lastWheelEvent = Date.now();
|
|
9160
|
+
};
|
|
9041
9161
|
handlers.keydown = (view, event) => {
|
|
9042
9162
|
view.inputState.setSelectionOrigin("select");
|
|
9043
9163
|
if (event.keyCode == 27 && view.inputState.tabFocusMode != 0)
|
|
@@ -9045,8 +9165,13 @@
|
|
|
9045
9165
|
return false;
|
|
9046
9166
|
};
|
|
9047
9167
|
observers.touchstart = (view, e) => {
|
|
9048
|
-
view.inputState
|
|
9049
|
-
|
|
9168
|
+
let iState = view.inputState, touch = e.targetTouches[0];
|
|
9169
|
+
iState.lastTouchTime = Date.now();
|
|
9170
|
+
if (touch) {
|
|
9171
|
+
iState.lastTouchX = touch.clientX;
|
|
9172
|
+
iState.lastTouchY = touch.clientY;
|
|
9173
|
+
}
|
|
9174
|
+
iState.setSelectionOrigin("select.pointer");
|
|
9050
9175
|
};
|
|
9051
9176
|
observers.touchmove = view => {
|
|
9052
9177
|
view.inputState.setSelectionOrigin("select.pointer");
|
|
@@ -9126,10 +9251,10 @@
|
|
|
9126
9251
|
if (start.pos != cur.pos && !extend) {
|
|
9127
9252
|
let startRange = rangeForClick(view, start.pos, start.assoc, type);
|
|
9128
9253
|
let from = Math.min(startRange.from, range.from), to = Math.max(startRange.to, range.to);
|
|
9129
|
-
range = from < range.from ? EditorSelection.range(from, to) : EditorSelection.range(to, from);
|
|
9254
|
+
range = from < range.from ? EditorSelection.range(from, to, range.assoc) : EditorSelection.range(to, from, range.assoc);
|
|
9130
9255
|
}
|
|
9131
9256
|
if (extend)
|
|
9132
|
-
return startSel.replaceRange(startSel.main.extend(range.from, range.to));
|
|
9257
|
+
return startSel.replaceRange(startSel.main.extend(range.from, range.to, range.assoc));
|
|
9133
9258
|
else if (multiple && type == 1 && startSel.ranges.length > 1 && (removed = removeRangeAround(startSel, cur.pos)))
|
|
9134
9259
|
return removed;
|
|
9135
9260
|
else if (multiple)
|
|
@@ -9282,8 +9407,7 @@
|
|
|
9282
9407
|
// spans multiple elements including this CodeMirror. The copy event may
|
|
9283
9408
|
// bubble through CodeMirror (e.g. when CodeMirror is the first or the last
|
|
9284
9409
|
// element in the selection), but we should let the parent handle it.
|
|
9285
|
-
|
|
9286
|
-
if (domSel && !hasSelection(view.contentDOM, domSel))
|
|
9410
|
+
if (!hasSelection(view.contentDOM, view.observer.selectionRange))
|
|
9287
9411
|
return false;
|
|
9288
9412
|
let { text, ranges, linewise } = copiedRange(view.state);
|
|
9289
9413
|
if (!text && !linewise)
|
|
@@ -10282,7 +10406,8 @@
|
|
|
10282
10406
|
get estimatedHeight() { return this.vertical ? this.size : -1; }
|
|
10283
10407
|
}
|
|
10284
10408
|
class ViewState {
|
|
10285
|
-
constructor(state) {
|
|
10409
|
+
constructor(view, state) {
|
|
10410
|
+
this.view = view;
|
|
10286
10411
|
this.state = state;
|
|
10287
10412
|
// These are contentDOM-local coordinates
|
|
10288
10413
|
this.pixelViewport = { left: 0, right: window.innerWidth, top: 0, bottom: 0 };
|
|
@@ -10293,12 +10418,14 @@
|
|
|
10293
10418
|
this.contentDOMHeight = 0; // contentDOM.getBoundingClientRect().height
|
|
10294
10419
|
this.editorHeight = 0; // scrollDOM.clientHeight, unscaled
|
|
10295
10420
|
this.editorWidth = 0; // scrollDOM.clientWidth, unscaled
|
|
10296
|
-
this.scrollTop = 0; // Last seen scrollDOM.scrollTop, scaled
|
|
10297
|
-
this.scrolledToBottom = false;
|
|
10298
10421
|
// The CSS-transformation scale of the editor (transformed size /
|
|
10299
10422
|
// concrete size)
|
|
10300
10423
|
this.scaleX = 1;
|
|
10301
10424
|
this.scaleY = 1;
|
|
10425
|
+
// Last seen vertical offset of the element at the top of the scroll
|
|
10426
|
+
// container, or top of the window if there's no wrapping scroller
|
|
10427
|
+
this.scrollOffset = 0;
|
|
10428
|
+
this.scrolledToBottom = false;
|
|
10302
10429
|
// The vertical position (document-relative) to which to anchor the
|
|
10303
10430
|
// scroll position. -1 means anchor to the end of the document.
|
|
10304
10431
|
this.scrollAnchorPos = 0;
|
|
@@ -10336,6 +10463,7 @@
|
|
|
10336
10463
|
this.updateViewportLines();
|
|
10337
10464
|
this.lineGaps = this.ensureLineGaps([]);
|
|
10338
10465
|
this.lineGapDeco = Decoration.set(this.lineGaps.map(gap => gap.draw(this, false)));
|
|
10466
|
+
this.scrollParent = view.scrollDOM;
|
|
10339
10467
|
this.computeVisibleRanges();
|
|
10340
10468
|
}
|
|
10341
10469
|
updateForViewport() {
|
|
@@ -10369,7 +10497,7 @@
|
|
|
10369
10497
|
let contentChanges = update.changedRanges;
|
|
10370
10498
|
let heightChanges = ChangedRange.extendWithRanges(contentChanges, heightRelevantDecoChanges(prevDeco, this.stateDeco, update ? update.changes : ChangeSet.empty(this.state.doc.length)));
|
|
10371
10499
|
let prevHeight = this.heightMap.height;
|
|
10372
|
-
let scrollAnchor = this.scrolledToBottom ? null : this.scrollAnchorAt(this.
|
|
10500
|
+
let scrollAnchor = this.scrolledToBottom ? null : this.scrollAnchorAt(this.scrollOffset);
|
|
10373
10501
|
clearHeightChangeFlag();
|
|
10374
10502
|
this.heightMap = this.heightMap.applyChanges(this.stateDeco, update.startState.doc, this.heightOracle.setDoc(this.state.doc), heightChanges);
|
|
10375
10503
|
if (this.heightMap.height != prevHeight || heightChangeFlag)
|
|
@@ -10401,12 +10529,12 @@
|
|
|
10401
10529
|
!update.state.facet(nativeSelectionHidden))
|
|
10402
10530
|
this.mustEnforceCursorAssoc = true;
|
|
10403
10531
|
}
|
|
10404
|
-
measure(
|
|
10405
|
-
let dom = view.contentDOM, style = window.getComputedStyle(dom);
|
|
10532
|
+
measure() {
|
|
10533
|
+
let { view } = this, dom = view.contentDOM, style = window.getComputedStyle(dom);
|
|
10406
10534
|
let oracle = this.heightOracle;
|
|
10407
10535
|
let whiteSpace = style.whiteSpace;
|
|
10408
10536
|
this.defaultTextDirection = style.direction == "rtl" ? Direction.RTL : Direction.LTR;
|
|
10409
|
-
let refresh = this.heightOracle.mustRefreshForWrapping(whiteSpace) || this.mustMeasureContent;
|
|
10537
|
+
let refresh = this.heightOracle.mustRefreshForWrapping(whiteSpace) || this.mustMeasureContent === "refresh";
|
|
10410
10538
|
let domRect = dom.getBoundingClientRect();
|
|
10411
10539
|
let measureContent = refresh || this.mustMeasureContent || this.contentDOMHeight != domRect.height;
|
|
10412
10540
|
this.contentDOMHeight = domRect.height;
|
|
@@ -10436,12 +10564,18 @@
|
|
|
10436
10564
|
this.editorWidth = view.scrollDOM.clientWidth;
|
|
10437
10565
|
result |= 16 /* UpdateFlag.Geometry */;
|
|
10438
10566
|
}
|
|
10439
|
-
let
|
|
10440
|
-
if (
|
|
10567
|
+
let scrollParent = scrollableParents(this.view.contentDOM, false).y;
|
|
10568
|
+
if (scrollParent != this.scrollParent) {
|
|
10569
|
+
this.scrollParent = scrollParent;
|
|
10570
|
+
this.scrollAnchorHeight = -1;
|
|
10571
|
+
this.scrollOffset = 0;
|
|
10572
|
+
}
|
|
10573
|
+
let scrollOffset = this.getScrollOffset();
|
|
10574
|
+
if (this.scrollOffset != scrollOffset) {
|
|
10441
10575
|
this.scrollAnchorHeight = -1;
|
|
10442
|
-
this.
|
|
10576
|
+
this.scrollOffset = scrollOffset;
|
|
10443
10577
|
}
|
|
10444
|
-
this.scrolledToBottom = isScrolledToBottom(view.
|
|
10578
|
+
this.scrolledToBottom = isScrolledToBottom(this.scrollParent || view.win);
|
|
10445
10579
|
// Pixel viewport
|
|
10446
10580
|
let pixelViewport = (this.printing ? fullPixelRange : visiblePixelRange)(dom, this.paddingTop);
|
|
10447
10581
|
let dTop = pixelViewport.top - this.pixelViewport.top, dBottom = pixelViewport.bottom - this.pixelViewport.bottom;
|
|
@@ -10718,9 +10852,14 @@
|
|
|
10718
10852
|
this.viewportLines.find(l => l.top <= height && l.bottom >= height)) ||
|
|
10719
10853
|
scaleBlock(this.heightMap.lineAt(this.scaler.fromDOM(height), QueryType$1.ByHeight, this.heightOracle, 0, 0), this.scaler);
|
|
10720
10854
|
}
|
|
10721
|
-
|
|
10722
|
-
let
|
|
10723
|
-
|
|
10855
|
+
getScrollOffset() {
|
|
10856
|
+
let base = this.scrollParent == this.view.scrollDOM ? this.scrollParent.scrollTop
|
|
10857
|
+
: (this.scrollParent ? this.scrollParent.getBoundingClientRect().top : 0) - this.view.contentDOM.getBoundingClientRect().top;
|
|
10858
|
+
return base * this.scaleY;
|
|
10859
|
+
}
|
|
10860
|
+
scrollAnchorAt(scrollOffset) {
|
|
10861
|
+
let block = this.lineBlockAtHeight(scrollOffset + 8);
|
|
10862
|
+
return block.from >= this.viewport.from || this.viewportLines[0].top - scrollOffset > 200 ? block : this.viewportLines[0];
|
|
10724
10863
|
}
|
|
10725
10864
|
elementAtHeight(height) {
|
|
10726
10865
|
return scaleBlock(this.heightMap.blockAt(this.scaler.fromDOM(height), this.heightOracle, 0, 0), this.scaler);
|
|
@@ -10973,6 +11112,21 @@
|
|
|
10973
11112
|
"&dark .cm-cursor": {
|
|
10974
11113
|
borderLeftColor: "#ddd"
|
|
10975
11114
|
},
|
|
11115
|
+
".cm-selectionHandle": {
|
|
11116
|
+
backgroundColor: "currentColor",
|
|
11117
|
+
width: "1.5px"
|
|
11118
|
+
},
|
|
11119
|
+
".cm-selectionHandle-start::before, .cm-selectionHandle-end::before": {
|
|
11120
|
+
content: '""',
|
|
11121
|
+
backgroundColor: "inherit",
|
|
11122
|
+
borderRadius: "50%",
|
|
11123
|
+
width: "8px",
|
|
11124
|
+
height: "8px",
|
|
11125
|
+
position: "absolute",
|
|
11126
|
+
left: "-3.25px"
|
|
11127
|
+
},
|
|
11128
|
+
".cm-selectionHandle-start::before": { top: "-8px" },
|
|
11129
|
+
".cm-selectionHandle-end::before": { bottom: "-8px" },
|
|
10976
11130
|
".cm-dropCursor": {
|
|
10977
11131
|
position: "absolute"
|
|
10978
11132
|
},
|
|
@@ -11967,7 +12121,7 @@
|
|
|
11967
12121
|
((trs) => this.update(trs));
|
|
11968
12122
|
this.dispatch = this.dispatch.bind(this);
|
|
11969
12123
|
this._root = (config.root || getRoot(config.parent) || document);
|
|
11970
|
-
this.viewState = new ViewState(config.state || EditorState.create(config));
|
|
12124
|
+
this.viewState = new ViewState(this, config.state || EditorState.create(config));
|
|
11971
12125
|
if (config.scrollTo && config.scrollTo.is(scrollIntoView$1))
|
|
11972
12126
|
this.viewState.scrollTarget = config.scrollTo.value.clip(this.viewState.state);
|
|
11973
12127
|
this.plugins = this.state.facet(viewPlugin).map(spec => new PluginInstance(spec));
|
|
@@ -11983,7 +12137,7 @@
|
|
|
11983
12137
|
this.requestMeasure();
|
|
11984
12138
|
if ((_a = document.fonts) === null || _a === void 0 ? void 0 : _a.ready)
|
|
11985
12139
|
document.fonts.ready.then(() => {
|
|
11986
|
-
this.viewState.mustMeasureContent =
|
|
12140
|
+
this.viewState.mustMeasureContent = "refresh";
|
|
11987
12141
|
this.requestMeasure();
|
|
11988
12142
|
});
|
|
11989
12143
|
}
|
|
@@ -12122,7 +12276,7 @@
|
|
|
12122
12276
|
try {
|
|
12123
12277
|
for (let plugin of this.plugins)
|
|
12124
12278
|
plugin.destroy(this);
|
|
12125
|
-
this.viewState = new ViewState(newState);
|
|
12279
|
+
this.viewState = new ViewState(this, newState);
|
|
12126
12280
|
this.plugins = newState.facet(viewPlugin).map(spec => new PluginInstance(spec));
|
|
12127
12281
|
this.pluginMap.clear();
|
|
12128
12282
|
for (let plugin of this.plugins)
|
|
@@ -12201,26 +12355,26 @@
|
|
|
12201
12355
|
if (flush)
|
|
12202
12356
|
this.observer.forceFlush();
|
|
12203
12357
|
let updated = null;
|
|
12204
|
-
let
|
|
12358
|
+
let scroll = this.viewState.scrollParent, scrollOffset = this.viewState.getScrollOffset();
|
|
12205
12359
|
let { scrollAnchorPos, scrollAnchorHeight } = this.viewState;
|
|
12206
|
-
if (Math.abs(
|
|
12360
|
+
if (Math.abs(scrollOffset - this.viewState.scrollOffset) > 1)
|
|
12207
12361
|
scrollAnchorHeight = -1;
|
|
12208
12362
|
this.viewState.scrollAnchorHeight = -1;
|
|
12209
12363
|
try {
|
|
12210
12364
|
for (let i = 0;; i++) {
|
|
12211
12365
|
if (scrollAnchorHeight < 0) {
|
|
12212
|
-
if (isScrolledToBottom(
|
|
12366
|
+
if (isScrolledToBottom(scroll || this.win)) {
|
|
12213
12367
|
scrollAnchorPos = -1;
|
|
12214
12368
|
scrollAnchorHeight = this.viewState.heightMap.height;
|
|
12215
12369
|
}
|
|
12216
12370
|
else {
|
|
12217
|
-
let block = this.viewState.scrollAnchorAt(
|
|
12371
|
+
let block = this.viewState.scrollAnchorAt(scrollOffset);
|
|
12218
12372
|
scrollAnchorPos = block.from;
|
|
12219
12373
|
scrollAnchorHeight = block.top;
|
|
12220
12374
|
}
|
|
12221
12375
|
}
|
|
12222
12376
|
this.updateState = 1 /* UpdateState.Measuring */;
|
|
12223
|
-
let changed = this.viewState.measure(
|
|
12377
|
+
let changed = this.viewState.measure();
|
|
12224
12378
|
if (!changed && !this.measureRequests.length && this.viewState.scrollTarget == null)
|
|
12225
12379
|
break;
|
|
12226
12380
|
if (i > 5) {
|
|
@@ -12281,10 +12435,15 @@
|
|
|
12281
12435
|
else {
|
|
12282
12436
|
let newAnchorHeight = scrollAnchorPos < 0 ? this.viewState.heightMap.height :
|
|
12283
12437
|
this.viewState.lineBlockAt(scrollAnchorPos).top;
|
|
12284
|
-
let diff = newAnchorHeight - scrollAnchorHeight;
|
|
12285
|
-
if (diff > 1 || diff < -1)
|
|
12286
|
-
|
|
12287
|
-
|
|
12438
|
+
let diff = (newAnchorHeight - scrollAnchorHeight) / this.scaleY;
|
|
12439
|
+
if ((diff > 1 || diff < -1) &&
|
|
12440
|
+
(scroll == this.scrollDOM || this.hasFocus ||
|
|
12441
|
+
Math.max(this.inputState.lastWheelEvent, this.inputState.lastTouchTime) > Date.now() - 100)) {
|
|
12442
|
+
scrollOffset = scrollOffset + diff;
|
|
12443
|
+
if (scroll)
|
|
12444
|
+
scroll.scrollTop += diff;
|
|
12445
|
+
else
|
|
12446
|
+
this.win.scrollBy(0, diff);
|
|
12288
12447
|
scrollAnchorHeight = -1;
|
|
12289
12448
|
continue;
|
|
12290
12449
|
}
|
|
@@ -13532,7 +13691,8 @@
|
|
|
13532
13691
|
combine(configs) {
|
|
13533
13692
|
return combineConfig(configs, {
|
|
13534
13693
|
cursorBlinkRate: 1200,
|
|
13535
|
-
drawRangeCursor: true
|
|
13694
|
+
drawRangeCursor: true,
|
|
13695
|
+
iosSelectionHandles: true
|
|
13536
13696
|
}, {
|
|
13537
13697
|
cursorBlinkRate: (a, b) => Math.min(a, b),
|
|
13538
13698
|
drawRangeCursor: (a, b) => a || b
|
|
@@ -13576,9 +13736,9 @@
|
|
|
13576
13736
|
let cursors = [];
|
|
13577
13737
|
for (let r of state.selection.ranges) {
|
|
13578
13738
|
let prim = r == state.selection.main;
|
|
13579
|
-
if (r.empty || conf.drawRangeCursor) {
|
|
13739
|
+
if (r.empty || conf.drawRangeCursor && !(prim && browser.ios && conf.iosSelectionHandles)) {
|
|
13580
13740
|
let className = prim ? "cm-cursor cm-cursor-primary" : "cm-cursor cm-cursor-secondary";
|
|
13581
|
-
let cursor = r.empty ? r : EditorSelection.cursor(r.head, r.
|
|
13741
|
+
let cursor = r.empty ? r : EditorSelection.cursor(r.head, r.assoc);
|
|
13582
13742
|
for (let piece of RectangleMarker.forRange(view, className, cursor))
|
|
13583
13743
|
cursors.push(piece);
|
|
13584
13744
|
}
|
|
@@ -13604,8 +13764,19 @@
|
|
|
13604
13764
|
const selectionLayer = /*@__PURE__*/layer({
|
|
13605
13765
|
above: false,
|
|
13606
13766
|
markers(view) {
|
|
13607
|
-
|
|
13608
|
-
|
|
13767
|
+
let markers = [], { main, ranges } = view.state.selection;
|
|
13768
|
+
for (let r of ranges)
|
|
13769
|
+
if (!r.empty) {
|
|
13770
|
+
for (let marker of RectangleMarker.forRange(view, "cm-selectionBackground", r))
|
|
13771
|
+
markers.push(marker);
|
|
13772
|
+
}
|
|
13773
|
+
if (browser.ios && !main.empty && view.state.facet(selectionConfig).iosSelectionHandles) {
|
|
13774
|
+
for (let piece of RectangleMarker.forRange(view, "cm-selectionHandle cm-selectionHandle-start", EditorSelection.cursor(main.from, 1)))
|
|
13775
|
+
markers.push(piece);
|
|
13776
|
+
for (let piece of RectangleMarker.forRange(view, "cm-selectionHandle cm-selectionHandle-end", EditorSelection.cursor(main.to, 1)))
|
|
13777
|
+
markers.push(piece);
|
|
13778
|
+
}
|
|
13779
|
+
return markers;
|
|
13609
13780
|
},
|
|
13610
13781
|
update(update, dom) {
|
|
13611
13782
|
return update.docChanged || update.selectionSet || update.viewportChanged || configChanged(update);
|
|
@@ -19937,30 +20108,44 @@
|
|
|
19937
20108
|
decorations.push(mark.range(match.end.from, match.end.to));
|
|
19938
20109
|
return decorations;
|
|
19939
20110
|
}
|
|
19940
|
-
|
|
19941
|
-
|
|
19942
|
-
|
|
19943
|
-
|
|
19944
|
-
|
|
19945
|
-
|
|
19946
|
-
let
|
|
19947
|
-
|
|
19948
|
-
|
|
19949
|
-
|
|
19950
|
-
|
|
19951
|
-
|
|
19952
|
-
|
|
19953
|
-
|
|
19954
|
-
|
|
19955
|
-
|
|
19956
|
-
|
|
19957
|
-
|
|
19958
|
-
|
|
19959
|
-
|
|
19960
|
-
|
|
20111
|
+
function bracketDeco(state) {
|
|
20112
|
+
let decorations = [];
|
|
20113
|
+
let config = state.facet(bracketMatchingConfig);
|
|
20114
|
+
for (let range of state.selection.ranges) {
|
|
20115
|
+
if (!range.empty)
|
|
20116
|
+
continue;
|
|
20117
|
+
let match = matchBrackets(state, range.head, -1, config)
|
|
20118
|
+
|| (range.head > 0 && matchBrackets(state, range.head - 1, 1, config))
|
|
20119
|
+
|| (config.afterCursor &&
|
|
20120
|
+
(matchBrackets(state, range.head, 1, config) ||
|
|
20121
|
+
(range.head < state.doc.length && matchBrackets(state, range.head + 1, -1, config))));
|
|
20122
|
+
if (match)
|
|
20123
|
+
decorations = decorations.concat(config.renderMatch(match, state));
|
|
20124
|
+
}
|
|
20125
|
+
return Decoration.set(decorations, true);
|
|
20126
|
+
}
|
|
20127
|
+
const bracketMatcher = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
20128
|
+
constructor(view) {
|
|
20129
|
+
this.paused = false;
|
|
20130
|
+
this.decorations = bracketDeco(view.state);
|
|
20131
|
+
}
|
|
20132
|
+
update(update) {
|
|
20133
|
+
if (update.docChanged || update.selectionSet || this.paused) {
|
|
20134
|
+
if (update.view.composing) {
|
|
20135
|
+
this.decorations = this.decorations.map(update.changes);
|
|
20136
|
+
this.paused = true;
|
|
20137
|
+
}
|
|
20138
|
+
else {
|
|
20139
|
+
this.decorations = bracketDeco(update.state);
|
|
20140
|
+
this.paused = false;
|
|
20141
|
+
}
|
|
20142
|
+
}
|
|
20143
|
+
}
|
|
20144
|
+
}, {
|
|
20145
|
+
decorations: v => v.decorations
|
|
19961
20146
|
});
|
|
19962
20147
|
const bracketMatchingUnique = [
|
|
19963
|
-
|
|
20148
|
+
bracketMatcher,
|
|
19964
20149
|
baseTheme$3
|
|
19965
20150
|
];
|
|
19966
20151
|
/**
|
|
@@ -20861,7 +21046,7 @@
|
|
|
20861
21046
|
function extendSel(target, how) {
|
|
20862
21047
|
let selection = updateSel(target.state.selection, range => {
|
|
20863
21048
|
let head = how(range);
|
|
20864
|
-
return EditorSelection.range(range.anchor, head.head, head.goalColumn, head.bidiLevel || undefined);
|
|
21049
|
+
return EditorSelection.range(range.anchor, head.head, head.goalColumn, head.bidiLevel || undefined, head.assoc);
|
|
20865
21050
|
});
|
|
20866
21051
|
if (selection.eq(target.state.selection))
|
|
20867
21052
|
return false;
|
|
@@ -23231,6 +23416,7 @@
|
|
|
23231
23416
|
};
|
|
23232
23417
|
}
|
|
23233
23418
|
|
|
23419
|
+
const setSelectedEffect = /*@__PURE__*/StateEffect.define();
|
|
23234
23420
|
function optionContent(config) {
|
|
23235
23421
|
let content = config.addToOptions.slice();
|
|
23236
23422
|
if (config.icons)
|
|
@@ -23322,6 +23508,16 @@
|
|
|
23322
23508
|
return;
|
|
23323
23509
|
}
|
|
23324
23510
|
}
|
|
23511
|
+
if (e.target == this.list) {
|
|
23512
|
+
let move = this.list.classList.contains("cm-completionListIncompleteTop") &&
|
|
23513
|
+
e.clientY < this.list.firstChild.getBoundingClientRect().top ? this.range.from - 1 :
|
|
23514
|
+
this.list.classList.contains("cm-completionListIncompleteBottom") &&
|
|
23515
|
+
e.clientY > this.list.lastChild.getBoundingClientRect().bottom ? this.range.to : null;
|
|
23516
|
+
if (move != null) {
|
|
23517
|
+
view.dispatch({ effects: setSelectedEffect.of(move) });
|
|
23518
|
+
e.preventDefault();
|
|
23519
|
+
}
|
|
23520
|
+
}
|
|
23325
23521
|
});
|
|
23326
23522
|
this.dom.addEventListener("focusout", (e) => {
|
|
23327
23523
|
let state = view.state.field(this.stateField, false);
|
|
@@ -23823,7 +24019,6 @@
|
|
|
23823
24019
|
const setActiveEffect = /*@__PURE__*/StateEffect.define({
|
|
23824
24020
|
map(sources, mapping) { return sources.map(s => s.map(mapping)); }
|
|
23825
24021
|
});
|
|
23826
|
-
const setSelectedEffect = /*@__PURE__*/StateEffect.define();
|
|
23827
24022
|
const completionState = /*@__PURE__*/StateField.define({
|
|
23828
24023
|
create() { return CompletionState.start(); },
|
|
23829
24024
|
update(value, tr) { return value.update(tr); },
|
|
@@ -24978,10 +25173,10 @@
|
|
|
24978
25173
|
let field = view.state.field(lintState, false);
|
|
24979
25174
|
if (!field)
|
|
24980
25175
|
return false;
|
|
24981
|
-
let sel = view.state.selection.main, next = field.diagnostics
|
|
24982
|
-
if (!next
|
|
24983
|
-
next = field.diagnostics
|
|
24984
|
-
if (!next
|
|
25176
|
+
let sel = view.state.selection.main, next = findDiagnostic(field.diagnostics, null, sel.to + 1);
|
|
25177
|
+
if (!next) {
|
|
25178
|
+
next = findDiagnostic(field.diagnostics, null, 0);
|
|
25179
|
+
if (!next || next.from == sel.from && next.to == sel.to)
|
|
24985
25180
|
return false;
|
|
24986
25181
|
}
|
|
24987
25182
|
view.dispatch({ selection: { anchor: next.from, head: next.to }, scrollIntoView: true });
|
|
@@ -25353,6 +25548,12 @@
|
|
|
25353
25548
|
padding: 0,
|
|
25354
25549
|
margin: 0
|
|
25355
25550
|
}
|
|
25551
|
+
},
|
|
25552
|
+
"&dark .cm-lintRange-active": { backgroundColor: "#86714a80" },
|
|
25553
|
+
"&dark .cm-panel.cm-panel-lint ul": {
|
|
25554
|
+
"& [aria-selected]": {
|
|
25555
|
+
backgroundColor: "#2e343e",
|
|
25556
|
+
},
|
|
25356
25557
|
}
|
|
25357
25558
|
});
|
|
25358
25559
|
function severityWeight(sev) {
|
|
@@ -27725,7 +27926,21 @@
|
|
|
27725
27926
|
}),
|
|
27726
27927
|
/*@__PURE__*/foldNodeProp.add({
|
|
27727
27928
|
"Block ClassBody SwitchBody EnumBody ObjectExpression ArrayExpression ObjectType": foldInside,
|
|
27728
|
-
BlockComment(tree) { return { from: tree.from + 2, to: tree.to - 2 }; }
|
|
27929
|
+
BlockComment(tree) { return { from: tree.from + 2, to: tree.to - 2 }; },
|
|
27930
|
+
JSXElement(tree) {
|
|
27931
|
+
let open = tree.firstChild;
|
|
27932
|
+
if (!open || open.name == "JSXSelfClosingTag")
|
|
27933
|
+
return null;
|
|
27934
|
+
let close = tree.lastChild;
|
|
27935
|
+
return { from: open.to, to: close.type.isError ? tree.to : close.from };
|
|
27936
|
+
},
|
|
27937
|
+
"JSXSelfClosingTag JSXOpenTag"(tree) {
|
|
27938
|
+
var _a;
|
|
27939
|
+
let name = (_a = tree.firstChild) === null || _a === void 0 ? void 0 : _a.nextSibling, close = tree.lastChild;
|
|
27940
|
+
if (!name || name.type.isError)
|
|
27941
|
+
return null;
|
|
27942
|
+
return { from: name.to, to: close.type.isError ? tree.to : close.from };
|
|
27943
|
+
}
|
|
27729
27944
|
})
|
|
27730
27945
|
]
|
|
27731
27946
|
}),
|