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 28c7136b21d058e3daa7570af558f5a415b000a7..d1b7d15a7e4dede5b030e4ae9fb2ab8aa8196446 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -7006,6 +7006,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 cb74ef64fc8d4014fb57f098df6440dda5e896d4..c7d376b31e0fb570c934c6a8846e37bf1f3b3262 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3965,6 +3965,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_config, session_storage_namespace);
 
@@ -4009,12 +4017,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 9c3a03faeee19f6f0a250680db36906ee64bf55a..0450700d02c74e047fa5124aa43b9f75b869917d 100644
--- a/content/common/frame.mojom
+++ b/content/common/frame.mojom
@@ -566,6 +566,10 @@ struct CreateNewWindowParams {
 
   // Governs how downloads are handled if `target_url` results in a download.
   blink.mojom.NavigationDownloadPolicy download_policy;
+
+  // 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 c1beba6701e68255c212e56d78ae8259e2ffdab9..9f77c2a5df8f25876f875c4a7148d82c3dd79db8 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -595,6 +595,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 a49794184baa977ddf03cd911f8d8d7d671df65f..7997c0de85315e30b350316f33e598a0221d583f 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 {
@@ -967,6 +968,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 ef3889063b562a37fbd945fe30db0d776ecaee7a..99e8449e9c515dd70ed88546a71f83ae139178fe 100644
--- a/content/public/browser/web_contents_delegate.cc
+++ b/content/public/browser/web_contents_delegate.cc
@@ -26,6 +26,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 348dcde05d71e7d16e4c7bb1d8d9f8718070e669..5a9cc64d6e0d9d01f5dc133c7fcab34101bc32db 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"
@@ -338,6 +339,13 @@ class CONTENT_EXPORT WebContentsDelegate {
       const StoragePartitionConfig& partition_config,
       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 03b637c4d3a68a2bff5a4e06f421f23f97f40911..6235fd626a377643851dbb98d4d089e5a59366db 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -32,6 +32,7 @@
 #include "third_party/blink/public/mojom/page/page.mojom.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"
@@ -302,6 +303,10 @@ WebView* RenderViewImpl::CreateView(
       /*openee_can_access_opener_origin=*/true, !creator->IsAllowedToDownload(),
       creator->IsAdSubframe());
 
+  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 2e7c332565ebe33b00ab7fff96a6a8dfc61422a6..0ab061f51d1d0c93f23bfcf5ba051172cea37eb8 100644
--- a/content/web_test/browser/web_test_content_browser_client.cc
+++ b/content/web_test/browser/web_test_content_browser_client.cc
@@ -438,6 +438,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 00e2a8c21d4f0ef00c942498251fa44065da63c0..0fc4b092fa276063e05f990bf920fecd60c6d26c 100644
--- a/content/web_test/browser/web_test_content_browser_client.h
+++ b/content/web_test/browser/web_test_content_browser_client.h
@@ -80,6 +80,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 34570168ccb123f5102dcf8fa6bbf98e7c373ec6..192701e56d258da41b3724292853885e4daf3420 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/common/navigation/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<Impression> 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 84eca5b0b66eda6bebf3fdc304438325545a1f17..2f0615ee1454946d6f46f6626ce9b860a0e04fee 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -2104,6 +2104,8 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
   WebWindowFeatures window_features =
       GetWindowFeaturesFromString(features, entered_window);
 
+  window_features.raw_features = features;
+
   // In fenced frames, we should always use `noopener`.
   if (GetFrame()->IsInFencedFrameTree()) {
     window_features.noopener = true;
