Bug 907396 - Replace GetParentStyleContextFrame with GetParentStyleContext which can return frame-less display:contents style contexts. r=bzbarsky

This commit is contained in:
Mats Palmgren 2014-11-20 18:24:10 +00:00
Родитель 49c85139e6
Коммит debd2f3e4d
13 изменённых файлов: 128 добавлений и 78 удалений

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

@ -1802,14 +1802,8 @@ VerifyContextParent(nsPresContext* aPresContext, nsIFrame* aFrame,
}
if (!aParentContext) {
// Get the correct parent context from the frame
// - if the frame is a placeholder, we get the out of flow frame's context
// as the parent context instead of asking the frame
// get the parent context from the frame (indirectly)
nsIFrame* providerFrame = aFrame->GetParentStyleContextFrame();
if (providerFrame)
aParentContext = providerFrame->StyleContext();
nsIFrame* providerFrame;
aParentContext = aFrame->GetParentStyleContext(&providerFrame);
// aParentContext could still be null
}
@ -2141,20 +2135,19 @@ RestyleManager::ReparentStyleContext(nsIFrame* aFrame)
nsStyleContext* oldContext = aFrame->StyleContext();
nsRefPtr<nsStyleContext> newContext;
nsIFrame* providerFrame = aFrame->GetParentStyleContextFrame();
nsIFrame* providerFrame;
nsStyleContext* newParentContext = aFrame->GetParentStyleContext(&providerFrame);
bool isChild = providerFrame && providerFrame->GetParent() == aFrame;
nsStyleContext* newParentContext = nullptr;
nsIFrame* providerChild = nullptr;
if (isChild) {
ReparentStyleContext(providerFrame);
// Get the style context again after ReparentStyleContext() which might have
// changed it.
newParentContext = providerFrame->StyleContext();
providerChild = providerFrame;
} else if (providerFrame) {
newParentContext = providerFrame->StyleContext();
} else {
NS_NOTREACHED("Reparenting something that has no usable parent? "
"Shouldn't happen!");
}
NS_ASSERTION(newParentContext, "Reparenting something that has no usable"
" parent? Shouldn't happen!");
// XXX need to do something here to produce the correct style context for
// an IB split whose first inline part is inside a first-line frame.
// Currently the first IB anonymous block's style context takes the first
@ -2550,6 +2543,9 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint)
MOZ_ASSERT(!(aRestyleHint & eRestyle_LaterSiblings),
"eRestyle_LaterSiblings must not be part of aRestyleHint");
AutoDisplayContentsAncestorPusher adcp(mTreeMatchContext, mFrame->PresContext(),
mFrame->GetContent() ? mFrame->GetContent()->GetParent() : nullptr);
// List of descendant elements of mContent we know we will eventually need to
// restyle. Before we return from this function, we call
// RestyleTracker::AddRestyleRootsIfAwaitingRestyle to ensure they get
@ -2649,9 +2645,8 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint)
MOZ_ASSERT(mFrame->StyleContext() == oldContext,
"frame should have been left with its old style context");
nsStyleContext* newParent =
mFrame->GetParentStyleContextFrame()->StyleContext();
nsIFrame* unused;
nsStyleContext* newParent = mFrame->GetParentStyleContext(&unused);
if (oldContext->GetParent() != newParent) {
// If we received eRestyleResult_Stop, then the old style context was
// left on mFrame. Since we ended up restyling our parent, change
@ -2890,20 +2885,14 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
nsIAtom* const pseudoTag = oldContext->GetPseudo();
const nsCSSPseudoElements::Type pseudoType = oldContext->GetPseudoType();
nsStyleContext* parentContext;
// Get the frame providing the parent style context. If it is a
// child, then resolve the provider first.
nsIFrame* providerFrame = aSelf->GetParentStyleContextFrame();
nsIFrame* providerFrame;
nsStyleContext* parentContext = aSelf->GetParentStyleContext(&providerFrame);
bool isChild = providerFrame && providerFrame->GetParent() == aSelf;
if (!isChild) {
if (providerFrame)
parentContext = providerFrame->StyleContext();
else
parentContext = nullptr;
}
else {
if (isChild) {
MOZ_ASSERT(providerFrame->GetContent() == aSelf->GetContent(),
"Postcondition for GetParentStyleContextFrame() violated. "
"Postcondition for GetParentStyleContext() violated. "
"That means we need to add the current element to the "
"ancestor filter.");
@ -3625,7 +3614,7 @@ ElementRestyler::RestyleContentChildren(nsIFrame* aParent,
NS_ASSERTION(outOfFlowFrame != mResolvedChild,
"out-of-flow frame not a true descendant");
// |nsFrame::GetParentStyleContextFrame| checks being out
// |nsFrame::GetParentStyleContext| checks being out
// of flow so that this works correctly.
do {
if (GetPrevContinuationWithSameStyle(outOfFlowFrame)) {

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

@ -2602,7 +2602,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle
// Figure out which frame has the main style for the document element,
// assigning it to mRootElementStyleFrame.
// Backgrounds should be propagated from that frame to the viewport.
mRootElementStyleFrame = contentFrame->GetParentStyleContextFrame();
contentFrame->GetParentStyleContext(&mRootElementStyleFrame);
bool isChild = mRootElementStyleFrame &&
mRootElementStyleFrame->GetParent() == contentFrame;
if (!isChild) {
@ -6287,15 +6287,19 @@ nsCSSFrameConstructor::IsValidSibling(nsIFrame* aSibling,
nsGkAtoms::menuFrame == parentType) {
// if we haven't already, construct a style context to find the display type of aContent
if (UNSET_DISPLAY == aDisplay) {
nsRefPtr<nsStyleContext> styleContext;
nsIFrame* styleParent = aSibling->GetParentStyleContextFrame();
nsIFrame* styleParent;
aSibling->GetParentStyleContext(&styleParent);
if (!styleParent) {
styleParent = aSibling->GetParent();
}
if (!styleParent) {
NS_NOTREACHED("Shouldn't happen");
return false;
}
// XXXbz when this code is killed, the state argument to
// ResolveStyleContext can be made non-optional.
styleContext = ResolveStyleContext(styleParent, aContent, nullptr);
nsRefPtr<nsStyleContext> styleContext =
ResolveStyleContext(styleParent, aContent, nullptr);
const nsStyleDisplay* display = styleContext->StyleDisplay();
aDisplay = display->mDisplay;
}

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

@ -4724,11 +4724,18 @@ nsDisplayTransform::GetDeltaToPerspectiveOrigin(const nsIFrame* aFrame,
//TODO: Should this be using our bounds or the parent's bounds?
// How do we handle aBoundsOverride in the latter case?
nsIFrame* parent = aFrame->GetParentStyleContextFrame();
if (!parent) {
nsIFrame* parent;
nsStyleContext* psc = aFrame->GetParentStyleContext(&parent);
if (!psc) {
return Point3D();
}
const nsStyleDisplay* display = parent->StyleDisplay();
if (!parent) {
parent = aFrame->GetParent();
if (!parent) {
return Point3D();
}
}
const nsStyleDisplay* display = psc->StyleDisplay();
nsRect boundingRect = nsDisplayTransform::GetFrameBoundsForTransform(parent);
/* Allows us to access named variables by index. */

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

@ -7734,15 +7734,33 @@ nsFrame::CorrectStyleParentFrame(nsIFrame* aProspectiveParent,
return nullptr;
}
nsIFrame*
nsFrame::DoGetParentStyleContextFrame() const
nsStyleContext*
nsFrame::DoGetParentStyleContext(nsIFrame** aProviderFrame) const
{
if (mContent && !mContent->GetParent() &&
!StyleContext()->GetPseudo()) {
// we're a frame for the root. We have no style context parent.
return nullptr;
*aProviderFrame = nullptr;
nsFrameManager* fm = PresContext()->FrameManager();
if (MOZ_LIKELY(mContent)) {
nsIContent* parentContent = mContent->GetFlattenedTreeParent();
if (MOZ_LIKELY(parentContent)) {
nsIAtom* pseudo = StyleContext()->GetPseudo();
if (!pseudo || !mContent->IsElement() ||
!nsCSSAnonBoxes::IsAnonBox(pseudo) ||
/* if next is true then it's really a request for the table frame's
parent context, see nsTable[Outer]Frame::GetParentStyleContext. */
pseudo == nsCSSAnonBoxes::tableOuter) {
nsStyleContext* sc = fm->GetDisplayContentsStyleFor(parentContent);
if (MOZ_UNLIKELY(sc)) {
return sc;
}
}
} else {
if (!StyleContext()->GetPseudo()) {
// we're a frame for the root. We have no style context parent.
return nullptr;
}
}
}
if (!(mState & NS_FRAME_OUT_OF_FLOW)) {
/*
* If this frame is an anonymous block created when an inline with a block
@ -7752,26 +7770,27 @@ nsFrame::DoGetParentStyleContextFrame() const
if (mState & NS_FRAME_PART_OF_IBSPLIT) {
nsIFrame* ibSplitSibling = GetIBSplitSiblingForAnonymousBlock(this);
if (ibSplitSibling) {
return ibSplitSibling;
return (*aProviderFrame = ibSplitSibling)->StyleContext();
}
}
// If this frame is one of the blocks that split an inline, we must
// return the "special" inline parent, i.e., the parent that this
// frame would have if we didn't mangle the frame structure.
return GetCorrectedParent(this);
*aProviderFrame = GetCorrectedParent(this);
return *aProviderFrame ? (*aProviderFrame)->StyleContext() : nullptr;
}
// We're an out-of-flow frame. For out-of-flow frames, we must
// resolve underneath the placeholder's parent. The placeholder is
// reached from the first-in-flow.
nsIFrame* placeholder = PresContext()->FrameManager()->
GetPlaceholderFrameFor(FirstInFlow());
nsIFrame* placeholder = fm->GetPlaceholderFrameFor(FirstInFlow());
if (!placeholder) {
NS_NOTREACHED("no placeholder frame for out-of-flow frame");
return GetCorrectedParent(this);
*aProviderFrame = GetCorrectedParent(this);
return *aProviderFrame ? (*aProviderFrame)->StyleContext() : nullptr;
}
return placeholder->GetParentStyleContextFrame();
return placeholder->GetParentStyleContext(aProviderFrame);
}
void

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

@ -221,18 +221,24 @@ public:
virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
#endif
virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE {
return DoGetParentStyleContextFrame();
virtual nsStyleContext* GetParentStyleContext(nsIFrame** aProviderFrame) const MOZ_OVERRIDE {
return DoGetParentStyleContext(aProviderFrame);
}
/**
* Do the work for getting the parent style context frame so that
* other frame's |GetParentStyleContextFrame| methods can call this
* other frame's |GetParentStyleContext| methods can call this
* method on *another* frame. (This function handles out-of-flow
* frames by using the frame manager's placeholder map and it also
* handles block-within-inline and generated content wrappers.)
*
* @param aProviderFrame (out) the frame associated with the returned value
* or null if the style context is for display:contents content.
* @return The style context that should be the parent of this frame's
* style context. Null is permitted, and means that this frame's
* style context should be the root of the style context tree.
*/
nsIFrame* DoGetParentStyleContextFrame() const;
nsStyleContext* DoGetParentStyleContext(nsIFrame** aProviderFrame) const;
virtual bool IsEmpty() MOZ_OVERRIDE;
virtual bool IsSelfEmpty() MOZ_OVERRIDE;

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

@ -2482,11 +2482,13 @@ public:
* return a grandparent or higher! Furthermore, if a child frame is
* returned it must have the same GetContent() as this frame.
*
* @return The frame whose style context should be the parent of this frame's
* @param aProviderFrame (out) the frame associated with the returned value
* or nullptr if the style context is for display:contents content.
* @return The style context that should be the parent of this frame's
* style context. Null is permitted, and means that this frame's
* style context should be the root of the style context tree.
*/
virtual nsIFrame* GetParentStyleContextFrame() const = 0;
virtual nsStyleContext* GetParentStyleContext(nsIFrame** aProviderFrame) const = 0;
/**
* Determines whether a frame is visible for painting;

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

@ -189,15 +189,26 @@ nsPlaceholderFrame::CanContinueTextRun() const
return mOutOfFlowFrame->CanContinueTextRun();
}
nsIFrame*
nsPlaceholderFrame::GetParentStyleContextFrame() const
nsStyleContext*
nsPlaceholderFrame::GetParentStyleContext(nsIFrame** aProviderFrame) const
{
NS_PRECONDITION(GetParent(), "How can we not have a parent here?");
nsIContent* parentContent = mContent ? mContent->GetParent() : nullptr;
if (parentContent) {
nsStyleContext* sc =
PresContext()->FrameManager()->GetDisplayContentsStyleFor(parentContent);
if (sc) {
*aProviderFrame = nullptr;
return sc;
}
}
// Lie about our pseudo so we can step out of all anon boxes and
// pseudo-elements. The other option would be to reimplement the
// {ib} split gunk here.
return CorrectStyleParentFrame(GetParent(), nsGkAtoms::placeholderFrame);
*aProviderFrame = CorrectStyleParentFrame(GetParent(), nsGkAtoms::placeholderFrame);
return *aProviderFrame ? (*aProviderFrame)->StyleContext() : nullptr;
}

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

@ -135,7 +135,7 @@ public:
}
#endif
virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE;
virtual nsStyleContext* GetParentStyleContext(nsIFrame** aProviderFrame) const MOZ_OVERRIDE;
/**
* @return the out-of-flow for aFrame if aFrame is a placeholder; otherwise

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

@ -295,9 +295,9 @@ nsTableColGroupFrame::RemoveFrame(ChildListID aListID,
nsTableColFrame* nextCol;
while (col && col->GetColType() == eColAnonymousCol) {
#ifdef DEBUG
nsIFrame* providerFrame = colFrame->GetParentStyleContextFrame();
if (colFrame->StyleContext()->GetParent() ==
providerFrame->StyleContext()) {
nsIFrame* providerFrame;
nsStyleContext* psc = colFrame->GetParentStyleContext(&providerFrame);
if (colFrame->StyleContext()->GetParent() == psc) {
NS_ASSERTION(col->StyleContext() == colFrame->StyleContext() &&
col->GetContent() == colFrame->GetContent(),
"How did that happen??");

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

@ -134,8 +134,8 @@ struct BCPropertyData
BCPixelSize mRightCellBorderWidth;
};
nsIFrame*
nsTableFrame::GetParentStyleContextFrame() const
nsStyleContext*
nsTableFrame::GetParentStyleContext(nsIFrame** aProviderFrame) const
{
// Since our parent, the table outer frame, returned this frame, we
// must return whatever our parent would normally have returned.
@ -143,10 +143,11 @@ nsTableFrame::GetParentStyleContextFrame() const
NS_PRECONDITION(GetParent(), "table constructed without outer table");
if (!mContent->GetParent() && !StyleContext()->GetPseudo()) {
// We're the root. We have no style context parent.
*aProviderFrame = nullptr;
return nullptr;
}
return GetParent()->DoGetParentStyleContextFrame();
return GetParent()->DoGetParentStyleContext(aProviderFrame);
}

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

@ -358,7 +358,8 @@ public:
nsFrameList& GetColGroups();
virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE;
virtual nsStyleContext*
GetParentStyleContext(nsIFrame** aProviderFrame) const MOZ_OVERRIDE;
/**
* Get the "type" of the frame

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

@ -2,7 +2,10 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsTableOuterFrame.h"
#include "nsFrameManager.h"
#include "nsTableFrame.h"
#include "nsTableCellFrame.h"
#include "nsStyleContext.h"
@ -102,25 +105,32 @@ nsTableCaptionFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext,
return result;
}
nsIFrame*
nsTableCaptionFrame::GetParentStyleContextFrame() const
nsStyleContext*
nsTableCaptionFrame::GetParentStyleContext(nsIFrame** aProviderFrame) const
{
NS_PRECONDITION(mContent->GetParent(),
"How could we not have a parent here?");
MOZ_ASSERT(GetContent()->GetParent(), "How could we not have a parent here?");
nsStyleContext* sc =
PresContext()->FrameManager()->GetDisplayContentsStyleFor(GetContent()->GetParent());
if (sc) {
*aProviderFrame = nullptr;
return sc;
}
// The caption's style context parent is the inner frame, unless
// it's anonymous.
nsIFrame* outerFrame = GetParent();
if (outerFrame && outerFrame->GetType() == nsGkAtoms::tableOuterFrame) {
nsIFrame* innerFrame = outerFrame->GetFirstPrincipalChild();
if (innerFrame) {
return nsFrame::CorrectStyleParentFrame(innerFrame,
StyleContext()->GetPseudo());
*aProviderFrame = nsFrame::CorrectStyleParentFrame(innerFrame,
StyleContext()->GetPseudo());
return *aProviderFrame ? (*aProviderFrame)->StyleContext() : nullptr;
}
}
NS_NOTREACHED("Where is our inner table frame?");
return nsBlockFrame::GetParentStyleContextFrame();
return nsBlockFrame::GetParentStyleContext(aProviderFrame);
}
#ifdef ACCESSIBILITY
@ -324,8 +334,8 @@ nsTableOuterFrame::BuildDisplayListForInnerTable(nsDisplayListBuilder* aBuilde
}
}
nsIFrame*
nsTableOuterFrame::GetParentStyleContextFrame() const
nsStyleContext*
nsTableOuterFrame::GetParentStyleContext(nsIFrame** aProviderFrame) const
{
// The table outer frame and the (inner) table frame split the style
// data by giving the table frame the style context associated with
@ -337,7 +347,7 @@ nsTableOuterFrame::GetParentStyleContextFrame() const
// children of the table inherit directly from the inner table, and
// the outer table's style context is a leaf.
return InnerTableFrame();
return (*aProviderFrame = InnerTableFrame())->StyleContext();
}
// INCREMENTAL REFLOW HELPER FUNCTIONS

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

@ -32,7 +32,7 @@ public:
const mozilla::LogicalSize& aPadding,
bool aShrinkWrap) MOZ_OVERRIDE;
virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE;
virtual nsStyleContext* GetParentStyleContext(nsIFrame** aProviderFrame) const MOZ_OVERRIDE;
#ifdef ACCESSIBILITY
virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
@ -136,7 +136,7 @@ public:
virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
#endif
virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE;
virtual nsStyleContext* GetParentStyleContext(nsIFrame** aProviderFrame) const MOZ_OVERRIDE;
/**
* Return the content for the cell at the given row and column.