@codemirror/view 6.4.0 → 6.4.2

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,23 @@
1
+ ## 6.4.2 (2022-11-10)
2
+
3
+ ### Bug fixes
4
+
5
+ Typing into a read-only editor no longer moves the cursor.
6
+
7
+ Fix an issue where hover tooltips were closed when the mouse was moved over them if they had a custom parent element.
8
+
9
+ Fix an issue where the editor could end up displaying incorrect height measurements (typically after initializing).
10
+
11
+ ## 6.4.1 (2022-11-07)
12
+
13
+ ### Bug fixes
14
+
15
+ Fix an issue where coordinates next to replaced widgets were returned incorrectly, causing the cursor to be drawn in the wrong place.
16
+
17
+ Update the `crosshairCursor` state on every mousemove event.
18
+
19
+ 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.
20
+
1
21
  ## 6.4.0 (2022-10-18)
2
22
 
3
23
  ### 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() {
@@ -1766,6 +1766,9 @@ const inputHandler = state.Facet.define();
1766
1766
  const perLineTextDirection = state.Facet.define({
1767
1767
  combine: values => values.some(x => x)
1768
1768
  });
1769
+ const nativeSelectionHidden = state.Facet.define({
1770
+ combine: values => values.some(x => x)
1771
+ });
1769
1772
  class ScrollTarget {
1770
1773
  constructor(range, y = "nearest", x = "nearest", yMargin = 5, xMargin = 5) {
1771
1774
  this.range = range;
@@ -2679,8 +2682,9 @@ class DocView extends ContentView {
2679
2682
  enforceCursorAssoc() {
2680
2683
  if (this.compositionDeco.size)
2681
2684
  return;
2682
- let cursor = this.view.state.selection.main;
2683
- let sel = getSelection(this.view.root);
2685
+ let { view } = this, cursor = view.state.selection.main;
2686
+ let sel = getSelection(view.root);
2687
+ let { anchorNode, anchorOffset } = view.observer.selectionRange;
2684
2688
  if (!sel || !cursor.empty || !cursor.assoc || !sel.modify)
2685
2689
  return;
2686
2690
  let line = LineView.find(this, cursor.head);
@@ -2695,6 +2699,12 @@ class DocView extends ContentView {
2695
2699
  let dom = this.domAtPos(cursor.head + cursor.assoc);
2696
2700
  sel.collapse(dom.node, dom.offset);
2697
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);
2698
2708
  }
2699
2709
  mayControlSelection() {
2700
2710
  let active = this.view.root.activeElement;
@@ -4779,7 +4789,7 @@ class ViewState {
4779
4789
  // Flag set when editor content was redrawn, so that the next
4780
4790
  // measure stage knows it must read DOM layout
4781
4791
  this.mustMeasureContent = true;
4782
- this.defaultTextDirection = exports.Direction.RTL;
4792
+ this.defaultTextDirection = exports.Direction.LTR;
4783
4793
  this.visibleRanges = [];
4784
4794
  // Cursor 'assoc' is only significant when the cursor is on a line
4785
4795
  // wrap point, where it must stick to the character that it is
@@ -4844,7 +4854,8 @@ class ViewState {
4844
4854
  if (scrollTarget)
4845
4855
  this.scrollTarget = scrollTarget;
4846
4856
  if (!this.mustEnforceCursorAssoc && update.selectionSet && update.view.lineWrapping &&
4847
- 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))
4848
4859
  this.mustEnforceCursorAssoc = true;
4849
4860
  }
4850
4861
  measure(view) {
@@ -4907,7 +4918,7 @@ class ViewState {
4907
4918
  oracle.heightChanged = false;
4908
4919
  for (let vp of this.viewports) {
4909
4920
  let heights = vp.from == this.viewport.from ? lineHeights : view.docView.measureVisibleLineHeights(vp);
4910
- this.heightMap = this.heightMap.updateHeight(oracle, 0, refresh, new MeasuredHeights(vp.from, heights));
4921
+ this.heightMap = (refresh ? HeightMap.empty().applyChanges(this.stateDeco, state.Text.empty, this.heightOracle, [new ChangedRange(0, 0, 0, view.state.doc.length)]) : this.heightMap).updateHeight(oracle, 0, refresh, new MeasuredHeights(vp.from, heights));
4911
4922
  }
4912
4923
  if (oracle.heightChanged)
4913
4924
  result |= 2 /* UpdateFlag.Height */;
@@ -5473,7 +5484,8 @@ class DOMChange {
5473
5484
  this.bounds = null;
5474
5485
  this.text = "";
5475
5486
  let { impreciseHead: iHead, impreciseAnchor: iAnchor } = view.docView;
5476
- if (start > -1 && !view.state.readOnly && (this.bounds = view.docView.domBoundsAround(start, end, 0))) {
5487
+ if (view.state.readOnly && start > -1) ;
5488
+ else if (start > -1 && (this.bounds = view.docView.domBoundsAround(start, end, 0))) {
5477
5489
  let selPoints = iHead || iAnchor ? [] : selectionPoints(view);
5478
5490
  let reader = new DOMReader(selPoints, view.state);
5479
5491
  reader.readRange(this.bounds.startDOM, this.bounds.endDOM);
@@ -5767,7 +5779,8 @@ class DOMObserver {
5767
5779
  this.onScroll = this.onScroll.bind(this);
5768
5780
  if (typeof ResizeObserver == "function") {
5769
5781
  this.resize = new ResizeObserver(() => {
5770
- if (this.view.docView.lastUpdate < Date.now() - 75)
5782
+ var _a;
5783
+ if (((_a = this.view.docView) === null || _a === void 0 ? void 0 : _a.lastUpdate) < Date.now() - 75)
5771
5784
  this.onResize();
5772
5785
  });
5773
5786
  this.resize.observe(view.scrollDOM);
@@ -7311,7 +7324,8 @@ function drawSelection(config = {}) {
7311
7324
  return [
7312
7325
  selectionConfig.of(config),
7313
7326
  drawSelectionPlugin,
7314
- hideNativeSelection
7327
+ hideNativeSelection,
7328
+ nativeSelectionHidden.of(true)
7315
7329
  ];
7316
7330
  }
7317
7331
  class Piece {
@@ -8096,6 +8110,9 @@ function crosshairCursor(options = {}) {
8096
8110
  keyup(e) {
8097
8111
  if (e.keyCode == code || !getter(e))
8098
8112
  this.set(false);
8113
+ },
8114
+ mousemove(e) {
8115
+ this.set(getter(e));
8099
8116
  }
8100
8117
  }
8101
8118
  });
@@ -8552,10 +8569,10 @@ class HoverPlugin {
8552
8569
  }
8553
8570
  }
8554
8571
  }
8555
- mouseleave() {
8572
+ mouseleave(e) {
8556
8573
  clearTimeout(this.hoverTimeout);
8557
8574
  this.hoverTimeout = -1;
8558
- if (this.active)
8575
+ if (this.active && !isInTooltip(e.relatedTarget))
8559
8576
  this.view.dispatch({ effects: this.setHover.of(null) });
8560
8577
  }
8561
8578
  destroy() {
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Text, RangeSet, MapMode, RangeValue, Facet, StateEffect, ChangeSet, findClusterBreak, EditorSelection, EditorState, findColumn, CharCategory, Prec, Transaction, codePointAt, codePointSize, combineConfig, StateField, RangeSetBuilder, countColumn } from '@codemirror/state';
1
+ import { Text, RangeSet, MapMode, RangeValue, Facet, StateEffect, ChangeSet, findClusterBreak, EditorSelection, EditorState, findColumn, CharCategory, Transaction, Prec, codePointAt, codePointSize, combineConfig, StateField, RangeSetBuilder, countColumn } from '@codemirror/state';
2
2
  import { StyleModule } from 'style-mod';
3
3
  import { keyName, base, shift } from 'w3c-keyname';
4
4
 
@@ -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() {
@@ -1761,6 +1761,9 @@ const inputHandler = /*@__PURE__*/Facet.define();
1761
1761
  const perLineTextDirection = /*@__PURE__*/Facet.define({
1762
1762
  combine: values => values.some(x => x)
1763
1763
  });
1764
+ const nativeSelectionHidden = /*@__PURE__*/Facet.define({
1765
+ combine: values => values.some(x => x)
1766
+ });
1764
1767
  class ScrollTarget {
1765
1768
  constructor(range, y = "nearest", x = "nearest", yMargin = 5, xMargin = 5) {
1766
1769
  this.range = range;
@@ -2673,8 +2676,9 @@ class DocView extends ContentView {
2673
2676
  enforceCursorAssoc() {
2674
2677
  if (this.compositionDeco.size)
2675
2678
  return;
2676
- let cursor = this.view.state.selection.main;
2677
- let sel = getSelection(this.view.root);
2679
+ let { view } = this, cursor = view.state.selection.main;
2680
+ let sel = getSelection(view.root);
2681
+ let { anchorNode, anchorOffset } = view.observer.selectionRange;
2678
2682
  if (!sel || !cursor.empty || !cursor.assoc || !sel.modify)
2679
2683
  return;
2680
2684
  let line = LineView.find(this, cursor.head);
@@ -2689,6 +2693,12 @@ class DocView extends ContentView {
2689
2693
  let dom = this.domAtPos(cursor.head + cursor.assoc);
2690
2694
  sel.collapse(dom.node, dom.offset);
2691
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);
2692
2702
  }
2693
2703
  mayControlSelection() {
2694
2704
  let active = this.view.root.activeElement;
@@ -4772,7 +4782,7 @@ class ViewState {
4772
4782
  // Flag set when editor content was redrawn, so that the next
4773
4783
  // measure stage knows it must read DOM layout
4774
4784
  this.mustMeasureContent = true;
4775
- this.defaultTextDirection = Direction.RTL;
4785
+ this.defaultTextDirection = Direction.LTR;
4776
4786
  this.visibleRanges = [];
4777
4787
  // Cursor 'assoc' is only significant when the cursor is on a line
4778
4788
  // wrap point, where it must stick to the character that it is
@@ -4837,7 +4847,8 @@ class ViewState {
4837
4847
  if (scrollTarget)
4838
4848
  this.scrollTarget = scrollTarget;
4839
4849
  if (!this.mustEnforceCursorAssoc && update.selectionSet && update.view.lineWrapping &&
4840
- 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))
4841
4852
  this.mustEnforceCursorAssoc = true;
4842
4853
  }
4843
4854
  measure(view) {
@@ -4900,7 +4911,7 @@ class ViewState {
4900
4911
  oracle.heightChanged = false;
4901
4912
  for (let vp of this.viewports) {
4902
4913
  let heights = vp.from == this.viewport.from ? lineHeights : view.docView.measureVisibleLineHeights(vp);
4903
- this.heightMap = this.heightMap.updateHeight(oracle, 0, refresh, new MeasuredHeights(vp.from, heights));
4914
+ this.heightMap = (refresh ? HeightMap.empty().applyChanges(this.stateDeco, Text.empty, this.heightOracle, [new ChangedRange(0, 0, 0, view.state.doc.length)]) : this.heightMap).updateHeight(oracle, 0, refresh, new MeasuredHeights(vp.from, heights));
4904
4915
  }
4905
4916
  if (oracle.heightChanged)
4906
4917
  result |= 2 /* UpdateFlag.Height */;
@@ -5466,7 +5477,8 @@ class DOMChange {
5466
5477
  this.bounds = null;
5467
5478
  this.text = "";
5468
5479
  let { impreciseHead: iHead, impreciseAnchor: iAnchor } = view.docView;
5469
- if (start > -1 && !view.state.readOnly && (this.bounds = view.docView.domBoundsAround(start, end, 0))) {
5480
+ if (view.state.readOnly && start > -1) ;
5481
+ else if (start > -1 && (this.bounds = view.docView.domBoundsAround(start, end, 0))) {
5470
5482
  let selPoints = iHead || iAnchor ? [] : selectionPoints(view);
5471
5483
  let reader = new DOMReader(selPoints, view.state);
5472
5484
  reader.readRange(this.bounds.startDOM, this.bounds.endDOM);
@@ -5760,7 +5772,8 @@ class DOMObserver {
5760
5772
  this.onScroll = this.onScroll.bind(this);
5761
5773
  if (typeof ResizeObserver == "function") {
5762
5774
  this.resize = new ResizeObserver(() => {
5763
- if (this.view.docView.lastUpdate < Date.now() - 75)
5775
+ var _a;
5776
+ if (((_a = this.view.docView) === null || _a === void 0 ? void 0 : _a.lastUpdate) < Date.now() - 75)
5764
5777
  this.onResize();
5765
5778
  });
5766
5779
  this.resize.observe(view.scrollDOM);
@@ -7304,7 +7317,8 @@ function drawSelection(config = {}) {
7304
7317
  return [
7305
7318
  selectionConfig.of(config),
7306
7319
  drawSelectionPlugin,
7307
- hideNativeSelection
7320
+ hideNativeSelection,
7321
+ nativeSelectionHidden.of(true)
7308
7322
  ];
7309
7323
  }
7310
7324
  class Piece {
@@ -8089,6 +8103,9 @@ function crosshairCursor(options = {}) {
8089
8103
  keyup(e) {
8090
8104
  if (e.keyCode == code || !getter(e))
8091
8105
  this.set(false);
8106
+ },
8107
+ mousemove(e) {
8108
+ this.set(getter(e));
8092
8109
  }
8093
8110
  }
8094
8111
  });
@@ -8545,10 +8562,10 @@ class HoverPlugin {
8545
8562
  }
8546
8563
  }
8547
8564
  }
8548
- mouseleave() {
8565
+ mouseleave(e) {
8549
8566
  clearTimeout(this.hoverTimeout);
8550
8567
  this.hoverTimeout = -1;
8551
- if (this.active)
8568
+ if (this.active && !isInTooltip(e.relatedTarget))
8552
8569
  this.view.dispatch({ effects: this.setHover.of(null) });
8553
8570
  }
8554
8571
  destroy() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/view",
3
- "version": "6.4.0",
3
+ "version": "6.4.2",
4
4
  "description": "DOM view component for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",