| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef RootFrameViewport_h |
| #define RootFrameViewport_h |
| |
| #include "core/CoreExport.h" |
| #include "platform/scroll/ScrollableArea.h" |
| |
| namespace blink { |
| |
| class FrameView; |
| class LayoutRect; |
| |
| // ScrollableArea for the root frame's viewport. This class ties together the |
| // concepts of layout and visual viewports, used in pinch-to-zoom. This class |
| // takes two ScrollableAreas, one for the visual viewport and one for the |
| // layout viewport, and delegates and composes the ScrollableArea API as needed |
| // between them. For most scrolling APIs, this class will split the scroll up |
| // between the two viewports in accord with the pinch-zoom semantics. For other |
| // APIs that don't make sense on the combined viewport, the call is delegated to |
| // the layout viewport. Thus, we could say this class is a decorator on the |
| // FrameView scrollable area that adds pinch-zoom semantics to scrolling. |
| class CORE_EXPORT RootFrameViewport final |
| : public GarbageCollectedFinalized<RootFrameViewport>, |
| public ScrollableArea { |
| USING_GARBAGE_COLLECTED_MIXIN(RootFrameViewport); |
| |
| public: |
| static RootFrameViewport* create(ScrollableArea& visualViewport, |
| ScrollableArea& layoutViewport) { |
| return new RootFrameViewport(visualViewport, layoutViewport); |
| } |
| |
| DECLARE_VIRTUAL_TRACE(); |
| |
| void setLayoutViewport(ScrollableArea&); |
| ScrollableArea& layoutViewport() const; |
| |
| // Convert from the root content document's coordinate space, into the |
| // coordinate space of the layout viewport's content. In the normal case, |
| // this will be a no-op since the root FrameView is the layout viewport and |
| // so the root content is the layout viewport's content but if the page |
| // sets a custom root scroller via document.rootScroller, another element |
| // may be the layout viewport. |
| LayoutRect rootContentsToLayoutViewportContents(FrameView& rootFrameView, |
| const LayoutRect&) const; |
| |
| void restoreToAnchor(const DoublePoint&); |
| |
| // Callback whenever the visual viewport changes scroll position or scale. |
| void didUpdateVisualViewport(); |
| |
| // ScrollableArea Implementation |
| bool isRootFrameViewport() const override { return true; } |
| void setScrollPosition(const DoublePoint&, |
| ScrollType, |
| ScrollBehavior = ScrollBehaviorInstant) override; |
| LayoutRect scrollIntoView(const LayoutRect& rectInContent, |
| const ScrollAlignment& alignX, |
| const ScrollAlignment& alignY, |
| ScrollType = ProgrammaticScroll) override; |
| DoubleRect visibleContentRectDouble( |
| IncludeScrollbarsInRect = ExcludeScrollbars) const override; |
| IntRect visibleContentRect( |
| IncludeScrollbarsInRect = ExcludeScrollbars) const override; |
| bool shouldUseIntegerScrollOffset() const override; |
| LayoutRect visualRectForScrollbarParts() const override { |
| ASSERT_NOT_REACHED(); |
| return LayoutRect(); |
| } |
| bool isActive() const override; |
| int scrollSize(ScrollbarOrientation) const override; |
| bool isScrollCornerVisible() const override; |
| IntRect scrollCornerRect() const override; |
| void setScrollOffset(const DoublePoint&, ScrollType) override; |
| IntPoint scrollPosition() const override; |
| DoublePoint scrollPositionDouble() const override; |
| IntPoint minimumScrollPosition() const override; |
| IntPoint maximumScrollPosition() const override; |
| DoublePoint maximumScrollPositionDouble() const override; |
| IntSize contentsSize() const override; |
| bool scrollbarsCanBeActive() const override; |
| IntRect scrollableAreaBoundingBox() const override; |
| bool userInputScrollable(ScrollbarOrientation) const override; |
| bool shouldPlaceVerticalScrollbarOnLeft() const override; |
| void scrollControlWasSetNeedsPaintInvalidation() override; |
| GraphicsLayer* layerForContainer() const override; |
| GraphicsLayer* layerForScrolling() const override; |
| GraphicsLayer* layerForHorizontalScrollbar() const override; |
| GraphicsLayer* layerForVerticalScrollbar() const override; |
| GraphicsLayer* layerForScrollCorner() const override; |
| ScrollResult userScroll(ScrollGranularity, const FloatSize&) override; |
| bool scrollAnimatorEnabled() const override; |
| HostWindow* getHostWindow() const override; |
| void serviceScrollAnimations(double) override; |
| void updateCompositorScrollAnimations() override; |
| void cancelProgrammaticScrollAnimation() override; |
| ScrollBehavior scrollBehaviorStyle() const override; |
| Widget* getWidget() override; |
| void clearScrollAnimators() override; |
| LayoutBox* layoutBox() const override; |
| |
| private: |
| RootFrameViewport(ScrollableArea& visualViewport, |
| ScrollableArea& layoutViewport); |
| |
| enum ViewportToScrollFirst { VisualViewport, LayoutViewport }; |
| |
| DoublePoint scrollOffsetFromScrollAnimators() const; |
| |
| void distributeScrollBetweenViewports(const DoublePoint&, |
| ScrollType, |
| ScrollBehavior, |
| ViewportToScrollFirst); |
| |
| // If either of the layout or visual viewports are scrolled explicitly (i.e. |
| // not through this class), their updated offset will not be reflected in this |
| // class' animator so use this method to pull updated values when necessary. |
| void updateScrollAnimator(); |
| |
| ScrollableArea& visualViewport() const { |
| ASSERT(m_visualViewport); |
| return *m_visualViewport; |
| } |
| |
| Member<ScrollableArea> m_visualViewport; |
| Member<ScrollableArea> m_layoutViewport; |
| }; |
| |
| DEFINE_TYPE_CASTS(RootFrameViewport, |
| ScrollableArea, |
| scrollableArea, |
| scrollableArea->isRootFrameViewport(), |
| scrollableArea.isRootFrameViewport()); |
| |
| } // namespace blink |
| |
| #endif // RootFrameViewport_h |