Added ReparentFrameView() and changed the block and inline code
to call it when pushing/pulling frames
This commit is contained in:
Родитель
5deed64036
Коммит
4fda80d9f5
|
@ -1839,6 +1839,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
PRInt32 n = line->ChildCount();
|
||||
while (--n >= 0) {
|
||||
frame->SetParent(this);
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
nsHTMLContainerFrame::ReparentFrameView(frame, mNextInFlow, this);
|
||||
lastFrame = frame;
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
@ -2070,8 +2073,16 @@ nsBlockFrame::PullFrame(nsBlockReflowState& aState,
|
|||
|
||||
// Change geometric parents
|
||||
if (aUpdateGeometricParent) {
|
||||
// Before we set the new parent frame get the current parent
|
||||
nsIFrame* oldParentFrame;
|
||||
frame->GetParent(&oldParentFrame);
|
||||
frame->SetParent(this);
|
||||
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
NS_ASSERTION(oldParentFrame != this, "unexpected parent frame");
|
||||
nsHTMLContainerFrame::ReparentFrameView(frame, oldParentFrame, this);
|
||||
|
||||
// The frame is being pulled from a next-in-flow; therefore we
|
||||
// need to add it to our sibling list.
|
||||
if (nsnull != aState.mPrevChild) {
|
||||
|
@ -3451,6 +3462,12 @@ nsBlockFrame::DrainOverflowLines()
|
|||
nsIFrame* frame = line->mFirstChild;
|
||||
while (nsnull != frame) {
|
||||
frame->SetParent(this);
|
||||
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
nsHTMLContainerFrame::ReparentFrameView(frame, prevBlock, this);
|
||||
|
||||
// Get the next frame
|
||||
lastFrame = frame;
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
|
|
@ -1839,6 +1839,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
PRInt32 n = line->ChildCount();
|
||||
while (--n >= 0) {
|
||||
frame->SetParent(this);
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
nsHTMLContainerFrame::ReparentFrameView(frame, mNextInFlow, this);
|
||||
lastFrame = frame;
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
@ -2070,8 +2073,16 @@ nsBlockFrame::PullFrame(nsBlockReflowState& aState,
|
|||
|
||||
// Change geometric parents
|
||||
if (aUpdateGeometricParent) {
|
||||
// Before we set the new parent frame get the current parent
|
||||
nsIFrame* oldParentFrame;
|
||||
frame->GetParent(&oldParentFrame);
|
||||
frame->SetParent(this);
|
||||
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
NS_ASSERTION(oldParentFrame != this, "unexpected parent frame");
|
||||
nsHTMLContainerFrame::ReparentFrameView(frame, oldParentFrame, this);
|
||||
|
||||
// The frame is being pulled from a next-in-flow; therefore we
|
||||
// need to add it to our sibling list.
|
||||
if (nsnull != aState.mPrevChild) {
|
||||
|
@ -3451,6 +3462,12 @@ nsBlockFrame::DrainOverflowLines()
|
|||
nsIFrame* frame = line->mFirstChild;
|
||||
while (nsnull != frame) {
|
||||
frame->SetParent(this);
|
||||
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
nsHTMLContainerFrame::ReparentFrameView(frame, prevBlock, this);
|
||||
|
||||
// Get the next frame
|
||||
lastFrame = frame;
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
|
|
@ -1839,6 +1839,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
PRInt32 n = line->ChildCount();
|
||||
while (--n >= 0) {
|
||||
frame->SetParent(this);
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
nsHTMLContainerFrame::ReparentFrameView(frame, mNextInFlow, this);
|
||||
lastFrame = frame;
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
@ -2070,8 +2073,16 @@ nsBlockFrame::PullFrame(nsBlockReflowState& aState,
|
|||
|
||||
// Change geometric parents
|
||||
if (aUpdateGeometricParent) {
|
||||
// Before we set the new parent frame get the current parent
|
||||
nsIFrame* oldParentFrame;
|
||||
frame->GetParent(&oldParentFrame);
|
||||
frame->SetParent(this);
|
||||
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
NS_ASSERTION(oldParentFrame != this, "unexpected parent frame");
|
||||
nsHTMLContainerFrame::ReparentFrameView(frame, oldParentFrame, this);
|
||||
|
||||
// The frame is being pulled from a next-in-flow; therefore we
|
||||
// need to add it to our sibling list.
|
||||
if (nsnull != aState.mPrevChild) {
|
||||
|
@ -3451,6 +3462,12 @@ nsBlockFrame::DrainOverflowLines()
|
|||
nsIFrame* frame = line->mFirstChild;
|
||||
while (nsnull != frame) {
|
||||
frame->SetParent(this);
|
||||
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
nsHTMLContainerFrame::ReparentFrameView(frame, prevBlock, this);
|
||||
|
||||
// Get the next frame
|
||||
lastFrame = frame;
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
|
|
@ -123,6 +123,91 @@ nsHTMLContainerFrame::CreateNextInFlow(nsIPresContext& aPresContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
ReparentFrameViewTo(nsIFrame* aFrame,
|
||||
nsIView* aNewParentView,
|
||||
nsIView* aOldParentView)
|
||||
{
|
||||
nsIView* view;
|
||||
|
||||
// Does aFrame have a view?
|
||||
aFrame->GetView(&view);
|
||||
if (view) {
|
||||
nsIViewManager* viewManager;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
// Verify that the current parent view is what we think it is
|
||||
nsIView* parentView;
|
||||
|
||||
view->GetParent(parentView);
|
||||
NS_ASSERTION(parentView == aOldParentView, "unexpected parent view");
|
||||
#endif
|
||||
|
||||
// Get the view manager
|
||||
aNewParentView->GetViewManager(viewManager);
|
||||
NS_ASSERTION(nsnull != viewManager, "null view manager");
|
||||
|
||||
// Change the parent view.
|
||||
PRInt32 zIndex;
|
||||
view->GetZIndex(zIndex);
|
||||
viewManager->RemoveChild(aOldParentView, view);
|
||||
|
||||
// XXX We need to insert this view in the correct place within its z-order...
|
||||
viewManager->InsertChild(aNewParentView, view, zIndex);
|
||||
NS_RELEASE(viewManager);
|
||||
|
||||
} else {
|
||||
// Iterate the child frames, and check each child frame to see if it has
|
||||
// a view
|
||||
nsIFrame* childFrame;
|
||||
|
||||
aFrame->FirstChild(nsnull, &childFrame);
|
||||
while (childFrame) {
|
||||
ReparentFrameViewTo(childFrame, aNewParentView, aOldParentView);
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsIView*
|
||||
GetViewFor(nsIFrame* aFrame)
|
||||
{
|
||||
nsIView* view;
|
||||
|
||||
aFrame->GetView(&view);
|
||||
if (!view) {
|
||||
nsPoint offset;
|
||||
aFrame->GetOffsetFromView(offset, &view);
|
||||
}
|
||||
|
||||
NS_POSTCONDITION(view, "no containing view");
|
||||
return view;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLContainerFrame::ReparentFrameView(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");
|
||||
|
||||
// First see if the old parent frame and the new parent frame are in the
|
||||
// same view sub-hierarchy
|
||||
nsIView* oldParentView = GetViewFor(aOldParentFrame);
|
||||
nsIView* newParentView = GetViewFor(aNewParentFrame);
|
||||
|
||||
if (oldParentView != newParentView) {
|
||||
return ReparentFrameViewTo(aChildFrame, newParentView, oldParentView);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext& aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
|
|
|
@ -62,6 +62,10 @@ public:
|
|||
nsIStyleContext* aStyleContext,
|
||||
PRBool aForce);
|
||||
|
||||
static nsresult ReparentFrameView(nsIFrame* aChildFrame,
|
||||
nsIFrame* aOldParentFrame,
|
||||
nsIFrame* aNewParentFrame);
|
||||
|
||||
protected:
|
||||
virtual PRIntn GetSkipSides() const = 0;
|
||||
};
|
||||
|
|
|
@ -1284,6 +1284,14 @@ nsInlineFrame::DrainOverflow()
|
|||
nsInlineFrame* prevInFlow = (nsInlineFrame*)mPrevInFlow;
|
||||
if (nsnull != prevInFlow) {
|
||||
if (prevInFlow->mOverflowFrames.NotEmpty()) {
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented.
|
||||
// XXX Doing it this way means an extra pass over the frames. We could
|
||||
// change InsertFrames() to do this, but that's a general purpose
|
||||
// function and it doesn't seem like this functionality belongs there...
|
||||
for (nsIFrame* f = prevInFlow->mOverflowFrames.FirstChild(); f; f->GetNextSibling(&f)) {
|
||||
nsHTMLContainerFrame::ReparentFrameView(f, prevInFlow, this);
|
||||
}
|
||||
mFrames.InsertFrames(this, nsnull, prevInFlow->mOverflowFrames);
|
||||
changedFirstFrame = PR_TRUE;
|
||||
}
|
||||
|
|
|
@ -1839,6 +1839,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
PRInt32 n = line->ChildCount();
|
||||
while (--n >= 0) {
|
||||
frame->SetParent(this);
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
nsHTMLContainerFrame::ReparentFrameView(frame, mNextInFlow, this);
|
||||
lastFrame = frame;
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
@ -2070,8 +2073,16 @@ nsBlockFrame::PullFrame(nsBlockReflowState& aState,
|
|||
|
||||
// Change geometric parents
|
||||
if (aUpdateGeometricParent) {
|
||||
// Before we set the new parent frame get the current parent
|
||||
nsIFrame* oldParentFrame;
|
||||
frame->GetParent(&oldParentFrame);
|
||||
frame->SetParent(this);
|
||||
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
NS_ASSERTION(oldParentFrame != this, "unexpected parent frame");
|
||||
nsHTMLContainerFrame::ReparentFrameView(frame, oldParentFrame, this);
|
||||
|
||||
// The frame is being pulled from a next-in-flow; therefore we
|
||||
// need to add it to our sibling list.
|
||||
if (nsnull != aState.mPrevChild) {
|
||||
|
@ -3451,6 +3462,12 @@ nsBlockFrame::DrainOverflowLines()
|
|||
nsIFrame* frame = line->mFirstChild;
|
||||
while (nsnull != frame) {
|
||||
frame->SetParent(this);
|
||||
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
nsHTMLContainerFrame::ReparentFrameView(frame, prevBlock, this);
|
||||
|
||||
// Get the next frame
|
||||
lastFrame = frame;
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
|
|
@ -1839,6 +1839,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
PRInt32 n = line->ChildCount();
|
||||
while (--n >= 0) {
|
||||
frame->SetParent(this);
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
nsHTMLContainerFrame::ReparentFrameView(frame, mNextInFlow, this);
|
||||
lastFrame = frame;
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
@ -2070,8 +2073,16 @@ nsBlockFrame::PullFrame(nsBlockReflowState& aState,
|
|||
|
||||
// Change geometric parents
|
||||
if (aUpdateGeometricParent) {
|
||||
// Before we set the new parent frame get the current parent
|
||||
nsIFrame* oldParentFrame;
|
||||
frame->GetParent(&oldParentFrame);
|
||||
frame->SetParent(this);
|
||||
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
NS_ASSERTION(oldParentFrame != this, "unexpected parent frame");
|
||||
nsHTMLContainerFrame::ReparentFrameView(frame, oldParentFrame, this);
|
||||
|
||||
// The frame is being pulled from a next-in-flow; therefore we
|
||||
// need to add it to our sibling list.
|
||||
if (nsnull != aState.mPrevChild) {
|
||||
|
@ -3451,6 +3462,12 @@ nsBlockFrame::DrainOverflowLines()
|
|||
nsIFrame* frame = line->mFirstChild;
|
||||
while (nsnull != frame) {
|
||||
frame->SetParent(this);
|
||||
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
nsHTMLContainerFrame::ReparentFrameView(frame, prevBlock, this);
|
||||
|
||||
// Get the next frame
|
||||
lastFrame = frame;
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
|
|
@ -1839,6 +1839,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
PRInt32 n = line->ChildCount();
|
||||
while (--n >= 0) {
|
||||
frame->SetParent(this);
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
nsHTMLContainerFrame::ReparentFrameView(frame, mNextInFlow, this);
|
||||
lastFrame = frame;
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
@ -2070,8 +2073,16 @@ nsBlockFrame::PullFrame(nsBlockReflowState& aState,
|
|||
|
||||
// Change geometric parents
|
||||
if (aUpdateGeometricParent) {
|
||||
// Before we set the new parent frame get the current parent
|
||||
nsIFrame* oldParentFrame;
|
||||
frame->GetParent(&oldParentFrame);
|
||||
frame->SetParent(this);
|
||||
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
NS_ASSERTION(oldParentFrame != this, "unexpected parent frame");
|
||||
nsHTMLContainerFrame::ReparentFrameView(frame, oldParentFrame, this);
|
||||
|
||||
// The frame is being pulled from a next-in-flow; therefore we
|
||||
// need to add it to our sibling list.
|
||||
if (nsnull != aState.mPrevChild) {
|
||||
|
@ -3451,6 +3462,12 @@ nsBlockFrame::DrainOverflowLines()
|
|||
nsIFrame* frame = line->mFirstChild;
|
||||
while (nsnull != frame) {
|
||||
frame->SetParent(this);
|
||||
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
nsHTMLContainerFrame::ReparentFrameView(frame, prevBlock, this);
|
||||
|
||||
// Get the next frame
|
||||
lastFrame = frame;
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
|
|
@ -123,6 +123,91 @@ nsHTMLContainerFrame::CreateNextInFlow(nsIPresContext& aPresContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
ReparentFrameViewTo(nsIFrame* aFrame,
|
||||
nsIView* aNewParentView,
|
||||
nsIView* aOldParentView)
|
||||
{
|
||||
nsIView* view;
|
||||
|
||||
// Does aFrame have a view?
|
||||
aFrame->GetView(&view);
|
||||
if (view) {
|
||||
nsIViewManager* viewManager;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
// Verify that the current parent view is what we think it is
|
||||
nsIView* parentView;
|
||||
|
||||
view->GetParent(parentView);
|
||||
NS_ASSERTION(parentView == aOldParentView, "unexpected parent view");
|
||||
#endif
|
||||
|
||||
// Get the view manager
|
||||
aNewParentView->GetViewManager(viewManager);
|
||||
NS_ASSERTION(nsnull != viewManager, "null view manager");
|
||||
|
||||
// Change the parent view.
|
||||
PRInt32 zIndex;
|
||||
view->GetZIndex(zIndex);
|
||||
viewManager->RemoveChild(aOldParentView, view);
|
||||
|
||||
// XXX We need to insert this view in the correct place within its z-order...
|
||||
viewManager->InsertChild(aNewParentView, view, zIndex);
|
||||
NS_RELEASE(viewManager);
|
||||
|
||||
} else {
|
||||
// Iterate the child frames, and check each child frame to see if it has
|
||||
// a view
|
||||
nsIFrame* childFrame;
|
||||
|
||||
aFrame->FirstChild(nsnull, &childFrame);
|
||||
while (childFrame) {
|
||||
ReparentFrameViewTo(childFrame, aNewParentView, aOldParentView);
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsIView*
|
||||
GetViewFor(nsIFrame* aFrame)
|
||||
{
|
||||
nsIView* view;
|
||||
|
||||
aFrame->GetView(&view);
|
||||
if (!view) {
|
||||
nsPoint offset;
|
||||
aFrame->GetOffsetFromView(offset, &view);
|
||||
}
|
||||
|
||||
NS_POSTCONDITION(view, "no containing view");
|
||||
return view;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLContainerFrame::ReparentFrameView(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");
|
||||
|
||||
// First see if the old parent frame and the new parent frame are in the
|
||||
// same view sub-hierarchy
|
||||
nsIView* oldParentView = GetViewFor(aOldParentFrame);
|
||||
nsIView* newParentView = GetViewFor(aNewParentFrame);
|
||||
|
||||
if (oldParentView != newParentView) {
|
||||
return ReparentFrameViewTo(aChildFrame, newParentView, oldParentView);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext& aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
|
|
|
@ -62,6 +62,10 @@ public:
|
|||
nsIStyleContext* aStyleContext,
|
||||
PRBool aForce);
|
||||
|
||||
static nsresult ReparentFrameView(nsIFrame* aChildFrame,
|
||||
nsIFrame* aOldParentFrame,
|
||||
nsIFrame* aNewParentFrame);
|
||||
|
||||
protected:
|
||||
virtual PRIntn GetSkipSides() const = 0;
|
||||
};
|
||||
|
|
|
@ -1284,6 +1284,14 @@ nsInlineFrame::DrainOverflow()
|
|||
nsInlineFrame* prevInFlow = (nsInlineFrame*)mPrevInFlow;
|
||||
if (nsnull != prevInFlow) {
|
||||
if (prevInFlow->mOverflowFrames.NotEmpty()) {
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented.
|
||||
// XXX Doing it this way means an extra pass over the frames. We could
|
||||
// change InsertFrames() to do this, but that's a general purpose
|
||||
// function and it doesn't seem like this functionality belongs there...
|
||||
for (nsIFrame* f = prevInFlow->mOverflowFrames.FirstChild(); f; f->GetNextSibling(&f)) {
|
||||
nsHTMLContainerFrame::ReparentFrameView(f, prevInFlow, this);
|
||||
}
|
||||
mFrames.InsertFrames(this, nsnull, prevInFlow->mOverflowFrames);
|
||||
changedFirstFrame = PR_TRUE;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче