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;
}