diff --git a/src/embed/app.spec.ts b/src/embed/app.spec.ts index 1fdbf02c..d26ea86e 100644 --- a/src/embed/app.spec.ts +++ b/src/embed/app.spec.ts @@ -1734,11 +1734,32 @@ describe('App embed tests', () => { appEmbed.destroy(); expect(removeEventListenerSpy).toHaveBeenCalledWith('resize', expect.any(Function)); - expect(removeEventListenerSpy).toHaveBeenCalledWith('scroll', expect.any(Function)); + expect(removeEventListenerSpy).toHaveBeenCalledWith('scroll', expect.any(Function), true); removeEventListenerSpy.mockRestore(); }); + test('should skip lazy load data when iframe is unavailable', async () => { + const appEmbed = new AppEmbed(getRootEl(), { + ...defaultViewConfig, + fullHeight: true, + lazyLoadingForFullHeight: true, + lazyLoadingMargin: '10px', + } as AppViewConfig); + + const mockTrigger = jest.spyOn(appEmbed, 'trigger'); + + await appEmbed.render(); + + (appEmbed as any).iFrame = undefined; + (appEmbed as any).sendFullHeightLazyLoadData(); + + expect(mockTrigger).not.toHaveBeenCalledWith( + HostEvent.VisibleEmbedCoordinates, + expect.anything() + ); + }); + test('should handle RequestVisibleEmbedCoordinates event and respond with correct data', async () => { // Mock the iframe element mockIFrame.getBoundingClientRect = jest.fn().mockReturnValue({ @@ -1780,6 +1801,24 @@ describe('App embed tests', () => { }, }); }); + + test('should not respond to RequestVisibleEmbedCoordinates when iframe is unavailable', async () => { + const appEmbed = new AppEmbed(getRootEl(), { + ...defaultViewConfig, + fullHeight: true, + lazyLoadingForFullHeight: true, + lazyLoadingMargin: '10px', + } as AppViewConfig); + + await appEmbed.render(); + + const mockResponder = jest.fn(); + + (appEmbed as any).iFrame = undefined; + (appEmbed as any).requestVisibleEmbedCoordinatesHandler({}, mockResponder); + + expect(mockResponder).not.toHaveBeenCalled(); + }); }); describe('IFrame height management', () => { @@ -1966,4 +2005,3 @@ describe('AppEmbed visualOverrides tests', () => { }); }); - diff --git a/src/embed/app.ts b/src/embed/app.ts index 82ee7668..f39dec7c 100644 --- a/src/embed/app.ts +++ b/src/embed/app.ts @@ -1130,9 +1130,13 @@ export class AppEmbed extends V1Embed { } private sendFullHeightLazyLoadData = () => { + if (!this.iFrame?.getBoundingClientRect) { + return; + } + const data = calculateVisibleElementData(this.iFrame); // this should be fired only if the lazyLoadingForFullHeight and fullHeight are true - if(this.viewConfig.lazyLoadingForFullHeight && this.viewConfig.fullHeight){ + if (this.viewConfig.lazyLoadingForFullHeight && this.viewConfig.fullHeight) { this.trigger(HostEvent.VisibleEmbedCoordinates, data); } } @@ -1145,6 +1149,11 @@ export class AppEmbed extends V1Embed { */ private requestVisibleEmbedCoordinatesHandler = (data: MessagePayload, responder: any) => { logger.info('Sending RequestVisibleEmbedCoordinates', data); + + if (!this.iFrame?.getBoundingClientRect) { + return; + } + const visibleCoordinatesData = calculateVisibleElementData(this.iFrame); responder({ type: EmbedEvent.RequestVisibleEmbedCoordinates, data: visibleCoordinatesData }); } @@ -1304,7 +1313,7 @@ export class AppEmbed extends V1Embed { private unregisterLazyLoadEvents() { if (this.viewConfig.fullHeight && this.viewConfig.lazyLoadingForFullHeight) { window.removeEventListener('resize', this.sendFullHeightLazyLoadData); - window.removeEventListener('scroll', this.sendFullHeightLazyLoadData); + window.removeEventListener('scroll', this.sendFullHeightLazyLoadData, true); } } diff --git a/src/embed/liveboard.spec.ts b/src/embed/liveboard.spec.ts index d434271f..d33026f3 100644 --- a/src/embed/liveboard.spec.ts +++ b/src/embed/liveboard.spec.ts @@ -1850,11 +1850,33 @@ describe('Liveboard/viz embed tests', () => { liveboardEmbed.destroy(); expect(removeEventListenerSpy).toHaveBeenCalledWith('resize', expect.anything()); - expect(removeEventListenerSpy).toHaveBeenCalledWith('scroll', expect.anything()); + expect(removeEventListenerSpy).toHaveBeenCalledWith('scroll', expect.anything(), true); removeEventListenerSpy.mockRestore(); }); + test('should skip lazy load data when iframe is unavailable', async () => { + const liveboardEmbed = new LiveboardEmbed(getRootEl(), { + ...defaultViewConfig, + liveboardId, + fullHeight: true, + lazyLoadingForFullHeight: true, + lazyLoadingMargin: '10px', + } as LiveboardViewConfig); + + const mockTrigger = jest.spyOn(liveboardEmbed, 'trigger'); + + await liveboardEmbed.render(); + + (liveboardEmbed as any).iFrame = undefined; + (liveboardEmbed as any).sendFullHeightLazyLoadData(); + + expect(mockTrigger).not.toHaveBeenCalledWith( + HostEvent.VisibleEmbedCoordinates, + expect.anything() + ); + }); + test('should handle RequestVisibleEmbedCoordinates event and respond with correct data', async () => { // Mock the iframe element mockIFrame.getBoundingClientRect = jest.fn().mockReturnValue({ @@ -1897,6 +1919,25 @@ describe('Liveboard/viz embed tests', () => { }, }); }); + + test('should not respond to RequestVisibleEmbedCoordinates when iframe is unavailable', async () => { + const liveboardEmbed = new LiveboardEmbed(getRootEl(), { + ...defaultViewConfig, + liveboardId, + fullHeight: true, + lazyLoadingForFullHeight: true, + lazyLoadingMargin: '10px', + } as LiveboardViewConfig); + + await liveboardEmbed.render(); + + const mockResponder = jest.fn(); + + (liveboardEmbed as any).iFrame = undefined; + (liveboardEmbed as any).requestVisibleEmbedCoordinatesHandler({}, mockResponder); + + expect(mockResponder).not.toHaveBeenCalled(); + }); }); describe('Host events for liveborad', () => { diff --git a/src/embed/liveboard.ts b/src/embed/liveboard.ts index dadd45ba..0beac722 100644 --- a/src/embed/liveboard.ts +++ b/src/embed/liveboard.ts @@ -825,9 +825,13 @@ export class LiveboardEmbed extends V1Embed { } private sendFullHeightLazyLoadData = () => { + if (!this.iFrame?.getBoundingClientRect) { + return; + } + const data = calculateVisibleElementData(this.iFrame); // this should be fired only if the lazyLoadingForFullHeight and fullHeight are true - if(this.viewConfig.lazyLoadingForFullHeight && this.viewConfig.fullHeight){ + if (this.viewConfig.lazyLoadingForFullHeight && this.viewConfig.fullHeight) { this.trigger(HostEvent.VisibleEmbedCoordinates, data); } }; @@ -840,6 +844,11 @@ export class LiveboardEmbed extends V1Embed { */ private requestVisibleEmbedCoordinatesHandler = (data: MessagePayload, responder: any) => { logger.info('Sending RequestVisibleEmbedCoordinates', data); + + if (!this.iFrame?.getBoundingClientRect) { + return; + } + const visibleCoordinatesData = calculateVisibleElementData(this.iFrame); responder({ type: EmbedEvent.RequestVisibleEmbedCoordinates, data: visibleCoordinatesData }); } @@ -1033,7 +1042,7 @@ export class LiveboardEmbed extends V1Embed { private unregisterLazyLoadEvents() { if (this.viewConfig.fullHeight && this.viewConfig.lazyLoadingForFullHeight) { window.removeEventListener('resize', this.sendFullHeightLazyLoadData); - window.removeEventListener('scroll', this.sendFullHeightLazyLoadData); + window.removeEventListener('scroll', this.sendFullHeightLazyLoadData, true); } }