fix: don't destroy BrowserView webContents when owning BrowserWindow hasn't been closed (#42372)
fix: don't destroy BrowserView webContents when owning BrowserWindow hasn't been closed (#42353) * fix: moves bv webContents close to closed event * chore: adds unit tests * chore: test that bv webContents are destroyed when parent bw closed Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: Anny Yang <anny@electronjs.org>
This commit is contained in:
parent
993d3331fa
commit
0d12131f50
2 changed files with 54 additions and 5 deletions
|
@ -54,7 +54,7 @@ BrowserWindow.prototype._init = function (this: BWT) {
|
||||||
|
|
||||||
this._browserViews = [];
|
this._browserViews = [];
|
||||||
|
|
||||||
this.on('close', () => {
|
this.on('closed', () => {
|
||||||
this._browserViews.forEach(b => b.webContents?.close({ waitForBeforeUnload: true }));
|
this._browserViews.forEach(b => b.webContents?.close({ waitForBeforeUnload: true }));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,12 @@ describe('BrowserView module', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
const p = once(w.webContents, 'destroyed');
|
if (!w.isDestroyed()) {
|
||||||
await closeWindow(w);
|
const p = once(w.webContents, 'destroyed');
|
||||||
w = null as any;
|
await closeWindow(w);
|
||||||
await p;
|
w = null as any;
|
||||||
|
await p;
|
||||||
|
}
|
||||||
|
|
||||||
if (view && view.webContents) {
|
if (view && view.webContents) {
|
||||||
const p = once(view.webContents, 'destroyed');
|
const p = once(view.webContents, 'destroyed');
|
||||||
|
@ -534,6 +536,53 @@ describe('BrowserView module', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('shutdown behavior', () => {
|
describe('shutdown behavior', () => {
|
||||||
|
it('emits the destroyed event when the host BrowserWindow is closed', async () => {
|
||||||
|
view = new BrowserView();
|
||||||
|
w.addBrowserView(view);
|
||||||
|
await view.webContents.loadURL(`data:text/html,
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<div id="bv_id">HELLO BROWSERVIEW</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`);
|
||||||
|
|
||||||
|
const query = 'document.getElementById("bv_id").textContent';
|
||||||
|
const contentBefore = await view.webContents.executeJavaScript(query);
|
||||||
|
expect(contentBefore).to.equal('HELLO BROWSERVIEW');
|
||||||
|
|
||||||
|
w.close();
|
||||||
|
|
||||||
|
const destroyed = once(view.webContents, 'destroyed');
|
||||||
|
const closed = once(w, 'closed');
|
||||||
|
await Promise.all([destroyed, closed]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not destroy its webContents if an owner BrowserWindow close event is prevented', async () => {
|
||||||
|
view = new BrowserView();
|
||||||
|
w.addBrowserView(view);
|
||||||
|
await view.webContents.loadURL(`data:text/html,
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<div id="bv_id">HELLO BROWSERVIEW</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`);
|
||||||
|
|
||||||
|
const query = 'document.getElementById("bv_id").textContent';
|
||||||
|
const contentBefore = await view.webContents.executeJavaScript(query);
|
||||||
|
expect(contentBefore).to.equal('HELLO BROWSERVIEW');
|
||||||
|
|
||||||
|
w.once('close', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
w.close();
|
||||||
|
|
||||||
|
const contentAfter = await view.webContents.executeJavaScript(query);
|
||||||
|
expect(contentAfter).to.equal('HELLO BROWSERVIEW');
|
||||||
|
});
|
||||||
|
|
||||||
it('does not crash on exit', async () => {
|
it('does not crash on exit', async () => {
|
||||||
const rc = await startRemoteControlApp();
|
const rc = await startRemoteControlApp();
|
||||||
await rc.remotely(() => {
|
await rc.remotely(() => {
|
||||||
|
|
Loading…
Reference in a new issue