Source/WebCore/ChangeLog

 12014-08-14 Wenson Hsieh <wenson_hsieh@apple.com>
 2
 3 Implement snapping behavior for iOS
 4 https://bugs.webkit.org/show_bug.cgi?id=135769
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Added support for snap points on iOS. This entails sending snap points from the web process to the UI process
 9 by encoding and decoding snap points and updating ScrollingTreeOverflowScrollingNodeIOS and WKWebView to support
 10 animation to snap points in the cases of mainframe and overflow scrolling, respectively.
 11
 12 There are no new tests yet -- we'll need to find a way to test this!
 13
 14 * WebCore.exp.in:
 15 * page/scrolling/AsyncScrollingCoordinator.cpp:
 16 (WebCore::setStateScrollingNodeSnapOffsetsAsFloat): Helper functions used to convert LayoutUnits to floats for snap offsets.
 17 (WebCore::AsyncScrollingCoordinator::frameViewLayoutUpdated): Update snap offsets for mainframe scrolling, as well as the state node.
 18 (WebCore::AsyncScrollingCoordinator::updateOverflowScrollingNode): Added snap offsets.
 19 * page/scrolling/AxisScrollSnapOffsets.h:
 20 (WebCore::closestSnapOffset): Computes the closest snap offset given a sorted vector of comparable types (e.g. float, LayoutUnit).
 21 * page/scrolling/ScrollingCoordinator.h:
 22 * page/scrolling/ScrollingStateScrollingNode.cpp:
 23 (WebCore::ScrollingStateScrollingNode::ScrollingStateScrollingNode):
 24 (WebCore::ScrollingStateScrollingNode::setHorizontalSnapOffsets):
 25 (WebCore::ScrollingStateScrollingNode::setVerticalSnapOffsets):
 26 * page/scrolling/ScrollingStateScrollingNode.h:
 27 (WebCore::ScrollingStateScrollingNode::horizontalSnapOffsets):
 28 (WebCore::ScrollingStateScrollingNode::verticalSnapOffsets):
 29 * page/scrolling/ScrollingTreeScrollingNode.cpp:
 30 (WebCore::ScrollingTreeScrollingNode::updateBeforeChildren):
 31 * page/scrolling/ScrollingTreeScrollingNode.h:
 32 (WebCore::ScrollingTreeScrollingNode::horizontalSnapOffsets):
 33 (WebCore::ScrollingTreeScrollingNode::verticalSnapOffsets):
 34 * rendering/RenderLayer.cpp:
 35 (WebCore::RenderLayer::updateScrollInfoAfterLayout): Update snap offsets for overflow scrolling.
 36 * rendering/RenderLayerCompositor.cpp:
 37 (WebCore::RenderLayerCompositor::updateScrollCoordinatedLayer): Updates the state node's snap offsets for overflow scrolling.
 38
1392014-08-14 Brent Fulgham <bfulgham@apple.com>
240
341 [Win] Correct build when DerivedSources location not supplied by build environment

Source/WebKit2/ChangeLog

 12014-08-14 Wenson Hsieh <wenson_hsieh@apple.com>
 2
 3 Implement snapping behavior for iOS
 4 https://bugs.webkit.org/show_bug.cgi?id=135769
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 * Shared/Scrolling/RemoteScrollingCoordinatorTransaction.cpp:
 9 (ArgumentCoder<ScrollingStateScrollingNode>::encode): Added snap offset encoding.
 10 (ArgumentCoder<ScrollingStateScrollingNode>::decode): Added snap offset decoding.
 11 * UIProcess/API/Cocoa/WKWebView.mm:
 12 (-[WKWebView scrollViewWillEndDragging:withVelocity:targetContentOffset:]): For mainframe scrolling, retargets the scroll destination to the appropriate snap point.
 13 * UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h: Added methods to extract relevant information for WKWebView from snap offsets in mainframe scrolling.
 14 * UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.mm:
 15 (-[WKOverflowScrollViewDelegate scrollViewWillEndDragging:withVelocity:targetContentOffset:]): For overflow scrolling, retargets the scroll destination to the appropriate snap point.
 16 (WebKit::ScrollingTreeOverflowScrollingNodeIOS::updateAfterChildren): Sets the deceleration factor to FAST if snap points are active.
 17 * UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm:
 18 (WebKit::RemoteScrollingCoordinatorProxy::adjustTargetContentOffsetForSnapping):
 19 (WebKit::RemoteScrollingCoordinatorProxy::shouldSnapForMainFrameScrolling):
 20 (WebKit::RemoteScrollingCoordinatorProxy::closestSnapOffsetForMainFrameScrolling): Invoked by WKWebView to retarget the scroll destination.
 21
