@codemirror/view 6.1.4 → 6.2.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,33 @@
1
+ ## 6.2.2 (2022-08-31)
2
+
3
+ ### Bug fixes
4
+
5
+ Don't reset the selection for selection change events that were suppressed by a node view.
6
+
7
+ ## 6.2.1 (2022-08-25)
8
+
9
+ ### Bug fixes
10
+
11
+ Don't use the global `document` variable to track focus, since that doesn't work in another window/frame.
12
+
13
+ Fix an issue where key handlers that didn't return true were sometimes called twice for the same keypress.
14
+
15
+ Avoid editing glitches when using deletion keys like ctrl-d on iOS.
16
+
17
+ Properly treat characters from the 'Arabic Presentation Forms-A' Unicode block as right-to-left.
18
+
19
+ Work around a Firefox bug that inserts text at the wrong point for specific cross-line selections.
20
+
21
+ ## 6.2.0 (2022-08-05)
22
+
23
+ ### Bug fixes
24
+
25
+ Fix a bug where `posAtCoords` would return the wrong results for positions to the right of wrapped lines.
26
+
27
+ ### New features
28
+
29
+ The new `EditorView.setRoot` method can be used when an editor view is moved to a new document or shadow root.
30
+
1
31
  ## 6.1.4 (2022-08-04)
2
32
 
3
33
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -22,8 +22,8 @@ function getSelection(root) {
22
22
  function contains(dom, node) {
23
23
  return node ? dom == node || dom.contains(node.nodeType != 1 ? node.parentNode : node) : false;
24
24
  }
25
- function deepActiveElement() {
26
- let elt = document.activeElement;
25
+ function deepActiveElement(doc) {
26
+ let elt = doc.activeElement;
27
27
  while (elt && elt.shadowRoot)
28
28
  elt = elt.shadowRoot.activeElement;
29
29
  return elt;
@@ -762,7 +762,7 @@ class MarkView extends ContentView {
762
762
  return new MarkView(this.mark, result, length);
763
763
  }
764
764
  domAtPos(pos) {
765
- return inlineDOMAtPos(this.dom, this.children, pos);
765
+ return inlineDOMAtPos(this, pos);
766
766
  }
767
767
  coordsAt(pos, side) {
768
768
  return coordsInChildren(this, pos, side);
@@ -913,11 +913,14 @@ class CompositionView extends WidgetView {
913
913
  // offset.
914
914
  function scanCompositionTree(pos, side, view, text, enterView, fromText) {
915
915
  if (view instanceof MarkView) {
916
- for (let child of view.children) {
917
- let hasComp = contains(child.dom, text);
918
- let len = hasComp ? text.nodeValue.length : child.length;
919
- if (pos < len || pos == len && child.getSide() <= 0)
920
- return hasComp ? scanCompositionTree(pos, side, child, text, enterView, fromText) : enterView(child, pos, side);
916
+ for (let child = view.dom.firstChild; child; child = child.nextSibling) {
917
+ let desc = ContentView.get(child);
918
+ if (!desc)
919
+ return fromText(pos, side);
920
+ let hasComp = contains(child, text);
921
+ let len = desc.length + (hasComp ? text.nodeValue.length : 0);
922
+ if (pos < len || pos == len && desc.getSide() <= 0)
923
+ return hasComp ? scanCompositionTree(pos, side, desc, text, enterView, fromText) : enterView(desc, pos, side);
921
924
  pos -= len;
922
925
  }
923
926
  return enterView(view, view.length, -1);
@@ -1007,8 +1010,8 @@ function inlineSiblingRect(view, side) {
1007
1010
  }
1008
1011
  return undefined;
1009
1012
  }
1010
- function inlineDOMAtPos(dom, children, pos) {
1011
- let i = 0;
1013
+ function inlineDOMAtPos(parent, pos) {
1014
+ let dom = parent.dom, { children } = parent, i = 0;
1012
1015
  for (let off = 0; i < children.length; i++) {
1013
1016
  let child = children[i], end = off + child.length;
1014
1017
  if (end == off && child.getSide() <= 0)
@@ -1019,10 +1022,16 @@ function inlineDOMAtPos(dom, children, pos) {
1019
1022
  break;
1020
1023
  off = end;
1021
1024
  }
1022
- for (; i > 0; i--) {
1023
- let before = children[i - 1].dom;
1024
- if (before.parentNode == dom)
1025
- return DOMPos.after(before);
1025
+ // if (i) return DOMPos.after(children[i - 1].dom!)
1026
+ for (let j = i; j > 0; j--) {
1027
+ let prev = children[j - 1];
1028
+ if (prev.dom.parentNode == dom)
1029
+ return prev.domAtPos(prev.length);
1030
+ }
1031
+ for (let j = i; j < children.length; j++) {
1032
+ let next = children[j];
1033
+ if (next.dom.parentNode == dom)
1034
+ return next.domAtPos(0);
1026
1035
  }
1027
1036
  return new DOMPos(dom, 0);
1028
1037
  }
@@ -1431,7 +1440,7 @@ class LineView extends ContentView {
1431
1440
  this.attrs = combineAttrs({ class: cls }, this.attrs || {});
1432
1441
  }
1433
1442
  domAtPos(pos) {
1434
- return inlineDOMAtPos(this.dom, this.children, pos);
1443
+ return inlineDOMAtPos(this, pos);
1435
1444
  }
1436
1445
  reuseDOM(node) {
1437
1446
  if (node.nodeName == "DIV") {
@@ -2077,9 +2086,10 @@ function charType(ch) {
2077
2086
  0x600 <= ch && ch <= 0x6f9 ? ArabicTypes[ch - 0x600] :
2078
2087
  0x6ee <= ch && ch <= 0x8ac ? 4 /* AL */ :
2079
2088
  0x2000 <= ch && ch <= 0x200b ? 256 /* NI */ :
2080
- ch == 0x200c ? 256 /* NI */ : 1 /* L */;
2089
+ 0xfb50 <= ch && ch <= 0xfdff ? 4 /* AL */ :
2090
+ ch == 0x200c ? 256 /* NI */ : 1 /* L */;
2081
2091
  }
2082
- const BidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
2092
+ const BidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac\ufb50-\ufdff]/;
2083
2093
  /**
2084
2094
  Represents a contiguous range of text that has a single direction
2085
2095
  (as in left-to-right or right-to-left).
@@ -2483,7 +2493,6 @@ class DocView extends ContentView {
2483
2493
  this.updateDeco();
2484
2494
  this.updateInner([new ChangedRange(0, 0, 0, view.state.doc.length)], 0);
2485
2495
  }
2486
- get root() { return this.view.root; }
2487
2496
  get editorView() { return this.view; }
2488
2497
  get length() { return this.view.state.doc.length; }
2489
2498
  // Update the document view to a given state. scrollIntoView can be
@@ -2606,7 +2615,7 @@ class DocView extends ContentView {
2606
2615
  this.dom.blur();
2607
2616
  this.dom.focus({ preventScroll: true });
2608
2617
  }
2609
- let rawSel = getSelection(this.root);
2618
+ let rawSel = getSelection(this.view.root);
2610
2619
  if (!rawSel) ;
2611
2620
  else if (main.empty) {
2612
2621
  // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=1612076
@@ -2649,7 +2658,7 @@ class DocView extends ContentView {
2649
2658
  if (this.compositionDeco.size)
2650
2659
  return;
2651
2660
  let cursor = this.view.state.selection.main;
2652
- let sel = getSelection(this.root);
2661
+ let sel = getSelection(this.view.root);
2653
2662
  if (!sel || !cursor.empty || !cursor.assoc || !sel.modify)
2654
2663
  return;
2655
2664
  let line = LineView.find(this, cursor.head);
@@ -2666,7 +2675,7 @@ class DocView extends ContentView {
2666
2675
  sel.modify("move", cursor.assoc < 0 ? "forward" : "backward", "lineboundary");
2667
2676
  }
2668
2677
  mayControlSelection() {
2669
- let active = this.root.activeElement;
2678
+ let active = this.view.root.activeElement;
2670
2679
  return active == this.dom ||
2671
2680
  hasSelection(this.dom, this.view.observer.selectionRange) && !(active && this.dom.contains(active));
2672
2681
  }
@@ -3019,7 +3028,7 @@ function upBot(rect, bottom) {
3019
3028
  return bottom > rect.bottom ? { top: rect.top, left: rect.left, right: rect.right, bottom } : rect;
3020
3029
  }
3021
3030
  function domPosAtCoords(parent, x, y) {
3022
- let closest, closestRect, closestX, closestY;
3031
+ let closest, closestRect, closestX, closestY, closestOverlap = false;
3023
3032
  let above, below, aboveRect, belowRect;
3024
3033
  for (let child = parent.firstChild; child; child = child.nextSibling) {
3025
3034
  let rects = clientRectsFor(child);
@@ -3035,6 +3044,7 @@ function domPosAtCoords(parent, x, y) {
3035
3044
  closestRect = rect;
3036
3045
  closestX = dx;
3037
3046
  closestY = dy;
3047
+ closestOverlap = !dx || (dx > 0 ? i < rects.length - 1 : i > 0);
3038
3048
  }
3039
3049
  if (dx == 0) {
3040
3050
  if (y > rect.bottom && (!aboveRect || aboveRect.bottom < rect.bottom)) {
@@ -3067,7 +3077,7 @@ function domPosAtCoords(parent, x, y) {
3067
3077
  let clipX = Math.max(closestRect.left, Math.min(closestRect.right, x));
3068
3078
  if (closest.nodeType == 3)
3069
3079
  return domPosInText(closest, clipX, y);
3070
- if (!closestX && closest.contentEditable == "true")
3080
+ if (closestOverlap && closest.contentEditable != "false")
3071
3081
  return domPosAtCoords(closest, clipX, y);
3072
3082
  let offset = Array.prototype.indexOf.call(parent.childNodes, closest) +
3073
3083
  (x >= (closestRect.left + closestRect.right) / 2 ? 1 : 0);
@@ -3164,7 +3174,8 @@ function posAtCoords(view, { x, y }, precise, bias = -1) {
3164
3174
  let range = doc.caretRangeFromPoint(x, y);
3165
3175
  if (range) {
3166
3176
  ({ startContainer: node, startOffset: offset } = range);
3167
- if (browser.safari && isSuspiciousSafariCaretResult(node, offset, x) ||
3177
+ if (!view.contentDOM.contains(node) ||
3178
+ browser.safari && isSuspiciousSafariCaretResult(node, offset, x) ||
3168
3179
  browser.chrome && isSuspiciousChromeCaretResult(node, offset, x))
3169
3180
  node = undefined;
3170
3181
  }
@@ -3457,9 +3468,10 @@ class InputState {
3457
3468
  // applyDOMChange, notify key handlers of it and reset to
3458
3469
  // the state they produce.
3459
3470
  let pending;
3460
- if (browser.ios && (pending = PendingKeys.find(key => key.keyCode == event.keyCode)) &&
3461
- !(event.ctrlKey || event.altKey || event.metaKey) && !event.synthetic) {
3462
- this.pendingIOSKey = pending;
3471
+ if (browser.ios && !event.synthetic && !event.altKey && !event.metaKey &&
3472
+ ((pending = PendingKeys.find(key => key.keyCode == event.keyCode)) && !event.ctrlKey ||
3473
+ EmacsyPendingKeys.indexOf(event.key) > -1 && event.ctrlKey && !event.shiftKey)) {
3474
+ this.pendingIOSKey = pending || event;
3463
3475
  setTimeout(() => this.flushIOSKey(view), 250);
3464
3476
  return true;
3465
3477
  }
@@ -3514,6 +3526,7 @@ const PendingKeys = [
3514
3526
  { key: "Enter", keyCode: 13, inputType: "insertParagraph" },
3515
3527
  { key: "Delete", keyCode: 46, inputType: "deleteContentForward" }
3516
3528
  ];
3529
+ const EmacsyPendingKeys = "dthko";
3517
3530
  // Key codes for modifier keys
3518
3531
  const modifierCodes = [16, 17, 18, 20, 91, 92, 224, 225];
3519
3532
  class MouseSelection {
@@ -5378,6 +5391,7 @@ const baseTheme$1 = buildTheme("." + baseThemeID, {
5378
5391
  ".cm-widgetBuffer": {
5379
5392
  verticalAlign: "text-top",
5380
5393
  height: "1em",
5394
+ width: 0,
5381
5395
  display: "inline"
5382
5396
  },
5383
5397
  ".cm-placeholder": {
@@ -5487,7 +5501,9 @@ class DOMObserver {
5487
5501
  this.flushSoon();
5488
5502
  };
5489
5503
  this.onSelectionChange = this.onSelectionChange.bind(this);
5490
- window.addEventListener("resize", this.onResize = this.onResize.bind(this));
5504
+ this.onResize = this.onResize.bind(this);
5505
+ this.onPrint = this.onPrint.bind(this);
5506
+ this.onScroll = this.onScroll.bind(this);
5491
5507
  if (typeof ResizeObserver == "function") {
5492
5508
  this.resize = new ResizeObserver(() => {
5493
5509
  if (this.view.docView.lastUpdate < Date.now() - 75)
@@ -5495,9 +5511,9 @@ class DOMObserver {
5495
5511
  });
5496
5512
  this.resize.observe(view.scrollDOM);
5497
5513
  }
5498
- window.addEventListener("beforeprint", this.onPrint = this.onPrint.bind(this));
5514
+ this.win = view.dom.ownerDocument.defaultView;
5515
+ this.addWindowListeners(this.win);
5499
5516
  this.start();
5500
- window.addEventListener("scroll", this.onScroll = this.onScroll.bind(this));
5501
5517
  if (typeof IntersectionObserver == "function") {
5502
5518
  this.intersection = new IntersectionObserver(entries => {
5503
5519
  if (this.parentCheck < 0)
@@ -5516,7 +5532,6 @@ class DOMObserver {
5516
5532
  }
5517
5533
  this.listenForScroll();
5518
5534
  this.readSelectionRange();
5519
- this.dom.ownerDocument.addEventListener("selectionchange", this.onSelectionChange);
5520
5535
  }
5521
5536
  onScroll(e) {
5522
5537
  if (this.intersecting)
@@ -5547,14 +5562,18 @@ class DOMObserver {
5547
5562
  }
5548
5563
  }
5549
5564
  onSelectionChange(event) {
5565
+ let wasChanged = this.selectionChanged;
5550
5566
  if (!this.readSelectionRange() || this.delayedAndroidKey)
5551
5567
  return;
5552
5568
  let { view } = this, sel = this.selectionRange;
5553
5569
  if (view.state.facet(editable) ? view.root.activeElement != this.dom : !hasSelection(view.dom, sel))
5554
5570
  return;
5555
5571
  let context = sel.anchorNode && view.docView.nearest(sel.anchorNode);
5556
- if (context && context.ignoreEvent(event))
5572
+ if (context && context.ignoreEvent(event)) {
5573
+ if (!wasChanged)
5574
+ this.selectionChanged = false;
5557
5575
  return;
5576
+ }
5558
5577
  // Deletions on IE11 fire their events in the wrong order, giving
5559
5578
  // us a selection change event before the DOM changes are
5560
5579
  // reported.
@@ -5571,7 +5590,8 @@ class DOMObserver {
5571
5590
  let { view } = this;
5572
5591
  // The Selection object is broken in shadow roots in Safari. See
5573
5592
  // https://github.com/codemirror/dev/issues/414
5574
- let range = browser.safari && view.root.nodeType == 11 && deepActiveElement() == this.dom &&
5593
+ let range = browser.safari && view.root.nodeType == 11 &&
5594
+ deepActiveElement(this.dom.ownerDocument) == this.dom &&
5575
5595
  safariSelectionRangeHack(this.view) || getSelection(view.root);
5576
5596
  if (!range || this.selectionRange.eq(range))
5577
5597
  return false;
@@ -5731,6 +5751,7 @@ class DOMObserver {
5731
5751
  let newSel = this.selectionChanged && hasSelection(this.dom, this.selectionRange);
5732
5752
  if (from < 0 && !newSel)
5733
5753
  return;
5754
+ this.view.inputState.lastFocusTime = 0;
5734
5755
  this.selectionChanged = false;
5735
5756
  let startState = this.view.state;
5736
5757
  let handled = this.onChange(from, to, typeOver);
@@ -5759,6 +5780,25 @@ class DOMObserver {
5759
5780
  return null;
5760
5781
  }
5761
5782
  }
5783
+ setWindow(win) {
5784
+ if (win != this.win) {
5785
+ this.removeWindowListeners(this.win);
5786
+ this.win = win;
5787
+ this.addWindowListeners(this.win);
5788
+ }
5789
+ }
5790
+ addWindowListeners(win) {
5791
+ win.addEventListener("resize", this.onResize);
5792
+ win.addEventListener("beforeprint", this.onPrint);
5793
+ win.addEventListener("scroll", this.onScroll);
5794
+ win.document.addEventListener("selectionchange", this.onSelectionChange);
5795
+ }
5796
+ removeWindowListeners(win) {
5797
+ win.removeEventListener("scroll", this.onScroll);
5798
+ win.removeEventListener("resize", this.onResize);
5799
+ win.removeEventListener("beforeprint", this.onPrint);
5800
+ win.document.removeEventListener("selectionchange", this.onSelectionChange);
5801
+ }
5762
5802
  destroy() {
5763
5803
  var _a, _b, _c;
5764
5804
  this.stop();
@@ -5767,10 +5807,7 @@ class DOMObserver {
5767
5807
  (_c = this.resize) === null || _c === void 0 ? void 0 : _c.disconnect();
5768
5808
  for (let dom of this.scrollTargets)
5769
5809
  dom.removeEventListener("scroll", this.onScroll);
5770
- window.removeEventListener("scroll", this.onScroll);
5771
- window.removeEventListener("resize", this.onResize);
5772
- window.removeEventListener("beforeprint", this.onPrint);
5773
- this.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange);
5810
+ this.removeWindowListeners(this.win);
5774
5811
  clearTimeout(this.parentCheck);
5775
5812
  clearTimeout(this.resizeTimeout);
5776
5813
  }
@@ -5799,7 +5836,7 @@ function safariSelectionRangeHack(view) {
5799
5836
  found = event.getTargetRanges()[0];
5800
5837
  }
5801
5838
  view.contentDOM.addEventListener("beforeinput", read, true);
5802
- document.execCommand("indent");
5839
+ view.dom.ownerDocument.execCommand("indent");
5803
5840
  view.contentDOM.removeEventListener("beforeinput", read, true);
5804
5841
  if (!found)
5805
5842
  return null;
@@ -6078,7 +6115,7 @@ class EditorView {
6078
6115
  this.dom.appendChild(this.scrollDOM);
6079
6116
  this._dispatch = config.dispatch || ((tr) => this.update([tr]));
6080
6117
  this.dispatch = this.dispatch.bind(this);
6081
- this.root = (config.root || getRoot(config.parent) || document);
6118
+ this._root = (config.root || getRoot(config.parent) || document);
6082
6119
  this.viewState = new ViewState(config.state || state.EditorState.create(config));
6083
6120
  this.plugins = this.state.facet(viewPlugin).map(spec => new PluginInstance(spec));
6084
6121
  for (let plugin of this.plugins)
@@ -6139,6 +6176,10 @@ class EditorView {
6139
6176
  composition there.
6140
6177
  */
6141
6178
  get compositionStarted() { return this.inputState.composing >= 0; }
6179
+ /**
6180
+ The document or shadow root that the view lives in.
6181
+ */
6182
+ get root() { return this._root; }
6142
6183
  dispatch(...input) {
6143
6184
  this._dispatch(input.length == 1 && input[0] instanceof state.Transaction ? input[0]
6144
6185
  : this.state.update(...input));
@@ -6474,7 +6515,7 @@ class EditorView {
6474
6515
  /**
6475
6516
  Find the text line or block widget at the given vertical
6476
6517
  position (which is interpreted as relative to the [top of the
6477
- document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop)
6518
+ document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop)).
6478
6519
  */
6479
6520
  elementAtHeight(height) {
6480
6521
  this.readMeasured();
@@ -6483,7 +6524,8 @@ class EditorView {
6483
6524
  /**
6484
6525
  Find the line block (see
6485
6526
  [`lineBlockAt`](https://codemirror.net/6/docs/ref/#view.EditorView.lineBlockAt) at the given
6486
- height.
6527
+ height, again interpreted relative to the [top of the
6528
+ document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop).
6487
6529
  */
6488
6530
  lineBlockAtHeight(height) {
6489
6531
  this.readMeasured();
@@ -6677,7 +6719,7 @@ class EditorView {
6677
6719
  // or closing, which leads us to ignore selection changes from the
6678
6720
  // context menu because it looks like the editor isn't focused.
6679
6721
  // This kludges around that.
6680
- return (document.hasFocus() || browser.safari && ((_a = this.inputState) === null || _a === void 0 ? void 0 : _a.lastContextMenu) > Date.now() - 3e4) &&
6722
+ return (this.dom.ownerDocument.hasFocus() || browser.safari && ((_a = this.inputState) === null || _a === void 0 ? void 0 : _a.lastContextMenu) > Date.now() - 3e4) &&
6681
6723
  this.root.activeElement == this.contentDOM;
6682
6724
  }
6683
6725
  /**
@@ -6690,6 +6732,17 @@ class EditorView {
6690
6732
  });
6691
6733
  }
6692
6734
  /**
6735
+ Update the [root](https://codemirror.net/6/docs/ref/##view.EditorViewConfig.root) in which the editor lives. This is only
6736
+ necessary when moving the editor's existing DOM to a new window or shadow root.
6737
+ */
6738
+ setRoot(root) {
6739
+ if (this._root != root) {
6740
+ this._root = root;
6741
+ this.observer.setWindow((root.nodeType == 9 ? root : root.ownerDocument).defaultView);
6742
+ this.mountStyles();
6743
+ }
6744
+ }
6745
+ /**
6693
6746
  Clean up this editor view, removing its element from the
6694
6747
  document, unregistering event handlers, and notifying
6695
6748
  plugins. The view instance can no longer be used after
@@ -6851,6 +6904,11 @@ the editor's vertical layout structure. The ones provided as
6851
6904
  functions are called _after_ the new viewport has been computed,
6852
6905
  and thus **must not** introduce block widgets or replacing
6853
6906
  decorations that cover line breaks.
6907
+
6908
+ If you want decorated ranges to behave like atomic units for
6909
+ cursor motion and deletion purposes, also provide the range set
6910
+ containing the decorations to
6911
+ [`EditorView.atomicRanges`](https://codemirror.net/6/docs/ref/#view.EditorView^atomicRanges).
6854
6912
  */
6855
6913
  EditorView.decorations = decorations;
6856
6914
  /**
@@ -7081,7 +7139,7 @@ function runHandlers(map, event, view, scope) {
7081
7139
  }
7082
7140
  return false;
7083
7141
  };
7084
- let scopeObj = map[scope], baseName;
7142
+ let scopeObj = map[scope], baseName, shiftName;
7085
7143
  if (scopeObj) {
7086
7144
  if (runFor(scopeObj[prefix + modifiers(name, event, !isChar)]))
7087
7145
  return true;
@@ -7089,8 +7147,8 @@ function runHandlers(map, event, view, scope) {
7089
7147
  (baseName = w3cKeyname.base[event.keyCode]) && baseName != name) {
7090
7148
  if (runFor(scopeObj[prefix + modifiers(baseName, event, true)]))
7091
7149
  return true;
7092
- else if (event.shiftKey && w3cKeyname.shift[event.keyCode] != baseName &&
7093
- runFor(scopeObj[prefix + modifiers(w3cKeyname.shift[event.keyCode], event, false)]))
7150
+ else if (event.shiftKey && (shiftName = w3cKeyname.shift[event.keyCode]) != name && shiftName != baseName &&
7151
+ runFor(scopeObj[prefix + modifiers(shiftName, event, false)]))
7094
7152
  return true;
7095
7153
  }
7096
7154
  else if (isChar && event.shiftKey) {
package/dist/index.d.ts CHANGED
@@ -647,10 +647,11 @@ declare class EditorView {
647
647
  */
648
648
  get compositionStarted(): boolean;
649
649
  private _dispatch;
650
+ private _root;
650
651
  /**
651
652
  The document or shadow root that the view lives in.
652
653
  */
653
- readonly root: DocumentOrShadowRoot;
654
+ get root(): DocumentOrShadowRoot;
654
655
  /**
655
656
  The DOM element that wraps the entire editor view.
656
657
  */
@@ -752,13 +753,14 @@ declare class EditorView {
752
753
  /**
753
754
  Find the text line or block widget at the given vertical
754
755
  position (which is interpreted as relative to the [top of the
755
- document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop)
756
+ document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop)).
756
757
  */
757
758
  elementAtHeight(height: number): BlockInfo;
758
759
  /**
759
760
  Find the line block (see
760
761
  [`lineBlockAt`](https://codemirror.net/6/docs/ref/#view.EditorView.lineBlockAt) at the given
761
- height.
762
+ height, again interpreted relative to the [top of the
763
+ document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop).
762
764
  */
763
765
  lineBlockAtHeight(height: number): BlockInfo;
764
766
  /**
@@ -921,6 +923,11 @@ declare class EditorView {
921
923
  */
922
924
  focus(): void;
923
925
  /**
926
+ Update the [root](https://codemirror.net/6/docs/ref/##view.EditorViewConfig.root) in which the editor lives. This is only
927
+ necessary when moving the editor's existing DOM to a new window or shadow root.
928
+ */
929
+ setRoot(root: Document | ShadowRoot): void;
930
+ /**
924
931
  Clean up this editor view, removing its element from the
925
932
  document, unregistering event handlers, and notifying
926
933
  plugins. The view instance can no longer be used after
@@ -1047,6 +1054,11 @@ declare class EditorView {
1047
1054
  functions are called _after_ the new viewport has been computed,
1048
1055
  and thus **must not** introduce block widgets or replacing
1049
1056
  decorations that cover line breaks.
1057
+
1058
+ If you want decorated ranges to behave like atomic units for
1059
+ cursor motion and deletion purposes, also provide the range set
1060
+ containing the decorations to
1061
+ [`EditorView.atomicRanges`](https://codemirror.net/6/docs/ref/#view.EditorView^atomicRanges).
1050
1062
  */
1051
1063
  static decorations: Facet<DecorationSet | ((view: EditorView) => DecorationSet), readonly (DecorationSet | ((view: EditorView) => DecorationSet))[]>;
1052
1064
  /**
package/dist/index.js CHANGED
@@ -18,8 +18,8 @@ function getSelection(root) {
18
18
  function contains(dom, node) {
19
19
  return node ? dom == node || dom.contains(node.nodeType != 1 ? node.parentNode : node) : false;
20
20
  }
21
- function deepActiveElement() {
22
- let elt = document.activeElement;
21
+ function deepActiveElement(doc) {
22
+ let elt = doc.activeElement;
23
23
  while (elt && elt.shadowRoot)
24
24
  elt = elt.shadowRoot.activeElement;
25
25
  return elt;
@@ -758,7 +758,7 @@ class MarkView extends ContentView {
758
758
  return new MarkView(this.mark, result, length);
759
759
  }
760
760
  domAtPos(pos) {
761
- return inlineDOMAtPos(this.dom, this.children, pos);
761
+ return inlineDOMAtPos(this, pos);
762
762
  }
763
763
  coordsAt(pos, side) {
764
764
  return coordsInChildren(this, pos, side);
@@ -909,11 +909,14 @@ class CompositionView extends WidgetView {
909
909
  // offset.
910
910
  function scanCompositionTree(pos, side, view, text, enterView, fromText) {
911
911
  if (view instanceof MarkView) {
912
- for (let child of view.children) {
913
- let hasComp = contains(child.dom, text);
914
- let len = hasComp ? text.nodeValue.length : child.length;
915
- if (pos < len || pos == len && child.getSide() <= 0)
916
- return hasComp ? scanCompositionTree(pos, side, child, text, enterView, fromText) : enterView(child, pos, side);
912
+ for (let child = view.dom.firstChild; child; child = child.nextSibling) {
913
+ let desc = ContentView.get(child);
914
+ if (!desc)
915
+ return fromText(pos, side);
916
+ let hasComp = contains(child, text);
917
+ let len = desc.length + (hasComp ? text.nodeValue.length : 0);
918
+ if (pos < len || pos == len && desc.getSide() <= 0)
919
+ return hasComp ? scanCompositionTree(pos, side, desc, text, enterView, fromText) : enterView(desc, pos, side);
917
920
  pos -= len;
918
921
  }
919
922
  return enterView(view, view.length, -1);
@@ -1003,8 +1006,8 @@ function inlineSiblingRect(view, side) {
1003
1006
  }
1004
1007
  return undefined;
1005
1008
  }
1006
- function inlineDOMAtPos(dom, children, pos) {
1007
- let i = 0;
1009
+ function inlineDOMAtPos(parent, pos) {
1010
+ let dom = parent.dom, { children } = parent, i = 0;
1008
1011
  for (let off = 0; i < children.length; i++) {
1009
1012
  let child = children[i], end = off + child.length;
1010
1013
  if (end == off && child.getSide() <= 0)
@@ -1015,10 +1018,16 @@ function inlineDOMAtPos(dom, children, pos) {
1015
1018
  break;
1016
1019
  off = end;
1017
1020
  }
1018
- for (; i > 0; i--) {
1019
- let before = children[i - 1].dom;
1020
- if (before.parentNode == dom)
1021
- return DOMPos.after(before);
1021
+ // if (i) return DOMPos.after(children[i - 1].dom!)
1022
+ for (let j = i; j > 0; j--) {
1023
+ let prev = children[j - 1];
1024
+ if (prev.dom.parentNode == dom)
1025
+ return prev.domAtPos(prev.length);
1026
+ }
1027
+ for (let j = i; j < children.length; j++) {
1028
+ let next = children[j];
1029
+ if (next.dom.parentNode == dom)
1030
+ return next.domAtPos(0);
1022
1031
  }
1023
1032
  return new DOMPos(dom, 0);
1024
1033
  }
@@ -1426,7 +1435,7 @@ class LineView extends ContentView {
1426
1435
  this.attrs = combineAttrs({ class: cls }, this.attrs || {});
1427
1436
  }
1428
1437
  domAtPos(pos) {
1429
- return inlineDOMAtPos(this.dom, this.children, pos);
1438
+ return inlineDOMAtPos(this, pos);
1430
1439
  }
1431
1440
  reuseDOM(node) {
1432
1441
  if (node.nodeName == "DIV") {
@@ -2071,9 +2080,10 @@ function charType(ch) {
2071
2080
  0x600 <= ch && ch <= 0x6f9 ? ArabicTypes[ch - 0x600] :
2072
2081
  0x6ee <= ch && ch <= 0x8ac ? 4 /* AL */ :
2073
2082
  0x2000 <= ch && ch <= 0x200b ? 256 /* NI */ :
2074
- ch == 0x200c ? 256 /* NI */ : 1 /* L */;
2083
+ 0xfb50 <= ch && ch <= 0xfdff ? 4 /* AL */ :
2084
+ ch == 0x200c ? 256 /* NI */ : 1 /* L */;
2075
2085
  }
2076
- const BidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
2086
+ const BidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac\ufb50-\ufdff]/;
2077
2087
  /**
2078
2088
  Represents a contiguous range of text that has a single direction
2079
2089
  (as in left-to-right or right-to-left).
@@ -2477,7 +2487,6 @@ class DocView extends ContentView {
2477
2487
  this.updateDeco();
2478
2488
  this.updateInner([new ChangedRange(0, 0, 0, view.state.doc.length)], 0);
2479
2489
  }
2480
- get root() { return this.view.root; }
2481
2490
  get editorView() { return this.view; }
2482
2491
  get length() { return this.view.state.doc.length; }
2483
2492
  // Update the document view to a given state. scrollIntoView can be
@@ -2600,7 +2609,7 @@ class DocView extends ContentView {
2600
2609
  this.dom.blur();
2601
2610
  this.dom.focus({ preventScroll: true });
2602
2611
  }
2603
- let rawSel = getSelection(this.root);
2612
+ let rawSel = getSelection(this.view.root);
2604
2613
  if (!rawSel) ;
2605
2614
  else if (main.empty) {
2606
2615
  // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=1612076
@@ -2643,7 +2652,7 @@ class DocView extends ContentView {
2643
2652
  if (this.compositionDeco.size)
2644
2653
  return;
2645
2654
  let cursor = this.view.state.selection.main;
2646
- let sel = getSelection(this.root);
2655
+ let sel = getSelection(this.view.root);
2647
2656
  if (!sel || !cursor.empty || !cursor.assoc || !sel.modify)
2648
2657
  return;
2649
2658
  let line = LineView.find(this, cursor.head);
@@ -2660,7 +2669,7 @@ class DocView extends ContentView {
2660
2669
  sel.modify("move", cursor.assoc < 0 ? "forward" : "backward", "lineboundary");
2661
2670
  }
2662
2671
  mayControlSelection() {
2663
- let active = this.root.activeElement;
2672
+ let active = this.view.root.activeElement;
2664
2673
  return active == this.dom ||
2665
2674
  hasSelection(this.dom, this.view.observer.selectionRange) && !(active && this.dom.contains(active));
2666
2675
  }
@@ -3013,7 +3022,7 @@ function upBot(rect, bottom) {
3013
3022
  return bottom > rect.bottom ? { top: rect.top, left: rect.left, right: rect.right, bottom } : rect;
3014
3023
  }
3015
3024
  function domPosAtCoords(parent, x, y) {
3016
- let closest, closestRect, closestX, closestY;
3025
+ let closest, closestRect, closestX, closestY, closestOverlap = false;
3017
3026
  let above, below, aboveRect, belowRect;
3018
3027
  for (let child = parent.firstChild; child; child = child.nextSibling) {
3019
3028
  let rects = clientRectsFor(child);
@@ -3029,6 +3038,7 @@ function domPosAtCoords(parent, x, y) {
3029
3038
  closestRect = rect;
3030
3039
  closestX = dx;
3031
3040
  closestY = dy;
3041
+ closestOverlap = !dx || (dx > 0 ? i < rects.length - 1 : i > 0);
3032
3042
  }
3033
3043
  if (dx == 0) {
3034
3044
  if (y > rect.bottom && (!aboveRect || aboveRect.bottom < rect.bottom)) {
@@ -3061,7 +3071,7 @@ function domPosAtCoords(parent, x, y) {
3061
3071
  let clipX = Math.max(closestRect.left, Math.min(closestRect.right, x));
3062
3072
  if (closest.nodeType == 3)
3063
3073
  return domPosInText(closest, clipX, y);
3064
- if (!closestX && closest.contentEditable == "true")
3074
+ if (closestOverlap && closest.contentEditable != "false")
3065
3075
  return domPosAtCoords(closest, clipX, y);
3066
3076
  let offset = Array.prototype.indexOf.call(parent.childNodes, closest) +
3067
3077
  (x >= (closestRect.left + closestRect.right) / 2 ? 1 : 0);
@@ -3158,7 +3168,8 @@ function posAtCoords(view, { x, y }, precise, bias = -1) {
3158
3168
  let range = doc.caretRangeFromPoint(x, y);
3159
3169
  if (range) {
3160
3170
  ({ startContainer: node, startOffset: offset } = range);
3161
- if (browser.safari && isSuspiciousSafariCaretResult(node, offset, x) ||
3171
+ if (!view.contentDOM.contains(node) ||
3172
+ browser.safari && isSuspiciousSafariCaretResult(node, offset, x) ||
3162
3173
  browser.chrome && isSuspiciousChromeCaretResult(node, offset, x))
3163
3174
  node = undefined;
3164
3175
  }
@@ -3451,9 +3462,10 @@ class InputState {
3451
3462
  // applyDOMChange, notify key handlers of it and reset to
3452
3463
  // the state they produce.
3453
3464
  let pending;
3454
- if (browser.ios && (pending = PendingKeys.find(key => key.keyCode == event.keyCode)) &&
3455
- !(event.ctrlKey || event.altKey || event.metaKey) && !event.synthetic) {
3456
- this.pendingIOSKey = pending;
3465
+ if (browser.ios && !event.synthetic && !event.altKey && !event.metaKey &&
3466
+ ((pending = PendingKeys.find(key => key.keyCode == event.keyCode)) && !event.ctrlKey ||
3467
+ EmacsyPendingKeys.indexOf(event.key) > -1 && event.ctrlKey && !event.shiftKey)) {
3468
+ this.pendingIOSKey = pending || event;
3457
3469
  setTimeout(() => this.flushIOSKey(view), 250);
3458
3470
  return true;
3459
3471
  }
@@ -3508,6 +3520,7 @@ const PendingKeys = [
3508
3520
  { key: "Enter", keyCode: 13, inputType: "insertParagraph" },
3509
3521
  { key: "Delete", keyCode: 46, inputType: "deleteContentForward" }
3510
3522
  ];
3523
+ const EmacsyPendingKeys = "dthko";
3511
3524
  // Key codes for modifier keys
3512
3525
  const modifierCodes = [16, 17, 18, 20, 91, 92, 224, 225];
3513
3526
  class MouseSelection {
@@ -5371,6 +5384,7 @@ const baseTheme$1 = /*@__PURE__*/buildTheme("." + baseThemeID, {
5371
5384
  ".cm-widgetBuffer": {
5372
5385
  verticalAlign: "text-top",
5373
5386
  height: "1em",
5387
+ width: 0,
5374
5388
  display: "inline"
5375
5389
  },
5376
5390
  ".cm-placeholder": {
@@ -5480,7 +5494,9 @@ class DOMObserver {
5480
5494
  this.flushSoon();
5481
5495
  };
5482
5496
  this.onSelectionChange = this.onSelectionChange.bind(this);
5483
- window.addEventListener("resize", this.onResize = this.onResize.bind(this));
5497
+ this.onResize = this.onResize.bind(this);
5498
+ this.onPrint = this.onPrint.bind(this);
5499
+ this.onScroll = this.onScroll.bind(this);
5484
5500
  if (typeof ResizeObserver == "function") {
5485
5501
  this.resize = new ResizeObserver(() => {
5486
5502
  if (this.view.docView.lastUpdate < Date.now() - 75)
@@ -5488,9 +5504,9 @@ class DOMObserver {
5488
5504
  });
5489
5505
  this.resize.observe(view.scrollDOM);
5490
5506
  }
5491
- window.addEventListener("beforeprint", this.onPrint = this.onPrint.bind(this));
5507
+ this.win = view.dom.ownerDocument.defaultView;
5508
+ this.addWindowListeners(this.win);
5492
5509
  this.start();
5493
- window.addEventListener("scroll", this.onScroll = this.onScroll.bind(this));
5494
5510
  if (typeof IntersectionObserver == "function") {
5495
5511
  this.intersection = new IntersectionObserver(entries => {
5496
5512
  if (this.parentCheck < 0)
@@ -5509,7 +5525,6 @@ class DOMObserver {
5509
5525
  }
5510
5526
  this.listenForScroll();
5511
5527
  this.readSelectionRange();
5512
- this.dom.ownerDocument.addEventListener("selectionchange", this.onSelectionChange);
5513
5528
  }
5514
5529
  onScroll(e) {
5515
5530
  if (this.intersecting)
@@ -5540,14 +5555,18 @@ class DOMObserver {
5540
5555
  }
5541
5556
  }
5542
5557
  onSelectionChange(event) {
5558
+ let wasChanged = this.selectionChanged;
5543
5559
  if (!this.readSelectionRange() || this.delayedAndroidKey)
5544
5560
  return;
5545
5561
  let { view } = this, sel = this.selectionRange;
5546
5562
  if (view.state.facet(editable) ? view.root.activeElement != this.dom : !hasSelection(view.dom, sel))
5547
5563
  return;
5548
5564
  let context = sel.anchorNode && view.docView.nearest(sel.anchorNode);
5549
- if (context && context.ignoreEvent(event))
5565
+ if (context && context.ignoreEvent(event)) {
5566
+ if (!wasChanged)
5567
+ this.selectionChanged = false;
5550
5568
  return;
5569
+ }
5551
5570
  // Deletions on IE11 fire their events in the wrong order, giving
5552
5571
  // us a selection change event before the DOM changes are
5553
5572
  // reported.
@@ -5564,7 +5583,8 @@ class DOMObserver {
5564
5583
  let { view } = this;
5565
5584
  // The Selection object is broken in shadow roots in Safari. See
5566
5585
  // https://github.com/codemirror/dev/issues/414
5567
- let range = browser.safari && view.root.nodeType == 11 && deepActiveElement() == this.dom &&
5586
+ let range = browser.safari && view.root.nodeType == 11 &&
5587
+ deepActiveElement(this.dom.ownerDocument) == this.dom &&
5568
5588
  safariSelectionRangeHack(this.view) || getSelection(view.root);
5569
5589
  if (!range || this.selectionRange.eq(range))
5570
5590
  return false;
@@ -5724,6 +5744,7 @@ class DOMObserver {
5724
5744
  let newSel = this.selectionChanged && hasSelection(this.dom, this.selectionRange);
5725
5745
  if (from < 0 && !newSel)
5726
5746
  return;
5747
+ this.view.inputState.lastFocusTime = 0;
5727
5748
  this.selectionChanged = false;
5728
5749
  let startState = this.view.state;
5729
5750
  let handled = this.onChange(from, to, typeOver);
@@ -5752,6 +5773,25 @@ class DOMObserver {
5752
5773
  return null;
5753
5774
  }
5754
5775
  }
5776
+ setWindow(win) {
5777
+ if (win != this.win) {
5778
+ this.removeWindowListeners(this.win);
5779
+ this.win = win;
5780
+ this.addWindowListeners(this.win);
5781
+ }
5782
+ }
5783
+ addWindowListeners(win) {
5784
+ win.addEventListener("resize", this.onResize);
5785
+ win.addEventListener("beforeprint", this.onPrint);
5786
+ win.addEventListener("scroll", this.onScroll);
5787
+ win.document.addEventListener("selectionchange", this.onSelectionChange);
5788
+ }
5789
+ removeWindowListeners(win) {
5790
+ win.removeEventListener("scroll", this.onScroll);
5791
+ win.removeEventListener("resize", this.onResize);
5792
+ win.removeEventListener("beforeprint", this.onPrint);
5793
+ win.document.removeEventListener("selectionchange", this.onSelectionChange);
5794
+ }
5755
5795
  destroy() {
5756
5796
  var _a, _b, _c;
5757
5797
  this.stop();
@@ -5760,10 +5800,7 @@ class DOMObserver {
5760
5800
  (_c = this.resize) === null || _c === void 0 ? void 0 : _c.disconnect();
5761
5801
  for (let dom of this.scrollTargets)
5762
5802
  dom.removeEventListener("scroll", this.onScroll);
5763
- window.removeEventListener("scroll", this.onScroll);
5764
- window.removeEventListener("resize", this.onResize);
5765
- window.removeEventListener("beforeprint", this.onPrint);
5766
- this.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange);
5803
+ this.removeWindowListeners(this.win);
5767
5804
  clearTimeout(this.parentCheck);
5768
5805
  clearTimeout(this.resizeTimeout);
5769
5806
  }
@@ -5792,7 +5829,7 @@ function safariSelectionRangeHack(view) {
5792
5829
  found = event.getTargetRanges()[0];
5793
5830
  }
5794
5831
  view.contentDOM.addEventListener("beforeinput", read, true);
5795
- document.execCommand("indent");
5832
+ view.dom.ownerDocument.execCommand("indent");
5796
5833
  view.contentDOM.removeEventListener("beforeinput", read, true);
5797
5834
  if (!found)
5798
5835
  return null;
@@ -6071,7 +6108,7 @@ class EditorView {
6071
6108
  this.dom.appendChild(this.scrollDOM);
6072
6109
  this._dispatch = config.dispatch || ((tr) => this.update([tr]));
6073
6110
  this.dispatch = this.dispatch.bind(this);
6074
- this.root = (config.root || getRoot(config.parent) || document);
6111
+ this._root = (config.root || getRoot(config.parent) || document);
6075
6112
  this.viewState = new ViewState(config.state || EditorState.create(config));
6076
6113
  this.plugins = this.state.facet(viewPlugin).map(spec => new PluginInstance(spec));
6077
6114
  for (let plugin of this.plugins)
@@ -6132,6 +6169,10 @@ class EditorView {
6132
6169
  composition there.
6133
6170
  */
6134
6171
  get compositionStarted() { return this.inputState.composing >= 0; }
6172
+ /**
6173
+ The document or shadow root that the view lives in.
6174
+ */
6175
+ get root() { return this._root; }
6135
6176
  dispatch(...input) {
6136
6177
  this._dispatch(input.length == 1 && input[0] instanceof Transaction ? input[0]
6137
6178
  : this.state.update(...input));
@@ -6467,7 +6508,7 @@ class EditorView {
6467
6508
  /**
6468
6509
  Find the text line or block widget at the given vertical
6469
6510
  position (which is interpreted as relative to the [top of the
6470
- document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop)
6511
+ document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop)).
6471
6512
  */
6472
6513
  elementAtHeight(height) {
6473
6514
  this.readMeasured();
@@ -6476,7 +6517,8 @@ class EditorView {
6476
6517
  /**
6477
6518
  Find the line block (see
6478
6519
  [`lineBlockAt`](https://codemirror.net/6/docs/ref/#view.EditorView.lineBlockAt) at the given
6479
- height.
6520
+ height, again interpreted relative to the [top of the
6521
+ document](https://codemirror.net/6/docs/ref/#view.EditorView.documentTop).
6480
6522
  */
6481
6523
  lineBlockAtHeight(height) {
6482
6524
  this.readMeasured();
@@ -6670,7 +6712,7 @@ class EditorView {
6670
6712
  // or closing, which leads us to ignore selection changes from the
6671
6713
  // context menu because it looks like the editor isn't focused.
6672
6714
  // This kludges around that.
6673
- return (document.hasFocus() || browser.safari && ((_a = this.inputState) === null || _a === void 0 ? void 0 : _a.lastContextMenu) > Date.now() - 3e4) &&
6715
+ return (this.dom.ownerDocument.hasFocus() || browser.safari && ((_a = this.inputState) === null || _a === void 0 ? void 0 : _a.lastContextMenu) > Date.now() - 3e4) &&
6674
6716
  this.root.activeElement == this.contentDOM;
6675
6717
  }
6676
6718
  /**
@@ -6683,6 +6725,17 @@ class EditorView {
6683
6725
  });
6684
6726
  }
6685
6727
  /**
6728
+ Update the [root](https://codemirror.net/6/docs/ref/##view.EditorViewConfig.root) in which the editor lives. This is only
6729
+ necessary when moving the editor's existing DOM to a new window or shadow root.
6730
+ */
6731
+ setRoot(root) {
6732
+ if (this._root != root) {
6733
+ this._root = root;
6734
+ this.observer.setWindow((root.nodeType == 9 ? root : root.ownerDocument).defaultView);
6735
+ this.mountStyles();
6736
+ }
6737
+ }
6738
+ /**
6686
6739
  Clean up this editor view, removing its element from the
6687
6740
  document, unregistering event handlers, and notifying
6688
6741
  plugins. The view instance can no longer be used after
@@ -6844,6 +6897,11 @@ the editor's vertical layout structure. The ones provided as
6844
6897
  functions are called _after_ the new viewport has been computed,
6845
6898
  and thus **must not** introduce block widgets or replacing
6846
6899
  decorations that cover line breaks.
6900
+
6901
+ If you want decorated ranges to behave like atomic units for
6902
+ cursor motion and deletion purposes, also provide the range set
6903
+ containing the decorations to
6904
+ [`EditorView.atomicRanges`](https://codemirror.net/6/docs/ref/#view.EditorView^atomicRanges).
6847
6905
  */
6848
6906
  EditorView.decorations = decorations;
6849
6907
  /**
@@ -7074,7 +7132,7 @@ function runHandlers(map, event, view, scope) {
7074
7132
  }
7075
7133
  return false;
7076
7134
  };
7077
- let scopeObj = map[scope], baseName;
7135
+ let scopeObj = map[scope], baseName, shiftName;
7078
7136
  if (scopeObj) {
7079
7137
  if (runFor(scopeObj[prefix + modifiers(name, event, !isChar)]))
7080
7138
  return true;
@@ -7082,8 +7140,8 @@ function runHandlers(map, event, view, scope) {
7082
7140
  (baseName = base[event.keyCode]) && baseName != name) {
7083
7141
  if (runFor(scopeObj[prefix + modifiers(baseName, event, true)]))
7084
7142
  return true;
7085
- else if (event.shiftKey && shift[event.keyCode] != baseName &&
7086
- runFor(scopeObj[prefix + modifiers(shift[event.keyCode], event, false)]))
7143
+ else if (event.shiftKey && (shiftName = shift[event.keyCode]) != name && shiftName != baseName &&
7144
+ runFor(scopeObj[prefix + modifiers(shiftName, event, false)]))
7087
7145
  return true;
7088
7146
  }
7089
7147
  else if (isChar && event.shiftKey) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/view",
3
- "version": "6.1.4",
3
+ "version": "6.2.2",
4
4
  "description": "DOM view component for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",