datafolder 1.0.6 → 1.0.8
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 +7 -2
- package/index.js +1 -1
- package/internal.md +121 -0
- package/package.json +8 -6
- 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 -0
- 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 +27 -16
- package/src/QyCache.d.ts +44 -0
- package/src/QyCache.js +71 -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 +3 -4
- 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 +30 -20
- 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 +11 -13
- 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 +21 -22
- 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 +56 -53
- package/src/QySnapshots.d.ts +27 -0
- package/src/QySnapshots.js +74 -66
- 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/rpc/getTriggerFiles.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/src/soc_pokec.js +7 -7
- package/static/codemirror.bundle/editor.bundle.js +370 -166
- package/static/datafolderui/QyStyledElement.js +8 -17
- package/static/datafolderui/QyUIFolderViewer.js +230 -0
- package/static/datafolderui/QyUIUtils.js +5 -5
- package/static/datafolderui/code-mirror.js +7 -7
- package/static/datafolderui/display-tree.js +22 -58
- package/static/datafolderui/explore-tree.js +10 -10
- package/static/datafolderui/folder-tree.js +71 -2
- package/static/datafolderui/hscrpt.js +26 -7
- package/static/datafolderui/json-view.js +34 -3
- package/static/datafolderui/main-page.js +67 -36
- package/static/datafolderui/query-editor.js +9 -9
- package/static/datafolderui/rpc-editor.js +31 -0
- package/static/datafolderui/trigger-editor.js +33 -0
- package/data/sampleDataFolder/qykv/history/acl/1_acl.txt +0 -1
- package/data/sampleDataFolder/qykv/history/acl/2_acl.txt +0 -1
- package/data/sampleDataFolder/qykv/history/acl/3_acl.txt +0 -1
- package/data/sampleDataFolder/qykv/history/acl/4_acl.txt +0 -1
- package/data/sampleDataFolder/qykv/history/acl/5_acl.txt +0 -1
- package/data/sampleDataFolder/qykv/snapshot/1/1_pM.txt +0 -0
- package/data/sampleDataFolder/qykv/snapshot/1/1_prefixPM.txt +0 -0
- package/data/sampleDataFolder/qykv/snapshot/1/1_vL.txt +0 -10
- package/data/sampleDataFolder/qykv/snapshot/2/1_pM.txt +0 -0
- package/data/sampleDataFolder/qykv/snapshot/2/1_prefixPM.txt +0 -0
- package/data/sampleDataFolder/qykv/snapshot/2/1_vL.txt +0 -1
- package/data/sampleDataFolder/qykv/snapshot/3/1_pM.txt +0 -0
- package/data/sampleDataFolder/qykv/snapshot/3/1_prefixPM.txt +0 -0
- package/data/sampleDataFolder/qykv/snapshot/3/1_vL.txt +0 -1
- package/data/sampleDataFolder/qykv/snapshot/4/1_pM.txt +0 -0
- package/data/sampleDataFolder/qykv/snapshot/4/1_prefixPM.txt +0 -0
- package/data/sampleDataFolder/qykv/snapshot/4/1_vL.txt +0 -1
- package/data/sampleDataFolder/qykv/snapshot/4/2_pM.txt +0 -0
- package/data/sampleDataFolder/qykv/snapshot/4/2_prefixPM.txt +0 -0
- package/data/sampleDataFolder/qykv/snapshot/4/2_vL.txt +0 -9
- package/data/sampleDataFolder/qykv/snapshot/5/1_pM.txt +0 -0
- package/data/sampleDataFolder/qykv/snapshot/5/1_prefixPM.txt +0 -0
- package/data/sampleDataFolder/qykv/snapshot/5/1_vL.txt +0 -55
- package/data/sampleDataFolder/qykv/snapshot/info/1.json +0 -1
- package/data/sampleDataFolder/qykv/snapshot/info/2.json +0 -1
- package/data/sampleDataFolder/qykv/snapshot/info/3.json +0 -1
- package/data/sampleDataFolder/qykv/snapshot/info/4.json +0 -1
- package/data/sampleDataFolder/qykv/snapshot/info/5.json +0 -1
- package/data/sampleDataFolder/qylog/2026/02/15/08/change.txt +0 -58
- package/data/sampleDataFolder/qylog/2026/02/15/08/stderr.txt +0 -11
- package/data/sampleDataFolder/qylog/2026/02/15/08/stdout.txt +0 -36
- package/static/datafolderui/QyUIFolderTree.js +0 -179
|
@@ -4907,16 +4907,16 @@
|
|
|
4907
4907
|
}
|
|
4908
4908
|
}
|
|
4909
4909
|
}
|
|
4910
|
-
function scrollableParents(dom) {
|
|
4911
|
-
let doc = dom.ownerDocument, x, y;
|
|
4910
|
+
function scrollableParents(dom, getX = true) {
|
|
4911
|
+
let doc = dom.ownerDocument, x = null, y = null;
|
|
4912
4912
|
for (let cur = dom.parentNode; cur;) {
|
|
4913
|
-
if (cur == doc.body || (x && y)) {
|
|
4913
|
+
if (cur == doc.body || ((!getX || x) && y)) {
|
|
4914
4914
|
break;
|
|
4915
4915
|
}
|
|
4916
4916
|
else if (cur.nodeType == 1) {
|
|
4917
4917
|
if (!y && cur.scrollHeight > cur.clientHeight)
|
|
4918
4918
|
y = cur;
|
|
4919
|
-
if (!x && cur.scrollWidth > cur.clientWidth)
|
|
4919
|
+
if (getX && !x && cur.scrollWidth > cur.clientWidth)
|
|
4920
4920
|
x = cur;
|
|
4921
4921
|
cur = cur.assignedSlot || cur.parentNode;
|
|
4922
4922
|
}
|
|
@@ -5041,6 +5041,8 @@
|
|
|
5041
5041
|
}
|
|
5042
5042
|
}
|
|
5043
5043
|
function isScrolledToBottom(elt) {
|
|
5044
|
+
if (elt instanceof Window)
|
|
5045
|
+
return elt.pageYOffset > Math.max(0, elt.document.documentElement.scrollHeight - elt.innerHeight - 4);
|
|
5044
5046
|
return elt.scrollTop > Math.max(1, elt.scrollHeight - elt.clientHeight - 4);
|
|
5045
5047
|
}
|
|
5046
5048
|
function textNodeBefore(startNode, startOffset) {
|
|
@@ -6938,7 +6940,7 @@
|
|
|
6938
6940
|
}
|
|
6939
6941
|
else if (tile.isText()) {
|
|
6940
6942
|
this.builder.ensureLine(null);
|
|
6941
|
-
if (!from && to == tile.length) {
|
|
6943
|
+
if (!from && to == tile.length && !this.cache.reused.has(tile)) {
|
|
6942
6944
|
this.builder.addText(tile.text, activeMarks, openMarks, this.cache.reuse(tile));
|
|
6943
6945
|
}
|
|
6944
6946
|
else {
|
|
@@ -7073,9 +7075,10 @@
|
|
|
7073
7075
|
marks.push(tile);
|
|
7074
7076
|
else if (tile === null || tile === void 0 ? void 0 : tile.isLine())
|
|
7075
7077
|
line = tile;
|
|
7078
|
+
else if (tile instanceof BlockWrapperTile) ; // Ignore
|
|
7076
7079
|
else if (parent.nodeName == "DIV" && !line && parent != this.view.contentDOM)
|
|
7077
7080
|
line = new LineTile(parent, lineBaseAttrs);
|
|
7078
|
-
else
|
|
7081
|
+
else if (!line)
|
|
7079
7082
|
marks.push(MarkTile.of(new MarkDecoration({ tagName: parent.nodeName.toLowerCase(), attributes: getAttrs(parent) }), parent));
|
|
7080
7083
|
}
|
|
7081
7084
|
return { line: line, marks };
|
|
@@ -7241,6 +7244,8 @@
|
|
|
7241
7244
|
if (composition || changes.length) {
|
|
7242
7245
|
let oldTile = this.tile;
|
|
7243
7246
|
let builder = new TileUpdate(this.view, oldTile, this.blockWrappers, this.decorations, this.dynamicDecorationMap);
|
|
7247
|
+
if (composition && Tile.get(composition.text))
|
|
7248
|
+
builder.cache.reused.set(Tile.get(composition.text), 2 /* Reused.DOM */);
|
|
7244
7249
|
this.tile = builder.run(changes, composition);
|
|
7245
7250
|
destroyDropped(oldTile, builder.cache.reused);
|
|
7246
7251
|
}
|
|
@@ -7701,6 +7706,19 @@
|
|
|
7701
7706
|
};
|
|
7702
7707
|
let { offsetWidth, offsetHeight } = this.view.scrollDOM;
|
|
7703
7708
|
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);
|
|
7709
|
+
// On mobile browsers, the visual viewport may be smaller than the
|
|
7710
|
+
// actual reported viewport, causing scrollRectIntoView to fail to
|
|
7711
|
+
// scroll properly. Unfortunately, this visual viewport cannot be
|
|
7712
|
+
// updated directly, and scrollIntoView is the only way a script
|
|
7713
|
+
// can affect it. So this tries to kludge around the problem by
|
|
7714
|
+
// calling scrollIntoView on the scroll target's line.
|
|
7715
|
+
if (window.visualViewport && window.innerHeight - window.visualViewport.height > 1 &&
|
|
7716
|
+
(rect.top > window.pageYOffset + window.visualViewport.offsetTop + window.visualViewport.height ||
|
|
7717
|
+
rect.bottom < window.pageYOffset + window.visualViewport.offsetTop)) {
|
|
7718
|
+
let line = this.view.docView.lineAt(range.head, 1);
|
|
7719
|
+
if (line)
|
|
7720
|
+
line.dom.scrollIntoView({ block: "nearest" });
|
|
7721
|
+
}
|
|
7704
7722
|
}
|
|
7705
7723
|
lineHasWidget(pos) {
|
|
7706
7724
|
let scan = (child) => child.isWidget() || child.children.some(scan);
|
|
@@ -8049,86 +8067,167 @@
|
|
|
8049
8067
|
let line = view.docView.lineAt(block.from, 2);
|
|
8050
8068
|
if (!line || line.length != block.length)
|
|
8051
8069
|
line = view.docView.lineAt(block.from, -2);
|
|
8052
|
-
return
|
|
8070
|
+
return new InlineCoordsScan(view, x, y, view.textDirectionAt(block.from)).scanTile(line, block.from);
|
|
8053
8071
|
}
|
|
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
|
-
|
|
8072
|
+
class InlineCoordsScan {
|
|
8073
|
+
constructor(view, x, y, baseDir) {
|
|
8074
|
+
this.view = view;
|
|
8075
|
+
this.x = x;
|
|
8076
|
+
this.y = y;
|
|
8077
|
+
this.baseDir = baseDir;
|
|
8078
|
+
// Cached bidi info
|
|
8079
|
+
this.line = null;
|
|
8080
|
+
this.spans = null;
|
|
8081
|
+
}
|
|
8082
|
+
bidiSpansAt(pos) {
|
|
8083
|
+
if (!this.line || this.line.from > pos || this.line.to < pos) {
|
|
8084
|
+
this.line = this.view.state.doc.lineAt(pos);
|
|
8085
|
+
this.spans = this.view.bidiSpans(this.line);
|
|
8086
|
+
}
|
|
8087
|
+
return this;
|
|
8088
|
+
}
|
|
8089
|
+
baseDirAt(pos, side) {
|
|
8090
|
+
let { line, spans } = this.bidiSpansAt(pos);
|
|
8091
|
+
let level = spans[BidiSpan.find(spans, pos - line.from, -1, side)].level;
|
|
8092
|
+
return level == this.baseDir;
|
|
8093
|
+
}
|
|
8094
|
+
dirAt(pos, side) {
|
|
8095
|
+
let { line, spans } = this.bidiSpansAt(pos);
|
|
8096
|
+
return spans[BidiSpan.find(spans, pos - line.from, -1, side)].dir;
|
|
8097
|
+
}
|
|
8098
|
+
// Used to short-circuit bidi tests for content with a uniform direction
|
|
8099
|
+
bidiIn(from, to) {
|
|
8100
|
+
let { spans, line } = this.bidiSpansAt(from);
|
|
8101
|
+
return spans.length > 1 || spans.length && (spans[0].level != this.baseDir || spans[0].to + line.from < to);
|
|
8102
|
+
}
|
|
8103
|
+
// Scan through the rectangles for the content of a tile with inline
|
|
8104
|
+
// content, looking for one that overlaps the queried position
|
|
8105
|
+
// vertically andis
|
|
8106
|
+
// closest horizontally. The caller is responsible for dividing its
|
|
8107
|
+
// content into N pieces, and pass an array with N+1 positions
|
|
8108
|
+
// (including the position after the last piece). For a text tile,
|
|
8109
|
+
// these will be character clusters, for a composite tile, these
|
|
8110
|
+
// will be child tiles.
|
|
8111
|
+
scan(positions, getRects) {
|
|
8112
|
+
let lo = 0, hi = positions.length - 1, seen = new Set();
|
|
8113
|
+
let bidi = this.bidiIn(positions[0], positions[hi]);
|
|
8114
|
+
let above, below;
|
|
8115
|
+
let closestI = -1, closestDx = 1e9, closestRect;
|
|
8116
|
+
// Because, when the content is bidirectional, a regular binary
|
|
8117
|
+
// search is hard to perform (the content order does not
|
|
8118
|
+
// correspond to visual order), this loop does something between a
|
|
8119
|
+
// regular binary search and a full scan, depending on what it can
|
|
8120
|
+
// get away with. The outer hi/lo bounds are only adjusted for
|
|
8121
|
+
// elements that are part of the base order.
|
|
8122
|
+
//
|
|
8123
|
+
// To make sure all elements inside those bounds are visited,
|
|
8124
|
+
// eventually, we keep a set of seen indices, and if the midpoint
|
|
8125
|
+
// has already been handled, we start in a random index within the
|
|
8126
|
+
// current bounds and scan forward until we find an index that
|
|
8127
|
+
// hasn't been seen yet.
|
|
8128
|
+
search: while (lo < hi) {
|
|
8129
|
+
let dist = hi - lo, mid = (lo + hi) >> 1;
|
|
8130
|
+
adjust: if (seen.has(mid)) {
|
|
8131
|
+
let scan = lo + Math.floor(Math.random() * dist);
|
|
8132
|
+
for (let i = 0; i < dist; i++) {
|
|
8133
|
+
if (!seen.has(scan)) {
|
|
8134
|
+
mid = scan;
|
|
8135
|
+
break adjust;
|
|
8136
|
+
}
|
|
8137
|
+
scan++;
|
|
8138
|
+
if (scan == hi)
|
|
8139
|
+
scan = lo; // Wrap around
|
|
8094
8140
|
}
|
|
8141
|
+
break search; // No index found, we're done
|
|
8095
8142
|
}
|
|
8143
|
+
seen.add(mid);
|
|
8144
|
+
let rects = getRects(mid);
|
|
8145
|
+
if (rects)
|
|
8146
|
+
for (let i = 0; i < rects.length; i++) {
|
|
8147
|
+
let rect = rects[i], side = 0;
|
|
8148
|
+
// Ignore empty rectangles when there are other rectangles
|
|
8149
|
+
if (rect.width == 0 && rects.length > 1)
|
|
8150
|
+
continue;
|
|
8151
|
+
if (rect.bottom < this.y) {
|
|
8152
|
+
if (!above || above.bottom < rect.bottom)
|
|
8153
|
+
above = rect;
|
|
8154
|
+
side = 1;
|
|
8155
|
+
}
|
|
8156
|
+
else if (rect.top > this.y) {
|
|
8157
|
+
if (!below || below.top > rect.top)
|
|
8158
|
+
below = rect;
|
|
8159
|
+
side = -1;
|
|
8160
|
+
}
|
|
8161
|
+
else {
|
|
8162
|
+
let off = rect.left > this.x ? this.x - rect.left : rect.right < this.x ? this.x - rect.right : 0;
|
|
8163
|
+
let dx = Math.abs(off);
|
|
8164
|
+
if (dx < closestDx) {
|
|
8165
|
+
closestI = mid;
|
|
8166
|
+
closestDx = dx;
|
|
8167
|
+
closestRect = rect;
|
|
8168
|
+
}
|
|
8169
|
+
if (off)
|
|
8170
|
+
side = (off < 0) == (this.baseDir == Direction.LTR) ? -1 : 1;
|
|
8171
|
+
}
|
|
8172
|
+
// Narrow binary search when it is safe to do so
|
|
8173
|
+
if (side == -1 && (!bidi || this.baseDirAt(positions[mid], 1)))
|
|
8174
|
+
hi = mid;
|
|
8175
|
+
else if (side == 1 && (!bidi || this.baseDirAt(positions[mid + 1], -1)))
|
|
8176
|
+
lo = mid + 1;
|
|
8177
|
+
}
|
|
8096
8178
|
}
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
|
|
8100
|
-
let
|
|
8101
|
-
|
|
8102
|
-
|
|
8103
|
-
break;
|
|
8104
|
-
i = next;
|
|
8179
|
+
// If no element with y overlap is found, find the nearest element
|
|
8180
|
+
// on the y axis, move this.y into it, and retry the scan.
|
|
8181
|
+
if (!closestRect) {
|
|
8182
|
+
let side = above && (!below || (this.y - above.bottom < below.top - this.y)) ? above : below;
|
|
8183
|
+
this.y = (side.top + side.bottom) / 2;
|
|
8184
|
+
return this.scan(positions, getRects);
|
|
8105
8185
|
}
|
|
8106
|
-
let
|
|
8107
|
-
return
|
|
8186
|
+
let ltr = (bidi ? this.dirAt(positions[closestI], 1) : this.baseDir) == Direction.LTR;
|
|
8187
|
+
return {
|
|
8188
|
+
i: closestI,
|
|
8189
|
+
// Test whether x is closes to the start or end of this element
|
|
8190
|
+
after: (this.x > (closestRect.left + closestRect.right) / 2) == ltr
|
|
8191
|
+
};
|
|
8108
8192
|
}
|
|
8109
|
-
|
|
8193
|
+
scanText(tile, offset) {
|
|
8194
|
+
let positions = [];
|
|
8195
|
+
for (let i = 0; i < tile.length; i = findClusterBreak(tile.text, i))
|
|
8196
|
+
positions.push(offset + i);
|
|
8197
|
+
positions.push(offset + tile.length);
|
|
8198
|
+
let scan = this.scan(positions, i => {
|
|
8199
|
+
let off = positions[i] - offset, end = positions[i + 1] - offset;
|
|
8200
|
+
return textRange(tile.dom, off, end).getClientRects();
|
|
8201
|
+
});
|
|
8202
|
+
return scan.after ? new PosAssoc(positions[scan.i + 1], -1) : new PosAssoc(positions[scan.i], 1);
|
|
8203
|
+
}
|
|
8204
|
+
scanTile(tile, offset) {
|
|
8110
8205
|
if (!tile.length)
|
|
8111
8206
|
return new PosAssoc(offset, 1);
|
|
8112
|
-
|
|
8207
|
+
if (tile.children.length == 1) { // Short-circuit single-child tiles
|
|
8208
|
+
let child = tile.children[0];
|
|
8209
|
+
if (child.isText())
|
|
8210
|
+
return this.scanText(child, offset);
|
|
8211
|
+
else if (child.isComposite())
|
|
8212
|
+
return this.scanTile(child, offset);
|
|
8213
|
+
}
|
|
8214
|
+
let positions = [offset];
|
|
8215
|
+
for (let i = 0, pos = offset; i < tile.children.length; i++)
|
|
8216
|
+
positions.push(pos += tile.children[i].length);
|
|
8217
|
+
let scan = this.scan(positions, i => {
|
|
8113
8218
|
let child = tile.children[i];
|
|
8114
8219
|
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);
|
|
8220
|
+
return null;
|
|
8221
|
+
return (child.dom.nodeType == 1 ? child.dom : textRange(child.dom, 0, child.length)).getClientRects();
|
|
8222
|
+
});
|
|
8223
|
+
let child = tile.children[scan.i], pos = positions[scan.i];
|
|
8224
|
+
if (child.isText())
|
|
8225
|
+
return this.scanText(child, pos);
|
|
8226
|
+
if (child.isComposite())
|
|
8227
|
+
return this.scanTile(child, pos);
|
|
8228
|
+
return scan.after ? new PosAssoc(positions[scan.i + 1], -1) : new PosAssoc(pos, 1);
|
|
8126
8229
|
}
|
|
8127
8230
|
}
|
|
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
8231
|
|
|
8133
8232
|
const LineBreakPlaceholder = "\uffff";
|
|
8134
8233
|
class DOMReader {
|
|
@@ -8272,7 +8371,7 @@
|
|
|
8272
8371
|
this.bounds = null;
|
|
8273
8372
|
this.text = "";
|
|
8274
8373
|
this.domChanged = start > -1;
|
|
8275
|
-
let { impreciseHead: iHead, impreciseAnchor: iAnchor } = view.docView;
|
|
8374
|
+
let { impreciseHead: iHead, impreciseAnchor: iAnchor } = view.docView, curSel = view.state.selection;
|
|
8276
8375
|
if (view.state.readOnly && start > -1) {
|
|
8277
8376
|
// Ignore changes when the editor is read-only
|
|
8278
8377
|
this.newSel = null;
|
|
@@ -8288,18 +8387,18 @@
|
|
|
8288
8387
|
let domSel = view.observer.selectionRange;
|
|
8289
8388
|
let head = iHead && iHead.node == domSel.focusNode && iHead.offset == domSel.focusOffset ||
|
|
8290
8389
|
!contains(view.contentDOM, domSel.focusNode)
|
|
8291
|
-
?
|
|
8390
|
+
? curSel.main.head
|
|
8292
8391
|
: view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset);
|
|
8293
8392
|
let anchor = iAnchor && iAnchor.node == domSel.anchorNode && iAnchor.offset == domSel.anchorOffset ||
|
|
8294
8393
|
!contains(view.contentDOM, domSel.anchorNode)
|
|
8295
|
-
?
|
|
8394
|
+
? curSel.main.anchor
|
|
8296
8395
|
: view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset);
|
|
8297
8396
|
// iOS will refuse to select the block gaps when doing
|
|
8298
8397
|
// select-all.
|
|
8299
8398
|
// Chrome will put the selection *inside* them, confusing
|
|
8300
8399
|
// posFromDOM
|
|
8301
8400
|
let vp = view.viewport;
|
|
8302
|
-
if ((browser.ios || browser.chrome) &&
|
|
8401
|
+
if ((browser.ios || browser.chrome) && curSel.main.empty && head != anchor &&
|
|
8303
8402
|
(vp.from > 0 || vp.to < view.state.doc.length)) {
|
|
8304
8403
|
let from = Math.min(head, anchor), to = Math.max(head, anchor);
|
|
8305
8404
|
let offFrom = vp.from - from, offTo = vp.to - to;
|
|
@@ -8308,10 +8407,22 @@
|
|
|
8308
8407
|
anchor = view.state.doc.length;
|
|
8309
8408
|
}
|
|
8310
8409
|
}
|
|
8311
|
-
if (view.inputState.composing > -1 &&
|
|
8312
|
-
this.newSel =
|
|
8313
|
-
|
|
8410
|
+
if (view.inputState.composing > -1 && curSel.ranges.length > 1) {
|
|
8411
|
+
this.newSel = curSel.replaceRange(EditorSelection.range(anchor, head));
|
|
8412
|
+
}
|
|
8413
|
+
else if (view.lineWrapping && anchor == head && !(curSel.main.empty && curSel.main.head == head) &&
|
|
8414
|
+
view.inputState.lastTouchTime > Date.now() - 100) {
|
|
8415
|
+
// If this is a cursor selection change in a line-wrapping
|
|
8416
|
+
// editor that may have been a touch, use the last touch
|
|
8417
|
+
// position to assign a side to the cursor.
|
|
8418
|
+
let before = view.coordsAtPos(head, -1), assoc = 0;
|
|
8419
|
+
if (before)
|
|
8420
|
+
assoc = view.inputState.lastTouchY <= before.bottom ? -1 : 1;
|
|
8421
|
+
this.newSel = EditorSelection.create([EditorSelection.cursor(head, assoc)]);
|
|
8422
|
+
}
|
|
8423
|
+
else {
|
|
8314
8424
|
this.newSel = EditorSelection.single(anchor, head);
|
|
8425
|
+
}
|
|
8315
8426
|
}
|
|
8316
8427
|
}
|
|
8317
8428
|
}
|
|
@@ -8347,7 +8458,7 @@
|
|
|
8347
8458
|
}
|
|
8348
8459
|
function applyDOMChange(view, domChange) {
|
|
8349
8460
|
let change;
|
|
8350
|
-
let { newSel } = domChange, sel =
|
|
8461
|
+
let { newSel } = domChange, { state } = view, sel = state.selection.main;
|
|
8351
8462
|
let lastKey = view.inputState.lastKeyTime > Date.now() - 100 ? view.inputState.lastKeyCode : -1;
|
|
8352
8463
|
if (domChange.bounds) {
|
|
8353
8464
|
let { from, to } = domChange.bounds;
|
|
@@ -8358,8 +8469,15 @@
|
|
|
8358
8469
|
preferredPos = sel.to;
|
|
8359
8470
|
preferredSide = "end";
|
|
8360
8471
|
}
|
|
8361
|
-
let
|
|
8362
|
-
if (
|
|
8472
|
+
let cmp = state.doc.sliceString(from, to, LineBreakPlaceholder), selEnd, diff;
|
|
8473
|
+
if (!sel.empty && sel.from >= from && sel.to <= to && (domChange.typeOver || cmp != domChange.text) &&
|
|
8474
|
+
cmp.slice(0, sel.from - from) == domChange.text.slice(0, sel.from - from) &&
|
|
8475
|
+
cmp.slice(sel.to - from) == domChange.text.slice(selEnd = domChange.text.length - (cmp.length - (sel.to - from)))) {
|
|
8476
|
+
// This looks like a selection replacement
|
|
8477
|
+
change = { from: sel.from, to: sel.to,
|
|
8478
|
+
insert: Text.of(domChange.text.slice(sel.from - from, selEnd).split(LineBreakPlaceholder)) };
|
|
8479
|
+
}
|
|
8480
|
+
else if (diff = findDiff(cmp, domChange.text, preferredPos - from, preferredSide)) {
|
|
8363
8481
|
// Chrome inserts two newlines when pressing shift-enter at the
|
|
8364
8482
|
// end of a line. DomChange drops one of those.
|
|
8365
8483
|
if (browser.chrome && lastKey == 13 &&
|
|
@@ -8369,16 +8487,12 @@
|
|
|
8369
8487
|
insert: Text.of(domChange.text.slice(diff.from, diff.toB).split(LineBreakPlaceholder)) };
|
|
8370
8488
|
}
|
|
8371
8489
|
}
|
|
8372
|
-
else if (newSel && (!view.hasFocus &&
|
|
8490
|
+
else if (newSel && (!view.hasFocus && state.facet(editable) || sameSelPos(newSel, sel))) {
|
|
8373
8491
|
newSel = null;
|
|
8374
8492
|
}
|
|
8375
8493
|
if (!change && !newSel)
|
|
8376
8494
|
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 &&
|
|
8495
|
+
if ((browser.mac || browser.android) && change && change.from == change.to && change.from == sel.head - 1 &&
|
|
8382
8496
|
/^\. ?$/.test(change.insert.toString()) && view.contentDOM.getAttribute("autocorrect") == "off") {
|
|
8383
8497
|
// Detect insert-period-on-double-space Mac and Android behavior,
|
|
8384
8498
|
// and transform it into a regular space insert.
|
|
@@ -8386,18 +8500,7 @@
|
|
|
8386
8500
|
newSel = EditorSelection.single(newSel.main.anchor - 1, newSel.main.head - 1);
|
|
8387
8501
|
change = { from: change.from, to: change.to, insert: Text.of([change.insert.toString().replace(".", " ")]) };
|
|
8388
8502
|
}
|
|
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) &&
|
|
8503
|
+
else if (state.doc.lineAt(sel.from).to < sel.to && view.docView.lineHasWidget(sel.to) &&
|
|
8401
8504
|
view.inputState.insertingTextAt > Date.now() - 50) {
|
|
8402
8505
|
// For a cross-line insertion, Chrome and Safari will crudely take
|
|
8403
8506
|
// the text of the line after the selection, flattening any
|
|
@@ -8406,7 +8509,7 @@
|
|
|
8406
8509
|
// replace of the text provided by the beforeinput event.
|
|
8407
8510
|
change = {
|
|
8408
8511
|
from: sel.from, to: sel.to,
|
|
8409
|
-
insert:
|
|
8512
|
+
insert: state.toText(view.inputState.insertingText)
|
|
8410
8513
|
};
|
|
8411
8514
|
}
|
|
8412
8515
|
else if (browser.chrome && change && change.from == change.to && change.from == sel.head &&
|
|
@@ -8428,7 +8531,7 @@
|
|
|
8428
8531
|
scrollIntoView = true;
|
|
8429
8532
|
userEvent = view.inputState.lastSelectionOrigin;
|
|
8430
8533
|
if (userEvent == "select.pointer")
|
|
8431
|
-
newSel = skipAtomsForSelection(
|
|
8534
|
+
newSel = skipAtomsForSelection(state.facet(atomicRanges).map(f => f(view)), newSel);
|
|
8432
8535
|
}
|
|
8433
8536
|
view.dispatch({ selection: newSel, scrollIntoView, userEvent });
|
|
8434
8537
|
return true;
|
|
@@ -8606,9 +8709,12 @@
|
|
|
8606
8709
|
this.lastKeyCode = 0;
|
|
8607
8710
|
this.lastKeyTime = 0;
|
|
8608
8711
|
this.lastTouchTime = 0;
|
|
8712
|
+
this.lastTouchX = 0;
|
|
8713
|
+
this.lastTouchY = 0;
|
|
8609
8714
|
this.lastFocusTime = 0;
|
|
8610
8715
|
this.lastScrollTop = 0;
|
|
8611
8716
|
this.lastScrollLeft = 0;
|
|
8717
|
+
this.lastWheelEvent = 0;
|
|
8612
8718
|
// On iOS, some keys need to have their default behavior happen
|
|
8613
8719
|
// (after which we retroactively handle them and reset the DOM) to
|
|
8614
8720
|
// avoid messing up the virtual keyboard state.
|
|
@@ -9038,6 +9144,9 @@
|
|
|
9038
9144
|
view.inputState.lastScrollTop = view.scrollDOM.scrollTop;
|
|
9039
9145
|
view.inputState.lastScrollLeft = view.scrollDOM.scrollLeft;
|
|
9040
9146
|
};
|
|
9147
|
+
observers.wheel = observers.mousewheel = view => {
|
|
9148
|
+
view.inputState.lastWheelEvent = Date.now();
|
|
9149
|
+
};
|
|
9041
9150
|
handlers.keydown = (view, event) => {
|
|
9042
9151
|
view.inputState.setSelectionOrigin("select");
|
|
9043
9152
|
if (event.keyCode == 27 && view.inputState.tabFocusMode != 0)
|
|
@@ -9045,8 +9154,13 @@
|
|
|
9045
9154
|
return false;
|
|
9046
9155
|
};
|
|
9047
9156
|
observers.touchstart = (view, e) => {
|
|
9048
|
-
view.inputState
|
|
9049
|
-
|
|
9157
|
+
let iState = view.inputState, touch = e.targetTouches[0];
|
|
9158
|
+
iState.lastTouchTime = Date.now();
|
|
9159
|
+
if (touch) {
|
|
9160
|
+
iState.lastTouchX = touch.clientX;
|
|
9161
|
+
iState.lastTouchY = touch.clientY;
|
|
9162
|
+
}
|
|
9163
|
+
iState.setSelectionOrigin("select.pointer");
|
|
9050
9164
|
};
|
|
9051
9165
|
observers.touchmove = view => {
|
|
9052
9166
|
view.inputState.setSelectionOrigin("select.pointer");
|
|
@@ -9282,8 +9396,7 @@
|
|
|
9282
9396
|
// spans multiple elements including this CodeMirror. The copy event may
|
|
9283
9397
|
// bubble through CodeMirror (e.g. when CodeMirror is the first or the last
|
|
9284
9398
|
// element in the selection), but we should let the parent handle it.
|
|
9285
|
-
|
|
9286
|
-
if (domSel && !hasSelection(view.contentDOM, domSel))
|
|
9399
|
+
if (!hasSelection(view.contentDOM, view.observer.selectionRange))
|
|
9287
9400
|
return false;
|
|
9288
9401
|
let { text, ranges, linewise } = copiedRange(view.state);
|
|
9289
9402
|
if (!text && !linewise)
|
|
@@ -10282,7 +10395,8 @@
|
|
|
10282
10395
|
get estimatedHeight() { return this.vertical ? this.size : -1; }
|
|
10283
10396
|
}
|
|
10284
10397
|
class ViewState {
|
|
10285
|
-
constructor(state) {
|
|
10398
|
+
constructor(view, state) {
|
|
10399
|
+
this.view = view;
|
|
10286
10400
|
this.state = state;
|
|
10287
10401
|
// These are contentDOM-local coordinates
|
|
10288
10402
|
this.pixelViewport = { left: 0, right: window.innerWidth, top: 0, bottom: 0 };
|
|
@@ -10293,12 +10407,14 @@
|
|
|
10293
10407
|
this.contentDOMHeight = 0; // contentDOM.getBoundingClientRect().height
|
|
10294
10408
|
this.editorHeight = 0; // scrollDOM.clientHeight, unscaled
|
|
10295
10409
|
this.editorWidth = 0; // scrollDOM.clientWidth, unscaled
|
|
10296
|
-
this.scrollTop = 0; // Last seen scrollDOM.scrollTop, scaled
|
|
10297
|
-
this.scrolledToBottom = false;
|
|
10298
10410
|
// The CSS-transformation scale of the editor (transformed size /
|
|
10299
10411
|
// concrete size)
|
|
10300
10412
|
this.scaleX = 1;
|
|
10301
10413
|
this.scaleY = 1;
|
|
10414
|
+
// Last seen vertical offset of the element at the top of the scroll
|
|
10415
|
+
// container, or top of the window if there's no wrapping scroller
|
|
10416
|
+
this.scrollOffset = 0;
|
|
10417
|
+
this.scrolledToBottom = false;
|
|
10302
10418
|
// The vertical position (document-relative) to which to anchor the
|
|
10303
10419
|
// scroll position. -1 means anchor to the end of the document.
|
|
10304
10420
|
this.scrollAnchorPos = 0;
|
|
@@ -10336,6 +10452,7 @@
|
|
|
10336
10452
|
this.updateViewportLines();
|
|
10337
10453
|
this.lineGaps = this.ensureLineGaps([]);
|
|
10338
10454
|
this.lineGapDeco = Decoration.set(this.lineGaps.map(gap => gap.draw(this, false)));
|
|
10455
|
+
this.scrollParent = view.scrollDOM;
|
|
10339
10456
|
this.computeVisibleRanges();
|
|
10340
10457
|
}
|
|
10341
10458
|
updateForViewport() {
|
|
@@ -10369,7 +10486,7 @@
|
|
|
10369
10486
|
let contentChanges = update.changedRanges;
|
|
10370
10487
|
let heightChanges = ChangedRange.extendWithRanges(contentChanges, heightRelevantDecoChanges(prevDeco, this.stateDeco, update ? update.changes : ChangeSet.empty(this.state.doc.length)));
|
|
10371
10488
|
let prevHeight = this.heightMap.height;
|
|
10372
|
-
let scrollAnchor = this.scrolledToBottom ? null : this.scrollAnchorAt(this.
|
|
10489
|
+
let scrollAnchor = this.scrolledToBottom ? null : this.scrollAnchorAt(this.scrollOffset);
|
|
10373
10490
|
clearHeightChangeFlag();
|
|
10374
10491
|
this.heightMap = this.heightMap.applyChanges(this.stateDeco, update.startState.doc, this.heightOracle.setDoc(this.state.doc), heightChanges);
|
|
10375
10492
|
if (this.heightMap.height != prevHeight || heightChangeFlag)
|
|
@@ -10401,12 +10518,12 @@
|
|
|
10401
10518
|
!update.state.facet(nativeSelectionHidden))
|
|
10402
10519
|
this.mustEnforceCursorAssoc = true;
|
|
10403
10520
|
}
|
|
10404
|
-
measure(
|
|
10405
|
-
let dom = view.contentDOM, style = window.getComputedStyle(dom);
|
|
10521
|
+
measure() {
|
|
10522
|
+
let { view } = this, dom = view.contentDOM, style = window.getComputedStyle(dom);
|
|
10406
10523
|
let oracle = this.heightOracle;
|
|
10407
10524
|
let whiteSpace = style.whiteSpace;
|
|
10408
10525
|
this.defaultTextDirection = style.direction == "rtl" ? Direction.RTL : Direction.LTR;
|
|
10409
|
-
let refresh = this.heightOracle.mustRefreshForWrapping(whiteSpace) || this.mustMeasureContent;
|
|
10526
|
+
let refresh = this.heightOracle.mustRefreshForWrapping(whiteSpace) || this.mustMeasureContent === "refresh";
|
|
10410
10527
|
let domRect = dom.getBoundingClientRect();
|
|
10411
10528
|
let measureContent = refresh || this.mustMeasureContent || this.contentDOMHeight != domRect.height;
|
|
10412
10529
|
this.contentDOMHeight = domRect.height;
|
|
@@ -10436,12 +10553,18 @@
|
|
|
10436
10553
|
this.editorWidth = view.scrollDOM.clientWidth;
|
|
10437
10554
|
result |= 16 /* UpdateFlag.Geometry */;
|
|
10438
10555
|
}
|
|
10439
|
-
let
|
|
10440
|
-
if (
|
|
10556
|
+
let scrollParent = scrollableParents(this.view.contentDOM, false).y;
|
|
10557
|
+
if (scrollParent != this.scrollParent) {
|
|
10558
|
+
this.scrollParent = scrollParent;
|
|
10441
10559
|
this.scrollAnchorHeight = -1;
|
|
10442
|
-
this.
|
|
10560
|
+
this.scrollOffset = 0;
|
|
10443
10561
|
}
|
|
10444
|
-
|
|
10562
|
+
let scrollOffset = this.getScrollOffset();
|
|
10563
|
+
if (this.scrollOffset != scrollOffset) {
|
|
10564
|
+
this.scrollAnchorHeight = -1;
|
|
10565
|
+
this.scrollOffset = scrollOffset;
|
|
10566
|
+
}
|
|
10567
|
+
this.scrolledToBottom = isScrolledToBottom(this.scrollParent || view.win);
|
|
10445
10568
|
// Pixel viewport
|
|
10446
10569
|
let pixelViewport = (this.printing ? fullPixelRange : visiblePixelRange)(dom, this.paddingTop);
|
|
10447
10570
|
let dTop = pixelViewport.top - this.pixelViewport.top, dBottom = pixelViewport.bottom - this.pixelViewport.bottom;
|
|
@@ -10718,9 +10841,14 @@
|
|
|
10718
10841
|
this.viewportLines.find(l => l.top <= height && l.bottom >= height)) ||
|
|
10719
10842
|
scaleBlock(this.heightMap.lineAt(this.scaler.fromDOM(height), QueryType$1.ByHeight, this.heightOracle, 0, 0), this.scaler);
|
|
10720
10843
|
}
|
|
10721
|
-
|
|
10722
|
-
let
|
|
10723
|
-
|
|
10844
|
+
getScrollOffset() {
|
|
10845
|
+
let base = this.scrollParent == this.view.scrollDOM ? this.scrollParent.scrollTop
|
|
10846
|
+
: (this.scrollParent ? this.scrollParent.getBoundingClientRect().top : 0) - this.view.contentDOM.getBoundingClientRect().top;
|
|
10847
|
+
return base * this.scaleY;
|
|
10848
|
+
}
|
|
10849
|
+
scrollAnchorAt(scrollOffset) {
|
|
10850
|
+
let block = this.lineBlockAtHeight(scrollOffset + 8);
|
|
10851
|
+
return block.from >= this.viewport.from || this.viewportLines[0].top - scrollOffset > 200 ? block : this.viewportLines[0];
|
|
10724
10852
|
}
|
|
10725
10853
|
elementAtHeight(height) {
|
|
10726
10854
|
return scaleBlock(this.heightMap.blockAt(this.scaler.fromDOM(height), this.heightOracle, 0, 0), this.scaler);
|
|
@@ -10973,6 +11101,21 @@
|
|
|
10973
11101
|
"&dark .cm-cursor": {
|
|
10974
11102
|
borderLeftColor: "#ddd"
|
|
10975
11103
|
},
|
|
11104
|
+
".cm-selectionHandle": {
|
|
11105
|
+
backgroundColor: "currentColor",
|
|
11106
|
+
width: "1.5px"
|
|
11107
|
+
},
|
|
11108
|
+
".cm-selectionHandle-start::before, .cm-selectionHandle-end::before": {
|
|
11109
|
+
content: '""',
|
|
11110
|
+
backgroundColor: "inherit",
|
|
11111
|
+
borderRadius: "50%",
|
|
11112
|
+
width: "8px",
|
|
11113
|
+
height: "8px",
|
|
11114
|
+
position: "absolute",
|
|
11115
|
+
left: "-3.25px"
|
|
11116
|
+
},
|
|
11117
|
+
".cm-selectionHandle-start::before": { top: "-8px" },
|
|
11118
|
+
".cm-selectionHandle-end::before": { bottom: "-8px" },
|
|
10976
11119
|
".cm-dropCursor": {
|
|
10977
11120
|
position: "absolute"
|
|
10978
11121
|
},
|
|
@@ -11967,7 +12110,7 @@
|
|
|
11967
12110
|
((trs) => this.update(trs));
|
|
11968
12111
|
this.dispatch = this.dispatch.bind(this);
|
|
11969
12112
|
this._root = (config.root || getRoot(config.parent) || document);
|
|
11970
|
-
this.viewState = new ViewState(config.state || EditorState.create(config));
|
|
12113
|
+
this.viewState = new ViewState(this, config.state || EditorState.create(config));
|
|
11971
12114
|
if (config.scrollTo && config.scrollTo.is(scrollIntoView$1))
|
|
11972
12115
|
this.viewState.scrollTarget = config.scrollTo.value.clip(this.viewState.state);
|
|
11973
12116
|
this.plugins = this.state.facet(viewPlugin).map(spec => new PluginInstance(spec));
|
|
@@ -11983,7 +12126,7 @@
|
|
|
11983
12126
|
this.requestMeasure();
|
|
11984
12127
|
if ((_a = document.fonts) === null || _a === void 0 ? void 0 : _a.ready)
|
|
11985
12128
|
document.fonts.ready.then(() => {
|
|
11986
|
-
this.viewState.mustMeasureContent =
|
|
12129
|
+
this.viewState.mustMeasureContent = "refresh";
|
|
11987
12130
|
this.requestMeasure();
|
|
11988
12131
|
});
|
|
11989
12132
|
}
|
|
@@ -12122,7 +12265,7 @@
|
|
|
12122
12265
|
try {
|
|
12123
12266
|
for (let plugin of this.plugins)
|
|
12124
12267
|
plugin.destroy(this);
|
|
12125
|
-
this.viewState = new ViewState(newState);
|
|
12268
|
+
this.viewState = new ViewState(this, newState);
|
|
12126
12269
|
this.plugins = newState.facet(viewPlugin).map(spec => new PluginInstance(spec));
|
|
12127
12270
|
this.pluginMap.clear();
|
|
12128
12271
|
for (let plugin of this.plugins)
|
|
@@ -12201,26 +12344,26 @@
|
|
|
12201
12344
|
if (flush)
|
|
12202
12345
|
this.observer.forceFlush();
|
|
12203
12346
|
let updated = null;
|
|
12204
|
-
let
|
|
12347
|
+
let scroll = this.viewState.scrollParent, scrollOffset = this.viewState.getScrollOffset();
|
|
12205
12348
|
let { scrollAnchorPos, scrollAnchorHeight } = this.viewState;
|
|
12206
|
-
if (Math.abs(
|
|
12349
|
+
if (Math.abs(scrollOffset - this.viewState.scrollOffset) > 1)
|
|
12207
12350
|
scrollAnchorHeight = -1;
|
|
12208
12351
|
this.viewState.scrollAnchorHeight = -1;
|
|
12209
12352
|
try {
|
|
12210
12353
|
for (let i = 0;; i++) {
|
|
12211
12354
|
if (scrollAnchorHeight < 0) {
|
|
12212
|
-
if (isScrolledToBottom(
|
|
12355
|
+
if (isScrolledToBottom(scroll || this.win)) {
|
|
12213
12356
|
scrollAnchorPos = -1;
|
|
12214
12357
|
scrollAnchorHeight = this.viewState.heightMap.height;
|
|
12215
12358
|
}
|
|
12216
12359
|
else {
|
|
12217
|
-
let block = this.viewState.scrollAnchorAt(
|
|
12360
|
+
let block = this.viewState.scrollAnchorAt(scrollOffset);
|
|
12218
12361
|
scrollAnchorPos = block.from;
|
|
12219
12362
|
scrollAnchorHeight = block.top;
|
|
12220
12363
|
}
|
|
12221
12364
|
}
|
|
12222
12365
|
this.updateState = 1 /* UpdateState.Measuring */;
|
|
12223
|
-
let changed = this.viewState.measure(
|
|
12366
|
+
let changed = this.viewState.measure();
|
|
12224
12367
|
if (!changed && !this.measureRequests.length && this.viewState.scrollTarget == null)
|
|
12225
12368
|
break;
|
|
12226
12369
|
if (i > 5) {
|
|
@@ -12281,10 +12424,15 @@
|
|
|
12281
12424
|
else {
|
|
12282
12425
|
let newAnchorHeight = scrollAnchorPos < 0 ? this.viewState.heightMap.height :
|
|
12283
12426
|
this.viewState.lineBlockAt(scrollAnchorPos).top;
|
|
12284
|
-
let diff = newAnchorHeight - scrollAnchorHeight;
|
|
12285
|
-
if (diff > 1 || diff < -1)
|
|
12286
|
-
|
|
12287
|
-
|
|
12427
|
+
let diff = (newAnchorHeight - scrollAnchorHeight) / this.scaleY;
|
|
12428
|
+
if ((diff > 1 || diff < -1) &&
|
|
12429
|
+
(scroll == this.scrollDOM || this.hasFocus ||
|
|
12430
|
+
Math.max(this.inputState.lastWheelEvent, this.inputState.lastTouchTime) > Date.now() - 100)) {
|
|
12431
|
+
scrollOffset = scrollOffset + diff;
|
|
12432
|
+
if (scroll)
|
|
12433
|
+
scroll.scrollTop += diff;
|
|
12434
|
+
else
|
|
12435
|
+
this.win.scrollBy(0, diff);
|
|
12288
12436
|
scrollAnchorHeight = -1;
|
|
12289
12437
|
continue;
|
|
12290
12438
|
}
|
|
@@ -13532,7 +13680,8 @@
|
|
|
13532
13680
|
combine(configs) {
|
|
13533
13681
|
return combineConfig(configs, {
|
|
13534
13682
|
cursorBlinkRate: 1200,
|
|
13535
|
-
drawRangeCursor: true
|
|
13683
|
+
drawRangeCursor: true,
|
|
13684
|
+
iosSelectionHandles: true
|
|
13536
13685
|
}, {
|
|
13537
13686
|
cursorBlinkRate: (a, b) => Math.min(a, b),
|
|
13538
13687
|
drawRangeCursor: (a, b) => a || b
|
|
@@ -13576,7 +13725,7 @@
|
|
|
13576
13725
|
let cursors = [];
|
|
13577
13726
|
for (let r of state.selection.ranges) {
|
|
13578
13727
|
let prim = r == state.selection.main;
|
|
13579
|
-
if (r.empty || conf.drawRangeCursor) {
|
|
13728
|
+
if (r.empty || conf.drawRangeCursor && !(prim && browser.ios && conf.iosSelectionHandles)) {
|
|
13580
13729
|
let className = prim ? "cm-cursor cm-cursor-primary" : "cm-cursor cm-cursor-secondary";
|
|
13581
13730
|
let cursor = r.empty ? r : EditorSelection.cursor(r.head, r.head > r.anchor ? -1 : 1);
|
|
13582
13731
|
for (let piece of RectangleMarker.forRange(view, className, cursor))
|
|
@@ -13604,8 +13753,19 @@
|
|
|
13604
13753
|
const selectionLayer = /*@__PURE__*/layer({
|
|
13605
13754
|
above: false,
|
|
13606
13755
|
markers(view) {
|
|
13607
|
-
|
|
13608
|
-
|
|
13756
|
+
let markers = [], { main, ranges } = view.state.selection;
|
|
13757
|
+
for (let r of ranges)
|
|
13758
|
+
if (!r.empty) {
|
|
13759
|
+
for (let marker of RectangleMarker.forRange(view, "cm-selectionBackground", r))
|
|
13760
|
+
markers.push(marker);
|
|
13761
|
+
}
|
|
13762
|
+
if (browser.ios && !main.empty && view.state.facet(selectionConfig).iosSelectionHandles) {
|
|
13763
|
+
for (let piece of RectangleMarker.forRange(view, "cm-selectionHandle cm-selectionHandle-start", EditorSelection.cursor(main.from, 1)))
|
|
13764
|
+
markers.push(piece);
|
|
13765
|
+
for (let piece of RectangleMarker.forRange(view, "cm-selectionHandle cm-selectionHandle-end", EditorSelection.cursor(main.to, 1)))
|
|
13766
|
+
markers.push(piece);
|
|
13767
|
+
}
|
|
13768
|
+
return markers;
|
|
13609
13769
|
},
|
|
13610
13770
|
update(update, dom) {
|
|
13611
13771
|
return update.docChanged || update.selectionSet || update.viewportChanged || configChanged(update);
|
|
@@ -19937,30 +20097,44 @@
|
|
|
19937
20097
|
decorations.push(mark.range(match.end.from, match.end.to));
|
|
19938
20098
|
return decorations;
|
|
19939
20099
|
}
|
|
19940
|
-
|
|
19941
|
-
|
|
19942
|
-
|
|
19943
|
-
|
|
19944
|
-
|
|
19945
|
-
|
|
19946
|
-
let
|
|
19947
|
-
|
|
19948
|
-
|
|
19949
|
-
|
|
19950
|
-
|
|
19951
|
-
|
|
19952
|
-
|
|
19953
|
-
|
|
19954
|
-
|
|
19955
|
-
|
|
19956
|
-
|
|
19957
|
-
|
|
19958
|
-
|
|
19959
|
-
|
|
19960
|
-
|
|
20100
|
+
function bracketDeco(state) {
|
|
20101
|
+
let decorations = [];
|
|
20102
|
+
let config = state.facet(bracketMatchingConfig);
|
|
20103
|
+
for (let range of state.selection.ranges) {
|
|
20104
|
+
if (!range.empty)
|
|
20105
|
+
continue;
|
|
20106
|
+
let match = matchBrackets(state, range.head, -1, config)
|
|
20107
|
+
|| (range.head > 0 && matchBrackets(state, range.head - 1, 1, config))
|
|
20108
|
+
|| (config.afterCursor &&
|
|
20109
|
+
(matchBrackets(state, range.head, 1, config) ||
|
|
20110
|
+
(range.head < state.doc.length && matchBrackets(state, range.head + 1, -1, config))));
|
|
20111
|
+
if (match)
|
|
20112
|
+
decorations = decorations.concat(config.renderMatch(match, state));
|
|
20113
|
+
}
|
|
20114
|
+
return Decoration.set(decorations, true);
|
|
20115
|
+
}
|
|
20116
|
+
const bracketMatcher = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
20117
|
+
constructor(view) {
|
|
20118
|
+
this.paused = false;
|
|
20119
|
+
this.decorations = bracketDeco(view.state);
|
|
20120
|
+
}
|
|
20121
|
+
update(update) {
|
|
20122
|
+
if (update.docChanged || update.selectionSet || this.paused) {
|
|
20123
|
+
if (update.view.composing) {
|
|
20124
|
+
this.decorations = this.decorations.map(update.changes);
|
|
20125
|
+
this.paused = true;
|
|
20126
|
+
}
|
|
20127
|
+
else {
|
|
20128
|
+
this.decorations = bracketDeco(update.state);
|
|
20129
|
+
this.paused = false;
|
|
20130
|
+
}
|
|
20131
|
+
}
|
|
20132
|
+
}
|
|
20133
|
+
}, {
|
|
20134
|
+
decorations: v => v.decorations
|
|
19961
20135
|
});
|
|
19962
20136
|
const bracketMatchingUnique = [
|
|
19963
|
-
|
|
20137
|
+
bracketMatcher,
|
|
19964
20138
|
baseTheme$3
|
|
19965
20139
|
];
|
|
19966
20140
|
/**
|
|
@@ -23231,6 +23405,7 @@
|
|
|
23231
23405
|
};
|
|
23232
23406
|
}
|
|
23233
23407
|
|
|
23408
|
+
const setSelectedEffect = /*@__PURE__*/StateEffect.define();
|
|
23234
23409
|
function optionContent(config) {
|
|
23235
23410
|
let content = config.addToOptions.slice();
|
|
23236
23411
|
if (config.icons)
|
|
@@ -23322,6 +23497,16 @@
|
|
|
23322
23497
|
return;
|
|
23323
23498
|
}
|
|
23324
23499
|
}
|
|
23500
|
+
if (e.target == this.list) {
|
|
23501
|
+
let move = this.list.classList.contains("cm-completionListIncompleteTop") &&
|
|
23502
|
+
e.clientY < this.list.firstChild.getBoundingClientRect().top ? this.range.from - 1 :
|
|
23503
|
+
this.list.classList.contains("cm-completionListIncompleteBottom") &&
|
|
23504
|
+
e.clientY > this.list.lastChild.getBoundingClientRect().bottom ? this.range.to : null;
|
|
23505
|
+
if (move != null) {
|
|
23506
|
+
view.dispatch({ effects: setSelectedEffect.of(move) });
|
|
23507
|
+
e.preventDefault();
|
|
23508
|
+
}
|
|
23509
|
+
}
|
|
23325
23510
|
});
|
|
23326
23511
|
this.dom.addEventListener("focusout", (e) => {
|
|
23327
23512
|
let state = view.state.field(this.stateField, false);
|
|
@@ -23823,7 +24008,6 @@
|
|
|
23823
24008
|
const setActiveEffect = /*@__PURE__*/StateEffect.define({
|
|
23824
24009
|
map(sources, mapping) { return sources.map(s => s.map(mapping)); }
|
|
23825
24010
|
});
|
|
23826
|
-
const setSelectedEffect = /*@__PURE__*/StateEffect.define();
|
|
23827
24011
|
const completionState = /*@__PURE__*/StateField.define({
|
|
23828
24012
|
create() { return CompletionState.start(); },
|
|
23829
24013
|
update(value, tr) { return value.update(tr); },
|
|
@@ -24978,10 +25162,10 @@
|
|
|
24978
25162
|
let field = view.state.field(lintState, false);
|
|
24979
25163
|
if (!field)
|
|
24980
25164
|
return false;
|
|
24981
|
-
let sel = view.state.selection.main, next = field.diagnostics
|
|
24982
|
-
if (!next
|
|
24983
|
-
next = field.diagnostics
|
|
24984
|
-
if (!next
|
|
25165
|
+
let sel = view.state.selection.main, next = findDiagnostic(field.diagnostics, null, sel.to + 1);
|
|
25166
|
+
if (!next) {
|
|
25167
|
+
next = findDiagnostic(field.diagnostics, null, 0);
|
|
25168
|
+
if (!next || next.from == sel.from && next.to == sel.to)
|
|
24985
25169
|
return false;
|
|
24986
25170
|
}
|
|
24987
25171
|
view.dispatch({ selection: { anchor: next.from, head: next.to }, scrollIntoView: true });
|
|
@@ -25353,6 +25537,12 @@
|
|
|
25353
25537
|
padding: 0,
|
|
25354
25538
|
margin: 0
|
|
25355
25539
|
}
|
|
25540
|
+
},
|
|
25541
|
+
"&dark .cm-lintRange-active": { backgroundColor: "#86714a80" },
|
|
25542
|
+
"&dark .cm-panel.cm-panel-lint ul": {
|
|
25543
|
+
"& [aria-selected]": {
|
|
25544
|
+
backgroundColor: "#2e343e",
|
|
25545
|
+
},
|
|
25356
25546
|
}
|
|
25357
25547
|
});
|
|
25358
25548
|
function severityWeight(sev) {
|
|
@@ -27725,7 +27915,21 @@
|
|
|
27725
27915
|
}),
|
|
27726
27916
|
/*@__PURE__*/foldNodeProp.add({
|
|
27727
27917
|
"Block ClassBody SwitchBody EnumBody ObjectExpression ArrayExpression ObjectType": foldInside,
|
|
27728
|
-
BlockComment(tree) { return { from: tree.from + 2, to: tree.to - 2 }; }
|
|
27918
|
+
BlockComment(tree) { return { from: tree.from + 2, to: tree.to - 2 }; },
|
|
27919
|
+
JSXElement(tree) {
|
|
27920
|
+
let open = tree.firstChild;
|
|
27921
|
+
if (!open || open.name == "JSXSelfClosingTag")
|
|
27922
|
+
return null;
|
|
27923
|
+
let close = tree.lastChild;
|
|
27924
|
+
return { from: open.to, to: close.type.isError ? tree.to : close.from };
|
|
27925
|
+
},
|
|
27926
|
+
"JSXSelfClosingTag JSXOpenTag"(tree) {
|
|
27927
|
+
var _a;
|
|
27928
|
+
let name = (_a = tree.firstChild) === null || _a === void 0 ? void 0 : _a.nextSibling, close = tree.lastChild;
|
|
27929
|
+
if (!name || name.type.isError)
|
|
27930
|
+
return null;
|
|
27931
|
+
return { from: name.to, to: close.type.isError ? tree.to : close.from };
|
|
27932
|
+
}
|
|
27729
27933
|
})
|
|
27730
27934
|
]
|
|
27731
27935
|
}),
|