Don't copy/paste code to cast to placeholder frames all over the place; use a

utility method instead.  Bug 276954, r+sr=roc, a=brendan
This commit is contained in:
bzbarsky%mit.edu 2005-04-14 15:30:35 +00:00
parent e2e353c87b
commit 7f0d146903
7 changed files with 59 additions and 107 deletions

View File

@ -647,12 +647,8 @@ DoCleanupFrameReferences(nsPresContext* aPresContext,
{
nsIContent* content = aFrameIn->GetContent();
nsIFrame* frame = aFrameIn;
// if the frame is a placeholder use the out of flow frame
if (nsLayoutAtoms::placeholderFrame == aFrameIn->GetType()) {
frame = ((nsPlaceholderFrame*)frame)->GetOutOfFlowFrame();
NS_ASSERTION(frame, "program error - null of of flow frame in placeholder");
}
nsIFrame* frame = nsPlaceholderFrame::GetRealFrameFor(aFrameIn);
// Remove the mapping from the content object to its frame
aFrameManager->SetPrimaryFrameFor(content, nsnull);
@ -1545,25 +1541,6 @@ PRBool IsBorderCollapse(nsIFrame* aFrame)
return PR_FALSE;
}
// a helper routine that automatically navigates placeholders.
static nsIFrame*
GetRealFrame(nsIFrame* aFrame)
{
nsIFrame* result = aFrame;
// We may be a placeholder. If we are, go to the real frame.
// See if it's a placeholder frame for a float.
PRBool isPlaceholder = (nsLayoutAtoms::placeholderFrame == aFrame->GetType());
if (isPlaceholder) {
// Get the out-of-flow frame that the placeholder points to.
// This is the real float that we should examine.
result = NS_STATIC_CAST(nsPlaceholderFrame*,aFrame)->GetOutOfFlowFrame();
NS_ASSERTION(result, "No out of flow frame found for placeholder!\n");
}
return result;
}
/**
* Utility method, called from MoveChildrenTo(), that recursively
* descends down the frame hierarchy looking for floating frames that
@ -1575,7 +1552,7 @@ static void
AdjustFloatParentPtrs(nsIFrame* aFrame,
nsFrameConstructorState& aState)
{
nsIFrame *outOfFlowFrame = GetRealFrame(aFrame);
nsIFrame *outOfFlowFrame = nsPlaceholderFrame::GetRealFrameFor(aFrame);
if (outOfFlowFrame && outOfFlowFrame != aFrame) {
@ -5305,14 +5282,9 @@ nsCSSFrameConstructor::ConstructHTMLFrame(nsFrameConstructorState& aState,
aTag, aStyleContext, newFrame,
display, frameHasBeenInitialized,
aFrameItems);
#ifdef DEBUG
nsIFrame* debugFrame = aFrameItems.lastChild;
if (debugFrame->GetType() == nsLayoutAtoms::placeholderFrame) {
debugFrame = ((nsPlaceholderFrame*)debugFrame)->GetOutOfFlowFrame();
}
NS_ASSERTION(debugFrame == newFrame,
NS_ASSERTION(nsPlaceholderFrame::GetRealFrameFor(aFrameItems.lastChild) ==
newFrame,
"Frame didn't get added to aFrameItems?");
#endif
addedToFrameList = PR_TRUE;
}
}
@ -5332,14 +5304,9 @@ nsCSSFrameConstructor::ConstructHTMLFrame(nsFrameConstructorState& aState,
rv = ConstructFieldSetFrame(aState, aContent, aParentFrame,
aTag, aStyleContext, newFrame,
aFrameItems, display, frameHasBeenInitialized);
#ifdef DEBUG
nsIFrame* debugFrame = aFrameItems.lastChild;
if (debugFrame->GetType() == nsLayoutAtoms::placeholderFrame) {
debugFrame = ((nsPlaceholderFrame*)debugFrame)->GetOutOfFlowFrame();
}
NS_ASSERTION(debugFrame == newFrame,
"Frame didn't get added to aFrameItems?");
#endif
NS_ASSERTION(nsPlaceholderFrame::GetRealFrameFor(aFrameItems.lastChild) ==
newFrame,
"Frame didn't get added to aFrameItems?");
addedToFrameList = PR_TRUE;
}
else if (nsHTMLAtoms::legend == aTag) {
@ -9418,8 +9385,8 @@ DoDeletingFrameSubtree(nsPresContext* aPresContext,
// See if it's a placeholder frame
if (nsLayoutAtoms::placeholderFrame == childFrame->GetType()) {
// Get the out-of-flow frame
nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)childFrame)->GetOutOfFlowFrame();
NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
nsIFrame* outOfFlowFrame =
nsPlaceholderFrame::GetRealFrameForPlaceholder(childFrame);
// Remove the mapping from the out-of-flow frame to its placeholder
aFrameManager->UnregisterPlaceholderFrame((nsPlaceholderFrame*)childFrame);
@ -9901,7 +9868,8 @@ UpdateViewsForTree(nsPresContext* aPresContext, nsIFrame* aFrame,
// only do frames that are in flow
if (nsLayoutAtoms::placeholderFrame == child->GetType()) { // placeholder
// get out of flow frame and start over there
nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)child)->GetOutOfFlowFrame();
nsIFrame* outOfFlowFrame =
nsPlaceholderFrame::GetRealFrameForPlaceholder(child);
NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
DoApplyRenderingChangeToTree(aPresContext, outOfFlowFrame,
@ -11098,7 +11066,7 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext,
}
} else if (nsLayoutAtoms::placeholderFrame == frameType) {
// create a continuing out of flow frame
nsIFrame* oofFrame = ((nsPlaceholderFrame*)aFrame)->GetOutOfFlowFrame();
nsIFrame* oofFrame = nsPlaceholderFrame::GetRealFrameForPlaceholder(aFrame);
nsIFrame* oofContFrame;
CreateContinuingFrame(aPresContext, oofFrame, aParentFrame, &oofContFrame);
if (!oofContFrame)
@ -11276,14 +11244,8 @@ nsCSSFrameConstructor::FindFrameWithContent(nsFrameManager* aFrameManager,
nsIContent* kidContent = kidFrame->GetContent();
if (kidContent == aContent) {
// We found a match. See if it's a placeholder frame
if (nsLayoutAtoms::placeholderFrame == kidFrame->GetType()) {
// Ignore the placeholder and return the out-of-flow frame instead
return ((nsPlaceholderFrame*)kidFrame)->GetOutOfFlowFrame();
}
// Return the matching child frame
return kidFrame;
// We found a match. Return the out-of-flow if it's a placeholder
return nsPlaceholderFrame::GetRealFrameFor(kidFrame);
}
// only do this if there is content

View File

@ -869,10 +869,10 @@ VerifyStyleTree(nsPresContext* aPresContext, nsIFrame* aFrame,
if (NS_FRAME_OUT_OF_FLOW != (child->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
// only do frames that are in flow
if (nsLayoutAtoms::placeholderFrame == child->GetType()) {
// placeholder: first recirse and verify the out of flow frame,
// placeholder: first recurse and verify the out of flow frame,
// then verify the placeholder's context
nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)child)->GetOutOfFlowFrame();
NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
nsIFrame* outOfFlowFrame =
nsPlaceholderFrame::GetRealFrameForPlaceholder(child);
// recurse to out of flow frame, letting the parent context get resolved
VerifyStyleTree(aPresContext, outOfFlowFrame, nsnull);
@ -946,7 +946,8 @@ nsFrameManager::ReParentStyleContext(nsIFrame* aFrame,
// only do frames that are in flow
if (nsLayoutAtoms::placeholderFrame == child->GetType()) {
// get out of flow frame and recurse there
nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)child)->GetOutOfFlowFrame();
nsIFrame* outOfFlowFrame =
nsPlaceholderFrame::GetRealFrameForPlaceholder(child);
NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
result = ReParentStyleContext(outOfFlowFrame, newContext);
@ -1295,7 +1296,7 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext,
if (nsLayoutAtoms::placeholderFrame == child->GetType()) { // placeholder
// get out of flow frame and recur there
nsIFrame* outOfFlowFrame =
NS_STATIC_CAST(nsPlaceholderFrame*,child)->GetOutOfFlowFrame();
nsPlaceholderFrame::GetRealFrameForPlaceholder(child);
NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
NS_ASSERTION(outOfFlowFrame != resolvedChild,
"out-of-flow frame not a true descendant");

View File

@ -141,7 +141,6 @@ private:
nsIFrame* GetNextSibling(nsIFrame* aFrame);
nsIFrame* GetPrevSibling(nsIFrame* aFrame);
nsIFrame* GetRealFrame(nsIFrame* aFrame);
nsIFrame* GetPlaceholderFrame(nsIFrame* aFrame);
PRBool IsPopupFrame(nsIFrame* aFrame);
@ -481,7 +480,7 @@ nsFocusIterator::nsFocusIterator(nsPresContext* aPresContext, nsIFrame* aStart)
{
nsIFrame* start = aStart;
if (aStart)
start = GetRealFrame(aStart);
start = nsPlaceholderFrame::GetRealFrameFor(aStart);
setStart(start);
setCurrent(start);
@ -506,28 +505,6 @@ nsFocusIterator::GetPlaceholderFrame(nsIFrame* aFrame)
return result;
}
nsIFrame*
nsFocusIterator::GetRealFrame(nsIFrame* aFrame)
{
nsIFrame* result = aFrame;
// See if it's a placeholder frame for a float.
if (aFrame) {
PRBool isPlaceholder = nsLayoutAtoms::placeholderFrame == aFrame->GetType();
if (isPlaceholder) {
// Get the out-of-flow frame that the placeholder points to.
// This is the real float that we should examine.
result = NS_STATIC_CAST(nsPlaceholderFrame*,aFrame)->GetOutOfFlowFrame();
NS_ASSERTION(result, "No out of flow frame found for placeholder!\n");
}
if (result != aFrame)
result = GetRealFrame(result);
}
return result;
}
PRBool
nsFocusIterator::IsPopupFrame(nsIFrame* aFrame)
{
@ -549,7 +526,7 @@ nsFocusIterator::GetFirstChild(nsIFrame* aFrame)
{
nsIFrame* result = aFrame->GetFirstChild(nsnull);
if (result)
result = GetRealFrame(result);
result = nsPlaceholderFrame::GetRealFrameFor(result);
if (result && IsPopupFrame(result))
result = GetNextSibling(result);
@ -565,7 +542,7 @@ nsFocusIterator::GetNextSibling(nsIFrame* aFrame)
if (placeholder) {
result = placeholder->GetNextSibling();
if (result)
result = GetRealFrame(result);
result = nsPlaceholderFrame::GetRealFrameFor(result);
}
if (result && IsPopupFrame(result))
@ -584,7 +561,7 @@ nsFocusIterator::GetPrevSibling(nsIFrame* aFrame)
if (parent) {
nsFrameList list(parent->GetFirstChild(nsnull));
result = list.GetPrevSiblingFor(placeholder);
result = GetRealFrame(result);
result = nsPlaceholderFrame::GetRealFrameFor(result);
}
}

View File

@ -176,10 +176,8 @@ nsLayoutUtils::GetFloatFromPlaceholder(nsIFrame* aFrame) {
}
nsIFrame *outOfFlowFrame =
NS_STATIC_CAST(nsPlaceholderFrame*, aFrame)->GetOutOfFlowFrame();
// This is a hack.
if (outOfFlowFrame &&
!outOfFlowFrame->GetStyleDisplay()->IsAbsolutelyPositioned()) {
nsPlaceholderFrame::GetRealFrameForPlaceholder(aFrame);
if (outOfFlowFrame->GetStyleDisplay()->IsFloating()) {
return outOfFlowFrame;
}

View File

@ -6988,17 +6988,11 @@ WalkFramesThroughPlaceholders(nsPresContext *aPresContext, nsIFrame *aFrame,
nsIFrame *child = aFrame->GetFirstChild(childList);
while (child) {
if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
// only do frames that are in flow
if (nsLayoutAtoms::placeholderFrame == child->GetType()) {
// get out of flow frame and recur there
nsIFrame* outOfFlowFrame =
NS_STATIC_CAST(nsPlaceholderFrame*, child)->GetOutOfFlowFrame();
NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
WalkFramesThroughPlaceholders(aPresContext, outOfFlowFrame,
aFunc, aClosure);
}
else
WalkFramesThroughPlaceholders(aPresContext, child, aFunc, aClosure);
// only do frames that are in flow, and recur through the
// out-of-flows of placeholders.
WalkFramesThroughPlaceholders(aPresContext,
nsPlaceholderFrame::GetRealFrameFor(child),
aFunc, aClosure);
}
child = child->GetNextSibling();
}

View File

@ -902,7 +902,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
NS_ASSERTION(IsContinuationPlaceholder(f),
"Overflow placeholders must be continuation placeholders");
ReparentFrame(f, this, ancestorRS->frame);
nsIFrame* oof = NS_STATIC_CAST(nsPlaceholderFrame*, f)->GetOutOfFlowFrame();
nsIFrame* oof = nsPlaceholderFrame::GetRealFrameForPlaceholder(f);
mFloats.RemoveFrame(oof);
ReparentFrame(oof, this, ancestorRS->frame);
// Clear the next-sibling in case the frame wasn't in mFloats
@ -4756,8 +4756,7 @@ nsBlockFrame::HandleOverflowPlaceholdersForPulledFrame(
ReparentFrame(frame, parent, this);
// continuation placeholders are always direct children of a block
nsPlaceholderFrame* placeholder = NS_STATIC_CAST(nsPlaceholderFrame*, frame);
nsIFrame* outOfFlow = placeholder->GetOutOfFlowFrame();
nsIFrame* outOfFlow = nsPlaceholderFrame::GetRealFrameForPlaceholder(frame);
if (!parent->mFloats.RemoveFrame(outOfFlow)) {
nsAutoOOFFrameList oofs(parent);
@ -7187,13 +7186,9 @@ nsBlockFrame::RenumberListsFor(nsPresContext* aPresContext,
return PR_FALSE;
PRBool kidRenumberedABullet = PR_FALSE;
nsIFrame* kid = aKid;
// if the frame is a placeholder, then get the out of flow frame
if (nsLayoutAtoms::placeholderFrame == aKid->GetType()) {
kid = NS_STATIC_CAST(nsPlaceholderFrame*, aKid)->GetOutOfFlowFrame();
NS_ASSERTION(kid, "no out-of-flow frame");
}
nsIFrame* kid = nsPlaceholderFrame::GetRealFrameFor(aKid);
// drill down through any wrappers to the real frame
kid = kid->GetContentInsertionFrame();

View File

@ -38,6 +38,7 @@
#define nsPlaceholderFrame_h___
#include "nsSplittableFrame.h"
#include "nsLayoutAtoms.h"
nsresult NS_NewPlaceholderFrame(nsIPresShell* aPresShell, nsIFrame** aInstancePtrResult);
@ -90,6 +91,30 @@ public:
virtual PRBool IsEmpty() { return PR_TRUE; }
virtual PRBool IsSelfEmpty() { return PR_TRUE; }
/**
* @return the out-of-flow for aFrame if aFrame is a placeholder; otherwise
* aFrame
*/
static nsIFrame* GetRealFrameFor(nsIFrame* aFrame) {
NS_PRECONDITION(aFrame, "Must have a frame to work with");
if (aFrame->GetType() == nsLayoutAtoms::placeholderFrame) {
return GetRealFrameForPlaceholder(aFrame);
}
return aFrame;
}
/**
* @return the out-of-flow for aFrame, which is known to be a placeholder
*/
static nsIFrame* GetRealFrameForPlaceholder(nsIFrame* aFrame) {
NS_PRECONDITION(aFrame->GetType() == nsLayoutAtoms::placeholderFrame,
"Must have placeholder frame as input");
nsIFrame* outOfFlow =
NS_STATIC_CAST(nsPlaceholderFrame*, aFrame)->GetOutOfFlowFrame();
NS_ASSERTION(outOfFlow, "Null out-of-flow for placeholder?");
return outOfFlow;
}
protected:
nsIFrame* mOutOfFlowFrame;
};