@codemirror/view 6.35.3 → 6.36.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 CHANGED
@@ -1,3 +1,21 @@
1
+ ## 6.36.1 (2024-12-19)
2
+
3
+ ### Bug fixes
4
+
5
+ Fix a crash in MatchDecorator when updating matches at the end of the document.
6
+
7
+ ## 6.36.0 (2024-12-17)
8
+
9
+ ### Bug fixes
10
+
11
+ Make selection rectangles verticaly align precisely, rather than introducing a slight overlap.
12
+
13
+ Fix an issue in `MatchDecorator` that caused it to fully rebuild its decorations on normal edits.
14
+
15
+ ### New features
16
+
17
+ View updates now have a `viewportMoved` flag that is only true when a viewport change originated from something other than mapping the viewport over a document change.
18
+
1
19
  ## 6.35.3 (2024-12-09)
2
20
 
3
21
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -2691,6 +2691,15 @@ class ViewUpdate {
2691
2691
  return (this.flags & 4 /* UpdateFlag.Viewport */) > 0;
2692
2692
  }
2693
2693
  /**
2694
+ Returns true when
2695
+ [`viewportChanged`](https://codemirror.net/6/docs/ref/#view.ViewUpdate.viewportChanged) is true
2696
+ and the viewport change is not just the result of mapping it in
2697
+ response to document changes.
2698
+ */
2699
+ get viewportMoved() {
2700
+ return (this.flags & 8 /* UpdateFlag.ViewportMoved */) > 0;
2701
+ }
2702
+ /**
2694
2703
  Indicates whether the height of a block element in the editor
2695
2704
  changed in this update.
2696
2705
  */
@@ -2702,7 +2711,7 @@ class ViewUpdate {
2702
2711
  editor, or elements within the editor, changed.
2703
2712
  */
2704
2713
  get geometryChanged() {
2705
- return this.docChanged || (this.flags & (8 /* UpdateFlag.Geometry */ | 2 /* UpdateFlag.Height */)) > 0;
2714
+ return this.docChanged || (this.flags & (16 /* UpdateFlag.Geometry */ | 2 /* UpdateFlag.Height */)) > 0;
2706
2715
  }
2707
2716
  /**
2708
2717
  True when this update indicates a focus change.
@@ -5929,7 +5938,7 @@ class ViewState {
5929
5938
  this.updateViewportLines();
5930
5939
  if (this.lineGaps.length || this.viewport.to - this.viewport.from > (2000 /* LG.Margin */ << 1))
5931
5940
  this.updateLineGaps(this.ensureLineGaps(this.mapLineGaps(this.lineGaps, update.changes)));
5932
- update.flags |= this.computeVisibleRanges();
5941
+ update.flags |= this.computeVisibleRanges(update.changes);
5933
5942
  if (scrollTarget)
5934
5943
  this.scrollTarget = scrollTarget;
5935
5944
  if (!this.mustEnforceCursorAssoc && update.selectionSet && update.view.lineWrapping &&
@@ -5954,7 +5963,7 @@ class ViewState {
5954
5963
  scaleY > .005 && Math.abs(this.scaleY - scaleY) > .005) {
5955
5964
  this.scaleX = scaleX;
5956
5965
  this.scaleY = scaleY;
5957
- result |= 8 /* UpdateFlag.Geometry */;
5966
+ result |= 16 /* UpdateFlag.Geometry */;
5958
5967
  refresh = measureContent = true;
5959
5968
  }
5960
5969
  }
