jedison 0.3.11 → 0.3.13

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.
@@ -1814,6 +1814,12 @@ class Instance extends EventEmitter {
1814
1814
  * @returns {*} The final value after constraint enforcement
1815
1815
  */
1816
1816
  setValue(newValue, notifyParent = true, initiator = "api") {
1817
+ if (this.value === newValue) {
1818
+ return this.value;
1819
+ }
1820
+ if (typeof this.value !== "object" && typeof newValue !== "object" && this.value === newValue) {
1821
+ return this.value;
1822
+ }
1817
1823
  const enforceConst = getSchemaXOption(this.schema, "enforceConst") ?? this.jedison.options.enforceConst;
1818
1824
  if (isSet(enforceConst) && equal(enforceConst, true)) {
1819
1825
  const schemaConst = getSchemaConst(this.schema);
@@ -1822,15 +1828,16 @@ class Instance extends EventEmitter {
1822
1828
  }
1823
1829
  }
1824
1830
  const valueChanged = different(this.value, newValue);
1831
+ if (!valueChanged) {
1832
+ return this.value;
1833
+ }
1825
1834
  this.value = newValue;
1835
+ this.isDirty = true;
1826
1836
  this.emit("set-value", newValue, initiator);
1827
- if (valueChanged) {
1828
- this.isDirty = true;
1829
- this.emit("change", initiator);
1830
- this.jedison.emit("instance-change", this, initiator);
1831
- if (notifyParent) {
1832
- this.emit("notifyParent", initiator);
1833
- }
1837
+ this.emit("change", initiator);
1838
+ this.jedison.emit("instance-change", this, initiator);
1839
+ if (notifyParent) {
1840
+ this.emit("notifyParent", initiator);
1834
1841
  }
1835
1842
  return this.value;
1836
1843
  }
@@ -1909,6 +1916,8 @@ class Editor {
1909
1916
  this.disabled = false;
1910
1917
  this.readOnly = this.instance.isReadOnly();
1911
1918
  this.showingValidationErrors = false;
1919
+ this.markdownEnabled = false;
1920
+ this.purifyEnabled = false;
1912
1921
  this.title = null;
1913
1922
  this.description = null;
1914
1923
  this.init();
@@ -1935,6 +1944,8 @@ class Editor {
1935
1944
  */
1936
1945
  init() {
1937
1946
  this.theme = this.instance.jedison.theme;
1947
+ this.markdownEnabled = getSchemaXOption(this.instance.schema, "parseMarkdown") ?? this.instance.jedison.options.parseMarkdown;
1948
+ this.purifyEnabled = getSchemaXOption(this.instance.schema, "purifyHtml") ?? this.instance.jedison.options.purifyHtml;
1938
1949
  }
1939
1950
  /**
1940
1951
  * Gets the json path level by counting how many "/" it has
@@ -2072,10 +2083,7 @@ class Editor {
2072
2083
  }
2073
2084
  }
2074
2085
  getHtmlFromMarkdown(content) {
2075
- if (this.instance.jedison.options.parseMarkdown && window.marked) {
2076
- return window.marked.parse(content);
2077
- }
2078
- return content;
2086
+ return window.marked.parse(content);
2079
2087
  }
2080
2088
  getTitle() {
2081
2089
  let titleFromSchema = false;
@@ -2087,11 +2095,11 @@ class Editor {
2087
2095
  }
2088
2096
  if (titleFromSchema) {
2089
2097
  this.title = compileTemplate(this.title, this.instance.getTemplateData());
2090
- this.title = this.getHtmlFromMarkdown(this.title);
2098
+ this.title = this.markdownEnabled ? this.getHtmlFromMarkdown(this.title) : this.title;
2091
2099
  const domPurifyOptions = combineDeep({}, this.instance.jedison.options.domPurifyOptions, {
2092
2100
  FORBID_TAGS: ["p"]
2093
2101
  });
2094
- this.title = this.purifyContent(this.title, domPurifyOptions);
2102
+ this.title = this.purifyEnabled ? this.purifyContent(this.title, domPurifyOptions) : this.title;
2095
2103
  }
2096
2104
  return this.title;
2097
2105
  }
@@ -2099,9 +2107,9 @@ class Editor {
2099
2107
  const schemaDescription = getSchemaDescription(this.instance.schema);
2100
2108
  if (isSet(schemaDescription)) {
2101
2109
  this.description = compileTemplate(schemaDescription, this.instance.getTemplateData());
2102
- this.description = this.getHtmlFromMarkdown(this.description);
2110
+ this.description = this.markdownEnabled ? this.getHtmlFromMarkdown(this.description) : this.description;
2103
2111
  const domPurifyOptions = this.instance.jedison.options.domPurifyOptions;
2104
- this.purifyContent(this.description, domPurifyOptions);
2112
+ this.description = this.purifyEnabled ? this.purifyContent(this.description, domPurifyOptions) : this.description;
2105
2113
  }
2106
2114
  return this.description;
2107
2115
  }
@@ -2113,12 +2121,12 @@ class Editor {
2113
2121
  }
2114
2122
  const domPurifyOptions = this.instance.jedison.options.domPurifyOptions;
2115
2123
  if (isSet(schemaInfo.title)) {
2116
- schemaInfo.title = this.getHtmlFromMarkdown(schemaInfo.title);
2117
- schemaInfo.title = this.purifyContent(schemaInfo.title, domPurifyOptions);
2124
+ schemaInfo.title = this.markdownEnabled ? this.getHtmlFromMarkdown(schemaInfo.title) : schemaInfo.title;
2125
+ schemaInfo.title = this.purifyEnabled ? this.purifyContent(schemaInfo.title, domPurifyOptions) : schemaInfo.title;
2118
2126
  }
2119
2127
  if (isSet(schemaInfo.content)) {
2120
- schemaInfo.content = this.getHtmlFromMarkdown(schemaInfo.content);
2121
- schemaInfo.content = this.purifyContent(schemaInfo.content, domPurifyOptions);
2128
+ schemaInfo.content = this.markdownEnabled ? this.getHtmlFromMarkdown(schemaInfo.content) : schemaInfo.content;
2129
+ schemaInfo.content = this.purifyEnabled ? this.purifyContent(schemaInfo.content, domPurifyOptions) : schemaInfo.content;
2122
2130
  }
2123
2131
  return schemaInfo;
2124
2132
  }
@@ -3350,7 +3358,7 @@ class EditorNumberInput extends EditorNumber {
3350
3358
  });
3351
3359
  this.control.input.addEventListener("focus", () => {
3352
3360
  if (this.control.input.value === "0") {
3353
- this.control.input.value = this.instance.getValue().toString;
3361
+ this.control.input.value = this.instance.getValue().toString();
3354
3362
  }
3355
3363
  });
3356
3364
  this.control.input.addEventListener("blur", () => {
@@ -4639,6 +4647,94 @@ class EditorArrayCheckboxes extends Editor {
4639
4647
  });
4640
4648
  }
4641
4649
  }
4650
+ class EditorNumberRange extends EditorNumber {
4651
+ static resolves(schema) {
4652
+ const schemaType = getSchemaType(schema);
4653
+ const isNumericType = schemaType === "number" || schemaType === "integer";
4654
+ if (!isNumericType) {
4655
+ return false;
4656
+ }
4657
+ if (getSchemaXOption(schema, "format") === "range") {
4658
+ return true;
4659
+ }
4660
+ const hasMin = isSet(schema.minimum) || isSet(schema.exclusiveMinimum);
4661
+ const hasMax = isSet(schema.maximum) || isSet(schema.exclusiveMaximum);
4662
+ return hasMin && hasMax;
4663
+ }
4664
+ build() {
4665
+ let optionMin = 0;
4666
+ let optionMax = 100;
4667
+ if (isSet(this.instance.schema.minimum)) {
4668
+ optionMin = this.instance.schema.minimum;
4669
+ } else if (isSet(this.instance.schema.exclusiveMinimum)) {
4670
+ optionMin = this.instance.schema.exclusiveMinimum + 0.01;
4671
+ }
4672
+ if (isSet(this.instance.schema.maximum)) {
4673
+ optionMax = this.instance.schema.maximum;
4674
+ } else if (isSet(this.instance.schema.exclusiveMaximum)) {
4675
+ optionMax = this.instance.schema.exclusiveMaximum - 0.01;
4676
+ }
4677
+ let optionStep;
4678
+ const schemaType = getSchemaType(this.instance.schema);
4679
+ const multipleOf2 = this.instance.schema.multipleOf;
4680
+ if (isSet(multipleOf2)) {
4681
+ optionStep = multipleOf2;
4682
+ } else if (schemaType === "integer") {
4683
+ optionStep = 1;
4684
+ } else {
4685
+ optionStep = 0.01;
4686
+ }
4687
+ this.control = this.theme.getInputRangeControl({
4688
+ title: this.getTitle(),
4689
+ description: this.getDescription(),
4690
+ type: "range",
4691
+ id: this.getIdFromPath(this.instance.path),
4692
+ titleIconClass: getSchemaXOption(this.instance.schema, "titleIconClass"),
4693
+ titleHidden: getSchemaXOption(this.instance.schema, "titleHidden"),
4694
+ info: this.getInfo()
4695
+ });
4696
+ this.control.input.setAttribute("min", optionMin);
4697
+ this.control.input.setAttribute("max", optionMax);
4698
+ this.control.input.setAttribute("step", optionStep);
4699
+ const inputAttributes = getSchemaXOption(this.instance.schema, "inputAttributes");
4700
+ if (inputAttributes && typeof inputAttributes === "object") {
4701
+ Object.keys(inputAttributes).forEach((attr) => {
4702
+ this.control.input.setAttribute(attr, inputAttributes[attr]);
4703
+ });
4704
+ }
4705
+ const currentValue = this.instance.getValue();
4706
+ this.control.output.textContent = currentValue !== void 0 ? currentValue : optionMin;
4707
+ }
4708
+ adaptForTable() {
4709
+ this.theme.adaptForTableInputControl(this.control);
4710
+ }
4711
+ addEventListeners() {
4712
+ this.control.input.addEventListener("input", () => {
4713
+ this.control.output.textContent = parseFloat(this.control.input.value);
4714
+ });
4715
+ this.control.input.addEventListener("change", () => {
4716
+ const value = parseFloat(this.control.input.value);
4717
+ this.control.output.textContent = value;
4718
+ this.instance.setValue(value, true, "user");
4719
+ });
4720
+ }
4721
+ sanitize(value) {
4722
+ const schemaType = getSchemaType(this.instance.schema);
4723
+ const numValue = Number(value);
4724
+ if (schemaType === "integer") {
4725
+ return Math.round(numValue);
4726
+ }
4727
+ return numValue;
4728
+ }
4729
+ refreshUI() {
4730
+ super.refreshUI();
4731
+ const currentValue = this.instance.getValue();
4732
+ this.control.input.value = currentValue !== void 0 ? currentValue : 0;
4733
+ if (this.control.output) {
4734
+ this.control.output.textContent = currentValue !== void 0 ? currentValue : 0;
4735
+ }
4736
+ }
4737
+ }
4642
4738
  class UiResolver {
4643
4739
  constructor(options) {
4644
4740
  this.customEditors = options.customEditors ?? [];
@@ -4663,6 +4759,7 @@ class UiResolver {
4663
4759
  EditorStringInput,
4664
4760
  EditorNumberIMask,
4665
4761
  EditorNumberRaty,
4762
+ EditorNumberRange,
4666
4763
  EditorNumberRadios,
4667
4764
  EditorNumberSelect,
4668
4765
  EditorNumberInput,
@@ -5013,7 +5110,7 @@ class Jedison extends EventEmitter {
5013
5110
  }, options);
5014
5111
  this.rootName = "#";
5015
5112
  this.pathSeparator = "/";
5016
- this.instances = {};
5113
+ this.instances = /* @__PURE__ */ new Map();
5017
5114
  this.root = null;
5018
5115
  this.translator = new Translator({
5019
5116
  language: this.options.language,
@@ -5190,14 +5287,13 @@ class Jedison extends EventEmitter {
5190
5287
  * Adds a child instance pointer to the instances list
5191
5288
  */
5192
5289
  register(instance) {
5193
- this.instances[instance.path] = instance;
5290
+ this.instances.set(instance.path, instance);
5194
5291
  }
5195
5292
  /**
5196
5293
  * Deletes a child instance pointer from the instances list
5197
5294
  */
5198
5295
  unregister(instance) {
5199
- this.instances[instance.path] = null;
5200
- delete this.instances[instance.path];
5296
+ this.instances.delete(instance.path);
5201
5297
  }
5202
5298
  logIfEditor(...params) {
5203
5299
  if (this.isEditor) {
@@ -5355,7 +5451,7 @@ class Jedison extends EventEmitter {
5355
5451
  * @return {*}
5356
5452
  */
5357
5453
  getInstance(path) {
5358
- return this.instances[path];
5454
+ return this.instances.get(path);
5359
5455
  }
5360
5456
  /**
5361
5457
  * Disables the root instance and it's children user interfaces
@@ -5376,25 +5472,23 @@ class Jedison extends EventEmitter {
5376
5472
  */
5377
5473
  getErrors(filters = ["error"]) {
5378
5474
  let results = [];
5379
- Object.keys(this.instances).forEach((key) => {
5380
- const instance = this.instances[key];
5475
+ for (const instance of this.instances.values()) {
5381
5476
  results = [...results, ...instance.getErrors()];
5382
- });
5477
+ }
5383
5478
  return results.filter((error) => {
5384
5479
  return filters.includes(error.type.toLowerCase());
5385
5480
  });
5386
5481
  }
5387
5482
  export() {
5388
5483
  const results = [];
5389
- Object.keys(this.instances).forEach((key) => {
5390
- const instance = this.instances[key];
5484
+ for (const instance of this.instances.values()) {
5391
5485
  results.push({
5392
5486
  path: instance.path ?? "-",
5393
5487
  type: instance.schema.type ?? "-",
5394
5488
  title: instance.ui.getTitle() ?? "-",
5395
5489
  value: instance.getValue() ?? "-"
5396
5490
  });
5397
- });
5491
+ }
5398
5492
  return results;
5399
5493
  }
5400
5494
  /**
@@ -5411,10 +5505,9 @@ class Jedison extends EventEmitter {
5411
5505
  return false;
5412
5506
  }
5413
5507
  const errors = errorsList ?? this.getErrors();
5414
- Object.keys(this.instances).forEach((key) => {
5415
- const instance = this.instances[key];
5508
+ for (const instance of this.instances.values()) {
5416
5509
  instance.ui.showValidationErrors(errors, true);
5417
- });
5510
+ }
5418
5511
  }
5419
5512
  watch(path, callback) {
5420
5513
  if (!this.watched[path]) {
@@ -6571,6 +6664,15 @@ class Theme {
6571
6664
  container.appendChild(actions);
6572
6665
  return { container, input, label, info, labelText, description, messages, actions };
6573
6666
  }
6667
+ getInputRangeControl(config) {
6668
+ const control = this.getInputControl(config);
6669
+ const output = document.createElement("output");
6670
+ output.className = "range-output";
6671
+ output.style.marginLeft = "10px";
6672
+ output.style.fontWeight = "bold";
6673
+ control.input.parentNode.insertBefore(output, control.input.nextSibling);
6674
+ return { ...control, output };
6675
+ }
6574
6676
  adaptForTableInputControl(control) {
6575
6677
  this.visuallyHidden(control.label);
6576
6678
  this.visuallyHidden(control.description);
@@ -6938,7 +7040,7 @@ class Theme {
6938
7040
  const arrayActions = document.createElement("span");
6939
7041
  const text = document.createElement("span");
6940
7042
  link.classList.add("jedi-nav-link");
6941
- link.setAttribute("href", "#" + config.id);
7043
+ link.setAttribute("href", "#tab-pane-" + config.id);
6942
7044
  text.classList.add("jedi-nav-text");
6943
7045
  text.textContent = config.hasErrors ? "⚠ " + config.title : config.title;
6944
7046
  link.appendChild(arrayActions);
@@ -6993,7 +7095,7 @@ class Theme {
6993
7095
  * Set tab attributes to make it toggleable
6994
7096
  */
6995
7097
  setTabPaneAttributes(element, active, id) {
6996
- element.setAttribute("id", id);
7098
+ element.setAttribute("id", "tab-pane-" + id);
6997
7099
  element.classList.add("jedi-tab-pane");
6998
7100
  }
6999
7101
  /**
@@ -7148,6 +7250,9 @@ class ThemeBootstrap3 extends Theme {
7148
7250
  }
7149
7251
  return control;
7150
7252
  }
7253
+ getInputRangeControl(config) {
7254
+ return super.getInputRangeControl(config);
7255
+ }
7151
7256
  adaptForTableInputControl(control, td) {
7152
7257
  super.adaptForTableInputControl(control, td);
7153
7258
  control.container.classList.remove("form-group");
@@ -7472,6 +7577,17 @@ class ThemeBootstrap4 extends Theme {
7472
7577
  }
7473
7578
  return control;
7474
7579
  }
7580
+ getInputRangeControl(config) {
7581
+ const control = super.getInputRangeControl(config);
7582
+ const { container, input, label } = control;
7583
+ container.classList.add("form-group");
7584
+ input.classList.add("custom-range");
7585
+ input.classList.remove("form-control");
7586
+ if (config.titleHidden) {
7587
+ this.visuallyHidden(label);
7588
+ }
7589
+ return control;
7590
+ }
7475
7591
  adaptForTableInputControl(control, td) {
7476
7592
  super.adaptForTableInputControl(control, td);
7477
7593
  control.container.classList.remove("form-group");
@@ -7820,6 +7936,17 @@ class ThemeBootstrap5 extends Theme {
7820
7936
  }
7821
7937
  return control;
7822
7938
  }
7939
+ getInputRangeControl(config) {
7940
+ const control = super.getInputRangeControl(config);
7941
+ const { container, input, label } = control;
7942
+ container.classList.add("mb-3");
7943
+ input.classList.add("form-range");
7944
+ input.classList.remove("form-control");
7945
+ if (config.titleHidden) {
7946
+ this.visuallyHidden(label);
7947
+ }
7948
+ return control;
7949
+ }
7823
7950
  adaptForTableInputControl(control, td) {
7824
7951
  super.adaptForTableInputControl(control, td);
7825
7952
  control.container.classList.remove("mb-3");
@@ -8048,6 +8175,7 @@ const index = {
8048
8175
  EditorStringTextarea,
8049
8176
  EditorStringAwesomplete,
8050
8177
  EditorStringInput,
8178
+ EditorNumberRange,
8051
8179
  EditorNumber,
8052
8180
  EditorNumberRadios,
8053
8181
  EditorNumberSelect,