Treat relatively positioned elements at original position for flowing around floats. b=205087 r+sr=bzbarsky
git-svn-id: svn://10.0.0.236/trunk@151166 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -131,6 +131,7 @@ LAYOUT_ATOM(viewportFrame, "ViewportFrame")
|
||||
// Alphabetical list of frame property names
|
||||
LAYOUT_ATOM(changeListProperty, "ChangeListProperty") // void*
|
||||
LAYOUT_ATOM(collapseOffsetProperty, "CollapseOffsetProperty") // nsPoint*
|
||||
LAYOUT_ATOM(computedOffsetProperty, "ComputedOffsetProperty") // nsPoint*
|
||||
LAYOUT_ATOM(IBSplitSpecialPrevSibling, "IBSplitSpecialPrevSibling")// nsIFrame*
|
||||
LAYOUT_ATOM(IBSplitSpecialSibling, "IBSplitSpecialSibling") // nsIFrame*
|
||||
LAYOUT_ATOM(maxElementWidthProperty, "MaxElementWidthProperty") // nscoord*
|
||||
|
||||
@@ -131,6 +131,7 @@ LAYOUT_ATOM(viewportFrame, "ViewportFrame")
|
||||
// Alphabetical list of frame property names
|
||||
LAYOUT_ATOM(changeListProperty, "ChangeListProperty") // void*
|
||||
LAYOUT_ATOM(collapseOffsetProperty, "CollapseOffsetProperty") // nsPoint*
|
||||
LAYOUT_ATOM(computedOffsetProperty, "ComputedOffsetProperty") // nsPoint*
|
||||
LAYOUT_ATOM(IBSplitSpecialPrevSibling, "IBSplitSpecialPrevSibling")// nsIFrame*
|
||||
LAYOUT_ATOM(IBSplitSpecialSibling, "IBSplitSpecialSibling") // nsIFrame*
|
||||
LAYOUT_ATOM(maxElementWidthProperty, "MaxElementWidthProperty") // nscoord*
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "nsSpaceManager.h"
|
||||
#include "nsIFontMetrics.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIFrameManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsStyleContext.h"
|
||||
#include "nsHTMLReflowCommand.h"
|
||||
@@ -291,6 +292,14 @@ ComputeShrinkwrapMargins(const nsStyleMargin* aStyleMargin, nscoord aWidth, nsMa
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nsPointDtor(nsIPresContext *aPresContext, nsIFrame *aFrame,
|
||||
nsIAtom *aPropertyName, void *aPropertyValue)
|
||||
{
|
||||
nsPoint *point = NS_STATIC_CAST(nsPoint*, aPropertyValue);
|
||||
delete point;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
|
||||
PRBool aApplyTopMargin,
|
||||
@@ -373,6 +382,23 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
|
||||
}
|
||||
|
||||
aComputedOffsets = aFrameRS.mComputedOffsets;
|
||||
if (NS_STYLE_POSITION_RELATIVE == display->mPosition) {
|
||||
nsIFrameManager *frameManager = mPresContext->GetFrameManager();
|
||||
nsPoint *offsets;
|
||||
frameManager->GetFrameProperty(mFrame,
|
||||
nsLayoutAtoms::computedOffsetProperty, 0,
|
||||
(void**)&offsets);
|
||||
if (offsets)
|
||||
offsets->MoveTo(aComputedOffsets.left, aComputedOffsets.top);
|
||||
else {
|
||||
offsets = new nsPoint(aComputedOffsets.left, aComputedOffsets.top);
|
||||
if (offsets)
|
||||
frameManager->SetFrameProperty(mFrame,
|
||||
nsLayoutAtoms::computedOffsetProperty,
|
||||
offsets, nsPointDtor);
|
||||
}
|
||||
}
|
||||
|
||||
aFrameRS.mLineLayout = nsnull;
|
||||
if (!aIsAdjacentWithTop) {
|
||||
aFrameRS.mFlags.mIsTopOfPage = PR_FALSE; // make sure this is cleared
|
||||
@@ -452,6 +478,16 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the translation to be used for adjusting the spacemanagager
|
||||
// coordinate system for the frame. The spacemanager coordinates are
|
||||
// <b>inside</b> the callers border+padding, but the x/y coordinates
|
||||
// are not (recall that frame coordinates are relative to the parents
|
||||
// origin and that the parents border/padding is <b>inside</b> the
|
||||
// parent frame. Therefore we have to subtract out the parents
|
||||
// border+padding before translating.
|
||||
nscoord tx = x - mOuterReflowState.mComputedBorderPadding.left;
|
||||
nscoord ty = y - mOuterReflowState.mComputedBorderPadding.top;
|
||||
|
||||
// If the element is relatively positioned, then adjust x and y accordingly
|
||||
if (NS_STYLE_POSITION_RELATIVE == aFrameRS.mStyleDisplay->mPosition) {
|
||||
x += aFrameRS.mComputedOffsets.left;
|
||||
@@ -477,15 +513,6 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
|
||||
}
|
||||
#endif
|
||||
|
||||
// Adjust spacemanager coordinate system for the frame. The
|
||||
// spacemanager coordinates are <b>inside</b> the callers
|
||||
// border+padding, but the x/y coordinates are not (recall that
|
||||
// frame coordinates are relative to the parents origin and that the
|
||||
// parents border/padding is <b>inside</b> the parent
|
||||
// frame. Therefore we have to subtract out the parents
|
||||
// border+padding before translating.
|
||||
nscoord tx = x - mOuterReflowState.mComputedBorderPadding.left;
|
||||
nscoord ty = y - mOuterReflowState.mComputedBorderPadding.top;
|
||||
mOuterReflowState.mSpaceManager->Translate(tx, ty);
|
||||
|
||||
// See if this is the child's initial reflow and we are supposed to
|
||||
|
||||
@@ -484,9 +484,25 @@ nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine,
|
||||
} else if (aLine->IsBlock()) {
|
||||
nsBlockFrame *kid = nsnull;
|
||||
aLine->mFirstChild->QueryInterface(kBlockFrameCID, (void**)&kid);
|
||||
if (kid) {
|
||||
nscoord kidx = kid->mRect.x, kidy = kid->mRect.y;
|
||||
mSpaceManager->Translate(kidx, kidy);
|
||||
// don't recover any state inside a block that has its own space
|
||||
// manager (we don't currently have any blocks like this, though,
|
||||
// thanks to our use of extra frames for 'overflow')
|
||||
if (kid && !(kid->GetStateBits() & NS_BLOCK_SPACE_MGR)) {
|
||||
nscoord tx = kid->mRect.x, ty = kid->mRect.y;
|
||||
|
||||
// If the element is relatively positioned, then adjust x and y
|
||||
// accordingly so that we consider relatively positioned frames
|
||||
// at their original position.
|
||||
if (NS_STYLE_POSITION_RELATIVE == kid->GetStyleDisplay()->mPosition) {
|
||||
nsPoint *offsets;
|
||||
if (NS_OK == mPresContext->GetFrameManager()->GetFrameProperty(kid,
|
||||
nsLayoutAtoms::computedOffsetProperty, 0, (void**)&offsets)) {
|
||||
tx -= offsets->x;
|
||||
ty -= offsets->y;
|
||||
}
|
||||
}
|
||||
|
||||
mSpaceManager->Translate(tx, ty);
|
||||
for (nsBlockFrame::line_iterator line = kid->begin_lines(),
|
||||
line_end = kid->end_lines();
|
||||
line != line_end;
|
||||
@@ -495,7 +511,7 @@ nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine,
|
||||
// moving relative to their parent block, only relative to
|
||||
// the space manager.
|
||||
RecoverFloats(line, 0);
|
||||
mSpaceManager->Translate(-kidx, -kidy);
|
||||
mSpaceManager->Translate(-tx, -ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -966,8 +982,6 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache,
|
||||
else {
|
||||
isLeftFloat = PR_FALSE;
|
||||
if (NS_UNCONSTRAINEDSIZE != mAvailSpaceRect.width) {
|
||||
nsIFrame* prevInFlow;
|
||||
floatFrame->GetPrevInFlow(&prevInFlow);
|
||||
if (prevInFlow) {
|
||||
region.x = prevRect.x;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "nsSpaceManager.h"
|
||||
#include "nsIFontMetrics.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIFrameManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsStyleContext.h"
|
||||
#include "nsHTMLReflowCommand.h"
|
||||
@@ -291,6 +292,14 @@ ComputeShrinkwrapMargins(const nsStyleMargin* aStyleMargin, nscoord aWidth, nsMa
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nsPointDtor(nsIPresContext *aPresContext, nsIFrame *aFrame,
|
||||
nsIAtom *aPropertyName, void *aPropertyValue)
|
||||
{
|
||||
nsPoint *point = NS_STATIC_CAST(nsPoint*, aPropertyValue);
|
||||
delete point;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
|
||||
PRBool aApplyTopMargin,
|
||||
@@ -373,6 +382,23 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
|
||||
}
|
||||
|
||||
aComputedOffsets = aFrameRS.mComputedOffsets;
|
||||
if (NS_STYLE_POSITION_RELATIVE == display->mPosition) {
|
||||
nsIFrameManager *frameManager = mPresContext->GetFrameManager();
|
||||
nsPoint *offsets;
|
||||
frameManager->GetFrameProperty(mFrame,
|
||||
nsLayoutAtoms::computedOffsetProperty, 0,
|
||||
(void**)&offsets);
|
||||
if (offsets)
|
||||
offsets->MoveTo(aComputedOffsets.left, aComputedOffsets.top);
|
||||
else {
|
||||
offsets = new nsPoint(aComputedOffsets.left, aComputedOffsets.top);
|
||||
if (offsets)
|
||||
frameManager->SetFrameProperty(mFrame,
|
||||
nsLayoutAtoms::computedOffsetProperty,
|
||||
offsets, nsPointDtor);
|
||||
}
|
||||
}
|
||||
|
||||
aFrameRS.mLineLayout = nsnull;
|
||||
if (!aIsAdjacentWithTop) {
|
||||
aFrameRS.mFlags.mIsTopOfPage = PR_FALSE; // make sure this is cleared
|
||||
@@ -452,6 +478,16 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the translation to be used for adjusting the spacemanagager
|
||||
// coordinate system for the frame. The spacemanager coordinates are
|
||||
// <b>inside</b> the callers border+padding, but the x/y coordinates
|
||||
// are not (recall that frame coordinates are relative to the parents
|
||||
// origin and that the parents border/padding is <b>inside</b> the
|
||||
// parent frame. Therefore we have to subtract out the parents
|
||||
// border+padding before translating.
|
||||
nscoord tx = x - mOuterReflowState.mComputedBorderPadding.left;
|
||||
nscoord ty = y - mOuterReflowState.mComputedBorderPadding.top;
|
||||
|
||||
// If the element is relatively positioned, then adjust x and y accordingly
|
||||
if (NS_STYLE_POSITION_RELATIVE == aFrameRS.mStyleDisplay->mPosition) {
|
||||
x += aFrameRS.mComputedOffsets.left;
|
||||
@@ -477,15 +513,6 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
|
||||
}
|
||||
#endif
|
||||
|
||||
// Adjust spacemanager coordinate system for the frame. The
|
||||
// spacemanager coordinates are <b>inside</b> the callers
|
||||
// border+padding, but the x/y coordinates are not (recall that
|
||||
// frame coordinates are relative to the parents origin and that the
|
||||
// parents border/padding is <b>inside</b> the parent
|
||||
// frame. Therefore we have to subtract out the parents
|
||||
// border+padding before translating.
|
||||
nscoord tx = x - mOuterReflowState.mComputedBorderPadding.left;
|
||||
nscoord ty = y - mOuterReflowState.mComputedBorderPadding.top;
|
||||
mOuterReflowState.mSpaceManager->Translate(tx, ty);
|
||||
|
||||
// See if this is the child's initial reflow and we are supposed to
|
||||
|
||||
@@ -484,9 +484,25 @@ nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine,
|
||||
} else if (aLine->IsBlock()) {
|
||||
nsBlockFrame *kid = nsnull;
|
||||
aLine->mFirstChild->QueryInterface(kBlockFrameCID, (void**)&kid);
|
||||
if (kid) {
|
||||
nscoord kidx = kid->mRect.x, kidy = kid->mRect.y;
|
||||
mSpaceManager->Translate(kidx, kidy);
|
||||
// don't recover any state inside a block that has its own space
|
||||
// manager (we don't currently have any blocks like this, though,
|
||||
// thanks to our use of extra frames for 'overflow')
|
||||
if (kid && !(kid->GetStateBits() & NS_BLOCK_SPACE_MGR)) {
|
||||
nscoord tx = kid->mRect.x, ty = kid->mRect.y;
|
||||
|
||||
// If the element is relatively positioned, then adjust x and y
|
||||
// accordingly so that we consider relatively positioned frames
|
||||
// at their original position.
|
||||
if (NS_STYLE_POSITION_RELATIVE == kid->GetStyleDisplay()->mPosition) {
|
||||
nsPoint *offsets;
|
||||
if (NS_OK == mPresContext->GetFrameManager()->GetFrameProperty(kid,
|
||||
nsLayoutAtoms::computedOffsetProperty, 0, (void**)&offsets)) {
|
||||
tx -= offsets->x;
|
||||
ty -= offsets->y;
|
||||
}
|
||||
}
|
||||
|
||||
mSpaceManager->Translate(tx, ty);
|
||||
for (nsBlockFrame::line_iterator line = kid->begin_lines(),
|
||||
line_end = kid->end_lines();
|
||||
line != line_end;
|
||||
@@ -495,7 +511,7 @@ nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine,
|
||||
// moving relative to their parent block, only relative to
|
||||
// the space manager.
|
||||
RecoverFloats(line, 0);
|
||||
mSpaceManager->Translate(-kidx, -kidy);
|
||||
mSpaceManager->Translate(-tx, -ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -966,8 +982,6 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache,
|
||||
else {
|
||||
isLeftFloat = PR_FALSE;
|
||||
if (NS_UNCONSTRAINEDSIZE != mAvailSpaceRect.width) {
|
||||
nsIFrame* prevInFlow;
|
||||
floatFrame->GetPrevInFlow(&prevInFlow);
|
||||
if (prevInFlow) {
|
||||
region.x = prevRect.x;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user