WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
scrollend-programmatic-for-review
scrollend-programmatic-for-review.diff (text/plain), 30.11 KB, created by
cathiechen
on 2020-03-17 05:27:06 PDT
(
hide
)
Description:
scrollend-programmatic-for-review
Filename:
MIME Type:
Creator:
cathiechen
Created:
2020-03-17 05:27:06 PDT
Size:
30.11 KB
patch
obsolete
>diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 6f70040829..1de831789a 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,52 @@ >+2020-03-17 Cathie Chen <cathiechen@igalia.com> >+ >+ Add support for scrollend event of programmatic scrolling >+ https://bugs.webkit.org/show_bug.cgi?id=209134 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Support scrollend event for programmatic scrolling. Save the scroll position when starting >+ a scroll (instant / animated). Compare the current scroll position with the save one, when >+ RenderLayer/ScrollView actually scrolls. If they are same, put the target to a list in document. >+ The targets in the list would dispatch scrollend events. >+ >+ * dom/Document.cpp: >+ (WebCore::Document::commonTeardown): >+ (WebCore::Document::addPendingScrollendEventTarget): Append the targets to m_pendingScrollendEventTargetList. >+ (WebCore::Document::runScrollSteps): Dispatch scrollend event for each target. >+ * dom/Document.h: Add m_pendingScrollendEventTargetList which keeps the scrollend event targets. >+ * page/FrameView.cpp: >+ (WebCore::FrameView::setScrollPosition): Add saveScrollendPosition to indicate the position should be saved for scrollend event or not. >+ (WebCore::FrameView::scrollToOffsetWithAnimation): checkScrollendEventPosition is the scroll position don't change. >+ (WebCore::FrameView::saveScrollendEventPosition): Save the scroll position, a scrollend event would be fired at this position. >+ (WebCore::FrameView::checkScrollendEventPosition): If position is equal to the saved one, add the target to the scrollend list. >+ (WebCore::FrameView::forceScrollend): Add the target to the list without checking its scroll position. >+ * page/FrameView.h: >+ * platform/ScrollAnimationSmooth.cpp: >+ (WebCore::ScrollAnimationSmooth::stop): If the animation is interrupted, call forceScrollend() to fire scrollend event without checking the position. >+ (WebCore::ScrollAnimationSmooth::animationTimerFired): When the animation ends natural, call checkScrollendEventPosition(). >+ * platform/ScrollView.cpp: >+ (WebCore::ScrollView::scrollTo): checkScrollendEventPosition when scrollPosition changed. >+ (WebCore::ScrollView::setScrollPosition): saveScrollendEventPosition for programmatic scrolling. checkScrollendEventPosition when the position doesn't change. >+ * platform/ScrollView.h: Add saveScrollendPosition flag. >+ * platform/ScrollableArea.h: >+ (WebCore::ScrollableArea::saveScrollendEventPosition): Ditto. >+ (WebCore::ScrollableArea::checkScrollendEventPosition): Ditto. >+ (WebCore::ScrollableArea::forceScrollend): Ditto. >+ * rendering/RenderBox.cpp: >+ (WebCore::RenderBox::setScrollPosition): >+ * rendering/RenderLayer.cpp: >+ (WebCore::RenderLayer::scrollToXPosition): >+ (WebCore::RenderLayer::scrollToYPosition): >+ (WebCore::RenderLayer::setScrollPosition): Replace scrollToPosition with setScrollPosition to consistent with FrameView interfaces. saveScrollendEventPosition for programmatic scrolling. >+ (WebCore::RenderLayer::scrollToOffset): checkScrollendEventPosition when scroll position doesn't change. >+ (WebCore::RenderLayer::scrollToOffsetWithAnimation): Ditto. >+ (WebCore::RenderLayer::scrollTo): checkScrollendEventPosition when the scrollPosition changed. >+ (WebCore::RenderLayer::scrollRectToVisible): AutoscrollStatus is available from eventHandler, so no need to add a function variable for it. >+ (WebCore::RenderLayer::autoscroll): >+ (WebCore::RenderLayer::scrollToPosition): Deleted. Replaced by scrollToPosition. >+ * rendering/RenderLayer.h: >+ > 2020-03-09 Cathie Chen <cathiechen@igalia.com> > > Add support for overscroll events parsing >diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp >index 6879fd159c..5071d9968a 100644 >--- a/Source/WebCore/dom/Document.cpp >+++ b/Source/WebCore/dom/Document.cpp >@@ -800,6 +800,10 @@ void Document::commonTeardown() > > m_pendingScrollEventTargetList = nullptr; > >+#if ENABLE(OVERSCROLL_EVENTS) >+ m_pendingScrollendEventTargetList = nullptr; >+#endif >+ > while (!m_timelines.computesEmpty()) > m_timelines.begin()->detachFromDocument(); > m_timeline = nullptr; >@@ -4067,6 +4071,23 @@ void Document::addPendingScrollEventTarget(ContainerNode& target) > targets.append(target); > } > >+#if ENABLE(OVERSCROLL_EVENTS) >+void Document::addPendingScrollendEventTarget(ContainerNode& target) >+{ >+ if (!m_pendingScrollendEventTargetList) >+ m_pendingScrollendEventTargetList = makeUnique<PendingScrollEventTargetList>(); >+ >+ auto& targets = m_pendingScrollendEventTargetList->targets; >+ if (targets.findMatching([&] (auto& entry) { return entry.ptr() == ⌖ }) != notFound) >+ return; >+ >+ if (targets.isEmpty()) >+ scheduleTimedRenderingUpdate(); >+ >+ targets.append(target); >+} >+#endif >+ > void Document::setNeedsVisualViewportScrollEvent() > { > if (!m_needsVisualViewportScrollEvent) >@@ -4092,6 +4113,18 @@ void Document::runScrollSteps() > if (auto* window = domWindow()) > window->visualViewport().dispatchEvent(Event::create(eventNames().scrollEvent, Event::CanBubble::No, Event::IsCancelable::No)); > } >+ >+#if ENABLE(OVERSCROLL_EVENTS) >+ // Deal with scrollend event. >+ if (m_pendingScrollendEventTargetList && !m_pendingScrollendEventTargetList->targets.isEmpty()) { >+ LOG_WITH_STREAM(Events, stream << "Document" << this << "sending scrollend events to pending scroll event targets"); >+ auto currentScrollendTargets = WTFMove(m_pendingScrollendEventTargetList->targets); >+ for (auto& target : currentScrollendTargets) { >+ auto bubbles = target->isDocumentNode() ? Event::CanBubble::Yes : Event::CanBubble::No; >+ target->dispatchEvent(Event::create(eventNames().scrollendEvent, bubbles, Event::IsCancelable::No)); >+ } >+ } >+#endif > } > > void Document::addAudioProducer(MediaProducer& audioProducer) >diff --git a/Source/WebCore/dom/Document.h b/Source/WebCore/dom/Document.h >index 559a9838b6..9242d54162 100644 >--- a/Source/WebCore/dom/Document.h >+++ b/Source/WebCore/dom/Document.h >@@ -1360,6 +1360,9 @@ public: > void runResizeSteps(); > > void addPendingScrollEventTarget(ContainerNode&); >+#if ENABLE(OVERSCROLL_EVENTS) >+ void addPendingScrollendEventTarget(ContainerNode&); >+#endif > void setNeedsVisualViewportScrollEvent(); > void runScrollSteps(); > >@@ -2039,6 +2042,9 @@ private: > > struct PendingScrollEventTargetList; > std::unique_ptr<PendingScrollEventTargetList> m_pendingScrollEventTargetList; >+#if ENABLE(OVERSCROLL_EVENTS) >+ std::unique_ptr<PendingScrollEventTargetList> m_pendingScrollendEventTargetList; >+#endif > > #if ENABLE(MEDIA_STREAM) > HashSet<HTMLMediaElement*> m_mediaStreamStateChangeElements; >diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp >index 5c0dab84e0..d74a1a1fe1 100644 >--- a/Source/WebCore/page/FrameView.cpp >+++ b/Source/WebCore/page/FrameView.cpp >@@ -2283,7 +2283,7 @@ void FrameView::scrollElementToRect(const Element& element, const IntRect& rect) > setScrollPosition(IntPoint(bounds.x() - centeringOffsetX - rect.x(), bounds.y() - centeringOffsetY - rect.y())); > } > >-void FrameView::setScrollPosition(const ScrollPosition& scrollPosition, ScrollClamping clamping, bool animated) >+void FrameView::setScrollPosition(const ScrollPosition& scrollPosition, ScrollClamping clamping, bool animated, bool saveScrollendPosition) > { > LOG_WITH_STREAM(Scrolling, stream << "FrameView::setScrollPosition " << scrollPosition << " , clearing anchor"); > >@@ -2299,7 +2299,7 @@ void FrameView::setScrollPosition(const ScrollPosition& scrollPosition, ScrollCl > if (animated) > scrollToOffsetWithAnimation(scrollOffsetFromPosition(scrollPosition), currentScrollType(), clamping); > else >- ScrollView::setScrollPosition(scrollPosition, clamping); >+ ScrollView::setScrollPosition(scrollPosition, clamping, animated, saveScrollendPosition); > > setCurrentScrollType(oldScrollType); > } >@@ -3622,12 +3622,48 @@ void FrameView::scrollToOffsetWithAnimation(const ScrollOffset& offset, ScrollTy > > if (currentScrollBehaviorStatus() == ScrollBehaviorStatus::InNonNativeAnimation) > scrollAnimator().cancelAnimations(); >+ >+#if ENABLE(OVERSCROLL_EVENTS) >+ if (offset == this->scrollOffset()) >+ checkScrollendEventPosition(scrollPositionFromOffset(offset)); >+#endif >+ > if (offset != this->scrollOffset()) > ScrollableArea::scrollToOffsetWithAnimation(offset); > > setCurrentScrollType(previousScrollType); > } > >+#if ENABLE(OVERSCROLL_EVENTS) >+void FrameView::saveScrollendEventPosition(const ScrollPosition& position) >+{ >+ if (!frame().settings().overscrollEventsEnabled()) >+ return; >+ >+ m_fireScrollendEventAtPosition = position; >+} >+ >+void FrameView::checkScrollendEventPosition(const ScrollPosition& position) >+{ >+ if (!m_fireScrollendEventAtPosition || m_fireScrollendEventAtPosition.value() != position) >+ return; >+ >+ if (Document* document = frame().document()) >+ document->addPendingScrollendEventTarget(*document); >+ >+ m_fireScrollendEventAtPosition = WTF::nullopt; >+} >+ >+void FrameView::forceScrollend() >+{ >+ if (!frame().settings().overscrollEventsEnabled()) >+ return; >+ >+ if (Document* document = frame().document()) >+ document->addPendingScrollendEventTarget(*document); >+} >+#endif >+ > float FrameView::adjustScrollStepForFixedContent(float step, ScrollbarOrientation orientation, ScrollGranularity granularity) > { > if (granularity != ScrollByPage || orientation == HorizontalScrollbar) >diff --git a/Source/WebCore/page/FrameView.h b/Source/WebCore/page/FrameView.h >index da61a1818e..2f9f773776 100644 >--- a/Source/WebCore/page/FrameView.h >+++ b/Source/WebCore/page/FrameView.h >@@ -227,7 +227,7 @@ public: > #if USE(COORDINATED_GRAPHICS) > WEBCORE_EXPORT void setFixedVisibleContentRect(const IntRect&) final; > #endif >- WEBCORE_EXPORT void setScrollPosition(const ScrollPosition&, ScrollClamping = ScrollClamping::Clamped, bool animated = false) final; >+ WEBCORE_EXPORT void setScrollPosition(const ScrollPosition&, ScrollClamping = ScrollClamping::Clamped, bool animated = false, bool saveScrollendPosition = true) final; > void restoreScrollbar(); > void scheduleScrollToFocusedElement(SelectionRevealMode); > void scrollToFocusedElementImmediatelyIfNeeded(); >@@ -660,6 +660,12 @@ public: > > bool inUpdateEmbeddedObjects() const { return m_inUpdateEmbeddedObjects; } > >+#if ENABLE(OVERSCROLL_EVENTS) >+ void saveScrollendEventPosition(const ScrollPosition&) final; >+ void checkScrollendEventPosition(const ScrollPosition&) final; >+ void forceScrollend() final; >+#endif >+ > protected: > bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) final; > void scrollContentsSlowPath(const IntRect& updateRect) final; >@@ -895,6 +901,10 @@ private: > > Pagination m_pagination; > >+#if ENABLE(OVERSCROLL_EVENTS) >+ Optional<ScrollPosition> m_fireScrollendEventAtPosition; >+#endif >+ > enum class ViewportRendererType : uint8_t { None, Document, Body }; > ViewportRendererType m_viewportRendererType { ViewportRendererType::None }; > ScrollPinningBehavior m_scrollPinningBehavior { DoNotPin }; >diff --git a/Source/WebCore/platform/ScrollAnimationSmooth.cpp b/Source/WebCore/platform/ScrollAnimationSmooth.cpp >index 2ca578a30f..925d4c0eb1 100644 >--- a/Source/WebCore/platform/ScrollAnimationSmooth.cpp >+++ b/Source/WebCore/platform/ScrollAnimationSmooth.cpp >@@ -80,6 +80,11 @@ void ScrollAnimationSmooth::scroll(const FloatPoint& position) > > void ScrollAnimationSmooth::stop() > { >+#if ENABLE(OVERSCROLL_EVENTS) >+ if (m_animationTimer.isActive()) >+ m_scrollableArea.forceScrollend(); >+#endif >+ > m_animationTimer.stop(); > m_scrollableArea.setScrollBehaviorStatus(ScrollBehaviorStatus::NotInAnimation); > } >@@ -410,8 +415,12 @@ void ScrollAnimationSmooth::animationTimerFired() > > if (continueAnimation) > startNextTimer(std::max(minimumTimerInterval, deltaToNextFrame)); >- else >+ else { > m_scrollableArea.setScrollBehaviorStatus(ScrollBehaviorStatus::NotInAnimation); >+#if ENABLE(OVERSCROLL_EVENTS) >+ m_scrollableArea.checkScrollendEventPosition(m_scrollableArea.scrollPosition()); >+#endif >+ } > > m_notifyPositionChangedFunction(FloatPoint(m_horizontalData.currentPosition, m_verticalData.currentPosition)); > } >diff --git a/Source/WebCore/platform/ScrollView.cpp b/Source/WebCore/platform/ScrollView.cpp >index 2fd15f7b30..e018e292e2 100644 >--- a/Source/WebCore/platform/ScrollView.cpp >+++ b/Source/WebCore/platform/ScrollView.cpp >@@ -486,6 +486,10 @@ void ScrollView::scrollTo(const ScrollPosition& newPosition) > > m_scrollPosition = newPosition; > >+#if ENABLE(OVERSCROLL_EVENTS) >+ checkScrollendEventPosition(m_scrollPosition); >+#endif >+ > if (scrollbarsSuppressed()) > return; > >@@ -513,7 +517,7 @@ void ScrollView::completeUpdatesAfterScrollTo(const IntSize& scrollDelta) > updateCompositingLayersAfterScrolling(); > } > >-void ScrollView::setScrollPosition(const ScrollPosition& scrollPosition, ScrollClamping clamping, bool/* animated*/) >+void ScrollView::setScrollPosition(const ScrollPosition& scrollPosition, ScrollClamping clamping, bool/* animated*/, bool saveScrollendPosition) > { > LOG_WITH_STREAM(Scrolling, stream << "ScrollView::setScrollPosition " << scrollPosition); > >@@ -525,13 +529,23 @@ void ScrollView::setScrollPosition(const ScrollPosition& scrollPosition, ScrollC > return; > } > >+ if (currentScrollBehaviorStatus() == ScrollBehaviorStatus::InNonNativeAnimation) >+ scrollAnimator().cancelAnimations(); >+ > ScrollPosition newScrollPosition = (!delegatesScrolling() && clamping == ScrollClamping::Clamped) ? adjustScrollPositionWithinRange(scrollPosition) : scrollPosition; >+#if ENABLE(OVERSCROLL_EVENTS) >+ if (saveScrollendPosition) >+ saveScrollendEventPosition(newScrollPosition); >+#else >+ UNUSED_PARAM(saveScrollendPosition); >+#endif > >- if ((!delegatesScrolling() || currentScrollType() == ScrollType::User) && currentScrollBehaviorStatus() == ScrollBehaviorStatus::NotInAnimation && newScrollPosition == this->scrollPosition()) >+ if ((!delegatesScrolling() || currentScrollType() == ScrollType::User) && currentScrollBehaviorStatus() == ScrollBehaviorStatus::NotInAnimation && newScrollPosition == this->scrollPosition()) { >+#if ENABLE(OVERSCROLL_EVENTS) >+ checkScrollendEventPosition(newScrollPosition); >+#endif > return; >- >- if (currentScrollBehaviorStatus() == ScrollBehaviorStatus::InNonNativeAnimation) >- scrollAnimator().cancelAnimations(); >+ } > > if (!requestScrollPositionUpdate(newScrollPosition, currentScrollType(), clamping)) > updateScrollbars(newScrollPosition); >diff --git a/Source/WebCore/platform/ScrollView.h b/Source/WebCore/platform/ScrollView.h >index 4cc2bb4c0b..deacbb1d3f 100644 >--- a/Source/WebCore/platform/ScrollView.h >+++ b/Source/WebCore/platform/ScrollView.h >@@ -261,7 +261,7 @@ public: > ScrollPosition cachedScrollPosition() const { return m_cachedScrollPosition; } > > // Functions for scrolling the view. >- virtual void setScrollPosition(const ScrollPosition&, ScrollClamping = ScrollClamping::Clamped, bool animated = false); >+ virtual void setScrollPosition(const ScrollPosition&, ScrollClamping = ScrollClamping::Clamped, bool animated = false, bool saveScrollendPosition = true); > > void scrollBy(const IntSize& s) { return setScrollPosition(scrollPosition() + s); } > >diff --git a/Source/WebCore/platform/ScrollableArea.h b/Source/WebCore/platform/ScrollableArea.h >index fdddf2f9be..fab8cbb33f 100644 >--- a/Source/WebCore/platform/ScrollableArea.h >+++ b/Source/WebCore/platform/ScrollableArea.h >@@ -343,6 +343,12 @@ public: > > virtual bool shouldPlaceBlockDirectionScrollbarOnLeft() const = 0; > >+#if ENABLE(OVERSCROLL_EVENTS) >+ virtual void saveScrollendEventPosition(const ScrollPosition&) { } >+ virtual void checkScrollendEventPosition(const ScrollPosition&) { } >+ virtual void forceScrollend() { } >+#endif >+ > protected: > WEBCORE_EXPORT ScrollableArea(); > WEBCORE_EXPORT virtual ~ScrollableArea(); >diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp >index 49c1fff03b..06c0cc6e52 100644 >--- a/Source/WebCore/rendering/RenderBox.cpp >+++ b/Source/WebCore/rendering/RenderBox.cpp >@@ -602,7 +602,7 @@ void RenderBox::setScrollPosition(const ScrollPosition& position, ScrollType scr > if (!hasOverflowClip() || !layer()) > return; > setupWheelEventMonitor(*layer()); >- layer()->scrollToPosition(position, scrollType, clamping, animated); >+ layer()->setScrollPosition(position, scrollType, clamping, animated); > } > > void RenderBox::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const >diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp >index fbf3609c00..4e72962fb9 100644 >--- a/Source/WebCore/rendering/RenderLayer.cpp >+++ b/Source/WebCore/rendering/RenderLayer.cpp >@@ -2603,21 +2603,30 @@ void RenderLayer::applyPostLayoutScrollPositionIfNeeded() > void RenderLayer::scrollToXPosition(int x, ScrollType scrollType, ScrollClamping clamping, bool animated) > { > ScrollPosition position(x, m_scrollPosition.y()); >- scrollToPosition(position, scrollType, clamping, animated); >+ setScrollPosition(position, scrollType, clamping, animated); > } > > void RenderLayer::scrollToYPosition(int y, ScrollType scrollType, ScrollClamping clamping, bool animated) > { > ScrollPosition position(m_scrollPosition.x(), y); >- scrollToPosition(position, scrollType, clamping, animated); >+ setScrollPosition(position, scrollType, clamping, animated); > } > >-void RenderLayer::scrollToPosition(const ScrollPosition& position, ScrollType scrollType, ScrollClamping clamping, bool animated) >+void RenderLayer::setScrollPosition(const ScrollPosition& position, ScrollType scrollType, ScrollClamping clamping, bool animated, bool saveScrollendPosition) > { >+ auto offset = scrollOffsetFromPosition(position); >+ ScrollOffset newScrollOffset = clamping == ScrollClamping::Clamped ? clampScrollOffset(offset) : offset; >+#if ENABLE(OVERSCROLL_EVENTS) >+ if (saveScrollendPosition) >+ saveScrollendEventPosition(scrollPositionFromOffset(newScrollOffset)); >+#else >+ UNUSED_PARAM(saveScrollendPosition); >+#endif >+ > if (animated) >- scrollToOffsetWithAnimation(scrollOffsetFromPosition(position), scrollType, clamping); >+ scrollToOffsetWithAnimation(newScrollOffset, scrollType, clamping); > else >- scrollToOffset(scrollOffsetFromPosition(position), scrollType, clamping); >+ scrollToOffset(newScrollOffset, scrollType, clamping); > } > > ScrollOffset RenderLayer::clampScrollOffset(const ScrollOffset& scrollOffset) const >@@ -2640,13 +2649,18 @@ void RenderLayer::scrollToOffset(const ScrollOffset& scrollOffset, ScrollType sc > scrollAnimator().cancelAnimations(); > > ScrollOffset clampedScrollOffset = clamping == ScrollClamping::Clamped ? clampScrollOffset(scrollOffset) : scrollOffset; >- if (clampedScrollOffset == this->scrollOffset()) >+ ScrollPosition clampedScrollPosition = scrollPositionFromOffset(clampedScrollOffset); >+ if (clampedScrollOffset == this->scrollOffset()) { >+#if ENABLE(OVERSCROLL_EVENTS) >+ checkScrollendEventPosition(clampedScrollPosition); >+#endif > return; >+ } > > auto previousScrollType = currentScrollType(); > setCurrentScrollType(scrollType); > >- if (!requestScrollPositionUpdate(scrollPositionFromOffset(clampedScrollOffset), scrollType, clamping)) >+ if (!requestScrollPositionUpdate(clampedScrollPosition, scrollType, clamping)) > scrollToOffsetWithoutAnimation(clampedScrollOffset, clamping); > setScrollBehaviorStatus(ScrollBehaviorStatus::NotInAnimation); > >@@ -2661,6 +2675,12 @@ void RenderLayer::scrollToOffsetWithAnimation(const ScrollOffset& offset, Scroll > ScrollOffset newScrollOffset = clamping == ScrollClamping::Clamped ? clampScrollOffset(offset) : offset; > if (currentScrollBehaviorStatus() == ScrollBehaviorStatus::InNonNativeAnimation) > scrollAnimator().cancelAnimations(); >+ >+#if ENABLE(OVERSCROLL_EVENTS) >+ if (newScrollOffset == this->scrollOffset()) >+ checkScrollendEventPosition(newScrollOffset); >+#endif >+ > if (newScrollOffset != this->scrollOffset()) > ScrollableArea::scrollToOffsetWithAnimation(newScrollOffset); > >@@ -2770,6 +2790,10 @@ void RenderLayer::scrollTo(const ScrollPosition& position) > if (Element* element = renderer().element()) > element->document().addPendingScrollEventTarget(*element); > >+#if ENABLE(OVERSCROLL_EVENTS) >+ checkScrollendEventPosition(m_scrollPosition); >+#endif >+ > if (scrollsOverflow()) > view.frameView().didChangeScrollOffset(); > >@@ -2815,12 +2839,13 @@ bool RenderLayer::allowsCurrentScroll() const > return box->hasHorizontalOverflow() || box->hasVerticalOverflow(); > } > >-void RenderLayer::scrollRectToVisible(const LayoutRect& absoluteRect, bool insideFixed, const ScrollRectToVisibleOptions& options, AutoscrollStatus autoscrollStatus) >+void RenderLayer::scrollRectToVisible(const LayoutRect& absoluteRect, bool insideFixed, const ScrollRectToVisibleOptions& options) > { > LOG_WITH_STREAM(Scrolling, stream << "Layer " << this << " scrollRectToVisible " << absoluteRect); > > RenderLayer* parentLayer = nullptr; > LayoutRect newRect = absoluteRect; >+ bool autoscrollNotInProgress = !renderer().frame().eventHandler().autoscrollInProgress(); > > // We may end up propagating a scroll event. It is important that we suspend events until > // the end of the function since they could delete the layer or the layer's renderer(). >@@ -2846,8 +2871,8 @@ void RenderLayer::scrollRectToVisible(const LayoutRect& absoluteRect, bool insid > ScrollOffset clampedScrollOffset = clampScrollOffset(scrollOffset() + toIntSize(roundedIntRect(revealRect).location())); > if (clampedScrollOffset != scrollOffset() || currentScrollBehaviorStatus() != ScrollBehaviorStatus::NotInAnimation) { > ScrollOffset oldScrollOffset = scrollOffset(); >- bool animated = autoscrollStatus == AutoscrollStatus::NotInProgress && useSmoothScrolling(options.behavior, box->element()); >- scrollToPosition(scrollPositionFromOffset(clampedScrollOffset), ScrollType::Programmatic, ScrollClamping::Clamped, animated); >+ bool animated = autoscrollNotInProgress && useSmoothScrolling(options.behavior, box->element()); >+ setScrollPosition(scrollPositionFromOffset(clampedScrollOffset), ScrollType::Programmatic, ScrollClamping::Clamped, animated, autoscrollNotInProgress); > IntSize scrollOffsetDifference = clampedScrollOffset - oldScrollOffset; > localExposeRect.move(-scrollOffsetDifference); > newRect = LayoutRect(box->localToAbsoluteQuad(FloatQuad(FloatRect(localExposeRect)), UseTransforms).boundingBox()); >@@ -2873,8 +2898,8 @@ void RenderLayer::scrollRectToVisible(const LayoutRect& absoluteRect, bool insid > scrollPosition = scrollPosition.constrainedBetween(IntPoint(), IntPoint(frameView.contentsSize())); > // FIXME: Should we use contentDocument()->scrollingElement()? > // See https://bugs.webkit.org/show_bug.cgi?id=205059 >- bool animated = autoscrollStatus == AutoscrollStatus::NotInProgress && ownerElement->contentDocument() && useSmoothScrolling(options.behavior, ownerElement->contentDocument()->documentElement()); >- frameView.setScrollPosition(scrollPosition, ScrollClamping::Clamped, animated); >+ bool animated = autoscrollNotInProgress && ownerElement->contentDocument() && useSmoothScrolling(options.behavior, ownerElement->contentDocument()->documentElement()); >+ frameView.setScrollPosition(scrollPosition, ScrollClamping::Clamped, animated, autoscrollNotInProgress); > > if (options.shouldAllowCrossOriginScrolling == ShouldAllowCrossOriginScrolling::Yes || frameView.safeToPropagateScrollToParent()) { > parentLayer = ownerElement->renderer()->enclosingLayer(); >@@ -2915,8 +2940,8 @@ void RenderLayer::scrollRectToVisible(const LayoutRect& absoluteRect, bool insid > ScrollOffset clampedScrollPosition = roundedIntPoint(revealRect.location()).constrainedBetween(minScrollPosition, maxScrollPosition); > // FIXME: Should we use document()->scrollingElement()? > // See https://bugs.webkit.org/show_bug.cgi?id=205059 >- bool animated = autoscrollStatus == AutoscrollStatus::NotInProgress && useSmoothScrolling(options.behavior, renderer().document().documentElement()); >- frameView.setScrollPosition(clampedScrollPosition, ScrollClamping::Clamped, animated); >+ bool animated = autoscrollNotInProgress && useSmoothScrolling(options.behavior, renderer().document().documentElement()); >+ frameView.setScrollPosition(clampedScrollPosition, ScrollClamping::Clamped, animated, autoscrollNotInProgress); > } > > // This is the outermost view of a web page, so after scrolling this view we >@@ -3055,7 +3080,7 @@ LayoutRect RenderLayer::getRectToExpose(const LayoutRect& visibleRect, const Lay > void RenderLayer::autoscroll(const IntPoint& positionInWindow) > { > IntPoint currentDocumentPosition = renderer().view().frameView().windowToContents(positionInWindow); >- scrollRectToVisible(LayoutRect(currentDocumentPosition, LayoutSize(1, 1)), false, { SelectionRevealMode::Reveal, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded, ShouldAllowCrossOriginScrolling::Yes }, AutoscrollStatus::InProgress); >+ scrollRectToVisible(LayoutRect(currentDocumentPosition, LayoutSize(1, 1)), false, { SelectionRevealMode::Reveal, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded, ShouldAllowCrossOriginScrolling::Yes }); > } > > bool RenderLayer::canResize() const >@@ -7010,6 +7035,36 @@ void RenderLayer::invalidateEventRegion() > #endif > } > >+#if ENABLE(OVERSCROLL_EVENTS) >+void RenderLayer::saveScrollendEventPosition(const ScrollPosition& position) >+{ >+ if (!renderer().settings().overscrollEventsEnabled()) >+ return; >+ >+ m_fireScrollendEventAtPosition = position; >+} >+ >+void RenderLayer::checkScrollendEventPosition(const ScrollPosition& position) >+{ >+ if (!m_fireScrollendEventAtPosition || m_fireScrollendEventAtPosition.value() != position) >+ return; >+ >+ if (Element* element = renderer().element()) >+ element->document().addPendingScrollendEventTarget(*element); >+ >+ m_fireScrollendEventAtPosition = WTF::nullopt; >+} >+ >+void RenderLayer::forceScrollend() >+{ >+ if (!renderer().settings().overscrollEventsEnabled()) >+ return; >+ >+ if (Element* element = renderer().element()) >+ element->document().addPendingScrollendEventTarget(*element); >+} >+#endif >+ > TextStream& operator<<(WTF::TextStream& ts, ClipRectsType clipRectsType) > { > switch (clipRectsType) { >diff --git a/Source/WebCore/rendering/RenderLayer.h b/Source/WebCore/rendering/RenderLayer.h >index 96d39ef4bf..7cde86ed03 100644 >--- a/Source/WebCore/rendering/RenderLayer.h >+++ b/Source/WebCore/rendering/RenderLayer.h >@@ -451,7 +451,7 @@ public: > > void scrollToXPosition(int x, ScrollType, ScrollClamping = ScrollClamping::Clamped, bool animated = false); > void scrollToYPosition(int y, ScrollType, ScrollClamping = ScrollClamping::Clamped, bool animated = false); >- void scrollToPosition(const ScrollPosition&, ScrollType, ScrollClamping = ScrollClamping::Clamped, bool animated = false); >+ void setScrollPosition(const ScrollPosition&, ScrollType, ScrollClamping = ScrollClamping::Clamped, bool animated = false, bool saveScrollendPosition = true); > > // These are only used by marquee. > void scrollToXOffset(int x) { scrollToOffset(ScrollOffset(x, scrollOffset().y()), ScrollType::Programmatic, ScrollClamping::Unclamped); } >@@ -462,9 +462,8 @@ public: > > void availableContentSizeChanged(AvailableSizeChangeReason) override; > >- enum AutoscrollStatus { NotInProgress, InProgress }; > // "absoluteRect" is in scaled document coordinates. >- void scrollRectToVisible(const LayoutRect& absoluteRect, bool insideFixed, const ScrollRectToVisibleOptions&, AutoscrollStatus = AutoscrollStatus::NotInProgress); >+ void scrollRectToVisible(const LayoutRect& absoluteRect, bool insideFixed, const ScrollRectToVisibleOptions&); > > bool scrollsOverflow() const; > bool hasScrollableHorizontalOverflow() const; >@@ -923,6 +922,12 @@ public: > > void invalidateEventRegion(); > >+#if ENABLE(OVERSCROLL_EVENTS) >+ void saveScrollendEventPosition(const ScrollPosition&) final; >+ void checkScrollendEventPosition(const ScrollPosition&) final; >+ void forceScrollend() final; >+#endif >+ > private: > > void setNextSibling(RenderLayer* next) { m_next = next; } >@@ -1353,6 +1358,10 @@ private: > > std::unique_ptr<RenderLayerFilters> m_filters; > std::unique_ptr<RenderLayerBacking> m_backing; >+ >+#if ENABLE(OVERSCROLL_EVENTS) >+ Optional<ScrollPosition> m_fireScrollendEventAtPosition; >+#endif > > PaintFrequencyTracker m_paintFrequencyTracker; > }; >diff --git a/Source/cmake/WebKitFeatures.cmake b/Source/cmake/WebKitFeatures.cmake >index 7e54ac8fa1..f07e402fe5 100644 >--- a/Source/cmake/WebKitFeatures.cmake >+++ b/Source/cmake/WebKitFeatures.cmake >@@ -181,7 +181,7 @@ macro(WEBKIT_OPTION_BEGIN) > WEBKIT_OPTION_DEFINE(ENABLE_OFFSCREEN_CANVAS "Toggle OffscreenCanvas support" PRIVATE OFF) > WEBKIT_OPTION_DEFINE(ENABLE_ORIENTATION_EVENTS "Toggle Orientation Events support" PRIVATE OFF) > WEBKIT_OPTION_DEFINE(ENABLE_OVERFLOW_SCROLLING_TOUCH "Toggle accelerated scrolling support" PRIVATE OFF) >- WEBKIT_OPTION_DEFINE(ENABLE_OVERSCROLL_EVENTS "Toggle overscroll events" PRIVATE OFF) >+ WEBKIT_OPTION_DEFINE(ENABLE_OVERSCROLL_EVENTS "Toggle overscroll events" PRIVATE ON) > WEBKIT_OPTION_DEFINE(ENABLE_PAYMENT_REQUEST "Toggle Payment Request support" PRIVATE OFF) > WEBKIT_OPTION_DEFINE(ENABLE_PDFKIT_PLUGIN "Toggle PDFKit plugin support" PRIVATE OFF) > WEBKIT_OPTION_DEFINE(ENABLE_PICTURE_IN_PICTURE_API "Toggle Picture-in-Picture API support" PRIVATE OFF)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 209134
:
393744
|
393745
|
393746
|
393747
|
395799
|
395800
|
395801
|
395802
|
395805
|
395806
|
395939
|
395940
|
395943
|
395944
|
396058
|
396059
|
396062
|
399465
|
399466