@vectoriox/iox-builder 1.5.9 → 1.5.10
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.
|
@@ -1277,16 +1277,12 @@ class InteractionEngineService {
|
|
|
1277
1277
|
return;
|
|
1278
1278
|
const cleanups = [];
|
|
1279
1279
|
for (const ix of node.interactions) {
|
|
1280
|
-
// Pre-state: hide target elements before their entrance animation fires
|
|
1281
|
-
//
|
|
1282
|
-
//
|
|
1283
|
-
//
|
|
1284
|
-
//
|
|
1285
|
-
|
|
1286
|
-
// click/hover keep pre-state because those triggers DO fire on the canvas.
|
|
1287
|
-
const skipPreState = inBuilder && (ix.trigger === 'pageLoad' ||
|
|
1288
|
-
ix.trigger === 'scrollProgress' ||
|
|
1289
|
-
ix.trigger === 'viewportEnter');
|
|
1280
|
+
// Pre-state: hide target elements before their entrance animation fires so
|
|
1281
|
+
// the user sees a real hidden→visible animation on the canvas. Every trigger
|
|
1282
|
+
// now runs live in the builder (see attachInteraction), so pre-state is applied
|
|
1283
|
+
// for all of them EXCEPT scrollProgress — that trigger is unimplemented (no-op),
|
|
1284
|
+
// so pre-stating it would leave the element stuck at opacity:0 forever.
|
|
1285
|
+
const skipPreState = inBuilder && ix.trigger === 'scrollProgress';
|
|
1290
1286
|
if (!skipPreState) {
|
|
1291
1287
|
for (const action of ix.actions) {
|
|
1292
1288
|
if (this.ENTRANCE_TYPES.has(action.type)) {
|
|
@@ -1413,16 +1409,13 @@ class InteractionEngineService {
|
|
|
1413
1409
|
}
|
|
1414
1410
|
// ── Private ──────────────────────────────────────────────
|
|
1415
1411
|
attachInteraction(node, ix, element) {
|
|
1416
|
-
//
|
|
1417
|
-
//
|
|
1418
|
-
//
|
|
1419
|
-
// the
|
|
1420
|
-
//
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
ix.trigger === 'viewportEnter')) {
|
|
1424
|
-
return () => { };
|
|
1425
|
-
}
|
|
1412
|
+
// All triggers run live in the builder canvas so the user sees the real
|
|
1413
|
+
// animation (pageLoad on attach, viewportEnter on scroll-into-view, click/hover).
|
|
1414
|
+
// The former NG0103 crash was caused by (a) Swiper's ResizeObserver created inside
|
|
1415
|
+
// the Angular zone — fixed in SliderContainerComponent via runOutsideAngular — and
|
|
1416
|
+
// (b) the overlay's Resize/MutationObservers synchronously re-dirtying the view
|
|
1417
|
+
// during synchronize() — fixed by coalescing overlay updates through a RAF.
|
|
1418
|
+
// scrollProgress is still unimplemented and returns a no-op below.
|
|
1426
1419
|
switch (ix.trigger) {
|
|
1427
1420
|
case 'pageLoad':
|
|
1428
1421
|
return this.attachPageLoad(node, ix, element);
|
|
@@ -2978,12 +2971,20 @@ class OverlayComponent {
|
|
|
2978
2971
|
// Tracks which badge was last clicked — used by Cmd+C in page-ui.
|
|
2979
2972
|
this.activeBadgeType = null;
|
|
2980
2973
|
this.subs = [];
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2974
|
+
// All overlay repositioning is funnelled through a single coalesced RAF.
|
|
2975
|
+
// Observer callbacks (Resize/Mutation) MUST NOT call updateAll()/markForCheck()
|
|
2976
|
+
// synchronously — during a live interaction animation they can fire while
|
|
2977
|
+
// Angular is inside ApplicationRef.synchronize(), re-dirtying the view within
|
|
2978
|
+
// the same loop and blowing past MAX_SYNC_RUNS → NG0103. scheduleUpdate() defers
|
|
2979
|
+
// the markForCheck to the next frame, outside the current synchronize() pass,
|
|
2980
|
+
// and collapses a burst of notifications into one update per frame.
|
|
2981
|
+
this._updateRaf = 0;
|
|
2982
|
+
this.scheduleUpdate = () => {
|
|
2983
|
+
cancelAnimationFrame(this._updateRaf);
|
|
2984
|
+
this._updateRaf = requestAnimationFrame(() => this.updateAll());
|
|
2986
2985
|
};
|
|
2986
|
+
this.boundUpdate = () => this.scheduleUpdate();
|
|
2987
|
+
this.boundScrollUpdate = () => this.scheduleUpdate();
|
|
2987
2988
|
this.activeScrollContainer = null;
|
|
2988
2989
|
}
|
|
2989
2990
|
ngOnInit() {
|
|
@@ -3003,16 +3004,16 @@ class OverlayComponent {
|
|
|
3003
3004
|
// Re-calculate overlay positions whenever zoom / device changes.
|
|
3004
3005
|
this.subs.push(this.viewportService.state$.subscribe(() => {
|
|
3005
3006
|
// Delay one frame so the DOM has applied the new transform/width.
|
|
3006
|
-
|
|
3007
|
+
this.scheduleUpdate();
|
|
3007
3008
|
}));
|
|
3008
3009
|
// Re-calculate when CSS rules change (margin/width applied via stylesheet).
|
|
3009
|
-
this.subs.push(this.styleRegistry.changes$.subscribe(() =>
|
|
3010
|
+
this.subs.push(this.styleRegistry.changes$.subscribe(() => this.scheduleUpdate()));
|
|
3010
3011
|
// Watch the canvas container for size changes (e.g. right panel open/close
|
|
3011
3012
|
// transition changes canvas width, shifting element positions).
|
|
3012
3013
|
const container = this.overlayService.getContainer();
|
|
3013
3014
|
if (container) {
|
|
3014
3015
|
if (typeof ResizeObserver !== 'undefined') {
|
|
3015
|
-
this.containerResizeObserver = new ResizeObserver(
|
|
3016
|
+
this.containerResizeObserver = new ResizeObserver(this.scheduleUpdate);
|
|
3016
3017
|
this.containerResizeObserver.observe(container);
|
|
3017
3018
|
}
|
|
3018
3019
|
}
|
|
@@ -3036,7 +3037,7 @@ class OverlayComponent {
|
|
|
3036
3037
|
this.resizeObserver?.disconnect();
|
|
3037
3038
|
this.containerResizeObserver?.disconnect();
|
|
3038
3039
|
this.mutationObserver?.disconnect();
|
|
3039
|
-
cancelAnimationFrame(this.
|
|
3040
|
+
cancelAnimationFrame(this._updateRaf);
|
|
3040
3041
|
window.removeEventListener('resize', this.boundUpdate);
|
|
3041
3042
|
this.activeScrollContainer?.removeEventListener('scroll', this.boundScrollUpdate);
|
|
3042
3043
|
this.activeScrollContainer = null;
|
|
@@ -3302,12 +3303,12 @@ class OverlayComponent {
|
|
|
3302
3303
|
skipFirst = false;
|
|
3303
3304
|
return;
|
|
3304
3305
|
}
|
|
3305
|
-
this.
|
|
3306
|
+
this.scheduleUpdate();
|
|
3306
3307
|
});
|
|
3307
3308
|
this.resizeObserver.observe(styledEl);
|
|
3308
3309
|
}
|
|
3309
3310
|
// MutationObserver — catches style attribute changes (margin, padding etc.)
|
|
3310
|
-
this.mutationObserver = new MutationObserver(
|
|
3311
|
+
this.mutationObserver = new MutationObserver(this.scheduleUpdate);
|
|
3311
3312
|
this.mutationObserver.observe(styledEl, {
|
|
3312
3313
|
attributes: true,
|
|
3313
3314
|
attributeFilter: ['style', 'class'],
|