mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 822906 - Use SplayTree to remove deleted frames from RestyleTracker. r=roc
This commit is contained in:
parent
ea05b35161
commit
8a5da117b6
@ -15,6 +15,7 @@
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsTPriorityQueue.h"
|
||||
#include "mozilla/SplayTree.h"
|
||||
|
||||
class nsCSSFrameConstructor;
|
||||
|
||||
@ -42,7 +43,35 @@ public:
|
||||
* be called on the parent.
|
||||
*/
|
||||
void AddFrame(nsIFrame* aFrame) {
|
||||
mEntryList.Push(Entry(aFrame, true));
|
||||
if (!mEntryList.contains(Entry(aFrame, true))) {
|
||||
mEntryList.insert(new Entry(aFrame, true));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a frame and all descendants of that frame.
|
||||
*/
|
||||
void RemoveFrameAndDescendants(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,23 +81,13 @@ public:
|
||||
* us from processing the same frame twice.
|
||||
*/
|
||||
void Flush() {
|
||||
while (!mEntryList.IsEmpty()) {
|
||||
Entry entry = mEntryList.Pop();
|
||||
while (!mEntryList.empty()) {
|
||||
Entry *entry = mEntryList.removeMin();
|
||||
|
||||
// Pop off any duplicate entries and copy back mInitial
|
||||
// if any have it set.
|
||||
while (!mEntryList.IsEmpty() &&
|
||||
mEntryList.Top().mFrame == entry.mFrame) {
|
||||
Entry next = mEntryList.Pop();
|
||||
|
||||
if (next.mInitial) {
|
||||
entry.mInitial = true;
|
||||
}
|
||||
}
|
||||
nsIFrame *frame = entry.mFrame;
|
||||
nsIFrame *frame = entry->mFrame;
|
||||
|
||||
bool updateParent = false;
|
||||
if (entry.mInitial) {
|
||||
if (entry->mInitial) {
|
||||
nsOverflowAreas* pre = static_cast<nsOverflowAreas*>
|
||||
(frame->Properties().Get(frame->PreTransformOverflowAreasProperty()));
|
||||
if (pre) {
|
||||
@ -80,23 +99,26 @@ public:
|
||||
updateParent = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If the overflow changed, then we want to also update the parent's
|
||||
// overflow. We always update the parent for initial frames.
|
||||
if (!updateParent) {
|
||||
updateParent = frame->UpdateOverflow() || entry.mInitial;
|
||||
updateParent = frame->UpdateOverflow() || entry->mInitial;
|
||||
}
|
||||
if (updateParent) {
|
||||
nsIFrame *parent = frame->GetParent();
|
||||
if (parent) {
|
||||
mEntryList.Push(Entry(parent, entry.mDepth - 1, false));
|
||||
if (!mEntryList.contains(Entry(parent, entry->mDepth - 1, false))) {
|
||||
mEntryList.insert(new Entry(parent, entry->mDepth - 1, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
delete entry;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
struct Entry
|
||||
struct Entry : SplayTreeNode<Entry>
|
||||
{
|
||||
Entry(nsIFrame* aFrame, bool aInitial)
|
||||
: mFrame(aFrame)
|
||||
@ -130,6 +152,17 @@ private:
|
||||
return mFrame < aOther.mFrame;
|
||||
}
|
||||
|
||||
static int compare(const Entry& aOne, const Entry& aTwo)
|
||||
{
|
||||
if (aOne < aTwo) {
|
||||
return -1;
|
||||
} else if (aOne == aTwo) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
nsIFrame* mFrame;
|
||||
/* Depth in the frame tree */
|
||||
uint32_t mDepth;
|
||||
@ -141,7 +174,7 @@ private:
|
||||
};
|
||||
|
||||
/* A list of frames to process, sorted by their depth in the frame tree */
|
||||
nsTPriorityQueue<Entry> mEntryList;
|
||||
SplayTree<Entry, Entry> mEntryList;
|
||||
};
|
||||
|
||||
class RestyleTracker {
|
||||
|
@ -8208,6 +8208,9 @@ 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");
|
||||
|
Loading…
Reference in New Issue
Block a user