diff --git a/mozilla/content/shared/public/nsLayoutAtomList.h b/mozilla/content/shared/public/nsLayoutAtomList.h index db808a06284..0354d390e85 100644 --- a/mozilla/content/shared/public/nsLayoutAtomList.h +++ b/mozilla/content/shared/public/nsLayoutAtomList.h @@ -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* diff --git a/mozilla/layout/base/nsLayoutAtomList.h b/mozilla/layout/base/nsLayoutAtomList.h index db808a06284..0354d390e85 100644 --- a/mozilla/layout/base/nsLayoutAtomList.h +++ b/mozilla/layout/base/nsLayoutAtomList.h @@ -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* diff --git a/mozilla/layout/generic/nsBlockReflowContext.cpp b/mozilla/layout/generic/nsBlockReflowContext.cpp index 288295dc6f0..daa6b3e5fe1 100644 --- a/mozilla/layout/generic/nsBlockReflowContext.cpp +++ b/mozilla/layout/generic/nsBlockReflowContext.cpp @@ -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 + // inside 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 inside 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 inside 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 inside 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 diff --git a/mozilla/layout/generic/nsBlockReflowState.cpp b/mozilla/layout/generic/nsBlockReflowState.cpp index ffcac711552..c74ad0a61de 100644 --- a/mozilla/layout/generic/nsBlockReflowState.cpp +++ b/mozilla/layout/generic/nsBlockReflowState.cpp @@ -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; } diff --git a/mozilla/layout/html/base/src/nsBlockReflowContext.cpp b/mozilla/layout/html/base/src/nsBlockReflowContext.cpp index 288295dc6f0..daa6b3e5fe1 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowContext.cpp +++ b/mozilla/layout/html/base/src/nsBlockReflowContext.cpp @@ -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 + // inside 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 inside 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 inside 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 inside 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 diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.cpp b/mozilla/layout/html/base/src/nsBlockReflowState.cpp index ffcac711552..c74ad0a61de 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.cpp +++ b/mozilla/layout/html/base/src/nsBlockReflowState.cpp @@ -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; }