Backed out 13 changesets (bug 1180118) for crashes on a CLOSED TREE

Backed out changeset c65d298d7cfa (bug 1180118)
Backed out changeset 7c5ebadc3fc9 (bug 1180118)
Backed out changeset 91a3e2205388 (bug 1180118)
Backed out changeset 15ad6049b940 (bug 1180118)
Backed out changeset 9b41cd9f2bc5 (bug 1180118)
Backed out changeset 37493f6eef20 (bug 1180118)
Backed out changeset b7ec8d4d2d7e (bug 1180118)
Backed out changeset cfeeae42d514 (bug 1180118)
Backed out changeset 9bcc3233f3c8 (bug 1180118)
Backed out changeset b99c358a6fea (bug 1180118)
Backed out changeset 4a7b79980353 (bug 1180118)
Backed out changeset 20984dfa4302 (bug 1180118)
Backed out changeset ef165b896cf4 (bug 1180118)
This commit is contained in:
Carsten "Tomcat" Book 2015-08-04 12:20:20 +02:00
parent 9ac5d002ee
commit 94b10d301f
21 changed files with 234 additions and 931 deletions

View File

@ -41,8 +41,6 @@
#include "nsDisplayList.h"
#include "RestyleTrackerInlines.h"
#include "nsSMILAnimationController.h"
#include "nsCSSRuleProcessor.h"
#include "ChildIterator.h"
#ifdef ACCESSIBILITY
#include "nsAccessibilityService.h"
@ -63,15 +61,6 @@ FrameTagToString(const nsIFrame* aFrame)
aFrame->ListTag(result);
return result;
}
static nsCString
ElementTagToString(dom::Element* aElement)
{
nsCString result;
nsDependentAtomString buf(aElement->NodeInfo()->NameAtom());
result.AppendPrintf("(%s@%p)", NS_ConvertUTF16toUTF8(buf).get(), aElement);
return result;
}
#endif
RestyleManager::RestyleManager(nsPresContext* aPresContext)
@ -992,12 +981,11 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
}
void
RestyleManager::RestyleElement(Element* aElement,
nsIFrame* aPrimaryFrame,
nsChangeHint aMinHint,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint,
const RestyleHintData& aRestyleHintData)
RestyleManager::RestyleElement(Element* aElement,
nsIFrame* aPrimaryFrame,
nsChangeHint aMinHint,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint)
{
MOZ_ASSERT(mReframingStyleContexts, "should have rsc");
NS_ASSERTION(aPrimaryFrame == aElement->GetPrimaryFrame(),
@ -1022,9 +1010,6 @@ RestyleManager::RestyleElement(Element* aElement,
newContext->StyleFont()->mFont.size) {
// The basis for 'rem' units has changed.
mRebuildAllRestyleHint |= aRestyleHint;
if (aRestyleHint & eRestyle_SomeDescendants) {
mRebuildAllRestyleHint |= eRestyle_Subtree;
}
NS_UpdateHint(mRebuildAllExtraHint, aMinHint);
StartRebuildAllStyleData(aRestyleTracker);
return;
@ -1037,7 +1022,7 @@ RestyleManager::RestyleElement(Element* aElement,
nsCSSFrameConstructor::REMOVE_FOR_RECONSTRUCTION, nullptr);
} else if (aPrimaryFrame) {
ComputeAndProcessStyleChange(aPrimaryFrame, aMinHint, aRestyleTracker,
aRestyleHint, aRestyleHintData);
aRestyleHint);
} else if (aRestyleHint & ~eRestyle_LaterSiblings) {
// We're restyling an element with no frame, so we should try to
// make one if its new style says it should have one. But in order
@ -1053,8 +1038,7 @@ RestyleManager::RestyleElement(Element* aElement,
newContext->StyleDisplay()->mDisplay == NS_STYLE_DISPLAY_CONTENTS) {
// Style change for a display:contents node that did not recreate frames.
ComputeAndProcessStyleChange(newContext, aElement, aMinHint,
aRestyleTracker, aRestyleHint,
aRestyleHintData);
aRestyleTracker, aRestyleHint);
}
}
}
@ -1179,15 +1163,13 @@ RestyleManager::AttributeWillChange(Element* aElement,
int32_t aModType,
const nsAttrValue* aNewValue)
{
RestyleHintData rsdata;
nsRestyleHint rshint =
mPresContext->StyleSet()->HasAttributeDependentStyle(aElement,
aAttribute,
aModType,
false,
aNewValue,
rsdata);
PostRestyleEvent(aElement, rshint, NS_STYLE_HINT_NONE, &rsdata);
aNewValue);
PostRestyleEvent(aElement, rshint, NS_STYLE_HINT_NONE);
}
// Forwarded nsIMutationObserver method, to handle restyling (and
@ -1270,15 +1252,14 @@ RestyleManager::AttributeChanged(Element* aElement,
// See if we can optimize away the style re-resolution -- must be called after
// the frame's AttributeChanged() in case it does something that affects the style
RestyleHintData rsdata;
nsRestyleHint rshint =
mPresContext->StyleSet()->HasAttributeDependentStyle(aElement,
aAttribute,
aModType,
true,
aOldValue,
rsdata);
PostRestyleEvent(aElement, rshint, hint, &rsdata);
aOldValue);
PostRestyleEvent(aElement, rshint, hint);
}
/* static */ uint64_t
@ -1575,9 +1556,6 @@ RestyleManager::RebuildAllStyleData(nsChangeHint aExtraHint,
NS_ASSERTION(!(aExtraHint & nsChangeHint_ReconstructFrame),
"Should not reconstruct the root of the frame tree. "
"Use ReconstructDocElementHierarchy instead.");
MOZ_ASSERT(!(aRestyleHint & ~(eRestyle_Subtree | eRestyle_ForceDescendants)),
"the only bits allowed in aRestyleHint are eRestyle_Subtree and "
"eRestyle_ForceDescendants");
NS_UpdateHint(mRebuildAllExtraHint, aExtraHint);
mRebuildAllRestyleHint |= aRestyleHint;
@ -1659,8 +1637,7 @@ RestyleManager::StartRebuildAllStyleData(RestyleTracker& aRestyleTracker)
// frame and not the root node's primary frame? (We could do
// roughly what we do for aRestyleHint above.)
ComputeAndProcessStyleChange(rootFrame,
changeHint, aRestyleTracker, restyleHint,
RestyleHintData());
changeHint, aRestyleTracker, restyleHint);
}
void
@ -1842,8 +1819,7 @@ RestyleManager::UpdateOnlyAnimationStyles()
void
RestyleManager::PostRestyleEvent(Element* aElement,
nsRestyleHint aRestyleHint,
nsChangeHint aMinChangeHint,
const RestyleHintData* aRestyleHintData)
nsChangeHint aMinChangeHint)
{
if (MOZ_UNLIKELY(!mPresContext) ||
MOZ_UNLIKELY(mPresContext->PresShell()->IsDestroying())) {
@ -1855,8 +1831,7 @@ RestyleManager::PostRestyleEvent(Element* aElement,
return;
}
mPendingRestyles.AddPendingRestyle(aElement, aRestyleHint, aMinChangeHint,
aRestyleHintData);
mPendingRestyles.AddPendingRestyle(aElement, aRestyleHint, aMinChangeHint);
// Set mHavePendingNonAnimationRestyles for any restyle that could
// possibly contain non-animation styles (i.e., those that require us
@ -1895,9 +1870,6 @@ RestyleManager::PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint,
NS_ASSERTION(!(aExtraHint & nsChangeHint_ReconstructFrame),
"Should not reconstruct the root of the frame tree. "
"Use ReconstructDocElementHierarchy instead.");
MOZ_ASSERT(!(aRestyleHint & eRestyle_SomeDescendants),
"PostRebuildAllStyleDataEvent does not handle "
"eRestyle_SomeDescendants");
mDoRebuildAllStyleData = true;
NS_UpdateHint(mRebuildAllExtraHint, aExtraHint);
@ -2495,8 +2467,6 @@ ElementRestyler::ElementRestyler(nsPresContext* aPresContext,
nsStyleChangeList* aChangeList,
nsChangeHint aHintsHandledByAncestors,
RestyleTracker& aRestyleTracker,
nsTArray<nsCSSSelector*>&
aSelectorsForDescendants,
TreeMatchContext& aTreeMatchContext,
nsTArray<nsIContent*>&
aVisibleKidsOfHiddenElement,
@ -2515,7 +2485,6 @@ ElementRestyler::ElementRestyler(nsPresContext* aPresContext,
, mParentFrameHintsNotHandledForDescendants(nsChangeHint(0))
, mHintsNotHandledForDescendants(nsChangeHint(0))
, mRestyleTracker(aRestyleTracker)
, mSelectorsForDescendants(aSelectorsForDescendants)
, mTreeMatchContext(aTreeMatchContext)
, mResolvedChild(nullptr)
, mContextsToClear(aContextsToClear)
@ -2548,7 +2517,6 @@ ElementRestyler::ElementRestyler(const ElementRestyler& aParentRestyler,
aParentRestyler.mHintsNotHandledForDescendants)
, mHintsNotHandledForDescendants(nsChangeHint(0))
, mRestyleTracker(aParentRestyler.mRestyleTracker)
, mSelectorsForDescendants(aParentRestyler.mSelectorsForDescendants)
, mTreeMatchContext(aParentRestyler.mTreeMatchContext)
, mResolvedChild(nullptr)
, mContextsToClear(aParentRestyler.mContextsToClear)
@ -2595,7 +2563,6 @@ ElementRestyler::ElementRestyler(ParentContextFromChildFrame,
nsChangeHint_Hints_NotHandledForDescendants)
, mHintsNotHandledForDescendants(nsChangeHint(0))
, mRestyleTracker(aParentRestyler.mRestyleTracker)
, mSelectorsForDescendants(aParentRestyler.mSelectorsForDescendants)
, mTreeMatchContext(aParentRestyler.mTreeMatchContext)
, mResolvedChild(nullptr)
, mContextsToClear(aParentRestyler.mContextsToClear)
@ -2617,7 +2584,6 @@ ElementRestyler::ElementRestyler(nsPresContext* aPresContext,
nsStyleChangeList* aChangeList,
nsChangeHint aHintsHandledByAncestors,
RestyleTracker& aRestyleTracker,
nsTArray<nsCSSSelector*>& aSelectorsForDescendants,
TreeMatchContext& aTreeMatchContext,
nsTArray<nsIContent*>&
aVisibleKidsOfHiddenElement,
@ -2634,7 +2600,6 @@ ElementRestyler::ElementRestyler(nsPresContext* aPresContext,
, mParentFrameHintsNotHandledForDescendants(nsChangeHint(0))
, mHintsNotHandledForDescendants(nsChangeHint(0))
, mRestyleTracker(aRestyleTracker)
, mSelectorsForDescendants(aSelectorsForDescendants)
, mTreeMatchContext(aTreeMatchContext)
, mResolvedChild(nullptr)
, mContextsToClear(aContextsToClear)
@ -2734,91 +2699,6 @@ ElementRestyler::CaptureChange(nsStyleContext* aOldContext,
RestyleManager::ChangeHintToString(mHintsNotHandledForDescendants).get());
}
class MOZ_STACK_CLASS AutoSelectorArrayTruncater final
{
public:
explicit AutoSelectorArrayTruncater(nsTArray<nsCSSSelector*>& aSelectorsForDescendants)
: mSelectorsForDescendants(aSelectorsForDescendants)
, mOriginalLength(aSelectorsForDescendants.Length())
{
}
~AutoSelectorArrayTruncater()
{
mSelectorsForDescendants.TruncateLength(mOriginalLength);
}
private:
nsTArray<nsCSSSelector*>& mSelectorsForDescendants;
size_t mOriginalLength;
};
/**
* Called when we are stopping a restyle with eRestyle_SomeDescendants, to
* search for descendants that match any of the selectors in
* mSelectorsForDescendants. If the element does match one of the selectors,
* we cause it to be restyled with eRestyle_Self.
*
* We traverse down the flattened tree unless we find an element that
* (a) already has a pending restyle, or (b) does not have a pending restyle
* but does match one of the selectors in mSelectorsForDescendants. For (a),
* we add the current mSelectorsForDescendants into the existing restyle data,
* and for (b) we add a new pending restyle with that array. So in both
* cases, when we come to restyling this element back up in
* ProcessPendingRestyles, we will again find the eRestyle_SomeDescendants
* hint and its selectors array.
*
* This ensures that we don't visit descendant elements and check them
* against mSelectorsForDescendants more than once.
*/
void
ElementRestyler::AddPendingRestylesForDescendantsMatchingSelectors(
Element* aElement,
Element* aRestyleRoot)
{
LOG_RESTYLE("considering element %s for eRestyle_SomeDescendants",
ElementTagToString(aElement).get());
LOG_RESTYLE_INDENT();
if (aElement->HasFlag(mRestyleTracker.RootBit())) {
aRestyleRoot = aElement;
}
if (mRestyleTracker.HasRestyleData(aElement)) {
nsRestyleHint rshint = eRestyle_SomeDescendants;
if (SelectorMatchesForRestyle(aElement)) {
LOG_RESTYLE("element has existing restyle data and matches a selector");
rshint |= eRestyle_Self;
} else {
LOG_RESTYLE("element has existing restyle data but doesn't match selectors");
}
RestyleHintData data;
data.mSelectorsForDescendants = mSelectorsForDescendants;
mRestyleTracker.AddPendingRestyle(aElement, rshint, nsChangeHint(0), &data,
Some(aRestyleRoot));
return;
}
if (SelectorMatchesForRestyle(aElement)) {
LOG_RESTYLE("element has no restyle data but matches a selector");
RestyleHintData data;
data.mSelectorsForDescendants = mSelectorsForDescendants;
mRestyleTracker.AddPendingRestyle(aElement,
eRestyle_Self | eRestyle_SomeDescendants,
nsChangeHint(0), &data,
Some(aRestyleRoot));
return;
}
FlattenedChildIterator it(aElement);
for (nsIContent* n = it.GetNextChild(); n; n = it.GetNextChild()) {
if (n->IsElement()) {
AddPendingRestylesForDescendantsMatchingSelectors(n->AsElement(),
aRestyleRoot);
}
}
}
/**
* Recompute style for mFrame (which should not have a prev continuation
* with the same style), all of its next continuations with the same
@ -2855,8 +2735,6 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint)
AutoDisplayContentsAncestorPusher adcp(mTreeMatchContext, mFrame->PresContext(),
mFrame->GetContent() ? mFrame->GetContent()->GetParent() : nullptr);
AutoSelectorArrayTruncater asat(mSelectorsForDescendants);
// List of descendant elements of mContent we know we will eventually need to
// restyle. Before we return from this function, we call
// RestyleTracker::AddRestyleRootsIfAwaitingRestyle to ensure they get
@ -2864,7 +2742,6 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint)
nsTArray<nsRefPtr<Element>> descendants;
nsRestyleHint hintToRestore = nsRestyleHint(0);
RestyleHintData hintDataToRestore;
if (mContent && mContent->IsElement() &&
// If we're resolving from the root of the frame tree (which
// we do when mDoRebuildAllStyleData), we need to avoid getting the
@ -2886,10 +2763,7 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint)
if (NS_UpdateHint(mHintsHandled, restyleData->mChangeHint)) {
mChangeList->AppendChange(mFrame, mContent, restyleData->mChangeHint);
}
mSelectorsForDescendants.AppendElements(
restyleData->mRestyleHintData.mSelectorsForDescendants);
hintToRestore = restyleData->mRestyleHint;
hintDataToRestore = Move(restyleData->mRestyleHintData);
aRestyleHint = nsRestyleHint(aRestyleHint | restyleData->mRestyleHint);
descendants.SwapElements(restyleData->mDescendants);
}
@ -2899,8 +2773,7 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint)
// we restyle children with nsRestyleHint(0). But we pass the
// eRestyle_ForceDescendants flag down too.
nsRestyleHint childRestyleHint =
nsRestyleHint(aRestyleHint & (eRestyle_SomeDescendants |
eRestyle_Subtree |
nsRestyleHint(aRestyleHint & (eRestyle_Subtree |
eRestyle_ForceDescendants));
nsRefPtr<nsStyleContext> oldContext = mFrame->StyleContext();
@ -3003,31 +2876,6 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint)
}
mRestyleTracker.AddRestyleRootsIfAwaitingRestyle(descendants);
if (mContent->IsElement()) {
if ((aRestyleHint & eRestyle_SomeDescendants) &&
!mSelectorsForDescendants.IsEmpty()) {
Element* element = mContent->AsElement();
LOG_RESTYLE("traversing descendants of element %s to propagate "
"eRestyle_SomeDescendants for these %d selectors:",
ElementTagToString(element).get(),
int(mSelectorsForDescendants.Length()));
LOG_RESTYLE_INDENT();
#ifdef RESTYLE_LOGGING
for (nsCSSSelector* sel : mSelectorsForDescendants) {
LOG_RESTYLE("%s", sel->RestrictedSelectorToString().get());
}
#endif
Element* restyleRoot = mRestyleTracker.FindClosestRestyleRoot(element);
FlattenedChildIterator it(element);
for (nsIContent* n = it.GetNextChild(); n; n = it.GetNextChild()) {
if (n->IsElement()) {
AddPendingRestylesForDescendantsMatchingSelectors(n->AsElement(),
restyleRoot);
}
}
}
}
return;
}
@ -3229,44 +3077,6 @@ ElementRestyler::ComputeRestyleResultFromNewContext(nsIFrame* aSelf,
return eRestyleResult_Stop;
}
bool
ElementRestyler::SelectorMatchesForRestyle(Element* aElement)
{
if (!aElement) {
return false;
}
for (nsCSSSelector* selector : mSelectorsForDescendants) {
if (nsCSSRuleProcessor::RestrictedSelectorMatches(aElement, selector,
mTreeMatchContext)) {
return true;
}
}
return false;
}
bool
ElementRestyler::MustRestyleSelf(nsRestyleHint aRestyleHint,
Element* aElement)
{
return (aRestyleHint & (eRestyle_Self | eRestyle_Subtree)) ||
((aRestyleHint & eRestyle_SomeDescendants) &&
SelectorMatchesForRestyle(aElement));
}
bool
ElementRestyler::CanReparentStyleContext(nsRestyleHint aRestyleHint)
{
// If we had any restyle hints other than the ones listed below,
// which don't control whether the current frame/element needs
// a new style context by looking up a new rule node, or if
// we are reconstructing the entire rule tree, then we can't
// use ReparentStyleContext.
return !(aRestyleHint & ~(eRestyle_Force |
eRestyle_ForceDescendants |
eRestyle_SomeDescendants)) &&
!mPresContext->StyleSet()->IsInRuleTreeReconstruct();
}
ElementRestyler::RestyleResult
ElementRestyler::RestyleSelf(nsIFrame* aSelf,
nsRestyleHint aRestyleHint,
@ -3290,7 +3100,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
RestyleResult result;
if (aRestyleHint & ~eRestyle_SomeDescendants) {
if (aRestyleHint) {
result = eRestyleResult_Continue;
} else {
result = ComputeRestyleResultFromFrame(aSelf);
@ -3375,91 +3185,90 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
"non pseudo-element frame without content node");
newContext = styleSet->ResolveStyleForNonElement(parentContext);
}
else if (!(aRestyleHint & (eRestyle_Self | eRestyle_Subtree))) {
Element* element = ElementForStyleContext(mParentContent, aSelf, pseudoType);
if (!(aRestyleHint & ~(eRestyle_Force | eRestyle_ForceDescendants)) &&
!styleSet->IsInRuleTreeReconstruct()) {
LOG_RESTYLE("reparenting style context");
newContext =
styleSet->ReparentStyleContext(oldContext, parentContext, element);
} else {
// Use ResolveStyleWithReplacement either for actual replacements
// or, with no replacements, as a substitute for
// ReparentStyleContext that rebuilds the path in the rule tree
// rather than reusing the rule node, as we need to do during a
// rule tree reconstruct.
Element* pseudoElement = PseudoElementForStyleContext(aSelf, pseudoType);
MOZ_ASSERT(!element || element != pseudoElement,
"pseudo-element for selector matching should be "
"the anonymous content node that we create, "
"not the real element");
LOG_RESTYLE("resolving style with replacement");
newContext =
styleSet->ResolveStyleWithReplacement(element, pseudoElement,
parentContext, oldContext,
aRestyleHint);
}
} else if (pseudoType == nsCSSPseudoElements::ePseudo_AnonBox) {
newContext = styleSet->ResolveAnonymousBoxStyle(pseudoTag,
parentContext);
}
else {
Element* element = ElementForStyleContext(mParentContent, aSelf, pseudoType);
if (!MustRestyleSelf(aRestyleHint, element)) {
if (CanReparentStyleContext(aRestyleHint)) {
LOG_RESTYLE("reparenting style context");
newContext =
styleSet->ReparentStyleContext(oldContext, parentContext, element);
if (pseudoTag) {
if (pseudoTag == nsCSSPseudoElements::before ||
pseudoTag == nsCSSPseudoElements::after) {
// XXX what other pseudos do we need to treat like this?
newContext = styleSet->ProbePseudoElementStyle(element,
pseudoType,
parentContext,
mTreeMatchContext);
if (!newContext) {
// This pseudo should no longer exist; gotta reframe
NS_UpdateHint(mHintsHandled, nsChangeHint_ReconstructFrame);
mChangeList->AppendChange(aSelf, element,
nsChangeHint_ReconstructFrame);
// We're reframing anyway; just keep the same context
newContext = oldContext;
#ifdef DEBUG
// oldContext's parent might have had its style structs swapped out
// with parentContext, so to avoid any assertions that might
// otherwise trigger in oldContext's parent's destructor, we set a
// flag on oldContext to skip it and its descendants in
// nsStyleContext::AssertStructsNotUsedElsewhere.
if (oldContext->GetParent() != parentContext) {
oldContext->AddStyleBit(NS_STYLE_IS_GOING_AWAY);
}
#endif
}
} else {
// Use ResolveStyleWithReplacement either for actual replacements
// or, with no replacements, as a substitute for
// ReparentStyleContext that rebuilds the path in the rule tree
// rather than reusing the rule node, as we need to do during a
// rule tree reconstruct.
Element* pseudoElement = PseudoElementForStyleContext(aSelf, pseudoType);
MOZ_ASSERT(!element || element != pseudoElement,
// Don't expect XUL tree stuff here, since it needs a comparator and
// all.
NS_ASSERTION(pseudoType <
nsCSSPseudoElements::ePseudo_PseudoElementCount,
"Unexpected pseudo type");
Element* pseudoElement =
PseudoElementForStyleContext(aSelf, pseudoType);
MOZ_ASSERT(element != pseudoElement,
"pseudo-element for selector matching should be "
"the anonymous content node that we create, "
"not the real element");
LOG_RESTYLE("resolving style with replacement");
nsRestyleHint rshint = aRestyleHint & ~eRestyle_SomeDescendants;
newContext =
styleSet->ResolveStyleWithReplacement(element, pseudoElement,
parentContext, oldContext,
rshint);
}
} else if (pseudoType == nsCSSPseudoElements::ePseudo_AnonBox) {
newContext = styleSet->ResolveAnonymousBoxStyle(pseudoTag,
parentContext);
}
else {
if (pseudoTag) {
if (pseudoTag == nsCSSPseudoElements::before ||
pseudoTag == nsCSSPseudoElements::after) {
// XXX what other pseudos do we need to treat like this?
newContext = styleSet->ProbePseudoElementStyle(element,
newContext = styleSet->ResolvePseudoElementStyle(element,
pseudoType,
parentContext,
mTreeMatchContext);
if (!newContext) {
// This pseudo should no longer exist; gotta reframe
NS_UpdateHint(mHintsHandled, nsChangeHint_ReconstructFrame);
mChangeList->AppendChange(aSelf, element,
nsChangeHint_ReconstructFrame);
// We're reframing anyway; just keep the same context
newContext = oldContext;
#ifdef DEBUG
// oldContext's parent might have had its style structs swapped out
// with parentContext, so to avoid any assertions that might
// otherwise trigger in oldContext's parent's destructor, we set a
// flag on oldContext to skip it and its descendants in
// nsStyleContext::AssertStructsNotUsedElsewhere.
if (oldContext->GetParent() != parentContext) {
oldContext->AddStyleBit(NS_STYLE_IS_GOING_AWAY);
}
#endif
}
} else {
// Don't expect XUL tree stuff here, since it needs a comparator and
// all.
NS_ASSERTION(pseudoType <
nsCSSPseudoElements::ePseudo_PseudoElementCount,
"Unexpected pseudo type");
Element* pseudoElement =
PseudoElementForStyleContext(aSelf, pseudoType);
MOZ_ASSERT(element != pseudoElement,
"pseudo-element for selector matching should be "
"the anonymous content node that we create, "
"not the real element");
newContext = styleSet->ResolvePseudoElementStyle(element,
pseudoType,
parentContext,
pseudoElement);
}
}
else {
NS_ASSERTION(aSelf->GetContent(),
"non pseudo-element frame without content node");
// Skip parent display based style fixup for anonymous subtrees:
TreeMatchContext::AutoParentDisplayBasedStyleFixupSkipper
parentDisplayBasedFixupSkipper(mTreeMatchContext,
element->IsRootOfNativeAnonymousSubtree());
newContext = styleSet->ResolveStyleFor(element, parentContext,
mTreeMatchContext);
pseudoElement);
}
}
else {
NS_ASSERTION(aSelf->GetContent(),
"non pseudo-element frame without content node");
// Skip parent display based style fixup for anonymous subtrees:
TreeMatchContext::AutoParentDisplayBasedStyleFixupSkipper
parentDisplayBasedFixupSkipper(mTreeMatchContext,
element->IsRootOfNativeAnonymousSubtree());
newContext = styleSet->ResolveStyleFor(element, parentContext,
mTreeMatchContext);
}
}
MOZ_ASSERT(newContext);
@ -3648,13 +3457,10 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
NS_ASSERTION(extraPseudoTag &&
extraPseudoTag != nsCSSAnonBoxes::mozNonElement,
"extra style context is not pseudo element");
Element* element = extraPseudoType != nsCSSPseudoElements::ePseudo_AnonBox
? mContent->AsElement() : nullptr;
if (!MustRestyleSelf(aRestyleHint, element)) {
if (CanReparentStyleContext(aRestyleHint)) {
newExtraContext =
styleSet->ReparentStyleContext(oldExtraContext, newContext, element);
} else {
if (!(aRestyleHint & (eRestyle_Self | eRestyle_Subtree))) {
Element* element = extraPseudoType != nsCSSPseudoElements::ePseudo_AnonBox
? mContent->AsElement() : nullptr;
if (styleSet->IsInRuleTreeReconstruct()) {
// Use ResolveStyleWithReplacement as a substitute for
// ReparentStyleContext that rebuilds the path in the rule tree
// rather than reusing the rule node, as we need to do during a
@ -3669,6 +3475,9 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
styleSet->ResolveStyleWithReplacement(element, pseudoElement,
newContext, oldExtraContext,
nsRestyleHint(0));
} else {
newExtraContext =
styleSet->ReparentStyleContext(oldExtraContext, newContext, element);
}
} else if (extraPseudoType == nsCSSPseudoElements::ePseudo_AnonBox) {
newExtraContext = styleSet->ResolveAnonymousBoxStyle(extraPseudoTag,
@ -3777,12 +3586,11 @@ ElementRestyler::RestyleChildren(nsRestyleHint aChildRestyleHint)
void
ElementRestyler::RestyleChildrenOfDisplayContentsElement(
nsIFrame* aParentFrame,
nsStyleContext* aNewContext,
nsChangeHint aMinHint,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint,
const RestyleHintData& aRestyleHintData)
nsIFrame* aParentFrame,
nsStyleContext* aNewContext,
nsChangeHint aMinHint,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint)
{
MOZ_ASSERT(!(mHintsHandled & nsChangeHint_ReconstructFrame), "why call me?");
@ -3811,8 +3619,8 @@ ElementRestyler::RestyleChildrenOfDisplayContentsElement(
!f->GetPrevContinuation()) {
if (!(f->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
ComputeStyleChangeFor(f, mChangeList, aMinHint, aRestyleTracker,
aRestyleHint, aRestyleHintData,
mContextsToClear, mSwappedStructOwners);
aRestyleHint, mContextsToClear,
mSwappedStructOwners);
}
}
}
@ -3829,7 +3637,6 @@ ElementRestyler::ComputeStyleChangeFor(nsIFrame* aFrame,
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint,
const RestyleHintData& aRestyleHintData,
nsTArray<ContextToClear>&
aContextsToClear,
nsTArray<nsRefPtr<nsStyleContext>>&
@ -3877,9 +3684,6 @@ ElementRestyler::ComputeStyleChangeFor(nsIFrame* aFrame,
Element* parent =
content ? content->GetParentElementCrossingShadowRoot() : nullptr;
treeMatchContext.InitAncestors(parent);
nsTArray<nsCSSSelector*> selectorsForDescendants;
selectorsForDescendants.AppendElements(
aRestyleHintData.mSelectorsForDescendants);
nsTArray<nsIContent*> visibleKidsOfHiddenElement;
for (nsIFrame* ibSibling = aFrame; ibSibling;
ibSibling = GetNextBlockInInlineSibling(propTable, ibSibling)) {
@ -3894,7 +3698,6 @@ ElementRestyler::ComputeStyleChangeFor(nsIFrame* aFrame,
// Inner loop over next-in-flows of the current frame
ElementRestyler restyler(presContext, cont, aChangeList,
aMinChange, aRestyleTracker,
selectorsForDescendants,
treeMatchContext,
visibleKidsOfHiddenElement,
aContextsToClear, aSwappedStructOwners);
@ -3993,25 +3796,21 @@ ElementRestyler::RestyleUndisplayedNodes(nsRestyleHint aChildRestyleHint,
}
nsRefPtr<nsStyleContext> undisplayedContext;
nsStyleSet* styleSet = mPresContext->StyleSet();
if (MustRestyleSelf(thisChildHint, element)) {
if (thisChildHint & (eRestyle_Self | eRestyle_Subtree)) {
undisplayedContext =
styleSet->ResolveStyleFor(element, aParentContext, mTreeMatchContext);
} else if (thisChildHint ||
styleSet->IsInRuleTreeReconstruct()) {
// XXX Should the above condition ignore eRestyle_Force(Descendants)
// like the corresponding check in RestyleSelf?
// Use ResolveStyleWithReplacement either for actual
// replacements, or as a substitute for ReparentStyleContext
// that rebuilds the path in the rule tree rather than reusing
// the rule node, as we need to do during a rule tree
// reconstruct.
nsRestyleHint rshint = thisChildHint & ~eRestyle_SomeDescendants;
undisplayedContext =
styleSet->ResolveStyleWithReplacement(element, nullptr,
aParentContext,
undisplayed->mStyle,
rshint);
thisChildHint);
} else {
undisplayedContext =
styleSet->ReparentStyleContext(undisplayed->mStyle,
@ -4291,11 +4090,10 @@ ClearCachedInheritedStyleDataOnDescendants(
}
void
RestyleManager::ComputeAndProcessStyleChange(nsIFrame* aFrame,
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint,
const RestyleHintData& aRestyleHintData)
RestyleManager::ComputeAndProcessStyleChange(nsIFrame* aFrame,
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint)
{
MOZ_ASSERT(mReframingStyleContexts, "should have rsc");
nsStyleChangeList changeList;
@ -4307,19 +4105,17 @@ RestyleManager::ComputeAndProcessStyleChange(nsIFrame* aFrame,
nsTArray<nsRefPtr<nsStyleContext>> swappedStructOwners;
ElementRestyler::ComputeStyleChangeFor(aFrame, &changeList, aMinChange,
aRestyleTracker, aRestyleHint,
aRestyleHintData,
contextsToClear, swappedStructOwners);
ProcessRestyledFrames(changeList);
ClearCachedInheritedStyleDataOnDescendants(contextsToClear);
}
void
RestyleManager::ComputeAndProcessStyleChange(nsStyleContext* aNewContext,
Element* aElement,
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint,
const RestyleHintData& aRestyleHintData)
RestyleManager::ComputeAndProcessStyleChange(nsStyleContext* aNewContext,
Element* aElement,
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint)
{
MOZ_ASSERT(mReframingStyleContexts, "should have rsc");
MOZ_ASSERT(aNewContext->StyleDisplay()->mDisplay == NS_STYLE_DISPLAY_CONTENTS);
@ -4333,8 +4129,6 @@ RestyleManager::ComputeAndProcessStyleChange(nsStyleContext* aNewContext,
Element* parentElement =
parent && parent->IsElement() ? parent->AsElement() : nullptr;
treeMatchContext.InitAncestors(parentElement);
nsTArray<nsCSSSelector*> selectorsForDescendants;
nsTArray<nsIContent*> visibleKidsOfHiddenElement;
nsTArray<ElementRestyler::ContextToClear> contextsToClear;
@ -4344,12 +4138,11 @@ RestyleManager::ComputeAndProcessStyleChange(nsStyleContext* aNewContext,
nsTArray<nsRefPtr<nsStyleContext>> swappedStructOwners;
nsStyleChangeList changeList;
ElementRestyler r(frame->PresContext(), aElement, &changeList, aMinChange,
aRestyleTracker, selectorsForDescendants, treeMatchContext,
aRestyleTracker, treeMatchContext,
visibleKidsOfHiddenElement, contextsToClear,
swappedStructOwners);
r.RestyleChildrenOfDisplayContentsElement(frame, aNewContext, aMinChange,
aRestyleTracker,
aRestyleHint, aRestyleHintData);
aRestyleTracker, aRestyleHint);
ProcessRestyledFrames(changeList);
ClearCachedInheritedStyleDataOnDescendants(contextsToClear);
}
@ -4430,11 +4223,9 @@ RestyleManager::RestyleHintToString(nsRestyleHint aHint)
{
nsCString result;
bool any = false;
const char* names[] = {
"Self", "SomeDescendants", "Subtree", "LaterSiblings", "CSSTransitions",
"CSSAnimations", "SVGAttrAnimations", "StyleAttribute",
"StyleAttribute_Animations", "Force", "ForceDescendants"
};
const char* names[] = { "Self", "Subtree", "LaterSiblings", "CSSTransitions",
"CSSAnimations", "SVGAttrAnimations", "StyleAttribute",
"StyleAttribute_Animations", "Force", "ForceDescendants" };
uint32_t hint = aHint & ((1 << ArrayLength(names)) - 1);
uint32_t rest = aHint & ~((1 << ArrayLength(names)) - 1);
for (uint32_t i = 0; i < ArrayLength(names); i++) {

View File

@ -127,24 +127,18 @@ public:
*/
nsresult ReparentStyleContext(nsIFrame* aFrame);
void ClearSelectors() {
mPendingRestyles.ClearSelectors();
}
private:
// Used when restyling an element with a frame.
void ComputeAndProcessStyleChange(nsIFrame* aFrame,
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint,
const RestyleHintData& aRestyleHintData);
void ComputeAndProcessStyleChange(nsIFrame* aFrame,
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint);
// Used when restyling a display:contents element.
void ComputeAndProcessStyleChange(nsStyleContext* aNewContext,
Element* aElement,
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint,
const RestyleHintData& aRestyleHintData);
void ComputeAndProcessStyleChange(nsStyleContext* aNewContext,
Element* aElement,
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint);
public:
@ -341,12 +335,10 @@ public:
* on them.
* @param aMinChangeHint: A minimum change hint for aContent and its
* descendants.
* @param aRestyleHintData: Additional data to go with aRestyleHint.
*/
void PostRestyleEvent(Element* aElement,
nsRestyleHint aRestyleHint,
nsChangeHint aMinChangeHint,
const RestyleHintData* aRestyleHintData = nullptr);
nsChangeHint aMinChangeHint);
void PostRestyleEventForLazyConstruction()
{
@ -431,8 +423,7 @@ private:
nsIFrame* aPrimaryFrame,
nsChangeHint aMinHint,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint,
const RestyleHintData& aRestyleHintData);
nsRestyleHint aRestyleHint);
void StartRebuildAllStyleData(RestyleTracker& aRestyleTracker);
void FinishRebuildAllStyleData();
@ -523,7 +514,6 @@ public:
nsStyleChangeList* aChangeList,
nsChangeHint aHintsHandledByAncestors,
RestyleTracker& aRestyleTracker,
nsTArray<nsCSSSelector*>& aSelectorsForDescendants,
TreeMatchContext& aTreeMatchContext,
nsTArray<nsIContent*>& aVisibleKidsOfHiddenElement,
nsTArray<ContextToClear>& aContextsToClear,
@ -554,7 +544,6 @@ public:
nsStyleChangeList* aChangeList,
nsChangeHint aHintsHandledByAncestors,
RestyleTracker& aRestyleTracker,
nsTArray<nsCSSSelector*>& aSelectorsForDescendants,
TreeMatchContext& aTreeMatchContext,
nsTArray<nsIContent*>& aVisibleKidsOfHiddenElement,
nsTArray<ContextToClear>& aContextsToClear,
@ -588,9 +577,7 @@ public:
nsStyleContext* aNewContext,
nsChangeHint aMinHint,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint,
const RestyleHintData&
aRestyleHintData);
nsRestyleHint aRestyleHint);
/**
* Re-resolve the style contexts for a frame tree, building aChangeList
@ -601,7 +588,6 @@ public:
nsChangeHint aMinChange,
RestyleTracker& aRestyleTracker,
nsRestyleHint aRestyleHint,
const RestyleHintData& aRestyleHintData,
nsTArray<ContextToClear>& aContextsToClear,
nsTArray<nsRefPtr<nsStyleContext>>&
aSwappedStructOwners);
@ -644,31 +630,6 @@ private:
*/
void RestyleChildren(nsRestyleHint aChildRestyleHint);
/**
* Returns true iff a selector in mSelectorsForDescendants matches aElement.
* This is called when processing a eRestyle_SomeDescendants restyle hint.
*/
bool SelectorMatchesForRestyle(Element* aElement);
/**
* Returns true iff aRestyleHint indicates that we should be restyling.
* Specifically, this will return true when eRestyle_Self or
* eRestyle_Subtree is present, or if eRestyle_SomeDescendants is
* present and the specified element matches one of the selectors in
* mSelectorsForDescendants.
*/
bool MustRestyleSelf(nsRestyleHint aRestyleHint, Element* aElement);
/**
* Returns true iff aRestyleHint indicates that we can call
* ReparentStyleContext rather than any other restyling method of
* nsStyleSet that looks up a new rule node, and if we are
* not in the process of reconstructing the whole rule tree.
* This is used to check whether it is appropriate to call
* ReparentStyleContext.
*/
bool CanReparentStyleContext(nsRestyleHint aRestyleHint);
/**
* Helpers for Restyle().
*/
@ -729,9 +690,6 @@ private:
eNotifyHidden
};
void AddPendingRestylesForDescendantsMatchingSelectors(Element* aElement,
Element* aRestyleRoot);
#ifdef RESTYLE_LOGGING
int32_t& LoggingDepth() { return mLoggingDepth; }
#endif
@ -759,7 +717,6 @@ private:
nsChangeHint mParentFrameHintsNotHandledForDescendants;
nsChangeHint mHintsNotHandledForDescendants;
RestyleTracker& mRestyleTracker;
nsTArray<nsCSSSelector*>& mSelectorsForDescendants;
TreeMatchContext& mTreeMatchContext;
nsIFrame* mResolvedChild; // child that provides our parent style context
// Array of style context subtrees in which we need to clear out cached

