@codemirror/view 6.39.7 → 6.39.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/index.cjs +32 -9
- package/dist/index.js +32 -9
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## 6.39.9 (2026-01-06)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Fix a bug where `EditorSelection.cursor()` with a non-zero `assoc` value would not be visually respected at soft-wrap boundaries on initial view creation.
|
|
6
|
+
|
|
7
|
+
Fix error caused by hover tooltips running a scheduled timeout after their editor has been destroyed.
|
|
8
|
+
|
|
9
|
+
Fix a bug that caused `EditorView.outerDecorations` to not affect the content height map.
|
|
10
|
+
|
|
11
|
+
Fix an issue where composition near a widget could get unnecessarily interrupted.
|
|
12
|
+
|
|
13
|
+
## 6.39.8 (2025-12-30)
|
|
14
|
+
|
|
15
|
+
### Bug fixes
|
|
16
|
+
|
|
17
|
+
Fix a bug that cause `coordsAtPos` to use the dimensions of widget buffers when there were more meaningful elements to use nearby.
|
|
18
|
+
|
|
19
|
+
Fix a data structure corruption that could cause crashes during viewport changes.
|
|
20
|
+
|
|
1
21
|
## 6.39.7 (2025-12-24)
|
|
2
22
|
|
|
3
23
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -2149,7 +2149,7 @@ class WidgetBufferTile extends Tile {
|
|
|
2149
2149
|
img.setAttribute("aria-hidden", "true");
|
|
2150
2150
|
super(img, 0, flags);
|
|
2151
2151
|
}
|
|
2152
|
-
get isHidden() { return
|
|
2152
|
+
get isHidden() { return true; }
|
|
2153
2153
|
get overrideDOMText() { return state.Text.empty; }
|
|
2154
2154
|
coordsIn(pos) { return this.dom.getBoundingClientRect(); }
|
|
2155
2155
|
}
|
|
@@ -2502,6 +2502,8 @@ class TileCache {
|
|
|
2502
2502
|
}
|
|
2503
2503
|
// Put a tile in the cache.
|
|
2504
2504
|
add(tile) {
|
|
2505
|
+
if (tile.demo)
|
|
2506
|
+
console.log("Add widget to cache");
|
|
2505
2507
|
let i = tile.constructor.bucket, bucket = this.buckets[i];
|
|
2506
2508
|
if (bucket.length < 6 /* C.Bucket */)
|
|
2507
2509
|
bucket.push(tile);
|
|
@@ -2526,6 +2528,8 @@ class TileCache {
|
|
|
2526
2528
|
}
|
|
2527
2529
|
findWidget(widget, length, flags) {
|
|
2528
2530
|
let widgets = this.buckets[0];
|
|
2531
|
+
if (widget.demo)
|
|
2532
|
+
console.log("looking for widget", widget, "in cache", widgets.slice());
|
|
2529
2533
|
if (widgets.length)
|
|
2530
2534
|
for (let i = 0, pass = 0;; i++) {
|
|
2531
2535
|
if (i == widgets.length) {
|
|
@@ -2541,10 +2545,14 @@ class TileCache {
|
|
|
2541
2545
|
widgets.splice(i, 1);
|
|
2542
2546
|
if (i < this.index[0])
|
|
2543
2547
|
this.index[0]--;
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
+
if (tile.length == length && (tile.flags & (496 /* TileFlag.Widget */ | 1 /* TileFlag.BreakAfter */)) == flags) {
|
|
2549
|
+
this.reused.set(tile, 1 /* Reused.Full */);
|
|
2550
|
+
return tile;
|
|
2551
|
+
}
|
|
2552
|
+
else {
|
|
2553
|
+
this.reused.set(tile, 2 /* Reused.DOM */);
|
|
2554
|
+
return new WidgetTile(tile.dom, length, widget, (tile.flags & ~(496 /* TileFlag.Widget */ | 1 /* TileFlag.BreakAfter */)) | flags);
|
|
2555
|
+
}
|
|
2548
2556
|
}
|
|
2549
2557
|
}
|
|
2550
2558
|
}
|
|
@@ -2558,6 +2566,10 @@ class TileCache {
|
|
|
2558
2566
|
this.reused.set(tile, type);
|
|
2559
2567
|
return tile.dom;
|
|
2560
2568
|
}
|
|
2569
|
+
clear() {
|
|
2570
|
+
for (let i = 0; i < this.buckets.length; i++)
|
|
2571
|
+
this.buckets[i].length = this.index[i] = 0;
|
|
2572
|
+
}
|
|
2561
2573
|
}
|
|
2562
2574
|
// This class organizes a pass over the document, guided by the array
|
|
2563
2575
|
// of replaced ranges. For ranges that haven't changed, it iterates
|
|
@@ -2600,17 +2612,20 @@ class TileUpdate {
|
|
|
2600
2612
|
}
|
|
2601
2613
|
if (!next)
|
|
2602
2614
|
break;
|
|
2603
|
-
this.forward(next.fromA, next.toA);
|
|
2604
2615
|
// Compositions need to be handled specially, forcing the
|
|
2605
2616
|
// focused text node and its parent nodes to remain stable at
|
|
2606
2617
|
// that point in the document.
|
|
2607
2618
|
if (composition && next.fromA <= composition.range.fromA && next.toA >= composition.range.toA) {
|
|
2619
|
+
this.forward(next.fromA, composition.range.fromA);
|
|
2608
2620
|
this.emit(posB, composition.range.fromB);
|
|
2621
|
+
this.cache.clear(); // Must not reuse DOM across composition
|
|
2609
2622
|
this.builder.addComposition(composition, compositionContext);
|
|
2610
2623
|
this.text.skip(composition.range.toB - composition.range.fromB);
|
|
2624
|
+
this.forward(composition.range.fromA, next.toA);
|
|
2611
2625
|
this.emit(composition.range.toB, next.toB);
|
|
2612
2626
|
}
|
|
2613
2627
|
else {
|
|
2628
|
+
this.forward(next.fromA, next.toA);
|
|
2614
2629
|
this.emit(posB, next.toB);
|
|
2615
2630
|
}
|
|
2616
2631
|
posB = next.toB;
|
|
@@ -6023,7 +6038,7 @@ class ViewState {
|
|
|
6023
6038
|
this.mustEnforceCursorAssoc = false;
|
|
6024
6039
|
let guessWrapping = state$1.facet(contentAttributes).some(v => typeof v != "function" && v.class == "cm-lineWrapping");
|
|
6025
6040
|
this.heightOracle = new HeightOracle(guessWrapping);
|
|
6026
|
-
this.stateDeco = state$1
|
|
6041
|
+
this.stateDeco = staticDeco(state$1);
|
|
6027
6042
|
this.heightMap = HeightMap.empty().applyChanges(this.stateDeco, state.Text.empty, this.heightOracle.setDoc(state$1.doc), [new ChangedRange(0, 0, 0, state$1.doc.length)]);
|
|
6028
6043
|
for (let i = 0; i < 2; i++) {
|
|
6029
6044
|
this.viewport = this.getViewport(0, null);
|
|
@@ -6062,7 +6077,7 @@ class ViewState {
|
|
|
6062
6077
|
update(update, scrollTarget = null) {
|
|
6063
6078
|
this.state = update.state;
|
|
6064
6079
|
let prevDeco = this.stateDeco;
|
|
6065
|
-
this.stateDeco = this.state
|
|
6080
|
+
this.stateDeco = staticDeco(this.state);
|
|
6066
6081
|
let contentChanges = update.changedRanges;
|
|
6067
6082
|
let heightChanges = ChangedRange.extendWithRanges(contentChanges, heightRelevantDecoChanges(prevDeco, this.stateDeco, update ? update.changes : state.ChangeSet.empty(this.state.doc.length)));
|
|
6068
6083
|
let prevHeight = this.heightMap.height;
|
|
@@ -6093,7 +6108,7 @@ class ViewState {
|
|
|
6093
6108
|
update.flags |= this.computeVisibleRanges(update.changes);
|
|
6094
6109
|
if (scrollTarget)
|
|
6095
6110
|
this.scrollTarget = scrollTarget;
|
|
6096
|
-
if (!this.mustEnforceCursorAssoc && update.selectionSet && update.view.lineWrapping &&
|
|
6111
|
+
if (!this.mustEnforceCursorAssoc && (update.selectionSet || update.focusChanged) && update.view.lineWrapping &&
|
|
6097
6112
|
update.state.selection.main.empty && update.state.selection.main.assoc &&
|
|
6098
6113
|
!update.state.facet(nativeSelectionHidden))
|
|
6099
6114
|
this.mustEnforceCursorAssoc = true;
|
|
@@ -6491,6 +6506,13 @@ const IdScaler = {
|
|
|
6491
6506
|
scale: 1,
|
|
6492
6507
|
eq(other) { return other == this; }
|
|
6493
6508
|
};
|
|
6509
|
+
function staticDeco(state$1) {
|
|
6510
|
+
let deco = state$1.facet(decorations).filter(d => typeof d != "function");
|
|
6511
|
+
let outer = state$1.facet(outerDecorations).filter(d => typeof d != "function");
|
|
6512
|
+
if (outer.length)
|
|
6513
|
+
deco.push(state.RangeSet.join(outer));
|
|
6514
|
+
return deco;
|
|
6515
|
+
}
|
|
6494
6516
|
// When the height is too big (> VP.MaxDOMHeight), scale down the
|
|
6495
6517
|
// regions outside the viewports so that the total height is
|
|
6496
6518
|
// VP.MaxDOMHeight.
|
|
@@ -10520,6 +10542,7 @@ class HoverPlugin {
|
|
|
10520
10542
|
}
|
|
10521
10543
|
destroy() {
|
|
10522
10544
|
clearTimeout(this.hoverTimeout);
|
|
10545
|
+
clearTimeout(this.restartTimeout);
|
|
10523
10546
|
this.view.dom.removeEventListener("mouseleave", this.mouseleave);
|
|
10524
10547
|
this.view.dom.removeEventListener("mousemove", this.mousemove);
|
|
10525
10548
|
}
|
package/dist/index.js
CHANGED
|
@@ -2145,7 +2145,7 @@ class WidgetBufferTile extends Tile {
|
|
|
2145
2145
|
img.setAttribute("aria-hidden", "true");
|
|
2146
2146
|
super(img, 0, flags);
|
|
2147
2147
|
}
|
|
2148
|
-
get isHidden() { return
|
|
2148
|
+
get isHidden() { return true; }
|
|
2149
2149
|
get overrideDOMText() { return Text.empty; }
|
|
2150
2150
|
coordsIn(pos) { return this.dom.getBoundingClientRect(); }
|
|
2151
2151
|
}
|
|
@@ -2498,6 +2498,8 @@ class TileCache {
|
|
|
2498
2498
|
}
|
|
2499
2499
|
// Put a tile in the cache.
|
|
2500
2500
|
add(tile) {
|
|
2501
|
+
if (tile.demo)
|
|
2502
|
+
console.log("Add widget to cache");
|
|
2501
2503
|
let i = tile.constructor.bucket, bucket = this.buckets[i];
|
|
2502
2504
|
if (bucket.length < 6 /* C.Bucket */)
|
|
2503
2505
|
bucket.push(tile);
|
|
@@ -2522,6 +2524,8 @@ class TileCache {
|
|
|
2522
2524
|
}
|
|
2523
2525
|
findWidget(widget, length, flags) {
|
|
2524
2526
|
let widgets = this.buckets[0];
|
|
2527
|
+
if (widget.demo)
|
|
2528
|
+
console.log("looking for widget", widget, "in cache", widgets.slice());
|
|
2525
2529
|
if (widgets.length)
|
|
2526
2530
|
for (let i = 0, pass = 0;; i++) {
|
|
2527
2531
|
if (i == widgets.length) {
|
|
@@ -2537,10 +2541,14 @@ class TileCache {
|
|
|
2537
2541
|
widgets.splice(i, 1);
|
|
2538
2542
|
if (i < this.index[0])
|
|
2539
2543
|
this.index[0]--;
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
+
if (tile.length == length && (tile.flags & (496 /* TileFlag.Widget */ | 1 /* TileFlag.BreakAfter */)) == flags) {
|
|
2545
|
+
this.reused.set(tile, 1 /* Reused.Full */);
|
|
2546
|
+
return tile;
|
|
2547
|
+
}
|
|
2548
|
+
else {
|
|
2549
|
+
this.reused.set(tile, 2 /* Reused.DOM */);
|
|
2550
|
+
return new WidgetTile(tile.dom, length, widget, (tile.flags & ~(496 /* TileFlag.Widget */ | 1 /* TileFlag.BreakAfter */)) | flags);
|
|
2551
|
+
}
|
|
2544
2552
|
}
|
|
2545
2553
|
}
|
|
2546
2554
|
}
|
|
@@ -2554,6 +2562,10 @@ class TileCache {
|
|
|
2554
2562
|
this.reused.set(tile, type);
|
|
2555
2563
|
return tile.dom;
|
|
2556
2564
|
}
|
|
2565
|
+
clear() {
|
|
2566
|
+
for (let i = 0; i < this.buckets.length; i++)
|
|
2567
|
+
this.buckets[i].length = this.index[i] = 0;
|
|
2568
|
+
}
|
|
2557
2569
|
}
|
|
2558
2570
|
// This class organizes a pass over the document, guided by the array
|
|
2559
2571
|
// of replaced ranges. For ranges that haven't changed, it iterates
|
|
@@ -2596,17 +2608,20 @@ class TileUpdate {
|
|
|
2596
2608
|
}
|
|
2597
2609
|
if (!next)
|
|
2598
2610
|
break;
|
|
2599
|
-
this.forward(next.fromA, next.toA);
|
|
2600
2611
|
// Compositions need to be handled specially, forcing the
|
|
2601
2612
|
// focused text node and its parent nodes to remain stable at
|
|
2602
2613
|
// that point in the document.
|
|
2603
2614
|
if (composition && next.fromA <= composition.range.fromA && next.toA >= composition.range.toA) {
|
|
2615
|
+
this.forward(next.fromA, composition.range.fromA);
|
|
2604
2616
|
this.emit(posB, composition.range.fromB);
|
|
2617
|
+
this.cache.clear(); // Must not reuse DOM across composition
|
|
2605
2618
|
this.builder.addComposition(composition, compositionContext);
|
|
2606
2619
|
this.text.skip(composition.range.toB - composition.range.fromB);
|
|
2620
|
+
this.forward(composition.range.fromA, next.toA);
|
|
2607
2621
|
this.emit(composition.range.toB, next.toB);
|
|
2608
2622
|
}
|
|
2609
2623
|
else {
|
|
2624
|
+
this.forward(next.fromA, next.toA);
|
|
2610
2625
|
this.emit(posB, next.toB);
|
|
2611
2626
|
}
|
|
2612
2627
|
posB = next.toB;
|
|
@@ -6018,7 +6033,7 @@ class ViewState {
|
|
|
6018
6033
|
this.mustEnforceCursorAssoc = false;
|
|
6019
6034
|
let guessWrapping = state.facet(contentAttributes).some(v => typeof v != "function" && v.class == "cm-lineWrapping");
|
|
6020
6035
|
this.heightOracle = new HeightOracle(guessWrapping);
|
|
6021
|
-
this.stateDeco = state
|
|
6036
|
+
this.stateDeco = staticDeco(state);
|
|
6022
6037
|
this.heightMap = HeightMap.empty().applyChanges(this.stateDeco, Text.empty, this.heightOracle.setDoc(state.doc), [new ChangedRange(0, 0, 0, state.doc.length)]);
|
|
6023
6038
|
for (let i = 0; i < 2; i++) {
|
|
6024
6039
|
this.viewport = this.getViewport(0, null);
|
|
@@ -6057,7 +6072,7 @@ class ViewState {
|
|
|
6057
6072
|
update(update, scrollTarget = null) {
|
|
6058
6073
|
this.state = update.state;
|
|
6059
6074
|
let prevDeco = this.stateDeco;
|
|
6060
|
-
this.stateDeco = this.state
|
|
6075
|
+
this.stateDeco = staticDeco(this.state);
|
|
6061
6076
|
let contentChanges = update.changedRanges;
|
|
6062
6077
|
let heightChanges = ChangedRange.extendWithRanges(contentChanges, heightRelevantDecoChanges(prevDeco, this.stateDeco, update ? update.changes : ChangeSet.empty(this.state.doc.length)));
|
|
6063
6078
|
let prevHeight = this.heightMap.height;
|
|
@@ -6088,7 +6103,7 @@ class ViewState {
|
|
|
6088
6103
|
update.flags |= this.computeVisibleRanges(update.changes);
|
|
6089
6104
|
if (scrollTarget)
|
|
6090
6105
|
this.scrollTarget = scrollTarget;
|
|
6091
|
-
if (!this.mustEnforceCursorAssoc && update.selectionSet && update.view.lineWrapping &&
|
|
6106
|
+
if (!this.mustEnforceCursorAssoc && (update.selectionSet || update.focusChanged) && update.view.lineWrapping &&
|
|
6092
6107
|
update.state.selection.main.empty && update.state.selection.main.assoc &&
|
|
6093
6108
|
!update.state.facet(nativeSelectionHidden))
|
|
6094
6109
|
this.mustEnforceCursorAssoc = true;
|
|
@@ -6486,6 +6501,13 @@ const IdScaler = {
|
|
|
6486
6501
|
scale: 1,
|
|
6487
6502
|
eq(other) { return other == this; }
|
|
6488
6503
|
};
|
|
6504
|
+
function staticDeco(state) {
|
|
6505
|
+
let deco = state.facet(decorations).filter(d => typeof d != "function");
|
|
6506
|
+
let outer = state.facet(outerDecorations).filter(d => typeof d != "function");
|
|
6507
|
+
if (outer.length)
|
|
6508
|
+
deco.push(RangeSet.join(outer));
|
|
6509
|
+
return deco;
|
|
6510
|
+
}
|
|
6489
6511
|
// When the height is too big (> VP.MaxDOMHeight), scale down the
|
|
6490
6512
|
// regions outside the viewports so that the total height is
|
|
6491
6513
|
// VP.MaxDOMHeight.
|
|
@@ -10515,6 +10537,7 @@ class HoverPlugin {
|
|
|
10515
10537
|
}
|
|
10516
10538
|
destroy() {
|
|
10517
10539
|
clearTimeout(this.hoverTimeout);
|
|
10540
|
+
clearTimeout(this.restartTimeout);
|
|
10518
10541
|
this.view.dom.removeEventListener("mouseleave", this.mouseleave);
|
|
10519
10542
|
this.view.dom.removeEventListener("mousemove", this.mousemove);
|
|
10520
10543
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codemirror/view",
|
|
3
|
-
"version": "6.39.
|
|
3
|
+
"version": "6.39.9",
|
|
4
4
|
"description": "DOM view component for the CodeMirror code editor",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "cm-runtests",
|
|
@@ -36,6 +36,6 @@
|
|
|
36
36
|
},
|
|
37
37
|
"repository": {
|
|
38
38
|
"type": "git",
|
|
39
|
-
"url": "https://github.com/codemirror/view.git"
|
|
39
|
+
"url": "git+https://github.com/codemirror/view.git"
|
|
40
40
|
}
|
|
41
41
|
}
|