1 /* 2 * Copyright (C) 2012 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_PAGE_POPUP_IMPL_H_ 32 #define THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_PAGE_POPUP_IMPL_H_ 33 34 #include "base/macros.h" 35 #include "third_party/blink/public/mojom/page/widget.mojom-blink.h" 36 #include "third_party/blink/public/platform/cross_variant_mojo_util.h" 37 #include "third_party/blink/public/web/web_page_popup.h" 38 #include "third_party/blink/renderer/core/core_export.h" 39 #include "third_party/blink/renderer/core/page/page_popup.h" 40 #include "third_party/blink/renderer/core/page/page_widget_delegate.h" 41 #include "third_party/blink/renderer/platform/heap/persistent.h" 42 #include "third_party/blink/renderer/platform/widget/widget_base_client.h" 43 #include "third_party/blink/renderer/platform/wtf/casting.h" 44 #include "third_party/blink/renderer/platform/wtf/ref_counted.h" 45 46 namespace cc { 47 class Layer; 48 } 49 50 namespace blink { 51 class Element; 52 class Page; 53 class PagePopupChromeClient; 54 class PagePopupClient; 55 class WebViewImpl; 56 class LocalDOMWindow; 57 class WidgetBase; 58 59 class CORE_EXPORT WebPagePopupImpl final : public WebPagePopup, 60 public PageWidgetEventHandler, 61 public PagePopup, 62 public RefCounted<WebPagePopupImpl>, 63 public WidgetBaseClient { 64 USING_FAST_MALLOC(WebPagePopupImpl); 65 66 public: 67 ~WebPagePopupImpl() override; 68 69 void Initialize(WebViewImpl*, PagePopupClient*); 70 71 // Cancel informs the PopupClient that it should initiate shutdown of this 72 // popup via ClosePopup(). It is called to indicate the popup was closed due 73 // to a user gesture outside the popup or other such reasons, where a default 74 // cancelled response can be made. 75 // 76 // When the user chooses a value in the popup and thus it is closed, or if the 77 // origin in the DOM disppears, then the Cancel() step would be skipped and go 78 // directly to ClosePopup(). 79 void Cancel(); 80 // Once ClosePopup() has been called, the WebPagePopupImpl should be disowned 81 // by any clients, and will be reaped when then browser closes its 82 // RenderWidget which closes this object. This will call back to the 83 // PopupClient to say DidClosePopup(), and to the WebViewImpl to cleanup 84 // its reference to the popup. 85 // 86 // Only HasSamePopupClient() may still be called after ClosePopup() runs. 87 void ClosePopup(); 88 89 // Returns whether another WebPagePopupImpl has the same PopupClient as this 90 // instance. May be called after ClosePopup() has run still, in order to 91 // determine if a popup sharing the same client was created immediately after 92 // closing one. HasSamePopupClient(WebPagePopupImpl * other)93 bool HasSamePopupClient(WebPagePopupImpl* other) { 94 return other && popup_client_ == other->popup_client_; 95 } 96 WidgetClient()97 WebWidgetClient* WidgetClient() const { return web_page_popup_client_; } 98 99 LocalDOMWindow* Window(); 100 101 // WebWidget implementation. 102 WebInputEventResult DispatchBufferedTouchEvents() override; 103 void SetCompositorVisible(bool visible) override; 104 void UpdateVisualState() override; 105 void WillBeginCompositorFrame() override; 106 107 // WebPagePopup implementation. 108 gfx::Point PositionRelativeToOwner() override; 109 WebDocument GetDocument() override; 110 WebPagePopupClient* GetClientForTesting() const override; 111 112 // PagePopup implementation. 113 void PostMessageToPopup(const String& message) override; 114 115 // PageWidgetEventHandler implementation. 116 WebInputEventResult HandleKeyEvent(const WebKeyboardEvent&) override; 117 118 private: 119 // WidgetBaseClient overrides: 120 void DispatchRafAlignedInput(base::TimeTicks frame_time) override; 121 void BeginMainFrame(base::TimeTicks last_frame_time) override; 122 void RecordTimeToFirstActivePaint(base::TimeDelta duration) override; 123 void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) final; 124 125 // WebWidget implementation. 126 // NOTE: The WebWidget may still be used after requesting the popup to be 127 // closed and destroyed. But the Page and the MainFrame are destroyed 128 // immediately. So all methods (outside of initialization) that are part 129 // of the WebWidget need to check if close has already been initiated (they 130 // can do so by checking |page_|) and not crash! https://crbug.com/906340 131 void SetCompositorHosts(cc::LayerTreeHost*, cc::AnimationHost*) override; 132 void BeginFrame(base::TimeTicks last_frame_time) override; 133 void UpdateLifecycle(WebLifecycleUpdate requested_update, 134 DocumentUpdateReason reason) override; 135 void Resize(const WebSize&) override; 136 void Close() override; 137 WebInputEventResult HandleInputEvent(const WebCoalescedInputEvent&) override; 138 void SetFocus(bool) override; 139 WebURL GetURLForDebugTrace() override; HitTestResultAt(const gfx::Point &)140 WebHitTestResult HitTestResultAt(const gfx::Point&) override { return {}; } 141 142 // PageWidgetEventHandler functions 143 WebInputEventResult HandleCharEvent(const WebKeyboardEvent&) override; 144 WebInputEventResult HandleGestureEvent(const WebGestureEvent&) override; 145 void HandleMouseDown(LocalFrame& main_frame, const WebMouseEvent&) override; 146 WebInputEventResult HandleMouseWheel(LocalFrame& main_frame, 147 const WebMouseWheelEvent&) override; 148 149 // This may only be called if page_ is non-null. 150 LocalFrame& MainFrame() const; 151 152 Element* FocusedElement() const; 153 154 bool IsViewportPointInWindow(int x, int y); 155 156 // PagePopup function 157 AXObject* RootAXObject() override; 158 void SetWindowRect(const IntRect&) override; 159 160 WebPagePopupImpl( 161 WebPagePopupClient*, 162 CrossVariantMojoAssociatedRemote<mojom::blink::WidgetHostInterfaceBase> 163 widget_host, 164 CrossVariantMojoAssociatedReceiver<mojom::blink::WidgetInterfaceBase> 165 widget); 166 void DestroyPage(); 167 void SetRootLayer(scoped_refptr<cc::Layer>); 168 169 WebRect WindowRectInScreen() const; 170 171 WebPagePopupClient* web_page_popup_client_; 172 WebViewImpl* web_view_; 173 // WebPagePopupImpl wraps its own Page that renders the content in the popup. 174 // This member is non-null between the call to Initialize() and the call to 175 // ClosePopup(). If page_ is non-null, it is guaranteed to have an attached 176 // main LocalFrame with a corresponding non-null LocalFrameView and non-null 177 // Document. 178 Persistent<Page> page_; 179 Persistent<PagePopupChromeClient> chrome_client_; 180 PagePopupClient* popup_client_; 181 bool closing_ = false; 182 183 scoped_refptr<cc::Layer> root_layer_; 184 base::TimeTicks raf_aligned_input_start_time_; 185 186 bool suppress_next_keypress_event_ = false; 187 188 // Base functionality all widgets have. This is a member as to avoid 189 // complicated inheritance structures. 190 std::unique_ptr<WidgetBase> widget_base_; 191 192 friend class WebPagePopup; 193 friend class PagePopupChromeClient; 194 195 DISALLOW_COPY_AND_ASSIGN(WebPagePopupImpl); 196 }; 197 198 // WebPagePopupImpl is the only implementation of WebPagePopup and PagePopup, so 199 // no further checking required. 200 template <> 201 struct DowncastTraits<WebPagePopupImpl> { 202 static bool AllowFrom(const WebPagePopup& widget) { return true; } 203 static bool AllowFrom(const PagePopup& popup) { return true; } 204 }; 205 206 } // namespace blink 207 #endif // THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_PAGE_POPUP_IMPL_H_ 208