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 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 bool newStoleBodyBackground = toLayoutBoxModelObject(bodyLayout)->ba
ckgroundStolenForBeingBody(style()); | 259 bool newStoleBodyBackground = toLayoutBoxModelObject(bodyLayout)->ba
ckgroundStolenForBeingBody(style()); |
260 bool oldStoleBodyBackground = oldStyle && toLayoutBoxModelObject(bod
yLayout)->backgroundStolenForBeingBody(oldStyle); | 260 bool oldStoleBodyBackground = oldStyle && toLayoutBoxModelObject(bod
yLayout)->backgroundStolenForBeingBody(oldStyle); |
261 if (newStoleBodyBackground != oldStoleBodyBackground | 261 if (newStoleBodyBackground != oldStoleBodyBackground |
262 && bodyLayout->style() && bodyLayout->style()->hasBackground())
{ | 262 && bodyLayout->style() && bodyLayout->style()->hasBackground())
{ |
263 bodyLayout->setShouldDoFullPaintInvalidation(); | 263 bodyLayout->setShouldDoFullPaintInvalidation(); |
264 } | 264 } |
265 } | 265 } |
266 } | 266 } |
267 | 267 |
268 if (FrameView *frameView = view()->frameView()) { | 268 if (FrameView *frameView = view()->frameView()) { |
269 bool newStyleIsViewportConstained = style()->hasViewportConstrainedPosit
ion(); | 269 bool newStyleIsViewportConstained = style()->position() == FixedPosition
; |
270 bool oldStyleIsViewportConstrained = oldStyle && oldStyle->hasViewportCo
nstrainedPosition(); | 270 bool oldStyleIsViewportConstrained = oldStyle && oldStyle->position() ==
FixedPosition; |
| 271 bool newStyleIsSticky = style()->position() == StickyPosition; |
| 272 bool oldStyleIsSticky = oldStyle && oldStyle->position() == StickyPositi
on; |
| 273 |
| 274 if (newStyleIsSticky != oldStyleIsSticky) { |
| 275 if (newStyleIsSticky) { |
| 276 frameView->addStickyPositionObject(); |
| 277 // During compositing inputs update we'll have the scroll |
| 278 // ancestor without having to walk up the tree and can compute |
| 279 // the sticky position constraints then. |
| 280 if (layer()) |
| 281 layer()->setNeedsCompositingInputsUpdate(); |
| 282 } else { |
| 283 // TODO: This should only remove the constraint for the current
object. |
| 284 invalidateScrollAncestorConstraints(); |
| 285 // This may get re-added to viewport constrained objects if the
object went |
| 286 // from sticky to fixed. |
| 287 frameView->removeViewportConstrainedObject(this); |
| 288 frameView->removeStickyPositionObject(); |
| 289 } |
| 290 } |
| 291 |
271 if (newStyleIsViewportConstained != oldStyleIsViewportConstrained) { | 292 if (newStyleIsViewportConstained != oldStyleIsViewportConstrained) { |
272 if (newStyleIsViewportConstained && layer()) | 293 if (newStyleIsViewportConstained && layer()) |
273 frameView->addViewportConstrainedObject(this); | 294 frameView->addViewportConstrainedObject(this); |
274 else | 295 else |
275 frameView->removeViewportConstrainedObject(this); | 296 frameView->removeViewportConstrainedObject(this); |
276 } | 297 } |
277 } | 298 } |
278 } | 299 } |
279 | 300 |
280 void LayoutBoxModelObject::createLayer(PaintLayerType type) | 301 void LayoutBoxModelObject::createLayer(PaintLayerType type) |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 { | 354 { |
334 if (TransformOperation* translate = style.translate()) { | 355 if (TransformOperation* translate = style.translate()) { |
335 if (translate->dependsOnBoxSize()) | 356 if (translate->dependsOnBoxSize()) |
336 return true; | 357 return true; |
337 } | 358 } |
338 return style.transform().dependsOnBoxSize() | 359 return style.transform().dependsOnBoxSize() |
339 || (style.transformOriginX() != Length(50, Percent) && style.transformOr
iginX().hasPercent()) | 360 || (style.transformOriginX() != Length(50, Percent) && style.transformOr
iginX().hasPercent()) |
340 || (style.transformOriginY() != Length(50, Percent) && style.transformOr
iginY().hasPercent()); | 361 || (style.transformOriginY() != Length(50, Percent) && style.transformOr
iginY().hasPercent()); |
341 } | 362 } |
342 | 363 |
| 364 void LayoutBoxModelObject::invalidateScrollAncestorConstraints() |
| 365 { |
| 366 if (!layer()) |
| 367 return; |
| 368 // This intentionally uses the stale ancestor overflow layer compositing |
| 369 // input as if we have saved constraints for this layer they were saved |
| 370 // in the previous frame. |
| 371 DisableCompositingQueryAsserts disabler; |
| 372 if (const PaintLayer* ancestorScrollingLayer = enclosingLayer()->ancestorOve
rflowLayer()) |
| 373 ancestorScrollingLayer->scrollableArea()->invalidateStickyConstraints(); |
| 374 } |
| 375 |
343 void LayoutBoxModelObject::invalidateTreeIfNeeded(PaintInvalidationState& paintI
nvalidationState) | 376 void LayoutBoxModelObject::invalidateTreeIfNeeded(PaintInvalidationState& paintI
nvalidationState) |
344 { | 377 { |
345 ASSERT(!needsLayout()); | 378 ASSERT(!needsLayout()); |
346 | 379 |
347 if (!shouldCheckForPaintInvalidation(paintInvalidationState)) | 380 if (!shouldCheckForPaintInvalidation(paintInvalidationState)) |
348 return; | 381 return; |
349 | 382 |
350 bool establishesNewPaintInvalidationContainer = isPaintInvalidationContainer
(); | 383 bool establishesNewPaintInvalidationContainer = isPaintInvalidationContainer
(); |
351 const LayoutBoxModelObject& newPaintInvalidationContainer = establishesNewPa
intInvalidationContainer ? *this : paintInvalidationState.paintInvalidationConta
iner(); | 384 const LayoutBoxModelObject& newPaintInvalidationContainer = establishesNewPa
intInvalidationContainer ? *this : paintInvalidationState.paintInvalidationConta
iner(); |
352 // FIXME: This assert should be re-enabled when we move paint invalidation t
o after compositing update. crbug.com/360286 | 385 // FIXME: This assert should be re-enabled when we move paint invalidation t
o after compositing update. crbug.com/360286 |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 | 621 |
589 else if (!style()->bottom().isAuto() | 622 else if (!style()->bottom().isAuto() |
590 && (!containingBlock->hasAutoHeightOrContainingBlockWithAutoHeight() | 623 && (!containingBlock->hasAutoHeightOrContainingBlockWithAutoHeight() |
591 || !style()->bottom().hasPercent() | 624 || !style()->bottom().hasPercent() |
592 || containingBlock->stretchesToViewport())) | 625 || containingBlock->stretchesToViewport())) |
593 offset.expand(LayoutUnit(), -valueForLength(style()->bottom(), containin
gBlock->availableHeight())); | 626 offset.expand(LayoutUnit(), -valueForLength(style()->bottom(), containin
gBlock->availableHeight())); |
594 | 627 |
595 return offset; | 628 return offset; |
596 } | 629 } |
597 | 630 |
| 631 void LayoutBoxModelObject::updateStickyPositionConstraints(PaintLayer* ancestorO
verflowLayer) const |
| 632 { |
| 633 const FloatSize constrainingSize = computeStickyConstrainingRect(ancestorOve
rflowLayer).size(); |
| 634 |
| 635 // Remove sticky constraints from old ancestor scroller if there was a chang
e. |
| 636 if (const PaintLayer* oldAncestorOverflowLayer = enclosingLayer()->ancestorO
verflowLayer()) { |
| 637 if (oldAncestorOverflowLayer != ancestorOverflowLayer) |
| 638 oldAncestorOverflowLayer->scrollableArea()->stickyConstraintsMap().r
emove(layer()); |
| 639 } |
| 640 |
| 641 PaintLayerScrollableArea* scrollableArea = ancestorOverflowLayer->scrollable
Area(); |
| 642 StickyPositionScrollingConstraints constraints; |
| 643 FloatSize skippedContainersOffset; |
| 644 LayoutBlock* containingBlock = this->containingBlock(); |
| 645 // Skip anonymous containing blocks. |
| 646 while (containingBlock->isAnonymous()) { |
| 647 skippedContainersOffset += toFloatSize(FloatPoint(containingBlock->frame
Rect().location())); |
| 648 containingBlock = containingBlock->containingBlock(); |
| 649 } |
| 650 LayoutBox* scrollAncestor = ancestorOverflowLayer->isRootLayer() ? nullptr :
toLayoutBox(ancestorOverflowLayer->layoutObject()); |
| 651 |
| 652 LayoutRect containerContentRect = containingBlock->contentBoxRect(); |
| 653 LayoutUnit maxWidth = containingBlock->availableLogicalWidth(); |
| 654 |
| 655 // Sticky positioned element ignore any override logical width on the contai
ning block (as they don't call |
| 656 // containingBlockLogicalWidthForContent). It's unclear whether this is tota
lly fine. |
| 657 // Compute the container-relative area within which the sticky element is al
lowed to move. |
| 658 containerContentRect.contractEdges( |
| 659 minimumValueForLength(style()->marginTop(), maxWidth), |
| 660 minimumValueForLength(style()->marginRight(), maxWidth), |
| 661 minimumValueForLength(style()->marginBottom(), maxWidth), |
| 662 minimumValueForLength(style()->marginLeft(), maxWidth)); |
| 663 |
| 664 // Map to the scroll ancestor. |
| 665 constraints.setScrollContainerRelativeContainingBlockRect(containingBlock->l
ocalToAncestorQuad(FloatRect(containerContentRect), scrollAncestor).boundingBox(
)); |
| 666 |
| 667 FloatRect stickyBoxRect = isLayoutInline() |
| 668 ? FloatRect(toLayoutInline(this)->linesBoundingBox()) |
| 669 : FloatRect(toLayoutBox(this)->frameRect()); |
| 670 FloatRect flippedStickyBoxRect = stickyBoxRect; |
| 671 containingBlock->flipForWritingMode(flippedStickyBoxRect); |
| 672 FloatPoint stickyLocation = flippedStickyBoxRect.location() + skippedContain
ersOffset; |
| 673 |
| 674 // TODO(flackr): Unfortunate to call localToAncestorQuad again, but we can't
just offset from the previously computed rect if there are transforms. |
| 675 // Map to the scroll ancestor. |
| 676 FloatRect scrollContainerRelativeContainerFrame = containingBlock->localToAn
cestorQuad(FloatRect(FloatPoint(), FloatSize(containingBlock->size())), scrollAn
cestor).boundingBox(); |
| 677 |
| 678 // If the containing block is our scroll ancestor, its location will not inc
lude the scroll offset which we need to include as |
| 679 // part of the sticky box rect so we include it here. |
| 680 if (containingBlock->hasOverflowClip()) { |
| 681 FloatSize scrollOffset(toFloatSize(containingBlock->layer()->scrollableA
rea()->adjustedScrollOffset())); |
| 682 stickyLocation -= scrollOffset; |
| 683 } |
| 684 |
| 685 constraints.setScrollContainerRelativeStickyBoxRect(FloatRect(scrollContaine
rRelativeContainerFrame.location() + toFloatSize(stickyLocation), flippedStickyB
oxRect.size())); |
| 686 |
| 687 // We skip the right or top sticky offset if there is not enough space to ho
nor both the left/right or top/bottom offsets. |
| 688 LayoutUnit horizontalOffsets = minimumValueForLength(style()->right(), const
rainingSize.width()) + |
| 689 minimumValueForLength(style()->left(), constrainingSize.width()); |
| 690 bool skipRight = false; |
| 691 bool skipLeft = false; |
| 692 if (!style()->left().isAuto() && !style()->right().isAuto()) { |
| 693 if (horizontalOffsets > containerContentRect.width() |
| 694 || horizontalOffsets + containerContentRect.width() > constrainingSi
ze.width()) { |
| 695 skipRight = style()->isLeftToRightDirection(); |
| 696 skipLeft = !skipRight; |
| 697 } |
| 698 } |
| 699 |
| 700 if (!style()->left().isAuto() && !skipLeft) { |
| 701 constraints.setLeftOffset(minimumValueForLength(style()->left(), constra
iningSize.width())); |
| 702 constraints.addAnchorEdge(StickyPositionScrollingConstraints::AnchorEdge
Left); |
| 703 } |
| 704 |
| 705 if (!style()->right().isAuto() && !skipRight) { |
| 706 constraints.setRightOffset(minimumValueForLength(style()->right(), const
rainingSize.width())); |
| 707 constraints.addAnchorEdge(StickyPositionScrollingConstraints::AnchorEdge
Right); |
| 708 } |
| 709 |
| 710 bool skipBottom = false; |
| 711 // TODO(flackr): Exclude top or bottom edge offset depending on the writing
mode when related |
| 712 // sections are fixed in spec: http://lists.w3.org/Archives/Public/www-style
/2014May/0286.html |
| 713 LayoutUnit verticalOffsets = minimumValueForLength(style()->top(), constrain
ingSize.height()) + |
| 714 minimumValueForLength(style()->bottom(), constrainingSize.height()); |
| 715 if (!style()->top().isAuto() && !style()->bottom().isAuto()) { |
| 716 if (verticalOffsets > containerContentRect.height() |
| 717 || verticalOffsets + containerContentRect.height() > constrainingSiz
e.height()) { |
| 718 skipBottom = true; |
| 719 } |
| 720 } |
| 721 |
| 722 if (!style()->top().isAuto()) { |
| 723 constraints.setTopOffset(minimumValueForLength(style()->top(), constrain
ingSize.height())); |
| 724 constraints.addAnchorEdge(StickyPositionScrollingConstraints::AnchorEdge
Top); |
| 725 } |
| 726 |
| 727 if (!style()->bottom().isAuto() && !skipBottom) { |
| 728 constraints.setBottomOffset(minimumValueForLength(style()->bottom(), con
strainingSize.height())); |
| 729 constraints.addAnchorEdge(StickyPositionScrollingConstraints::AnchorEdge
Bottom); |
| 730 } |
| 731 scrollableArea->stickyConstraintsMap().set(layer(), constraints); |
| 732 } |
| 733 |
| 734 FloatRect LayoutBoxModelObject::computeStickyConstrainingRect(const PaintLayer*
ancestorOverflowLayer) const |
| 735 { |
| 736 if (ancestorOverflowLayer->isRootLayer()) |
| 737 return view()->frameView()->visibleContentRect(); |
| 738 |
| 739 LayoutBox* enclosingClippingBox = toLayoutBox(ancestorOverflowLayer->layoutO
bject()); |
| 740 FloatRect constrainingRect; |
| 741 constrainingRect = FloatRect(enclosingClippingBox->overflowClipRect(LayoutPo
int())); |
| 742 constrainingRect.move(enclosingClippingBox->paddingLeft(), enclosingClipping
Box->paddingTop()); |
| 743 constrainingRect.contract(FloatSize(enclosingClippingBox->paddingLeft() + en
closingClippingBox->paddingRight(), |
| 744 enclosingClippingBox->paddingTop() + enclosingClippingBox->paddingBottom
())); |
| 745 return constrainingRect; |
| 746 } |
| 747 |
| 748 LayoutSize LayoutBoxModelObject::stickyPositionOffset() const |
| 749 { |
| 750 const PaintLayer* ancestorOverflowLayer = enclosingLayer()->ancestorOverflow
Layer(); |
| 751 // TODO: Force compositing input update if we ask for offset before composit
ing inputs have been computed? |
| 752 if (!ancestorOverflowLayer) |
| 753 return LayoutSize(); |
| 754 FloatRect constrainingRect = computeStickyConstrainingRect(ancestorOverflowL
ayer); |
| 755 PaintLayerScrollableArea* scrollableArea = ancestorOverflowLayer->scrollable
Area(); |
| 756 |
| 757 // The sticky offset is physical, so we can just return the delta computed i
n absolute coords (though it may be wrong with transforms). |
| 758 // TODO: Force compositing input update if we ask for offset with stale comp
ositing inputs. |
| 759 if (!scrollableArea->stickyConstraintsMap().contains(layer())) |
| 760 return LayoutSize(); |
| 761 return LayoutSize(scrollableArea->stickyConstraintsMap().get(layer()).comput
eStickyOffset(constrainingRect)); |
| 762 } |
| 763 |
598 LayoutPoint LayoutBoxModelObject::adjustedPositionRelativeToOffsetParent(const L
ayoutPoint& startPoint) const | 764 LayoutPoint LayoutBoxModelObject::adjustedPositionRelativeToOffsetParent(const L
ayoutPoint& startPoint) const |
599 { | 765 { |
600 // If the element is the HTML body element or doesn't have a parent | 766 // If the element is the HTML body element or doesn't have a parent |
601 // return 0 and stop this algorithm. | 767 // return 0 and stop this algorithm. |
602 if (isBody() || !parent()) | 768 if (isBody() || !parent()) |
603 return LayoutPoint(); | 769 return LayoutPoint(); |
604 | 770 |
605 LayoutPoint referencePoint = startPoint; | 771 LayoutPoint referencePoint = startPoint; |
606 referencePoint.move(parent()->columnOffset(referencePoint)); | 772 referencePoint.move(parent()->columnOffset(referencePoint)); |
607 | 773 |
608 // If the offsetParent of the element is null, or is the HTML body element, | 774 // If the offsetParent of the element is null, or is the HTML body element, |
609 // return the distance between the canvas origin and the left border edge | 775 // return the distance between the canvas origin and the left border edge |
610 // of the element and stop this algorithm. | 776 // of the element and stop this algorithm. |
611 Element* element = offsetParent(); | 777 Element* element = offsetParent(); |
612 if (!element) | 778 if (!element) |
613 return referencePoint; | 779 return referencePoint; |
614 | 780 |
615 if (const LayoutBoxModelObject* offsetParent = element->layoutBoxModelObject
()) { | 781 if (const LayoutBoxModelObject* offsetParent = element->layoutBoxModelObject
()) { |
616 if (offsetParent->isBox() && !offsetParent->isBody()) | 782 if (offsetParent->isBox() && !offsetParent->isBody()) |
617 referencePoint.move(-toLayoutBox(offsetParent)->borderLeft(), -toLay
outBox(offsetParent)->borderTop()); | 783 referencePoint.move(-toLayoutBox(offsetParent)->borderLeft(), -toLay
outBox(offsetParent)->borderTop()); |
618 if (!isOutOfFlowPositioned() || flowThreadContainingBlock()) { | 784 if (!isOutOfFlowPositioned() || flowThreadContainingBlock()) { |
619 if (isInFlowPositioned()) | 785 if (isInFlowPositioned()) |
620 referencePoint.move(relativePositionOffset()); | 786 referencePoint.move(offsetForInFlowPosition()); |
621 | 787 |
622 LayoutObject* current; | 788 LayoutObject* current; |
623 for (current = parent(); current != offsetParent && current->parent(
); current = current->parent()) { | 789 for (current = parent(); current != offsetParent && current->parent(
); current = current->parent()) { |
624 // FIXME: What are we supposed to do inside SVG content? | 790 // FIXME: What are we supposed to do inside SVG content? |
625 if (!isOutOfFlowPositioned()) { | 791 if (!isOutOfFlowPositioned()) { |
626 if (current->isBox() && !current->isTableRow()) | 792 if (current->isBox() && !current->isTableRow()) |
627 referencePoint.moveBy(toLayoutBox(current)->topLeftLocat
ion()); | 793 referencePoint.moveBy(toLayoutBox(current)->topLeftLocat
ion()); |
628 referencePoint.move(current->parent()->columnOffset(referenc
ePoint)); | 794 referencePoint.move(current->parent()->columnOffset(referenc
ePoint)); |
629 } | 795 } |
630 } | 796 } |
631 | 797 |
632 if (offsetParent->isBox() && offsetParent->isBody() && !offsetParent
->isPositioned()) | 798 if (offsetParent->isBox() && offsetParent->isBody() && !offsetParent
->isPositioned()) |
633 referencePoint.moveBy(toLayoutBox(offsetParent)->topLeftLocation
()); | 799 referencePoint.moveBy(toLayoutBox(offsetParent)->topLeftLocation
()); |
634 } | 800 } |
635 } | 801 } |
636 | 802 |
637 return referencePoint; | 803 return referencePoint; |
638 } | 804 } |
639 | 805 |
640 LayoutSize LayoutBoxModelObject::offsetForInFlowPosition() const | 806 LayoutSize LayoutBoxModelObject::offsetForInFlowPosition() const |
641 { | 807 { |
642 return isRelPositioned() ? relativePositionOffset() : LayoutSize(); | 808 if (isRelPositioned()) |
| 809 return relativePositionOffset(); |
| 810 |
| 811 if (isStickyPositioned()) |
| 812 return stickyPositionOffset(); |
| 813 |
| 814 return LayoutSize(); |
643 } | 815 } |
644 | 816 |
645 LayoutUnit LayoutBoxModelObject::offsetLeft() const | 817 LayoutUnit LayoutBoxModelObject::offsetLeft() const |
646 { | 818 { |
647 // Note that LayoutInline and LayoutBox override this to pass a different | 819 // Note that LayoutInline and LayoutBox override this to pass a different |
648 // startPoint to adjustedPositionRelativeToOffsetParent. | 820 // startPoint to adjustedPositionRelativeToOffsetParent. |
649 return adjustedPositionRelativeToOffsetParent(LayoutPoint()).x(); | 821 return adjustedPositionRelativeToOffsetParent(LayoutPoint()).x(); |
650 } | 822 } |
651 | 823 |
652 LayoutUnit LayoutBoxModelObject::offsetTop() const | 824 LayoutUnit LayoutBoxModelObject::offsetTop() const |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
955 const LayoutObject* LayoutBoxModelObject::pushMappingToContainer(const LayoutBox
ModelObject* ancestorToStopAt, LayoutGeometryMap& geometryMap) const | 1127 const LayoutObject* LayoutBoxModelObject::pushMappingToContainer(const LayoutBox
ModelObject* ancestorToStopAt, LayoutGeometryMap& geometryMap) const |
956 { | 1128 { |
957 ASSERT(ancestorToStopAt != this); | 1129 ASSERT(ancestorToStopAt != this); |
958 | 1130 |
959 bool ancestorSkipped; | 1131 bool ancestorSkipped; |
960 LayoutObject* container = this->container(ancestorToStopAt, &ancestorSkipped
); | 1132 LayoutObject* container = this->container(ancestorToStopAt, &ancestorSkipped
); |
961 if (!container) | 1133 if (!container) |
962 return nullptr; | 1134 return nullptr; |
963 | 1135 |
964 bool isInline = isLayoutInline(); | 1136 bool isInline = isLayoutInline(); |
965 bool isFixedPos = !isInline && style()->position() == FixedPosition; | 1137 bool isFixedPosition = !isInline && style()->position() == FixedPosition; |
966 bool hasTransform = !isInline && hasLayer() && layer()->transform(); | 1138 bool hasTransform = !isInline && hasLayer() && layer()->transform(); |
967 | 1139 |
968 LayoutSize adjustmentForSkippedAncestor; | 1140 LayoutSize adjustmentForSkippedAncestor; |
969 if (ancestorSkipped) { | 1141 if (ancestorSkipped) { |
970 // There can't be a transform between paintInvalidationContainer and anc
estorToStopAt, because transforms create containers, so it should be safe | 1142 // There can't be a transform between paintInvalidationContainer and anc
estorToStopAt, because transforms create containers, so it should be safe |
971 // to just subtract the delta between the ancestor and ancestorToStopAt. | 1143 // to just subtract the delta between the ancestor and ancestorToStopAt. |
972 adjustmentForSkippedAncestor = -ancestorToStopAt->offsetFromAncestorCont
ainer(container); | 1144 adjustmentForSkippedAncestor = -ancestorToStopAt->offsetFromAncestorCont
ainer(container); |
973 } | 1145 } |
974 | 1146 |
975 bool offsetDependsOnPoint = false; | 1147 bool offsetDependsOnPoint = false; |
976 LayoutSize containerOffset = offsetFromContainer(container, LayoutPoint(), &
offsetDependsOnPoint); | 1148 LayoutSize containerOffset = offsetFromContainer(container, LayoutPoint(), &
offsetDependsOnPoint); |
| 1149 LayoutSize stickyOffset; |
| 1150 if (style()->position() == StickyPosition) |
| 1151 stickyOffset = offsetForInFlowPosition(); |
977 | 1152 |
978 bool preserve3D = container->style()->preserves3D() || style()->preserves3D(
); | 1153 bool preserve3D = container->style()->preserves3D() || style()->preserves3D(
); |
979 if (shouldUseTransformFromContainer(container)) { | 1154 if (shouldUseTransformFromContainer(container)) { |
980 TransformationMatrix t; | 1155 TransformationMatrix t; |
981 getTransformFromContainer(container, containerOffset, t); | 1156 getTransformFromContainer(container, containerOffset, t); |
982 t.translateRight(adjustmentForSkippedAncestor.width().toFloat(), adjustm
entForSkippedAncestor.height().toFloat()); | 1157 t.translateRight(adjustmentForSkippedAncestor.width().toFloat(), adjustm
entForSkippedAncestor.height().toFloat()); |
983 geometryMap.push(this, t, preserve3D, offsetDependsOnPoint, isFixedPos,
hasTransform); | 1158 geometryMap.push(this, t, preserve3D, offsetDependsOnPoint, isFixedPosit
ion, hasTransform, LayoutSize(), stickyOffset); |
984 } else { | 1159 } else { |
985 containerOffset += adjustmentForSkippedAncestor; | 1160 containerOffset += adjustmentForSkippedAncestor; |
986 geometryMap.push(this, containerOffset, preserve3D, offsetDependsOnPoint
, isFixedPos, hasTransform); | 1161 geometryMap.push(this, containerOffset, preserve3D, offsetDependsOnPoint
, isFixedPosition, hasTransform, LayoutSize(), stickyOffset); |
987 } | 1162 } |
988 | 1163 |
989 return ancestorSkipped ? ancestorToStopAt : container; | 1164 return ancestorSkipped ? ancestorToStopAt : container; |
990 } | 1165 } |
991 | 1166 |
992 void LayoutBoxModelObject::moveChildTo(LayoutBoxModelObject* toBoxModelObject, L
ayoutObject* child, LayoutObject* beforeChild, bool fullRemoveInsert) | 1167 void LayoutBoxModelObject::moveChildTo(LayoutBoxModelObject* toBoxModelObject, L
ayoutObject* child, LayoutObject* beforeChild, bool fullRemoveInsert) |
993 { | 1168 { |
994 // We assume that callers have cleared their positioned objects list for chi
ld moves (!fullRemoveInsert) so the | 1169 // We assume that callers have cleared their positioned objects list for chi
ld moves (!fullRemoveInsert) so the |
995 // positioned layoutObject maps don't become stale. It would be too slow to
do the map lookup on each call. | 1170 // positioned layoutObject maps don't become stale. It would be too slow to
do the map lookup on each call. |
996 ASSERT(!fullRemoveInsert || !isLayoutBlock() || !toLayoutBlock(this)->hasPos
itionedObjects()); | 1171 ASSERT(!fullRemoveInsert || !isLayoutBlock() || !toLayoutBlock(this)->hasPos
itionedObjects()); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1058 if (rootElementStyle->hasBackground()) | 1233 if (rootElementStyle->hasBackground()) |
1059 return false; | 1234 return false; |
1060 | 1235 |
1061 if (node() != document().firstBodyElement()) | 1236 if (node() != document().firstBodyElement()) |
1062 return false; | 1237 return false; |
1063 | 1238 |
1064 return true; | 1239 return true; |
1065 } | 1240 } |
1066 | 1241 |
1067 } // namespace blink | 1242 } // namespace blink |
OLD | NEW |