diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 43ce556264..4d449ed9c3 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -635,8 +635,16 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) { void WebContents::WebContentsDestroyed() { // The RenderViewDeleted was not called when the WebContents is destroyed. RenderViewDeleted(web_contents()->GetRenderViewHost()); - Emit("destroyed"); RemoveFromWeakMap(); + + // We can not call Destroy here because we need to call Emit first, but we + // also do not want any method to be used, so just mark as destroyed here. + MarkDestroyed(); + + Emit("destroyed"); + + // Destroy the native class in next tick. + base::MessageLoop::current()->PostTask(FROM_HERE, GetDestroyClosure()); } void WebContents::NavigationEntryCommitted( diff --git a/spec/api-browser-window-spec.coffee b/spec/api-browser-window-spec.coffee index 38c8217041..724f149cd9 100644 --- a/spec/api-browser-window-spec.coffee +++ b/spec/api-browser-window-spec.coffee @@ -55,6 +55,12 @@ describe 'browser-window module', -> done() w.loadURL 'file://' + path.join(fixtures, 'api', 'close-beforeunload-false.html') + describe 'BrowserWindow.destroy()', -> + it 'prevents users to access methods of webContents', -> + webContents = w.webContents + w.destroy() + assert.throws (-> webContents.getId()), /Object has been destroyed/ + describe 'BrowserWindow.loadURL(url)', -> it 'should emit did-start-loading event', (done) -> w.webContents.on 'did-start-loading', ->