void RootFrameViewport::setScrollOffset(const ScrollOffset& offset, ScrollType scrollType, ScrollBehavior scrollBehavior) { updateScrollAnimator(); if (scrollBehavior == ScrollBehaviorAuto) scrollBehavior = scrollBehaviorStyle(); if (scrollType == ProgrammaticScroll && !layoutViewport().isProgrammaticallyScrollable()) return; if (scrollType == AnchoringScroll) { distributeScrollBetweenViewports(offset, scrollType, scrollBehavior, LayoutViewport); return; } if (scrollBehavior == ScrollBehaviorSmooth) { distributeScrollBetweenViewports(offset, scrollType, scrollBehavior, VisualViewport); return; } ScrollOffset clampedOffset = clampScrollOffset(offset); ScrollableArea::setScrollOffset(clampedOffset, scrollType, scrollBehavior); }
void RootFrameViewport::setScrollPosition(const DoublePoint& position, ScrollType scrollType, ScrollBehavior scrollBehavior) { updateScrollAnimator(); // TODO(bokan): Support smooth scrolling the visual viewport. if (scrollBehavior == ScrollBehaviorAuto) scrollBehavior = scrollBehaviorStyle(); if (scrollBehavior == ScrollBehaviorSmooth) { layoutViewport().setScrollPosition(position, scrollType, scrollBehavior); return; } if (scrollType == ProgrammaticScroll && !layoutViewport().isProgrammaticallyScrollable()) return; DoublePoint clampedPosition = clampScrollPosition(position); ScrollableArea::setScrollPosition(clampedPosition, scrollType, scrollBehavior); }
void RootFrameViewport::setScrollPosition(const DoublePoint& position, ScrollType scrollType, ScrollBehavior scrollBehavior) { updateScrollAnimator(); if (scrollBehavior == ScrollBehaviorAuto) scrollBehavior = scrollBehaviorStyle(); if (scrollType == ProgrammaticScroll && !layoutViewport().isProgrammaticallyScrollable()) return; if (scrollBehavior == ScrollBehaviorSmooth) { distributeScrollBetweenViewports(position, scrollType, scrollBehavior); return; } DoublePoint clampedPosition = clampScrollPosition(position); ScrollableArea::setScrollPosition(clampedPosition, scrollType, scrollBehavior); }
ScrollResult RootFrameViewport::handleWheel(const PlatformWheelEvent& event) { updateScrollAnimator(); ScrollableArea& primary = !m_invertScrollOrder ? layoutViewport() : visualViewport(); ScrollableArea& secondary = !m_invertScrollOrder ? visualViewport() : layoutViewport(); ScrollResult viewScrollResult = primary.handleWheel(event); // The visual viewport will only accept pixel scrolls. if (!event.canScroll() || event.granularity() == ScrollByPageWheelEvent) return viewScrollResult; // TODO(sataya.m) : The delta in PlatformWheelEvent is negative when scrolling the // wheel towards the user, so negate it to get the scroll delta that should be applied // to the page. unusedScrollDelta computed in the ScrollResult is also negative. Say // there is WheelEvent({0, -10} and page scroll by 2px and unusedScrollDelta computed // is {0, -8}. Due to which we have to negate the unusedScrollDelta to obtain the expected // animation.Please address http://crbug.com/504389. DoublePoint oldOffset = secondary.scrollPositionDouble(); DoublePoint locationDelta; if (viewScrollResult.didScroll()) { locationDelta = -DoublePoint(viewScrollResult.unusedScrollDeltaX, viewScrollResult.unusedScrollDeltaY); } else { if (event.railsMode() != PlatformEvent::RailsModeVertical) locationDelta.setX(-event.deltaX()); if (event.railsMode() != PlatformEvent::RailsModeHorizontal) locationDelta.setY(-event.deltaY()); } DoublePoint targetPosition = secondary.clampScrollPosition( secondary.scrollPositionDouble() + toDoubleSize(locationDelta)); secondary.setScrollPosition(targetPosition, UserScroll); DoublePoint usedLocationDelta(secondary.scrollPositionDouble() - oldOffset); bool didScrollX = viewScrollResult.didScrollX || usedLocationDelta.x(); bool didScrollY = viewScrollResult.didScrollY || usedLocationDelta.y(); return ScrollResult(didScrollX, didScrollY, -viewScrollResult.unusedScrollDeltaX - usedLocationDelta.x(), -viewScrollResult.unusedScrollDeltaY - usedLocationDelta.y()); }
ScrollResultOneDimensional RootFrameViewport::userScroll(ScrollDirectionPhysical direction, ScrollGranularity granularity, float delta) { updateScrollAnimator(); ScrollbarOrientation orientation; if (direction == ScrollUp || direction == ScrollDown) orientation = VerticalScrollbar; else orientation = HorizontalScrollbar; if (layoutViewport().userInputScrollable(orientation) && visualViewport().userInputScrollable(orientation)) return ScrollableArea::userScroll(direction, granularity, delta); if (visualViewport().userInputScrollable(orientation)) return visualViewport().userScroll(direction, granularity, delta); if (layoutViewport().userInputScrollable(orientation)) return layoutViewport().userScroll(direction, granularity, delta); return ScrollResultOneDimensional(false, delta); }
ScrollResult RootFrameViewport::userScroll(ScrollGranularity granularity, const FloatSize& delta) { // TODO(bokan/ymalik): Once smooth scrolling is permanently enabled we // should be able to remove this method override and use the base class // version: ScrollableArea::userScroll. updateScrollAnimator(); // Distribute the scroll between the visual and layout viewport. float stepX = scrollStep(granularity, HorizontalScrollbar); float stepY = scrollStep(granularity, VerticalScrollbar); FloatSize pixelDelta(delta); pixelDelta.scale(stepX, stepY); // Precompute the amount of possible scrolling since, when animated, // ScrollAnimator::userScroll will report having consumed the total given // scroll delta, regardless of how much will actually scroll, but we need to // know how much to leave for the layout viewport. FloatSize visualConsumedDelta = visualViewport().scrollAnimator().computeDeltaToConsume(pixelDelta); // Split the remaining delta between scrollable and unscrollable axes of the // layout viewport. We only pass a delta to the scrollable axes and remember // how much was held back so we can add it to the unused delta in the // result. FloatSize layoutDelta = pixelDelta - visualConsumedDelta; FloatSize scrollableAxisDelta( layoutViewport().userInputScrollable(HorizontalScrollbar) ? layoutDelta.width() : 0, layoutViewport().userInputScrollable(VerticalScrollbar) ? layoutDelta.height() : 0); // If there won't be any scrolling, bail early so we don't produce any side // effects like cancelling existing animations. if (visualConsumedDelta.isZero() && scrollableAxisDelta.isZero()) { return ScrollResult(false, false, pixelDelta.width(), pixelDelta.height()); } cancelProgrammaticScrollAnimation(); // TODO(bokan): Why do we call userScroll on the animators directly and // not through the ScrollableAreas? ScrollResult visualResult = visualViewport().scrollAnimator().userScroll( granularity, visualConsumedDelta); if (visualConsumedDelta == pixelDelta) return visualResult; ScrollResult layoutResult = layoutViewport().scrollAnimator().userScroll( granularity, scrollableAxisDelta); // Remember to add any delta not used because of !userInputScrollable to the // unusedScrollDelta in the result. FloatSize unscrollableAxisDelta = layoutDelta - scrollableAxisDelta; return ScrollResult( visualResult.didScrollX || layoutResult.didScrollX, visualResult.didScrollY || layoutResult.didScrollY, layoutResult.unusedScrollDeltaX + unscrollableAxisDelta.width(), layoutResult.unusedScrollDeltaY + unscrollableAxisDelta.height()); }