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) 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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 98 // the middle of recomputing the style so we can't rely on any of its | 98 // the middle of recomputing the style so we can't rely on any of its |
| 99 // information), which is why it's easier to just update it for every layout. | 99 // information), which is why it's easier to just update it for every layout. |
| 100 static TrackedDescendantsMap* gPositionedDescendantsMap = nullptr; | 100 static TrackedDescendantsMap* gPositionedDescendantsMap = nullptr; |
| 101 static TrackedContainerMap* gPositionedContainerMap = nullptr; | 101 static TrackedContainerMap* gPositionedContainerMap = nullptr; |
| 102 | 102 |
| 103 // This map keeps track of the descendants whose 'height' is percentage associat ed | 103 // This map keeps track of the descendants whose 'height' is percentage associat ed |
| 104 // with a containing block. Like |gPositionedDescendantsMap|, it is also recompu ted | 104 // with a containing block. Like |gPositionedDescendantsMap|, it is also recompu ted |
| 105 // for every layout (see the comment above about why). | 105 // for every layout (see the comment above about why). |
| 106 static TrackedDescendantsMap* gPercentHeightDescendantsMap = nullptr; | 106 static TrackedDescendantsMap* gPercentHeightDescendantsMap = nullptr; |
| 107 | 107 |
| 108 typedef WTF::HashSet<LayoutBlock*> DelayedUpdateScrollInfoSet; | 108 typedef WTF::HashSet<LayoutBlock*> DelayedUpdateScrollInfoSet; |
|
mstensho (USE GERRIT)
2016/02/22 10:05:19
I've mentioned this quite a few times already:
Ca
| |
| 109 static int gDelayUpdateScrollInfo = 0; | 109 static int gDelayUpdateScrollInfo = 0; |
| 110 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = nullptr; | 110 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = nullptr; |
| 111 | 111 |
| 112 LayoutBlock::LayoutBlock(ContainerNode* node) | 112 LayoutBlock::LayoutBlock(ContainerNode* node) |
| 113 : LayoutBox(node) | 113 : LayoutBox(node) |
| 114 , m_hasMarginBeforeQuirk(false) | 114 , m_hasMarginBeforeQuirk(false) |
| 115 , m_hasMarginAfterQuirk(false) | 115 , m_hasMarginAfterQuirk(false) |
| 116 , m_beingDestroyed(false) | 116 , m_beingDestroyed(false) |
| 117 , m_hasMarkupTruncation(false) | 117 , m_hasMarkupTruncation(false) |
| 118 , m_widthAvailableToChildrenChanged(false) | 118 , m_widthAvailableToChildrenChanged(false) |
| 119 , m_heightAvailableToChildrenChanged(false) | |
| 119 , m_hasOnlySelfCollapsingChildren(false) | 120 , m_hasOnlySelfCollapsingChildren(false) |
| 120 , m_descendantsWithFloatsMarkedForLayout(false) | 121 , m_descendantsWithFloatsMarkedForLayout(false) |
| 121 , m_hasPositionedObjects(false) | 122 , m_hasPositionedObjects(false) |
| 122 , m_hasPercentHeightDescendants(false) | 123 , m_hasPercentHeightDescendants(false) |
| 123 { | 124 { |
| 124 // LayoutBlockFlow calls setChildrenInline(true). | 125 // LayoutBlockFlow calls setChildrenInline(true). |
| 125 // By default, subclasses do not have inline children. | 126 // By default, subclasses do not have inline children. |
| 126 } | 127 } |
| 127 | 128 |
| 128 void LayoutBlock::removeFromGlobalMaps() | 129 void LayoutBlock::removeFromGlobalMaps() |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 227 // Remove our fixed positioned descendants from their current contai ning block. | 228 // Remove our fixed positioned descendants from their current contai ning block. |
| 228 // They will be inserted into our positioned objects list during lay out. | 229 // They will be inserted into our positioned objects list during lay out. |
| 229 if (LayoutBlock* cb = containerForFixedPosition()) | 230 if (LayoutBlock* cb = containerForFixedPosition()) |
| 230 cb->removePositionedObjects(this, NewContainingBlock); | 231 cb->removePositionedObjects(this, NewContainingBlock); |
| 231 } | 232 } |
| 232 } | 233 } |
| 233 | 234 |
| 234 LayoutBox::styleWillChange(diff, newStyle); | 235 LayoutBox::styleWillChange(diff, newStyle); |
| 235 } | 236 } |
| 236 | 237 |
| 237 static bool borderOrPaddingLogicalWidthChanged(const ComputedStyle& oldStyle, co nst ComputedStyle& newStyle) | 238 enum LogicalExtent { LogicalWidth, LogicalHeight }; |
| 239 static bool borderOrPaddingLogicalDimensionChanged(const ComputedStyle& oldStyle , const ComputedStyle& newStyle, LogicalExtent logicalExtent) | |
| 238 { | 240 { |
| 239 if (newStyle.isHorizontalWritingMode()) { | 241 if (newStyle.isHorizontalWritingMode() == (logicalExtent == LogicalWidth)) { |
| 240 return oldStyle.borderLeftWidth() != newStyle.borderLeftWidth() | 242 return oldStyle.borderLeftWidth() != newStyle.borderLeftWidth() |
| 241 || oldStyle.borderRightWidth() != newStyle.borderRightWidth() | 243 || oldStyle.borderRightWidth() != newStyle.borderRightWidth() |
| 242 || oldStyle.paddingLeft() != newStyle.paddingLeft() | 244 || oldStyle.paddingLeft() != newStyle.paddingLeft() |
| 243 || oldStyle.paddingRight() != newStyle.paddingRight(); | 245 || oldStyle.paddingRight() != newStyle.paddingRight(); |
| 244 } | 246 } |
| 245 | 247 |
| 246 return oldStyle.borderTopWidth() != newStyle.borderTopWidth() | 248 return oldStyle.borderTopWidth() != newStyle.borderTopWidth() |
| 247 || oldStyle.borderBottomWidth() != newStyle.borderBottomWidth() | 249 || oldStyle.borderBottomWidth() != newStyle.borderBottomWidth() |
| 248 || oldStyle.paddingTop() != newStyle.paddingTop() | 250 || oldStyle.paddingTop() != newStyle.paddingTop() |
| 249 || oldStyle.paddingBottom() != newStyle.paddingBottom(); | 251 || oldStyle.paddingBottom() != newStyle.paddingBottom(); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 272 if (LayoutBlock* cb = containingBlock()) | 274 if (LayoutBlock* cb = containingBlock()) |
| 273 cb->removePositionedObjects(this, NewContainingBlock); | 275 cb->removePositionedObjects(this, NewContainingBlock); |
| 274 } | 276 } |
| 275 } | 277 } |
| 276 | 278 |
| 277 if (TextAutosizer* textAutosizer = document().textAutosizer()) | 279 if (TextAutosizer* textAutosizer = document().textAutosizer()) |
| 278 textAutosizer->record(this); | 280 textAutosizer->record(this); |
| 279 | 281 |
| 280 propagateStyleToAnonymousChildren(true); | 282 propagateStyleToAnonymousChildren(true); |
| 281 | 283 |
| 282 // It's possible for our border/padding to change, but for the overall logic al width of the block to | 284 // It's possible for our border/padding to change, but for the overall logic al width or height of the block to |
| 283 // end up being the same. We keep track of this change so in layoutBlock, we can know to set relayoutChildren=true. | 285 // end up being the same. We keep track of this change so in layoutBlock, we can know to set relayoutChildren=true. |
| 284 m_widthAvailableToChildrenChanged |= oldStyle && diff.needsFullLayout() && n eedsLayout() && borderOrPaddingLogicalWidthChanged(*oldStyle, newStyle); | 286 m_widthAvailableToChildrenChanged |= oldStyle && diff.needsFullLayout() && n eedsLayout() && borderOrPaddingLogicalDimensionChanged(*oldStyle, newStyle, Logi calWidth); |
| 287 m_heightAvailableToChildrenChanged |= oldStyle && diff.needsFullLayout() && needsLayout() && borderOrPaddingLogicalDimensionChanged(*oldStyle, newStyle, Log icalHeight); | |
| 285 } | 288 } |
| 286 | 289 |
| 287 void LayoutBlock::invalidatePaintOfSubtreesIfNeeded(PaintInvalidationState& chil dPaintInvalidationState) | 290 void LayoutBlock::invalidatePaintOfSubtreesIfNeeded(PaintInvalidationState& chil dPaintInvalidationState) |
| 288 { | 291 { |
| 289 LayoutBox::invalidatePaintOfSubtreesIfNeeded(childPaintInvalidationState); | 292 LayoutBox::invalidatePaintOfSubtreesIfNeeded(childPaintInvalidationState); |
| 290 | 293 |
| 291 // Take care of positioned objects. This is required as PaintInvalidationSta te keeps a single clip rect. | 294 // Take care of positioned objects. This is required as PaintInvalidationSta te keeps a single clip rect. |
| 292 if (TrackedLayoutBoxListHashSet* positionedObjects = this->positionedObjects ()) { | 295 if (TrackedLayoutBoxListHashSet* positionedObjects = this->positionedObjects ()) { |
| 293 for (auto* box : *positionedObjects) { | 296 for (auto* box : *positionedObjects) { |
| 294 | 297 |
| (...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 885 | 888 |
| 886 // It's safe to check for control clip here, since controls can never be tab le cells. | 889 // It's safe to check for control clip here, since controls can never be tab le cells. |
| 887 // If we have a lightweight clip, there can never be any overflow from child ren. | 890 // If we have a lightweight clip, there can never be any overflow from child ren. |
| 888 if (hasControlClip() && m_overflow) | 891 if (hasControlClip() && m_overflow) |
| 889 clearLayoutOverflow(); | 892 clearLayoutOverflow(); |
| 890 | 893 |
| 891 invalidateBackgroundObscurationStatus(); | 894 invalidateBackgroundObscurationStatus(); |
| 892 | 895 |
| 893 if (needsScrollAnchoring) | 896 if (needsScrollAnchoring) |
| 894 scrollableArea()->scrollAnchor().restore(); | 897 scrollableArea()->scrollAnchor().restore(); |
| 898 | |
| 899 m_heightAvailableToChildrenChanged = false; | |
| 895 } | 900 } |
| 896 | 901 |
| 897 bool LayoutBlock::widthAvailableToChildrenHasChanged() | 902 bool LayoutBlock::widthAvailableToChildrenHasChanged() |
| 898 { | 903 { |
| 904 // TODO(robhogan): Does m_widthAvailableToChildrenChanged always get reset w hen it needs to? | |
|
mstensho (USE GERRIT)
2016/02/22 10:05:19
To answer your rhetorical question: No! :)
Yeah,
| |
| 899 bool widthAvailableToChildrenHasChanged = m_widthAvailableToChildrenChanged; | 905 bool widthAvailableToChildrenHasChanged = m_widthAvailableToChildrenChanged; |
| 900 m_widthAvailableToChildrenChanged = false; | 906 m_widthAvailableToChildrenChanged = false; |
| 901 | 907 |
| 902 // If we use border-box sizing, have percentage padding, and our parent has changed width then the width available to our children has changed even | 908 // If we use border-box sizing, have percentage padding, and our parent has changed width then the width available to our children has changed even |
| 903 // though our own width has remained the same. | 909 // though our own width has remained the same. |
| 904 widthAvailableToChildrenHasChanged |= style()->boxSizing() == BORDER_BOX && needsPreferredWidthsRecalculation() && view()->layoutState()->containingBlockLog icalWidthChanged(); | 910 widthAvailableToChildrenHasChanged |= style()->boxSizing() == BORDER_BOX && needsPreferredWidthsRecalculation() && view()->layoutState()->containingBlockLog icalWidthChanged(); |
| 905 | 911 |
| 906 return widthAvailableToChildrenHasChanged; | 912 return widthAvailableToChildrenHasChanged; |
| 907 } | 913 } |
| 908 | 914 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 988 addVisualOverflow(LayoutRect(inflatedRect)); | 994 addVisualOverflow(LayoutRect(inflatedRect)); |
| 989 } | 995 } |
| 990 | 996 |
| 991 bool LayoutBlock::createsNewFormattingContext() const | 997 bool LayoutBlock::createsNewFormattingContext() const |
| 992 { | 998 { |
| 993 return isInlineBlockOrInlineTable() || isFloatingOrOutOfFlowPositioned() || hasOverflowClip() || isFlexItemIncludingDeprecated() | 999 return isInlineBlockOrInlineTable() || isFloatingOrOutOfFlowPositioned() || hasOverflowClip() || isFlexItemIncludingDeprecated() |
| 994 || style()->specifiesColumns() || isLayoutFlowThread() || isTableCell() || isTableCaption() || isFieldset() || isWritingModeRoot() | 1000 || style()->specifiesColumns() || isLayoutFlowThread() || isTableCell() || isTableCaption() || isFieldset() || isWritingModeRoot() |
| 995 || isDocumentElement() || isColumnSpanAll() || isGridItem() || style()-> containsPaint(); | 1001 || isDocumentElement() || isColumnSpanAll() || isGridItem() || style()-> containsPaint(); |
| 996 } | 1002 } |
| 997 | 1003 |
| 1004 bool static changeInAvailableLogicalHeightAffectsChild(LayoutBlock* parent, Layo utBox& child) | |
|
mstensho (USE GERRIT)
2016/02/22 10:05:19
"bool static"? Can you really say that? Shouldn't
| |
| 1005 { | |
| 1006 if (parent->style()->boxSizing() != BORDER_BOX) | |
| 1007 return false; | |
| 1008 return parent->style()->isHorizontalWritingMode() && !child.style()->isHoriz ontalWritingMode(); | |
| 1009 } | |
| 1010 | |
| 998 void LayoutBlock::updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, L ayoutBox& child) | 1011 void LayoutBlock::updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, L ayoutBox& child) |
| 999 { | 1012 { |
| 1000 if (child.isOutOfFlowPositioned()) { | 1013 if (child.isOutOfFlowPositioned()) { |
| 1001 // It's rather useless to mark out-of-flow children at this point. We ma y not be their | 1014 // It's rather useless to mark out-of-flow children at this point. We ma y not be their |
| 1002 // containing block (and if we are, it's just pure luck), so this would be the wrong place | 1015 // containing block (and if we are, it's just pure luck), so this would be the wrong place |
| 1003 // for it. Furthermore, it would cause trouble for out-of-flow descendan ts of column | 1016 // for it. Furthermore, it would cause trouble for out-of-flow descendan ts of column |
| 1004 // spanners, if the containing block is outside the spanner but inside t he multicol container. | 1017 // spanners, if the containing block is outside the spanner but inside t he multicol container. |
| 1005 return; | 1018 return; |
| 1006 } | 1019 } |
| 1007 // FIXME: Technically percentage height objects only need a relayout if thei r percentage isn't going to be turned into | 1020 // FIXME: Technically percentage height objects only need a relayout if thei r percentage isn't going to be turned into |
| 1008 // an auto value. Add a method to determine this, so that we can avoid the r elayout. | 1021 // an auto value. Add a method to determine this, so that we can avoid the r elayout. |
| 1009 bool hasRelativeLogicalHeight = child.hasRelativeLogicalHeight() | 1022 bool hasRelativeLogicalHeight = child.hasRelativeLogicalHeight() |
| 1010 || (child.isAnonymous() && this->hasRelativeLogicalHeight()) | 1023 || (child.isAnonymous() && this->hasRelativeLogicalHeight()) |
| 1011 || child.stretchesToViewport(); | 1024 || child.stretchesToViewport(); |
| 1012 if (relayoutChildren || (hasRelativeLogicalHeight && !isLayoutView())) { | 1025 if (relayoutChildren || (hasRelativeLogicalHeight && !isLayoutView()) |
| 1026 || (m_heightAvailableToChildrenChanged && changeInAvailableLogicalHeight AffectsChild(this, child))) { | |
| 1013 child.setChildNeedsLayout(MarkOnlyThis); | 1027 child.setChildNeedsLayout(MarkOnlyThis); |
| 1014 | 1028 |
| 1015 // If the child has percentage padding or an embedded content box, we al so need to invalidate the childs pref widths. | 1029 // If the child has percentage padding or an embedded content box, we al so need to invalidate the childs pref widths. |
| 1016 if (child.needsPreferredWidthsRecalculation()) | 1030 if (child.needsPreferredWidthsRecalculation()) |
| 1017 child.setPreferredLogicalWidthsDirty(MarkOnlyThis); | 1031 child.setPreferredLogicalWidthsDirty(MarkOnlyThis); |
| 1018 } | 1032 } |
| 1019 } | 1033 } |
| 1020 | 1034 |
| 1021 void LayoutBlock::simplifiedNormalFlowLayout() | 1035 void LayoutBlock::simplifiedNormalFlowLayout() |
| 1022 { | 1036 { |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1199 SubtreeLayoutScope layoutScope(*positionedObject); | 1213 SubtreeLayoutScope layoutScope(*positionedObject); |
| 1200 // A fixed position element with an absolute positioned ancestor has no way of knowing if the latter has changed position. So | 1214 // A fixed position element with an absolute positioned ancestor has no way of knowing if the latter has changed position. So |
| 1201 // if this is a fixed position element, mark it for layout if it has an abspos ancestor and needs to move with that ancestor, i.e. | 1215 // if this is a fixed position element, mark it for layout if it has an abspos ancestor and needs to move with that ancestor, i.e. |
| 1202 // it has static position. | 1216 // it has static position. |
| 1203 markFixedPositionObjectForLayoutIfNeeded(positionedObject, layoutScope); | 1217 markFixedPositionObjectForLayoutIfNeeded(positionedObject, layoutScope); |
| 1204 if (info == LayoutOnlyFixedPositionedObjects) { | 1218 if (info == LayoutOnlyFixedPositionedObjects) { |
| 1205 positionedObject->layoutIfNeeded(); | 1219 positionedObject->layoutIfNeeded(); |
| 1206 continue; | 1220 continue; |
| 1207 } | 1221 } |
| 1208 | 1222 |
| 1209 if (!positionedObject->normalChildNeedsLayout() && (relayoutChildren || needsLayoutDueToStaticPosition(positionedObject))) | 1223 if (!positionedObject->normalChildNeedsLayout() && (relayoutChildren || m_heightAvailableToChildrenChanged || needsLayoutDueToStaticPosition(positionedO bject))) |
| 1210 layoutScope.setChildNeedsLayout(positionedObject); | 1224 layoutScope.setChildNeedsLayout(positionedObject); |
| 1211 | 1225 |
| 1212 // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths. | 1226 // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths. |
| 1213 if (relayoutChildren && positionedObject->needsPreferredWidthsRecalculat ion()) | 1227 if (relayoutChildren && positionedObject->needsPreferredWidthsRecalculat ion()) |
| 1214 positionedObject->setPreferredLogicalWidthsDirty(MarkOnlyThis); | 1228 positionedObject->setPreferredLogicalWidthsDirty(MarkOnlyThis); |
| 1215 | 1229 |
| 1216 LayoutUnit logicalTopEstimate; | 1230 LayoutUnit logicalTopEstimate; |
| 1217 bool needsBlockDirectionLocationSetBeforeLayout = isPaginated && positio nedObject->paginationBreakability() != ForbidBreaks; | 1231 bool needsBlockDirectionLocationSetBeforeLayout = isPaginated && positio nedObject->paginationBreakability() != ForbidBreaks; |
| 1218 if (needsBlockDirectionLocationSetBeforeLayout) { | 1232 if (needsBlockDirectionLocationSetBeforeLayout) { |
| 1219 // Out-of-flow objects are normally positioned after layout (while i n-flow objects are | 1233 // Out-of-flow objects are normally positioned after layout (while i n-flow objects are |
| (...skipping 1628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2848 void LayoutBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Layout Object* obj) const | 2862 void LayoutBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Layout Object* obj) const |
| 2849 { | 2863 { |
| 2850 showLayoutObject(); | 2864 showLayoutObject(); |
| 2851 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box()) | 2865 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box()) |
| 2852 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1); | 2866 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1); |
| 2853 } | 2867 } |
| 2854 | 2868 |
| 2855 #endif | 2869 #endif |
| 2856 | 2870 |
| 2857 } // namespace blink | 2871 } // namespace blink |
| OLD | NEW |