Bug 1331047: Also traverse native anonymous content in the style system. r=bholley

MozReview-Commit-ID: 6wTqBAqTH69
This commit is contained in:
Emilio Cobos Álvarez 2017-04-22 22:33:16 +02:00
Родитель 78d50744d2
Коммит c11e3ca7bf
2 изменённых файлов: 9 добавлений и 64 удалений

Просмотреть файл

@ -494,52 +494,6 @@ AllChildrenIterator::GetPreviousChild()
return nullptr;
}
static bool
IsNativeAnonymousImplementationOfPseudoElement(nsIContent* aContent)
{
// First, we need a frame. This leads to the tricky issue of what we can
// infer if the frame is null.
//
// Unlike regular nodes, native anonymous content (NAC) gets created during
// frame construction, which happens after the main style traversal. This
// means that we have to manually resolve style for those nodes shortly after
// they're created, either by (a) invoking ResolvePseudoElementStyle (for PE
// NAC), or (b) handing the subtree off to Servo for a mini-traversal (for
// non-PE NAC). We have assertions in nsCSSFrameConstructor that we don't do
// both.
//
// Once that happens, the NAC has a frame. So if we have no frame here,
// we're either not NAC, or in the process of doing (b). Either way, this
// isn't a PE.
nsIFrame* f = aContent->GetPrimaryFrame();
if (!f) {
return false;
}
// Get the pseudo type.
CSSPseudoElementType pseudoType = f->StyleContext()->GetPseudoType();
// In general nodes never get anonymous box style. However, there are a few
// special cases:
//
// * We somewhat-confusingly give text nodes a style context tagged with
// ":-moz-text", so we need to check for the anonymous box case here.
// * The primary frame for table elements is an anonymous box that inherits
// from the table's style.
if (pseudoType == CSSPseudoElementType::InheritingAnonBox) {
MOZ_ASSERT(f->StyleContext()->GetPseudo() == nsCSSAnonBoxes::mozText ||
f->StyleContext()->GetPseudo() == nsCSSAnonBoxes::tableWrapper);
return false;
}
MOZ_ASSERT(pseudoType != CSSPseudoElementType::NonInheritingAnonBox);
// Finally check the actual pseudo type.
bool isImpl = pseudoType != CSSPseudoElementType::NotPseudo;
MOZ_ASSERT_IF(isImpl, aContent->IsRootOfNativeAnonymousSubtree());
return isImpl;
}
/* static */ bool
StyleChildrenIterator::IsNeeded(const Element* aElement)
{
@ -571,18 +525,7 @@ StyleChildrenIterator::IsNeeded(const Element* aElement)
nsIContent*
StyleChildrenIterator::GetNextChild()
{
while (nsIContent* child = AllChildrenIterator::GetNextChild()) {
if (IsNativeAnonymousImplementationOfPseudoElement(child)) {
// Skip any native-anonymous children that are used to implement pseudo-
// elements. These match pseudo-element selectors instead of being
// considered a child of their host, and thus the style system needs to
// handle them separately.
} else {
return child;
}
}
return nullptr;
return AllChildrenIterator::GetNextChild();
}
} // namespace dom

Просмотреть файл

@ -255,12 +255,14 @@ private:
/**
* StyleChildrenIterator traverses the children of the element from the
* perspective of the style system, particularly the children we need to traverse
* during restyle. This is identical to AllChildrenIterator with
* (eAllChildren | eSkipDocumentLevelNativeAnonymousContent), _except_ that we
* detect and skip any native anonymous children that are used to implement
* pseudo-elements (since the style system needs to cascade those using
* different algorithms).
* perspective of the style system, particularly the children we need to
* traverse during restyle.
*
* At present, this is identical to AllChildrenIterator with
* (eAllChildren | eSkipDocumentLevelNativeAnonymousContent). We used to have
* detect and skip any native anonymous children that are used to implement some
* special magic in here that went away, but we keep the separate class so
* we can reintroduce special magic back if needed.
*
* Note: it assumes that no mutation of the DOM or frame tree takes place during
* iteration, and will break horribly if that is not true.