| 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());
|
| + } else {
|
| layer()->scrollableArea()->updateAfterLayout();
|
| + }
|
| }
|
| }
|
|
|
|
|