mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 704911. Don't restyle based on state selectors that match our node but don't depend on the state that's changing. r=dbaron
This commit is contained in:
parent
3687e2d7b5
commit
fd8c7db48c
1
layout/reftests/css-selectors/reftest.list
Normal file
1
layout/reftests/css-selectors/reftest.list
Normal file
@ -0,0 +1 @@
|
||||
== state-dependent-in-any.html state-dependent-in-any-ref.html
|
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
span { color: green; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<input value="Test"><span>This should be green</span>
|
||||
</body>
|
||||
</html>
|
16
layout/reftests/css-selectors/state-dependent-in-any.html
Normal file
16
layout/reftests/css-selectors/state-dependent-in-any.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
span { color: red; }
|
||||
:-moz-any(:valid) + span { color: green; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<input required><span>This should be green</span>
|
||||
<script>
|
||||
document.body.offsetWidth;
|
||||
document.getElementsByTagName("input")[0].value = "Test"
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -92,6 +92,9 @@ include css-submit-invalid/reftest.list
|
||||
# css text-overflow
|
||||
include text-overflow/reftest.list
|
||||
|
||||
# css selectors
|
||||
include css-selectors/reftest.list
|
||||
|
||||
# css transitions
|
||||
include css-transitions/reftest.list
|
||||
|
||||
|
@ -899,7 +899,7 @@ struct RuleCascadeData {
|
||||
RuleHash mRuleHash;
|
||||
RuleHash*
|
||||
mPseudoElementRuleHashes[nsCSSPseudoElements::ePseudo_PseudoElementCount];
|
||||
nsTArray<nsCSSSelector*> mStateSelectors;
|
||||
nsTArray<nsCSSRuleProcessor::StateSelector> mStateSelectors;
|
||||
nsEventStates mSelectorDocumentStates;
|
||||
PLDHashTable mClassSelectors;
|
||||
PLDHashTable mIdSelectors;
|
||||
@ -2367,22 +2367,26 @@ nsCSSRuleProcessor::HasStateDependentStyle(StateRuleProcessorData* aData)
|
||||
// code will be matching selectors that aren't real selectors in any
|
||||
// stylesheet (e.g., if there is a selector "body > p:hover > a", then
|
||||
// "body > p:hover" will be in |cascade->mStateSelectors|). Note that
|
||||
// |IsStateSelector| below determines which selectors are in
|
||||
// |ComputeSelectorStateDependence| below determines which selectors are in
|
||||
// |cascade->mStateSelectors|.
|
||||
nsRestyleHint hint = nsRestyleHint(0);
|
||||
if (cascade) {
|
||||
nsCSSSelector **iter = cascade->mStateSelectors.Elements(),
|
||||
**end = iter + cascade->mStateSelectors.Length();
|
||||
StateSelector *iter = cascade->mStateSelectors.Elements(),
|
||||
*end = iter + cascade->mStateSelectors.Length();
|
||||
NodeMatchContext nodeContext(aData->mStateMask, false);
|
||||
for(; iter != end; ++iter) {
|
||||
nsCSSSelector* selector = *iter;
|
||||
nsCSSSelector* selector = iter->mSelector;
|
||||
nsEventStates states = iter->mStates;
|
||||
|
||||
nsRestyleHint possibleChange = RestyleHintForOp(selector->mOperator);
|
||||
|
||||
// If hint already includes all the bits of possibleChange,
|
||||
// don't bother calling SelectorMatches, since even if it returns false
|
||||
// hint won't change.
|
||||
// Also don't bother calling SelectorMatches if none of the
|
||||
// states passed in are relevant here.
|
||||
if ((possibleChange & ~hint) &&
|
||||
states.HasAtLeastOneOfStates(aData->mStateMask) &&
|
||||
SelectorMatches(aData->mElement, selector, nodeContext,
|
||||
aData->mTreeMatchContext) &&
|
||||
SelectorMatchesTree(aData->mElement, selector->mNext,
|
||||
@ -2620,11 +2624,13 @@ nsCSSRuleProcessor::ClearRuleCascades()
|
||||
}
|
||||
|
||||
|
||||
// This function should return true only for selectors that need to be
|
||||
// checked by |HasStateDependentStyle|.
|
||||
// This function should return the set of states that this selector
|
||||
// depends on; this is used to implement HasStateDependentStyle. It
|
||||
// does NOT recur down into things like :not and :-moz-any.
|
||||
inline
|
||||
bool IsStateSelector(nsCSSSelector& aSelector)
|
||||
nsEventStates ComputeSelectorStateDependence(nsCSSSelector& aSelector)
|
||||
{
|
||||
nsEventStates states;
|
||||
for (nsPseudoClassList* pseudoClass = aSelector.mPseudoClassList;
|
||||
pseudoClass; pseudoClass = pseudoClass->mNext) {
|
||||
// Tree pseudo-elements overload mPseudoClassList for things that
|
||||
@ -2632,11 +2638,9 @@ bool IsStateSelector(nsCSSSelector& aSelector)
|
||||
if (pseudoClass->mType >= nsCSSPseudoClasses::ePseudoClass_Count) {
|
||||
continue;
|
||||
}
|
||||
if (!sPseudoClassStates[pseudoClass->mType].IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
states |= sPseudoClassStates[pseudoClass->mType];
|
||||
}
|
||||
return false;
|
||||
return states;
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -2684,8 +2688,12 @@ AddSelector(RuleCascadeData* aCascade,
|
||||
}
|
||||
|
||||
// Build mStateSelectors.
|
||||
if (IsStateSelector(*negation))
|
||||
aCascade->mStateSelectors.AppendElement(aSelectorInTopLevel);
|
||||
nsEventStates dependentStates = ComputeSelectorStateDependence(*negation);
|
||||
if (!dependentStates.IsEmpty()) {
|
||||
aCascade->mStateSelectors.AppendElement(
|
||||
nsCSSRuleProcessor::StateSelector(dependentStates,
|
||||
aSelectorInTopLevel));
|
||||
}
|
||||
|
||||
// Build mIDSelectors
|
||||
if (negation == aSelectorInTopLevel) {
|
||||
|
@ -51,12 +51,14 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCSSRules.h"
|
||||
#include "nsRuleWalker.h"
|
||||
#include "nsEventStates.h"
|
||||
|
||||
struct RuleCascadeData;
|
||||
struct nsCSSSelectorList;
|
||||
struct CascadeEnumData;
|
||||
struct TreeMatchContext;
|
||||
class nsCSSKeyframesRule;
|
||||
class nsCSSSelector;
|
||||
|
||||
/**
|
||||
* The CSS style rule processor provides a mechanism for sibling style
|
||||
@ -161,6 +163,16 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
struct StateSelector {
|
||||
StateSelector(nsEventStates aStates, nsCSSSelector* aSelector)
|
||||
: mStates(aStates),
|
||||
mSelector(aSelector)
|
||||
{}
|
||||
|
||||
nsEventStates mStates;
|
||||
nsCSSSelector* mSelector;
|
||||
};
|
||||
|
||||
private:
|
||||
static bool CascadeSheet(nsCSSStyleSheet* aSheet, CascadeEnumData* aData);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user