mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 931668 - Part 24: Avoid copying RestyleData::mDescendants when modifying an existing entry. r=dbaron
--HG-- extra : rebase_source : 0b9905bdff6f9ceec823b2091aadc39f0ca467bc
This commit is contained in:
parent
f4fc11c565
commit
4987707ff9
@ -2420,14 +2420,14 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint)
|
||||
// we'll fail to do the restyling we need to do.
|
||||
(mContent->GetParent() || mContent->GetPrimaryFrame() == mFrame)) {
|
||||
mContent->OwnerDoc()->FlushPendingLinkUpdates();
|
||||
RestyleTracker::RestyleData restyleData;
|
||||
if (mRestyleTracker.GetRestyleData(mContent->AsElement(), &restyleData)) {
|
||||
if (NS_UpdateHint(mHintsHandled, restyleData.mChangeHint)) {
|
||||
mChangeList->AppendChange(mFrame, mContent, restyleData.mChangeHint);
|
||||
nsAutoPtr<RestyleTracker::RestyleData> restyleData;
|
||||
if (mRestyleTracker.GetRestyleData(mContent->AsElement(), restyleData)) {
|
||||
if (NS_UpdateHint(mHintsHandled, restyleData->mChangeHint)) {
|
||||
mChangeList->AppendChange(mFrame, mContent, restyleData->mChangeHint);
|
||||
}
|
||||
hintToRestore = restyleData.mRestyleHint;
|
||||
aRestyleHint = nsRestyleHint(aRestyleHint | restyleData.mRestyleHint);
|
||||
descendants.SwapElements(restyleData.mDescendants);
|
||||
hintToRestore = restyleData->mRestyleHint;
|
||||
aRestyleHint = nsRestyleHint(aRestyleHint | restyleData->mRestyleHint);
|
||||
descendants.SwapElements(restyleData->mDescendants);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3138,12 +3138,12 @@ ElementRestyler::RestyleUndisplayedChildren(nsRestyleHint aChildRestyleHint)
|
||||
}
|
||||
|
||||
nsRestyleHint thisChildHint = aChildRestyleHint;
|
||||
RestyleTracker::RestyleData undisplayedRestyleData;
|
||||
nsAutoPtr<RestyleTracker::RestyleData> undisplayedRestyleData;
|
||||
Element* element = undisplayed->mContent->AsElement();
|
||||
if (mRestyleTracker.GetRestyleData(element,
|
||||
&undisplayedRestyleData)) {
|
||||
undisplayedRestyleData)) {
|
||||
thisChildHint =
|
||||
nsRestyleHint(thisChildHint | undisplayedRestyleData.mRestyleHint);
|
||||
nsRestyleHint(thisChildHint | undisplayedRestyleData->mRestyleHint);
|
||||
}
|
||||
nsRefPtr<nsStyleContext> undisplayedContext;
|
||||
nsStyleSet* styleSet = mPresContext->StyleSet();
|
||||
|
@ -29,7 +29,7 @@ struct LaterSiblingCollector {
|
||||
|
||||
static PLDHashOperator
|
||||
CollectLaterSiblings(nsISupports* aElement,
|
||||
RestyleTracker::RestyleData& aData,
|
||||
nsAutoPtr<RestyleTracker::RestyleData>& aData,
|
||||
void* aSiblingCollector)
|
||||
{
|
||||
dom::Element* element =
|
||||
@ -42,7 +42,7 @@ CollectLaterSiblings(nsISupports* aElement,
|
||||
// document.
|
||||
if (element->GetCrossShadowCurrentDoc() == collector->tracker->Document() &&
|
||||
element->HasFlag(collector->tracker->RestyleBit()) &&
|
||||
(aData.mRestyleHint & eRestyle_LaterSiblings)) {
|
||||
(aData->mRestyleHint & eRestyle_LaterSiblings)) {
|
||||
collector->elements->AppendElement(element);
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ struct RestyleCollector {
|
||||
|
||||
static PLDHashOperator
|
||||
CollectRestyles(nsISupports* aElement,
|
||||
RestyleTracker::RestyleData& aData,
|
||||
nsAutoPtr<RestyleTracker::RestyleData>& aData,
|
||||
void* aRestyleCollector)
|
||||
{
|
||||
dom::Element* element =
|
||||
@ -83,7 +83,7 @@ CollectRestyles(nsISupports* aElement,
|
||||
// the bit, since any descendants that didn't get added
|
||||
// to the roots list because we had the bits will be
|
||||
// completely restyled in a moment.
|
||||
(aData.mChangeHint & nsChangeHint_ReconstructFrame),
|
||||
(aData->mChangeHint & nsChangeHint_ReconstructFrame),
|
||||
"Why did this not get handled while processing mRestyleRoots?");
|
||||
|
||||
// Unset the restyle bits now, so if they get readded later as we
|
||||
@ -96,8 +96,8 @@ CollectRestyles(nsISupports* aElement,
|
||||
RestyleTracker::RestyleEnumerateData* currentRestyle =
|
||||
*restyleArrayPtr;
|
||||
currentRestyle->mElement = element;
|
||||
currentRestyle->mRestyleHint = aData.mRestyleHint;
|
||||
currentRestyle->mChangeHint = aData.mChangeHint;
|
||||
currentRestyle->mRestyleHint = aData->mRestyleHint;
|
||||
currentRestyle->mChangeHint = aData->mChangeHint;
|
||||
|
||||
// Increment to the next slot in the array
|
||||
*restyleArrayPtr = currentRestyle + 1;
|
||||
@ -164,16 +164,14 @@ RestyleTracker::DoProcessRestyles()
|
||||
for (uint32_t i = 0; i < laterSiblingArr.Length(); ++i) {
|
||||
Element* element = laterSiblingArr[i];
|
||||
NS_ASSERTION(element->HasFlag(RestyleBit()), "How did that happen?");
|
||||
RestyleData data;
|
||||
RestyleData* data;
|
||||
#ifdef DEBUG
|
||||
bool found =
|
||||
#endif
|
||||
mPendingRestyles.Get(element, &data);
|
||||
NS_ASSERTION(found, "Where did our entry go?");
|
||||
data.mRestyleHint =
|
||||
nsRestyleHint(data.mRestyleHint & ~eRestyle_LaterSiblings);
|
||||
|
||||
mPendingRestyles.Put(element, data);
|
||||
data->mRestyleHint =
|
||||
nsRestyleHint(data->mRestyleHint & ~eRestyle_LaterSiblings);
|
||||
}
|
||||
|
||||
mHaveLaterSiblingRestyles = false;
|
||||
@ -197,13 +195,13 @@ RestyleTracker::DoProcessRestyles()
|
||||
continue;
|
||||
}
|
||||
|
||||
RestyleData data;
|
||||
if (!GetRestyleData(element, &data)) {
|
||||
nsAutoPtr<RestyleData> data;
|
||||
if (!GetRestyleData(element, data)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ProcessOneRestyle(element, data.mRestyleHint, data.mChangeHint);
|
||||
AddRestyleRootsIfAwaitingRestyle(data.mDescendants);
|
||||
ProcessOneRestyle(element, data->mRestyleHint, data->mChangeHint);
|
||||
AddRestyleRootsIfAwaitingRestyle(data->mDescendants);
|
||||
}
|
||||
|
||||
if (mHaveLaterSiblingRestyles) {
|
||||
@ -243,7 +241,7 @@ RestyleTracker::DoProcessRestyles()
|
||||
}
|
||||
|
||||
bool
|
||||
RestyleTracker::GetRestyleData(Element* aElement, RestyleData* aData)
|
||||
RestyleTracker::GetRestyleData(Element* aElement, nsAutoPtr<RestyleData>& aData)
|
||||
{
|
||||
NS_PRECONDITION(aElement->GetCrossShadowCurrentDoc() == Document(),
|
||||
"Unexpected document; this will lead to incorrect behavior!");
|
||||
@ -253,11 +251,8 @@ RestyleTracker::GetRestyleData(Element* aElement, RestyleData* aData)
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool gotData =
|
||||
#endif
|
||||
mPendingRestyles.Get(aElement, aData);
|
||||
NS_ASSERTION(gotData, "Must have data if restyle bit is set");
|
||||
mPendingRestyles.RemoveAndForget(aElement, aData);
|
||||
NS_ASSERTION(aData.get(), "Must have data if restyle bit is set");
|
||||
|
||||
if (aData->mRestyleHint & eRestyle_LaterSiblings) {
|
||||
// Someone readded the eRestyle_LaterSiblings hint for this
|
||||
@ -266,15 +261,14 @@ RestyleTracker::GetRestyleData(Element* aElement, RestyleData* aData)
|
||||
// since it's no longer a root with the new restyle data.
|
||||
NS_ASSERTION(aData->mDescendants.IsEmpty(),
|
||||
"expected descendants to be handled by now");
|
||||
RestyleData newData;
|
||||
newData.mChangeHint = nsChangeHint(0);
|
||||
newData.mRestyleHint = eRestyle_LaterSiblings;
|
||||
RestyleData* newData = new RestyleData;
|
||||
newData->mChangeHint = nsChangeHint(0);
|
||||
newData->mRestyleHint = eRestyle_LaterSiblings;
|
||||
mPendingRestyles.Put(aElement, newData);
|
||||
aElement->UnsetFlags(RootBit());
|
||||
aData->mRestyleHint =
|
||||
nsRestyleHint(aData->mRestyleHint & ~eRestyle_LaterSiblings);
|
||||
} else {
|
||||
mPendingRestyles.Remove(aElement);
|
||||
aElement->UnsetFlags(mRestyleBits);
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
#define mozilla_RestyleTracker_h
|
||||
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsContainerFrame.h"
|
||||
#include "mozilla/SplayTree.h"
|
||||
|
||||
@ -286,8 +286,18 @@ public:
|
||||
Element::FlagsType RootBit() const {
|
||||
return mRestyleBits & ~ELEMENT_PENDING_RESTYLE_FLAGS;
|
||||
}
|
||||
|
||||
|
||||
struct RestyleData {
|
||||
RestyleData() {
|
||||
mRestyleHint = nsRestyleHint(0);
|
||||
mChangeHint = NS_STYLE_HINT_NONE;
|
||||
}
|
||||
|
||||
RestyleData(nsRestyleHint aRestyleHint, nsChangeHint aChangeHint) {
|
||||
mRestyleHint = aRestyleHint;
|
||||
mChangeHint = aChangeHint;
|
||||
}
|
||||
|
||||
nsRestyleHint mRestyleHint; // What we want to restyle
|
||||
nsChangeHint mChangeHint; // The minimal change hint for "self"
|
||||
|
||||
@ -306,10 +316,9 @@ public:
|
||||
* eRestyle_LaterSiblings hint in it.
|
||||
*
|
||||
* The return value indicates whether any restyle data was found for
|
||||
* the element. If false is returned, then the state of *aData is
|
||||
* undefined.
|
||||
* the element. aData is set to nullptr iff false is returned.
|
||||
*/
|
||||
bool GetRestyleData(Element* aElement, RestyleData* aData);
|
||||
bool GetRestyleData(Element* aElement, nsAutoPtr<RestyleData>& aData);
|
||||
|
||||
/**
|
||||
* For each element in aElements, appends it to mRestyleRoots if it
|
||||
@ -353,14 +362,14 @@ private:
|
||||
*/
|
||||
void DoProcessRestyles();
|
||||
|
||||
typedef nsDataHashtable<nsISupportsHashKey, RestyleData> PendingRestyleTable;
|
||||
typedef nsClassHashtable<nsISupportsHashKey, RestyleData> PendingRestyleTable;
|
||||
typedef nsAutoTArray< nsRefPtr<Element>, 32> RestyleRootArray;
|
||||
// Our restyle bits. These will be a subset of ELEMENT_ALL_RESTYLE_FLAGS, and
|
||||
// will include one flag from ELEMENT_PENDING_RESTYLE_FLAGS and one flag
|
||||
// that's not in ELEMENT_PENDING_RESTYLE_FLAGS.
|
||||
Element::FlagsType mRestyleBits;
|
||||
RestyleManager* mRestyleManager; // Owns us
|
||||
// A hashtable that maps elements to RestyleData structs. The
|
||||
// A hashtable that maps elements to pointers to RestyleData structs. The
|
||||
// values only make sense if the element's current document is our
|
||||
// document and it has our RestyleBit() flag set. In particular,
|
||||
// said bit might not be set if the element had a restyle posted and
|
||||
@ -384,9 +393,7 @@ RestyleTracker::AddPendingRestyleToTable(Element* aElement,
|
||||
nsRestyleHint aRestyleHint,
|
||||
nsChangeHint aMinChangeHint)
|
||||
{
|
||||
RestyleData existingData;
|
||||
existingData.mRestyleHint = nsRestyleHint(0);
|
||||
existingData.mChangeHint = NS_STYLE_HINT_NONE;
|
||||
RestyleData* existingData;
|
||||
|
||||
// Check the RestyleBit() flag before doing the hashtable Get, since
|
||||
// it's possible that the data in the hashtable isn't actually
|
||||
@ -395,15 +402,20 @@ RestyleTracker::AddPendingRestyleToTable(Element* aElement,
|
||||
mPendingRestyles.Get(aElement, &existingData);
|
||||
} else {
|
||||
aElement->SetFlags(RestyleBit());
|
||||
existingData = nullptr;
|
||||
}
|
||||
|
||||
if (!existingData) {
|
||||
mPendingRestyles.Put(aElement,
|
||||
new RestyleData(aRestyleHint, aMinChangeHint));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hadRestyleLaterSiblings =
|
||||
(existingData.mRestyleHint & eRestyle_LaterSiblings) != 0;
|
||||
existingData.mRestyleHint =
|
||||
nsRestyleHint(existingData.mRestyleHint | aRestyleHint);
|
||||
NS_UpdateHint(existingData.mChangeHint, aMinChangeHint);
|
||||
|
||||
mPendingRestyles.Put(aElement, existingData);
|
||||
(existingData->mRestyleHint & eRestyle_LaterSiblings) != 0;
|
||||
existingData->mRestyleHint =
|
||||
nsRestyleHint(existingData->mRestyleHint | aRestyleHint);
|
||||
NS_UpdateHint(existingData->mChangeHint, aMinChangeHint);
|
||||
|
||||
return hadRestyleLaterSiblings;
|
||||
}
|
||||
@ -459,11 +471,10 @@ RestyleTracker::AddPendingRestyle(Element* aElement,
|
||||
// invariant that if two elements appear in the array and one
|
||||
// is an ancestor of the other, that the ancestor appears after
|
||||
// the descendant.
|
||||
RestyleData curData;
|
||||
// XXX We should avoid copying RestyleData::mDescendants around.
|
||||
RestyleData* curData;
|
||||
mPendingRestyles.Get(cur, &curData);
|
||||
curData.mDescendants.AppendElement(aElement);
|
||||
mPendingRestyles.Put(cur, curData);
|
||||
NS_ASSERTION(curData, "expected to find a RestyleData for cur");
|
||||
curData->mDescendants.AppendElement(aElement);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user