@schukai/monster 4.136.7 → 4.136.8
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/package.json +1 -1
- package/source/components/form/select.mjs +82 -22
- package/source/components/form/util/floating-ui.mjs +19 -11
- package/source/components/form/util/popper.mjs +4 -0
- package/source/components/navigation/site-navigation.mjs +79 -58
- package/source/types/version.mjs +1 -1
- package/test/cases/components/form/message-state-button.mjs +36 -60
- package/test/cases/components/form/select.mjs +46 -0
- package/test/cases/monster.mjs +1 -1
- package/test/web/import.js +4 -0
- package/test/web/test.html +2 -2
- package/test/web/tests.js +6841 -2575
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"author":"Volker Schukai","dependencies":{"@floating-ui/dom":"^1.7.6"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.136.
|
|
1
|
+
{"author":"Volker Schukai","dependencies":{"@floating-ui/dom":"^1.7.6"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.136.8"}
|
|
@@ -2238,22 +2238,56 @@ function parseSlotsToOptions() {
|
|
|
2238
2238
|
function buildSelectionLabel(value) {
|
|
2239
2239
|
const strict = this.getOption("features.useStrictValueComparison") === true;
|
|
2240
2240
|
const map = this[optionsMapSymbol];
|
|
2241
|
-
const key = strict ? value :
|
|
2241
|
+
const key = strict ? value : getSelectionStateKey.call(this, value);
|
|
2242
2242
|
|
|
2243
2243
|
if (map && map.has(key)) {
|
|
2244
2244
|
if (clearUnresolvedSelectionValue.call(this, value)) {
|
|
2245
|
-
this[lookupCacheSymbol].delete(value);
|
|
2245
|
+
this[lookupCacheSymbol].delete(getSelectionCacheKey.call(this, value));
|
|
2246
2246
|
}
|
|
2247
2247
|
return map.get(key);
|
|
2248
2248
|
}
|
|
2249
2249
|
|
|
2250
|
-
|
|
2251
|
-
|
|
2250
|
+
const cacheKey = getSelectionCacheKey.call(this, value);
|
|
2251
|
+
if (this[lookupCacheSymbol].has(cacheKey)) {
|
|
2252
|
+
return this[lookupCacheSymbol].get(cacheKey);
|
|
2252
2253
|
}
|
|
2253
2254
|
|
|
2254
2255
|
return undefined;
|
|
2255
2256
|
}
|
|
2256
2257
|
|
|
2258
|
+
/**
|
|
2259
|
+
* @private
|
|
2260
|
+
* @param {*} value
|
|
2261
|
+
* @returns {string}
|
|
2262
|
+
*/
|
|
2263
|
+
function getSelectionValueLabel(value) {
|
|
2264
|
+
if (isValueIsEmpty.call(this, value)) {
|
|
2265
|
+
return "";
|
|
2266
|
+
}
|
|
2267
|
+
|
|
2268
|
+
if (isPrimitive(value)) {
|
|
2269
|
+
return String(value);
|
|
2270
|
+
}
|
|
2271
|
+
|
|
2272
|
+
if (isObject(value)) {
|
|
2273
|
+
for (const key of ["value", "id", "key"]) {
|
|
2274
|
+
const candidate = value?.[key];
|
|
2275
|
+
if (!isValueIsEmpty.call(this, candidate) && isPrimitive(candidate)) {
|
|
2276
|
+
return String(candidate);
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
|
|
2280
|
+
try {
|
|
2281
|
+
const json = JSON.stringify(value);
|
|
2282
|
+
if (isString(json)) {
|
|
2283
|
+
return json;
|
|
2284
|
+
}
|
|
2285
|
+
} catch (e) {}
|
|
2286
|
+
}
|
|
2287
|
+
|
|
2288
|
+
return String(value);
|
|
2289
|
+
}
|
|
2290
|
+
|
|
2257
2291
|
/**
|
|
2258
2292
|
* @private
|
|
2259
2293
|
* @param {*} value
|
|
@@ -2262,7 +2296,33 @@ function buildSelectionLabel(value) {
|
|
|
2262
2296
|
function getSelectionStateKey(value) {
|
|
2263
2297
|
return this.getOption("features.useStrictValueComparison") === true
|
|
2264
2298
|
? value
|
|
2265
|
-
:
|
|
2299
|
+
: getSelectionValueLabel.call(this, value);
|
|
2300
|
+
}
|
|
2301
|
+
|
|
2302
|
+
/**
|
|
2303
|
+
* @private
|
|
2304
|
+
* @param {*} value
|
|
2305
|
+
* @returns {*}
|
|
2306
|
+
*/
|
|
2307
|
+
function getSelectionCacheKey(value) {
|
|
2308
|
+
return getSelectionStateKey.call(this, value);
|
|
2309
|
+
}
|
|
2310
|
+
|
|
2311
|
+
/**
|
|
2312
|
+
* @private
|
|
2313
|
+
* @param {*} current
|
|
2314
|
+
* @param {*} expected
|
|
2315
|
+
* @returns {boolean}
|
|
2316
|
+
*/
|
|
2317
|
+
function areLookupValuesEqual(current, expected) {
|
|
2318
|
+
if (this.getOption("features.useStrictValueComparison") === true) {
|
|
2319
|
+
return current === expected;
|
|
2320
|
+
}
|
|
2321
|
+
|
|
2322
|
+
return (
|
|
2323
|
+
getSelectionValueLabel.call(this, current) ===
|
|
2324
|
+
getSelectionValueLabel.call(this, expected)
|
|
2325
|
+
);
|
|
2266
2326
|
}
|
|
2267
2327
|
|
|
2268
2328
|
/**
|
|
@@ -2357,6 +2417,8 @@ function buildSelectionItem(value, preferredLabel) {
|
|
|
2357
2417
|
*/
|
|
2358
2418
|
async function lookupValueAndCache(value) {
|
|
2359
2419
|
const lookupUrl = this.getOption("lookup.url");
|
|
2420
|
+
const lookupValue = getSelectionValueLabel.call(this, value);
|
|
2421
|
+
const cacheKey = getSelectionCacheKey.call(this, value);
|
|
2360
2422
|
// A more robust check for invalid values. 0 and "" are valid.
|
|
2361
2423
|
if (
|
|
2362
2424
|
!lookupUrl ||
|
|
@@ -2381,7 +2443,10 @@ async function lookupValueAndCache(value) {
|
|
|
2381
2443
|
|
|
2382
2444
|
const markerOpen = this.getOption("filter.marker.open", "{");
|
|
2383
2445
|
const markerClose = this.getOption("filter.marker.close", "}");
|
|
2384
|
-
const url = lookupUrl.replace(
|
|
2446
|
+
const url = lookupUrl.replace(
|
|
2447
|
+
`${markerOpen}filter${markerClose}`,
|
|
2448
|
+
lookupValue,
|
|
2449
|
+
);
|
|
2385
2450
|
|
|
2386
2451
|
const data = await fetchData.call(this, url);
|
|
2387
2452
|
|
|
@@ -2407,8 +2472,9 @@ async function lookupValueAndCache(value) {
|
|
|
2407
2472
|
}
|
|
2408
2473
|
|
|
2409
2474
|
// The lookup might return more than the requested value, so we cache all of them.
|
|
2410
|
-
|
|
2411
|
-
|
|
2475
|
+
const itemCacheKey = getSelectionCacheKey.call(this, itemValue);
|
|
2476
|
+
if (this[lookupCacheSymbol].get(itemCacheKey) !== itemLabel) {
|
|
2477
|
+
this[lookupCacheSymbol].set(itemCacheKey, itemLabel);
|
|
2412
2478
|
refreshSelection = true;
|
|
2413
2479
|
}
|
|
2414
2480
|
|
|
@@ -2416,13 +2482,13 @@ async function lookupValueAndCache(value) {
|
|
|
2416
2482
|
refreshSelection = true;
|
|
2417
2483
|
}
|
|
2418
2484
|
|
|
2419
|
-
if (
|
|
2485
|
+
if (areLookupValuesEqual.call(this, itemValue, value)) {
|
|
2420
2486
|
found = true;
|
|
2421
2487
|
}
|
|
2422
2488
|
}
|
|
2423
2489
|
|
|
2424
|
-
if (!found && !this[lookupCacheSymbol].has(
|
|
2425
|
-
this[lookupCacheSymbol].set(
|
|
2490
|
+
if (!found && !this[lookupCacheSymbol].has(cacheKey)) {
|
|
2491
|
+
this[lookupCacheSymbol].set(cacheKey, lookupValue);
|
|
2426
2492
|
refreshSelection = true;
|
|
2427
2493
|
}
|
|
2428
2494
|
|
|
@@ -2433,8 +2499,8 @@ async function lookupValueAndCache(value) {
|
|
|
2433
2499
|
hasError = true;
|
|
2434
2500
|
addErrorAttribute(this, e);
|
|
2435
2501
|
|
|
2436
|
-
if (!this[lookupCacheSymbol].has(
|
|
2437
|
-
this[lookupCacheSymbol].set(
|
|
2502
|
+
if (!this[lookupCacheSymbol].has(cacheKey)) {
|
|
2503
|
+
this[lookupCacheSymbol].set(cacheKey, lookupValue);
|
|
2438
2504
|
refreshSelection = true;
|
|
2439
2505
|
}
|
|
2440
2506
|
|
|
@@ -2482,11 +2548,7 @@ function getSelectionLabel(value) {
|
|
|
2482
2548
|
});
|
|
2483
2549
|
}
|
|
2484
2550
|
|
|
2485
|
-
|
|
2486
|
-
return `${value}`;
|
|
2487
|
-
}
|
|
2488
|
-
|
|
2489
|
-
return this.getOption("labels.cannot-be-loaded", value);
|
|
2551
|
+
return getSelectionValueLabel.call(this, value);
|
|
2490
2552
|
}
|
|
2491
2553
|
|
|
2492
2554
|
/**
|
|
@@ -2556,17 +2618,15 @@ function initOptionObserver() {
|
|
|
2556
2618
|
if (isArray(options)) {
|
|
2557
2619
|
for (const o of options) {
|
|
2558
2620
|
if (isPrimitive(o)) {
|
|
2559
|
-
const key =
|
|
2621
|
+
const key = getSelectionStateKey.call(self, o);
|
|
2560
2622
|
if (!map.has(key)) {
|
|
2561
2623
|
map.set(key, o);
|
|
2562
2624
|
}
|
|
2563
2625
|
} else if (isObject(o)) {
|
|
2564
2626
|
const v = o?.value;
|
|
2565
2627
|
const l = o?.label;
|
|
2566
|
-
// If strict is true, use value as is (could be number, symbol, etc.)
|
|
2567
|
-
// If strict is false, use String(value) to allow loose matching
|
|
2568
2628
|
if (v !== undefined) {
|
|
2569
|
-
const key =
|
|
2629
|
+
const key = getSelectionStateKey.call(self, v);
|
|
2570
2630
|
if (!map.has(key)) {
|
|
2571
2631
|
map.set(key, l);
|
|
2572
2632
|
}
|
|
@@ -219,15 +219,13 @@ function buildFloatingMiddleware(
|
|
|
219
219
|
const kv = line.split(":");
|
|
220
220
|
const fn = kv.shift();
|
|
221
221
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
);
|
|
230
|
-
break;
|
|
222
|
+
switch (fn) {
|
|
223
|
+
case "flip":
|
|
224
|
+
result[key] = flip(detectOverflowOptions);
|
|
225
|
+
break;
|
|
226
|
+
case "shift":
|
|
227
|
+
result[key] = shift(normalizeShiftOptions(kv, detectOverflowOptions));
|
|
228
|
+
break;
|
|
231
229
|
case "autoPlacement":
|
|
232
230
|
let defaultAllowedPlacements = ["top", "bottom", "left", "right"];
|
|
233
231
|
|
|
@@ -922,7 +920,10 @@ function startAutoUpdate(controlElement, popperElement, callback) {
|
|
|
922
920
|
stopAutoUpdate(popperElement);
|
|
923
921
|
autoUpdateCleanupMap.set(
|
|
924
922
|
popperElement,
|
|
925
|
-
autoUpdate(controlElement, popperElement, callback
|
|
923
|
+
autoUpdate(controlElement, popperElement, callback, {
|
|
924
|
+
elementResize: typeof ResizeObserver === "function",
|
|
925
|
+
layoutShift: false,
|
|
926
|
+
}),
|
|
926
927
|
);
|
|
927
928
|
}
|
|
928
929
|
|
|
@@ -939,6 +940,10 @@ function stopAutoUpdate(popperElement) {
|
|
|
939
940
|
function startFloatingResizeObserver(controlElement, popperElement, config) {
|
|
940
941
|
stopFloatingResizeObserver(popperElement);
|
|
941
942
|
|
|
943
|
+
if (typeof ResizeObserver !== "function") {
|
|
944
|
+
return;
|
|
945
|
+
}
|
|
946
|
+
|
|
942
947
|
const observer = new ResizeObserver(() => {
|
|
943
948
|
scheduleSettlingPass(controlElement, popperElement, config);
|
|
944
949
|
});
|
|
@@ -949,7 +954,10 @@ function startFloatingResizeObserver(controlElement, popperElement, config) {
|
|
|
949
954
|
|
|
950
955
|
function stopFloatingResizeObserver(popperElement) {
|
|
951
956
|
const observer = floatingResizeObserverMap.get(popperElement);
|
|
952
|
-
if (
|
|
957
|
+
if (
|
|
958
|
+
typeof ResizeObserver === "function" &&
|
|
959
|
+
observer instanceof ResizeObserver
|
|
960
|
+
) {
|
|
953
961
|
observer.disconnect();
|
|
954
962
|
}
|
|
955
963
|
floatingResizeObserverMap.delete(popperElement);
|
|
@@ -44,6 +44,13 @@ const activeSubmenuHiderSymbol = Symbol("activeSubmenuHider");
|
|
|
44
44
|
const hideHamburgerMenuSymbol = Symbol("hideHamburgerMenu");
|
|
45
45
|
const hamburgerCloseButtonSymbol = Symbol("hamburgerCloseButton");
|
|
46
46
|
|
|
47
|
+
function getAutoUpdateOptions() {
|
|
48
|
+
return {
|
|
49
|
+
elementResize: typeof ResizeObserver === "function",
|
|
50
|
+
layoutShift: false,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
47
54
|
/**
|
|
48
55
|
* A responsive site navigation that automatically moves menu items into a hamburger menu
|
|
49
56
|
* when there isn't enough available space.
|
|
@@ -215,39 +222,48 @@ function initEventHandler() {
|
|
|
215
222
|
|
|
216
223
|
hamburgerNav.scrollIntoView({ block: "start", behavior: "smooth" });
|
|
217
224
|
|
|
218
|
-
cleanup = autoUpdate(
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
225
|
+
cleanup = autoUpdate(
|
|
226
|
+
hamburgerButton,
|
|
227
|
+
hamburgerNav,
|
|
228
|
+
() => {
|
|
229
|
+
if (window.innerWidth > 768) {
|
|
230
|
+
const strategy = getBestPositionStrategy(this);
|
|
231
|
+
|
|
232
|
+
computePosition(hamburgerButton, hamburgerNav, {
|
|
233
|
+
placement: "bottom-end",
|
|
234
|
+
strategy: strategy,
|
|
235
|
+
middleware: [
|
|
236
|
+
offset(8),
|
|
237
|
+
flip(),
|
|
238
|
+
shift({ padding: 8 }),
|
|
239
|
+
size({
|
|
240
|
+
apply: ({ availableHeight, elements }) => {
|
|
241
|
+
Object.assign(elements.floating.style, {
|
|
242
|
+
maxHeight: `${availableHeight}px`,
|
|
243
|
+
overflowY: "auto",
|
|
244
|
+
});
|
|
245
|
+
},
|
|
246
|
+
padding: 8,
|
|
247
|
+
}),
|
|
248
|
+
],
|
|
249
|
+
}).then(({ x, y, strategy }) => {
|
|
250
|
+
Object.assign(hamburgerNav.style, {
|
|
251
|
+
position: strategy,
|
|
252
|
+
left: `${x}px`,
|
|
253
|
+
top: `${y}px`,
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
} else {
|
|
257
|
+
// Mobile view (fullscreen overlay), position is handled by CSS
|
|
240
258
|
Object.assign(hamburgerNav.style, {
|
|
241
|
-
position:
|
|
242
|
-
left:
|
|
243
|
-
top:
|
|
259
|
+
position: "",
|
|
260
|
+
left: "",
|
|
261
|
+
top: "",
|
|
244
262
|
});
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
}
|
|
250
|
-
});
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
getAutoUpdateOptions(),
|
|
266
|
+
);
|
|
251
267
|
setTimeout(() => document.addEventListener("click", handleOutsideClick), 0);
|
|
252
268
|
};
|
|
253
269
|
|
|
@@ -395,35 +411,40 @@ function setupSubmenu(parentLi, context = "visible", level = 1) {
|
|
|
395
411
|
level,
|
|
396
412
|
});
|
|
397
413
|
if (!cleanup) {
|
|
398
|
-
cleanup = autoUpdate(
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
size({
|
|
406
|
-
apply: ({ availableHeight, elements }) => {
|
|
407
|
-
Object.assign(elements.floating.style, {
|
|
408
|
-
maxHeight: `${availableHeight}px`,
|
|
409
|
-
overflowY: "auto",
|
|
410
|
-
});
|
|
411
|
-
},
|
|
412
|
-
padding: 8,
|
|
413
|
-
}),
|
|
414
|
+
cleanup = autoUpdate(
|
|
415
|
+
parentLi,
|
|
416
|
+
submenu,
|
|
417
|
+
() => {
|
|
418
|
+
const middleware = [offset(8), flip(), shift({ padding: 8 })];
|
|
419
|
+
const containsSubmenus = submenu.querySelector(
|
|
420
|
+
"ul, div[part='mega-menu']",
|
|
414
421
|
);
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
422
|
+
if (!containsSubmenus) {
|
|
423
|
+
middleware.push(
|
|
424
|
+
size({
|
|
425
|
+
apply: ({ availableHeight, elements }) => {
|
|
426
|
+
Object.assign(elements.floating.style, {
|
|
427
|
+
maxHeight: `${availableHeight}px`,
|
|
428
|
+
overflowY: "auto",
|
|
429
|
+
});
|
|
430
|
+
},
|
|
431
|
+
padding: 8,
|
|
432
|
+
}),
|
|
433
|
+
);
|
|
434
|
+
}
|
|
435
|
+
computePosition(parentLi, submenu, {
|
|
436
|
+
placement: level === 1 ? "bottom-start" : "right-start",
|
|
437
|
+
middleware: middleware,
|
|
438
|
+
}).then(({ x, y, strategy }) => {
|
|
439
|
+
Object.assign(submenu.style, {
|
|
440
|
+
position: strategy,
|
|
441
|
+
left: `${x}px`,
|
|
442
|
+
top: `${y}px`,
|
|
443
|
+
});
|
|
424
444
|
});
|
|
425
|
-
}
|
|
426
|
-
|
|
445
|
+
},
|
|
446
|
+
getAutoUpdateOptions(),
|
|
447
|
+
);
|
|
427
448
|
}
|
|
428
449
|
};
|
|
429
450
|
|
package/source/types/version.mjs
CHANGED
|
@@ -73,8 +73,9 @@ describe("MessageStateButton", function () {
|
|
|
73
73
|
|
|
74
74
|
describe("document.createElement", function () {
|
|
75
75
|
it("should instance of message-state-button", function () {
|
|
76
|
-
expect(
|
|
77
|
-
.
|
|
76
|
+
expect(
|
|
77
|
+
document.createElement("monster-message-state-button"),
|
|
78
|
+
).is.instanceof(MessageStateButton);
|
|
78
79
|
});
|
|
79
80
|
});
|
|
80
81
|
});
|
|
@@ -93,9 +94,7 @@ describe("MessageStateButton", function () {
|
|
|
93
94
|
|
|
94
95
|
setTimeout(() => {
|
|
95
96
|
try {
|
|
96
|
-
const inner = button.shadowRoot.querySelector(
|
|
97
|
-
"monster-state-button",
|
|
98
|
-
);
|
|
97
|
+
const inner = button.shadowRoot.querySelector("monster-state-button");
|
|
99
98
|
expect(inner).to.exist;
|
|
100
99
|
|
|
101
100
|
button.setAttribute("disabled", "");
|
|
@@ -231,19 +230,22 @@ describe("MessageStateButton", function () {
|
|
|
231
230
|
|
|
232
231
|
setTimeout(() => {
|
|
233
232
|
try {
|
|
234
|
-
button.setMessage(
|
|
233
|
+
button.setMessage(
|
|
234
|
+
"<div><strong>Saved</strong><p>plain html</p></div>",
|
|
235
|
+
);
|
|
235
236
|
button.showMessage();
|
|
236
237
|
|
|
237
238
|
setTimeout(() => {
|
|
238
239
|
try {
|
|
239
|
-
const content =
|
|
240
|
+
const content =
|
|
241
|
+
button.shadowRoot.querySelector('[part="content"]');
|
|
240
242
|
const message = button.shadowRoot.querySelector(
|
|
241
243
|
'[data-monster-role="message"]',
|
|
242
244
|
);
|
|
243
245
|
expect(content).to.exist;
|
|
244
|
-
expect(
|
|
245
|
-
"
|
|
246
|
-
);
|
|
246
|
+
expect(
|
|
247
|
+
content.getAttribute("data-monster-overflow-mode"),
|
|
248
|
+
).to.equal("both");
|
|
247
249
|
expect(
|
|
248
250
|
content.getAttribute("data-monster-message-layout"),
|
|
249
251
|
).to.equal("prose");
|
|
@@ -306,10 +308,7 @@ describe("MessageStateButton", function () {
|
|
|
306
308
|
try {
|
|
307
309
|
const wrapper = document.createElement("div");
|
|
308
310
|
const line = document.createElement("div");
|
|
309
|
-
line.setAttribute(
|
|
310
|
-
"style",
|
|
311
|
-
"white-space: nowrap; overflow-x: auto;",
|
|
312
|
-
);
|
|
311
|
+
line.setAttribute("style", "white-space: nowrap; overflow-x: auto;");
|
|
313
312
|
line.textContent =
|
|
314
313
|
"this is intentionally a single long line to trigger wide layout";
|
|
315
314
|
wrapper.appendChild(line);
|
|
@@ -319,14 +318,15 @@ describe("MessageStateButton", function () {
|
|
|
319
318
|
|
|
320
319
|
setTimeout(() => {
|
|
321
320
|
try {
|
|
322
|
-
const content =
|
|
321
|
+
const content =
|
|
322
|
+
button.shadowRoot.querySelector('[part="content"]');
|
|
323
323
|
const message = button.shadowRoot.querySelector(
|
|
324
324
|
'[data-monster-role="message"]',
|
|
325
325
|
);
|
|
326
326
|
expect(content).to.exist;
|
|
327
|
-
expect(
|
|
328
|
-
"
|
|
329
|
-
);
|
|
327
|
+
expect(
|
|
328
|
+
content.getAttribute("data-monster-overflow-mode"),
|
|
329
|
+
).to.equal("both");
|
|
330
330
|
expect(
|
|
331
331
|
content.getAttribute("data-monster-message-layout"),
|
|
332
332
|
).to.equal("wide");
|
|
@@ -351,7 +351,8 @@ describe("MessageStateButton", function () {
|
|
|
351
351
|
|
|
352
352
|
beforeEach(() => {
|
|
353
353
|
originalInnerWidth = window.innerWidth;
|
|
354
|
-
originalGetBoundingClientRect =
|
|
354
|
+
originalGetBoundingClientRect =
|
|
355
|
+
HTMLElement.prototype.getBoundingClientRect;
|
|
355
356
|
});
|
|
356
357
|
|
|
357
358
|
afterEach(() => {
|
|
@@ -360,7 +361,8 @@ describe("MessageStateButton", function () {
|
|
|
360
361
|
writable: true,
|
|
361
362
|
value: originalInnerWidth,
|
|
362
363
|
});
|
|
363
|
-
HTMLElement.prototype.getBoundingClientRect =
|
|
364
|
+
HTMLElement.prototype.getBoundingClientRect =
|
|
365
|
+
originalGetBoundingClientRect;
|
|
364
366
|
let mocks = document.getElementById("mocks");
|
|
365
367
|
mocks.innerHTML = "";
|
|
366
368
|
});
|
|
@@ -388,14 +390,7 @@ describe("MessageStateButton", function () {
|
|
|
388
390
|
};
|
|
389
391
|
}
|
|
390
392
|
|
|
391
|
-
return
|
|
392
|
-
width: 100,
|
|
393
|
-
height: 40,
|
|
394
|
-
top: 0,
|
|
395
|
-
left: 0,
|
|
396
|
-
right: 100,
|
|
397
|
-
bottom: 40,
|
|
398
|
-
};
|
|
393
|
+
return originalGetBoundingClientRect.call(this);
|
|
399
394
|
};
|
|
400
395
|
|
|
401
396
|
setTimeout(() => {
|
|
@@ -405,18 +400,12 @@ describe("MessageStateButton", function () {
|
|
|
405
400
|
);
|
|
406
401
|
button.showMessage();
|
|
407
402
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
expect(popper.style.maxWidth).to.equal("512px");
|
|
415
|
-
done();
|
|
416
|
-
} catch (e) {
|
|
417
|
-
done(e);
|
|
418
|
-
}
|
|
419
|
-
}, 0);
|
|
403
|
+
const popper = button.shadowRoot.querySelector(
|
|
404
|
+
'[data-monster-role="popper"]',
|
|
405
|
+
);
|
|
406
|
+
expect(popper.style.width).to.equal("512px");
|
|
407
|
+
expect(popper.style.maxWidth).to.equal("512px");
|
|
408
|
+
done();
|
|
420
409
|
} catch (e) {
|
|
421
410
|
done(e);
|
|
422
411
|
}
|
|
@@ -446,14 +435,7 @@ describe("MessageStateButton", function () {
|
|
|
446
435
|
};
|
|
447
436
|
}
|
|
448
437
|
|
|
449
|
-
return
|
|
450
|
-
width: 100,
|
|
451
|
-
height: 40,
|
|
452
|
-
top: 0,
|
|
453
|
-
left: 0,
|
|
454
|
-
right: 100,
|
|
455
|
-
bottom: 40,
|
|
456
|
-
};
|
|
438
|
+
return originalGetBoundingClientRect.call(this);
|
|
457
439
|
};
|
|
458
440
|
|
|
459
441
|
setTimeout(() => {
|
|
@@ -465,18 +447,12 @@ describe("MessageStateButton", function () {
|
|
|
465
447
|
button.setMessage(wrapper);
|
|
466
448
|
button.showMessage();
|
|
467
449
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
expect(popper.style.maxWidth).to.equal("768px");
|
|
475
|
-
done();
|
|
476
|
-
} catch (e) {
|
|
477
|
-
done(e);
|
|
478
|
-
}
|
|
479
|
-
}, 0);
|
|
450
|
+
const popper = button.shadowRoot.querySelector(
|
|
451
|
+
'[data-monster-role="popper"]',
|
|
452
|
+
);
|
|
453
|
+
expect(popper.style.width).to.equal("768px");
|
|
454
|
+
expect(popper.style.maxWidth).to.equal("768px");
|
|
455
|
+
done();
|
|
480
456
|
} catch (e) {
|
|
481
457
|
done(e);
|
|
482
458
|
}
|
|
@@ -980,6 +980,52 @@ describe('Select', function () {
|
|
|
980
980
|
}, 250);
|
|
981
981
|
});
|
|
982
982
|
|
|
983
|
+
it('should keep unresolved object lookup values visible by key and mark their badge', function (done) {
|
|
984
|
+
this.timeout(3000);
|
|
985
|
+
|
|
986
|
+
let mocks = document.getElementById('mocks');
|
|
987
|
+
const requests = [];
|
|
988
|
+
global['fetch'] = function (url) {
|
|
989
|
+
requests.push(url.toString());
|
|
990
|
+
return createJsonResponse({
|
|
991
|
+
items: [],
|
|
992
|
+
pagination: {
|
|
993
|
+
total: 0,
|
|
994
|
+
page: 1,
|
|
995
|
+
perPage: 1
|
|
996
|
+
}
|
|
997
|
+
});
|
|
998
|
+
};
|
|
999
|
+
|
|
1000
|
+
const select = document.createElement('monster-select');
|
|
1001
|
+
select.setOption('lookup.url', 'https://example.com/items?filter={filter}');
|
|
1002
|
+
select.setOption('mapping.selector', 'items.*');
|
|
1003
|
+
select.setOption('mapping.labelTemplate', '${name}');
|
|
1004
|
+
select.setOption('mapping.valueTemplate', '${id}');
|
|
1005
|
+
select.setOption('selection', [{value: {id: 'missing-key'}}]);
|
|
1006
|
+
mocks.appendChild(select);
|
|
1007
|
+
|
|
1008
|
+
setTimeout(() => {
|
|
1009
|
+
try {
|
|
1010
|
+
const badge = select.shadowRoot.querySelector('[data-monster-role=badge]');
|
|
1011
|
+
const badgeLabel = select.shadowRoot.querySelector('[data-monster-role=badge-label]');
|
|
1012
|
+
|
|
1013
|
+
expect(requests).to.include('https://example.com/items?filter=missing-key');
|
|
1014
|
+
expect(badge).to.be.instanceof(HTMLDivElement);
|
|
1015
|
+
expect(badgeLabel).to.be.instanceof(HTMLDivElement);
|
|
1016
|
+
expect(badgeLabel.textContent.trim()).to.equal('missing-key');
|
|
1017
|
+
expect(badge.className).to.contain('monster-badge-warning');
|
|
1018
|
+
expect(badge.className).to.not.contain('monster-badge-primary');
|
|
1019
|
+
expect(badge.getAttribute('data-monster-unresolved')).to.equal('true');
|
|
1020
|
+
expect(badgeLabel.textContent).to.not.contain(select.getOption('labels.cannot-be-loaded'));
|
|
1021
|
+
} catch (e) {
|
|
1022
|
+
return done(e);
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
done();
|
|
1026
|
+
}, 250);
|
|
1027
|
+
});
|
|
1028
|
+
|
|
983
1029
|
it('should clear the unresolved badge state once a local option can resolve the value', function (done) {
|
|
984
1030
|
this.timeout(4000);
|
|
985
1031
|
|
package/test/cases/monster.mjs
CHANGED