2 * Copyright (C) 2013 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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
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.
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.
31 #ifndef VisualViewport_h
32 #define VisualViewport_h
34 #include "core/CoreExport.h"
35 #include "core/events/Event.h"
36 #include "platform/geometry/FloatRect.h"
37 #include "platform/geometry/FloatSize.h"
38 #include "platform/geometry/IntSize.h"
39 #include "platform/graphics/GraphicsLayerClient.h"
40 #include "platform/scroll/ScrollableArea.h"
41 #include "public/platform/WebScrollbar.h"
42 #include "public/platform/WebSize.h"
46 class WebScrollbarLayer;
53 class GraphicsContext;
59 // Represents the visual viewport the user is currently seeing the page through.
60 // This class corresponds to the InnerViewport on the compositor. It is a
61 // ScrollableArea; it's offset is set through the GraphicsLayer <-> CC sync
62 // mechanisms. Its contents is the page's main FrameView, which corresponds to
63 // the outer viewport. The inner viewport is always contained in the outer
64 // viewport and can pan within it.
65 class CORE_EXPORT VisualViewport final
66 : public GarbageCollectedFinalized<VisualViewport>,
67 public GraphicsLayerClient,
68 public ScrollableArea {
69 USING_GARBAGE_COLLECTED_MIXIN(VisualViewport);
72 static VisualViewport* create(FrameHost& host) {
73 return new VisualViewport(host);
75 ~VisualViewport() override;
77 DECLARE_VIRTUAL_TRACE();
79 void attachToLayerTree(GraphicsLayer*);
81 GraphicsLayer* rootGraphicsLayer() { return m_rootTransformLayer.get(); }
82 GraphicsLayer* containerLayer() {
83 return m_innerViewportContainerLayer.get();
85 GraphicsLayer* scrollLayer() { return m_innerViewportScrollLayer.get(); }
86 GraphicsLayer* pageScaleLayer() { return m_pageScaleLayer.get(); }
87 GraphicsLayer* overscrollElasticityLayer() {
88 return m_overscrollElasticityLayer.get();
91 void initializeScrollbars();
93 // Sets the location of the visual viewport relative to the outer viewport.
94 // The coordinates are in partial CSS pixels.
95 void setLocation(const FloatPoint&);
96 // FIXME: This should be called moveBy
97 void move(const ScrollOffset&);
99 // Sets the size of the inner viewport when unscaled in CSS pixels.
100 void setSize(const IntSize&);
101 IntSize size() const { return m_size; }
103 // Gets the scaled size, i.e. the viewport in root view space.
104 FloatSize visibleSize() const;
106 // Resets the viewport to initial state.
109 // Let the viewport know that the main frame changed size (either through
110 // screen rotation on Android or window resize elsewhere).
111 void mainFrameDidChangeSize();
113 // Sets scale and location in one operation, preventing intermediate clamping.
114 void setScaleAndLocation(float scale, const FloatPoint& location);
115 void setScale(float);
116 float scale() const { return m_scale; }
118 // Update scale factor, magnifying or minifying by magnifyDelta, centered
119 // around the point specified by anchor in window coordinates. Returns false
120 // if page scale factor is left unchanged.
121 bool magnifyScaleAroundAnchor(float magnifyDelta, const FloatPoint& anchor);
123 void setScrollLayerOnScrollbars(WebLayer*) const;
125 // The portion of the unzoomed frame visible in the visual viewport,
126 // in partial CSS pixels. Relative to the main frame.
127 FloatRect visibleRect() const;
129 // The viewport rect relative to the document origin, in partial CSS pixels.
130 FloatRect visibleRectInDocument() const;
132 // Convert the given rect in the main FrameView's coordinates into a rect
133 // in the viewport. The given and returned rects are in CSS pixels, meaning
134 // scale isn't applied.
135 FloatRect mainViewToViewportCSSPixels(const FloatRect&) const;
136 FloatPoint viewportCSSPixelsToRootFrame(const FloatPoint&) const;
138 // Clamp the given point, in document coordinates, to the maximum/minimum
139 // scroll extents of the viewport within the document.
140 IntPoint clampDocumentOffsetAtScale(const IntPoint& offset, float scale);
142 // FIXME: This is kind of a hack. Ideally, we would just resize the
143 // viewports to account for browser controls. However, FrameView includes much
144 // more than just scrolling so we can't simply resize it without incurring
145 // all sorts of side-effects. Until we can seperate out the scrollability
146 // aspect from FrameView, we use this method to let VisualViewport make the
147 // necessary adjustments so that we don't incorrectly clamp scroll offsets
148 // coming from the compositor. crbug.com/422328
149 void setBrowserControlsAdjustment(float);
151 // Adjust the viewport's offset so that it remains bounded by the outer
153 void clampToBoundaries();
155 FloatRect viewportToRootFrame(const FloatRect&) const;
156 IntRect viewportToRootFrame(const IntRect&) const;
157 FloatRect rootFrameToViewport(const FloatRect&) const;
158 IntRect rootFrameToViewport(const IntRect&) const;
160 FloatPoint viewportToRootFrame(const FloatPoint&) const;
161 FloatPoint rootFrameToViewport(const FloatPoint&) const;
162 IntPoint viewportToRootFrame(const IntPoint&) const;
163 IntPoint rootFrameToViewport(const IntPoint&) const;
165 // ScrollableArea implementation
166 HostWindow* getHostWindow() const override;
167 bool shouldUseIntegerScrollOffset() const override;
168 void setScrollOffset(const ScrollOffset&,
170 ScrollBehavior = ScrollBehaviorInstant) override;
171 LayoutRect visualRectForScrollbarParts() const override {
172 ASSERT_NOT_REACHED();
175 bool isActive() const override { return false; }
176 int scrollSize(ScrollbarOrientation) const override;
177 bool isScrollCornerVisible() const override { return false; }
178 IntRect scrollCornerRect() const override { return IntRect(); }
179 IntSize scrollOffsetInt() const override { return flooredIntSize(m_offset); }
180 ScrollOffset scrollOffset() const override { return m_offset; }
181 IntSize minimumScrollOffsetInt() const override;
182 IntSize maximumScrollOffsetInt() const override;
183 ScrollOffset maximumScrollOffset() const override;
184 int visibleHeight() const override { return visibleRect().height(); }
185 int visibleWidth() const override { return visibleRect().width(); }
186 IntSize contentsSize() const override;
187 bool scrollbarsCanBeActive() const override { return false; }
188 IntRect scrollableAreaBoundingBox() const override;
189 bool userInputScrollable(ScrollbarOrientation) const override { return true; }
190 bool shouldPlaceVerticalScrollbarOnLeft() const override { return false; }
191 bool scrollAnimatorEnabled() const override;
192 void scrollControlWasSetNeedsPaintInvalidation() override {}
193 void updateScrollOffset(const ScrollOffset&, ScrollType) override;
194 GraphicsLayer* layerForContainer() const override;
195 GraphicsLayer* layerForScrolling() const override;
196 GraphicsLayer* layerForHorizontalScrollbar() const override;
197 GraphicsLayer* layerForVerticalScrollbar() const override;
198 Widget* getWidget() override;
199 CompositorAnimationTimeline* compositorAnimationTimeline() const override;
200 IntRect visibleContentRect(
201 IncludeScrollbarsInRect = ExcludeScrollbars) const override;
203 // Visual Viewport API implementation.
206 double clientWidth();
207 double clientHeight();
210 // Used for gathering data on user pinch-zoom statistics.
211 void userDidChangeScale();
212 void sendUMAMetrics();
213 void startTrackingPinchStats();
215 // Heuristic-based function for determining if we should disable workarounds
216 // for viewing websites that are not optimized for mobile devices.
217 bool shouldDisableDesktopWorkarounds() const;
220 explicit VisualViewport(FrameHost&);
222 bool didSetScaleOrLocation(float scale, const FloatPoint& location);
224 bool visualViewportSuppliesScrollbars() const;
226 void updateStyleAndLayoutIgnorePendingStylesheets();
228 void enqueueScrollEvent();
229 void enqueueResizeEvent();
231 // GraphicsLayerClient implementation.
232 bool needsRepaint(const GraphicsLayer&) const {
233 ASSERT_NOT_REACHED();
236 IntRect computeInterestRect(const GraphicsLayer*, const IntRect&) const;
237 void paintContents(const GraphicsLayer*,
239 GraphicsLayerPaintingPhase,
240 const IntRect&) const override;
241 String debugName(const GraphicsLayer*) const override;
243 void setupScrollbar(WebScrollbar::Orientation);
245 void notifyRootFrameViewport() const;
247 LocalFrame* mainFrame() const;
249 FrameHost& frameHost() const {
254 Member<FrameHost> m_frameHost;
255 std::unique_ptr<GraphicsLayer> m_rootTransformLayer;
256 std::unique_ptr<GraphicsLayer> m_innerViewportContainerLayer;
257 std::unique_ptr<GraphicsLayer> m_overscrollElasticityLayer;
258 std::unique_ptr<GraphicsLayer> m_pageScaleLayer;
259 std::unique_ptr<GraphicsLayer> m_innerViewportScrollLayer;
260 std::unique_ptr<GraphicsLayer> m_overlayScrollbarHorizontal;
261 std::unique_ptr<GraphicsLayer> m_overlayScrollbarVertical;
262 std::unique_ptr<WebScrollbarLayer> m_webOverlayScrollbarHorizontal;
263 std::unique_ptr<WebScrollbarLayer> m_webOverlayScrollbarVertical;
265 // Offset of the visual viewport from the main frame's origin, in CSS pixels.
266 ScrollOffset m_offset;
269 float m_browserControlsAdjustment;
270 float m_maxPageScale;
271 bool m_trackPinchZoomStatsForPage;
276 #endif // VisualViewport_h