summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/frame/root_frame_viewport.h
blob: 67449d770b15b390c53da886da195188188d4d6d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// 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 THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_ROOT_FRAME_VIEWPORT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_ROOT_FRAME_VIEWPORT_H_

#include "base/single_thread_task_runner.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/graphics/scroll_types.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"

namespace blink {

class LocalFrameView;
struct PhysicalRect;
struct WebScrollIntoViewParams;

// 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
// LocalFrameView scrollable area that adds pinch-zoom semantics to scrolling.
class CORE_EXPORT RootFrameViewport final
    : public GarbageCollected<RootFrameViewport>,
      public ScrollableArea {
  USING_GARBAGE_COLLECTED_MIXIN(RootFrameViewport);

 public:
  RootFrameViewport(ScrollableArea& visual_viewport,
                    ScrollableArea& layout_viewport);

  void Trace(blink::Visitor*) override;

  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 LocalFrameView 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.
  PhysicalRect RootContentsToLayoutViewportContents(
      LocalFrameView& root_frame_view,
      const PhysicalRect&) const;

  void RestoreToAnchor(const ScrollOffset&);

  // Callback whenever the visual viewport changes scroll position or scale.
  void DidUpdateVisualViewport();

  // ScrollableArea Implementation
  bool IsRootFrameViewport() const override { return true; }
  void SetScrollOffset(const ScrollOffset&,
                       ScrollType,
                       ScrollBehavior,
                       ScrollCallback on_finish) override;
  PhysicalRect ScrollIntoView(const PhysicalRect&,
                              const WebScrollIntoViewParams&) override;
  IntRect VisibleContentRect(
      IncludeScrollbarsInRect = kExcludeScrollbars) const override;
  PhysicalRect VisibleScrollSnapportRect(
      IncludeScrollbarsInRect = kExcludeScrollbars) const override;
  bool ShouldUseIntegerScrollOffset() const override;
  bool IsThrottled() const override {
    // RootFrameViewport is always in the main frame, so the frame does not get
    // throttled.
    return false;
  }
  bool IsActive() const override;
  int ScrollSize(ScrollbarOrientation) const override;
  bool IsScrollCornerVisible() const override;
  IntRect ScrollCornerRect() const override;
  void UpdateScrollOffset(const ScrollOffset&, ScrollType) override;
  IntSize ScrollOffsetInt() const override;
  ScrollOffset GetScrollOffset() const override;
  IntSize MinimumScrollOffsetInt() const override;
  IntSize MaximumScrollOffsetInt() const override;
  ScrollOffset MaximumScrollOffset() const override;
  IntSize ClampScrollOffset(const IntSize&) const override;
  ScrollOffset ClampScrollOffset(const ScrollOffset&) const override;
  IntSize ContentsSize() const override;
  bool ScrollbarsCanBeActive() const override;
  bool UserInputScrollable(ScrollbarOrientation) const override;
  bool ShouldPlaceVerticalScrollbarOnLeft() const override;
  void ScrollControlWasSetNeedsPaintInvalidation() override;
  GraphicsLayer* LayerForScrolling() const override;
  GraphicsLayer* LayerForHorizontalScrollbar() const override;
  GraphicsLayer* LayerForVerticalScrollbar() const override;
  GraphicsLayer* LayerForScrollCorner() const override;
  int HorizontalScrollbarHeight(
      OverlayScrollbarClipBehavior =
          kIgnorePlatformOverlayScrollbarSize) const override;
  int VerticalScrollbarWidth(
      OverlayScrollbarClipBehavior =
          kIgnorePlatformOverlayScrollbarSize) const override;
  ScrollResult UserScroll(ScrollGranularity,
                          const FloatSize&,
                          ScrollableArea::ScrollCallback on_finish) override;
  CompositorElementId GetCompositorElementId() const override;
  CompositorElementId GetScrollbarElementId(
      ScrollbarOrientation orientation) override;
  bool ScrollAnimatorEnabled() const override;
  ChromeClient* GetChromeClient() const override;
  SmoothScrollSequencer* GetSmoothScrollSequencer() const override;
  void ServiceScrollAnimations(double) override;
  void UpdateCompositorScrollAnimations() override;
  void CancelProgrammaticScrollAnimation() override;
  ScrollBehavior ScrollBehaviorStyle() const override;
  WebColorScheme UsedColorScheme() const override;
  void ClearScrollableArea() override;
  LayoutBox* GetLayoutBox() const override;
  FloatQuad LocalToVisibleContentQuad(const FloatQuad&,
                                      const LayoutObject*,
                                      unsigned = 0) const final;
  scoped_refptr<base::SingleThreadTaskRunner> GetTimerTaskRunner() const final;
  ScrollbarTheme& GetPageScrollbarTheme() const override;

  void SetPendingHistoryRestoreScrollOffset(
      const HistoryItem::ViewState& view_state,
      bool should_restore_scroll) override {
    pending_view_state_ = view_state;
    should_restore_scroll_ = should_restore_scroll;
  }
  bool ApplyPendingHistoryRestoreScrollOffset() override;

  const cc::SnapContainerData* GetSnapContainerData() const override;
  void SetSnapContainerData(base::Optional<cc::SnapContainerData>) override;

 private:
  FRIEND_TEST_ALL_PREFIXES(RootFrameViewportTest, DistributeScrollOrder);

  enum ViewportToScrollFirst { kVisualViewport, kLayoutViewport };

  ScrollOffset ScrollOffsetFromScrollAnimators() const;

  void DistributeScrollBetweenViewports(
      const ScrollOffset&,
      ScrollType,
      ScrollBehavior,
      ViewportToScrollFirst,
      ScrollCallback on_finish = ScrollCallback());

  // 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& GetVisualViewport() const {
    DCHECK(visual_viewport_);
    return *visual_viewport_;
  }

  ScrollOffset ClampToUserScrollableOffset(const ScrollOffset&) const;

  Member<ScrollableArea> visual_viewport_;
  Member<ScrollableArea> layout_viewport_;
  base::Optional<HistoryItem::ViewState> pending_view_state_;
  bool should_restore_scroll_;
};

template <>
struct DowncastTraits<RootFrameViewport> {
  static bool AllowFrom(const ScrollableArea& scrollable_area) {
    return scrollable_area.IsRootFrameViewport();
  }
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_ROOT_FRAME_VIEWPORT_H_