@schukai/monster 3.97.1 → 3.98.1
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/package.json +1 -1
- package/source/components/accessibility/locale-picker.mjs +549 -543
- package/source/components/datatable/columnbar.mjs +50 -3
- package/source/components/datatable/constants.mjs +7 -0
- package/source/components/datatable/datatable/header.mjs +1 -0
- package/source/components/datatable/datatable.mjs +1168 -942
- package/source/components/datatable/filter/date-range.mjs +145 -14
- package/source/components/datatable/filter/input.mjs +50 -3
- package/source/components/datatable/filter/range.mjs +92 -7
- package/source/components/datatable/filter-button.mjs +46 -3
- package/source/components/datatable/filter.mjs +95 -10
- package/source/components/datatable/pagination.mjs +82 -7
- package/source/components/datatable/save-button.mjs +46 -3
- package/source/components/datatable/style/datatable.pcss +1 -0
- package/source/components/datatable/stylesheet/datatable.mjs +7 -14
- package/source/components/form/field-set.mjs +77 -6
- package/source/components/form/select.mjs +149 -30
- package/source/components/layout/details.mjs +50 -3
- package/source/components/layout/tabs.mjs +50 -3
- package/source/components/notify/monitor-attribute-errors.mjs +235 -0
- package/source/components/notify/style/monitor-attribute-errors.pcss +0 -0
- package/source/components/notify/stylesheet/monitor-attribute-errors.mjs +38 -0
- package/source/dom/customelement.mjs +3 -3
- package/source/i18n/util.mjs +122 -122
- package/source/types/version.mjs +1 -1
- package/test/cases/monster.mjs +1 -1
- package/test/web/import.js +1 -0
- package/test/web/test.html +2 -2
- package/test/web/tests.js +432 -13
@@ -28,6 +28,7 @@ import { isFunction } from "../../types/is.mjs";
|
|
28
28
|
import { FieldSetStyleSheet } from "./stylesheet/field-set.mjs";
|
29
29
|
import "../layout/collapse.mjs";
|
30
30
|
import "./toggle-switch.mjs";
|
31
|
+
import {getLocaleOfDocument} from "../../dom/locale.mjs";
|
31
32
|
|
32
33
|
export { FieldSet };
|
33
34
|
|
@@ -120,12 +121,7 @@ class FieldSet extends CustomControl {
|
|
120
121
|
templates: {
|
121
122
|
main: getTemplate(),
|
122
123
|
},
|
123
|
-
labels:
|
124
|
-
toggleSwitchOn: "✔",
|
125
|
-
toggleSwitchOff: "✖",
|
126
|
-
toggleSwitchLabel: "Expand",
|
127
|
-
title: "",
|
128
|
-
},
|
124
|
+
labels:getTranslations(),
|
129
125
|
classes: {},
|
130
126
|
disabled: false,
|
131
127
|
features: {
|
@@ -246,6 +242,81 @@ class FieldSet extends CustomControl {
|
|
246
242
|
}
|
247
243
|
}
|
248
244
|
|
245
|
+
/**
|
246
|
+
* @private
|
247
|
+
* @returns {object}
|
248
|
+
*/
|
249
|
+
function getTranslations() {
|
250
|
+
const locale = getLocaleOfDocument();
|
251
|
+
switch (locale.language) {
|
252
|
+
case 'de':
|
253
|
+
return {
|
254
|
+
toggleSwitchOn: "✔",
|
255
|
+
toggleSwitchOff: "✖",
|
256
|
+
toggleSwitchLabel: "Erweitern",
|
257
|
+
title: ""
|
258
|
+
};
|
259
|
+
case 'fr':
|
260
|
+
return {
|
261
|
+
toggleSwitchOn: "✔",
|
262
|
+
toggleSwitchOff: "✖",
|
263
|
+
toggleSwitchLabel: "Développer",
|
264
|
+
title: ""
|
265
|
+
};
|
266
|
+
case 'sp':
|
267
|
+
return {
|
268
|
+
toggleSwitchOn: "✔",
|
269
|
+
toggleSwitchOff: "✖",
|
270
|
+
toggleSwitchLabel: "Expandir",
|
271
|
+
title: ""
|
272
|
+
};
|
273
|
+
case 'it':
|
274
|
+
return {
|
275
|
+
toggleSwitchOn: "✔",
|
276
|
+
toggleSwitchOff: "✖",
|
277
|
+
toggleSwitchLabel: "Espandi",
|
278
|
+
title: ""
|
279
|
+
};
|
280
|
+
case 'pl':
|
281
|
+
return {
|
282
|
+
toggleSwitchOn: "✔",
|
283
|
+
toggleSwitchOff: "✖",
|
284
|
+
toggleSwitchLabel: "Rozwiń",
|
285
|
+
title: ""
|
286
|
+
};
|
287
|
+
case 'no':
|
288
|
+
return {
|
289
|
+
toggleSwitchOn: "✔",
|
290
|
+
toggleSwitchOff: "✖",
|
291
|
+
toggleSwitchLabel: "Utvid",
|
292
|
+
title: ""
|
293
|
+
};
|
294
|
+
case 'dk':
|
295
|
+
return {
|
296
|
+
toggleSwitchOn: "✔",
|
297
|
+
toggleSwitchOff: "✖",
|
298
|
+
toggleSwitchLabel: "Udvid",
|
299
|
+
title: ""
|
300
|
+
};
|
301
|
+
case 'sw':
|
302
|
+
return {
|
303
|
+
toggleSwitchOn: "✔",
|
304
|
+
toggleSwitchOff: "✖",
|
305
|
+
toggleSwitchLabel: "Expandera",
|
306
|
+
title: ""
|
307
|
+
};
|
308
|
+
default:
|
309
|
+
case 'en':
|
310
|
+
return {
|
311
|
+
toggleSwitchOn: "✔",
|
312
|
+
toggleSwitchOff: "✖",
|
313
|
+
toggleSwitchLabel: "Expand",
|
314
|
+
title: ""
|
315
|
+
};
|
316
|
+
}
|
317
|
+
}
|
318
|
+
|
319
|
+
|
249
320
|
/**
|
250
321
|
* @private
|
251
322
|
*/
|
@@ -61,6 +61,7 @@ import {
|
|
61
61
|
getDocumentTranslations,
|
62
62
|
Translations,
|
63
63
|
} from "../../i18n/translations.mjs";
|
64
|
+
import {getLocaleOfDocument} from "../../dom/locale.mjs";
|
64
65
|
|
65
66
|
export {
|
66
67
|
Select,
|
@@ -69,18 +70,6 @@ export {
|
|
69
70
|
getSelectionTemplate,
|
70
71
|
};
|
71
72
|
|
72
|
-
/**
|
73
|
-
* @private
|
74
|
-
* @type {string}
|
75
|
-
*/
|
76
|
-
const noOptionsAvailableMessage = "No options available.";
|
77
|
-
|
78
|
-
/**
|
79
|
-
* @private
|
80
|
-
* @type {string}
|
81
|
-
*/
|
82
|
-
const clickToLoadOptionsMessage = "Click to load options.";
|
83
|
-
|
84
73
|
/**
|
85
74
|
* @private
|
86
75
|
* @type {Symbol}
|
@@ -438,22 +427,7 @@ class Select extends CustomControl {
|
|
438
427
|
url: null,
|
439
428
|
grouping: false,
|
440
429
|
},
|
441
|
-
labels:
|
442
|
-
"cannot-be-loaded": "Cannot be loaded",
|
443
|
-
"no-options-available": noOptionsAvailableMessage,
|
444
|
-
"click-to-load-options": clickToLoadOptionsMessage,
|
445
|
-
"select-an-option": "Select an option",
|
446
|
-
"summary-text": {
|
447
|
-
zero: "No entries were selected",
|
448
|
-
one: '<span class="monster-badge-primary-pill">1</span> entry was selected',
|
449
|
-
other:
|
450
|
-
'<span class="monster-badge-primary-pill">${count}</span> entries were selected',
|
451
|
-
},
|
452
|
-
"no-options":
|
453
|
-
"Unfortunately, there are no options available in the list.",
|
454
|
-
"no-options-found":
|
455
|
-
"No options are available in the list. Please consider modifying the filter.",
|
456
|
-
},
|
430
|
+
labels: getTranslations(),
|
457
431
|
messages: {
|
458
432
|
control: null,
|
459
433
|
selected: null,
|
@@ -778,6 +752,147 @@ class Select extends CustomControl {
|
|
778
752
|
}
|
779
753
|
}
|
780
754
|
|
755
|
+
/**
|
756
|
+
* @private
|
757
|
+
* @returns {object}
|
758
|
+
*/
|
759
|
+
function getTranslations() {
|
760
|
+
const locale = getLocaleOfDocument();
|
761
|
+
switch (locale.language) {
|
762
|
+
case 'de':
|
763
|
+
return {
|
764
|
+
"cannot-be-loaded": "Kann nicht geladen werden",
|
765
|
+
"no-options-available": "Keine Optionen verfügbar.",
|
766
|
+
"click-to-load-options": "Klicken, um Optionen zu laden.",
|
767
|
+
"select-an-option": "Wähle eine Option",
|
768
|
+
"summary-text": {
|
769
|
+
zero: "Keine Einträge ausgewählt",
|
770
|
+
one: '<span class="monster-badge-primary-pill">1</span> Eintrag ausgewählt',
|
771
|
+
other: '<span class="monster-badge-primary-pill">${count}</span> Einträge ausgewählt',
|
772
|
+
},
|
773
|
+
"no-options": "Leider gibt es keine Optionen in der Liste.",
|
774
|
+
"no-options-found": "Keine Optionen in der Liste verfügbar. Bitte ändern Sie den Filter."
|
775
|
+
};
|
776
|
+
case 'fr':
|
777
|
+
return {
|
778
|
+
"cannot-be-loaded": "Impossible de charger",
|
779
|
+
"no-options-available": "Aucune option disponible.",
|
780
|
+
"click-to-load-options": "Cliquez pour charger les options.",
|
781
|
+
"select-an-option": "Sélectionnez une option",
|
782
|
+
"summary-text": {
|
783
|
+
zero: "Aucune entrée sélectionnée",
|
784
|
+
one: '<span class="monster-badge-primary-pill">1</span> entrée sélectionnée',
|
785
|
+
other: '<span class="monster-badge-primary-pill">${count}</span> entrées sélectionnées',
|
786
|
+
},
|
787
|
+
"no-options": "Malheureusement, il n'y a pas d'options disponibles dans la liste.",
|
788
|
+
"no-options-found": "Aucune option disponible dans la liste. Veuillez modifier le filtre."
|
789
|
+
};
|
790
|
+
|
791
|
+
case 'sp':
|
792
|
+
return {
|
793
|
+
"cannot-be-loaded": "No se puede cargar",
|
794
|
+
"no-options-available": "No hay opciones disponibles.",
|
795
|
+
"click-to-load-options": "Haga clic para cargar opciones.",
|
796
|
+
"select-an-option": "Seleccione una opción",
|
797
|
+
"summary-text": {
|
798
|
+
zero: "No se seleccionaron entradas",
|
799
|
+
one: '<span class="monster-badge-primary-pill">1</span> entrada seleccionada',
|
800
|
+
other: '<span class="monster-badge-primary-pill">${count}</span> entradas seleccionadas',
|
801
|
+
},
|
802
|
+
"no-options": "Desafortunadamente, no hay opciones disponibles en la lista.",
|
803
|
+
"no-options-found": "No hay opciones disponibles en la lista. Considere modificar el filtro."
|
804
|
+
};
|
805
|
+
case 'it':
|
806
|
+
return {
|
807
|
+
"cannot-be-loaded": "Non può essere caricato",
|
808
|
+
"no-options-available": "Nessuna opzione disponibile.",
|
809
|
+
"click-to-load-options": "Clicca per caricare le opzioni.",
|
810
|
+
"select-an-option": "Seleziona un'opzione",
|
811
|
+
"summary-text": {
|
812
|
+
zero: "Nessuna voce selezionata",
|
813
|
+
one: '<span class="monster-badge-primary-pill">1</span> voce selezionata',
|
814
|
+
other: '<span class="monster-badge-primary-pill">${count}</span> voci selezionate',
|
815
|
+
},
|
816
|
+
"no-options": "Purtroppo, non ci sono opzioni disponibili nella lista.",
|
817
|
+
"no-options-found": "Nessuna opzione disponibile nella lista. Si prega di modificare il filtro."
|
818
|
+
};
|
819
|
+
case 'pl':
|
820
|
+
return {
|
821
|
+
"cannot-be-loaded": "Nie można załadować",
|
822
|
+
"no-options-available": "Brak dostępnych opcji.",
|
823
|
+
"click-to-load-options": "Kliknij, aby załadować opcje.",
|
824
|
+
"select-an-option": "Wybierz opcję",
|
825
|
+
"summary-text": {
|
826
|
+
zero: "Nie wybrano żadnych wpisów",
|
827
|
+
one: '<span class="monster-badge-primary-pill">1</span> wpis został wybrany',
|
828
|
+
other: '<span class="monster-badge-primary-pill">${count}</span> wpisy zostały wybrane',
|
829
|
+
},
|
830
|
+
"no-options": "Niestety, nie ma dostępnych opcji na liście.",
|
831
|
+
"no-options-found": "Brak dostępnych opcji na liście. Rozważ zmianę filtra."
|
832
|
+
};
|
833
|
+
case 'no':
|
834
|
+
return {
|
835
|
+
"cannot-be-loaded": "Kan ikke lastes",
|
836
|
+
"no-options-available": "Ingen alternativer tilgjengelig.",
|
837
|
+
"click-to-load-options": "Klikk for å laste alternativer.",
|
838
|
+
"select-an-option": "Velg et alternativ",
|
839
|
+
"summary-text": {
|
840
|
+
zero: "Ingen oppføringer ble valgt",
|
841
|
+
one: '<span class="monster-badge-primary-pill">1</span> oppføring valgt',
|
842
|
+
other: '<span class="monster-badge-primary-pill">${count}</span> oppføringer valgt',
|
843
|
+
},
|
844
|
+
"no-options": "Dessverre er det ingen alternativer tilgjengelig i listen.",
|
845
|
+
"no-options-found": "Ingen alternativer tilgjengelig på listen. Vurder å endre filteret."
|
846
|
+
};
|
847
|
+
|
848
|
+
case 'dk':
|
849
|
+
return {
|
850
|
+
"cannot-be-loaded": "Kan ikke indlæses",
|
851
|
+
"no-options-available": "Ingen muligheder tilgængelige.",
|
852
|
+
"click-to-load-options": "Klik for at indlæse muligheder.",
|
853
|
+
"select-an-option": "Vælg en mulighed",
|
854
|
+
"summary-text": {
|
855
|
+
zero: "Ingen indlæg blev valgt",
|
856
|
+
one: '<span class="monster-badge-primary-pill">1</span> indlæg blev valgt',
|
857
|
+
other: '<span class="monster-badge-primary-pill">${count}</span> indlæg blev valgt',
|
858
|
+
},
|
859
|
+
"no-options": "Desværre er der ingen muligheder tilgængelige på listen.",
|
860
|
+
"no-options-found": "Ingen muligheder tilgængelige på listen. Overvej at ændre filteret."
|
861
|
+
};
|
862
|
+
case 'sw':
|
863
|
+
return {
|
864
|
+
"cannot-be-loaded": "Kan inte laddas",
|
865
|
+
"no-options-available": "Inga alternativ tillgängliga.",
|
866
|
+
"click-to-load-options": "Klicka för att ladda alternativ.",
|
867
|
+
"select-an-option": "Välj ett alternativ",
|
868
|
+
"summary-text": {
|
869
|
+
zero: "Inga poster valdes",
|
870
|
+
one: '<span class="monster-badge-primary-pill">1</span> post valdes',
|
871
|
+
other: '<span class="monster-badge-primary-pill">${count}</span> poster valdes',
|
872
|
+
},
|
873
|
+
"no-options": "Tyvärr finns det inga alternativ tillgängliga i listan.",
|
874
|
+
"no-options-found": "Inga alternativ finns tillgängliga i listan. Överväg att modifiera filtret."
|
875
|
+
};
|
876
|
+
|
877
|
+
default:
|
878
|
+
case 'en':
|
879
|
+
return {
|
880
|
+
"cannot-be-loaded": "Cannot be loaded",
|
881
|
+
"no-options-available": "No options available.",
|
882
|
+
"click-to-load-options": "Click to load options.",
|
883
|
+
"select-an-option": "Select an option",
|
884
|
+
"summary-text": {
|
885
|
+
zero: "No entries were selected",
|
886
|
+
one: '<span class="monster-badge-primary-pill">1</span> entry was selected',
|
887
|
+
other: '<span class="monster-badge-primary-pill">${count}</span> entries were selected',
|
888
|
+
},
|
889
|
+
"no-options": "Unfortunately, there are no options available in the list.",
|
890
|
+
"no-options-found": "No options are available in the list. Please consider modifying the filter."
|
891
|
+
};
|
892
|
+
}
|
893
|
+
}
|
894
|
+
|
895
|
+
|
781
896
|
/**
|
782
897
|
* @private
|
783
898
|
*/
|
@@ -1192,6 +1307,10 @@ function initOptionObserver() {
|
|
1192
1307
|
);
|
1193
1308
|
}
|
1194
1309
|
|
1310
|
+
/**
|
1311
|
+
* @private
|
1312
|
+
* @returns {Translations}
|
1313
|
+
*/
|
1195
1314
|
function getDefaultTranslation() {
|
1196
1315
|
const translation = new Translations("en").assignTranslations(
|
1197
1316
|
this.getOption("labels", {}),
|
@@ -1906,7 +2025,7 @@ function areOptionsAvailableAndInit() {
|
|
1906
2025
|
if (this.getOption("features.emptyValueIfNoOptions") === true) {
|
1907
2026
|
this.value = "";
|
1908
2027
|
}
|
1909
|
-
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE,
|
2028
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, "No options available.");
|
1910
2029
|
return false;
|
1911
2030
|
}
|
1912
2031
|
|
@@ -1958,7 +2077,7 @@ function areOptionsAvailableAndInit() {
|
|
1958
2077
|
|
1959
2078
|
setStatusOrRemoveBadges.call(this);
|
1960
2079
|
|
1961
|
-
removeAttributeToken(this, ATTRIBUTE_ERRORMESSAGE,
|
2080
|
+
removeAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, "No options available.");
|
1962
2081
|
return true;
|
1963
2082
|
}
|
1964
2083
|
|
@@ -22,6 +22,7 @@ import { isString } from "../../types/is.mjs";
|
|
22
22
|
import { generateUniqueConfigKey } from "../host/util.mjs";
|
23
23
|
import { Collapse, nameSymbol } from "./collapse.mjs";
|
24
24
|
import { instanceSymbol } from "../../constants.mjs";
|
25
|
+
import {getLocaleOfDocument} from "../../dom/locale.mjs";
|
25
26
|
|
26
27
|
export { Details };
|
27
28
|
|
@@ -86,9 +87,7 @@ class Details extends Collapse {
|
|
86
87
|
templates: {
|
87
88
|
main: getTemplate(),
|
88
89
|
},
|
89
|
-
labels:
|
90
|
-
button: "Details",
|
91
|
-
},
|
90
|
+
labels: getTranslations(),
|
92
91
|
});
|
93
92
|
}
|
94
93
|
|
@@ -136,6 +135,54 @@ class Details extends Collapse {
|
|
136
135
|
}
|
137
136
|
}
|
138
137
|
|
138
|
+
/**
|
139
|
+
* @private
|
140
|
+
* @returns {object}
|
141
|
+
*/
|
142
|
+
function getTranslations() {
|
143
|
+
const locale = getLocaleOfDocument();
|
144
|
+
switch (locale.language) {
|
145
|
+
case 'de':
|
146
|
+
return {
|
147
|
+
button: "Details"
|
148
|
+
};
|
149
|
+
case 'fr':
|
150
|
+
return {
|
151
|
+
button: "Détails"
|
152
|
+
};
|
153
|
+
case 'sp':
|
154
|
+
return {
|
155
|
+
button: "Detalles"
|
156
|
+
};
|
157
|
+
case 'it':
|
158
|
+
return {
|
159
|
+
button: "Dettagli"
|
160
|
+
};
|
161
|
+
case 'pl':
|
162
|
+
return {
|
163
|
+
button: "Szczegóły"
|
164
|
+
};
|
165
|
+
case 'no':
|
166
|
+
return {
|
167
|
+
button: "Detaljer"
|
168
|
+
};
|
169
|
+
case 'dk':
|
170
|
+
return {
|
171
|
+
button: "Detaljer"
|
172
|
+
};
|
173
|
+
case 'sw':
|
174
|
+
return {
|
175
|
+
button: "Detaljer"
|
176
|
+
};
|
177
|
+
default:
|
178
|
+
case 'en':
|
179
|
+
return {
|
180
|
+
button: "Details"
|
181
|
+
};
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
|
139
186
|
/**
|
140
187
|
* @private
|
141
188
|
* @return {Select}
|
@@ -59,6 +59,7 @@ import {
|
|
59
59
|
popperInstanceSymbol,
|
60
60
|
setEventListenersModifiers,
|
61
61
|
} from "../form/util/popper.mjs";
|
62
|
+
import {getLocaleOfDocument} from "../../dom/locale.mjs";
|
62
63
|
|
63
64
|
export { Tabs };
|
64
65
|
|
@@ -195,9 +196,7 @@ class Tabs extends CustomElement {
|
|
195
196
|
templates: {
|
196
197
|
main: getTemplate(),
|
197
198
|
},
|
198
|
-
labels:
|
199
|
-
"new-tab-label": "New Tab",
|
200
|
-
},
|
199
|
+
labels: getTranslations(),
|
201
200
|
buttons: {
|
202
201
|
standard: [],
|
203
202
|
popper: [],
|
@@ -374,6 +373,54 @@ class Tabs extends CustomElement {
|
|
374
373
|
}
|
375
374
|
}
|
376
375
|
|
376
|
+
/**
|
377
|
+
* @private
|
378
|
+
* @returns {object}
|
379
|
+
*/
|
380
|
+
function getTranslations() {
|
381
|
+
const locale = getLocaleOfDocument();
|
382
|
+
switch (locale.language) {
|
383
|
+
case 'de':
|
384
|
+
return {
|
385
|
+
"new-tab-label": "Neuer Tab"
|
386
|
+
};
|
387
|
+
case 'fr':
|
388
|
+
return {
|
389
|
+
"new-tab-label": "Nouvel Onglet"
|
390
|
+
};
|
391
|
+
case 'sp':
|
392
|
+
return {
|
393
|
+
"new-tab-label": "Nueva Pestaña"
|
394
|
+
};
|
395
|
+
case 'it':
|
396
|
+
return {
|
397
|
+
"new-tab-label": "Nuova Scheda"
|
398
|
+
};
|
399
|
+
case 'pl':
|
400
|
+
return {
|
401
|
+
"new-tab-label": "Nowa Karta"
|
402
|
+
};
|
403
|
+
case 'no':
|
404
|
+
return {
|
405
|
+
"new-tab-label": "Ny Fane"
|
406
|
+
};
|
407
|
+
case 'dk':
|
408
|
+
return {
|
409
|
+
"new-tab-label": "Ny Fane"
|
410
|
+
};
|
411
|
+
case 'sw':
|
412
|
+
return {
|
413
|
+
"new-tab-label": "Ny Flik"
|
414
|
+
};
|
415
|
+
default:
|
416
|
+
case 'en':
|
417
|
+
return {
|
418
|
+
"new-tab-label": "New Tab"
|
419
|
+
};
|
420
|
+
}
|
421
|
+
}
|
422
|
+
|
423
|
+
|
377
424
|
/**
|
378
425
|
* @private
|
379
426
|
*/
|
@@ -0,0 +1,235 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved.
|
3
|
+
* Node module: @schukai/monster
|
4
|
+
*
|
5
|
+
* This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
|
6
|
+
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
|
7
|
+
*
|
8
|
+
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
|
9
|
+
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
|
10
|
+
* For more information about purchasing a commercial license, please contact schukai GmbH.
|
11
|
+
*/
|
12
|
+
|
13
|
+
import {instanceSymbol} from "../../constants.mjs";
|
14
|
+
import {addAttributeToken, hasObjectLink} from "../../dom/attributes.mjs";
|
15
|
+
import {
|
16
|
+
ATTRIBUTE_ERRORMESSAGE,
|
17
|
+
ATTRIBUTE_ROLE,
|
18
|
+
customElementUpdaterLinkSymbol,
|
19
|
+
} from "../../dom/constants.mjs";
|
20
|
+
import {CustomControl} from "../../dom/customcontrol.mjs";
|
21
|
+
import {CustomElement} from "../../dom/customelement.mjs";
|
22
|
+
import {
|
23
|
+
assembleMethodSymbol,
|
24
|
+
registerCustomElement,
|
25
|
+
} from "../../dom/customelement.mjs";
|
26
|
+
import {findTargetElementFromEvent} from "../../dom/events.mjs";
|
27
|
+
import {isFunction} from "../../types/is.mjs";
|
28
|
+
import {MonitorAttributeErrorsStyleSheet} from "./stylesheet/monitor-attribute-errors.mjs";
|
29
|
+
import {fireCustomEvent} from "../../dom/events.mjs";
|
30
|
+
import {getDocument} from "../../dom/util.mjs";
|
31
|
+
import {clone} from "../../util/clone.mjs";
|
32
|
+
|
33
|
+
export {MonitorAttributeErrors};
|
34
|
+
|
35
|
+
/**
|
36
|
+
* @private
|
37
|
+
* @type {symbol}
|
38
|
+
*/
|
39
|
+
const mutationObserversSymbol = Symbol("mutationObservers");
|
40
|
+
|
41
|
+
/**
|
42
|
+
* A MonitorAttributeErrors
|
43
|
+
*
|
44
|
+
* @fragments /fragments/components/notify/monitor-attribute-errors/
|
45
|
+
*
|
46
|
+
* @example /examples/components/notify/monitor-attribute-errors-simple
|
47
|
+
*
|
48
|
+
* @since 3.98.0
|
49
|
+
* @copyright schukai GmbH
|
50
|
+
* @summary A beautiful MonitorAttributeErrors that can make your life easier and also looks good.
|
51
|
+
*/
|
52
|
+
class MonitorAttributeErrors extends CustomElement {
|
53
|
+
/**
|
54
|
+
* This method is called by the `instanceof` operator.
|
55
|
+
* @returns {symbol}
|
56
|
+
*/
|
57
|
+
static get [instanceSymbol]() {
|
58
|
+
return Symbol.for(
|
59
|
+
"@schukai/monster/components/notify/monitor-attribute-errors@@instance",
|
60
|
+
);
|
61
|
+
}
|
62
|
+
|
63
|
+
/**
|
64
|
+
*
|
65
|
+
* @return {Components.Notify.MonitorAttributeErrors
|
66
|
+
*/
|
67
|
+
[assembleMethodSymbol]() {
|
68
|
+
super[assembleMethodSymbol]();
|
69
|
+
return this;
|
70
|
+
}
|
71
|
+
|
72
|
+
/**
|
73
|
+
* @return {void}
|
74
|
+
*/
|
75
|
+
connectedCallback() {
|
76
|
+
super.connectedCallback();
|
77
|
+
setupMutationObserver.call(this, getDocument());
|
78
|
+
}
|
79
|
+
|
80
|
+
/**
|
81
|
+
* @return {void}
|
82
|
+
*/
|
83
|
+
disconnectedCallback() {
|
84
|
+
super.disconnectedCallback();
|
85
|
+
deactivateAllObservers.call(this);
|
86
|
+
}
|
87
|
+
|
88
|
+
/**
|
89
|
+
* To set the options via the HTML Tag, the attribute `data-monster-options` must be used.
|
90
|
+
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
|
91
|
+
*
|
92
|
+
* The individual configuration values can be found in the table.
|
93
|
+
*
|
94
|
+
* @property {Object} templates Template definitions
|
95
|
+
* @property {string} templates.main Main template
|
96
|
+
* @property {Object} features Features
|
97
|
+
* @property {boolean} features.notifyUser Notify user (monster-notify control is required)
|
98
|
+
* @property {Object} notifyUser Notify user
|
99
|
+
* @property {string} notifyUser.selector Selector for the notify user control (feature notifyUser must be enabled)
|
100
|
+
*/
|
101
|
+
get defaults() {
|
102
|
+
return Object.assign({}, super.defaults, {
|
103
|
+
templates: {
|
104
|
+
main: getTemplate(),
|
105
|
+
},
|
106
|
+
features: {
|
107
|
+
notifyUser: false,
|
108
|
+
},
|
109
|
+
|
110
|
+
notifyUser: {
|
111
|
+
selector: "monster-notify",
|
112
|
+
},
|
113
|
+
|
114
|
+
actions: {
|
115
|
+
click: () => {
|
116
|
+
throw new Error("the click action is not defined");
|
117
|
+
},
|
118
|
+
},
|
119
|
+
});
|
120
|
+
}
|
121
|
+
|
122
|
+
/**
|
123
|
+
* @return {string}
|
124
|
+
*/
|
125
|
+
static getTag() {
|
126
|
+
return "monster-monitor-attribute-errors";
|
127
|
+
}
|
128
|
+
|
129
|
+
/**
|
130
|
+
* @return {CSSStyleSheet[]}
|
131
|
+
*/
|
132
|
+
static getCSSStyleSheet() {
|
133
|
+
return [MonitorAttributeErrorsStyleSheet];
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
137
|
+
/**
|
138
|
+
* @private
|
139
|
+
* @param root
|
140
|
+
*/
|
141
|
+
function setupMutationObserver(root) {
|
142
|
+
const self = this;
|
143
|
+
|
144
|
+
if (!this?.[mutationObserversSymbol]) {
|
145
|
+
this[mutationObserversSymbol] = [];
|
146
|
+
}
|
147
|
+
|
148
|
+
const config = {
|
149
|
+
childList: true,
|
150
|
+
subtree: true,
|
151
|
+
attributes: true,
|
152
|
+
attributeFilter: ["data-monster-error"],
|
153
|
+
};
|
154
|
+
|
155
|
+
const callback = (mutationsList, observer) => {
|
156
|
+
for (const mutation of mutationsList) {
|
157
|
+
if (mutation.type === "childList") {
|
158
|
+
mutation.addedNodes.forEach((node) => {
|
159
|
+
checkNodeForErrors(node);
|
160
|
+
observeShadowRoots(node);
|
161
|
+
});
|
162
|
+
}
|
163
|
+
if (
|
164
|
+
mutation.type === "attributes" &&
|
165
|
+
mutation.attributeName === "data-monster-error"
|
166
|
+
) {
|
167
|
+
const node = mutation.target;
|
168
|
+
|
169
|
+
checkNodeForErrors(node);
|
170
|
+
}
|
171
|
+
}
|
172
|
+
};
|
173
|
+
|
174
|
+
const observer = new MutationObserver(callback);
|
175
|
+
observer.observe(root, config);
|
176
|
+
this[mutationObserversSymbol].push(observer); // Speichert den Observer
|
177
|
+
|
178
|
+
root.querySelectorAll("*").forEach((node) => {
|
179
|
+
checkNodeForErrors(node);
|
180
|
+
observeShadowRoots(node);
|
181
|
+
});
|
182
|
+
|
183
|
+
function checkNodeForErrors(node) {
|
184
|
+
if (node.nodeType === 1 && node.hasAttribute("data-monster-error")) {
|
185
|
+
|
186
|
+
const fktOpen = console.groupCollapsed || console.group || console.log || function () {
|
187
|
+
};
|
188
|
+
const fktLog = console.log || function () {
|
189
|
+
};
|
190
|
+
const fktClose = console.groupEnd || function () {
|
191
|
+
};
|
192
|
+
|
193
|
+
fktOpen("MonitorAttributeErrors " + node.tagName);
|
194
|
+
fktLog(node);
|
195
|
+
fktLog(node.getAttribute('data-monster-error'));
|
196
|
+
fktClose();
|
197
|
+
|
198
|
+
if (self.getOption("features.notifyUser")) {
|
199
|
+
const notifyUser = getDocument().querySelector(self.getOption("notifyUser.selector"));
|
200
|
+
if (notifyUser) {
|
201
|
+
notifyUser.push(node.getAttribute('data-monster-error'));
|
202
|
+
}
|
203
|
+
}
|
204
|
+
|
205
|
+
}
|
206
|
+
}
|
207
|
+
|
208
|
+
function observeShadowRoots(node) {
|
209
|
+
if (
|
210
|
+
node.nodeType === 1 &&
|
211
|
+
node.shadowRoot &&
|
212
|
+
node.shadowRoot.mode === "open"
|
213
|
+
) {
|
214
|
+
setupMutationObserver.call(self, node.shadowRoot);
|
215
|
+
}
|
216
|
+
}
|
217
|
+
}
|
218
|
+
|
219
|
+
function deactivateAllObservers() {
|
220
|
+
this[mutationObserversSymbol].forEach((observer) => {
|
221
|
+
observer.disconnect();
|
222
|
+
});
|
223
|
+
this[mutationObserversSymbol] = [];
|
224
|
+
}
|
225
|
+
|
226
|
+
/**
|
227
|
+
* @private
|
228
|
+
* @return {string}
|
229
|
+
*/
|
230
|
+
function getTemplate() {
|
231
|
+
// language=HTML
|
232
|
+
return `<div></div>`;
|
233
|
+
}
|
234
|
+
|
235
|
+
registerCustomElement(MonitorAttributeErrors);
|