Bug 899808 - Fix matching of pseudo-elements in scoped style sheets. r=dbaron

This commit is contained in:
Cameron McCormack 2013-10-11 10:28:49 +11:00
parent b3cfa7f32d
commit f6c813d402
7 changed files with 68 additions and 0 deletions

View File

@ -20,6 +20,8 @@
== scoped-style-020.html scoped-style-020-ref.html
== scoped-style-021.html scoped-style-021-ref.html
== scoped-style-022.html scoped-style-022-ref.html
== scoped-style-023.html scoped-style-023-ref.html
== scoped-style-024.html scoped-style-024-ref.html
== scoped-style-important-001.html scoped-style-important-001-ref.html
== scoped-style-important-002.html scoped-style-important-002-ref.html
== scoped-style-important-003.html scoped-style-important-003-ref.html

View File

@ -0,0 +1,4 @@
<!DOCTYPE html>
<body>
<p><span style="color: green">First line</span><br><span style="color: blue">Second line</span></p>
</body>

View File

@ -0,0 +1,8 @@
<!DOCTYPE html>
<body>
<style scoped>
p::first-line { color: green; }
span { color: blue; }
</style>
<p>First line<br><span>Second line</span></p>
</body>

View File

@ -0,0 +1,4 @@
<!DOCTYPE html>
<body>
<p style="color: green">Hello.</p>
</body>

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<body>
<style scoped>
p[data-test] { color: green; }
</style>
<p>Hello.</p>
<script>
document.body.offsetHeight;
document.querySelector("p").setAttribute("data-test", "");
</script>
</body>

View File

@ -173,9 +173,33 @@ struct MOZ_STACK_CLASS TreeMatchContext {
return true;
}
#ifdef DEBUG
void AssertHasAllStyleScopes(mozilla::dom::Element* aElement)
{
int32_t i = mStyleScopes.Length() - 1;
nsINode* node = aElement->GetParentNode();
while (node && i != -1) {
if (node->IsScopedStyleRoot()) {
MOZ_ASSERT(mStyleScopes[i] == node);
--i;
}
node = node->GetParentNode();
}
while (node) {
MOZ_ASSERT(!node->IsScopedStyleRoot());
node = node->GetParentNode();
}
MOZ_ASSERT(i == -1);
}
#endif
bool SetStyleScopeForSelectorMatching(mozilla::dom::Element* aSubject,
mozilla::dom::Element* aScope)
{
#ifdef DEBUG
AssertHasAllStyleScopes(aSubject);
#endif
mForScopedStyle = !!aScope;
if (!aScope) {
// This is not for a scoped style sheet; return true, as we want

View File

@ -1157,12 +1157,21 @@ nsStyleSet::WalkRuleProcessors(nsIStyleRuleProcessor::EnumFunc aFunc,
(*aFunc)(mRuleProcessors[eTransitionSheet], aData);
}
static void
InitAncestorsIfInStyleScope(TreeMatchContext& aTreeContext, Element* aElement)
{
if (aElement->IsElementInStyleScope()) {
aTreeContext.InitAncestors(aElement->GetParentElement());
}
}
already_AddRefed<nsStyleContext>
nsStyleSet::ResolveStyleFor(Element* aElement,
nsStyleContext* aParentContext)
{
TreeMatchContext treeContext(true, nsRuleWalker::eRelevantLinkUnvisited,
aElement->OwnerDoc());
InitAncestorsIfInStyleScope(treeContext, aElement);
return ResolveStyleFor(aElement, aParentContext, treeContext);
}
@ -1337,6 +1346,7 @@ nsStyleSet::ResolvePseudoElementStyle(Element* aParentElement,
nsRuleWalker ruleWalker(mRuleTree, mAuthorStyleDisabled);
TreeMatchContext treeContext(true, nsRuleWalker::eRelevantLinkUnvisited,
aParentElement->OwnerDoc());
InitAncestorsIfInStyleScope(treeContext, aParentElement);
PseudoElementRuleProcessorData data(PresContext(), aParentElement,
&ruleWalker, aType, treeContext);
WalkRestrictionRule(aType, &ruleWalker);
@ -1380,6 +1390,7 @@ nsStyleSet::ProbePseudoElementStyle(Element* aParentElement,
{
TreeMatchContext treeContext(true, nsRuleWalker::eRelevantLinkUnvisited,
aParentElement->OwnerDoc());
InitAncestorsIfInStyleScope(treeContext, aParentElement);
return ProbePseudoElementStyle(aParentElement, aType, aParentContext,
treeContext);
}
@ -1518,6 +1529,7 @@ nsStyleSet::ResolveXULTreePseudoStyle(Element* aParentElement,
nsRuleWalker ruleWalker(mRuleTree, mAuthorStyleDisabled);
TreeMatchContext treeContext(true, nsRuleWalker::eRelevantLinkUnvisited,
aParentElement->OwnerDoc());
InitAncestorsIfInStyleScope(treeContext, aParentElement);
XULTreeRuleProcessorData data(PresContext(), aParentElement, &ruleWalker,
aPseudoTag, aComparator, treeContext);
FileRules(EnumRulesMatching<XULTreeRuleProcessorData>, &data, aParentElement,
@ -1880,6 +1892,7 @@ nsStyleSet::HasDocumentStateDependentStyle(nsPresContext* aPresContext,
TreeMatchContext treeContext(false, nsRuleWalker::eLinksVisitedOrUnvisited,
aContent->OwnerDoc());
InitAncestorsIfInStyleScope(treeContext, aContent->AsElement());
StatefulData data(aPresContext, aContent->AsElement(), aStateMask,
treeContext);
WalkRuleProcessors(SheetHasDocumentStateStyle, &data, true);
@ -1903,6 +1916,7 @@ nsStyleSet::HasStateDependentStyle(nsPresContext* aPresContext,
{
TreeMatchContext treeContext(false, nsRuleWalker::eLinksVisitedOrUnvisited,
aElement->OwnerDoc());
InitAncestorsIfInStyleScope(treeContext, aElement);
StatefulData data(aPresContext, aElement, aStateMask, treeContext);
WalkRuleProcessors(SheetHasStatefulStyle, &data, false);
return data.mHint;
@ -1938,6 +1952,7 @@ nsStyleSet::HasAttributeDependentStyle(nsPresContext* aPresContext,
{
TreeMatchContext treeContext(false, nsRuleWalker::eLinksVisitedOrUnvisited,
aElement->OwnerDoc());
InitAncestorsIfInStyleScope(treeContext, aElement);
AttributeData data(aPresContext, aElement, aAttribute,
aModType, aAttrHasChanged, treeContext);
WalkRuleProcessors(SheetHasAttributeStyle, &data, false);