1222014-08-14 Enrica Casucci <enrica@apple.com>
223
324 [Services with UI] Selection services don't work inside <iframes>.

Source/WebCore/WebCore.exp.in

@@__ZN7WebCore4toJSEPN3JSC9ExecStateEPNS_17JSDOMGlobalObjectEPNS_12DOMWindowCSSE
30113011__ZN7WebCore16FilterOperationsaSERKS0_
30123012#endif
30133013
 3014#if ENABLE(CSS_SCROLL_SNAP)
 3015__ZN7WebCore27ScrollingStateScrollingNode22setVerticalSnapOffsetsERKN3WTF6VectorIfLm0ENS1_15CrashOnOverflowEEE
 3016__ZN7WebCore27ScrollingStateScrollingNode24setHorizontalSnapOffsetsERKN3WTF6VectorIfLm0ENS1_15CrashOnOverflowEEE
 3017#endif
 3018
30143019#if ENABLE(DASHBOARD_SUPPORT)
30153020__ZNK7WebCore8Document16annotatedRegionsEv
30163021#endif

Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp

@@void AsyncScrollingCoordinator::scrollingStateTreePropertiesChanged()
5959 scheduleTreeStateCommit();
6060}
6161
 62static inline void setStateScrollingNodeSnapOffsetsAsFloat(ScrollEventAxis axis, ScrollingStateScrollingNode* node, const Vector<LayoutUnit>& snapOffsets, float deviceScaleFactor)
 63{
 64 ASSERT(node);
 65 Vector<float> snapOffsetsAsFloat;
 66 snapOffsetsAsFloat.reserveCapacity(snapOffsets.size());
 67 for (size_t i = 0; i < snapOffsets.size(); i++)
 68 snapOffsetsAsFloat.append(roundToDevicePixel(snapOffsets[i], deviceScaleFactor, false));
 69
 70 if (axis == ScrollEventAxis::Horizontal)
 71 node->setHorizontalSnapOffsets(snapOffsetsAsFloat);
 72 else
 73 node->setVerticalSnapOffsets(snapOffsetsAsFloat);
 74}
 75
6276void AsyncScrollingCoordinator::frameViewLayoutUpdated(FrameView* frameView)
6377{
6478 ASSERT(isMainThread());

@@void AsyncScrollingCoordinator::frameViewLayoutUpdated(FrameView* frameView)
97111 node->setTotalContentsSize(frameView->totalContentsSize());
98112 node->setReachableContentsSize(frameView->totalContentsSize());
99113
 114#if ENABLE(CSS_SCROLL_SNAP)
 115 frameView->updateSnapOffsets();
 116 if (frameView->horizontalSnapOffsets())
 117 setStateScrollingNodeSnapOffsetsAsFloat(ScrollEventAxis::Horizontal, node, *frameView->horizontalSnapOffsets(), frameView->frame().document()->deviceScaleFactor());
 118
 119 if (frameView->verticalSnapOffsets())
 120 setStateScrollingNodeSnapOffsetsAsFloat(ScrollEventAxis::Vertical, node, *frameView->verticalSnapOffsets(), frameView->frame().document()->deviceScaleFactor());
 121#endif
 122
100123 ScrollableAreaParameters scrollParameters;
101124 scrollParameters.horizontalScrollElasticity = frameView->horizontalScrollElasticity();
102125 scrollParameters.verticalScrollElasticity = frameView->verticalScrollElasticity();

@@void AsyncScrollingCoordinator::updateOverflowScrollingNode(ScrollingNodeID node
399422 node->setTotalContentsSize(scrollingGeometry->contentSize);
400423 node->setReachableContentsSize(scrollingGeometry->reachableContentSize);
401424 node->setScrollableAreaSize(scrollingGeometry->scrollableAreaSize);
 425#if ENABLE(CSS_SCROLL_SNAP)
 426 setStateScrollingNodeSnapOffsetsAsFloat(ScrollEventAxis::Horizontal, node, scrollingGeometry->horizontalSnapOffsets, scrolledContentsLayer->deviceScaleFactor());
 427 setStateScrollingNodeSnapOffsetsAsFloat(ScrollEventAxis::Vertical, node, scrollingGeometry->verticalSnapOffsets, scrolledContentsLayer->deviceScaleFactor());
 428#endif
402429 }
403430}
404431

