1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/generic/nsAbsoluteContainingBlock.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,502 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* 1.10 + * code for managing absolutely positioned children of a rendering 1.11 + * object that is a containing block for them 1.12 + */ 1.13 + 1.14 +#include "nsAbsoluteContainingBlock.h" 1.15 + 1.16 +#include "nsContainerFrame.h" 1.17 +#include "nsGkAtoms.h" 1.18 +#include "nsIPresShell.h" 1.19 +#include "nsHTMLReflowState.h" 1.20 +#include "nsPresContext.h" 1.21 +#include "nsCSSFrameConstructor.h" 1.22 + 1.23 +#ifdef DEBUG 1.24 +#include "nsBlockFrame.h" 1.25 + 1.26 +static void PrettyUC(nscoord aSize, char* aBuf) 1.27 +{ 1.28 + if (NS_UNCONSTRAINEDSIZE == aSize) { 1.29 + strcpy(aBuf, "UC"); 1.30 + } else { 1.31 + if((int32_t)0xdeadbeef == aSize) { 1.32 + strcpy(aBuf, "deadbeef"); 1.33 + } else { 1.34 + sprintf(aBuf, "%d", aSize); 1.35 + } 1.36 + } 1.37 +} 1.38 +#endif 1.39 + 1.40 +nsresult 1.41 +nsAbsoluteContainingBlock::SetInitialChildList(nsIFrame* aDelegatingFrame, 1.42 + ChildListID aListID, 1.43 + nsFrameList& aChildList) 1.44 +{ 1.45 + NS_PRECONDITION(mChildListID == aListID, "unexpected child list name"); 1.46 +#ifdef DEBUG 1.47 + nsFrame::VerifyDirtyBitSet(aChildList); 1.48 +#endif 1.49 + mAbsoluteFrames.SetFrames(aChildList); 1.50 + return NS_OK; 1.51 +} 1.52 + 1.53 +nsresult 1.54 +nsAbsoluteContainingBlock::AppendFrames(nsIFrame* aDelegatingFrame, 1.55 + ChildListID aListID, 1.56 + nsFrameList& aFrameList) 1.57 +{ 1.58 + NS_ASSERTION(mChildListID == aListID, "unexpected child list"); 1.59 + 1.60 + // Append the frames to our list of absolutely positioned frames 1.61 +#ifdef DEBUG 1.62 + nsFrame::VerifyDirtyBitSet(aFrameList); 1.63 +#endif 1.64 + mAbsoluteFrames.AppendFrames(nullptr, aFrameList); 1.65 + 1.66 + // no damage to intrinsic widths, since absolutely positioned frames can't 1.67 + // change them 1.68 + aDelegatingFrame->PresContext()->PresShell()-> 1.69 + FrameNeedsReflow(aDelegatingFrame, nsIPresShell::eResize, 1.70 + NS_FRAME_HAS_DIRTY_CHILDREN); 1.71 + 1.72 + return NS_OK; 1.73 +} 1.74 + 1.75 +nsresult 1.76 +nsAbsoluteContainingBlock::InsertFrames(nsIFrame* aDelegatingFrame, 1.77 + ChildListID aListID, 1.78 + nsIFrame* aPrevFrame, 1.79 + nsFrameList& aFrameList) 1.80 +{ 1.81 + NS_ASSERTION(mChildListID == aListID, "unexpected child list"); 1.82 + NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == aDelegatingFrame, 1.83 + "inserting after sibling frame with different parent"); 1.84 + 1.85 +#ifdef DEBUG 1.86 + nsFrame::VerifyDirtyBitSet(aFrameList); 1.87 +#endif 1.88 + mAbsoluteFrames.InsertFrames(nullptr, aPrevFrame, aFrameList); 1.89 + 1.90 + // no damage to intrinsic widths, since absolutely positioned frames can't 1.91 + // change them 1.92 + aDelegatingFrame->PresContext()->PresShell()-> 1.93 + FrameNeedsReflow(aDelegatingFrame, nsIPresShell::eResize, 1.94 + NS_FRAME_HAS_DIRTY_CHILDREN); 1.95 + 1.96 + return NS_OK; 1.97 +} 1.98 + 1.99 +void 1.100 +nsAbsoluteContainingBlock::RemoveFrame(nsIFrame* aDelegatingFrame, 1.101 + ChildListID aListID, 1.102 + nsIFrame* aOldFrame) 1.103 +{ 1.104 + NS_ASSERTION(mChildListID == aListID, "unexpected child list"); 1.105 + nsIFrame* nif = aOldFrame->GetNextInFlow(); 1.106 + if (nif) { 1.107 + static_cast<nsContainerFrame*>(nif->GetParent()) 1.108 + ->DeleteNextInFlowChild(nif, false); 1.109 + } 1.110 + 1.111 + mAbsoluteFrames.DestroyFrame(aOldFrame); 1.112 +} 1.113 + 1.114 +nsresult 1.115 +nsAbsoluteContainingBlock::Reflow(nsContainerFrame* aDelegatingFrame, 1.116 + nsPresContext* aPresContext, 1.117 + const nsHTMLReflowState& aReflowState, 1.118 + nsReflowStatus& aReflowStatus, 1.119 + const nsRect& aContainingBlock, 1.120 + bool aConstrainHeight, 1.121 + bool aCBWidthChanged, 1.122 + bool aCBHeightChanged, 1.123 + nsOverflowAreas* aOverflowAreas) 1.124 +{ 1.125 + nsReflowStatus reflowStatus = NS_FRAME_COMPLETE; 1.126 + 1.127 + bool reflowAll = aReflowState.ShouldReflowAllKids(); 1.128 + 1.129 + nsIFrame* kidFrame; 1.130 + nsOverflowContinuationTracker tracker(aDelegatingFrame, true); 1.131 + for (kidFrame = mAbsoluteFrames.FirstChild(); kidFrame; kidFrame = kidFrame->GetNextSibling()) { 1.132 + bool kidNeedsReflow = reflowAll || NS_SUBTREE_DIRTY(kidFrame) || 1.133 + FrameDependsOnContainer(kidFrame, aCBWidthChanged, aCBHeightChanged); 1.134 + if (kidNeedsReflow && !aPresContext->HasPendingInterrupt()) { 1.135 + // Reflow the frame 1.136 + nsReflowStatus kidStatus = NS_FRAME_COMPLETE; 1.137 + ReflowAbsoluteFrame(aDelegatingFrame, aPresContext, aReflowState, 1.138 + aContainingBlock, 1.139 + aConstrainHeight, kidFrame, kidStatus, 1.140 + aOverflowAreas); 1.141 + nsIFrame* nextFrame = kidFrame->GetNextInFlow(); 1.142 + if (!NS_FRAME_IS_FULLY_COMPLETE(kidStatus)) { 1.143 + // Need a continuation 1.144 + if (!nextFrame) { 1.145 + nextFrame = 1.146 + aPresContext->PresShell()->FrameConstructor()-> 1.147 + CreateContinuingFrame(aPresContext, kidFrame, aDelegatingFrame); 1.148 + } 1.149 + // Add it as an overflow container. 1.150 + //XXXfr This is a hack to fix some of our printing dataloss. 1.151 + // See bug 154892. Not sure how to do it "right" yet; probably want 1.152 + // to keep continuations within an nsAbsoluteContainingBlock eventually. 1.153 + tracker.Insert(nextFrame, kidStatus); 1.154 + NS_MergeReflowStatusInto(&reflowStatus, kidStatus); 1.155 + } 1.156 + else { 1.157 + // Delete any continuations 1.158 + if (nextFrame) { 1.159 + nsOverflowContinuationTracker::AutoFinish fini(&tracker, kidFrame); 1.160 + static_cast<nsContainerFrame*>(nextFrame->GetParent()) 1.161 + ->DeleteNextInFlowChild(nextFrame, true); 1.162 + } 1.163 + } 1.164 + } 1.165 + else { 1.166 + tracker.Skip(kidFrame, reflowStatus); 1.167 + if (aOverflowAreas) { 1.168 + aDelegatingFrame->ConsiderChildOverflow(*aOverflowAreas, kidFrame); 1.169 + } 1.170 + } 1.171 + 1.172 + // Make a CheckForInterrupt call, here, not just HasPendingInterrupt. That 1.173 + // will make sure that we end up reflowing aDelegatingFrame in cases when 1.174 + // one of our kids interrupted. Otherwise we'd set the dirty or 1.175 + // dirty-children bit on the kid in the condition below, and then when 1.176 + // reflow completes and we go to mark dirty bits on all ancestors of that 1.177 + // kid we'll immediately bail out, because the kid already has a dirty bit. 1.178 + // In particular, we won't set any dirty bits on aDelegatingFrame, so when 1.179 + // the following reflow happens we won't reflow the kid in question. This 1.180 + // might be slightly suboptimal in cases where |kidFrame| itself did not 1.181 + // interrupt, since we'll trigger a reflow of it too when it's not strictly 1.182 + // needed. But the logic to not do that is enough more complicated, and 1.183 + // the case enough of an edge case, that this is probably better. 1.184 + if (kidNeedsReflow && aPresContext->CheckForInterrupt(aDelegatingFrame)) { 1.185 + if (aDelegatingFrame->GetStateBits() & NS_FRAME_IS_DIRTY) { 1.186 + kidFrame->AddStateBits(NS_FRAME_IS_DIRTY); 1.187 + } else { 1.188 + kidFrame->AddStateBits(NS_FRAME_HAS_DIRTY_CHILDREN); 1.189 + } 1.190 + } 1.191 + } 1.192 + 1.193 + // Abspos frames can't cause their parent to be incomplete, 1.194 + // only overflow incomplete. 1.195 + if (NS_FRAME_IS_NOT_COMPLETE(reflowStatus)) 1.196 + NS_FRAME_SET_OVERFLOW_INCOMPLETE(reflowStatus); 1.197 + 1.198 + NS_MergeReflowStatusInto(&aReflowStatus, reflowStatus); 1.199 + return NS_OK; 1.200 +} 1.201 + 1.202 +static inline bool IsFixedPaddingSize(const nsStyleCoord& aCoord) 1.203 + { return aCoord.ConvertsToLength(); } 1.204 +static inline bool IsFixedMarginSize(const nsStyleCoord& aCoord) 1.205 + { return aCoord.ConvertsToLength(); } 1.206 +static inline bool IsFixedOffset(const nsStyleCoord& aCoord) 1.207 + { return aCoord.ConvertsToLength(); } 1.208 + 1.209 +bool 1.210 +nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f, 1.211 + bool aCBWidthChanged, 1.212 + bool aCBHeightChanged) 1.213 +{ 1.214 + const nsStylePosition* pos = f->StylePosition(); 1.215 + // See if f's position might have changed because it depends on a 1.216 + // placeholder's position 1.217 + // This can happen in the following cases: 1.218 + // 1) Vertical positioning. "top" must be auto and "bottom" must be auto 1.219 + // (otherwise the vertical position is completely determined by 1.220 + // whichever of them is not auto and the height). 1.221 + // 2) Horizontal positioning. "left" must be auto and "right" must be auto 1.222 + // (otherwise the horizontal position is completely determined by 1.223 + // whichever of them is not auto and the width). 1.224 + // See nsHTMLReflowState::InitAbsoluteConstraints -- these are the 1.225 + // only cases when we call CalculateHypotheticalBox(). 1.226 + if ((pos->mOffset.GetTopUnit() == eStyleUnit_Auto && 1.227 + pos->mOffset.GetBottomUnit() == eStyleUnit_Auto) || 1.228 + (pos->mOffset.GetLeftUnit() == eStyleUnit_Auto && 1.229 + pos->mOffset.GetRightUnit() == eStyleUnit_Auto)) { 1.230 + return true; 1.231 + } 1.232 + if (!aCBWidthChanged && !aCBHeightChanged) { 1.233 + // skip getting style data 1.234 + return false; 1.235 + } 1.236 + const nsStylePadding* padding = f->StylePadding(); 1.237 + const nsStyleMargin* margin = f->StyleMargin(); 1.238 + if (aCBWidthChanged) { 1.239 + // See if f's width might have changed. 1.240 + // If border-left, border-right, padding-left, padding-right, 1.241 + // width, min-width, and max-width are all lengths, 'none', or enumerated, 1.242 + // then our frame width does not depend on the parent width. 1.243 + // Note that borders never depend on the parent width 1.244 + // XXX All of the enumerated values except -moz-available are ok too. 1.245 + if (pos->WidthDependsOnContainer() || 1.246 + pos->MinWidthDependsOnContainer() || 1.247 + pos->MaxWidthDependsOnContainer() || 1.248 + !IsFixedPaddingSize(padding->mPadding.GetLeft()) || 1.249 + !IsFixedPaddingSize(padding->mPadding.GetRight())) { 1.250 + return true; 1.251 + } 1.252 + 1.253 + // See if f's position might have changed. If we're RTL then the 1.254 + // rules are slightly different. We'll assume percentage or auto 1.255 + // margins will always induce a dependency on the size 1.256 + if (!IsFixedMarginSize(margin->mMargin.GetLeft()) || 1.257 + !IsFixedMarginSize(margin->mMargin.GetRight())) { 1.258 + return true; 1.259 + } 1.260 + if (f->StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) { 1.261 + // Note that even if 'left' is a length, our position can 1.262 + // still depend on the containing block width, because if 1.263 + // 'right' is also a length we will discard 'left' and be 1.264 + // positioned relative to the containing block right edge. 1.265 + // 'left' length and 'right' auto is the only combination 1.266 + // we can be sure of. 1.267 + if (!IsFixedOffset(pos->mOffset.GetLeft()) || 1.268 + pos->mOffset.GetRightUnit() != eStyleUnit_Auto) { 1.269 + return true; 1.270 + } 1.271 + } else { 1.272 + if (!IsFixedOffset(pos->mOffset.GetLeft())) { 1.273 + return true; 1.274 + } 1.275 + } 1.276 + } 1.277 + if (aCBHeightChanged) { 1.278 + // See if f's height might have changed. 1.279 + // If border-top, border-bottom, padding-top, padding-bottom, 1.280 + // min-height, and max-height are all lengths or 'none', 1.281 + // and height is a length or height and bottom are auto and top is not auto, 1.282 + // then our frame height does not depend on the parent height. 1.283 + // Note that borders never depend on the parent height 1.284 + if ((pos->HeightDependsOnContainer() && 1.285 + !(pos->mHeight.GetUnit() == eStyleUnit_Auto && 1.286 + pos->mOffset.GetBottomUnit() == eStyleUnit_Auto && 1.287 + pos->mOffset.GetTopUnit() != eStyleUnit_Auto)) || 1.288 + pos->MinHeightDependsOnContainer() || 1.289 + pos->MaxHeightDependsOnContainer() || 1.290 + !IsFixedPaddingSize(padding->mPadding.GetTop()) || 1.291 + !IsFixedPaddingSize(padding->mPadding.GetBottom())) { 1.292 + return true; 1.293 + } 1.294 + 1.295 + // See if f's position might have changed. 1.296 + if (!IsFixedMarginSize(margin->mMargin.GetTop()) || 1.297 + !IsFixedMarginSize(margin->mMargin.GetBottom())) { 1.298 + return true; 1.299 + } 1.300 + if (!IsFixedOffset(pos->mOffset.GetTop())) { 1.301 + return true; 1.302 + } 1.303 + } 1.304 + return false; 1.305 +} 1.306 + 1.307 +void 1.308 +nsAbsoluteContainingBlock::DestroyFrames(nsIFrame* aDelegatingFrame, 1.309 + nsIFrame* aDestructRoot) 1.310 +{ 1.311 + mAbsoluteFrames.DestroyFramesFrom(aDestructRoot); 1.312 +} 1.313 + 1.314 +void 1.315 +nsAbsoluteContainingBlock::MarkSizeDependentFramesDirty() 1.316 +{ 1.317 + DoMarkFramesDirty(false); 1.318 +} 1.319 + 1.320 +void 1.321 +nsAbsoluteContainingBlock::MarkAllFramesDirty() 1.322 +{ 1.323 + DoMarkFramesDirty(true); 1.324 +} 1.325 + 1.326 +void 1.327 +nsAbsoluteContainingBlock::DoMarkFramesDirty(bool aMarkAllDirty) 1.328 +{ 1.329 + for (nsIFrame* kidFrame = mAbsoluteFrames.FirstChild(); 1.330 + kidFrame; 1.331 + kidFrame = kidFrame->GetNextSibling()) { 1.332 + if (aMarkAllDirty) { 1.333 + kidFrame->AddStateBits(NS_FRAME_IS_DIRTY); 1.334 + } else if (FrameDependsOnContainer(kidFrame, true, true)) { 1.335 + // Add the weakest flags that will make sure we reflow this frame later 1.336 + kidFrame->AddStateBits(NS_FRAME_HAS_DIRTY_CHILDREN); 1.337 + } 1.338 + } 1.339 +} 1.340 + 1.341 +// XXX Optimize the case where it's a resize reflow and the absolutely 1.342 +// positioned child has the exact same size and position and skip the 1.343 +// reflow... 1.344 + 1.345 +// When bug 154892 is checked in, make sure that when 1.346 +// mChildListID == kFixedList, the height is unconstrained. 1.347 +// since we don't allow replicated frames to split. 1.348 + 1.349 +nsresult 1.350 +nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegatingFrame, 1.351 + nsPresContext* aPresContext, 1.352 + const nsHTMLReflowState& aReflowState, 1.353 + const nsRect& aContainingBlock, 1.354 + bool aConstrainHeight, 1.355 + nsIFrame* aKidFrame, 1.356 + nsReflowStatus& aStatus, 1.357 + nsOverflowAreas* aOverflowAreas) 1.358 +{ 1.359 +#ifdef DEBUG 1.360 + if (nsBlockFrame::gNoisyReflow) { 1.361 + nsFrame::IndentBy(stdout,nsBlockFrame::gNoiseIndent); 1.362 + printf("abs pos "); 1.363 + if (aKidFrame) { 1.364 + nsAutoString name; 1.365 + aKidFrame->GetFrameName(name); 1.366 + printf("%s ", NS_LossyConvertUTF16toASCII(name).get()); 1.367 + } 1.368 + 1.369 + char width[16]; 1.370 + char height[16]; 1.371 + PrettyUC(aReflowState.AvailableWidth(), width); 1.372 + PrettyUC(aReflowState.AvailableHeight(), height); 1.373 + printf(" a=%s,%s ", width, height); 1.374 + PrettyUC(aReflowState.ComputedWidth(), width); 1.375 + PrettyUC(aReflowState.ComputedHeight(), height); 1.376 + printf("c=%s,%s \n", width, height); 1.377 + } 1.378 + AutoNoisyIndenter indent(nsBlockFrame::gNoisy); 1.379 +#endif // DEBUG 1.380 + 1.381 + nscoord availWidth = aContainingBlock.width; 1.382 + if (availWidth == -1) { 1.383 + NS_ASSERTION(aReflowState.ComputedWidth() != NS_UNCONSTRAINEDSIZE, 1.384 + "Must have a useful width _somewhere_"); 1.385 + availWidth = 1.386 + aReflowState.ComputedWidth() + aReflowState.ComputedPhysicalPadding().LeftRight(); 1.387 + } 1.388 + 1.389 + nsHTMLReflowMetrics kidDesiredSize(aReflowState); 1.390 + nsHTMLReflowState kidReflowState(aPresContext, aReflowState, aKidFrame, 1.391 + nsSize(availWidth, NS_UNCONSTRAINEDSIZE), 1.392 + aContainingBlock.width, 1.393 + aContainingBlock.height); 1.394 + 1.395 + // Send the WillReflow() notification and position the frame 1.396 + aKidFrame->WillReflow(aPresContext); 1.397 + 1.398 + // Get the border values 1.399 + const nsMargin& border = aReflowState.mStyleBorder->GetComputedBorder(); 1.400 + 1.401 + bool constrainHeight = (aReflowState.AvailableHeight() != NS_UNCONSTRAINEDSIZE) 1.402 + && aConstrainHeight 1.403 + // Don't split if told not to (e.g. for fixed frames) 1.404 + && (aDelegatingFrame->GetType() != nsGkAtoms::inlineFrame) 1.405 + //XXX we don't handle splitting frames for inline absolute containing blocks yet 1.406 + && (aKidFrame->GetRect().y <= aReflowState.AvailableHeight()); 1.407 + // Don't split things below the fold. (Ideally we shouldn't *have* 1.408 + // anything totally below the fold, but we can't position frames 1.409 + // across next-in-flow breaks yet. 1.410 + if (constrainHeight) { 1.411 + kidReflowState.AvailableHeight() = aReflowState.AvailableHeight() - border.top 1.412 + - kidReflowState.ComputedPhysicalMargin().top; 1.413 + if (NS_AUTOOFFSET != kidReflowState.ComputedPhysicalOffsets().top) 1.414 + kidReflowState.AvailableHeight() -= kidReflowState.ComputedPhysicalOffsets().top; 1.415 + } 1.416 + 1.417 + // Do the reflow 1.418 + nsresult rv = aKidFrame->Reflow(aPresContext, kidDesiredSize, kidReflowState, aStatus); 1.419 + 1.420 + // If we're solving for 'left' or 'top', then compute it now that we know the 1.421 + // width/height 1.422 + if ((NS_AUTOOFFSET == kidReflowState.ComputedPhysicalOffsets().left) || 1.423 + (NS_AUTOOFFSET == kidReflowState.ComputedPhysicalOffsets().top)) { 1.424 + nscoord aContainingBlockWidth = aContainingBlock.width; 1.425 + nscoord aContainingBlockHeight = aContainingBlock.height; 1.426 + 1.427 + if (-1 == aContainingBlockWidth) { 1.428 + // Get the containing block width/height 1.429 + kidReflowState.ComputeContainingBlockRectangle(aPresContext, 1.430 + &aReflowState, 1.431 + aContainingBlockWidth, 1.432 + aContainingBlockHeight); 1.433 + } 1.434 + 1.435 + if (NS_AUTOOFFSET == kidReflowState.ComputedPhysicalOffsets().left) { 1.436 + NS_ASSERTION(NS_AUTOOFFSET != kidReflowState.ComputedPhysicalOffsets().right, 1.437 + "Can't solve for both left and right"); 1.438 + kidReflowState.ComputedPhysicalOffsets().left = aContainingBlockWidth - 1.439 + kidReflowState.ComputedPhysicalOffsets().right - 1.440 + kidReflowState.ComputedPhysicalMargin().right - 1.441 + kidDesiredSize.Width() - 1.442 + kidReflowState.ComputedPhysicalMargin().left; 1.443 + } 1.444 + if (NS_AUTOOFFSET == kidReflowState.ComputedPhysicalOffsets().top) { 1.445 + kidReflowState.ComputedPhysicalOffsets().top = aContainingBlockHeight - 1.446 + kidReflowState.ComputedPhysicalOffsets().bottom - 1.447 + kidReflowState.ComputedPhysicalMargin().bottom - 1.448 + kidDesiredSize.Height() - 1.449 + kidReflowState.ComputedPhysicalMargin().top; 1.450 + } 1.451 + } 1.452 + 1.453 + // Position the child relative to our padding edge 1.454 + nsRect rect(border.left + kidReflowState.ComputedPhysicalOffsets().left + kidReflowState.ComputedPhysicalMargin().left, 1.455 + border.top + kidReflowState.ComputedPhysicalOffsets().top + kidReflowState.ComputedPhysicalMargin().top, 1.456 + kidDesiredSize.Width(), kidDesiredSize.Height()); 1.457 + 1.458 + // Offset the frame rect by the given origin of the absolute containing block. 1.459 + // If the frame is auto-positioned on both sides of an axis, it will be 1.460 + // positioned based on its containing block and we don't need to offset. 1.461 + if (aContainingBlock.TopLeft() != nsPoint(0, 0)) { 1.462 + if (!(kidReflowState.mStylePosition->mOffset.GetLeftUnit() == eStyleUnit_Auto && 1.463 + kidReflowState.mStylePosition->mOffset.GetRightUnit() == eStyleUnit_Auto)) { 1.464 + rect.x += aContainingBlock.x; 1.465 + } 1.466 + if (!(kidReflowState.mStylePosition->mOffset.GetTopUnit() == eStyleUnit_Auto && 1.467 + kidReflowState.mStylePosition->mOffset.GetBottomUnit() == eStyleUnit_Auto)) { 1.468 + rect.y += aContainingBlock.y; 1.469 + } 1.470 + } 1.471 + 1.472 + aKidFrame->SetRect(rect); 1.473 + 1.474 + nsView* view = aKidFrame->GetView(); 1.475 + if (view) { 1.476 + // Size and position the view and set its opacity, visibility, content 1.477 + // transparency, and clip 1.478 + nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, aKidFrame, view, 1.479 + kidDesiredSize.VisualOverflow()); 1.480 + } else { 1.481 + nsContainerFrame::PositionChildViews(aKidFrame); 1.482 + } 1.483 + 1.484 + aKidFrame->DidReflow(aPresContext, &kidReflowState, nsDidReflowStatus::FINISHED); 1.485 + 1.486 +#ifdef DEBUG 1.487 + if (nsBlockFrame::gNoisyReflow) { 1.488 + nsFrame::IndentBy(stdout,nsBlockFrame::gNoiseIndent - 1); 1.489 + printf("abs pos "); 1.490 + if (aKidFrame) { 1.491 + nsAutoString name; 1.492 + aKidFrame->GetFrameName(name); 1.493 + printf("%s ", NS_LossyConvertUTF16toASCII(name).get()); 1.494 + } 1.495 + printf("%p rect=%d,%d,%d,%d\n", static_cast<void*>(aKidFrame), 1.496 + rect.x, rect.y, rect.width, rect.height); 1.497 + } 1.498 +#endif 1.499 + 1.500 + if (aOverflowAreas) { 1.501 + aOverflowAreas->UnionWith(kidDesiredSize.mOverflowAreas + rect.TopLeft()); 1.502 + } 1.503 + 1.504 + return rv; 1.505 +}