зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1355351: Simplify nsLayoutUtils callers, and make child iterators notice display: contents pseudos. r=heycam
This also happens to fix other bugs, like making display: contents pseudos animatable, which weren't before. MozReview-Commit-ID: LhwTPNbFvSZ --HG-- extra : rebase_source : 785105b08d6bfa15ad257e61b769a263c6810ad0
This commit is contained in:
Родитель
135c333511
Коммит
6fe2b3e89d
|
@ -519,24 +519,17 @@ EffectCompositor::GetElementToRestyle(dom::Element* aElement,
|
|||
return aElement;
|
||||
}
|
||||
|
||||
nsIFrame* primaryFrame = aElement->GetPrimaryFrame();
|
||||
if (!primaryFrame) {
|
||||
return nullptr;
|
||||
}
|
||||
nsIFrame* pseudoFrame;
|
||||
if (aPseudoType == CSSPseudoElementType::before) {
|
||||
pseudoFrame = nsLayoutUtils::GetBeforeFrame(primaryFrame);
|
||||
} else if (aPseudoType == CSSPseudoElementType::after) {
|
||||
pseudoFrame = nsLayoutUtils::GetAfterFrame(primaryFrame);
|
||||
} else {
|
||||
NS_NOTREACHED("Should not try to get the element to restyle for a pseudo "
|
||||
"other that :before or :after");
|
||||
return nullptr;
|
||||
return nsLayoutUtils::GetBeforePseudo(aElement);
|
||||
}
|
||||
if (!pseudoFrame) {
|
||||
return nullptr;
|
||||
|
||||
if (aPseudoType == CSSPseudoElementType::after) {
|
||||
return nsLayoutUtils::GetAfterPseudo(aElement);
|
||||
}
|
||||
return pseudoFrame->GetContent()->AsElement();
|
||||
|
||||
NS_NOTREACHED("Should not try to get the element to restyle for a pseudo "
|
||||
"other that :before or :after");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -1464,19 +1464,17 @@ KeyframeEffectReadOnly::GetAnimationFrame() const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsIFrame* frame = mTarget->mElement->GetPrimaryFrame();
|
||||
if (!frame) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIFrame* frame;
|
||||
if (mTarget->mPseudoType == CSSPseudoElementType::before) {
|
||||
frame = nsLayoutUtils::GetBeforeFrame(frame);
|
||||
frame = nsLayoutUtils::GetBeforeFrame(mTarget->mElement);
|
||||
} else if (mTarget->mPseudoType == CSSPseudoElementType::after) {
|
||||
frame = nsLayoutUtils::GetAfterFrame(frame);
|
||||
frame = nsLayoutUtils::GetAfterFrame(mTarget->mElement);
|
||||
} else {
|
||||
frame = mTarget->mElement->GetPrimaryFrame();
|
||||
MOZ_ASSERT(mTarget->mPseudoType == CSSPseudoElementType::NotPseudo,
|
||||
"unknown mTarget->mPseudoType");
|
||||
}
|
||||
|
||||
if (!frame) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -317,11 +317,9 @@ AllChildrenIterator::Get() const
|
|||
{
|
||||
switch (mPhase) {
|
||||
case eAtBeforeKid: {
|
||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||
MOZ_ASSERT(frame, "No frame at eAtBeforeKid phase");
|
||||
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
|
||||
MOZ_ASSERT(beforeFrame, "No content before frame at eAtBeforeKid phase");
|
||||
return beforeFrame->GetContent();
|
||||
Element* before = nsLayoutUtils::GetBeforePseudo(mOriginalContent);
|
||||
MOZ_ASSERT(before, "No content before frame at eAtBeforeKid phase");
|
||||
return before;
|
||||
}
|
||||
|
||||
case eAtExplicitKids:
|
||||
|
@ -331,11 +329,9 @@ AllChildrenIterator::Get() const
|
|||
return mAnonKids[mAnonKidsIdx];
|
||||
|
||||
case eAtAfterKid: {
|
||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||
MOZ_ASSERT(frame, "No frame at eAtAfterKid phase");
|
||||
nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(frame);
|
||||
MOZ_ASSERT(afterFrame, "No content before frame at eAtBeforeKid phase");
|
||||
return afterFrame->GetContent();
|
||||
Element* after = nsLayoutUtils::GetAfterPseudo(mOriginalContent);
|
||||
MOZ_ASSERT(after, "No content after frame at eAtAfterKid phase");
|
||||
return after;
|
||||
}
|
||||
|
||||
default:
|
||||
|
@ -349,15 +345,10 @@ AllChildrenIterator::Seek(nsIContent* aChildToFind)
|
|||
{
|
||||
if (mPhase == eAtBegin || mPhase == eAtBeforeKid) {
|
||||
mPhase = eAtExplicitKids;
|
||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
|
||||
if (beforeFrame) {
|
||||
if (beforeFrame->GetContent() == aChildToFind) {
|
||||
mPhase = eAtBeforeKid;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Element* beforePseudo = nsLayoutUtils::GetBeforePseudo(mOriginalContent);
|
||||
if (beforePseudo && beforePseudo == aChildToFind) {
|
||||
mPhase = eAtBeforeKid;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -404,13 +395,10 @@ AllChildrenIterator::GetNextChild()
|
|||
{
|
||||
if (mPhase == eAtBegin) {
|
||||
mPhase = eAtExplicitKids;
|
||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
|
||||
if (beforeFrame) {
|
||||
mPhase = eAtBeforeKid;
|
||||
return beforeFrame->GetContent();
|
||||
}
|
||||
Element* beforeContent = nsLayoutUtils::GetBeforePseudo(mOriginalContent);
|
||||
if (beforeContent) {
|
||||
mPhase = eAtBeforeKid;
|
||||
return beforeContent;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -446,13 +434,10 @@ AllChildrenIterator::GetNextChild()
|
|||
return mAnonKids[mAnonKidsIdx];
|
||||
}
|
||||
|
||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(frame);
|
||||
if (afterFrame) {
|
||||
mPhase = eAtAfterKid;
|
||||
return afterFrame->GetContent();
|
||||
}
|
||||
Element* afterContent = nsLayoutUtils::GetAfterPseudo(mOriginalContent);
|
||||
if (afterContent) {
|
||||
mPhase = eAtAfterKid;
|
||||
return afterContent;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -466,13 +451,10 @@ AllChildrenIterator::GetPreviousChild()
|
|||
if (mPhase == eAtEnd) {
|
||||
MOZ_ASSERT(mAnonKidsIdx == mAnonKids.Length());
|
||||
mPhase = eAtAnonKids;
|
||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(frame);
|
||||
if (afterFrame) {
|
||||
mPhase = eAtAfterKid;
|
||||
return afterFrame->GetContent();
|
||||
}
|
||||
Element* afterContent = nsLayoutUtils::GetAfterPseudo(mOriginalContent);
|
||||
if (afterContent) {
|
||||
mPhase = eAtAfterKid;
|
||||
return afterContent;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -501,13 +483,10 @@ AllChildrenIterator::GetPreviousChild()
|
|||
return kid;
|
||||
}
|
||||
|
||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
|
||||
if (beforeFrame) {
|
||||
mPhase = eAtBeforeKid;
|
||||
return beforeFrame->GetContent();
|
||||
}
|
||||
Element* beforeContent = nsLayoutUtils::GetBeforePseudo(mOriginalContent);
|
||||
if (beforeContent) {
|
||||
mPhase = eAtBeforeKid;
|
||||
return beforeContent;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3756,11 +3756,11 @@ nsDOMWindowUtils::GetOMTAStyle(nsIDOMElement* aElement,
|
|||
|
||||
RefPtr<nsROCSSPrimitiveValue> cssValue = nullptr;
|
||||
nsIFrame* frame = element->GetPrimaryFrame();
|
||||
if (frame && !aPseudoElement.IsEmpty()) {
|
||||
if (!aPseudoElement.IsEmpty()) {
|
||||
if (aPseudoElement.EqualsLiteral("::before")) {
|
||||
frame = nsLayoutUtils::GetBeforeFrame(frame);
|
||||
frame = nsLayoutUtils::GetBeforeFrame(element);
|
||||
} else if (aPseudoElement.EqualsLiteral("::after")) {
|
||||
frame = nsLayoutUtils::GetAfterFrame(frame);
|
||||
frame = nsLayoutUtils::GetAfterFrame(element);
|
||||
} else {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
|
|
@ -3329,14 +3329,14 @@ ElementRestyler::MustReframeForPseudo(CSSPseudoElementType aPseudoType,
|
|||
// Check for a ::before pseudo style and the absence of a ::before content,
|
||||
// but only if aFrame is null or is the first continuation/ib-split.
|
||||
if ((aFrame && !nsLayoutUtils::IsFirstContinuationOrIBSplitSibling(aFrame)) ||
|
||||
nsLayoutUtils::GetBeforeFrameForContent(aGenConParentFrame, aContent)) {
|
||||
nsLayoutUtils::GetBeforeFrame(aContent)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Similarly for ::after, but check for being the last continuation/
|
||||
// ib-split.
|
||||
if ((aFrame && nsLayoutUtils::GetNextContinuationOrIBSplitSibling(aFrame)) ||
|
||||
nsLayoutUtils::GetAfterFrameForContent(aGenConParentFrame, aContent)) {
|
||||
nsLayoutUtils::GetAfterFrame(aContent)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -335,25 +335,16 @@ ServoRestyleManager::FrameForPseudoElement(const nsIContent* aContent,
|
|||
nsIAtom* aPseudoTagOrNull)
|
||||
{
|
||||
MOZ_ASSERT_IF(aPseudoTagOrNull, aContent->IsElement());
|
||||
nsIFrame* primaryFrame = aContent->GetPrimaryFrame();
|
||||
|
||||
if (!aPseudoTagOrNull) {
|
||||
return primaryFrame;
|
||||
return aContent->GetPrimaryFrame();
|
||||
}
|
||||
|
||||
// FIXME(emilio): Need to take into account display: contents pseudos!
|
||||
if (!primaryFrame) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// NOTE: we probably need to special-case display: contents here. Gecko's
|
||||
// RestyleManager passes the primary frame of the parent instead.
|
||||
if (aPseudoTagOrNull == nsCSSPseudoElements::before) {
|
||||
return nsLayoutUtils::GetBeforeFrameForContent(primaryFrame, aContent);
|
||||
return nsLayoutUtils::GetBeforeFrame(aContent);
|
||||
}
|
||||
|
||||
if (aPseudoTagOrNull == nsCSSPseudoElements::after) {
|
||||
return nsLayoutUtils::GetAfterFrameForContent(primaryFrame, aContent);
|
||||
return nsLayoutUtils::GetAfterFrame(aContent);
|
||||
}
|
||||
|
||||
MOZ_CRASH("Unkown pseudo-element given to "
|
||||
|
|
|
@ -6738,9 +6738,8 @@ nsCSSFrameConstructor::FindFrameForContentSibling(nsIContent* aContent,
|
|||
nsIFrame* sibling = aContent->GetPrimaryFrame();
|
||||
if (!sibling && GetDisplayContentsStyleFor(aContent)) {
|
||||
// A display:contents node - check if it has a ::before / ::after frame...
|
||||
sibling = aPrevSibling ?
|
||||
nsLayoutUtils::GetAfterFrameForContent(aParentFrame, aContent) :
|
||||
nsLayoutUtils::GetBeforeFrameForContent(aParentFrame, aContent);
|
||||
sibling = aPrevSibling ? nsLayoutUtils::GetAfterFrame(aContent)
|
||||
: nsLayoutUtils::GetBeforeFrame(aContent);
|
||||
if (!sibling) {
|
||||
// ... then recurse into children ...
|
||||
const bool forward = !aPrevSibling;
|
||||
|
@ -6751,9 +6750,8 @@ nsCSSFrameConstructor::FindFrameForContentSibling(nsIContent* aContent,
|
|||
}
|
||||
if (!sibling) {
|
||||
// ... then ::after / ::before on the opposite end.
|
||||
sibling = aPrevSibling ?
|
||||
nsLayoutUtils::GetBeforeFrameForContent(aParentFrame, aContent) :
|
||||
nsLayoutUtils::GetAfterFrameForContent(aParentFrame, aContent);
|
||||
sibling = aPrevSibling ? nsLayoutUtils::GetAfterFrame(aContent)
|
||||
: nsLayoutUtils::GetBeforeFrame(aContent);
|
||||
}
|
||||
if (!sibling) {
|
||||
return nullptr;
|
||||
|
|
|
@ -1585,36 +1585,40 @@ nsLayoutUtils::GetChildListNameFor(nsIFrame* aChildFrame)
|
|||
return id;
|
||||
}
|
||||
|
||||
/*static*/ nsIFrame*
|
||||
nsLayoutUtils::GetBeforeFrameForContent(nsIFrame* aFrame,
|
||||
const nsIContent* aContent)
|
||||
static Element*
|
||||
GetPseudo(const nsIContent* aContent, nsIAtom* aPseudoProperty)
|
||||
{
|
||||
auto* pseudo =
|
||||
static_cast<Element*>(aContent->GetProperty(nsGkAtoms::beforePseudoProperty));
|
||||
MOZ_ASSERT(aPseudoProperty == nsGkAtoms::beforePseudoProperty ||
|
||||
aPseudoProperty == nsGkAtoms::afterPseudoProperty);
|
||||
return static_cast<Element*>(aContent->GetProperty(aPseudoProperty));
|
||||
}
|
||||
|
||||
/*static*/ Element*
|
||||
nsLayoutUtils::GetBeforePseudo(const nsIContent* aContent)
|
||||
{
|
||||
return GetPseudo(aContent, nsGkAtoms::beforePseudoProperty);
|
||||
}
|
||||
|
||||
/*static*/ nsIFrame*
|
||||
nsLayoutUtils::GetBeforeFrame(const nsIContent* aContent)
|
||||
{
|
||||
Element* pseudo = GetBeforePseudo(aContent);
|
||||
return pseudo ? pseudo->GetPrimaryFrame() : nullptr;
|
||||
}
|
||||
|
||||
/*static*/ nsIFrame*
|
||||
nsLayoutUtils::GetBeforeFrame(nsIFrame* aFrame)
|
||||
/*static*/ Element*
|
||||
nsLayoutUtils::GetAfterPseudo(const nsIContent* aContent)
|
||||
{
|
||||
return GetBeforeFrameForContent(aFrame, aFrame->GetContent());
|
||||
return GetPseudo(aContent, nsGkAtoms::afterPseudoProperty);
|
||||
}
|
||||
|
||||
/*static*/ nsIFrame*
|
||||
nsLayoutUtils::GetAfterFrameForContent(nsIFrame* aFrame,
|
||||
const nsIContent* aContent)
|
||||
nsLayoutUtils::GetAfterFrame(const nsIContent* aContent)
|
||||
{
|
||||
auto* pseudo =
|
||||
static_cast<Element*>(aContent->GetProperty(nsGkAtoms::afterPseudoProperty));
|
||||
Element* pseudo = GetAfterPseudo(aContent);
|
||||
return pseudo ? pseudo->GetPrimaryFrame() : nullptr;
|
||||
}
|
||||
|
||||
/*static*/ nsIFrame*
|
||||
nsLayoutUtils::GetAfterFrame(nsIFrame* aFrame)
|
||||
{
|
||||
return GetAfterFrameForContent(aFrame, aFrame->GetContent());
|
||||
}
|
||||
|
||||
// static
|
||||
nsIFrame*
|
||||
nsLayoutUtils::GetClosestFrameOfType(nsIFrame* aFrame,
|
||||
|
|
|
@ -286,50 +286,26 @@ public:
|
|||
static mozilla::layout::FrameChildListID GetChildListNameFor(nsIFrame* aChildFrame);
|
||||
|
||||
/**
|
||||
* GetBeforeFrameForContent returns the ::before frame for aContent, if
|
||||
* one exists. This is typically O(1). The frame passed in must be
|
||||
* the first-in-flow.
|
||||
*
|
||||
* @param aGenConParentFrame an ancestor of the ::before frame
|
||||
* @param aContent the content whose ::before is wanted
|
||||
* @return the ::before frame or nullptr if there isn't one
|
||||
* Returns the ::before pseudo-element for aContent, if any.
|
||||
*/
|
||||
static nsIFrame* GetBeforeFrameForContent(nsIFrame* aGenConParentFrame,
|
||||
const nsIContent* aContent);
|
||||
static mozilla::dom::Element* GetBeforePseudo(const nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* GetBeforeFrame returns the outermost ::before frame of the given frame, if
|
||||
* one exists. This is typically O(1). The frame passed in must be
|
||||
* the first-in-flow.
|
||||
*
|
||||
* @param aFrame the frame whose ::before is wanted
|
||||
* @return the :before frame or nullptr if there isn't one
|
||||
* Returns the frame corresponding to the ::before pseudo-element for
|
||||
* aContent, if any.
|
||||
*/
|
||||
static nsIFrame* GetBeforeFrame(nsIFrame* aFrame);
|
||||
static nsIFrame* GetBeforeFrame(const nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* GetAfterFrameForContent returns the ::after frame for aContent, if one
|
||||
* exists. This will walk the in-flow chain of aGenConParentFrame to the
|
||||
* last-in-flow if needed. This function is typically O(N) in the number
|
||||
* of child frames, following in-flows, etc.
|
||||
*
|
||||
* @param aGenConParentFrame an ancestor of the ::after frame
|
||||
* @param aContent the content whose ::after is wanted
|
||||
* @return the ::after frame or nullptr if there isn't one
|
||||
* Returns the ::after pseudo-element for aContent, if any.
|
||||
*/
|
||||
static nsIFrame* GetAfterFrameForContent(nsIFrame* aGenConParentFrame,
|
||||
const nsIContent* aContent);
|
||||
static mozilla::dom::Element* GetAfterPseudo(const nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* GetAfterFrame returns the outermost ::after frame of the given frame, if one
|
||||
* exists. This will walk the in-flow chain to the last-in-flow if
|
||||
* needed. This function is typically O(N) in the number of child
|
||||
* frames, following in-flows, etc.
|
||||
*
|
||||
* @param aFrame the frame whose ::after is wanted
|
||||
* @return the :after frame or nullptr if there isn't one
|
||||
* Returns the frame corresponding to the ::after pseudo-element for aContent,
|
||||
* if any.
|
||||
*/
|
||||
static nsIFrame* GetAfterFrame(nsIFrame* aFrame);
|
||||
static nsIFrame* GetAfterFrame(const nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Given a frame, search up the frame tree until we find an
|
||||
|
|
|
@ -10365,19 +10365,16 @@ nsIFrame::IsPseudoStackingContextFromStyle() {
|
|||
Element*
|
||||
nsIFrame::GetPseudoElement(CSSPseudoElementType aType)
|
||||
{
|
||||
nsIFrame* frame = nullptr;
|
||||
|
||||
if (aType == CSSPseudoElementType::before) {
|
||||
frame = nsLayoutUtils::GetBeforeFrame(this);
|
||||
} else if (aType == CSSPseudoElementType::after) {
|
||||
frame = nsLayoutUtils::GetAfterFrame(this);
|
||||
if (!mContent) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (frame) {
|
||||
nsIContent* content = frame->GetContent();
|
||||
if (content->IsElement()) {
|
||||
return content->AsElement();
|
||||
}
|
||||
if (aType == CSSPseudoElementType::before) {
|
||||
return nsLayoutUtils::GetBeforePseudo(mContent);
|
||||
}
|
||||
|
||||
if (aType == CSSPseudoElementType::after) {
|
||||
return nsLayoutUtils::GetAfterPseudo(mContent);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
|
Загрузка…
Ссылка в новой задаче