OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |