Bug 893962 - Refactor the application of relative positioning. r=dbaron

This commit is contained in:
Corey Ford 2013-07-15 17:28:09 -07:00
parent dde89d90b7
commit a7574f8535
6 changed files with 33 additions and 27 deletions

View File

@ -333,8 +333,7 @@ nsBlockReflowContext::PlaceBlock(const nsHTMLReflowState& aReflowState,
aBottomMarginResult.Zero();
}
nscoord x = mX;
nscoord y = mY;
nsPoint position(mX, mY);
nscoord backupContainingBlockAdvance = 0;
// Check whether the block's bottom margin collapses with its top
@ -358,7 +357,7 @@ nsBlockReflowContext::PlaceBlock(const nsHTMLReflowState& aReflowState,
printf(": ");
nsFrame::ListTag(stdout, mFrame);
printf(" -- collapsing top & bottom margin together; y=%d spaceY=%d\n",
y, mSpace.y);
position.y, mSpace.y);
#endif
// Section 8.3.1 of CSS 2.1 says that blocks with adjoining
// top/bottom margins whose top margin collapses with their
@ -385,7 +384,7 @@ nsBlockReflowContext::PlaceBlock(const nsHTMLReflowState& aReflowState,
// even if there's some sort of integer overflow that makes y +
// mMetrics.height appear to go beyond the available height.
if (!empty && !aForceFit && mSpace.height != NS_UNCONSTRAINEDSIZE) {
nscoord yMost = y - backupContainingBlockAdvance + mMetrics.height;
nscoord yMost = position.y - backupContainingBlockAdvance + mMetrics.height;
if (yMost > mSpace.YMost()) {
// didn't fit, we must acquit.
mFrame->DidReflow(mPresContext, &aReflowState, nsDidReflowStatus::FINISHED);
@ -393,20 +392,16 @@ nsBlockReflowContext::PlaceBlock(const nsHTMLReflowState& aReflowState,
}
}
aInFlowBounds = nsRect(x, y - backupContainingBlockAdvance,
aInFlowBounds = nsRect(position.x, position.y - backupContainingBlockAdvance,
mMetrics.width, mMetrics.height);
// Apply CSS relative positioning
const nsStyleDisplay* styleDisp = mFrame->StyleDisplay();
if (NS_STYLE_POSITION_RELATIVE == styleDisp->mPosition) {
x += aReflowState.mComputedOffsets.left;
y += aReflowState.mComputedOffsets.top;
}
aReflowState.ApplyRelativePositioning(&position);
// Now place the frame and complete the reflow process
nsContainerFrame::FinishReflowChild(mFrame, mPresContext, &aReflowState, mMetrics, x, y, 0);
nsContainerFrame::FinishReflowChild(mFrame, mPresContext, &aReflowState,
mMetrics, position.x, position.y, 0);
aOverflowAreas = mMetrics.mOverflowAreas + nsPoint(x, y);
aOverflowAreas = mMetrics.mOverflowAreas + position;
return true;
}

View File

@ -476,12 +476,8 @@ nsCanvasFrame::Reflow(nsPresContext* aPresContext,
nsPoint kidPt(kidReflowState.mComputedMargin.left,
kidReflowState.mComputedMargin.top);
// Apply CSS relative positioning
const nsStyleDisplay* styleDisp = kidFrame->StyleDisplay();
if (NS_STYLE_POSITION_RELATIVE == styleDisp->mPosition) {
kidPt += nsPoint(kidReflowState.mComputedOffsets.left,
kidReflowState.mComputedOffsets.top);
}
kidReflowState.ApplyRelativePositioning(&kidPt);
// Reflow the frame
ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,

View File

@ -2400,12 +2400,7 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
"We gave flex item unconstrained available height, so it "
"should be complete");
// Apply CSS relative positioning
const nsStyleDisplay* styleDisp = curItem.Frame()->StyleDisplay();
if (NS_STYLE_POSITION_RELATIVE == styleDisp->mPosition) {
physicalPosn.x += childReflowState.mComputedOffsets.left;
physicalPosn.y += childReflowState.mComputedOffsets.top;
}
childReflowState.ApplyRelativePositioning(&physicalPosn);
rv = FinishReflowChild(curItem.Frame(), aPresContext,
&childReflowState, childDesiredSize,

View File

@ -838,6 +838,16 @@ nsHTMLReflowState::ComputeRelativeOffsets(uint8_t aCBDirection,
}
}
/* static */ void
nsHTMLReflowState::ApplyRelativePositioning(const nsStyleDisplay* aDisplay,
const nsMargin &aComputedOffsets,
nsPoint* aPosition)
{
if (NS_STYLE_POSITION_RELATIVE == aDisplay->mPosition) {
*aPosition += nsPoint(aComputedOffsets.left, aComputedOffsets.top);
}
}
nsIFrame*
nsHTMLReflowState::GetHypotheticalBoxContainer(nsIFrame* aFrame,
nscoord& aCBLeftEdge,

View File

@ -533,6 +533,15 @@ public:
nscoord aContainingBlockHeight,
nsMargin& aComputedOffsets);
// If a relatively positioned element, adjust the position appropriately.
static void ApplyRelativePositioning(const nsStyleDisplay* aDisplay,
const nsMargin& aComputedOffsets,
nsPoint* aPosition);
void ApplyRelativePositioning(nsPoint* aPosition) const {
ApplyRelativePositioning(mStyleDisplay, mComputedOffsets, aPosition);
}
#ifdef DEBUG
// Reflow trace methods. Defined in nsFrame.cpp so they have access
// to the display-reflow infrastructure.

View File

@ -2628,8 +2628,9 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflo
if (pfd->GetFlag(PFD_RELATIVEPOS)) {
// right and bottom are handled by
// nsHTMLReflowState::ComputeRelativeOffsets
nsPoint change(pfd->mOffsets.left, pfd->mOffsets.top);
origin += change;
nsHTMLReflowState::ApplyRelativePositioning(pfd->mFrame->StyleDisplay(),
pfd->mOffsets,
&origin);
frame->SetPosition(origin);
}