Source/WebCore/page/scrolling/AxisScrollSnapOffsets.h

@@class ScrollableArea;
4242
4343void updateSnapOffsetsForScrollableArea(ScrollableArea&, HTMLElement& scrollingElement, const RenderBox& scrollingElementBox, const RenderStyle& scrollingElementStyle);
4444
 45template<typename T>
 46T closestSnapOffset(const Vector<T>& snapOffsets, T scrollDestination, float velocity)
 47{
 48 ASSERT(snapOffsets.size());
 49 if (scrollDestination <= snapOffsets.first())
 50 return snapOffsets.first();
 51
 52 if (scrollDestination >= snapOffsets.last())
 53 return snapOffsets.last();
 54
 55 size_t lowerIndex = 0;
 56 size_t upperIndex = snapOffsets.size() - 1;
 57 while (lowerIndex < upperIndex - 1) {
 58 size_t middleIndex = (lowerIndex + upperIndex) / 2;
 59 if (scrollDestination < snapOffsets[middleIndex])
 60 upperIndex = middleIndex;
 61 else if (scrollDestination > snapOffsets[middleIndex])
 62 lowerIndex = middleIndex;
 63 else {
 64 upperIndex = middleIndex;
 65 lowerIndex = middleIndex;
 66 break;
 67 }
 68 }
 69 T lowerSnapPosition = snapOffsets[lowerIndex];
 70 T upperSnapPosition = snapOffsets[upperIndex];
 71 // Nonzero velocity indicates a flick gesture. Even if another snap point is closer, snap to the one in the direction of the flick gesture.
 72 if (velocity)
 73 return velocity < 0 ? lowerSnapPosition : upperSnapPosition;
 74
 75 bool isCloserToLowerSnapPosition = scrollDestination - lowerSnapPosition <= upperSnapPosition - scrollDestination;
 76 return isCloserToLowerSnapPosition ? lowerSnapPosition : upperSnapPosition;
 77}
 78
4579} // namespace WebCore
4680
4781#endif // CSS_SCROLL_SNAP

Source/WebCore/page/scrolling/ScrollingCoordinator.h

4343#include <wtf/RetainPtr.h>
4444#endif
4545
 46#if ENABLE(CSS_SCROLL_SNAP)
 47#include "AxisScrollSnapOffsets.h"
 48#endif
 49
4650namespace WebCore {
4751
4852typedef unsigned SynchronousScrollingReasons;

@@public:
164168 FloatSize reachableContentSize; // Smaller than contentSize when overflow is hidden on one axis.
165169 FloatPoint scrollPosition;
166170 IntPoint scrollOrigin;
 171#if ENABLE(CSS_SCROLL_SNAP)
 172 Vector<LayoutUnit> horizontalSnapOffsets;
 173 Vector<LayoutUnit> verticalSnapOffsets;
 174#endif
167175 };
168176
169177 virtual void updateFrameScrollingNode(ScrollingNodeID, GraphicsLayer* /*scrollLayer*/, GraphicsLayer* /*scrolledContentsLayer*/, GraphicsLayer* /*counterScrollingLayer*/, GraphicsLayer* /*insetClipLayer*/, const ScrollingGeometry* = nullptr) { }

Source/WebCore/page/scrolling/ScrollingStateScrollingNode.cpp

