From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Thu, 20 Sep 2018 17:45:32 -0700
Subject: can_create_window.patch

This adds a hook to the window creation flow so that Electron can intercede and
potentially prevent a window from being created.

TODO(loc): this patch is currently broken.

diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 0e1a439de32f166818c59cb7aa010544360c9112..2e222a1bf9cb50efa990f875b102001998691f06 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -5213,6 +5213,7 @@ void RenderFrameHostImpl::CreateNewWindow(
           last_committed_origin_, params->window_container_type,
           params->target_url, params->referrer.To<Referrer>(),
           params->frame_name, params->disposition, *params->features,
+          params->raw_features, params->body,
           effective_transient_activation_state, params->opener_suppressed,
           &no_javascript_access);
 
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index f4751d821d34a998407b37ca4b8221cd8a2ad135..762d4d6164df6f097c3dd77c695a3270a225ec68 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3560,6 +3560,14 @@ RenderFrameHostDelegate* WebContentsImpl::CreateNewWindow(
   }
   auto* new_contents_impl = new_contents.get();
 
+  // Call this earlier than Chrome to associate the web preferences with the
+  // WebContents before the view gets created.
+  if (delegate_) {
+    delegate_->WebContentsCreatedWithFullParams(this, render_process_id,
+                                                opener->GetRoutingID(),
+                                                params, new_contents_impl);
+  }
+
   new_contents_impl->GetController().SetSessionStorageNamespace(
       partition_id, session_storage_namespace);
 
@@ -3601,12 +3609,6 @@ RenderFrameHostDelegate* WebContentsImpl::CreateNewWindow(
     AddDestructionObserver(new_contents_impl);
   }
 
