@codemirror/state 0.19.3 → 0.19.7
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 +28 -0
- package/dist/index.cjs +87 -64
- package/dist/index.d.ts +3 -1
- package/dist/index.js +86 -61
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
## 0.19.7 (2022-02-11)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Avoid recomputing facets on state reconfiguration if that facet's inputs stayed precisely the same.
|
|
6
|
+
|
|
7
|
+
Selection ranges created with `EditorSelection.range` will now have an assoc pointing at their anchor, when non-empty.
|
|
8
|
+
|
|
9
|
+
## 0.19.6 (2021-11-19)
|
|
10
|
+
|
|
11
|
+
### Bug fixes
|
|
12
|
+
|
|
13
|
+
Fix a bug that caused facet compare functions to be called with an invalid value in some situations.
|
|
14
|
+
|
|
15
|
+
Fix a bug that caused dynamic facet values to be incorrectly kept unchanged when reconfiguration changed one of their dependencies.
|
|
16
|
+
|
|
17
|
+
## 0.19.5 (2021-11-10)
|
|
18
|
+
|
|
19
|
+
### Bug fixes
|
|
20
|
+
|
|
21
|
+
Fix a bug that would cause dynamic facet values influenced by a state reconfiguration to not properly recompute.
|
|
22
|
+
|
|
23
|
+
## 0.19.4 (2021-11-05)
|
|
24
|
+
|
|
25
|
+
### Bug fixes
|
|
26
|
+
|
|
27
|
+
When reconfiguring a state, effects from the reconfiguring transaction can now be seen by newly added state fields.
|
|
28
|
+
|
|
1
29
|
## 0.19.3 (2021-11-03)
|
|
2
30
|
|
|
3
31
|
### New features
|
package/dist/index.cjs
CHANGED
|
@@ -265,7 +265,9 @@ class ChangeSet extends ChangeDesc {
|
|
|
265
265
|
map(other, before = false) { return other.empty ? this : mapSet(this, other, before, true); }
|
|
266
266
|
/**
|
|
267
267
|
Iterate over the changed ranges in the document, calling `f` for
|
|
268
|
-
each
|
|
268
|
+
each, with the range in the original document (`fromA`-`toA`)
|
|
269
|
+
and the range that replaces it in the new document
|
|
270
|
+
(`fromB`-`toB`).
|
|
269
271
|
|
|
270
272
|
When `individual` is true, adjacent changes are reported
|
|
271
273
|
separately.
|
|
@@ -835,7 +837,8 @@ class EditorSelection {
|
|
|
835
837
|
*/
|
|
836
838
|
static range(anchor, head, goalColumn) {
|
|
837
839
|
let goal = (goalColumn !== null && goalColumn !== void 0 ? goalColumn : 33554431 /* NoGoalColumn */) << 5 /* GoalColumnOffset */;
|
|
838
|
-
return head < anchor ? new SelectionRange(head, anchor, 16 /* Inverted */ | goal
|
|
840
|
+
return head < anchor ? new SelectionRange(head, anchor, 16 /* Inverted */ | goal | 8 /* AssocAfter */)
|
|
841
|
+
: new SelectionRange(anchor, head, goal | (head > anchor ? 4 /* AssocBefore */ : 0));
|
|
839
842
|
}
|
|
840
843
|
}
|
|
841
844
|
function normalized(ranges, mainIndex = 0) {
|
|
@@ -967,21 +970,23 @@ class FacetProvider {
|
|
|
967
970
|
depAddrs.push(addresses[dep.id]);
|
|
968
971
|
}
|
|
969
972
|
return (state, tr) => {
|
|
970
|
-
|
|
973
|
+
let oldVal = state.values[idx];
|
|
974
|
+
if (oldVal === Uninitialized) {
|
|
971
975
|
state.values[idx] = getter(state);
|
|
972
976
|
return 1 /* Changed */;
|
|
973
977
|
}
|
|
974
|
-
|
|
978
|
+
if (tr) {
|
|
975
979
|
let depChanged = (depDoc && tr.docChanged) || (depSel && (tr.docChanged || tr.selection)) ||
|
|
976
980
|
depAddrs.some(addr => (ensureAddr(state, addr) & 1 /* Changed */) > 0);
|
|
977
|
-
if (
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
981
|
+
if (depChanged) {
|
|
982
|
+
let newVal = getter(state);
|
|
983
|
+
if (multi ? !compareArray(newVal, oldVal, compare) : !compare(newVal, oldVal)) {
|
|
984
|
+
state.values[idx] = newVal;
|
|
985
|
+
return 1 /* Changed */;
|
|
986
|
+
}
|
|
987
|
+
}
|
|
984
988
|
}
|
|
989
|
+
return 0;
|
|
985
990
|
};
|
|
986
991
|
}
|
|
987
992
|
}
|
|
@@ -999,8 +1004,7 @@ function dynamicFacetSlot(addresses, facet, providers) {
|
|
|
999
1004
|
let dynamic = providerAddrs.filter(p => !(p & 1));
|
|
1000
1005
|
let idx = addresses[facet.id] >> 1;
|
|
1001
1006
|
return (state, tr) => {
|
|
1002
|
-
let
|
|
1003
|
-
let changed = oldAddr == null;
|
|
1007
|
+
let oldVal = state.values[idx], changed = oldVal === Uninitialized;
|
|
1004
1008
|
for (let dynAddr of dynamic) {
|
|
1005
1009
|
if (ensureAddr(state, dynAddr) & 1 /* Changed */)
|
|
1006
1010
|
changed = true;
|
|
@@ -1016,17 +1020,13 @@ function dynamicFacetSlot(addresses, facet, providers) {
|
|
|
1016
1020
|
else
|
|
1017
1021
|
values.push(value);
|
|
1018
1022
|
}
|
|
1019
|
-
let
|
|
1020
|
-
if (
|
|
1023
|
+
let value = facet.combine(values);
|
|
1024
|
+
if (oldVal !== Uninitialized && facet.compare(value, oldVal))
|
|
1021
1025
|
return 0;
|
|
1022
|
-
state.values[idx] =
|
|
1026
|
+
state.values[idx] = value;
|
|
1023
1027
|
return 1 /* Changed */;
|
|
1024
1028
|
};
|
|
1025
1029
|
}
|
|
1026
|
-
function maybeIndex(state, id) {
|
|
1027
|
-
let found = state.config.address[id];
|
|
1028
|
-
return found == null ? null : found >> 1;
|
|
1029
|
-
}
|
|
1030
1030
|
const initField = Facet.define({ static: true });
|
|
1031
1031
|
/**
|
|
1032
1032
|
Fields can store additional information in an editor state, and
|
|
@@ -1071,24 +1071,19 @@ class StateField {
|
|
|
1071
1071
|
slot(addresses) {
|
|
1072
1072
|
let idx = addresses[this.id] >> 1;
|
|
1073
1073
|
return (state, tr) => {
|
|
1074
|
-
|
|
1074
|
+
let oldVal = state.values[idx];
|
|
1075
|
+
if (oldVal === Uninitialized) {
|
|
1075
1076
|
state.values[idx] = this.create(state);
|
|
1076
1077
|
return 1 /* Changed */;
|
|
1077
1078
|
}
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
oldVal = tr.startState.values[idx];
|
|
1079
|
+
if (tr) {
|
|
1080
|
+
let value = this.updateF(oldVal, tr);
|
|
1081
|
+
if (!this.compareF(oldVal, value)) {
|
|
1082
|
+
state.values[idx] = value;
|
|
1083
|
+
return 1 /* Changed */;
|
|
1084
|
+
}
|
|
1085
1085
|
}
|
|
1086
|
-
|
|
1087
|
-
if (!changed && !this.compareF(oldVal, value))
|
|
1088
|
-
changed = 1 /* Changed */;
|
|
1089
|
-
if (changed)
|
|
1090
|
-
state.values[idx] = value;
|
|
1091
|
-
return changed;
|
|
1086
|
+
return 0;
|
|
1092
1087
|
};
|
|
1093
1088
|
}
|
|
1094
1089
|
/**
|
|
@@ -1200,15 +1195,16 @@ class CompartmentInstance {
|
|
|
1200
1195
|
}
|
|
1201
1196
|
}
|
|
1202
1197
|
class Configuration {
|
|
1203
|
-
constructor(base, compartments, dynamicSlots, address, staticValues) {
|
|
1198
|
+
constructor(base, compartments, dynamicSlots, address, staticValues, facets) {
|
|
1204
1199
|
this.base = base;
|
|
1205
1200
|
this.compartments = compartments;
|
|
1206
1201
|
this.dynamicSlots = dynamicSlots;
|
|
1207
1202
|
this.address = address;
|
|
1208
1203
|
this.staticValues = staticValues;
|
|
1204
|
+
this.facets = facets;
|
|
1209
1205
|
this.statusTemplate = [];
|
|
1210
1206
|
while (this.statusTemplate.length < dynamicSlots.length)
|
|
1211
|
-
this.statusTemplate.push(0 /*
|
|
1207
|
+
this.statusTemplate.push(0 /* Unresolved */);
|
|
1212
1208
|
}
|
|
1213
1209
|
staticFacet(facet) {
|
|
1214
1210
|
let addr = this.address[facet.id];
|
|
@@ -1227,25 +1223,44 @@ class Configuration {
|
|
|
1227
1223
|
let address = Object.create(null);
|
|
1228
1224
|
let staticValues = [];
|
|
1229
1225
|
let dynamicSlots = [];
|
|
1226
|
+
let dynamicValues = [];
|
|
1230
1227
|
for (let field of fields) {
|
|
1231
1228
|
address[field.id] = dynamicSlots.length << 1;
|
|
1232
1229
|
dynamicSlots.push(a => field.slot(a));
|
|
1230
|
+
dynamicValues.push(oldState && oldState.config.address[field.id] != null ? oldState.field(field) : Uninitialized);
|
|
1233
1231
|
}
|
|
1232
|
+
let canReuseCache = new Map;
|
|
1233
|
+
let canReuseDep = (dep) => {
|
|
1234
|
+
if (!(dep instanceof Facet))
|
|
1235
|
+
return true;
|
|
1236
|
+
let cached = canReuseCache.get(dep);
|
|
1237
|
+
if (cached != null)
|
|
1238
|
+
return cached;
|
|
1239
|
+
canReuseCache.set(dep, false);
|
|
1240
|
+
if (!oldFacets || !sameArray(oldFacets[dep.id] || [], facets[dep.id] || []))
|
|
1241
|
+
return;
|
|
1242
|
+
for (let input of facets[dep.id] || [])
|
|
1243
|
+
if (!input.dependencies.every(canReuseDep))
|
|
1244
|
+
return;
|
|
1245
|
+
canReuseCache.set(dep, true);
|
|
1246
|
+
};
|
|
1247
|
+
let oldFacets = oldState === null || oldState === void 0 ? void 0 : oldState.config.facets;
|
|
1234
1248
|
for (let id in facets) {
|
|
1235
1249
|
let providers = facets[id], facet = providers[0].facet;
|
|
1250
|
+
let oldProviders = oldFacets && oldFacets[id] || [];
|
|
1251
|
+
let canReuse = sameArray(providers, oldProviders);
|
|
1236
1252
|
if (providers.every(p => p.type == 0 /* Static */)) {
|
|
1237
1253
|
address[facet.id] = (staticValues.length << 1) | 1;
|
|
1238
|
-
let value = facet.combine(providers.map(p => p.value));
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
let oldVal = getAddr(oldState, oldAddr);
|
|
1242
|
-
if (facet.compare(value, oldVal))
|
|
1243
|
-
value = oldVal;
|
|
1244
|
-
}
|
|
1254
|
+
let value = canReuse ? oldState.facet(facet) : facet.combine(providers.map(p => p.value)), oldValue;
|
|
1255
|
+
if (!canReuse && oldState && facet.compare(value, oldValue = oldState.facet(facet)))
|
|
1256
|
+
value = oldValue;
|
|
1245
1257
|
staticValues.push(value);
|
|
1246
1258
|
}
|
|
1247
1259
|
else {
|
|
1248
1260
|
for (let p of providers) {
|
|
1261
|
+
let canReuseThis = p.dependencies.every(canReuseDep);
|
|
1262
|
+
if (!canReuseThis)
|
|
1263
|
+
canReuse = false;
|
|
1249
1264
|
if (p.type == 0 /* Static */) {
|
|
1250
1265
|
address[p.id] = (staticValues.length << 1) | 1;
|
|
1251
1266
|
staticValues.push(p.value);
|
|
@@ -1253,13 +1268,20 @@ class Configuration {
|
|
|
1253
1268
|
else {
|
|
1254
1269
|
address[p.id] = dynamicSlots.length << 1;
|
|
1255
1270
|
dynamicSlots.push(a => p.dynamicSlot(a));
|
|
1271
|
+
let oldAddr = oldState && canReuseThis ? oldState.config.address[p.id] : null;
|
|
1272
|
+
dynamicValues.push(oldAddr != null ? getAddr(oldState, oldAddr) : Uninitialized);
|
|
1256
1273
|
}
|
|
1257
1274
|
}
|
|
1258
1275
|
address[facet.id] = dynamicSlots.length << 1;
|
|
1259
1276
|
dynamicSlots.push(a => dynamicFacetSlot(a, facet, providers));
|
|
1277
|
+
dynamicValues.push(canReuse || oldProviders.length ? oldState.facet(facet) : Uninitialized);
|
|
1260
1278
|
}
|
|
1261
1279
|
}
|
|
1262
|
-
|
|
1280
|
+
let dynamic = dynamicSlots.map(f => f(address));
|
|
1281
|
+
return {
|
|
1282
|
+
configuration: new Configuration(base, newCompartments, dynamic, address, staticValues, facets),
|
|
1283
|
+
values: dynamicValues
|
|
1284
|
+
};
|
|
1263
1285
|
}
|
|
1264
1286
|
}
|
|
1265
1287
|
function flatten(extension, compartments, newCompartments) {
|
|
@@ -1311,6 +1333,7 @@ function flatten(extension, compartments, newCompartments) {
|
|
|
1311
1333
|
inner(extension, Prec_.default);
|
|
1312
1334
|
return result.reduce((a, b) => a.concat(b));
|
|
1313
1335
|
}
|
|
1336
|
+
const Uninitialized = {};
|
|
1314
1337
|
function ensureAddr(state, addr) {
|
|
1315
1338
|
if (addr & 1)
|
|
1316
1339
|
return 2 /* Computed */;
|
|
@@ -1836,28 +1859,20 @@ class EditorState {
|
|
|
1836
1859
|
/**
|
|
1837
1860
|
The current selection.
|
|
1838
1861
|
*/
|
|
1839
|
-
selection,
|
|
1862
|
+
selection,
|
|
1863
|
+
/**
|
|
1864
|
+
@internal
|
|
1865
|
+
*/
|
|
1866
|
+
values, tr = null) {
|
|
1840
1867
|
this.config = config;
|
|
1841
1868
|
this.doc = doc;
|
|
1842
1869
|
this.selection = selection;
|
|
1870
|
+
this.values = values;
|
|
1843
1871
|
/**
|
|
1844
1872
|
@internal
|
|
1845
1873
|
*/
|
|
1846
1874
|
this.applying = null;
|
|
1847
1875
|
this.status = config.statusTemplate.slice();
|
|
1848
|
-
if (tr && tr.startState.config == config) {
|
|
1849
|
-
this.values = tr.startState.values.slice();
|
|
1850
|
-
}
|
|
1851
|
-
else {
|
|
1852
|
-
this.values = config.dynamicSlots.map(_ => null);
|
|
1853
|
-
// Copy over old values for shared facets/fields if this is a reconfigure
|
|
1854
|
-
if (tr)
|
|
1855
|
-
for (let id in config.address) {
|
|
1856
|
-
let cur = config.address[id], prev = tr.startState.config.address[id];
|
|
1857
|
-
if (prev != null && (cur & 1) == 0)
|
|
1858
|
-
this.values[cur >> 1] = getAddr(tr.startState, prev);
|
|
1859
|
-
}
|
|
1860
|
-
}
|
|
1861
1876
|
this.applying = tr;
|
|
1862
1877
|
// Fill in the computed state immediately, so that further queries
|
|
1863
1878
|
// for it made during the update return this state
|
|
@@ -1918,7 +1933,17 @@ class EditorState {
|
|
|
1918
1933
|
base = asArray(base).concat(effect.value);
|
|
1919
1934
|
}
|
|
1920
1935
|
}
|
|
1921
|
-
|
|
1936
|
+
let startValues;
|
|
1937
|
+
if (!conf) {
|
|
1938
|
+
let resolved = Configuration.resolve(base, compartments, this);
|
|
1939
|
+
conf = resolved.configuration;
|
|
1940
|
+
let intermediateState = new EditorState(conf, this.doc, this.selection, resolved.values, null);
|
|
1941
|
+
startValues = intermediateState.values;
|
|
1942
|
+
}
|
|
1943
|
+
else {
|
|
1944
|
+
startValues = tr.startState.values.slice();
|
|
1945
|
+
}
|
|
1946
|
+
new EditorState(conf, tr.newDoc, tr.newSelection, startValues, tr);
|
|
1922
1947
|
}
|
|
1923
1948
|
/**
|
|
1924
1949
|
Create a [transaction spec](https://codemirror.net/6/docs/ref/#state.TransactionSpec) that
|
|
@@ -2042,7 +2067,7 @@ class EditorState {
|
|
|
2042
2067
|
transactions.
|
|
2043
2068
|
*/
|
|
2044
2069
|
static create(config = {}) {
|
|
2045
|
-
let configuration = Configuration.resolve(config.extensions || [], new Map);
|
|
2070
|
+
let { configuration, values } = Configuration.resolve(config.extensions || [], new Map);
|
|
2046
2071
|
let doc = config.doc instanceof text.Text ? config.doc
|
|
2047
2072
|
: text.Text.of((config.doc || "").split(configuration.staticFacet(EditorState.lineSeparator) || DefaultSplit));
|
|
2048
2073
|
let selection = !config.selection ? EditorSelection.single(0)
|
|
@@ -2051,7 +2076,7 @@ class EditorState {
|
|
|
2051
2076
|
checkSelection(selection, doc.length);
|
|
2052
2077
|
if (!configuration.staticFacet(allowMultipleSelections))
|
|
2053
2078
|
selection = selection.asSingle();
|
|
2054
|
-
return new EditorState(configuration, doc, selection);
|
|
2079
|
+
return new EditorState(configuration, doc, selection, values);
|
|
2055
2080
|
}
|
|
2056
2081
|
/**
|
|
2057
2082
|
The size (in columns) of a tab in the document, determined by
|
|
@@ -2264,9 +2289,7 @@ combine = {}) {
|
|
|
2264
2289
|
|
|
2265
2290
|
Object.defineProperty(exports, 'Text', {
|
|
2266
2291
|
enumerable: true,
|
|
2267
|
-
get: function () {
|
|
2268
|
-
return text.Text;
|
|
2269
|
-
}
|
|
2292
|
+
get: function () { return text.Text; }
|
|
2270
2293
|
});
|
|
2271
2294
|
exports.Annotation = Annotation;
|
|
2272
2295
|
exports.AnnotationType = AnnotationType;
|
package/dist/index.d.ts
CHANGED
|
@@ -163,7 +163,9 @@ declare class ChangeSet extends ChangeDesc {
|
|
|
163
163
|
map(other: ChangeDesc, before?: boolean): ChangeSet;
|
|
164
164
|
/**
|
|
165
165
|
Iterate over the changed ranges in the document, calling `f` for
|
|
166
|
-
each
|
|
166
|
+
each, with the range in the original document (`fromA`-`toA`)
|
|
167
|
+
and the range that replaces it in the new document
|
|
168
|
+
(`fromB`-`toB`).
|
|
167
169
|
|
|
168
170
|
When `individual` is true, adjacent changes are reported
|
|
169
171
|
separately.
|
package/dist/index.js
CHANGED
|
@@ -261,7 +261,9 @@ class ChangeSet extends ChangeDesc {
|
|
|
261
261
|
map(other, before = false) { return other.empty ? this : mapSet(this, other, before, true); }
|
|
262
262
|
/**
|
|
263
263
|
Iterate over the changed ranges in the document, calling `f` for
|
|
264
|
-
each
|
|
264
|
+
each, with the range in the original document (`fromA`-`toA`)
|
|
265
|
+
and the range that replaces it in the new document
|
|
266
|
+
(`fromB`-`toB`).
|
|
265
267
|
|
|
266
268
|
When `individual` is true, adjacent changes are reported
|
|
267
269
|
separately.
|
|
@@ -831,7 +833,8 @@ class EditorSelection {
|
|
|
831
833
|
*/
|
|
832
834
|
static range(anchor, head, goalColumn) {
|
|
833
835
|
let goal = (goalColumn !== null && goalColumn !== void 0 ? goalColumn : 33554431 /* NoGoalColumn */) << 5 /* GoalColumnOffset */;
|
|
834
|
-
return head < anchor ? new SelectionRange(head, anchor, 16 /* Inverted */ | goal
|
|
836
|
+
return head < anchor ? new SelectionRange(head, anchor, 16 /* Inverted */ | goal | 8 /* AssocAfter */)
|
|
837
|
+
: new SelectionRange(anchor, head, goal | (head > anchor ? 4 /* AssocBefore */ : 0));
|
|
835
838
|
}
|
|
836
839
|
}
|
|
837
840
|
function normalized(ranges, mainIndex = 0) {
|
|
@@ -963,21 +966,23 @@ class FacetProvider {
|
|
|
963
966
|
depAddrs.push(addresses[dep.id]);
|
|
964
967
|
}
|
|
965
968
|
return (state, tr) => {
|
|
966
|
-
|
|
969
|
+
let oldVal = state.values[idx];
|
|
970
|
+
if (oldVal === Uninitialized) {
|
|
967
971
|
state.values[idx] = getter(state);
|
|
968
972
|
return 1 /* Changed */;
|
|
969
973
|
}
|
|
970
|
-
|
|
974
|
+
if (tr) {
|
|
971
975
|
let depChanged = (depDoc && tr.docChanged) || (depSel && (tr.docChanged || tr.selection)) ||
|
|
972
976
|
depAddrs.some(addr => (ensureAddr(state, addr) & 1 /* Changed */) > 0);
|
|
973
|
-
if (
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
977
|
+
if (depChanged) {
|
|
978
|
+
let newVal = getter(state);
|
|
979
|
+
if (multi ? !compareArray(newVal, oldVal, compare) : !compare(newVal, oldVal)) {
|
|
980
|
+
state.values[idx] = newVal;
|
|
981
|
+
return 1 /* Changed */;
|
|
982
|
+
}
|
|
983
|
+
}
|
|
980
984
|
}
|
|
985
|
+
return 0;
|
|
981
986
|
};
|
|
982
987
|
}
|
|
983
988
|
}
|
|
@@ -995,8 +1000,7 @@ function dynamicFacetSlot(addresses, facet, providers) {
|
|
|
995
1000
|
let dynamic = providerAddrs.filter(p => !(p & 1));
|
|
996
1001
|
let idx = addresses[facet.id] >> 1;
|
|
997
1002
|
return (state, tr) => {
|
|
998
|
-
let
|
|
999
|
-
let changed = oldAddr == null;
|
|
1003
|
+
let oldVal = state.values[idx], changed = oldVal === Uninitialized;
|
|
1000
1004
|
for (let dynAddr of dynamic) {
|
|
1001
1005
|
if (ensureAddr(state, dynAddr) & 1 /* Changed */)
|
|
1002
1006
|
changed = true;
|
|
@@ -1012,17 +1016,13 @@ function dynamicFacetSlot(addresses, facet, providers) {
|
|
|
1012
1016
|
else
|
|
1013
1017
|
values.push(value);
|
|
1014
1018
|
}
|
|
1015
|
-
let
|
|
1016
|
-
if (
|
|
1019
|
+
let value = facet.combine(values);
|
|
1020
|
+
if (oldVal !== Uninitialized && facet.compare(value, oldVal))
|
|
1017
1021
|
return 0;
|
|
1018
|
-
state.values[idx] =
|
|
1022
|
+
state.values[idx] = value;
|
|
1019
1023
|
return 1 /* Changed */;
|
|
1020
1024
|
};
|
|
1021
1025
|
}
|
|
1022
|
-
function maybeIndex(state, id) {
|
|
1023
|
-
let found = state.config.address[id];
|
|
1024
|
-
return found == null ? null : found >> 1;
|
|
1025
|
-
}
|
|
1026
1026
|
const initField = /*@__PURE__*/Facet.define({ static: true });
|
|
1027
1027
|
/**
|
|
1028
1028
|
Fields can store additional information in an editor state, and
|
|
@@ -1067,24 +1067,19 @@ class StateField {
|
|
|
1067
1067
|
slot(addresses) {
|
|
1068
1068
|
let idx = addresses[this.id] >> 1;
|
|
1069
1069
|
return (state, tr) => {
|
|
1070
|
-
|
|
1070
|
+
let oldVal = state.values[idx];
|
|
1071
|
+
if (oldVal === Uninitialized) {
|
|
1071
1072
|
state.values[idx] = this.create(state);
|
|
1072
1073
|
return 1 /* Changed */;
|
|
1073
1074
|
}
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
oldVal = tr.startState.values[idx];
|
|
1075
|
+
if (tr) {
|
|
1076
|
+
let value = this.updateF(oldVal, tr);
|
|
1077
|
+
if (!this.compareF(oldVal, value)) {
|
|
1078
|
+
state.values[idx] = value;
|
|
1079
|
+
return 1 /* Changed */;
|
|
1080
|
+
}
|
|
1081
1081
|
}
|
|
1082
|
-
|
|
1083
|
-
if (!changed && !this.compareF(oldVal, value))
|
|
1084
|
-
changed = 1 /* Changed */;
|
|
1085
|
-
if (changed)
|
|
1086
|
-
state.values[idx] = value;
|
|
1087
|
-
return changed;
|
|
1082
|
+
return 0;
|
|
1088
1083
|
};
|
|
1089
1084
|
}
|
|
1090
1085
|
/**
|
|
@@ -1196,15 +1191,16 @@ class CompartmentInstance {
|
|
|
1196
1191
|
}
|
|
1197
1192
|
}
|
|
1198
1193
|
class Configuration {
|
|
1199
|
-
constructor(base, compartments, dynamicSlots, address, staticValues) {
|
|
1194
|
+
constructor(base, compartments, dynamicSlots, address, staticValues, facets) {
|
|
1200
1195
|
this.base = base;
|
|
1201
1196
|
this.compartments = compartments;
|
|
1202
1197
|
this.dynamicSlots = dynamicSlots;
|
|
1203
1198
|
this.address = address;
|
|
1204
1199
|
this.staticValues = staticValues;
|
|
1200
|
+
this.facets = facets;
|
|
1205
1201
|
this.statusTemplate = [];
|
|
1206
1202
|
while (this.statusTemplate.length < dynamicSlots.length)
|
|
1207
|
-
this.statusTemplate.push(0 /*
|
|
1203
|
+
this.statusTemplate.push(0 /* Unresolved */);
|
|
1208
1204
|
}
|
|
1209
1205
|
staticFacet(facet) {
|
|
1210
1206
|
let addr = this.address[facet.id];
|
|
@@ -1223,25 +1219,44 @@ class Configuration {
|
|
|
1223
1219
|
let address = Object.create(null);
|
|
1224
1220
|
let staticValues = [];
|
|
1225
1221
|
let dynamicSlots = [];
|
|
1222
|
+
let dynamicValues = [];
|
|
1226
1223
|
for (let field of fields) {
|
|
1227
1224
|
address[field.id] = dynamicSlots.length << 1;
|
|
1228
1225
|
dynamicSlots.push(a => field.slot(a));
|
|
1226
|
+
dynamicValues.push(oldState && oldState.config.address[field.id] != null ? oldState.field(field) : Uninitialized);
|
|
1229
1227
|
}
|
|
1228
|
+
let canReuseCache = new Map;
|
|
1229
|
+
let canReuseDep = (dep) => {
|
|
1230
|
+
if (!(dep instanceof Facet))
|
|
1231
|
+
return true;
|
|
1232
|
+
let cached = canReuseCache.get(dep);
|
|
1233
|
+
if (cached != null)
|
|
1234
|
+
return cached;
|
|
1235
|
+
canReuseCache.set(dep, false);
|
|
1236
|
+
if (!oldFacets || !sameArray(oldFacets[dep.id] || [], facets[dep.id] || []))
|
|
1237
|
+
return;
|
|
1238
|
+
for (let input of facets[dep.id] || [])
|
|
1239
|
+
if (!input.dependencies.every(canReuseDep))
|
|
1240
|
+
return;
|
|
1241
|
+
canReuseCache.set(dep, true);
|
|
1242
|
+
};
|
|
1243
|
+
let oldFacets = oldState === null || oldState === void 0 ? void 0 : oldState.config.facets;
|
|
1230
1244
|
for (let id in facets) {
|
|
1231
1245
|
let providers = facets[id], facet = providers[0].facet;
|
|
1246
|
+
let oldProviders = oldFacets && oldFacets[id] || [];
|
|
1247
|
+
let canReuse = sameArray(providers, oldProviders);
|
|
1232
1248
|
if (providers.every(p => p.type == 0 /* Static */)) {
|
|
1233
1249
|
address[facet.id] = (staticValues.length << 1) | 1;
|
|
1234
|
-
let value = facet.combine(providers.map(p => p.value));
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
let oldVal = getAddr(oldState, oldAddr);
|
|
1238
|
-
if (facet.compare(value, oldVal))
|
|
1239
|
-
value = oldVal;
|
|
1240
|
-
}
|
|
1250
|
+
let value = canReuse ? oldState.facet(facet) : facet.combine(providers.map(p => p.value)), oldValue;
|
|
1251
|
+
if (!canReuse && oldState && facet.compare(value, oldValue = oldState.facet(facet)))
|
|
1252
|
+
value = oldValue;
|
|
1241
1253
|
staticValues.push(value);
|
|
1242
1254
|
}
|
|
1243
1255
|
else {
|
|
1244
1256
|
for (let p of providers) {
|
|
1257
|
+
let canReuseThis = p.dependencies.every(canReuseDep);
|
|
1258
|
+
if (!canReuseThis)
|
|
1259
|
+
canReuse = false;
|
|
1245
1260
|
if (p.type == 0 /* Static */) {
|
|
1246
1261
|
address[p.id] = (staticValues.length << 1) | 1;
|
|
1247
1262
|
staticValues.push(p.value);
|
|
@@ -1249,13 +1264,20 @@ class Configuration {
|
|
|
1249
1264
|
else {
|
|
1250
1265
|
address[p.id] = dynamicSlots.length << 1;
|
|
1251
1266
|
dynamicSlots.push(a => p.dynamicSlot(a));
|
|
1267
|
+
let oldAddr = oldState && canReuseThis ? oldState.config.address[p.id] : null;
|
|
1268
|
+
dynamicValues.push(oldAddr != null ? getAddr(oldState, oldAddr) : Uninitialized);
|
|
1252
1269
|
}
|
|
1253
1270
|
}
|
|
1254
1271
|
address[facet.id] = dynamicSlots.length << 1;
|
|
1255
1272
|
dynamicSlots.push(a => dynamicFacetSlot(a, facet, providers));
|
|
1273
|
+
dynamicValues.push(canReuse || oldProviders.length ? oldState.facet(facet) : Uninitialized);
|
|
1256
1274
|
}
|
|
1257
1275
|
}
|
|
1258
|
-
|
|
1276
|
+
let dynamic = dynamicSlots.map(f => f(address));
|
|
1277
|
+
return {
|
|
1278
|
+
configuration: new Configuration(base, newCompartments, dynamic, address, staticValues, facets),
|
|
1279
|
+
values: dynamicValues
|
|
1280
|
+
};
|
|
1259
1281
|
}
|
|
1260
1282
|
}
|
|
1261
1283
|
function flatten(extension, compartments, newCompartments) {
|
|
@@ -1307,6 +1329,7 @@ function flatten(extension, compartments, newCompartments) {
|
|
|
1307
1329
|
inner(extension, Prec_.default);
|
|
1308
1330
|
return result.reduce((a, b) => a.concat(b));
|
|
1309
1331
|
}
|
|
1332
|
+
const Uninitialized = {};
|
|
1310
1333
|
function ensureAddr(state, addr) {
|
|
1311
1334
|
if (addr & 1)
|
|
1312
1335
|
return 2 /* Computed */;
|
|
@@ -1831,28 +1854,20 @@ class EditorState {
|
|
|
1831
1854
|
/**
|
|
1832
1855
|
The current selection.
|
|
1833
1856
|
*/
|
|
1834
|
-
selection,
|
|
1857
|
+
selection,
|
|
1858
|
+
/**
|
|
1859
|
+
@internal
|
|
1860
|
+
*/
|
|
1861
|
+
values, tr = null) {
|
|
1835
1862
|
this.config = config;
|
|
1836
1863
|
this.doc = doc;
|
|
1837
1864
|
this.selection = selection;
|
|
1865
|
+
this.values = values;
|
|
1838
1866
|
/**
|
|
1839
1867
|
@internal
|
|
1840
1868
|
*/
|
|
1841
1869
|
this.applying = null;
|
|
1842
1870
|
this.status = config.statusTemplate.slice();
|
|
1843
|
-
if (tr && tr.startState.config == config) {
|
|
1844
|
-
this.values = tr.startState.values.slice();
|
|
1845
|
-
}
|
|
1846
|
-
else {
|
|
1847
|
-
this.values = config.dynamicSlots.map(_ => null);
|
|
1848
|
-
// Copy over old values for shared facets/fields if this is a reconfigure
|
|
1849
|
-
if (tr)
|
|
1850
|
-
for (let id in config.address) {
|
|
1851
|
-
let cur = config.address[id], prev = tr.startState.config.address[id];
|
|
1852
|
-
if (prev != null && (cur & 1) == 0)
|
|
1853
|
-
this.values[cur >> 1] = getAddr(tr.startState, prev);
|
|
1854
|
-
}
|
|
1855
|
-
}
|
|
1856
1871
|
this.applying = tr;
|
|
1857
1872
|
// Fill in the computed state immediately, so that further queries
|
|
1858
1873
|
// for it made during the update return this state
|
|
@@ -1913,7 +1928,17 @@ class EditorState {
|
|
|
1913
1928
|
base = asArray(base).concat(effect.value);
|
|
1914
1929
|
}
|
|
1915
1930
|
}
|
|
1916
|
-
|
|
1931
|
+
let startValues;
|
|
1932
|
+
if (!conf) {
|
|
1933
|
+
let resolved = Configuration.resolve(base, compartments, this);
|
|
1934
|
+
conf = resolved.configuration;
|
|
1935
|
+
let intermediateState = new EditorState(conf, this.doc, this.selection, resolved.values, null);
|
|
1936
|
+
startValues = intermediateState.values;
|
|
1937
|
+
}
|
|
1938
|
+
else {
|
|
1939
|
+
startValues = tr.startState.values.slice();
|
|
1940
|
+
}
|
|
1941
|
+
new EditorState(conf, tr.newDoc, tr.newSelection, startValues, tr);
|
|
1917
1942
|
}
|
|
1918
1943
|
/**
|
|
1919
1944
|
Create a [transaction spec](https://codemirror.net/6/docs/ref/#state.TransactionSpec) that
|
|
@@ -2037,7 +2062,7 @@ class EditorState {
|
|
|
2037
2062
|
transactions.
|
|
2038
2063
|
*/
|
|
2039
2064
|
static create(config = {}) {
|
|
2040
|
-
let configuration = Configuration.resolve(config.extensions || [], new Map);
|
|
2065
|
+
let { configuration, values } = Configuration.resolve(config.extensions || [], new Map);
|
|
2041
2066
|
let doc = config.doc instanceof Text ? config.doc
|
|
2042
2067
|
: Text.of((config.doc || "").split(configuration.staticFacet(EditorState.lineSeparator) || DefaultSplit));
|
|
2043
2068
|
let selection = !config.selection ? EditorSelection.single(0)
|
|
@@ -2046,7 +2071,7 @@ class EditorState {
|
|
|
2046
2071
|
checkSelection(selection, doc.length);
|
|
2047
2072
|
if (!configuration.staticFacet(allowMultipleSelections))
|
|
2048
2073
|
selection = selection.asSingle();
|
|
2049
|
-
return new EditorState(configuration, doc, selection);
|
|
2074
|
+
return new EditorState(configuration, doc, selection, values);
|
|
2050
2075
|
}
|
|
2051
2076
|
/**
|
|
2052
2077
|
The size (in columns) of a tab in the document, determined by
|