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) 2007 David Smith (catfish.man@gmail.com) | 4 * (C) 2007 David Smith (catfish.man@gmail.com) |
5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
All rights reserved. | 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
All rights reserved. |
6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
7 * | 7 * |
8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
(...skipping 1521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1532 addVisualOverflow(inflatedRect); | 1532 addVisualOverflow(inflatedRect); |
1533 } | 1533 } |
1534 | 1534 |
1535 bool RenderBlock::createsNewFormattingContext() const | 1535 bool RenderBlock::createsNewFormattingContext() const |
1536 { | 1536 { |
1537 return isInlineBlockOrInlineTable() || isFloatingOrOutOfFlowPositioned() ||
hasOverflowClip() || isFlexItemIncludingDeprecated() | 1537 return isInlineBlockOrInlineTable() || isFloatingOrOutOfFlowPositioned() ||
hasOverflowClip() || isFlexItemIncludingDeprecated() |
1538 || style()->specifiesColumns() || isRenderFlowThread() || isTableCell()
|| isTableCaption() || isFieldset() || isWritingModeRoot() | 1538 || style()->specifiesColumns() || isRenderFlowThread() || isTableCell()
|| isTableCaption() || isFieldset() || isWritingModeRoot() |
1539 || isDocumentElement() || style()->columnSpan() || isGridItem(); | 1539 || isDocumentElement() || style()->columnSpan() || isGridItem(); |
1540 } | 1540 } |
1541 | 1541 |
1542 void RenderBlock::updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, R
enderBox* child) | 1542 void RenderBlock::updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, R
enderBox& child) |
1543 { | 1543 { |
1544 // FIXME: Technically percentage height objects only need a relayout if thei
r percentage isn't going to be turned into | 1544 // FIXME: Technically percentage height objects only need a relayout if thei
r percentage isn't going to be turned into |
1545 // an auto value. Add a method to determine this, so that we can avoid the r
elayout. | 1545 // an auto value. Add a method to determine this, so that we can avoid the r
elayout. |
1546 if (relayoutChildren || (child->hasRelativeLogicalHeight() && !isRenderView(
))) | 1546 if (relayoutChildren || (child.hasRelativeLogicalHeight() && !isRenderView()
)) |
1547 child->setChildNeedsLayout(MarkOnlyThis); | 1547 child.setChildNeedsLayout(MarkOnlyThis); |
1548 | 1548 |
1549 // If relayoutChildren is set and the child has percentage padding or an emb
edded content box, we also need to invalidate the childs pref widths. | 1549 // If relayoutChildren is set and the child has percentage padding or an emb
edded content box, we also need to invalidate the childs pref widths. |
1550 if (relayoutChildren && child->needsPreferredWidthsRecalculation()) | 1550 if (relayoutChildren && child.needsPreferredWidthsRecalculation()) |
1551 child->setPreferredLogicalWidthsDirty(MarkOnlyThis); | 1551 child.setPreferredLogicalWidthsDirty(MarkOnlyThis); |
1552 } | 1552 } |
1553 | 1553 |
1554 void RenderBlock::simplifiedNormalFlowLayout() | 1554 void RenderBlock::simplifiedNormalFlowLayout() |
1555 { | 1555 { |
1556 if (childrenInline()) { | 1556 if (childrenInline()) { |
1557 ListHashSet<RootInlineBox*> lineBoxes; | 1557 ListHashSet<RootInlineBox*> lineBoxes; |
1558 for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) { | 1558 for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) { |
1559 RenderObject* o = walker.current(); | 1559 RenderObject* o = walker.current(); |
1560 if (!o->isOutOfFlowPositioned() && (o->isReplaced() || o->isFloating
())) { | 1560 if (!o->isOutOfFlowPositioned() && (o->isReplaced() || o->isFloating
())) { |
1561 o->layoutIfNeeded(); | 1561 o->layoutIfNeeded(); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1658 if (newLeft != box->logicalLeft()) | 1658 if (newLeft != box->logicalLeft()) |
1659 layoutScope.setChildNeedsLayout(child); | 1659 layoutScope.setChildNeedsLayout(child); |
1660 } else if (hasStaticBlockPosition) { | 1660 } else if (hasStaticBlockPosition) { |
1661 LayoutUnit oldTop = box->logicalTop(); | 1661 LayoutUnit oldTop = box->logicalTop(); |
1662 box->updateLogicalHeight(); | 1662 box->updateLogicalHeight(); |
1663 if (box->logicalTop() != oldTop) | 1663 if (box->logicalTop() != oldTop) |
1664 layoutScope.setChildNeedsLayout(child); | 1664 layoutScope.setChildNeedsLayout(child); |
1665 } | 1665 } |
1666 } | 1666 } |
1667 | 1667 |
1668 LayoutUnit RenderBlock::marginIntrinsicLogicalWidthForChild(RenderBox* child) co
nst | 1668 LayoutUnit RenderBlock::marginIntrinsicLogicalWidthForChild(RenderBox& child) co
nst |
1669 { | 1669 { |
1670 // A margin has three types: fixed, percentage, and auto (variable). | 1670 // A margin has three types: fixed, percentage, and auto (variable). |
1671 // Auto and percentage margins become 0 when computing min/max width. | 1671 // Auto and percentage margins become 0 when computing min/max width. |
1672 // Fixed margins can be added in as is. | 1672 // Fixed margins can be added in as is. |
1673 Length marginLeft = child->style()->marginStartUsing(style()); | 1673 Length marginLeft = child.style()->marginStartUsing(style()); |
1674 Length marginRight = child->style()->marginEndUsing(style()); | 1674 Length marginRight = child.style()->marginEndUsing(style()); |
1675 LayoutUnit margin = 0; | 1675 LayoutUnit margin = 0; |
1676 if (marginLeft.isFixed()) | 1676 if (marginLeft.isFixed()) |
1677 margin += marginLeft.value(); | 1677 margin += marginLeft.value(); |
1678 if (marginRight.isFixed()) | 1678 if (marginRight.isFixed()) |
1679 margin += marginRight.value(); | 1679 margin += marginRight.value(); |
1680 return margin; | 1680 return margin; |
1681 } | 1681 } |
1682 | 1682 |
1683 void RenderBlock::layoutPositionedObjects(bool relayoutChildren, PositionedLayou
tBehavior info) | 1683 void RenderBlock::layoutPositionedObjects(bool relayoutChildren, PositionedLayou
tBehavior info) |
1684 { | 1684 { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1722 | 1722 |
1723 // If we are paginated or in a line grid, go ahead and compute a vertica
l position for our object now. | 1723 // If we are paginated or in a line grid, go ahead and compute a vertica
l position for our object now. |
1724 // If it's wrong we'll lay out again. | 1724 // If it's wrong we'll lay out again. |
1725 LayoutUnit oldLogicalTop = 0; | 1725 LayoutUnit oldLogicalTop = 0; |
1726 bool needsBlockDirectionLocationSetBeforeLayout = r->needsLayout() && vi
ew()->layoutState()->needsBlockDirectionLocationSetBeforeLayout(); | 1726 bool needsBlockDirectionLocationSetBeforeLayout = r->needsLayout() && vi
ew()->layoutState()->needsBlockDirectionLocationSetBeforeLayout(); |
1727 if (needsBlockDirectionLocationSetBeforeLayout) { | 1727 if (needsBlockDirectionLocationSetBeforeLayout) { |
1728 if (isHorizontalWritingMode() == r->isHorizontalWritingMode()) | 1728 if (isHorizontalWritingMode() == r->isHorizontalWritingMode()) |
1729 r->updateLogicalHeight(); | 1729 r->updateLogicalHeight(); |
1730 else | 1730 else |
1731 r->updateLogicalWidth(); | 1731 r->updateLogicalWidth(); |
1732 oldLogicalTop = logicalTopForChild(r); | 1732 oldLogicalTop = logicalTopForChild(*r); |
1733 } | 1733 } |
1734 | 1734 |
1735 // FIXME: We should be able to do a r->setNeedsPositionedMovementLayout(
) here instead of a full layout. Need | 1735 // FIXME: We should be able to do a r->setNeedsPositionedMovementLayout(
) here instead of a full layout. Need |
1736 // to investigate why it does not trigger the correct invalidations in t
hat case. crbug.com/350756 | 1736 // to investigate why it does not trigger the correct invalidations in t
hat case. crbug.com/350756 |
1737 if (info == ForcedLayoutAfterContainingBlockMoved) | 1737 if (info == ForcedLayoutAfterContainingBlockMoved) |
1738 r->setNeedsLayout(); | 1738 r->setNeedsLayout(); |
1739 | 1739 |
1740 r->layoutIfNeeded(); | 1740 r->layoutIfNeeded(); |
1741 | 1741 |
1742 // Lay out again if our estimate was wrong. | 1742 // Lay out again if our estimate was wrong. |
1743 if (needsBlockDirectionLocationSetBeforeLayout && logicalTopForChild(r)
!= oldLogicalTop) | 1743 if (needsBlockDirectionLocationSetBeforeLayout && logicalTopForChild(*r)
!= oldLogicalTop) |
1744 r->forceChildLayout(); | 1744 r->forceChildLayout(); |
1745 } | 1745 } |
1746 | 1746 |
1747 if (hasColumns()) | 1747 if (hasColumns()) |
1748 view()->layoutState()->setColumnInfo(columnInfo()); // FIXME: Kind of gr
oss. We just put this back into the layout state so that pop() will work. | 1748 view()->layoutState()->setColumnInfo(columnInfo()); // FIXME: Kind of gr
oss. We just put this back into the layout state so that pop() will work. |
1749 } | 1749 } |
1750 | 1750 |
1751 void RenderBlock::markPositionedObjectsForLayout() | 1751 void RenderBlock::markPositionedObjectsForLayout() |
1752 { | 1752 { |
1753 if (TrackedRendererListHashSet* positionedDescendants = positionedObjects())
{ | 1753 if (TrackedRendererListHashSet* positionedDescendants = positionedObjects())
{ |
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2419 // If they don't agree, then we return a visible position just before or aft
er the child | 2419 // If they don't agree, then we return a visible position just before or aft
er the child |
2420 RenderObject* ancestor = parent; | 2420 RenderObject* ancestor = parent; |
2421 while (ancestor && !ancestor->nonPseudoNode()) | 2421 while (ancestor && !ancestor->nonPseudoNode()) |
2422 ancestor = ancestor->parent(); | 2422 ancestor = ancestor->parent(); |
2423 | 2423 |
2424 // If we can't find an ancestor to check editability on, or editability is u
nchanged, we recur like normal | 2424 // If we can't find an ancestor to check editability on, or editability is u
nchanged, we recur like normal |
2425 if (isEditingBoundary(ancestor, child)) | 2425 if (isEditingBoundary(ancestor, child)) |
2426 return child->positionForPoint(pointInChildCoordinates); | 2426 return child->positionForPoint(pointInChildCoordinates); |
2427 | 2427 |
2428 // Otherwise return before or after the child, depending on if the click was
to the logical left or logical right of the child | 2428 // Otherwise return before or after the child, depending on if the click was
to the logical left or logical right of the child |
2429 LayoutUnit childMiddle = parent->logicalWidthForChild(child) / 2; | 2429 LayoutUnit childMiddle = parent->logicalWidthForChild(*child) / 2; |
2430 LayoutUnit logicalLeft = parent->isHorizontalWritingMode() ? pointInChildCoo
rdinates.x() : pointInChildCoordinates.y(); | 2430 LayoutUnit logicalLeft = parent->isHorizontalWritingMode() ? pointInChildCoo
rdinates.x() : pointInChildCoordinates.y(); |
2431 if (logicalLeft < childMiddle) | 2431 if (logicalLeft < childMiddle) |
2432 return ancestor->createPositionWithAffinity(childNode->nodeIndex(), DOWN
STREAM); | 2432 return ancestor->createPositionWithAffinity(childNode->nodeIndex(), DOWN
STREAM); |
2433 return ancestor->createPositionWithAffinity(childNode->nodeIndex() + 1, UPST
REAM); | 2433 return ancestor->createPositionWithAffinity(childNode->nodeIndex() + 1, UPST
REAM); |
2434 } | 2434 } |
2435 | 2435 |
2436 PositionWithAffinity RenderBlock::positionForPointWithInlineChildren(const Layou
tPoint& pointInLogicalContents) | 2436 PositionWithAffinity RenderBlock::positionForPointWithInlineChildren(const Layou
tPoint& pointInLogicalContents) |
2437 { | 2437 { |
2438 ASSERT(childrenInline()); | 2438 ASSERT(childrenInline()); |
2439 | 2439 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2554 | 2554 |
2555 if (childrenInline()) | 2555 if (childrenInline()) |
2556 return positionForPointWithInlineChildren(pointInLogicalContents); | 2556 return positionForPointWithInlineChildren(pointInLogicalContents); |
2557 | 2557 |
2558 RenderBox* lastCandidateBox = lastChildBox(); | 2558 RenderBox* lastCandidateBox = lastChildBox(); |
2559 while (lastCandidateBox && !isChildHitTestCandidate(lastCandidateBox)) | 2559 while (lastCandidateBox && !isChildHitTestCandidate(lastCandidateBox)) |
2560 lastCandidateBox = lastCandidateBox->previousSiblingBox(); | 2560 lastCandidateBox = lastCandidateBox->previousSiblingBox(); |
2561 | 2561 |
2562 bool blocksAreFlipped = style()->isFlippedBlocksWritingMode(); | 2562 bool blocksAreFlipped = style()->isFlippedBlocksWritingMode(); |
2563 if (lastCandidateBox) { | 2563 if (lastCandidateBox) { |
2564 if (pointInLogicalContents.y() > logicalTopForChild(lastCandidateBox) | 2564 if (pointInLogicalContents.y() > logicalTopForChild(*lastCandidateBox) |
2565 || (!blocksAreFlipped && pointInLogicalContents.y() == logicalTopFor
Child(lastCandidateBox))) | 2565 || (!blocksAreFlipped && pointInLogicalContents.y() == logicalTopFor
Child(*lastCandidateBox))) |
2566 return positionForPointRespectingEditingBoundaries(this, lastCandida
teBox, pointInContents); | 2566 return positionForPointRespectingEditingBoundaries(this, lastCandida
teBox, pointInContents); |
2567 | 2567 |
2568 for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBo
x->nextSiblingBox()) { | 2568 for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBo
x->nextSiblingBox()) { |
2569 if (!isChildHitTestCandidate(childBox)) | 2569 if (!isChildHitTestCandidate(childBox)) |
2570 continue; | 2570 continue; |
2571 LayoutUnit childLogicalBottom = logicalTopForChild(childBox) + logic
alHeightForChild(childBox); | 2571 LayoutUnit childLogicalBottom = logicalTopForChild(*childBox) + logi
calHeightForChild(*childBox); |
2572 // We hit child if our click is above the bottom of its padding box
(like IE6/7 and FF3). | 2572 // We hit child if our click is above the bottom of its padding box
(like IE6/7 and FF3). |
2573 if (isChildHitTestCandidate(childBox) && (pointInLogicalContents.y()
< childLogicalBottom | 2573 if (isChildHitTestCandidate(childBox) && (pointInLogicalContents.y()
< childLogicalBottom |
2574 || (blocksAreFlipped && pointInLogicalContents.y() == childLogic
alBottom))) | 2574 || (blocksAreFlipped && pointInLogicalContents.y() == childLogic
alBottom))) |
2575 return positionForPointRespectingEditingBoundaries(this, childBo
x, pointInContents); | 2575 return positionForPointRespectingEditingBoundaries(this, childBo
x, pointInContents); |
2576 } | 2576 } |
2577 } | 2577 } |
2578 | 2578 |
2579 // We only get here if there are no hit test candidate children below the cl
ick. | 2579 // We only get here if there are no hit test candidate children below the cl
ick. |
2580 return RenderBox::positionForPoint(point); | 2580 return RenderBox::positionForPoint(point); |
2581 } | 2581 } |
(...skipping 1076 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3658 ASSERT(layoutState->renderer() == this); | 3658 ASSERT(layoutState->renderer() == this); |
3659 | 3659 |
3660 LayoutSize offsetDelta = layoutState->layoutOffset() - layoutState->page
Offset(); | 3660 LayoutSize offsetDelta = layoutState->layoutOffset() - layoutState->page
Offset(); |
3661 return isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.wi
dth(); | 3661 return isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.wi
dth(); |
3662 } | 3662 } |
3663 | 3663 |
3664 ASSERT_NOT_REACHED(); | 3664 ASSERT_NOT_REACHED(); |
3665 return 0; | 3665 return 0; |
3666 } | 3666 } |
3667 | 3667 |
3668 LayoutUnit RenderBlock::collapsedMarginBeforeForChild(const RenderBox* child) co
nst | 3668 LayoutUnit RenderBlock::collapsedMarginBeforeForChild(const RenderBox& child) co
nst |
3669 { | 3669 { |
3670 // If the child has the same directionality as we do, then we can just retur
n its | 3670 // If the child has the same directionality as we do, then we can just retur
n its |
3671 // collapsed margin. | 3671 // collapsed margin. |
3672 if (!child->isWritingModeRoot()) | 3672 if (!child.isWritingModeRoot()) |
3673 return child->collapsedMarginBefore(); | 3673 return child.collapsedMarginBefore(); |
3674 | 3674 |
3675 // The child has a different directionality. If the child is parallel, then
it's just | 3675 // The child has a different directionality. If the child is parallel, then
it's just |
3676 // flipped relative to us. We can use the collapsed margin for the opposite
edge. | 3676 // flipped relative to us. We can use the collapsed margin for the opposite
edge. |
3677 if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) | 3677 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) |
3678 return child->collapsedMarginAfter(); | 3678 return child.collapsedMarginAfter(); |
3679 | 3679 |
3680 // The child is perpendicular to us, which means its margins don't collapse
but are on the | 3680 // The child is perpendicular to us, which means its margins don't collapse
but are on the |
3681 // "logical left/right" sides of the child box. We can just return the raw
margin in this case. | 3681 // "logical left/right" sides of the child box. We can just return the raw
margin in this case. |
3682 return marginBeforeForChild(child); | 3682 return marginBeforeForChild(child); |
3683 } | 3683 } |
3684 | 3684 |
3685 LayoutUnit RenderBlock::collapsedMarginAfterForChild(const RenderBox* child) co
nst | 3685 LayoutUnit RenderBlock::collapsedMarginAfterForChild(const RenderBox& child) con
st |
3686 { | 3686 { |
3687 // If the child has the same directionality as we do, then we can just retur
n its | 3687 // If the child has the same directionality as we do, then we can just retur
n its |
3688 // collapsed margin. | 3688 // collapsed margin. |
3689 if (!child->isWritingModeRoot()) | 3689 if (!child.isWritingModeRoot()) |
3690 return child->collapsedMarginAfter(); | 3690 return child.collapsedMarginAfter(); |
3691 | 3691 |
3692 // The child has a different directionality. If the child is parallel, then
it's just | 3692 // The child has a different directionality. If the child is parallel, then
it's just |
3693 // flipped relative to us. We can use the collapsed margin for the opposite
edge. | 3693 // flipped relative to us. We can use the collapsed margin for the opposite
edge. |
3694 if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) | 3694 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) |
3695 return child->collapsedMarginBefore(); | 3695 return child.collapsedMarginBefore(); |
3696 | 3696 |
3697 // The child is perpendicular to us, which means its margins don't collapse
but are on the | 3697 // The child is perpendicular to us, which means its margins don't collapse
but are on the |
3698 // "logical left/right" side of the child box. We can just return the raw m
argin in this case. | 3698 // "logical left/right" side of the child box. We can just return the raw m
argin in this case. |
3699 return marginAfterForChild(child); | 3699 return marginAfterForChild(child); |
3700 } | 3700 } |
3701 | 3701 |
3702 bool RenderBlock::hasMarginBeforeQuirk(const RenderBox* child) const | 3702 bool RenderBlock::hasMarginBeforeQuirk(const RenderBox* child) const |
3703 { | 3703 { |
3704 // If the child has the same directionality as we do, then we can just retur
n its | 3704 // If the child has the same directionality as we do, then we can just retur
n its |
3705 // margin quirk. | 3705 // margin quirk. |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3917 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m
arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render
Object* obj) const | 3917 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m
arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render
Object* obj) const |
3918 { | 3918 { |
3919 showRenderObject(); | 3919 showRenderObject(); |
3920 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot
Box()) | 3920 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot
Box()) |
3921 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa
bel2, obj, 1); | 3921 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa
bel2, obj, 1); |
3922 } | 3922 } |
3923 | 3923 |
3924 #endif | 3924 #endif |
3925 | 3925 |
3926 } // namespace blink | 3926 } // namespace blink |
OLD | NEW |