Bug 649726 - Move nsHTMLContainerFrame static view methods to nsContainerFrame. r=bz.

This commit is contained in:
Jonathan Watt 2011-04-19 12:55:11 +01:00
Родитель 1640530e4f
Коммит a5b747bfa7
13 изменённых файлов: 286 добавлений и 286 удалений

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

@ -287,7 +287,7 @@ SplitInlineAncestors(nsIFrame* aFrame)
nsFrameList tail = container->StealFramesAfter(frame);
// Reparent views as necessary
rv = nsHTMLContainerFrame::ReparentFrameViewList(presContext, tail, parent, newParent);
rv = nsContainerFrame::ReparentFrameViewList(presContext, tail, parent, newParent);
if (NS_FAILED(rv)) {
return rv;
}

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

@ -1331,8 +1331,8 @@ MoveChildrenTo(nsPresContext* aPresContext,
if (aNewParent->HasView() || aOldParent->HasView() || !sameGrandParent) {
// Move the frames into the new view
nsHTMLContainerFrame::ReparentFrameViewList(aPresContext, aFrameList,
aOldParent, aNewParent);
nsContainerFrame::ReparentFrameViewList(aPresContext, aFrameList,
aOldParent, aNewParent);
}
for (nsFrameList::Enumerator e(aFrameList); !e.AtEnd(); e.Next()) {
@ -1907,7 +1907,7 @@ nsCSSFrameConstructor::ConstructTable(nsFrameConstructorState& aState,
// Init the table outer frame and see if we need to create a view, e.g.
// the frame is absolutely positioned
InitAndRestoreFrame(aState, content, geometricParent, nsnull, newFrame);
nsHTMLContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
nsContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
// Create the inner table frame
nsIFrame* innerFrame;
@ -1987,7 +1987,7 @@ nsCSSFrameConstructor::ConstructTableRow(nsFrameConstructorState& aState,
return NS_ERROR_OUT_OF_MEMORY;
}
InitAndRestoreFrame(aState, content, aParentFrame, nsnull, newFrame);
nsHTMLContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
nsContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
nsFrameItems childItems;
nsresult rv;
@ -2088,7 +2088,7 @@ nsCSSFrameConstructor::ConstructTableCell(nsFrameConstructorState& aState,
// Initialize the table cell frame
InitAndRestoreFrame(aState, content, aParentFrame, nsnull, newFrame);
nsHTMLContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
nsContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
// Resolve pseudo style and initialize the body cell frame
nsRefPtr<nsStyleContext> innerPseudoStyle;
@ -2438,7 +2438,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle
processChildren = PR_TRUE;
// See if we need to create a view
nsHTMLContainerFrame::CreateViewForFrame(contentFrame, PR_FALSE);
nsContainerFrame::CreateViewForFrame(contentFrame, PR_FALSE);
} else {
return NS_ERROR_FAILURE;
}
@ -2957,7 +2957,7 @@ nsCSSFrameConstructor::ConstructButtonFrame(nsFrameConstructorState& aState,
return rv;
}
// See if we need to create a view
nsHTMLContainerFrame::CreateViewForFrame(buttonFrame, PR_FALSE);
nsContainerFrame::CreateViewForFrame(buttonFrame, PR_FALSE);
nsRefPtr<nsStyleContext> innerBlockContext;
innerBlockContext =
@ -3085,7 +3085,7 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsFrameConstructorState& aState,
aState.GetGeometricParent(aStyleDisplay, aParentFrame),
nsnull, comboboxFrame);
nsHTMLContainerFrame::CreateViewForFrame(comboboxFrame, PR_FALSE);
nsContainerFrame::CreateViewForFrame(comboboxFrame, PR_FALSE);
rv = aState.AddChild(comboboxFrame, aFrameItems, content, styleContext,
aParentFrame);
@ -3224,7 +3224,7 @@ nsCSSFrameConstructor::InitializeSelectFrame(nsFrameConstructorState& aState,
}
}
nsHTMLContainerFrame::CreateViewForFrame(scrollFrame, aBuildCombobox);
nsContainerFrame::CreateViewForFrame(scrollFrame, aBuildCombobox);
BuildScrollFrame(aState, aContent, aStyleContext, scrolledFrame,
geometricParent, scrollFrame);
@ -3275,7 +3275,7 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsFrameConstructorState& aState,
// See if we need to create a view, e.g. the frame is absolutely
// positioned
nsHTMLContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
nsContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
// Resolve style and initialize the frame
nsRefPtr<nsStyleContext> fieldsetContentStyle;
@ -3756,8 +3756,8 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt
newFrame);
NS_ASSERTION(NS_SUCCEEDED(rv), "InitAndRestoreFrame failed");
// See whether we need to create a view
nsHTMLContainerFrame::CreateViewForFrame(newFrame,
(bits & FCDATA_FORCE_VIEW) != 0);
nsContainerFrame::CreateViewForFrame(newFrame,
(bits & FCDATA_FORCE_VIEW) != 0);
frameToAddToList = newFrame;
}
@ -4235,7 +4235,7 @@ nsCSSFrameConstructor::BeginBuildingScrollFrame(nsFrameConstructorState& aState,
InitAndRestoreFrame(aState, aContent, aParentFrame, nsnull, gfxScrollFrame);
// Create a view
nsHTMLContainerFrame::CreateViewForFrame(gfxScrollFrame, PR_FALSE);
nsContainerFrame::CreateViewForFrame(gfxScrollFrame, PR_FALSE);
}
// if there are any anonymous children for the scroll frame, create
@ -4917,7 +4917,7 @@ nsCSSFrameConstructor::ConstructSVGForeignObjectFrame(nsFrameConstructorState& a
// We don't allow this frame to be out of flow
InitAndRestoreFrame(aState, content, aParentFrame, nsnull, newFrame);
nsHTMLContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
nsContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
nsresult rv = aState.AddChild(newFrame, aFrameItems, content, styleContext,
aParentFrame, PR_FALSE, PR_FALSE);
@ -8383,7 +8383,7 @@ nsCSSFrameConstructor::CreateContinuingOuterTableFrame(nsIPresShell* aPresShe
if (newFrame) {
newFrame->Init(aContent, aParentFrame, aFrame);
nsHTMLContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
nsContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
// Create a continuing inner table frame, and if there's a caption then
// replicate the caption
@ -8429,7 +8429,7 @@ nsCSSFrameConstructor::CreateContinuingTableFrame(nsIPresShell* aPresShell,
if (newFrame) {
newFrame->Init(aContent, aParentFrame, aFrame);
nsHTMLContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
nsContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
// Replicate any header/footer frames
nsFrameItems childFrames;
@ -8509,7 +8509,7 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext,
if (newFrame) {
newFrame->Init(content, aParentFrame, aFrame);
nsHTMLContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
nsContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
}
} else if (nsGkAtoms::inlineFrame == frameType) {
@ -10648,7 +10648,7 @@ nsCSSFrameConstructor::ConstructBlock(nsFrameConstructorState& aState,
InitAndRestoreFrame(aState, aContent, aParentFrame, nsnull, columnSetFrame);
// See if we need to create a view
nsHTMLContainerFrame::CreateViewForFrame(columnSetFrame, PR_FALSE);
nsContainerFrame::CreateViewForFrame(columnSetFrame, PR_FALSE);
blockStyle = mPresShell->StyleSet()->
ResolveAnonymousBoxStyle(nsCSSAnonBoxes::columnContent, aStyleContext);
parent = columnSetFrame;
@ -10788,7 +10788,7 @@ nsCSSFrameConstructor::ConstructInline(nsFrameConstructorState& aState,
// this is part of the fix for bug 42372
// Any inline frame might need a view (because of opacity, or fixed background)
nsHTMLContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
nsContainerFrame::CreateViewForFrame(newFrame, PR_FALSE);
if (positioned) {
// Relatively positioned frames becomes a container for child
@ -10877,7 +10877,7 @@ nsCSSFrameConstructor::CreateIBSiblings(nsFrameConstructorState& aState,
PR_FALSE);
// Any frame could have a view
nsHTMLContainerFrame::CreateViewForFrame(blockFrame, PR_FALSE);
nsContainerFrame::CreateViewForFrame(blockFrame, PR_FALSE);
// Find the first non-block child which defines the end of our block kids
// and the start of our next inline's kids

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

@ -674,8 +674,8 @@ static void ReparentFrame(nsIFrame* aFrame, nsIFrame* aOldParent,
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
nsHTMLContainerFrame::ReparentFrameView(aFrame->PresContext(), aFrame,
aOldParent, aNewParent);
nsContainerFrame::ReparentFrameView(aFrame->PresContext(), aFrame,
aOldParent, aNewParent);
}
//////////////////////////////////////////////////////////////////////

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

@ -439,8 +439,8 @@ nsCanvasFrame::Reflow(nsPresContext* aPresContext,
if (overflow) {
NS_ASSERTION(overflow->OnlyChild(),
"must have doc root as canvas frame's only child");
nsHTMLContainerFrame::ReparentFrameViewList(aPresContext, *overflow,
prevCanvasFrame, this);
nsContainerFrame::ReparentFrameViewList(aPresContext, *overflow,
prevCanvasFrame, this);
// Prepend overflow to the our child list. There may already be
// children placeholders for fixed-pos elements, which don't get
// reflowed but must not be lost until the canvas frame is destroyed.

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

@ -869,8 +869,8 @@ nsColumnSetFrame::DrainOverflowColumns()
if (prev) {
nsAutoPtr<nsFrameList> overflows(prev->StealOverflowFrames());
if (overflows) {
nsHTMLContainerFrame::ReparentFrameViewList(PresContext(), *overflows,
prev, this);
nsContainerFrame::ReparentFrameViewList(PresContext(), *overflows,
prev, this);
mFrames.InsertFrames(this, nsnull, *overflows);
}

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

@ -407,6 +407,106 @@ nsContainerFrame::PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset,
/////////////////////////////////////////////////////////////////////////////
// Helper member functions
static nsresult
ReparentFrameViewTo(nsIFrame* aFrame,
nsIViewManager* aViewManager,
nsIView* aNewParentView,
nsIView* aOldParentView)
{
// XXX What to do about placeholder views for "position: fixed" elements?
// They should be reparented too.
// Does aFrame have a view?
if (aFrame->HasView()) {
#ifdef MOZ_XUL
if (aFrame->GetType() == nsGkAtoms::menuPopupFrame) {
// This view must be parented by the root view, don't reparent it.
return NS_OK;
}
#endif
nsIView* view = aFrame->GetView();
// Verify that the current parent view is what we think it is
//nsIView* parentView;
//NS_ASSERTION(parentView == aOldParentView, "unexpected parent view");
aViewManager->RemoveChild(view);
// The view will remember the Z-order and other attributes that have been set on it.
nsIView* insertBefore = nsLayoutUtils::FindSiblingViewFor(aNewParentView, aFrame);
aViewManager->InsertChild(aNewParentView, view, insertBefore, insertBefore != nsnull);
} else {
PRInt32 listIndex = 0;
nsIAtom* listName = nsnull;
// This loop iterates through every child list name, and also
// executes once with listName == nsnull.
do {
// Iterate the child frames, and check each child frame to see if it has
// a view
nsIFrame* childFrame = aFrame->GetFirstChild(listName);
for (; childFrame; childFrame = childFrame->GetNextSibling()) {
ReparentFrameViewTo(childFrame, aViewManager,
aNewParentView, aOldParentView);
}
listName = aFrame->GetAdditionalChildListName(listIndex++);
} while (listName);
}
return NS_OK;
}
nsresult
nsContainerFrame::CreateViewForFrame(nsIFrame* aFrame,
PRBool aForce)
{
if (aFrame->HasView()) {
return NS_OK;
}
// If we don't yet have a view, see if we need a view
if (!aForce && !aFrame->NeedsView()) {
// don't need a view
return NS_OK;
}
nsIView* parentView = aFrame->GetParent()->GetClosestView();
NS_ASSERTION(parentView, "no parent with view");
nsIViewManager* viewManager = parentView->GetViewManager();
NS_ASSERTION(viewManager, "null view manager");
// Create a view
nsIView* view = viewManager->CreateView(aFrame->GetRect(), parentView);
if (!view)
return NS_ERROR_OUT_OF_MEMORY;
SyncFrameViewProperties(aFrame->PresContext(), aFrame, nsnull, view);
nsIView* insertBefore = nsLayoutUtils::FindSiblingViewFor(parentView, aFrame);
// we insert this view 'above' the insertBefore view, unless insertBefore is null,
// in which case we want to call with aAbove == PR_FALSE to insert at the beginning
// in document order
viewManager->InsertChild(parentView, view, insertBefore, insertBefore != nsnull);
// REVIEW: Don't create a widget for fixed-pos elements anymore.
// ComputeRepaintRegionForCopy will calculate the right area to repaint
// when we scroll.
// Reparent views on any child frames (or their descendants) to this
// view. We can just call ReparentFrameViewTo on this frame because
// we know this frame has no view, so it will crawl the children. Also,
// we know that any descendants with views must have 'parentView' as their
// parent view.
ReparentFrameViewTo(aFrame, viewManager, view, parentView);
// Remember our view
aFrame->SetView(view);
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
("nsHTMLContainerFrame::CreateViewForFrame: frame=%p view=%p",
aFrame));
return NS_OK;
}
/**
* Position the view associated with |aKidFrame|, if there is one. A
* container frame should call this method after positioning a frame,
@ -436,6 +536,128 @@ nsContainerFrame::PositionFrameView(nsIFrame* aKidFrame)
vm->MoveViewTo(view, pt.x, pt.y);
}
nsresult
nsContainerFrame::ReparentFrameView(nsPresContext* aPresContext,
nsIFrame* aChildFrame,
nsIFrame* aOldParentFrame,
nsIFrame* aNewParentFrame)
{
NS_PRECONDITION(aChildFrame, "null child frame pointer");
NS_PRECONDITION(aOldParentFrame, "null old parent frame pointer");
NS_PRECONDITION(aNewParentFrame, "null new parent frame pointer");
NS_PRECONDITION(aOldParentFrame != aNewParentFrame, "same old and new parent frame");
// See if either the old parent frame or the new parent frame have a view
while (!aOldParentFrame->HasView() && !aNewParentFrame->HasView()) {
// Walk up both the old parent frame and the new parent frame nodes
// stopping when we either find a common parent or views for one
// or both of the frames.
//
// This works well in the common case where we push/pull and the old parent
// frame and the new parent frame are part of the same flow. They will
// typically be the same distance (height wise) from the
aOldParentFrame = aOldParentFrame->GetParent();
aNewParentFrame = aNewParentFrame->GetParent();
// We should never walk all the way to the root frame without finding
// a view
NS_ASSERTION(aOldParentFrame && aNewParentFrame, "didn't find view");
// See if we reached a common ancestor
if (aOldParentFrame == aNewParentFrame) {
break;
}
}
// See if we found a common parent frame
if (aOldParentFrame == aNewParentFrame) {
// We found a common parent and there are no views between the old parent
// and the common parent or the new parent frame and the common parent.
// Because neither the old parent frame nor the new parent frame have views,
// then any child views don't need reparenting
return NS_OK;
}
// We found views for one or both of the ancestor frames before we
// found a common ancestor.
nsIView* oldParentView = aOldParentFrame->GetClosestView();
nsIView* newParentView = aNewParentFrame->GetClosestView();
// See if the old parent frame and the new parent frame are in the
// same view sub-hierarchy. If they are then we don't have to do
// anything
if (oldParentView != newParentView) {
// They're not so we need to reparent any child views
return ReparentFrameViewTo(aChildFrame, oldParentView->GetViewManager(), newParentView,
oldParentView);
}
return NS_OK;
}
nsresult
nsContainerFrame::ReparentFrameViewList(nsPresContext* aPresContext,
const nsFrameList& aChildFrameList,
nsIFrame* aOldParentFrame,
nsIFrame* aNewParentFrame)
{
NS_PRECONDITION(aChildFrameList.NotEmpty(), "empty child frame list");
NS_PRECONDITION(aOldParentFrame, "null old parent frame pointer");
NS_PRECONDITION(aNewParentFrame, "null new parent frame pointer");
NS_PRECONDITION(aOldParentFrame != aNewParentFrame, "same old and new parent frame");
// See if either the old parent frame or the new parent frame have a view
while (!aOldParentFrame->HasView() && !aNewParentFrame->HasView()) {
// Walk up both the old parent frame and the new parent frame nodes
// stopping when we either find a common parent or views for one
// or both of the frames.
//
// This works well in the common case where we push/pull and the old parent
// frame and the new parent frame are part of the same flow. They will
// typically be the same distance (height wise) from the
aOldParentFrame = aOldParentFrame->GetParent();
aNewParentFrame = aNewParentFrame->GetParent();
// We should never walk all the way to the root frame without finding
// a view
NS_ASSERTION(aOldParentFrame && aNewParentFrame, "didn't find view");
// See if we reached a common ancestor
if (aOldParentFrame == aNewParentFrame) {
break;
}
}
// See if we found a common parent frame
if (aOldParentFrame == aNewParentFrame) {
// We found a common parent and there are no views between the old parent
// and the common parent or the new parent frame and the common parent.
// Because neither the old parent frame nor the new parent frame have views,
// then any child views don't need reparenting
return NS_OK;
}
// We found views for one or both of the ancestor frames before we
// found a common ancestor.
nsIView* oldParentView = aOldParentFrame->GetClosestView();
nsIView* newParentView = aNewParentFrame->GetClosestView();
// See if the old parent frame and the new parent frame are in the
// same view sub-hierarchy. If they are then we don't have to do
// anything
if (oldParentView != newParentView) {
nsIViewManager* viewManager = oldParentView->GetViewManager();
// They're not so we need to reparent any child views
for (nsFrameList::Enumerator e(aChildFrameList); !e.AtEnd(); e.Next()) {
ReparentFrameViewTo(e.get(), viewManager, newParentView, oldParentView);
}
}
return NS_OK;
}
static nsIWidget*
GetPresContextContainerWidget(nsPresContext* aPresContext)
{
@ -880,8 +1102,8 @@ nsContainerFrame::ReflowOverflowContainerChildren(nsPresContext* aPres
ExcessOverflowContainersProperty());
if (excessFrames) {
excessFrames->ApplySetParent(this);
nsHTMLContainerFrame::ReparentFrameViewList(aPresContext, *excessFrames,
prev, this);
nsContainerFrame::ReparentFrameViewList(aPresContext, *excessFrames,
prev, this);
overflowContainers = excessFrames;
rv = SetPropTableFrames(aPresContext, overflowContainers,
OverflowContainersProperty());
@ -1264,7 +1486,7 @@ nsContainerFrame::PushChildren(nsPresContext* aPresContext,
// When pushing and pulling frames we need to check for whether any
// views need to be reparented.
for (nsIFrame* f = aFromChild; f; f = f->GetNextSibling()) {
nsHTMLContainerFrame::ReparentFrameView(aPresContext, f, this, nextInFlow);
nsContainerFrame::ReparentFrameView(aPresContext, f, this, nextInFlow);
}
nextInFlow->mFrames.InsertFrames(nextInFlow, nsnull, tail);
}
@ -1298,9 +1520,9 @@ nsContainerFrame::MoveOverflowToChildList(nsPresContext* aPresContext)
"bad overflow list");
// When pushing and pulling frames we need to check for whether any
// views need to be reparented.
nsHTMLContainerFrame::ReparentFrameViewList(aPresContext,
*prevOverflowFrames,
prevInFlow, this);
nsContainerFrame::ReparentFrameViewList(aPresContext,
*prevOverflowFrames,
prevInFlow, this);
mFrames.AppendFrames(this, *prevOverflowFrames);
result = PR_TRUE;
}
@ -1448,9 +1670,9 @@ nsOverflowContinuationTracker::Insert(nsIFrame* aOverflowCont,
SetUpListWalker();
}
if (aOverflowCont->GetParent() != mParent) {
nsHTMLContainerFrame::ReparentFrameView(presContext, aOverflowCont,
aOverflowCont->GetParent(),
mParent);
nsContainerFrame::ReparentFrameView(presContext, aOverflowCont,
aOverflowCont->GetParent(),
mParent);
}
mOverflowContList->InsertFrame(mParent, mPrevOverflowCont, aOverflowCont);
aReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW;

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

@ -117,9 +117,26 @@ public:
nsIFrame* aNextInFlow,
PRBool aDeletingEmptyFrames);
/**
* Helper method to wrap views around frames. Used by containers
* under special circumstances (can be used by leaf frames as well)
*/
static nsresult CreateViewForFrame(nsIFrame* aFrame,
PRBool aForce);
// Positions the frame's view based on the frame's origin
static void PositionFrameView(nsIFrame* aKidFrame);
static nsresult ReparentFrameView(nsPresContext* aPresContext,
nsIFrame* aChildFrame,
nsIFrame* aOldParentFrame,
nsIFrame* aNewParentFrame);
static nsresult ReparentFrameViewList(nsPresContext* aPresContext,
const nsFrameList& aChildFrameList,
nsIFrame* aOldParentFrame,
nsIFrame* aNewParentFrame);
// Set the view's size and position after its frame has been reflowed.
//
// Flags:

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

@ -369,8 +369,8 @@ nsFirstLetterFrame::DrainOverflowFrames(nsPresContext* aPresContext)
// When pushing and pulling frames we need to check for whether any
// views need to be reparented.
nsHTMLContainerFrame::ReparentFrameViewList(aPresContext, *overflowFrames,
prevInFlow, this);
nsContainerFrame::ReparentFrameViewList(aPresContext, *overflowFrames,
prevInFlow, this);
mFrames.InsertFrames(this, nsnull, *overflowFrames);
}
}

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

@ -634,226 +634,4 @@ nsHTMLContainerFrame::CreateNextInFlow(nsPresContext* aPresContext,
return NS_OK;
}
static nsresult
ReparentFrameViewTo(nsIFrame* aFrame,
nsIViewManager* aViewManager,
nsIView* aNewParentView,
nsIView* aOldParentView)
{
// XXX What to do about placeholder views for "position: fixed" elements?
// They should be reparented too.
// Does aFrame have a view?
if (aFrame->HasView()) {
#ifdef MOZ_XUL
if (aFrame->GetType() == nsGkAtoms::menuPopupFrame) {
// This view must be parented by the root view, don't reparent it.
return NS_OK;
}
#endif
nsIView* view = aFrame->GetView();
// Verify that the current parent view is what we think it is
//nsIView* parentView;
//NS_ASSERTION(parentView == aOldParentView, "unexpected parent view");
aViewManager->RemoveChild(view);
// The view will remember the Z-order and other attributes that have been set on it.
nsIView* insertBefore = nsLayoutUtils::FindSiblingViewFor(aNewParentView, aFrame);
aViewManager->InsertChild(aNewParentView, view, insertBefore, insertBefore != nsnull);
} else {
PRInt32 listIndex = 0;
nsIAtom* listName = nsnull;
// This loop iterates through every child list name, and also
// executes once with listName == nsnull.
do {
// Iterate the child frames, and check each child frame to see if it has
// a view
nsIFrame* childFrame = aFrame->GetFirstChild(listName);
for (; childFrame; childFrame = childFrame->GetNextSibling()) {
ReparentFrameViewTo(childFrame, aViewManager,
aNewParentView, aOldParentView);
}
listName = aFrame->GetAdditionalChildListName(listIndex++);
} while (listName);
}
return NS_OK;
}
nsresult
nsHTMLContainerFrame::ReparentFrameView(nsPresContext* aPresContext,
nsIFrame* aChildFrame,
nsIFrame* aOldParentFrame,
nsIFrame* aNewParentFrame)
{
NS_PRECONDITION(aChildFrame, "null child frame pointer");
NS_PRECONDITION(aOldParentFrame, "null old parent frame pointer");
NS_PRECONDITION(aNewParentFrame, "null new parent frame pointer");
NS_PRECONDITION(aOldParentFrame != aNewParentFrame, "same old and new parent frame");
// See if either the old parent frame or the new parent frame have a view
while (!aOldParentFrame->HasView() && !aNewParentFrame->HasView()) {
// Walk up both the old parent frame and the new parent frame nodes
// stopping when we either find a common parent or views for one
// or both of the frames.
//
// This works well in the common case where we push/pull and the old parent
// frame and the new parent frame are part of the same flow. They will
// typically be the same distance (height wise) from the
aOldParentFrame = aOldParentFrame->GetParent();
aNewParentFrame = aNewParentFrame->GetParent();
// We should never walk all the way to the root frame without finding
// a view
NS_ASSERTION(aOldParentFrame && aNewParentFrame, "didn't find view");
// See if we reached a common ancestor
if (aOldParentFrame == aNewParentFrame) {
break;
}
}
// See if we found a common parent frame
if (aOldParentFrame == aNewParentFrame) {
// We found a common parent and there are no views between the old parent
// and the common parent or the new parent frame and the common parent.
// Because neither the old parent frame nor the new parent frame have views,
// then any child views don't need reparenting
return NS_OK;
}
// We found views for one or both of the ancestor frames before we
// found a common ancestor.
nsIView* oldParentView = aOldParentFrame->GetClosestView();
nsIView* newParentView = aNewParentFrame->GetClosestView();
// See if the old parent frame and the new parent frame are in the
// same view sub-hierarchy. If they are then we don't have to do
// anything
if (oldParentView != newParentView) {
// They're not so we need to reparent any child views
return ReparentFrameViewTo(aChildFrame, oldParentView->GetViewManager(), newParentView,
oldParentView);
}
return NS_OK;
}
nsresult
nsHTMLContainerFrame::ReparentFrameViewList(nsPresContext* aPresContext,
const nsFrameList& aChildFrameList,
nsIFrame* aOldParentFrame,
nsIFrame* aNewParentFrame)
{
NS_PRECONDITION(aChildFrameList.NotEmpty(), "empty child frame list");
NS_PRECONDITION(aOldParentFrame, "null old parent frame pointer");
NS_PRECONDITION(aNewParentFrame, "null new parent frame pointer");
NS_PRECONDITION(aOldParentFrame != aNewParentFrame, "same old and new parent frame");
// See if either the old parent frame or the new parent frame have a view
while (!aOldParentFrame->HasView() && !aNewParentFrame->HasView()) {
// Walk up both the old parent frame and the new parent frame nodes
// stopping when we either find a common parent or views for one
// or both of the frames.
//
// This works well in the common case where we push/pull and the old parent
// frame and the new parent frame are part of the same flow. They will
// typically be the same distance (height wise) from the
aOldParentFrame = aOldParentFrame->GetParent();
aNewParentFrame = aNewParentFrame->GetParent();
// We should never walk all the way to the root frame without finding
// a view
NS_ASSERTION(aOldParentFrame && aNewParentFrame, "didn't find view");
// See if we reached a common ancestor
if (aOldParentFrame == aNewParentFrame) {
break;
}
}
// See if we found a common parent frame
if (aOldParentFrame == aNewParentFrame) {
// We found a common parent and there are no views between the old parent
// and the common parent or the new parent frame and the common parent.
// Because neither the old parent frame nor the new parent frame have views,
// then any child views don't need reparenting
return NS_OK;
}
// We found views for one or both of the ancestor frames before we
// found a common ancestor.
nsIView* oldParentView = aOldParentFrame->GetClosestView();
nsIView* newParentView = aNewParentFrame->GetClosestView();
// See if the old parent frame and the new parent frame are in the
// same view sub-hierarchy. If they are then we don't have to do
// anything
if (oldParentView != newParentView) {
nsIViewManager* viewManager = oldParentView->GetViewManager();
// They're not so we need to reparent any child views
for (nsFrameList::Enumerator e(aChildFrameList); !e.AtEnd(); e.Next()) {
ReparentFrameViewTo(e.get(), viewManager, newParentView, oldParentView);
}
}
return NS_OK;
}
nsresult
nsHTMLContainerFrame::CreateViewForFrame(nsIFrame* aFrame,
PRBool aForce)
{
if (aFrame->HasView()) {
return NS_OK;
}
// If we don't yet have a view, see if we need a view
if (!aForce && !aFrame->NeedsView()) {
// don't need a view
return NS_OK;
}
nsIView* parentView = aFrame->GetParent()->GetClosestView();
NS_ASSERTION(parentView, "no parent with view");
nsIViewManager* viewManager = parentView->GetViewManager();
NS_ASSERTION(viewManager, "null view manager");
// Create a view
nsIView* view = viewManager->CreateView(aFrame->GetRect(), parentView);
if (!view)
return NS_ERROR_OUT_OF_MEMORY;
SyncFrameViewProperties(aFrame->PresContext(), aFrame, nsnull, view);
nsIView* insertBefore = nsLayoutUtils::FindSiblingViewFor(parentView, aFrame);
// we insert this view 'above' the insertBefore view, unless insertBefore is null,
// in which case we want to call with aAbove == PR_FALSE to insert at the beginning
// in document order
viewManager->InsertChild(parentView, view, insertBefore, insertBefore != nsnull);
// REVIEW: Don't create a widget for fixed-pos elements anymore.
// ComputeRepaintRegionForCopy will calculate the right area to repaint
// when we scroll.
// Reparent views on any child frames (or their descendants) to this
// view. We can just call ReparentFrameViewTo on this frame because
// we know this frame has no view, so it will crawl the children. Also,
// we know that any descendants with views must have 'parentView' as their
// parent view.
ReparentFrameViewTo(aFrame, viewManager, view, parentView);
// Remember our view
aFrame->SetView(view);
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
("nsHTMLContainerFrame::CreateViewForFrame: frame=%p view=%p",
aFrame));
return NS_OK;
}
NS_IMPL_FRAMEARENA_HELPERS(nsHTMLContainerFrame)

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

@ -71,23 +71,6 @@ class nsHTMLContainerFrame : public nsContainerFrame {
public:
NS_DECL_FRAMEARENA_HELPERS
/**
* Helper method to wrap views around frames. Used by containers
* under special circumstances (can be used by leaf frames as well)
*/
static nsresult CreateViewForFrame(nsIFrame* aFrame,
PRBool aForce);
static nsresult ReparentFrameView(nsPresContext* aPresContext,
nsIFrame* aChildFrame,
nsIFrame* aOldParentFrame,
nsIFrame* aNewParentFrame);
static nsresult ReparentFrameViewList(nsPresContext* aPresContext,
const nsFrameList& aChildFrameList,
nsIFrame* aOldParentFrame,
nsIFrame* aNewParentFrame);
/**
* Helper method to create next-in-flows if necessary. If aFrame
* already has a next-in-flow then this method does

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

@ -328,9 +328,9 @@ nsInlineFrame::Reflow(nsPresContext* aPresContext,
if (prevOverflowFrames) {
// When pushing and pulling frames we need to check for whether any
// views need to be reparented.
nsHTMLContainerFrame::ReparentFrameViewList(aPresContext,
*prevOverflowFrames,
prevInFlow, this);
nsContainerFrame::ReparentFrameViewList(aPresContext,
*prevOverflowFrames,
prevInFlow, this);
// Check if we should do the lazilySetParentPointer optimization.
// Only do it in simple cases where we're being reflowed for the
@ -436,9 +436,9 @@ nsInlineFrame::PullOverflowsFromPrevInFlow()
nsAutoPtr<nsFrameList> prevOverflowFrames(prevInFlow->StealOverflowFrames());
if (prevOverflowFrames) {
// Assume that our prev-in-flow has the same line container that we do.
nsHTMLContainerFrame::ReparentFrameViewList(PresContext(),
*prevOverflowFrames,
prevInFlow, this);
nsContainerFrame::ReparentFrameViewList(PresContext(),
*prevOverflowFrames,
prevInFlow, this);
mFrames.InsertFrames(this, nsnull, *prevOverflowFrames);
}
}
@ -816,7 +816,7 @@ nsInlineFrame::PullOneFrame(nsPresContext* aPresContext,
if (irs.mLineLayout) {
irs.mLineLayout->SetDirtyNextLine();
}
nsHTMLContainerFrame::ReparentFrameView(aPresContext, frame, nextInFlow, this);
nsContainerFrame::ReparentFrameView(aPresContext, frame, nextInFlow, this);
break;
}
nextInFlow = (nsInlineFrame*) nextInFlow->GetNextInFlow();

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

@ -178,7 +178,7 @@ nsSubDocumentFrame::Init(nsIContent* aContent,
// really need it or not, and the inner view will get it as the
// parent.
if (!HasView()) {
rv = nsHTMLContainerFrame::CreateViewForFrame(this, PR_TRUE);
rv = nsContainerFrame::CreateViewForFrame(this, PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
}

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

@ -114,7 +114,7 @@ static void
CreateViewsForFrames(const nsFrameList& aFrames)
{
for (nsFrameList::Enumerator f(aFrames); !f.AtEnd(); f.Next()) {
nsHTMLContainerFrame::CreateViewForFrame(f.get(), PR_TRUE);
nsContainerFrame::CreateViewForFrame(f.get(), PR_TRUE);
}
}