1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_BROWSER_UI_VIEWS_BUBBLE_WEBUI_BUBBLE_VIEW_H_
6 #define CHROME_BROWSER_UI_VIEWS_BUBBLE_WEBUI_BUBBLE_VIEW_H_
7 
8 #include <memory>
9 #include <utility>
10 
11 #include "base/memory/weak_ptr.h"
12 #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
13 #include "ui/views/controls/webview/webview.h"
14 #include "ui/webui/mojo_bubble_web_ui_controller.h"
15 
16 namespace content {
17 class BrowserContext;
18 }  // namespace content
19 
20 // WebUIBubbleView is used to host WebUI that notifies its host when rendering
21 // has finished by calling Host::ShowUI(). Similarly WebUIBubbleView notifies
22 // its host of WebUI size changes by calling Host::OnWebViewSizeChanged().
23 class WebUIBubbleView : public views::WebView,
24                         public ui::MojoBubbleWebUIController::Embedder {
25  public:
26   class Host {
27    public:
28     virtual void ShowUI() = 0;
29     virtual void CloseUI() = 0;
30     virtual void OnWebViewSizeChanged() = 0;
31   };
32 
33   explicit WebUIBubbleView(content::BrowserContext* browser_context);
34   ~WebUIBubbleView() override;
35 
36   // The type T enables WebUIBubbleView to know what WebUIController is being
37   // used for the hosted WebUI and allows it to make sure the associated WebUI
38   // is a MojoBubbleWebUIController at compile time.
39   template <typename T>
LoadURL(const GURL & url)40   void LoadURL(const GURL& url) {
41     // Lie to WebContents so it starts rendering and eventually calls ShowUI().
42     GetWebContents()->WasShown();
43     SetVisible(true);
44     LoadInitialURL(url);
45     T* async_webui_controller =
46         GetWebContents()->GetWebUI()->GetController()->template GetAs<T>();
47     // Depends on the WebUIController object being constructed synchronously
48     // when the navigation is started in LoadInitialURL().
49     async_webui_controller->set_embedder(weak_ptr_factory_.GetWeakPtr());
50   }
51 
set_host(Host * host)52   void set_host(Host* host) { host_ = host; }
53 
54   // WebView:
55   void PreferredSizeChanged() override;
56   bool HandleContextMenu(content::RenderFrameHost* render_frame_host,
57                          const content::ContextMenuParams& params) override;
58   content::KeyboardEventProcessingResult PreHandleKeyboardEvent(
59       content::WebContents* source,
60       const content::NativeWebKeyboardEvent& event) override;
61   bool HandleKeyboardEvent(
62       content::WebContents* source,
63       const content::NativeWebKeyboardEvent& event) override;
64 
65   // MojoBubbleWebUIController::Embedder:
66   void ShowUI() override;
67   void CloseUI() override;
68 
69  private:
70   // |host_| does not always have to be set. The WebUIBubbleView can be cached
71   // and running in the background without a host being present.
72   Host* host_ = nullptr;
73 
74   // A handler to handle unhandled keyboard messages coming back from the
75   // renderer process.
76   views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
77 
78   base::WeakPtrFactory<WebUIBubbleView> weak_ptr_factory_{this};
79 };
80 
81 #endif  // CHROME_BROWSER_UI_VIEWS_BUBBLE_WEBUI_BUBBLE_VIEW_H_
82