@codemirror/view 6.9.1 → 6.9.3
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 +22 -0
- package/dist/index.cjs +72 -34
- package/dist/index.js +72 -34
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
## 6.9.3 (2023-03-21)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Work around a Firefox issue that caused `coordsAtPos` to return rectangles with the full line height on empty lines.
|
|
6
|
+
|
|
7
|
+
Opening a context menu by clicking below the content element but inside the editor now properly shows the browser's menu for editable elements.
|
|
8
|
+
|
|
9
|
+
Fix an issue that broke composition (especially of Chinese IME) after widget decorations.
|
|
10
|
+
|
|
11
|
+
Fix an issue that would cause the cursor to jump around during compositions inside nested mark decorations.
|
|
12
|
+
|
|
13
|
+
## 6.9.2 (2023-03-08)
|
|
14
|
+
|
|
15
|
+
### Bug fixes
|
|
16
|
+
|
|
17
|
+
Work around a Firefox CSS bug that caused cursors to stop blinking in a scrolled editor.
|
|
18
|
+
|
|
19
|
+
Fix an issue in `drawSelection` where the selection extended into the editor's padding.
|
|
20
|
+
|
|
21
|
+
Fix pasting of links copied from iOS share sheet.
|
|
22
|
+
|
|
1
23
|
## 6.9.1 (2023-02-17)
|
|
2
24
|
|
|
3
25
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -957,8 +957,9 @@ function scanCompositionTree(pos, side, view, text, enterView, fromText) {
|
|
|
957
957
|
}
|
|
958
958
|
function posFromDOMInCompositionTree(node, offset, view, text) {
|
|
959
959
|
if (view instanceof MarkView) {
|
|
960
|
+
let pos = 0;
|
|
960
961
|
for (let child of view.children) {
|
|
961
|
-
let
|
|
962
|
+
let hasComp = contains(child.dom, text);
|
|
962
963
|
if (contains(child.dom, node))
|
|
963
964
|
return pos + (hasComp ? posFromDOMInCompositionTree(node, offset, child, text) : child.localPosFromDOM(node, offset));
|
|
964
965
|
pos += hasComp ? text.nodeValue.length : child.length;
|
|
@@ -992,7 +993,7 @@ class WidgetBufferView extends ContentView {
|
|
|
992
993
|
}
|
|
993
994
|
}
|
|
994
995
|
getSide() { return this.side; }
|
|
995
|
-
domAtPos(pos) { return DOMPos.before(this.dom); }
|
|
996
|
+
domAtPos(pos) { return this.side > 0 ? DOMPos.before(this.dom) : DOMPos.after(this.dom); }
|
|
996
997
|
localPosFromDOM() { return 0; }
|
|
997
998
|
domBoundsAround() { return null; }
|
|
998
999
|
coordsAt(pos) {
|
|
@@ -1516,7 +1517,7 @@ class LineView extends ContentView {
|
|
|
1516
1517
|
measureTextSize() {
|
|
1517
1518
|
if (this.children.length == 0 || this.length > 20)
|
|
1518
1519
|
return null;
|
|
1519
|
-
let totalWidth = 0;
|
|
1520
|
+
let totalWidth = 0, textHeight;
|
|
1520
1521
|
for (let child of this.children) {
|
|
1521
1522
|
if (!(child instanceof TextView) || /[^ -~]/.test(child.text))
|
|
1522
1523
|
return null;
|
|
@@ -1524,14 +1525,26 @@ class LineView extends ContentView {
|
|
|
1524
1525
|
if (rects.length != 1)
|
|
1525
1526
|
return null;
|
|
1526
1527
|
totalWidth += rects[0].width;
|
|
1528
|
+
textHeight = rects[0].height;
|
|
1527
1529
|
}
|
|
1528
1530
|
return !totalWidth ? null : {
|
|
1529
1531
|
lineHeight: this.dom.getBoundingClientRect().height,
|
|
1530
|
-
charWidth: totalWidth / this.length
|
|
1532
|
+
charWidth: totalWidth / this.length,
|
|
1533
|
+
textHeight
|
|
1531
1534
|
};
|
|
1532
1535
|
}
|
|
1533
1536
|
coordsAt(pos, side) {
|
|
1534
|
-
|
|
1537
|
+
let rect = coordsInChildren(this, pos, side);
|
|
1538
|
+
// Correct rectangle height for empty lines when the returned
|
|
1539
|
+
// height is larger than the text height.
|
|
1540
|
+
if (!this.children.length && rect && this.parent) {
|
|
1541
|
+
let { heightOracle } = this.parent.view.viewState, height = rect.bottom - rect.top;
|
|
1542
|
+
if (Math.abs(height - heightOracle.lineHeight) < 2 && heightOracle.textHeight < height) {
|
|
1543
|
+
let dist = (height - heightOracle.textHeight) / 2;
|
|
1544
|
+
return { top: rect.top + dist, bottom: rect.bottom - dist, left: rect.left, right: rect.left };
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
return rect;
|
|
1535
1548
|
}
|
|
1536
1549
|
become(_other) { return false; }
|
|
1537
1550
|
get type() { return exports.BlockType.Text; }
|
|
@@ -2812,7 +2825,7 @@ class DocView extends ContentView {
|
|
|
2812
2825
|
}
|
|
2813
2826
|
}
|
|
2814
2827
|
// If no workable line exists, force a layout of a measurable element
|
|
2815
|
-
let dummy = document.createElement("div"), lineHeight, charWidth;
|
|
2828
|
+
let dummy = document.createElement("div"), lineHeight, charWidth, textHeight;
|
|
2816
2829
|
dummy.className = "cm-line";
|
|
2817
2830
|
dummy.style.width = "99999px";
|
|
2818
2831
|
dummy.textContent = "abc def ghi jkl mno pqr stu";
|
|
@@ -2821,9 +2834,10 @@ class DocView extends ContentView {
|
|
|
2821
2834
|
let rect = clientRectsFor(dummy.firstChild)[0];
|
|
2822
2835
|
lineHeight = dummy.getBoundingClientRect().height;
|
|
2823
2836
|
charWidth = rect ? rect.width / 27 : 7;
|
|
2837
|
+
textHeight = rect ? rect.height : lineHeight;
|
|
2824
2838
|
dummy.remove();
|
|
2825
2839
|
});
|
|
2826
|
-
return { lineHeight, charWidth };
|
|
2840
|
+
return { lineHeight, charWidth, textHeight };
|
|
2827
2841
|
}
|
|
2828
2842
|
childCursor(pos = this.length) {
|
|
2829
2843
|
// Move back to start of last element when possible, so that
|
|
@@ -2988,22 +3002,32 @@ class CompositionWidget extends WidgetType {
|
|
|
2988
3002
|
ignoreEvent() { return false; }
|
|
2989
3003
|
get customView() { return CompositionView; }
|
|
2990
3004
|
}
|
|
2991
|
-
function nearbyTextNode(
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
node
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3005
|
+
function nearbyTextNode(startNode, startOffset, side) {
|
|
3006
|
+
if (side <= 0)
|
|
3007
|
+
for (let node = startNode, offset = startOffset;;) {
|
|
3008
|
+
if (node.nodeType == 3)
|
|
3009
|
+
return node;
|
|
3010
|
+
if (node.nodeType == 1 && offset > 0) {
|
|
3011
|
+
node = node.childNodes[offset - 1];
|
|
3012
|
+
offset = maxOffset(node);
|
|
3013
|
+
}
|
|
3014
|
+
else {
|
|
3015
|
+
break;
|
|
3016
|
+
}
|
|
3002
3017
|
}
|
|
3003
|
-
|
|
3004
|
-
|
|
3018
|
+
if (side >= 0)
|
|
3019
|
+
for (let node = startNode, offset = startOffset;;) {
|
|
3020
|
+
if (node.nodeType == 3)
|
|
3021
|
+
return node;
|
|
3022
|
+
if (node.nodeType == 1 && offset < node.childNodes.length && side >= 0) {
|
|
3023
|
+
node = node.childNodes[offset];
|
|
3024
|
+
offset = 0;
|
|
3025
|
+
}
|
|
3026
|
+
else {
|
|
3027
|
+
break;
|
|
3028
|
+
}
|
|
3005
3029
|
}
|
|
3006
|
-
|
|
3030
|
+
return null;
|
|
3007
3031
|
}
|
|
3008
3032
|
function nextToUneditable(node, offset) {
|
|
3009
3033
|
if (node.nodeType != 1)
|
|
@@ -3167,7 +3191,7 @@ function domPosInText(node, x, y) {
|
|
|
3167
3191
|
return { node, offset: closestOffset > -1 ? closestOffset : generalSide > 0 ? node.nodeValue.length : 0 };
|
|
3168
3192
|
}
|
|
3169
3193
|
function posAtCoords(view, coords, precise, bias = -1) {
|
|
3170
|
-
var _a;
|
|
3194
|
+
var _a, _b;
|
|
3171
3195
|
let content = view.contentDOM.getBoundingClientRect(), docTop = content.top + view.viewState.paddingTop;
|
|
3172
3196
|
let block, { docHeight } = view.viewState;
|
|
3173
3197
|
let { x, y } = coords, yOffset = y - docTop;
|
|
@@ -3244,7 +3268,7 @@ function posAtCoords(view, coords, precise, bias = -1) {
|
|
|
3244
3268
|
let nearest = view.docView.nearest(node);
|
|
3245
3269
|
if (!nearest)
|
|
3246
3270
|
return null;
|
|
3247
|
-
if (nearest.isWidget) {
|
|
3271
|
+
if (nearest.isWidget && ((_b = nearest.dom) === null || _b === void 0 ? void 0 : _b.nodeType) == 1) {
|
|
3248
3272
|
let rect = nearest.dom.getBoundingClientRect();
|
|
3249
3273
|
return coords.y < rect.top || coords.y <= rect.bottom && coords.x <= (rect.left + rect.right) / 2
|
|
3250
3274
|
? nearest.posAtStart : nearest.posAtEnd;
|
|
@@ -3439,8 +3463,16 @@ class InputState {
|
|
|
3439
3463
|
this.registeredEvents.push(type);
|
|
3440
3464
|
}
|
|
3441
3465
|
view.scrollDOM.addEventListener("mousedown", (event) => {
|
|
3442
|
-
if (event.target == view.scrollDOM && event.clientY > view.contentDOM.getBoundingClientRect().bottom)
|
|
3466
|
+
if (event.target == view.scrollDOM && event.clientY > view.contentDOM.getBoundingClientRect().bottom) {
|
|
3443
3467
|
handleEvent(handlers.mousedown, event);
|
|
3468
|
+
if (!event.defaultPrevented && event.button == 2) {
|
|
3469
|
+
// Make sure the content covers the entire scroller height, in order
|
|
3470
|
+
// to catch a native context menu click below it
|
|
3471
|
+
let start = view.contentDOM.style.minHeight;
|
|
3472
|
+
view.contentDOM.style.minHeight = "100%";
|
|
3473
|
+
setTimeout(() => view.contentDOM.style.minHeight = start, 200);
|
|
3474
|
+
}
|
|
3475
|
+
}
|
|
3444
3476
|
});
|
|
3445
3477
|
if (browser.chrome && browser.chrome_version == 102) { // FIXME remove at some point
|
|
3446
3478
|
// On Chrome 102, viewport updates somehow stop wheel-based
|
|
@@ -3974,7 +4006,7 @@ handlers.paste = (view, event) => {
|
|
|
3974
4006
|
view.observer.flush();
|
|
3975
4007
|
let data = brokenClipboardAPI ? null : event.clipboardData;
|
|
3976
4008
|
if (data) {
|
|
3977
|
-
doPaste(view, data.getData("text/plain"));
|
|
4009
|
+
doPaste(view, data.getData("text/plain") || data.getData("text/uri-text"));
|
|
3978
4010
|
event.preventDefault();
|
|
3979
4011
|
}
|
|
3980
4012
|
else {
|
|
@@ -4134,8 +4166,9 @@ class HeightOracle {
|
|
|
4134
4166
|
this.lineWrapping = lineWrapping;
|
|
4135
4167
|
this.doc = state.Text.empty;
|
|
4136
4168
|
this.heightSamples = {};
|
|
4137
|
-
this.lineHeight = 14;
|
|
4169
|
+
this.lineHeight = 14; // The height of an entire line (line-height)
|
|
4138
4170
|
this.charWidth = 7;
|
|
4171
|
+
this.textHeight = 14; // The height of the actual font (font-size)
|
|
4139
4172
|
this.lineLength = 30;
|
|
4140
4173
|
// Used to track, during updateHeight, if any actual heights changed
|
|
4141
4174
|
this.heightChanged = false;
|
|
@@ -4170,12 +4203,13 @@ class HeightOracle {
|
|
|
4170
4203
|
}
|
|
4171
4204
|
return newHeight;
|
|
4172
4205
|
}
|
|
4173
|
-
refresh(whiteSpace, lineHeight, charWidth, lineLength, knownHeights) {
|
|
4206
|
+
refresh(whiteSpace, lineHeight, charWidth, textHeight, lineLength, knownHeights) {
|
|
4174
4207
|
let lineWrapping = wrappingWhiteSpace.indexOf(whiteSpace) > -1;
|
|
4175
4208
|
let changed = Math.round(lineHeight) != Math.round(this.lineHeight) || this.lineWrapping != lineWrapping;
|
|
4176
4209
|
this.lineWrapping = lineWrapping;
|
|
4177
4210
|
this.lineHeight = lineHeight;
|
|
4178
4211
|
this.charWidth = charWidth;
|
|
4212
|
+
this.textHeight = textHeight;
|
|
4179
4213
|
this.lineLength = lineLength;
|
|
4180
4214
|
if (changed) {
|
|
4181
4215
|
this.heightSamples = {};
|
|
@@ -5023,8 +5057,8 @@ class ViewState {
|
|
|
5023
5057
|
if (oracle.mustRefreshForHeights(lineHeights))
|
|
5024
5058
|
refresh = true;
|
|
5025
5059
|
if (refresh || oracle.lineWrapping && Math.abs(contentWidth - this.contentDOMWidth) > oracle.charWidth) {
|
|
5026
|
-
let { lineHeight, charWidth } = view.docView.measureTextSize();
|
|
5027
|
-
refresh = lineHeight > 0 && oracle.refresh(whiteSpace, lineHeight, charWidth, contentWidth / charWidth, lineHeights);
|
|
5060
|
+
let { lineHeight, charWidth, textHeight } = view.docView.measureTextSize();
|
|
5061
|
+
refresh = lineHeight > 0 && oracle.refresh(whiteSpace, lineHeight, charWidth, textHeight, contentWidth / charWidth, lineHeights);
|
|
5028
5062
|
if (refresh) {
|
|
5029
5063
|
view.docView.minWidth = 0;
|
|
5030
5064
|
result |= 8 /* UpdateFlag.Geometry */;
|
|
@@ -5435,6 +5469,9 @@ const baseTheme$1 = buildTheme("." + baseThemeID, {
|
|
|
5435
5469
|
padding: "0 2px 0 6px"
|
|
5436
5470
|
},
|
|
5437
5471
|
".cm-layer": {
|
|
5472
|
+
position: "absolute",
|
|
5473
|
+
left: 0,
|
|
5474
|
+
top: 0,
|
|
5438
5475
|
contain: "size style",
|
|
5439
5476
|
"& > *": {
|
|
5440
5477
|
position: "absolute"
|
|
@@ -6595,7 +6632,7 @@ class EditorView {
|
|
|
6595
6632
|
if (this.destroyed)
|
|
6596
6633
|
return;
|
|
6597
6634
|
if (this.measureScheduled > -1)
|
|
6598
|
-
cancelAnimationFrame(this.measureScheduled);
|
|
6635
|
+
this.win.cancelAnimationFrame(this.measureScheduled);
|
|
6599
6636
|
this.measureScheduled = 0; // Prevent requestMeasure calls from scheduling another animation frame
|
|
6600
6637
|
if (flush)
|
|
6601
6638
|
this.observer.forceFlush();
|
|
@@ -7033,7 +7070,7 @@ class EditorView {
|
|
|
7033
7070
|
this.dom.remove();
|
|
7034
7071
|
this.observer.destroy();
|
|
7035
7072
|
if (this.measureScheduled > -1)
|
|
7036
|
-
cancelAnimationFrame(this.measureScheduled);
|
|
7073
|
+
this.win.cancelAnimationFrame(this.measureScheduled);
|
|
7037
7074
|
this.destroyed = true;
|
|
7038
7075
|
}
|
|
7039
7076
|
/**
|
|
@@ -7545,9 +7582,10 @@ function rectanglesForRange(view, className, range) {
|
|
|
7545
7582
|
let from = Math.max(range.from, view.viewport.from), to = Math.min(range.to, view.viewport.to);
|
|
7546
7583
|
let ltr = view.textDirection == exports.Direction.LTR;
|
|
7547
7584
|
let content = view.contentDOM, contentRect = content.getBoundingClientRect(), base = getBase(view);
|
|
7548
|
-
let lineStyle = window.getComputedStyle(
|
|
7549
|
-
let leftSide = contentRect.left +
|
|
7550
|
-
|
|
7585
|
+
let lineElt = content.querySelector(".cm-line"), lineStyle = lineElt && window.getComputedStyle(lineElt);
|
|
7586
|
+
let leftSide = contentRect.left +
|
|
7587
|
+
(lineStyle ? parseInt(lineStyle.paddingLeft) + Math.min(0, parseInt(lineStyle.textIndent)) : 0);
|
|
7588
|
+
let rightSide = contentRect.right - (lineStyle ? parseInt(lineStyle.paddingRight) : 0);
|
|
7551
7589
|
let startBlock = blockAt(view, from), endBlock = blockAt(view, to);
|
|
7552
7590
|
let visualStart = startBlock.type == exports.BlockType.Text ? startBlock : null;
|
|
7553
7591
|
let visualEnd = endBlock.type == exports.BlockType.Text ? endBlock : null;
|
package/dist/index.js
CHANGED
|
@@ -953,8 +953,9 @@ function scanCompositionTree(pos, side, view, text, enterView, fromText) {
|
|
|
953
953
|
}
|
|
954
954
|
function posFromDOMInCompositionTree(node, offset, view, text) {
|
|
955
955
|
if (view instanceof MarkView) {
|
|
956
|
+
let pos = 0;
|
|
956
957
|
for (let child of view.children) {
|
|
957
|
-
let
|
|
958
|
+
let hasComp = contains(child.dom, text);
|
|
958
959
|
if (contains(child.dom, node))
|
|
959
960
|
return pos + (hasComp ? posFromDOMInCompositionTree(node, offset, child, text) : child.localPosFromDOM(node, offset));
|
|
960
961
|
pos += hasComp ? text.nodeValue.length : child.length;
|
|
@@ -988,7 +989,7 @@ class WidgetBufferView extends ContentView {
|
|
|
988
989
|
}
|
|
989
990
|
}
|
|
990
991
|
getSide() { return this.side; }
|
|
991
|
-
domAtPos(pos) { return DOMPos.before(this.dom); }
|
|
992
|
+
domAtPos(pos) { return this.side > 0 ? DOMPos.before(this.dom) : DOMPos.after(this.dom); }
|
|
992
993
|
localPosFromDOM() { return 0; }
|
|
993
994
|
domBoundsAround() { return null; }
|
|
994
995
|
coordsAt(pos) {
|
|
@@ -1511,7 +1512,7 @@ class LineView extends ContentView {
|
|
|
1511
1512
|
measureTextSize() {
|
|
1512
1513
|
if (this.children.length == 0 || this.length > 20)
|
|
1513
1514
|
return null;
|
|
1514
|
-
let totalWidth = 0;
|
|
1515
|
+
let totalWidth = 0, textHeight;
|
|
1515
1516
|
for (let child of this.children) {
|
|
1516
1517
|
if (!(child instanceof TextView) || /[^ -~]/.test(child.text))
|
|
1517
1518
|
return null;
|
|
@@ -1519,14 +1520,26 @@ class LineView extends ContentView {
|
|
|
1519
1520
|
if (rects.length != 1)
|
|
1520
1521
|
return null;
|
|
1521
1522
|
totalWidth += rects[0].width;
|
|
1523
|
+
textHeight = rects[0].height;
|
|
1522
1524
|
}
|
|
1523
1525
|
return !totalWidth ? null : {
|
|
1524
1526
|
lineHeight: this.dom.getBoundingClientRect().height,
|
|
1525
|
-
charWidth: totalWidth / this.length
|
|
1527
|
+
charWidth: totalWidth / this.length,
|
|
1528
|
+
textHeight
|
|
1526
1529
|
};
|
|
1527
1530
|
}
|
|
1528
1531
|
coordsAt(pos, side) {
|
|
1529
|
-
|
|
1532
|
+
let rect = coordsInChildren(this, pos, side);
|
|
1533
|
+
// Correct rectangle height for empty lines when the returned
|
|
1534
|
+
// height is larger than the text height.
|
|
1535
|
+
if (!this.children.length && rect && this.parent) {
|
|
1536
|
+
let { heightOracle } = this.parent.view.viewState, height = rect.bottom - rect.top;
|
|
1537
|
+
if (Math.abs(height - heightOracle.lineHeight) < 2 && heightOracle.textHeight < height) {
|
|
1538
|
+
let dist = (height - heightOracle.textHeight) / 2;
|
|
1539
|
+
return { top: rect.top + dist, bottom: rect.bottom - dist, left: rect.left, right: rect.left };
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
return rect;
|
|
1530
1543
|
}
|
|
1531
1544
|
become(_other) { return false; }
|
|
1532
1545
|
get type() { return BlockType.Text; }
|
|
@@ -2806,7 +2819,7 @@ class DocView extends ContentView {
|
|
|
2806
2819
|
}
|
|
2807
2820
|
}
|
|
2808
2821
|
// If no workable line exists, force a layout of a measurable element
|
|
2809
|
-
let dummy = document.createElement("div"), lineHeight, charWidth;
|
|
2822
|
+
let dummy = document.createElement("div"), lineHeight, charWidth, textHeight;
|
|
2810
2823
|
dummy.className = "cm-line";
|
|
2811
2824
|
dummy.style.width = "99999px";
|
|
2812
2825
|
dummy.textContent = "abc def ghi jkl mno pqr stu";
|
|
@@ -2815,9 +2828,10 @@ class DocView extends ContentView {
|
|
|
2815
2828
|
let rect = clientRectsFor(dummy.firstChild)[0];
|
|
2816
2829
|
lineHeight = dummy.getBoundingClientRect().height;
|
|
2817
2830
|
charWidth = rect ? rect.width / 27 : 7;
|
|
2831
|
+
textHeight = rect ? rect.height : lineHeight;
|
|
2818
2832
|
dummy.remove();
|
|
2819
2833
|
});
|
|
2820
|
-
return { lineHeight, charWidth };
|
|
2834
|
+
return { lineHeight, charWidth, textHeight };
|
|
2821
2835
|
}
|
|
2822
2836
|
childCursor(pos = this.length) {
|
|
2823
2837
|
// Move back to start of last element when possible, so that
|
|
@@ -2982,22 +2996,32 @@ class CompositionWidget extends WidgetType {
|
|
|
2982
2996
|
ignoreEvent() { return false; }
|
|
2983
2997
|
get customView() { return CompositionView; }
|
|
2984
2998
|
}
|
|
2985
|
-
function nearbyTextNode(
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
node
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2999
|
+
function nearbyTextNode(startNode, startOffset, side) {
|
|
3000
|
+
if (side <= 0)
|
|
3001
|
+
for (let node = startNode, offset = startOffset;;) {
|
|
3002
|
+
if (node.nodeType == 3)
|
|
3003
|
+
return node;
|
|
3004
|
+
if (node.nodeType == 1 && offset > 0) {
|
|
3005
|
+
node = node.childNodes[offset - 1];
|
|
3006
|
+
offset = maxOffset(node);
|
|
3007
|
+
}
|
|
3008
|
+
else {
|
|
3009
|
+
break;
|
|
3010
|
+
}
|
|
2996
3011
|
}
|
|
2997
|
-
|
|
2998
|
-
|
|
3012
|
+
if (side >= 0)
|
|
3013
|
+
for (let node = startNode, offset = startOffset;;) {
|
|
3014
|
+
if (node.nodeType == 3)
|
|
3015
|
+
return node;
|
|
3016
|
+
if (node.nodeType == 1 && offset < node.childNodes.length && side >= 0) {
|
|
3017
|
+
node = node.childNodes[offset];
|
|
3018
|
+
offset = 0;
|
|
3019
|
+
}
|
|
3020
|
+
else {
|
|
3021
|
+
break;
|
|
3022
|
+
}
|
|
2999
3023
|
}
|
|
3000
|
-
|
|
3024
|
+
return null;
|
|
3001
3025
|
}
|
|
3002
3026
|
function nextToUneditable(node, offset) {
|
|
3003
3027
|
if (node.nodeType != 1)
|
|
@@ -3161,7 +3185,7 @@ function domPosInText(node, x, y) {
|
|
|
3161
3185
|
return { node, offset: closestOffset > -1 ? closestOffset : generalSide > 0 ? node.nodeValue.length : 0 };
|
|
3162
3186
|
}
|
|
3163
3187
|
function posAtCoords(view, coords, precise, bias = -1) {
|
|
3164
|
-
var _a;
|
|
3188
|
+
var _a, _b;
|
|
3165
3189
|
let content = view.contentDOM.getBoundingClientRect(), docTop = content.top + view.viewState.paddingTop;
|
|
3166
3190
|
let block, { docHeight } = view.viewState;
|
|
3167
3191
|
let { x, y } = coords, yOffset = y - docTop;
|
|
@@ -3238,7 +3262,7 @@ function posAtCoords(view, coords, precise, bias = -1) {
|
|
|
3238
3262
|
let nearest = view.docView.nearest(node);
|
|
3239
3263
|
if (!nearest)
|
|
3240
3264
|
return null;
|
|
3241
|
-
if (nearest.isWidget) {
|
|
3265
|
+
if (nearest.isWidget && ((_b = nearest.dom) === null || _b === void 0 ? void 0 : _b.nodeType) == 1) {
|
|
3242
3266
|
let rect = nearest.dom.getBoundingClientRect();
|
|
3243
3267
|
return coords.y < rect.top || coords.y <= rect.bottom && coords.x <= (rect.left + rect.right) / 2
|
|
3244
3268
|
? nearest.posAtStart : nearest.posAtEnd;
|
|
@@ -3433,8 +3457,16 @@ class InputState {
|
|
|
3433
3457
|
this.registeredEvents.push(type);
|
|
3434
3458
|
}
|
|
3435
3459
|
view.scrollDOM.addEventListener("mousedown", (event) => {
|
|
3436
|
-
if (event.target == view.scrollDOM && event.clientY > view.contentDOM.getBoundingClientRect().bottom)
|
|
3460
|
+
if (event.target == view.scrollDOM && event.clientY > view.contentDOM.getBoundingClientRect().bottom) {
|
|
3437
3461
|
handleEvent(handlers.mousedown, event);
|
|
3462
|
+
if (!event.defaultPrevented && event.button == 2) {
|
|
3463
|
+
// Make sure the content covers the entire scroller height, in order
|
|
3464
|
+
// to catch a native context menu click below it
|
|
3465
|
+
let start = view.contentDOM.style.minHeight;
|
|
3466
|
+
view.contentDOM.style.minHeight = "100%";
|
|
3467
|
+
setTimeout(() => view.contentDOM.style.minHeight = start, 200);
|
|
3468
|
+
}
|
|
3469
|
+
}
|
|
3438
3470
|
});
|
|
3439
3471
|
if (browser.chrome && browser.chrome_version == 102) { // FIXME remove at some point
|
|
3440
3472
|
// On Chrome 102, viewport updates somehow stop wheel-based
|
|
@@ -3968,7 +4000,7 @@ handlers.paste = (view, event) => {
|
|
|
3968
4000
|
view.observer.flush();
|
|
3969
4001
|
let data = brokenClipboardAPI ? null : event.clipboardData;
|
|
3970
4002
|
if (data) {
|
|
3971
|
-
doPaste(view, data.getData("text/plain"));
|
|
4003
|
+
doPaste(view, data.getData("text/plain") || data.getData("text/uri-text"));
|
|
3972
4004
|
event.preventDefault();
|
|
3973
4005
|
}
|
|
3974
4006
|
else {
|
|
@@ -4128,8 +4160,9 @@ class HeightOracle {
|
|
|
4128
4160
|
this.lineWrapping = lineWrapping;
|
|
4129
4161
|
this.doc = Text.empty;
|
|
4130
4162
|
this.heightSamples = {};
|
|
4131
|
-
this.lineHeight = 14;
|
|
4163
|
+
this.lineHeight = 14; // The height of an entire line (line-height)
|
|
4132
4164
|
this.charWidth = 7;
|
|
4165
|
+
this.textHeight = 14; // The height of the actual font (font-size)
|
|
4133
4166
|
this.lineLength = 30;
|
|
4134
4167
|
// Used to track, during updateHeight, if any actual heights changed
|
|
4135
4168
|
this.heightChanged = false;
|
|
@@ -4164,12 +4197,13 @@ class HeightOracle {
|
|
|
4164
4197
|
}
|
|
4165
4198
|
return newHeight;
|
|
4166
4199
|
}
|
|
4167
|
-
refresh(whiteSpace, lineHeight, charWidth, lineLength, knownHeights) {
|
|
4200
|
+
refresh(whiteSpace, lineHeight, charWidth, textHeight, lineLength, knownHeights) {
|
|
4168
4201
|
let lineWrapping = wrappingWhiteSpace.indexOf(whiteSpace) > -1;
|
|
4169
4202
|
let changed = Math.round(lineHeight) != Math.round(this.lineHeight) || this.lineWrapping != lineWrapping;
|
|
4170
4203
|
this.lineWrapping = lineWrapping;
|
|
4171
4204
|
this.lineHeight = lineHeight;
|
|
4172
4205
|
this.charWidth = charWidth;
|
|
4206
|
+
this.textHeight = textHeight;
|
|
4173
4207
|
this.lineLength = lineLength;
|
|
4174
4208
|
if (changed) {
|
|
4175
4209
|
this.heightSamples = {};
|
|
@@ -5016,8 +5050,8 @@ class ViewState {
|
|
|
5016
5050
|
if (oracle.mustRefreshForHeights(lineHeights))
|
|
5017
5051
|
refresh = true;
|
|
5018
5052
|
if (refresh || oracle.lineWrapping && Math.abs(contentWidth - this.contentDOMWidth) > oracle.charWidth) {
|
|
5019
|
-
let { lineHeight, charWidth } = view.docView.measureTextSize();
|
|
5020
|
-
refresh = lineHeight > 0 && oracle.refresh(whiteSpace, lineHeight, charWidth, contentWidth / charWidth, lineHeights);
|
|
5053
|
+
let { lineHeight, charWidth, textHeight } = view.docView.measureTextSize();
|
|
5054
|
+
refresh = lineHeight > 0 && oracle.refresh(whiteSpace, lineHeight, charWidth, textHeight, contentWidth / charWidth, lineHeights);
|
|
5021
5055
|
if (refresh) {
|
|
5022
5056
|
view.docView.minWidth = 0;
|
|
5023
5057
|
result |= 8 /* UpdateFlag.Geometry */;
|
|
@@ -5428,6 +5462,9 @@ const baseTheme$1 = /*@__PURE__*/buildTheme("." + baseThemeID, {
|
|
|
5428
5462
|
padding: "0 2px 0 6px"
|
|
5429
5463
|
},
|
|
5430
5464
|
".cm-layer": {
|
|
5465
|
+
position: "absolute",
|
|
5466
|
+
left: 0,
|
|
5467
|
+
top: 0,
|
|
5431
5468
|
contain: "size style",
|
|
5432
5469
|
"& > *": {
|
|
5433
5470
|
position: "absolute"
|
|
@@ -6588,7 +6625,7 @@ class EditorView {
|
|
|
6588
6625
|
if (this.destroyed)
|
|
6589
6626
|
return;
|
|
6590
6627
|
if (this.measureScheduled > -1)
|
|
6591
|
-
cancelAnimationFrame(this.measureScheduled);
|
|
6628
|
+
this.win.cancelAnimationFrame(this.measureScheduled);
|
|
6592
6629
|
this.measureScheduled = 0; // Prevent requestMeasure calls from scheduling another animation frame
|
|
6593
6630
|
if (flush)
|
|
6594
6631
|
this.observer.forceFlush();
|
|
@@ -7026,7 +7063,7 @@ class EditorView {
|
|
|
7026
7063
|
this.dom.remove();
|
|
7027
7064
|
this.observer.destroy();
|
|
7028
7065
|
if (this.measureScheduled > -1)
|
|
7029
|
-
cancelAnimationFrame(this.measureScheduled);
|
|
7066
|
+
this.win.cancelAnimationFrame(this.measureScheduled);
|
|
7030
7067
|
this.destroyed = true;
|
|
7031
7068
|
}
|
|
7032
7069
|
/**
|
|
@@ -7538,9 +7575,10 @@ function rectanglesForRange(view, className, range) {
|
|
|
7538
7575
|
let from = Math.max(range.from, view.viewport.from), to = Math.min(range.to, view.viewport.to);
|
|
7539
7576
|
let ltr = view.textDirection == Direction.LTR;
|
|
7540
7577
|
let content = view.contentDOM, contentRect = content.getBoundingClientRect(), base = getBase(view);
|
|
7541
|
-
let lineStyle = window.getComputedStyle(
|
|
7542
|
-
let leftSide = contentRect.left +
|
|
7543
|
-
|
|
7578
|
+
let lineElt = content.querySelector(".cm-line"), lineStyle = lineElt && window.getComputedStyle(lineElt);
|
|
7579
|
+
let leftSide = contentRect.left +
|
|
7580
|
+
(lineStyle ? parseInt(lineStyle.paddingLeft) + Math.min(0, parseInt(lineStyle.textIndent)) : 0);
|
|
7581
|
+
let rightSide = contentRect.right - (lineStyle ? parseInt(lineStyle.paddingRight) : 0);
|
|
7544
7582
|
let startBlock = blockAt(view, from), endBlock = blockAt(view, to);
|
|
7545
7583
|
let visualStart = startBlock.type == BlockType.Text ? startBlock : null;
|
|
7546
7584
|
let visualEnd = endBlock.type == BlockType.Text ? endBlock : null;
|