-  if (delegate_) {
-    delegate_->WebContentsCreated(this, render_process_id,
-                                  opener->GetRoutingID(), params.frame_name,
-                                  params.target_url, new_contents_impl);
-  }
-
   observers_.ForEachObserver([&](WebContentsObserver* observer) {
     observer->DidOpenRequestedURL(new_contents_impl, opener, params.target_url,
                                   params.referrer.To<Referrer>(),
diff --git a/content/common/frame.mojom b/content/common/frame.mojom
index 182c6bf04e9937080efcedfc617fb9e072f10500..6fb3a1ee4a31e9a228e8ab04b1ce21c8af50ae74 100644
--- a/content/common/frame.mojom
+++ b/content/common/frame.mojom
@@ -330,6 +330,10 @@ struct CreateNewWindowParams {
   // The impression associated with the navigation in the new window, if
   // one is specified.
   Impression? impression;
+
+  // Extra fields added by Electron.
+  string raw_features;
+  network.mojom.URLRequestBody? body;
 };
 
 // Operation result when the renderer asks the browser to create a new window.
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index c84ae68f2f271185e6021fcd0b41fe68c42a17e7..b84afa745f7a2b378f7cda18b7cdbb5357e2234c 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -554,6 +554,8 @@ bool ContentBrowserClient::CanCreateWindow(
     const std::string& frame_name,
     WindowOpenDisposition disposition,
     const blink::mojom::WindowFeatures& features,
+    const std::string& raw_features,
+    const scoped_refptr<network::ResourceRequestBody>& body,
     bool user_gesture,
     bool opener_suppressed,
     bool* no_javascript_access) {
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index c4fc708ab2789d2cf873bb8a5cff64259ab1d184..a9b4f7770a04d713de363c80c3a0f2b107b6d426 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -155,6 +155,7 @@ class NetworkService;
 class TrustedURLLoaderHeaderClient;
 }  // namespace mojom
 struct ResourceRequest;
+class ResourceRequestBody;
 }  // namespace network
 
 namespace sandbox {
@@ -905,6 +906,8 @@ class CONTENT_EXPORT ContentBrowserClient {
       const std::string& frame_name,
       WindowOpenDisposition disposition,
       const blink::mojom::WindowFeatures& features,
+      const std::string& raw_features,
+      const scoped_refptr<network::ResourceRequestBody>& body,
       bool user_gesture,
       bool opener_suppressed,
       bool* no_javascript_access);
diff --git a/content/public/browser/web_contents_delegate.cc b/content/public/browser/web_contents_delegate.cc
index 23ef0fe1e0275778bccd1bbae8ec46fa3dc24a7c..41bae2ebe3c6db1fc81a90763f304e90b8a1005c 100644
--- a/content/public/browser/web_contents_delegate.cc
+++ b/content/public/browser/web_contents_delegate.cc
@@ -27,6 +27,17 @@ namespace content {
 
 WebContentsDelegate::WebContentsDelegate() = default;
 
+void WebContentsDelegate::WebContentsCreatedWithFullParams(
+    WebContents* source_contents,
+    int opener_render_process_id,
+    int opener_render_frame_id,
+    const mojom::CreateNewWindowParams& params,
+    WebContents* new_contents) {
+  WebContentsCreated(source_contents, opener_render_process_id,
+                     opener_render_frame_id, params.frame_name,
+                     params.target_url, new_contents);
+}
+
 WebContents* WebContentsDelegate::OpenURLFromTab(WebContents* source,
                                                  const OpenURLParams& params) {
   return nullptr;
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h
index 21d30d1b60ba870a35be87f8d1823ef5e3902a01..73b85693d59f25160df21c3b535869b3d03c3a76 100644
--- a/content/public/browser/web_contents_delegate.h
+++ b/content/public/browser/web_contents_delegate.h
@@ -17,6 +17,7 @@
 #include "base/strings/string16.h"
 #include "build/build_config.h"
 #include "content/common/content_export.h"
+#include "content/common/frame.mojom.h"
 #include "content/public/browser/eye_dropper.h"
 #include "content/public/browser/invalidate_type.h"
 #include "content/public/browser/media_stream_request.h"
@@ -337,6 +338,13 @@ class CONTENT_EXPORT WebContentsDelegate {
       const std::string& partition_id,
       SessionStorageNamespace* session_storage_namespace);
 
+  virtual void WebContentsCreatedWithFullParams(
+      WebContents* source_contents,
+      int opener_render_process_id,
+      int opener_render_frame_id,
+      const mojom::CreateNewWindowParams& params,
+      WebContents* new_contents);
+
   // Notifies the delegate about the creation of a new WebContents. This
   // typically happens when popups are created.
   virtual void WebContentsCreated(WebContents* source_contents,
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 7fc0a7edbfe1f274ed685277d3a5d4b560dd87d2..5efeed6fdf1e9f707db658a0da3408e16a6a66e0 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -28,6 +28,7 @@
 #include "third_party/blink/public/platform/impression_conversions.h"
 #include "third_party/blink/public/platform/modules/video_capture/web_video_capture_impl_manager.h"
 #include "third_party/blink/public/platform/url_conversion.h"
+#include "third_party/blink/public/platform/web_url_request_util.h"
 #include "third_party/blink/public/web/modules/mediastream/web_media_stream_device_observer.h"
 #include "third_party/blink/public/web/web_frame_widget.h"
 #include "third_party/blink/public/web/web_local_frame.h"
@@ -385,6 +386,9 @@ WebView* RenderViewImpl::CreateView(
   if (impression) {
     params->impression = blink::ConvertWebImpressionToImpression(*impression);
   }
+  params->raw_features = features.raw_features.Utf8(
+      WTF::UTF8ConversionMode::kStrictUTF8ConversionReplacingUnpairedSurrogatesWithFFFD);
+  params->body = GetRequestBodyForWebURLRequest(request);
 
   // We preserve this information before sending the message since |params| is
   // moved on send.
diff --git a/content/web_test/browser/web_test_content_browser_client.cc b/content/web_test/browser/web_test_content_browser_client.cc
index 52bfdcfe1b1530133582dcd6bdef4ea80c8d8b45..adf92fa28b0a638cb311c48bc142448022513375 100644
--- a/content/web_test/browser/web_test_content_browser_client.cc
+++ b/content/web_test/browser/web_test_content_browser_client.cc
@@ -442,6 +442,8 @@ bool WebTestContentBrowserClient::CanCreateWindow(
     const std::string& frame_name,
     WindowOpenDisposition disposition,
     const blink::mojom::WindowFeatures& features,
+    const std::string& raw_features,
+    const scoped_refptr<network::ResourceRequestBody>& body,
     bool user_gesture,
     bool opener_suppressed,
     bool* no_javascript_access) {
diff --git a/content/web_test/browser/web_test_content_browser_client.h b/content/web_test/browser/web_test_content_browser_client.h
index 15262ff3e3a7be037d5eedda3279c8897628e4d8..4e285a97787d9f487b5424b2dfc2b0fff2df53a2 100644
--- a/content/web_test/browser/web_test_content_browser_client.h
+++ b/content/web_test/browser/web_test_content_browser_client.h
@@ -83,6 +83,8 @@ class WebTestContentBrowserClient : public ShellContentBrowserClient {
                        const std::string& frame_name,
                        WindowOpenDisposition disposition,
                        const blink::mojom::WindowFeatures& features,
+                       const std::string& raw_features,
+                       const scoped_refptr<network::ResourceRequestBody>& body,
                        bool user_gesture,
                        bool opener_suppressed,
                        bool* no_javascript_access) override;
diff --git a/third_party/blink/public/web/web_window_features.h b/third_party/blink/public/web/web_window_features.h
index 4f735ad0d97eaac9a57dad137e479f8a7ec33a36..0a3c5821962c85609b64b3625fa6b8d658cd9ab2 100644
--- a/third_party/blink/public/web/web_window_features.h
+++ b/third_party/blink/public/web/web_window_features.h
@@ -31,6 +31,8 @@
 #ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_WINDOW_FEATURES_H_
 #define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_WINDOW_FEATURES_H_
 
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
 namespace blink {
 
 struct WebWindowFeatures {
@@ -60,6 +62,8 @@ struct WebWindowFeatures {
   bool noreferrer = false;
   bool background = false;
   bool persistent = false;
+
+  String raw_features;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index 74539b9e48b034355e67e43eb528e8597d4cefdd..1cd316f90a037d8736e89bbfb28fb26523ccd97b 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -2019,6 +2019,7 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
   }
 
   WebWindowFeatures window_features = GetWindowFeaturesFromString(features);
+  window_features.raw_features = features;
 
   FrameLoadRequest frame_request(incumbent_window,
                                  ResourceRequest(completed_url));
