@codemirror/view 6.22.1 → 6.22.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,11 @@
1
+ ## 6.22.2 (2023-12-08)
2
+
3
+ ### Bug fixes
4
+
5
+ Fix an issue in the bidirectional motion that could cause the cursor to get stuck in a loop when a zero-width non-joiner char was placed on a direction boundary.
6
+
7
+ Fix a bug that corrupts the editor's internal view tree data structure on some types of edits, putting the editor in a broken state.
8
+
1
9
  ## 6.22.1 (2023-11-27)
2
10
 
3
11
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -96,6 +96,15 @@ function windowRect(win) {
96
96
  return { left: 0, right: win.innerWidth,
97
97
  top: 0, bottom: win.innerHeight };
98
98
  }
99
+ function getScale(elt, rect) {
100
+ let scaleX = rect.width / elt.offsetWidth;
101
+ let scaleY = rect.height / elt.offsetHeight;
102
+ if (scaleX > 0.995 && scaleX < 1.005 || !isFinite(scaleX) || Math.abs(rect.width - elt.offsetWidth) < 1)
103
+ scaleX = 1;
104
+ if (scaleY > 0.995 && scaleY < 1.005 || !isFinite(scaleY) || Math.abs(rect.height - elt.offsetHeight) < 1)
105
+ scaleY = 1;
106
+ return { scaleX, scaleY };
107
+ }
99
108
  function scrollRectIntoView(dom, rect, side, x, y, xMargin, yMargin, ltr) {
100
109
  let doc = dom.ownerDocument, win = doc.defaultView || window;
101
110
  for (let cur = dom, stop = false; cur && !stop;) {
@@ -113,8 +122,7 @@ function scrollRectIntoView(dom, rect, side, x, y, xMargin, yMargin, ltr) {
113
122
  continue;
114
123
  }
115
124
  let rect = cur.getBoundingClientRect();
116
- scaleX = rect.width / cur.offsetWidth;
117
- scaleY = rect.height / cur.offsetHeight;
125
+ ({ scaleX, scaleY } = getScale(cur, rect));
118
126
  // Make sure scrollbar width isn't included in the rectangle
119
127
  bounding = { left: rect.left, right: rect.left + cur.clientWidth * scaleX,
120
128
  top: rect.top, bottom: rect.top + cur.clientHeight * scaleY };
@@ -541,7 +549,8 @@ class ContentView {
541
549
  getSide() { return 0; }
542
550
  destroy() {
543
551
  for (let child of this.children)
544
- child.destroy();
552
+ if (child.parent == this)
553
+ child.destroy();
545
554
  this.parent = null;
546
555
  }
547
556
  }
@@ -778,7 +787,7 @@ class MarkView extends ContentView {
778
787
  if (source && (!(source instanceof MarkView && source.mark.eq(this.mark)) ||
779
788
  (from && openStart <= 0) || (to < this.length && openEnd <= 0)))
780
789
  return false;
781
- mergeChildrenInto(this, from, to, source ? source.children : [], openStart - 1, openEnd - 1);
790
+ mergeChildrenInto(this, from, to, source ? source.children.slice() : [], openStart - 1, openEnd - 1);
782
791
  this.markDirty();
783
792
  return true;
784
793
  }
@@ -1114,7 +1123,7 @@ class LineView extends ContentView {
1114
1123
  }
1115
1124
  if (hasStart)
1116
1125
  this.setDeco(source ? source.attrs : null);
1117
- mergeChildrenInto(this, from, to, source ? source.children : [], openStart, openEnd);
1126
+ mergeChildrenInto(this, from, to, source ? source.children.slice() : [], openStart, openEnd);
1118
1127
  return true;
1119
1128
  }
1120
1129
  split(at) {
@@ -2185,9 +2194,8 @@ function charType(ch) {
2185
2194
  0x590 <= ch && ch <= 0x5f4 ? 2 /* T.R */ :
2186
2195
  0x600 <= ch && ch <= 0x6f9 ? ArabicTypes[ch - 0x600] :
2187
2196
  0x6ee <= ch && ch <= 0x8ac ? 4 /* T.AL */ :
2188
- 0x2000 <= ch && ch <= 0x200b ? 256 /* T.NI */ :
2189
- 0xfb50 <= ch && ch <= 0xfdff ? 4 /* T.AL */ :
2190
- ch == 0x200c ? 256 /* T.NI */ : 1 /* T.L */;
2197
+ 0x2000 <= ch && ch <= 0x200c ? 256 /* T.NI */ :
2198
+ 0xfb50 <= ch && ch <= 0xfdff ? 4 /* T.AL */ : 1 /* T.L */;
2191
2199
  }
2192
2200
  const BidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac\ufb50-\ufdff]/;
2193
2201
  /**
@@ -2608,7 +2616,7 @@ function moveVisually(line, order, dir, start, forward) {
2608
2616
  let indexForward = forward == (span.dir == dir);
2609
2617
  let nextIndex = state.findClusterBreak(line.text, startIndex, indexForward);
2610
2618
  movedOver = line.text.slice(Math.min(startIndex, nextIndex), Math.max(startIndex, nextIndex));
2611
- if (nextIndex != span.side(forward, dir))
2619
+ if (nextIndex > span.from && nextIndex < span.to)
2612
2620
  return state.EditorSelection.cursor(nextIndex + line.from, indexForward ? -1 : 1, span.level);
2613
2621
  let nextSpan = spanI == (forward ? order.length - 1 : 0) ? null : order[spanI + (forward ? 1 : -1)];
2614
2622
  if (!nextSpan && span.level != dir)
@@ -5362,12 +5370,7 @@ class ViewState {
5362
5370
  this.mustMeasureContent = false;
5363
5371
  let result = 0, bias = 0;
5364
5372
  if (domRect.width && domRect.height) {
5365
- let scaleX = domRect.width / dom.offsetWidth;
5366
- let scaleY = domRect.height / dom.offsetHeight;
5367
- if (scaleX > 0.995 && scaleX < 1.005 || !isFinite(scaleX) || Math.abs(domRect.width - dom.offsetWidth) < 1)
5368
- scaleX = 1;
5369
- if (scaleY > 0.995 && scaleY < 1.005 || !isFinite(scaleY) || Math.abs(domRect.height - dom.offsetHeight) < 1)
5370
- scaleY = 1;
5373
+ let { scaleX, scaleY } = getScale(dom, domRect);
5371
5374
  if (this.scaleX != scaleX || this.scaleY != scaleY) {
5372
5375
  this.scaleX = scaleX;
5373
5376
  this.scaleY = scaleY;
@@ -7237,6 +7240,7 @@ class EditorView {
7237
7240
  if (this.viewState.scrollTarget) {
7238
7241
  this.docView.scrollIntoView(this.viewState.scrollTarget);
7239
7242
  this.viewState.scrollTarget = null;
7243
+ scrollAnchorHeight = -1;
7240
7244
  continue;
7241
7245
  }
7242
7246
  else {
package/dist/index.js CHANGED
@@ -94,6 +94,15 @@ function windowRect(win) {
94
94
  return { left: 0, right: win.innerWidth,
95
95
  top: 0, bottom: win.innerHeight };
96
96
  }
97
+ function getScale(elt, rect) {
98
+ let scaleX = rect.width / elt.offsetWidth;
99
+ let scaleY = rect.height / elt.offsetHeight;
100
+ if (scaleX > 0.995 && scaleX < 1.005 || !isFinite(scaleX) || Math.abs(rect.width - elt.offsetWidth) < 1)
101
+ scaleX = 1;
102
+ if (scaleY > 0.995 && scaleY < 1.005 || !isFinite(scaleY) || Math.abs(rect.height - elt.offsetHeight) < 1)
103
+ scaleY = 1;
104
+ return { scaleX, scaleY };
105
+ }
97
106
  function scrollRectIntoView(dom, rect, side, x, y, xMargin, yMargin, ltr) {
98
107
  let doc = dom.ownerDocument, win = doc.defaultView || window;
99
108
  for (let cur = dom, stop = false; cur && !stop;) {
@@ -111,8 +120,7 @@ function scrollRectIntoView(dom, rect, side, x, y, xMargin, yMargin, ltr) {
111
120
  continue;
112
121
  }
113
122
  let rect = cur.getBoundingClientRect();
114
- scaleX = rect.width / cur.offsetWidth;
115
- scaleY = rect.height / cur.offsetHeight;
123
+ ({ scaleX, scaleY } = getScale(cur, rect));
116
124
  // Make sure scrollbar width isn't included in the rectangle
117
125
  bounding = { left: rect.left, right: rect.left + cur.clientWidth * scaleX,
118
126
  top: rect.top, bottom: rect.top + cur.clientHeight * scaleY };
@@ -539,7 +547,8 @@ class ContentView {
539
547
  getSide() { return 0; }
540
548
  destroy() {
541
549
  for (let child of this.children)
542
- child.destroy();
550
+ if (child.parent == this)
551
+ child.destroy();
543
552
  this.parent = null;
544
553
  }
545
554
  }
@@ -776,7 +785,7 @@ class MarkView extends ContentView {
776
785
  if (source && (!(source instanceof MarkView && source.mark.eq(this.mark)) ||
777
786
  (from && openStart <= 0) || (to < this.length && openEnd <= 0)))
778
787
  return false;
779
- mergeChildrenInto(this, from, to, source ? source.children : [], openStart - 1, openEnd - 1);
788
+ mergeChildrenInto(this, from, to, source ? source.children.slice() : [], openStart - 1, openEnd - 1);
780
789
  this.markDirty();
781
790
  return true;
782
791
  }
@@ -1112,7 +1121,7 @@ class LineView extends ContentView {
1112
1121
  }
1113
1122
  if (hasStart)
1114
1123
  this.setDeco(source ? source.attrs : null);
1115
- mergeChildrenInto(this, from, to, source ? source.children : [], openStart, openEnd);
1124
+ mergeChildrenInto(this, from, to, source ? source.children.slice() : [], openStart, openEnd);
1116
1125
  return true;
1117
1126
  }
1118
1127
  split(at) {
@@ -2181,9 +2190,8 @@ function charType(ch) {
2181
2190
  0x590 <= ch && ch <= 0x5f4 ? 2 /* T.R */ :
2182
2191
  0x600 <= ch && ch <= 0x6f9 ? ArabicTypes[ch - 0x600] :
2183
2192
  0x6ee <= ch && ch <= 0x8ac ? 4 /* T.AL */ :
2184
- 0x2000 <= ch && ch <= 0x200b ? 256 /* T.NI */ :
2185
- 0xfb50 <= ch && ch <= 0xfdff ? 4 /* T.AL */ :
2186
- ch == 0x200c ? 256 /* T.NI */ : 1 /* T.L */;
2193
+ 0x2000 <= ch && ch <= 0x200c ? 256 /* T.NI */ :
2194
+ 0xfb50 <= ch && ch <= 0xfdff ? 4 /* T.AL */ : 1 /* T.L */;
2187
2195
  }
