| Index: third_party/WebKit/Source/core/input/ScrollManager.cpp
|
| diff --git a/third_party/WebKit/Source/core/input/ScrollManager.cpp b/third_party/WebKit/Source/core/input/ScrollManager.cpp
|
| index 5e0c606de4da1f9155cf4e7a8fcf68e0316e35cd..ea0084fd482f74bcc753e3c903703190e4310a54 100644
|
| --- a/third_party/WebKit/Source/core/input/ScrollManager.cpp
|
| +++ b/third_party/WebKit/Source/core/input/ScrollManager.cpp
|
| @@ -79,7 +79,9 @@ AutoscrollController* ScrollManager::GetAutoscrollController() const {
|
| }
|
|
|
| void ScrollManager::RecomputeScrollChain(const Node& start_node,
|
| + const ScrollState& scroll_state,
|
| std::deque<int>& scroll_chain) {
|
| + DCHECK(!scroll_chain.size());
|
| scroll_chain.clear();
|
|
|
| DCHECK(start_node.GetLayoutObject());
|
| @@ -104,7 +106,8 @@ void ScrollManager::RecomputeScrollChain(const Node& start_node,
|
| }
|
|
|
| if (cur_element) {
|
| - scroll_chain.push_front(DOMNodeIds::IdForNode(cur_element));
|
| + if (CanScroll(scroll_state, cur_element))
|
| + scroll_chain.push_front(DOMNodeIds::IdForNode(cur_element));
|
| if (IsViewportScrollingElement(*cur_element) ||
|
| cur_element == document_element)
|
| break;
|
| @@ -114,6 +117,39 @@ void ScrollManager::RecomputeScrollChain(const Node& start_node,
|
| }
|
| }
|
|
|
| +bool ScrollManager::CanScroll(const ScrollState& scroll_state,
|
| + const Element* current_element) {
|
| + const double delta_x = scroll_state.isBeginning() ? scroll_state.deltaXHint()
|
| + : scroll_state.deltaX();
|
| + const double delta_y = scroll_state.isBeginning() ? scroll_state.deltaYHint()
|
| + : scroll_state.deltaY();
|
| + DCHECK(delta_x || delta_y);
|
| + DCHECK(current_element);
|
| +
|
| + ScrollableArea* scrollable_area = nullptr;
|
| + if (current_element == frame_->GetDocument()->documentElement()) {
|
| + scrollable_area =
|
| + frame_->View() ? frame_->View()->GetScrollableArea() : nullptr;
|
| + } else {
|
| + scrollable_area = current_element->GetLayoutBox()
|
| + ? current_element->GetLayoutBox()->GetScrollableArea()
|
| + : nullptr;
|
| + }
|
| + if (!scrollable_area)
|
| + return false;
|
| +
|
| + if (scroll_state.ignoreDeltaHints()) {
|
| + DCHECK(scroll_state.isBeginning());
|
| + return true;
|
| + }
|
| +
|
| + ScrollOffset current_offset = scrollable_area->GetScrollOffset();
|
| + ScrollOffset target_offset = current_offset + ScrollOffset(delta_x, delta_y);
|
| + ScrollOffset clamped_offset =
|
| + scrollable_area->ClampScrollOffset(target_offset);
|
| + return clamped_offset != current_offset;
|
| +}
|
| +
|
| bool ScrollManager::LogicalScroll(ScrollDirection direction,
|
| ScrollGranularity granularity,
|
| Node* start_node,
|
| @@ -183,16 +219,14 @@ void ScrollManager::SetFrameWasScrolledByUser() {
|
| document_loader->GetInitialScrollState().was_scrolled_by_user = true;
|
| }
|
|
|
| -void ScrollManager::CustomizedScroll(const Node& start_node,
|
| - ScrollState& scroll_state) {
|
| +void ScrollManager::CustomizedScroll(ScrollState& scroll_state) {
|
| if (scroll_state.FullyConsumed())
|
| return;
|
|
|
| if (scroll_state.deltaX() || scroll_state.deltaY())
|
| frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
|
|
|
| - if (current_scroll_chain_.empty())
|
| - RecomputeScrollChain(start_node, current_scroll_chain_);
|
| + DCHECK(!current_scroll_chain_.empty());
|
| scroll_state.SetScrollChain(current_scroll_chain_);
|
|
|
| scroll_state.distributeToScrollChainDescendant();
|
| @@ -318,6 +352,8 @@ WebInputEventResult ScrollManager::HandleGestureScrollBegin(
|
| IntPoint position = FlooredIntPoint(gesture_event.PositionInRootFrame());
|
| scroll_state_data->position_x = position.X();
|
| scroll_state_data->position_y = position.Y();
|
| + scroll_state_data->delta_x_hint = -gesture_event.DeltaXInRootFrame();
|
| + scroll_state_data->delta_y_hint = -gesture_event.DeltaYInRootFrame();
|
| scroll_state_data->is_beginning = true;
|
| scroll_state_data->from_user_input = true;
|
| scroll_state_data->is_direct_manipulation =
|
| @@ -325,7 +361,12 @@ WebInputEventResult ScrollManager::HandleGestureScrollBegin(
|
| scroll_state_data->delta_consumed_for_scroll_sequence =
|
| delta_consumed_for_scroll_sequence_;
|
| ScrollState* scroll_state = ScrollState::Create(std::move(scroll_state_data));
|
| - CustomizedScroll(*scroll_gesture_handling_node_.Get(), *scroll_state);
|
| + RecomputeScrollChain(*scroll_gesture_handling_node_.Get(), *scroll_state,
|
| + current_scroll_chain_);
|
| + if (current_scroll_chain_.empty()) {
|
| + return WebInputEventResult::kNotHandled;
|
| + }
|
| + CustomizedScroll(*scroll_state);
|
|
|
| if (gesture_event.source_device == kWebGestureDeviceTouchscreen)
|
| UseCounter::Count(frame_->GetDocument(), UseCounter::kScrollByTouch);
|
| @@ -394,7 +435,11 @@ WebInputEventResult ScrollManager::HandleGestureScrollUpdate(
|
| scroll_state->SetCurrentNativeScrollingElement(
|
| previous_gesture_scrolled_element_);
|
| }
|
| - CustomizedScroll(*node, *scroll_state);
|
| +
|
| + if (current_scroll_chain_.empty())
|
| + return WebInputEventResult::kNotHandled;
|
| +
|
| + CustomizedScroll(*scroll_state);
|
| previous_gesture_scrolled_element_ =
|
| scroll_state->CurrentNativeScrollingElement();
|
| delta_consumed_for_scroll_sequence_ =
|
| @@ -435,7 +480,8 @@ WebInputEventResult ScrollManager::HandleGestureScrollEnd(
|
| delta_consumed_for_scroll_sequence_;
|
| ScrollState* scroll_state =
|
| ScrollState::Create(std::move(scroll_state_data));
|
| - CustomizedScroll(*node, *scroll_state);
|
| + if (!current_scroll_chain_.empty())
|
| + CustomizedScroll(*scroll_state);
|
| }
|
|
|
| ClearGestureScrollState();
|
|
|