Skip to content

Commit 5da6711

Browse files
authored
Merge branch 'master' into copilot/implement-automated-eval-test-suite
2 parents 568b04d + 28ad300 commit 5da6711

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

projects/igniteui-angular/core/src/services/overlay/overlay.spec.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,44 @@ describe('igxOverlay', () => {
12401240
// expect(mockElement.style.height).toBe('100px');
12411241
// });
12421242

1243+
it('#16988 - should not reposition overlay when detached', fakeAsync(() => {
1244+
const fixture = TestBed.createComponent(EmptyPageComponent);
1245+
fixture.debugElement.nativeElement.appendChild(outlet);
1246+
outlet.style.width = '800px';
1247+
outlet.style.height = '600px';
1248+
outlet.style.position = 'fixed';
1249+
outlet.style.top = '100px';
1250+
outlet.style.left = '200px';
1251+
outlet.style.overflow = 'hidden';
1252+
fixture.detectChanges();
1253+
1254+
const positionStrategy = new ContainerPositionStrategy();
1255+
const overlaySettings: OverlaySettings = {
1256+
outlet,
1257+
positionStrategy
1258+
};
1259+
1260+
const id = fixture.componentInstance.overlay.attach(SimpleDynamicComponent, overlaySettings);
1261+
fixture.componentInstance.overlay.show(id);
1262+
tick();
1263+
1264+
// Capture the content element while it is still in the DOM
1265+
const contentElement = fixture.nativeElement.parentElement.getElementsByClassName(CLASS_OVERLAY_CONTENT_MODAL)[0] as HTMLElement;
1266+
1267+
// Detaching the overlay calls dispose() on the position strategy which disconnects
1268+
// the IntersectionObserver and sets it to null. However, if a callback was already
1269+
// queued by the observer before disconnect, it will still fire and call updatePosition
1270+
// with the now-detached contentElement (parentElement === null).
1271+
fixture.componentInstance.overlay.detach(id);
1272+
tick();
1273+
1274+
// Simulate the stale IntersectionObserver callback firing after detach.
1275+
// Should not throw even though contentElement is no longer attached to the DOM.
1276+
expect(() => (positionStrategy as any).updatePosition(contentElement)).not.toThrow();
1277+
1278+
fixture.componentInstance.overlay.detachAll();
1279+
}));
1280+
12431281
it('should close overlay on outside click when target is point, #8297', fakeAsync(() => {
12441282
const fixture = TestBed.createComponent(EmptyPageComponent);
12451283
const overlay = fixture.componentInstance.overlay;

projects/igniteui-angular/core/src/services/overlay/position/container-position-strategy.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,15 @@ export class ContainerPositionStrategy extends GlobalPositionStrategy {
4242
}
4343

4444
private updatePosition(contentElement: HTMLElement): void {
45+
const outletElement = contentElement.parentElement?.parentElement;
46+
if (!outletElement)
47+
return;
48+
4549
// TODO: consider using new anchor() CSS function when it becomes more widely supported: https://caniuse.com/mdn-css_properties_anchor
46-
const parentRect = contentElement.parentElement.parentElement.getBoundingClientRect();
47-
contentElement.parentElement.style.width = `${parentRect.width}px`;
48-
contentElement.parentElement.style.height = `${parentRect.height}px`;
49-
contentElement.parentElement.style.top = `${parentRect.top}px`;
50-
contentElement.parentElement.style.left = `${parentRect.left}px`;
50+
const outletRect = outletElement.getBoundingClientRect();
51+
contentElement.parentElement.style.width = `${outletRect.width}px`;
52+
contentElement.parentElement.style.height = `${outletRect.height}px`;
53+
contentElement.parentElement.style.top = `${outletRect.top}px`;
54+
contentElement.parentElement.style.left = `${outletRect.left}px`;
5155
}
5256
}

0 commit comments

Comments
 (0)