@@ScrollingStateScrollingNode::ScrollingStateScrollingNode(const ScrollingStateScr
4848 , m_scrollPosition(stateNode.scrollPosition())
4949 , m_requestedScrollPosition(stateNode.requestedScrollPosition())
5050 , m_scrollOrigin(stateNode.scrollOrigin())
 51#if ENABLE(CSS_SCROLL_SNAP)
 52 , m_horizontalSnapOffsets(stateNode.horizontalSnapOffsets())
 53 , m_verticalSnapOffsets(stateNode.verticalSnapOffsets())
 54#endif
5155 , m_scrollableAreaParameters(stateNode.scrollableAreaParameters())
5256 , m_requestedScrollPositionRepresentsProgrammaticScroll(stateNode.requestedScrollPositionRepresentsProgrammaticScroll())
5357{

@@void ScrollingStateScrollingNode::setScrollOrigin(const IntPoint& scrollOrigin)
102106 setPropertyChanged(ScrollOrigin);
103107}
104108
 109#if ENABLE(CSS_SCROLL_SNAP)
 110void ScrollingStateScrollingNode::setHorizontalSnapOffsets(const Vector<float>& snapOffsets)
 111{
 112 if (m_horizontalSnapOffsets == snapOffsets)
 113 return;
 114
 115 m_horizontalSnapOffsets = snapOffsets;
 116 setPropertyChanged(HorizontalSnapOffsets);
 117}
 118
 119void ScrollingStateScrollingNode::setVerticalSnapOffsets(const Vector<float>& snapOffsets)
 120{
 121 if (m_verticalSnapOffsets == snapOffsets)
 122 return;
 123
 124 m_verticalSnapOffsets = snapOffsets;
 125 setPropertyChanged(VerticalSnapOffsets);
 126}
 127#endif
 128
105129void ScrollingStateScrollingNode::setScrollableAreaParameters(const ScrollableAreaParameters& parameters)
106130{
107131 if (m_scrollableAreaParameters == parameters)

Source/WebCore/page/scrolling/ScrollingStateScrollingNode.h

@@public:
4848 ScrollableAreaParams,
4949 RequestedScrollPosition,
5050 NumScrollingStateNodeBits,
 51#if ENABLE(CSS_SCROLL_SNAP)
 52 HorizontalSnapOffsets,
 53 VerticalSnapOffsets,
 54#endif
5155 };
5256
5357 const FloatSize& scrollableAreaSize() const { return m_scrollableAreaSize; }

@@public:
6569 const IntPoint& scrollOrigin() const { return m_scrollOrigin; }
6670 void setScrollOrigin(const IntPoint&);
6771
 72#if ENABLE(CSS_SCROLL_SNAP)
 73 const Vector<float>& horizontalSnapOffsets() const { return m_horizontalSnapOffsets; }
 74 void setHorizontalSnapOffsets(const Vector<float>&);
 75
 76 const Vector<float>& verticalSnapOffsets() const { return m_verticalSnapOffsets; }
 77 void setVerticalSnapOffsets(const Vector<float>&);
 78#endif
 79
6880 const ScrollableAreaParameters& scrollableAreaParameters() const { return m_scrollableAreaParameters; }
6981 void setScrollableAreaParameters(const ScrollableAreaParameters& params);
7082

@@private:
8597 FloatPoint m_scrollPosition;
8698 FloatPoint m_requestedScrollPosition;
8799 IntPoint m_scrollOrigin;
 100#if ENABLE(CSS_SCROLL_SNAP)
 101 Vector<float> m_horizontalSnapOffsets;
 102 Vector<float> m_verticalSnapOffsets;
 103#endif
88104 ScrollableAreaParameters m_scrollableAreaParameters;
89105 bool m_requestedScrollPositionRepresentsProgrammaticScroll;
90106};

Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp

@@void ScrollingTreeScrollingNode::updateBeforeChildren(const ScrollingStateNode&
6767 if (state.hasChangedProperty(ScrollingStateScrollingNode::ScrollOrigin))
6868 m_scrollOrigin = state.scrollOrigin();
6969
 70#if ENABLE(CSS_SCROLL_SNAP)
 71 if (state.hasChangedProperty(ScrollingStateScrollingNode::HorizontalSnapOffsets))
 72 m_horizontalSnapOffsets = state.horizontalSnapOffsets();
 73
 74 if (state.hasChangedProperty(ScrollingStateScrollingNode::VerticalSnapOffsets))
 75 m_verticalSnapOffsets = state.verticalSnapOffsets();
 76#endif
 77
7078 if (state.hasChangedProperty(ScrollingStateScrollingNode::ScrollableAreaParams))
7179 m_scrollableAreaParameters = state.scrollableAreaParameters();
7280}

Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h

@@public:
5757
5858 virtual FloatPoint scrollPosition() const = 0;
5959
 60#if ENABLE(CSS_SCROLL_SNAP)
 61 const Vector<float>& horizontalSnapOffsets() const { return m_horizontalSnapOffsets; }
 62 const Vector<float>& verticalSnapOffsets() const { return m_verticalSnapOffsets; }
 63#endif
 64
