| diff --git content/browser/web_contents/web_contents_impl.cc content/browser/web_contents/web_contents_impl.cc |
| index 0fe5a498d698..9d5379624671 100644 |
| --- content/browser/web_contents/web_contents_impl.cc |
| +++ content/browser/web_contents/web_contents_impl.cc |
| @@ -2069,15 +2069,22 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) { |
| std::string unique_name; |
| frame_tree_.root()->SetFrameName(params.main_frame_name, unique_name); |
| |
| - WebContentsViewDelegate* delegate = |
| - GetContentClient()->browser()->GetWebContentsViewDelegate(this); |
| + if (params.view && params.delegate_view) { |
| + view_.reset(params.view); |
| + render_view_host_delegate_view_ = params.delegate_view; |
| + } |
| |
| - if (browser_plugin_guest_) { |
| - view_.reset(new WebContentsViewChildFrame( |
| - this, delegate, &render_view_host_delegate_view_)); |
| - } else { |
| - view_.reset(CreateWebContentsView(this, delegate, |
| - &render_view_host_delegate_view_)); |
| + if (!view_) { |
| + WebContentsViewDelegate* delegate = |
| + GetContentClient()->browser()->GetWebContentsViewDelegate(this); |
| + |
| + if (browser_plugin_guest_) { |
| + view_.reset(new WebContentsViewChildFrame( |
| + this, delegate, &render_view_host_delegate_view_)); |
| + } else { |
| + view_.reset(CreateWebContentsView(this, delegate, |
| + &render_view_host_delegate_view_)); |
| + } |
| } |
| CHECK(render_view_host_delegate_view_); |
| CHECK(view_.get()); |
| @@ -2897,6 +2904,15 @@ RenderFrameHostDelegate* WebContentsImpl::CreateNewWindow( |
| // objects. |
| create_params.renderer_initiated_creation = !is_new_browsing_instance; |
| |
| + if (delegate_) { |
| + delegate_->GetCustomWebContentsView(this, |
| + params.target_url, |
| + render_process_id, |
| + opener->GetRoutingID(), |
| + &create_params.view, |
| + &create_params.delegate_view); |
| + } |
| + |
| std::unique_ptr<WebContentsImpl> new_contents; |
| if (!is_guest) { |
| create_params.context = view_->GetNativeView(); |
| @@ -6370,6 +6386,9 @@ void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, |
| // This is an outermost WebContents. |
| SetAsFocusedWebContentsIfNecessary(); |
| } |
| + |
| + for (auto& observer : observers_) |
| + observer.OnFrameFocused(node->current_frame_host()); |
| } |
| |
| void WebContentsImpl::DidCallFocus() { |
| diff --git content/public/browser/web_contents.cc content/public/browser/web_contents.cc |
| index d1d8ff84e1d2..e7cca94f8647 100644 |
| --- content/public/browser/web_contents.cc |
| +++ content/public/browser/web_contents.cc |
| @@ -28,6 +28,8 @@ WebContents::CreateParams::CreateParams(BrowserContext* context, |
| renderer_initiated_creation(false), |
| desired_renderer_state(kOkayToHaveRendererProcess), |
| starting_sandbox_flags(blink::mojom::WebSandboxFlags::kNone), |
| + view(nullptr), |
| + delegate_view(nullptr), |
| is_never_visible(false) {} |
| |
| WebContents::CreateParams::CreateParams(const CreateParams& other) = default; |
| diff --git content/public/browser/web_contents.h content/public/browser/web_contents.h |
| index b471bd1f78c6..19fb0c70ac94 100644 |
| --- content/public/browser/web_contents.h |
| +++ content/public/browser/web_contents.h |
| @@ -84,9 +84,11 @@ class BrowserPluginGuestDelegate; |
| class InterstitialPage; |
| class RenderFrameHost; |
| class RenderViewHost; |
| +class RenderViewHostDelegateView; |
| class RenderWidgetHost; |
| class RenderWidgetHostView; |
| class WebContentsDelegate; |
| +class WebContentsView; |
| class WebUI; |
| struct CustomContextMenuContext; |
| struct DropData; |
| @@ -214,6 +216,10 @@ class WebContents : public PageNavigator, |
| // Sandboxing flags set on the new WebContents. |
| blink::mojom::WebSandboxFlags starting_sandbox_flags; |
| |
| + // Optionally specify the view and delegate view. |
| + content::WebContentsView* view; |
| + content::RenderViewHostDelegateView* delegate_view; |
| + |
| // Value used to set the last time the WebContents was made active, this is |
| // the value that'll be returned by GetLastActiveTime(). If this is left |
| // default initialized then the value is not passed on to the WebContents |
| diff --git content/public/browser/web_contents_delegate.h content/public/browser/web_contents_delegate.h |
| index d10b0f458416..84e09b266d48 100644 |
| --- content/public/browser/web_contents_delegate.h |
| +++ content/public/browser/web_contents_delegate.h |
| @@ -59,10 +59,12 @@ class ColorChooser; |
| class FileSelectListener; |
| class JavaScriptDialogManager; |
| class RenderFrameHost; |
| +class RenderViewHostDelegateView; |
| class RenderWidgetHost; |
| class SessionStorageNamespace; |
| class SiteInstance; |
| class WebContentsImpl; |
| +class WebContentsView; |
| struct ContextMenuParams; |
| struct DropData; |
| struct MediaPlayerWatchTime; |
| @@ -327,6 +329,14 @@ class CONTENT_EXPORT WebContentsDelegate { |
| const std::string& partition_id, |
| SessionStorageNamespace* session_storage_namespace); |
| |
| + virtual void GetCustomWebContentsView( |
| + WebContents* web_contents, |
| + const GURL& target_url, |
| + int opener_render_process_id, |
| + int opener_render_frame_id, |
| + content::WebContentsView** view, |
| + content::RenderViewHostDelegateView** delegate_view) {} |
| + |
| // 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 content/public/browser/web_contents_observer.h content/public/browser/web_contents_observer.h |
| index 0b9a8c72a426..1c6ca61171cd 100644 |
| --- content/public/browser/web_contents_observer.h |
| +++ content/public/browser/web_contents_observer.h |
| @@ -582,6 +582,10 @@ class CONTENT_EXPORT WebContentsObserver : public IPC::Listener { |
| // WebContents has gained/lost focus. |
| virtual void OnFocusChangedInPage(FocusedNodeDetails* details) {} |
| |
| + // Notification that |render_frame_host| for this WebContents has gained |
| + // focus. |
| + virtual void OnFrameFocused(RenderFrameHost* render_frame_host) {} |
| + |
| // Notifies that the manifest URL for the main frame changed to |
| // |manifest_url|. This will be invoked when a document with a manifest loads |
| // or when the manifest URL changes (possibly to nothing). It is not invoked |