Bug 1355351: Clean up pseudo-element props. r=heycam
MozReview-Commit-ID: JZAhEN3chPs
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -6140,16 +6140,19 @@ nsCSSFrameConstructor::AddFrameConstruct
}
static void
AddGenConPseudoToFrame(nsIFrame* aOwnerFrame, nsIContent* aContent)
{
NS_ASSERTION(nsLayoutUtils::IsFirstContinuationOrIBSplitSibling(aOwnerFrame),
"property should only be set on first continuation/ib-sibling");
+ // FIXME(emilio): Remove this property, and use the frame of the generated
+ // content itself to tear the content down? It should be quite simpler.
+
FrameProperties props = aOwnerFrame->Properties();
nsIFrame::ContentArray* value = props.Get(nsIFrame::GenConProperty());
if (!value) {
value = new nsIFrame::ContentArray;
props.Set(nsIFrame::GenConProperty(), value);
}
value->AppendElement(aContent);
}
@@ -6401,17 +6404,17 @@ AdjustAppendParentForAfterContent(nsFram
nsIContent* aChild,
nsIFrame** aAfterFrame)
{
// If the parent frame has any pseudo-elements or aContainer is a
// display:contents node then we need to walk through the child
// frames to find the first one that is either a ::after frame for an
// ancestor of aChild or a frame that is for a node later in the
// document than aChild and return that in aAfterFrame.
- if (aParentFrame->GetGenConPseudos() ||
+ if (aParentFrame->Properties().Get(nsIFrame::GenConProperty()) ||
nsLayoutUtils::HasPseudoStyle(aContainer, aParentFrame->StyleContext(),
CSSPseudoElementType::after,
aParentFrame->PresContext()) ||
aFrameManager->GetDisplayContentsStyleFor(aContainer)) {
nsIFrame* afterFrame = nullptr;
nsContainerFrame* parent =
static_cast<nsContainerFrame*>(aParentFrame->LastContinuation());
bool done = false;
@@ -8534,35 +8537,33 @@ nsCSSFrameConstructor::ContentRemoved(ns
if (!childFrame || childFrame->GetContent() != aChild) {
// XXXbz the GetContent() != aChild check is needed due to bug 135040.
// Remove it once that's fixed.
ClearUndisplayedContentIn(aChild, aContainer);
}
MOZ_ASSERT(!childFrame || !GetDisplayContentsStyleFor(aChild),
"display:contents nodes shouldn't have a frame");
if (!childFrame && GetDisplayContentsStyleFor(aChild)) {
- nsIFrame* ancestorFrame = nullptr;
nsIContent* ancestor = aContainer;
- for (; ancestor; ancestor = ancestor->GetParent()) {
- ancestorFrame = ancestor->GetPrimaryFrame();
- if (ancestorFrame) {
- break;
- }
- }
- if (ancestorFrame) {
- nsTArray<nsIContent*>* generated = ancestorFrame->GetGenConPseudos();
- if (generated) {
- *aDidReconstruct = true;
- LAYOUT_PHASE_TEMP_EXIT();
- // XXXmats Can we recreate frames only for the ::after/::before content?
- // XXX Perhaps even only those that belong to the aChild sub-tree?
- RecreateFramesForContent(ancestor, false, aFlags, aDestroyedFramesFor);
- LAYOUT_PHASE_TEMP_REENTER();
- return;
- }
+ while (!ancestor->GetPrimaryFrame()) {
+ // FIXME(emilio): Should this use the flattened tree parent instead?
+ ancestor = ancestor->GetParent();
+ MOZ_ASSERT(ancestor, "we can't have a display: contents subtree root!");
+ }
+
+ nsIFrame* ancestorFrame = ancestor->GetPrimaryFrame();
+ if (ancestorFrame->Properties().Get(nsIFrame::GenConProperty())) {
+ *aDidReconstruct = true;
+ LAYOUT_PHASE_TEMP_EXIT();
+
+ // XXXmats Can we recreate frames only for the ::after/::before content?
+ // XXX Perhaps even only those that belong to the aChild sub-tree?
+ RecreateFramesForContent(ancestor, false, aFlags, aDestroyedFramesFor);
+ LAYOUT_PHASE_TEMP_REENTER();
+ return;
}
FlattenedChildIterator iter(aChild);
for (nsIContent* c = iter.GetNextChild(); c; c = iter.GetNextChild()) {
if (c->GetPrimaryFrame() || GetDisplayContentsStyleFor(c)) {
LAYOUT_PHASE_TEMP_EXIT();
ContentRemoved(aChild, c, nullptr, aFlags, aDidReconstruct, aDestroyedFramesFor);
LAYOUT_PHASE_TEMP_REENTER();
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -1584,90 +1584,34 @@ nsLayoutUtils::GetChildListNameFor(nsIFr
return id;
}
/*static*/ nsIFrame*
nsLayoutUtils::GetBeforeFrameForContent(nsIFrame* aFrame,
const nsIContent* aContent)
{
- // We need to call GetGenConPseudos() on the first continuation/ib-split.
- // Find it, for symmetry with GetAfterFrameForContent.
- nsContainerFrame* genConParentFrame =
- FirstContinuationOrIBSplitSibling(aFrame)->GetContentInsertionFrame();
- if (!genConParentFrame) {
- return nullptr;
- }
- nsTArray<nsIContent*>* prop = genConParentFrame->GetGenConPseudos();
- if (prop) {
- const nsTArray<nsIContent*>& pseudos(*prop);
- for (uint32_t i = 0; i < pseudos.Length(); ++i) {
- if (pseudos[i]->GetParent() == aContent &&
- pseudos[i]->NodeInfo()->NameAtom() == nsGkAtoms::mozgeneratedcontentbefore) {
- return pseudos[i]->GetPrimaryFrame();
- }
- }
- }
- // If the first child frame is a pseudo-frame, then try that.
- // Note that the frame we create for the generated content is also a
- // pseudo-frame and so don't drill down in that case.
- nsIFrame* childFrame = genConParentFrame->PrincipalChildList().FirstChild();
- if (childFrame &&
- childFrame->IsPseudoFrame(aContent) &&
- !childFrame->IsGeneratedContentFrame()) {
- return GetBeforeFrameForContent(childFrame, aContent);
- }
- return nullptr;
+ auto* pseudo =
+ static_cast<Element*>(aContent->GetProperty(nsGkAtoms::beforePseudoProperty));
+ return pseudo ? pseudo->GetPrimaryFrame() : nullptr;
}
/*static*/ nsIFrame*
nsLayoutUtils::GetBeforeFrame(nsIFrame* aFrame)
{
return GetBeforeFrameForContent(aFrame, aFrame->GetContent());
}
/*static*/ nsIFrame*
nsLayoutUtils::GetAfterFrameForContent(nsIFrame* aFrame,
const nsIContent* aContent)
{
- // We need to call GetGenConPseudos() on the first continuation,
- // but callers are likely to pass the last.
- nsContainerFrame* genConParentFrame =
- FirstContinuationOrIBSplitSibling(aFrame)->GetContentInsertionFrame();
- if (!genConParentFrame) {
- return nullptr;
- }
- nsTArray<nsIContent*>* prop = genConParentFrame->GetGenConPseudos();
- if (prop) {
- const nsTArray<nsIContent*>& pseudos(*prop);
- for (uint32_t i = 0; i < pseudos.Length(); ++i) {
- if (pseudos[i]->GetParent() == aContent &&
- pseudos[i]->NodeInfo()->NameAtom() == nsGkAtoms::mozgeneratedcontentafter) {
- return pseudos[i]->GetPrimaryFrame();
- }
- }
- }
- // If the last child frame is a pseudo-frame, then try that.
- // Note that the frame we create for the generated content is also a
- // pseudo-frame and so don't drill down in that case.
- genConParentFrame = aFrame->GetContentInsertionFrame();
- if (!genConParentFrame) {
- return nullptr;
- }
- nsIFrame* lastParentContinuation =
- LastContinuationWithChild(static_cast<nsContainerFrame*>(
- LastContinuationOrIBSplitSibling(genConParentFrame)));
- nsIFrame* childFrame =
- lastParentContinuation->GetChildList(nsIFrame::kPrincipalList).LastChild();
- if (childFrame &&
- childFrame->IsPseudoFrame(aContent) &&
- !childFrame->IsGeneratedContentFrame()) {
- return GetAfterFrameForContent(childFrame->FirstContinuation(), aContent);
- }
- return nullptr;
+ auto* pseudo =
+ static_cast<Element*>(aContent->GetProperty(nsGkAtoms::afterPseudoProperty));
+ return pseudo ? pseudo->GetPrimaryFrame() : nullptr;
}
/*static*/ nsIFrame*
nsLayoutUtils::GetAfterFrame(nsIFrame* aFrame)
{
return GetAfterFrameForContent(aFrame, aFrame->GetContent());
}
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -1175,20 +1175,16 @@ public:
return GetBidiData().baseLevel;
}
nsBidiLevel GetEmbeddingLevel()
{
return GetBidiData().embeddingLevel;
}
- nsTArray<nsIContent*>* GetGenConPseudos() {
- return Properties().Get(GenConProperty());
- }
-
/**
* Return the distance between the border edge of the frame and the
* margin edge of the frame. Like GetRect(), returns the dimensions
* as of the most recent reflow.
*
* This doesn't include any margin collapsing that may have occurred.
*
* It also treats 'auto' margins as zero, and treats any margins that