1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_INPUT_SCROLL_MANAGER_H_
6 #define THIRD_PARTY_BLINK_RENDERER_CORE_INPUT_SCROLL_MANAGER_H_
7 
8 #include <memory>
9 
10 #include "base/callback_helpers.h"
11 #include "cc/input/snap_fling_controller.h"
12 #include "third_party/blink/public/platform/web_input_event_result.h"
13 #include "third_party/blink/renderer/core/core_export.h"
14 #include "third_party/blink/renderer/core/dom/dom_node_ids.h"
15 #include "third_party/blink/renderer/core/page/event_with_hit_test_results.h"
16 #include "third_party/blink/renderer/core/scroll/scroll_types.h"
17 #include "third_party/blink/renderer/platform/geometry/layout_size.h"
18 #include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
19 #include "third_party/blink/renderer/platform/heap/handle.h"
20 #include "third_party/blink/renderer/platform/heap/visitor.h"
21 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
22 #include "third_party/blink/renderer/platform/wtf/deque.h"
23 
24 namespace blink {
25 
26 class AutoscrollController;
27 class LayoutBox;
28 class LayoutObject;
29 class LocalFrame;
30 class PaintLayer;
31 class PaintLayerScrollableArea;
32 class Page;
33 class Scrollbar;
34 class ScrollState;
35 class WebGestureEvent;
36 
37 // This class takes care of scrolling and resizing and the related states. The
38 // user action that causes scrolling or resizing is determined in other *Manager
39 // classes and they call into this class for doing the work.
40 class CORE_EXPORT ScrollManager : public GarbageCollected<ScrollManager>,
41                                   public cc::SnapFlingClient {
42  public:
43   explicit ScrollManager(LocalFrame&);
44   ScrollManager(const ScrollManager&) = delete;
45   ScrollManager& operator=(const ScrollManager&) = delete;
46   virtual ~ScrollManager() = default;
47   void Trace(Visitor*) const;
48 
49   void Clear();
50 
51   bool MiddleClickAutoscrollInProgress() const;
52   void StopMiddleClickAutoscroll();
53   AutoscrollController* GetAutoscrollController() const;
54   void StopAutoscroll();
55 
56   // Performs a chaining logical scroll, within a *single* frame, starting
57   // from either a provided starting node or a default based on the focused or
58   // most recently clicked node, falling back to the frame.
59   // Returns true if the scroll was consumed.
60   // direction - The logical direction to scroll in. This will be converted to
61   //             a physical direction for each LayoutBox we try to scroll
62   //             based on that box's writing mode.
63   // granularity - The units that the  scroll delta parameter is in.
64   // startNode - Optional. If provided, start chaining from the given node.
65   //             If not, use the current focus or last clicked node.
66   bool LogicalScroll(mojom::blink::ScrollDirection,
67                      ScrollGranularity,
68                      Node* start_node,
69                      Node* mouse_press_node);
70 
71   // Performs a logical scroll that chains, crossing frames, starting from
72   // the given node or a reasonable default (focus/last clicked).
73   bool BubblingScroll(mojom::blink::ScrollDirection,
74                       ScrollGranularity,
75                       Node* starting_node,
76                       Node* mouse_press_node);
77 
78   // TODO(crbug.com/616491): Consider moving all gesture related functions to
79   // another class.
80 
81   // Handle the provided scroll gesture event, propagating down to child frames
82   // as necessary.
83   WebInputEventResult HandleGestureScrollEvent(const WebGestureEvent&);
84 
85   WebInputEventResult HandleGestureScrollEnd(const WebGestureEvent&);
86 
87   bool IsScrollbarHandlingGestures() const;
88 
89   // Returns true if the gesture event should be handled in ScrollManager.
90   bool CanHandleGestureEvent(const GestureEventWithHitTestResults&);
91 
92   // These functions are related to |m_resizeScrollableArea|.
93   bool InResizeMode() const;
94   void Resize(const WebMouseEvent&);
95   // Clears |m_resizeScrollableArea|. if |shouldNotBeNull| is true this
96   // function DCHECKs to make sure that variable is indeed not null.
97   void ClearResizeScrollableArea(bool should_not_be_null);
98   void SetResizeScrollableArea(PaintLayer*, IntPoint);
99 
100   // SnapFlingClient implementation.
101   bool GetSnapFlingInfoAndSetAnimatingSnapTarget(
102       const gfx::Vector2dF& natural_displacement,
103       gfx::Vector2dF* out_initial_position,
104       gfx::Vector2dF* out_target_position) const override;
105   gfx::Vector2dF ScrollByForSnapFling(const gfx::Vector2dF& delta) override;
106   void ScrollEndForSnapFling(bool did_finish) override;
107   void RequestAnimationForSnapFling() override;
108 
109   void AnimateSnapFling(base::TimeTicks monotonic_time);
110 
111  private:
112   Node* NodeTargetForScrollableAreaElementId(
113       CompositorElementId scrollable_area_element_id) const;
114   WebInputEventResult HandleGestureScrollUpdate(const WebGestureEvent&);
115   WebInputEventResult HandleGestureScrollBegin(const WebGestureEvent&);
116 
117   // Handling of GestureScrollEnd may be deferred if there's an outstanding
118   // scroll animation. This is the callback that invokes the deferred operation.
119   void HandleDeferredGestureScrollEnd(const WebGestureEvent& gesture_event);
120 
121   WebInputEventResult PassScrollGestureEvent(const WebGestureEvent&,
122                                              LayoutObject*);
123 
124   Node* GetScrollEventTarget();
125 
126   void ClearGestureScrollState();
127 
128   void CustomizedScroll(ScrollState&);
129 
130   Page* GetPage() const;
131 
132   bool HandleScrollGestureOnResizer(Node*, const WebGestureEvent&);
133 
134   void RecomputeScrollChain(const Node& start_node,
135                             const ScrollState&,
136                             Deque<DOMNodeId>& scroll_chain);
137   bool CanScroll(const ScrollState&, const Node& current_node);
138 
139   // scroller_size is set only when scrolling non root scroller.
140   void ComputeScrollRelatedMetrics(
141       uint32_t* non_composited_main_thread_scrolling_reasons);
142   void RecordScrollRelatedMetrics(const WebGestureDevice);
143 
144   WebGestureEvent SynthesizeGestureScrollBegin(
145       const WebGestureEvent& update_event);
146 
147   bool SnapAtGestureScrollEnd(const WebGestureEvent& end_event,
148                               base::ScopedClosureRunner callback);
149 
150   void NotifyScrollPhaseBeginForCustomizedScroll(const ScrollState&);
151   void NotifyScrollPhaseEndForCustomizedScroll();
152 
153   LayoutBox* LayoutBoxForSnapping() const;
154 
155   // NOTE: If adding a new field to this class please ensure that it is
156   // cleared in |ScrollManager::clear()|.
157 
158   const Member<LocalFrame> frame_;
159 
160   // Only used with the ScrollCustomization runtime enabled feature.
161   Deque<DOMNodeId> current_scroll_chain_;
162 
163   Member<Node> scroll_gesture_handling_node_;
164 
165   bool last_gesture_scroll_over_embedded_content_view_;
166 
167   // The most recent Node to scroll natively during this scroll
168   // sequence. Null if no native element has scrolled this scroll
169   // sequence, or if the most recent element to scroll used scroll
170   // customization.
171   Member<Node> previous_gesture_scrolled_node_;
172 
173   FloatSize last_scroll_delta_for_scroll_gesture_;
174 
175   // True iff some of the delta has been consumed for the current
176   // scroll sequence in this frame, or any child frames. Only used
177   // with ScrollCustomization. If some delta has been consumed, a
178   // scroll which shouldn't propagate can't cause any element to
179   // scroll other than the |m_previousGestureScrolledNode|.
180   bool delta_consumed_for_scroll_sequence_;
181 
182   // True iff some of the delta has been consumed for the current
183   // scroll sequence on the specific axis.
184   bool did_scroll_x_for_scroll_gesture_;
185   bool did_scroll_y_for_scroll_gesture_;
186 
187   Member<Scrollbar> scrollbar_handling_scroll_gesture_;
188 
189   Member<PaintLayerScrollableArea> resize_scrollable_area_;
190 
191   std::unique_ptr<cc::SnapFlingController> snap_fling_controller_;
192 
193   LayoutSize
194       offset_from_resize_corner_;  // In the coords of m_resizeScrollableArea.
195 };
196 
197 }  // namespace blink
198 
199 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_INPUT_SCROLL_MANAGER_H_
200