diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index 0f7a0ce919ac..f9f8bd37fdac 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -2764,20 +2764,23 @@ private: * against mSelectorsForDescendants more than once. */ void -ElementRestyler::AddPendingRestylesForDescendantsMatchingSelectors(Element* aElement) +ElementRestyler::AddPendingRestylesForDescendantsMatchingSelectors( + Element* aElement, + Element* aRestyleRoot) { + if (aElement->HasFlag(mRestyleTracker.RootBit())) { + aRestyleRoot = aElement; + } + if (mRestyleTracker.HasRestyleData(aElement)) { nsRestyleHint rshint = eRestyle_SomeDescendants; if (SelectorMatchesForRestyle(aElement)) { rshint |= eRestyle_Self; } - // XXX Traversing up the tree in AddPendingRestyle can be wasteful, - // as we can do this multiple times for descendants of the element - // we stopped restyling at, up in Restyle(). We should track the - // current restyle root as we traverse down here to avoid that. RestyleHintData data; data.mSelectorsForDescendants = mSelectorsForDescendants; - mRestyleTracker.AddPendingRestyle(aElement, rshint, nsChangeHint(0), &data); + mRestyleTracker.AddPendingRestyle(aElement, rshint, nsChangeHint(0), &data, + Some(aRestyleRoot)); return; } @@ -2786,14 +2789,16 @@ ElementRestyler::AddPendingRestylesForDescendantsMatchingSelectors(Element* aEle data.mSelectorsForDescendants = mSelectorsForDescendants; mRestyleTracker.AddPendingRestyle(aElement, eRestyle_Self | eRestyle_SomeDescendants, - nsChangeHint(0), &data); + nsChangeHint(0), &data, + Some(aRestyleRoot)); return; } FlattenedChildIterator it(aElement); for (nsIContent* n = it.GetNextChild(); n; n = it.GetNextChild()) { if (n->IsElement()) { - AddPendingRestylesForDescendantsMatchingSelectors(n->AsElement()); + AddPendingRestylesForDescendantsMatchingSelectors(n->AsElement(), + aRestyleRoot); } } } @@ -2986,10 +2991,13 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint) if (mContent->IsElement()) { if ((aRestyleHint & eRestyle_SomeDescendants) && !mSelectorsForDescendants.IsEmpty()) { - FlattenedChildIterator it(mContent->AsElement()); + Element* element = mContent->AsElement(); + Element* restyleRoot = mRestyleTracker.FindClosestRestyleRoot(element); + FlattenedChildIterator it(element); for (nsIContent* n = it.GetNextChild(); n; n = it.GetNextChild()) { if (n->IsElement()) { - AddPendingRestylesForDescendantsMatchingSelectors(n->AsElement()); + AddPendingRestylesForDescendantsMatchingSelectors(n->AsElement(), + restyleRoot); } } } diff --git a/layout/base/RestyleManager.h b/layout/base/RestyleManager.h index 13afc16188f5..91e6fc30485a 100644 --- a/layout/base/RestyleManager.h +++ b/layout/base/RestyleManager.h @@ -715,7 +715,8 @@ private: eNotifyHidden }; - void AddPendingRestylesForDescendantsMatchingSelectors(Element* aElement); + void AddPendingRestylesForDescendantsMatchingSelectors(Element* aElement, + Element* aRestyleRoot); #ifdef RESTYLE_LOGGING int32_t& LoggingDepth() { return mLoggingDepth; }