@schukai/monster 4.154.0 → 4.154.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/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.","exports":{".":"./source/monster.mjs","./CHANGELOG.md":"./CHANGELOG.md","./LICENSE":"./LICENSE","./README.md":"./README.md","./package.json":"./package.json","./source/*":"./source/*","./test/*":"./test/*"},"files":["source","test/cases","test/util","CHANGELOG.md"],"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"},"sideEffects":["./source/monster.mjs","./source/components/**","./source/i18n/**","./test/**"],"type":"module","version":"4.154.0"}
1
+ {"author":"Volker Schukai","dependencies":{"@floating-ui/dom":"^1.7.6"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","exports":{".":"./source/monster.mjs","./CHANGELOG.md":"./CHANGELOG.md","./LICENSE":"./LICENSE","./README.md":"./README.md","./package.json":"./package.json","./source/*":"./source/*","./test/*":"./test/*"},"files":["source","test/cases","test/util","CHANGELOG.md"],"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"},"sideEffects":["./source/monster.mjs","./source/components/**","./source/i18n/**","./test/**"],"type":"module","version":"4.154.1"}
@@ -6,6 +6,25 @@ import { ResizeObserverMock } from "../../../util/resize-observer.mjs";
6
6
  const expect = chai.expect;
7
7
  chai.use(chaiDom);
8
8
 
9
+ /**
10
+ * Waits for a value to appear instead of for a fixed delay.
11
+ *
12
+ * The components under test attach their ResizeObserver inside a
13
+ * requestAnimationFrame, so the precondition is a frame, not a number of
14
+ * milliseconds. A headless browser without a compositor schedules frames less
15
+ * regularly, which is why a fixed 30ms wait failed in CI webkit while passing
16
+ * everywhere else. The deadline keeps a genuine absence failing.
17
+ */
18
+ async function waitForValue(produce, timeout = 2000, interval = 10) {
19
+ const deadline = Date.now() + timeout;
20
+ for (;;) {
21
+ const value = produce();
22
+ if (value !== undefined && value !== null) return value;
23
+ if (Date.now() >= deadline) return value;
24
+ await new Promise((resolve) => setTimeout(resolve, interval));
25
+ }
26
+ }
27
+
9
28
  // Supply geometry before the first layout can populate the measurement cache.
10
29
  function installColumnBarGeometry(parentWidth) {
11
30
  const original = HTMLElement.prototype.getBoundingClientRect;
@@ -434,10 +453,13 @@ describe("Datatable drag scroll", function () {
434
453
  );
435
454
  expect(control).to.exist;
436
455
  expect(control.classList.contains("small")).to.equal(false);
437
- expect(TrackingResizeObserver.instances).to.have.length.greaterThan(0);
438
- const tableResizeObserver = TrackingResizeObserver.instances.find(
439
- (observer) => observer.elements.includes(wrapper),
456
+ const tableResizeObserver = await waitForValue(() =>
457
+ TrackingResizeObserver.instances.find((observer) =>
458
+ observer.elements.includes(wrapper),
459
+ ),
440
460
  );
461
+
462
+ expect(TrackingResizeObserver.instances).to.have.length.greaterThan(0);
441
463
  expect(tableResizeObserver).to.exist;
442
464
 
443
465
  let scheduledCallback = null;
@@ -456,6 +478,10 @@ describe("Datatable drag scroll", function () {
456
478
  scheduledCallback();
457
479
 
458
480
  expect(control.classList.contains("small")).to.equal(true);
481
+
482
+ // The responsive layout stays in the document otherwise, and the
483
+ // browser keeps rendering it for the rest of the run.
484
+ wrapper.remove();
459
485
  } finally {
460
486
  window.ResizeObserver = OriginalResizeObserver;
461
487
  globalThis.ResizeObserver = originalGlobalResizeObserver;
@@ -546,8 +572,10 @@ describe("Datatable drag scroll", function () {
546
572
  dotsContainer.querySelector(".dots-overflow-indicator"),
547
573
  ).to.equal(null);
548
574
 
549
- const columnBarResizeObserver = TrackingResizeObserver.instances.find(
550
- (observer) => observer.elements.includes(control),
575
+ const columnBarResizeObserver = await waitForValue(() =>
576
+ TrackingResizeObserver.instances.find((observer) =>
577
+ observer.elements.includes(control),
578
+ ),
551
579
  );
552
580
  expect(columnBarResizeObserver).to.exist;
553
581
 
@@ -660,11 +688,15 @@ describe("Datatable drag scroll", function () {
660
688
  const first = await createColumnBar();
661
689
  const second = await createColumnBar();
662
690
 
663
- const firstResizeObserver = TrackingResizeObserver.instances.find(
664
- (observer) => observer.elements.includes(first.control),
691
+ const firstResizeObserver = await waitForValue(() =>
692
+ TrackingResizeObserver.instances.find((observer) =>
693
+ observer.elements.includes(first.control),
694
+ ),
665
695
  );
666
- const secondResizeObserver = TrackingResizeObserver.instances.find(
667
- (observer) => observer.elements.includes(second.control),
696
+ const secondResizeObserver = await waitForValue(() =>
697
+ TrackingResizeObserver.instances.find((observer) =>
698
+ observer.elements.includes(second.control),
699
+ ),
668
700
  );
669
701
 
670
702
  expect(firstResizeObserver).to.exist;
@@ -77,7 +77,16 @@ describe("SiteNavigation", function () {
77
77
  resizeObserver.triggerResize([]);
78
78
  resizeObserver.triggerResize([]);
79
79
 
80
- await new Promise(resolve => setTimeout(resolve, 260));
80
+ // The component debounces resizes with a 200ms DeadMansSwitch and then
81
+ // requests exactly one frame. Waiting 260ms left 60ms of margin over
82
+ // that debounce, which is not enough under software rendering: the run
83
+ // then measured zero scheduled frames. Waiting for the first request
84
+ // keeps the coalescing assertion strict without assuming wall clock.
85
+ const deadline = Date.now() + 5000;
86
+ while (scheduledCallbacks.length === 0 && Date.now() < deadline) {
87
+ await new Promise((resolve) => setTimeout(resolve, 10));
88
+ }
89
+
81
90
  expect(scheduledCallbacks.length).to.equal(1);
82
91
  scheduledCallbacks.shift()();
83
92
  } finally {