@codemirror/view 6.2.3 → 6.2.4

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.2.4 (2022-09-16)
2
+
3
+ ### Bug fixes
4
+
5
+ Highlight the active line even when there is a selection. Prevent the active line background from obscuring the selection backdrop.
6
+
7
+ Fix an issue where elements with negative margins would confuse the editor's scrolling-into-view logic.
8
+
9
+ Fix scrolling to a specific position in an editor that has not been in view yet.
10
+
1
11
  ## 6.2.3 (2022-09-08)
2
12
 
3
13
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -109,7 +109,7 @@ function scrollRectIntoView(dom, rect, side, x, y, xMargin, yMargin, ltr) {
109
109
  }
110
110
  else {
111
111
  if (cur.scrollHeight <= cur.clientHeight && cur.scrollWidth <= cur.clientWidth) {
112
- cur = cur.parentNode;
112
+ cur = cur.assignedSlot || cur.parentNode;
113
113
  continue;
114
114
  }
115
115
  let rect = cur.getBoundingClientRect();
@@ -160,24 +160,28 @@ function scrollRectIntoView(dom, rect, side, x, y, xMargin, yMargin, ltr) {
160
160
  win.scrollBy(moveX, moveY);
161
161
  }
162
162
  else {
163
+ let movedX = 0, movedY = 0;
163
164
  if (moveY) {
164
165
  let start = cur.scrollTop;
165
166
  cur.scrollTop += moveY;
166
- moveY = cur.scrollTop - start;
167
+ movedY = cur.scrollTop - start;
167
168
  }
168
169
  if (moveX) {
169
170
  let start = cur.scrollLeft;
170
171
  cur.scrollLeft += moveX;
171
- moveX = cur.scrollLeft - start;
172
+ movedX = cur.scrollLeft - start;
172
173
  }
173
- rect = { left: rect.left - moveX, top: rect.top - moveY,
174
- right: rect.right - moveX, bottom: rect.bottom - moveY };
174
+ rect = { left: rect.left - movedX, top: rect.top - movedY,
175
+ right: rect.right - movedX, bottom: rect.bottom - movedY };
176
+ if (movedX && Math.abs(movedX - moveX) < 1)
177
+ x = "nearest";
178
+ if (movedY && Math.abs(movedY - moveY) < 1)
179
+ y = "nearest";
175
180
  }
176
181
  }
177
182
  if (top)
178
183
  break;
179
184
  cur = cur.assignedSlot || cur.parentNode;
180
- x = y = "nearest";
181
185
  }
