fa0446679672de8a2af3da364bb811d5c5e49e1b
[platform/framework/web/crosswalk-tizen.git] /
1 /*
2  * Copyright (C) 2013 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 VisualViewport_h
32 #define VisualViewport_h
33
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"
43 #include <memory>
44
45 namespace blink {
46 class WebScrollbarLayer;
47 class WebLayer;
48 }
49
50 namespace blink {
51
52 class FrameHost;
53 class GraphicsContext;
54 class GraphicsLayer;
55 class IntRect;
56 class IntSize;
57 class LocalFrame;
58
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);
70
71  public:
72   static VisualViewport* create(FrameHost& host) {
73     return new VisualViewport(host);
74   }
75   ~VisualViewport() override;
76
77   DECLARE_VIRTUAL_TRACE();
78
79   void attachToLayerTree(GraphicsLayer*);
80
81   GraphicsLayer* rootGraphicsLayer() { return m_rootTransformLayer.get(); }
82   GraphicsLayer* containerLayer() {
83     return m_innerViewportContainerLayer.get();
84   }
85   GraphicsLayer* scrollLayer() { return m_innerViewportScrollLayer.get(); }
86   GraphicsLayer* pageScaleLayer() { return m_pageScaleLayer.get(); }
87   GraphicsLayer* overscrollElasticityLayer() {
88     return m_overscrollElasticityLayer.get();
89   }
90
91   void initializeScrollbars();
92
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&);
98
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; }
102
103   // Gets the scaled size, i.e. the viewport in root view space.
104   FloatSize visibleSize() const;
105
106   // Resets the viewport to initial state.
107   void reset();
108
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();
112
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; }
117
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);
122
123   void setScrollLayerOnScrollbars(WebLayer*) const;
124
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;
128
129   // The viewport rect relative to the document origin, in partial CSS pixels.
130   FloatRect visibleRectInDocument() const;
131
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;
137
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);
141
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);
150
151   // Adjust the viewport's offset so that it remains bounded by the outer
152   // viepwort.
153   void clampToBoundaries();
154
155   FloatRect viewportToRootFrame(const FloatRect&) const;
156   IntRect viewportToRootFrame(const IntRect&) const;
157   FloatRect rootFrameToViewport(const FloatRect&) const;
158   IntRect rootFrameToViewport(const IntRect&) const;
159
160   FloatPoint viewportToRootFrame(const FloatPoint&) const;
161   FloatPoint rootFrameToViewport(const FloatPoint&) const;
162   IntPoint viewportToRootFrame(const IntPoint&) const;
163   IntPoint rootFrameToViewport(const IntPoint&) const;
164
165   // ScrollableArea implementation
166   HostWindow* getHostWindow() const override;
167   bool shouldUseIntegerScrollOffset() const override;
168   void setScrollOffset(const ScrollOffset&,
169                        ScrollType,
170                        ScrollBehavior = ScrollBehaviorInstant) override;
171   LayoutRect visualRectForScrollbarParts() const override {
172     ASSERT_NOT_REACHED();
173     return LayoutRect();
174   }
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;
202
203   // Visual Viewport API implementation.
204   double scrollLeft();
205   double scrollTop();
206   double clientWidth();
207   double clientHeight();
208   double pageScale();
209
210   // Used for gathering data on user pinch-zoom statistics.
211   void userDidChangeScale();
212   void sendUMAMetrics();
213   void startTrackingPinchStats();
214
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;
218
219  private:
220   explicit VisualViewport(FrameHost&);
221
222   bool didSetScaleOrLocation(float scale, const FloatPoint& location);
223
224   bool visualViewportSuppliesScrollbars() const;
225
226   void updateStyleAndLayoutIgnorePendingStylesheets();
227
228   void enqueueScrollEvent();
229   void enqueueResizeEvent();
230
231   // GraphicsLayerClient implementation.
232   bool needsRepaint(const GraphicsLayer&) const {
233     ASSERT_NOT_REACHED();
234     return true;
235   }
236   IntRect computeInterestRect(const GraphicsLayer*, const IntRect&) const;
237   void paintContents(const GraphicsLayer*,
238                      GraphicsContext&,
239                      GraphicsLayerPaintingPhase,
240                      const IntRect&) const override;
241   String debugName(const GraphicsLayer*) const override;
242
243   void setupScrollbar(WebScrollbar::Orientation);
244
245   void notifyRootFrameViewport() const;
246
247   LocalFrame* mainFrame() const;
248
249   FrameHost& frameHost() const {
250     ASSERT(m_frameHost);
251     return *m_frameHost;
252   }
253
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;
264
265   // Offset of the visual viewport from the main frame's origin, in CSS pixels.
266   ScrollOffset m_offset;
267   float m_scale;
268   IntSize m_size;
269   float m_browserControlsAdjustment;
270   float m_maxPageScale;
271   bool m_trackPinchZoomStatsForPage;
272 };
273
274 }  // namespace blink
275
276 #endif  // VisualViewport_h