Index: third_party/WebKit/Source/core/layout/LayoutBlock.cpp |
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp |
index 7daa88b77c873e20b2aba1437feb64eb10f7c978..f3bababbf581770dbcbb18408331997287960a69 100644 |
--- a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp |
+++ b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp |
@@ -87,26 +87,6 @@ struct SameSizeAsLayoutBlock : public LayoutBox { |
static_assert(sizeof(LayoutBlock) == sizeof(SameSizeAsLayoutBlock), "LayoutBlock should stay small"); |
-// This map keeps track of the positioned objects associated with a containing |
-// block. |
-// |
-// This map is populated during layout. It is kept across layouts to handle |
-// that we skip unchanged sub-trees during layout, in such a way that we are |
-// able to lay out deeply nested out-of-flow descendants if their containing |
-// block got laid out. The map could be invalidated during style change but |
-// keeping track of containing blocks at that time is complicated (we are in |
-// the middle of recomputing the style so we can't rely on any of its |
-// information), which is why it's easier to just update it for every layout. |
-static TrackedDescendantsMap* gPositionedDescendantsMap = nullptr; |
- |
-// This map keeps track of the descendants whose 'height' is percentage associated |
-// with a containing block. Like |gPositionedDescendantsMap|, it is also recomputed |
-// for every layout (see the comment above about why). |
-static TrackedDescendantsMap* gPercentHeightDescendantsMap = nullptr; |
- |
-static TrackedContainerMap* gPositionedContainerMap = nullptr; |
-static TrackedContainerMap* gPercentHeightContainerMap = nullptr; |
- |
struct ScrollInfo { |
ScrollInfo() : autoHorizontalScrollBarChanged(false), autoVerticalScrollBarChanged(false) {} |
DoubleSize scrollOffset; |
@@ -140,34 +120,20 @@ LayoutBlock::LayoutBlock(ContainerNode* node) |
// By default, subclasses do not have inline children. |
} |
-static void removeBlockFromDescendantAndContainerMaps(LayoutBlock* block, TrackedDescendantsMap*& descendantMap, TrackedContainerMap*& containerMap) |
+LayoutBlock::~LayoutBlock() |
{ |
- if (OwnPtr<TrackedLayoutBoxListHashSet> descendantSet = descendantMap->take(block)) { |
- for (auto& descendant : *descendantSet) { |
- TrackedContainerMap::iterator it = containerMap->find(descendant); |
- ASSERT(it != containerMap->end()); |
- if (it == containerMap->end()) |
- continue; |
- HashSet<LayoutBlock*>* containerSet = it->value.get(); |
- ASSERT(containerSet->contains(block)); |
- containerSet->remove(block); |
- if (containerSet->isEmpty()) |
- containerMap->remove(it); |
+ if (TrackedLayoutBoxListHashSet* descendants = positionedObjects()) { |
+ for (LayoutBox* descendant : *descendants) { |
+ ASSERT(descendant->positionedContainer() == this); |
+ descendant->setPositionedContainer(nullptr); |
+ } |
+ } |
+ if (TrackedLayoutBoxListHashSet* descendants = percentHeightDescendants()) { |
+ for (LayoutBox* descendant : *descendants) { |
+ ASSERT(descendant->percentHeightContainer() == this); |
+ descendant->setPercentHeightContainer(nullptr); |
} |
} |
-} |
- |
-void LayoutBlock::removeFromGlobalMaps() |
-{ |
- if (gPercentHeightDescendantsMap) |
- removeBlockFromDescendantAndContainerMaps(this, gPercentHeightDescendantsMap, gPercentHeightContainerMap); |
- if (gPositionedDescendantsMap) |
- removeBlockFromDescendantAndContainerMaps(this, gPositionedDescendantsMap, gPositionedContainerMap); |
-} |
- |
-LayoutBlock::~LayoutBlock() |
-{ |
- removeFromGlobalMaps(); |
} |
void LayoutBlock::willBeDestroyed() |
@@ -1396,77 +1362,34 @@ void LayoutBlock::setSelectionState(SelectionState state) |
inlineBoxWrapper()->root().setHasSelectedChildren(state != SelectionNone); |
} |
-void LayoutBlock::insertIntoTrackedLayoutBoxMaps(LayoutBox* descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap) |
+void LayoutBlock::insertPositionedObject(LayoutBox* descendant) |
{ |
- if (!descendantsMap) { |
- descendantsMap = new TrackedDescendantsMap; |
- containerMap = new TrackedContainerMap; |
- } |
- |
- TrackedLayoutBoxListHashSet* descendantSet = descendantsMap->get(this); |
- if (!descendantSet) { |
- descendantSet = new TrackedLayoutBoxListHashSet; |
- descendantsMap->set(this, adoptPtr(descendantSet)); |
- } |
- bool added = descendantSet->add(descendant).isNewEntry; |
- if (!added) { |
- ASSERT(containerMap->get(descendant)); |
- ASSERT(containerMap->get(descendant)->contains(this)); |
- return; |
- } |
- |
- HashSet<LayoutBlock*>* containerSet = containerMap->get(descendant); |
- if (!containerSet) { |
- containerSet = new HashSet<LayoutBlock*>; |
- containerMap->set(descendant, adoptPtr(containerSet)); |
+ ASSERT(!isAnonymousBlock()); |
+ OwnPtr<TrackedLayoutBoxListHashSet>& positionedDescendants = ensureLayoutBlockRareData().m_positionedDescendants; |
+ if (!positionedDescendants) |
+ positionedDescendants = adoptPtr(new TrackedLayoutBoxListHashSet); |
+ if (descendant->positionedContainer()) { |
+ if (descendant->positionedContainer() == this) { |
+ ASSERT(positionedDescendants->contains(descendant)); |
+ return; |
+ } |
+ descendant->removeFromPositionedContainer(); |
} |
- ASSERT(!containerSet->contains(this)); |
- containerSet->add(this); |
+ positionedDescendants->add(descendant); |
+ descendant->setPositionedContainer(this); |
} |
-void LayoutBlock::removeFromTrackedLayoutBoxMaps(LayoutBox* descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap) |
+void LayoutBlock::removePositionedObject(LayoutBox* descendant) |
{ |
- if (!descendantsMap) |
- return; |
- |
- OwnPtr<HashSet<LayoutBlock*>> containerSet = containerMap->take(descendant); |
- if (!containerSet) |
+ TrackedLayoutBoxListHashSet* positionedDescendants = positionedObjects(); |
+ if (!descendant->positionedContainer()) { |
+ ASSERT(!positionedDescendants || !positionedDescendants->contains(descendant)); |
return; |
- |
- for (auto* container : *containerSet) { |
- // FIXME: Disabling this assert temporarily until we fix the layout |
- // bugs associated with positioned objects not properly cleared from |
- // their ancestor chain before being moved. See webkit bug 93766. |
- // ASSERT(descendant->isDescendantOf(container)); |
- |
- TrackedDescendantsMap::iterator descendantsMapIterator = descendantsMap->find(container); |
- ASSERT(descendantsMapIterator != descendantsMap->end()); |
- if (descendantsMapIterator == descendantsMap->end()) |
- continue; |
- TrackedLayoutBoxListHashSet* descendantSet = descendantsMapIterator->value.get(); |
- ASSERT(descendantSet->contains(descendant)); |
- descendantSet->remove(descendant); |
- if (descendantSet->isEmpty()) |
- descendantsMap->remove(descendantsMapIterator); |
} |
-} |
- |
-TrackedLayoutBoxListHashSet* LayoutBlock::positionedObjects() const |
-{ |
- if (gPositionedDescendantsMap) |
- return gPositionedDescendantsMap->get(this); |
- return nullptr; |
-} |
- |
-void LayoutBlock::insertPositionedObject(LayoutBox* o) |
-{ |
- ASSERT(!isAnonymousBlock()); |
- insertIntoTrackedLayoutBoxMaps(o, gPositionedDescendantsMap, gPositionedContainerMap); |
-} |
- |
-void LayoutBlock::removePositionedObject(LayoutBox* o) |
-{ |
- removeFromTrackedLayoutBoxMaps(o, gPositionedDescendantsMap, gPositionedContainerMap); |
+ ASSERT(descendant->positionedContainer() == this); |
+ ASSERT(positionedDescendants && positionedDescendants->contains(descendant)); |
+ positionedDescendants->remove(descendant); |
+ descendant->setPositionedContainer(nullptr); |
} |
void LayoutBlock::removePositionedObjects(LayoutBlock* o, ContainingBlockState containingBlockState) |
@@ -1505,49 +1428,51 @@ void LayoutBlock::removePositionedObjects(LayoutBlock* o, ContainingBlockState c |
} |
} |
- for (unsigned i = 0; i < deadObjects.size(); i++) |
- removePositionedObject(deadObjects.at(i)); |
+ for (auto* deadObject : deadObjects) |
+ deadObject->removeFromPositionedContainer(); |
} |
void LayoutBlock::addPercentHeightDescendant(LayoutBox* descendant) |
{ |
- insertIntoTrackedLayoutBoxMaps(descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap); |
+ OwnPtr<TrackedLayoutBoxListHashSet>& percentHeightDescendants = ensureLayoutBlockRareData().m_percentHeightDescendants; |
+ if (!percentHeightDescendants) |
+ percentHeightDescendants = adoptPtr(new TrackedLayoutBoxListHashSet); |
+ if (descendant->percentHeightContainer()) { |
+ if (descendant->percentHeightContainer() == this) { |
+ ASSERT(percentHeightDescendants->contains(descendant)); |
+ return; |
+ } |
+ descendant->removeFromPercentHeightContainer(); |
+ } |
+ percentHeightDescendants->add(descendant); |
+ descendant->setPercentHeightContainer(this); |
} |
void LayoutBlock::removePercentHeightDescendant(LayoutBox* descendant) |
{ |
- removeFromTrackedLayoutBoxMaps(descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap); |
-} |
- |
-TrackedLayoutBoxListHashSet* LayoutBlock::percentHeightDescendants() const |
-{ |
- return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0; |
-} |
- |
-bool LayoutBlock::hasPercentHeightContainerMap() |
-{ |
- return gPercentHeightContainerMap; |
+ TrackedLayoutBoxListHashSet* percentHeightDescendants = this->percentHeightDescendants(); |
+ if (!descendant->percentHeightContainer()) { |
+ ASSERT(!percentHeightDescendants || !percentHeightDescendants->contains(descendant)); |
+ return; |
+ } |
+ ASSERT(descendant->percentHeightContainer() == this); |
+ ASSERT(percentHeightDescendants && percentHeightDescendants->contains(descendant)); |
+ percentHeightDescendants->remove(descendant); |
+ descendant->setPercentHeightContainer(nullptr); |
} |
bool LayoutBlock::hasPercentHeightDescendant(LayoutBox* descendant) |
{ |
- // We don't null check gPercentHeightContainerMap since the caller |
- // already ensures this and we need to call this function on every |
- // descendant in clearPercentHeightDescendantsFrom(). |
- ASSERT(gPercentHeightContainerMap); |
- return gPercentHeightContainerMap->contains(descendant); |
+ return percentHeightDescendants() && percentHeightDescendants()->contains(descendant); |
} |
void LayoutBlock::dirtyForLayoutFromPercentageHeightDescendants(SubtreeLayoutScope& layoutScope) |
{ |
- if (!gPercentHeightDescendantsMap) |
- return; |
- |
- TrackedLayoutBoxListHashSet* descendants = gPercentHeightDescendantsMap->get(this); |
- if (!descendants) |
+ TrackedLayoutBoxListHashSet* percentHeightDescendants = this->percentHeightDescendants(); |
+ if (!percentHeightDescendants) |
return; |
- for (auto* box : *descendants) { |
+ for (auto* box : *percentHeightDescendants) { |
ASSERT(box->isDescendantOf(this)); |
while (box != this) { |
if (box->normalChildNeedsLayout()) |
@@ -1561,35 +1486,6 @@ void LayoutBlock::dirtyForLayoutFromPercentageHeightDescendants(SubtreeLayoutSco |
} |
} |
-void LayoutBlock::removePercentHeightDescendantIfNeeded(LayoutBox* descendant) |
-{ |
- // We query the map directly, rather than looking at style's |
- // logicalHeight()/logicalMinHeight()/logicalMaxHeight() since those |
- // can change with writing mode/directional changes. |
- if (!hasPercentHeightContainerMap()) |
- return; |
- |
- if (!hasPercentHeightDescendant(descendant)) |
- return; |
- |
- removePercentHeightDescendant(descendant); |
-} |
- |
-void LayoutBlock::clearPercentHeightDescendantsFrom(LayoutBox* parent) |
-{ |
- ASSERT(gPercentHeightContainerMap); |
- for (LayoutObject* curr = parent->slowFirstChild(); curr; curr = curr->nextInPreOrder(parent)) { |
- if (!curr->isBox()) |
- continue; |
- |
- LayoutBox* box = toLayoutBox(curr); |
- if (!hasPercentHeightDescendant(box)) |
- continue; |
- |
- removePercentHeightDescendant(box); |
- } |
-} |
- |
LayoutUnit LayoutBlock::textIndentOffset() const |
{ |
LayoutUnit cw = 0; |
@@ -2876,15 +2772,9 @@ bool LayoutBlock::tryLayoutDoingPositionedMovementOnly() |
#if ENABLE(ASSERT) |
void LayoutBlock::checkPositionedObjectsNeedLayout() |
{ |
- if (!gPositionedDescendantsMap) |
- return; |
- |
if (TrackedLayoutBoxListHashSet* positionedDescendantSet = positionedObjects()) { |
- TrackedLayoutBoxListHashSet::const_iterator end = positionedDescendantSet->end(); |
- for (TrackedLayoutBoxListHashSet::const_iterator it = positionedDescendantSet->begin(); it != end; ++it) { |
- LayoutBox* currBox = *it; |
- ASSERT(!currBox->needsLayout()); |
- } |
+ for (LayoutBox* box : *positionedDescendantSet) |
+ ASSERT(!box->needsLayout()); |
} |
} |