6065protected:
6166 ScrollingTreeScrollingNode(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
6267

@@private:
9297 FloatSize m_reachableContentsSize;
9398 FloatPoint m_lastCommittedScrollPosition;
9499 IntPoint m_scrollOrigin;
95 
 100#if ENABLE(CSS_SCROLL_SNAP)
 101 Vector<float> m_horizontalSnapOffsets;
 102 Vector<float> m_verticalSnapOffsets;
 103#endif
96104 ScrollableAreaParameters m_scrollableAreaParameters;
97105};
98106

Source/WebCore/rendering/RenderLayer.cpp

@@void RenderLayer::updateScrollInfoAfterLayout()
33093309 // Composited scrolling may need to be enabled or disabled if the amount of overflow changed.
33103310 if (compositor().updateLayerCompositingState(*this))
33113311 compositor().setCompositingLayersNeedRebuild();
 3312
 3313#if ENABLE(CSS_SCROLL_SNAP)
 3314 // FIXME: Ensure that offsets are also updated in case of programmatic style changes.
 3315 // https://bugs.webkit.org/show_bug.cgi?id=135964
 3316 updateSnapOffsets();
 3317#endif
33123318}
33133319
33143320bool RenderLayer::overflowControlsIntersectRect(const IntRect& localRect) const

Source/WebCore/rendering/RenderLayerCompositor.cpp

@@void RenderLayerCompositor::updateScrollCoordinatedLayer(RenderLayer& layer, Scr
37703770 scrollingGeometry.scrollableAreaSize = layer.visibleSize();
37713771 scrollingGeometry.contentSize = layer.contentsSize();
37723772 scrollingGeometry.reachableContentSize = layer.scrollableContentsSize();
 3773#if ENABLE(CSS_SCROLL_SNAP)
 3774 if (auto* offsets = layer.horizontalSnapOffsets())
 3775 scrollingGeometry.horizontalSnapOffsets = *offsets;
 3776 if (auto* offsets = layer.verticalSnapOffsets())
 3777 scrollingGeometry.verticalSnapOffsets = *offsets;
 3778#endif
37733779 scrollingCoordinator->updateOverflowScrollingNode(nodeID, backing->scrollingLayer(), backing->scrollingContentsLayer(), &scrollingGeometry);
37743780 }
37753781 }

Source/WebKit2/Shared/Scrolling/RemoteScrollingCoordinatorTransaction.cpp

@@void ArgumentCoder<ScrollingStateScrollingNode>::encode(ArgumentEncoder& encoder
128128 SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ReachableContentsSize, reachableContentsSize)
129129 SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ScrollPosition, scrollPosition)
130130 SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ScrollOrigin, scrollOrigin)
 131#if ENABLE(CSS_SCROLL_SNAP)
 132 SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::HorizontalSnapOffsets, horizontalSnapOffsets)
 133 SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::VerticalSnapOffsets, verticalSnapOffsets)
 134#endif
131135 SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ScrollableAreaParams, scrollableAreaParameters)
132136 SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::RequestedScrollPosition, requestedScrollPosition)
133137 SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::RequestedScrollPosition, requestedScrollPositionRepresentsProgrammaticScroll)

@@bool ArgumentCoder<ScrollingStateScrollingNode>::decode(ArgumentDecoder& decoder
193197 SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ReachableContentsSize, FloatSize, setReachableContentsSize);
194198 SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ScrollPosition, FloatPoint, setScrollPosition);
195199 SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ScrollOrigin, IntPoint, setScrollOrigin);
 200#if ENABLE(CSS_SCROLL_SNAP)
 201 SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::HorizontalSnapOffsets, Vector<float>, setHorizontalSnapOffsets);
 202 SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::VerticalSnapOffsets, Vector<float>, setVerticalSnapOffsets);
 203#endif
