Browse Source

fix: workaround for hang when preventDefault-ing nativeWindowOpen (#22750)

* fix: enable workaround for nativeWindowOpen hang

* add test

* test: ensure window doesn't leak into other test

* update to use new webcontents delegate methods

Co-authored-by: Andy Locascio <[email protected]>
trop[bot] 5 years ago
parent
commit
a6ff42c190

+ 1 - 1
docs/api/structures/extension.md

@@ -5,4 +5,4 @@
 * `name` String
 * `path` String - The extension's file path.
 * `version` String
-* `url` String - The extension's `chrome-extension://` URL.
+* `url` String - The extension's `chrome-extension://` URL.

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

@@ -654,6 +654,30 @@ void WebContents::WebContentsCreated(content::WebContents* source_contents,
   tracker->frame_name = frame_name;
 }
 
+bool WebContents::IsWebContentsCreationOverridden(
+    content::SiteInstance* source_site_instance,
+    content::mojom::WindowContainerType window_container_type,
+    const GURL& opener_url,
+    const std::string& frame_name,
+    const GURL& target_url) {
+  if (Emit("-will-add-new-contents", target_url, frame_name)) {
+    return true;
+  }
+  return false;
+}
+
+content::WebContents* WebContents::CreateCustomWebContents(
+    content::RenderFrameHost* opener,
+    content::SiteInstance* source_site_instance,
+    bool is_new_browsing_instance,
+    const GURL& opener_url,
+    const std::string& frame_name,
+    const GURL& target_url,
+    const std::string& partition_id,
+    content::SessionStorageNamespace* session_storage_namespace) {
+  return nullptr;
+}
+
 void WebContents::AddNewContents(
     content::WebContents* source,
     std::unique_ptr<content::WebContents> new_contents,

+ 15 - 0
shell/browser/api/electron_api_web_contents.h

@@ -376,6 +376,21 @@ class WebContents : public gin_helper::TrackableObject<WebContents>,
                               const base::string16& message,
                               int32_t line_no,
                               const base::string16& source_id) override;
+  bool IsWebContentsCreationOverridden(
+      content::SiteInstance* source_site_instance,
+      content::mojom::WindowContainerType window_container_type,
+      const GURL& opener_url,
+      const std::string& frame_name,
+      const GURL& target_url) override;
+  content::WebContents* CreateCustomWebContents(
+      content::RenderFrameHost* opener,
+      content::SiteInstance* source_site_instance,
+      bool is_new_browsing_instance,
+      const GURL& opener_url,
+      const std::string& frame_name,
+      const GURL& target_url,
+      const std::string& partition_id,
+      content::SessionStorageNamespace* session_storage_namespace) override;
   void WebContentsCreated(content::WebContents* source_contents,
                           int opener_render_process_id,
                           int opener_render_frame_id,

+ 22 - 0
spec-main/api-web-contents-spec.ts

@@ -1828,4 +1828,26 @@ describe('webContents module', () => {
       expect(body).to.equal('401');
     });
   });
+
+  it('emits a cancelable event before creating a child webcontents', async () => {
+    const w = new BrowserWindow({
+      show: false,
+      webPreferences: {
+        sandbox: true
+      }
+    });
+    w.webContents.on('-will-add-new-contents' as any, (event: any, url: any) => {
+      expect(url).to.equal('about:blank');
+      event.preventDefault();
+    });
+    let wasCalled = false;
+    w.webContents.on('new-window' as any, () => {
+      wasCalled = true;
+    });
+    await w.loadURL('about:blank');
+    await w.webContents.executeJavaScript(`window.open('about:blank')`);
+    await new Promise((resolve) => { process.nextTick(resolve); });
+    expect(wasCalled).to.equal(false);
+    await closeAllWindows();
+  });
 });