Chromium Code Reviews| Index: Source/core/layout/LayoutBlock.cpp |
| diff --git a/Source/core/layout/LayoutBlock.cpp b/Source/core/layout/LayoutBlock.cpp |
| index 169fd76f33b98b850f25c986e25aa8086be89612..8f3982221cd98f6a9bac99f64d783e0bb9c03cbf 100644 |
| --- a/Source/core/layout/LayoutBlock.cpp |
| +++ b/Source/core/layout/LayoutBlock.cpp |
| @@ -108,9 +108,22 @@ static TrackedDescendantsMap* gPercentHeightDescendantsMap = nullptr; |
| static TrackedContainerMap* gPositionedContainerMap = nullptr; |
| static TrackedContainerMap* gPercentHeightContainerMap = nullptr; |
| -typedef WTF::HashSet<LayoutBlock*> DelayedUpdateScrollInfoSet; |
| +struct ScrollInfo { |
| + DoubleSize scrollOffset; |
| + bool autoHorizontalScrollBarChanged; |
| + bool autoVerticalScrollBarChanged; |
| + bool hasOffset() const { return scrollOffset != DoubleSize(); } |
| + bool scrollBarsChanged() const { return autoHorizontalScrollBarChanged || autoVerticalScrollBarChanged; } |
| + void merge(const ScrollInfo& other) |
| + { |
| + // We always keep the first scrollOffset we saw for this block, so don't copy that field. |
| + autoHorizontalScrollBarChanged |= other.autoHorizontalScrollBarChanged; |
| + autoVerticalScrollBarChanged |= other.autoVerticalScrollBarChanged; |
| + } |
| +}; |
| +typedef WTF::HashMap<LayoutBlock*, ScrollInfo> DelayedUpdateScrollInfoMap; |
| static int gDelayUpdateScrollInfo = 0; |
| -static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = nullptr; |
| +static DelayedUpdateScrollInfoMap* gDelayedUpdateScrollInfoMap = nullptr; |
| LayoutBlock::LayoutBlock(ContainerNode* node) |
| : LayoutBox(node) |
| @@ -232,8 +245,8 @@ void LayoutBlock::willBeDestroyed() |
| m_lineBoxes.deleteLineBoxes(); |
| - if (UNLIKELY(gDelayedUpdateScrollInfoSet != 0)) |
| - gDelayedUpdateScrollInfoSet->remove(this); |
| + if (UNLIKELY(gDelayedUpdateScrollInfoMap != 0)) |
| + gDelayedUpdateScrollInfoMap->remove(this); |
| if (TextAutosizer* textAutosizer = document().textAutosizer()) |
| textAutosizer->destroy(this); |
| @@ -828,10 +841,10 @@ bool LayoutBlock::isSelfCollapsingBlock() const |
| void LayoutBlock::startDelayUpdateScrollInfo() |
| { |
| if (gDelayUpdateScrollInfo == 0) { |
| - ASSERT(!gDelayedUpdateScrollInfoSet); |
| - gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet; |
| + ASSERT(!gDelayedUpdateScrollInfoMap); |
| + gDelayedUpdateScrollInfoMap = new DelayedUpdateScrollInfoMap; |
| } |
| - ASSERT(gDelayedUpdateScrollInfoSet); |
| + ASSERT(gDelayedUpdateScrollInfoMap); |
| ++gDelayUpdateScrollInfo; |
| } |
| @@ -840,14 +853,16 @@ void LayoutBlock::finishDelayUpdateScrollInfo() |
| --gDelayUpdateScrollInfo; |
| ASSERT(gDelayUpdateScrollInfo >= 0); |
| if (gDelayUpdateScrollInfo == 0) { |
| - ASSERT(gDelayedUpdateScrollInfoSet); |
| + ASSERT(gDelayedUpdateScrollInfoMap); |
| - OwnPtr<DelayedUpdateScrollInfoSet> infoSet(adoptPtr(gDelayedUpdateScrollInfoSet)); |
| - gDelayedUpdateScrollInfoSet = nullptr; |
| + OwnPtr<DelayedUpdateScrollInfoMap> infoMap(adoptPtr(gDelayedUpdateScrollInfoMap)); |
| + gDelayedUpdateScrollInfoMap = nullptr; |
| - for (auto* block : *infoSet) { |
| - if (block->hasOverflowClip()) { |
| - block->layer()->scrollableArea()->updateAfterLayout(); |
| + for (auto block : *infoMap) { |
| + if (block.key->hasOverflowClip()) { |
| + DeprecatedPaintLayerScrollableArea* scrollableArea = block.key->layer()->scrollableArea(); |
| + ScrollInfo& scrollInfo = block.value; |
| + scrollableArea->finalizeScrollDimensions(scrollInfo.scrollOffset, scrollInfo.autoHorizontalScrollBarChanged, scrollInfo.autoVerticalScrollBarChanged); |
| } |
| } |
| } |
| @@ -865,10 +880,21 @@ void LayoutBlock::updateScrollInfoAfterLayout() |
| return; |
| } |
| - if (gDelayUpdateScrollInfo) |
| - gDelayedUpdateScrollInfoSet->add(this); |
| - else |
| + if (gDelayUpdateScrollInfo) { |
| + LayoutUnit logicalWidthExcludingScrollbar = logicalWidth() - scrollbarLogicalWidth(); |
| + LayoutUnit logicalHeightExcludingScrollbar = logicalHeight() - scrollbarLogicalHeight(); |
| + ScrollInfo scrollInfo; |
| + layer()->scrollableArea()->updateScrollDimensions(scrollInfo.scrollOffset, scrollInfo.autoHorizontalScrollBarChanged, scrollInfo.autoVerticalScrollBarChanged); |
| + DelayedUpdateScrollInfoMap::AddResult scrollInfoIterator = gDelayedUpdateScrollInfoMap->add(this, scrollInfo); |
| + if (!scrollInfoIterator.isNewEntry) |
| + scrollInfoIterator.storedValue->value.merge(scrollInfo); |
| + if (scrollInfo.autoHorizontalScrollBarChanged) |
| + setLogicalHeight(logicalHeightExcludingScrollbar + scrollbarLogicalHeight()); |
| + if (scrollInfo.autoVerticalScrollBarChanged) |
| + setLogicalWidth(logicalWidthExcludingScrollbar + scrollbarLogicalWidth()); |
|
cbiesinger
2015/11/18 18:41:35
I thought more about this block and I am no longer
|
| + } else { |
| layer()->scrollableArea()->updateAfterLayout(); |
| + } |
| } |
| } |