@codemirror/state 0.19.2 → 0.19.6
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 +26 -0
- package/dist/index.cjs +103 -63
- package/dist/index.d.ts +26 -8
- package/dist/index.js +103 -63
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
## 0.19.6 (2021-11-19)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Fix a bug that caused facet compare functions to be called with an invalid value in some situations.
|
|
6
|
+
|
|
7
|
+
Fix a bug that caused dynamic facet values to be incorrectly kept unchanged when reconfiguration changed one of their dependencies.
|
|
8
|
+
|
|
9
|
+
## 0.19.5 (2021-11-10)
|
|
10
|
+
|
|
11
|
+
### Bug fixes
|
|
12
|
+
|
|
13
|
+
Fix a bug that would cause dynamic facet values influenced by a state reconfiguration to not properly recompute.
|
|
14
|
+
|
|
15
|
+
## 0.19.4 (2021-11-05)
|
|
16
|
+
|
|
17
|
+
### Bug fixes
|
|
18
|
+
|
|
19
|
+
When reconfiguring a state, effects from the reconfiguring transaction can now be seen by newly added state fields.
|
|
20
|
+
|
|
21
|
+
## 0.19.3 (2021-11-03)
|
|
22
|
+
|
|
23
|
+
### New features
|
|
24
|
+
|
|
25
|
+
The precedence levels (under `Prec`) now have more generic names, because their 'meaningful' names were entirely inappropriate in many situations.
|
|
26
|
+
|
|
1
27
|
## 0.19.2 (2021-09-13)
|
|
2
28
|
|
|
3
29
|
### New features
|
package/dist/index.cjs
CHANGED
|
@@ -967,21 +967,23 @@ class FacetProvider {
|
|
|
967
967
|
depAddrs.push(addresses[dep.id]);
|
|
968
968
|
}
|
|
969
969
|
return (state, tr) => {
|
|
970
|
-
|
|
970
|
+
let oldVal = state.values[idx];
|
|
971
|
+
if (oldVal === Uninitialized) {
|
|
971
972
|
state.values[idx] = getter(state);
|
|
972
973
|
return 1 /* Changed */;
|
|
973
974
|
}
|
|
974
|
-
|
|
975
|
+
if (tr) {
|
|
975
976
|
let depChanged = (depDoc && tr.docChanged) || (depSel && (tr.docChanged || tr.selection)) ||
|
|
976
977
|
depAddrs.some(addr => (ensureAddr(state, addr) & 1 /* Changed */) > 0);
|
|
977
|
-
if (
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
978
|
+
if (depChanged) {
|
|
979
|
+
let newVal = getter(state);
|
|
980
|
+
if (multi ? !compareArray(newVal, oldVal, compare) : !compare(newVal, oldVal)) {
|
|
981
|
+
state.values[idx] = newVal;
|
|
982
|
+
return 1 /* Changed */;
|
|
983
|
+
}
|
|
984
|
+
}
|
|
984
985
|
}
|
|
986
|
+
return 0;
|
|
985
987
|
};
|
|
986
988
|
}
|
|
987
989
|
}
|
|
@@ -999,8 +1001,7 @@ function dynamicFacetSlot(addresses, facet, providers) {
|
|
|
999
1001
|
let dynamic = providerAddrs.filter(p => !(p & 1));
|
|
1000
1002
|
let idx = addresses[facet.id] >> 1;
|
|
1001
1003
|
return (state, tr) => {
|
|
1002
|
-
let
|
|
1003
|
-
let changed = oldAddr == null;
|
|
1004
|
+
let oldVal = state.values[idx], changed = oldVal === Uninitialized || !tr;
|
|
1004
1005
|
for (let dynAddr of dynamic) {
|
|
1005
1006
|
if (ensureAddr(state, dynAddr) & 1 /* Changed */)
|
|
1006
1007
|
changed = true;
|
|
@@ -1016,17 +1017,13 @@ function dynamicFacetSlot(addresses, facet, providers) {
|
|
|
1016
1017
|
else
|
|
1017
1018
|
values.push(value);
|
|
1018
1019
|
}
|
|
1019
|
-
let
|
|
1020
|
-
if (
|
|
1020
|
+
let value = facet.combine(values);
|
|
1021
|
+
if (oldVal !== Uninitialized && facet.compare(value, oldVal))
|
|
1021
1022
|
return 0;
|
|
1022
|
-
state.values[idx] =
|
|
1023
|
+
state.values[idx] = value;
|
|
1023
1024
|
return 1 /* Changed */;
|
|
1024
1025
|
};
|
|
1025
1026
|
}
|
|
1026
|
-
function maybeIndex(state, id) {
|
|
1027
|
-
let found = state.config.address[id];
|
|
1028
|
-
return found == null ? null : found >> 1;
|
|
1029
|
-
}
|
|
1030
1027
|
const initField = Facet.define({ static: true });
|
|
1031
1028
|
/**
|
|
1032
1029
|
Fields can store additional information in an editor state, and
|
|
@@ -1071,24 +1068,19 @@ class StateField {
|
|
|
1071
1068
|
slot(addresses) {
|
|
1072
1069
|
let idx = addresses[this.id] >> 1;
|
|
1073
1070
|
return (state, tr) => {
|
|
1074
|
-
|
|
1071
|
+
let oldVal = state.values[idx];
|
|
1072
|
+
if (oldVal === Uninitialized) {
|
|
1075
1073
|
state.values[idx] = this.create(state);
|
|
1076
1074
|
return 1 /* Changed */;
|
|
1077
1075
|
}
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
oldVal = tr.startState.values[idx];
|
|
1076
|
+
if (tr) {
|
|
1077
|
+
let value = this.updateF(oldVal, tr);
|
|
1078
|
+
if (!this.compareF(oldVal, value)) {
|
|
1079
|
+
state.values[idx] = value;
|
|
1080
|
+
return 1 /* Changed */;
|
|
1081
|
+
}
|
|
1085
1082
|
}
|
|
1086
|
-
|
|
1087
|
-
if (!changed && !this.compareF(oldVal, value))
|
|
1088
|
-
changed = 1 /* Changed */;
|
|
1089
|
-
if (changed)
|
|
1090
|
-
state.values[idx] = value;
|
|
1091
|
-
return changed;
|
|
1083
|
+
return 0;
|
|
1092
1084
|
};
|
|
1093
1085
|
}
|
|
1094
1086
|
/**
|
|
@@ -1106,7 +1098,7 @@ class StateField {
|
|
|
1106
1098
|
*/
|
|
1107
1099
|
get extension() { return this; }
|
|
1108
1100
|
}
|
|
1109
|
-
const Prec_ = {
|
|
1101
|
+
const Prec_ = { lowest: 4, low: 3, default: 2, high: 1, highest: 0 };
|
|
1110
1102
|
function prec(value) {
|
|
1111
1103
|
return (ext) => new PrecExtension(ext, value);
|
|
1112
1104
|
}
|
|
@@ -1122,23 +1114,42 @@ precedence and then by order within each precedence.
|
|
|
1122
1114
|
*/
|
|
1123
1115
|
const Prec = {
|
|
1124
1116
|
/**
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1117
|
+
The lowest precedence level. Meant for things that should end up
|
|
1118
|
+
near the end of the extension order.
|
|
1119
|
+
*/
|
|
1120
|
+
lowest: prec(Prec_.lowest),
|
|
1121
|
+
/**
|
|
1122
|
+
A lower-than-default precedence, for extensions.
|
|
1128
1123
|
*/
|
|
1129
|
-
|
|
1124
|
+
low: prec(Prec_.low),
|
|
1130
1125
|
/**
|
|
1131
|
-
The
|
|
1126
|
+
The default precedence, which is also used for extensions
|
|
1127
|
+
without an explicit precedence.
|
|
1132
1128
|
*/
|
|
1133
1129
|
default: prec(Prec_.default),
|
|
1134
1130
|
/**
|
|
1135
|
-
A higher-than-default precedence
|
|
1131
|
+
A higher-than-default precedence, for extensions that should
|
|
1132
|
+
come before those with default precedence.
|
|
1133
|
+
*/
|
|
1134
|
+
high: prec(Prec_.high),
|
|
1135
|
+
/**
|
|
1136
|
+
The highest precedence level, for extensions that should end up
|
|
1137
|
+
near the start of the precedence ordering.
|
|
1138
|
+
*/
|
|
1139
|
+
highest: prec(Prec_.highest),
|
|
1140
|
+
// FIXME Drop these in some future breaking version
|
|
1141
|
+
/**
|
|
1142
|
+
Backwards-compatible synonym for `Prec.lowest`.
|
|
1136
1143
|
*/
|
|
1137
|
-
|
|
1144
|
+
fallback: prec(Prec_.lowest),
|
|
1138
1145
|
/**
|
|
1139
|
-
|
|
1146
|
+
Backwards-compatible synonym for `Prec.high`.
|
|
1140
1147
|
*/
|
|
1141
|
-
|
|
1148
|
+
extend: prec(Prec_.high),
|
|
1149
|
+
/**
|
|
1150
|
+
Backwards-compatible synonym for `Prec.highest`.
|
|
1151
|
+
*/
|
|
1152
|
+
override: prec(Prec_.highest)
|
|
1142
1153
|
};
|
|
1143
1154
|
class PrecExtension {
|
|
1144
1155
|
constructor(inner, prec) {
|
|
@@ -1189,7 +1200,7 @@ class Configuration {
|
|
|
1189
1200
|
this.staticValues = staticValues;
|
|
1190
1201
|
this.statusTemplate = [];
|
|
1191
1202
|
while (this.statusTemplate.length < dynamicSlots.length)
|
|
1192
|
-
this.statusTemplate.push(0 /*
|
|
1203
|
+
this.statusTemplate.push(0 /* Unresolved */);
|
|
1193
1204
|
}
|
|
1194
1205
|
staticFacet(facet) {
|
|
1195
1206
|
let addr = this.address[facet.id];
|
|
@@ -1208,9 +1219,11 @@ class Configuration {
|
|
|
1208
1219
|
let address = Object.create(null);
|
|
1209
1220
|
let staticValues = [];
|
|
1210
1221
|
let dynamicSlots = [];
|
|
1222
|
+
let dynamicDeps = [];
|
|
1211
1223
|
for (let field of fields) {
|
|
1212
1224
|
address[field.id] = dynamicSlots.length << 1;
|
|
1213
1225
|
dynamicSlots.push(a => field.slot(a));
|
|
1226
|
+
dynamicDeps.push([]);
|
|
1214
1227
|
}
|
|
1215
1228
|
for (let id in facets) {
|
|
1216
1229
|
let providers = facets[id], facet = providers[0].facet;
|
|
@@ -1234,17 +1247,41 @@ class Configuration {
|
|
|
1234
1247
|
else {
|
|
1235
1248
|
address[p.id] = dynamicSlots.length << 1;
|
|
1236
1249
|
dynamicSlots.push(a => p.dynamicSlot(a));
|
|
1250
|
+
dynamicDeps.push(p.dependencies.filter(d => typeof d != "string").map(d => d.id));
|
|
1237
1251
|
}
|
|
1238
1252
|
}
|
|
1239
1253
|
address[facet.id] = dynamicSlots.length << 1;
|
|
1240
1254
|
dynamicSlots.push(a => dynamicFacetSlot(a, facet, providers));
|
|
1255
|
+
dynamicDeps.push(providers.filter(p => p.type != 0 /* Static */).map(d => d.id));
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
let dynamicValues = dynamicSlots.map(_ => Uninitialized);
|
|
1259
|
+
if (oldState) {
|
|
1260
|
+
let canReuse = (id, depth) => {
|
|
1261
|
+
if (depth > 7)
|
|
1262
|
+
return false;
|
|
1263
|
+
let addr = address[id];
|
|
1264
|
+
if (!(addr & 1))
|
|
1265
|
+
return dynamicDeps[addr >> 1].every(id => canReuse(id, depth + 1));
|
|
1266
|
+
let oldAddr = oldState.config.address[id];
|
|
1267
|
+
return oldAddr != null && getAddr(oldState, oldAddr) == staticValues[addr >> 1];
|
|
1268
|
+
};
|
|
1269
|
+
// Copy over old values for shared facets/fields, if we can
|
|
1270
|
+
// prove that they don't need to be recomputed.
|
|
1271
|
+
for (let id in address) {
|
|
1272
|
+
let cur = address[id], prev = oldState.config.address[id];
|
|
1273
|
+
if (prev != null && (cur & 1) == 0 && canReuse(+id, 0))
|
|
1274
|
+
dynamicValues[cur >> 1] = getAddr(oldState, prev);
|
|
1241
1275
|
}
|
|
1242
1276
|
}
|
|
1243
|
-
return
|
|
1277
|
+
return {
|
|
1278
|
+
configuration: new Configuration(base, newCompartments, dynamicSlots.map(f => f(address)), address, staticValues),
|
|
1279
|
+
values: dynamicValues
|
|
1280
|
+
};
|
|
1244
1281
|
}
|
|
1245
1282
|
}
|
|
1246
1283
|
function flatten(extension, compartments, newCompartments) {
|
|
1247
|
-
let result = [[], [], [], []];
|
|
1284
|
+
let result = [[], [], [], [], []];
|
|
1248
1285
|
let seen = new Map();
|
|
1249
1286
|
function inner(ext, prec) {
|
|
1250
1287
|
let known = seen.get(ext);
|
|
@@ -1292,6 +1329,7 @@ function flatten(extension, compartments, newCompartments) {
|
|
|
1292
1329
|
inner(extension, Prec_.default);
|
|
1293
1330
|
return result.reduce((a, b) => a.concat(b));
|
|
1294
1331
|
}
|
|
1332
|
+
const Uninitialized = {};
|
|
1295
1333
|
function ensureAddr(state, addr) {
|
|
1296
1334
|
if (addr & 1)
|
|
1297
1335
|
return 2 /* Computed */;
|
|
@@ -1576,7 +1614,7 @@ class Transaction {
|
|
|
1576
1614
|
*/
|
|
1577
1615
|
isUserEvent(event) {
|
|
1578
1616
|
let e = this.annotation(Transaction.userEvent);
|
|
1579
|
-
return e && (e == event || e.length > event.length && e.slice(0, event.length) == event && e[event.length] == ".");
|
|
1617
|
+
return !!(e && (e == event || e.length > event.length && e.slice(0, event.length) == event && e[event.length] == "."));
|
|
1580
1618
|
}
|
|
1581
1619
|
}
|
|
1582
1620
|
/**
|
|
@@ -1817,28 +1855,20 @@ class EditorState {
|
|
|
1817
1855
|
/**
|
|
1818
1856
|
The current selection.
|
|
1819
1857
|
*/
|
|
1820
|
-
selection,
|
|
1858
|
+
selection,
|
|
1859
|
+
/**
|
|
1860
|
+
@internal
|
|
1861
|
+
*/
|
|
1862
|
+
values, tr = null) {
|
|
1821
1863
|
this.config = config;
|
|
1822
1864
|
this.doc = doc;
|
|
1823
1865
|
this.selection = selection;
|
|
1866
|
+
this.values = values;
|
|
1824
1867
|
/**
|
|
1825
1868
|
@internal
|
|
1826
1869
|
*/
|
|
1827
1870
|
this.applying = null;
|
|
1828
1871
|
this.status = config.statusTemplate.slice();
|
|
1829
|
-
if (tr && tr.startState.config == config) {
|
|
1830
|
-
this.values = tr.startState.values.slice();
|
|
1831
|
-
}
|
|
1832
|
-
else {
|
|
1833
|
-
this.values = config.dynamicSlots.map(_ => null);
|
|
1834
|
-
// Copy over old values for shared facets/fields if this is a reconfigure
|
|
1835
|
-
if (tr)
|
|
1836
|
-
for (let id in config.address) {
|
|
1837
|
-
let cur = config.address[id], prev = tr.startState.config.address[id];
|
|
1838
|
-
if (prev != null && (cur & 1) == 0)
|
|
1839
|
-
this.values[cur >> 1] = getAddr(tr.startState, prev);
|
|
1840
|
-
}
|
|
1841
|
-
}
|
|
1842
1872
|
this.applying = tr;
|
|
1843
1873
|
// Fill in the computed state immediately, so that further queries
|
|
1844
1874
|
// for it made during the update return this state
|
|
@@ -1899,7 +1929,17 @@ class EditorState {
|
|
|
1899
1929
|
base = asArray(base).concat(effect.value);
|
|
1900
1930
|
}
|
|
1901
1931
|
}
|
|
1902
|
-
|
|
1932
|
+
let startValues;
|
|
1933
|
+
if (!conf) {
|
|
1934
|
+
let resolved = Configuration.resolve(base, compartments, this);
|
|
1935
|
+
conf = resolved.configuration;
|
|
1936
|
+
let intermediateState = new EditorState(conf, this.doc, this.selection, resolved.values, null);
|
|
1937
|
+
startValues = intermediateState.values;
|
|
1938
|
+
}
|
|
1939
|
+
else {
|
|
1940
|
+
startValues = tr.startState.values.slice();
|
|
1941
|
+
}
|
|
1942
|
+
new EditorState(conf, tr.newDoc, tr.newSelection, startValues, tr);
|
|
1903
1943
|
}
|
|
1904
1944
|
/**
|
|
1905
1945
|
Create a [transaction spec](https://codemirror.net/6/docs/ref/#state.TransactionSpec) that
|
|
@@ -2023,7 +2063,7 @@ class EditorState {
|
|
|
2023
2063
|
transactions.
|
|
2024
2064
|
*/
|
|
2025
2065
|
static create(config = {}) {
|
|
2026
|
-
let configuration = Configuration.resolve(config.extensions || [], new Map);
|
|
2066
|
+
let { configuration, values } = Configuration.resolve(config.extensions || [], new Map);
|
|
2027
2067
|
let doc = config.doc instanceof text.Text ? config.doc
|
|
2028
2068
|
: text.Text.of((config.doc || "").split(configuration.staticFacet(EditorState.lineSeparator) || DefaultSplit));
|
|
2029
2069
|
let selection = !config.selection ? EditorSelection.single(0)
|
|
@@ -2032,7 +2072,7 @@ class EditorState {
|
|
|
2032
2072
|
checkSelection(selection, doc.length);
|
|
2033
2073
|
if (!configuration.staticFacet(allowMultipleSelections))
|
|
2034
2074
|
selection = selection.asSingle();
|
|
2035
|
-
return new EditorState(configuration, doc, selection);
|
|
2075
|
+
return new EditorState(configuration, doc, selection, values);
|
|
2036
2076
|
}
|
|
2037
2077
|
/**
|
|
2038
2078
|
The size (in columns) of a tab in the document, determined by
|
package/dist/index.d.ts
CHANGED
|
@@ -509,21 +509,39 @@ precedence and then by order within each precedence.
|
|
|
509
509
|
*/
|
|
510
510
|
declare const Prec: {
|
|
511
511
|
/**
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
specified later in the extension ordering.
|
|
512
|
+
The lowest precedence level. Meant for things that should end up
|
|
513
|
+
near the end of the extension order.
|
|
515
514
|
*/
|
|
516
|
-
|
|
515
|
+
lowest: (ext: Extension) => Extension;
|
|
516
|
+
/**
|
|
517
|
+
A lower-than-default precedence, for extensions.
|
|
518
|
+
*/
|
|
519
|
+
low: (ext: Extension) => Extension;
|
|
517
520
|
/**
|
|
518
|
-
The
|
|
521
|
+
The default precedence, which is also used for extensions
|
|
522
|
+
without an explicit precedence.
|
|
519
523
|
*/
|
|
520
524
|
default: (ext: Extension) => Extension;
|
|
521
525
|
/**
|
|
522
|
-
A higher-than-default precedence
|
|
526
|
+
A higher-than-default precedence, for extensions that should
|
|
527
|
+
come before those with default precedence.
|
|
528
|
+
*/
|
|
529
|
+
high: (ext: Extension) => Extension;
|
|
530
|
+
/**
|
|
531
|
+
The highest precedence level, for extensions that should end up
|
|
532
|
+
near the start of the precedence ordering.
|
|
533
|
+
*/
|
|
534
|
+
highest: (ext: Extension) => Extension;
|
|
535
|
+
/**
|
|
536
|
+
Backwards-compatible synonym for `Prec.lowest`.
|
|
537
|
+
*/
|
|
538
|
+
fallback: (ext: Extension) => Extension;
|
|
539
|
+
/**
|
|
540
|
+
Backwards-compatible synonym for `Prec.high`.
|
|
523
541
|
*/
|
|
524
542
|
extend: (ext: Extension) => Extension;
|
|
525
543
|
/**
|
|
526
|
-
|
|
544
|
+
Backwards-compatible synonym for `Prec.highest`.
|
|
527
545
|
*/
|
|
528
546
|
override: (ext: Extension) => Extension;
|
|
529
547
|
};
|
|
@@ -783,7 +801,7 @@ declare class Transaction {
|
|
|
783
801
|
has `"select.pointer"` as user event, `"select"` and
|
|
784
802
|
`"select.pointer"` will match it.
|
|
785
803
|
*/
|
|
786
|
-
isUserEvent(event: string): boolean
|
|
804
|
+
isUserEvent(event: string): boolean;
|
|
787
805
|
/**
|
|
788
806
|
Annotation used to store transaction timestamps.
|
|
789
807
|
*/
|
package/dist/index.js
CHANGED
|
@@ -963,21 +963,23 @@ class FacetProvider {
|
|
|
963
963
|
depAddrs.push(addresses[dep.id]);
|
|
964
964
|
}
|
|
965
965
|
return (state, tr) => {
|
|
966
|
-
|
|
966
|
+
let oldVal = state.values[idx];
|
|
967
|
+
if (oldVal === Uninitialized) {
|
|
967
968
|
state.values[idx] = getter(state);
|
|
968
969
|
return 1 /* Changed */;
|
|
969
970
|
}
|
|
970
|
-
|
|
971
|
+
if (tr) {
|
|
971
972
|
let depChanged = (depDoc && tr.docChanged) || (depSel && (tr.docChanged || tr.selection)) ||
|
|
972
973
|
depAddrs.some(addr => (ensureAddr(state, addr) & 1 /* Changed */) > 0);
|
|
973
|
-
if (
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
974
|
+
if (depChanged) {
|
|
975
|
+
let newVal = getter(state);
|
|
976
|
+
if (multi ? !compareArray(newVal, oldVal, compare) : !compare(newVal, oldVal)) {
|
|
977
|
+
state.values[idx] = newVal;
|
|
978
|
+
return 1 /* Changed */;
|
|
979
|
+
}
|
|
980
|
+
}
|
|
980
981
|
}
|
|
982
|
+
return 0;
|
|
981
983
|
};
|
|
982
984
|
}
|
|
983
985
|
}
|
|
@@ -995,8 +997,7 @@ function dynamicFacetSlot(addresses, facet, providers) {
|
|
|
995
997
|
let dynamic = providerAddrs.filter(p => !(p & 1));
|
|
996
998
|
let idx = addresses[facet.id] >> 1;
|
|
997
999
|
return (state, tr) => {
|
|
998
|
-
let
|
|
999
|
-
let changed = oldAddr == null;
|
|
1000
|
+
let oldVal = state.values[idx], changed = oldVal === Uninitialized || !tr;
|
|
1000
1001
|
for (let dynAddr of dynamic) {
|
|
1001
1002
|
if (ensureAddr(state, dynAddr) & 1 /* Changed */)
|
|
1002
1003
|
changed = true;
|
|
@@ -1012,17 +1013,13 @@ function dynamicFacetSlot(addresses, facet, providers) {
|
|
|
1012
1013
|
else
|
|
1013
1014
|
values.push(value);
|
|
1014
1015
|
}
|
|
1015
|
-
let
|
|
1016
|
-
if (
|
|
1016
|
+
let value = facet.combine(values);
|
|
1017
|
+
if (oldVal !== Uninitialized && facet.compare(value, oldVal))
|
|
1017
1018
|
return 0;
|
|
1018
|
-
state.values[idx] =
|
|
1019
|
+
state.values[idx] = value;
|
|
1019
1020
|
return 1 /* Changed */;
|
|
1020
1021
|
};
|
|
1021
1022
|
}
|
|
1022
|
-
function maybeIndex(state, id) {
|
|
1023
|
-
let found = state.config.address[id];
|
|
1024
|
-
return found == null ? null : found >> 1;
|
|
1025
|
-
}
|
|
1026
1023
|
const initField = /*@__PURE__*/Facet.define({ static: true });
|
|
1027
1024
|
/**
|
|
1028
1025
|
Fields can store additional information in an editor state, and
|
|
@@ -1067,24 +1064,19 @@ class StateField {
|
|
|
1067
1064
|
slot(addresses) {
|
|
1068
1065
|
let idx = addresses[this.id] >> 1;
|
|
1069
1066
|
return (state, tr) => {
|
|
1070
|
-
|
|
1067
|
+
let oldVal = state.values[idx];
|
|
1068
|
+
if (oldVal === Uninitialized) {
|
|
1071
1069
|
state.values[idx] = this.create(state);
|
|
1072
1070
|
return 1 /* Changed */;
|
|
1073
1071
|
}
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
oldVal = tr.startState.values[idx];
|
|
1072
|
+
if (tr) {
|
|
1073
|
+
let value = this.updateF(oldVal, tr);
|
|
1074
|
+
if (!this.compareF(oldVal, value)) {
|
|
1075
|
+
state.values[idx] = value;
|
|
1076
|
+
return 1 /* Changed */;
|
|
1077
|
+
}
|
|
1081
1078
|
}
|
|
1082
|
-
|
|
1083
|
-
if (!changed && !this.compareF(oldVal, value))
|
|
1084
|
-
changed = 1 /* Changed */;
|
|
1085
|
-
if (changed)
|
|
1086
|
-
state.values[idx] = value;
|
|
1087
|
-
return changed;
|
|
1079
|
+
return 0;
|
|
1088
1080
|
};
|
|
1089
1081
|
}
|
|
1090
1082
|
/**
|
|
@@ -1102,7 +1094,7 @@ class StateField {
|
|
|
1102
1094
|
*/
|
|
1103
1095
|
get extension() { return this; }
|
|
1104
1096
|
}
|
|
1105
|
-
const Prec_ = {
|
|
1097
|
+
const Prec_ = { lowest: 4, low: 3, default: 2, high: 1, highest: 0 };
|
|
1106
1098
|
function prec(value) {
|
|
1107
1099
|
return (ext) => new PrecExtension(ext, value);
|
|
1108
1100
|
}
|
|
@@ -1118,23 +1110,42 @@ precedence and then by order within each precedence.
|
|
|
1118
1110
|
*/
|
|
1119
1111
|
const Prec = {
|
|
1120
1112
|
/**
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1113
|
+
The lowest precedence level. Meant for things that should end up
|
|
1114
|
+
near the end of the extension order.
|
|
1115
|
+
*/
|
|
1116
|
+
lowest: /*@__PURE__*/prec(Prec_.lowest),
|
|
1117
|
+
/**
|
|
1118
|
+
A lower-than-default precedence, for extensions.
|
|
1124
1119
|
*/
|
|
1125
|
-
|
|
1120
|
+
low: /*@__PURE__*/prec(Prec_.low),
|
|
1126
1121
|
/**
|
|
1127
|
-
The
|
|
1122
|
+
The default precedence, which is also used for extensions
|
|
1123
|
+
without an explicit precedence.
|
|
1128
1124
|
*/
|
|
1129
1125
|
default: /*@__PURE__*/prec(Prec_.default),
|
|
1130
1126
|
/**
|
|
1131
|
-
A higher-than-default precedence
|
|
1127
|
+
A higher-than-default precedence, for extensions that should
|
|
1128
|
+
come before those with default precedence.
|
|
1129
|
+
*/
|
|
1130
|
+
high: /*@__PURE__*/prec(Prec_.high),
|
|
1131
|
+
/**
|
|
1132
|
+
The highest precedence level, for extensions that should end up
|
|
1133
|
+
near the start of the precedence ordering.
|
|
1134
|
+
*/
|
|
1135
|
+
highest: /*@__PURE__*/prec(Prec_.highest),
|
|
1136
|
+
// FIXME Drop these in some future breaking version
|
|
1137
|
+
/**
|
|
1138
|
+
Backwards-compatible synonym for `Prec.lowest`.
|
|
1132
1139
|
*/
|
|
1133
|
-
|
|
1140
|
+
fallback: /*@__PURE__*/prec(Prec_.lowest),
|
|
1134
1141
|
/**
|
|
1135
|
-
|
|
1142
|
+
Backwards-compatible synonym for `Prec.high`.
|
|
1136
1143
|
*/
|
|
1137
|
-
|
|
1144
|
+
extend: /*@__PURE__*/prec(Prec_.high),
|
|
1145
|
+
/**
|
|
1146
|
+
Backwards-compatible synonym for `Prec.highest`.
|
|
1147
|
+
*/
|
|
1148
|
+
override: /*@__PURE__*/prec(Prec_.highest)
|
|
1138
1149
|
};
|
|
1139
1150
|
class PrecExtension {
|
|
1140
1151
|
constructor(inner, prec) {
|
|
@@ -1185,7 +1196,7 @@ class Configuration {
|
|
|
1185
1196
|
this.staticValues = staticValues;
|
|
1186
1197
|
this.statusTemplate = [];
|
|
1187
1198
|
while (this.statusTemplate.length < dynamicSlots.length)
|
|
1188
|
-
this.statusTemplate.push(0 /*
|
|
1199
|
+
this.statusTemplate.push(0 /* Unresolved */);
|
|
1189
1200
|
}
|
|
1190
1201
|
staticFacet(facet) {
|
|
1191
1202
|
let addr = this.address[facet.id];
|
|
@@ -1204,9 +1215,11 @@ class Configuration {
|
|
|
1204
1215
|
let address = Object.create(null);
|
|
1205
1216
|
let staticValues = [];
|
|
1206
1217
|
let dynamicSlots = [];
|
|
1218
|
+
let dynamicDeps = [];
|
|
1207
1219
|
for (let field of fields) {
|
|
1208
1220
|
address[field.id] = dynamicSlots.length << 1;
|
|
1209
1221
|
dynamicSlots.push(a => field.slot(a));
|
|
1222
|
+
dynamicDeps.push([]);
|
|
1210
1223
|
}
|
|
1211
1224
|
for (let id in facets) {
|
|
1212
1225
|
let providers = facets[id], facet = providers[0].facet;
|
|
@@ -1230,17 +1243,41 @@ class Configuration {
|
|
|
1230
1243
|
else {
|
|
1231
1244
|
address[p.id] = dynamicSlots.length << 1;
|
|
1232
1245
|
dynamicSlots.push(a => p.dynamicSlot(a));
|
|
1246
|
+
dynamicDeps.push(p.dependencies.filter(d => typeof d != "string").map(d => d.id));
|
|
1233
1247
|
}
|
|
1234
1248
|
}
|
|
1235
1249
|
address[facet.id] = dynamicSlots.length << 1;
|
|
1236
1250
|
dynamicSlots.push(a => dynamicFacetSlot(a, facet, providers));
|
|
1251
|
+
dynamicDeps.push(providers.filter(p => p.type != 0 /* Static */).map(d => d.id));
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
let dynamicValues = dynamicSlots.map(_ => Uninitialized);
|
|
1255
|
+
if (oldState) {
|
|
1256
|
+
let canReuse = (id, depth) => {
|
|
1257
|
+
if (depth > 7)
|
|
1258
|
+
return false;
|
|
1259
|
+
let addr = address[id];
|
|
1260
|
+
if (!(addr & 1))
|
|
1261
|
+
return dynamicDeps[addr >> 1].every(id => canReuse(id, depth + 1));
|
|
1262
|
+
let oldAddr = oldState.config.address[id];
|
|
1263
|
+
return oldAddr != null && getAddr(oldState, oldAddr) == staticValues[addr >> 1];
|
|
1264
|
+
};
|
|
1265
|
+
// Copy over old values for shared facets/fields, if we can
|
|
1266
|
+
// prove that they don't need to be recomputed.
|
|
1267
|
+
for (let id in address) {
|
|
1268
|
+
let cur = address[id], prev = oldState.config.address[id];
|
|
1269
|
+
if (prev != null && (cur & 1) == 0 && canReuse(+id, 0))
|
|
1270
|
+
dynamicValues[cur >> 1] = getAddr(oldState, prev);
|
|
1237
1271
|
}
|
|
1238
1272
|
}
|
|
1239
|
-
return
|
|
1273
|
+
return {
|
|
1274
|
+
configuration: new Configuration(base, newCompartments, dynamicSlots.map(f => f(address)), address, staticValues),
|
|
1275
|
+
values: dynamicValues
|
|
1276
|
+
};
|
|
1240
1277
|
}
|
|
1241
1278
|
}
|
|
1242
1279
|
function flatten(extension, compartments, newCompartments) {
|
|
1243
|
-
let result = [[], [], [], []];
|
|
1280
|
+
let result = [[], [], [], [], []];
|
|
1244
1281
|
let seen = new Map();
|
|
1245
1282
|
function inner(ext, prec) {
|
|
1246
1283
|
let known = seen.get(ext);
|
|
@@ -1288,6 +1325,7 @@ function flatten(extension, compartments, newCompartments) {
|
|
|
1288
1325
|
inner(extension, Prec_.default);
|
|
1289
1326
|
return result.reduce((a, b) => a.concat(b));
|
|
1290
1327
|
}
|
|
1328
|
+
const Uninitialized = {};
|
|
1291
1329
|
function ensureAddr(state, addr) {
|
|
1292
1330
|
if (addr & 1)
|
|
1293
1331
|
return 2 /* Computed */;
|
|
@@ -1572,7 +1610,7 @@ class Transaction {
|
|
|
1572
1610
|
*/
|
|
1573
1611
|
isUserEvent(event) {
|
|
1574
1612
|
let e = this.annotation(Transaction.userEvent);
|
|
1575
|
-
return e && (e == event || e.length > event.length && e.slice(0, event.length) == event && e[event.length] == ".");
|
|
1613
|
+
return !!(e && (e == event || e.length > event.length && e.slice(0, event.length) == event && e[event.length] == "."));
|
|
1576
1614
|
}
|
|
1577
1615
|
}
|
|
1578
1616
|
/**
|
|
@@ -1812,28 +1850,20 @@ class EditorState {
|
|
|
1812
1850
|
/**
|
|
1813
1851
|
The current selection.
|
|
1814
1852
|
*/
|
|
1815
|
-
selection,
|
|
1853
|
+
selection,
|
|
1854
|
+
/**
|
|
1855
|
+
@internal
|
|
1856
|
+
*/
|
|
1857
|
+
values, tr = null) {
|
|
1816
1858
|
this.config = config;
|
|
1817
1859
|
this.doc = doc;
|
|
1818
1860
|
this.selection = selection;
|
|
1861
|
+
this.values = values;
|
|
1819
1862
|
/**
|
|
1820
1863
|
@internal
|
|
1821
1864
|
*/
|
|
1822
1865
|
this.applying = null;
|
|
1823
1866
|
this.status = config.statusTemplate.slice();
|
|
1824
|
-
if (tr && tr.startState.config == config) {
|
|
1825
|
-
this.values = tr.startState.values.slice();
|
|
1826
|
-
}
|
|
1827
|
-
else {
|
|
1828
|
-
this.values = config.dynamicSlots.map(_ => null);
|
|
1829
|
-
// Copy over old values for shared facets/fields if this is a reconfigure
|
|
1830
|
-
if (tr)
|
|
1831
|
-
for (let id in config.address) {
|
|
1832
|
-
let cur = config.address[id], prev = tr.startState.config.address[id];
|
|
1833
|
-
if (prev != null && (cur & 1) == 0)
|
|
1834
|
-
this.values[cur >> 1] = getAddr(tr.startState, prev);
|
|
1835
|
-
}
|
|
1836
|
-
}
|
|
1837
1867
|
this.applying = tr;
|
|
1838
1868
|
// Fill in the computed state immediately, so that further queries
|
|
1839
1869
|
// for it made during the update return this state
|
|
@@ -1894,7 +1924,17 @@ class EditorState {
|
|
|
1894
1924
|
base = asArray(base).concat(effect.value);
|
|
1895
1925
|
}
|
|
1896
1926
|
}
|
|
1897
|
-
|
|
1927
|
+
let startValues;
|
|
1928
|
+
if (!conf) {
|
|
1929
|
+
let resolved = Configuration.resolve(base, compartments, this);
|
|
1930
|
+
conf = resolved.configuration;
|
|
1931
|
+
let intermediateState = new EditorState(conf, this.doc, this.selection, resolved.values, null);
|
|
1932
|
+
startValues = intermediateState.values;
|
|
1933
|
+
}
|
|
1934
|
+
else {
|
|
1935
|
+
startValues = tr.startState.values.slice();
|
|
1936
|
+
}
|
|
1937
|
+
new EditorState(conf, tr.newDoc, tr.newSelection, startValues, tr);
|
|
1898
1938
|
}
|
|
1899
1939
|
/**
|
|
1900
1940
|
Create a [transaction spec](https://codemirror.net/6/docs/ref/#state.TransactionSpec) that
|
|
@@ -2018,7 +2058,7 @@ class EditorState {
|
|
|
2018
2058
|
transactions.
|
|
2019
2059
|
*/
|
|
2020
2060
|
static create(config = {}) {
|
|
2021
|
-
let configuration = Configuration.resolve(config.extensions || [], new Map);
|
|
2061
|
+
let { configuration, values } = Configuration.resolve(config.extensions || [], new Map);
|
|
2022
2062
|
let doc = config.doc instanceof Text ? config.doc
|
|
2023
2063
|
: Text.of((config.doc || "").split(configuration.staticFacet(EditorState.lineSeparator) || DefaultSplit));
|
|
2024
2064
|
let selection = !config.selection ? EditorSelection.single(0)
|
|
@@ -2027,7 +2067,7 @@ class EditorState {
|
|
|
2027
2067
|
checkSelection(selection, doc.length);
|
|
2028
2068
|
if (!configuration.staticFacet(allowMultipleSelections))
|
|
2029
2069
|
selection = selection.asSingle();
|
|
2030
|
-
return new EditorState(configuration, doc, selection);
|
|
2070
|
+
return new EditorState(configuration, doc, selection, values);
|
|
2031
2071
|
}
|
|
2032
2072
|
/**
|
|
2033
2073
|
The size (in columns) of a tab in the document, determined by
|