fix(modal, popover): remove trigger click listeners when overlay is unmounted (#26167)

This commit is contained in:
Amanda Johnston
2022-10-26 13:59:43 -05:00
committed by GitHub
parent a7e15babf3
commit 1320948b24
4 changed files with 61 additions and 8 deletions

View File

@ -332,7 +332,17 @@ export class Modal implements ComponentInterface, OverlayInterface {
} }
connectedCallback() { connectedCallback() {
prepareOverlay(this.el); const { configureTriggerInteraction, el } = this;
prepareOverlay(el);
configureTriggerInteraction();
}
disconnectedCallback() {
const { destroyTriggerInteraction } = this;
if (destroyTriggerInteraction) {
destroyTriggerInteraction();
}
} }
componentWillLoad() { componentWillLoad() {
@ -371,7 +381,6 @@ export class Modal implements ComponentInterface, OverlayInterface {
raf(() => this.present()); raf(() => this.present());
} }
this.breakpointsChanged(this.breakpoints); this.breakpointsChanged(this.breakpoints);
this.configureTriggerInteraction();
} }
private configureTriggerInteraction = () => { private configureTriggerInteraction = () => {

View File

@ -2,15 +2,34 @@ import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright'; import { test } from '@utils/test/playwright';
test.describe('modal: trigger', () => { test.describe('modal: trigger', () => {
test('should open modal by left clicking on trigger', async ({ page }) => { test.beforeEach(async ({ page, skip }) => {
skip.rtl();
skip.mode('ios');
await page.goto('/src/components/modal/test/trigger'); await page.goto('/src/components/modal/test/trigger');
});
test('should open modal by left clicking on trigger', async ({ page }) => {
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent'); const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
await page.click('#left-click-trigger'); await page.click('#left-click-trigger');
await ionModalDidPresent.next(); await ionModalDidPresent.next();
const modal = await page.locator('.left-click-modal'); const modal = page.locator('.left-click-modal');
await expect(modal).toBeVisible();
});
test('should still open modal when it has been removed and re-added to DOM', async ({ page }) => {
const button = page.locator('#left-click-trigger');
const modal = page.locator('ion-modal');
await modal.evaluate((modal: HTMLIonModalElement) => {
modal.remove();
document.querySelector('ion-button')?.insertAdjacentElement('afterend', modal);
});
await page.waitForChanges();
await button.click();
await expect(modal).toBeVisible(); await expect(modal).toBeVisible();
}); });
}); });

View File

@ -311,7 +311,18 @@ export class Popover implements ComponentInterface, PopoverInterface {
@Event({ eventName: 'didDismiss' }) didDismissShorthand!: EventEmitter<OverlayEventDetail>; @Event({ eventName: 'didDismiss' }) didDismissShorthand!: EventEmitter<OverlayEventDetail>;
connectedCallback() { connectedCallback() {
prepareOverlay(this.el); const { configureTriggerInteraction, el } = this;
prepareOverlay(el);
configureTriggerInteraction();
}
disconnectedCallback() {
const { destroyTriggerInteraction } = this;
if (destroyTriggerInteraction) {
destroyTriggerInteraction();
}
} }
componentWillLoad() { componentWillLoad() {
@ -344,8 +355,6 @@ export class Popover implements ComponentInterface, PopoverInterface {
this.dismiss(undefined, undefined, false); this.dismiss(undefined, undefined, false);
}); });
} }
this.configureTriggerInteraction();
} }
/** /**

View File

@ -5,7 +5,9 @@ import { test } from '@utils/test/playwright';
import { openPopover } from '../test.utils'; import { openPopover } from '../test.utils';
test.describe('popover: trigger', async () => { test.describe('popover: trigger', async () => {
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page, skip }) => {
skip.rtl();
skip.mode('ios');
await page.goto('/src/components/popover/test/trigger'); await page.goto('/src/components/popover/test/trigger');
}); });
@ -32,6 +34,20 @@ test.describe('popover: trigger', async () => {
await checkPopover(page, '.hover-popover'); await checkPopover(page, '.hover-popover');
}); });
test('should still open popover when it has been removed and re-added to DOM', async ({ page }) => {
const button = page.locator('#left-click-trigger');
const popover = page.locator('.left-click-popover');
await popover.evaluate((popover: HTMLIonPopoverElement) => {
popover.remove();
document.querySelector('ion-button')?.insertAdjacentElement('afterend', popover);
});
await page.waitForChanges();
await button.click();
await expect(popover).toBeVisible();
});
}); });
const checkPopover = async (page: E2EPage, popoverSelector: string) => { const checkPopover = async (page: E2EPage, popoverSelector: string) => {