From ba8f80267c2874307357cf0bf99457a29b9a9d19 Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Wed, 23 Oct 2019 06:44:21 +0200 Subject: [PATCH] fix: send ELECTRON_BROWSER_CONTEXT_RELEASE asynchronously (#20632) * fix: send ELECTRON_BROWSER_CONTEXT_RELEASE asynchronously * test: remote references should be able to be cleared for all cases --- lib/browser/remote/objects-registry.ts | 4 ++++ lib/browser/remote/server.ts | 1 - lib/renderer/api/remote.js | 2 +- spec-main/api-remote-spec.ts | 30 +++++++++++++++++++++--- spec-main/fixtures/api/send-on-exit.html | 11 +++++++++ 5 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 spec-main/fixtures/api/send-on-exit.html diff --git a/lib/browser/remote/objects-registry.ts b/lib/browser/remote/objects-registry.ts index 97fa39c5eede..0de48c3960d6 100644 --- a/lib/browser/remote/objects-registry.ts +++ b/lib/browser/remote/objects-registry.ts @@ -127,6 +127,10 @@ class ObjectsRegistry { this.clear(webContents, contextId) } } + // Note that the "render-view-deleted" event may not be emitted on time when + // the renderer process get destroyed because of navigation, we rely on the + // renderer process to send "ELECTRON_BROWSER_CONTEXT_RELEASE" message to + // guard this situation. webContents.on('render-view-deleted' as any, listener) } } diff --git a/lib/browser/remote/server.ts b/lib/browser/remote/server.ts index d1cfab1e8019..5dcf3b884802 100644 --- a/lib/browser/remote/server.ts +++ b/lib/browser/remote/server.ts @@ -541,7 +541,6 @@ handleRemoteCommand('ELECTRON_BROWSER_DEREFERENCE', function (event, contextId, handleRemoteCommand('ELECTRON_BROWSER_CONTEXT_RELEASE', (event, contextId) => { objectsRegistry.clear(event.sender, contextId) - return null }) handleRemoteCommand('ELECTRON_BROWSER_GUEST_WEB_CONTENTS', function (event, contextId, guestInstanceId, stack) { diff --git a/lib/renderer/api/remote.js b/lib/renderer/api/remote.js index ebe6e62ecbda..53087896d908 100644 --- a/lib/renderer/api/remote.js +++ b/lib/renderer/api/remote.js @@ -19,7 +19,7 @@ const contextId = v8Util.getHiddenValue(global, 'contextId') // to guard that situation. process.on('exit', () => { const command = 'ELECTRON_BROWSER_CONTEXT_RELEASE' - ipcRendererInternal.sendSync(command, contextId) + ipcRendererInternal.send(command, contextId) }) // Convert the arguments object into an array of meta data. diff --git a/spec-main/api-remote-spec.ts b/spec-main/api-remote-spec.ts index 130576811c55..13d8e3b9ce0c 100644 --- a/spec-main/api-remote-spec.ts +++ b/spec-main/api-remote-spec.ts @@ -1,18 +1,21 @@ +import * as path from 'path' import { expect } from 'chai' import { closeWindow } from './window-helpers' import { ifdescribe } from './spec-helpers'; -import { BrowserWindow } from 'electron' +import { ipcMain, BrowserWindow } from 'electron' const features = process.electronBinding('features') ifdescribe(features.isRemoteModuleEnabled())('remote module', () => { + const fixtures = path.join(__dirname, 'fixtures') + let w = null as unknown as BrowserWindow - before(async () => { + beforeEach(async () => { w = new BrowserWindow({show: false, webPreferences: {nodeIntegration: true}}) await w.loadURL('about:blank') }) - after(async () => { + afterEach(async () => { await closeWindow(w) }) @@ -112,4 +115,25 @@ ifdescribe(features.isRemoteModuleEnabled())('remote module', () => { await expect(remotely(`require('electron').remote.getCurrentWebContents()`)).to.eventually.be.rejected(`Blocked remote.getCurrentWebContents()`) }) }) + + describe('remote references', () => { + it('render-view-deleted is sent when page is destroyed', (done) => { + w.webContents.once('render-view-deleted' as any, () => { + done() + }) + w.destroy() + }) + + // The ELECTRON_BROWSER_CONTEXT_RELEASE message relies on this to work. + it('message can be sent on exit when page is being navigated', (done) => { + after(() => { ipcMain.removeAllListeners('SENT_ON_EXIT') }) + ipcMain.once('SENT_ON_EXIT', () => { + done() + }) + w.webContents.once('did-finish-load', () => { + w.webContents.loadURL('about:blank') + }) + w.loadFile(path.join(fixtures, 'api', 'send-on-exit.html')) + }) + }) }) diff --git a/spec-main/fixtures/api/send-on-exit.html b/spec-main/fixtures/api/send-on-exit.html new file mode 100644 index 000000000000..8be9b4b06a77 --- /dev/null +++ b/spec-main/fixtures/api/send-on-exit.html @@ -0,0 +1,11 @@ + + + + +