From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Anonymous <anonymous@electronjs.org>
Date: Thu, 20 Sep 2018 17:47:15 -0700
Subject: webui_in_subframes.patch


diff --git a/content/browser/frame_host/render_frame_host_delegate.cc b/content/browser/frame_host/render_frame_host_delegate.cc
index 26b8eec2bb763c6a1e29309abe34c4c068eee609..fb3843168f14fa7b584e2ec52f1c1495aa7dd070 100644
--- a/content/browser/frame_host/render_frame_host_delegate.cc
+++ b/content/browser/frame_host/render_frame_host_delegate.cc
@@ -99,7 +99,9 @@ RenderFrameHostDelegate::GetFocusedFrameIncludingInnerWebContents() {
 }
 
 std::unique_ptr<WebUIImpl>
-RenderFrameHostDelegate::CreateWebUIForRenderFrameHost(const GURL& url) {
+RenderFrameHostDelegate::CreateWebUIForRenderFrameHost(
+    const GURL& url,
+    const std::string& frame_name) {
   return nullptr;
 }
 
diff --git a/content/browser/frame_host/render_frame_host_delegate.h b/content/browser/frame_host/render_frame_host_delegate.h
index 7919ac1e579592815fa96e88f30537c51b110fa9..03f33191521354031357a4886fe7ef3417ba17b6 100644
--- a/content/browser/frame_host/render_frame_host_delegate.h
+++ b/content/browser/frame_host/render_frame_host_delegate.h
@@ -278,7 +278,8 @@ class CONTENT_EXPORT RenderFrameHostDelegate {
   // Creates a WebUI object for a frame navigating to |url|. If no WebUI
   // applies, returns null.
   virtual std::unique_ptr<WebUIImpl> CreateWebUIForRenderFrameHost(
-      const GURL& url);
+      const GURL& url,
+      const std::string& frame_name);
 
   // Called by |frame| to notify that it has received an update on focused
   // element. |bounds_in_root_view| is the rectangle containing the element that
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 783dc705f748bc6c9d3b8630ce12ad39ff2fd7d2..9fa14c824032463cedbbf5db41f1dbe3490c4a69 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -26,6 +26,7 @@
 #include "base/task_scheduler/post_task.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
+#include "base/unguessable_token.h"
 #include "build/build_config.h"
 #include "cc/base/switches.h"
 #include "content/browser/accessibility/browser_accessibility_manager.h"
@@ -4314,8 +4315,23 @@ bool RenderFrameHostImpl::UpdatePendingWebUI(const GURL& dest_url,
       DCHECK(web_ui_);
       should_reuse_web_ui_ = true;
     } else {
+      // Give the frame a name if it does not already have one.
+      // The reason is web ui code base the frame look up on the frame name.
+      std::string frame_name = GetFrameName();
+      if (frame_name.empty() && !frame_tree_node_->IsMainFrame()) {
+        frame_name = base::StringPrintf("frame_%i", frame_tree_node_->frame_tree_node_id());
+        frame_tree_node_->SetFrameName(
+            frame_name, frame_name + base::UnguessableToken::Create().ToString());
+      }
+
+      // If the web ui is in subframes, the parent frame bindings does not have the web ui binding,
+      // so we reset the bindings for the subframes.
+      if (!frame_tree_node_->IsMainFrame() && new_web_ui_type != WebUI::kNoWebUI) {
+        entry_bindings = NavigationEntryImpl::kInvalidBindings;
+      }
+
       // Otherwise create a new pending WebUI.
-      pending_web_ui_ = delegate_->CreateWebUIForRenderFrameHost(dest_url);
+      pending_web_ui_ = delegate_->CreateWebUIForRenderFrameHost(dest_url, frame_name);
       DCHECK(pending_web_ui_);
       pending_web_ui_type_ = new_web_ui_type;
 
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 64ad6ca91d9331a09d09f7e29b7c24a0c12852a2..88211169a7d731cb805f34c48ae4caf2fdcd1c84 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -788,6 +788,25 @@ RenderFrameHostManager* WebContentsImpl::GetRenderManagerForTesting() {
   return GetRenderManager();
 }
 
+void SendMessageToFrameTreeWebUIs(RenderFrameHostImpl* parent_frame_host,
+                                  const IPC::Message& message,
+                                  int& dispatch_count) {
+  // Get the web ui or the pending one if it's not yet commited.
+  WebUIImpl* web_ui = parent_frame_host->web_ui()
+      ? parent_frame_host->web_ui()
+      : parent_frame_host->pending_web_ui();
+  if (web_ui && web_ui->OnMessageReceived(message, parent_frame_host)) {
+    ++dispatch_count;
+  }
+
+  size_t child_count = parent_frame_host->frame_tree_node()->child_count();
+  for (size_t i = 0; i < child_count; ++i) {
+    RenderFrameHostImpl* sub_frame_host =
+        parent_frame_host->frame_tree_node()->child_at(i)->current_frame_host();
+    SendMessageToFrameTreeWebUIs(sub_frame_host, message, dispatch_count);
+  }
+}
+
 bool WebContentsImpl::OnMessageReceived(RenderViewHostImpl* render_view_host,
                                         const IPC::Message& message) {
   for (auto& observer : observers_) {
@@ -823,9 +842,10 @@ bool WebContentsImpl::OnMessageReceived(RenderViewHostImpl* render_view_host,
 
 bool WebContentsImpl::OnMessageReceived(RenderFrameHostImpl* render_frame_host,
                                         const IPC::Message& message) {
-  {
-    WebUIImpl* web_ui = render_frame_host->web_ui();
-    if (web_ui && web_ui->OnMessageReceived(message, render_frame_host))
+  int dispatch_count = 0;
+  if (render_frame_host) {
+    SendMessageToFrameTreeWebUIs(render_frame_host, message, dispatch_count);
+    if (dispatch_count > 0)
       return true;
   }
 
@@ -5974,8 +5994,9 @@ NavigationControllerImpl& WebContentsImpl::GetControllerForRenderManager() {
 }
 
 std::unique_ptr<WebUIImpl> WebContentsImpl::CreateWebUIForRenderFrameHost(
-    const GURL& url) {
-  return CreateWebUI(url);
+    const GURL& url,
+    const std::string& frame_name) {
+  return CreateWebUI(url/*, frame_name*/);
 }
 
 NavigationEntry*
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index d16a99122772385e6fcdb13a8080c82ee0695232..907738e0bf80e4a34c5f068e67a6ba15d5d8338d 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -542,7 +542,8 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
       SiteInstance* source_site_instance) const override;
   void EnsureOpenerProxiesExist(RenderFrameHost* source_rfh) override;
   std::unique_ptr<WebUIImpl> CreateWebUIForRenderFrameHost(
-      const GURL& url) override;
+      const GURL& url,
+      const std::string& frame_name) override;
   void SetFocusedFrame(FrameTreeNode* node, SiteInstance* source) override;
   void DidCallFocus() override;
   RenderFrameHost* GetFocusedFrameIncludingInnerWebContents() override;
