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

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutBlock.cpp

Issue 1674323002: Detect a change in border that affects a positioned object's height or position (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Updated Created 4 years, 10 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
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutBlock.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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) 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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutBlock.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698