mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1180118 - Part 6: Return eRestyle_SomeDescendants from HasAttributeDependentStyle where appropriate. r=bzbarsky
This commit is contained in:
parent
9bb0cce6bd
commit
1a33569ab2
@ -159,11 +159,9 @@ public:
|
||||
void ToString(nsAString& aString, mozilla::CSSStyleSheet* aSheet,
|
||||
bool aAppend = false) const;
|
||||
|
||||
#ifdef DEBUG
|
||||
bool IsRestrictedSelector() const {
|
||||
return PseudoType() == nsCSSPseudoElements::ePseudo_NotPseudoElement;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
void AddPseudoClassInternal(nsPseudoClassList *aPseudoClass);
|
||||
|
@ -2781,14 +2781,77 @@ nsCSSRuleProcessor::HasDocumentStateDependentStyle(StateRuleProcessorData* aData
|
||||
}
|
||||
|
||||
struct AttributeEnumData {
|
||||
explicit AttributeEnumData(AttributeRuleProcessorData *aData)
|
||||
: data(aData), change(nsRestyleHint(0)) {}
|
||||
AttributeEnumData(AttributeRuleProcessorData *aData,
|
||||
RestyleHintData& aRestyleHintData)
|
||||
: data(aData), change(nsRestyleHint(0)), hintData(aRestyleHintData) {}
|
||||
|
||||
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,
|
||||
@ -2803,18 +2866,26 @@ AttributeEnumFunc(nsCSSSelector* aSelector,
|
||||
return;
|
||||
}
|
||||
|
||||
nsRestyleHint possibleChange = RestyleHintForOp(aSelector->mOperator);
|
||||
nsRestyleHint possibleChange =
|
||||
RestyleHintForSelectorWithAttributeChange(aData->change,
|
||||
aSelector, aRightmostSelector);
|
||||
|
||||
// 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.
|
||||
// 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.
|
||||
NodeMatchContext nodeContext(EventStates(), false);
|
||||
if ((possibleChange & ~(aData->change)) &&
|
||||
if (((possibleChange & (~(aData->change) | eRestyle_SomeDescendants))) &&
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2846,7 +2917,7 @@ nsCSSRuleProcessor::HasAttributeDependentStyle(
|
||||
// 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);
|
||||
AttributeEnumData data(aData, aRestyleHintDataResult);
|
||||
|
||||
// Don't do our special handling of certain attributes if the attr
|
||||
// hasn't changed yet.
|
||||
|
Loading…
Reference in New Issue
Block a user