@codemirror/view 6.21.1 → 6.21.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 CHANGED
@@ -1,3 +1,19 @@
1
+ ## 6.21.3 (2023-10-06)
2
+
3
+ ### Bug fixes
4
+
5
+ Fix an issue that caused `coordsForChar` to return the wrong rectangle for characters after a line wrap in Safari.
6
+
7
+ Make the context menu work when clicking below the content in a fixed-height editor.
8
+
9
+ Tooltips that have been put below/above their target position because there is no room on their default side now stay there on further updates.
10
+
11
+ ## 6.21.2 (2023-10-02)
12
+
13
+ ### Bug fixes
14
+
15
+ Fix a regression that broke dragging text from inside the editor.
16
+
1
17
  ## 6.21.1 (2023-10-02)
2
18
 
3
19
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -2981,7 +2981,12 @@ class DocView extends ContentView {
2981
2981
  if (end == off)
2982
2982
  return null;
2983
2983
  let rects = textRange(child.dom, off, end).getClientRects();
2984
- return !rects.length || rects[0].top >= rects[0].bottom ? null : rects[0];
2984
+ for (let i = 0; i < rects.length; i++) {
2985
+ let rect = rects[i];
2986
+ if (i == rects.length - 1 || rect.top < rect.bottom && rect.left < rect.right)
2987
+ return rect;
2988
+ }
2989
+ return null;
2985
2990
  }
