// Copyright 2016 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_INPUT_SCROLL_MANAGER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_INPUT_SCROLL_MANAGER_H_ #include #include "base/macros.h" #include "third_party/blink/public/platform/web_input_event_result.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/dom_node_ids.h" #include "third_party/blink/renderer/core/page/event_with_hit_test_results.h" #include "third_party/blink/renderer/platform/geometry/layout_size.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/visitor.h" #include "third_party/blink/renderer/platform/scroll/scroll_snap_data.h" #include "third_party/blink/renderer/platform/scroll/scroll_types.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" namespace blink { class AutoscrollController; class LayoutBox; class LayoutObject; class LocalFrame; class PaintLayer; class PaintLayerScrollableArea; class Page; class Scrollbar; class ScrollState; class WebGestureEvent; // This class takes care of scrolling and resizing and the related states. The // user action that causes scrolling or resizing is determined in other *Manager // classes and they call into this class for doing the work. class CORE_EXPORT ScrollManager : public GarbageCollectedFinalized, public SnapFlingClient { public: explicit ScrollManager(LocalFrame&); virtual ~ScrollManager() = default; void Trace(blink::Visitor*); void Clear(); bool MiddleClickAutoscrollInProgress() const; void StopMiddleClickAutoscroll(); AutoscrollController* GetAutoscrollController() const; void StopAutoscroll(); // Performs a chaining logical scroll, within a *single* frame, starting // from either a provided starting node or a default based on the focused or // most recently clicked node, falling back to the frame. // Returns true if the scroll was consumed. // direction - The logical direction to scroll in. This will be converted to // a physical direction for each LayoutBox we try to scroll // based on that box's writing mode. // granularity - The units that the scroll delta parameter is in. // startNode - Optional. If provided, start chaining from the given node. // If not, use the current focus or last clicked node. bool LogicalScroll(ScrollDirection, ScrollGranularity, Node* start_node, Node* mouse_press_node); // Performs a logical scroll that chains, crossing frames, starting from // the given node or a reasonable default (focus/last clicked). bool BubblingScroll(ScrollDirection, ScrollGranularity, Node* starting_node, Node* mouse_press_node); // TODO(crbug.com/616491): Consider moving all gesture related functions to // another class. // Handle the provided scroll gesture event, propagating down to child frames // as necessary. WebInputEventResult HandleGestureScrollEvent(const WebGestureEvent&); WebInputEventResult HandleGestureScrollEnd(const WebGestureEvent&); bool IsScrollbarHandlingGestures() const; // Returns true if the gesture event should be handled in ScrollManager. bool CanHandleGestureEvent(const GestureEventWithHitTestResults&); // These functions are related to |m_resizeScrollableArea|. bool InResizeMode() const; void Resize(const WebMouseEvent&); // Clears |m_resizeScrollableArea|. if |shouldNotBeNull| is true this // function DCHECKs to make sure that variable is indeed not null. void ClearResizeScrollableArea(bool should_not_be_null); void SetResizeScrollableArea(PaintLayer*, IntPoint); // SnapFlingClient implementation. bool GetSnapFlingInfo(const gfx::Vector2dF& natural_displacement, gfx::Vector2dF* out_initial_position, gfx::Vector2dF* out_target_position) const override; gfx::Vector2dF ScrollByForSnapFling(const gfx::Vector2dF& delta) override; void ScrollEndForSnapFling() override; void RequestAnimationForSnapFling() override; void AnimateSnapFling(base::TimeTicks monotonic_time); private: WebInputEventResult HandleGestureScrollUpdate(const WebGestureEvent&); WebInputEventResult HandleGestureScrollBegin(const WebGestureEvent&); WebInputEventResult PassScrollGestureEvent(const WebGestureEvent&, LayoutObject*); void ClearGestureScrollState(); void CustomizedScroll(ScrollState&); Page* GetPage() const; bool HandleScrollGestureOnResizer(Node*, const WebGestureEvent&); void RecomputeScrollChain(const Node& start_node, const ScrollState&, std::deque& scroll_chain); bool CanScroll(const ScrollState&, const Node& current_node); // scroller_size is set only when scrolling non root scroller. void ComputeScrollRelatedMetrics( uint32_t* non_composited_main_thread_scrolling_reasons); void RecordScrollRelatedMetrics(const WebGestureDevice); WebGestureEvent SynthesizeGestureScrollBegin( const WebGestureEvent& update_event); void SnapAtGestureScrollEnd(); void NotifyScrollPhaseBeginForCustomizedScroll(const ScrollState&); void NotifyScrollPhaseEndForCustomizedScroll(); LayoutBox* LayoutBoxForSnapping() const; // NOTE: If adding a new field to this class please ensure that it is // cleared in |ScrollManager::clear()|. const Member frame_; // Only used with the ScrollCustomization runtime enabled feature. std::deque current_scroll_chain_; Member scroll_gesture_handling_node_; bool last_gesture_scroll_over_embedded_content_view_; // The most recent Node to scroll natively during this scroll // sequence. Null if no native element has scrolled this scroll // sequence, or if the most recent element to scroll used scroll // customization. Member previous_gesture_scrolled_node_; // True iff some of the delta has been consumed for the current // scroll sequence in this frame, or any child frames. Only used // with ScrollCustomization. If some delta has been consumed, a // scroll which shouldn't propagate can't cause any element to // scroll other than the |m_previousGestureScrolledNode|. bool delta_consumed_for_scroll_sequence_; // True iff some of the delta has been consumed for the current // scroll sequence on the specific axis. bool did_scroll_x_for_scroll_gesture_; bool did_scroll_y_for_scroll_gesture_; Member scrollbar_handling_scroll_gesture_; Member resize_scrollable_area_; std::unique_ptr snap_fling_controller_; LayoutSize offset_from_resize_corner_; // In the coords of m_resizeScrollableArea. DISALLOW_COPY_AND_ASSIGN(ScrollManager); }; } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_INPUT_SCROLL_MANAGER_H_