@codemirror/view 6.0.2 → 6.0.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,13 @@
1
+ ## 6.0.3 (2022-07-08)
2
+
3
+ ### Bug fixes
4
+
5
+ Fix a problem where `posAtCoords` could incorrectly return the start of the next line when querying positions between lines.
6
+
7
+ Fix an issue where registering a high-precedence keymap made keymap handling take precedence over other keydown event handlers.
8
+
9
+ Ctrl/Cmd-clicking can now remove ranges from a multi-range selection.
10
+
1
11
  ## 6.0.2 (2022-06-23)
2
12
 
3
13
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -3137,7 +3137,8 @@ function posAtCoords(view, { x, y }, precise, bias = -1) {
3137
3137
  let range = doc.caretRangeFromPoint(x, y);
3138
3138
  if (range) {
3139
3139
  ({ startContainer: node, startOffset: offset } = range);
3140
- if (browser.safari && isSuspiciousCaretResult(node, offset, x))
3140
+ if (browser.safari && isSuspiciousSafariCaretResult(node, offset, x) ||
3141
+ browser.chrome && isSuspiciousChromeCaretResult(node, offset, x))
3141
3142
  node = undefined;
3142
3143
  }
3143
3144
  }
@@ -3164,7 +3165,7 @@ function posAtCoordsImprecise(view, contentRect, block, x, y) {
3164
3165
  // the space between lines as belonging to the last character of the
3165
3166
  // line before. This is used to detect such a result so that it can be
3166
3167
  // ignored (issue #401).
3167
- function isSuspiciousCaretResult(node, offset, x) {
3168
+ function isSuspiciousSafariCaretResult(node, offset, x) {
3168
3169
  let len;
3169
3170
  if (node.nodeType != 3 || offset != (len = node.nodeValue.length))
3170
3171
  return false;
@@ -3173,6 +3174,22 @@ function isSuspiciousCaretResult(node, offset, x) {
3173
3174
  return false;
3174
3175
  return textRange(node, len - 1, len).getBoundingClientRect().left > x;
3175
3176
  }
3177
+ // Chrome will move positions between lines to the start of the next line
3178
+ function isSuspiciousChromeCaretResult(node, offset, x) {
3179
+ if (offset != 0)
3180
+ return false;
3181
+ for (let cur = node;;) {
3182
+ let parent = cur.parentNode;
3183
+ if (!parent || parent.nodeType != 1 || parent.firstChild != cur)
3184
+ return false;
3185
+ if (parent.classList.contains("cm-line"))
3186
+ break;
3187
+ cur = parent;
3188
+ }
3189
+ let rect = node.nodeType == 1 ? node.getBoundingClientRect()
3190
+ : textRange(node, 0, Math.max(node.nodeValue.length, 1)).getBoundingClientRect();
3191
+ return x - rect.left > 5;
3192
+ }
3176
3193
  function moveToLineBoundary(view, start, forward, includeWrap) {
3177
3194
  let line = view.state.doc.lineAt(start.head);
3178
3195
  let coords = !includeWrap || !view.lineWrapping ? null
@@ -3731,6 +3748,8 @@ function basicMouseSelection(view, event) {
3731
3748
  }
3732
3749
  if (extend)
3733
3750
  return startSel.replaceRange(startSel.main.extend(range.from, range.to));
3751
+ else if (multiple && startSel.ranges.length > 1 && startSel.ranges.some(r => r.eq(range)))
3752
+ return removeRange(startSel, range);
3734
3753
  else if (multiple)
3735
3754
  return startSel.addRange(range);
3736
3755
  else
@@ -3738,6 +3757,12 @@ function basicMouseSelection(view, event) {
3738
3757
  }
3739
3758
  };
3740
3759
  }
3760
+ function removeRange(sel, range) {
3761
+ for (let i = 0;; i++) {
3762
+ if (sel.ranges[i].eq(range))
3763
+ return state.EditorSelection.create(sel.ranges.slice(0, i).concat(sel.ranges.slice(i + 1)), sel.mainIndex == i ? 0 : sel.mainIndex - (sel.mainIndex > i ? 1 : 0));
3764
+ }
3765
+ }
3741
3766
  handlers.dragstart = (view, event) => {
3742
3767
  let { selection: { main } } = view.state;
3743
3768
  let { mouseSelection } = view.inputState;
@@ -5222,8 +5247,8 @@ const baseTheme$1 = buildTheme("." + baseThemeID, {
5222
5247
  // Two animations defined so that we can switch between them to
5223
5248
  // restart the animation without forcing another style
5224
5249
  // recomputation.
5225
- "@keyframes cm-blink": { "0%": {}, "50%": { visibility: "hidden" }, "100%": {} },
5226
- "@keyframes cm-blink2": { "0%": {}, "50%": { visibility: "hidden" }, "100%": {} },
5250
+ "@keyframes cm-blink": { "0%": {}, "50%": { opacity: 0 }, "100%": {} },
5251
+ "@keyframes cm-blink2": { "0%": {}, "50%": { opacity: 0 }, "100%": {} },
5227
5252
  ".cm-cursor, .cm-dropCursor": {
5228
5253
  position: "absolute",
5229
5254
  borderLeft: "1.2px solid black",
@@ -6890,11 +6915,11 @@ function modifiers(name, event, shift) {
6890
6915
  name = "Shift-" + name;
6891
6916
  return name;
6892
6917
  }
6893
- const handleKeyEvents = EditorView.domEventHandlers({
6918
+ const handleKeyEvents = state.Prec.default(EditorView.domEventHandlers({
6894
6919
  keydown(event, view) {
6895
6920
  return runHandlers(getKeymap(view.state), event, view, "editor");
6896
6921
  }
6897
- });
6922
+ }));
6898
6923
  /**
6899
6924
  Facet used for registering keymaps.
6900
6925
 
package/dist/index.js CHANGED
@@ -3131,7 +3131,8 @@ function posAtCoords(view, { x, y }, precise, bias = -1) {
3131
3131
  let range = doc.caretRangeFromPoint(x, y);
3132
3132
  if (range) {
3133
3133
  ({ startContainer: node, startOffset: offset } = range);
3134
- if (browser.safari && isSuspiciousCaretResult(node, offset, x))
3134
+ if (browser.safari && isSuspiciousSafariCaretResult(node, offset, x) ||
3135
+ browser.chrome && isSuspiciousChromeCaretResult(node, offset, x))
3135
3136
  node = undefined;
3136
3137
  }
3137
3138
  }
@@ -3158,7 +3159,7 @@ function posAtCoordsImprecise(view, contentRect, block, x, y) {
3158
3159
  // the space between lines as belonging to the last character of the
3159
3160
  // line before. This is used to detect such a result so that it can be
3160
3161
  // ignored (issue #401).
3161
- function isSuspiciousCaretResult(node, offset, x) {
3162
+ function isSuspiciousSafariCaretResult(node, offset, x) {
3162
3163
  let len;
3163
3164
  if (node.nodeType != 3 || offset != (len = node.nodeValue.length))
3164
3165
  return false;
@@ -3167,6 +3168,22 @@ function isSuspiciousCaretResult(node, offset, x) {
3167
3168
  return false;
3168
3169
  return textRange(node, len - 1, len).getBoundingClientRect().left > x;
3169
3170
  }
3171
+ // Chrome will move positions between lines to the start of the next line
3172
+ function isSuspiciousChromeCaretResult(node, offset, x) {
3173
+ if (offset != 0)
3174
+ return false;
3175
+ for (let cur = node;;) {
3176
+ let parent = cur.parentNode;
3177
+ if (!parent || parent.nodeType != 1 || parent.firstChild != cur)
3178
+ return false;
3179
+ if (parent.classList.contains("cm-line"))
3180
+ break;
3181
+ cur = parent;
3182
+ }
3183
+ let rect = node.nodeType == 1 ? node.getBoundingClientRect()
3184
+ : textRange(node, 0, Math.max(node.nodeValue.length, 1)).getBoundingClientRect();
3185
+ return x - rect.left > 5;
3186
+ }
3170
3187
  function moveToLineBoundary(view, start, forward, includeWrap) {
3171
3188
  let line = view.state.doc.lineAt(start.head);
3172
3189
  let coords = !includeWrap || !view.lineWrapping ? null
@@ -3725,6 +3742,8 @@ function basicMouseSelection(view, event) {
3725
3742
  }
3726
3743
  if (extend)
3727
3744
  return startSel.replaceRange(startSel.main.extend(range.from, range.to));
3745
+ else if (multiple && startSel.ranges.length > 1 && startSel.ranges.some(r => r.eq(range)))
3746
+ return removeRange(startSel, range);
3728
3747
  else if (multiple)
3729
3748
  return startSel.addRange(range);
3730
3749
  else
@@ -3732,6 +3751,12 @@ function basicMouseSelection(view, event) {
3732
3751
  }
3733
3752
  };
3734
3753
  }
3754
+ function removeRange(sel, range) {
3755
+ for (let i = 0;; i++) {
3756
+ if (sel.ranges[i].eq(range))
3757
+ return EditorSelection.create(sel.ranges.slice(0, i).concat(sel.ranges.slice(i + 1)), sel.mainIndex == i ? 0 : sel.mainIndex - (sel.mainIndex > i ? 1 : 0));
3758
+ }
3759
+ }
3735
3760
  handlers.dragstart = (view, event) => {
3736
3761
  let { selection: { main } } = view.state;
3737
3762
  let { mouseSelection } = view.inputState;
@@ -5215,8 +5240,8 @@ const baseTheme$1 = /*@__PURE__*/buildTheme("." + baseThemeID, {
5215
5240
  // Two animations defined so that we can switch between them to
5216
5241
  // restart the animation without forcing another style
5217
5242
  // recomputation.
5218
- "@keyframes cm-blink": { "0%": {}, "50%": { visibility: "hidden" }, "100%": {} },
5219
- "@keyframes cm-blink2": { "0%": {}, "50%": { visibility: "hidden" }, "100%": {} },
5243
+ "@keyframes cm-blink": { "0%": {}, "50%": { opacity: 0 }, "100%": {} },
5244
+ "@keyframes cm-blink2": { "0%": {}, "50%": { opacity: 0 }, "100%": {} },
5220
5245
  ".cm-cursor, .cm-dropCursor": {
5221
5246
  position: "absolute",
5222
5247
  borderLeft: "1.2px solid black",
@@ -6883,11 +6908,11 @@ function modifiers(name, event, shift) {
6883
6908
  name = "Shift-" + name;
6884
6909
  return name;
6885
6910
  }
6886
- const handleKeyEvents = /*@__PURE__*/EditorView.domEventHandlers({
6911
+ const handleKeyEvents = /*@__PURE__*/Prec.default(/*@__PURE__*/EditorView.domEventHandlers({
6887
6912
  keydown(event, view) {
6888
6913
  return runHandlers(getKeymap(view.state), event, view, "editor");
6889
6914
  }
6890
- });
6915
+ }));
6891
6916
  /**
6892
6917
  Facet used for registering keymaps.
6893
6918
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/view",
3
- "version": "6.0.2",
3
+ "version": "6.0.3",
4
4
  "description": "DOM view component for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",