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