summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state.cc
blob: 93d56565eb7a493b9da78c5740be597705e57ab3 (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
// 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.

#include "third_party/blink/renderer/core/page/scrolling/scroll_state.h"

#include <memory>
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"

namespace blink {

namespace {
Element* ElementForId(int element_id) {
  Node* node = DOMNodeIds::NodeForId(element_id);
  DCHECK(node);
  if (!node)
    return nullptr;
  DCHECK(node->IsElementNode());
  if (!node->IsElementNode())
    return nullptr;
  return static_cast<Element*>(node);
}
}  // namespace

ScrollState* ScrollState::Create(ScrollStateInit init) {
  std::unique_ptr<ScrollStateData> scroll_state_data =
      std::make_unique<ScrollStateData>();
  scroll_state_data->delta_x = init.deltaX();
  scroll_state_data->delta_y = init.deltaY();
  scroll_state_data->delta_x_hint = init.deltaXHint();
  scroll_state_data->delta_y_hint = init.deltaYHint();
  scroll_state_data->position_x = init.positionX();
  scroll_state_data->position_y = init.positionY();
  scroll_state_data->velocity_x = init.velocityX();
  scroll_state_data->velocity_y = init.velocityY();
  scroll_state_data->is_beginning = init.isBeginning();
  scroll_state_data->is_in_inertial_phase = init.isInInertialPhase();
  scroll_state_data->is_ending = init.isEnding();
  scroll_state_data->from_user_input = init.fromUserInput();
  scroll_state_data->is_direct_manipulation = init.isDirectManipulation();
  scroll_state_data->delta_granularity = init.deltaGranularity();
  ScrollState* scroll_state = new ScrollState(std::move(scroll_state_data));
  return scroll_state;
}

ScrollState* ScrollState::Create(std::unique_ptr<ScrollStateData> data) {
  ScrollState* scroll_state = new ScrollState(std::move(data));
  return scroll_state;
}

ScrollState::ScrollState(std::unique_ptr<ScrollStateData> data)
    : data_(std::move(data)) {}

void ScrollState::consumeDelta(double x,
                               double y,
                               ExceptionState& exception_state) {
  if ((data_->delta_x > 0 && 0 > x) || (data_->delta_x < 0 && 0 < x) ||
      (data_->delta_y > 0 && 0 > y) || (data_->delta_y < 0 && 0 < y)) {
    exception_state.ThrowDOMException(
        DOMExceptionCode::kInvalidModificationError,
        "Can't increase delta using consumeDelta");
    return;
  }
  if (fabs(x) > fabs(data_->delta_x) || fabs(y) > fabs(data_->delta_y)) {
    exception_state.ThrowDOMException(
        DOMExceptionCode::kInvalidModificationError,
        "Can't change direction of delta using consumeDelta");
    return;
  }
  ConsumeDeltaNative(x, y);
}

void ScrollState::distributeToScrollChainDescendant() {
  if (!scroll_chain_.empty()) {
    int descendant_id = scroll_chain_.front();
    scroll_chain_.pop_front();
    ElementForId(descendant_id)->CallDistributeScroll(*this);
  }
}

void ScrollState::ConsumeDeltaNative(double x, double y) {
  data_->delta_x -= x;
  data_->delta_y -= y;

  if (x)
    data_->caused_scroll_x = true;
  if (y)
    data_->caused_scroll_y = true;
  if (x || y)
    data_->delta_consumed_for_scroll_sequence = true;
}

Element* ScrollState::CurrentNativeScrollingElement() {
  if (data_->current_native_scrolling_element() == CompositorElementId()) {
    element_.Clear();
    return nullptr;
  }
  return element_;
}

void ScrollState::SetCurrentNativeScrollingElement(Element* element) {
  element_ = element;
  data_->set_current_native_scrolling_element(
      CompositorElementIdFromDOMNodeId(DOMNodeIds::IdForNode(element)));
}

}  // namespace blink