mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 977991 patch 3 - Add ability for RuleNodeWithReplacement to replace the style attribute rule and its important rule. r=birtles
This allows posting a restyle that says that only the rule(s) from the StyleAttrSheet cascade level will be replaced, which avoids running selector matching. Part 4 will ensure that we only invoke this code for element styles (and not pseudo-element or anonymous box styles). Despite that, I prefer having the runtime check here as well given that it's a very simple way to ensure we don't do something silly that might have security implications.
This commit is contained in:
parent
b4d8a65955
commit
5e262a47d8
@ -313,6 +313,15 @@ enum nsRestyleHint {
|
||||
// superset of the work.)
|
||||
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
|
||||
// contexts on the descendants. (Irrelevant if eRestyle_Self or
|
||||
// eRestyle_Subtree is also set, since those imply a superset of the
|
||||
// work.) Supported only for element style contexts and not for
|
||||
// pseudo-elements or anonymous boxes, on which it converts to
|
||||
// eRestyle_Self.
|
||||
eRestyle_StyleAttribute = (1<<6),
|
||||
|
||||
// Continue the restyling process to the current frame's children even
|
||||
// if this frame's restyling resulted in no style changes.
|
||||
eRestyle_Force = (1<<8),
|
||||
|
@ -1339,12 +1339,12 @@ static const CascadeLevel gCascadeLevels[] = {
|
||||
{ nsStyleSet::eSVGAttrAnimationSheet, false, false, eRestyle_SVGAttrAnimations },
|
||||
{ nsStyleSet::eDocSheet, false, false, nsRestyleHint(0) },
|
||||
{ nsStyleSet::eScopedDocSheet, false, false, nsRestyleHint(0) },
|
||||
{ nsStyleSet::eStyleAttrSheet, false, false, nsRestyleHint(0) },
|
||||
{ nsStyleSet::eStyleAttrSheet, false, true, eRestyle_StyleAttribute },
|
||||
{ nsStyleSet::eOverrideSheet, false, false, nsRestyleHint(0) },
|
||||
{ nsStyleSet::eAnimationSheet, false, false, eRestyle_CSSAnimations },
|
||||
{ nsStyleSet::eScopedDocSheet, true, false, nsRestyleHint(0) },
|
||||
{ nsStyleSet::eDocSheet, true, false, nsRestyleHint(0) },
|
||||
{ nsStyleSet::eStyleAttrSheet, true, false, nsRestyleHint(0) },
|
||||
{ nsStyleSet::eStyleAttrSheet, true, false, eRestyle_StyleAttribute },
|
||||
{ nsStyleSet::eOverrideSheet, true, false, nsRestyleHint(0) },
|
||||
{ nsStyleSet::eUserSheet, true, false, nsRestyleHint(0) },
|
||||
{ nsStyleSet::eAgentSheet, true, false, nsRestyleHint(0) },
|
||||
@ -1360,6 +1360,7 @@ nsStyleSet::RuleNodeWithReplacement(Element* aElement,
|
||||
NS_ABORT_IF_FALSE(!(aReplacements & ~(eRestyle_CSSTransitions |
|
||||
eRestyle_CSSAnimations |
|
||||
eRestyle_SVGAttrAnimations |
|
||||
eRestyle_StyleAttribute |
|
||||
eRestyle_Force |
|
||||
eRestyle_ForceDescendants)),
|
||||
// FIXME: Once bug 979133 lands we'll have a better
|
||||
@ -1387,6 +1388,12 @@ nsStyleSet::RuleNodeWithReplacement(Element* aElement,
|
||||
nsRuleWalker ruleWalker(mRuleTree, mAuthorStyleDisabled);
|
||||
auto rulesIndex = rules.Length();
|
||||
|
||||
// We need to transfer this information between the non-!important and
|
||||
// !important phases for the style attribute level.
|
||||
nsRuleNode* lastScopedRN = nullptr;
|
||||
nsRuleNode* lastStyleAttrRN = nullptr;
|
||||
bool haveImportantStyleAttrRules = false;
|
||||
|
||||
for (const CascadeLevel *level = gCascadeLevels,
|
||||
*levelEnd = ArrayEnd(gCascadeLevels);
|
||||
level != levelEnd; ++level) {
|
||||
@ -1446,7 +1453,37 @@ nsStyleSet::RuleNodeWithReplacement(Element* aElement,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case eRestyle_StyleAttribute: {
|
||||
if (!level->mIsImportant) {
|
||||
// First time through, we handle the non-!important rule.
|
||||
MOZ_ASSERT(aPseudoType ==
|
||||
nsCSSPseudoElements::ePseudo_NotPseudoElement,
|
||||
"this code doesn't know how to replace "
|
||||
"pseudo-element rules");
|
||||
nsHTMLCSSStyleSheet* ruleProcessor =
|
||||
static_cast<nsHTMLCSSStyleSheet*>(
|
||||
mRuleProcessors[eStyleAttrSheet].get());
|
||||
if (ruleProcessor &&
|
||||
// check condition we asserted above (belt & braces security)
|
||||
aPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement) {
|
||||
lastScopedRN = ruleWalker.CurrentNode();
|
||||
ruleProcessor->ElementRulesMatching(PresContext(),
|
||||
aElement,
|
||||
&ruleWalker);
|
||||
lastStyleAttrRN = ruleWalker.CurrentNode();
|
||||
haveImportantStyleAttrRules =
|
||||
!ruleWalker.GetCheckForImportantRules();
|
||||
}
|
||||
} else {
|
||||
// Second time through, we handle the !important rule(s).
|
||||
if (haveImportantStyleAttrRules) {
|
||||
AddImportantRules(lastStyleAttrRN, lastScopedRN, &ruleWalker);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_ASSERT(false, "unexpected result from gCascadeLevels lookup");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user