Bug 832611 - Use NotifyDestroyingFrame to remove frames from the OverflowChangedTracker. r=roc

This commit is contained in:
Matt Woodrow 2013-01-26 14:34:58 +13:00
parent 7ca25e2d6d
commit ef1378f2db
3 changed files with 27 additions and 33 deletions

View File

@ -49,29 +49,12 @@ public:
}
/**
* Remove a frame and all descendants of that frame.
* Remove a frame.
*/
void RemoveFrameAndDescendants(nsIFrame* aFrame) {
void RemoveFrame(nsIFrame* aFrame) {
if (mEntryList.contains(Entry(aFrame, 0, false))) {
delete mEntryList.remove(Entry(aFrame, 0, false));
}
if (mEntryList.empty()) {
return;
}
nsAutoTArray<nsIFrame::ChildList,4> childListArray;
aFrame->GetCrossDocChildLists(&childListArray);
nsIFrame::ChildListArrayIterator lists(childListArray);
for (; !lists.IsDone(); lists.Next()) {
nsFrameList::Enumerator childFrames(lists.CurrentList());
for (; !childFrames.AtEnd(); childFrames.Next()) {
RemoveFrameAndDescendants(childFrames.get());
if (mEntryList.empty()) {
return;
}
}
}
}
/**
@ -138,26 +121,19 @@ private:
}
/**
* Sort by the depth in the frame tree, and then
* the frame pointer.
* Sort by the frame pointer.
*/
bool operator<(const Entry& aOther) const
{
if (mDepth != aOther.mDepth) {
// nsTPriorityQueue implements a min-heap and we
// want the highest depth first, so reverse this check.
return mDepth > aOther.mDepth;
}
return mFrame < aOther.mFrame;
}
static int compare(const Entry& aOne, const Entry& aTwo)
{
if (aOne < aTwo) {
return -1;
} else if (aOne == aTwo) {
if (aOne == aTwo) {
return 0;
} else if (aOne < aTwo) {
return -1;
} else {
return 1;
}

View File

@ -1430,6 +1430,7 @@ nsCSSFrameConstructor::nsCSSFrameConstructor(nsIDocument *aDocument,
, mInStyleRefresh(false)
, mHoverGeneration(0)
, mRebuildAllExtraHint(nsChangeHint(0))
, mOverflowChangedTracker(nullptr)
, mAnimationGeneration(0)
, mPendingRestyles(ELEMENT_HAS_PENDING_RESTYLE |
ELEMENT_IS_POTENTIAL_RESTYLE_ROOT, this)
@ -1509,6 +1510,10 @@ nsCSSFrameConstructor::NotifyDestroyingFrame(nsIFrame* aFrame)
CountersDirty();
}
if (mOverflowChangedTracker) {
mOverflowChangedTracker->RemoveFrame(aFrame);
}
nsFrameManager::NotifyDestroyingFrame(aFrame);
}
@ -8118,6 +8123,10 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList,
SAMPLE_LABEL("CSS", "ProcessRestyledFrames");
MOZ_ASSERT(!GetOverflowChangedTracker(),
"Can't have multiple overflow changed trackers!");
SetOverflowChangedTracker(&aTracker);
// Make sure to not rebuild quote or counter lists while we're
// processing restyles
BeginUpdate();
@ -8202,9 +8211,6 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList,
// the style resolution we will do for the frame construction
// happens async when we're not in an animation restyle already,
// problems could arise.
if (content->GetPrimaryFrame()) {
aTracker.RemoveFrameAndDescendants(content->GetPrimaryFrame());
}
RecreateFramesForContent(content, false);
} else {
NS_ASSERTION(frame, "This shouldn't happen");
@ -8306,6 +8312,7 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList,
#endif
}
SetOverflowChangedTracker(nullptr);
aChangeList.Clear();
return NS_OK;
}

View File

@ -307,6 +307,15 @@ public:
PostRestyleEventCommon(aElement, aRestyleHint, aMinChangeHint, true);
}
OverflowChangedTracker *GetOverflowChangedTracker() const
{
return mOverflowChangedTracker;
}
void SetOverflowChangedTracker(OverflowChangedTracker *aTracker)
{
mOverflowChangedTracker = aTracker;
}
private:
/**
* Notify the frame constructor that an element needs to have its
@ -1895,6 +1904,8 @@ private:
nsCOMPtr<nsILayoutHistoryState> mTempFrameTreeState;
OverflowChangedTracker *mOverflowChangedTracker;
// The total number of animation flushes by this frame constructor.
// Used to keep the layer and animation manager in sync.
uint64_t mAnimationGeneration;