View File

@ -169,9 +169,6 @@ CollectRestyles(nsISupports* aElement,
currentRestyle->mElement = element;
currentRestyle->mRestyleHint = aData->mRestyleHint;
currentRestyle->mChangeHint = aData->mChangeHint;
// We can move aData since we'll be clearing mPendingRestyles after
// we finish enumerating it.
currentRestyle->mRestyleHintData = Move(aData->mRestyleHintData);
#if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API)
currentRestyle->mBacktrace = Move(aData->mBacktrace);
#endif
@ -189,8 +186,7 @@ CollectRestyles(nsISupports* aElement,
inline void
RestyleTracker::ProcessOneRestyle(Element* aElement,
nsRestyleHint aRestyleHint,
nsChangeHint aChangeHint,
const RestyleHintData& aRestyleHintData)
nsChangeHint aChangeHint)
{
NS_PRECONDITION((aRestyleHint & eRestyle_LaterSiblings) == 0,
"Someone should have handled this before calling us");
@ -215,7 +211,7 @@ RestyleTracker::ProcessOneRestyle(Element* aElement,
}
#endif
mRestyleManager->RestyleElement(aElement, primaryFrame, aChangeHint,
*this, aRestyleHint, aRestyleHintData);
*this, aRestyleHint);
} else if (aChangeHint &&
(primaryFrame ||
(aChangeHint & nsChangeHint_ReconstructFrame))) {
@ -371,8 +367,7 @@ RestyleTracker::DoProcessRestyles()
profilerRAII.emplace("Paint", "Styles", Move(data->mBacktrace));
}
#endif
ProcessOneRestyle(element, data->mRestyleHint, data->mChangeHint,
data->mRestyleHintData);
ProcessOneRestyle(element, data->mRestyleHint, data->mChangeHint);
AddRestyleRootsIfAwaitingRestyle(data->mDescendants);
if (isTimelineRecording) {
@ -432,8 +427,7 @@ RestyleTracker::DoProcessRestyles()
ProcessOneRestyle(currentRestyle->mElement,
currentRestyle->mRestyleHint,
currentRestyle->mChangeHint,
currentRestyle->mRestyleHintData);
currentRestyle->mChangeHint);
if (isTimelineRecording) {
mozilla::UniquePtr<TimelineMarker> marker =
@ -447,9 +441,6 @@ RestyleTracker::DoProcessRestyles()
}
}
// mPendingRestyles is now empty.
mHaveSelectors = false;
mRestyleManager->EndProcessingRestyles();
}
@ -515,23 +506,4 @@ RestyleTracker::AddRestyleRootsIfAwaitingRestyle(
}
}
void
RestyleTracker::ClearSelectors()
{
if (!mHaveSelectors) {
return;
}
for (auto it = mPendingRestyles.Iter(); !it.Done(); it.Next()) {
RestyleData* data = it.Data();
if (data->mRestyleHint & eRestyle_SomeDescendants) {
data->mRestyleHint =
(data->mRestyleHint & ~eRestyle_SomeDescendants) | eRestyle_Subtree;
data->mRestyleHintData.mSelectorsForDescendants.Clear();
} else {
MOZ_ASSERT(data->mRestyleHintData.mSelectorsForDescendants.IsEmpty());
}
}
mHaveSelectors = false;
}
} // namespace mozilla

