зеркало из https://github.com/mozilla/gecko-dev.git
Fix for bug #2062. When sizing the view, take into account child frames
that stick outside the right/bottom edges of the parent's frame
This commit is contained in:
Родитель
386c052ce9
Коммит
d0002c6559
|
@ -212,7 +212,25 @@ nsAreaFrame::Paint(nsIPresContext& aPresContext,
|
|||
NS_IMETHODIMP
|
||||
nsAreaFrame::GetPositionedInfo(nscoord& aXMost, nscoord& aYMost) const
|
||||
{
|
||||
return mAbsoluteContainer.GetPositionedInfo(aXMost, aYMost);
|
||||
nsresult rv = mAbsoluteContainer.GetPositionedInfo(aXMost, aYMost);
|
||||
|
||||
// If we have child frames that stick outside of our box, and they should
|
||||
// be visible, then include them too so the total size is correct
|
||||
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
|
||||
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
||||
mStyleContext->GetStyleData(eStyleStruct_Display);
|
||||
|
||||
if (NS_STYLE_OVERFLOW_VISIBLE == display->mOverflow) {
|
||||
if (mCombinedArea.XMost() > aXMost) {
|
||||
aXMost = mCombinedArea.XMost();
|
||||
}
|
||||
if (mCombinedArea.YMost() > aYMost) {
|
||||
aYMost = mCombinedArea.YMost();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -251,7 +269,7 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
// If we have one then set the space manager
|
||||
// If we have a space manager, then set it in the reflow state
|
||||
if (nsnull != mSpaceManager) {
|
||||
// Modify the reflow state and set the space manager
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
|
@ -270,9 +288,9 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext,
|
|||
rv = mAbsoluteContainer.Reflow(aPresContext, aReflowState);
|
||||
}
|
||||
|
||||
// Compute our desired size taking into account floaters that stick outside
|
||||
// our box. Note that if this frame has a height specified by CSS then we
|
||||
// don't do this
|
||||
// Compute our desired size taking into account floaters and child frames
|
||||
// that stick outside our box. Note that if this frame has a height specified
|
||||
// by CSS then we don't do this
|
||||
if ((mFlags & NS_AREA_WRAP_HEIGHT) &&
|
||||
(NS_UNCONSTRAINEDSIZE == aReflowState.computedHeight) &&
|
||||
(NS_FRAME_OUTSIDE_CHILDREN & mState)) {
|
||||
|
@ -285,6 +303,12 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
// If we have children that stick outside our box, then remember the
|
||||
// combined area, because we'll need it later when sizing our view
|
||||
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
|
||||
mCombinedArea = aDesiredSize.mCombinedArea;
|
||||
}
|
||||
|
||||
// XXX This code is really temporary; the lower level frame
|
||||
// classes need to contribute to the area that needs damage
|
||||
// repair. This class should only worry about damage repairing
|
||||
|
@ -349,6 +373,57 @@ nsAreaFrame::GetFrameType(nsIAtom** aType) const
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAreaFrame::DidReflow(nsIPresContext& aPresContext,
|
||||
nsDidReflowStatus aStatus)
|
||||
{
|
||||
if (NS_FRAME_REFLOW_FINISHED == aStatus) {
|
||||
// If we should position our view, and we have child frames that stick
|
||||
// outside our box, then we need to size our view large enough to include
|
||||
// those child frames
|
||||
if ((mState & NS_FRAME_SYNC_FRAME_AND_VIEW) &&
|
||||
(mState & NS_FRAME_OUTSIDE_CHILDREN)) {
|
||||
|
||||
nsIView* view;
|
||||
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
||||
mStyleContext->GetStyleData(eStyleStruct_Display);
|
||||
|
||||
GetView(&view);
|
||||
if (view && (NS_STYLE_OVERFLOW_VISIBLE == display->mOverflow)) {
|
||||
// Don't let our base class position the view since we're doing it
|
||||
mState &= ~NS_FRAME_SYNC_FRAME_AND_VIEW;
|
||||
|
||||
// Set the view's bit that indicates that it has transparent content
|
||||
nsIViewManager* vm;
|
||||
|
||||
view->GetViewManager(vm);
|
||||
vm->SetViewContentTransparency(view, PR_TRUE);
|
||||
|
||||
// Position and size view relative to its parent, not relative to our
|
||||
// parent frame (our parent frame may not have a view).
|
||||
nsIView* parentWithView;
|
||||
nsPoint origin;
|
||||
|
||||
// XXX We need to handle the case where child frames stick out on the
|
||||
// left and top edges as well...
|
||||
GetOffsetFromView(origin, &parentWithView);
|
||||
vm->ResizeView(view, mCombinedArea.XMost(), mCombinedArea.YMost());
|
||||
vm->MoveViewTo(view, origin.x, origin.y);
|
||||
NS_RELEASE(vm);
|
||||
|
||||
// Call our base class
|
||||
nsresult rv = nsBlockFrame::DidReflow(aPresContext, aStatus);
|
||||
|
||||
// Set the flag again...
|
||||
mState |= NS_FRAME_SYNC_FRAME_AND_VIEW;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsBlockFrame::DidReflow(aPresContext, aStatus);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Diagnostics
|
||||
|
||||
|
|
|
@ -72,6 +72,9 @@ public:
|
|||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD DidReflow(nsIPresContext& aPresContext,
|
||||
nsDidReflowStatus aStatus);
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
NS_IMETHOD Paint(nsIPresContext& aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
|
@ -98,6 +101,7 @@ protected:
|
|||
private:
|
||||
nsSpaceManager* mSpaceManager;
|
||||
nsAbsoluteContainingBlock mAbsoluteContainer;
|
||||
nsRect mCombinedArea;
|
||||
};
|
||||
|
||||
#endif /* nsAreaFrame_h___ */
|
||||
|
|
|
@ -212,7 +212,25 @@ nsAreaFrame::Paint(nsIPresContext& aPresContext,
|
|||
NS_IMETHODIMP
|
||||
nsAreaFrame::GetPositionedInfo(nscoord& aXMost, nscoord& aYMost) const
|
||||
{
|
||||
return mAbsoluteContainer.GetPositionedInfo(aXMost, aYMost);
|
||||
nsresult rv = mAbsoluteContainer.GetPositionedInfo(aXMost, aYMost);
|
||||
|
||||
// If we have child frames that stick outside of our box, and they should
|
||||
// be visible, then include them too so the total size is correct
|
||||
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
|
||||
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
||||
mStyleContext->GetStyleData(eStyleStruct_Display);
|
||||
|
||||
if (NS_STYLE_OVERFLOW_VISIBLE == display->mOverflow) {
|
||||
if (mCombinedArea.XMost() > aXMost) {
|
||||
aXMost = mCombinedArea.XMost();
|
||||
}
|
||||
if (mCombinedArea.YMost() > aYMost) {
|
||||
aYMost = mCombinedArea.YMost();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -251,7 +269,7 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
// If we have one then set the space manager
|
||||
// If we have a space manager, then set it in the reflow state
|
||||
if (nsnull != mSpaceManager) {
|
||||
// Modify the reflow state and set the space manager
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
|
@ -270,9 +288,9 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext,
|
|||
rv = mAbsoluteContainer.Reflow(aPresContext, aReflowState);
|
||||
}
|
||||
|
||||
// Compute our desired size taking into account floaters that stick outside
|
||||
// our box. Note that if this frame has a height specified by CSS then we
|
||||
// don't do this
|
||||
// Compute our desired size taking into account floaters and child frames
|
||||
// that stick outside our box. Note that if this frame has a height specified
|
||||
// by CSS then we don't do this
|
||||
if ((mFlags & NS_AREA_WRAP_HEIGHT) &&
|
||||
(NS_UNCONSTRAINEDSIZE == aReflowState.computedHeight) &&
|
||||
(NS_FRAME_OUTSIDE_CHILDREN & mState)) {
|
||||
|
@ -285,6 +303,12 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
// If we have children that stick outside our box, then remember the
|
||||
// combined area, because we'll need it later when sizing our view
|
||||
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
|
||||
mCombinedArea = aDesiredSize.mCombinedArea;
|
||||
}
|
||||
|
||||
// XXX This code is really temporary; the lower level frame
|
||||
// classes need to contribute to the area that needs damage
|
||||
// repair. This class should only worry about damage repairing
|
||||
|
@ -349,6 +373,57 @@ nsAreaFrame::GetFrameType(nsIAtom** aType) const
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAreaFrame::DidReflow(nsIPresContext& aPresContext,
|
||||
nsDidReflowStatus aStatus)
|
||||
{
|
||||
if (NS_FRAME_REFLOW_FINISHED == aStatus) {
|
||||
// If we should position our view, and we have child frames that stick
|
||||
// outside our box, then we need to size our view large enough to include
|
||||
// those child frames
|
||||
if ((mState & NS_FRAME_SYNC_FRAME_AND_VIEW) &&
|
||||
(mState & NS_FRAME_OUTSIDE_CHILDREN)) {
|
||||
|
||||
nsIView* view;
|
||||
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
||||
mStyleContext->GetStyleData(eStyleStruct_Display);
|
||||
|
||||
GetView(&view);
|
||||
if (view && (NS_STYLE_OVERFLOW_VISIBLE == display->mOverflow)) {
|
||||
// Don't let our base class position the view since we're doing it
|
||||
mState &= ~NS_FRAME_SYNC_FRAME_AND_VIEW;
|
||||
|
||||
// Set the view's bit that indicates that it has transparent content
|
||||
nsIViewManager* vm;
|
||||
|
||||
view->GetViewManager(vm);
|
||||
vm->SetViewContentTransparency(view, PR_TRUE);
|
||||
|
||||
// Position and size view relative to its parent, not relative to our
|
||||
// parent frame (our parent frame may not have a view).
|
||||
nsIView* parentWithView;
|
||||
nsPoint origin;
|
||||
|
||||
// XXX We need to handle the case where child frames stick out on the
|
||||
// left and top edges as well...
|
||||
GetOffsetFromView(origin, &parentWithView);
|
||||
vm->ResizeView(view, mCombinedArea.XMost(), mCombinedArea.YMost());
|
||||
vm->MoveViewTo(view, origin.x, origin.y);
|
||||
NS_RELEASE(vm);
|
||||
|
||||
// Call our base class
|
||||
nsresult rv = nsBlockFrame::DidReflow(aPresContext, aStatus);
|
||||
|
||||
// Set the flag again...
|
||||
mState |= NS_FRAME_SYNC_FRAME_AND_VIEW;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsBlockFrame::DidReflow(aPresContext, aStatus);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Diagnostics
|
||||
|
||||
|
|
|
@ -72,6 +72,9 @@ public:
|
|||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD DidReflow(nsIPresContext& aPresContext,
|
||||
nsDidReflowStatus aStatus);
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
NS_IMETHOD Paint(nsIPresContext& aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
|
@ -98,6 +101,7 @@ protected:
|
|||
private:
|
||||
nsSpaceManager* mSpaceManager;
|
||||
nsAbsoluteContainingBlock mAbsoluteContainer;
|
||||
nsRect mCombinedArea;
|
||||
};
|
||||
|
||||
#endif /* nsAreaFrame_h___ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче