@codemirror/view 6.0.0 → 6.0.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.
@@ -11,6 +11,6 @@ jobs:
11
11
  with:
12
12
  # You should create a personal access token and store it in your repository
13
13
  token: ${{ secrets.DISPATCH_AUTH }}
14
- repo: codemirror.next
14
+ repo: dev
15
15
  owner: codemirror
16
16
  event_type: push
package/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 6.0.1 (2022-06-17)
2
+
3
+ ### Bug fixes
4
+
5
+ Avoid DOM selection corruption when the editor doesn't have focus but has selection and updates its content.
6
+
7
+ Fall back to dispatching by key code when a key event produces a non-ASCII character (so that Cyrillic and Arabic keyboards can still use bindings specified with Latin characters).
8
+
1
9
  ## 6.0.0 (2022-06-08)
2
10
 
3
11
  ### New features
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # @codemirror/view [![NPM version](https://img.shields.io/npm/v/@codemirror/view.svg)](https://www.npmjs.org/package/@codemirror/view)
2
2
 
3
- [ [**WEBSITE**](https://codemirror.net/6/) | [**DOCS**](https://codemirror.net/6/docs/ref/#view) | [**ISSUES**](https://github.com/codemirror/codemirror.next/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/view/blob/main/CHANGELOG.md) ]
3
+ [ [**WEBSITE**](https://codemirror.net/) | [**DOCS**](https://codemirror.net/docs/ref/#view) | [**ISSUES**](https://github.com/codemirror/dev/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/view/blob/main/CHANGELOG.md) ]
4
4
 
5
5
  This package implements the DOM view component for the
6
- [CodeMirror](https://codemirror.net/6/) code editor.
6
+ [CodeMirror](https://codemirror.net/) code editor.
7
7
 
8
- The [project page](https://codemirror.net/6/) has more information, a
9
- number of [examples](https://codemirror.net/6/examples/) and the
10
- [documentation](https://codemirror.net/6/docs/).
8
+ The [project page](https://codemirror.net/) has more information, a
9
+ number of [examples](https://codemirror.net/examples/) and the
10
+ [documentation](https://codemirror.net/docs/).
11
11
 
12
12
  This code is released under an
13
13
  [MIT license](https://github.com/codemirror/view/tree/main/LICENSE).
package/dist/index.cjs CHANGED
@@ -2545,7 +2545,7 @@ class DocView extends ContentView {
2545
2545
  }
2546
2546
  // Sync the DOM selection to this.state.selection
2547
2547
  updateSelection(mustRead = false, fromPointer = false) {
2548
- if (mustRead)
2548
+ if (mustRead || !this.view.observer.selectionRange.focusNode)
2549
2549
  this.view.observer.readSelectionRange();
2550
2550
  if (!(fromPointer || this.mayControlSelection()) ||
2551
2551
  browser.ios && this.view.inputState.rapidCompositionStart)
@@ -2580,7 +2580,8 @@ class DocView extends ContentView {
2580
2580
  this.dom.focus({ preventScroll: true });
2581
2581
  }
2582
2582
  let rawSel = getSelection(this.root);
2583
- if (main.empty) {
2583
+ if (!rawSel) ;
2584
+ else if (main.empty) {
2584
2585
  // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=1612076
2585
2586
  if (browser.gecko) {
2586
2587
  let nextTo = nextToUneditable(anchor.node, anchor.offset);
@@ -2622,7 +2623,7 @@ class DocView extends ContentView {
2622
2623
  return;
2623
2624
  let cursor = this.view.state.selection.main;
2624
2625
  let sel = getSelection(this.root);
2625
- if (!cursor.empty || !cursor.assoc || !sel.modify)
2626
+ if (!sel || !cursor.empty || !cursor.assoc || !sel.modify)
2626
2627
  return;
2627
2628
  let line = LineView.find(this, cursor.head);
2628
2629
  if (!line)
@@ -2638,8 +2639,9 @@ class DocView extends ContentView {
2638
2639
  sel.modify("move", cursor.assoc < 0 ? "forward" : "backward", "lineboundary");
2639
2640
  }
2640
2641
  mayControlSelection() {
2641
- return this.view.state.facet(editable) ? this.root.activeElement == this.dom
2642
- : hasSelection(this.dom, this.view.observer.selectionRange);
2642
+ let active = this.root.activeElement;
2643
+ return active == this.dom ||
2644
+ hasSelection(this.dom, this.view.observer.selectionRange) && !(active && this.dom.contains(active));
2643
2645
  }
2644
2646
  nearest(dom) {
2645
2647
  for (let cur = dom; cur;) {
@@ -3536,7 +3538,7 @@ function isInPrimarySelection(view, event) {
3536
3538
  // On boundary clicks, check whether the coordinates are inside the
3537
3539
  // selection's client rectangles
3538
3540
  let sel = getSelection(view.root);
3539
- if (sel.rangeCount == 0)
3541
+ if (!sel || sel.rangeCount == 0)
3540
3542
  return true;
3541
3543
  let rects = sel.getRangeAt(0).getClientRects();
3542
3544
  for (let i = 0; i < rects.length; i++) {
@@ -5495,12 +5497,12 @@ class DOMObserver {
5495
5497
  this.flush(false);
5496
5498
  }
5497
5499
  readSelectionRange() {
5498
- let { root } = this.view, domSel = getSelection(root);
5500
+ let { root } = this.view;
5499
5501
  // The Selection object is broken in shadow roots in Safari. See
5500
- // https://github.com/codemirror/codemirror.next/issues/414
5502
+ // https://github.com/codemirror/dev/issues/414
5501
5503
  let range = browser.safari && root.nodeType == 11 && deepActiveElement() == this.view.contentDOM &&
5502
- safariSelectionRangeHack(this.view) || domSel;
5503
- if (this.selectionRange.eq(range))
5504
+ safariSelectionRangeHack(this.view) || getSelection(root);
5505
+ if (!range || this.selectionRange.eq(range))
5504
5506
  return false;
5505
5507
  this.selectionRange.setRange(range);
5506
5508
  return this.selectionChanged = true;
@@ -6966,7 +6968,8 @@ function buildKeymap(bindings, platform = currentPlatform) {
6966
6968
  return bound;
6967
6969
  }
6968
6970
  function runHandlers(map, event, view, scope) {
6969
- let name = w3cKeyname.keyName(event), isChar = name.length == 1 && name != " ";
6971
+ let name = w3cKeyname.keyName(event);
6972
+ let charCode = state.codePointAt(name, 0), isChar = state.codePointSize(charCode) == name.length && name != " ";
6970
6973
  let prefix = "", fallthrough = false;
6971
6974
  if (storedPrefix && storedPrefix.view == view && storedPrefix.scope == scope) {
6972
6975
  prefix = storedPrefix.prefix + " ";
@@ -6987,10 +6990,13 @@ function runHandlers(map, event, view, scope) {
6987
6990
  if (scopeObj) {
6988
6991
  if (runFor(scopeObj[prefix + modifiers(name, event, !isChar)]))
6989
6992
  return true;
6990
- if (isChar && (event.shiftKey || event.altKey || event.metaKey) &&
6993
+ if (isChar && (event.shiftKey || event.altKey || event.metaKey || charCode > 127) &&
6991
6994
  (baseName = w3cKeyname.base[event.keyCode]) && baseName != name) {
6992
6995
  if (runFor(scopeObj[prefix + modifiers(baseName, event, true)]))
6993
6996
  return true;
6997
+ else if (event.shiftKey && w3cKeyname.shift[event.keyCode] != baseName &&
6998
+ runFor(scopeObj[prefix + modifiers(w3cKeyname.shift[event.keyCode], event, false)]))
6999
+ return true;
6994
7000
  }
6995
7001
  else if (isChar && event.shiftKey) {
6996
7002
  if (runFor(scopeObj[prefix + modifiers(name, event, true)]))
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { Text, RangeSet, MapMode, RangeValue, Facet, StateEffect, ChangeSet, findClusterBreak, EditorSelection, EditorState, findColumn, CharCategory, Prec, Transaction, combineConfig, StateField, RangeSetBuilder, codePointAt, countColumn } from '@codemirror/state';
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';
2
2
  import { StyleModule } from 'style-mod';
3
- import { keyName, base } from 'w3c-keyname';
3
+ import { keyName, base, shift } from 'w3c-keyname';
4
4
 
5
5
  function getSelection(root) {
6
6
  let target;
@@ -2539,7 +2539,7 @@ class DocView extends ContentView {
2539
2539
  }
2540
2540
  // Sync the DOM selection to this.state.selection
2541
2541
  updateSelection(mustRead = false, fromPointer = false) {
2542
- if (mustRead)
2542
+ if (mustRead || !this.view.observer.selectionRange.focusNode)
2543
2543
  this.view.observer.readSelectionRange();
2544
2544
  if (!(fromPointer || this.mayControlSelection()) ||
2545
2545
  browser.ios && this.view.inputState.rapidCompositionStart)
@@ -2574,7 +2574,8 @@ class DocView extends ContentView {
2574
2574
  this.dom.focus({ preventScroll: true });
2575
2575
  }
2576
2576
  let rawSel = getSelection(this.root);
2577
- if (main.empty) {
2577
+ if (!rawSel) ;
2578
+ else if (main.empty) {
2578
2579
  // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=1612076
2579
2580
  if (browser.gecko) {
2580
2581
  let nextTo = nextToUneditable(anchor.node, anchor.offset);
@@ -2616,7 +2617,7 @@ class DocView extends ContentView {
2616
2617
  return;
2617
2618
  let cursor = this.view.state.selection.main;
2618
2619
  let sel = getSelection(this.root);
2619
- if (!cursor.empty || !cursor.assoc || !sel.modify)
2620
+ if (!sel || !cursor.empty || !cursor.assoc || !sel.modify)
2620
2621
  return;
2621
2622
  let line = LineView.find(this, cursor.head);
2622
2623
  if (!line)
@@ -2632,8 +2633,9 @@ class DocView extends ContentView {
2632
2633
  sel.modify("move", cursor.assoc < 0 ? "forward" : "backward", "lineboundary");
2633
2634
  }
2634
2635
  mayControlSelection() {
2635
- return this.view.state.facet(editable) ? this.root.activeElement == this.dom
2636
- : hasSelection(this.dom, this.view.observer.selectionRange);
2636
+ let active = this.root.activeElement;
2637
+ return active == this.dom ||
2638
+ hasSelection(this.dom, this.view.observer.selectionRange) && !(active && this.dom.contains(active));
2637
2639
  }
2638
2640
  nearest(dom) {
2639
2641
  for (let cur = dom; cur;) {
@@ -3530,7 +3532,7 @@ function isInPrimarySelection(view, event) {
3530
3532
  // On boundary clicks, check whether the coordinates are inside the
3531
3533
  // selection's client rectangles
3532
3534
  let sel = getSelection(view.root);
3533
- if (sel.rangeCount == 0)
3535
+ if (!sel || sel.rangeCount == 0)
3534
3536
  return true;
3535
3537
  let rects = sel.getRangeAt(0).getClientRects();
3536
3538
  for (let i = 0; i < rects.length; i++) {
@@ -5488,12 +5490,12 @@ class DOMObserver {
5488
5490
  this.flush(false);
5489
5491
  }
5490
5492
  readSelectionRange() {
5491
- let { root } = this.view, domSel = getSelection(root);
5493
+ let { root } = this.view;
5492
5494
  // The Selection object is broken in shadow roots in Safari. See
5493
- // https://github.com/codemirror/codemirror.next/issues/414
5495
+ // https://github.com/codemirror/dev/issues/414
5494
5496
  let range = browser.safari && root.nodeType == 11 && deepActiveElement() == this.view.contentDOM &&
5495
- safariSelectionRangeHack(this.view) || domSel;
5496
- if (this.selectionRange.eq(range))
5497
+ safariSelectionRangeHack(this.view) || getSelection(root);
5498
+ if (!range || this.selectionRange.eq(range))
5497
5499
  return false;
5498
5500
  this.selectionRange.setRange(range);
5499
5501
  return this.selectionChanged = true;
@@ -6959,7 +6961,8 @@ function buildKeymap(bindings, platform = currentPlatform) {
6959
6961
  return bound;
6960
6962
  }
6961
6963
  function runHandlers(map, event, view, scope) {
6962
- let name = keyName(event), isChar = name.length == 1 && name != " ";
6964
+ let name = keyName(event);
6965
+ let charCode = codePointAt(name, 0), isChar = codePointSize(charCode) == name.length && name != " ";
6963
6966
  let prefix = "", fallthrough = false;
6964
6967
  if (storedPrefix && storedPrefix.view == view && storedPrefix.scope == scope) {
6965
6968
  prefix = storedPrefix.prefix + " ";
@@ -6980,10 +6983,13 @@ function runHandlers(map, event, view, scope) {
6980
6983
  if (scopeObj) {
6981
6984
  if (runFor(scopeObj[prefix + modifiers(name, event, !isChar)]))
6982
6985
  return true;
6983
- if (isChar && (event.shiftKey || event.altKey || event.metaKey) &&
6986
+ if (isChar && (event.shiftKey || event.altKey || event.metaKey || charCode > 127) &&
6984
6987
  (baseName = base[event.keyCode]) && baseName != name) {
6985
6988
  if (runFor(scopeObj[prefix + modifiers(baseName, event, true)]))
6986
6989
  return true;
6990
+ else if (event.shiftKey && shift[event.keyCode] != baseName &&
6991
+ runFor(scopeObj[prefix + modifiers(shift[event.keyCode], event, false)]))
6992
+ return true;
6987
6993
  }
6988
6994
  else if (isChar && event.shiftKey) {
6989
6995
  if (runFor(scopeObj[prefix + modifiers(name, event, true)]))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/view",
3
- "version": "6.0.0",
3
+ "version": "6.0.1",
4
4
  "description": "DOM view component for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",