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

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: Comments and merge. 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 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
1607 } 1607 }
1608 1608
1609 LayoutBoxModelObject::mapAbsoluteToLocalPoint(mode, transformState); 1609 LayoutBoxModelObject::mapAbsoluteToLocalPoint(mode, transformState);
1610 } 1610 }
1611 1611
1612 LayoutSize LayoutBox::offsetFromContainer(const LayoutObject* o, const LayoutPoi nt& point, bool* offsetDependsOnPoint) const 1612 LayoutSize LayoutBox::offsetFromContainer(const LayoutObject* o, const LayoutPoi nt& point, bool* offsetDependsOnPoint) const
1613 { 1613 {
1614 ASSERT(o == container()); 1614 ASSERT(o == container());
1615 1615
1616 LayoutSize offset; 1616 LayoutSize offset;
1617 if (isRelPositioned()) 1617 if (isInFlowPositioned())
1618 offset += offsetForInFlowPosition(); 1618 offset += offsetForInFlowPosition();
1619 1619
1620 if (!isInline() || isReplaced()) { 1620 if (!isInline() || isReplaced()) {
1621 offset += topLeftLocationOffset(); 1621 offset += topLeftLocationOffset();
1622 if (o->isLayoutFlowThread()) { 1622 if (o->isLayoutFlowThread()) {
1623 // So far the point has been in flow thread coordinates (i.e. as if everything in 1623 // So far the point has been in flow thread coordinates (i.e. as if everything in
1624 // the fragmentation context lived in one tall single column). Conve rt it to a 1624 // the fragmentation context lived in one tall single column). Conve rt it to a
1625 // visual point now. 1625 // visual point now.
1626 LayoutPoint pointInContainer = point + offset; 1626 LayoutPoint pointInContainer = point + offset;
1627 offset += o->columnOffset(pointInContainer); 1627 offset += o->columnOffset(pointInContainer);
1628 if (offsetDependsOnPoint) 1628 if (offsetDependsOnPoint)
1629 *offsetDependsOnPoint = true; 1629 *offsetDependsOnPoint = true;
1630 } 1630 }
1631 } 1631 }
1632 1632
1633 if (o->hasOverflowClip()) 1633 if (o->hasOverflowClip())
1634 offset -= toLayoutBox(o)->scrolledContentOffset(); 1634 offset -= toLayoutBox(o)->scrolledContentOffset();
1635 1635
1636 if (style()->position() == AbsolutePosition && o->isRelPositioned() && o->is LayoutInline()) 1636 if (style()->position() == AbsolutePosition && o->isInFlowPositioned() && o- >isLayoutInline())
1637 offset += toLayoutInline(o)->offsetForInFlowPositionedInline(*this); 1637 offset += toLayoutInline(o)->offsetForInFlowPositionedInline(*this);
1638 1638
1639 return offset; 1639 return offset;
1640 } 1640 }
1641 1641
1642 InlineBox* LayoutBox::createInlineBox() 1642 InlineBox* LayoutBox::createInlineBox()
1643 { 1643 {
1644 return new InlineBox(*this); 1644 return new InlineBox(*this);
1645 } 1645 }
1646 1646
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1685 } else if (isReplaced()) { 1685 } else if (isReplaced()) {
1686 // FIXME: the call to roundedLayoutPoint() below is temporary and should be removed once 1686 // FIXME: the call to roundedLayoutPoint() below is temporary and should be removed once
1687 // the transition to LayoutUnit-based types is complete (crbug.com/32123 7) 1687 // the transition to LayoutUnit-based types is complete (crbug.com/32123 7)
1688 setLocationAndUpdateOverflowControlsIfNeeded(box->topLeft()); 1688 setLocationAndUpdateOverflowControlsIfNeeded(box->topLeft());
1689 setInlineBoxWrapper(box); 1689 setInlineBoxWrapper(box);
1690 } 1690 }
1691 } 1691 }
1692 1692
1693 void LayoutBox::moveWithEdgeOfInlineContainerIfNecessary(bool isHorizontal) 1693 void LayoutBox::moveWithEdgeOfInlineContainerIfNecessary(bool isHorizontal)
1694 { 1694 {
1695 ASSERT(isOutOfFlowPositioned() && container()->isLayoutInline() && container ()->isRelPositioned()); 1695 ASSERT(isOutOfFlowPositioned() && container()->isLayoutInline() && container ()->isInFlowPositioned());
1696 // If this object is inside a relative positioned inline and its inline posi tion is an explicit offset from the edge of its container 1696 // If this object is inside a relative positioned inline and its inline posi tion is an explicit offset from the edge of its container
1697 // then it will need to move if its inline container has changed width. We d o not track if the width has changed 1697 // then it will need to move if its inline container has changed width. We d o not track if the width has changed
1698 // 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 1698 // 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
1699 // move to the new offset created by the new width. 1699 // move to the new offset created by the new width.
1700 if (!normalChildNeedsLayout() && !style()->hasStaticInlinePosition(isHorizon tal)) 1700 if (!normalChildNeedsLayout() && !style()->hasStaticInlinePosition(isHorizon tal))
1701 setChildNeedsLayout(MarkOnlyThis); 1701 setChildNeedsLayout(MarkOnlyThis);
1702 } 1702 }
1703 1703
1704 void LayoutBox::deleteLineBoxWrapper() 1704 void LayoutBox::deleteLineBoxWrapper()
1705 { 1705 {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1791 topLeft.move(locationOffset()); 1791 topLeft.move(locationOffset());
1792 1792
1793 // We are now in our parent container's coordinate space. Apply our transfo rm to obtain a bounding box 1793 // We are now in our parent container's coordinate space. Apply our transfo rm to obtain a bounding box
1794 // in the parent's coordinate space that encloses us. 1794 // in the parent's coordinate space that encloses us.
1795 if (hasLayer() && layer()->transform()) { 1795 if (hasLayer() && layer()->transform()) {
1796 rect = LayoutRect(layer()->transform()->mapRect(pixelSnappedIntRect(rect ))); 1796 rect = LayoutRect(layer()->transform()->mapRect(pixelSnappedIntRect(rect )));
1797 topLeft = rect.location(); 1797 topLeft = rect.location();
1798 topLeft.move(locationOffset()); 1798 topLeft.move(locationOffset());
1799 } 1799 }
1800 1800
1801 if (position == AbsolutePosition && o->isRelPositioned() && o->isLayoutInlin e()) { 1801 if (position == AbsolutePosition && o->isInFlowPositioned() && o->isLayoutIn line()) {
1802 topLeft += toLayoutInline(o)->offsetForInFlowPositionedInline(*this); 1802 topLeft += toLayoutInline(o)->offsetForInFlowPositionedInline(*this);
1803 } else if (styleToUse.hasInFlowPosition() && layer()) { 1803 } else if (styleToUse.hasInFlowPosition() && layer()) {
1804 // Apply the relative position offset when invalidating a rectangle. Th e layer 1804 // Apply the relative position offset when invalidating a rectangle. Th e layer
1805 // is translated, but the layout box isn't, so we need to do this to get the 1805 // is translated, but the layout box isn't, so we need to do this to get the
1806 // right dirty rect. Since this is called from LayoutObject::setStyle, the relative position 1806 // right dirty rect. Since this is called from LayoutObject::setStyle, the relative position
1807 // flag on the LayoutObject has been cleared, so use the one on the styl e(). 1807 // flag on the LayoutObject has been cleared, so use the one on the styl e().
1808 topLeft += layer()->offsetForInFlowPosition(); 1808 topLeft += layer()->offsetForInFlowPosition();
1809 } 1809 }
1810 1810
1811 // FIXME: We ignore the lightweight clipping rect that controls use, since i f |o| is in mid-layout, 1811 // 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
2713 return containingBlock->isHorizontalWritingMode() ? viewportRect.wid th() : viewportRect.height(); 2713 return containingBlock->isHorizontalWritingMode() ? viewportRect.wid th() : viewportRect.height();
2714 } 2714 }
2715 } 2715 }
2716 2716
2717 if (hasOverrideContainingBlockLogicalWidth()) 2717 if (hasOverrideContainingBlockLogicalWidth())
2718 return overrideContainingBlockContentLogicalWidth(); 2718 return overrideContainingBlockContentLogicalWidth();
2719 2719
2720 if (containingBlock->isBox()) 2720 if (containingBlock->isBox())
2721 return toLayoutBox(containingBlock)->clientLogicalWidth(); 2721 return toLayoutBox(containingBlock)->clientLogicalWidth();
2722 2722
2723 ASSERT(containingBlock->isLayoutInline() && containingBlock->isRelPositioned ()); 2723 ASSERT(containingBlock->isLayoutInline() && containingBlock->isInFlowPositio ned());
2724 2724
2725 const LayoutInline* flow = toLayoutInline(containingBlock); 2725 const LayoutInline* flow = toLayoutInline(containingBlock);
2726 InlineFlowBox* first = flow->firstLineBox(); 2726 InlineFlowBox* first = flow->firstLineBox();
2727 InlineFlowBox* last = flow->lastLineBox(); 2727 InlineFlowBox* last = flow->lastLineBox();
2728 2728
2729 // If the containing block is empty, return a width of 0. 2729 // If the containing block is empty, return a width of 0.
2730 if (!first || !last) 2730 if (!first || !last)
2731 return LayoutUnit(); 2731 return LayoutUnit();
2732 2732
2733 LayoutUnit fromLeft; 2733 LayoutUnit fromLeft;
(...skipping 25 matching lines...) Expand all
2759 2759
2760 if (hasOverrideContainingBlockLogicalHeight()) 2760 if (hasOverrideContainingBlockLogicalHeight())
2761 return overrideContainingBlockContentLogicalHeight(); 2761 return overrideContainingBlockContentLogicalHeight();
2762 2762
2763 if (containingBlock->isBox()) { 2763 if (containingBlock->isBox()) {
2764 const LayoutBlock* cb = containingBlock->isLayoutBlock() ? 2764 const LayoutBlock* cb = containingBlock->isLayoutBlock() ?
2765 toLayoutBlock(containingBlock) : containingBlock->containingBlock(); 2765 toLayoutBlock(containingBlock) : containingBlock->containingBlock();
2766 return cb->clientLogicalHeight(); 2766 return cb->clientLogicalHeight();
2767 } 2767 }
2768 2768
2769 ASSERT(containingBlock->isLayoutInline() && containingBlock->isRelPositioned ()); 2769 ASSERT(containingBlock->isLayoutInline() && containingBlock->isInFlowPositio ned());
2770 2770
2771 const LayoutInline* flow = toLayoutInline(containingBlock); 2771 const LayoutInline* flow = toLayoutInline(containingBlock);
2772 InlineFlowBox* first = flow->firstLineBox(); 2772 InlineFlowBox* first = flow->firstLineBox();
2773 InlineFlowBox* last = flow->lastLineBox(); 2773 InlineFlowBox* last = flow->lastLineBox();
2774 2774
2775 // If the containing block is empty, return a height of 0. 2775 // If the containing block is empty, return a height of 0.
2776 if (!first || !last) 2776 if (!first || !last)
2777 return LayoutUnit(); 2777 return LayoutUnit();
2778 2778
2779 LayoutUnit heightResult; 2779 LayoutUnit heightResult;
(...skipping 10 matching lines...) Expand all
2790 { 2790 {
2791 if (!logicalLeft.isAuto() || !logicalRight.isAuto()) 2791 if (!logicalLeft.isAuto() || !logicalRight.isAuto())
2792 return; 2792 return;
2793 2793
2794 // FIXME: The static distance computation has not been patched for mixed wri ting modes yet. 2794 // FIXME: The static distance computation has not been patched for mixed wri ting modes yet.
2795 if (child->parent()->style()->direction() == LTR) { 2795 if (child->parent()->style()->direction() == LTR) {
2796 LayoutUnit staticPosition = child->layer()->staticInlinePosition() - con tainerBlock->borderLogicalLeft(); 2796 LayoutUnit staticPosition = child->layer()->staticInlinePosition() - con tainerBlock->borderLogicalLeft();
2797 for (LayoutObject* curr = child->parent(); curr && curr != containerBloc k; curr = curr->container()) { 2797 for (LayoutObject* curr = child->parent(); curr && curr != containerBloc k; curr = curr->container()) {
2798 if (curr->isBox()) { 2798 if (curr->isBox()) {
2799 staticPosition += toLayoutBox(curr)->logicalLeft(); 2799 staticPosition += toLayoutBox(curr)->logicalLeft();
2800 if (toLayoutBox(curr)->isRelPositioned()) 2800 if (toLayoutBox(curr)->isInFlowPositioned())
2801 staticPosition += toLayoutBox(curr)->relativePositionOffset( ).width(); 2801 staticPosition += toLayoutBox(curr)->offsetForInFlowPosition ().width();
2802 } else if (curr->isInline()) { 2802 } else if (curr->isInline()) {
2803 if (curr->isRelPositioned()) { 2803 if (curr->isInFlowPositioned()) {
2804 if (!curr->style()->logicalLeft().isAuto()) 2804 if (!curr->style()->logicalLeft().isAuto())
2805 staticPosition += valueForLength(curr->style()->logicalL eft(), curr->containingBlock()->availableWidth()); 2805 staticPosition += valueForLength(curr->style()->logicalL eft(), curr->containingBlock()->availableWidth());
2806 else 2806 else
2807 staticPosition -= valueForLength(curr->style()->logicalR ight(), curr->containingBlock()->availableWidth()); 2807 staticPosition -= valueForLength(curr->style()->logicalR ight(), curr->containingBlock()->availableWidth());
2808 } 2808 }
2809 } 2809 }
2810 } 2810 }
2811 logicalLeft.setValue(Fixed, staticPosition); 2811 logicalLeft.setValue(Fixed, staticPosition);
2812 } else { 2812 } else {
2813 LayoutBox* enclosingBox = child->parent()->enclosingBox(); 2813 LayoutBox* enclosingBox = child->parent()->enclosingBox();
2814 LayoutUnit staticPosition = child->layer()->staticInlinePosition() + con tainerLogicalWidth + containerBlock->borderLogicalLeft(); 2814 LayoutUnit staticPosition = child->layer()->staticInlinePosition() + con tainerLogicalWidth + containerBlock->borderLogicalLeft();
2815 for (LayoutObject* curr = child->parent(); curr; curr = curr->container( )) { 2815 for (LayoutObject* curr = child->parent(); curr; curr = curr->container( )) {
2816 if (curr->isBox()) { 2816 if (curr->isBox()) {
2817 if (curr != containerBlock) { 2817 if (curr != containerBlock) {
2818 staticPosition -= toLayoutBox(curr)->logicalLeft(); 2818 staticPosition -= toLayoutBox(curr)->logicalLeft();
2819 if (toLayoutBox(curr)->isRelPositioned()) 2819 if (toLayoutBox(curr)->isInFlowPositioned())
2820 staticPosition -= toLayoutBox(curr)->relativePositionOff set().width(); 2820 staticPosition -= toLayoutBox(curr)->offsetForInFlowPosi tion().width();
2821 } 2821 }
2822 if (curr == enclosingBox) 2822 if (curr == enclosingBox)
2823 staticPosition -= enclosingBox->logicalWidth(); 2823 staticPosition -= enclosingBox->logicalWidth();
2824 } else if (curr->isInline()) { 2824 } else if (curr->isInline()) {
2825 if (curr->isRelPositioned()) { 2825 if (curr->isInFlowPositioned()) {
2826 if (!curr->style()->logicalLeft().isAuto()) 2826 if (!curr->style()->logicalLeft().isAuto())
2827 staticPosition -= valueForLength(curr->style()->logicalL eft(), curr->containingBlock()->availableWidth()); 2827 staticPosition -= valueForLength(curr->style()->logicalL eft(), curr->containingBlock()->availableWidth());
2828 else 2828 else
2829 staticPosition += valueForLength(curr->style()->logicalR ight(), curr->containingBlock()->availableWidth()); 2829 staticPosition += valueForLength(curr->style()->logicalR ight(), curr->containingBlock()->availableWidth());
2830 } 2830 }
2831 } 2831 }
2832 if (curr == containerBlock) 2832 if (curr == containerBlock)
2833 break; 2833 break;
2834 } 2834 }
2835 logicalRight.setValue(Fixed, staticPosition); 2835 logicalRight.setValue(Fixed, staticPosition);
(...skipping 1560 matching lines...) Expand 10 before | Expand all | Expand 10 after
4396 LayoutRect rect = borderBoxRect(); 4396 LayoutRect rect = borderBoxRect();
4397 // We want to include the margin, but only when it adds height. Quirky margi ns don't contribute height 4397 // We want to include the margin, but only when it adds height. Quirky margi ns don't contribute height
4398 // nor do the margins of self-collapsing blocks. 4398 // nor do the margins of self-collapsing blocks.
4399 if (!styleRef().hasMarginAfterQuirk() && !isSelfCollapsingBlock()) 4399 if (!styleRef().hasMarginAfterQuirk() && !isSelfCollapsingBlock())
4400 rect.expand(isHorizontalWritingMode() ? LayoutSize(LayoutUnit(), marginA fter()) : LayoutSize(marginAfter(), LayoutUnit())); 4400 rect.expand(isHorizontalWritingMode() ? LayoutSize(LayoutUnit(), marginA fter()) : LayoutSize(marginAfter(), LayoutUnit()));
4401 4401
4402 if (!hasOverflowClip()) 4402 if (!hasOverflowClip())
4403 rect.unite(layoutOverflowRect()); 4403 rect.unite(layoutOverflowRect());
4404 4404
4405 bool hasTransform = hasLayer() && layer()->transform(); 4405 bool hasTransform = hasLayer() && layer()->transform();
4406 if (isRelPositioned() || hasTransform) { 4406 if (isInFlowPositioned() || hasTransform) {
4407 // If we are relatively positioned or if we have a transform, then we ha ve to convert 4407 // If we are relatively positioned or if we have a transform, then we ha ve to convert
4408 // this rectangle into physical coordinates, apply relative positioning and transforms 4408 // this rectangle into physical coordinates, apply relative positioning and transforms
4409 // to it, and then convert it back. 4409 // to it, and then convert it back.
4410 flipForWritingMode(rect); 4410 flipForWritingMode(rect);
4411 4411
4412 if (hasTransform) 4412 if (hasTransform)
4413 rect = layer()->currentTransform().mapRect(rect); 4413 rect = layer()->currentTransform().mapRect(rect);
4414 4414
4415 if (isRelPositioned()) 4415 if (isInFlowPositioned())
4416 rect.move(offsetForInFlowPosition()); 4416 rect.move(offsetForInFlowPosition());
4417 4417
4418 // Now we need to flip back. 4418 // Now we need to flip back.
4419 flipForWritingMode(rect); 4419 flipForWritingMode(rect);
4420 } 4420 }
4421 4421
4422 // If the writing modes of the child and parent match, then we don't have to 4422 // If the writing modes of the child and parent match, then we don't have to
4423 // do anything fancy. Just return the result. 4423 // do anything fancy. Just return the result.
4424 if (parentStyle.writingMode() == style()->writingMode()) 4424 if (parentStyle.writingMode() == style()->writingMode())
4425 return rect; 4425 return rect;
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
4748 bool LayoutBox::canRenderBorderImage() const 4748 bool LayoutBox::canRenderBorderImage() const
4749 { 4749 {
4750 if (!style()->hasBorderDecoration()) 4750 if (!style()->hasBorderDecoration())
4751 return false; 4751 return false;
4752 4752
4753 StyleImage* borderImage = style()->borderImage().image(); 4753 StyleImage* borderImage = style()->borderImage().image();
4754 return borderImage && borderImage->canRender(*this, style()->effectiveZoom() ) && borderImage->isLoaded(); 4754 return borderImage && borderImage->canRender(*this, style()->effectiveZoom() ) && borderImage->isLoaded();
4755 } 4755 }
4756 4756
4757 } // namespace blink 4757 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698