Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(189)

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp

Issue 1308273010: Adapt and reland old position sticky implementation (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Merge with master and skip anonymous containing blocks for sticky container. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com)
6 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
7 * Copyright (C) 2010 Google Inc. All rights reserved. 7 * Copyright (C) 2010 Google Inc. All rights reserved.
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
(...skipping 20 matching lines...) Expand all
31 #include "core/layout/ImageQualityController.h" 31 #include "core/layout/ImageQualityController.h"
32 #include "core/layout/LayoutBlock.h" 32 #include "core/layout/LayoutBlock.h"
33 #include "core/layout/LayoutFlowThread.h" 33 #include "core/layout/LayoutFlowThread.h"
34 #include "core/layout/LayoutGeometryMap.h" 34 #include "core/layout/LayoutGeometryMap.h"
35 #include "core/layout/LayoutInline.h" 35 #include "core/layout/LayoutInline.h"
36 #include "core/layout/LayoutObject.h" 36 #include "core/layout/LayoutObject.h"
37 #include "core/layout/LayoutTextFragment.h" 37 #include "core/layout/LayoutTextFragment.h"
38 #include "core/layout/LayoutView.h" 38 #include "core/layout/LayoutView.h"
39 #include "core/layout/compositing/CompositedLayerMapping.h" 39 #include "core/layout/compositing/CompositedLayerMapping.h"
40 #include "core/layout/compositing/PaintLayerCompositor.h" 40 #include "core/layout/compositing/PaintLayerCompositor.h"
41 #include "core/page/scrolling/ScrollingConstraints.h" 41 #include "core/page/scrolling/StickyPositionViewportConstraints.h"
42 #include "core/page/scrolling/ViewportConstraints.h"
42 #include "core/paint/PaintLayer.h" 43 #include "core/paint/PaintLayer.h"
43 #include "core/style/BorderEdge.h" 44 #include "core/style/BorderEdge.h"
44 #include "core/style/ShadowList.h" 45 #include "core/style/ShadowList.h"
45 #include "platform/LengthFunctions.h" 46 #include "platform/LengthFunctions.h"
46 #include "platform/geometry/TransformState.h" 47 #include "platform/geometry/TransformState.h"
47 #include "wtf/CurrentTime.h" 48 #include "wtf/CurrentTime.h"
48 49
49 namespace blink { 50 namespace blink {
50 51
51 class FloatStateForStyleChange { 52 class FloatStateForStyleChange {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 if (parent() && diff.needsPaintInvalidationLayer()) { 171 if (parent() && diff.needsPaintInvalidationLayer()) {
171 if (oldStyle->hasAutoClip() != newStyle.hasAutoClip() 172 if (oldStyle->hasAutoClip() != newStyle.hasAutoClip()
172 || oldStyle->clip() != newStyle.clip()) 173 || oldStyle->clip() != newStyle.clip())
173 layer()->clipper().clearClipRectsIncludingDescendants(); 174 layer()->clipper().clearClipRectsIncludingDescendants();
174 } 175 }
175 } 176 }
176 177
177 LayoutObject::styleWillChange(diff, newStyle); 178 LayoutObject::styleWillChange(diff, newStyle);
178 } 179 }
179 180
181 static inline LayoutBox* findScrollAncestor(const LayoutObject* startObject)
182 {
183 // If compositing inputs should be fresh, we can get the scroll parent from
184 // the PaintLayer.
185 PaintLayer* layer = startObject->enclosingLayer();
186 if (layer && !layer->needsCompositingInputsUpdate()) {
chrishtr 2016/01/30 01:49:02 The computations for position:sticky should be don
flackr 2016/02/03 22:48:38 Currently this is also called during styleChanged
187 const PaintLayer* scrollAncestor = layer->ancestorScrollingLayer();
188 if (!scrollAncestor)
189 return nullptr;
190 return toLayoutBox(scrollAncestor->layoutObject());
191 }
192
193 LayoutBox* curBox = startObject->containingBlock();
194 // Scrolling propagates along the containing block chain.
195 // TODO(flackr): We could add scroll ancestor as an input to layout so that
chrishtr 2016/01/30 01:49:03 PaintLayer's scrollParent ancestor-dependent input
196 // we don't have to walk up to find the scroll ancestor.
197 while (curBox && !curBox->isLayoutView()) {
198 if (curBox->hasOverflowClip())
199 return curBox;
200 curBox = curBox->containingBlock();
201 }
202
203 return nullptr;
204 }
205
180 void LayoutBoxModelObject::styleDidChange(StyleDifference diff, const ComputedSt yle* oldStyle) 206 void LayoutBoxModelObject::styleDidChange(StyleDifference diff, const ComputedSt yle* oldStyle)
181 { 207 {
182 bool hadTransform = hasTransformRelatedProperty(); 208 bool hadTransform = hasTransformRelatedProperty();
183 bool hadLayer = hasLayer(); 209 bool hadLayer = hasLayer();
184 bool layerWasSelfPainting = hadLayer && layer()->isSelfPaintingLayer(); 210 bool layerWasSelfPainting = hadLayer && layer()->isSelfPaintingLayer();
185 bool wasFloatingBeforeStyleChanged = FloatStateForStyleChange::wasFloating(t his); 211 bool wasFloatingBeforeStyleChanged = FloatStateForStyleChange::wasFloating(t his);
186 212
187 LayoutObject::styleDidChange(diff, oldStyle); 213 LayoutObject::styleDidChange(diff, oldStyle);
188 updateFromStyle(); 214 updateFromStyle();
189 215
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 bool newStoleBodyBackground = toLayoutBoxModelObject(bodyLayout)->ba ckgroundStolenForBeingBody(style()); 286 bool newStoleBodyBackground = toLayoutBoxModelObject(bodyLayout)->ba ckgroundStolenForBeingBody(style());
261 bool oldStoleBodyBackground = oldStyle && toLayoutBoxModelObject(bod yLayout)->backgroundStolenForBeingBody(oldStyle); 287 bool oldStoleBodyBackground = oldStyle && toLayoutBoxModelObject(bod yLayout)->backgroundStolenForBeingBody(oldStyle);
262 if (newStoleBodyBackground != oldStoleBodyBackground 288 if (newStoleBodyBackground != oldStoleBodyBackground
263 && bodyLayout->style() && bodyLayout->style()->hasBackground()) { 289 && bodyLayout->style() && bodyLayout->style()->hasBackground()) {
264 bodyLayout->setShouldDoFullPaintInvalidation(); 290 bodyLayout->setShouldDoFullPaintInvalidation();
265 } 291 }
266 } 292 }
267 } 293 }
268 294
269 if (FrameView *frameView = view()->frameView()) { 295 if (FrameView *frameView = view()->frameView()) {
270 bool newStyleIsViewportConstained = style()->hasViewportConstrainedPosit ion(); 296 bool newStyleIsViewportConstained = style()->position() == FixedPosition ;
271 bool oldStyleIsViewportConstrained = oldStyle && oldStyle->hasViewportCo nstrainedPosition(); 297 bool oldStyleIsViewportConstrained = oldStyle && oldStyle->position() == FixedPosition;
298 bool newStyleIsSticky = style()->position() == StickyPosition;
299 bool oldStyleIsSticky = oldStyle && oldStyle->position() == StickyPositi on;
300
301 // Sticky positioned elements are only viewport constrained if they have no ancestor scroller.
302 if (newStyleIsSticky || oldStyleIsSticky) {
303 if (!findScrollAncestor(this)) {
304 newStyleIsViewportConstained |= newStyleIsSticky;
305 oldStyleIsViewportConstrained |= oldStyleIsSticky;
306 }
307 }
308
272 if (newStyleIsViewportConstained != oldStyleIsViewportConstrained) { 309 if (newStyleIsViewportConstained != oldStyleIsViewportConstrained) {
273 if (newStyleIsViewportConstained && layer()) 310 if (newStyleIsViewportConstained && layer())
274 frameView->addViewportConstrainedObject(this); 311 frameView->addViewportConstrainedObject(this);
275 else 312 else
276 frameView->removeViewportConstrainedObject(this); 313 frameView->removeViewportConstrainedObject(this);
277 } 314 }
315
316 if (newStyleIsSticky != oldStyleIsSticky) {
317 if (newStyleIsSticky)
318 frameView->addStickyPositionObject();
319 else
320 frameView->removeStickyPositionObject();
321 }
278 } 322 }
279 } 323 }
280 324
281 void LayoutBoxModelObject::createLayer(PaintLayerType type) 325 void LayoutBoxModelObject::createLayer(PaintLayerType type)
282 { 326 {
283 // If the current paint invalidation container is not a stacking context and this object is 327 // If the current paint invalidation container is not a stacking context and this object is
284 // a or treated as a stacking context, creating this layer may cause this ob ject and its 328 // a or treated as a stacking context, creating this layer may cause this ob ject and its
285 // descendants to change paint invalidation container. Therefore we must eag erly invalidate 329 // descendants to change paint invalidation container. Therefore we must eag erly invalidate
286 // them on the original paint invalidation container before creating the lay er. 330 // them on the original paint invalidation container before creating the lay er.
287 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && isRooted() && style Ref().isTreatedAsOrStackingContext()) { 331 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && isRooted() && style Ref().isTreatedAsOrStackingContext()) {
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 633
590 else if (!style()->bottom().isAuto() 634 else if (!style()->bottom().isAuto()
591 && (!containingBlock->hasAutoHeightOrContainingBlockWithAutoHeight() 635 && (!containingBlock->hasAutoHeightOrContainingBlockWithAutoHeight()
592 || !style()->bottom().hasPercent() 636 || !style()->bottom().hasPercent()
593 || containingBlock->stretchesToViewport())) 637 || containingBlock->stretchesToViewport()))
594 offset.expand(0, -valueForLength(style()->bottom(), containingBlock->ava ilableHeight())); 638 offset.expand(0, -valueForLength(style()->bottom(), containingBlock->ava ilableHeight()));
595 639
596 return offset; 640 return offset;
597 } 641 }
598 642
643 void LayoutBoxModelObject::computeStickyPositionConstraints(StickyPositionViewpo rtConstraints& constraints, const FloatRect& constrainingRect) const
644 {
645 FloatSize skippedContainersOffset;
646 LayoutBlock* containingBlock = this->containingBlock();
647 // Skip anonymous containing blocks.
648 while (containingBlock->isAnonymous()) {
chrishtr 2016/01/30 01:49:02 Why exactly? Is there a test for this?
flackr 2016/02/03 22:48:38 I was matching firefox and safari on http://flackr
chrishtr 2016/02/23 16:31:51 And file a spec bug?
flackr 2016/03/07 19:07:33 Done: bug is here https://www.w3.org/Bugs/Public/s
649 skippedContainersOffset += toFloatSize(FloatPoint(containingBlock->frame Rect().location()));
650 containingBlock = containingBlock->containingBlock();
651 }
652 LayoutBox* scrollAncestor = findScrollAncestor(this);
653
654 LayoutRect containerContentRect = containingBlock->contentBoxRect();
655 LayoutUnit maxWidth = containingBlock->availableLogicalWidth();
656
657 // Sticky positioned element ignore any override logical width on the contai ning block (as they don't call
658 // containingBlockLogicalWidthForContent). It's unclear whether this is tota lly fine.
659 // Compute the container-relative area within which the sticky element is al lowed to move.
660 containerContentRect.contractEdges(
661 minimumValueForLength(style()->marginTop(), maxWidth),
662 minimumValueForLength(style()->marginRight(), maxWidth),
663 minimumValueForLength(style()->marginBottom(), maxWidth),
664 minimumValueForLength(style()->marginLeft(), maxWidth));
665
666 // Map to the scroll ancestor.
667 constraints.setAbsoluteContainingBlockRect(containingBlock->localToAncestorQ uad(FloatRect(containerContentRect), scrollAncestor).boundingBox());
668
669 FloatRect stickyBoxRect = isLayoutInline()
670 ? FloatRect(toLayoutInline(this)->linesBoundingBox())
671 : FloatRect(toLayoutBox(this)->frameRect());
672 FloatRect flippedStickyBoxRect = stickyBoxRect;
673 containingBlock->flipForWritingMode(flippedStickyBoxRect);
674 FloatPoint stickyLocation = flippedStickyBoxRect.location() + skippedContain ersOffset;
675
676 // FIXME: sucks to call localToAbsolute again, but we can't just offset from the previously computed rect if there are transforms.
chrishtr 2016/01/30 01:49:02 s/localToAbsolute/localToAncestorQuad
flackr 2016/02/22 22:55:23 Done.
677 // Map to the view to avoid including page scale factor.
678 FloatRect absContainerFrame = containingBlock->localToAncestorQuad(FloatRect (FloatPoint(), FloatSize(containingBlock->size())), scrollAncestor).boundingBox( );
chrishtr 2016/01/30 01:49:02 s/absContainerFrame/stickyBoxRect/
flackr 2016/02/22 22:55:23 This is the container's frame rect which we add to
679
680 // If the containing block is our scroll ancestor, its location will not inc lude the scroll offset which we need to include as
681 // part of the sticky box rect so we include it here.
682 if (containingBlock->hasOverflowClip()) {
683 FloatSize scrollOffset(toFloatSize(containingBlock->layer()->scrollableA rea()->adjustedScrollOffset()));
684 stickyLocation -= scrollOffset;
685 }
686
687 // We can't call localToAbsolute on |this| because that will recur. FIXME: F or now, assume that |this| is not transformed.
chrishtr 2016/01/30 01:49:02 What is this comment about again? Why a need to ma
flackr 2016/02/22 22:55:23 This actually seems unnecessary. If there is a tra
688 constraints.setAbsoluteStickyBoxRect(FloatRect(absContainerFrame.location() + toFloatSize(stickyLocation), flippedStickyBoxRect.size()));
689
690 LayoutUnit horizontalOffsets = minimumValueForLength(style()->right(), const rainingRect.width()) +
691 minimumValueForLength(style()->left(), constrainingRect.width());
692 bool skipRight = false;
693 bool skipLeft = false;
694 if (!style()->left().isAuto() && !style()->right().isAuto()) {
chrishtr 2016/01/30 01:49:02 Document this code and what it's for.
flackr 2016/02/22 22:55:23 Done.
695 if (horizontalOffsets > containerContentRect.width()
696 || horizontalOffsets + containerContentRect.width() > constrainingRe ct.width()) {
697 skipRight = style()->isLeftToRightDirection();
698 skipLeft = !skipRight;
699 }
700 }
701
702 if (!style()->left().isAuto() && !skipLeft) {
703 constraints.setLeftOffset(minimumValueForLength(style()->left(), constra iningRect.width()));
704 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft);
705 }
706
707 if (!style()->right().isAuto() && !skipRight) {
708 constraints.setRightOffset(minimumValueForLength(style()->right(), const rainingRect.width()));
709 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeRight);
710 }
711
712 bool skipBottom = false;
713 // FIXME(ostap): Exclude top or bottom edge offset depending on the writing mode when related
chrishtr 2016/01/30 01:49:02 s/FIXME/TODO/ throughout, and replace names with f
flackr 2016/02/22 22:55:23 Done.
714 // sections are fixed in spec: http://lists.w3.org/Archives/Public/www-style /2014May/0286.html
715 LayoutUnit verticalOffsets = minimumValueForLength(style()->top(), constrain ingRect.width()) +
716 minimumValueForLength(style()->bottom(), constrainingRect.width());
717 if (!style()->top().isAuto() && !style()->bottom().isAuto()) {
718 if (verticalOffsets > containerContentRect.height()
719 || verticalOffsets + containerContentRect.height() > constrainingRec t.height()) {
720 skipBottom = true;
721 }
722 }
723
724 if (!style()->top().isAuto()) {
725 constraints.setTopOffset(minimumValueForLength(style()->top(), constrain ingRect.height()));
726 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop);
727 }
728
729 if (!style()->bottom().isAuto() && !skipBottom) {
730 constraints.setBottomOffset(minimumValueForLength(style()->bottom(), con strainingRect.height()));
731 constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeBottom);
732 }
733 }
734
735 FloatRect LayoutBoxModelObject::computeStickyConstrainingRect() const
736 {
737 FloatRect constrainingRect;
738
739 ASSERT(hasLayer());
740 LayoutBox* enclosingClippingBox = findScrollAncestor(this);
741 if (enclosingClippingBox) {
742 constrainingRect = FloatRect(enclosingClippingBox->overflowClipRect(Layo utPoint()));
743 constrainingRect.move(enclosingClippingBox->paddingLeft(), enclosingClip pingBox->paddingTop());
744 constrainingRect.contract(FloatSize(enclosingClippingBox->paddingLeft() + enclosingClippingBox->paddingRight(),
745 enclosingClippingBox->paddingTop() + enclosingClippingBox->paddingBo ttom()));
746 } else {
747 constrainingRect = view()->frameView()->visibleContentRect();
748 }
749
750 return constrainingRect;
751 }
752
753 LayoutSize LayoutBoxModelObject::stickyPositionOffset() const
754 {
755 FloatRect constrainingRect = computeStickyConstrainingRect();
756 StickyPositionViewportConstraints constraints;
757 computeStickyPositionConstraints(constraints, constrainingRect);
758
759 // The sticky offset is physical, so we can just return the delta computed i n absolute coords (though it may be wrong with transforms).
760 return LayoutSize(constraints.computeStickyOffset(constrainingRect));
761 }
762
599 LayoutPoint LayoutBoxModelObject::adjustedPositionRelativeToOffsetParent(const L ayoutPoint& startPoint) const 763 LayoutPoint LayoutBoxModelObject::adjustedPositionRelativeToOffsetParent(const L ayoutPoint& startPoint) const
600 { 764 {
601 // If the element is the HTML body element or doesn't have a parent 765 // If the element is the HTML body element or doesn't have a parent
602 // return 0 and stop this algorithm. 766 // return 0 and stop this algorithm.
603 if (isBody() || !parent()) 767 if (isBody() || !parent())
604 return LayoutPoint(); 768 return LayoutPoint();
605 769
606 LayoutPoint referencePoint = startPoint; 770 LayoutPoint referencePoint = startPoint;
607 referencePoint.move(parent()->columnOffset(referencePoint)); 771 referencePoint.move(parent()->columnOffset(referencePoint));
608 772
609 // If the offsetParent of the element is null, or is the HTML body element, 773 // If the offsetParent of the element is null, or is the HTML body element,
610 // return the distance between the canvas origin and the left border edge 774 // return the distance between the canvas origin and the left border edge
611 // of the element and stop this algorithm. 775 // of the element and stop this algorithm.
612 Element* element = offsetParent(); 776 Element* element = offsetParent();
613 if (!element) 777 if (!element)
614 return referencePoint; 778 return referencePoint;
615 779
616 if (const LayoutBoxModelObject* offsetParent = element->layoutBoxModelObject ()) { 780 if (const LayoutBoxModelObject* offsetParent = element->layoutBoxModelObject ()) {
617 if (offsetParent->isBox() && !offsetParent->isBody()) 781 if (offsetParent->isBox() && !offsetParent->isBody())
618 referencePoint.move(-toLayoutBox(offsetParent)->borderLeft(), -toLay outBox(offsetParent)->borderTop()); 782 referencePoint.move(-toLayoutBox(offsetParent)->borderLeft(), -toLay outBox(offsetParent)->borderTop());
619 if (!isOutOfFlowPositioned() || flowThreadContainingBlock()) { 783 if (!isOutOfFlowPositioned() || flowThreadContainingBlock()) {
620 if (isInFlowPositioned()) 784 if (isInFlowPositioned())
621 referencePoint.move(relativePositionOffset()); 785 referencePoint.move(offsetForInFlowPosition());
622 786
623 LayoutObject* current; 787 LayoutObject* current;
624 for (current = parent(); current != offsetParent && current->parent( ); current = current->parent()) { 788 for (current = parent(); current != offsetParent && current->parent( ); current = current->parent()) {
625 // FIXME: What are we supposed to do inside SVG content? 789 // FIXME: What are we supposed to do inside SVG content?
626 if (!isOutOfFlowPositioned()) { 790 if (!isOutOfFlowPositioned()) {
627 if (current->isBox() && !current->isTableRow()) 791 if (current->isBox() && !current->isTableRow())
628 referencePoint.moveBy(toLayoutBox(current)->topLeftLocat ion()); 792 referencePoint.moveBy(toLayoutBox(current)->topLeftLocat ion());
629 referencePoint.move(current->parent()->columnOffset(referenc ePoint)); 793 referencePoint.move(current->parent()->columnOffset(referenc ePoint));
630 } 794 }
631 } 795 }
632 796
633 if (offsetParent->isBox() && offsetParent->isBody() && !offsetParent ->isPositioned()) 797 if (offsetParent->isBox() && offsetParent->isBody() && !offsetParent ->isPositioned())
634 referencePoint.moveBy(toLayoutBox(offsetParent)->topLeftLocation ()); 798 referencePoint.moveBy(toLayoutBox(offsetParent)->topLeftLocation ());
635 } 799 }
636 } 800 }
637 801
638 return referencePoint; 802 return referencePoint;
639 } 803 }
640 804
641 LayoutSize LayoutBoxModelObject::offsetForInFlowPosition() const 805 LayoutSize LayoutBoxModelObject::offsetForInFlowPosition() const
642 { 806 {
643 return isRelPositioned() ? relativePositionOffset() : LayoutSize(); 807 if (isRelPositioned())
808 return relativePositionOffset();
809
810 if (isStickyPositioned())
811 return stickyPositionOffset();
812
813 return LayoutSize();
644 } 814 }
645 815
646 LayoutUnit LayoutBoxModelObject::offsetLeft() const 816 LayoutUnit LayoutBoxModelObject::offsetLeft() const
647 { 817 {
648 // Note that LayoutInline and LayoutBox override this to pass a different 818 // Note that LayoutInline and LayoutBox override this to pass a different
649 // startPoint to adjustedPositionRelativeToOffsetParent. 819 // startPoint to adjustedPositionRelativeToOffsetParent.
650 return adjustedPositionRelativeToOffsetParent(LayoutPoint()).x(); 820 return adjustedPositionRelativeToOffsetParent(LayoutPoint()).x();
651 } 821 }
652 822
653 LayoutUnit LayoutBoxModelObject::offsetTop() const 823 LayoutUnit LayoutBoxModelObject::offsetTop() const
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 const LayoutObject* LayoutBoxModelObject::pushMappingToContainer(const LayoutBox ModelObject* ancestorToStopAt, LayoutGeometryMap& geometryMap) const 1126 const LayoutObject* LayoutBoxModelObject::pushMappingToContainer(const LayoutBox ModelObject* ancestorToStopAt, LayoutGeometryMap& geometryMap) const
957 { 1127 {
958 ASSERT(ancestorToStopAt != this); 1128 ASSERT(ancestorToStopAt != this);
959 1129
960 bool ancestorSkipped; 1130 bool ancestorSkipped;
961 LayoutObject* container = this->container(ancestorToStopAt, &ancestorSkipped ); 1131 LayoutObject* container = this->container(ancestorToStopAt, &ancestorSkipped );
962 if (!container) 1132 if (!container)
963 return nullptr; 1133 return nullptr;
964 1134
965 bool isInline = isLayoutInline(); 1135 bool isInline = isLayoutInline();
966 bool isFixedPos = !isInline && style()->position() == FixedPosition; 1136 bool isFixedPosition = !isInline && style()->position() == FixedPosition;
967 bool hasTransform = !isInline && hasLayer() && layer()->transform(); 1137 bool hasTransform = !isInline && hasLayer() && layer()->transform();
968 1138
969 LayoutSize adjustmentForSkippedAncestor; 1139 LayoutSize adjustmentForSkippedAncestor;
970 if (ancestorSkipped) { 1140 if (ancestorSkipped) {
971 // There can't be a transform between paintInvalidationContainer and anc estorToStopAt, because transforms create containers, so it should be safe 1141 // There can't be a transform between paintInvalidationContainer and anc estorToStopAt, because transforms create containers, so it should be safe
972 // to just subtract the delta between the ancestor and ancestorToStopAt. 1142 // to just subtract the delta between the ancestor and ancestorToStopAt.
973 adjustmentForSkippedAncestor = -ancestorToStopAt->offsetFromAncestorCont ainer(container); 1143 adjustmentForSkippedAncestor = -ancestorToStopAt->offsetFromAncestorCont ainer(container);
974 } 1144 }
975 1145
976 bool offsetDependsOnPoint = false; 1146 bool offsetDependsOnPoint = false;
977 LayoutSize containerOffset = offsetFromContainer(container, LayoutPoint(), & offsetDependsOnPoint); 1147 LayoutSize containerOffset = offsetFromContainer(container, LayoutPoint(), & offsetDependsOnPoint);
1148 LayoutSize stickyOffset;
1149 if (style()->position() == StickyPosition)
1150 stickyOffset = offsetForInFlowPosition();
978 1151
979 bool preserve3D = container->style()->preserves3D() || style()->preserves3D( ); 1152 bool preserve3D = container->style()->preserves3D() || style()->preserves3D( );
980 if (shouldUseTransformFromContainer(container)) { 1153 if (shouldUseTransformFromContainer(container)) {
981 TransformationMatrix t; 1154 TransformationMatrix t;
982 getTransformFromContainer(container, containerOffset, t); 1155 getTransformFromContainer(container, containerOffset, t);
983 t.translateRight(adjustmentForSkippedAncestor.width().toFloat(), adjustm entForSkippedAncestor.height().toFloat()); 1156 t.translateRight(adjustmentForSkippedAncestor.width().toFloat(), adjustm entForSkippedAncestor.height().toFloat());
984 geometryMap.push(this, t, preserve3D, offsetDependsOnPoint, isFixedPos, hasTransform); 1157 geometryMap.push(this, t, preserve3D, offsetDependsOnPoint, isFixedPosit ion, hasTransform, LayoutSize(), stickyOffset);
985 } else { 1158 } else {
986 containerOffset += adjustmentForSkippedAncestor; 1159 containerOffset += adjustmentForSkippedAncestor;
987 geometryMap.push(this, containerOffset, preserve3D, offsetDependsOnPoint , isFixedPos, hasTransform); 1160 geometryMap.push(this, containerOffset, preserve3D, offsetDependsOnPoint , isFixedPosition, hasTransform, LayoutSize(), stickyOffset);
988 } 1161 }
989 1162
990 return ancestorSkipped ? ancestorToStopAt : container; 1163 return ancestorSkipped ? ancestorToStopAt : container;
991 } 1164 }
992 1165
993 void LayoutBoxModelObject::moveChildTo(LayoutBoxModelObject* toBoxModelObject, L ayoutObject* child, LayoutObject* beforeChild, bool fullRemoveInsert) 1166 void LayoutBoxModelObject::moveChildTo(LayoutBoxModelObject* toBoxModelObject, L ayoutObject* child, LayoutObject* beforeChild, bool fullRemoveInsert)
994 { 1167 {
995 // We assume that callers have cleared their positioned objects list for chi ld moves (!fullRemoveInsert) so the 1168 // We assume that callers have cleared their positioned objects list for chi ld moves (!fullRemoveInsert) so the
996 // positioned layoutObject maps don't become stale. It would be too slow to do the map lookup on each call. 1169 // positioned layoutObject maps don't become stale. It would be too slow to do the map lookup on each call.
997 ASSERT(!fullRemoveInsert || !isLayoutBlock() || !toLayoutBlock(this)->hasPos itionedObjects()); 1170 ASSERT(!fullRemoveInsert || !isLayoutBlock() || !toLayoutBlock(this)->hasPos itionedObjects());
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 if (rootElementStyle->hasBackground()) 1232 if (rootElementStyle->hasBackground())
1060 return false; 1233 return false;
1061 1234
1062 if (node() != document().firstBodyElement()) 1235 if (node() != document().firstBodyElement())
1063 return false; 1236 return false;
1064 1237
1065 return true; 1238 return true;
1066 } 1239 }
1067 1240
1068 } // namespace blink 1241 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698