@@ -5964,13 +5973,13 @@ class ViewState {
5964
5973
  if (this.paddingTop != paddingTop || this.paddingBottom != paddingBottom) {
5965
5974
  this.paddingTop = paddingTop;
5966
5975
  this.paddingBottom = paddingBottom;
5967
- result |= 8 /* UpdateFlag.Geometry */ | 2 /* UpdateFlag.Height */;
5976
+ result |= 16 /* UpdateFlag.Geometry */ | 2 /* UpdateFlag.Height */;
5968
5977
  }
5969
5978
  if (this.editorWidth != view.scrollDOM.clientWidth) {
5970
5979
  if (oracle.lineWrapping)
5971
5980
  measureContent = true;
5972
5981
  this.editorWidth = view.scrollDOM.clientWidth;
5973
- result |= 8 /* UpdateFlag.Geometry */;
5982
+ result |= 16 /* UpdateFlag.Geometry */;
5974
5983
  }
5975
5984
  let scrollTop = view.scrollDOM.scrollTop * this.scaleY;
5976
5985
  if (this.scrollTop != scrollTop) {
@@ -5994,7 +6003,7 @@ class ViewState {
5994
6003
  if (this.contentDOMWidth != contentWidth || this.editorHeight != view.scrollDOM.clientHeight) {
5995
6004
  this.contentDOMWidth = domRect.width;
5996
6005
  this.editorHeight = view.scrollDOM.clientHeight;
5997
- result |= 8 /* UpdateFlag.Geometry */;
6006
+ result |= 16 /* UpdateFlag.Geometry */;
5998
6007
  }
5999
6008
  if (measureContent) {
6000
6009
  let lineHeights = view.docView.measureVisibleLineHeights(this.viewport);
@@ -6005,7 +6014,7 @@ class ViewState {
6005
6014
  refresh = lineHeight > 0 && oracle.refresh(whiteSpace, lineHeight, charWidth, textHeight, contentWidth / charWidth, lineHeights);
6006
6015
  if (refresh) {
6007
6016
  view.docView.minWidth = 0;
6008
- result |= 8 /* UpdateFlag.Geometry */;
6017
+ result |= 16 /* UpdateFlag.Geometry */;
6009
6018
  }
6010
6019
  }
6011
6020
  if (dTop > 0 && dBottom > 0)
@@ -6218,7 +6227,7 @@ class ViewState {
6218
6227
  this.lineGapDeco = Decoration.set(gaps.map(gap => gap.draw(this, this.heightOracle.lineWrapping)));
6219
6228
  }
6220
6229
  }
6221
- computeVisibleRanges() {
6230
+ computeVisibleRanges(changes) {
6222
6231
  let deco = this.stateDeco;
6223
6232
  if (this.lineGaps.length)
6224
6233
  deco = deco.concat(this.lineGapDeco);
@@ -6227,10 +6236,22 @@ class ViewState {
6227
6236
  span(from, to) { ranges.push({ from, to }); },
6228
6237
  point() { }
6229
6238
  }, 20);
6230
- let changed = ranges.length != this.visibleRanges.length ||
6231
- this.visibleRanges.some((r, i) => r.from != ranges[i].from || r.to != ranges[i].to);
6239
+ let changed = 0;
6240
+ if (ranges.length != this.visibleRanges.length) {
6241
+ changed = 8 /* UpdateFlag.ViewportMoved */ | 4 /* UpdateFlag.Viewport */;
6242
+ }
6243
+ else {
6244
+ for (let i = 0; i < ranges.length && !(changed & 8 /* UpdateFlag.ViewportMoved */); i++) {
6245
+ let old = this.visibleRanges[i], nw = ranges[i];
6246
+ if (old.from != nw.from || old.to != nw.to) {
6247
+ changed |= 4 /* UpdateFlag.Viewport */;
6248
+ if (!(changes && changes.mapPos(old.from, -1) == nw.from && changes.mapPos(old.to, 1) == nw.to))
6249
+ changed |= 8 /* UpdateFlag.ViewportMoved */;
6250
+ }
6251
+ }
6252
+ }
6232
6253
  this.visibleRanges = ranges;
6233
- return changed ? 4 /* UpdateFlag.Viewport */ : 0;
6254
+ return changed;
6234
6255
  }
6235
6256
  lineBlockAt(pos) {
6236
6257
  return (pos >= this.viewport.from && pos <= this.viewport.to &&
@@ -8845,7 +8866,7 @@ function rectanglesForRange(view, className, range) {
8845
8866
  return pieces(top).concat(between).concat(pieces(bottom));
8846
8867
  }
8847
8868
  function piece(left, top, right, bottom) {
8848
- return new RectangleMarker(className, left - base.left, top - base.top - 0.01 /* C.Epsilon */, right - left, bottom - top + 0.01 /* C.Epsilon */);
8869
+ return new RectangleMarker(className, left - base.left, top - base.top, right - left, bottom - top);
8849
8870
  }
8850
8871
  function pieces({ top, bottom, horizontal }) {
8851
8872
  let pieces = [];
@@ -9272,12 +9293,12 @@ class MatchDecorator {
9272
9293
  let changeFrom = 1e9, changeTo = -1;
9273
9294
  if (update.docChanged)
9274
9295
  update.changes.iterChanges((_f, _t, from, to) => {
9275
- if (to > update.view.viewport.from && from < update.view.viewport.to) {
9296
+ if (to >= update.view.viewport.from && from <= update.view.viewport.to) {
9276
9297
  changeFrom = Math.min(from, changeFrom);
9277
9298
  changeTo = Math.max(to, changeTo);
9278
9299
  }
9279
9300
  });
9280
- if (update.viewportChanged || changeTo - changeFrom > 1000)
9301
+ if (update.viewportMoved || changeTo - changeFrom > 1000)
9281
9302
  return this.createDeco(update.view);
9282
9303
  if (changeTo > -1)
9283
9304
  return this.updateRange(update.view, deco.map(update.changes), changeFrom, changeTo);
package/dist/index.d.cts CHANGED
@@ -523,6 +523,13 @@ declare class ViewUpdate {
523
523
  */
524
524
  get viewportChanged(): boolean;
525
525
  /**
526
+ Returns true when
527
+ [`viewportChanged`](https://codemirror.net/6/docs/ref/#view.ViewUpdate.viewportChanged) is true
528
+ and the viewport change is not just the result of mapping it in
529
+ response to document changes.
530
+ */
531
+ get viewportMoved(): boolean;
532
+ /**
526
533
  Indicates whether the height of a block element in the editor
527
534
  changed in this update.
528
535
  */
package/dist/index.d.ts CHANGED
@@ -523,6 +523,13 @@ declare class ViewUpdate {
523
523
  */
524
524
  get viewportChanged(): boolean;
525
525
  /**
526
+ Returns true when
527
+ [`viewportChanged`](https://codemirror.net/6/docs/ref/#view.ViewUpdate.viewportChanged) is true
528
+ and the viewport change is not just the result of mapping it in
529
+ response to document changes.
530
+ */
531
+ get viewportMoved(): boolean;
532
+ /**
526
533
  Indicates whether the height of a block element in the editor
527
534
  changed in this update.
528
535
  */
package/dist/index.js CHANGED
@@ -2687,6 +2687,15 @@ class ViewUpdate {
2687
2687
  return (this.flags & 4 /* UpdateFlag.Viewport */) > 0;
2688
2688
  }
2689
2689
  /**
2690
+ Returns true when
2691
+ [`viewportChanged`](https://codemirror.net/6/docs/ref/#view.ViewUpdate.viewportChanged) is true
2692
+ and the viewport change is not just the result of mapping it in
2693
+ response to document changes.
2694
+ */
2695
+ get viewportMoved() {
2696
+ return (this.flags & 8 /* UpdateFlag.ViewportMoved */) > 0;
2697
+ }
2698
+ /**
2690
2699
  Indicates whether the height of a block element in the editor
2691
2700
  changed in this update.
2692
2701
  */
@@ -2698,7 +2707,7 @@ class ViewUpdate {
2698
2707
  editor, or elements within the editor, changed.
2699
2708
  */
2700
2709
  get geometryChanged() {
2701
- return this.docChanged || (this.flags & (8 /* UpdateFlag.Geometry */ | 2 /* UpdateFlag.Height */)) > 0;
2710
+ return this.docChanged || (this.flags & (16 /* UpdateFlag.Geometry */ | 2 /* UpdateFlag.Height */)) > 0;
2702
2711
  }
2703
2712
  /**
2704
2713
  True when this update indicates a focus change.
@@ -5924,7 +5933,7 @@ class ViewState {
5924
5933
  this.updateViewportLines();
5925
5934
  if (this.lineGaps.length || this.viewport.to - this.viewport.from > (2000 /* LG.Margin */ << 1))
5926
5935
  this.updateLineGaps(this.ensureLineGaps(this.mapLineGaps(this.lineGaps, update.changes)));
5927
- update.flags |= this.computeVisibleRanges();
5936
+ update.flags |= this.computeVisibleRanges(update.changes);
5928
5937
  if (scrollTarget)
5929
5938
  this.scrollTarget = scrollTarget;
5930
5939
  if (!this.mustEnforceCursorAssoc && update.selectionSet && update.view.lineWrapping &&
@@ -5949,7 +5958,7 @@ class ViewState {
5949
5958
  scaleY > .005 && Math.abs(this.scaleY - scaleY) > .005) {
5950
5959
  this.scaleX = scaleX;
5951
5960
  this.scaleY = scaleY;
5952
- result |= 8 /* UpdateFlag.Geometry */;
5961
+ result |= 16 /* UpdateFlag.Geometry */;
5953
5962
  refresh = measureContent = true;
5954
5963
  }
5955
5964
  }
@@ -5959,13 +5968,13 @@ class ViewState {
5959
5968
  if (this.paddingTop != paddingTop || this.paddingBottom != paddingBottom) {
5960
5969
  this.paddingTop = paddingTop;
5961
5970
  this.paddingBottom = paddingBottom;
5962
- result |= 8 /* UpdateFlag.Geometry */ | 2 /* UpdateFlag.Height */;
5971
+ result |= 16 /* UpdateFlag.Geometry */ | 2 /* UpdateFlag.Height */;
5963
5972
  }
5964
5973
  if (this.editorWidth != view.scrollDOM.clientWidth) {
5965
5974
  if (oracle.lineWrapping)
5966
5975
  measureContent = true;
5967
5976
  this.editorWidth = view.scrollDOM.clientWidth;
5968
- result |= 8 /* UpdateFlag.Geometry */;
5977
+ result |= 16 /* UpdateFlag.Geometry */;
5969
5978
  }
5970
5979
  let scrollTop = view.scrollDOM.scrollTop * this.scaleY;
5971
5980
  if (this.scrollTop != scrollTop) {
@@ -5989,7 +5998,7 @@ class ViewState {
5989
5998
  if (this.contentDOMWidth != contentWidth || this.editorHeight != view.scrollDOM.clientHeight) {
5990
5999
  this.contentDOMWidth = domRect.width;
5991
6000
  this.editorHeight = view.scrollDOM.clientHeight;
5992
- result |= 8 /* UpdateFlag.Geometry */;
6001
+ result |= 16 /* UpdateFlag.Geometry */;
5993
6002
  }
5994
6003
  if (measureContent) {
5995
6004
  let lineHeights = view.docView.measureVisibleLineHeights(this.viewport);
@@ -6000,7 +6009,7 @@ class ViewState {
6000
6009
  refresh = lineHeight > 0 && oracle.refresh(whiteSpace, lineHeight, charWidth, textHeight, contentWidth / charWidth, lineHeights);
6001
6010
  if (refresh) {
6002
6011
  view.docView.minWidth = 0;
6003
- result |= 8 /* UpdateFlag.Geometry */;
6012
+ result |= 16 /* UpdateFlag.Geometry */;
6004
6013
  }
6005
6014
  }
6006
6015
  if (dTop > 0 && dBottom > 0)
@@ -6213,7 +6222,7 @@ class ViewState {
6213
6222
  this.lineGapDeco = Decoration.set(gaps.map(gap => gap.draw(this, this.heightOracle.lineWrapping)));
6214
6223
  }
6215
6224
  }
6216
- computeVisibleRanges() {
6225
+ computeVisibleRanges(changes) {
6217
6226
  let deco = this.stateDeco;
6218
6227
  if (this.lineGaps.length)
6219
6228
  deco = deco.concat(this.lineGapDeco);
@@ -6222,10 +6231,22 @@ class ViewState {
6222
6231
  span(from, to) { ranges.push({ from, to }); },
6223
6232
  point() { }
6224
6233
  }, 20);
6225
- let changed = ranges.length != this.visibleRanges.length ||
6226
- this.visibleRanges.some((r, i) => r.from != ranges[i].from || r.to != ranges[i].to);
6234
+ let changed = 0;
6235
+ if (ranges.length != this.visibleRanges.length) {
6236
+ changed = 8 /* UpdateFlag.ViewportMoved */ | 4 /* UpdateFlag.Viewport */;
6237
+ }
6238
+ else {
6239
+ for (let i = 0; i < ranges.length && !(changed & 8 /* UpdateFlag.ViewportMoved */); i++) {
6240
+ let old = this.visibleRanges[i], nw = ranges[i];
6241
+ if (old.from != nw.from || old.to != nw.to) {
6242
+ changed |= 4 /* UpdateFlag.Viewport */;
6243
+ if (!(changes && changes.mapPos(old.from, -1) == nw.from && changes.mapPos(old.to, 1) == nw.to))
6244
+ changed |= 8 /* UpdateFlag.ViewportMoved */;
6245
+ }
6246
+ }
6247
+ }
6227
6248
  this.visibleRanges = ranges;
6228
- return changed ? 4 /* UpdateFlag.Viewport */ : 0;
6249
+ return changed;
6229
6250
  }
6230
6251
  lineBlockAt(pos) {
6231
6252
  return (pos >= this.viewport.from && pos <= this.viewport.to &&
@@ -8840,7 +8861,7 @@ function rectanglesForRange(view, className, range) {
8840
8861
  return pieces(top).concat(between).concat(pieces(bottom));
8841
8862
  }
8842
8863
  function piece(left, top, right, bottom) {
8843
- return new RectangleMarker(className, left - base.left, top - base.top - 0.01 /* C.Epsilon */, right - left, bottom - top + 0.01 /* C.Epsilon */);
8864
+ return new RectangleMarker(className, left - base.left, top - base.top, right - left, bottom - top);
8844
8865
  }
8845
8866
  function pieces({ top, bottom, horizontal }) {
8846
8867
  let pieces = [];
@@ -9267,12 +9288,12 @@ class MatchDecorator {
9267
9288
  let changeFrom = 1e9, changeTo = -1;
9268
9289
  if (update.docChanged)
9269
9290
  update.changes.iterChanges((_f, _t, from, to) => {
9270
- if (to > update.view.viewport.from && from < update.view.viewport.to) {
9291
+ if (to >= update.view.viewport.from && from <= update.view.viewport.to) {
9271
9292
  changeFrom = Math.min(from, changeFrom);
9272
9293
  changeTo = Math.max(to, changeTo);
9273
9294
  }
9274
9295
  });
9275
- if (update.viewportChanged || changeTo - changeFrom > 1000)
9296
+ if (update.viewportMoved || changeTo - changeFrom > 1000)
9276
9297
  return this.createDeco(update.view);
9277
9298
  if (changeTo > -1)
9278
9299
  return this.updateRange(update.view, deco.map(update.changes), changeFrom, changeTo);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/view",
3
- "version": "6.35.3",
3
+ "version": "6.36.1",
4
4
  "description": "DOM view component for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",