@schukai/monster 4.133.0 → 4.135.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/package.json +1 -1
- package/source/components/form/message-state-button.mjs +6 -0
- package/source/components/form/select.mjs +13 -0
- package/source/components/form/util/floating-ui.mjs +298 -19
- package/source/data/datasource/server/restapi.mjs +4 -1
- package/source/data/datasource/server/webconnect.mjs +4 -1
- package/source/data/datasource/server.mjs +4 -1
- package/source/data/datasource/storage.mjs +3 -0
- package/source/data/datasource.mjs +6 -0
- package/source/dom/assembler.mjs +3 -0
- package/source/dom/customcontrol.mjs +5 -0
- package/source/dom/customelement.mjs +5 -0
- package/source/dom/focusmanager.mjs +3 -0
- package/source/dom/resource/link/stylesheet.mjs +4 -1
- package/source/dom/resource/link.mjs +4 -1
- package/source/dom/resource/script.mjs +4 -1
- package/source/dom/resource.mjs +4 -1
- package/source/dom/resourcemanager.mjs +7 -1
- package/source/dom/template.mjs +6 -0
- package/source/dom/updater.mjs +9 -0
- package/source/i18n/formatter.mjs +1 -0
- package/source/i18n/locale.mjs +1 -0
- package/source/i18n/provider.mjs +4 -0
- package/source/i18n/providers/embed.mjs +1 -0
- package/source/i18n/providers/fetch.mjs +1 -0
- package/source/i18n/translations.mjs +5 -0
- package/source/logging/handler/console.mjs +1 -0
- package/source/logging/handler.mjs +4 -0
- package/source/logging/logentry.mjs +1 -0
- package/source/logging/logger.mjs +4 -0
- package/source/net/webconnect/message.mjs +4 -1
- package/source/net/webconnect.mjs +4 -1
- package/source/types/observablequeue.mjs +4 -1
- package/source/types/observer.mjs +4 -0
- package/test/cases/components/form/floating-ui.mjs +77 -0
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.
|
|
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.135.0"}
|
|
@@ -466,6 +466,11 @@ function initControlReferences() {
|
|
|
466
466
|
this[messageElementSymbol] = this.shadowRoot.querySelector(
|
|
467
467
|
`[${ATTRIBUTE_ROLE}=message]`,
|
|
468
468
|
);
|
|
469
|
+
if (this[popperElementSymbol] instanceof HTMLElement) {
|
|
470
|
+
this[popperElementSymbol].monsterBeforeFloatingUpdate = () => {
|
|
471
|
+
applyMeasuredMessageWidth.call(this);
|
|
472
|
+
};
|
|
473
|
+
}
|
|
469
474
|
applyResolvedMessagePresentation.call(this);
|
|
470
475
|
}
|
|
471
476
|
|
|
@@ -868,6 +873,7 @@ function applyMeasuredMessageWidth() {
|
|
|
868
873
|
Math.min(measuredWidth || minWidth, maxWidth),
|
|
869
874
|
);
|
|
870
875
|
|
|
876
|
+
popper.dataset.monsterPreferredMaxWidth = `${maxWidth}`;
|
|
871
877
|
popper.style.width = `${targetWidth}px`;
|
|
872
878
|
popper.style.minWidth = `${minWidth}px`;
|
|
873
879
|
popper.style.maxWidth = `${maxWidth}px`;
|
|
@@ -2453,6 +2453,7 @@ function getOptionElements() {
|
|
|
2453
2453
|
function calcAndSetOptionsDimension() {
|
|
2454
2454
|
const options = getOptionElements.call(this);
|
|
2455
2455
|
const container = this[optionsElementSymbol];
|
|
2456
|
+
const content = this[popperElementSymbol]?.querySelector?.('[part="content"]');
|
|
2456
2457
|
if (!(container instanceof HTMLElement && options instanceof NodeList)) {
|
|
2457
2458
|
return;
|
|
2458
2459
|
}
|
|
@@ -2541,8 +2542,17 @@ function calcAndSetOptionsDimension() {
|
|
|
2541
2542
|
|
|
2542
2543
|
const domRect = this[controlElementSymbol].getBoundingClientRect();
|
|
2543
2544
|
|
|
2545
|
+
this[popperElementSymbol].dataset.monsterPreferredWidth = `${Math.ceil(
|
|
2546
|
+
domRect.width,
|
|
2547
|
+
)}`;
|
|
2544
2548
|
this[popperElementSymbol].style.width = `${domRect.width}px`;
|
|
2549
|
+
this[popperElementSymbol].style.minWidth = `${domRect.width}px`;
|
|
2545
2550
|
container.style.overflowX = "auto";
|
|
2551
|
+
|
|
2552
|
+
if (content instanceof HTMLElement) {
|
|
2553
|
+
content.style.overflowX = "hidden";
|
|
2554
|
+
content.style.overflowY = "hidden";
|
|
2555
|
+
}
|
|
2546
2556
|
}
|
|
2547
2557
|
|
|
2548
2558
|
/**
|
|
@@ -4429,6 +4439,9 @@ function initControlReferences() {
|
|
|
4429
4439
|
this[popperElementSymbol] = this.shadowRoot.querySelector(
|
|
4430
4440
|
`[${ATTRIBUTE_ROLE}=popper]`,
|
|
4431
4441
|
);
|
|
4442
|
+
this[popperElementSymbol].monsterBeforeFloatingUpdate = () => {
|
|
4443
|
+
calcAndSetOptionsDimension.call(this);
|
|
4444
|
+
};
|
|
4432
4445
|
this[inlineFilterElementSymbol] = this.shadowRoot.querySelector(
|
|
4433
4446
|
`[${ATTRIBUTE_ROLE}=filter][name="inline-filter"]`,
|
|
4434
4447
|
);
|
|
@@ -27,6 +27,7 @@ import { isArray, isFunction, isObject, isString } from "../../../types/is.mjs";
|
|
|
27
27
|
import { Processing } from "../../../util/processing.mjs";
|
|
28
28
|
|
|
29
29
|
export {
|
|
30
|
+
applyAdaptiveFloatingElementSize,
|
|
30
31
|
closePositionedPopper,
|
|
31
32
|
resolveClippingBoundaryElement,
|
|
32
33
|
isPositionedPopperOpen,
|
|
@@ -35,6 +36,8 @@ export {
|
|
|
35
36
|
};
|
|
36
37
|
|
|
37
38
|
const autoUpdateCleanupMap = new WeakMap();
|
|
39
|
+
const settlingFrameMap = new WeakMap();
|
|
40
|
+
const floatingResizeObserverMap = new WeakMap();
|
|
38
41
|
|
|
39
42
|
/**
|
|
40
43
|
* @private
|
|
@@ -67,16 +70,26 @@ function enableFloatingPositioning(controlElement, popperElement, config) {
|
|
|
67
70
|
popperElement.style.removeProperty("visibility");
|
|
68
71
|
popperElement.style.display = "block";
|
|
69
72
|
|
|
73
|
+
startFloatingResizeObserver(controlElement, popperElement, config);
|
|
70
74
|
startAutoUpdate(controlElement, popperElement, () => {
|
|
75
|
+
runFloatingUpdateHook(popperElement);
|
|
71
76
|
syncFloatingPopover(controlElement, popperElement, config);
|
|
72
77
|
});
|
|
78
|
+
runFloatingUpdateHook(popperElement);
|
|
73
79
|
syncFloatingPopover(controlElement, popperElement, config);
|
|
74
80
|
}
|
|
75
81
|
|
|
76
|
-
function syncFloatingPopover(
|
|
82
|
+
function syncFloatingPopover(
|
|
83
|
+
controlElement,
|
|
84
|
+
popperElement,
|
|
85
|
+
config,
|
|
86
|
+
allowSettlingPass = true,
|
|
87
|
+
) {
|
|
77
88
|
const arrowElement = popperElement.querySelector("[data-monster-role=arrow]");
|
|
78
89
|
const floatingMiddleware = [...config.floatingMiddleware];
|
|
79
90
|
|
|
91
|
+
resetAdaptiveFloatingElementSize(popperElement);
|
|
92
|
+
|
|
80
93
|
if (
|
|
81
94
|
arrowElement instanceof HTMLElement &&
|
|
82
95
|
config.middlewareTokens.includes("arrow")
|
|
@@ -101,6 +114,10 @@ function syncFloatingPopover(controlElement, popperElement, config) {
|
|
|
101
114
|
if (middlewareData.arrow) {
|
|
102
115
|
applyFloatingArrowStyles(arrowElement, placement, middlewareData.arrow);
|
|
103
116
|
}
|
|
117
|
+
|
|
118
|
+
if (allowSettlingPass) {
|
|
119
|
+
scheduleSettlingPass(controlElement, popperElement, config);
|
|
120
|
+
}
|
|
104
121
|
});
|
|
105
122
|
}
|
|
106
123
|
|
|
@@ -253,30 +270,249 @@ function createAdaptiveSizeMiddleware(detectOverflowOptions, popperElement) {
|
|
|
253
270
|
return;
|
|
254
271
|
}
|
|
255
272
|
|
|
256
|
-
|
|
273
|
+
applyAdaptiveFloatingElementSize(floatingElement, {
|
|
257
274
|
availableWidth,
|
|
258
|
-
readMaxDimension(floatingElement, "maxWidth"),
|
|
259
|
-
);
|
|
260
|
-
const maxHeight = clampAvailableDimension(
|
|
261
275
|
availableHeight,
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
276
|
+
});
|
|
277
|
+
},
|
|
278
|
+
}),
|
|
279
|
+
);
|
|
280
|
+
}
|
|
267
281
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
282
|
+
function applyAdaptiveFloatingElementSize(
|
|
283
|
+
floatingElement,
|
|
284
|
+
{ availableWidth, availableHeight },
|
|
285
|
+
) {
|
|
286
|
+
const maxWidth = clampAvailableDimension(
|
|
287
|
+
availableWidth,
|
|
288
|
+
readMaxDimension(floatingElement, "maxWidth"),
|
|
289
|
+
);
|
|
290
|
+
const maxHeight = clampAvailableDimension(
|
|
291
|
+
availableHeight,
|
|
292
|
+
readMaxDimension(floatingElement, "maxHeight"),
|
|
293
|
+
);
|
|
294
|
+
const nextStyle = {
|
|
295
|
+
boxSizing: "border-box",
|
|
296
|
+
};
|
|
271
297
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
298
|
+
if (Number.isFinite(maxWidth) && maxWidth > 0) {
|
|
299
|
+
nextStyle.maxWidth = `${maxWidth}px`;
|
|
300
|
+
} else {
|
|
301
|
+
nextStyle.maxWidth = "";
|
|
302
|
+
}
|
|
275
303
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
304
|
+
if (Number.isFinite(maxHeight) && maxHeight > 0) {
|
|
305
|
+
nextStyle.maxHeight = `${maxHeight}px`;
|
|
306
|
+
} else {
|
|
307
|
+
nextStyle.maxHeight = "";
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
Object.assign(floatingElement.style, nextStyle);
|
|
311
|
+
|
|
312
|
+
syncPreferredFloatingWidth(floatingElement, maxWidth);
|
|
313
|
+
syncPreferredFloatingMaxWidth(floatingElement, maxWidth);
|
|
314
|
+
applyAdaptiveFloatingContentSize(floatingElement, maxHeight);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function applyAdaptiveFloatingContentSize(floatingElement, maxHeight) {
|
|
318
|
+
const contentElement = getFloatingContentElement(floatingElement);
|
|
319
|
+
if (!(contentElement instanceof HTMLElement)) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (contentElement.dataset.monsterOverflowMode === "visible") {
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const reservedHeight = getReservedFloatingHeight(
|
|
328
|
+
floatingElement,
|
|
329
|
+
contentElement,
|
|
330
|
+
);
|
|
331
|
+
const contentMaxHeight = clampAvailableDimension(
|
|
332
|
+
Number.isFinite(maxHeight) ? maxHeight - reservedHeight : null,
|
|
333
|
+
readMaxDimension(contentElement, "maxHeight"),
|
|
279
334
|
);
|
|
335
|
+
|
|
336
|
+
if (Number.isFinite(contentMaxHeight) && contentMaxHeight > 0) {
|
|
337
|
+
contentElement.style.maxHeight = `${contentMaxHeight}px`;
|
|
338
|
+
} else {
|
|
339
|
+
contentElement.style.maxHeight = "";
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
syncNestedScrollContainerHeight(contentElement, contentMaxHeight);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
function getFloatingContentElement(floatingElement) {
|
|
346
|
+
for (const child of floatingElement.children) {
|
|
347
|
+
if (!(child instanceof HTMLElement)) {
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
const part = child.getAttribute("part");
|
|
352
|
+
if (
|
|
353
|
+
isString(part) &&
|
|
354
|
+
part
|
|
355
|
+
.split(/\s+/)
|
|
356
|
+
.filter((token) => token.length > 0)
|
|
357
|
+
.includes("content")
|
|
358
|
+
) {
|
|
359
|
+
return child;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function getReservedFloatingHeight(floatingElement, contentElement) {
|
|
367
|
+
const floatingStyle = getComputedStyle(floatingElement);
|
|
368
|
+
let reservedHeight = 0;
|
|
369
|
+
|
|
370
|
+
reservedHeight += readBoxDimension(floatingStyle.paddingTop);
|
|
371
|
+
reservedHeight += readBoxDimension(floatingStyle.paddingBottom);
|
|
372
|
+
reservedHeight += readBoxDimension(floatingStyle.borderTopWidth);
|
|
373
|
+
reservedHeight += readBoxDimension(floatingStyle.borderBottomWidth);
|
|
374
|
+
|
|
375
|
+
for (const child of floatingElement.children) {
|
|
376
|
+
if (!(child instanceof HTMLElement) || child === contentElement) {
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const childStyle = getComputedStyle(child);
|
|
381
|
+
reservedHeight += child.getBoundingClientRect().height;
|
|
382
|
+
reservedHeight += readBoxDimension(childStyle.marginTop);
|
|
383
|
+
reservedHeight += readBoxDimension(childStyle.marginBottom);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
return Math.max(0, reservedHeight);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
function readBoxDimension(rawValue) {
|
|
390
|
+
const value = Number.parseFloat(rawValue);
|
|
391
|
+
return Number.isFinite(value) ? value : 0;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
function syncNestedScrollContainerHeight(contentElement, contentMaxHeight) {
|
|
395
|
+
const nestedScrollableElement = getNestedScrollableElement(contentElement);
|
|
396
|
+
if (!(nestedScrollableElement instanceof HTMLElement)) {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
if (Number.isFinite(contentMaxHeight) && contentMaxHeight > 0) {
|
|
401
|
+
nestedScrollableElement.style.height = `${contentMaxHeight}px`;
|
|
402
|
+
nestedScrollableElement.style.maxHeight = `${contentMaxHeight}px`;
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
nestedScrollableElement.style.height = "";
|
|
407
|
+
nestedScrollableElement.style.maxHeight = "";
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
function syncPreferredFloatingWidth(floatingElement, maxWidth) {
|
|
411
|
+
const preferredWidth = Number.parseFloat(
|
|
412
|
+
floatingElement.dataset.monsterPreferredWidth || "",
|
|
413
|
+
);
|
|
414
|
+
if (!Number.isFinite(preferredWidth) || preferredWidth <= 0) {
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
const contentElement = getFloatingContentElement(floatingElement);
|
|
419
|
+
if (!(contentElement instanceof HTMLElement)) {
|
|
420
|
+
floatingElement.style.width = `${preferredWidth}px`;
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
const floatingRect = floatingElement.getBoundingClientRect();
|
|
425
|
+
const contentRect = contentElement.getBoundingClientRect();
|
|
426
|
+
const reservedWidth = Math.max(0, floatingRect.width - contentRect.width);
|
|
427
|
+
const contentRequiredWidth = getRequiredContentWidth(contentElement);
|
|
428
|
+
const preferredFloatingWidth = preferredWidth;
|
|
429
|
+
const requiredFloatingWidth = Math.max(
|
|
430
|
+
preferredFloatingWidth,
|
|
431
|
+
contentRequiredWidth + reservedWidth,
|
|
432
|
+
);
|
|
433
|
+
const nextFloatingWidth = clampAvailableDimension(
|
|
434
|
+
requiredFloatingWidth,
|
|
435
|
+
Number.isFinite(maxWidth) ? maxWidth : Infinity,
|
|
436
|
+
);
|
|
437
|
+
|
|
438
|
+
if (Number.isFinite(nextFloatingWidth) && nextFloatingWidth > 0) {
|
|
439
|
+
floatingElement.style.width = `${nextFloatingWidth}px`;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
function syncPreferredFloatingMaxWidth(floatingElement, maxWidth) {
|
|
444
|
+
const preferredMaxWidth = Number.parseFloat(
|
|
445
|
+
floatingElement.dataset.monsterPreferredMaxWidth || "",
|
|
446
|
+
);
|
|
447
|
+
if (!Number.isFinite(preferredMaxWidth) || preferredMaxWidth <= 0) {
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
const nextFloatingMaxWidth = clampAvailableDimension(
|
|
452
|
+
preferredMaxWidth,
|
|
453
|
+
Number.isFinite(maxWidth) ? maxWidth : Infinity,
|
|
454
|
+
);
|
|
455
|
+
if (Number.isFinite(nextFloatingMaxWidth) && nextFloatingMaxWidth > 0) {
|
|
456
|
+
floatingElement.style.maxWidth = `${nextFloatingMaxWidth}px`;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
function resetAdaptiveFloatingElementSize(floatingElement) {
|
|
461
|
+
if (!(floatingElement instanceof HTMLElement)) {
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
floatingElement.style.removeProperty("maxHeight");
|
|
466
|
+
|
|
467
|
+
const contentElement = getFloatingContentElement(floatingElement);
|
|
468
|
+
if (!(contentElement instanceof HTMLElement)) {
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
contentElement.style.removeProperty("maxHeight");
|
|
473
|
+
|
|
474
|
+
const nestedScrollableElement = getNestedScrollableElement(contentElement);
|
|
475
|
+
if (!(nestedScrollableElement instanceof HTMLElement)) {
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
nestedScrollableElement.style.removeProperty("height");
|
|
480
|
+
nestedScrollableElement.style.removeProperty("maxHeight");
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
function runFloatingUpdateHook(popperElement) {
|
|
484
|
+
const hook = popperElement?.monsterBeforeFloatingUpdate;
|
|
485
|
+
if (typeof hook === "function") {
|
|
486
|
+
hook();
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
function getRequiredContentWidth(contentElement) {
|
|
491
|
+
const nestedScrollableElement = getNestedScrollableElement(contentElement);
|
|
492
|
+
if (nestedScrollableElement instanceof HTMLElement) {
|
|
493
|
+
return Math.max(
|
|
494
|
+
contentElement.scrollWidth,
|
|
495
|
+
nestedScrollableElement.scrollWidth,
|
|
496
|
+
contentElement.clientWidth,
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
return Math.max(contentElement.scrollWidth, contentElement.clientWidth);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
function getNestedScrollableElement(contentElement) {
|
|
504
|
+
for (const child of contentElement.children) {
|
|
505
|
+
if (!(child instanceof HTMLElement)) {
|
|
506
|
+
continue;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
const style = getComputedStyle(child);
|
|
510
|
+
if (["auto", "scroll"].includes(style.overflowY)) {
|
|
511
|
+
return child;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
return null;
|
|
280
516
|
}
|
|
281
517
|
|
|
282
518
|
function buildDetectOverflowOptions(boundaryElement) {
|
|
@@ -418,6 +654,8 @@ function startAutoUpdate(controlElement, popperElement, callback) {
|
|
|
418
654
|
}
|
|
419
655
|
|
|
420
656
|
function stopAutoUpdate(popperElement) {
|
|
657
|
+
cancelSettlingPass(popperElement);
|
|
658
|
+
stopFloatingResizeObserver(popperElement);
|
|
421
659
|
const cleanup = autoUpdateCleanupMap.get(popperElement);
|
|
422
660
|
if (typeof cleanup === "function") {
|
|
423
661
|
cleanup();
|
|
@@ -425,6 +663,47 @@ function stopAutoUpdate(popperElement) {
|
|
|
425
663
|
autoUpdateCleanupMap.delete(popperElement);
|
|
426
664
|
}
|
|
427
665
|
|
|
666
|
+
function startFloatingResizeObserver(controlElement, popperElement, config) {
|
|
667
|
+
stopFloatingResizeObserver(popperElement);
|
|
668
|
+
|
|
669
|
+
const observer = new ResizeObserver(() => {
|
|
670
|
+
scheduleSettlingPass(controlElement, popperElement, config);
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
observer.observe(popperElement);
|
|
674
|
+
floatingResizeObserverMap.set(popperElement, observer);
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
function stopFloatingResizeObserver(popperElement) {
|
|
678
|
+
const observer = floatingResizeObserverMap.get(popperElement);
|
|
679
|
+
if (observer instanceof ResizeObserver) {
|
|
680
|
+
observer.disconnect();
|
|
681
|
+
}
|
|
682
|
+
floatingResizeObserverMap.delete(popperElement);
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
function scheduleSettlingPass(controlElement, popperElement, config) {
|
|
686
|
+
if (settlingFrameMap.has(popperElement)) {
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
const frameId = requestAnimationFrame(() => {
|
|
691
|
+
settlingFrameMap.delete(popperElement);
|
|
692
|
+
runFloatingUpdateHook(popperElement);
|
|
693
|
+
syncFloatingPopover(controlElement, popperElement, config, false);
|
|
694
|
+
});
|
|
695
|
+
|
|
696
|
+
settlingFrameMap.set(popperElement, frameId);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
function cancelSettlingPass(popperElement) {
|
|
700
|
+
const frameId = settlingFrameMap.get(popperElement);
|
|
701
|
+
if (typeof frameId === "number") {
|
|
702
|
+
cancelAnimationFrame(frameId);
|
|
703
|
+
}
|
|
704
|
+
settlingFrameMap.delete(popperElement);
|
|
705
|
+
}
|
|
706
|
+
|
|
428
707
|
function applyFloatingArrowStyles(arrowElement, placement, arrowData) {
|
|
429
708
|
if (!(arrowElement instanceof HTMLElement)) {
|
|
430
709
|
return;
|
|
@@ -35,11 +35,14 @@ const rawDataSymbol = Symbol.for(
|
|
|
35
35
|
/**
|
|
36
36
|
* The RestAPI is a class that enables a REST API server.
|
|
37
37
|
*
|
|
38
|
+
* @fragments /fragments/libraries/data/datasource/server/restapi/
|
|
39
|
+
*
|
|
38
40
|
* @externalExample ../../../../example/data/datasource/server/restapi.mjs
|
|
41
|
+
* @example /examples/libraries/data/datasource/server/restapi/simple/ Configure read and write endpoints
|
|
39
42
|
* @license AGPLv3
|
|
40
43
|
* @since 1.22.0
|
|
41
44
|
* @copyright Volker Schukai
|
|
42
|
-
* @summary
|
|
45
|
+
* @summary A REST-backed datasource for reading and writing application state over HTTP.
|
|
43
46
|
*/
|
|
44
47
|
class RestAPI extends Server {
|
|
45
48
|
/**
|
|
@@ -31,11 +31,14 @@ const webConnectSymbol = Symbol("connection");
|
|
|
31
31
|
/**
|
|
32
32
|
* The RestAPI is a class that enables a REST API server.
|
|
33
33
|
*
|
|
34
|
+
* @fragments /fragments/libraries/data/datasource/server/webconnect/
|
|
35
|
+
*
|
|
34
36
|
* @externalExample ../../../../example/data/datasource/server/webconnect.mjs
|
|
37
|
+
* @example /examples/libraries/data/datasource/server/webconnect/simple/ Configure a realtime datasource bridge
|
|
35
38
|
* @license AGPLv3
|
|
36
39
|
* @since 3.1.0
|
|
37
40
|
* @copyright Volker Schukai
|
|
38
|
-
* @summary
|
|
41
|
+
* @summary A realtime datasource that bridges WebConnect messages into the datasource API.
|
|
39
42
|
*/
|
|
40
43
|
class WebConnect extends Server {
|
|
41
44
|
/**
|
|
@@ -30,10 +30,13 @@ const serverVersionSymbol = Symbol("serverVersion");
|
|
|
30
30
|
/**
|
|
31
31
|
* Base class for all server data sources
|
|
32
32
|
*
|
|
33
|
+
* @fragments /fragments/libraries/data/datasource/server/
|
|
34
|
+
*
|
|
35
|
+
* @example /examples/libraries/data/datasource/server/simple/ Transform and prepare server payloads
|
|
33
36
|
* @license AGPLv3
|
|
34
37
|
* @since 3.4.0
|
|
35
38
|
* @copyright Volker Schukai
|
|
36
|
-
* @summary
|
|
39
|
+
* @summary A base datasource layer for reading, transforming and writing structured server payloads.
|
|
37
40
|
*/
|
|
38
41
|
class Server extends Datasource {
|
|
39
42
|
/**
|
|
@@ -29,6 +29,9 @@ const storageObjectSymbol = Symbol.for(
|
|
|
29
29
|
/**
|
|
30
30
|
* The class represents a record.
|
|
31
31
|
*
|
|
32
|
+
* @fragments /fragments/libraries/data/datasource/storage/
|
|
33
|
+
*
|
|
34
|
+
* @example /examples/libraries/data/datasource/storage/simple/ Read and write JSON through Web Storage
|
|
32
35
|
* @license AGPLv3
|
|
33
36
|
* @since 1.22.0
|
|
34
37
|
* @copyright Volker Schukai
|
|
@@ -48,6 +48,12 @@ const internalDataSymbol = Symbol.for(
|
|
|
48
48
|
* The datasource class is the basis for dealing with different data sources.
|
|
49
49
|
* It provides a unified interface for accessing data
|
|
50
50
|
* @externalExample ../../example/data/datasource.mjs
|
|
51
|
+
* @fragments /fragments/libraries/data/datasource/
|
|
52
|
+
* @example /examples/libraries/data/datasource/basic-read-write/ Implement a small in memory datasource with read and write
|
|
53
|
+
* @example /examples/libraries/data/datasource/observer-log/ Attach observers and react to subject changes
|
|
54
|
+
* @example /examples/libraries/data/datasource/skip-noop-events/ Compare skipNoopEvents with repeated writes
|
|
55
|
+
* @example /examples/libraries/data/datasource/render-list/ Drive a small UI list from datasource updates
|
|
56
|
+
* @example /examples/libraries/data/datasource/async-options/ Use datasource options to control async reads
|
|
51
57
|
* @license AGPLv3
|
|
52
58
|
* @since 1.22.0
|
|
53
59
|
* @copyright Volker Schukai
|
package/source/dom/assembler.mjs
CHANGED
|
@@ -29,6 +29,9 @@ const ATTRIBUTEPREFIX = "data-monster-";
|
|
|
29
29
|
/**
|
|
30
30
|
* Assembler class
|
|
31
31
|
*
|
|
32
|
+
* @fragments /fragments/libraries/dom/assembler/
|
|
33
|
+
*
|
|
34
|
+
* @example /examples/libraries/dom/assembler/simple/ Basic assembly flow
|
|
32
35
|
* @license AGPLv3
|
|
33
36
|
* @since 1.6.0
|
|
34
37
|
* @copyright Volker Schukai
|
|
@@ -50,6 +50,11 @@ const attachedInternalSymbol = Symbol("attachedInternal");
|
|
|
50
50
|
* Read the HTML specification for Custom Element Reactions: {@link https://html.spec.whatwg.org/dev/custom-elements.html#custom-element-reactions|Custom Element Reactions}.
|
|
51
51
|
*
|
|
52
52
|
* @fragments /fragments/libraries/dom/customcontrol/
|
|
53
|
+
* @example /examples/libraries/dom/customcontrol/text-input/ Build a minimal form associated text control
|
|
54
|
+
* @example /examples/libraries/dom/customcontrol/validation/ Add validation and reportValidity behaviour
|
|
55
|
+
* @example /examples/libraries/dom/customcontrol/formdata-submit/ Submit structured FormData from a custom control
|
|
56
|
+
* @example /examples/libraries/dom/customcontrol/reset-behaviour/ Restore the control state on form reset
|
|
57
|
+
* @example /examples/libraries/dom/customcontrol/disabled-sync/ Sync disabled state from form containers into the control
|
|
53
58
|
*
|
|
54
59
|
* @summary A form-oriented base class for Monster controls with value handling, validation and control semantics.
|
|
55
60
|
* @license AGPLv3
|
|
@@ -190,6 +190,11 @@ let hostVisibilityStyleSheet = null;
|
|
|
190
190
|
* And in the [HTML Standard](https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements) or in the [WHATWG Wiki](https://wiki.whatwg.org/wiki/Custom_Elements).
|
|
191
191
|
*
|
|
192
192
|
* @fragments /fragments/libraries/dom/customelement/
|
|
193
|
+
* @example /examples/libraries/dom/customelement/simple-card/ Register a minimal element with inline template and stylesheet
|
|
194
|
+
* @example /examples/libraries/dom/customelement/options-from-attributes/ Read declarative options from data-monster-options
|
|
195
|
+
* @example /examples/libraries/dom/customelement/runtime-option-updates/ Update component state via setOption and setOptions
|
|
196
|
+
* @example /examples/libraries/dom/customelement/document-template/ Resolve the template from the surrounding document
|
|
197
|
+
* @example /examples/libraries/dom/customelement/visibility-events/ React to show hide and visibility events
|
|
193
198
|
*
|
|
194
199
|
* @license AGPLv3
|
|
195
200
|
* @since 1.7.0
|
|
@@ -42,6 +42,9 @@ const stackSymbol = Symbol("stack");
|
|
|
42
42
|
/**
|
|
43
43
|
* With the focus manager the focus can be stored in a document, recalled and moved.
|
|
44
44
|
*
|
|
45
|
+
* @fragments /fragments/libraries/dom/focusmanager/
|
|
46
|
+
*
|
|
47
|
+
* @example /examples/libraries/dom/focusmanager/simple/ Store and restore focus inside a dialog flow
|
|
45
48
|
* @license AGPLv3
|
|
46
49
|
* @since 1.25.0
|
|
47
50
|
* @copyright Volker Schukai
|
|
@@ -20,10 +20,13 @@ export { Stylesheet };
|
|
|
20
20
|
/**
|
|
21
21
|
* This class is used by the resource manager to embed external resources.
|
|
22
22
|
*
|
|
23
|
+
* @fragments /fragments/libraries/dom/resource/link/stylesheet/
|
|
24
|
+
*
|
|
25
|
+
* @example /examples/libraries/dom/resource/link/stylesheet/simple/ Configure a stylesheet resource
|
|
23
26
|
* @license AGPLv3
|
|
24
27
|
* @since 1.25.0
|
|
25
28
|
* @copyright Volker Schukai
|
|
26
|
-
* @summary A
|
|
29
|
+
* @summary A link resource specialized for loading external stylesheets.
|
|
27
30
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link
|
|
28
31
|
*/
|
|
29
32
|
class Stylesheet extends Link {
|
|
@@ -30,10 +30,13 @@ export { Link };
|
|
|
30
30
|
/**
|
|
31
31
|
* This class is used by the resource manager to embed external resources.
|
|
32
32
|
*
|
|
33
|
+
* @fragments /fragments/libraries/dom/resource/link/
|
|
34
|
+
*
|
|
35
|
+
* @example /examples/libraries/dom/resource/link/simple/ Create and connect a link resource
|
|
33
36
|
* @license AGPLv3
|
|
34
37
|
* @since 1.25.0
|
|
35
38
|
* @copyright Volker Schukai
|
|
36
|
-
* @summary A
|
|
39
|
+
* @summary A link resource for attaching external link-based assets such as stylesheets or preloads.
|
|
37
40
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link
|
|
38
41
|
*/
|
|
39
42
|
class Link extends Resource {
|
|
@@ -29,10 +29,13 @@ export { Script };
|
|
|
29
29
|
/**
|
|
30
30
|
* This class is used by the resource manager to embed scripts.
|
|
31
31
|
*
|
|
32
|
+
* @fragments /fragments/libraries/dom/resource/script/
|
|
33
|
+
*
|
|
34
|
+
* @example /examples/libraries/dom/resource/script/simple/ Create and connect a script resource
|
|
32
35
|
* @license AGPLv3
|
|
33
36
|
* @since 1.25.0
|
|
34
37
|
* @copyright Volker Schukai
|
|
35
|
-
* @summary A
|
|
38
|
+
* @summary A script resource for inserting external JavaScript files into the document.
|
|
36
39
|
*/
|
|
37
40
|
class Script extends Resource {
|
|
38
41
|
/**
|
package/source/dom/resource.mjs
CHANGED
|
@@ -56,10 +56,13 @@ const referenceSymbol = Symbol("reference");
|
|
|
56
56
|
/**
|
|
57
57
|
* This class is the base class for all resources to be loaded.
|
|
58
58
|
*
|
|
59
|
+
* @fragments /fragments/libraries/dom/resource/
|
|
60
|
+
*
|
|
61
|
+
* @example /examples/libraries/dom/resource/simple/ Create and connect a DOM resource
|
|
59
62
|
* @license AGPLv3
|
|
60
63
|
* @since 1.25.0
|
|
61
64
|
* @copyright Volker Schukai
|
|
62
|
-
* @summary A
|
|
65
|
+
* @summary A base resource abstraction for creating, connecting and observing DOM-loaded assets.
|
|
63
66
|
*/
|
|
64
67
|
class Resource extends BaseWithOptions {
|
|
65
68
|
/**
|
|
@@ -28,10 +28,16 @@ export { ResourceManager };
|
|
|
28
28
|
/**
|
|
29
29
|
* The ResourceManager is a singleton that manages all resources.
|
|
30
30
|
*
|
|
31
|
+
* @fragments /fragments/libraries/dom/resourcemanager/
|
|
32
|
+
*
|
|
33
|
+
* @example /examples/libraries/dom/resourcemanager/simple/ Register and connect multiple resources
|
|
34
|
+
* @example /examples/libraries/dom/resourcemanager/data-url-bundle/ Connect script stylesheet and data resources from inline urls
|
|
35
|
+
* @example /examples/libraries/dom/resourcemanager/separate-registration/ Register resources in separate steps and inspect the internal groups
|
|
36
|
+
* @example /examples/libraries/dom/resourcemanager/availability-check/ Wait for registered resources to report availability
|
|
31
37
|
* @license AGPLv3
|
|
32
38
|
* @since 1.25.0
|
|
33
39
|
* @copyright Volker Schukai
|
|
34
|
-
* @summary A
|
|
40
|
+
* @summary A resource coordinator for registering and connecting scripts, stylesheets and data assets.
|
|
35
41
|
*/
|
|
36
42
|
class ResourceManager extends Base {
|
|
37
43
|
/**
|
package/source/dom/template.mjs
CHANGED
|
@@ -25,6 +25,12 @@ export { Template };
|
|
|
25
25
|
/**
|
|
26
26
|
* The template class provides methods for creating templates.
|
|
27
27
|
*
|
|
28
|
+
* @fragments /fragments/libraries/dom/template/
|
|
29
|
+
*
|
|
30
|
+
* @example /examples/libraries/dom/template/simple/ Clone a named template fragment
|
|
31
|
+
* @example /examples/libraries/dom/template/theme-specific/ Resolve theme specific templates by id suffix
|
|
32
|
+
* @example /examples/libraries/dom/template/prefixed-lookup/ Resolve prefixed templates near the current node
|
|
33
|
+
* @example /examples/libraries/dom/template/repeated-clones/ Clone the same template multiple times without mutating the source
|
|
28
34
|
* @license AGPLv3
|
|
29
35
|
* @since 1.6.0
|
|
30
36
|
* @copyright Volker Schukai
|
package/source/dom/updater.mjs
CHANGED
|
@@ -105,6 +105,15 @@ const queuedSnapshotSymbol = Symbol("queuedSnapshot");
|
|
|
105
105
|
* @fragments /fragments/libraries/dom/updater/
|
|
106
106
|
*
|
|
107
107
|
* @example /examples/libraries/dom/updater/simple/ Simple example
|
|
108
|
+
* @example /examples/libraries/dom/updater/properties-and-patch/ Properties, patching and keyed list rendering
|
|
109
|
+
* @example /examples/libraries/dom/updater/attributes-and-aria/ Attribute and ARIA mapping
|
|
110
|
+
* @example /examples/libraries/dom/updater/bind-types/ Bound value casting
|
|
111
|
+
* @example /examples/libraries/dom/updater/retrieve-once/ One-time retrieval without live events
|
|
112
|
+
* @example /examples/libraries/dom/updater/insert-template-list/ Template insertion for iterable data
|
|
113
|
+
* @example /examples/libraries/dom/updater/custom-callbacks/ Custom pipe callbacks
|
|
114
|
+
* @example /examples/libraries/dom/updater/batch-updates/ Batched update processing
|
|
115
|
+
* @example /examples/libraries/dom/updater/control-properties/ Property updates on native controls
|
|
116
|
+
* @example /examples/libraries/dom/updater/select-multiple-array/ Multi-select array binding
|
|
108
117
|
*
|
|
109
118
|
* @license AGPLv3
|
|
110
119
|
* @since 1.8.0
|
|
@@ -35,6 +35,7 @@ const internalTranslationSymbol = Symbol("internalTranslation");
|
|
|
35
35
|
* @license AGPLv3
|
|
36
36
|
* @since 1.26.0
|
|
37
37
|
* @copyright Volker Schukai
|
|
38
|
+
* @summary An i18n formatter for locale-aware number, date and text presentation.
|
|
38
39
|
*/
|
|
39
40
|
class Formatter extends TextFormatter {
|
|
40
41
|
/**
|
package/source/i18n/locale.mjs
CHANGED
|
@@ -68,6 +68,7 @@ const localeStringSymbol = Symbol("localeString");
|
|
|
68
68
|
* @license AGPLv3
|
|
69
69
|
* @since 1.13.0
|
|
70
70
|
* @copyright Volker Schukai
|
|
71
|
+
* @summary A locale value object for parsing, validating and formatting language-region identifiers.
|
|
71
72
|
* @see https://datatracker.ietf.org/doc/html/rfc3066
|
|
72
73
|
*/
|
|
73
74
|
class Locale extends Base {
|
package/source/i18n/provider.mjs
CHANGED
|
@@ -38,9 +38,13 @@ const translationsLinkSymbol = Symbol.for(
|
|
|
38
38
|
/**
|
|
39
39
|
* A provider makes a translation object available.
|
|
40
40
|
*
|
|
41
|
+
* @fragments /fragments/libraries/i18n/provider/
|
|
42
|
+
*
|
|
43
|
+
* @example /examples/libraries/i18n/provider/simple/ Assign translations to a document
|
|
41
44
|
* @license AGPLv3
|
|
42
45
|
* @since 1.13.0
|
|
43
46
|
* @copyright Volker Schukai
|
|
47
|
+
* @summary A translation provider base class for loading and attaching locale-dependent text sources.
|
|
44
48
|
* @see {@link https://datatracker.ietf.org/doc/html/rfc3066}
|
|
45
49
|
*/
|
|
46
50
|
class Provider extends BaseWithOptions {
|
|
@@ -30,6 +30,7 @@ export { Embed };
|
|
|
30
30
|
* @license AGPLv3
|
|
31
31
|
* @since 1.13.0
|
|
32
32
|
* @copyright Volker Schukai
|
|
33
|
+
* @summary A translation provider that reads embedded locale resources from the current document.
|
|
33
34
|
* @see {@link https://datatracker.ietf.org/doc/html/rfc3066}
|
|
34
35
|
*/
|
|
35
36
|
class Embed extends Provider {
|
|
@@ -31,6 +31,7 @@ export { Fetch };
|
|
|
31
31
|
* @license AGPLv3
|
|
32
32
|
* @since 1.13.0
|
|
33
33
|
* @copyright Volker Schukai
|
|
34
|
+
* @summary A translation provider that loads locale resources from remote endpoints via fetch.
|
|
34
35
|
* @see {@link https://datatracker.ietf.org/doc/html/rfc3066}
|
|
35
36
|
* @tutorial i18n-locale-and-formatter
|
|
36
37
|
*/
|
|
@@ -36,9 +36,14 @@ export { Translations, getDocumentTranslations };
|
|
|
36
36
|
* @fragments /fragments/libraries/i18n/translations/
|
|
37
37
|
*
|
|
38
38
|
* @externalExample ../../example/i18n/translations.mjs
|
|
39
|
+
* @example /examples/libraries/i18n/translations/simple/ Resolve singular and plural translations
|
|
40
|
+
* @example /examples/libraries/i18n/translations/bulk-assignment/ Load multiple translation keys from plain objects
|
|
41
|
+
* @example /examples/libraries/i18n/translations/fallbacks/ Use explicit default text when a key is missing
|
|
42
|
+
* @example /examples/libraries/i18n/translations/plural-keywords/ Resolve plural texts with explicit plural rule keywords
|
|
39
43
|
* @license AGPLv3
|
|
40
44
|
* @since 1.13.0
|
|
41
45
|
* @copyright Volker Schukai
|
|
46
|
+
* @summary A translation registry for storing localized text keys and resolving plural-aware output.
|
|
42
47
|
* @see https://datatracker.ietf.org/doc/html/rfc3066
|
|
43
48
|
*/
|
|
44
49
|
class Translations extends Base {
|
|
@@ -22,9 +22,13 @@ export { Handler };
|
|
|
22
22
|
/**
|
|
23
23
|
* The log handler is the interface between the log entries and the log listeners.
|
|
24
24
|
*
|
|
25
|
+
* @fragments /fragments/libraries/logging/handler/
|
|
26
|
+
*
|
|
27
|
+
* @example /examples/libraries/logging/handler/simple/ Filter log entries before forwarding them
|
|
25
28
|
* @license AGPLv3
|
|
26
29
|
* @since 1.5.0
|
|
27
30
|
* @copyright Volker Schukai
|
|
31
|
+
* @summary A logging handler base class for processing and exporting log entries.
|
|
28
32
|
*/
|
|
29
33
|
class Handler extends Base {
|
|
30
34
|
constructor() {
|
|
@@ -68,9 +68,13 @@ const OFF = 0;
|
|
|
68
68
|
/**
|
|
69
69
|
* The logger is a class that takes care of logging.
|
|
70
70
|
*
|
|
71
|
+
* @fragments /fragments/libraries/logging/logger/
|
|
72
|
+
*
|
|
73
|
+
* @example /examples/libraries/logging/logger/simple/ Write entries through a console handler
|
|
71
74
|
* @license AGPLv3
|
|
72
75
|
* @since 1.5.0
|
|
73
76
|
* @copyright Volker Schukai
|
|
77
|
+
* @summary A logger for collecting log entries and forwarding them to one or more handlers.
|
|
74
78
|
*/
|
|
75
79
|
class Logger extends Base {
|
|
76
80
|
/**
|
|
@@ -22,10 +22,13 @@ const dataSymbol = Symbol("@@data");
|
|
|
22
22
|
/**
|
|
23
23
|
* This class represents a WebSocket message.
|
|
24
24
|
*
|
|
25
|
+
* @fragments /fragments/libraries/net/webconnect/message/
|
|
26
|
+
*
|
|
27
|
+
* @example /examples/libraries/net/webconnect/message/simple/ Serialize and restore a structured message
|
|
25
28
|
* @license AGPLv3
|
|
26
29
|
* @since 3.4.0
|
|
27
30
|
* @copyright Volker Schukai
|
|
28
|
-
* @summary
|
|
31
|
+
* @summary A structured WebSocket message object for typed payload exchange over WebConnect.
|
|
29
32
|
*/
|
|
30
33
|
class Message extends Base {
|
|
31
34
|
/**
|
|
@@ -209,11 +209,14 @@ function connectServer(resolve, reject) {
|
|
|
209
209
|
/**
|
|
210
210
|
* The RestAPI is a class that enables a REST API server.
|
|
211
211
|
*
|
|
212
|
+
* @fragments /fragments/libraries/net/webconnect/
|
|
213
|
+
*
|
|
212
214
|
* @externalExample ../../example/net/webconnect.mjs
|
|
215
|
+
* @example /examples/libraries/net/webconnect/simple/ Connect and consume structured messages
|
|
213
216
|
* @license AGPLv3
|
|
214
217
|
* @since 3.1.0
|
|
215
218
|
* @copyright Volker Schukai
|
|
216
|
-
* @summary
|
|
219
|
+
* @summary A WebSocket connection wrapper for sending, receiving and observing structured real-time messages.
|
|
217
220
|
*/
|
|
218
221
|
class WebConnect extends BaseWithOptions {
|
|
219
222
|
/**
|
|
@@ -23,9 +23,12 @@ export { ObservableQueue };
|
|
|
23
23
|
*
|
|
24
24
|
* `Queue.add()` and `Queue.clear()` notify all observers.
|
|
25
25
|
*
|
|
26
|
+
* @fragments /fragments/libraries/types/observablequeue/
|
|
27
|
+
*
|
|
28
|
+
* @example /examples/libraries/types/observablequeue/simple/ Observe queue changes while items are added
|
|
26
29
|
* @since 3.3.0
|
|
27
30
|
* @copyright Volker Schukai
|
|
28
|
-
* @summary
|
|
31
|
+
* @summary A FIFO queue that notifies observers whenever its contents change.
|
|
29
32
|
*/
|
|
30
33
|
class ObservableQueue extends Queue {
|
|
31
34
|
/**
|
|
@@ -40,8 +40,12 @@ export { Observer };
|
|
|
40
40
|
* observer.update(mySubject);
|
|
41
41
|
* greeter.update(mySubject);
|
|
42
42
|
*
|
|
43
|
+
* @fragments /fragments/libraries/types/observer/
|
|
44
|
+
*
|
|
45
|
+
* @example /examples/libraries/types/observer/simple/ Schedule a deduplicated observer update
|
|
43
46
|
* @license AGPLv3
|
|
44
47
|
* @since 1.0.0
|
|
48
|
+
* @summary An asynchronous observer that batches updates per subject and callback.
|
|
45
49
|
*/
|
|
46
50
|
class Observer extends Base {
|
|
47
51
|
/**
|
|
@@ -4,6 +4,7 @@ import { initJSDOM } from "../../../util/jsdom.mjs";
|
|
|
4
4
|
let expect = chai.expect;
|
|
5
5
|
|
|
6
6
|
let resolveClippingBoundaryElement;
|
|
7
|
+
let applyAdaptiveFloatingElementSize;
|
|
7
8
|
|
|
8
9
|
describe("form floating-ui boundary resolution", function () {
|
|
9
10
|
before(function (done) {
|
|
@@ -15,6 +16,7 @@ describe("form floating-ui boundary resolution", function () {
|
|
|
15
16
|
})
|
|
16
17
|
.then((m) => {
|
|
17
18
|
resolveClippingBoundaryElement = m.resolveClippingBoundaryElement;
|
|
19
|
+
applyAdaptiveFloatingElementSize = m.applyAdaptiveFloatingElementSize;
|
|
18
20
|
done();
|
|
19
21
|
})
|
|
20
22
|
.catch((e) => done(e));
|
|
@@ -58,4 +60,79 @@ describe("form floating-ui boundary resolution", function () {
|
|
|
58
60
|
|
|
59
61
|
expect(resolveClippingBoundaryElement(control, popper)).to.equal(wrapper);
|
|
60
62
|
});
|
|
63
|
+
|
|
64
|
+
it("should adapt the content max height to the available popper height", function () {
|
|
65
|
+
const mocks = document.getElementById("mocks");
|
|
66
|
+
const popper = document.createElement("div");
|
|
67
|
+
const header = document.createElement("div");
|
|
68
|
+
const content = document.createElement("div");
|
|
69
|
+
const footer = document.createElement("div");
|
|
70
|
+
|
|
71
|
+
popper.style.maxHeight = "300px";
|
|
72
|
+
content.style.maxHeight = "240px";
|
|
73
|
+
content.setAttribute("part", "content");
|
|
74
|
+
|
|
75
|
+
popper.appendChild(header);
|
|
76
|
+
popper.appendChild(content);
|
|
77
|
+
popper.appendChild(footer);
|
|
78
|
+
mocks.appendChild(popper);
|
|
79
|
+
|
|
80
|
+
header.getBoundingClientRect = () => {
|
|
81
|
+
return {
|
|
82
|
+
width: 180,
|
|
83
|
+
height: 30,
|
|
84
|
+
top: 0,
|
|
85
|
+
left: 0,
|
|
86
|
+
right: 180,
|
|
87
|
+
bottom: 30,
|
|
88
|
+
x: 0,
|
|
89
|
+
y: 0,
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
popper.getBoundingClientRect = () => {
|
|
93
|
+
return {
|
|
94
|
+
width: 220,
|
|
95
|
+
height: 200,
|
|
96
|
+
top: 0,
|
|
97
|
+
left: 0,
|
|
98
|
+
right: 220,
|
|
99
|
+
bottom: 200,
|
|
100
|
+
x: 0,
|
|
101
|
+
y: 0,
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
footer.getBoundingClientRect = () => {
|
|
105
|
+
return {
|
|
106
|
+
width: 180,
|
|
107
|
+
height: 30,
|
|
108
|
+
top: 0,
|
|
109
|
+
left: 0,
|
|
110
|
+
right: 180,
|
|
111
|
+
bottom: 30,
|
|
112
|
+
x: 0,
|
|
113
|
+
y: 0,
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
content.getBoundingClientRect = () => {
|
|
117
|
+
return {
|
|
118
|
+
width: 180,
|
|
119
|
+
height: 140,
|
|
120
|
+
top: 0,
|
|
121
|
+
left: 0,
|
|
122
|
+
right: 180,
|
|
123
|
+
bottom: 140,
|
|
124
|
+
x: 0,
|
|
125
|
+
y: 0,
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
applyAdaptiveFloatingElementSize(popper, {
|
|
130
|
+
availableWidth: 220,
|
|
131
|
+
availableHeight: 160,
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
expect(popper.style.maxHeight).to.equal("160px");
|
|
135
|
+
expect(content.style.maxWidth).to.equal("");
|
|
136
|
+
expect(content.style.maxHeight).to.equal("100px");
|
|
137
|
+
});
|
|
61
138
|
});
|