Implement sticky positioning
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Aug 2012 17:39:45 +0000 (17:39 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Aug 2012 17:39:45 +0000 (17:39 +0000)
commit902706fc5933f0f8970e143390ef1894ff96dc86
treefa38a511ade275504d23c6260ffd0215ea2d3433
parentf1f599c1e08167b9d3e6c55d97374a5bfc8d39c3
Implement sticky positioning
https://bugs.webkit.org/show_bug.cgi?id=90046

Reviewed by Ojan Vafai.

Source/WebCore:

Initial implementation of position: -webkit-sticky, which
constrains an element to be positioned inside the intersection
of its container box, and the viewport. Sticky elements create
stacking context.

A stickily positioned element behaves like position:relative
(space is reserved for it in-flow), but with an offset that is
determined by the sticky position. Changed isInFlowPositioned()
to cover relative and sticky.

Added a convenience isPositioned() to RenderObject(), which
is true for an object with any non-static position value.

Tests: fast/css/sticky/inflow-sticky.html
       fast/css/sticky/inline-sticky-abspos-child.html
       fast/css/sticky/inline-sticky.html
       fast/css/sticky/replaced-sticky.html
       fast/css/sticky/sticky-as-positioning-container.html
       fast/css/sticky/sticky-left-percentage.html
       fast/css/sticky/sticky-left.html
       fast/css/sticky/sticky-margins.html
       fast/css/sticky/sticky-side-margins.html
       fast/css/sticky/sticky-stacking-context.html
       fast/css/sticky/sticky-top-margins.html
       fast/css/sticky/sticky-top.html
       fast/css/sticky/sticky-writing-mode-horizontal-bt.html
       fast/css/sticky/sticky-writing-mode-vertical-lr.html
       fast/css/sticky/sticky-writing-mode-vertical-rl.html

* css/StyleResolver.cpp:
(WebCore::StyleResolver::adjustRenderStyle): Have position:sticky
create stacking context from the get-go, to make scrolling optimizations easier later.
* page/FrameView.cpp:
(WebCore::FrameView::scrollContentsFastPath): Use hasViewportConstrainedPosition().
* page/FrameView.h: FrameView's "fixed" objects contains both fixed and sticky objects now.
* rendering/RenderBlock.cpp: Use isPositioned().
(WebCore::RenderBlock::isSelectionRoot):
(WebCore::RenderBlock::renderName):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::styleWillChange): Need to look for both stick and fixed positioning to
determine whether to add something to FrameView's fixed object set.
(WebCore::RenderBox::computeRectForRepaint): Need to take the sticky offset into account
when computing repaint rects.
* rendering/RenderBox.h: Implement frameRectForStickyPositioning() for boxes.
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::updateBoxModelInfoFromStyle):
(WebCore::RenderBoxModelObject::adjustedPositionRelativeToOffsetParent):
(WebCore::RenderBoxModelObject::stickyPositionOffset): Compute the sticky position
offset by taking into account the viewport rect, and the conteriner's contentRect
inset by its margins.
(WebCore::RenderBoxModelObject::offsetForInFlowPosition): Convenience wrapper
for getting relative or sticky offset.
* rendering/RenderBoxModelObject.h: Have requiresLayer() use isPositioned().
(WebCore::RenderBoxModelObject::stickyPositionLogicalOffset):
* rendering/RenderInline.cpp:
(WebCore::RenderInline::styleWillChange): Need to implement this to
add/remove objects from FrameView's fixed object list, since, prior to sticky,
only boxes could be fixed.
(WebCore::RenderInline::renderName):
(WebCore::RenderInline::positionForPoint):
(WebCore::RenderInline::computeRectForRepaint):
* rendering/RenderInline.h:
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::updateLayerPositionsAfterScroll): Have to look for fixed or sticky.
(WebCore::RenderLayer::calculateClipRects): Use isPositioned().
(WebCore::RenderLayer::shouldBeNormalFlowOnly): Ditto.
* rendering/RenderLayer.h:
* rendering/RenderObject.cpp:
(WebCore::RenderObject::styleWillChange):
(WebCore::RenderObject::propagateStyleToAnonymousChildren): Should use isInFlowPositioned(),
not just isRelPositioned().
(WebCore::RenderObject::offsetParent): Use isPositioned().
* rendering/RenderObject.h:
(WebCore::RenderObject::isInFlowPositioned):
(WebCore::RenderObject::isStickyPositioned):
(WebCore::RenderObject::setStickyPositioned):
(WebCore::RenderObject::RenderObjectBitfields::RenderObjectBitfields):
(RenderObjectBitfields):
* rendering/RenderStyle.h: add hasViewportConstrainedPosition() for fixed or sticky position.

