@codemirror/view 6.3.1 → 6.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/dist/index.cjs +75 -63
- package/dist/index.d.ts +5 -0
- package/dist/index.js +75 -63
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
## 6.4.1 (2022-11-07)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Fix an issue where coordinates next to replaced widgets were returned incorrectly, causing the cursor to be drawn in the wrong place.
|
|
6
|
+
|
|
7
|
+
Update the `crosshairCursor` state on every mousemove event.
|
|
8
|
+
|
|
9
|
+
Avoid an issue in the way that the editor enforces cursor associativity that could cause the cursor to get stuck on single-character wrapped lines.
|
|
10
|
+
|
|
11
|
+
## 6.4.0 (2022-10-18)
|
|
12
|
+
|
|
13
|
+
### Bug fixes
|
|
14
|
+
|
|
15
|
+
Avoid an issue where `scrollPastEnd` makes a single-line editor have a vertical scrollbar.
|
|
16
|
+
|
|
17
|
+
Work around a Chrome bug where it inserts a newline when you press space at the start of a wrapped line.
|
|
18
|
+
|
|
19
|
+
Align `rectangularSelection`'s behavior with other popular editors by making it create cursors at the end of lines that are too short to touch the rectangle.
|
|
20
|
+
|
|
21
|
+
Fix an issue where coordinates on mark decoration boundaries were sometimes taken from the wrong side of the position.
|
|
22
|
+
|
|
23
|
+
Prevent scrolling artifacts caused by attempts to scroll stuff into view when the editor isn't being displayed.
|
|
24
|
+
|
|
25
|
+
### New features
|
|
26
|
+
|
|
27
|
+
`TooltipView` objects can now provide a `destroy` method to be called when the tooltip is removed.
|
|
28
|
+
|
|
1
29
|
## 6.3.1 (2022-10-10)
|
|
2
30
|
|
|
3
31
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -875,7 +875,7 @@ class WidgetView extends ContentView {
|
|
|
875
875
|
if (pos > 0 ? i == 0 : i == rects.length - 1 || rect.top < rect.bottom)
|
|
876
876
|
break;
|
|
877
877
|
}
|
|
878
|
-
return flattenRect(rect, this.side > 0);
|
|
878
|
+
return this.length ? rect : flattenRect(rect, this.side > 0);
|
|
879
879
|
}
|
|
880
880
|
get isEditable() { return false; }
|
|
881
881
|
destroy() {
|
|
@@ -1054,57 +1054,31 @@ function joinInlineInto(parent, view, open) {
|
|
|
1054
1054
|
parent.length += view.length;
|
|
1055
1055
|
}
|
|
1056
1056
|
function coordsInChildren(view, pos, side) {
|
|
1057
|
-
|
|
1058
|
-
return fallbackRect(view);
|
|
1059
|
-
return (side <= 0 ? coordsInChildrenBefore : coordsInChildrenAfter)(view, pos);
|
|
1060
|
-
}
|
|
1061
|
-
function coordsInChildrenBefore(view, pos) {
|
|
1062
|
-
// Find the last leaf in the tree that touches pos and doesn't have getSide() > 0
|
|
1063
|
-
let found = null, foundPos = -1;
|
|
1057
|
+
let before = null, beforePos = -1, after = null, afterPos = -1;
|
|
1064
1058
|
function scan(view, pos) {
|
|
1065
1059
|
for (let i = 0, off = 0; i < view.children.length && off <= pos; i++) {
|
|
1066
1060
|
let child = view.children[i], end = off + child.length;
|
|
1067
1061
|
if (end >= pos) {
|
|
1068
1062
|
if (child.children.length) {
|
|
1069
|
-
|
|
1070
|
-
return true;
|
|
1063
|
+
scan(child, pos - off);
|
|
1071
1064
|
}
|
|
1072
|
-
else if (end
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
found = child;
|
|
1076
|
-
foundPos = pos - off;
|
|
1065
|
+
else if (!after && (end > pos || off == end && child.getSide() > 0)) {
|
|
1066
|
+
after = child;
|
|
1067
|
+
afterPos = pos - off;
|
|
1077
1068
|
}
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
}
|
|
1082
|
-
scan(view, pos);
|
|
1083
|
-
return found ? found.coordsAt(Math.max(0, foundPos), -1) : coordsInChildrenAfter(view, pos);
|
|
1084
|
-
}
|
|
1085
|
-
function coordsInChildrenAfter(view, pos) {
|
|
1086
|
-
// Find the first leaf in the tree that touches pos and doesn't have getSide() < 0
|
|
1087
|
-
let found = null, foundPos = -1;
|
|
1088
|
-
function scan(view, pos) {
|
|
1089
|
-
for (let i = view.children.length - 1, off = view.length; i >= 0 && off >= pos; i--) {
|
|
1090
|
-
let child = view.children[i];
|
|
1091
|
-
off -= child.length;
|
|
1092
|
-
if (off <= pos) {
|
|
1093
|
-
if (child.children.length) {
|
|
1094
|
-
if (scan(child, pos - off))
|
|
1095
|
-
return true;
|
|
1096
|
-
}
|
|
1097
|
-
else if (off <= pos) {
|
|
1098
|
-
if (off == pos && child.getSide() < 0)
|
|
1099
|
-
return true;
|
|
1100
|
-
found = child;
|
|
1101
|
-
foundPos = pos - off;
|
|
1069
|
+
else if (off < pos || (off == end && child.getSide() < 0)) {
|
|
1070
|
+
before = child;
|
|
1071
|
+
beforePos = pos - off;
|
|
1102
1072
|
}
|
|
1103
1073
|
}
|
|
1074
|
+
off = end;
|
|
1104
1075
|
}
|
|
1105
1076
|
}
|
|
1106
1077
|
scan(view, pos);
|
|
1107
|
-
|
|
1078
|
+
let target = (side < 0 ? before : after) || before || after;
|
|
1079
|
+
if (target)
|
|
1080
|
+
return target.coordsAt(Math.max(0, target == before ? beforePos : afterPos), side);
|
|
1081
|
+
return fallbackRect(view);
|
|
1108
1082
|
}
|
|
1109
1083
|
function fallbackRect(view) {
|
|
1110
1084
|
let last = view.dom.lastChild;
|
|
@@ -1792,6 +1766,9 @@ const inputHandler = state.Facet.define();
|
|
|
1792
1766
|
const perLineTextDirection = state.Facet.define({
|
|
1793
1767
|
combine: values => values.some(x => x)
|
|
1794
1768
|
});
|
|
1769
|
+
const nativeSelectionHidden = state.Facet.define({
|
|
1770
|
+
combine: values => values.some(x => x)
|
|
1771
|
+
});
|
|
1795
1772
|
class ScrollTarget {
|
|
1796
1773
|
constructor(range, y = "nearest", x = "nearest", yMargin = 5, xMargin = 5) {
|
|
1797
1774
|
this.range = range;
|
|
@@ -2705,8 +2682,9 @@ class DocView extends ContentView {
|
|
|
2705
2682
|
enforceCursorAssoc() {
|
|
2706
2683
|
if (this.compositionDeco.size)
|
|
2707
2684
|
return;
|
|
2708
|
-
let cursor =
|
|
2709
|
-
let sel = getSelection(
|
|
2685
|
+
let { view } = this, cursor = view.state.selection.main;
|
|
2686
|
+
let sel = getSelection(view.root);
|
|
2687
|
+
let { anchorNode, anchorOffset } = view.observer.selectionRange;
|
|
2710
2688
|
if (!sel || !cursor.empty || !cursor.assoc || !sel.modify)
|
|
2711
2689
|
return;
|
|
2712
2690
|
let line = LineView.find(this, cursor.head);
|
|
@@ -2721,6 +2699,12 @@ class DocView extends ContentView {
|
|
|
2721
2699
|
let dom = this.domAtPos(cursor.head + cursor.assoc);
|
|
2722
2700
|
sel.collapse(dom.node, dom.offset);
|
|
2723
2701
|
sel.modify("move", cursor.assoc < 0 ? "forward" : "backward", "lineboundary");
|
|
2702
|
+
// This can go wrong in corner cases like single-character lines,
|
|
2703
|
+
// so check and reset if necessary.
|
|
2704
|
+
view.observer.readSelectionRange();
|
|
2705
|
+
let newRange = view.observer.selectionRange;
|
|
2706
|
+
if (view.docView.posFromDOM(newRange.anchorNode, newRange.anchorOffset) != cursor.from)
|
|
2707
|
+
sel.collapse(anchorNode, anchorOffset);
|
|
2724
2708
|
}
|
|
2725
2709
|
mayControlSelection() {
|
|
2726
2710
|
let active = this.view.root.activeElement;
|
|
@@ -4805,7 +4789,7 @@ class ViewState {
|
|
|
4805
4789
|
// Flag set when editor content was redrawn, so that the next
|
|
4806
4790
|
// measure stage knows it must read DOM layout
|
|
4807
4791
|
this.mustMeasureContent = true;
|
|
4808
|
-
this.defaultTextDirection = exports.Direction.
|
|
4792
|
+
this.defaultTextDirection = exports.Direction.LTR;
|
|
4809
4793
|
this.visibleRanges = [];
|
|
4810
4794
|
// Cursor 'assoc' is only significant when the cursor is on a line
|
|
4811
4795
|
// wrap point, where it must stick to the character that it is
|
|
@@ -4870,7 +4854,8 @@ class ViewState {
|
|
|
4870
4854
|
if (scrollTarget)
|
|
4871
4855
|
this.scrollTarget = scrollTarget;
|
|
4872
4856
|
if (!this.mustEnforceCursorAssoc && update.selectionSet && update.view.lineWrapping &&
|
|
4873
|
-
update.state.selection.main.empty && update.state.selection.main.assoc
|
|
4857
|
+
update.state.selection.main.empty && update.state.selection.main.assoc &&
|
|
4858
|
+
!update.state.facet(nativeSelectionHidden))
|
|
4874
4859
|
this.mustEnforceCursorAssoc = true;
|
|
4875
4860
|
}
|
|
4876
4861
|
measure(view) {
|
|
@@ -4933,7 +4918,9 @@ class ViewState {
|
|
|
4933
4918
|
oracle.heightChanged = false;
|
|
4934
4919
|
for (let vp of this.viewports) {
|
|
4935
4920
|
let heights = vp.from == this.viewport.from ? lineHeights : view.docView.measureVisibleLineHeights(vp);
|
|
4936
|
-
this.heightMap =
|
|
4921
|
+
this.heightMap = refresh
|
|
4922
|
+
? HeightMap.empty().applyChanges(this.stateDeco, state.Text.empty, this.heightOracle, [new ChangedRange(0, 0, 0, view.state.doc.length)])
|
|
4923
|
+
: this.heightMap.updateHeight(oracle, 0, refresh, new MeasuredHeights(vp.from, heights));
|
|
4937
4924
|
}
|
|
4938
4925
|
if (oracle.heightChanged)
|
|
4939
4926
|
result |= 2 /* UpdateFlag.Height */;
|
|
@@ -5572,6 +5559,15 @@ function applyDOMChange(view, domChange) {
|
|
|
5572
5559
|
newSel = state.EditorSelection.single(newSel.main.anchor - 1, newSel.main.head - 1);
|
|
5573
5560
|
change = { from: sel.from, to: sel.to, insert: state.Text.of([" "]) };
|
|
5574
5561
|
}
|
|
5562
|
+
else if (browser.chrome && change && change.from == change.to && change.from == sel.head &&
|
|
5563
|
+
change.insert.toString() == "\n " && view.lineWrapping) {
|
|
5564
|
+
// In Chrome, if you insert a space at the start of a wrapped
|
|
5565
|
+
// line, it will actually insert a newline and a space, causing a
|
|
5566
|
+
// bogus new line to be created in CodeMirror (#968)
|
|
5567
|
+
if (newSel)
|
|
5568
|
+
newSel = state.EditorSelection.single(newSel.main.anchor - 1, newSel.main.head - 1);
|
|
5569
|
+
change = { from: sel.from, to: sel.to, insert: state.Text.of([" "]) };
|
|
5570
|
+
}
|
|
5575
5571
|
if (change) {
|
|
5576
5572
|
let startState = view.state;
|
|
5577
5573
|
if (browser.ios && view.inputState.flushIOSKey(view))
|
|
@@ -5784,7 +5780,8 @@ class DOMObserver {
|
|
|
5784
5780
|
this.onScroll = this.onScroll.bind(this);
|
|
5785
5781
|
if (typeof ResizeObserver == "function") {
|
|
5786
5782
|
this.resize = new ResizeObserver(() => {
|
|
5787
|
-
|
|
5783
|
+
var _a;
|
|
5784
|
+
if (((_a = this.view.docView) === null || _a === void 0 ? void 0 : _a.lastUpdate) < Date.now() - 75)
|
|
5788
5785
|
this.onResize();
|
|
5789
5786
|
});
|
|
5790
5787
|
this.resize.observe(view.scrollDOM);
|
|
@@ -6496,17 +6493,19 @@ class EditorView {
|
|
|
6496
6493
|
logException(this.state, e);
|
|
6497
6494
|
}
|
|
6498
6495
|
}
|
|
6499
|
-
if (this.viewState.
|
|
6500
|
-
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
}
|
|
6504
|
-
else {
|
|
6505
|
-
let diff = this.viewState.lineBlockAt(refBlock.from).top - refBlock.top;
|
|
6506
|
-
if (diff > 1 || diff < -1) {
|
|
6507
|
-
this.scrollDOM.scrollTop += diff;
|
|
6496
|
+
if (this.viewState.editorHeight) {
|
|
6497
|
+
if (this.viewState.scrollTarget) {
|
|
6498
|
+
this.docView.scrollIntoView(this.viewState.scrollTarget);
|
|
6499
|
+
this.viewState.scrollTarget = null;
|
|
6508
6500
|
scrolled = true;
|
|
6509
6501
|
}
|
|
6502
|
+
else {
|
|
6503
|
+
let diff = this.viewState.lineBlockAt(refBlock.from).top - refBlock.top;
|
|
6504
|
+
if (diff > 1 || diff < -1) {
|
|
6505
|
+
this.scrollDOM.scrollTop += diff;
|
|
6506
|
+
scrolled = true;
|
|
6507
|
+
}
|
|
6508
|
+
}
|
|
6510
6509
|
}
|
|
6511
6510
|
if (redrawn)
|
|
6512
6511
|
this.docView.updateSelection(true);
|
|
@@ -7326,7 +7325,8 @@ function drawSelection(config = {}) {
|
|
|
7326
7325
|
return [
|
|
7327
7326
|
selectionConfig.of(config),
|
|
7328
7327
|
drawSelectionPlugin,
|
|
7329
|
-
hideNativeSelection
|
|
7328
|
+
hideNativeSelection,
|
|
7329
|
+
nativeSelectionHidden.of(true)
|
|
7330
7330
|
];
|
|
7331
7331
|
}
|
|
7332
7332
|
class Piece {
|
|
@@ -7912,7 +7912,8 @@ const plugin = ViewPlugin.fromClass(class {
|
|
|
7912
7912
|
this.attrs = { style: "padding-bottom: 1000px" };
|
|
7913
7913
|
}
|
|
7914
7914
|
update(update) {
|
|
7915
|
-
let
|
|
7915
|
+
let { view } = update;
|
|
7916
|
+
let height = view.viewState.editorHeight - view.defaultLineHeight - view.documentPadding.top - 0.5;
|
|
7916
7917
|
if (height != this.height) {
|
|
7917
7918
|
this.height = height;
|
|
7918
7919
|
this.attrs = { style: `padding-bottom: ${height}px` };
|
|
@@ -8014,7 +8015,10 @@ function rectangleFor(state$1, a, b) {
|
|
|
8014
8015
|
for (let i = startLine; i <= endLine; i++) {
|
|
8015
8016
|
let line = state$1.doc.line(i);
|
|
8016
8017
|
let start = state.findColumn(line.text, startCol, state$1.tabSize, true);
|
|
8017
|
-
if (start
|
|
8018
|
+
if (start < 0) {
|
|
8019
|
+
ranges.push(state.EditorSelection.cursor(line.to));
|
|
8020
|
+
}
|
|
8021
|
+
else {
|
|
8018
8022
|
let end = state.findColumn(line.text, endCol, state$1.tabSize);
|
|
8019
8023
|
ranges.push(state.EditorSelection.range(line.from + start, line.from + end));
|
|
8020
8024
|
}
|
|
@@ -8107,6 +8111,9 @@ function crosshairCursor(options = {}) {
|
|
|
8107
8111
|
keyup(e) {
|
|
8108
8112
|
if (e.keyCode == code || !getter(e))
|
|
8109
8113
|
this.set(false);
|
|
8114
|
+
},
|
|
8115
|
+
mousemove(e) {
|
|
8116
|
+
this.set(getter(e));
|
|
8110
8117
|
}
|
|
8111
8118
|
}
|
|
8112
8119
|
});
|
|
@@ -8126,6 +8133,7 @@ class TooltipViewManager {
|
|
|
8126
8133
|
this.tooltipViews = this.tooltips.map(createTooltipView);
|
|
8127
8134
|
}
|
|
8128
8135
|
update(update) {
|
|
8136
|
+
var _a;
|
|
8129
8137
|
let input = update.state.facet(this.facet);
|
|
8130
8138
|
let tooltips = input.filter(x => x);
|
|
8131
8139
|
if (input === this.input) {
|
|
@@ -8154,8 +8162,10 @@ class TooltipViewManager {
|
|
|
8154
8162
|
}
|
|
8155
8163
|
}
|
|
8156
8164
|
for (let t of this.tooltipViews)
|
|
8157
|
-
if (tooltipViews.indexOf(t) < 0)
|
|
8165
|
+
if (tooltipViews.indexOf(t) < 0) {
|
|
8158
8166
|
t.dom.remove();
|
|
8167
|
+
(_a = t.destroy) === null || _a === void 0 ? void 0 : _a.call(t);
|
|
8168
|
+
}
|
|
8159
8169
|
this.input = input;
|
|
8160
8170
|
this.tooltips = tooltips;
|
|
8161
8171
|
this.tooltipViews = tooltipViews;
|
|
@@ -8274,11 +8284,13 @@ const tooltipPlugin = ViewPlugin.fromClass(class {
|
|
|
8274
8284
|
return tooltipView;
|
|
8275
8285
|
}
|
|
8276
8286
|
destroy() {
|
|
8277
|
-
var _a;
|
|
8287
|
+
var _a, _b;
|
|
8278
8288
|
this.view.win.removeEventListener("resize", this.measureSoon);
|
|
8279
|
-
for (let
|
|
8280
|
-
dom.remove();
|
|
8281
|
-
|
|
8289
|
+
for (let tooltipView of this.manager.tooltipViews) {
|
|
8290
|
+
tooltipView.dom.remove();
|
|
8291
|
+
(_a = tooltipView.destroy) === null || _a === void 0 ? void 0 : _a.call(tooltipView);
|
|
8292
|
+
}
|
|
8293
|
+
(_b = this.intersectionObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
|
|
8282
8294
|
clearTimeout(this.measureTimeout);
|
|
8283
8295
|
}
|
|
8284
8296
|
readMeasure() {
|
package/dist/index.d.ts
CHANGED
|
@@ -1579,6 +1579,11 @@ interface TooltipView {
|
|
|
1579
1579
|
*/
|
|
1580
1580
|
update?(update: ViewUpdate): void;
|
|
1581
1581
|
/**
|
|
1582
|
+
Called when the tooltip is removed from the editor or the editor
|
|
1583
|
+
is destroyed.
|
|
1584
|
+
*/
|
|
1585
|
+
destroy?(): void;
|
|
1586
|
+
/**
|
|
1582
1587
|
Called when the tooltip has been (re)positioned.
|
|
1583
1588
|
*/
|
|
1584
1589
|
positioned?(): void;
|
package/dist/index.js
CHANGED
|
@@ -871,7 +871,7 @@ class WidgetView extends ContentView {
|
|
|
871
871
|
if (pos > 0 ? i == 0 : i == rects.length - 1 || rect.top < rect.bottom)
|
|
872
872
|
break;
|
|
873
873
|
}
|
|
874
|
-
return flattenRect(rect, this.side > 0);
|
|
874
|
+
return this.length ? rect : flattenRect(rect, this.side > 0);
|
|
875
875
|
}
|
|
876
876
|
get isEditable() { return false; }
|
|
877
877
|
destroy() {
|
|
@@ -1050,57 +1050,31 @@ function joinInlineInto(parent, view, open) {
|
|
|
1050
1050
|
parent.length += view.length;
|
|
1051
1051
|
}
|
|
1052
1052
|
function coordsInChildren(view, pos, side) {
|
|
1053
|
-
|
|
1054
|
-
return fallbackRect(view);
|
|
1055
|
-
return (side <= 0 ? coordsInChildrenBefore : coordsInChildrenAfter)(view, pos);
|
|
1056
|
-
}
|
|
1057
|
-
function coordsInChildrenBefore(view, pos) {
|
|
1058
|
-
// Find the last leaf in the tree that touches pos and doesn't have getSide() > 0
|
|
1059
|
-
let found = null, foundPos = -1;
|
|
1053
|
+
let before = null, beforePos = -1, after = null, afterPos = -1;
|
|
1060
1054
|
function scan(view, pos) {
|
|
1061
1055
|
for (let i = 0, off = 0; i < view.children.length && off <= pos; i++) {
|
|
1062
1056
|
let child = view.children[i], end = off + child.length;
|
|
1063
1057
|
if (end >= pos) {
|
|
1064
1058
|
if (child.children.length) {
|
|
1065
|
-
|
|
1066
|
-
return true;
|
|
1059
|
+
scan(child, pos - off);
|
|
1067
1060
|
}
|
|
1068
|
-
else if (end
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
found = child;
|
|
1072
|
-
foundPos = pos - off;
|
|
1061
|
+
else if (!after && (end > pos || off == end && child.getSide() > 0)) {
|
|
1062
|
+
after = child;
|
|
1063
|
+
afterPos = pos - off;
|
|
1073
1064
|
}
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
}
|
|
1078
|
-
scan(view, pos);
|
|
1079
|
-
return found ? found.coordsAt(Math.max(0, foundPos), -1) : coordsInChildrenAfter(view, pos);
|
|
1080
|
-
}
|
|
1081
|
-
function coordsInChildrenAfter(view, pos) {
|
|
1082
|
-
// Find the first leaf in the tree that touches pos and doesn't have getSide() < 0
|
|
1083
|
-
let found = null, foundPos = -1;
|
|
1084
|
-
function scan(view, pos) {
|
|
1085
|
-
for (let i = view.children.length - 1, off = view.length; i >= 0 && off >= pos; i--) {
|
|
1086
|
-
let child = view.children[i];
|
|
1087
|
-
off -= child.length;
|
|
1088
|
-
if (off <= pos) {
|
|
1089
|
-
if (child.children.length) {
|
|
1090
|
-
if (scan(child, pos - off))
|
|
1091
|
-
return true;
|
|
1092
|
-
}
|
|
1093
|
-
else if (off <= pos) {
|
|
1094
|
-
if (off == pos && child.getSide() < 0)
|
|
1095
|
-
return true;
|
|
1096
|
-
found = child;
|
|
1097
|
-
foundPos = pos - off;
|
|
1065
|
+
else if (off < pos || (off == end && child.getSide() < 0)) {
|
|
1066
|
+
before = child;
|
|
1067
|
+
beforePos = pos - off;
|
|
1098
1068
|
}
|
|
1099
1069
|
}
|
|
1070
|
+
off = end;
|
|
1100
1071
|
}
|
|
1101
1072
|
}
|
|
1102
1073
|
scan(view, pos);
|
|
1103
|
-
|
|
1074
|
+
let target = (side < 0 ? before : after) || before || after;
|
|
1075
|
+
if (target)
|
|
1076
|
+
return target.coordsAt(Math.max(0, target == before ? beforePos : afterPos), side);
|
|
1077
|
+
return fallbackRect(view);
|
|
1104
1078
|
}
|
|
1105
1079
|
function fallbackRect(view) {
|
|
1106
1080
|
let last = view.dom.lastChild;
|
|
@@ -1787,6 +1761,9 @@ const inputHandler = /*@__PURE__*/Facet.define();
|
|
|
1787
1761
|
const perLineTextDirection = /*@__PURE__*/Facet.define({
|
|
1788
1762
|
combine: values => values.some(x => x)
|
|
1789
1763
|
});
|
|
1764
|
+
const nativeSelectionHidden = /*@__PURE__*/Facet.define({
|
|
1765
|
+
combine: values => values.some(x => x)
|
|
1766
|
+
});
|
|
1790
1767
|
class ScrollTarget {
|
|
1791
1768
|
constructor(range, y = "nearest", x = "nearest", yMargin = 5, xMargin = 5) {
|
|
1792
1769
|
this.range = range;
|
|
@@ -2699,8 +2676,9 @@ class DocView extends ContentView {
|
|
|
2699
2676
|
enforceCursorAssoc() {
|
|
2700
2677
|
if (this.compositionDeco.size)
|
|
2701
2678
|
return;
|
|
2702
|
-
let cursor =
|
|
2703
|
-
let sel = getSelection(
|
|
2679
|
+
let { view } = this, cursor = view.state.selection.main;
|
|
2680
|
+
let sel = getSelection(view.root);
|
|
2681
|
+
let { anchorNode, anchorOffset } = view.observer.selectionRange;
|
|
2704
2682
|
if (!sel || !cursor.empty || !cursor.assoc || !sel.modify)
|
|
2705
2683
|
return;
|
|
2706
2684
|
let line = LineView.find(this, cursor.head);
|
|
@@ -2715,6 +2693,12 @@ class DocView extends ContentView {
|
|
|
2715
2693
|
let dom = this.domAtPos(cursor.head + cursor.assoc);
|
|
2716
2694
|
sel.collapse(dom.node, dom.offset);
|
|
2717
2695
|
sel.modify("move", cursor.assoc < 0 ? "forward" : "backward", "lineboundary");
|
|
2696
|
+
// This can go wrong in corner cases like single-character lines,
|
|
2697
|
+
// so check and reset if necessary.
|
|
2698
|
+
view.observer.readSelectionRange();
|
|
2699
|
+
let newRange = view.observer.selectionRange;
|
|
2700
|
+
if (view.docView.posFromDOM(newRange.anchorNode, newRange.anchorOffset) != cursor.from)
|
|
2701
|
+
sel.collapse(anchorNode, anchorOffset);
|
|
2718
2702
|
}
|
|
2719
2703
|
mayControlSelection() {
|
|
2720
2704
|
let active = this.view.root.activeElement;
|
|
@@ -4798,7 +4782,7 @@ class ViewState {
|
|
|
4798
4782
|
// Flag set when editor content was redrawn, so that the next
|
|
4799
4783
|
// measure stage knows it must read DOM layout
|
|
4800
4784
|
this.mustMeasureContent = true;
|
|
4801
|
-
this.defaultTextDirection = Direction.
|
|
4785
|
+
this.defaultTextDirection = Direction.LTR;
|
|
4802
4786
|
this.visibleRanges = [];
|
|
4803
4787
|
// Cursor 'assoc' is only significant when the cursor is on a line
|
|
4804
4788
|
// wrap point, where it must stick to the character that it is
|
|
@@ -4863,7 +4847,8 @@ class ViewState {
|
|
|
4863
4847
|
if (scrollTarget)
|
|
4864
4848
|
this.scrollTarget = scrollTarget;
|
|
4865
4849
|
if (!this.mustEnforceCursorAssoc && update.selectionSet && update.view.lineWrapping &&
|
|
4866
|
-
update.state.selection.main.empty && update.state.selection.main.assoc
|
|
4850
|
+
update.state.selection.main.empty && update.state.selection.main.assoc &&
|
|
4851
|
+
!update.state.facet(nativeSelectionHidden))
|
|
4867
4852
|
this.mustEnforceCursorAssoc = true;
|
|
4868
4853
|
}
|
|
4869
4854
|
measure(view) {
|
|
@@ -4926,7 +4911,9 @@ class ViewState {
|
|
|
4926
4911
|
oracle.heightChanged = false;
|
|
4927
4912
|
for (let vp of this.viewports) {
|
|
4928
4913
|
let heights = vp.from == this.viewport.from ? lineHeights : view.docView.measureVisibleLineHeights(vp);
|
|
4929
|
-
this.heightMap =
|
|
4914
|
+
this.heightMap = refresh
|
|
4915
|
+
? HeightMap.empty().applyChanges(this.stateDeco, Text.empty, this.heightOracle, [new ChangedRange(0, 0, 0, view.state.doc.length)])
|
|
4916
|
+
: this.heightMap.updateHeight(oracle, 0, refresh, new MeasuredHeights(vp.from, heights));
|
|
4930
4917
|
}
|
|
4931
4918
|
if (oracle.heightChanged)
|
|
4932
4919
|
result |= 2 /* UpdateFlag.Height */;
|
|
@@ -5565,6 +5552,15 @@ function applyDOMChange(view, domChange) {
|
|
|
5565
5552
|
newSel = EditorSelection.single(newSel.main.anchor - 1, newSel.main.head - 1);
|
|
5566
5553
|
change = { from: sel.from, to: sel.to, insert: Text.of([" "]) };
|
|
5567
5554
|
}
|
|
5555
|
+
else if (browser.chrome && change && change.from == change.to && change.from == sel.head &&
|
|
5556
|
+
change.insert.toString() == "\n " && view.lineWrapping) {
|
|
5557
|
+
// In Chrome, if you insert a space at the start of a wrapped
|
|
5558
|
+
// line, it will actually insert a newline and a space, causing a
|
|
5559
|
+
// bogus new line to be created in CodeMirror (#968)
|
|
5560
|
+
if (newSel)
|
|
5561
|
+
newSel = EditorSelection.single(newSel.main.anchor - 1, newSel.main.head - 1);
|
|
5562
|
+
change = { from: sel.from, to: sel.to, insert: Text.of([" "]) };
|
|
5563
|
+
}
|
|
5568
5564
|
if (change) {
|
|
5569
5565
|
let startState = view.state;
|
|
5570
5566
|
if (browser.ios && view.inputState.flushIOSKey(view))
|
|
@@ -5777,7 +5773,8 @@ class DOMObserver {
|
|
|
5777
5773
|
this.onScroll = this.onScroll.bind(this);
|
|
5778
5774
|
if (typeof ResizeObserver == "function") {
|
|
5779
5775
|
this.resize = new ResizeObserver(() => {
|
|
5780
|
-
|
|
5776
|
+
var _a;
|
|
5777
|
+
if (((_a = this.view.docView) === null || _a === void 0 ? void 0 : _a.lastUpdate) < Date.now() - 75)
|
|
5781
5778
|
this.onResize();
|
|
5782
5779
|
});
|
|
5783
5780
|
this.resize.observe(view.scrollDOM);
|
|
@@ -6489,17 +6486,19 @@ class EditorView {
|
|
|
6489
6486
|
logException(this.state, e);
|
|
6490
6487
|
}
|
|
6491
6488
|
}
|
|
6492
|
-
if (this.viewState.
|
|
6493
|
-
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
}
|
|
6497
|
-
else {
|
|
6498
|
-
let diff = this.viewState.lineBlockAt(refBlock.from).top - refBlock.top;
|
|
6499
|
-
if (diff > 1 || diff < -1) {
|
|
6500
|
-
this.scrollDOM.scrollTop += diff;
|
|
6489
|
+
if (this.viewState.editorHeight) {
|
|
6490
|
+
if (this.viewState.scrollTarget) {
|
|
6491
|
+
this.docView.scrollIntoView(this.viewState.scrollTarget);
|
|
6492
|
+
this.viewState.scrollTarget = null;
|
|
6501
6493
|
scrolled = true;
|
|
6502
6494
|
}
|
|
6495
|
+
else {
|
|
6496
|
+
let diff = this.viewState.lineBlockAt(refBlock.from).top - refBlock.top;
|
|
6497
|
+
if (diff > 1 || diff < -1) {
|
|
6498
|
+
this.scrollDOM.scrollTop += diff;
|
|
6499
|
+
scrolled = true;
|
|
6500
|
+
}
|
|
6501
|
+
}
|
|
6503
6502
|
}
|
|
6504
6503
|
if (redrawn)
|
|
6505
6504
|
this.docView.updateSelection(true);
|
|
@@ -7319,7 +7318,8 @@ function drawSelection(config = {}) {
|
|
|
7319
7318
|
return [
|
|
7320
7319
|
selectionConfig.of(config),
|
|
7321
7320
|
drawSelectionPlugin,
|
|
7322
|
-
hideNativeSelection
|
|
7321
|
+
hideNativeSelection,
|
|
7322
|
+
nativeSelectionHidden.of(true)
|
|
7323
7323
|
];
|
|
7324
7324
|
}
|
|
7325
7325
|
class Piece {
|
|
@@ -7905,7 +7905,8 @@ const plugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
7905
7905
|
this.attrs = { style: "padding-bottom: 1000px" };
|
|
7906
7906
|
}
|
|
7907
7907
|
update(update) {
|
|
7908
|
-
let
|
|
7908
|
+
let { view } = update;
|
|
7909
|
+
let height = view.viewState.editorHeight - view.defaultLineHeight - view.documentPadding.top - 0.5;
|
|
7909
7910
|
if (height != this.height) {
|
|
7910
7911
|
this.height = height;
|
|
7911
7912
|
this.attrs = { style: `padding-bottom: ${height}px` };
|
|
@@ -8007,7 +8008,10 @@ function rectangleFor(state, a, b) {
|
|
|
8007
8008
|
for (let i = startLine; i <= endLine; i++) {
|
|
8008
8009
|
let line = state.doc.line(i);
|
|
8009
8010
|
let start = findColumn(line.text, startCol, state.tabSize, true);
|
|
8010
|
-
if (start
|
|
8011
|
+
if (start < 0) {
|
|
8012
|
+
ranges.push(EditorSelection.cursor(line.to));
|
|
8013
|
+
}
|
|
8014
|
+
else {
|
|
8011
8015
|
let end = findColumn(line.text, endCol, state.tabSize);
|
|
8012
8016
|
ranges.push(EditorSelection.range(line.from + start, line.from + end));
|
|
8013
8017
|
}
|
|
@@ -8100,6 +8104,9 @@ function crosshairCursor(options = {}) {
|
|
|
8100
8104
|
keyup(e) {
|
|
8101
8105
|
if (e.keyCode == code || !getter(e))
|
|
8102
8106
|
this.set(false);
|
|
8107
|
+
},
|
|
8108
|
+
mousemove(e) {
|
|
8109
|
+
this.set(getter(e));
|
|
8103
8110
|
}
|
|
8104
8111
|
}
|
|
8105
8112
|
});
|
|
@@ -8119,6 +8126,7 @@ class TooltipViewManager {
|
|
|
8119
8126
|
this.tooltipViews = this.tooltips.map(createTooltipView);
|
|
8120
8127
|
}
|
|
8121
8128
|
update(update) {
|
|
8129
|
+
var _a;
|
|
8122
8130
|
let input = update.state.facet(this.facet);
|
|
8123
8131
|
let tooltips = input.filter(x => x);
|
|
8124
8132
|
if (input === this.input) {
|
|
@@ -8147,8 +8155,10 @@ class TooltipViewManager {
|
|
|
8147
8155
|
}
|
|
8148
8156
|
}
|
|
8149
8157
|
for (let t of this.tooltipViews)
|
|
8150
|
-
if (tooltipViews.indexOf(t) < 0)
|
|
8158
|
+
if (tooltipViews.indexOf(t) < 0) {
|
|
8151
8159
|
t.dom.remove();
|
|
8160
|
+
(_a = t.destroy) === null || _a === void 0 ? void 0 : _a.call(t);
|
|
8161
|
+
}
|
|
8152
8162
|
this.input = input;
|
|
8153
8163
|
this.tooltips = tooltips;
|
|
8154
8164
|
this.tooltipViews = tooltipViews;
|
|
@@ -8267,11 +8277,13 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
8267
8277
|
return tooltipView;
|
|
8268
8278
|
}
|
|
8269
8279
|
destroy() {
|
|
8270
|
-
var _a;
|
|
8280
|
+
var _a, _b;
|
|
8271
8281
|
this.view.win.removeEventListener("resize", this.measureSoon);
|
|
8272
|
-
for (let
|
|
8273
|
-
dom.remove();
|
|
8274
|
-
|
|
8282
|
+
for (let tooltipView of this.manager.tooltipViews) {
|
|
8283
|
+
tooltipView.dom.remove();
|
|
8284
|
+
(_a = tooltipView.destroy) === null || _a === void 0 ? void 0 : _a.call(tooltipView);
|
|
8285
|
+
}
|
|
8286
|
+
(_b = this.intersectionObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
|
|
8275
8287
|
clearTimeout(this.measureTimeout);
|
|
8276
8288
|
}
|
|
8277
8289
|
readMeasure() {
|