196204 SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ScrollableAreaParams, ScrollableAreaParameters, setScrollableAreaParameters);
197205
198206 if (node.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) {

Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm

8383#import "PrintInfo.h"
8484#import "ProcessThrottler.h"
8585#import "RemoteLayerTreeDrawingAreaProxy.h"
 86#import "RemoteScrollingCoordinatorProxy.h"
8687#import "WKPDFView.h"
8788#import "WKScrollView.h"
8889#import "WKWebViewContentProviderRegistry.h"

@@static WebCore::FloatPoint constrainContentOffset(WebCore::FloatPoint contentOff
12991300 // zooming. We'll animate to the right place once the zoom finishes.
13001301 if ([scrollView isZooming])
13011302 *targetContentOffset = [scrollView contentOffset];
 1303#if ENABLE(CSS_SCROLL_SNAP) && ENABLE(ASYNC_SCROLLING)
 1304 if (WebKit::RemoteScrollingCoordinatorProxy* coordinator = _page->scrollingCoordinatorProxy()) {
 1305 CGSize maxScrollDimensions = CGSizeMake(scrollView.contentSize.width - scrollView.bounds.size.width, scrollView.contentSize.height - scrollView.bounds.size.height);
 1306 coordinator->adjustTargetContentOffsetForSnapping(maxScrollDimensions, velocity, targetContentOffset);
 1307 }
 1308#endif
13021309}
13031310
13041311- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate

Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h

@@public:
8484 void scrollingTreeNodeWillStartPanGesture();
8585 void scrollingTreeNodeWillStartScroll();
8686 void scrollingTreeNodeDidEndScroll();
 87#if ENABLE(CSS_SCROLL_SNAP)
 88 void adjustTargetContentOffsetForSnapping(CGSize maxScrollDimensions, CGPoint velocity, CGPoint* targetContentOffset) const;
 89#endif
8790#endif
8891
8992private:
9093 void connectStateNodeLayers(WebCore::ScrollingStateTree&, const RemoteLayerTreeHost&);
 94#if ENABLE(CSS_SCROLL_SNAP)
 95 bool shouldSnapForMainFrameScrolling(WebCore::ScrollEventAxis) const;
 96 float closestSnapOffsetForMainFrameScrolling(WebCore::ScrollEventAxis, float scrollDestination, float velocity) const;
 97#endif
9198
9299 WebPageProxy& m_webPageProxy;
93100 RefPtr<RemoteScrollingTree> m_scrollingTree;

Source/WebKit2/UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.mm

3737#import <UIKit/UIScrollView.h>
3838#import <wtf/TemporaryChange.h>
3939
 40#if ENABLE(CSS_SCROLL_SNAP)
 41#import <WebCore/AxisScrollSnapOffsets.h>
 42#endif
 43
4044using namespace WebCore;
4145
4246@interface WKOverflowScrollViewDelegate : NSObject <UIScrollViewDelegate> {

@@using namespace WebCore;
7377 _scrollingTreeNode->overflowScrollWillStart();
7478}
7579
 80#if ENABLE(CSS_SCROLL_SNAP)
 81- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
 82{
 83 if (_scrollingTreeNode->horizontalSnapOffsets().size() > 0)
 84 targetContentOffset->x = closestSnapOffset<float>(_scrollingTreeNode->horizontalSnapOffsets(), targetContentOffset->x, velocity.x);
 85 if (_scrollingTreeNode->verticalSnapOffsets().size() > 0)
 86 targetContentOffset->y = closestSnapOffset<float>(_scrollingTreeNode->verticalSnapOffsets(), targetContentOffset->y, velocity.y);
 87}
 88#endif
 89
7690- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)willDecelerate
7791{
7892 if (_inUserInteraction && !willDecelerate) {

@@void ScrollingTreeOverflowScrollingNodeIOS::updateAfterChildren(const ScrollingS
188202
189203 scrollView.contentInset = insets;
190204 }
191 
 205
 206#if ENABLE(CSS_SCROLL_SNAP)
 207 // FIXME: If only one axis snaps in 2D scrolling, the other axis will decelerate fast as well. Is this what we want?
 208 if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::HorizontalSnapOffsets) || scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::VerticalSnapOffsets))
 209 scrollView.decelerationRate = horizontalSnapOffsets().size() || verticalSnapOffsets().size() ? UIScrollViewDecelerationRateFast : UIScrollViewDecelerationRateNormal;
 210#endif
192211 END_BLOCK_OBJC_EXCEPTIONS
193212 }
194213}

Source/WebKit2/UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm

2323 * THE POSSIBILITY OF SUCH DAMAGE.
2424 */
2525
26 #include "config.h"
27 #include "RemoteScrollingCoordinatorProxy.h"
 26#import "config.h"
 27#import "RemoteScrollingCoordinatorProxy.h"
