jedison 1.5.0 → 1.6.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 +20 -0
- package/dist/cjs/jedison.cjs +1 -1
- package/dist/cjs/jedison.cjs.map +1 -1
- package/dist/esm/jedison.js +818 -162
- package/dist/esm/jedison.js.map +1 -1
- package/dist/umd/jedison.umd.js +1 -1
- package/dist/umd/jedison.umd.js.map +1 -1
- package/package.json +7 -2
package/dist/esm/jedison.js
CHANGED
|
@@ -32,7 +32,7 @@ function replaceAll(str, find, replace) {
|
|
|
32
32
|
return str.replace(new RegExp(escapeRegExp(find), "g"), replace);
|
|
33
33
|
}
|
|
34
34
|
function pathToAttribute(path) {
|
|
35
|
-
return replaceAll(replaceAll(path, "#", "root"), "/", "-");
|
|
35
|
+
return replaceAll(replaceAll(path, "#", "root"), "/", "-").replace(/[^a-zA-Z0-9_-]/g, "");
|
|
36
36
|
}
|
|
37
37
|
function hasOwn(obj, prop) {
|
|
38
38
|
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|
@@ -220,6 +220,19 @@ function removeDuplicatesFromArray(arr) {
|
|
|
220
220
|
}
|
|
221
221
|
return uniqueObjects;
|
|
222
222
|
}
|
|
223
|
+
function resolveInstancePath(currentPath, sourcePath) {
|
|
224
|
+
if (sourcePath.startsWith("#")) return sourcePath;
|
|
225
|
+
const parts = currentPath.split("/");
|
|
226
|
+
parts.pop();
|
|
227
|
+
for (const part of sourcePath.split("/")) {
|
|
228
|
+
if (part === "..") {
|
|
229
|
+
if (parts.length > 1) parts.pop();
|
|
230
|
+
} else if (part !== "." && part !== "") {
|
|
231
|
+
parts.push(part);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return parts.join("/");
|
|
235
|
+
}
|
|
223
236
|
function generateRandomID(maxLength2) {
|
|
224
237
|
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
225
238
|
let randomID = "";
|
|
@@ -510,14 +523,33 @@ function allOf(context) {
|
|
|
510
523
|
let errors = [];
|
|
511
524
|
const allOf2 = getSchemaAllOf(context.schema);
|
|
512
525
|
if (isSet(allOf2)) {
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
526
|
+
const enableSubErrors = getSchemaXOption(context.schema, "subErrors") ?? context.validator.subErrors;
|
|
527
|
+
if (enableSubErrors) {
|
|
528
|
+
const schemaResults = [];
|
|
529
|
+
allOf2.forEach((schema, index2) => {
|
|
530
|
+
const subSchemaErrors = context.validator.getErrors(context.value, schema, context.key, context.path);
|
|
531
|
+
if (subSchemaErrors.length > 0) {
|
|
532
|
+
schemaResults.push({ schemaIndex: index2, errors: subSchemaErrors });
|
|
533
|
+
}
|
|
517
534
|
});
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
535
|
+
if (schemaResults.length > 0) {
|
|
536
|
+
errors.push({
|
|
537
|
+
type: "error",
|
|
538
|
+
path: context.path,
|
|
539
|
+
constraint: "allOf",
|
|
540
|
+
subErrors: schemaResults
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
} else {
|
|
544
|
+
allOf2.forEach((schema) => {
|
|
545
|
+
const subSchemaErrors = context.validator.getErrors(context.value, schema, context.key, context.path);
|
|
546
|
+
subSchemaErrors.forEach((error) => {
|
|
547
|
+
error.path = context.path;
|
|
548
|
+
});
|
|
549
|
+
errors.push(...subSchemaErrors);
|
|
550
|
+
});
|
|
551
|
+
errors = removeDuplicatesFromArray(errors);
|
|
552
|
+
}
|
|
521
553
|
}
|
|
522
554
|
return errors;
|
|
523
555
|
}
|
|
@@ -546,23 +578,46 @@ function anyOf(context) {
|
|
|
546
578
|
const errors = [];
|
|
547
579
|
const anyOf2 = getSchemaAnyOf(context.schema);
|
|
548
580
|
if (isSet(anyOf2)) {
|
|
581
|
+
const enableSubErrors = getSchemaXOption(context.schema, "subErrors") ?? context.validator.subErrors;
|
|
549
582
|
let valid = false;
|
|
550
|
-
|
|
551
|
-
const
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
errors.push({
|
|
559
|
-
type: "error",
|
|
560
|
-
path: context.path,
|
|
561
|
-
constraint: "anyOf",
|
|
562
|
-
messages: [
|
|
563
|
-
context.translator.translate("errorAnyOf")
|
|
564
|
-
]
|
|
583
|
+
if (enableSubErrors) {
|
|
584
|
+
const schemaResults = [];
|
|
585
|
+
anyOf2.forEach((schema, index2) => {
|
|
586
|
+
const anyOfErrors = context.validator.getErrors(context.value, schema, context.key, context.path);
|
|
587
|
+
if (anyOfErrors.length === 0) {
|
|
588
|
+
valid = true;
|
|
589
|
+
}
|
|
590
|
+
schemaResults.push({ schemaIndex: index2, errors: anyOfErrors });
|
|
565
591
|
});
|
|
592
|
+
if (!valid) {
|
|
593
|
+
errors.push({
|
|
594
|
+
type: "error",
|
|
595
|
+
path: context.path,
|
|
596
|
+
constraint: "anyOf",
|
|
597
|
+
messages: [
|
|
598
|
+
context.translator.translate("errorAnyOf")
|
|
599
|
+
],
|
|
600
|
+
subErrors: schemaResults.filter((r) => r.errors.length > 0)
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
} else {
|
|
604
|
+
for (const schema of anyOf2) {
|
|
605
|
+
const anyOfErrors = context.validator.getErrors(context.value, schema, context.key, context.path);
|
|
606
|
+
if (anyOfErrors.length === 0) {
|
|
607
|
+
valid = true;
|
|
608
|
+
break;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
if (!valid) {
|
|
612
|
+
errors.push({
|
|
613
|
+
type: "error",
|
|
614
|
+
path: context.path,
|
|
615
|
+
constraint: "anyOf",
|
|
616
|
+
messages: [
|
|
617
|
+
context.translator.translate("errorAnyOf")
|
|
618
|
+
]
|
|
619
|
+
});
|
|
620
|
+
}
|
|
566
621
|
}
|
|
567
622
|
}
|
|
568
623
|
return errors;
|
|
@@ -630,10 +685,8 @@ function exclusiveMinimum(context) {
|
|
|
630
685
|
function format(context) {
|
|
631
686
|
const errors = [];
|
|
632
687
|
const format2 = getSchemaFormat(context.schema);
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
assertFormat = context.schema.options.assertFormat;
|
|
636
|
-
}
|
|
688
|
+
const xAssertFormat = getSchemaXOption(context.schema, "assertFormat");
|
|
689
|
+
const assertFormat = xAssertFormat !== void 0 ? xAssertFormat : context.validator.assertFormat;
|
|
637
690
|
if (isSet(format2) && isString(context.value) && assertFormat) {
|
|
638
691
|
let regexp;
|
|
639
692
|
if (format2 === "email") {
|
|
@@ -673,18 +726,23 @@ function items(context) {
|
|
|
673
726
|
messages: [context.translator.translate("errorItems")]
|
|
674
727
|
});
|
|
675
728
|
} else if (isObject(items2)) {
|
|
729
|
+
const enableSubErrors = getSchemaXOption(context.schema, "subErrors") ?? context.validator.subErrors;
|
|
676
730
|
context.value.slice(prefixItemsSchemasCount).forEach((itemValue, i) => {
|
|
677
731
|
const index2 = prefixItemsSchemasCount + i;
|
|
678
732
|
const tmpErrors = context.validator.getErrors(itemValue, items2, index2, context.path + "/" + index2);
|
|
679
733
|
if (tmpErrors.length > 0) {
|
|
680
|
-
|
|
734
|
+
const error = {
|
|
681
735
|
type: "error",
|
|
682
736
|
path: context.path,
|
|
683
737
|
constraint: "items",
|
|
684
738
|
messages: [
|
|
685
739
|
compileTemplate(context.translator.translate("errorItems"), { index: index2 })
|
|
686
740
|
]
|
|
687
|
-
}
|
|
741
|
+
};
|
|
742
|
+
if (enableSubErrors) {
|
|
743
|
+
error.subErrors = tmpErrors;
|
|
744
|
+
}
|
|
745
|
+
errors.push(error);
|
|
688
746
|
}
|
|
689
747
|
});
|
|
690
748
|
}
|
|
@@ -862,23 +920,64 @@ function oneOf(context) {
|
|
|
862
920
|
const oneOf2 = getSchemaOneOf(context.schema);
|
|
863
921
|
if (isSet(oneOf2)) {
|
|
864
922
|
let counter = 0;
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
923
|
+
const enableSubErrors = getSchemaXOption(context.schema, "subErrors") ?? context.validator.subErrors;
|
|
924
|
+
if (enableSubErrors) {
|
|
925
|
+
const schemaResults = [];
|
|
926
|
+
oneOf2.forEach((schema, index2) => {
|
|
927
|
+
const oneOfErrors = context.validator.getErrors(context.value, schema, context.key, context.path);
|
|
928
|
+
if (oneOfErrors.length === 0) {
|
|
929
|
+
counter++;
|
|
930
|
+
schemaResults.push({ schemaIndex: index2, matched: true, errors: [] });
|
|
931
|
+
} else {
|
|
932
|
+
schemaResults.push({ schemaIndex: index2, matched: false, errors: oneOfErrors });
|
|
933
|
+
}
|
|
934
|
+
});
|
|
935
|
+
if (counter !== 1) {
|
|
936
|
+
const error = {
|
|
937
|
+
type: "error",
|
|
938
|
+
path: context.path,
|
|
939
|
+
constraint: "oneOf",
|
|
940
|
+
messages: [
|
|
941
|
+
compileTemplate(context.translator.translate("errorOneOf"), {
|
|
942
|
+
counter
|
|
943
|
+
})
|
|
944
|
+
]
|
|
945
|
+
};
|
|
946
|
+
if (counter === 0) {
|
|
947
|
+
error.subErrors = schemaResults.filter((r) => !r.matched).map((r) => ({
|
|
948
|
+
schemaIndex: r.schemaIndex,
|
|
949
|
+
errors: r.errors
|
|
950
|
+
}));
|
|
951
|
+
} else {
|
|
952
|
+
error.matchingSchemas = schemaResults.filter((r) => r.matched).map((r) => r.schemaIndex);
|
|
953
|
+
}
|
|
954
|
+
errors.push(error);
|
|
869
955
|
}
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
counter
|
|
879
|
-
})
|
|
880
|
-
]
|
|
956
|
+
} else {
|
|
957
|
+
const matchingSchemas = [];
|
|
958
|
+
oneOf2.forEach((schema, index2) => {
|
|
959
|
+
const oneOfErrors = context.validator.getErrors(context.value, schema, context.key, context.path);
|
|
960
|
+
if (oneOfErrors.length === 0) {
|
|
961
|
+
counter++;
|
|
962
|
+
matchingSchemas.push(index2);
|
|
963
|
+
}
|
|
881
964
|
});
|
|
965
|
+
if (counter !== 1) {
|
|
966
|
+
const error = {
|
|
967
|
+
type: "error",
|
|
968
|
+
path: context.path,
|
|
969
|
+
constraint: "oneOf",
|
|
970
|
+
messages: [
|
|
971
|
+
compileTemplate(context.translator.translate("errorOneOf"), {
|
|
972
|
+
counter
|
|
973
|
+
})
|
|
974
|
+
]
|
|
975
|
+
};
|
|
976
|
+
if (counter > 0) {
|
|
977
|
+
error.matchingSchemas = matchingSchemas;
|
|
978
|
+
}
|
|
979
|
+
errors.push(error);
|
|
980
|
+
}
|
|
882
981
|
}
|
|
883
982
|
}
|
|
884
983
|
return errors;
|
|
@@ -931,6 +1030,8 @@ function patternProperties(context) {
|
|
|
931
1030
|
function properties(context) {
|
|
932
1031
|
const schemaProperties = getSchemaProperties(context.schema);
|
|
933
1032
|
const invalidProperties = [];
|
|
1033
|
+
const enableSubErrors = getSchemaXOption(context.schema, "subErrors") ?? context.validator.subErrors;
|
|
1034
|
+
const propertySubErrors = [];
|
|
934
1035
|
if (isObject(context.value) && isSet(schemaProperties)) {
|
|
935
1036
|
Object.keys(schemaProperties).forEach((propertyName) => {
|
|
936
1037
|
if (hasOwn(context.value, propertyName)) {
|
|
@@ -943,19 +1044,26 @@ function properties(context) {
|
|
|
943
1044
|
);
|
|
944
1045
|
if (propertyErrors.length > 0) {
|
|
945
1046
|
invalidProperties.push(propertyName);
|
|
1047
|
+
if (enableSubErrors) {
|
|
1048
|
+
propertySubErrors.push({ property: propertyName, errors: propertyErrors });
|
|
1049
|
+
}
|
|
946
1050
|
}
|
|
947
1051
|
}
|
|
948
1052
|
});
|
|
949
1053
|
}
|
|
950
1054
|
if (invalidProperties.length > 0) {
|
|
951
|
-
|
|
1055
|
+
const error = {
|
|
952
1056
|
type: "error",
|
|
953
1057
|
path: context.path,
|
|
954
1058
|
constraint: "properties",
|
|
955
1059
|
messages: [
|
|
956
1060
|
compileTemplate(context.translator.translate("errorProperties"), { properties: invalidProperties.join(", ") })
|
|
957
1061
|
]
|
|
958
|
-
}
|
|
1062
|
+
};
|
|
1063
|
+
if (enableSubErrors) {
|
|
1064
|
+
error.subErrors = propertySubErrors;
|
|
1065
|
+
}
|
|
1066
|
+
return [error];
|
|
959
1067
|
}
|
|
960
1068
|
return [];
|
|
961
1069
|
}
|
|
@@ -1232,9 +1340,11 @@ function dependentRequired(context) {
|
|
|
1232
1340
|
Object.keys(dependentRequired2).forEach((key) => {
|
|
1233
1341
|
if (isSet(context.value[key])) {
|
|
1234
1342
|
const requiredProperties = dependentRequired2[key];
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1343
|
+
if (isArray(requiredProperties)) {
|
|
1344
|
+
missingProperties = requiredProperties.filter((property) => {
|
|
1345
|
+
return !hasOwn(context.value, property);
|
|
1346
|
+
});
|
|
1347
|
+
}
|
|
1238
1348
|
}
|
|
1239
1349
|
});
|
|
1240
1350
|
const invalid = missingProperties.length > 0;
|
|
@@ -1293,12 +1403,13 @@ function prefixItems(context) {
|
|
|
1293
1403
|
const errors = [];
|
|
1294
1404
|
const prefixItems2 = getSchemaPrefixItems(context.schema);
|
|
1295
1405
|
if (isArray(context.value) && isSet(prefixItems2)) {
|
|
1406
|
+
const enableSubErrors = getSchemaXOption(context.schema, "subErrors") ?? context.validator.subErrors;
|
|
1296
1407
|
prefixItems2.forEach((itemSchema, index2) => {
|
|
1297
1408
|
const itemValue = context.value[index2];
|
|
1298
1409
|
if (isSet(itemValue)) {
|
|
1299
1410
|
const tmpErrors = context.validator.getErrors(itemValue, itemSchema, index2, context.path + "/" + index2);
|
|
1300
1411
|
if (tmpErrors.length > 0) {
|
|
1301
|
-
|
|
1412
|
+
const error = {
|
|
1302
1413
|
type: "error",
|
|
1303
1414
|
path: context.path,
|
|
1304
1415
|
constraint: "prefixItems",
|
|
@@ -1307,7 +1418,11 @@ function prefixItems(context) {
|
|
|
1307
1418
|
index: index2
|
|
1308
1419
|
})
|
|
1309
1420
|
]
|
|
1310
|
-
}
|
|
1421
|
+
};
|
|
1422
|
+
if (enableSubErrors) {
|
|
1423
|
+
error.subErrors = tmpErrors;
|
|
1424
|
+
}
|
|
1425
|
+
errors.push(error);
|
|
1311
1426
|
}
|
|
1312
1427
|
}
|
|
1313
1428
|
});
|
|
@@ -1538,6 +1653,7 @@ class Validator {
|
|
|
1538
1653
|
this.constraints = config.constraints ?? {};
|
|
1539
1654
|
this.assertFormat = config.assertFormat ? config.assertFormat : false;
|
|
1540
1655
|
this.translator = config.translator ? config.translator : false;
|
|
1656
|
+
this.subErrors = config.subErrors ?? false;
|
|
1541
1657
|
this.draft = draft202012;
|
|
1542
1658
|
this.jsonSchemaDrafts = {
|
|
1543
1659
|
"http://json-schema.org/draft-04/schema#": draft04,
|
|
@@ -2123,11 +2239,13 @@ class Editor {
|
|
|
2123
2239
|
});
|
|
2124
2240
|
this.control.messages.innerHTML = "";
|
|
2125
2241
|
this.showingValidationErrors = false;
|
|
2242
|
+
this.setAriaInvalid(false);
|
|
2126
2243
|
const neverShowErrors = this.instance.jedison.options.showErrors === "never" || getSchemaXOption(this.instance.schema, "showErrors") === "never";
|
|
2127
2244
|
if (neverShowErrors && !force || errors.length === 0) {
|
|
2128
2245
|
return;
|
|
2129
2246
|
}
|
|
2130
2247
|
const muteValidationMessages = getSchemaXOption(this.instance.schema, "muteValidationMessages") ?? this.instance.jedison.options.muteValidationMessages ?? [];
|
|
2248
|
+
let hasErrors = false;
|
|
2131
2249
|
errors.forEach((error) => {
|
|
2132
2250
|
if (muteValidationMessages.includes(error.constraint)) {
|
|
2133
2251
|
return;
|
|
@@ -2135,6 +2253,7 @@ class Editor {
|
|
|
2135
2253
|
error.messages.forEach((message) => {
|
|
2136
2254
|
let invalidFeedback;
|
|
2137
2255
|
if (error.type === "error") {
|
|
2256
|
+
hasErrors = true;
|
|
2138
2257
|
invalidFeedback = this.getErrorFeedback({
|
|
2139
2258
|
message
|
|
2140
2259
|
});
|
|
@@ -2146,8 +2265,20 @@ class Editor {
|
|
|
2146
2265
|
this.control.messages.appendChild(invalidFeedback);
|
|
2147
2266
|
});
|
|
2148
2267
|
});
|
|
2268
|
+
if (hasErrors) {
|
|
2269
|
+
this.setAriaInvalid(true);
|
|
2270
|
+
}
|
|
2149
2271
|
this.showingValidationErrors = true;
|
|
2150
2272
|
}
|
|
2273
|
+
setAriaInvalid(invalid) {
|
|
2274
|
+
if (this.control.input) {
|
|
2275
|
+
if (invalid) {
|
|
2276
|
+
this.control.input.setAttribute("aria-invalid", "true");
|
|
2277
|
+
} else {
|
|
2278
|
+
this.control.input.removeAttribute("aria-invalid");
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2281
|
+
}
|
|
2151
2282
|
/**
|
|
2152
2283
|
* Get an error message container
|
|
2153
2284
|
*/
|
|
@@ -2234,6 +2365,8 @@ class Editor {
|
|
|
2234
2365
|
}
|
|
2235
2366
|
return schemaInfo;
|
|
2236
2367
|
}
|
|
2368
|
+
refreshLegendWarning() {
|
|
2369
|
+
}
|
|
2237
2370
|
/**
|
|
2238
2371
|
* Updates control UI when its state changes
|
|
2239
2372
|
*/
|
|
@@ -2635,6 +2768,21 @@ class InstanceMultiple extends Instance {
|
|
|
2635
2768
|
* Returns the index of the instance that has less validation errors
|
|
2636
2769
|
*/
|
|
2637
2770
|
getFittestIndex(value) {
|
|
2771
|
+
const discriminator = getSchemaXOption(this.schema, "discriminator");
|
|
2772
|
+
if (isSet(discriminator) && isObject(value)) {
|
|
2773
|
+
const propName = isString(discriminator) ? discriminator : discriminator.propertyName;
|
|
2774
|
+
const discriminatorValue = value[propName];
|
|
2775
|
+
if (isSet(discriminatorValue)) {
|
|
2776
|
+
for (let index2 = 0; index2 < this.schemas.length; index2++) {
|
|
2777
|
+
const schema = this.schemas[index2];
|
|
2778
|
+
const propSchema = schema.properties && schema.properties[propName];
|
|
2779
|
+
if (propSchema) {
|
|
2780
|
+
const propErrors = this.jedison.validator.getErrors(discriminatorValue, propSchema, propName, this.path);
|
|
2781
|
+
if (propErrors.length === 0) return index2;
|
|
2782
|
+
}
|
|
2783
|
+
}
|
|
2784
|
+
}
|
|
2785
|
+
}
|
|
2638
2786
|
let fittestIndex;
|
|
2639
2787
|
let championErrors;
|
|
2640
2788
|
for (let index2 = 0; index2 < this.instances.length; index2++) {
|
|
@@ -2761,9 +2909,11 @@ class InstanceObject extends Instance {
|
|
|
2761
2909
|
Object.keys(dependentRequired2).forEach((key) => {
|
|
2762
2910
|
if (isSet(this.value[key])) {
|
|
2763
2911
|
const requiredProperties = dependentRequired2[key];
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2912
|
+
if (isArray(requiredProperties)) {
|
|
2913
|
+
missingProperties = requiredProperties.filter((property2) => {
|
|
2914
|
+
return !hasOwn(this.value, property2);
|
|
2915
|
+
});
|
|
2916
|
+
}
|
|
2767
2917
|
}
|
|
2768
2918
|
});
|
|
2769
2919
|
return missingProperties.includes(property);
|
|
@@ -3149,6 +3299,15 @@ class EditorRadios extends EditorBoolean {
|
|
|
3149
3299
|
radio.checked = radioValue === this.instance.getValue();
|
|
3150
3300
|
});
|
|
3151
3301
|
}
|
|
3302
|
+
setAriaInvalid(invalid) {
|
|
3303
|
+
this.control.radios.forEach((radio) => {
|
|
3304
|
+
if (invalid) {
|
|
3305
|
+
radio.setAttribute("aria-invalid", "true");
|
|
3306
|
+
} else {
|
|
3307
|
+
radio.removeAttribute("aria-invalid");
|
|
3308
|
+
}
|
|
3309
|
+
});
|
|
3310
|
+
}
|
|
3152
3311
|
}
|
|
3153
3312
|
class EditorBooleanSelect extends EditorBoolean {
|
|
3154
3313
|
static resolves(schema) {
|
|
@@ -3218,18 +3377,86 @@ class EditorStringRadios extends EditorString {
|
|
|
3218
3377
|
static resolves(schema) {
|
|
3219
3378
|
return getSchemaType(schema) === "string" && (getSchemaXOption(schema, "format") === "radios" || getSchemaXOption(schema, "format") === "radios-inline");
|
|
3220
3379
|
}
|
|
3380
|
+
init() {
|
|
3381
|
+
super.init();
|
|
3382
|
+
this.setupEnumSource();
|
|
3383
|
+
}
|
|
3384
|
+
setupEnumSource() {
|
|
3385
|
+
const enumSourceRaw = getSchemaXOption(this.instance.schema, "enumSource");
|
|
3386
|
+
if (!isSet(enumSourceRaw)) return;
|
|
3387
|
+
const enumSource = resolveInstancePath(this.instance.path, enumSourceRaw);
|
|
3388
|
+
const src = this.instance.jedison.getInstance(enumSource);
|
|
3389
|
+
if (src) this.enumSourceValues = src.getValue();
|
|
3390
|
+
this.instance.jedison.watch(enumSource, () => {
|
|
3391
|
+
if (!this.control) return;
|
|
3392
|
+
const s = this.instance.jedison.getInstance(enumSource);
|
|
3393
|
+
if (s) {
|
|
3394
|
+
this.enumSourceValues = s.getValue();
|
|
3395
|
+
this.refreshOptions();
|
|
3396
|
+
}
|
|
3397
|
+
});
|
|
3398
|
+
}
|
|
3399
|
+
getEnumSourceValues() {
|
|
3400
|
+
if (this.enumSourceValues !== void 0) {
|
|
3401
|
+
if (isArray(this.enumSourceValues)) return this.enumSourceValues;
|
|
3402
|
+
if (isObject(this.enumSourceValues)) return Object.keys(this.enumSourceValues);
|
|
3403
|
+
return [];
|
|
3404
|
+
}
|
|
3405
|
+
return getSchemaEnum(this.instance.schema) || [];
|
|
3406
|
+
}
|
|
3221
3407
|
build() {
|
|
3408
|
+
const values = this.getEnumSourceValues();
|
|
3222
3409
|
this.control = this.theme.getRadiosControl({
|
|
3223
3410
|
title: this.getTitle(),
|
|
3224
3411
|
description: this.getDescription(),
|
|
3225
|
-
values
|
|
3226
|
-
titles: getSchemaXOption(this.instance.schema, "enumTitles") ||
|
|
3412
|
+
values,
|
|
3413
|
+
titles: getSchemaXOption(this.instance.schema, "enumTitles") || values,
|
|
3227
3414
|
id: this.getIdFromPath(this.instance.path),
|
|
3228
3415
|
titleHidden: getSchemaXOption(this.instance.schema, "titleHidden"),
|
|
3229
3416
|
inline: getSchemaXOption(this.instance.schema, "format") === "radios-inline",
|
|
3230
3417
|
info: this.getInfo()
|
|
3231
3418
|
});
|
|
3232
3419
|
}
|
|
3420
|
+
refreshOptions() {
|
|
3421
|
+
const values = this.getEnumSourceValues();
|
|
3422
|
+
const titles = getSchemaXOption(this.instance.schema, "enumTitles") || values;
|
|
3423
|
+
const id = this.getIdFromPath(this.instance.path);
|
|
3424
|
+
const messagesId = id + "-messages";
|
|
3425
|
+
const descriptionId = id + "-description";
|
|
3426
|
+
const describedBy = messagesId + " " + descriptionId;
|
|
3427
|
+
this.control.radioControls.forEach((rc) => {
|
|
3428
|
+
if (rc.parentNode) rc.parentNode.removeChild(rc);
|
|
3429
|
+
});
|
|
3430
|
+
this.control.radios = [];
|
|
3431
|
+
this.control.labels = [];
|
|
3432
|
+
this.control.radioControls = [];
|
|
3433
|
+
this.control.labelTexts = [];
|
|
3434
|
+
values.forEach((value, index2) => {
|
|
3435
|
+
const radioControl = document.createElement("div");
|
|
3436
|
+
const radio = document.createElement("input");
|
|
3437
|
+
const label = document.createElement("label");
|
|
3438
|
+
const labelText = document.createElement("span");
|
|
3439
|
+
radio.setAttribute("type", "radio");
|
|
3440
|
+
radio.setAttribute("id", id + "-" + index2);
|
|
3441
|
+
radio.setAttribute("name", id);
|
|
3442
|
+
radio.setAttribute("value", value);
|
|
3443
|
+
radio.setAttribute("aria-describedby", describedBy);
|
|
3444
|
+
label.setAttribute("for", id + "-" + index2);
|
|
3445
|
+
label.classList.add("jedi-title");
|
|
3446
|
+
label.classList.add("jedi-label");
|
|
3447
|
+
labelText.textContent = titles && titles[index2] !== void 0 ? titles[index2] : value;
|
|
3448
|
+
radioControl.appendChild(radio);
|
|
3449
|
+
radioControl.appendChild(label);
|
|
3450
|
+
label.appendChild(labelText);
|
|
3451
|
+
this.control.radios.push(radio);
|
|
3452
|
+
this.control.labels.push(label);
|
|
3453
|
+
this.control.labelTexts.push(labelText);
|
|
3454
|
+
this.control.radioControls.push(radioControl);
|
|
3455
|
+
this.control.fieldset.insertBefore(radioControl, this.control.description);
|
|
3456
|
+
});
|
|
3457
|
+
this.addEventListeners();
|
|
3458
|
+
this.refreshUI();
|
|
3459
|
+
}
|
|
3233
3460
|
adaptForTable() {
|
|
3234
3461
|
this.theme.adaptForTableRadiosControl(this.control);
|
|
3235
3462
|
}
|
|
@@ -3246,23 +3473,73 @@ class EditorStringRadios extends EditorString {
|
|
|
3246
3473
|
radio.checked = radio.value === this.instance.getValue();
|
|
3247
3474
|
});
|
|
3248
3475
|
}
|
|
3476
|
+
setAriaInvalid(invalid) {
|
|
3477
|
+
this.control.radios.forEach((radio) => {
|
|
3478
|
+
if (invalid) {
|
|
3479
|
+
radio.setAttribute("aria-invalid", "true");
|
|
3480
|
+
} else {
|
|
3481
|
+
radio.removeAttribute("aria-invalid");
|
|
3482
|
+
}
|
|
3483
|
+
});
|
|
3484
|
+
}
|
|
3249
3485
|
}
|
|
3250
3486
|
class EditorStringSelect extends EditorString {
|
|
3251
3487
|
static resolves(schema) {
|
|
3252
|
-
return getSchemaType(schema) === "string" && isSet(getSchemaEnum(schema));
|
|
3488
|
+
return getSchemaType(schema) === "string" && (isSet(getSchemaEnum(schema)) || isSet(getSchemaXOption(schema, "enumSource")));
|
|
3489
|
+
}
|
|
3490
|
+
init() {
|
|
3491
|
+
super.init();
|
|
3492
|
+
this.setupEnumSource();
|
|
3493
|
+
}
|
|
3494
|
+
setupEnumSource() {
|
|
3495
|
+
const enumSourceRaw = getSchemaXOption(this.instance.schema, "enumSource");
|
|
3496
|
+
if (!isSet(enumSourceRaw)) return;
|
|
3497
|
+
const enumSource = resolveInstancePath(this.instance.path, enumSourceRaw);
|
|
3498
|
+
const src = this.instance.jedison.getInstance(enumSource);
|
|
3499
|
+
if (src) this.enumSourceValues = src.getValue();
|
|
3500
|
+
this.instance.jedison.watch(enumSource, () => {
|
|
3501
|
+
if (!this.control) return;
|
|
3502
|
+
const s = this.instance.jedison.getInstance(enumSource);
|
|
3503
|
+
if (s) {
|
|
3504
|
+
this.enumSourceValues = s.getValue();
|
|
3505
|
+
this.refreshOptions();
|
|
3506
|
+
}
|
|
3507
|
+
});
|
|
3508
|
+
}
|
|
3509
|
+
getEnumSourceValues() {
|
|
3510
|
+
if (this.enumSourceValues !== void 0) {
|
|
3511
|
+
if (isArray(this.enumSourceValues)) return this.enumSourceValues;
|
|
3512
|
+
if (isObject(this.enumSourceValues)) return Object.keys(this.enumSourceValues);
|
|
3513
|
+
return [];
|
|
3514
|
+
}
|
|
3515
|
+
return getSchemaEnum(this.instance.schema) || [];
|
|
3253
3516
|
}
|
|
3254
3517
|
build() {
|
|
3518
|
+
const values = this.getEnumSourceValues();
|
|
3255
3519
|
this.control = this.theme.getSelectControl({
|
|
3256
3520
|
title: this.getTitle(),
|
|
3257
3521
|
description: this.getDescription(),
|
|
3258
|
-
values
|
|
3259
|
-
titles: getSchemaXOption(this.instance.schema, "enumTitles") ||
|
|
3522
|
+
values,
|
|
3523
|
+
titles: getSchemaXOption(this.instance.schema, "enumTitles") || values,
|
|
3260
3524
|
id: this.getIdFromPath(this.instance.path),
|
|
3261
3525
|
titleIconClass: getSchemaXOption(this.instance.schema, "titleIconClass"),
|
|
3262
3526
|
titleHidden: getSchemaXOption(this.instance.schema, "titleHidden"),
|
|
3263
3527
|
info: this.getInfo()
|
|
3264
3528
|
});
|
|
3265
3529
|
}
|
|
3530
|
+
refreshOptions() {
|
|
3531
|
+
const values = this.getEnumSourceValues();
|
|
3532
|
+
const titles = getSchemaXOption(this.instance.schema, "enumTitles") || values;
|
|
3533
|
+
const select = this.control.input;
|
|
3534
|
+
select.innerHTML = "";
|
|
3535
|
+
values.forEach((value, i) => {
|
|
3536
|
+
const option = document.createElement("option");
|
|
3537
|
+
option.setAttribute("value", value);
|
|
3538
|
+
option.textContent = titles && titles[i] !== void 0 ? titles[i] : value;
|
|
3539
|
+
select.appendChild(option);
|
|
3540
|
+
});
|
|
3541
|
+
this.refreshUI();
|
|
3542
|
+
}
|
|
3266
3543
|
adaptForTable() {
|
|
3267
3544
|
this.theme.adaptForTableSelectControl(this.control);
|
|
3268
3545
|
}
|
|
@@ -3504,25 +3781,75 @@ class EditorNumberRadios extends EditorNumber {
|
|
|
3504
3781
|
radio.checked = Number(radio.value) === Number(this.instance.getValue());
|
|
3505
3782
|
});
|
|
3506
3783
|
}
|
|
3784
|
+
setAriaInvalid(invalid) {
|
|
3785
|
+
this.control.radios.forEach((radio) => {
|
|
3786
|
+
if (invalid) {
|
|
3787
|
+
radio.setAttribute("aria-invalid", "true");
|
|
3788
|
+
} else {
|
|
3789
|
+
radio.removeAttribute("aria-invalid");
|
|
3790
|
+
}
|
|
3791
|
+
});
|
|
3792
|
+
}
|
|
3507
3793
|
}
|
|
3508
3794
|
class EditorNumberSelect extends EditorNumber {
|
|
3509
3795
|
static resolves(schema) {
|
|
3510
3796
|
const schemaType = getSchemaType(schema);
|
|
3511
3797
|
const typeIsNumeric = schemaType === "number" || schemaType === "integer";
|
|
3512
|
-
return typeIsNumeric && isSet(getSchemaEnum(schema));
|
|
3798
|
+
return typeIsNumeric && (isSet(getSchemaEnum(schema)) || isSet(getSchemaXOption(schema, "enumSource")));
|
|
3799
|
+
}
|
|
3800
|
+
init() {
|
|
3801
|
+
super.init();
|
|
3802
|
+
this.setupEnumSource();
|
|
3803
|
+
}
|
|
3804
|
+
setupEnumSource() {
|
|
3805
|
+
const enumSourceRaw = getSchemaXOption(this.instance.schema, "enumSource");
|
|
3806
|
+
if (!isSet(enumSourceRaw)) return;
|
|
3807
|
+
const enumSource = resolveInstancePath(this.instance.path, enumSourceRaw);
|
|
3808
|
+
const src = this.instance.jedison.getInstance(enumSource);
|
|
3809
|
+
if (src) this.enumSourceValues = src.getValue();
|
|
3810
|
+
this.instance.jedison.watch(enumSource, () => {
|
|
3811
|
+
if (!this.control) return;
|
|
3812
|
+
const s = this.instance.jedison.getInstance(enumSource);
|
|
3813
|
+
if (s) {
|
|
3814
|
+
this.enumSourceValues = s.getValue();
|
|
3815
|
+
this.refreshOptions();
|
|
3816
|
+
}
|
|
3817
|
+
});
|
|
3818
|
+
}
|
|
3819
|
+
getEnumSourceValues() {
|
|
3820
|
+
if (this.enumSourceValues !== void 0) {
|
|
3821
|
+
if (isArray(this.enumSourceValues)) return this.enumSourceValues;
|
|
3822
|
+
if (isObject(this.enumSourceValues)) return Object.keys(this.enumSourceValues);
|
|
3823
|
+
return [];
|
|
3824
|
+
}
|
|
3825
|
+
return getSchemaEnum(this.instance.schema) || [];
|
|
3513
3826
|
}
|
|
3514
3827
|
build() {
|
|
3828
|
+
const values = this.getEnumSourceValues();
|
|
3515
3829
|
this.control = this.theme.getSelectControl({
|
|
3516
3830
|
title: this.getTitle(),
|
|
3517
3831
|
description: this.getDescription(),
|
|
3518
|
-
values
|
|
3519
|
-
titles: getSchemaXOption(this.instance.schema, "enumTitles") ||
|
|
3832
|
+
values,
|
|
3833
|
+
titles: getSchemaXOption(this.instance.schema, "enumTitles") || values,
|
|
3520
3834
|
id: this.getIdFromPath(this.instance.path),
|
|
3521
3835
|
titleIconClass: getSchemaXOption(this.instance.schema, "titleIconClass"),
|
|
3522
3836
|
titleHidden: getSchemaXOption(this.instance.schema, "titleHidden"),
|
|
3523
3837
|
info: this.getInfo()
|
|
3524
3838
|
});
|
|
3525
3839
|
}
|
|
3840
|
+
refreshOptions() {
|
|
3841
|
+
const values = this.getEnumSourceValues();
|
|
3842
|
+
const titles = getSchemaXOption(this.instance.schema, "enumTitles") || values;
|
|
3843
|
+
const select = this.control.input;
|
|
3844
|
+
select.innerHTML = "";
|
|
3845
|
+
values.forEach((value, i) => {
|
|
3846
|
+
const option = document.createElement("option");
|
|
3847
|
+
option.setAttribute("value", value);
|
|
3848
|
+
option.textContent = titles && titles[i] !== void 0 ? titles[i] : value;
|
|
3849
|
+
select.appendChild(option);
|
|
3850
|
+
});
|
|
3851
|
+
this.refreshUI();
|
|
3852
|
+
}
|
|
3526
3853
|
adaptForTable() {
|
|
3527
3854
|
this.theme.adaptForTableSelectControl(this.control);
|
|
3528
3855
|
}
|
|
@@ -3645,6 +3972,10 @@ class EditorObject extends Editor {
|
|
|
3645
3972
|
if (isSet(additionalProperties2) && additionalProperties2 === false) {
|
|
3646
3973
|
addProperty = false;
|
|
3647
3974
|
}
|
|
3975
|
+
const objectAdd = getSchemaXOption(this.instance.schema, "objectAdd") ?? this.instance.jedison.options.objectAdd;
|
|
3976
|
+
if (isSet(objectAdd) && objectAdd === false) {
|
|
3977
|
+
addProperty = false;
|
|
3978
|
+
}
|
|
3648
3979
|
let enablePropertiesToggle = false;
|
|
3649
3980
|
if (isSet(this.instance.jedison.options.enablePropertiesToggle)) {
|
|
3650
3981
|
enablePropertiesToggle = this.instance.jedison.options.enablePropertiesToggle;
|
|
@@ -3671,30 +4002,30 @@ class EditorObject extends Editor {
|
|
|
3671
4002
|
});
|
|
3672
4003
|
this.control.jsonData.input.value = JSON.stringify(this.instance.getValue(), null, 2);
|
|
3673
4004
|
}
|
|
4005
|
+
announcePropertyAdded(propertyName, child) {
|
|
4006
|
+
const schemaTitle = getSchemaTitle(child.schema);
|
|
4007
|
+
const label = isSet(schemaTitle) ? schemaTitle : propertyName;
|
|
4008
|
+
const ariaLiveMessage = this.theme.getAriaLiveMessage();
|
|
4009
|
+
ariaLiveMessage.textContent = label + " " + this.instance.jedison.translator.translate("objectPropertyAdded");
|
|
4010
|
+
this.control.ariaLive.appendChild(ariaLiveMessage);
|
|
4011
|
+
}
|
|
4012
|
+
addProperty(input, postAction) {
|
|
4013
|
+
const propertyName = input.value.split(" ").join("");
|
|
4014
|
+
if (propertyName.length === 0) return;
|
|
4015
|
+
if (isSet(this.instance.value[propertyName])) return;
|
|
4016
|
+
const schema = this.instance.getPropertySchema(propertyName);
|
|
4017
|
+
const child = this.instance.createChild(schema, propertyName);
|
|
4018
|
+
child.activate();
|
|
4019
|
+
this.instance.setValue(this.instance.value, true, "user");
|
|
4020
|
+
input.value = "";
|
|
4021
|
+
this.announcePropertyAdded(propertyName, child);
|
|
4022
|
+
postAction();
|
|
4023
|
+
}
|
|
3674
4024
|
addEventListeners() {
|
|
3675
|
-
this.control.
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
return;
|
|
3680
|
-
}
|
|
3681
|
-
const propertyExist = isSet(this.instance.value[propertyName]);
|
|
3682
|
-
if (propertyExist) {
|
|
3683
|
-
return;
|
|
3684
|
-
}
|
|
3685
|
-
const schema = this.instance.getPropertySchema(propertyName);
|
|
3686
|
-
const child = this.instance.createChild(schema, propertyName);
|
|
3687
|
-
child.activate();
|
|
3688
|
-
this.instance.setValue(this.instance.value, true, "user");
|
|
3689
|
-
this.control.addPropertyControl.input.value = "";
|
|
3690
|
-
const ariaLive = this.control.ariaLive;
|
|
3691
|
-
const schemaTitle = getSchemaTitle(child.schema);
|
|
3692
|
-
const label = isSet(schemaTitle) ? schemaTitle : propertyName;
|
|
3693
|
-
const ariaLiveMessage = this.theme.getAriaLiveMessage();
|
|
3694
|
-
ariaLiveMessage.textContent = label + " " + this.instance.jedison.translator.translate("objectPropertyAdded");
|
|
3695
|
-
ariaLive.appendChild(ariaLiveMessage);
|
|
3696
|
-
this.control.propertiesContainer.close();
|
|
3697
|
-
this.control.propertiesContainer.showModal();
|
|
4025
|
+
this.control.quickAddPropertyBtn.addEventListener("click", () => {
|
|
4026
|
+
this.addProperty(this.control.quickAddPropertyControl.input, () => {
|
|
4027
|
+
this.control.quickAddPropertyContainer.close();
|
|
4028
|
+
});
|
|
3698
4029
|
});
|
|
3699
4030
|
this.control.jsonData.saveBtn.addEventListener("click", () => {
|
|
3700
4031
|
try {
|
|
@@ -3724,9 +4055,7 @@ class EditorObject extends Editor {
|
|
|
3724
4055
|
const declaredProperties = Object.keys(this.instance.properties);
|
|
3725
4056
|
const instanceProperties = this.instance.children.map((child) => child.getKey());
|
|
3726
4057
|
const properties2 = [.../* @__PURE__ */ new Set([...declaredProperties, ...instanceProperties])];
|
|
3727
|
-
|
|
3728
|
-
this.control.propertiesActivators.removeChild(this.control.propertiesActivators.firstChild);
|
|
3729
|
-
}
|
|
4058
|
+
this.control.propertiesActivators.replaceChildren();
|
|
3730
4059
|
const {
|
|
3731
4060
|
container: defaultGroupContainer,
|
|
3732
4061
|
group: defaultGroup
|
|
@@ -3783,12 +4112,28 @@ class EditorObject extends Editor {
|
|
|
3783
4112
|
checkbox.disabled = this.disabled || isRequired;
|
|
3784
4113
|
checkbox.checked = hasOwn(currentValue, property);
|
|
3785
4114
|
});
|
|
4115
|
+
const propGroupOrder = getSchemaXOption(this.instance.schema, "propGroupOrder");
|
|
4116
|
+
if (isSet(propGroupOrder) && Array.isArray(propGroupOrder)) {
|
|
4117
|
+
const orderedContainers = [defaultGroupContainer];
|
|
4118
|
+
propGroupOrder.forEach((groupName) => {
|
|
4119
|
+
if (isSet(propertiesGroups[groupName])) {
|
|
4120
|
+
orderedContainers.push(propertiesGroups[groupName].container);
|
|
4121
|
+
}
|
|
4122
|
+
});
|
|
4123
|
+
Object.keys(propertiesGroups).forEach((groupName) => {
|
|
4124
|
+
if (!propGroupOrder.includes(groupName)) {
|
|
4125
|
+
orderedContainers.push(propertiesGroups[groupName].container);
|
|
4126
|
+
}
|
|
4127
|
+
});
|
|
4128
|
+
this.control.propertiesActivators.replaceChildren();
|
|
4129
|
+
orderedContainers.forEach((container) => {
|
|
4130
|
+
this.control.propertiesActivators.appendChild(container);
|
|
4131
|
+
});
|
|
4132
|
+
}
|
|
3786
4133
|
}
|
|
3787
4134
|
}
|
|
3788
4135
|
refreshEditors() {
|
|
3789
|
-
|
|
3790
|
-
this.control.childrenSlot.removeChild(this.control.childrenSlot.firstChild);
|
|
3791
|
-
}
|
|
4136
|
+
this.control.childrenSlot.replaceChildren();
|
|
3792
4137
|
this.instance.children.forEach((child) => {
|
|
3793
4138
|
const optIn = this.theme.getCheckboxControl({
|
|
3794
4139
|
id: child.path + "-opt-in",
|
|
@@ -3822,11 +4167,32 @@ class EditorObject extends Editor {
|
|
|
3822
4167
|
}
|
|
3823
4168
|
});
|
|
3824
4169
|
}
|
|
4170
|
+
refreshLegendWarning() {
|
|
4171
|
+
if (!this.control.legendText) return;
|
|
4172
|
+
const navWarning = getSchemaXOption(this.instance.schema, "navWarning") ?? true;
|
|
4173
|
+
const hasErrors = navWarning && this.instance.hasNestedValidationErrors();
|
|
4174
|
+
const existing = this.control.legendText.querySelector(".jedi-legend-warning");
|
|
4175
|
+
if (existing) existing.parentNode.removeChild(existing);
|
|
4176
|
+
if (hasErrors) {
|
|
4177
|
+
const warning = document.createElement("span");
|
|
4178
|
+
warning.classList.add("jedi-legend-warning");
|
|
4179
|
+
warning.textContent = "⚠";
|
|
4180
|
+
const navWarningMessage = getSchemaXOption(this.instance.schema, "navWarningMessage");
|
|
4181
|
+
if (navWarningMessage) warning.setAttribute("title", navWarningMessage);
|
|
4182
|
+
this.theme.styleLegendWarning(warning);
|
|
4183
|
+
this.control.legendText.appendChild(warning);
|
|
4184
|
+
}
|
|
4185
|
+
}
|
|
4186
|
+
showValidationErrors(errors, force = false) {
|
|
4187
|
+
super.showValidationErrors(errors, force);
|
|
4188
|
+
this.refreshLegendWarning();
|
|
4189
|
+
}
|
|
3825
4190
|
refreshUI() {
|
|
3826
4191
|
super.refreshUI();
|
|
3827
4192
|
this.refreshPropertiesSlot();
|
|
3828
4193
|
this.refreshEditors();
|
|
3829
4194
|
this.refreshJsonData();
|
|
4195
|
+
this.refreshLegendWarning();
|
|
3830
4196
|
}
|
|
3831
4197
|
}
|
|
3832
4198
|
class EditorObjectGrid extends EditorObject {
|
|
@@ -3904,6 +4270,8 @@ class EditorObjectCategories extends EditorObject {
|
|
|
3904
4270
|
const categoriesMap = /* @__PURE__ */ new Map();
|
|
3905
4271
|
this.instance.children.forEach((child) => {
|
|
3906
4272
|
if (!child.isActive) return;
|
|
4273
|
+
const hidden = getSchemaXOption(child.schema, "hidden");
|
|
4274
|
+
if (isSet(hidden) && hidden === true) return;
|
|
3907
4275
|
const childSchemaType = getSchemaType(child.schema);
|
|
3908
4276
|
const xCategory = getSchemaXOption(child.schema, "category");
|
|
3909
4277
|
let categoryName;
|
|
@@ -3963,6 +4331,22 @@ class EditorObjectNav extends EditorObject {
|
|
|
3963
4331
|
super.init();
|
|
3964
4332
|
this.activeTabIndex = 0;
|
|
3965
4333
|
}
|
|
4334
|
+
isChildVisible(child) {
|
|
4335
|
+
if (!child.isActive) return false;
|
|
4336
|
+
const hidden = getSchemaXOption(child.schema, "hidden");
|
|
4337
|
+
return !(isSet(hidden) && hidden === true);
|
|
4338
|
+
}
|
|
4339
|
+
getVisibleChildIndices() {
|
|
4340
|
+
return this.instance.children.reduce((indices, child, index2) => {
|
|
4341
|
+
if (this.isChildVisible(child)) indices.push(index2);
|
|
4342
|
+
return indices;
|
|
4343
|
+
}, []);
|
|
4344
|
+
}
|
|
4345
|
+
ensureActiveTabIsVisible(visibleIndices) {
|
|
4346
|
+
if (!visibleIndices.includes(this.activeTabIndex)) {
|
|
4347
|
+
this.activeTabIndex = visibleIndices[0] ?? 0;
|
|
4348
|
+
}
|
|
4349
|
+
}
|
|
3966
4350
|
refreshEditors() {
|
|
3967
4351
|
while (this.control.childrenSlot.firstChild) {
|
|
3968
4352
|
this.control.childrenSlot.removeChild(this.control.childrenSlot.lastChild);
|
|
@@ -3984,31 +4368,32 @@ class EditorObjectNav extends EditorObject {
|
|
|
3984
4368
|
row.appendChild(tabContentCol);
|
|
3985
4369
|
tabListCol.appendChild(tabList);
|
|
3986
4370
|
tabContentCol.appendChild(tabContent);
|
|
4371
|
+
const visibleIndices = this.getVisibleChildIndices();
|
|
4372
|
+
this.ensureActiveTabIsVisible(visibleIndices);
|
|
3987
4373
|
this.instance.children.forEach((child, index2) => {
|
|
3988
|
-
if (child
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
}
|
|
4374
|
+
if (!this.isChildVisible(child)) return;
|
|
4375
|
+
const active = index2 === this.activeTabIndex;
|
|
4376
|
+
const id = pathToAttribute(child.path);
|
|
4377
|
+
const schemaTitle = getSchemaTitle(child.schema);
|
|
4378
|
+
const navWarning = getSchemaXOption(this.instance.schema, "navWarning") ?? true;
|
|
4379
|
+
const navWarningMessage = getSchemaXOption(this.instance.schema, "navWarningMessage");
|
|
4380
|
+
const tab = this.theme.getTab({
|
|
4381
|
+
hasErrors: navWarning && child.hasNestedValidationErrors(),
|
|
4382
|
+
navWarningMessage,
|
|
4383
|
+
title: isSet(schemaTitle) ? schemaTitle : child.getKey(),
|
|
4384
|
+
id,
|
|
4385
|
+
active
|
|
4386
|
+
});
|
|
4387
|
+
tab.list.addEventListener("click", () => {
|
|
4388
|
+
this.activeTabIndex = index2;
|
|
4389
|
+
});
|
|
4390
|
+
this.theme.setTabPaneAttributes(child.ui.control.container, active, id);
|
|
4391
|
+
tabList.appendChild(tab.list);
|
|
4392
|
+
tabContent.appendChild(child.ui.control.container);
|
|
4393
|
+
if (this.disabled || this.instance.isReadOnly()) {
|
|
4394
|
+
child.ui.disable();
|
|
4395
|
+
} else {
|
|
4396
|
+
child.ui.enable();
|
|
4012
4397
|
}
|
|
4013
4398
|
});
|
|
4014
4399
|
}
|
|
@@ -4086,10 +4471,19 @@ class EditorArray extends Editor {
|
|
|
4086
4471
|
});
|
|
4087
4472
|
const btnGroup = this.theme.getBtnGroup();
|
|
4088
4473
|
deleteBtn.addEventListener("click", () => {
|
|
4089
|
-
const
|
|
4090
|
-
|
|
4474
|
+
const schemaConfirm = getSchemaXOption(this.instance.schema, "arrayDeleteConfirm");
|
|
4475
|
+
const globalConfirm = this.instance.jedison.options.arrayDeleteConfirm;
|
|
4476
|
+
const shouldConfirm = isSet(schemaConfirm) ? schemaConfirm : globalConfirm;
|
|
4477
|
+
const doDelete = () => {
|
|
4091
4478
|
this.activeItemIndex = clamp(index2 - 1, 0, this.instance.value.length - 1);
|
|
4092
4479
|
this.instance.deleteItem(index2, "user");
|
|
4480
|
+
};
|
|
4481
|
+
if (shouldConfirm) {
|
|
4482
|
+
if (window.confirm(this.instance.jedison.translator.translate("arrayConfirmDelete"))) {
|
|
4483
|
+
doDelete();
|
|
4484
|
+
}
|
|
4485
|
+
} else {
|
|
4486
|
+
doDelete();
|
|
4093
4487
|
}
|
|
4094
4488
|
});
|
|
4095
4489
|
moveUpBtn.addEventListener("click", () => {
|
|
@@ -4182,6 +4576,27 @@ class EditorArray extends Editor {
|
|
|
4182
4576
|
});
|
|
4183
4577
|
this.refreshAddBtn();
|
|
4184
4578
|
this.refreshJsonData();
|
|
4579
|
+
this.refreshLegendWarning();
|
|
4580
|
+
}
|
|
4581
|
+
refreshLegendWarning() {
|
|
4582
|
+
if (!this.control.legendText) return;
|
|
4583
|
+
const navWarning = getSchemaXOption(this.instance.schema, "navWarning") ?? true;
|
|
4584
|
+
const hasErrors = navWarning && this.instance.hasNestedValidationErrors();
|
|
4585
|
+
const existing = this.control.legendText.querySelector(".jedi-legend-warning");
|
|
4586
|
+
if (existing) existing.parentNode.removeChild(existing);
|
|
4587
|
+
if (hasErrors) {
|
|
4588
|
+
const warning = document.createElement("span");
|
|
4589
|
+
warning.classList.add("jedi-legend-warning");
|
|
4590
|
+
warning.textContent = "⚠";
|
|
4591
|
+
const navWarningMessage = getSchemaXOption(this.instance.schema, "navWarningMessage");
|
|
4592
|
+
if (navWarningMessage) warning.setAttribute("title", navWarningMessage);
|
|
4593
|
+
this.theme.styleLegendWarning(warning);
|
|
4594
|
+
this.control.legendText.appendChild(warning);
|
|
4595
|
+
}
|
|
4596
|
+
}
|
|
4597
|
+
showValidationErrors(errors, force = false) {
|
|
4598
|
+
super.showValidationErrors(errors, force);
|
|
4599
|
+
this.refreshLegendWarning();
|
|
4185
4600
|
}
|
|
4186
4601
|
}
|
|
4187
4602
|
class EditorArrayTuple extends EditorArray {
|
|
@@ -4256,20 +4671,22 @@ class EditorArrayTable extends EditorArray {
|
|
|
4256
4671
|
if (this.instance.children.length) {
|
|
4257
4672
|
const schemaItems = getSchemaItems(this.instance.schema);
|
|
4258
4673
|
const thTitle = this.theme.getTableHeader();
|
|
4259
|
-
if (schemaItems
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4674
|
+
if (schemaItems) {
|
|
4675
|
+
if (schemaItems.title) {
|
|
4676
|
+
const fakeLabel = this.theme.getFakeLabel({
|
|
4677
|
+
content: schemaItems.title
|
|
4678
|
+
});
|
|
4679
|
+
thTitle.appendChild(fakeLabel.label);
|
|
4680
|
+
}
|
|
4681
|
+
const schemaXInfo = getSchemaXOption(schemaItems, "info");
|
|
4682
|
+
if (isSet(schemaXInfo)) {
|
|
4683
|
+
const infoContent = this.getInfo(schemaItems);
|
|
4684
|
+
const info = this.theme.getInfo(infoContent);
|
|
4685
|
+
if (schemaXInfo.variant === "modal") {
|
|
4686
|
+
this.theme.infoAsModal(info, this.getIdFromPath(this.instance.path), infoContent);
|
|
4687
|
+
}
|
|
4688
|
+
thTitle.appendChild(info.container);
|
|
4271
4689
|
}
|
|
4272
|
-
thTitle.appendChild(info.container);
|
|
4273
4690
|
}
|
|
4274
4691
|
table.thead.appendChild(thTitle);
|
|
4275
4692
|
}
|
|
@@ -4489,6 +4906,45 @@ class EditorArrayChoices extends Editor {
|
|
|
4489
4906
|
const hasValidItemType = isSet(schemaItems) && isSet(schemaItemsType) && (validTypes.includes(schemaItemsType) || isArray(schemaItemsType) && schemaItemsType.some((type2) => validTypes.includes(type2)));
|
|
4490
4907
|
return hasChoicesFormat && choicesInstalled && isArrayType && isUniqueItems && hasTypes && hasValidItemType;
|
|
4491
4908
|
}
|
|
4909
|
+
init() {
|
|
4910
|
+
super.init();
|
|
4911
|
+
this.setupEnumSource();
|
|
4912
|
+
}
|
|
4913
|
+
setupEnumSource() {
|
|
4914
|
+
const enumSourceRaw = getSchemaXOption(this.instance.schema, "enumSource");
|
|
4915
|
+
if (!isSet(enumSourceRaw)) return;
|
|
4916
|
+
const enumSource = resolveInstancePath(this.instance.path, enumSourceRaw);
|
|
4917
|
+
const src = this.instance.jedison.getInstance(enumSource);
|
|
4918
|
+
if (src) this.enumSourceValues = src.getValue();
|
|
4919
|
+
this.instance.jedison.watch(enumSource, () => {
|
|
4920
|
+
if (!this.control) return;
|
|
4921
|
+
const s = this.instance.jedison.getInstance(enumSource);
|
|
4922
|
+
if (s) {
|
|
4923
|
+
this.enumSourceValues = s.getValue();
|
|
4924
|
+
this.refreshOptions();
|
|
4925
|
+
}
|
|
4926
|
+
});
|
|
4927
|
+
}
|
|
4928
|
+
getEnumSourceValues() {
|
|
4929
|
+
if (this.enumSourceValues !== void 0) {
|
|
4930
|
+
if (isArray(this.enumSourceValues)) return this.enumSourceValues;
|
|
4931
|
+
if (isObject(this.enumSourceValues)) return Object.keys(this.enumSourceValues);
|
|
4932
|
+
return [];
|
|
4933
|
+
}
|
|
4934
|
+
return this.instance.schema.items && this.instance.schema.items.enum || [];
|
|
4935
|
+
}
|
|
4936
|
+
refreshOptions() {
|
|
4937
|
+
if (!this.choicesInstance) return;
|
|
4938
|
+
const values = this.getEnumSourceValues();
|
|
4939
|
+
const currentValue = this.instance.getValue();
|
|
4940
|
+
const itemEnumTitles = getSchemaXOption(this.instance.schema.items || {}, "enumTitles") || [];
|
|
4941
|
+
const choices = values.map((item, index2) => ({
|
|
4942
|
+
value: item,
|
|
4943
|
+
label: itemEnumTitles[index2] || item,
|
|
4944
|
+
selected: isArray(currentValue) && currentValue.includes(item)
|
|
4945
|
+
}));
|
|
4946
|
+
this.choicesInstance.setChoices(choices, "value", "label", true);
|
|
4947
|
+
}
|
|
4492
4948
|
build() {
|
|
4493
4949
|
this.control = this.theme.getSelectControl({
|
|
4494
4950
|
title: this.getTitle(),
|
|
@@ -4503,8 +4959,8 @@ class EditorArrayChoices extends Editor {
|
|
|
4503
4959
|
this.control.input.setAttribute("multiple", "");
|
|
4504
4960
|
try {
|
|
4505
4961
|
const value = this.instance.getValue();
|
|
4506
|
-
const itemEnum = this.
|
|
4507
|
-
const itemEnumTitles = getSchemaXOption(this.instance.schema.items, "enumTitles")
|
|
4962
|
+
const itemEnum = this.getEnumSourceValues();
|
|
4963
|
+
const itemEnumTitles = getSchemaXOption(this.instance.schema.items || {}, "enumTitles") || [];
|
|
4508
4964
|
const choicesOptions = getSchemaXOption(this.instance.schema, "choicesOptions") ?? {};
|
|
4509
4965
|
if (this.choicesInstance) {
|
|
4510
4966
|
this.choicesInstance.destroy();
|
|
@@ -4659,6 +5115,7 @@ class EditorMultiple extends Editor {
|
|
|
4659
5115
|
}
|
|
4660
5116
|
build() {
|
|
4661
5117
|
this.switcherInput = getSchemaXOption(this.instance.schema, "switcherInput") ?? this.instance.jedison.options.switcherInput;
|
|
5118
|
+
this.embedSwitcher = getSchemaXOption(this.instance.schema, "embedSwitcher") ?? this.instance.jedison.options.embedSwitcher;
|
|
4662
5119
|
this.control = this.theme.getMultipleControl({
|
|
4663
5120
|
titleHidden: getSchemaXOption(this.instance.schema, "titleHidden"),
|
|
4664
5121
|
id: this.getIdFromPath(this.instance.path),
|
|
@@ -4667,6 +5124,9 @@ class EditorMultiple extends Editor {
|
|
|
4667
5124
|
switcher: this.switcherInput,
|
|
4668
5125
|
readOnly: this.instance.isReadOnly()
|
|
4669
5126
|
});
|
|
5127
|
+
if (this.embedSwitcher) {
|
|
5128
|
+
this.control.header.style.display = "none";
|
|
5129
|
+
}
|
|
4670
5130
|
}
|
|
4671
5131
|
adaptForTable(td) {
|
|
4672
5132
|
this.theme.adaptForTableMultipleControl(this.control, td);
|
|
@@ -4691,6 +5151,17 @@ class EditorMultiple extends Editor {
|
|
|
4691
5151
|
this.refreshDisabledState();
|
|
4692
5152
|
this.control.childrenSlot.innerHTML = "";
|
|
4693
5153
|
this.control.childrenSlot.appendChild(this.instance.activeInstance.ui.control.container);
|
|
5154
|
+
if (this.embedSwitcher) {
|
|
5155
|
+
const slot = this.instance.activeInstance.ui.control.switcherSlot;
|
|
5156
|
+
if (slot) {
|
|
5157
|
+
slot.innerHTML = "";
|
|
5158
|
+
slot.appendChild(this.control.switcher.container);
|
|
5159
|
+
this.control.header.style.display = "none";
|
|
5160
|
+
} else {
|
|
5161
|
+
this.control.header.style.display = "";
|
|
5162
|
+
this.control.header.appendChild(this.control.switcher.container);
|
|
5163
|
+
}
|
|
5164
|
+
}
|
|
4694
5165
|
if (this.switcherInput === "select") {
|
|
4695
5166
|
this.control.switcher.input.value = this.instance.index;
|
|
4696
5167
|
}
|
|
@@ -5060,6 +5531,38 @@ class EditorNumberRaty extends EditorNumber {
|
|
|
5060
5531
|
this.raty.score(this.instance.getValue());
|
|
5061
5532
|
}
|
|
5062
5533
|
}
|
|
5534
|
+
class EditorAnyJson extends Editor {
|
|
5535
|
+
static resolves(schema) {
|
|
5536
|
+
return getSchemaXOption(schema, "format") === "json";
|
|
5537
|
+
}
|
|
5538
|
+
build() {
|
|
5539
|
+
this.control = this.theme.getTextareaControl({
|
|
5540
|
+
title: this.getTitle(),
|
|
5541
|
+
description: this.getDescription(),
|
|
5542
|
+
id: this.getIdFromPath(this.instance.path),
|
|
5543
|
+
titleIconClass: getSchemaXOption(this.instance.schema, "titleIconClass"),
|
|
5544
|
+
titleHidden: getSchemaXOption(this.instance.schema, "titleHidden"),
|
|
5545
|
+
info: this.getInfo()
|
|
5546
|
+
});
|
|
5547
|
+
this.jsonErrorEl = document.createElement("div");
|
|
5548
|
+
this.jsonErrorEl.style.color = "red";
|
|
5549
|
+
this.control.container.appendChild(this.jsonErrorEl);
|
|
5550
|
+
}
|
|
5551
|
+
addEventListeners() {
|
|
5552
|
+
this.control.input.addEventListener("change", () => {
|
|
5553
|
+
try {
|
|
5554
|
+
const parsed = JSON.parse(this.control.input.value);
|
|
5555
|
+
this.jsonErrorEl.textContent = "";
|
|
5556
|
+
this.instance.setValue(parsed, true, "user");
|
|
5557
|
+
} catch (e) {
|
|
5558
|
+
this.jsonErrorEl.textContent = e.message;
|
|
5559
|
+
}
|
|
5560
|
+
});
|
|
5561
|
+
}
|
|
5562
|
+
refreshUI() {
|
|
5563
|
+
this.control.input.value = JSON.stringify(this.instance.getValue(), null, 2);
|
|
5564
|
+
}
|
|
5565
|
+
}
|
|
5063
5566
|
class EditorArrayCheckboxes extends Editor {
|
|
5064
5567
|
static resolves(schema) {
|
|
5065
5568
|
const schemaType = getSchemaType(schema);
|
|
@@ -5069,22 +5572,93 @@ class EditorArrayCheckboxes extends Editor {
|
|
|
5069
5572
|
const isUniqueItems = getSchemaUniqueItems(schema) === true;
|
|
5070
5573
|
const hasEnum = isSet(schemaItems) && isSet(getSchemaEnum(schema.items));
|
|
5071
5574
|
const hasTypes = isSet(schemaItems) && isSet(schemaItemsType);
|
|
5575
|
+
const hasEnumSource = isSet(getSchemaXOption(schema, "enumSource"));
|
|
5072
5576
|
const validTypes = ["string", "number", "integer"];
|
|
5073
5577
|
const hasValidItemType = isSet(schemaItems) && isSet(schemaItemsType) && (validTypes.includes(schemaItemsType) || isArray(schemaItemsType) && schemaItemsType.some((type2) => validTypes.includes(type2)));
|
|
5074
|
-
return isArrayType && isUniqueItems && hasEnum && hasTypes && hasValidItemType;
|
|
5578
|
+
return isArrayType && isUniqueItems && (hasEnumSource || hasEnum && hasTypes && hasValidItemType);
|
|
5579
|
+
}
|
|
5580
|
+
init() {
|
|
5581
|
+
super.init();
|
|
5582
|
+
this.setupEnumSource();
|
|
5583
|
+
}
|
|
5584
|
+
setupEnumSource() {
|
|
5585
|
+
const enumSourceRaw = getSchemaXOption(this.instance.schema, "enumSource");
|
|
5586
|
+
if (!isSet(enumSourceRaw)) return;
|
|
5587
|
+
const enumSource = resolveInstancePath(this.instance.path, enumSourceRaw);
|
|
5588
|
+
const src = this.instance.jedison.getInstance(enumSource);
|
|
5589
|
+
if (src) this.enumSourceValues = src.getValue();
|
|
5590
|
+
this.instance.jedison.watch(enumSource, () => {
|
|
5591
|
+
if (!this.control) return;
|
|
5592
|
+
const s = this.instance.jedison.getInstance(enumSource);
|
|
5593
|
+
if (s) {
|
|
5594
|
+
this.enumSourceValues = s.getValue();
|
|
5595
|
+
this.refreshOptions();
|
|
5596
|
+
}
|
|
5597
|
+
});
|
|
5598
|
+
}
|
|
5599
|
+
getEnumSourceValues() {
|
|
5600
|
+
if (this.enumSourceValues !== void 0) {
|
|
5601
|
+
if (isArray(this.enumSourceValues)) return this.enumSourceValues;
|
|
5602
|
+
if (isObject(this.enumSourceValues)) return Object.keys(this.enumSourceValues);
|
|
5603
|
+
return [];
|
|
5604
|
+
}
|
|
5605
|
+
return getSchemaEnum(this.instance.schema.items) || [];
|
|
5075
5606
|
}
|
|
5076
5607
|
build() {
|
|
5608
|
+
const values = this.getEnumSourceValues();
|
|
5609
|
+
const schemaItems = this.instance.schema.items || {};
|
|
5610
|
+
const titles = getSchemaXOption(schemaItems, "enumTitles") || values;
|
|
5077
5611
|
this.control = this.theme.getCheckboxesControl({
|
|
5078
5612
|
title: this.getTitle(),
|
|
5079
5613
|
description: this.getDescription(),
|
|
5080
|
-
values
|
|
5081
|
-
titles
|
|
5614
|
+
values,
|
|
5615
|
+
titles,
|
|
5082
5616
|
id: this.getIdFromPath(this.instance.path),
|
|
5083
5617
|
titleHidden: getSchemaXOption(this.instance.schema, "titleHidden"),
|
|
5084
5618
|
inline: getSchemaXOption(this.instance.schema, "format") === "checkboxes-inline",
|
|
5085
5619
|
info: this.getInfo()
|
|
5086
5620
|
});
|
|
5087
5621
|
}
|
|
5622
|
+
refreshOptions() {
|
|
5623
|
+
const values = this.getEnumSourceValues();
|
|
5624
|
+
const schemaItems = this.instance.schema.items || {};
|
|
5625
|
+
const titles = getSchemaXOption(schemaItems, "enumTitles") || values;
|
|
5626
|
+
const id = this.getIdFromPath(this.instance.path);
|
|
5627
|
+
const messagesId = id + "-messages";
|
|
5628
|
+
const descriptionId = id + "-description";
|
|
5629
|
+
const describedBy = messagesId + " " + descriptionId;
|
|
5630
|
+
this.control.checkboxControls.forEach((cc) => {
|
|
5631
|
+
if (cc.parentNode) cc.parentNode.removeChild(cc);
|
|
5632
|
+
});
|
|
5633
|
+
this.control.checkboxes = [];
|
|
5634
|
+
this.control.labels = [];
|
|
5635
|
+
this.control.checkboxControls = [];
|
|
5636
|
+
this.control.labelTexts = [];
|
|
5637
|
+
values.forEach((value, index2) => {
|
|
5638
|
+
const checkboxId = id + "-" + index2;
|
|
5639
|
+
const checkboxControl = document.createElement("div");
|
|
5640
|
+
const checkbox = document.createElement("input");
|
|
5641
|
+
const label = document.createElement("label");
|
|
5642
|
+
const labelText = document.createElement("span");
|
|
5643
|
+
checkbox.setAttribute("type", "checkbox");
|
|
5644
|
+
checkbox.setAttribute("id", checkboxId);
|
|
5645
|
+
checkbox.setAttribute("name", id);
|
|
5646
|
+
checkbox.setAttribute("value", value);
|
|
5647
|
+
checkbox.setAttribute("aria-describedby", describedBy);
|
|
5648
|
+
label.setAttribute("for", checkboxId);
|
|
5649
|
+
labelText.textContent = titles && titles[index2] !== void 0 ? titles[index2] : value;
|
|
5650
|
+
checkboxControl.appendChild(checkbox);
|
|
5651
|
+
checkboxControl.appendChild(label);
|
|
5652
|
+
label.appendChild(labelText);
|
|
5653
|
+
this.control.checkboxes.push(checkbox);
|
|
5654
|
+
this.control.labels.push(label);
|
|
5655
|
+
this.control.labelTexts.push(labelText);
|
|
5656
|
+
this.control.checkboxControls.push(checkboxControl);
|
|
5657
|
+
this.control.fieldset.insertBefore(checkboxControl, this.control.description);
|
|
5658
|
+
});
|
|
5659
|
+
this.addEventListeners();
|
|
5660
|
+
this.refreshUI();
|
|
5661
|
+
}
|
|
5088
5662
|
adaptForTable(td) {
|
|
5089
5663
|
this.theme.adaptForTableCheckboxesControl(this.control, td);
|
|
5090
5664
|
}
|
|
@@ -5117,6 +5691,15 @@ class EditorArrayCheckboxes extends Editor {
|
|
|
5117
5691
|
checkbox.checked = value.includes(checkbox.value);
|
|
5118
5692
|
});
|
|
5119
5693
|
}
|
|
5694
|
+
setAriaInvalid(invalid) {
|
|
5695
|
+
this.control.checkboxes.forEach((checkbox) => {
|
|
5696
|
+
if (invalid) {
|
|
5697
|
+
checkbox.setAttribute("aria-invalid", "true");
|
|
5698
|
+
} else {
|
|
5699
|
+
checkbox.removeAttribute("aria-invalid");
|
|
5700
|
+
}
|
|
5701
|
+
});
|
|
5702
|
+
}
|
|
5120
5703
|
}
|
|
5121
5704
|
class EditorNumberRange extends EditorNumber {
|
|
5122
5705
|
static resolves(schema) {
|
|
@@ -5291,6 +5874,7 @@ class UiResolver {
|
|
|
5291
5874
|
EditorNumberInputNullable,
|
|
5292
5875
|
EditorMultiple,
|
|
5293
5876
|
EditorIfThenElse,
|
|
5877
|
+
EditorAnyJson,
|
|
5294
5878
|
EditorRadios,
|
|
5295
5879
|
EditorBooleanCheckbox,
|
|
5296
5880
|
EditorBooleanSelect,
|
|
@@ -5629,14 +6213,17 @@ class Jedison extends EventEmitter {
|
|
|
5629
6213
|
btnContents: true,
|
|
5630
6214
|
btnIcons: true,
|
|
5631
6215
|
arrayDelete: true,
|
|
6216
|
+
arrayDeleteConfirm: true,
|
|
5632
6217
|
arrayMove: true,
|
|
5633
6218
|
arrayAdd: true,
|
|
6219
|
+
objectAdd: true,
|
|
5634
6220
|
arrayButtonsPosition: "left",
|
|
5635
6221
|
startCollapsed: false,
|
|
5636
6222
|
deactivateNonRequired: false,
|
|
5637
6223
|
schema: {},
|
|
5638
6224
|
showErrors: "change",
|
|
5639
6225
|
switcherInput: "select",
|
|
6226
|
+
embedSwitcher: false,
|
|
5640
6227
|
data: void 0,
|
|
5641
6228
|
assertFormat: false,
|
|
5642
6229
|
customEditors: [],
|
|
@@ -5661,6 +6248,7 @@ class Jedison extends EventEmitter {
|
|
|
5661
6248
|
enforceMinItems: true,
|
|
5662
6249
|
enforceMaxItems: true,
|
|
5663
6250
|
enforceEnum: true,
|
|
6251
|
+
subErrors: false,
|
|
5664
6252
|
debug: false
|
|
5665
6253
|
}, options);
|
|
5666
6254
|
this.rootName = "#";
|
|
@@ -5728,7 +6316,8 @@ class Jedison extends EventEmitter {
|
|
|
5728
6316
|
refParser: this.refParser,
|
|
5729
6317
|
assertFormat: this.options.assertFormat,
|
|
5730
6318
|
translator: this.translator,
|
|
5731
|
-
constraints: this.options.constraints
|
|
6319
|
+
constraints: this.options.constraints,
|
|
6320
|
+
subErrors: this.options.subErrors
|
|
5732
6321
|
});
|
|
5733
6322
|
this.root = this.createInstance({
|
|
5734
6323
|
jedison: this,
|
|
@@ -6280,6 +6869,8 @@ class Theme {
|
|
|
6280
6869
|
const dummyInputId = "legend-dummy-input-" + config.id;
|
|
6281
6870
|
left.classList.add("jedi-editor-legend-left");
|
|
6282
6871
|
right.classList.add("jedi-editor-legend-right");
|
|
6872
|
+
right.style.display = "flex";
|
|
6873
|
+
right.style.alignItems = "center";
|
|
6283
6874
|
legend.classList.add("jedi-editor-legend");
|
|
6284
6875
|
legend.style.fontSize = "inherit";
|
|
6285
6876
|
legend.setAttribute("aria-labelledby", legendLabelId);
|
|
@@ -6495,6 +7086,18 @@ class Theme {
|
|
|
6495
7086
|
});
|
|
6496
7087
|
return toggle;
|
|
6497
7088
|
}
|
|
7089
|
+
getQuickAddPropertyToggle(config) {
|
|
7090
|
+
const toggle = this.getButton(config);
|
|
7091
|
+
toggle.classList.add("jedi-quick-add-property-toggle");
|
|
7092
|
+
toggle.addEventListener("click", () => {
|
|
7093
|
+
if (config.propertiesContainer.open) {
|
|
7094
|
+
config.propertiesContainer.close();
|
|
7095
|
+
} else {
|
|
7096
|
+
config.propertiesContainer.showModal();
|
|
7097
|
+
}
|
|
7098
|
+
});
|
|
7099
|
+
return toggle;
|
|
7100
|
+
}
|
|
6498
7101
|
/**
|
|
6499
7102
|
* Container that will collapse and expand to show and hide it contents
|
|
6500
7103
|
*/
|
|
@@ -6557,6 +7160,17 @@ class Theme {
|
|
|
6557
7160
|
});
|
|
6558
7161
|
return html;
|
|
6559
7162
|
}
|
|
7163
|
+
getQuickAddPropertySlot(config) {
|
|
7164
|
+
const html = document.createElement("dialog");
|
|
7165
|
+
html.classList.add("jedi-quick-add-property-slot");
|
|
7166
|
+
html.setAttribute("id", config.id);
|
|
7167
|
+
window.addEventListener("click", (event) => {
|
|
7168
|
+
if (event.target === html) {
|
|
7169
|
+
html.close();
|
|
7170
|
+
}
|
|
7171
|
+
});
|
|
7172
|
+
return html;
|
|
7173
|
+
}
|
|
6560
7174
|
/**
|
|
6561
7175
|
* Container for properties editing elements like property activators
|
|
6562
7176
|
*/
|
|
@@ -6909,17 +7523,25 @@ class Theme {
|
|
|
6909
7523
|
collapse,
|
|
6910
7524
|
startCollapsed: config.startCollapsed
|
|
6911
7525
|
});
|
|
6912
|
-
const
|
|
7526
|
+
const quickAddPropertyContainer = this.getQuickAddPropertySlot({
|
|
7527
|
+
id: "quick-add-property-slot-" + config.id
|
|
7528
|
+
});
|
|
7529
|
+
const quickAddPropertyControl = this.getInputControl({
|
|
6913
7530
|
type: "text",
|
|
6914
|
-
id: "jedi-add-property-input-" + config.id,
|
|
7531
|
+
id: "jedi-quick-add-property-input-" + config.id,
|
|
6915
7532
|
title: config.addPropertyContent
|
|
6916
7533
|
});
|
|
6917
|
-
const
|
|
7534
|
+
const quickAddPropertyBtn = this.getAddPropertyButton({
|
|
6918
7535
|
content: config.addPropertyContent,
|
|
6919
7536
|
icon: "add"
|
|
6920
7537
|
});
|
|
7538
|
+
const quickAddPropertyToggle = this.getQuickAddPropertyToggle({
|
|
7539
|
+
content: config.addPropertyContent,
|
|
7540
|
+
icon: "add",
|
|
7541
|
+
propertiesContainer: quickAddPropertyContainer
|
|
7542
|
+
});
|
|
6921
7543
|
const fieldset = this.getFieldset();
|
|
6922
|
-
const { legend, infoContainer, legendText } = this.getLegend({
|
|
7544
|
+
const { legend, infoContainer, legendText, right } = this.getLegend({
|
|
6923
7545
|
content: config.title,
|
|
6924
7546
|
id: config.id,
|
|
6925
7547
|
titleHidden: config.titleHidden
|
|
@@ -6927,9 +7549,13 @@ class Theme {
|
|
|
6927
7549
|
if (((_a = config == null ? void 0 : config.info) == null ? void 0 : _a.variant) === "modal") {
|
|
6928
7550
|
this.infoAsModal(info, config.id, config.info);
|
|
6929
7551
|
}
|
|
6930
|
-
addPropertyBtn.classList.add("jedi-object-add");
|
|
6931
7552
|
container.appendChild(fieldset);
|
|
6932
7553
|
container.appendChild(propertiesContainer);
|
|
7554
|
+
container.appendChild(quickAddPropertyContainer);
|
|
7555
|
+
if (config.addProperty) {
|
|
7556
|
+
quickAddPropertyContainer.appendChild(quickAddPropertyControl.container);
|
|
7557
|
+
quickAddPropertyContainer.appendChild(quickAddPropertyBtn);
|
|
7558
|
+
}
|
|
6933
7559
|
if (config.editJsonData) {
|
|
6934
7560
|
container.appendChild(jsonData.dialog);
|
|
6935
7561
|
}
|
|
@@ -6943,18 +7569,19 @@ class Theme {
|
|
|
6943
7569
|
body.appendChild(description);
|
|
6944
7570
|
}
|
|
6945
7571
|
body.appendChild(messages);
|
|
7572
|
+
const switcherSlot = document.createElement("div");
|
|
7573
|
+
switcherSlot.classList.add("jedi-switcher-slot");
|
|
6946
7574
|
if (config.readOnly === false) {
|
|
6947
|
-
|
|
7575
|
+
right.appendChild(switcherSlot);
|
|
7576
|
+
right.appendChild(actions);
|
|
6948
7577
|
}
|
|
6949
7578
|
body.appendChild(childrenSlot);
|
|
6950
|
-
if (config.addProperty) {
|
|
6951
|
-
propertiesContainer.appendChild(addPropertyControl.container);
|
|
6952
|
-
propertiesContainer.appendChild(addPropertyBtn);
|
|
6953
|
-
propertiesContainer.appendChild(document.createElement("hr"));
|
|
6954
|
-
}
|
|
6955
7579
|
if (config.editJsonData) {
|
|
6956
7580
|
actions.appendChild(jsonData.toggle);
|
|
6957
7581
|
}
|
|
7582
|
+
if (config.addProperty) {
|
|
7583
|
+
actions.appendChild(quickAddPropertyToggle);
|
|
7584
|
+
}
|
|
6958
7585
|
if (config.enablePropertiesToggle) {
|
|
6959
7586
|
actions.appendChild(propertiesToggle);
|
|
6960
7587
|
propertiesContainer.appendChild(ariaLive);
|
|
@@ -6975,13 +7602,17 @@ class Theme {
|
|
|
6975
7602
|
propertiesToggle,
|
|
6976
7603
|
jsonData,
|
|
6977
7604
|
propertiesContainer,
|
|
6978
|
-
|
|
6979
|
-
|
|
7605
|
+
quickAddPropertyContainer,
|
|
7606
|
+
quickAddPropertyControl,
|
|
7607
|
+
quickAddPropertyBtn,
|
|
7608
|
+
quickAddPropertyToggle,
|
|
6980
7609
|
ariaLive,
|
|
6981
7610
|
propertiesActivators,
|
|
6982
7611
|
legend,
|
|
6983
7612
|
legendText,
|
|
6984
|
-
infoContainer
|
|
7613
|
+
infoContainer,
|
|
7614
|
+
right,
|
|
7615
|
+
switcherSlot
|
|
6985
7616
|
};
|
|
6986
7617
|
}
|
|
6987
7618
|
/**
|
|
@@ -7002,7 +7633,7 @@ class Theme {
|
|
|
7002
7633
|
});
|
|
7003
7634
|
const fieldset = this.getFieldset();
|
|
7004
7635
|
const info = this.getInfo(config.info);
|
|
7005
|
-
const { legend, legendText, infoContainer } = this.getLegend({
|
|
7636
|
+
const { legend, legendText, infoContainer, right } = this.getLegend({
|
|
7006
7637
|
content: config.title,
|
|
7007
7638
|
id: config.id,
|
|
7008
7639
|
titleHidden: config.titleHidden
|
|
@@ -7042,7 +7673,12 @@ class Theme {
|
|
|
7042
7673
|
body.appendChild(description);
|
|
7043
7674
|
}
|
|
7044
7675
|
body.appendChild(messages);
|
|
7045
|
-
|
|
7676
|
+
const switcherSlot = document.createElement("div");
|
|
7677
|
+
switcherSlot.classList.add("jedi-switcher-slot");
|
|
7678
|
+
if (config.readOnly === false) {
|
|
7679
|
+
right.appendChild(switcherSlot);
|
|
7680
|
+
right.appendChild(actions);
|
|
7681
|
+
}
|
|
7046
7682
|
actions.appendChild(btnGroup);
|
|
7047
7683
|
if (config.editJsonData) {
|
|
7048
7684
|
btnGroup.appendChild(jsonData.toggle);
|
|
@@ -7066,7 +7702,8 @@ class Theme {
|
|
|
7066
7702
|
addBtn,
|
|
7067
7703
|
jsonData,
|
|
7068
7704
|
legend,
|
|
7069
|
-
legendText
|
|
7705
|
+
legendText,
|
|
7706
|
+
switcherSlot
|
|
7070
7707
|
};
|
|
7071
7708
|
}
|
|
7072
7709
|
getArrayItem(config = {}) {
|
|
@@ -7102,8 +7739,10 @@ class Theme {
|
|
|
7102
7739
|
const messages = this.getMessagesSlot();
|
|
7103
7740
|
const childrenSlot = this.getChildrenSlot();
|
|
7104
7741
|
const randomId = generateRandomID(5);
|
|
7742
|
+
const knownSwitchers = ["select", "radios", "radios-inline"];
|
|
7743
|
+
const switcherType = knownSwitchers.includes(config.switcher) ? config.switcher : "select";
|
|
7105
7744
|
let switcher;
|
|
7106
|
-
if (
|
|
7745
|
+
if (switcherType === "select") {
|
|
7107
7746
|
switcher = this.getSwitcherSelect({
|
|
7108
7747
|
values: config.switcherOptionValues,
|
|
7109
7748
|
titles: config.switcherOptionsLabels,
|
|
@@ -7111,10 +7750,11 @@ class Theme {
|
|
|
7111
7750
|
id: config.id + "-switcher-" + randomId,
|
|
7112
7751
|
label: config.id + "-switcher-" + randomId,
|
|
7113
7752
|
titleHidden: true,
|
|
7114
|
-
readOnly: config.readOnly
|
|
7753
|
+
readOnly: config.readOnly,
|
|
7754
|
+
noSpacing: true
|
|
7115
7755
|
});
|
|
7116
7756
|
}
|
|
7117
|
-
if (
|
|
7757
|
+
if (switcherType === "radios" || switcherType === "radios-inline") {
|
|
7118
7758
|
switcher = this.getSwitcherRadios({
|
|
7119
7759
|
values: config.switcherOptionValues,
|
|
7120
7760
|
titles: config.switcherOptionsLabels,
|
|
@@ -7123,7 +7763,8 @@ class Theme {
|
|
|
7123
7763
|
label: config.id + "-switcher-" + randomId,
|
|
7124
7764
|
titleHidden: true,
|
|
7125
7765
|
readOnly: config.readOnly,
|
|
7126
|
-
inline:
|
|
7766
|
+
inline: switcherType === "radios-inline",
|
|
7767
|
+
noSpacing: true
|
|
7127
7768
|
});
|
|
7128
7769
|
}
|
|
7129
7770
|
switcher.container.classList.add("jedi-switcher");
|
|
@@ -7661,6 +8302,8 @@ class Theme {
|
|
|
7661
8302
|
tabList.classList.add("jedi-nav-list");
|
|
7662
8303
|
return tabList;
|
|
7663
8304
|
}
|
|
8305
|
+
styleLegendWarning(span) {
|
|
8306
|
+
}
|
|
7664
8307
|
/**
|
|
7665
8308
|
* A Tab is a wrapper for content
|
|
7666
8309
|
*/
|
|
@@ -7972,7 +8615,9 @@ class ThemeBootstrap3 extends Theme {
|
|
|
7972
8615
|
getSelectControl(config) {
|
|
7973
8616
|
const control = super.getSelectControl(config);
|
|
7974
8617
|
const { container, input, label } = control;
|
|
7975
|
-
|
|
8618
|
+
if (!config.noSpacing) {
|
|
8619
|
+
container.classList.add("form-group");
|
|
8620
|
+
}
|
|
7976
8621
|
input.classList.add("form-control");
|
|
7977
8622
|
if (config.titleHidden) {
|
|
7978
8623
|
this.visuallyHidden(label);
|
|
@@ -8272,7 +8917,9 @@ class ThemeBootstrap4 extends Theme {
|
|
|
8272
8917
|
getRadiosControl(config) {
|
|
8273
8918
|
const control = super.getRadiosControl(config);
|
|
8274
8919
|
const { container, fieldset, radios, labels, labelTexts, radioControls, description, messages } = control;
|
|
8275
|
-
|
|
8920
|
+
if (!config.noSpacing) {
|
|
8921
|
+
container.classList.add("form-group");
|
|
8922
|
+
}
|
|
8276
8923
|
radioControls.forEach((radioControl, index2) => {
|
|
8277
8924
|
radioControl.classList.add("form-check");
|
|
8278
8925
|
radios[index2].classList.add("form-check-input");
|
|
@@ -8344,7 +8991,9 @@ class ThemeBootstrap4 extends Theme {
|
|
|
8344
8991
|
getSelectControl(config) {
|
|
8345
8992
|
const control = super.getSelectControl(config);
|
|
8346
8993
|
const { container, input } = control;
|
|
8347
|
-
|
|
8994
|
+
if (!config.noSpacing) {
|
|
8995
|
+
container.classList.add("form-group");
|
|
8996
|
+
}
|
|
8348
8997
|
input.classList.add("form-control");
|
|
8349
8998
|
return control;
|
|
8350
8999
|
}
|
|
@@ -8553,6 +9202,9 @@ class ThemeBootstrap5 extends Theme {
|
|
|
8553
9202
|
legend.classList.add("py-2");
|
|
8554
9203
|
return superLegend;
|
|
8555
9204
|
}
|
|
9205
|
+
styleLegendWarning(span) {
|
|
9206
|
+
span.classList.add("ms-1");
|
|
9207
|
+
}
|
|
8556
9208
|
getLabel(config) {
|
|
8557
9209
|
const labelObj = super.getLabel(config);
|
|
8558
9210
|
if (labelObj.icon.classList) {
|
|
@@ -8651,7 +9303,9 @@ class ThemeBootstrap5 extends Theme {
|
|
|
8651
9303
|
getRadiosControl(config) {
|
|
8652
9304
|
const control = super.getRadiosControl(config);
|
|
8653
9305
|
const { container, fieldset, radios, labels, labelTexts, radioControls, description, messages } = control;
|
|
8654
|
-
|
|
9306
|
+
if (!config.noSpacing) {
|
|
9307
|
+
container.classList.add("mb-3");
|
|
9308
|
+
}
|
|
8655
9309
|
radioControls.forEach((radioControl, index2) => {
|
|
8656
9310
|
radioControl.classList.add("form-check");
|
|
8657
9311
|
radios[index2].classList.add("form-check-input");
|
|
@@ -8716,7 +9370,9 @@ class ThemeBootstrap5 extends Theme {
|
|
|
8716
9370
|
getSelectControl(config) {
|
|
8717
9371
|
const control = super.getSelectControl(config);
|
|
8718
9372
|
const { container, input } = control;
|
|
8719
|
-
|
|
9373
|
+
if (!config.noSpacing) {
|
|
9374
|
+
container.classList.add("mb-3");
|
|
9375
|
+
}
|
|
8720
9376
|
input.classList.add("form-select");
|
|
8721
9377
|
return control;
|
|
8722
9378
|
}
|