Bug 930270 - Don't initialize the ancestor filter for elements outside the document. r=dbaron

--HG--
extra : rebase_source : fa10a28a8bbd9eaf670f8133ccd81a9c706ebec7
This commit is contained in:
Cameron McCormack 2013-11-01 13:44:40 +11:00
parent 4e7fba2e7b
commit 0c0dd6f24f
6 changed files with 59 additions and 10 deletions

View File

@ -0,0 +1,6 @@
<nobr>
<form>
<style scoped></style>
<input required="required">
<button>
<nobr>

View File

@ -0,0 +1,9 @@
<!DOCTYPE html>
<body>
<style scoped>span { color: red; }</style>
<div><span></span></div>
<script>
var div = document.querySelector("div");
div.parentNode.removeChild(div);
getComputedStyle(div.firstChild, "").color;
</script>

View File

@ -98,3 +98,5 @@ load 880862.html
load 873222.html
load 915440.html
load 927734-1.html
load 930270-1.html
load 930270-2.html

View File

@ -3440,6 +3440,32 @@ TreeMatchContext::InitAncestors(Element *aElement)
}
}
void
TreeMatchContext::InitStyleScopes(Element* aElement)
{
MOZ_ASSERT(mStyleScopes.IsEmpty());
if (MOZ_LIKELY(aElement)) {
// Collect up the ancestors
nsAutoTArray<Element*, 50> ancestors;
Element* cur = aElement;
do {
ancestors.AppendElement(cur);
nsINode* parent = cur->GetParentNode();
if (!parent || !parent->IsElement()) {
break;
}
cur = parent->AsElement();
} while (true);
// Now push them in reverse order.
for (uint32_t i = ancestors.Length(); i-- != 0; ) {
PushStyleScope(ancestors[i]);
}
}
}
void
AncestorFilter::PushAncestor(Element *aElement)
{

View File

@ -139,10 +139,16 @@ struct MOZ_STACK_CLASS TreeMatchContext {
* Initialize the ancestor filter and list of style scopes. If aElement is
* not null, it and all its ancestors will be passed to
* mAncestorFilter.PushAncestor and PushStyleScope, starting from the root and
* going down the tree.
* going down the tree. Must only be called for elements in a document.
*/
void InitAncestors(mozilla::dom::Element *aElement);
/**
* Like InitAncestors, but only initializes the style scope list, not the
* ancestor filter. May be called for elements outside a document.
*/
void InitStyleScopes(mozilla::dom::Element* aElement);
void PushStyleScope(mozilla::dom::Element* aElement)
{
NS_PRECONDITION(aElement, "aElement must not be null");

View File

@ -1158,10 +1158,10 @@ nsStyleSet::WalkRuleProcessors(nsIStyleRuleProcessor::EnumFunc aFunc,
}
static void
InitAncestorsIfInStyleScope(TreeMatchContext& aTreeContext, Element* aElement)
InitStyleScopes(TreeMatchContext& aTreeContext, Element* aElement)
{
if (aElement->IsElementInStyleScope()) {
aTreeContext.InitAncestors(aElement->GetParentElement());
aTreeContext.InitStyleScopes(aElement->GetParentElement());
}
}
@ -1171,7 +1171,7 @@ nsStyleSet::ResolveStyleFor(Element* aElement,
{
TreeMatchContext treeContext(true, nsRuleWalker::eRelevantLinkUnvisited,
aElement->OwnerDoc());
InitAncestorsIfInStyleScope(treeContext, aElement);
InitStyleScopes(treeContext, aElement);
return ResolveStyleFor(aElement, aParentContext, treeContext);
}
@ -1347,7 +1347,7 @@ nsStyleSet::ResolvePseudoElementStyle(Element* aParentElement,
nsRuleWalker ruleWalker(mRuleTree, mAuthorStyleDisabled);
TreeMatchContext treeContext(true, nsRuleWalker::eRelevantLinkUnvisited,
aParentElement->OwnerDoc());
InitAncestorsIfInStyleScope(treeContext, aParentElement);
InitStyleScopes(treeContext, aParentElement);
PseudoElementRuleProcessorData data(PresContext(), aParentElement,
&ruleWalker, aType, treeContext,
aPseudoElement);
@ -1392,7 +1392,7 @@ nsStyleSet::ProbePseudoElementStyle(Element* aParentElement,
{
TreeMatchContext treeContext(true, nsRuleWalker::eRelevantLinkUnvisited,
aParentElement->OwnerDoc());
InitAncestorsIfInStyleScope(treeContext, aParentElement);
InitStyleScopes(treeContext, aParentElement);
return ProbePseudoElementStyle(aParentElement, aType, aParentContext,
treeContext);
}
@ -1533,7 +1533,7 @@ nsStyleSet::ResolveXULTreePseudoStyle(Element* aParentElement,
nsRuleWalker ruleWalker(mRuleTree, mAuthorStyleDisabled);
TreeMatchContext treeContext(true, nsRuleWalker::eRelevantLinkUnvisited,
aParentElement->OwnerDoc());
InitAncestorsIfInStyleScope(treeContext, aParentElement);
InitStyleScopes(treeContext, aParentElement);
XULTreeRuleProcessorData data(PresContext(), aParentElement, &ruleWalker,
aPseudoTag, aComparator, treeContext);
FileRules(EnumRulesMatching<XULTreeRuleProcessorData>, &data, aParentElement,
@ -1896,7 +1896,7 @@ nsStyleSet::HasDocumentStateDependentStyle(nsPresContext* aPresContext,
TreeMatchContext treeContext(false, nsRuleWalker::eLinksVisitedOrUnvisited,
aContent->OwnerDoc());
InitAncestorsIfInStyleScope(treeContext, aContent->AsElement());
InitStyleScopes(treeContext, aContent->AsElement());
StatefulData data(aPresContext, aContent->AsElement(), aStateMask,
treeContext);
WalkRuleProcessors(SheetHasDocumentStateStyle, &data, true);
@ -1920,7 +1920,7 @@ nsStyleSet::HasStateDependentStyle(nsPresContext* aPresContext,
{
TreeMatchContext treeContext(false, nsRuleWalker::eLinksVisitedOrUnvisited,
aElement->OwnerDoc());
InitAncestorsIfInStyleScope(treeContext, aElement);
InitStyleScopes(treeContext, aElement);
StatefulData data(aPresContext, aElement, aStateMask, treeContext);
WalkRuleProcessors(SheetHasStatefulStyle, &data, false);
return data.mHint;
@ -1956,7 +1956,7 @@ nsStyleSet::HasAttributeDependentStyle(nsPresContext* aPresContext,
{
TreeMatchContext treeContext(false, nsRuleWalker::eLinksVisitedOrUnvisited,
aElement->OwnerDoc());
InitAncestorsIfInStyleScope(treeContext, aElement);
InitStyleScopes(treeContext, aElement);
AttributeData data(aPresContext, aElement, aAttribute,
aModType, aAttrHasChanged, treeContext);
WalkRuleProcessors(SheetHasAttributeStyle, &data, false);