@schukai/monster 4.142.0 → 4.142.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.","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.142.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.","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.142.1"}
@@ -610,6 +610,9 @@ function initEventHandler() {
610
610
  };
611
611
 
612
612
  self[resizeObserverSymbol] = new ResizeObserver((entries) => {
613
+ if (self[layoutStateSymbol]?.suppressResize) {
614
+ return;
615
+ }
613
616
  if (!hasContainerResizeEntry.call(self, entries)) {
614
617
  return;
615
618
  }
@@ -211,4 +211,115 @@ describe("ButtonBar", function () {
211
211
  globalThis.requestAnimationFrame = originalGlobalRequestAnimationFrame;
212
212
  }
213
213
  });
214
+
215
+ it("should ignore resize feedback caused by its own layout writes", async function () {
216
+ const OriginalResizeObserver = window.ResizeObserver;
217
+ const originalGlobalResizeObserver = globalThis.ResizeObserver;
218
+ const originalRequestAnimationFrame = window.requestAnimationFrame;
219
+ const originalGlobalRequestAnimationFrame = globalThis.requestAnimationFrame;
220
+
221
+ class TrackingResizeObserver extends ResizeObserverMock {
222
+ static instances = [];
223
+
224
+ constructor(callback) {
225
+ super(callback);
226
+ TrackingResizeObserver.instances.push(this);
227
+ }
228
+ }
229
+
230
+ const scheduledCallbacks = [];
231
+ const flushOneFrame = async () => {
232
+ const callback = scheduledCallbacks.shift();
233
+ if (callback instanceof Function) {
234
+ callback();
235
+ await new Promise((resolve) => setTimeout(resolve, 0));
236
+ }
237
+ };
238
+ const flushFrames = async () => {
239
+ while (scheduledCallbacks.length > 0) {
240
+ await flushOneFrame();
241
+ }
242
+ };
243
+
244
+ try {
245
+ window.ResizeObserver = TrackingResizeObserver;
246
+ globalThis.ResizeObserver = TrackingResizeObserver;
247
+ window.requestAnimationFrame = (callback) => {
248
+ scheduledCallbacks.push(callback);
249
+ return scheduledCallbacks.length;
250
+ };
251
+ globalThis.requestAnimationFrame = window.requestAnimationFrame;
252
+
253
+ const mocks = document.getElementById("mocks");
254
+ mocks.innerHTML = `
255
+ <div id="feedback-bar-wrapper">
256
+ <monster-button-bar id="feedback-bar">
257
+ <button type="button">One</button>
258
+ <button type="button">Two</button>
259
+ <button type="button">Three</button>
260
+ </monster-button-bar>
261
+ </div>
262
+ `;
263
+
264
+ const wrapper = document.getElementById("feedback-bar-wrapper");
265
+ const bar = document.getElementById("feedback-bar");
266
+
267
+ wrapper.style.boxSizing = "border-box";
268
+ wrapper.style.width = "80px";
269
+ Object.defineProperty(wrapper, "clientWidth", {
270
+ configurable: true,
271
+ value: 80,
272
+ });
273
+
274
+ const buttons = Array.from(bar.querySelectorAll("button"));
275
+ for (const button of buttons) {
276
+ Object.defineProperty(button, "offsetWidth", {
277
+ configurable: true,
278
+ value: 48,
279
+ });
280
+ button.getBoundingClientRect = () => ({
281
+ width: 48,
282
+ height: 32,
283
+ top: 0,
284
+ left: 0,
285
+ right: 48,
286
+ bottom: 32,
287
+ x: 0,
288
+ y: 0,
289
+ });
290
+ }
291
+
292
+ const switchButton = bar.shadowRoot.querySelector(
293
+ '[data-monster-role="switch"]',
294
+ );
295
+ Object.defineProperty(switchButton, "offsetWidth", {
296
+ configurable: true,
297
+ value: 20,
298
+ });
299
+
300
+ await flushOneFrame();
301
+
302
+ const resizeObserver = TrackingResizeObserver.instances.find((observer) =>
303
+ observer.elements.includes(wrapper),
304
+ );
305
+ expect(resizeObserver).to.exist;
306
+
307
+ const suppressedFrameCount = scheduledCallbacks.length;
308
+ resizeObserver.triggerResize([{ target: wrapper }]);
309
+ expect(scheduledCallbacks.length).to.equal(suppressedFrameCount);
310
+
311
+ await flushFrames();
312
+
313
+ resizeObserver.triggerResize([{ target: wrapper }]);
314
+ expect(scheduledCallbacks.length).to.equal(1);
315
+
316
+ await flushFrames();
317
+ expect(scheduledCallbacks.length).to.equal(0);
318
+ } finally {
319
+ window.ResizeObserver = OriginalResizeObserver;
320
+ globalThis.ResizeObserver = originalGlobalResizeObserver;
321
+ window.requestAnimationFrame = originalRequestAnimationFrame;
322
+ globalThis.requestAnimationFrame = originalGlobalRequestAnimationFrame;
323
+ }
324
+ });
214
325
  });