182
186
  else if (cur.nodeType == 11) { // A shadow root
183
187
  cur = cur.host;
@@ -4659,10 +4663,10 @@ class DecorationComparator {
4659
4663
 
4660
4664
  function visiblePixelRange(dom, paddingTop) {
4661
4665
  let rect = dom.getBoundingClientRect();
4662
- let left = Math.max(0, rect.left), right = Math.min(innerWidth, rect.right);
4663
- let top = Math.max(0, rect.top), bottom = Math.min(innerHeight, rect.bottom);
4664
- let body = dom.ownerDocument.body;
4665
- for (let parent = dom.parentNode; parent && parent != body;) {
4666
+ let doc = dom.ownerDocument, win = doc.defaultView;
4667
+ let left = Math.max(0, rect.left), right = Math.min(win.innerWidth, rect.right);
4668
+ let top = Math.max(0, rect.top), bottom = Math.min(win.innerHeight, rect.bottom);
4669
+ for (let parent = dom.parentNode; parent && parent != doc.body;) {
4666
4670
  if (parent.nodeType == 1) {
4667
4671
  let elt = parent;
4668
4672
  let style = window.getComputedStyle(elt);
@@ -4857,7 +4861,7 @@ class ViewState {
4857
4861
  if (inView)
4858
4862
  measureContent = true;
4859
4863
  }
4860
- if (!this.inView)
4864
+ if (!this.inView && !this.scrollTarget)
4861
4865
  return 0;
4862
4866
  let contentWidth = dom.clientWidth;
4863
4867
  if (this.contentDOMWidth != contentWidth || this.editorHeight != view.scrollDOM.clientHeight) {
@@ -5301,8 +5305,8 @@ const baseTheme$1 = buildTheme("." + baseThemeID, {
5301
5305
  "&.cm-focused .cm-cursor": {
5302
5306
  display: "block"
5303
5307
  },
5304
- "&light .cm-activeLine": { backgroundColor: "#f3f9ff" },
5305
- "&dark .cm-activeLine": { backgroundColor: "#223039" },
5308
+ "&light .cm-activeLine": { backgroundColor: "#cceeff44" },
5309
+ "&dark .cm-activeLine": { backgroundColor: "#99eeff33" },
5306
5310
  "&light .cm-specialChar": { color: "red" },
5307
5311
  "&dark .cm-specialChar": { color: "#f78" },
5308
5312
  ".cm-gutters": {
@@ -6175,7 +6179,7 @@ class EditorView {
6175
6179
  /**
6176
6180
  @internal
6177
6181
  */
6178
- get win() { return this.dom.ownerDocument.defaultView; }
6182
+ get win() { return this.dom.ownerDocument.defaultView || window; }
6179
6183
  dispatch(...input) {
6180
6184
  this._dispatch(input.length == 1 && input[0] instanceof state.Transaction ? input[0]
6181
6185
  : this.state.update(...input));
@@ -7539,9 +7543,15 @@ class MatchDecorator {
7539
7543
  if (decorate) {
7540
7544
  this.addMatch = (match, view, from, add) => decorate(add, from, from + match[0].length, match, view);
7541
7545
  }
7546
+ else if (typeof decoration == "function") {
7547
+ this.addMatch = (match, view, from, add) => {
7548
+ let deco = decoration(match, view, from);
7549
+ if (deco)
7550
+ add(from, from + match[0].length, deco);
7551
+ };
7552
+ }
7542
7553
  else if (decoration) {
7543
- let getDeco = typeof decoration == "function" ? decoration : () => decoration;
7544
- this.addMatch = (match, view, from, add) => add(from, from + match[0].length, getDeco(match, view, from));
7554
+ this.addMatch = (match, _view, from, add) => add(from, from + match[0].length, decoration);
7545
7555
  }
7546
7556
  else {
7547
7557
  throw new RangeError("Either 'decorate' or 'decoration' should be provided to MatchDecorator");
@@ -7808,8 +7818,6 @@ const activeLineHighlighter = ViewPlugin.fromClass(class {
7808
7818
  getDeco(view) {
7809
7819
  let lastLineStart = -1, deco = [];
7810
7820
  for (let r of view.state.selection.ranges) {
7811
- if (!r.empty)
7812
- return Decoration.none;
7813
7821
  let line = view.lineBlockAt(r.head);
7814
7822
  if (line.from > lastLineStart) {
7815
7823
  deco.push(lineDeco.range(line.from));
@@ -8027,8 +8035,9 @@ Creates an extension that configures tooltip behavior.
8027
8035
  function tooltips(config = {}) {
8028
8036
  return tooltipConfig.of(config);
8029
8037
  }
8030
- function windowSpace() {
8031
- return { top: 0, left: 0, bottom: innerHeight, right: innerWidth };
8038
+ function windowSpace(view) {
8039
+ let { win } = view;
8040
+ return { top: 0, left: 0, bottom: win.innerHeight, right: win.innerWidth };
8032
8041
  }
8033
8042
  const tooltipConfig = state.Facet.define({
8034
8043
  combine: values => {
@@ -9123,14 +9132,13 @@ const activeLineGutterMarker = new class extends GutterMarker {
9123
9132
  };
9124
9133
  const activeLineGutterHighlighter = gutterLineClass.compute(["selection"], state$1 => {
9125
9134
  let marks = [], last = -1;
9126
- for (let range of state$1.selection.ranges)
9127
- if (range.empty) {
9128
- let linePos = state$1.doc.lineAt(range.head).from;
9129
- if (linePos > last) {
9130
- last = linePos;
9131
- marks.push(activeLineGutterMarker.range(linePos));
9132
- }
9135
+ for (let range of state$1.selection.ranges) {
9136
+ let linePos = state$1.doc.lineAt(range.head).from;
9137
+ if (linePos > last) {
9138
+ last = linePos;
9139
+ marks.push(activeLineGutterMarker.range(linePos));
9133
9140
  }
9141
+ }
9134
9142
  return state.RangeSet.of(marks);
9135
9143
  });
9136
9144
  /**
package/dist/index.d.ts CHANGED
@@ -1386,7 +1386,7 @@ declare class MatchDecorator {
1386
1386
  The decoration to apply to matches, either directly or as a
1387
1387
  function of the match.
1388
1388
  */
1389
- decoration?: Decoration | ((match: RegExpExecArray, view: EditorView, pos: number) => Decoration);
1389
+ decoration?: Decoration | ((match: RegExpExecArray, view: EditorView, pos: number) => Decoration | null);
1390
1390
  /**
1391
1391
  Customize the way decorations are added for matches. This
1392
1392
  function, when given, will be called for matches and should
package/dist/index.js CHANGED
@@ -105,7 +105,7 @@ function scrollRectIntoView(dom, rect, side, x, y, xMargin, yMargin, ltr) {
105
105
  }
106
106
  else {
107
107
  if (cur.scrollHeight <= cur.clientHeight && cur.scrollWidth <= cur.clientWidth) {
108
- cur = cur.parentNode;
108
+ cur = cur.assignedSlot || cur.parentNode;
109
109
  continue;
110
110
  }
111
111
  let rect = cur.getBoundingClientRect();
@@ -156,24 +156,28 @@ function scrollRectIntoView(dom, rect, side, x, y, xMargin, yMargin, ltr) {
156
156
  win.scrollBy(moveX, moveY);
157
157
  }
158
158
  else {
159
+ let movedX = 0, movedY = 0;
159
160
  if (moveY) {
160
161
  let start = cur.scrollTop;
161
162
  cur.scrollTop += moveY;
162
- moveY = cur.scrollTop - start;
163
+ movedY = cur.scrollTop - start;
163
164
  }
164
165
  if (moveX) {
165
166
  let start = cur.scrollLeft;
166
167
  cur.scrollLeft += moveX;
167
- moveX = cur.scrollLeft - start;
168
+ movedX = cur.scrollLeft - start;
168
169
  }
169
- rect = { left: rect.left - moveX, top: rect.top - moveY,
170
- right: rect.right - moveX, bottom: rect.bottom - moveY };
170
+ rect = { left: rect.left - movedX, top: rect.top - movedY,
171
+ right: rect.right - movedX, bottom: rect.bottom - movedY };
172
+ if (movedX && Math.abs(movedX - moveX) < 1)
173
+ x = "nearest";
174
+ if (movedY && Math.abs(movedY - moveY) < 1)
175
+ y = "nearest";
171
176
  }
172
177
  }
173
178
  if (top)
174
179
  break;
175
180
  cur = cur.assignedSlot || cur.parentNode;
176
- x = y = "nearest";
177
181
  }
178
182
  else if (cur.nodeType == 11) { // A shadow root
179
183
  cur = cur.host;
@@ -4652,10 +4656,10 @@ class DecorationComparator {
4652
4656
 
4653
4657
  function visiblePixelRange(dom, paddingTop) {
4654
4658
  let rect = dom.getBoundingClientRect();
4655
- let left = Math.max(0, rect.left), right = Math.min(innerWidth, rect.right);
4656
- let top = Math.max(0, rect.top), bottom = Math.min(innerHeight, rect.bottom);
4657
- let body = dom.ownerDocument.body;
4658
- for (let parent = dom.parentNode; parent && parent != body;) {
4659
+ let doc = dom.ownerDocument, win = doc.defaultView;
4660
+ let left = Math.max(0, rect.left), right = Math.min(win.innerWidth, rect.right);
4661
+ let top = Math.max(0, rect.top), bottom = Math.min(win.innerHeight, rect.bottom);
4662
+ for (let parent = dom.parentNode; parent && parent != doc.body;) {
4659
4663
  if (parent.nodeType == 1) {
4660
4664
  let elt = parent;
4661
4665
  let style = window.getComputedStyle(elt);
@@ -4850,7 +4854,7 @@ class ViewState {
4850
4854
  if (inView)
4851
4855
  measureContent = true;
4852
4856
  }
4853
- if (!this.inView)
4857
+ if (!this.inView && !this.scrollTarget)
4854
4858
  return 0;
4855
4859
  let contentWidth = dom.clientWidth;
4856
4860
  if (this.contentDOMWidth != contentWidth || this.editorHeight != view.scrollDOM.clientHeight) {
@@ -5294,8 +5298,8 @@ const baseTheme$1 = /*@__PURE__*/buildTheme("." + baseThemeID, {
5294
5298
  "&.cm-focused .cm-cursor": {
5295
5299
  display: "block"
5296
5300
  },
5297
- "&light .cm-activeLine": { backgroundColor: "#f3f9ff" },
5298
- "&dark .cm-activeLine": { backgroundColor: "#223039" },
5301
+ "&light .cm-activeLine": { backgroundColor: "#cceeff44" },
5302
+ "&dark .cm-activeLine": { backgroundColor: "#99eeff33" },
5299
5303
  "&light .cm-specialChar": { color: "red" },
5300
5304
  "&dark .cm-specialChar": { color: "#f78" },
5301
5305
  ".cm-gutters": {
@@ -6168,7 +6172,7 @@ class EditorView {
6168
6172
  /**
6169
6173
  @internal
6170
6174
  */
6171
- get win() { return this.dom.ownerDocument.defaultView; }
6175
+ get win() { return this.dom.ownerDocument.defaultView || window; }
6172
6176
  dispatch(...input) {
6173
6177
  this._dispatch(input.length == 1 && input[0] instanceof Transaction ? input[0]
6174
6178
  : this.state.update(...input));
@@ -7532,9 +7536,15 @@ class MatchDecorator {
7532
7536
  if (decorate) {
7533
7537
  this.addMatch = (match, view, from, add) => decorate(add, from, from + match[0].length, match, view);
7534
7538
  }
7539
+ else if (typeof decoration == "function") {
7540
+ this.addMatch = (match, view, from, add) => {
7541
+ let deco = decoration(match, view, from);
7542
+ if (deco)
7543
+ add(from, from + match[0].length, deco);
7544
+ };
7545
+ }
7535
7546
  else if (decoration) {
7536
- let getDeco = typeof decoration == "function" ? decoration : () => decoration;
7537
- this.addMatch = (match, view, from, add) => add(from, from + match[0].length, getDeco(match, view, from));
7547
+ this.addMatch = (match, _view, from, add) => add(from, from + match[0].length, decoration);
7538
7548
  }
7539
7549
  else {
7540
7550
  throw new RangeError("Either 'decorate' or 'decoration' should be provided to MatchDecorator");
@@ -7801,8 +7811,6 @@ const activeLineHighlighter = /*@__PURE__*/ViewPlugin.fromClass(class {
7801
7811
  getDeco(view) {
7802
7812
  let lastLineStart = -1, deco = [];
7803
7813
  for (let r of view.state.selection.ranges) {
7804
- if (!r.empty)
7805
- return Decoration.none;
7806
7814
  let line = view.lineBlockAt(r.head);
7807
7815
  if (line.from > lastLineStart) {
7808
7816
  deco.push(lineDeco.range(line.from));
@@ -8020,8 +8028,9 @@ Creates an extension that configures tooltip behavior.
8020
8028
  function tooltips(config = {}) {
8021
8029
  return tooltipConfig.of(config);
8022
8030
  }
8023
- function windowSpace() {
8024
- return { top: 0, left: 0, bottom: innerHeight, right: innerWidth };
8031
+ function windowSpace(view) {
8032
+ let { win } = view;
8033
+ return { top: 0, left: 0, bottom: win.innerHeight, right: win.innerWidth };
8025
8034
  }
8026
8035
  const tooltipConfig = /*@__PURE__*/Facet.define({
8027
8036
  combine: values => {
@@ -9116,14 +9125,13 @@ const activeLineGutterMarker = /*@__PURE__*/new class extends GutterMarker {
9116
9125
  };
9117
9126
  const activeLineGutterHighlighter = /*@__PURE__*/gutterLineClass.compute(["selection"], state => {
9118
9127
  let marks = [], last = -1;
9119
- for (let range of state.selection.ranges)
9120
- if (range.empty) {
9121
- let linePos = state.doc.lineAt(range.head).from;
9122
- if (linePos > last) {
9123
- last = linePos;
9124
- marks.push(activeLineGutterMarker.range(linePos));
9125
- }
9128
+ for (let range of state.selection.ranges) {
9129
+ let linePos = state.doc.lineAt(range.head).from;
9130
+ if (linePos > last) {
9131
+ last = linePos;
9132
+ marks.push(activeLineGutterMarker.range(linePos));
9126
9133
  }
9134
+ }
9127
9135
  return RangeSet.of(marks);
9128
9136
  });
9129
9137
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/view",
3
- "version": "6.2.3",
3
+ "version": "6.2.4",
4
4
  "description": "DOM view component for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",