Chromium Code Reviews| 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 static inline LayoutBox* findScrollAncestor(const LayoutObject* startObject) | |
| 632 { | |
| 633 PaintLayer* layer = startObject->enclosingLayer(); | |
| 634 const PaintLayer* scrollAncestor = layer->ancestorOverflowLayer(); | |
| 635 if (!scrollAncestor || scrollAncestor->isRootLayer()) | |
| 636 return nullptr; | |
| 637 return toLayoutBox(scrollAncestor->layoutObject()); | |
| 638 } | |
| 639 | |
| 640 const StickyPositionScrollingConstraints& LayoutBoxModelObject::ensureStickyPosi tionConstraints(const FloatSize& constrainingSize) const | |
| 641 { | |
| 642 const PaintLayer* scrollAncestorLayer = enclosingLayer()->ancestorOverflowLa yer(); | |
| 643 PaintLayerScrollableArea* scrollableArea = enclosingLayer()->ancestorOverflo wLayer()->scrollableArea(); | |
| 644 auto addResult = scrollableArea->stickyConstraintsMap().add(layer(), StickyP ositionScrollingConstraints()); | |
| 645 StickyPositionScrollingConstraints& constraints = addResult.storedValue->val ue; | |
| 646 if (!addResult.isNewEntry) | |
| 647 return constraints; | |
| 648 | |
| 649 FloatSize skippedContainersOffset; | |
| 650 LayoutBlock* containingBlock = this->containingBlock(); | |
| 651 // Skip anonymous containing blocks. | |
| 652 while (containingBlock->isAnonymous()) { | |
| 653 skippedContainersOffset += toFloatSize(FloatPoint(containingBlock->frame Rect().location())); | |
| 654 containingBlock = containingBlock->containingBlock(); | |
| 655 } | |
| 656 LayoutBox* scrollAncestor = scrollAncestorLayer->isRootLayer() ? nullptr : t oLayoutBox(scrollAncestorLayer->layoutObject()); | |
| 657 | |
| 658 LayoutRect containerContentRect = containingBlock->contentBoxRect(); | |
| 659 LayoutUnit maxWidth = containingBlock->availableLogicalWidth(); | |
| 660 | |
| 661 // Sticky positioned element ignore any override logical width on the contai ning block (as they don't call | |
| 662 // containingBlockLogicalWidthForContent). It's unclear whether this is tota lly fine. | |
| 663 // Compute the container-relative area within which the sticky element is al lowed to move. | |
| 664 containerContentRect.contractEdges( | |
| 665 minimumValueForLength(style()->marginTop(), maxWidth), | |
| 666 minimumValueForLength(style()->marginRight(), maxWidth), | |
| 667 minimumValueForLength(style()->marginBottom(), maxWidth), | |
| 668 minimumValueForLength(style()->marginLeft(), maxWidth)); | |
| 669 | |
| 670 // Map to the scroll ancestor. | |
| 671 constraints.setScrollContainerRelativeContainingBlockRect(containingBlock->l ocalToAncestorQuad(FloatRect(containerContentRect), scrollAncestor).boundingBox( )); | |
| 672 | |
| 673 FloatRect stickyBoxRect = isLayoutInline() | |
| 674 ? FloatRect(toLayoutInline(this)->linesBoundingBox()) | |
| 675 : FloatRect(toLayoutBox(this)->frameRect()); | |
| 676 FloatRect flippedStickyBoxRect = stickyBoxRect; | |
| 677 containingBlock->flipForWritingMode(flippedStickyBoxRect); | |
| 678 FloatPoint stickyLocation = flippedStickyBoxRect.location() + skippedContain ersOffset; | |
| 679 | |
| 680 // TODO(flackr): Unfortunate to call localToAncestorQuad again, but we can't just offset from the previously computed rect if there are transforms. | |
| 681 // Map to the scroll ancestor. | |
| 682 FloatRect scrollContainerRelativeContainerFrame = containingBlock->localToAn cestorQuad(FloatRect(FloatPoint(), FloatSize(containingBlock->size())), scrollAn cestor).boundingBox(); | |
|
chrishtr
2016/02/23 16:31:51
For these localToAncestor* methods, you should con
flackr
2016/03/07 19:07:33
I think we actually want neither, but I will think
| |
| 683 | |
| 684 // If the containing block is our scroll ancestor, its location will not inc lude the scroll offset which we need to include as | |
| 685 // part of the sticky box rect so we include it here. | |
| 686 if (containingBlock->hasOverflowClip()) { | |
| 687 FloatSize scrollOffset(toFloatSize(containingBlock->layer()->scrollableA rea()->adjustedScrollOffset())); | |
| 688 stickyLocation -= scrollOffset; | |
| 689 } | |
| 690 | |
| 691 constraints.setScrollContainerRelativeStickyBoxRect(FloatRect(scrollContaine rRelativeContainerFrame.location() + toFloatSize(stickyLocation), flippedStickyB oxRect.size())); | |
| 692 | |
| 693 // 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. | |
| 694 LayoutUnit horizontalOffsets = minimumValueForLength(style()->right(), const rainingSize.width()) + | |
| 695 minimumValueForLength(style()->left(), constrainingSize.width()); | |
| 696 bool skipRight = false; | |
| 697 bool skipLeft = false; | |
| 698 if (!style()->left().isAuto() && !style()->right().isAuto()) { | |
| 699 if (horizontalOffsets > containerContentRect.width() | |
| 700 || horizontalOffsets + containerContentRect.width() > constrainingSi ze.width()) { | |
| 701 skipRight = style()->isLeftToRightDirection(); | |
| 702 skipLeft = !skipRight; | |
| 703 } | |
| 704 } | |
| 705 | |
| 706 if (!style()->left().isAuto() && !skipLeft) { | |
| 707 constraints.setLeftOffset(minimumValueForLength(style()->left(), constra iningSize.width())); | |
| 708 constraints.addAnchorEdge(StickyPositionScrollingConstraints::AnchorEdge Left); | |
| 709 } | |
| 710 | |
| 711 if (!style()->right().isAuto() && !skipRight) { | |
| 712 constraints.setRightOffset(minimumValueForLength(style()->right(), const rainingSize.width())); | |
| 713 constraints.addAnchorEdge(StickyPositionScrollingConstraints::AnchorEdge Right); | |
| 714 } | |
| 715 | |
| 716 bool skipBottom = false; | |
| 717 // TODO(flackr): Exclude top or bottom edge offset depending on the writing mode when related | |
| 718 // sections are fixed in spec: http://lists.w3.org/Archives/Public/www-style /2014May/0286.html | |
| 719 LayoutUnit verticalOffsets = minimumValueForLength(style()->top(), constrain ingSize.height()) + | |
| 720 minimumValueForLength(style()->bottom(), constrainingSize.height()); | |
| 721 if (!style()->top().isAuto() && !style()->bottom().isAuto()) { | |
| 722 if (verticalOffsets > containerContentRect.height() | |
| 723 || verticalOffsets + containerContentRect.height() > constrainingSiz e.height()) { | |
| 724 skipBottom = true; | |
| 725 } | |
| 726 } | |
| 727 | |
| 728 if (!style()->top().isAuto()) { | |
| 729 constraints.setTopOffset(minimumValueForLength(style()->top(), constrain ingSize.height())); | |
| 730 constraints.addAnchorEdge(StickyPositionScrollingConstraints::AnchorEdge Top); | |
| 731 } | |
| 732 | |
| 733 if (!style()->bottom().isAuto() && !skipBottom) { | |
| 734 constraints.setBottomOffset(minimumValueForLength(style()->bottom(), con strainingSize.height())); | |
| 735 constraints.addAnchorEdge(StickyPositionScrollingConstraints::AnchorEdge Bottom); | |
| 736 } | |
| 737 return constraints; | |
| 738 } | |
| 739 | |
| 740 FloatRect LayoutBoxModelObject::computeStickyConstrainingRect() const | |
| 741 { | |
| 742 FloatRect constrainingRect; | |
| 743 | |
| 744 ASSERT(hasLayer()); | |
| 745 LayoutBox* enclosingClippingBox = findScrollAncestor(this); | |
| 746 if (enclosingClippingBox) { | |
| 747 constrainingRect = FloatRect(enclosingClippingBox->overflowClipRect(Layo utPoint())); | |
| 748 constrainingRect.move(enclosingClippingBox->paddingLeft(), enclosingClip pingBox->paddingTop()); | |
| 749 constrainingRect.contract(FloatSize(enclosingClippingBox->paddingLeft() + enclosingClippingBox->paddingRight(), | |
| 750 enclosingClippingBox->paddingTop() + enclosingClippingBox->paddingBo ttom())); | |
| 751 } else { | |
| 752 constrainingRect = view()->frameView()->visibleContentRect(); | |
| 753 } | |
| 754 | |
| 755 return constrainingRect; | |
| 756 } | |
| 757 | |
| 758 LayoutSize LayoutBoxModelObject::stickyPositionOffset() const | |
| 759 { | |
| 760 // TODO: Force compositing input update if we ask for offset before this is | |
| 761 // ready rather than returning no offset or stale offset. | |
| 762 if (layer()->needsCompositingInputsUpdate()) | |
| 763 return LayoutSize(); | |
| 764 FloatRect constrainingRect = computeStickyConstrainingRect(); | |
| 765 const StickyPositionScrollingConstraints& constraints = ensureStickyPosition Constraints(constrainingRect.size()); | |
| 766 | |
| 767 // The sticky offset is physical, so we can just return the delta computed i n absolute coords (though it may be wrong with transforms). | |
| 768 return LayoutSize(constraints.computeStickyOffset(constrainingRect)); | |
| 769 } | |
| 770 | |
| 598 LayoutPoint LayoutBoxModelObject::adjustedPositionRelativeToOffsetParent(const L ayoutPoint& startPoint) const | 771 LayoutPoint LayoutBoxModelObject::adjustedPositionRelativeToOffsetParent(const L ayoutPoint& startPoint) const |
| 599 { | 772 { |
| 600 // If the element is the HTML body element or doesn't have a parent | 773 // If the element is the HTML body element or doesn't have a parent |
| 601 // return 0 and stop this algorithm. | 774 // return 0 and stop this algorithm. |
| 602 if (isBody() || !parent()) | 775 if (isBody() || !parent()) |
| 603 return LayoutPoint(); | 776 return LayoutPoint(); |
| 604 | 777 |
| 605 LayoutPoint referencePoint = startPoint; | 778 LayoutPoint referencePoint = startPoint; |
| 606 referencePoint.move(parent()->columnOffset(referencePoint)); | 779 referencePoint.move(parent()->columnOffset(referencePoint)); |
| 607 | 780 |
| 608 // If the offsetParent of the element is null, or is the HTML body element, | 781 // 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 | 782 // return the distance between the canvas origin and the left border edge |
| 610 // of the element and stop this algorithm. | 783 // of the element and stop this algorithm. |
| 611 Element* element = offsetParent(); | 784 Element* element = offsetParent(); |
| 612 if (!element) | 785 if (!element) |
| 613 return referencePoint; | 786 return referencePoint; |
| 614 | 787 |
| 615 if (const LayoutBoxModelObject* offsetParent = element->layoutBoxModelObject ()) { | 788 if (const LayoutBoxModelObject* offsetParent = element->layoutBoxModelObject ()) { |
| 616 if (offsetParent->isBox() && !offsetParent->isBody()) | 789 if (offsetParent->isBox() && !offsetParent->isBody()) |
| 617 referencePoint.move(-toLayoutBox(offsetParent)->borderLeft(), -toLay outBox(offsetParent)->borderTop()); | 790 referencePoint.move(-toLayoutBox(offsetParent)->borderLeft(), -toLay outBox(offsetParent)->borderTop()); |
| 618 if (!isOutOfFlowPositioned() || flowThreadContainingBlock()) { | 791 if (!isOutOfFlowPositioned() || flowThreadContainingBlock()) { |
| 619 if (isInFlowPositioned()) | 792 if (isInFlowPositioned()) |
| 620 referencePoint.move(relativePositionOffset()); | 793 referencePoint.move(offsetForInFlowPosition()); |
| 621 | 794 |
| 622 LayoutObject* current; | 795 LayoutObject* current; |
| 623 for (current = parent(); current != offsetParent && current->parent( ); current = current->parent()) { | 796 for (current = parent(); current != offsetParent && current->parent( ); current = current->parent()) { |
| 624 // FIXME: What are we supposed to do inside SVG content? | 797 // FIXME: What are we supposed to do inside SVG content? |
| 625 if (!isOutOfFlowPositioned()) { | 798 if (!isOutOfFlowPositioned()) { |
| 626 if (current->isBox() && !current->isTableRow()) | 799 if (current->isBox() && !current->isTableRow()) |
| 627 referencePoint.moveBy(toLayoutBox(current)->topLeftLocat ion()); | 800 referencePoint.moveBy(toLayoutBox(current)->topLeftLocat ion()); |
| 628 referencePoint.move(current->parent()->columnOffset(referenc ePoint)); | 801 referencePoint.move(current->parent()->columnOffset(referenc ePoint)); |
| 629 } | 802 } |
| 630 } | 803 } |
| 631 | 804 |
| 632 if (offsetParent->isBox() && offsetParent->isBody() && !offsetParent ->isPositioned()) | 805 if (offsetParent->isBox() && offsetParent->isBody() && !offsetParent ->isPositioned()) |
| 633 referencePoint.moveBy(toLayoutBox(offsetParent)->topLeftLocation ()); | 806 referencePoint.moveBy(toLayoutBox(offsetParent)->topLeftLocation ()); |
| 634 } | 807 } |
| 635 } | 808 } |
| 636 | 809 |
| 637 return referencePoint; | 810 return referencePoint; |
| 638 } | 811 } |
| 639 | 812 |
| 640 LayoutSize LayoutBoxModelObject::offsetForInFlowPosition() const | 813 LayoutSize LayoutBoxModelObject::offsetForInFlowPosition() const |
| 641 { | 814 { |
| 642 return isRelPositioned() ? relativePositionOffset() : LayoutSize(); | 815 if (isRelPositioned()) |
| 816 return relativePositionOffset(); | |
| 817 | |
| 818 if (isStickyPositioned()) | |
| 819 return stickyPositionOffset(); | |
| 820 | |
| 821 return LayoutSize(); | |
| 643 } | 822 } |
| 644 | 823 |
| 645 LayoutUnit LayoutBoxModelObject::offsetLeft() const | 824 LayoutUnit LayoutBoxModelObject::offsetLeft() const |
| 646 { | 825 { |
| 647 // Note that LayoutInline and LayoutBox override this to pass a different | 826 // Note that LayoutInline and LayoutBox override this to pass a different |
| 648 // startPoint to adjustedPositionRelativeToOffsetParent. | 827 // startPoint to adjustedPositionRelativeToOffsetParent. |
| 649 return adjustedPositionRelativeToOffsetParent(LayoutPoint()).x(); | 828 return adjustedPositionRelativeToOffsetParent(LayoutPoint()).x(); |
| 650 } | 829 } |
| 651 | 830 |
| 652 LayoutUnit LayoutBoxModelObject::offsetTop() const | 831 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 | 1134 const LayoutObject* LayoutBoxModelObject::pushMappingToContainer(const LayoutBox ModelObject* ancestorToStopAt, LayoutGeometryMap& geometryMap) const |
| 956 { | 1135 { |
| 957 ASSERT(ancestorToStopAt != this); | 1136 ASSERT(ancestorToStopAt != this); |
| 958 | 1137 |
| 959 bool ancestorSkipped; | 1138 bool ancestorSkipped; |
| 960 LayoutObject* container = this->container(ancestorToStopAt, &ancestorSkipped ); | 1139 LayoutObject* container = this->container(ancestorToStopAt, &ancestorSkipped ); |
| 961 if (!container) | 1140 if (!container) |
| 962 return nullptr; | 1141 return nullptr; |
| 963 | 1142 |
| 964 bool isInline = isLayoutInline(); | 1143 bool isInline = isLayoutInline(); |
| 965 bool isFixedPos = !isInline && style()->position() == FixedPosition; | 1144 bool isFixedPosition = !isInline && style()->position() == FixedPosition; |
| 966 bool hasTransform = !isInline && hasLayer() && layer()->transform(); | 1145 bool hasTransform = !isInline && hasLayer() && layer()->transform(); |
| 967 | 1146 |
| 968 LayoutSize adjustmentForSkippedAncestor; | 1147 LayoutSize adjustmentForSkippedAncestor; |
| 969 if (ancestorSkipped) { | 1148 if (ancestorSkipped) { |
| 970 // There can't be a transform between paintInvalidationContainer and anc estorToStopAt, because transforms create containers, so it should be safe | 1149 // 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. | 1150 // to just subtract the delta between the ancestor and ancestorToStopAt. |
| 972 adjustmentForSkippedAncestor = -ancestorToStopAt->offsetFromAncestorCont ainer(container); | 1151 adjustmentForSkippedAncestor = -ancestorToStopAt->offsetFromAncestorCont ainer(container); |
| 973 } | 1152 } |
| 974 | 1153 |
| 975 bool offsetDependsOnPoint = false; | 1154 bool offsetDependsOnPoint = false; |
| 976 LayoutSize containerOffset = offsetFromContainer(container, LayoutPoint(), & offsetDependsOnPoint); | 1155 LayoutSize containerOffset = offsetFromContainer(container, LayoutPoint(), & offsetDependsOnPoint); |
| 1156 LayoutSize stickyOffset; | |
| 1157 if (style()->position() == StickyPosition) | |
| 1158 stickyOffset = offsetForInFlowPosition(); | |
| 977 | 1159 |
| 978 bool preserve3D = container->style()->preserves3D() || style()->preserves3D( ); | 1160 bool preserve3D = container->style()->preserves3D() || style()->preserves3D( ); |
| 979 if (shouldUseTransformFromContainer(container)) { | 1161 if (shouldUseTransformFromContainer(container)) { |
| 980 TransformationMatrix t; | 1162 TransformationMatrix t; |
| 981 getTransformFromContainer(container, containerOffset, t); | 1163 getTransformFromContainer(container, containerOffset, t); |
| 982 t.translateRight(adjustmentForSkippedAncestor.width().toFloat(), adjustm entForSkippedAncestor.height().toFloat()); | 1164 t.translateRight(adjustmentForSkippedAncestor.width().toFloat(), adjustm entForSkippedAncestor.height().toFloat()); |
| 983 geometryMap.push(this, t, preserve3D, offsetDependsOnPoint, isFixedPos, hasTransform); | 1165 geometryMap.push(this, t, preserve3D, offsetDependsOnPoint, isFixedPosit ion, hasTransform, LayoutSize(), stickyOffset); |
| 984 } else { | 1166 } else { |
| 985 containerOffset += adjustmentForSkippedAncestor; | 1167 containerOffset += adjustmentForSkippedAncestor; |
| 986 geometryMap.push(this, containerOffset, preserve3D, offsetDependsOnPoint , isFixedPos, hasTransform); | 1168 geometryMap.push(this, containerOffset, preserve3D, offsetDependsOnPoint , isFixedPosition, hasTransform, LayoutSize(), stickyOffset); |
| 987 } | 1169 } |
| 988 | 1170 |
| 989 return ancestorSkipped ? ancestorToStopAt : container; | 1171 return ancestorSkipped ? ancestorToStopAt : container; |
| 990 } | 1172 } |
| 991 | 1173 |
| 992 void LayoutBoxModelObject::moveChildTo(LayoutBoxModelObject* toBoxModelObject, L ayoutObject* child, LayoutObject* beforeChild, bool fullRemoveInsert) | 1174 void LayoutBoxModelObject::moveChildTo(LayoutBoxModelObject* toBoxModelObject, L ayoutObject* child, LayoutObject* beforeChild, bool fullRemoveInsert) |
| 993 { | 1175 { |
| 994 // We assume that callers have cleared their positioned objects list for chi ld moves (!fullRemoveInsert) so the | 1176 // 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. | 1177 // 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()); | 1178 ASSERT(!fullRemoveInsert || !isLayoutBlock() || !toLayoutBlock(this)->hasPos itionedObjects()); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1058 if (rootElementStyle->hasBackground()) | 1240 if (rootElementStyle->hasBackground()) |
| 1059 return false; | 1241 return false; |
| 1060 | 1242 |
| 1061 if (node() != document().firstBodyElement()) | 1243 if (node() != document().firstBodyElement()) |
| 1062 return false; | 1244 return false; |
| 1063 | 1245 |
| 1064 return true; | 1246 return true; |
| 1065 } | 1247 } |
| 1066 | 1248 |
| 1067 } // namespace blink | 1249 } // namespace blink |
| OLD | NEW |