From c885568e5607390b3f705ebf4e73d7854ea4c3e1 Mon Sep 17 00:00:00 2001 From: Corey Ford Date: Wed, 11 Sep 2013 11:51:42 -0700 Subject: [PATCH] Bug 911786 - Part 2: Reapply relative positioning when moving frames without reflowing them. r=dholbert --- layout/generic/nsBlockFrame.cpp | 8 ++------ layout/generic/nsBlockReflowState.cpp | 3 +-- layout/generic/nsFrame.cpp | 16 ++++++++++++++++ layout/generic/nsIFrame.h | 7 +++++++ layout/generic/nsLineLayout.cpp | 4 +--- 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 4b5c5fbb0d52..ec47e9b0daf2 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -2582,9 +2582,7 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState, if (aLine->IsBlock()) { if (aDY) { - nsPoint p = kid->GetPosition(); - p.y += aDY; - kid->SetPosition(p); + kid->MovePositionBy(nsPoint(0, aDY)); } // Make sure the frame's view and any child views are updated @@ -2598,9 +2596,7 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState, int32_t n = aLine->GetChildCount(); while (--n >= 0) { if (aDY) { - nsPoint p = kid->GetPosition(); - p.y += aDY; - kid->SetPosition(p); + kid->MovePositionBy(nsPoint(0, aDY)); } // Make sure the frame's view and any child views are updated ::PlaceFrameView(kid); diff --git a/layout/generic/nsBlockReflowState.cpp b/layout/generic/nsBlockReflowState.cpp index c572a3eb5f7d..daafd017b715 100644 --- a/layout/generic/nsBlockReflowState.cpp +++ b/layout/generic/nsBlockReflowState.cpp @@ -386,8 +386,7 @@ nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine, while (fc) { nsIFrame* floatFrame = fc->mFloat; if (aDeltaY != 0) { - nsPoint p = floatFrame->GetPosition(); - floatFrame->SetPosition(nsPoint(p.x, p.y + aDeltaY)); + floatFrame->MovePositionBy(nsPoint(0, aDeltaY)); nsContainerFrame::PositionFrameView(floatFrame); nsContainerFrame::PositionChildViews(floatFrame); } diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index aa837d3e59d5..0d087536a394 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -5070,6 +5070,22 @@ ComputeOutlineAndEffectsRect(nsIFrame* aFrame, return r; } +void +nsIFrame::MovePositionBy(const nsPoint& aTranslation) +{ + nsPoint position = GetNormalPosition() + aTranslation; + + const nsMargin* computedOffsets = nullptr; + if (IsRelativelyPositioned()) { + computedOffsets = static_cast + (Properties().Get(nsIFrame::ComputedOffsetProperty())); + } + nsHTMLReflowState::ApplyRelativePositioning(this, computedOffsets ? + *computedOffsets : nsMargin(), + &position); + SetPosition(position); +} + nsPoint nsIFrame::GetNormalPosition() const { diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 880557441aba..586eefc43a81 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -866,6 +866,13 @@ public: } void SetPosition(const nsPoint& aPt) { mRect.MoveTo(aPt); } + /** + * Move the frame, accounting for relative positioning. Use this when + * adjusting the frame's position by a known amount, to properly update its + * saved normal position (see GetNormalPosition below). + */ + void MovePositionBy(const nsPoint& aTranslation); + /** * Return frame's position without relative positioning */ diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index c1b089f9ec69..1fbf0e25880e 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -2196,9 +2196,7 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) static void SlideSpanFrameRect(nsIFrame* aFrame, nscoord aDeltaWidth) { - nsRect r = aFrame->GetRect(); - r.x -= aDeltaWidth; - aFrame->SetRect(r); + aFrame->MovePositionBy(nsPoint(-aDeltaWidth, 0)); } bool