2188
2196
  const BidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac\ufb50-\ufdff]/;
2189
2197
  /**
@@ -2604,7 +2612,7 @@ function moveVisually(line, order, dir, start, forward) {
2604
2612
  let indexForward = forward == (span.dir == dir);
2605
2613
  let nextIndex = findClusterBreak(line.text, startIndex, indexForward);
2606
2614
  movedOver = line.text.slice(Math.min(startIndex, nextIndex), Math.max(startIndex, nextIndex));
2607
- if (nextIndex != span.side(forward, dir))
2615
+ if (nextIndex > span.from && nextIndex < span.to)
2608
2616
  return EditorSelection.cursor(nextIndex + line.from, indexForward ? -1 : 1, span.level);
2609
2617
  let nextSpan = spanI == (forward ? order.length - 1 : 0) ? null : order[spanI + (forward ? 1 : -1)];
2610
2618
  if (!nextSpan && span.level != dir)
@@ -5357,12 +5365,7 @@ class ViewState {
5357
5365
  this.mustMeasureContent = false;
5358
5366
  let result = 0, bias = 0;
5359
5367
  if (domRect.width && domRect.height) {
5360
- let scaleX = domRect.width / dom.offsetWidth;
5361
- let scaleY = domRect.height / dom.offsetHeight;
5362
- if (scaleX > 0.995 && scaleX < 1.005 || !isFinite(scaleX) || Math.abs(domRect.width - dom.offsetWidth) < 1)
5363
- scaleX = 1;
5364
- if (scaleY > 0.995 && scaleY < 1.005 || !isFinite(scaleY) || Math.abs(domRect.height - dom.offsetHeight) < 1)
5365
- scaleY = 1;
5368
+ let { scaleX, scaleY } = getScale(dom, domRect);
5366
5369
  if (this.scaleX != scaleX || this.scaleY != scaleY) {
5367
5370
  this.scaleX = scaleX;
5368
5371
  this.scaleY = scaleY;
@@ -7232,6 +7235,7 @@ class EditorView {
7232
7235
  if (this.viewState.scrollTarget) {
7233
7236
  this.docView.scrollIntoView(this.viewState.scrollTarget);
7234
7237
  this.viewState.scrollTarget = null;
7238
+ scrollAnchorHeight = -1;
7235
7239
  continue;
7236
7240
  }
7237
7241
  else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/view",
3
- "version": "6.22.1",
3
+ "version": "6.22.2",
4
4
  "description": "DOM view component for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",