View File

@ -17,7 +17,6 @@
#include "mozilla/SplayTree.h"
#include "mozilla/RestyleLogging.h"
#include "GeckoProfiler.h"
#include "mozilla/Maybe.h"
#if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API)
#include "ProfilerBacktrace.h"
@ -231,7 +230,6 @@ public:
explicit RestyleTracker(Element::FlagsType aRestyleBits)
: mRestyleBits(aRestyleBits)
, mHaveLaterSiblingRestyles(false)
, mHaveSelectors(false)
{
NS_PRECONDITION((mRestyleBits & ~ELEMENT_ALL_RESTYLE_FLAGS) == 0,
"Why do we have these bits set?");
@ -258,19 +256,9 @@ public:
/**
* Add a restyle for the given element to the tracker. Returns true
* if the element already had eRestyle_LaterSiblings set on it.
*
* aRestyleRoot is the closest restyle root for aElement. If the caller
* does not know what the closest restyle root is, Nothing should be
* passed. A Some(nullptr) restyle root can be passed if there is no
* ancestor element that is a restyle root.
*/
bool AddPendingRestyle(Element* aElement, nsRestyleHint aRestyleHint,
nsChangeHint aMinChangeHint,
const RestyleHintData* aRestyleHintData = nullptr,
mozilla::Maybe<Element*> aRestyleRoot =
mozilla::Nothing());
Element* FindClosestRestyleRoot(Element* aElement);
nsChangeHint aMinChangeHint);
/**
* Process the restyles we've been tracking.
@ -288,9 +276,8 @@ public:
}
struct Hints {
nsRestyleHint mRestyleHint; // What we want to restyle
nsChangeHint mChangeHint; // The minimal change hint for "self"
RestyleHintData mRestyleHintData; // Data associated with mRestyleHint
nsRestyleHint mRestyleHint; // What we want to restyle
nsChangeHint mChangeHint; // The minimal change hint for "self"
};
struct RestyleData : Hints {
@ -299,13 +286,9 @@ public:
mChangeHint = NS_STYLE_HINT_NONE;
}
RestyleData(nsRestyleHint aRestyleHint, nsChangeHint aChangeHint,
const RestyleHintData* aRestyleHintData) {
RestyleData(nsRestyleHint aRestyleHint, nsChangeHint aChangeHint) {
mRestyleHint = aRestyleHint;
mChangeHint = aChangeHint;
if (aRestyleHintData) {
mRestyleHintData = *aRestyleHintData;
}
}
// Descendant elements we must check that we ended up restyling, ordered
@ -330,14 +313,6 @@ public:
*/
bool GetRestyleData(Element* aElement, nsAutoPtr<RestyleData>& aData);
/**
* Returns whether there is a RestyleData entry in mPendingRestyles
* for the given element.
*/
bool HasRestyleData(Element* aElement) {
return mPendingRestyles.Contains(aElement);
}
/**
* For each element in aElements, appends it to mRestyleRoots if it
* has its restyle bit set. This is used to ensure we restyle elements
@ -353,14 +328,6 @@ public:
void AddRestyleRootsIfAwaitingRestyle(
const nsTArray<nsRefPtr<Element>>& aElements);
/**
* Converts any eRestyle_SomeDescendants restyle hints in the pending restyle
* table into eRestyle_Subtree hints and clears out the associated arrays of
* nsCSSSelector pointers. This is called in response to a style sheet change
* that might have cause an nsCSSSelector to be destroyed.
*/
void ClearSelectors();
/**
* The document we're associated with.
*/
@ -374,8 +341,7 @@ public:
private:
bool AddPendingRestyleToTable(Element* aElement, nsRestyleHint aRestyleHint,
nsChangeHint aMinChangeHint,
const RestyleHintData* aRestyleHintData = nullptr);
nsChangeHint aMinChangeHint);
/**
* Handle a single mPendingRestyles entry. aRestyleHint must not
@ -384,8 +350,7 @@ private:
*/
inline void ProcessOneRestyle(Element* aElement,
nsRestyleHint aRestyleHint,
nsChangeHint aChangeHint,
const RestyleHintData& aRestyleHintData);
nsChangeHint aChangeHint);
typedef nsClassHashtable<nsISupportsHashKey, RestyleData> PendingRestyleTable;
typedef nsAutoTArray< nsRefPtr<Element>, 32> RestyleRootArray;
@ -411,24 +376,15 @@ private:
// flag. We need this to avoid enumerating the hashtable looking
// for such entries when we can't possibly have any.
bool mHaveLaterSiblingRestyles;
// True if we have some entries with selectors in the restyle hint data.
// We use this to skip iterating over mPendingRestyles in ClearSelectors.
bool mHaveSelectors;
};
inline bool
RestyleTracker::AddPendingRestyleToTable(Element* aElement,
nsRestyleHint aRestyleHint,
nsChangeHint aMinChangeHint,
const RestyleHintData* aRestyleHintData)
nsChangeHint aMinChangeHint)
{
RestyleData* existingData;
if (aRestyleHintData &&
!aRestyleHintData->mSelectorsForDescendants.IsEmpty()) {
mHaveSelectors = true;
}
// Check the RestyleBit() flag before doing the hashtable Get, since
// it's possible that the data in the hashtable isn't actually
// relevant anymore (if the flag is not set).
@ -440,8 +396,7 @@ RestyleTracker::AddPendingRestyleToTable(Element* aElement,
}
if (!existingData) {
RestyleData* rd =
new RestyleData(aRestyleHint, aMinChangeHint, aRestyleHintData);
RestyleData* rd = new RestyleData(aRestyleHint, aMinChangeHint);
#if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API)
if (profiler_feature_active("restyle")) {
rd->mBacktrace.reset(profiler_get_backtrace());
@ -456,63 +411,46 @@ RestyleTracker::AddPendingRestyleToTable(Element* aElement,
existingData->mRestyleHint =
nsRestyleHint(existingData->mRestyleHint | aRestyleHint);
NS_UpdateHint(existingData->mChangeHint, aMinChangeHint);
if (aRestyleHintData) {
existingData->mRestyleHintData.mSelectorsForDescendants
.AppendElements(aRestyleHintData->mSelectorsForDescendants);
}
return hadRestyleLaterSiblings;
}
inline mozilla::dom::Element*
RestyleTracker::FindClosestRestyleRoot(Element* aElement)
{
Element* cur = aElement;
while (!cur->HasFlag(RootBit())) {
nsIContent* parent = cur->GetFlattenedTreeParent();
// Stop if we have no parent or the parent is not an element or
// we're part of the viewport scrollbars (because those are not
// frametree descendants of the primary frame of the root
// element).
// XXXbz maybe the primary frame of the root should be the root scrollframe?
if (!parent || !parent->IsElement() ||
// If we've hit the root via a native anonymous kid and that
// this native anonymous kid is not obviously a descendant
// of the root's primary frame, assume we're under the root
// scrollbars. Since those don't get reresolved when
// reresolving the root, we need to make sure to add the
// element to mRestyleRoots.
(cur->IsInNativeAnonymousSubtree() && !parent->GetParent() &&
cur->GetPrimaryFrame() &&
cur->GetPrimaryFrame()->GetParent() != parent->GetPrimaryFrame())) {
return nullptr;
}
cur = parent->AsElement();
}
return cur;
}
inline bool
RestyleTracker::AddPendingRestyle(Element* aElement,
nsRestyleHint aRestyleHint,
nsChangeHint aMinChangeHint,
const RestyleHintData* aRestyleHintData,
mozilla::Maybe<Element*> aRestyleRoot)
nsChangeHint aMinChangeHint)
{
bool hadRestyleLaterSiblings =
AddPendingRestyleToTable(aElement, aRestyleHint, aMinChangeHint,
aRestyleHintData);
AddPendingRestyleToTable(aElement, aRestyleHint, aMinChangeHint);
// We can only treat this element as a restyle root if we would
// actually restyle its descendants (so either call
// ReResolveStyleContext on it or just reframe it).
if ((aRestyleHint & ~eRestyle_LaterSiblings) ||
(aMinChangeHint & nsChangeHint_ReconstructFrame)) {
Element* cur =
aRestyleRoot ? *aRestyleRoot : FindClosestRestyleRoot(aElement);
if (!cur) {
mRestyleRoots.AppendElement(aElement);
cur = aElement;
Element* cur = aElement;
while (!cur->HasFlag(RootBit())) {
nsIContent* parent = cur->GetFlattenedTreeParent();
// Stop if we have no parent or the parent is not an element or
// we're part of the viewport scrollbars (because those are not
// frametree descendants of the primary frame of the root
// element).
// XXXbz maybe the primary frame of the root should be the root scrollframe?
if (!parent || !parent->IsElement() ||
// If we've hit the root via a native anonymous kid and that
// this native anonymous kid is not obviously a descendant
// of the root's primary frame, assume we're under the root
// scrollbars. Since those don't get reresolved when
// reresolving the root, we need to make sure to add the
// element to mRestyleRoots.
(cur->IsInNativeAnonymousSubtree() && !parent->GetParent() &&
cur->GetPrimaryFrame() &&
cur->GetPrimaryFrame()->GetParent() != parent->GetPrimaryFrame())) {
mRestyleRoots.AppendElement(aElement);
cur = aElement;
break;
}
cur = parent->AsElement();
}
// At this point some ancestor of aElement (possibly aElement
// itself) is in mRestyleRoots. Set the root bit on aElement, to

View File

@ -8,11 +8,8 @@
#ifndef nsChangeHint_h___
#define nsChangeHint_h___
#include "mozilla/Types.h"
#include "nsDebug.h"
#include "nsTArray.h"
struct nsCSSSelector;
#include "mozilla/Types.h"
// Defines for various style related constants
@ -380,40 +377,36 @@ enum nsRestyleHint {
// work.)
eRestyle_Self = (1<<0),
// Rerun selector matching on descendants of the element that match
// a given selector.
eRestyle_SomeDescendants = (1<<1),
// Rerun selector matching on the element and all of its descendants.
// (Implies eRestyle_ForceDescendants, which ensures that we continue
// the restyling process for all descendants, but doesn't cause
// selector matching.)
eRestyle_Subtree = (1<<2),
eRestyle_Subtree = (1<<1),
// Rerun selector matching on all later siblings of the element and
// all of their descendants.
eRestyle_LaterSiblings = (1<<3),
eRestyle_LaterSiblings = (1<<2),
// Replace the style data coming from CSS transitions without updating
// any other style data. If a new style context results, update style
// contexts on the descendants. (Irrelevant if eRestyle_Self or
// eRestyle_Subtree is also set, since those imply a superset of the
// work.)
eRestyle_CSSTransitions = (1<<4),
eRestyle_CSSTransitions = (1<<3),
// Replace the style data coming from CSS animations without updating
// any other style data. If a new style context results, update style
// contexts on the descendants. (Irrelevant if eRestyle_Self or
// eRestyle_Subtree is also set, since those imply a superset of the
// work.)
eRestyle_CSSAnimations = (1<<5),
eRestyle_CSSAnimations = (1<<4),
// Replace the style data coming from SVG animations (SMIL Animations)
// without updating any other style data. If a new style context
// results, update style contexts on the descendants. (Irrelevant if
// eRestyle_Self or eRestyle_Subtree is also set, since those imply a
// superset of the work.)
eRestyle_SVGAttrAnimations = (1<<6),
eRestyle_SVGAttrAnimations = (1<<5),
// Replace the style data coming from inline style without updating
// any other style data. If a new style context results, update style
@ -424,22 +417,22 @@ enum nsRestyleHint {
// eRestyle_Self.
// If the change is for the advance of a declarative animation, use
// the value below instead.
eRestyle_StyleAttribute = (1<<7),
eRestyle_StyleAttribute = (1<<6),
// Same as eRestyle_StyleAttribute, but for when the change results
// from the advance of a declarative animation.
eRestyle_StyleAttribute_Animations = (1<<8),
eRestyle_StyleAttribute_Animations = (1<<7),
// Continue the restyling process to the current frame's children even
// if this frame's restyling resulted in no style changes.
eRestyle_Force = (1<<9),
eRestyle_Force = (1<<8),
// Continue the restyling process to all of the current frame's
// descendants, even if any frame's restyling resulted in no style
// changes. (Implies eRestyle_Force.) Note that this is weaker than
// eRestyle_Subtree, which makes us rerun selector matching on all
// descendants rather than just continuing the restyling process.
eRestyle_ForceDescendants = (1<<10),
eRestyle_ForceDescendants = (1<<9),
// Useful unions:
eRestyle_AllHintsWithAnimations = eRestyle_CSSTransitions |
@ -490,19 +483,4 @@ inline nsRestyleHint operator^=(nsRestyleHint& aLeft, nsRestyleHint aRight)
return aLeft = aLeft ^ aRight;
}
namespace mozilla {
/**
* Additional data used in conjunction with an nsRestyleHint to control the
* restyle process.
*/
struct RestyleHintData
{
// When eRestyle_SomeDescendants is used, this array contains the selectors
// that identify which descendants will be restyled.
nsTArray<nsCSSSelector*> mSelectorsForDescendants;
};
} // namespace mozilla
#endif /* nsChangeHint_h___ */

View File

@ -210,9 +210,7 @@ CommonAnimationManager::HasDocumentStateDependentStyle(StateRuleProcessorData* a
}
nsRestyleHint
CommonAnimationManager::HasAttributeDependentStyle(
AttributeRuleProcessorData* aData,
RestyleHintData& aRestyleHintDataResult)
CommonAnimationManager::HasAttributeDependentStyle(AttributeRuleProcessorData* aData)
{
return nsRestyleHint(0);
}

View File

@ -52,8 +52,7 @@ public:
virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override;
virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override;
virtual nsRestyleHint
HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
RestyleHintData& aRestyleHintDataResult) override;
HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override;
virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override;
virtual void RulesMatching(ElementRuleProcessorData* aData) override;
virtual void RulesMatching(PseudoElementRuleProcessorData* aData) override;

View File

@ -1709,15 +1709,6 @@ CSSStyleSheet::List(FILE* out, int32_t aIndent) const
void
CSSStyleSheet::ClearRuleCascades()
{
// We might be in ClearRuleCascades because we had a modification
// to the sheet that resulted in an nsCSSSelector being destroyed.
// Tell the RestyleManager for each document we're used in
// so that they can drop any nsCSSSelector pointers (used for
// eRestyle_SomeDescendants) in their mPendingRestyles.
for (nsStyleSet* styleSet : mStyleSets) {
styleSet->ClearSelectors();
}
bool removedSheetFromRuleProcessorCache = false;
if (mRuleProcessors) {
nsCSSRuleProcessor **iter = mRuleProcessors->Elements(),

View File

@ -62,9 +62,7 @@ SVGAttrAnimationRuleProcessor::HasDocumentStateDependentStyle(StateRuleProcessor
}
/* virtual */ nsRestyleHint
SVGAttrAnimationRuleProcessor::HasAttributeDependentStyle(
AttributeRuleProcessorData* aData,
RestyleHintData& aRestyleHintDataResult)
SVGAttrAnimationRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData)
{
return nsRestyleHint(0);
}

View File

@ -44,8 +44,7 @@ public:
virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override;
virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override;
virtual nsRestyleHint
HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
RestyleHintData& aRestyleHintDataResult) override;
HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override;
virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override;
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf)
const MOZ_MUST_OVERRIDE override;

View File

@ -559,7 +559,7 @@ nsCSSSelector::ToString(nsAString& aString, CSSStyleSheet* aSheet,
const nsCSSSelector *s = stack.ElementAt(index);
stack.RemoveElementAt(index);
s->AppendToStringWithoutCombinators(aString, aSheet, false);
s->AppendToStringWithoutCombinators(aString, aSheet);
// Append the combinator, if needed.
if (!stack.IsEmpty()) {
@ -583,85 +583,24 @@ nsCSSSelector::ToString(nsAString& aString, CSSStyleSheet* aSheet,
}
void
nsCSSSelector::AppendToStringWithoutCombinators(
nsAString& aString,
CSSStyleSheet* aSheet,
bool aUseStandardNamespacePrefixes) const
nsCSSSelector::AppendToStringWithoutCombinators
(nsAString& aString, CSSStyleSheet* aSheet) const
{
AppendToStringWithoutCombinatorsOrNegations(aString, aSheet, false,
aUseStandardNamespacePrefixes);
AppendToStringWithoutCombinatorsOrNegations(aString, aSheet, false);
for (const nsCSSSelector* negation = mNegations; negation;
negation = negation->mNegations) {
aString.AppendLiteral(":not(");
negation->AppendToStringWithoutCombinatorsOrNegations(
aString, aSheet, true, aUseStandardNamespacePrefixes);
negation->AppendToStringWithoutCombinatorsOrNegations(aString, aSheet,
true);
aString.Append(char16_t(')'));
}
}
#ifdef DEBUG
nsCString
nsCSSSelector::RestrictedSelectorToString() const
{
MOZ_ASSERT(IsRestrictedSelector());
nsString result;
AppendToStringWithoutCombinators(result, nullptr, true);
return NS_ConvertUTF16toUTF8(result);
}
static bool
AppendStandardNamespacePrefixToString(nsAString& aString, int32_t aNameSpace)
{
if (aNameSpace == kNameSpaceID_Unknown) {
// Wildcard namespace; no prefix to write.
return false;
}
switch (aNameSpace) {
case kNameSpaceID_None:
break;
case kNameSpaceID_XML:
aString.AppendLiteral("xml");
break;
case kNameSpaceID_XHTML:
aString.AppendLiteral("html");
break;
case kNameSpaceID_XLink:
aString.AppendLiteral("xlink");
break;
case kNameSpaceID_XSLT:
aString.AppendLiteral("xsl");
break;
case kNameSpaceID_XBL:
aString.AppendLiteral("xbl");
break;
case kNameSpaceID_MathML:
aString.AppendLiteral("math");
break;
case kNameSpaceID_RDF:
aString.AppendLiteral("rdf");
break;
case kNameSpaceID_XUL:
aString.AppendLiteral("xul");
break;
case kNameSpaceID_SVG:
aString.AppendLiteral("svg");
break;
default:
aString.AppendLiteral("ns");
aString.AppendInt(aNameSpace);
break;
}
return true;
}
#endif
void
nsCSSSelector::AppendToStringWithoutCombinatorsOrNegations
(nsAString& aString, CSSStyleSheet* aSheet,
bool aIsNegated,
bool aUseStandardNamespacePrefixes) const
bool aIsNegated) const
{
nsAutoString temp;
bool isPseudoElement = IsPseudoElement();
@ -677,18 +616,7 @@ nsCSSSelector::AppendToStringWithoutCombinatorsOrNegations
// null, that means that the only namespaces we could have are the
// wildcard namespace (which can be implicit in this case) and the "none"
// namespace, which then needs to be explicitly specified.
if (aUseStandardNamespacePrefixes) {
#ifdef DEBUG
// We have no sheet to look up prefix information from. This is
// only for debugging, so use some "standard" prefixes that
// are recognizable.
wroteNamespace =
AppendStandardNamespacePrefixToString(aString, mNameSpace);
if (wroteNamespace) {
aString.Append(char16_t('|'));
}
#endif
} else if (!sheetNS) {
if (!sheetNS) {
NS_ASSERTION(mNameSpace == kNameSpaceID_Unknown ||
mNameSpace == kNameSpaceID_None,
"How did we get this namespace?");
@ -812,12 +740,7 @@ nsCSSSelector::AppendToStringWithoutCombinatorsOrNegations
aString.Append(char16_t('*'));
aString.Append(char16_t('|'));
} else if (list->mNameSpace != kNameSpaceID_None) {
if (aUseStandardNamespacePrefixes) {
#ifdef DEBUG
AppendStandardNamespacePrefixToString(aString, list->mNameSpace);
aString.Append(char16_t('|'));
#endif
} else if (aSheet) {
if (aSheet) {
nsXMLNameSpaceMap *sheetNS = aSheet->GetNameSpaceMap();
nsIAtom *prefixAtom = sheetNS->FindPrefix(list->mNameSpace);
// Default namespaces don't apply to attribute selectors, so

View File

@ -159,27 +159,16 @@ public:
void ToString(nsAString& aString, mozilla::CSSStyleSheet* aSheet,
bool aAppend = false) const;
bool IsRestrictedSelector() const {
return PseudoType() == nsCSSPseudoElements::ePseudo_NotPseudoElement;
}
#ifdef DEBUG
nsCString RestrictedSelectorToString() const;
#endif
private:
void AddPseudoClassInternal(nsPseudoClassList *aPseudoClass);
nsCSSSelector* Clone(bool aDeepNext, bool aDeepNegations) const;
void AppendToStringWithoutCombinators(
nsAString& aString,
mozilla::CSSStyleSheet* aSheet,
bool aUseStandardNamespacePrefixes) const;
void AppendToStringWithoutCombinatorsOrNegations(
nsAString& aString,
mozilla::CSSStyleSheet* aSheet,
bool aIsNegated,
bool aUseStandardNamespacePrefixes) const;
void AppendToStringWithoutCombinators(nsAString& aString,
mozilla::CSSStyleSheet* aSheet) const;
void AppendToStringWithoutCombinatorsOrNegations(nsAString& aString,
mozilla::CSSStyleSheet* aSheet,
bool aIsNegated)
const;
// Returns true if this selector can have a namespace specified (which
// happens if and only if the default namespace would apply to this
// selector).

View File

@ -783,39 +783,12 @@ RuleHash::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
//--------------------------------
/**
* A struct that stores an nsCSSSelector pointer along side a pointer to
* the rightmost nsCSSSelector in the selector. For example, for
*
* .main p > span
*
* if mSelector points to the |p| nsCSSSelector, mRightmostSelector would
* point to the |span| nsCSSSelector.
*
* Both mSelector and mRightmostSelector are always top-level selectors,
* i.e. they aren't selectors within a :not() or :-moz-any().
*/
struct SelectorPair
{
SelectorPair(nsCSSSelector* aSelector, nsCSSSelector* aRightmostSelector)
: mSelector(aSelector), mRightmostSelector(aRightmostSelector)
{
MOZ_ASSERT(aSelector);
MOZ_ASSERT(mRightmostSelector);
}
SelectorPair(const SelectorPair& aOther)
: mSelector(aOther.mSelector)
, mRightmostSelector(aOther.mRightmostSelector) {}
nsCSSSelector* const mSelector;
nsCSSSelector* const mRightmostSelector;
};
// A hash table mapping atoms to lists of selectors
struct AtomSelectorEntry : public PLDHashEntryHdr {
nsIAtom *mAtom;
// Auto length 2, because a decent fraction of these arrays ends up
// with 2 elements, and each entry is cheap.
nsAutoTArray<SelectorPair, 2> mSelectors;
nsAutoTArray<nsCSSSelector*, 2> mSelectors;
};
static void
@ -938,7 +911,7 @@ struct RuleCascadeData {
// Looks up or creates the appropriate list in |mAttributeSelectors|.
// Returns null only on allocation failure.
nsTArray<SelectorPair>* AttributeListFor(nsIAtom* aAttribute);
nsTArray<nsCSSSelector*>* AttributeListFor(nsIAtom* aAttribute);
nsMediaQueryResultCacheKey mCacheKey;
RuleCascadeData* mNext; // for a different medium
@ -1002,7 +975,7 @@ RuleCascadeData::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
return n;
}
nsTArray<SelectorPair>*
nsTArray<nsCSSSelector*>*
RuleCascadeData::AttributeListFor(nsIAtom* aAttribute)
{
AtomSelectorEntry *entry =
@ -2320,63 +2293,6 @@ static bool SelectorMatches(Element* aElement,
#undef STATE_CHECK
#ifdef DEBUG
static bool
HasPseudoClassSelectorArgsWithCombinators(nsCSSSelector* aSelector)
{
for (nsPseudoClassList* p = aSelector->mPseudoClassList; p; p = p->mNext) {
if (nsCSSPseudoClasses::HasSelectorListArg(p->mType)) {
for (nsCSSSelectorList* l = p->u.mSelectors; l; l = l->mNext) {
if (l->mSelectors->mNext) {
return true;
}
}
}
}
for (nsCSSSelector* n = aSelector->mNegations; n; n = n->mNegations) {
if (n->mNext) {
return true;
}
}
return false;
}
#endif
/* static */ bool
nsCSSRuleProcessor::RestrictedSelectorMatches(
Element* aElement,
nsCSSSelector* aSelector,
TreeMatchContext& aTreeMatchContext)
{
MOZ_ASSERT(aSelector->IsRestrictedSelector(),
"aSelector must not have a pseudo-element");
NS_WARN_IF_FALSE(!HasPseudoClassSelectorArgsWithCombinators(aSelector),
"processing eRestyle_SomeDescendants can be slow if "
"pseudo-classes with selector arguments can now have "
"combinators in them");
// We match aSelector as if :visited and :link both match visited and
// unvisited links.
NodeMatchContext nodeContext(EventStates(),
nsCSSRuleProcessor::IsLink(aElement));
if (nodeContext.mIsRelevantLink) {
aTreeMatchContext.SetHaveRelevantLink();
}
aTreeMatchContext.ResetForUnvisitedMatching();
bool matches = SelectorMatches(aElement, aSelector, nodeContext,
aTreeMatchContext, SelectorMatchesFlags::NONE);
if (nodeContext.mIsRelevantLink) {
aTreeMatchContext.ResetForVisitedMatching();
if (SelectorMatches(aElement, aSelector, nodeContext, aTreeMatchContext,
SelectorMatchesFlags::NONE)) {
matches = true;
}
}
return matches;
}
// Right now, there are four operators:
// ' ', the descendant combinator, is greedy
// '~', the indirect adjacent sibling combinator, is greedy
@ -2781,81 +2697,16 @@ nsCSSRuleProcessor::HasDocumentStateDependentStyle(StateRuleProcessorData* aData
}
struct AttributeEnumData {
AttributeEnumData(AttributeRuleProcessorData *aData,
RestyleHintData& aRestyleHintData)
: data(aData), change(nsRestyleHint(0)), hintData(aRestyleHintData) {}
explicit AttributeEnumData(AttributeRuleProcessorData *aData)
: data(aData), change(nsRestyleHint(0)) {}
AttributeRuleProcessorData *data;
nsRestyleHint change;
RestyleHintData& hintData;
};
static inline nsRestyleHint
RestyleHintForSelectorWithAttributeChange(nsRestyleHint aCurrentHint,
nsCSSSelector* aSelector,
nsCSSSelector* aRightmostSelector)
{
MOZ_ASSERT(aSelector);
char16_t oper = aSelector->mOperator;
if (oper == char16_t('+') || oper == char16_t('~')) {
return eRestyle_LaterSiblings;
}
if (oper == char16_t(':')) {
return eRestyle_Subtree;
}
if (oper != char16_t(0)) {
// Check whether the selector is in a form that supports
// eRestyle_SomeDescendants. If it isn't, return eRestyle_Subtree.
if (aCurrentHint & eRestyle_Subtree) {
// No point checking, since we'll end up restyling the whole
// subtree anyway.
return eRestyle_Subtree;
}
if (!aRightmostSelector) {
// aSelector wasn't a top-level selector, which means we were inside
// a :not() or :-moz-any(). We don't support that.
return eRestyle_Subtree;
}
MOZ_ASSERT(aSelector != aRightmostSelector,
"if aSelector == aRightmostSelector then we should have "
"no operator");
// Check that aRightmostSelector can be passed to RestrictedSelectorMatches.
if (!aRightmostSelector->IsRestrictedSelector()) {
return eRestyle_Subtree;
}
// We also don't support pseudo-elements on any of the selectors
// between aRightmostSelector and aSelector.
// XXX Can we lift this restriction, so that we don't have to loop
// over all the selectors?
for (nsCSSSelector* sel = aRightmostSelector->mNext;
sel != aSelector;
sel = sel->mNext) {
MOZ_ASSERT(sel, "aSelector must be reachable from aRightmostSelector");
if (sel->PseudoType() != nsCSSPseudoElements::ePseudo_NotPseudoElement) {
return eRestyle_Subtree;
}
}
return eRestyle_SomeDescendants;
}
return eRestyle_Self;
}
static void
AttributeEnumFunc(nsCSSSelector* aSelector,
nsCSSSelector* aRightmostSelector,
AttributeEnumData* aData)
AttributeEnumFunc(nsCSSSelector* aSelector, AttributeEnumData* aData)
{
AttributeRuleProcessorData *data = aData->data;
@ -2866,36 +2717,18 @@ AttributeEnumFunc(nsCSSSelector* aSelector,
return;
}
nsRestyleHint possibleChange =
RestyleHintForSelectorWithAttributeChange(aData->change,
aSelector, aRightmostSelector);
nsRestyleHint possibleChange = RestyleHintForOp(aSelector->mOperator);
// If, ignoring eRestyle_SomeDescendants, enumData->change already includes
// all the bits of possibleChange, don't bother calling SelectorMatches, since
// even if it returns false enumData->change won't change. If possibleChange
// has eRestyle_SomeDescendants, we need to call SelectorMatches(Tree)
// regardless as it might give us new selectors to append to
// mSelectorsForDescendants.
// If enumData->change already includes all the bits of possibleChange, don't
// bother calling SelectorMatches, since even if it returns false
// enumData->change won't change.
NodeMatchContext nodeContext(EventStates(), false);
if (((possibleChange & (~(aData->change) | eRestyle_SomeDescendants))) &&
if ((possibleChange & ~(aData->change)) &&
SelectorMatches(data->mElement, aSelector, nodeContext,
data->mTreeMatchContext, SelectorMatchesFlags::UNKNOWN) &&
SelectorMatchesTree(data->mElement, aSelector->mNext,
data->mTreeMatchContext, false)) {
aData->change = nsRestyleHint(aData->change | possibleChange);
if (possibleChange & eRestyle_SomeDescendants) {
aData->hintData.mSelectorsForDescendants.AppendElement(aRightmostSelector);
}
}
}
static MOZ_ALWAYS_INLINE void
EnumerateSelectors(nsTArray<SelectorPair>& aSelectors, AttributeEnumData* aData)
{
SelectorPair *iter = aSelectors.Elements(),
*end = iter + aSelectors.Length();
for (; iter != end; ++iter) {
AttributeEnumFunc(iter->mSelector, iter->mRightmostSelector, aData);
}
}
@ -2905,19 +2738,17 @@ EnumerateSelectors(nsTArray<nsCSSSelector*>& aSelectors, AttributeEnumData* aDat
nsCSSSelector **iter = aSelectors.Elements(),
**end = iter + aSelectors.Length();
for (; iter != end; ++iter) {
AttributeEnumFunc(*iter, nullptr, aData);
AttributeEnumFunc(*iter, aData);
}
}
nsRestyleHint
nsCSSRuleProcessor::HasAttributeDependentStyle(
AttributeRuleProcessorData* aData,
RestyleHintData& aRestyleHintDataResult)
nsCSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData)
{
// We could try making use of aData->mModType, but :not rules make it a bit
// of a pain to do so... So just ignore it for now.
AttributeEnumData data(aData, aRestyleHintDataResult);
AttributeEnumData data(aData);
// Don't do our special handling of certain attributes if the attr
// hasn't changed yet.
@ -3239,9 +3070,7 @@ AddSelector(RuleCascadeData* aCascade,
// The part between combinators at the top level of the selector
nsCSSSelector* aSelectorInTopLevel,
// The part we should look through (might be in :not or :-moz-any())
nsCSSSelector* aSelectorPart,
// The right-most selector at the top level
nsCSSSelector* aRightmostSelector)
nsCSSSelector* aSelectorPart)
{
// It's worth noting that this loop over negations isn't quite
// optimal for two reasons. One, we could add something to one of
@ -3266,13 +3095,12 @@ AddSelector(RuleCascadeData* aCascade,
break;
}
case nsCSSPseudoClasses::ePseudoClass_mozTableBorderNonzero: {
nsTArray<SelectorPair> *array =
nsTArray<nsCSSSelector*> *array =
aCascade->AttributeListFor(nsGkAtoms::border);
if (!array) {
return false;
}
array->AppendElement(SelectorPair(aSelectorInTopLevel,
aRightmostSelector));
array->AppendElement(aSelectorInTopLevel);
break;
}
default: {
@ -3296,8 +3124,7 @@ AddSelector(RuleCascadeData* aCascade,
AtomSelectorEntry *entry = static_cast<AtomSelectorEntry*>
(PL_DHashTableAdd(&aCascade->mIdSelectors, curID->mAtom, fallible));
if (entry) {
entry->mSelectors.AppendElement(SelectorPair(aSelectorInTopLevel,
aRightmostSelector));
entry->mSelectors.AppendElement(aSelectorInTopLevel);
}
}
} else if (negation->mIDList) {
@ -3312,8 +3139,7 @@ AddSelector(RuleCascadeData* aCascade,
(PL_DHashTableAdd(&aCascade->mClassSelectors, curClass->mAtom,
fallible));
if (entry) {
entry->mSelectors.AppendElement(SelectorPair(aSelectorInTopLevel,
aRightmostSelector));
entry->mSelectors.AppendElement(aSelectorInTopLevel);
}
}
} else if (negation->mClassList) {
@ -3323,20 +3149,18 @@ AddSelector(RuleCascadeData* aCascade,
// Build mAttributeSelectors.
for (nsAttrSelector *attr = negation->mAttrList; attr;
attr = attr->mNext) {
nsTArray<SelectorPair> *array =
nsTArray<nsCSSSelector*> *array =
aCascade->AttributeListFor(attr->mCasedAttr);
if (!array) {
return false;
}
array->AppendElement(SelectorPair(aSelectorInTopLevel,
aRightmostSelector));
array->AppendElement(aSelectorInTopLevel);
if (attr->mLowercaseAttr != attr->mCasedAttr) {
array = aCascade->AttributeListFor(attr->mLowercaseAttr);
if (!array) {
return false;
}
array->AppendElement(SelectorPair(aSelectorInTopLevel,
aRightmostSelector));
array->AppendElement(aSelectorInTopLevel);
}
}
@ -3346,8 +3170,7 @@ AddSelector(RuleCascadeData* aCascade,
if (pseudoClass->mType == nsCSSPseudoClasses::ePseudoClass_any) {
for (nsCSSSelectorList *l = pseudoClass->u.mSelectors; l; l = l->mNext) {
nsCSSSelector *s = l->mSelectors;
if (!AddSelector(aCascade, aSelectorInTopLevel, s,
aRightmostSelector)) {
if (!AddSelector(aCascade, aSelectorInTopLevel, s)) {
return false;
}
}
@ -3428,7 +3251,7 @@ AddRule(RuleSelectorPair* aRuleInfo, RuleCascadeData* aCascade)
continue;
}
}
if (!AddSelector(cascade, selector, selector, aRuleInfo->mSelector)) {
if (!AddSelector(cascade, selector, selector)) {
return false;
}
}

View File

@ -112,21 +112,6 @@ public:
*/
static bool IsLink(mozilla::dom::Element* aElement);
/**
* Returns true if the given aElement matches aSelector.
* Like nsCSSRuleProcessor.cpp's SelectorMatches (and unlike
* SelectorMatchesTree), this does not check an entire selector list
* separated by combinators.
*
* :visited and :link will match both visited and non-visited links,
* as if aTreeMatchContext->mVisitedHandling were eLinksVisitedOrUnvisited.
*
* aSelector is restricted to not containing pseudo-elements.
*/
static bool RestrictedSelectorMatches(mozilla::dom::Element* aElement,
nsCSSSelector* aSelector,
TreeMatchContext& aTreeMatchContext);
// nsIStyleRuleProcessor
virtual void RulesMatching(ElementRuleProcessorData* aData) override;
@ -144,9 +129,7 @@ public:
virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override;
virtual nsRestyleHint
HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
mozilla::RestyleHintData& aRestyleHintDataResult)
override;
HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override;
virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override;

View File

@ -144,9 +144,7 @@ nsHTMLCSSStyleSheet::HasDocumentStateDependentStyle(StateRuleProcessorData* aDat
// Test if style is dependent on attribute
/* virtual */ nsRestyleHint
nsHTMLCSSStyleSheet::HasAttributeDependentStyle(
AttributeRuleProcessorData* aData,
RestyleHintData& aRestyleHintDataResult)
nsHTMLCSSStyleSheet::HasAttributeDependentStyle(AttributeRuleProcessorData* aData)
{
// Perhaps should check that it's XUL, SVG, (or HTML) namespace, but
// it doesn't really matter.

View File

@ -43,8 +43,7 @@ public:
virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override;
virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override;
virtual nsRestyleHint
HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
mozilla::RestyleHintData& aRestyleHintDataResult) override;
HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override;
virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override;
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf)
const MOZ_MUST_OVERRIDE override;

View File

@ -335,9 +335,7 @@ nsHTMLStyleSheet::HasDocumentStateDependentStyle(StateRuleProcessorData* aData)
}
/* virtual */ nsRestyleHint
nsHTMLStyleSheet::HasAttributeDependentStyle(
AttributeRuleProcessorData* aData,
RestyleHintData& aRestyleHintDataResult)
nsHTMLStyleSheet::HasAttributeDependentStyle(AttributeRuleProcessorData* aData)
{
// Do nothing on before-change checks
if (!aData->mAttrHasChanged) {

View File

@ -45,8 +45,7 @@ public:
virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override;
virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override;
virtual nsRestyleHint
HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
mozilla::RestyleHintData& aRestyleHintDataResult) override;
HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override;
virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override;
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf)
const MOZ_MUST_OVERRIDE override;

View File

@ -115,9 +115,8 @@ public:
* only, and may err on the side of reporting more dependencies than
* really exist.
*/
virtual nsRestyleHint HasAttributeDependentStyle(
AttributeRuleProcessorData* aData,
mozilla::RestyleHintData& aRestyleHintDataResult) = 0;
virtual nsRestyleHint
HasAttributeDependentStyle(AttributeRuleProcessorData* aData) = 0;
/**
* Do any processing that needs to happen as a result of a change in

View File

@ -385,14 +385,6 @@ SortStyleSheetsByScope(nsTArray<CSSStyleSheet*>& aSheets)
nsresult
nsStyleSet::GatherRuleProcessors(sheetType aType)
{
// We might be in GatherRuleProcessors because we are dropping a sheet,
// resulting in an nsCSSSelector being destroyed. Tell the
// RestyleManager for each document we're used in so that they can
// drop any nsCSSSelector pointers (used for eRestyle_SomeDescendants)
// in their mPendingRestyles.
if (IsCSSSheetType(aType)) {
ClearSelectors();
}
nsCOMPtr<nsIStyleRuleProcessor> oldRuleProcessor(mRuleProcessors[aType]);
nsTArray<nsCOMPtr<nsIStyleRuleProcessor>> oldScopedDocRuleProcessors;
if (aType == eAgentSheet || aType == eUserSheet) {
@ -2385,16 +2377,14 @@ struct MOZ_STACK_CLASS AttributeData : public AttributeRuleProcessorData {
aAttrHasChanged, aOtherValue, aTreeMatchContext),
mHint(nsRestyleHint(0))
{}
nsRestyleHint mHint;
RestyleHintData mHintData;
nsRestyleHint mHint;
};
static bool
SheetHasAttributeStyle(nsIStyleRuleProcessor* aProcessor, void *aData)
{
AttributeData* data = (AttributeData*)aData;
nsRestyleHint hint =
aProcessor->HasAttributeDependentStyle(data, data->mHintData);
nsRestyleHint hint = aProcessor->HasAttributeDependentStyle(data);
data->mHint = nsRestyleHint(data->mHint | hint);
return true; // continue
}
@ -2405,9 +2395,7 @@ nsStyleSet::HasAttributeDependentStyle(Element* aElement,
nsIAtom* aAttribute,
int32_t aModType,
bool aAttrHasChanged,
const nsAttrValue* aOtherValue,
mozilla::RestyleHintData&
aRestyleHintDataResult)
const nsAttrValue* aOtherValue)
{
TreeMatchContext treeContext(false, nsRuleWalker::eLinksVisitedOrUnvisited,
aElement->OwnerDoc());
@ -2415,11 +2403,6 @@ nsStyleSet::HasAttributeDependentStyle(Element* aElement,
AttributeData data(PresContext(), aElement, aAttribute,
aModType, aAttrHasChanged, aOtherValue, treeContext);
WalkRuleProcessors(SheetHasAttributeStyle, &data, false);
if (!(data.mHint & eRestyle_Subtree)) {
// No point keeping the list of selectors around if we are going to
// restyle the whole subtree unconditionally.
aRestyleHintDataResult = Move(data.mHintData);
}
return data.mHint;
}
@ -2506,9 +2489,3 @@ nsStyleSet::HasRuleProcessorUsedByMultipleStyleSets(sheetType aSheetType)
static_cast<nsCSSRuleProcessor*>(mRuleProcessors[aSheetType].get());
return rp->IsUsedByMultipleStyleSets();
}
void
nsStyleSet::ClearSelectors()
{
PresContext()->RestyleManager()->ClearSelectors();
}

View File

@ -286,9 +286,7 @@ class nsStyleSet final
nsIAtom* aAttribute,
int32_t aModType,
bool aAttrHasChanged,
const nsAttrValue* aOtherValue,
mozilla::RestyleHintData&
aRestyleHintDataResult);
const nsAttrValue* aOtherValue);
/*
* Do any processing that needs to happen as a result of a change in
@ -399,10 +397,6 @@ class nsStyleSet final
bool HasRuleProcessorUsedByMultipleStyleSets(sheetType aSheetType);
// Tells the RestyleManager for the document using this style set
// to drop any nsCSSSelector pointers it has.
void ClearSelectors();
private:
nsStyleSet(const nsStyleSet& aCopy) = delete;
nsStyleSet& operator=(const nsStyleSet& aCopy) = delete;