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(); |
+ } |
} |
} |