12012-07-24 Simon Fraser <simon.fraser@apple.com>
2
3 Implement sticky positioning
4 https://bugs.webkit.org/show_bug.cgi?id=90046
5
6 Reviewed by NOBODY (OOPS!).
7
8 Initial implementation of position: -webit-sticky, which
9 constraints an element to be positioned inside the interection
10 of its container box, and the viewport.
11
12 A stickily positioned element behaves like position:relative
13 (space is reserved for it in-flow), but with an offset that is
14 determined by the sticky position. Added isInFlowPositioned()
15 to cover relative and sticky.
16
17 Tests: fast/css/sticky/inflow-sticky.html
18 fast/css/sticky/inline-sticky.html
19 fast/css/sticky/replaced-sticky.html
20 fast/css/sticky/sticky-as-positioning-container.html
21 fast/css/sticky/sticky-left-percentage.html
22 fast/css/sticky/sticky-left.html
23 fast/css/sticky/sticky-top.html
24
25 * page/FrameView.cpp:
26 (WebCore::FrameView::scrollContentsFastPath): Need to consider sticky
27 as well as fixed elements when scrolling.
28 * page/FrameView.h: Comment to note that m_fixedObjects contains
29 both fixed and sticky objects.
30 * rendering/LayoutState.cpp:
31 (WebCore::LayoutState::LayoutState): isRelPositioned() -> isInFlowPositioned().
32 * rendering/RenderBlock.cpp:
33 (WebCore::RenderBlock::isSelectionRoot): isRelPositioned() -> isInFlowPositioned().
34 (WebCore::RenderBlock::blockSelectionGaps): Ditto. Also RenderLayer's relativePositionOffset()
35 is renamed to offsetForInFlowPosition().
36 (WebCore::positionForPointRespectingEditingBoundaries): Handle sticky.
37 * rendering/RenderBox.cpp:
38 (WebCore::RenderBox::styleWillChange): Take sticky into account when registering/unregistering
39 fixed objects.
40 (WebCore::RenderBox::mapLocalToContainer): Take sticky into account.
41 (WebCore::RenderBox::mapAbsoluteToLocalPoint): This does now get called during layout, but
42 there's no harm in it, so removing the assertion.
43 (WebCore::RenderBox::offsetFromContainer): Take sticky into account.
44 (WebCore::RenderBox::computeRectForRepaint):
45 (WebCore::RenderBox::layoutOverflowRectForPropagation):
46 * rendering/RenderBox.h: Sticky positioning forces a layer, like relative.
47 Add virtual frameRectForStickyPositioning() method that RenderInline overrides to
48 handle split inlines.
49 * rendering/RenderBoxModelObject.cpp:
50 (WebCore::RenderBoxModelObject::updateBoxModelInfoFromStyle): Call setStickyPositioned().
51 (WebCore::RenderBoxModelObject::adjustedPositionRelativeToOffsetParent): Take any
52 sticky offset into account.
53 (WebCore::RenderBoxModelObject::stickyPositionOffset): Compute the sticky offset. This maps
54 the viewport rect into the coordinate space of the containing block, and then computes
55 the sticky offset using the viewport and containing block rects as constraints.
56 (WebCore::RenderBoxModelObject::mapAbsoluteToLocalPoint): Remove the assertion about
57 being called during layout. We use this to map the viewport rect to local coords when
58 computing the sticky offset.
59 * rendering/RenderBoxModelObject.h: Add some OVERRIDE.
60 (WebCore::RenderBoxModelObject::stickyPositionLogicalOffset): New method.
61 (WebCore::RenderBoxModelObject::requiresLayer): Use isInFlowPositioned().
62 * rendering/RenderInline.cpp:
63 (WebCore::updateStyleOfAnonymousBlockContinuations): Add a FIXME
64 (WebCore::RenderInline::styleWillChange): Implement this here to handle
65 sticky on inlines. RenderBox handles sticky on other renderers.
66 (WebCore::RenderInline::styleDidChange): Some FIXMEs related to continutations.
67 (WebCore::RenderInline::addChildIgnoringContinuation):
68 (WebCore::RenderInline::clippedOverflowRectForRepaint):
69 (WebCore::RenderInline::computeRectForRepaint):
70 (WebCore::RenderInline::offsetFromContainer):
71 (WebCore::RenderInline::mapLocalToContainer):
72 * rendering/RenderInline.h:
73 (WebCore::RenderInline::requiresLayer):
74 * rendering/RenderLayer.cpp:
75 (WebCore::RenderLayer::updateLayerPositionsAfterScroll): Need to look for both sticky
76 and fixed elements when updating layer positions.
77 (WebCore::RenderLayer::updateLayerPosition): Store the sticky position
78 offset in the layer's 'offsetForInFlowPosition'.
79 (WebCore::isPositionedContainer): Use isInFlowPositioned().
80 (WebCore::RenderLayer::calculateClipRects): Sticky behaves like relative positioning
81 for clipping.
82 (WebCore::RenderLayer::shouldBeNormalFlowOnly):
83 * rendering/RenderLayer.h:
84 (WebCore::RenderLayer::offsetForInFlowPosition):
85 (RenderLayer):
86 * rendering/RenderObject.h:
87 (RenderObject):
88 (WebCore::RenderObject::isInFlowPositioned):
89 (WebCore::RenderObject::isRelPositioned):
90 (WebCore::RenderObject::isStickyPositioned):
91 (WebCore::RenderObject::setStickyPositioned):
92 (WebCore::RenderObject::RenderObjectBitfields::RenderObjectBitfields):
93 (RenderObjectBitfields):
94