@codemirror/view 6.39.17 → 6.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/index.cjs +21 -12
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +21 -12
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## 6.40.0 (2026-03-12)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Fix a bug that caused Shift-Enter/Backspace/Delete on iOS to lose the shift modifier when delivered to key event handlers.
|
|
6
|
+
|
|
7
|
+
Fix an issue where `EditorView.moveVertically` could move to the wrong place in wrapped lines with a large line height.
|
|
8
|
+
|
|
9
|
+
Make sure the selection head associativity is properly set for mouse selections made with shift held down.
|
|
10
|
+
|
|
11
|
+
### New features
|
|
12
|
+
|
|
13
|
+
`WidgetType.updateDOM` is now called with the previous widget value as third argument.
|
|
14
|
+
|
|
1
15
|
## 6.39.17 (2026-03-10)
|
|
2
16
|
|
|
3
17
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -134,7 +134,7 @@ class WidgetType {
|
|
|
134
134
|
couldn't (in which case the widget will be redrawn). The default
|
|
135
135
|
implementation just returns false.
|
|
136
136
|
*/
|
|
137
|
-
updateDOM(dom, view) { return false; }
|
|
137
|
+
updateDOM(dom, view, from) { return false; }
|
|
138
138
|
/**
|
|
139
139
|
@internal
|
|
140
140
|
*/
|
|
@@ -2539,7 +2539,7 @@ class TileCache {
|
|
|
2539
2539
|
let tile = widgets[i];
|
|
2540
2540
|
if (!this.reused.has(tile) &&
|
|
2541
2541
|
(pass == 0 ? tile.widget.compare(widget)
|
|
2542
|
-
: tile.widget.constructor == widget.constructor && widget.updateDOM(tile.dom, this.view))) {
|
|
2542
|
+
: tile.widget.constructor == widget.constructor && widget.updateDOM(tile.dom, this.view, tile.widget))) {
|
|
2543
2543
|
widgets.splice(i, 1);
|
|
2544
2544
|
if (i < this.index[0])
|
|
2545
2545
|
this.index[0]--;
|
|
@@ -3395,6 +3395,7 @@ class DocView {
|
|
|
3395
3395
|
this.blockWrappers = this.view.state.facet(blockWrappers).map(v => typeof v == "function" ? v(this.view) : v);
|
|
3396
3396
|
}
|
|
3397
3397
|
scrollIntoView(target) {
|
|
3398
|
+
var _a;
|
|
3398
3399
|
if (target.isSnapshot) {
|
|
3399
3400
|
let ref = this.view.viewState.lineBlockAt(target.range.head);
|
|
3400
3401
|
this.view.scrollDOM.scrollTop = ref.top - target.yMargin;
|
|
@@ -3411,7 +3412,7 @@ class DocView {
|
|
|
3411
3412
|
}
|
|
3412
3413
|
}
|
|
3413
3414
|
let { range } = target;
|
|
3414
|
-
let rect = this.coordsAt(range.head, range.
|
|
3415
|
+
let rect = this.coordsAt(range.head, (_a = range.assoc) !== null && _a !== void 0 ? _a : (range.empty ? 0 : range.head > range.anchor ? -1 : 1)), other;
|
|
3415
3416
|
if (!rect)
|
|
3416
3417
|
return;
|
|
3417
3418
|
if (!range.empty && (other = this.coordsAt(range.anchor, range.anchor > range.head ? -1 : 1)))
|
|
@@ -3678,7 +3679,8 @@ function moveVertically(view, start, forward, distance) {
|
|
|
3678
3679
|
return state.EditorSelection.cursor(startPos, start.assoc);
|
|
3679
3680
|
let goal = start.goalColumn, startY;
|
|
3680
3681
|
let rect = view.contentDOM.getBoundingClientRect();
|
|
3681
|
-
let startCoords = view.coordsAtPos(startPos, (start.empty ? start.
|
|
3682
|
+
let startCoords = view.coordsAtPos(startPos, start.assoc || ((start.empty ? forward : start.head == start.from) ? 1 : -1));
|
|
3683
|
+
let docTop = view.documentTop;
|
|
3682
3684
|
if (startCoords) {
|
|
3683
3685
|
if (goal == null)
|
|
3684
3686
|
goal = startCoords.left - rect.left;
|
|
@@ -3691,9 +3693,16 @@ function moveVertically(view, start, forward, distance) {
|
|
|
3691
3693
|
startY = (dir < 0 ? line.top : line.bottom) + docTop;
|
|
3692
3694
|
}
|
|
3693
3695
|
let resolvedGoal = rect.left + goal;
|
|
3694
|
-
let dist = distance !== null && distance !== void 0 ? distance :
|
|
3695
|
-
let
|
|
3696
|
-
|
|
3696
|
+
let halfText = view.viewState.heightOracle.textHeight >> 1, dist = distance !== null && distance !== void 0 ? distance : halfText;
|
|
3697
|
+
for (let scan = 0;; scan += halfText) {
|
|
3698
|
+
let y = startY + (dist + scan) * dir;
|
|
3699
|
+
let pos = posAtCoords(view, { x: resolvedGoal, y }, false, dir);
|
|
3700
|
+
if (forward ? y > rect.bottom : y < rect.top)
|
|
3701
|
+
return state.EditorSelection.cursor(pos.pos, pos.assoc);
|
|
3702
|
+
let posCoords = view.coordsAtPos(pos.pos, pos.assoc), mid = posCoords ? (posCoords.top + posCoords.bottom) / 2 : 0;
|
|
3703
|
+
if (!posCoords || (forward ? mid > startY : mid < startY))
|
|
3704
|
+
return state.EditorSelection.cursor(pos.pos, pos.assoc, undefined, goal);
|
|
3705
|
+
}
|
|
3697
3706
|
}
|
|
3698
3707
|
function skipAtomicRanges(atoms, pos, bias) {
|
|
3699
3708
|
for (;;) {
|
|
@@ -4552,9 +4561,9 @@ class InputState {
|
|
|
4552
4561
|
// applyDOMChange, notify key handlers of it and reset to
|
|
4553
4562
|
// the state they produce.
|
|
4554
4563
|
let pending;
|
|
4555
|
-
if (browser.ios && !event.synthetic && !event.altKey && !event.metaKey &&
|
|
4564
|
+
if (browser.ios && !event.synthetic && !event.altKey && !event.metaKey && !event.shiftKey &&
|
|
4556
4565
|
((pending = PendingKeys.find(key => key.keyCode == event.keyCode)) && !event.ctrlKey ||
|
|
4557
|
-
EmacsyPendingKeys.indexOf(event.key) > -1 && event.ctrlKey
|
|
4566
|
+
EmacsyPendingKeys.indexOf(event.key) > -1 && event.ctrlKey)) {
|
|
4558
4567
|
this.pendingIOSKey = pending || event;
|
|
4559
4568
|
setTimeout(() => this.flushIOSKey(), 250);
|
|
4560
4569
|
return true;
|
|
@@ -4958,10 +4967,10 @@ function basicMouseSelection(view, event) {
|
|
|
4958
4967
|
if (start.pos != cur.pos && !extend) {
|
|
4959
4968
|
let startRange = rangeForClick(view, start.pos, start.assoc, type);
|
|
4960
4969
|
let from = Math.min(startRange.from, range.from), to = Math.max(startRange.to, range.to);
|
|
4961
|
-
range = from < range.from ? state.EditorSelection.range(from, to) : state.EditorSelection.range(to, from);
|
|
4970
|
+
range = from < range.from ? state.EditorSelection.range(from, to, range.assoc) : state.EditorSelection.range(to, from, range.assoc);
|
|
4962
4971
|
}
|
|
4963
4972
|
if (extend)
|
|
4964
|
-
return startSel.replaceRange(startSel.main.extend(range.from, range.to));
|
|
4973
|
+
return startSel.replaceRange(startSel.main.extend(range.from, range.to, range.assoc));
|
|
4965
4974
|
else if (multiple && type == 1 && startSel.ranges.length > 1 && (removed = removeRangeAround(startSel, cur.pos)))
|
|
4966
4975
|
return removed;
|
|
4967
4976
|
else if (multiple)
|
|
@@ -9454,7 +9463,7 @@ const cursorLayer = layer({
|
|
|
9454
9463
|
let prim = r == state$1.selection.main;
|
|
9455
9464
|
if (r.empty || conf.drawRangeCursor && !(prim && browser.ios && conf.iosSelectionHandles)) {
|
|
9456
9465
|
let className = prim ? "cm-cursor cm-cursor-primary" : "cm-cursor cm-cursor-secondary";
|
|
9457
|
-
let cursor = r.empty ? r : state.EditorSelection.cursor(r.head, r.
|
|
9466
|
+
let cursor = r.empty ? r : state.EditorSelection.cursor(r.head, r.assoc);
|
|
9458
9467
|
for (let piece of RectangleMarker.forRange(view, className, cursor))
|
|
9459
9468
|
cursors.push(piece);
|
|
9460
9469
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -224,7 +224,7 @@ declare abstract class WidgetType {
|
|
|
224
224
|
couldn't (in which case the widget will be redrawn). The default
|
|
225
225
|
implementation just returns false.
|
|
226
226
|
*/
|
|
227
|
-
updateDOM(dom: HTMLElement, view: EditorView): boolean;
|
|
227
|
+
updateDOM(dom: HTMLElement, view: EditorView, from: this): boolean;
|
|
228
228
|
/**
|
|
229
229
|
The estimated height this widget will have, to be used when
|
|
230
230
|
estimating the height of content that hasn't been drawn. May
|
package/dist/index.d.ts
CHANGED
|
@@ -224,7 +224,7 @@ declare abstract class WidgetType {
|
|
|
224
224
|
couldn't (in which case the widget will be redrawn). The default
|
|
225
225
|
implementation just returns false.
|
|
226
226
|
*/
|
|
227
|
-
updateDOM(dom: HTMLElement, view: EditorView): boolean;
|
|
227
|
+
updateDOM(dom: HTMLElement, view: EditorView, from: this): boolean;
|
|
228
228
|
/**
|
|
229
229
|
The estimated height this widget will have, to be used when
|
|
230
230
|
estimating the height of content that hasn't been drawn. May
|
package/dist/index.js
CHANGED
|
@@ -132,7 +132,7 @@ class WidgetType {
|
|
|
132
132
|
couldn't (in which case the widget will be redrawn). The default
|
|
133
133
|
implementation just returns false.
|
|
134
134
|
*/
|
|
135
|
-
updateDOM(dom, view) { return false; }
|
|
135
|
+
updateDOM(dom, view, from) { return false; }
|
|
136
136
|
/**
|
|
137
137
|
@internal
|
|
138
138
|
*/
|
|
@@ -2535,7 +2535,7 @@ class TileCache {
|
|
|
2535
2535
|
let tile = widgets[i];
|
|
2536
2536
|
if (!this.reused.has(tile) &&
|
|
2537
2537
|
(pass == 0 ? tile.widget.compare(widget)
|
|
2538
|
-
: tile.widget.constructor == widget.constructor && widget.updateDOM(tile.dom, this.view))) {
|
|
2538
|
+
: tile.widget.constructor == widget.constructor && widget.updateDOM(tile.dom, this.view, tile.widget))) {
|
|
2539
2539
|
widgets.splice(i, 1);
|
|
2540
2540
|
if (i < this.index[0])
|
|
2541
2541
|
this.index[0]--;
|
|
@@ -3391,6 +3391,7 @@ class DocView {
|
|
|
3391
3391
|
this.blockWrappers = this.view.state.facet(blockWrappers).map(v => typeof v == "function" ? v(this.view) : v);
|
|
3392
3392
|
}
|
|
3393
3393
|
scrollIntoView(target) {
|
|
3394
|
+
var _a;
|
|
3394
3395
|
if (target.isSnapshot) {
|
|
3395
3396
|
let ref = this.view.viewState.lineBlockAt(target.range.head);
|
|
3396
3397
|
this.view.scrollDOM.scrollTop = ref.top - target.yMargin;
|
|
@@ -3407,7 +3408,7 @@ class DocView {
|
|
|
3407
3408
|
}
|
|
3408
3409
|
}
|
|
3409
3410
|
let { range } = target;
|
|
3410
|
-
let rect = this.coordsAt(range.head, range.
|
|
3411
|
+
let rect = this.coordsAt(range.head, (_a = range.assoc) !== null && _a !== void 0 ? _a : (range.empty ? 0 : range.head > range.anchor ? -1 : 1)), other;
|
|
3411
3412
|
if (!rect)
|
|
3412
3413
|
return;
|
|
3413
3414
|
if (!range.empty && (other = this.coordsAt(range.anchor, range.anchor > range.head ? -1 : 1)))
|
|
@@ -3674,7 +3675,8 @@ function moveVertically(view, start, forward, distance) {
|
|
|
3674
3675
|
return EditorSelection.cursor(startPos, start.assoc);
|
|
3675
3676
|
let goal = start.goalColumn, startY;
|
|
3676
3677
|
let rect = view.contentDOM.getBoundingClientRect();
|
|
3677
|
-
let startCoords = view.coordsAtPos(startPos, (start.empty ? start.
|
|
3678
|
+
let startCoords = view.coordsAtPos(startPos, start.assoc || ((start.empty ? forward : start.head == start.from) ? 1 : -1));
|
|
3679
|
+
let docTop = view.documentTop;
|
|
3678
3680
|
if (startCoords) {
|
|
3679
3681
|
if (goal == null)
|
|
3680
3682
|
goal = startCoords.left - rect.left;
|
|
@@ -3687,9 +3689,16 @@ function moveVertically(view, start, forward, distance) {
|
|
|
3687
3689
|
startY = (dir < 0 ? line.top : line.bottom) + docTop;
|
|
3688
3690
|
}
|
|
3689
3691
|
let resolvedGoal = rect.left + goal;
|
|
3690
|
-
let dist = distance !== null && distance !== void 0 ? distance :
|
|
3691
|
-
let
|
|
3692
|
-
|
|
3692
|
+
let halfText = view.viewState.heightOracle.textHeight >> 1, dist = distance !== null && distance !== void 0 ? distance : halfText;
|
|
3693
|
+
for (let scan = 0;; scan += halfText) {
|
|
3694
|
+
let y = startY + (dist + scan) * dir;
|
|
3695
|
+
let pos = posAtCoords(view, { x: resolvedGoal, y }, false, dir);
|
|
3696
|
+
if (forward ? y > rect.bottom : y < rect.top)
|
|
3697
|
+
return EditorSelection.cursor(pos.pos, pos.assoc);
|
|
3698
|
+
let posCoords = view.coordsAtPos(pos.pos, pos.assoc), mid = posCoords ? (posCoords.top + posCoords.bottom) / 2 : 0;
|
|
3699
|
+
if (!posCoords || (forward ? mid > startY : mid < startY))
|
|
3700
|
+
return EditorSelection.cursor(pos.pos, pos.assoc, undefined, goal);
|
|
3701
|
+
}
|
|
3693
3702
|
}
|
|
3694
3703
|
function skipAtomicRanges(atoms, pos, bias) {
|
|
3695
3704
|
for (;;) {
|
|
@@ -4548,9 +4557,9 @@ class InputState {
|
|
|
4548
4557
|
// applyDOMChange, notify key handlers of it and reset to
|
|
4549
4558
|
// the state they produce.
|
|
4550
4559
|
let pending;
|
|
4551
|
-
if (browser.ios && !event.synthetic && !event.altKey && !event.metaKey &&
|
|
4560
|
+
if (browser.ios && !event.synthetic && !event.altKey && !event.metaKey && !event.shiftKey &&
|
|
4552
4561
|
((pending = PendingKeys.find(key => key.keyCode == event.keyCode)) && !event.ctrlKey ||
|
|
4553
|
-
EmacsyPendingKeys.indexOf(event.key) > -1 && event.ctrlKey
|
|
4562
|
+
EmacsyPendingKeys.indexOf(event.key) > -1 && event.ctrlKey)) {
|
|
4554
4563
|
this.pendingIOSKey = pending || event;
|
|
4555
4564
|
setTimeout(() => this.flushIOSKey(), 250);
|
|
4556
4565
|
return true;
|
|
@@ -4954,10 +4963,10 @@ function basicMouseSelection(view, event) {
|
|
|
4954
4963
|
if (start.pos != cur.pos && !extend) {
|
|
4955
4964
|
let startRange = rangeForClick(view, start.pos, start.assoc, type);
|
|
4956
4965
|
let from = Math.min(startRange.from, range.from), to = Math.max(startRange.to, range.to);
|
|
4957
|
-
range = from < range.from ? EditorSelection.range(from, to) : EditorSelection.range(to, from);
|
|
4966
|
+
range = from < range.from ? EditorSelection.range(from, to, range.assoc) : EditorSelection.range(to, from, range.assoc);
|
|
4958
4967
|
}
|
|
4959
4968
|
if (extend)
|
|
4960
|
-
return startSel.replaceRange(startSel.main.extend(range.from, range.to));
|
|
4969
|
+
return startSel.replaceRange(startSel.main.extend(range.from, range.to, range.assoc));
|
|
4961
4970
|
else if (multiple && type == 1 && startSel.ranges.length > 1 && (removed = removeRangeAround(startSel, cur.pos)))
|
|
4962
4971
|
return removed;
|
|
4963
4972
|
else if (multiple)
|
|
@@ -9449,7 +9458,7 @@ const cursorLayer = /*@__PURE__*/layer({
|
|
|
9449
9458
|
let prim = r == state.selection.main;
|
|
9450
9459
|
if (r.empty || conf.drawRangeCursor && !(prim && browser.ios && conf.iosSelectionHandles)) {
|
|
9451
9460
|
let className = prim ? "cm-cursor cm-cursor-primary" : "cm-cursor cm-cursor-secondary";
|
|
9452
|
-
let cursor = r.empty ? r : EditorSelection.cursor(r.head, r.
|
|
9461
|
+
let cursor = r.empty ? r : EditorSelection.cursor(r.head, r.assoc);
|
|
9453
9462
|
for (let piece of RectangleMarker.forRange(view, className, cursor))
|
|
9454
9463
|
cursors.push(piece);
|
|
9455
9464
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codemirror/view",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.40.0",
|
|
4
4
|
"description": "DOM view component for the CodeMirror code editor",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "cm-runtests",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"sideEffects": false,
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@codemirror/state": "^6.
|
|
29
|
+
"@codemirror/state": "^6.6.0",
|
|
30
30
|
"crelt": "^1.0.6",
|
|
31
31
|
"style-mod": "^4.1.0",
|
|
32
32
|
"w3c-keyname": "^2.2.4"
|