Merge pull request #8110 from electron/track-render-view-by-process-id
Don't clear until render view is deleted for process id
This commit is contained in:
commit
c27633dff4
3 changed files with 63 additions and 7 deletions
|
@ -19,17 +19,14 @@ class ObjectsRegistry {
|
||||||
// registered then the already assigned ID would be returned.
|
// registered then the already assigned ID would be returned.
|
||||||
add (webContents, obj) {
|
add (webContents, obj) {
|
||||||
// Get or assign an ID to the object.
|
// Get or assign an ID to the object.
|
||||||
let id = this.saveToStorage(obj)
|
const id = this.saveToStorage(obj)
|
||||||
|
|
||||||
// Add object to the set of referenced objects.
|
// Add object to the set of referenced objects.
|
||||||
let webContentsId = webContents.getId()
|
const webContentsId = webContents.getId()
|
||||||
let owner = this.owners[webContentsId]
|
let owner = this.owners[webContentsId]
|
||||||
if (!owner) {
|
if (!owner) {
|
||||||
owner = this.owners[webContentsId] = new Set()
|
owner = this.owners[webContentsId] = new Set()
|
||||||
// Clear the storage when webContents is reloaded/navigated.
|
this.registerDeleteListener(webContents, webContentsId)
|
||||||
webContents.once('render-view-deleted', () => {
|
|
||||||
this.clear(webContentsId)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
if (!owner.has(id)) {
|
if (!owner.has(id)) {
|
||||||
owner.add(id)
|
owner.add(id)
|
||||||
|
@ -90,9 +87,21 @@ class ObjectsRegistry {
|
||||||
pointer.count -= 1
|
pointer.count -= 1
|
||||||
if (pointer.count === 0) {
|
if (pointer.count === 0) {
|
||||||
v8Util.deleteHiddenValue(pointer.object, 'atomId')
|
v8Util.deleteHiddenValue(pointer.object, 'atomId')
|
||||||
return delete this.storage[id]
|
delete this.storage[id]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Private: Clear the storage when webContents is reloaded/navigated.
|
||||||
|
registerDeleteListener (webContents, webContentsId) {
|
||||||
|
const processId = webContents.getProcessId()
|
||||||
|
const listener = (event, deletedProcessId) => {
|
||||||
|
if (deletedProcessId === processId) {
|
||||||
|
webContents.removeListener('render-view-deleted', listener)
|
||||||
|
this.clear(webContentsId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
webContents.on('render-view-deleted', listener)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = new ObjectsRegistry()
|
module.exports = new ObjectsRegistry()
|
||||||
|
|
|
@ -517,4 +517,19 @@ describe('ipc module', function () {
|
||||||
ipcRenderer.removeAllListeners('test-event')
|
ipcRenderer.removeAllListeners('test-event')
|
||||||
assert.equal(ipcRenderer.listenerCount('test-event'), 0)
|
assert.equal(ipcRenderer.listenerCount('test-event'), 0)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('remote objects registry', function () {
|
||||||
|
it('does not dereference until the render view is deleted (regression)', function (done) {
|
||||||
|
w = new BrowserWindow({
|
||||||
|
show: true
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.once('error-message', (event, message) => {
|
||||||
|
assert(message.startsWith('Cannot call function \'getURL\' on missing remote object'), message)
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
|
||||||
|
w.loadURL('file://' + path.join(fixtures, 'api', 'render-view-deleted.html'))
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
32
spec/fixtures/api/render-view-deleted.html
vendored
Normal file
32
spec/fixtures/api/render-view-deleted.html
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title></title>
|
||||||
|
<script>
|
||||||
|
const {ipcRenderer, remote} = require('electron')
|
||||||
|
|
||||||
|
const contents = remote.getCurrentWebContents()
|
||||||
|
|
||||||
|
// This should not trigger a dereference and a remote getURL call should not fail
|
||||||
|
contents.emit('render-view-deleted', {}, 'not-a-process-id')
|
||||||
|
try {
|
||||||
|
contents.getURL()
|
||||||
|
} catch (error) {
|
||||||
|
ipcRenderer.send('error-message', 'Unexpected error on getURL call')
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should trigger a dereference and a remote getURL call should fail
|
||||||
|
contents.emit('render-view-deleted', {}, contents.getProcessId())
|
||||||
|
try {
|
||||||
|
contents.getURL()
|
||||||
|
ipcRenderer.send('error-message', 'No error thrown')
|
||||||
|
} catch (error) {
|
||||||
|
ipcRenderer.send('error-message', error.message)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in a new issue