2828
2929#if PLATFORM(IOS)
3030#if ENABLE(ASYNC_SCROLLING)
3131
32 #include "LayerRepresentation.h"
33 #include "RemoteLayerTreeHost.h"
34 #include "WebPageProxy.h"
35 #include <WebCore/ScrollingStateFrameScrollingNode.h>
36 #include <WebCore/ScrollingStateOverflowScrollingNode.h>
37 #include <WebCore/ScrollingStateTree.h>
38 #include <UIKit/UIView.h>
 32#import "LayerRepresentation.h"
 33#import "RemoteLayerTreeHost.h"
 34#import "WebPageProxy.h"
 35#import <UIKit/UIView.h>
 36#import <WebCore/ScrollingStateFrameScrollingNode.h>
 37#import <WebCore/ScrollingStateOverflowScrollingNode.h>
 38#import <WebCore/ScrollingStateTree.h>
 39
 40#if ENABLE(CSS_SCROLL_SNAP)
 41#import <WebCore/AxisScrollSnapOffsets.h>
 42#import <WebCore/ScrollTypes.h>
 43#import <WebCore/ScrollingTreeFrameScrollingNode.h>
 44#endif
3945
4046using namespace WebCore;
4147

@@void RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidEndScroll()
106112 m_webPageProxy.overflowScrollDidEndScroll();
107113}
108114
 115#if ENABLE(CSS_SCROLL_SNAP)
 116void RemoteScrollingCoordinatorProxy::adjustTargetContentOffsetForSnapping(CGSize maxScrollDimensions, CGPoint velocity, CGPoint* targetContentOffset) const
 117{
 118 if (shouldSnapForMainFrameScrolling(WebCore::ScrollEventAxis::Horizontal) && targetContentOffset->x > 0 && targetContentOffset->x < maxScrollDimensions.width) {
 119 float potentialSnapPosition = closestSnapOffsetForMainFrameScrolling(WebCore::ScrollEventAxis::Horizontal, targetContentOffset->x, velocity.x);
 120 targetContentOffset->x = std::min<float>(maxScrollDimensions.width, potentialSnapPosition);
 121 }
 122 // FIXME: We should account for how the top navigation bar changes in size.
 123 if (shouldSnapForMainFrameScrolling(WebCore::ScrollEventAxis::Vertical) && targetContentOffset->y > 0 && targetContentOffset->y < maxScrollDimensions.height) {
 124 float potentialSnapPosition = closestSnapOffsetForMainFrameScrolling(WebCore::ScrollEventAxis::Vertical, targetContentOffset->y, velocity.y);
 125 targetContentOffset->y = std::min<float>(maxScrollDimensions.height, potentialSnapPosition);
 126 }
 127}
 128
 129bool RemoteScrollingCoordinatorProxy::shouldSnapForMainFrameScrolling(ScrollEventAxis axis) const
 130{
 131 ScrollingTreeNode* root = m_scrollingTree->rootNode();
 132 if (root && root->isFrameScrollingNode()) {
 133 ScrollingTreeFrameScrollingNode* rootFrame = static_cast<ScrollingTreeFrameScrollingNode*>(root);
 134 const Vector<float>& snapOffsets = axis == ScrollEventAxis::Horizontal ? rootFrame->horizontalSnapOffsets() : rootFrame->verticalSnapOffsets();
 135 return snapOffsets.size() > 0;
 136 }
 137 return false;
 138}
 139
 140float RemoteScrollingCoordinatorProxy::closestSnapOffsetForMainFrameScrolling(ScrollEventAxis axis, float scrollDestination, float velocity) const
 141{
 142 ScrollingTreeNode* root = m_scrollingTree->rootNode();
 143 ASSERT(root && root->isFrameScrollingNode());
 144 ScrollingTreeFrameScrollingNode* rootFrame = static_cast<ScrollingTreeFrameScrollingNode*>(root);
 145 const Vector<float>& snapOffsets = axis == ScrollEventAxis::Horizontal ? rootFrame->horizontalSnapOffsets() : rootFrame->verticalSnapOffsets();
 146 return closestSnapOffset<float>(snapOffsets, scrollDestination, velocity);
 147}
 148#endif
 149
109150} // namespace WebKit
110151
111152