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 3e7b18a7f9ba48b010c329a3f857122977a7e205..ec3a51fcd891841f945b4f3629968330f25dd1c0 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -6421,6 +6421,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 aac8edf20fc6dbf4aeee6793a76ea1916d121c63..603edba3e661be67f55f8c2ee30dc27d0ca2db49 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3727,6 +3727,14 @@ FrameTree* 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);
 
@@ -3769,12 +3777,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
     AddWebContentsDestructionObserver(new_contents_impl);
   }
 
-  if (delegate_) {
-    delegate_->WebContentsCreated(this, render_process_id,
-                                  opener->GetRoutingID(), params.frame_name,
-                                  params.target_url, new_contents_impl);
-  }
-
   observers_.NotifyObservers(&WebContentsObserver::DidOpenRequestedURL,
                              new_contents_impl, opener, params.target_url,
                              params.referrer.To<Referrer>(), params.disposition,
diff --git a/content/common/frame.mojom b/content/common/frame.mojom
index 192a5084eac3e9426ac8ddc4984b572d55c7a88a..63f53ff39240ea59a03f1a6f9d032444b0e4214d 100644
--- a/content/common/frame.mojom
+++ b/content/common/frame.mojom
@@ -523,6 +523,10 @@ struct CreateNewWindowParams {
   // The impression associated with the navigation in the new window, if
   // one is specified.
   blink.mojom.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 997125e855c0f6393251193fa86c90d179cd9eb9..e5cf4b0c818ba7dcc3b942cdc989285641d2348c 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -563,6 +563,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 65638e207d6bffd24a1121eb32c86545ba884007..8c68f9f74414a027aa0f7a66238c05ea6054ddf1 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -164,6 +164,7 @@ class NetworkService;
 class TrustedURLLoaderHeaderClient;
 }  // namespace mojom
 struct ResourceRequest;
+class ResourceRequestBody;
 }  // namespace network
 
 namespace sandbox {
@@ -927,6 +928,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 4a57554c9e540516af83567183a34384ac722ebf..31c73efb73bb69076abd6b9c4f139072a9f7f603 100644
--- a/content/public/browser/web_contents_delegate.cc
+++ b/content/public/browser/web_contents_delegate.cc
@@ -28,6 +28,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 a0da74d5cbe4ab8be84d6f1a92f444e858320745..5936fa4bce09895595ccb294504f5b89c967d8c0 100644
--- a/content/public/browser/web_contents_delegate.h
+++ b/content/public/browser/web_contents_delegate.h
@@ -16,6 +16,7 @@
 #include "base/memory/scoped_refptr.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"
@@ -335,6 +336,13 @@ class CONTENT_EXPORT WebContentsDelegate {
       const StoragePartitionId& 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 afec7767d905488a51b2dbba031b8a85d6d0138a..57f970d15bf03f817680982fa8605c333485804b 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -31,6 +31,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"
@@ -289,6 +290,10 @@ WebView* RenderViewImpl::CreateView(
     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.
   bool is_background_tab =
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 c6872573086e628a894f482877db2d417552c6a1..5e67b6a59c3e3d6881f738985ab947a2d7902f0a 100644
--- a/content/web_test/browser/web_test_content_browser_client.cc
+++ b/content/web_test/browser/web_test_content_browser_client.cc
@@ -450,6 +450,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 427656a1a01a9305459a8f1d6616fd0666413b39..c8e296286cdd148348932d2bdfa4d064f8cbe36d 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 84d32491a56528a84b4395fba1d54cdbb38d522b..09998a83c449ef8cd9f360fbcdcf7edc0bbfa4a9 100644
--- a/third_party/blink/public/web/web_window_features.h
+++ b/third_party/blink/public/web/web_window_features.h
@@ -34,6 +34,7 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 #include "third_party/blink/public/platform/web_impression.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
 namespace blink {
 
@@ -68,6 +69,8 @@ struct WebWindowFeatures {
   // Represents the attribution source declared by Attribution Reporting related
   // window features, if any.
   absl::optional<WebImpression> impression;
+
+  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 229eba91cdfe6cb9eea403cb1e8e6af2066ffcc9..f5cb3041c92246471258eb4b7a2a9164b516f717 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -2002,6 +2002,7 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
 
   WebWindowFeatures window_features =
       GetWindowFeaturesFromString(features, incumbent_window);
+  window_features.raw_features = features;
 
   FrameLoadRequest frame_request(incumbent_window,
                                  ResourceRequest(completed_url));
