blob: e86a8510ffeed6c981c144d47e9536d4b3b6ecce [file] [log] [blame]
// 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 <memory>
#include "base/macros.h"
#include "cc/input/snap_fling_controller.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/core/scroll/scroll_types.h"
#include "third_party/blink/renderer/platform/geometry/layout_size.h"
#include "third_party/blink/renderer/platform/graphics/compositor_element_id.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/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/deque.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 GarbageCollected<ScrollManager>,
public cc::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:
Node* NodeTargetForScrollableAreaElementId(
CompositorElementId scrollable_area_element_id) const;
WebInputEventResult HandleGestureScrollUpdate(const WebGestureEvent&);
WebInputEventResult HandleGestureScrollBegin(const WebGestureEvent&);
// Handling of GestureScrollEnd may be deferred if there's an outstanding
// scroll animation. This is the callback that invokes the deferred operation.
void HandleDeferredGestureScrollEnd(const WebGestureEvent& gesture_event);
WebInputEventResult PassScrollGestureEvent(const WebGestureEvent&,
LayoutObject*);
Node* GetScrollEventTarget();
void ClearGestureScrollState();
void CustomizedScroll(ScrollState&);
Page* GetPage() const;
bool HandleScrollGestureOnResizer(Node*, const WebGestureEvent&);
void RecomputeScrollChain(const Node& start_node,
const ScrollState&,
Deque<DOMNodeId>& 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);
bool SnapAtGestureScrollEnd(const WebGestureEvent& end_event);
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<LocalFrame> frame_;
// Only used with the ScrollCustomization runtime enabled feature.
Deque<DOMNodeId> current_scroll_chain_;
Member<Node> 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<Node> previous_gesture_scrolled_node_;
FloatSize last_scroll_delta_for_scroll_gesture_;
// 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> scrollbar_handling_scroll_gesture_;
Member<PaintLayerScrollableArea> resize_scrollable_area_;
std::unique_ptr<cc::SnapFlingController> 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_