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

Side by Side Diff: Source/core/layout/LayoutBox.cpp

Issue 1212893005: Add position: sticky as supported position value when CSSStickyPosition is enabled. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 5 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, 2010 Apple Inc. All rights reserv ed. 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv ed.
7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. 7 * Copyright (C) 2013 Adobe Systems Incorporated. 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 1228 matching lines...) Expand 10 before | Expand all | Expand 10 after
1239 { 1239 {
1240 if (!maxDepthToTest) 1240 if (!maxDepthToTest)
1241 return false; 1241 return false;
1242 for (LayoutObject* child = slowFirstChild(); child; child = child->nextSibli ng()) { 1242 for (LayoutObject* child = slowFirstChild(); child; child = child->nextSibli ng()) {
1243 if (!child->isBox()) 1243 if (!child->isBox())
1244 continue; 1244 continue;
1245 LayoutBox* childBox = toLayoutBox(child); 1245 LayoutBox* childBox = toLayoutBox(child);
1246 if (!isCandidateForOpaquenessTest(*childBox)) 1246 if (!isCandidateForOpaquenessTest(*childBox))
1247 continue; 1247 continue;
1248 LayoutPoint childLocation = childBox->location(); 1248 LayoutPoint childLocation = childBox->location();
1249 if (childBox->isRelPositioned()) 1249 if (childBox->isInFlowPositioned())
1250 childLocation.move(childBox->relativePositionOffset()); 1250 childLocation.move(childBox->offsetForInFlowPosition());
1251 LayoutRect childLocalRect = localRect; 1251 LayoutRect childLocalRect = localRect;
1252 childLocalRect.moveBy(-childLocation); 1252 childLocalRect.moveBy(-childLocation);
1253 if (childLocalRect.y() < 0 || childLocalRect.x() < 0) { 1253 if (childLocalRect.y() < 0 || childLocalRect.x() < 0) {
1254 // If there is unobscured area above/left of a static positioned box then the rect is probably not covered. 1254 // If there is unobscured area above/left of a static positioned box then the rect is probably not covered.
1255 if (childBox->style()->position() == StaticPosition) 1255 if (childBox->style()->position() == StaticPosition)
1256 return false; 1256 return false;
1257 continue; 1257 continue;
1258 } 1258 }
1259 if (childLocalRect.maxY() > childBox->size().height() || childLocalRect. maxX() > childBox->size().width()) 1259 if (childLocalRect.maxY() > childBox->size().height() || childLocalRect. maxX() > childBox->size().width())
1260 continue; 1260 continue;
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
1630 } 1630 }
1631 1631
1632 LayoutBoxModelObject::mapAbsoluteToLocalPoint(mode, transformState); 1632 LayoutBoxModelObject::mapAbsoluteToLocalPoint(mode, transformState);
1633 } 1633 }
1634 1634
1635 LayoutSize LayoutBox::offsetFromContainer(const LayoutObject* o, const LayoutPoi nt& point, bool* offsetDependsOnPoint) const 1635 LayoutSize LayoutBox::offsetFromContainer(const LayoutObject* o, const LayoutPoi nt& point, bool* offsetDependsOnPoint) const
1636 { 1636 {
1637 ASSERT(o == container()); 1637 ASSERT(o == container());
1638 1638
1639 LayoutSize offset; 1639 LayoutSize offset;
1640 if (isRelPositioned()) 1640 if (isInFlowPositioned())
1641 offset += offsetForInFlowPosition(); 1641 offset += offsetForInFlowPosition();
1642 1642
1643 if (!isInline() || isReplaced()) { 1643 if (!isInline() || isReplaced()) {
1644 offset += topLeftLocationOffset(); 1644 offset += topLeftLocationOffset();
1645 if (o->isLayoutFlowThread()) { 1645 if (o->isLayoutFlowThread()) {
1646 // So far the point has been in flow thread coordinates (i.e. as if everything in 1646 // So far the point has been in flow thread coordinates (i.e. as if everything in
1647 // the fragmentation context lived in one tall single column). Conve rt it to a 1647 // the fragmentation context lived in one tall single column). Conve rt it to a
1648 // visual point now. 1648 // visual point now.
1649 LayoutPoint pointInContainer = point + offset; 1649 LayoutPoint pointInContainer = point + offset;
1650 offset += o->columnOffset(pointInContainer); 1650 offset += o->columnOffset(pointInContainer);
1651 if (offsetDependsOnPoint) 1651 if (offsetDependsOnPoint)
1652 *offsetDependsOnPoint = true; 1652 *offsetDependsOnPoint = true;
1653 } 1653 }
1654 } 1654 }
1655 1655
1656 if (o->hasOverflowClip()) 1656 if (o->hasOverflowClip())
1657 offset -= toLayoutBox(o)->scrolledContentOffset(); 1657 offset -= toLayoutBox(o)->scrolledContentOffset();
1658 1658
1659 if (style()->position() == AbsolutePosition && o->isRelPositioned() && o->is LayoutInline()) 1659 if (style()->position() == AbsolutePosition && o->isInFlowPositioned() && o- >isLayoutInline())
1660 offset += toLayoutInline(o)->offsetForInFlowPositionedInline(*this); 1660 offset += toLayoutInline(o)->offsetForInFlowPositionedInline(*this);
1661 1661
1662 return offset; 1662 return offset;
1663 } 1663 }
1664 1664
1665 InlineBox* LayoutBox::createInlineBox() 1665 InlineBox* LayoutBox::createInlineBox()
1666 { 1666 {
1667 return new InlineBox(*this); 1667 return new InlineBox(*this);
1668 } 1668 }
1669 1669
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1708 } else if (isReplaced()) { 1708 } else if (isReplaced()) {
1709 // FIXME: the call to roundedLayoutPoint() below is temporary and should be removed once 1709 // FIXME: the call to roundedLayoutPoint() below is temporary and should be removed once
1710 // the transition to LayoutUnit-based types is complete (crbug.com/32123 7) 1710 // the transition to LayoutUnit-based types is complete (crbug.com/32123 7)
1711 setLocationAndUpdateOverflowControlsIfNeeded(box->topLeft()); 1711 setLocationAndUpdateOverflowControlsIfNeeded(box->topLeft());
1712 setInlineBoxWrapper(box); 1712 setInlineBoxWrapper(box);
1713 } 1713 }
1714 } 1714 }
1715 1715
1716 void LayoutBox::moveWithEdgeOfInlineContainerIfNecessary(bool isHorizontal) 1716 void LayoutBox::moveWithEdgeOfInlineContainerIfNecessary(bool isHorizontal)
1717 { 1717 {
1718 ASSERT(isOutOfFlowPositioned() && container()->isLayoutInline() && container ()->isRelPositioned()); 1718 ASSERT(isOutOfFlowPositioned() && container()->isLayoutInline() && container ()->isInFlowPositioned());
1719 // If this object is inside a relative positioned inline and its inline posi tion is an explicit offset from the edge of its container 1719 // If this object is inside a relative positioned inline and its inline posi tion is an explicit offset from the edge of its container
1720 // then it will need to move if its inline container has changed width. We d o not track if the width has changed 1720 // then it will need to move if its inline container has changed width. We d o not track if the width has changed
1721 // but if we are here then we are laying out lines inside it, so it probably has - mark our object for layout so that it can 1721 // but if we are here then we are laying out lines inside it, so it probably has - mark our object for layout so that it can
1722 // move to the new offset created by the new width. 1722 // move to the new offset created by the new width.
1723 if (!normalChildNeedsLayout() && !style()->hasStaticInlinePosition(isHorizon tal)) 1723 if (!normalChildNeedsLayout() && !style()->hasStaticInlinePosition(isHorizon tal))
1724 setChildNeedsLayout(MarkOnlyThis); 1724 setChildNeedsLayout(MarkOnlyThis);
1725 } 1725 }
1726 1726
1727 void LayoutBox::deleteLineBoxWrapper() 1727 void LayoutBox::deleteLineBoxWrapper()
1728 { 1728 {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1814 topLeft.move(locationOffset()); 1814 topLeft.move(locationOffset());
1815 1815
1816 // We are now in our parent container's coordinate space. Apply our transfo rm to obtain a bounding box 1816 // We are now in our parent container's coordinate space. Apply our transfo rm to obtain a bounding box
1817 // in the parent's coordinate space that encloses us. 1817 // in the parent's coordinate space that encloses us.
1818 if (hasLayer() && layer()->transform()) { 1818 if (hasLayer() && layer()->transform()) {
1819 rect = LayoutRect(layer()->transform()->mapRect(pixelSnappedIntRect(rect ))); 1819 rect = LayoutRect(layer()->transform()->mapRect(pixelSnappedIntRect(rect )));
1820 topLeft = rect.location(); 1820 topLeft = rect.location();
1821 topLeft.move(locationOffset()); 1821 topLeft.move(locationOffset());
1822 } 1822 }
1823 1823
1824 if (position == AbsolutePosition && o->isRelPositioned() && o->isLayoutInlin e()) { 1824 if (position == AbsolutePosition && o->isInFlowPositioned() && o->isLayoutIn line()) {
1825 topLeft += toLayoutInline(o)->offsetForInFlowPositionedInline(*this); 1825 topLeft += toLayoutInline(o)->offsetForInFlowPositionedInline(*this);
1826 } else if (styleToUse.hasInFlowPosition() && layer()) { 1826 } else if (styleToUse.hasInFlowPosition() && layer()) {
1827 // Apply the relative position offset when invalidating a rectangle. Th e layer 1827 // Apply the relative position offset when invalidating a rectangle. Th e layer
1828 // is translated, but the layout box isn't, so we need to do this to get the 1828 // is translated, but the layout box isn't, so we need to do this to get the
1829 // right dirty rect. Since this is called from LayoutObject::setStyle, the relative position 1829 // right dirty rect. Since this is called from LayoutObject::setStyle, the relative position
1830 // flag on the LayoutObject has been cleared, so use the one on the styl e(). 1830 // flag on the LayoutObject has been cleared, so use the one on the styl e().
1831 topLeft += layer()->offsetForInFlowPosition(); 1831 topLeft += layer()->offsetForInFlowPosition();
1832 } 1832 }
1833 1833
1834 // FIXME: We ignore the lightweight clipping rect that controls use, since i f |o| is in mid-layout, 1834 // FIXME: We ignore the lightweight clipping rect that controls use, since i f |o| is in mid-layout,
(...skipping 901 matching lines...) Expand 10 before | Expand all | Expand 10 after
2736 return containingBlock->isHorizontalWritingMode() ? viewportRect.wid th() : viewportRect.height(); 2736 return containingBlock->isHorizontalWritingMode() ? viewportRect.wid th() : viewportRect.height();
2737 } 2737 }
2738 } 2738 }
2739 2739
2740 if (hasOverrideContainingBlockLogicalWidth()) 2740 if (hasOverrideContainingBlockLogicalWidth())
2741 return overrideContainingBlockContentLogicalWidth(); 2741 return overrideContainingBlockContentLogicalWidth();
2742 2742
2743 if (containingBlock->isBox()) 2743 if (containingBlock->isBox())
2744 return toLayoutBox(containingBlock)->clientLogicalWidth(); 2744 return toLayoutBox(containingBlock)->clientLogicalWidth();
2745 2745
2746 ASSERT(containingBlock->isLayoutInline() && containingBlock->isRelPositioned ()); 2746 ASSERT(containingBlock->isLayoutInline() && containingBlock->isInFlowPositio ned());
2747 2747
2748 const LayoutInline* flow = toLayoutInline(containingBlock); 2748 const LayoutInline* flow = toLayoutInline(containingBlock);
2749 InlineFlowBox* first = flow->firstLineBox(); 2749 InlineFlowBox* first = flow->firstLineBox();
2750 InlineFlowBox* last = flow->lastLineBox(); 2750 InlineFlowBox* last = flow->lastLineBox();
2751 2751
2752 // If the containing block is empty, return a width of 0. 2752 // If the containing block is empty, return a width of 0.
2753 if (!first || !last) 2753 if (!first || !last)
2754 return LayoutUnit(); 2754 return LayoutUnit();
2755 2755
2756 LayoutUnit fromLeft; 2756 LayoutUnit fromLeft;
(...skipping 25 matching lines...) Expand all
2782 2782
2783 if (hasOverrideContainingBlockLogicalHeight()) 2783 if (hasOverrideContainingBlockLogicalHeight())
2784 return overrideContainingBlockContentLogicalHeight(); 2784 return overrideContainingBlockContentLogicalHeight();
2785 2785
2786 if (containingBlock->isBox()) { 2786 if (containingBlock->isBox()) {
2787 const LayoutBlock* cb = containingBlock->isLayoutBlock() ? 2787 const LayoutBlock* cb = containingBlock->isLayoutBlock() ?
2788 toLayoutBlock(containingBlock) : containingBlock->containingBlock(); 2788 toLayoutBlock(containingBlock) : containingBlock->containingBlock();
2789 return cb->clientLogicalHeight(); 2789 return cb->clientLogicalHeight();
2790 } 2790 }
2791 2791
2792 ASSERT(containingBlock->isLayoutInline() && containingBlock->isRelPositioned ()); 2792 ASSERT(containingBlock->isLayoutInline() && containingBlock->isInFlowPositio ned());
2793 2793
2794 const LayoutInline* flow = toLayoutInline(containingBlock); 2794 const LayoutInline* flow = toLayoutInline(containingBlock);
2795 InlineFlowBox* first = flow->firstLineBox(); 2795 InlineFlowBox* first = flow->firstLineBox();
2796 InlineFlowBox* last = flow->lastLineBox(); 2796 InlineFlowBox* last = flow->lastLineBox();
2797 2797
2798 // If the containing block is empty, return a height of 0. 2798 // If the containing block is empty, return a height of 0.
2799 if (!first || !last) 2799 if (!first || !last)
2800 return LayoutUnit(); 2800 return LayoutUnit();
2801 2801
2802 LayoutUnit heightResult; 2802 LayoutUnit heightResult;
(...skipping 10 matching lines...) Expand all
2813 { 2813 {
2814 if (!logicalLeft.isAuto() || !logicalRight.isAuto()) 2814 if (!logicalLeft.isAuto() || !logicalRight.isAuto())
2815 return; 2815 return;
2816 2816
2817 // FIXME: The static distance computation has not been patched for mixed wri ting modes yet. 2817 // FIXME: The static distance computation has not been patched for mixed wri ting modes yet.
2818 if (child->parent()->style()->direction() == LTR) { 2818 if (child->parent()->style()->direction() == LTR) {
2819 LayoutUnit staticPosition = child->layer()->staticInlinePosition() - con tainerBlock->borderLogicalLeft(); 2819 LayoutUnit staticPosition = child->layer()->staticInlinePosition() - con tainerBlock->borderLogicalLeft();
2820 for (LayoutObject* curr = child->parent(); curr && curr != containerBloc k; curr = curr->container()) { 2820 for (LayoutObject* curr = child->parent(); curr && curr != containerBloc k; curr = curr->container()) {
2821 if (curr->isBox()) { 2821 if (curr->isBox()) {
2822 staticPosition += toLayoutBox(curr)->logicalLeft(); 2822 staticPosition += toLayoutBox(curr)->logicalLeft();
2823 if (toLayoutBox(curr)->isRelPositioned()) 2823 if (toLayoutBox(curr)->isInFlowPositioned())
2824 staticPosition += toLayoutBox(curr)->relativePositionOffset( ).width(); 2824 staticPosition += toLayoutBox(curr)->offsetForInFlowPosition ().width();
2825 } else if (curr->isInline()) { 2825 } else if (curr->isInline()) {
2826 if (curr->isRelPositioned()) { 2826 if (curr->isInFlowPositioned()) {
2827 if (!curr->style()->logicalLeft().isAuto()) 2827 if (!curr->style()->logicalLeft().isAuto())
2828 staticPosition += valueForLength(curr->style()->logicalL eft(), curr->containingBlock()->availableWidth()); 2828 staticPosition += valueForLength(curr->style()->logicalL eft(), curr->containingBlock()->availableWidth());
2829 else 2829 else
2830 staticPosition -= valueForLength(curr->style()->logicalR ight(), curr->containingBlock()->availableWidth()); 2830 staticPosition -= valueForLength(curr->style()->logicalR ight(), curr->containingBlock()->availableWidth());
2831 } 2831 }
2832 } 2832 }
2833 } 2833 }
2834 logicalLeft.setValue(Fixed, staticPosition); 2834 logicalLeft.setValue(Fixed, staticPosition);
2835 } else { 2835 } else {
2836 LayoutBox* enclosingBox = child->parent()->enclosingBox(); 2836 LayoutBox* enclosingBox = child->parent()->enclosingBox();
2837 LayoutUnit staticPosition = child->layer()->staticInlinePosition() + con tainerLogicalWidth + containerBlock->borderLogicalLeft(); 2837 LayoutUnit staticPosition = child->layer()->staticInlinePosition() + con tainerLogicalWidth + containerBlock->borderLogicalLeft();
2838 for (LayoutObject* curr = child->parent(); curr; curr = curr->container( )) { 2838 for (LayoutObject* curr = child->parent(); curr; curr = curr->container( )) {
2839 if (curr->isBox()) { 2839 if (curr->isBox()) {
2840 if (curr != containerBlock) { 2840 if (curr != containerBlock) {
2841 staticPosition -= toLayoutBox(curr)->logicalLeft(); 2841 staticPosition -= toLayoutBox(curr)->logicalLeft();
2842 if (toLayoutBox(curr)->isRelPositioned()) 2842 if (toLayoutBox(curr)->isInFlowPositioned())
2843 staticPosition -= toLayoutBox(curr)->relativePositionOff set().width(); 2843 staticPosition -= toLayoutBox(curr)->offsetForInFlowPosi tion().width();
2844 } 2844 }
2845 if (curr == enclosingBox) 2845 if (curr == enclosingBox)
2846 staticPosition -= enclosingBox->logicalWidth(); 2846 staticPosition -= enclosingBox->logicalWidth();
2847 } else if (curr->isInline()) { 2847 } else if (curr->isInline()) {
2848 if (curr->isRelPositioned()) { 2848 if (curr->isInFlowPositioned()) {
2849 if (!curr->style()->logicalLeft().isAuto()) 2849 if (!curr->style()->logicalLeft().isAuto())
2850 staticPosition -= valueForLength(curr->style()->logicalL eft(), curr->containingBlock()->availableWidth()); 2850 staticPosition -= valueForLength(curr->style()->logicalL eft(), curr->containingBlock()->availableWidth());
2851 else 2851 else
2852 staticPosition += valueForLength(curr->style()->logicalR ight(), curr->containingBlock()->availableWidth()); 2852 staticPosition += valueForLength(curr->style()->logicalR ight(), curr->containingBlock()->availableWidth());
2853 } 2853 }
2854 } 2854 }
2855 if (curr == containerBlock) 2855 if (curr == containerBlock)
2856 break; 2856 break;
2857 } 2857 }
2858 logicalRight.setValue(Fixed, staticPosition); 2858 logicalRight.setValue(Fixed, staticPosition);
(...skipping 1560 matching lines...) Expand 10 before | Expand all | Expand 10 after
4419 LayoutRect rect = borderBoxRect(); 4419 LayoutRect rect = borderBoxRect();
4420 // We want to include the margin, but only when it adds height. Quirky margi ns don't contribute height 4420 // We want to include the margin, but only when it adds height. Quirky margi ns don't contribute height
4421 // nor do the margins of self-collapsing blocks. 4421 // nor do the margins of self-collapsing blocks.
4422 if (!styleRef().hasMarginAfterQuirk() && !isSelfCollapsingBlock()) 4422 if (!styleRef().hasMarginAfterQuirk() && !isSelfCollapsingBlock())
4423 rect.expand(isHorizontalWritingMode() ? LayoutSize(LayoutUnit(), marginA fter()) : LayoutSize(marginAfter(), LayoutUnit())); 4423 rect.expand(isHorizontalWritingMode() ? LayoutSize(LayoutUnit(), marginA fter()) : LayoutSize(marginAfter(), LayoutUnit()));
4424 4424
4425 if (!hasOverflowClip()) 4425 if (!hasOverflowClip())
4426 rect.unite(layoutOverflowRect()); 4426 rect.unite(layoutOverflowRect());
4427 4427
4428 bool hasTransform = hasLayer() && layer()->transform(); 4428 bool hasTransform = hasLayer() && layer()->transform();
4429 if (isRelPositioned() || hasTransform) { 4429 if (isInFlowPositioned() || hasTransform) {
4430 // If we are relatively positioned or if we have a transform, then we ha ve to convert 4430 // If we are relatively positioned or if we have a transform, then we ha ve to convert
4431 // this rectangle into physical coordinates, apply relative positioning and transforms 4431 // this rectangle into physical coordinates, apply relative positioning and transforms
4432 // to it, and then convert it back. 4432 // to it, and then convert it back.
4433 flipForWritingMode(rect); 4433 flipForWritingMode(rect);
4434 4434
4435 if (hasTransform) 4435 if (hasTransform)
4436 rect = layer()->currentTransform().mapRect(rect); 4436 rect = layer()->currentTransform().mapRect(rect);
4437 4437
4438 if (isRelPositioned()) 4438 if (isInFlowPositioned())
4439 rect.move(offsetForInFlowPosition()); 4439 rect.move(offsetForInFlowPosition());
4440 4440
4441 // Now we need to flip back. 4441 // Now we need to flip back.
4442 flipForWritingMode(rect); 4442 flipForWritingMode(rect);
4443 } 4443 }
4444 4444
4445 // If the writing modes of the child and parent match, then we don't have to 4445 // If the writing modes of the child and parent match, then we don't have to
4446 // do anything fancy. Just return the result. 4446 // do anything fancy. Just return the result.
4447 if (parentStyle.writingMode() == style()->writingMode()) 4447 if (parentStyle.writingMode() == style()->writingMode())
4448 return rect; 4448 return rect;
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
4771 bool LayoutBox::canRenderBorderImage() const 4771 bool LayoutBox::canRenderBorderImage() const
4772 { 4772 {
4773 if (!style()->hasBorderDecoration()) 4773 if (!style()->hasBorderDecoration())
4774 return false; 4774 return false;
4775 4775
4776 StyleImage* borderImage = style()->borderImage().image(); 4776 StyleImage* borderImage = style()->borderImage().image();
4777 return borderImage && borderImage->canRender(*this, style()->effectiveZoom() ) && borderImage->isLoaded(); 4777 return borderImage && borderImage->canRender(*this, style()->effectiveZoom() ) && borderImage->isLoaded();
4778 } 4778 }
4779 4779
4780 } // namespace blink 4780 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698