LayoutTests:

Various ref tests for sticky positioning.

* fast/css/sticky/inflow-sticky-expected.html: Added.
* fast/css/sticky/inflow-sticky.html: Added.
* fast/css/sticky/inline-sticky-abspos-child-expected.html: Added.
* fast/css/sticky/inline-sticky-abspos-child.html: Added.
* fast/css/sticky/inline-sticky-expected.html: Added.
* fast/css/sticky/inline-sticky.html: Added.
* fast/css/sticky/replaced-sticky-expected.html: Added.
* fast/css/sticky/replaced-sticky.html: Added.
* fast/css/sticky/sticky-as-positioning-container-expected.html: Added.
* fast/css/sticky/sticky-as-positioning-container.html: Added.
* fast/css/sticky/sticky-left-expected.html: Added.
* fast/css/sticky/sticky-left-percentage-expected.html: Added.
* fast/css/sticky/sticky-left-percentage.html: Added.
* fast/css/sticky/sticky-left.html: Added.
* fast/css/sticky/sticky-margins-expected.html: Added.
* fast/css/sticky/sticky-margins.html: Added.
* fast/css/sticky/sticky-side-margins-expected.html: Added.
* fast/css/sticky/sticky-side-margins.html: Added.
* fast/css/sticky/sticky-stacking-context-expected.html: Added.
* fast/css/sticky/sticky-stacking-context.html: Added.
* fast/css/sticky/sticky-top-expected.html: Added.
* fast/css/sticky/sticky-top-margins-expected.html: Added.
* fast/css/sticky/sticky-top-margins.html: Added.
* fast/css/sticky/sticky-top.html: Added.
* fast/css/sticky/sticky-writing-mode-horizontal-bt-expected.html: Added.
* fast/css/sticky/sticky-writing-mode-horizontal-bt.html: Added.
* fast/css/sticky/sticky-writing-mode-vertical-lr-expected.html: Added.
* fast/css/sticky/sticky-writing-mode-vertical-lr.html: Added.
* fast/css/sticky/sticky-writing-mode-vertical-rl-expected.html: Added.
* fast/css/sticky/sticky-writing-mode-vertical-rl.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@126774 268f45cc-cd09-0410-ab3c-d52691b4dbfc
47 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/css/sticky/inflow-sticky-expected.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/inflow-sticky.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/inline-sticky-abspos-child-expected.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/inline-sticky-abspos-child.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/inline-sticky-expected.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/inline-sticky.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/replaced-sticky-expected.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/replaced-sticky.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-as-positioning-container-expected.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-as-positioning-container.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-left-expected.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-left-percentage-expected.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-left-percentage.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-left.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-margins-expected.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-margins.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-side-margins-expected.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-side-margins.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-stacking-context-expected.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-stacking-context.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-top-expected.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-top-margins-expected.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-top-margins.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-top.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-writing-mode-horizontal-bt-expected.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-writing-mode-horizontal-bt.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-writing-mode-vertical-lr-expected.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-writing-mode-vertical-lr.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-writing-mode-vertical-rl-expected.html [new file with mode: 0644]
LayoutTests/fast/css/sticky/sticky-writing-mode-vertical-rl.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/css/StyleResolver.cpp
Source/WebCore/page/FrameView.cpp
Source/WebCore/page/FrameView.h
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderBox.cpp
Source/WebCore/rendering/RenderBox.h
Source/WebCore/rendering/RenderBoxModelObject.cpp
Source/WebCore/rendering/RenderBoxModelObject.h
Source/WebCore/rendering/RenderInline.cpp
Source/WebCore/rendering/RenderInline.h
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayer.h
Source/WebCore/rendering/RenderObject.cpp
Source/WebCore/rendering/RenderObject.h
Source/WebCore/rendering/style/RenderStyle.h