2986
2991
  measureVisibleLineHeights(viewport) {
2987
2992
  let result = [], { from, to } = viewport;
@@ -3635,22 +3640,6 @@ class InputState {
3635
3640
  this.compositionPendingChange = false;
3636
3641
  this.mouseSelection = null;
3637
3642
  this.handleEvent = this.handleEvent.bind(this);
3638
- view.scrollDOM.addEventListener("mousedown", (event) => {
3639
- if (event.target == view.scrollDOM && event.clientY > view.contentDOM.getBoundingClientRect().bottom) {
3640
- this.runHandlers("mousedown", event);
3641
- if (!event.defaultPrevented && event.button == 2) {
3642
- // Make sure the content covers the entire scroller height, in order
3643
- // to catch a native context menu click below it
3644
- let start = view.contentDOM.style.minHeight;
3645
- view.contentDOM.style.minHeight = "100%";
3646
- setTimeout(() => view.contentDOM.style.minHeight = start, 200);
3647
- }
3648
- }
3649
- });
3650
- view.scrollDOM.addEventListener("drop", (event) => {
3651
- if (event.target == view.scrollDOM && event.clientY > view.contentDOM.getBoundingClientRect().bottom)
3652
- this.runHandlers("drop", event);
3653
- });
3654
3643
  this.notifiedFocused = view.hasFocus;
3655
3644
  // On Safari adding an input event handler somehow prevents an
3656
3645
  // issue where the composition vanishes when you press enter.
@@ -4071,7 +4060,7 @@ handlers.mousedown = (view, event) => {
4071
4060
  let mouseSel = view.inputState.mouseSelection;
4072
4061
  if (mouseSel) {
4073
4062
  mouseSel.start(event);
4074
- return !mouseSel.dragging;
4063
+ return mouseSel.dragging === false;
4075
4064
  }
4076
4065
  }
4077
4066
  return false;
@@ -5786,6 +5775,7 @@ const baseTheme$1 = buildTheme("." + baseThemeID, {
5786
5775
  whiteSpace: "pre",
5787
5776
  wordWrap: "normal",
5788
5777
  boxSizing: "border-box",
5778
+ minHeight: "100%",
5789
5779
  padding: "4px 0",
5790
5780
  outline: "none",
5791
5781
  "&[contenteditable=true]": {
@@ -6704,8 +6694,10 @@ class DOMObserver {
6704
6694
  if (readSelection)
6705
6695
  this.readSelectionRange();
6706
6696
  let domChange = this.readChange();
6707
- if (!domChange)
6697
+ if (!domChange) {
6698
+ this.view.requestMeasure();
6708
6699
  return false;
6700
+ }
6709
6701
  let startState = this.view.state;
6710
6702
  let handled = applyDOMChange(this.view, domChange);
6711
6703
  // The view wasn't updated
@@ -9049,7 +9041,7 @@ class TooltipViewManager {
9049
9041
  this.tooltips = this.input.filter(t => t);
9050
9042
  this.tooltipViews = this.tooltips.map(createTooltipView);
9051
9043
  }
9052
- update(update) {
9044
+ update(update, above) {
9053
9045
  var _a;
9054
9046
  let input = update.state.facet(this.facet);
9055
9047
  let tooltips = input.filter(x => x);
@@ -9059,7 +9051,7 @@ class TooltipViewManager {
9059
9051
  t.update(update);
9060
9052
  return false;
9061
9053
  }
9062
- let tooltipViews = [];
9054
+ let tooltipViews = [], newAbove = above ? [] : null;
9063
9055
  for (let i = 0; i < tooltips.length; i++) {
9064
9056
  let tip = tooltips[i], known = -1;
9065
9057
  if (!tip)
@@ -9071,9 +9063,13 @@ class TooltipViewManager {
9071
9063
  }
9072
9064
  if (known < 0) {
9073
9065
  tooltipViews[i] = this.createTooltipView(tip);
9066
+ if (newAbove)
9067
+ newAbove[i] = !!tip.above;
9074
9068
  }
9075
9069
  else {
9076
9070
  let tooltipView = tooltipViews[i] = this.tooltipViews[known];
9071
+ if (newAbove)
9072
+ newAbove[i] = above[known];
9077
9073
  if (tooltipView.update)
9078
9074
  tooltipView.update(update);
9079
9075
  }
@@ -9083,6 +9079,10 @@ class TooltipViewManager {
9083
9079
  t.dom.remove();
9084
9080
  (_a = t.destroy) === null || _a === void 0 ? void 0 : _a.call(t);
9085
9081
  }
9082
+ if (above) {
9083
+ newAbove.forEach((val, i) => above[i] = val);
9084
+ above.length = newAbove.length;
9085
+ }
9086
9086
  this.input = input;
9087
9087
  this.tooltips = tooltips;
9088
9088
  this.tooltipViews = tooltipViews;
@@ -9113,6 +9113,7 @@ const knownHeight = new WeakMap();
9113
9113
  const tooltipPlugin = ViewPlugin.fromClass(class {
9114
9114
  constructor(view) {
9115
9115
  this.view = view;
9116
+ this.above = [];
9116
9117
  this.inView = true;
9117
9118
  this.madeAbsolute = false;
9118
9119
  this.lastTransaction = 0;
@@ -9161,7 +9162,7 @@ const tooltipPlugin = ViewPlugin.fromClass(class {
9161
9162
  update(update) {
9162
9163
  if (update.transactions.length)
9163
9164
  this.lastTransaction = Date.now();
9164
- let updated = this.manager.update(update);
9165
+ let updated = this.manager.update(update, this.above);
9165
9166
  if (updated)
9166
9167
  this.observeIntersection();
9167
9168
  let shouldMeasure = updated || update.geometryChanged;
@@ -9277,12 +9278,12 @@ const tooltipPlugin = ViewPlugin.fromClass(class {
9277
9278
  let left = size.width > space.right - space.left ? (ltr ? space.left : space.right - size.width)
9278
9279
  : ltr ? Math.min(pos.left - (arrow ? 14 /* Arrow.Offset */ : 0) + offset.x, space.right - width)
9279
9280
  : Math.max(space.left, pos.left - width + (arrow ? 14 /* Arrow.Offset */ : 0) - offset.x);
9280
- let above = !!tooltip.above;
9281
+ let above = this.above[i];
9281
9282
  if (!tooltip.strictSide && (above
9282
9283
  ? pos.top - (size.bottom - size.top) - offset.y < space.top
9283
9284
  : pos.bottom + (size.bottom - size.top) + offset.y > space.bottom) &&
9284
9285
  above == (space.bottom - pos.bottom > pos.top - space.top))
9285
- above = !above;
9286
+ above = this.above[i] = !above;
9286
9287
  let spaceVert = (above ? pos.top - space.top : space.bottom - pos.bottom) - arrowHeight;
9287
9288
  if (spaceVert < height && tView.resize !== false) {
9288
9289
  if (spaceVert < this.view.defaultLineHeight) {
package/dist/index.js CHANGED
@@ -2977,7 +2977,12 @@ class DocView extends ContentView {
2977
2977
  if (end == off)
2978
2978
  return null;
2979
2979
  let rects = textRange(child.dom, off, end).getClientRects();
2980
- return !rects.length || rects[0].top >= rects[0].bottom ? null : rects[0];
2980
+ for (let i = 0; i < rects.length; i++) {
2981
+ let rect = rects[i];
2982
+ if (i == rects.length - 1 || rect.top < rect.bottom && rect.left < rect.right)
2983
+ return rect;
2984
+ }
2985
+ return null;
2981
2986
  }
2982
2987
  measureVisibleLineHeights(viewport) {
2983
2988
  let result = [], { from, to } = viewport;
@@ -3631,22 +3636,6 @@ class InputState {
3631
3636
  this.compositionPendingChange = false;
3632
3637
  this.mouseSelection = null;
3633
3638
  this.handleEvent = this.handleEvent.bind(this);
3634
- view.scrollDOM.addEventListener("mousedown", (event) => {
3635
- if (event.target == view.scrollDOM && event.clientY > view.contentDOM.getBoundingClientRect().bottom) {
3636
- this.runHandlers("mousedown", event);
3637
- if (!event.defaultPrevented && event.button == 2) {
3638
- // Make sure the content covers the entire scroller height, in order
3639
- // to catch a native context menu click below it
3640
- let start = view.contentDOM.style.minHeight;
3641
- view.contentDOM.style.minHeight = "100%";
3642
- setTimeout(() => view.contentDOM.style.minHeight = start, 200);
3643
- }
3644
- }
3645
- });
3646
- view.scrollDOM.addEventListener("drop", (event) => {
3647
- if (event.target == view.scrollDOM && event.clientY > view.contentDOM.getBoundingClientRect().bottom)
3648
- this.runHandlers("drop", event);
3649
- });
3650
3639
  this.notifiedFocused = view.hasFocus;
3651
3640
  // On Safari adding an input event handler somehow prevents an
3652
3641
  // issue where the composition vanishes when you press enter.
@@ -4067,7 +4056,7 @@ handlers.mousedown = (view, event) => {
4067
4056
  let mouseSel = view.inputState.mouseSelection;
4068
4057
  if (mouseSel) {
4069
4058
  mouseSel.start(event);
4070
- return !mouseSel.dragging;
4059
+ return mouseSel.dragging === false;
4071
4060
  }
4072
4061
  }
4073
4062
  return false;
@@ -5781,6 +5770,7 @@ const baseTheme$1 = /*@__PURE__*/buildTheme("." + baseThemeID, {
5781
5770
  whiteSpace: "pre",
5782
5771
  wordWrap: "normal",
5783
5772
  boxSizing: "border-box",
5773
+ minHeight: "100%",
5784
5774
  padding: "4px 0",
5785
5775
  outline: "none",
5786
5776
  "&[contenteditable=true]": {
@@ -6699,8 +6689,10 @@ class DOMObserver {
6699
6689
  if (readSelection)
6700
6690
  this.readSelectionRange();
6701
6691
  let domChange = this.readChange();
6702
- if (!domChange)
6692
+ if (!domChange) {
6693
+ this.view.requestMeasure();
6703
6694
  return false;
6695
+ }
6704
6696
  let startState = this.view.state;
6705
6697
  let handled = applyDOMChange(this.view, domChange);
6706
6698
  // The view wasn't updated
@@ -9044,7 +9036,7 @@ class TooltipViewManager {
9044
9036
  this.tooltips = this.input.filter(t => t);
9045
9037
  this.tooltipViews = this.tooltips.map(createTooltipView);
9046
9038
  }
9047
- update(update) {
9039
+ update(update, above) {
9048
9040
  var _a;
9049
9041
  let input = update.state.facet(this.facet);
9050
9042
  let tooltips = input.filter(x => x);
@@ -9054,7 +9046,7 @@ class TooltipViewManager {
9054
9046
  t.update(update);
9055
9047
  return false;
9056
9048
  }
9057
- let tooltipViews = [];
9049
+ let tooltipViews = [], newAbove = above ? [] : null;
9058
9050
  for (let i = 0; i < tooltips.length; i++) {
9059
9051
  let tip = tooltips[i], known = -1;
9060
9052
  if (!tip)
@@ -9066,9 +9058,13 @@ class TooltipViewManager {
9066
9058
  }
9067
9059
  if (known < 0) {
9068
9060
  tooltipViews[i] = this.createTooltipView(tip);
9061
+ if (newAbove)
9062
+ newAbove[i] = !!tip.above;
9069
9063
  }
9070
9064
  else {
9071
9065
  let tooltipView = tooltipViews[i] = this.tooltipViews[known];
9066
+ if (newAbove)
9067
+ newAbove[i] = above[known];
9072
9068
  if (tooltipView.update)
9073
9069
  tooltipView.update(update);
9074
9070
  }
@@ -9078,6 +9074,10 @@ class TooltipViewManager {
9078
9074
  t.dom.remove();
9079
9075
  (_a = t.destroy) === null || _a === void 0 ? void 0 : _a.call(t);
9080
9076
  }
9077
+ if (above) {
9078
+ newAbove.forEach((val, i) => above[i] = val);
9079
+ above.length = newAbove.length;
9080
+ }
9081
9081
  this.input = input;
9082
9082
  this.tooltips = tooltips;
9083
9083
  this.tooltipViews = tooltipViews;
@@ -9108,6 +9108,7 @@ const knownHeight = /*@__PURE__*/new WeakMap();
9108
9108
  const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
9109
9109
  constructor(view) {
9110
9110
  this.view = view;
9111
+ this.above = [];
9111
9112
  this.inView = true;
9112
9113
  this.madeAbsolute = false;
9113
9114
  this.lastTransaction = 0;
@@ -9156,7 +9157,7 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
9156
9157
  update(update) {
9157
9158
  if (update.transactions.length)
9158
9159
  this.lastTransaction = Date.now();
9159
- let updated = this.manager.update(update);
9160
+ let updated = this.manager.update(update, this.above);
9160
9161
  if (updated)
9161
9162
  this.observeIntersection();
9162
9163
  let shouldMeasure = updated || update.geometryChanged;
@@ -9272,12 +9273,12 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
9272
9273
  let left = size.width > space.right - space.left ? (ltr ? space.left : space.right - size.width)
9273
9274
  : ltr ? Math.min(pos.left - (arrow ? 14 /* Arrow.Offset */ : 0) + offset.x, space.right - width)
9274
9275
  : Math.max(space.left, pos.left - width + (arrow ? 14 /* Arrow.Offset */ : 0) - offset.x);
9275
- let above = !!tooltip.above;
9276
+ let above = this.above[i];
9276
9277
  if (!tooltip.strictSide && (above
9277
9278
  ? pos.top - (size.bottom - size.top) - offset.y < space.top
9278
9279
  : pos.bottom + (size.bottom - size.top) + offset.y > space.bottom) &&
9279
9280
  above == (space.bottom - pos.bottom > pos.top - space.top))
9280
- above = !above;
9281
+ above = this.above[i] = !above;
9281
9282
  let spaceVert = (above ? pos.top - space.top : space.bottom - pos.bottom) - arrowHeight;
9282
9283
  if (spaceVert < height && tView.resize !== false) {
9283
9284
  if (spaceVert < this.view.defaultLineHeight) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/view",
3
- "version": "6.21.1",
3
+ "version": "6.21.3",
4
4
  "description": "DOM view component for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",