@schukai/monster 4.43.2 → 4.43.3
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 +8 -0
- package/package.json +1 -1
- package/source/components/accessibility/locale-picker.mjs +538 -538
- package/source/components/accessibility/locale-select.mjs +172 -172
- package/source/components/content/viewer.mjs +823 -823
- package/source/components/datatable/constants.mjs +15 -15
- package/source/components/datatable/datatable/header.mjs +253 -253
- package/source/components/datatable/datatable.mjs +1284 -1284
- package/source/components/datatable/filter.mjs +1339 -1342
- package/source/components/datatable/pagination.mjs +502 -502
- package/source/components/datatable/stylesheet/datatable.mjs +13 -6
- package/source/components/form/quantity.mjs +229 -229
- package/source/components/form/select.mjs +2963 -2963
- package/source/components/form/stylesheet/quantity.mjs +13 -6
- package/source/components/form/stylesheet/select.mjs +13 -6
- package/source/components/navigation/site-navigation.mjs +330 -330
- package/source/components/navigation/stylesheet/site-navigation.mjs +13 -6
- package/source/components/style/typography.css +4 -2
- package/source/dom/customelement.mjs +959 -963
- package/source/dom/slotted.mjs +87 -87
- package/source/i18n/util.mjs +149 -149
- package/source/monster.mjs +3 -0
- package/source/types/is.mjs +64 -64
- package/source/types/typeof.mjs +16 -16
- package/source/types/version.mjs +1 -1
- package/test/cases/monster.mjs +1 -1
- package/test/web/test.html +2 -2
- package/test/web/tests.js +2724 -1287
package/source/dom/slotted.mjs
CHANGED
@@ -28,46 +28,46 @@ export { getSlottedElements, getSlottedNodes };
|
|
28
28
|
* @throws {Error} query must be a string
|
29
29
|
*/
|
30
30
|
function getSlottedNodes(query, name) {
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
31
|
+
const result = new Set();
|
32
|
+
|
33
|
+
if (!this.shadowRoot) {
|
34
|
+
return result;
|
35
|
+
}
|
36
|
+
|
37
|
+
let selector = "slot";
|
38
|
+
if (name !== undefined) {
|
39
|
+
if (name === null) {
|
40
|
+
selector += ":not([name])";
|
41
|
+
} else {
|
42
|
+
selector += `[name=${validateString(name)}]`;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
const slots = this.shadowRoot.querySelectorAll(selector);
|
47
|
+
|
48
|
+
for (const [, slot] of Object.entries(slots)) {
|
49
|
+
slot.assignedNodes().forEach(function (node) {
|
50
|
+
if (node === null || node === undefined) {
|
51
|
+
return;
|
52
|
+
}
|
53
|
+
|
54
|
+
if (isString(query)) {
|
55
|
+
node.querySelectorAll(query).forEach(function (n) {
|
56
|
+
result.add(n);
|
57
|
+
});
|
58
|
+
|
59
|
+
if (node.matches(query)) {
|
60
|
+
result.add(node);
|
61
|
+
}
|
62
|
+
} else if (query !== undefined) {
|
63
|
+
throw new Error("query must be a string");
|
64
|
+
} else {
|
65
|
+
result.add(node);
|
66
|
+
}
|
67
|
+
});
|
68
|
+
}
|
69
|
+
|
70
|
+
return result;
|
71
71
|
}
|
72
72
|
|
73
73
|
/**
|
@@ -81,51 +81,51 @@ function getSlottedNodes(query, name) {
|
|
81
81
|
* @throws {Error} query must be a string
|
82
82
|
*/
|
83
83
|
function getSlottedElements(query, name) {
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
84
|
+
const result = new Set();
|
85
|
+
|
86
|
+
if (!(this.shadowRoot instanceof ShadowRoot)) {
|
87
|
+
return result;
|
88
|
+
}
|
89
|
+
|
90
|
+
let selector = "slot";
|
91
|
+
if (name !== undefined) {
|
92
|
+
if (name === null) {
|
93
|
+
selector += ":not([name])";
|
94
|
+
} else {
|
95
|
+
selector += `[name=${validateString(name)}]`;
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
const slots = this.shadowRoot.querySelectorAll(selector);
|
100
|
+
|
101
|
+
for (const [, slot] of Object.entries(slots)) {
|
102
|
+
slot.assignedElements().forEach(function (node) {
|
103
|
+
if (
|
104
|
+
!(node instanceof HTMLElement) &&
|
105
|
+
!(node instanceof SVGElement) &&
|
106
|
+
!(node instanceof MathMLElement)
|
107
|
+
)
|
108
|
+
return;
|
109
|
+
|
110
|
+
if (isString(query)) {
|
111
|
+
if (query.length > 0) {
|
112
|
+
node.querySelectorAll(query).forEach(function (n) {
|
113
|
+
result.add(n);
|
114
|
+
});
|
115
|
+
|
116
|
+
if (node.matches(query)) {
|
117
|
+
result.add(node);
|
118
|
+
}
|
119
|
+
} else {
|
120
|
+
result.add(node);
|
121
|
+
}
|
122
|
+
} else if (query !== undefined) {
|
123
|
+
throw new Error("query must be a string and not empty");
|
124
|
+
} else {
|
125
|
+
result.add(node);
|
126
|
+
}
|
127
|
+
});
|
128
|
+
}
|
129
|
+
|
130
|
+
return result;
|
131
131
|
}
|
package/source/i18n/util.mjs
CHANGED
@@ -23,24 +23,24 @@ import { languages } from "./map/languages.mjs";
|
|
23
23
|
* @return {number} The normalized number as a floating-point value. Returns NaN if the input is not a parsable number.
|
24
24
|
*/
|
25
25
|
export function normalizeNumber(input, locale = navigator.language) {
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
26
|
+
if (input === null || input === undefined) return NaN;
|
27
|
+
if (typeof input === "number") return input; // If input is already a number, return it directly
|
28
|
+
if (typeof input !== "string") return NaN;
|
29
|
+
|
30
|
+
const cleaned = input.trim().replace(/\s/g, "");
|
31
|
+
const decimalSeparator = getDecimalSeparator(locale);
|
32
|
+
let normalized = cleaned;
|
33
|
+
|
34
|
+
if (decimalSeparator === "," && cleaned.includes(".")) {
|
35
|
+
normalized = cleaned.replace(/\./g, "").replace(",", ".");
|
36
|
+
} else if (decimalSeparator === "." && cleaned.includes(",")) {
|
37
|
+
normalized = cleaned.replace(/,/g, "").replace(".", ".");
|
38
|
+
} else if (decimalSeparator === "," && cleaned.includes(",")) {
|
39
|
+
normalized = cleaned.replace(",", ".");
|
40
|
+
}
|
41
|
+
|
42
|
+
const result = parseFloat(normalized);
|
43
|
+
return Number.isNaN(result) ? NaN : result;
|
44
44
|
}
|
45
45
|
|
46
46
|
/**
|
@@ -50,9 +50,9 @@ export function normalizeNumber(input, locale = navigator.language) {
|
|
50
50
|
* @return {string} The decimal separator used in the specified locale.
|
51
51
|
*/
|
52
52
|
function getDecimalSeparator(locale = navigator.language) {
|
53
|
-
|
54
|
-
|
55
|
-
|
53
|
+
const numberWithDecimal = 1.1;
|
54
|
+
const formatted = new Intl.NumberFormat(locale).format(numberWithDecimal);
|
55
|
+
return formatted.replace(/\d/g, "")[0]; // z.B. "," oder "."
|
56
56
|
}
|
57
57
|
|
58
58
|
/**
|
@@ -64,132 +64,132 @@ function getDecimalSeparator(locale = navigator.language) {
|
|
64
64
|
* @return {Object} An object containing information about the detected language, preferred language, and available languages.
|
65
65
|
*/
|
66
66
|
export function detectUserLanguagePreference() {
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
67
|
+
const currentLang = document.documentElement.lang;
|
68
|
+
|
69
|
+
let preferredLanguages = [];
|
70
|
+
|
71
|
+
if (typeof navigator.language === "string" && navigator.language.length > 0) {
|
72
|
+
preferredLanguages = [navigator.language];
|
73
|
+
}
|
74
|
+
|
75
|
+
if (Array.isArray(navigator.languages) && navigator.languages.length > 0) {
|
76
|
+
preferredLanguages = navigator.languages;
|
77
|
+
}
|
78
|
+
|
79
|
+
// add to preferredLanguages all the base languages of the preferred languages
|
80
|
+
preferredLanguages = preferredLanguages.concat(
|
81
|
+
preferredLanguages.map((lang) => lang.split("-")[0]),
|
82
|
+
);
|
83
|
+
|
84
|
+
if (!currentLang && preferredLanguages.length === 0) {
|
85
|
+
return {
|
86
|
+
message: "No language information available.",
|
87
|
+
};
|
88
|
+
}
|
89
|
+
|
90
|
+
const linkTags = document.querySelectorAll("link[hreflang]");
|
91
|
+
if (linkTags.length === 0) {
|
92
|
+
return {
|
93
|
+
current: currentLang || null,
|
94
|
+
message: "No <link> tags with hreflang available.",
|
95
|
+
};
|
96
|
+
}
|
97
|
+
|
98
|
+
const availableLanguages = [...linkTags].map((link) => {
|
99
|
+
const fullLang = link.getAttribute("hreflang");
|
100
|
+
const baseLang = fullLang.split("-")[0];
|
101
|
+
let label = link.getAttribute("data-monster-label");
|
102
|
+
if (!label) {
|
103
|
+
label = link.getAttribute("title");
|
104
|
+
if (!label) {
|
105
|
+
label = languages?.[fullLang];
|
106
|
+
if (!label) {
|
107
|
+
label = languages?.[baseLang];
|
108
|
+
}
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
return {
|
113
|
+
fullLang,
|
114
|
+
baseLang,
|
115
|
+
label,
|
116
|
+
href: link.getAttribute("href"),
|
117
|
+
};
|
118
|
+
});
|
119
|
+
|
120
|
+
// filter availableLanguages to only include languages that are in the preferredLanguages array
|
121
|
+
const offerableLanguages = availableLanguages.filter(
|
122
|
+
(lang) =>
|
123
|
+
preferredLanguages.includes(lang.fullLang) ||
|
124
|
+
preferredLanguages.includes(lang.baseLang),
|
125
|
+
);
|
126
|
+
|
127
|
+
const allOfferableLanguages = availableLanguages.filter(
|
128
|
+
(lang) => lang.baseLang !== currentLang && lang.fullLang !== currentLang,
|
129
|
+
);
|
130
|
+
|
131
|
+
if (offerableLanguages.length === 0) {
|
132
|
+
return {
|
133
|
+
current: currentLang || null,
|
134
|
+
message: "No available languages match the user's preferences.",
|
135
|
+
available: availableLanguages.map((lang) => ({
|
136
|
+
...lang,
|
137
|
+
weight: 1,
|
138
|
+
})),
|
139
|
+
allOfferable: allOfferableLanguages,
|
140
|
+
};
|
141
|
+
}
|
142
|
+
|
143
|
+
// Helper function to determine the "weight" of a language match
|
144
|
+
function getWeight(langEntry) {
|
145
|
+
// Full match has priority 3
|
146
|
+
if (preferredLanguages.includes(langEntry.fullLang)) return 3;
|
147
|
+
// Base language match has priority 2
|
148
|
+
if (preferredLanguages.includes(langEntry.baseLang)) return 2;
|
149
|
+
// No match is priority 1
|
150
|
+
return 1;
|
151
|
+
}
|
152
|
+
|
153
|
+
// Sort the available languages by descending weight
|
154
|
+
offerableLanguages.sort((a, b) => getWeight(b) - getWeight(a));
|
155
|
+
|
156
|
+
// The best match is the first in the sorted list
|
157
|
+
const bestMatch = offerableLanguages[0];
|
158
|
+
const bestMatchWeight = getWeight(bestMatch);
|
159
|
+
|
160
|
+
const currentLabel = languages?.[currentLang] || currentLang;
|
161
|
+
|
162
|
+
// If we found a language that matches user preferences (weight > 0)
|
163
|
+
if (bestMatchWeight > 0) {
|
164
|
+
return {
|
165
|
+
current: currentLang || null,
|
166
|
+
currentLabel: currentLabel,
|
167
|
+
preferred: {
|
168
|
+
full: bestMatch.fullLang,
|
169
|
+
base: bestMatch.baseLang,
|
170
|
+
label: bestMatch.label,
|
171
|
+
href: bestMatch.href,
|
172
|
+
},
|
173
|
+
available: availableLanguages.map((lang) => ({
|
174
|
+
...lang,
|
175
|
+
weight: getWeight(lang),
|
176
|
+
})),
|
177
|
+
offerable: offerableLanguages.map((lang) => ({
|
178
|
+
...lang,
|
179
|
+
weight: getWeight(lang),
|
180
|
+
})),
|
181
|
+
allOfferable: allOfferableLanguages,
|
182
|
+
};
|
183
|
+
}
|
184
|
+
|
185
|
+
// If no language matched the user's preferences
|
186
|
+
return {
|
187
|
+
current: currentLang || null,
|
188
|
+
message: "None of the preferred languages are available.",
|
189
|
+
available: availableLanguages.map((lang) => ({
|
190
|
+
...lang,
|
191
|
+
weight: getWeight(lang),
|
192
|
+
})),
|
193
|
+
allOfferable: allOfferableLanguages,
|
194
|
+
};
|
195
195
|
}
|
package/source/monster.mjs
CHANGED
@@ -62,6 +62,7 @@ export * from "./components/form/api-button.mjs";
|
|
62
62
|
export * from "./components/form/digits.mjs";
|
63
63
|
export * from "./components/form/tree-select.mjs";
|
64
64
|
export * from "./components/form/popper-button.mjs";
|
65
|
+
export * from "./components/form/quantity.mjs";
|
65
66
|
export * from "./components/form/input-group.mjs";
|
66
67
|
export * from "./components/form/shadow-reload.mjs";
|
67
68
|
export * from "./components/form/button.mjs";
|
@@ -106,12 +107,14 @@ export * from "./components/datatable/embedded-pagination.mjs";
|
|
106
107
|
export * from "./components/datatable/status.mjs";
|
107
108
|
export * from "./components/datatable/change-button.mjs";
|
108
109
|
export * from "./components/datatable/constants.mjs";
|
110
|
+
export * from "./components/accessibility/locale-select.mjs";
|
109
111
|
export * from "./components/accessibility/locale-picker.mjs";
|
110
112
|
export * from "./components/state/log/entry.mjs";
|
111
113
|
export * from "./components/state/state.mjs";
|
112
114
|
export * from "./components/state/log.mjs";
|
113
115
|
export * from "./components/navigation/wizard-navigation.mjs";
|
114
116
|
export * from "./components/navigation/table-of-content.mjs";
|
117
|
+
export * from "./components/navigation/site-navigation.mjs";
|
115
118
|
export * from "./components/data/metric-graph.mjs";
|
116
119
|
export * from "./components/data/metric.mjs";
|
117
120
|
export * from "./components/data/kpi-tile.mjs";
|