@samline/forms 2.8.0 → 2.9.0
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 +15 -1
- package/README.md +43 -31
- package/dist/browser/global.d.ts +49 -3
- package/dist/browser/global.global.js +12 -12
- package/dist/browser/global.global.js.map +1 -1
- package/dist/browser/index.cjs +222 -35
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.d.cts +1 -1
- package/dist/browser/index.d.ts +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/{chunk-23VZAYA3.js → chunk-6MA5TF6R.js} +223 -36
- package/dist/chunk-6MA5TF6R.js.map +1 -0
- package/dist/index.cjs +222 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/{registry-GzopYPCR.d.cts → registry-CPe_lf8-.d.cts} +50 -4
- package/dist/{registry-GzopYPCR.d.ts → registry-CPe_lf8-.d.ts} +50 -4
- package/package.json +9 -6
- package/dist/chunk-23VZAYA3.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -520,6 +520,7 @@ var createDestroy = (state2, _helpers) => () => {
|
|
|
520
520
|
}
|
|
521
521
|
}
|
|
522
522
|
state2.watchedFields.clear();
|
|
523
|
+
state2.groupWatchers.clear();
|
|
523
524
|
state2.subscribers.clear();
|
|
524
525
|
state2.submitHandlers.clear();
|
|
525
526
|
state2.fieldCache.clear();
|
|
@@ -747,9 +748,9 @@ var writeFieldValue = (fields, value) => {
|
|
|
747
748
|
continue;
|
|
748
749
|
}
|
|
749
750
|
if (field instanceof HTMLSelectElement && field.multiple) {
|
|
750
|
-
const
|
|
751
|
+
const selectedValues2 = normalizedArray ?? [normalizedValue];
|
|
751
752
|
for (const option of field.options) {
|
|
752
|
-
option.selected =
|
|
753
|
+
option.selected = selectedValues2.includes(option.value);
|
|
753
754
|
}
|
|
754
755
|
continue;
|
|
755
756
|
}
|
|
@@ -784,8 +785,7 @@ var submitForm = (form2) => {
|
|
|
784
785
|
var createGetValue = (state2, helpers) => (name) => readFieldValue(helpers.getFieldsByName(name));
|
|
785
786
|
|
|
786
787
|
// src/api/observe.ts
|
|
787
|
-
var
|
|
788
|
-
if (state2.isDestroyed) return () => void 0;
|
|
788
|
+
var observeField = (state2, field, callback) => {
|
|
789
789
|
const callbacks = state2.watchedFields.get(field) ?? /* @__PURE__ */ new Set();
|
|
790
790
|
callbacks.add(callback);
|
|
791
791
|
state2.watchedFields.set(field, callbacks);
|
|
@@ -800,6 +800,26 @@ var createObserve = (state2, helpers) => (field, callback) => {
|
|
|
800
800
|
}
|
|
801
801
|
};
|
|
802
802
|
};
|
|
803
|
+
var observeFields = (state2, fields, callback) => {
|
|
804
|
+
const names = Array.from(new Set(fields));
|
|
805
|
+
if (names.length === 0) return () => void 0;
|
|
806
|
+
const entry = { fields: names, callback };
|
|
807
|
+
state2.groupWatchers.add(entry);
|
|
808
|
+
if (state2.element) {
|
|
809
|
+
const values = Object.fromEntries(names.map((name) => [name, state2.api.getValue(name)]));
|
|
810
|
+
callback(values, null, state2.element, state2.api.getState());
|
|
811
|
+
}
|
|
812
|
+
return () => {
|
|
813
|
+
state2.groupWatchers.delete(entry);
|
|
814
|
+
};
|
|
815
|
+
};
|
|
816
|
+
var createObserve = (state2, _helpers) => {
|
|
817
|
+
function observe(field, callback) {
|
|
818
|
+
if (state2.isDestroyed) return () => void 0;
|
|
819
|
+
return Array.isArray(field) ? observeFields(state2, field, callback) : observeField(state2, field, callback);
|
|
820
|
+
}
|
|
821
|
+
return observe;
|
|
822
|
+
};
|
|
803
823
|
|
|
804
824
|
// src/api/on-submit.ts
|
|
805
825
|
var createOnSubmit = (state2, _helpers) => (callback, preventDefault = true) => {
|
|
@@ -871,6 +891,75 @@ var createSetErrors = (state2, helpers) => (fields) => {
|
|
|
871
891
|
return state2.api;
|
|
872
892
|
};
|
|
873
893
|
|
|
894
|
+
// src/api/set-options.ts
|
|
895
|
+
var isGroup = (entry) => typeof entry === "object" && entry !== null && Array.isArray(entry.options);
|
|
896
|
+
var createOption = (entry) => {
|
|
897
|
+
const option = document.createElement("option");
|
|
898
|
+
if (typeof entry === "object") {
|
|
899
|
+
option.value = String(entry.value);
|
|
900
|
+
option.textContent = entry.label ?? String(entry.value);
|
|
901
|
+
option.disabled = Boolean(entry.disabled);
|
|
902
|
+
if (entry.selected) option.defaultSelected = true;
|
|
903
|
+
} else {
|
|
904
|
+
option.value = String(entry);
|
|
905
|
+
option.textContent = String(entry);
|
|
906
|
+
}
|
|
907
|
+
return option;
|
|
908
|
+
};
|
|
909
|
+
var buildNodes = (options) => {
|
|
910
|
+
const nodes = [];
|
|
911
|
+
let hasExplicitSelection = false;
|
|
912
|
+
const track = (option) => {
|
|
913
|
+
if (option.defaultSelected) hasExplicitSelection = true;
|
|
914
|
+
return option;
|
|
915
|
+
};
|
|
916
|
+
for (const entry of options) {
|
|
917
|
+
if (entry === null || entry === void 0) continue;
|
|
918
|
+
if (isGroup(entry)) {
|
|
919
|
+
const group = document.createElement("optgroup");
|
|
920
|
+
group.label = entry.label;
|
|
921
|
+
group.disabled = Boolean(entry.disabled);
|
|
922
|
+
for (const child of entry.options) {
|
|
923
|
+
if (child === null || child === void 0) continue;
|
|
924
|
+
group.appendChild(track(createOption(child)));
|
|
925
|
+
}
|
|
926
|
+
nodes.push(group);
|
|
927
|
+
continue;
|
|
928
|
+
}
|
|
929
|
+
nodes.push(track(createOption(entry)));
|
|
930
|
+
}
|
|
931
|
+
return { nodes, hasExplicitSelection };
|
|
932
|
+
};
|
|
933
|
+
var selectedValues = (select) => Array.from(select.selectedOptions, (option) => option.value);
|
|
934
|
+
var restoreSelection = (select, previous) => {
|
|
935
|
+
if (previous.length === 0) return;
|
|
936
|
+
const options = Array.from(select.options);
|
|
937
|
+
if (select.multiple) {
|
|
938
|
+
for (const option of options) option.selected = previous.includes(option.value);
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
const match = options.find((option) => option.value === previous[0]);
|
|
942
|
+
if (match) match.selected = true;
|
|
943
|
+
};
|
|
944
|
+
var sameValues = (left, right) => left.length === right.length && left.every((value, index) => value === right[index]);
|
|
945
|
+
var createSetOptions = (state2, helpers) => (name, options, config = {}) => {
|
|
946
|
+
if (!state2.element || state2.isDestroyed) return state2.api;
|
|
947
|
+
const selects = helpers.getFieldsByName(name).filter((field) => field instanceof HTMLSelectElement);
|
|
948
|
+
if (selects.length === 0) return state2.api;
|
|
949
|
+
const keepValue = config.keepValue ?? true;
|
|
950
|
+
const changed = [];
|
|
951
|
+
for (const select of selects) {
|
|
952
|
+
const previous = selectedValues(select);
|
|
953
|
+
const { nodes, hasExplicitSelection } = buildNodes(options);
|
|
954
|
+
select.replaceChildren(...nodes);
|
|
955
|
+
if (keepValue && !hasExplicitSelection) restoreSelection(select, previous);
|
|
956
|
+
if (!sameValues(previous, selectedValues(select))) changed.push(select);
|
|
957
|
+
}
|
|
958
|
+
helpers.commitOwnMutations(selects);
|
|
959
|
+
changed[0]?.dispatchEvent(new Event("input", { bubbles: true }));
|
|
960
|
+
return state2.api;
|
|
961
|
+
};
|
|
962
|
+
|
|
874
963
|
// src/api/set-value.ts
|
|
875
964
|
var createSetValue = (state2, helpers) => (name, value) => {
|
|
876
965
|
if (state2.isDestroyed) return state2.api;
|
|
@@ -894,28 +983,46 @@ var createSubscribe = (state2, _helpers) => (listener) => {
|
|
|
894
983
|
};
|
|
895
984
|
|
|
896
985
|
// src/api/unwatch.ts
|
|
897
|
-
var
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
986
|
+
var sameFields = (left, right) => left.length === right.size && left.every((name) => right.has(name));
|
|
987
|
+
var createUnwatch = (state2, _helpers) => {
|
|
988
|
+
function unwatch(field, callback) {
|
|
989
|
+
if (field === void 0 || field === "") {
|
|
990
|
+
state2.watchedFields.clear();
|
|
991
|
+
state2.groupWatchers.clear();
|
|
992
|
+
return state2.api;
|
|
993
|
+
}
|
|
994
|
+
if (Array.isArray(field)) {
|
|
995
|
+
const names = new Set(field);
|
|
996
|
+
for (const entry of Array.from(state2.groupWatchers)) {
|
|
997
|
+
if (!sameFields(entry.fields, names)) continue;
|
|
998
|
+
if (callback && entry.callback !== callback) continue;
|
|
999
|
+
state2.groupWatchers.delete(entry);
|
|
1000
|
+
}
|
|
1001
|
+
return state2.api;
|
|
1002
|
+
}
|
|
1003
|
+
if (!callback) {
|
|
1004
|
+
state2.watchedFields.delete(field);
|
|
1005
|
+
return state2.api;
|
|
1006
|
+
}
|
|
1007
|
+
const callbacks = state2.watchedFields.get(field);
|
|
1008
|
+
callbacks?.delete(callback);
|
|
1009
|
+
if (callbacks && callbacks.size === 0) {
|
|
1010
|
+
state2.watchedFields.delete(field);
|
|
1011
|
+
}
|
|
904
1012
|
return state2.api;
|
|
905
1013
|
}
|
|
906
|
-
|
|
907
|
-
callbacks?.delete(callback);
|
|
908
|
-
if (callbacks && callbacks.size === 0) {
|
|
909
|
-
state2.watchedFields.delete(field);
|
|
910
|
-
}
|
|
911
|
-
return state2.api;
|
|
1014
|
+
return unwatch;
|
|
912
1015
|
};
|
|
913
1016
|
|
|
914
1017
|
// src/api/watch.ts
|
|
915
|
-
var createWatch = (state2, helpers) =>
|
|
1018
|
+
var createWatch = (state2, helpers) => {
|
|
916
1019
|
const observe = createObserve(state2, helpers);
|
|
917
|
-
|
|
918
|
-
|
|
1020
|
+
function watch(field, callback) {
|
|
1021
|
+
if (Array.isArray(field)) observe(field, callback);
|
|
1022
|
+
else observe(field, callback);
|
|
1023
|
+
return state2.api;
|
|
1024
|
+
}
|
|
1025
|
+
return watch;
|
|
919
1026
|
};
|
|
920
1027
|
|
|
921
1028
|
// src/core/validation.ts
|
|
@@ -1083,6 +1190,7 @@ var createFormController = (target, options = {}) => {
|
|
|
1083
1190
|
attributes,
|
|
1084
1191
|
validators: normalizedOptions.validators ?? {},
|
|
1085
1192
|
watchedFields: /* @__PURE__ */ new Map(),
|
|
1193
|
+
groupWatchers: /* @__PURE__ */ new Set(),
|
|
1086
1194
|
subscribers: /* @__PURE__ */ new Set(),
|
|
1087
1195
|
submitHandlers: /* @__PURE__ */ new Set(),
|
|
1088
1196
|
fieldCache: /* @__PURE__ */ new Map(),
|
|
@@ -1253,7 +1361,7 @@ var createFormController = (target, options = {}) => {
|
|
|
1253
1361
|
}
|
|
1254
1362
|
return affected;
|
|
1255
1363
|
};
|
|
1256
|
-
const
|
|
1364
|
+
const emitSingleWatchers = (name) => {
|
|
1257
1365
|
if (!state2.element || !state2.api) return;
|
|
1258
1366
|
const callbacks = state2.watchedFields.get(name);
|
|
1259
1367
|
if (!callbacks || callbacks.size === 0) return;
|
|
@@ -1262,6 +1370,23 @@ var createFormController = (target, options = {}) => {
|
|
|
1262
1370
|
const snapshot = state2.api.getState();
|
|
1263
1371
|
callbacks.forEach((callback) => callback(value, fieldElement, state2.element, snapshot));
|
|
1264
1372
|
};
|
|
1373
|
+
const emitGroupWatchers = (names) => {
|
|
1374
|
+
if (!state2.element || !state2.api || state2.groupWatchers.size === 0) return;
|
|
1375
|
+
let snapshot;
|
|
1376
|
+
for (const entry of Array.from(state2.groupWatchers)) {
|
|
1377
|
+
const changed = names ? names.find((name) => entry.fields.includes(name)) : null;
|
|
1378
|
+
if (changed === void 0) continue;
|
|
1379
|
+
snapshot ?? (snapshot = state2.api.getState());
|
|
1380
|
+
const values = Object.fromEntries(
|
|
1381
|
+
entry.fields.map((field) => [field, state2.api.getValue(field)])
|
|
1382
|
+
);
|
|
1383
|
+
entry.callback(values, changed, state2.element, snapshot);
|
|
1384
|
+
}
|
|
1385
|
+
};
|
|
1386
|
+
const emitFieldWatchers = (name) => {
|
|
1387
|
+
emitSingleWatchers(name);
|
|
1388
|
+
emitGroupWatchers([name]);
|
|
1389
|
+
};
|
|
1265
1390
|
const runAutoSubmit = () => {
|
|
1266
1391
|
state2.autoSubmitTimer = null;
|
|
1267
1392
|
if (!state2.element || state2.isDestroyed || !state2.autoSubmitEnabled) return;
|
|
@@ -1282,8 +1407,20 @@ var createFormController = (target, options = {}) => {
|
|
|
1282
1407
|
}
|
|
1283
1408
|
runAutoSubmit();
|
|
1284
1409
|
};
|
|
1410
|
+
const selectSnapshots = /* @__PURE__ */ new WeakMap();
|
|
1411
|
+
const readSelectSnapshot = (select) => Array.from(select.selectedOptions, (option) => option.value).join("\0");
|
|
1412
|
+
const snapshotSelect = (select) => {
|
|
1413
|
+
selectSnapshots.set(select, readSelectSnapshot(select));
|
|
1414
|
+
};
|
|
1415
|
+
const snapshotAllSelects = () => {
|
|
1416
|
+
if (!state2.element) return;
|
|
1417
|
+
for (const field of getNamedFields(state2.element)) {
|
|
1418
|
+
if (field instanceof HTMLSelectElement) snapshotSelect(field);
|
|
1419
|
+
}
|
|
1420
|
+
};
|
|
1285
1421
|
const emitAllFieldWatchers = () => {
|
|
1286
|
-
for (const name of Array.from(state2.watchedFields.keys()))
|
|
1422
|
+
for (const name of Array.from(state2.watchedFields.keys())) emitSingleWatchers(name);
|
|
1423
|
+
emitGroupWatchers(null);
|
|
1287
1424
|
};
|
|
1288
1425
|
const applyReset = () => {
|
|
1289
1426
|
if (!state2.element || state2.isDestroyed) return;
|
|
@@ -1295,6 +1432,7 @@ var createFormController = (target, options = {}) => {
|
|
|
1295
1432
|
state2.validationElementErrors.clear();
|
|
1296
1433
|
clearAttributes(state2.element, [attributes.error, attributes.filled, "aria-invalid"]);
|
|
1297
1434
|
syncVisualState();
|
|
1435
|
+
snapshotAllSelects();
|
|
1298
1436
|
emitAllFieldWatchers();
|
|
1299
1437
|
notifySubscribers();
|
|
1300
1438
|
};
|
|
@@ -1309,7 +1447,8 @@ var createFormController = (target, options = {}) => {
|
|
|
1309
1447
|
validateNames,
|
|
1310
1448
|
emitFieldWatchers,
|
|
1311
1449
|
scheduleAutoSubmit,
|
|
1312
|
-
applyReset
|
|
1450
|
+
applyReset,
|
|
1451
|
+
commitOwnMutations: (selects) => commitOwnMutations(selects)
|
|
1313
1452
|
};
|
|
1314
1453
|
const handleDelegatedEvent = (event) => {
|
|
1315
1454
|
const target2 = event.target;
|
|
@@ -1317,6 +1456,7 @@ var createFormController = (target, options = {}) => {
|
|
|
1317
1456
|
const name = target2.name;
|
|
1318
1457
|
if (!name) return;
|
|
1319
1458
|
clearFieldCache();
|
|
1459
|
+
if (target2 instanceof HTMLSelectElement) snapshotSelect(target2);
|
|
1320
1460
|
const canonical = resolveCanonicalForName(state2, name) ?? name;
|
|
1321
1461
|
const displayName = resolveDisplayNameForName(state2, name);
|
|
1322
1462
|
if (normalizedOptions.clearManualErrorsOnChange) {
|
|
@@ -1327,8 +1467,9 @@ var createFormController = (target, options = {}) => {
|
|
|
1327
1467
|
if (state2.isValidated && affectedValidationNames.some((field) => state2.validators[field] !== void 0)) {
|
|
1328
1468
|
validateNames(affectedValidationNames);
|
|
1329
1469
|
}
|
|
1330
|
-
|
|
1331
|
-
if (canonical !== name)
|
|
1470
|
+
emitSingleWatchers(canonical);
|
|
1471
|
+
if (canonical !== name) emitSingleWatchers(name);
|
|
1472
|
+
emitGroupWatchers(canonical !== name ? [canonical, name] : [canonical]);
|
|
1332
1473
|
notifySubscribers();
|
|
1333
1474
|
scheduleAutoSubmit();
|
|
1334
1475
|
};
|
|
@@ -1409,18 +1550,62 @@ var createFormController = (target, options = {}) => {
|
|
|
1409
1550
|
const cancel = () => clearTimeout(timer);
|
|
1410
1551
|
state2.cleanups.add(cancel);
|
|
1411
1552
|
};
|
|
1553
|
+
const touchesFields = (node) => node instanceof Element && (isFieldElement(node) || node.querySelector("input, select, textarea") !== null);
|
|
1554
|
+
const isStructural = (record) => record.type === "attributes" || Array.from(record.addedNodes).some(touchesFields) || Array.from(record.removedNodes).some(touchesFields);
|
|
1555
|
+
const isOptionNode = (node) => node instanceof HTMLOptionElement || node instanceof HTMLOptGroupElement;
|
|
1556
|
+
const optionListOwner = (record) => {
|
|
1557
|
+
if (record.type !== "childList") return null;
|
|
1558
|
+
const touchesOptions = Array.from(record.addedNodes).some(isOptionNode) || Array.from(record.removedNodes).some(isOptionNode);
|
|
1559
|
+
if (!touchesOptions) return null;
|
|
1560
|
+
const target2 = record.target;
|
|
1561
|
+
if (target2 instanceof HTMLSelectElement) return target2;
|
|
1562
|
+
if (target2 instanceof HTMLOptGroupElement && target2.parentElement instanceof HTMLSelectElement) {
|
|
1563
|
+
return target2.parentElement;
|
|
1564
|
+
}
|
|
1565
|
+
return null;
|
|
1566
|
+
};
|
|
1567
|
+
const handleMutations = (records) => {
|
|
1568
|
+
if (state2.isDestroyed) return;
|
|
1569
|
+
const structural = records.some(isStructural);
|
|
1570
|
+
const changedNames = /* @__PURE__ */ new Set();
|
|
1571
|
+
for (const record of records) {
|
|
1572
|
+
const select = optionListOwner(record);
|
|
1573
|
+
if (!select || !select.name) continue;
|
|
1574
|
+
const next = readSelectSnapshot(select);
|
|
1575
|
+
if (selectSnapshots.get(select) !== next) changedNames.add(select.name);
|
|
1576
|
+
selectSnapshots.set(select, next);
|
|
1577
|
+
}
|
|
1578
|
+
if (!structural && changedNames.size === 0) return;
|
|
1579
|
+
clearFieldCache();
|
|
1580
|
+
if (structural) {
|
|
1581
|
+
snapshotAllSelects();
|
|
1582
|
+
if (state2.isValidated) validateNames();
|
|
1583
|
+
else syncVisualState();
|
|
1584
|
+
} else {
|
|
1585
|
+
const affected = /* @__PURE__ */ new Set();
|
|
1586
|
+
for (const name of changedNames) {
|
|
1587
|
+
for (const field of getAffectedValidationNames(name)) affected.add(field);
|
|
1588
|
+
}
|
|
1589
|
+
const names = Array.from(affected);
|
|
1590
|
+
syncVisualState(Array.from(changedNames));
|
|
1591
|
+
if (state2.isValidated && names.some((field) => state2.validators[field] !== void 0)) {
|
|
1592
|
+
validateNames(names);
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
for (const name of changedNames) emitFieldWatchers(name);
|
|
1596
|
+
notifySubscribers();
|
|
1597
|
+
};
|
|
1598
|
+
const commitOwnMutations = (selects) => {
|
|
1599
|
+
selects.forEach(snapshotSelect);
|
|
1600
|
+
const pending = state2.mutationObserver?.takeRecords() ?? [];
|
|
1601
|
+
const foreign = pending.filter(
|
|
1602
|
+
(record) => !selects.some((select) => select.contains(record.target))
|
|
1603
|
+
);
|
|
1604
|
+
if (foreign.length > 0) handleMutations(foreign);
|
|
1605
|
+
};
|
|
1412
1606
|
const startMutationObserver = () => {
|
|
1413
1607
|
if (!state2.element || typeof MutationObserver === "undefined") return;
|
|
1414
|
-
|
|
1415
|
-
const isRelevant = (record) => record.type === "attributes" || Array.from(record.addedNodes).some(touchesFields) || Array.from(record.removedNodes).some(touchesFields);
|
|
1416
|
-
state2.mutationObserver = new MutationObserver((records) => {
|
|
1417
|
-
if (state2.isDestroyed || !records.some(isRelevant)) return;
|
|
1418
|
-
clearFieldCache();
|
|
1419
|
-
if (state2.isValidated) {
|
|
1420
|
-
validateNames();
|
|
1421
|
-
} else syncVisualState();
|
|
1422
|
-
notifySubscribers();
|
|
1423
|
-
});
|
|
1608
|
+
state2.mutationObserver = new MutationObserver(handleMutations);
|
|
1424
1609
|
state2.mutationObserver.observe(state2.element, {
|
|
1425
1610
|
childList: true,
|
|
1426
1611
|
subtree: true,
|
|
@@ -1449,6 +1634,7 @@ var createFormController = (target, options = {}) => {
|
|
|
1449
1634
|
setErrors: createSetErrors(state2, helpers),
|
|
1450
1635
|
clearErrors: createClearErrors(state2, helpers),
|
|
1451
1636
|
setValue: createSetValue(state2, helpers),
|
|
1637
|
+
setOptions: createSetOptions(state2, helpers),
|
|
1452
1638
|
getValue: createGetValue(state2, helpers),
|
|
1453
1639
|
getField: createGetField(state2, helpers),
|
|
1454
1640
|
validate: createValidate(state2, helpers),
|
|
@@ -1468,6 +1654,7 @@ var createFormController = (target, options = {}) => {
|
|
|
1468
1654
|
addListener2(document, "input", handleExternalDelegatedEvent);
|
|
1469
1655
|
addListener2(state2.element, "submit", handleSubmitEvent);
|
|
1470
1656
|
addListener2(state2.element, "reset", handleResetEvent);
|
|
1657
|
+
snapshotAllSelects();
|
|
1471
1658
|
startMutationObserver();
|
|
1472
1659
|
}
|
|
1473
1660
|
if (normalizedOptions.autoSubmit) {
|