Browse Source

fix: crash when navigating from a page with webview that has inherited zoom level (#24764)

* fix: cleanup webview zoom level observers on navigation

* add spec

* webview should be on same partition

* wait for webview to finish loading

Co-authored-by: deepak1556 <[email protected]>
trop[bot] 4 years ago
parent
commit
720e49d73d

+ 5 - 0
shell/browser/api/electron_api_web_contents.cc

@@ -1413,6 +1413,11 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) {
 // we need to make sure the api::WebContents is also deleted.
 // For #4, the WebContents will be destroyed by embedder.
 void WebContents::WebContentsDestroyed() {
+  // Give chance for guest delegate to cleanup its observers
+  // since the native class is only destroyed in the next tick.
+  if (guest_delegate_)
+    guest_delegate_->WillDestroy();
+
   // Cleanup relationships with other parts.
   RemoveFromWeakMap();
 

+ 4 - 0
shell/browser/web_view_guest_delegate.cc

@@ -57,6 +57,10 @@ void WebViewGuestDelegate::AttachToIframe(
   api_web_contents_->Emit("did-attach");
 }
 
+void WebViewGuestDelegate::WillDestroy() {
+  ResetZoomController();
+}
+
 void WebViewGuestDelegate::DidDetach() {
   ResetZoomController();
 }

+ 1 - 0
shell/browser/web_view_guest_delegate.h

@@ -24,6 +24,7 @@ class WebViewGuestDelegate : public content::BrowserPluginGuestDelegate,
   // Attach to the iframe.
   void AttachToIframe(content::WebContents* embedder_web_contents,
                       int embedder_frame_id);
+  void WillDestroy();
 
  protected:
   // content::BrowserPluginGuestDelegate:

+ 19 - 0
spec-main/webview-spec.ts

@@ -301,6 +301,25 @@ describe('<webview> tag', function () {
       const [, zoomLevel] = await emittedOnce(ipcMain, 'webview-origin-zoom-level');
       expect(zoomLevel).to.equal(2.0);
     });
+
+    it('does not crash when navigating with zoom level inherited from parent', async () => {
+      const w = new BrowserWindow({
+        show: false,
+        webPreferences: {
+          webviewTag: true,
+          nodeIntegration: true,
+          zoomFactor: 1.2,
+          session: webviewSession
+        }
+      });
+      const attachPromise = emittedOnce(w.webContents, 'did-attach-webview');
+      const readyPromise = emittedOnce(ipcMain, 'dom-ready');
+      w.loadFile(path.join(fixtures, 'pages', 'webview-zoom-inherited.html'));
+      const [, webview] = await attachPromise;
+      await readyPromise;
+      expect(webview.getZoomFactor()).to.equal(1.2);
+      await w.loadURL(`${zoomScheme}://host1`);
+    });
   });
 
   describe('nativeWindowOpen option', () => {

+ 12 - 0
spec/fixtures/pages/webview-zoom-inherited.html

@@ -0,0 +1,12 @@
+<html>
+<body>
+<webview src="./a.html" id="view" partition="webview-temp"/>
+</body>
+<script>
+  const {ipcRenderer} = require('electron')
+  const view = document.getElementById('view')
+  view.addEventListener('dom-ready', () => {
+    ipcRenderer.send('dom-ready')
+  })
+</script>
+</html>