@codemirror/state 6.0.0 → 6.1.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,25 @@
1
+ ## 6.1.1 (2022-08-03)
2
+
3
+ ### Bug fixes
4
+
5
+ Fix a bug in range set span iteration that would cause decorations to be inappropriately split in some situations.
6
+
7
+ ## 6.1.0 (2022-06-30)
8
+
9
+ ### Bug fixes
10
+
11
+ Refine change mapping to preserve insertions made by concurrent changes.
12
+
13
+ ### New features
14
+
15
+ The `enables` option to `Facet.define` may now take a function, which will be called with the facet value to create the extensions.
16
+
17
+ ## 6.0.1 (2022-06-17)
18
+
19
+ ### Bug fixes
20
+
21
+ Fix a problem that caused effects' `map` methods to be called with an incorrect change set when filtering changes.
22
+
1
23
  ## 6.0.0 (2022-06-08)
2
24
 
3
25
  ### Breaking changes
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # @codemirror/state [![NPM version](https://img.shields.io/npm/v/@codemirror/state.svg)](https://www.npmjs.org/package/@codemirror/state)
2
2
 
3
- [ [**WEBSITE**](https://codemirror.net/6/) | [**DOCS**](https://codemirror.net/6/docs/ref/#state) | [**ISSUES**](https://github.com/codemirror/codemirror.next/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/state/blob/main/CHANGELOG.md) ]
3
+ [ [**WEBSITE**](https://codemirror.net/) | [**DOCS**](https://codemirror.net/docs/ref/#state) | [**ISSUES**](https://github.com/codemirror/dev/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/state/blob/main/CHANGELOG.md) ]
4
4
 
5
5
  This package implements the editor state data structures 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/state/tree/main/LICENSE).
package/dist/index.cjs CHANGED
@@ -1130,51 +1130,65 @@ function iterChanges(desc, f, individual) {
1130
1130
  }
1131
1131
  }
1132
1132
  function mapSet(setA, setB, before, mkSet = false) {
1133
+ // Produce a copy of setA that applies to the document after setB
1134
+ // has been applied (assuming both start at the same document).
1133
1135
  let sections = [], insert = mkSet ? [] : null;
1134
1136
  let a = new SectionIter(setA), b = new SectionIter(setB);
1135
- for (let posA = 0, posB = 0;;) {
1136
- if (a.ins == -1) {
1137
- posA += a.len;
1138
- a.next();
1139
- }
1140
- else if (b.ins == -1 && posB < posA) {
1141
- let skip = Math.min(b.len, posA - posB);
1142
- b.forward(skip);
1143
- addSection(sections, skip, -1);
1144
- posB += skip;
1137
+ // Iterate over both sets in parallel. inserted tracks, for changes
1138
+ // in A that have to be processed piece-by-piece, whether their
1139
+ // content has been inserted already, and refers to the section
1140
+ // index.
1141
+ for (let inserted = -1;;) {
1142
+ if (a.ins == -1 && b.ins == -1) {
1143
+ // Move across ranges skipped by both sets.
1144
+ let len = Math.min(a.len, b.len);
1145
+ addSection(sections, len, -1);
1146
+ a.forward(len);
1147
+ b.forward(len);
1145
1148
  }
1146
- else if (b.ins >= 0 && (a.done || posB < posA || posB == posA && (b.len < a.len || b.len == a.len && !before))) {
1149
+ else if (b.ins >= 0 && (a.ins < 0 || inserted == a.i || a.off == 0 && (b.len < a.len || b.len == a.len && !before))) {
1150
+ // If there's a change in B that comes before the next change in
1151
+ // A (ordered by start pos, then len, then before flag), skip
1152
+ // that (and process any changes in A it covers).
1153
+ let len = b.len;
1147
1154
  addSection(sections, b.ins, -1);
1148
- while (posA > posB && !a.done && posA + a.len < posB + b.len) {
1149
- posA += a.len;
1150
- a.next();
1155
+ while (len) {
1156
+ let piece = Math.min(a.len, len);
1157
+ if (a.ins >= 0 && inserted < a.i && a.len <= piece) {
1158
+ addSection(sections, 0, a.ins);
1159
+ if (insert)
1160
+ addInsert(insert, sections, a.text);
1161
+ inserted = a.i;
1162
+ }
1163
+ a.forward(piece);
1164
+ len -= piece;
1151
1165
  }
1152
- posB += b.len;
1153
1166
  b.next();
1154
1167
  }
1155
1168
  else if (a.ins >= 0) {
1156
- let len = 0, end = posA + a.len;
1157
- for (;;) {
1158
- if (b.ins >= 0 && posB > posA && posB + b.len < end) {
1159
- len += b.ins;
1160
- posB += b.len;
1161
- b.next();
1169
+ // Process the part of a change in A up to the start of the next
1170
+ // non-deletion change in B (if overlapping).
1171
+ let len = 0, left = a.len;
1172
+ while (left) {
1173
+ if (b.ins == -1) {
1174
+ let piece = Math.min(left, b.len);
1175
+ len += piece;
1176
+ left -= piece;
1177
+ b.forward(piece);
1162
1178
  }
1163
- else if (b.ins == -1 && posB < end) {
1164
- let skip = Math.min(b.len, end - posB);
1165
- len += skip;
1166
- b.forward(skip);
1167
- posB += skip;
1179
+ else if (b.ins == 0 && b.len < left) {
1180
+ left -= b.len;
1181
+ b.next();
1168
1182
  }
1169
1183
  else {
1170
1184
  break;
1171
1185
  }
1172
1186
  }
1173
- addSection(sections, len, a.ins);
1174
- if (insert)
1187
+ addSection(sections, len, inserted < a.i ? a.ins : 0);
1188
+ if (insert && inserted < a.i)
1175
1189
  addInsert(insert, sections, a.text);
1176
- posA = end;
1177
- a.next();
1190
+ inserted = a.i;
1191
+ a.forward(a.len - left);
1178
1192
  }
1179
1193
  else if (a.done && b.done) {
1180
1194
  return insert ? ChangeSet.createSet(sections, insert) : ChangeDesc.create(sections);
@@ -1556,21 +1570,17 @@ class Facet {
1556
1570
  /**
1557
1571
  @internal
1558
1572
  */
1559
- compare, isStatic,
1560
- /**
1561
- @internal
1562
- */
1563
- extensions) {
1573
+ compare, isStatic, enables) {
1564
1574
  this.combine = combine;
1565
1575
  this.compareInput = compareInput;
1566
1576
  this.compare = compare;
1567
1577
  this.isStatic = isStatic;
1568
- this.extensions = extensions;
1569
1578
  /**
1570
1579
  @internal
1571
1580
  */
1572
1581
  this.id = nextID++;
1573
1582
  this.default = combine([]);
1583
+ this.extensions = typeof enables == "function" ? enables(this) : enables;
1574
1584
  }
1575
1585
  /**
1576
1586
  Define a new facet.
@@ -2001,7 +2011,7 @@ function flatten(extension, compartments, newCompartments) {
2001
2011
  else if (ext instanceof FacetProvider) {
2002
2012
  result[prec].push(ext);
2003
2013
  if (ext.facet.extensions)
2004
- inner(ext.facet.extensions, prec);
2014
+ inner(ext.facet.extensions, Prec_.default);
2005
2015
  }
2006
2016
  else {
2007
2017
  let content = ext.extension;
@@ -2439,7 +2449,7 @@ function filterTransaction(tr) {
2439
2449
  else {
2440
2450
  let filtered = tr.changes.filter(result);
2441
2451
  changes = filtered.changes;
2442
- back = filtered.filtered.invertedDesc;
2452
+ back = filtered.filtered.mapDesc(filtered.changes).invertedDesc;
2443
2453
  }
2444
2454
  tr = Transaction.create(state, changes, tr.selection && tr.selection.map(back), StateEffect.mapEffects(tr.effects, back), tr.annotations, tr.scrollIntoView);
2445
2455
  }
@@ -2712,7 +2722,7 @@ class EditorState {
2712
2722
  if (fields)
2713
2723
  for (let prop in fields) {
2714
2724
  let value = fields[prop];
2715
- if (value instanceof StateField)
2725
+ if (value instanceof StateField && this.config.address[value.id] != null)
2716
2726
  result[prop] = value.spec.toJSON(this.field(fields[prop]), this);
2717
2727
  }
2718
2728
  return result;
@@ -2729,8 +2739,10 @@ class EditorState {
2729
2739
  let fieldInit = [];
2730
2740
  if (fields)
2731
2741
  for (let prop in fields) {
2732
- let field = fields[prop], value = json[prop];
2733
- fieldInit.push(field.init(state => field.spec.fromJSON(value, state)));
2742
+ if (Object.prototype.hasOwnProperty.call(json, prop)) {
2743
+ let field = fields[prop], value = json[prop];
2744
+ fieldInit.push(field.init(state => field.spec.fromJSON(value, state)));
2745
+ }
2734
2746
  }
2735
2747
  return EditorState.create({
2736
2748
  doc: json.doc,
@@ -2791,7 +2803,7 @@ class EditorState {
2791
2803
  if (i == "$")
2792
2804
  return "$";
2793
2805
  let n = +(i || 1);
2794
- return n > insert.length ? m : insert[n - 1];
2806
+ return !n || n > insert.length ? m : insert[n - 1];
2795
2807
  });
2796
2808
  return phrase;
2797
2809
  }
@@ -3722,6 +3734,8 @@ class SpanCursor {
3722
3734
  let nextVal = this.cursor.value;
3723
3735
  if (!nextVal.point) { // Opening a range
3724
3736
  this.addActive(trackOpen);
3737
+ if (this.cursor.from < from && this.cursor.to > from)
3738
+ trackExtra++;
3725
3739
  this.cursor.next();
3726
3740
  }
3727
3741
  else if (wasPoint && this.cursor.to == this.to && this.cursor.from < this.cursor.to) {
package/dist/index.d.ts CHANGED
@@ -505,13 +505,14 @@ declare type FacetConfig<Input, Output> = {
505
505
  */
506
506
  static?: boolean;
507
507
  /**
508
- If given, these extension(s) will be added to any state where
509
- this facet is provided. (Note that, while a facet's default
510
- value can be read from a state even if the facet wasn't present
511
- in the state at all, these extensions won't be added in that
508
+ If given, these extension(s) (or the result of calling the given
509
+ function with the facet) will be added to any state where this
510
+ facet is provided. (Note that, while a facet's default value can
511
+ be read from a state even if the facet wasn't present in the
512
+ state at all, these extensions won't be added in that
512
513
  situation.)
513
514
  */
514
- enables?: Extension;
515
+ enables?: Extension | ((self: Facet<Input, Output>) => Extension);
515
516
  };
516
517
  /**
517
518
  A facet is a labeled value that is associated with an editor
package/dist/index.js CHANGED
@@ -1125,51 +1125,65 @@ function iterChanges(desc, f, individual) {
1125
1125
  }
1126
1126
  }
1127
1127
  function mapSet(setA, setB, before, mkSet = false) {
1128
+ // Produce a copy of setA that applies to the document after setB
1129
+ // has been applied (assuming both start at the same document).
1128
1130
  let sections = [], insert = mkSet ? [] : null;
1129
1131
  let a = new SectionIter(setA), b = new SectionIter(setB);
1130
- for (let posA = 0, posB = 0;;) {
1131
- if (a.ins == -1) {
1132
- posA += a.len;
1133
- a.next();
1134
- }
1135
- else if (b.ins == -1 && posB < posA) {
1136
- let skip = Math.min(b.len, posA - posB);
1137
- b.forward(skip);
1138
- addSection(sections, skip, -1);
1139
- posB += skip;
1132
+ // Iterate over both sets in parallel. inserted tracks, for changes
1133
+ // in A that have to be processed piece-by-piece, whether their
1134
+ // content has been inserted already, and refers to the section
1135
+ // index.
1136
+ for (let inserted = -1;;) {
1137
+ if (a.ins == -1 && b.ins == -1) {
1138
+ // Move across ranges skipped by both sets.
1139
+ let len = Math.min(a.len, b.len);
1140
+ addSection(sections, len, -1);
1141
+ a.forward(len);
1142
+ b.forward(len);
1140
1143
  }
1141
- else if (b.ins >= 0 && (a.done || posB < posA || posB == posA && (b.len < a.len || b.len == a.len && !before))) {
1144
+ else if (b.ins >= 0 && (a.ins < 0 || inserted == a.i || a.off == 0 && (b.len < a.len || b.len == a.len && !before))) {
1145
+ // If there's a change in B that comes before the next change in
1146
+ // A (ordered by start pos, then len, then before flag), skip
1147
+ // that (and process any changes in A it covers).
1148
+ let len = b.len;
1142
1149
  addSection(sections, b.ins, -1);
1143
- while (posA > posB && !a.done && posA + a.len < posB + b.len) {
1144
- posA += a.len;
1145
- a.next();
1150
+ while (len) {
1151
+ let piece = Math.min(a.len, len);
1152
+ if (a.ins >= 0 && inserted < a.i && a.len <= piece) {
1153
+ addSection(sections, 0, a.ins);
1154
+ if (insert)
1155
+ addInsert(insert, sections, a.text);
1156
+ inserted = a.i;
1157
+ }
1158
+ a.forward(piece);
1159
+ len -= piece;
1146
1160
  }
1147
- posB += b.len;
1148
1161
  b.next();
1149
1162
  }
1150
1163
  else if (a.ins >= 0) {
1151
- let len = 0, end = posA + a.len;
1152
- for (;;) {
1153
- if (b.ins >= 0 && posB > posA && posB + b.len < end) {
1154
- len += b.ins;
1155
- posB += b.len;
1156
- b.next();
1164
+ // Process the part of a change in A up to the start of the next
1165
+ // non-deletion change in B (if overlapping).
1166
+ let len = 0, left = a.len;
1167
+ while (left) {
1168
+ if (b.ins == -1) {
1169
+ let piece = Math.min(left, b.len);
1170
+ len += piece;
1171
+ left -= piece;
1172
+ b.forward(piece);
1157
1173
  }
1158
- else if (b.ins == -1 && posB < end) {
1159
- let skip = Math.min(b.len, end - posB);
1160
- len += skip;
1161
- b.forward(skip);
1162
- posB += skip;
1174
+ else if (b.ins == 0 && b.len < left) {
1175
+ left -= b.len;
1176
+ b.next();
1163
1177
  }
1164
1178
  else {
1165
1179
  break;
1166
1180
  }
1167
1181
  }
1168
- addSection(sections, len, a.ins);
1169
- if (insert)
1182
+ addSection(sections, len, inserted < a.i ? a.ins : 0);
1183
+ if (insert && inserted < a.i)
1170
1184
  addInsert(insert, sections, a.text);
1171
- posA = end;
1172
- a.next();
1185
+ inserted = a.i;
1186
+ a.forward(a.len - left);
1173
1187
  }
1174
1188
  else if (a.done && b.done) {
1175
1189
  return insert ? ChangeSet.createSet(sections, insert) : ChangeDesc.create(sections);
@@ -1551,21 +1565,17 @@ class Facet {
1551
1565
  /**
1552
1566
  @internal
1553
1567
  */
1554
- compare, isStatic,
1555
- /**
1556
- @internal
1557
- */
1558
- extensions) {
1568
+ compare, isStatic, enables) {
1559
1569
  this.combine = combine;
1560
1570
  this.compareInput = compareInput;
1561
1571
  this.compare = compare;
1562
1572
  this.isStatic = isStatic;
1563
- this.extensions = extensions;
1564
1573
  /**
1565
1574
  @internal
1566
1575
  */
1567
1576
  this.id = nextID++;
1568
1577
  this.default = combine([]);
1578
+ this.extensions = typeof enables == "function" ? enables(this) : enables;
1569
1579
  }
1570
1580
  /**
1571
1581
  Define a new facet.
@@ -1996,7 +2006,7 @@ function flatten(extension, compartments, newCompartments) {
1996
2006
  else if (ext instanceof FacetProvider) {
1997
2007
  result[prec].push(ext);
1998
2008
  if (ext.facet.extensions)
1999
- inner(ext.facet.extensions, prec);
2009
+ inner(ext.facet.extensions, Prec_.default);
2000
2010
  }
2001
2011
  else {
2002
2012
  let content = ext.extension;
@@ -2434,7 +2444,7 @@ function filterTransaction(tr) {
2434
2444
  else {
2435
2445
  let filtered = tr.changes.filter(result);
2436
2446
  changes = filtered.changes;
2437
- back = filtered.filtered.invertedDesc;
2447
+ back = filtered.filtered.mapDesc(filtered.changes).invertedDesc;
2438
2448
  }
2439
2449
  tr = Transaction.create(state, changes, tr.selection && tr.selection.map(back), StateEffect.mapEffects(tr.effects, back), tr.annotations, tr.scrollIntoView);
2440
2450
  }
@@ -2706,7 +2716,7 @@ class EditorState {
2706
2716
  if (fields)
2707
2717
  for (let prop in fields) {
2708
2718
  let value = fields[prop];
2709
- if (value instanceof StateField)
2719
+ if (value instanceof StateField && this.config.address[value.id] != null)
2710
2720
  result[prop] = value.spec.toJSON(this.field(fields[prop]), this);
2711
2721
  }
2712
2722
  return result;
@@ -2723,8 +2733,10 @@ class EditorState {
2723
2733
  let fieldInit = [];
2724
2734
  if (fields)
2725
2735
  for (let prop in fields) {
2726
- let field = fields[prop], value = json[prop];
2727
- fieldInit.push(field.init(state => field.spec.fromJSON(value, state)));
2736
+ if (Object.prototype.hasOwnProperty.call(json, prop)) {
2737
+ let field = fields[prop], value = json[prop];
2738
+ fieldInit.push(field.init(state => field.spec.fromJSON(value, state)));
2739
+ }
2728
2740
  }
2729
2741
  return EditorState.create({
2730
2742
  doc: json.doc,
@@ -2785,7 +2797,7 @@ class EditorState {
2785
2797
  if (i == "$")
2786
2798
  return "$";
2787
2799
  let n = +(i || 1);
2788
- return n > insert.length ? m : insert[n - 1];
2800
+ return !n || n > insert.length ? m : insert[n - 1];
2789
2801
  });
2790
2802
  return phrase;
2791
2803
  }
@@ -3716,6 +3728,8 @@ class SpanCursor {
3716
3728
  let nextVal = this.cursor.value;
3717
3729
  if (!nextVal.point) { // Opening a range
3718
3730
  this.addActive(trackOpen);
3731
+ if (this.cursor.from < from && this.cursor.to > from)
3732
+ trackExtra++;
3719
3733
  this.cursor.next();
3720
3734
  }
3721
3735
  else if (wasPoint && this.cursor.to == this.to && this.cursor.from < this.cursor.to) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/state",
3
- "version": "6.0.0",
3
+ "version": "6.1.1",
4
4
  "description": "Editor state data structures for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",