fix: manually manage WebContents of webview when it is detached

This commit is contained in:
Cheng Zhao 2018-09-07 15:41:48 +09:00
Родитель 8e963f10ef
Коммит 92e094c5f6
5 изменённых файлов: 38 добавлений и 10 удалений

Просмотреть файл

@ -483,16 +483,20 @@ WebContents::~WebContents() {
RenderViewDeleted(web_contents()->GetRenderViewHost());
if (type_ == BROWSER_WINDOW && owner_window()) {
for (ExtendedWebContentsObserver& observer : observers_)
observer.OnCloseContents();
if (type_ == WEB_VIEW) {
DestroyWebContents(false /* async */);
} else {
DestroyWebContents(!IsGuest() /* async */);
if (type_ == BROWSER_WINDOW && owner_window()) {
for (ExtendedWebContentsObserver& observer : observers_)
observer.OnCloseContents();
} else {
DestroyWebContents(true /* async */);
}
// The WebContentsDestroyed will not be called automatically because we
// destroy the webContents in the next tick. So we have to manually
// call it here to make sure "destroyed" event is emitted.
WebContentsDestroyed();
}
// The WebContentsDestroyed will not be called automatically because we
// destroy the webContents in the next tick. So we have to manually
// call it here to make sure "destroyed" event is emitted.
WebContentsDestroyed();
}
}
@ -1048,7 +1052,7 @@ bool WebContents::OnMessageReceived(const IPC::Message& message,
// 2. garbage collection;
// 3. user closes the window of webContents;
// 4. the embedder detaches the frame.
// For webview only #4 will happen, for BrowserWindow both #1 and #3 may
// For webview both #1 and #4 may happen, for BrowserWindow both #1 and #3 may
// happen. The #2 should never happen for webContents, because webview is
// managed by GuestViewManager, and BrowserWindow's webContents is managed
// by api::BrowserWindow.

Просмотреть файл

@ -70,6 +70,19 @@ const createGuest = function (embedder, params) {
}
// Clear the guest from map when it is destroyed.
//
// The guest WebContents is usually destroyed in 2 cases:
// 1. The embedder frame is closed (reloaded or destroyed), and it
// automatically closes the guest frame.
// 2. The guest frame is detached dynamically via JS, and it is manually
// destroyed when the renderer sends the GUEST_VIEW_MANAGER_DESTROY_GUEST
// message.
// The second case relies on the libcc patch:
// https://github.com/electron/libchromiumcontent/pull/676
// The patch was introduced to work around a bug in Chromium:
// https://github.com/electron/electron/issues/14211
// We should revisit the bug to see if we can remove our libcc patch, the
// patch was introduced in Chrome 66.
guest.once('destroyed', () => {
if (guestInstanceId in guestInstances) {
detachGuest(embedder, guestInstanceId)
@ -319,6 +332,13 @@ ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST_SYNC', function (event, par
event.returnValue = createGuest(event.sender, params)
})
ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_DESTROY_GUEST', function (event, guestInstanceId) {
const guest = getGuest(guestInstanceId)
if (guest) {
guest.destroy()
}
})
ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', function (event, embedderFrameId, elementInstanceId, guestInstanceId, params) {
attachGuest(event, embedderFrameId, elementInstanceId, guestInstanceId, params)
})

Просмотреть файл

@ -94,6 +94,9 @@ module.exports = {
createGuestSync: function (params) {
return ipcRenderer.sendSync('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST_SYNC', params)
},
destroyGuest: function (guestInstanceId) {
ipcRenderer.send('ELECTRON_GUEST_VIEW_MANAGER_DESTROY_GUEST', guestInstanceId)
},
attachGuest: function (elementInstanceId, guestInstanceId, params, contentWindow) {
const embedderFrameId = webFrame.getWebFrameId(contentWindow)
if (embedderFrameId < 0) { // this error should not happen.

Просмотреть файл

@ -76,6 +76,7 @@ class WebViewImpl {
// heard back from createGuest yet. We will not reset the flag in this case so
// that we don't end up allocating a second guest.
if (this.guestInstanceId) {
guestViewInternal.destroyGuest(this.guestInstanceId)
this.guestInstanceId = void 0
}

2
vendor/libchromiumcontent поставляемый

@ -1 +1 @@
Subproject commit d2ffd8ab4b238cb9fa16026ea95bd24b5c79915f
Subproject commit 6fdee949b2b153cb6e64217ee984e010b5e9028c