CSS Scroll Snap - support snapping to nested elements
authorbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 16 Jun 2015 20:44:18 +0000 (20:44 +0000)
committerbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 16 Jun 2015 20:44:18 +0000 (20:44 +0000)
commit6f99a99077976a950eb394c5649b072f98d2e51c
tree165de231b503d8cb3a375fe7989cf33f7b8012fd
parentbdefca51d73b5754e388bea4b40329fe98134864
CSS Scroll Snap - support snapping to nested elements
https://bugs.webkit.org/show_bug.cgi?id=145843
<rdar://problem/21339581>

Reviewed by Darin Adler.

Source/WebCore:

Tested by css3/scroll-snap/nested-elements.html

The Scroll Snap Point implementation was not properly handling nested elements.
This could be resolved by recursively calling 'appendChildSnapOffsets', but this
seemed like an inefficient approach, especially considering how often this method
is called during various scaling and other operations.

Instead, do the following:
(1) Add a new HashSet to RenderView that holds a collection of RenderElements that
    have scroll-snap-coordinates.
(2) During RenderElement::styleWillChange, register all elements that have the
    scroll-snap-coordinates style with the RenderView.
(3) When performing 'appendChildSnapOffsets', refer to the HashSet of elements, select the
    subset of these entries relevant to the current scrolling container, and build up the
    set of scroll-snap-coordinates needed for the current scrolling container.

* page/scrolling/AxisScrollSnapOffsets.cpp:
(WebCore::appendChildSnapOffsets): Check the scroll-snap-coordinate RenderElement HashSet
for the RenderView to find all elements that are children of the current scrolling container.
Add the scroll-snap-coordinates for these RenderElements to the current set of snap points.
* rendering/RenderElement.cpp:
(WebCore::findEnclosingScrollableContainer): New helper function.
(WebCore::RenderElement::styleWillChange): If the current element has scroll-snap-coordinate
defined, remember it for later so we can use it with the relevant scrolling container
after layout completes.
(WebCore::RenderElement::willBeRemovedFromTree): Unregister the current element from the
RenderView.
(WebCore::RenderElement::findEnclosingScrollableContainer): Added. Locate the relevant
scrolling container for the current object.
* rendering/RenderElement.h:
* rendering/RenderView.cpp:
(WebCore::Document::registerRenderElementWithScrollSnapCoordinates): Added.
(WebCore::Document::unregisterRenderElementWithScrollSnapCoordinates): Added.
* rendering/RenderView.h:

LayoutTests:

* css3/scroll-snap/nested-elements-expected.txt: Added.
* css3/scroll-snap/nested-elements.html: Added.
* css3/scroll-snap/scroll-snap-offsets-expected.txt: Updated to
  account for 50%/50% scroll-snap-coordinates.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@185606 268f45cc-cd09-0410-ab3c-d52691b4dbfc
12 files changed:
LayoutTests/ChangeLog
LayoutTests/css3/scroll-snap/nested-elements-expected.txt [new file with mode: 0644]
LayoutTests/css3/scroll-snap/nested-elements.html [new file with mode: 0644]
LayoutTests/css3/scroll-snap/scroll-snap-offsets-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/page/scrolling/AxisScrollSnapOffsets.cpp
Source/WebCore/rendering/RenderBox.cpp
Source/WebCore/rendering/RenderBox.h
Source/WebCore/rendering/RenderElement.cpp
Source/WebCore/rendering/RenderView.cpp
Source/WebCore/rendering/RenderView.h
WebKit.xcworkspace/xcshareddata/xcschemes/All Source (target WebProcess).xcscheme