mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-10 00:27:41 +08:00
fix(modal, popover): remove trigger click listeners when overlay is unmounted (#26167)
This commit is contained in:
@ -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 = () => {
|
||||||
|
|||||||
@ -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();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -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) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user