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: http://svn.webkit.org/repository/webkit/trunk@126774 268f45cc-cd09-0410-ab3c-d52691b4dbfc
47 files changed