1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /* rendering object for CSS "display: flex" and "display: -webkit-box" */ 8 9 #ifndef nsFlexContainerFrame_h___ 10 #define nsFlexContainerFrame_h___ 11 12 #include <tuple> 13 14 #include "mozilla/dom/FlexBinding.h" 15 #include "mozilla/UniquePtr.h" 16 #include "nsContainerFrame.h" 17 18 namespace mozilla { 19 class LogicalPoint; 20 class PresShell; 21 } // namespace mozilla 22 23 nsContainerFrame* NS_NewFlexContainerFrame(mozilla::PresShell* aPresShell, 24 mozilla::ComputedStyle* aStyle); 25 26 /** 27 * These structures are used to capture data during reflow to be 28 * extracted by devtools via Chrome APIs. The structures are only 29 * created when requested in GetFlexFrameWithComputedInfo(), and 30 * the structures are attached to the nsFlexContainerFrame via the 31 * FlexContainerInfo property. 32 */ 33 struct ComputedFlexItemInfo { 34 nsCOMPtr<nsINode> mNode; 35 nsRect mFrameRect; 36 /** 37 * mMainBaseSize is a measure of the size of the item in the main 38 * axis before the flex sizing algorithm is applied. In the spec, 39 * this is called "flex base size", but we use this name to connect 40 * the value to the other main axis sizes. 41 */ 42 nscoord mMainBaseSize; 43 /** 44 * mMainDeltaSize is the amount that the flex sizing algorithm 45 * adds to the mMainBaseSize, before clamping to mMainMinSize and 46 * mMainMaxSize. This can be thought of as the amount by which the 47 * flex layout algorithm "wants" to shrink or grow the item, and 48 * would do, if it was unconstrained. Since the flex sizing 49 * algorithm proceeds linearly, the mMainDeltaSize for an item only 50 * respects the resolved size of items already frozen. 51 */ 52 nscoord mMainDeltaSize; 53 nscoord mMainMinSize; 54 nscoord mMainMaxSize; 55 nscoord mCrossMinSize; 56 nscoord mCrossMaxSize; 57 mozilla::dom::FlexItemClampState mClampState; 58 }; 59 60 struct ComputedFlexLineInfo { 61 nsTArray<ComputedFlexItemInfo> mItems; 62 nscoord mCrossStart; 63 nscoord mCrossSize; 64 nscoord mFirstBaselineOffset; 65 nscoord mLastBaselineOffset; 66 mozilla::dom::FlexLineGrowthState mGrowthState; 67 }; 68 69 struct ComputedFlexContainerInfo { 70 nsTArray<ComputedFlexLineInfo> mLines; 71 mozilla::dom::FlexPhysicalDirection mMainAxisDirection; 72 mozilla::dom::FlexPhysicalDirection mCrossAxisDirection; 73 }; 74 75 /** 76 * This is the rendering object used for laying out elements with 77 * "display: flex" or "display: inline-flex". 78 * 79 * We also use this class for elements with "display: -webkit-box" or 80 * "display: -webkit-inline-box" (but not "-moz-box" / "-moz-inline-box" -- 81 * those are rendered with old-school XUL frame classes). 82 * 83 * Note: we represent the -webkit-box family of properties (-webkit-box-orient, 84 * -webkit-box-flex, etc.) as aliases for their -moz equivalents. And for 85 * -webkit-{inline-}box containers, nsFlexContainerFrame will honor those 86 * "legacy" properties for alignment/flexibility/etc. *instead of* honoring the 87 * modern flexbox & alignment properties. For brevity, many comments in 88 * nsFlexContainerFrame.cpp simply refer to these properties using their 89 * "-webkit" versions, since we're mostly expecting to encounter them in that 90 * form. (Technically, the "-moz" versions of these properties *can* influence 91 * layout here as well (since that's what the -webkit versions are aliased to) 92 * -- but only inside of a "display:-webkit-{inline-}box" container.) 93 */ 94 class nsFlexContainerFrame final : public nsContainerFrame { 95 public: 96 NS_DECL_FRAMEARENA_HELPERS(nsFlexContainerFrame) 97 NS_DECL_QUERYFRAME 98 99 // Factory method: 100 friend nsContainerFrame* NS_NewFlexContainerFrame( 101 mozilla::PresShell* aPresShell, ComputedStyle* aStyle); 102 103 // Forward-decls of helper classes 104 class FlexItem; 105 class FlexLine; 106 class FlexboxAxisTracker; 107 struct StrutInfo; 108 class CachedBAxisMeasurement; 109 class CachedFlexItemData; 110 struct SharedFlexData; 111 class FlexItemIterator; 112 113 // nsIFrame overrides 114 void Init(nsIContent* aContent, nsContainerFrame* aParent, 115 nsIFrame* aPrevInFlow) override; 116 IsFrameOfType(uint32_t aFlags)117 bool IsFrameOfType(uint32_t aFlags) const override { 118 return nsContainerFrame::IsFrameOfType( 119 aFlags & ~(nsIFrame::eCanContainOverflowContainers)); 120 } 121 122 void BuildDisplayList(nsDisplayListBuilder* aBuilder, 123 const nsDisplayListSet& aLists) override; 124 125 void MarkIntrinsicISizesDirty() override; 126 127 void Reflow(nsPresContext* aPresContext, ReflowOutput& aReflowOutput, 128 const ReflowInput& aReflowInput, 129 nsReflowStatus& aStatus) override; 130 131 nscoord GetMinISize(gfxContext* aRenderingContext) override; 132 nscoord GetPrefISize(gfxContext* aRenderingContext) override; 133 134 #ifdef DEBUG_FRAME_DUMP 135 nsresult GetFrameName(nsAString& aResult) const override; 136 #endif 137 138 nscoord GetLogicalBaseline(mozilla::WritingMode aWM) const override; 139 GetVerticalAlignBaseline(mozilla::WritingMode aWM,nscoord * aBaseline)140 bool GetVerticalAlignBaseline(mozilla::WritingMode aWM, 141 nscoord* aBaseline) const override { 142 return GetNaturalBaselineBOffset(aWM, BaselineSharingGroup::First, 143 aBaseline); 144 } 145 GetNaturalBaselineBOffset(mozilla::WritingMode aWM,BaselineSharingGroup aBaselineGroup,nscoord * aBaseline)146 bool GetNaturalBaselineBOffset(mozilla::WritingMode aWM, 147 BaselineSharingGroup aBaselineGroup, 148 nscoord* aBaseline) const override { 149 if (HasAnyStateBits(NS_STATE_FLEX_SYNTHESIZE_BASELINE)) { 150 return false; 151 } 152 *aBaseline = aBaselineGroup == BaselineSharingGroup::First 153 ? mBaselineFromLastReflow 154 : mLastBaselineFromLastReflow; 155 return true; 156 } 157 158 /** 159 * Returns the effective value of -webkit-line-clamp for this flex container. 160 * 161 * This will be 0 if the property is 'none', or if the element is not 162 * display:-webkit-(inline-)box and -webkit-box-orient:vertical. 163 */ 164 uint32_t GetLineClampValue() const; 165 166 // nsContainerFrame overrides 167 bool DrainSelfOverflowList() override; 168 void AppendFrames(ChildListID aListID, nsFrameList& aFrameList) override; 169 void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, 170 const nsLineList::iterator* aPrevFrameLine, 171 nsFrameList& aFrameList) override; 172 void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override; 173 mozilla::StyleAlignFlags CSSAlignmentForAbsPosChild( 174 const ReflowInput& aChildRI, 175 mozilla::LogicalAxis aLogicalAxis) const override; 176 177 /** 178 * Helper function to calculate packing space and initial offset of alignment 179 * subjects in MainAxisPositionTracker() and CrossAxisPositionTracker() for 180 * space-between, space-around, and space-evenly. 181 * * @param aNumThingsToPack Number of alignment subjects. 182 * @param aAlignVal Value for align-content or 183 * justify-content. 184 * @param aFirstSubjectOffset Outparam for first subject offset. 185 * @param aNumPackingSpacesRemaining Outparam for number of equal-sized 186 * packing spaces to apply between each 187 * alignment subject. 188 * @param aPackingSpaceRemaining Outparam for total amount of packing 189 * space to be divided up. 190 */ 191 static void CalculatePackingSpace( 192 uint32_t aNumThingsToPack, 193 const mozilla::StyleContentDistribution& aAlignVal, 194 nscoord* aFirstSubjectOffset, uint32_t* aNumPackingSpacesRemaining, 195 nscoord* aPackingSpaceRemaining); 196 197 /** 198 * This property is created by a call to 199 * nsFlexContainerFrame::GetFlexFrameWithComputedInfo. 200 */ NS_DECLARE_FRAME_PROPERTY_DELETABLE(FlexContainerInfo,ComputedFlexContainerInfo)201 NS_DECLARE_FRAME_PROPERTY_DELETABLE(FlexContainerInfo, 202 ComputedFlexContainerInfo) 203 /** 204 * This function should only be called on a nsFlexContainerFrame 205 * that has just been returned by a call to 206 * GetFlexFrameWithComputedInfo. 207 */ 208 const ComputedFlexContainerInfo* GetFlexContainerInfo() { 209 const ComputedFlexContainerInfo* info = GetProperty(FlexContainerInfo()); 210 NS_WARNING_ASSERTION(info, 211 "Property generation wasn't requested. " 212 "This is a known issue in Print Preview. " 213 "See Bug 1157012."); 214 return info; 215 } 216 217 /** 218 * Return aFrame as a flex frame after ensuring it has computed flex info. 219 * @return nullptr if aFrame is null or doesn't have a flex frame 220 * as its content insertion frame. 221 * @note this might destroy layout/style data since it may flush layout. 222 */ 223 MOZ_CAN_RUN_SCRIPT_BOUNDARY 224 static nsFlexContainerFrame* GetFlexFrameWithComputedInfo(nsIFrame* aFrame); 225 226 /** 227 * Given a frame for a flex item, this method returns true IFF that flex 228 * item's inline axis is the same as (i.e. not orthogonal to) its flex 229 * container's main axis. 230 * 231 * (This method is only intended to be used from external 232 * callers. Inside of flex reflow code, FlexItem::IsInlineAxisMainAxis() is 233 * equivalent & more optimal.) 234 * 235 * @param aFrame a flex item (must return true from IsFlexItem) 236 * @return true iff aFrame's inline axis is the same as (i.e. not orthogonal 237 * to) its flex container's main axis. Otherwise, false. 238 */ 239 static bool IsItemInlineAxisMainAxis(nsIFrame* aFrame); 240 241 /** 242 * Returns true iff the given computed 'flex-basis' & main-size property 243 * values collectively represent a used flex-basis of 'content'. 244 * See https://drafts.csswg.org/css-flexbox-1/#valdef-flex-basis-auto 245 * 246 * @param aFlexBasis the computed 'flex-basis' for a flex item. 247 * @param aMainSize the computed main-size property for a flex item. 248 */ 249 static bool IsUsedFlexBasisContent(const StyleFlexBasis& aFlexBasis, 250 const StyleSize& aMainSize); 251 252 /** 253 * Callback for nsFrame::MarkIntrinsicISizesDirty() on a flex item. 254 */ 255 static void MarkCachedFlexMeasurementsDirty(nsIFrame* aItemFrame); 256 257 protected: 258 // Protected constructor & destructor nsFlexContainerFrame(ComputedStyle * aStyle,nsPresContext * aPresContext)259 explicit nsFlexContainerFrame(ComputedStyle* aStyle, 260 nsPresContext* aPresContext) 261 : nsContainerFrame(aStyle, aPresContext, kClassID) {} 262 263 virtual ~nsFlexContainerFrame(); 264 265 // Protected flex-container-specific methods / member-vars 266 267 /* 268 * This method does the bulk of the flex layout, implementing the algorithm 269 * described at: 270 * http://dev.w3.org/csswg/css-flexbox/#layout-algorithm 271 * (with a few initialization pieces happening in the caller, Reflow(). 272 * 273 * (The logic behind the division of work between Reflow and DoFlexLayout is 274 * as follows: DoFlexLayout() begins at the step that we have to jump back 275 * to, if we find any visibility:collapse children, and Reflow() does 276 * everything before that point.) 277 * 278 * @param aContentBoxMainSize [in/out] initially, the "tentative" content-box 279 * main-size of the flex container; "tentative" 280 * because it may be unconstrained or may run off 281 * the page. In those cases, this method will 282 * resolve it to a final value before returning. 283 * @param aContentBoxCrossSize [out] the final content-box cross-size of the 284 * flex container. 285 * @param aFlexContainerAscent [out] the flex container's ascent, derived from 286 * any baseline-aligned flex items in the first 287 * flex line, if any such items exist. Otherwise, 288 * nscoord_MIN. 289 * @param aAvailableBSizeForContent the fragmentainer's available block-size 290 * for our content, when we run the flex 291 * layout algorithm. This may be 292 * unconstrained, even in a context where the 293 * flex container is ultimately being 294 * fragmented, because flex container 295 * fragmentation usually starts out by 296 * performing flex layout without regard to 297 * pagination. 298 * @param aColumnWrapThreshold the block-size threshold to wrap to a new line. 299 * Used only by multi-line column-oriented flex 300 * container if the available block-size is 301 * constrained. 302 */ 303 void DoFlexLayout(const ReflowInput& aReflowInput, nsReflowStatus& aStatus, 304 nscoord& aContentBoxMainSize, nscoord& aContentBoxCrossSize, 305 nscoord& aFlexContainerAscent, 306 nscoord aAvailableBSizeForContent, 307 nscoord aColumnWrapThreshold, nsTArray<FlexLine>& aLines, 308 nsTArray<StrutInfo>& aStruts, 309 nsTArray<nsIFrame*>& aPlaceholders, 310 const FlexboxAxisTracker& aAxisTracker, 311 nscoord aMainGapSize, nscoord aCrossGapSize, 312 bool aHasLineClampEllipsis, 313 ComputedFlexContainerInfo* const aContainerInfo); 314 315 /** 316 * If our devtools have requested a ComputedFlexContainerInfo for this flex 317 * container, this method ensures that we have one (and if one already exists, 318 * this method reinitializes it to look like a freshly-created one). 319 * 320 * @return the pointer to a freshly created or reinitialized 321 * ComputedFlexContainerInfo if our devtools have requested it; 322 * otherwise nullptr. 323 */ 324 ComputedFlexContainerInfo* CreateOrClearFlexContainerInfo(); 325 326 /** 327 * Helpers for DoFlexLayout to computed fields in ComputedFlexContainerInfo. 328 */ 329 static void CreateFlexLineAndFlexItemInfo( 330 ComputedFlexContainerInfo& aContainerInfo, 331 const nsTArray<FlexLine>& aLines); 332 333 static void ComputeFlexDirections(ComputedFlexContainerInfo& aContainerInfo, 334 const FlexboxAxisTracker& aAxisTracker); 335 336 static void UpdateFlexLineAndItemInfo( 337 ComputedFlexContainerInfo& aContainerInfo, 338 const nsTArray<FlexLine>& aLines); 339 340 #ifdef DEBUG 341 void SanityCheckAnonymousFlexItems() const; 342 #endif // DEBUG 343 344 /** 345 * Returns a new FlexItem for the given child frame, directly constructed at 346 * the end of aLine. Guaranteed to return non-null. 347 * 348 * Before returning, this method also processes the FlexItem to resolve its 349 * flex basis (including e.g. auto-height) as well as to resolve 350 * "min-height:auto", via ResolveAutoFlexBasisAndMinSize(). (Basically, the 351 * returned FlexItem will be ready to participate in the "Resolve the 352 * Flexible Lengths" step of the Flex Layout Algorithm.) 353 * https://drafts.csswg.org/css-flexbox-1/#algo-flex 354 * 355 * Note that this method **does not** update aLine's main-size bookkeeping to 356 * account for the newly-constructed flex item. The caller is responsible for 357 * determining whether this line is a good fit for the new item. If so, 358 * updating aLine's bookkeeping (via FlexLine::AddLastItemToMainSizeTotals), 359 * or moving the new item to a new line otherwise. 360 */ 361 FlexItem* GenerateFlexItemForChild(FlexLine& aLine, nsIFrame* aChildFrame, 362 const ReflowInput& aParentReflowInput, 363 const FlexboxAxisTracker& aAxisTracker, 364 bool aHasLineClampEllipsis); 365 366 /** 367 * This method looks up cached block-axis measurements for a flex item, or 368 * does a measuring reflow and caches those measurements. 369 * 370 * This avoids exponential reflows - see the comment above the 371 * CachedBAxisMeasurement struct. 372 */ 373 const CachedBAxisMeasurement& MeasureAscentAndBSizeForFlexItem( 374 FlexItem& aItem, ReflowInput& aChildReflowInput); 375 376 /** 377 * This method performs a "measuring" reflow to get the content BSize of 378 * aFlexItem.Frame() (treating it as if it had a computed BSize of "auto"), 379 * and returns the resulting BSize measurement. 380 * (Helper for ResolveAutoFlexBasisAndMinSize().) 381 */ 382 nscoord MeasureFlexItemContentBSize(FlexItem& aFlexItem, 383 bool aForceBResizeForMeasuringReflow, 384 bool aHasLineClampEllipsis, 385 const ReflowInput& aParentReflowInput); 386 387 /** 388 * This method resolves an "auto" flex-basis and/or min-main-size value 389 * on aFlexItem, if needed. 390 * (Helper for GenerateFlexItemForChild().) 391 */ 392 void ResolveAutoFlexBasisAndMinSize(FlexItem& aFlexItem, 393 const ReflowInput& aItemReflowInput, 394 const FlexboxAxisTracker& aAxisTracker, 395 bool aHasLineClampEllipsis); 396 397 /** 398 * Returns true if "this" is the nsFlexContainerFrame for a -moz-box or 399 * a -moz-inline-box -- these boxes have special behavior for flex items with 400 * "visibility:collapse". 401 * 402 * @param aFlexStyleDisp This frame's StyleDisplay(). (Just an optimization to 403 * avoid repeated lookup; some callers already have it.) 404 * @return true if "this" is the nsFlexContainerFrame for a -moz-{inline}box. 405 */ 406 bool ShouldUseMozBoxCollapseBehavior(const nsStyleDisplay* aFlexStyleDisp); 407 408 /** 409 * This method: 410 * - Creates FlexItems for all of our child frames (except placeholders). 411 * - Groups those FlexItems into FlexLines. 412 * - Returns those FlexLines in the outparam |aLines|. 413 * 414 * This corresponds to "Collect flex items into flex lines" step in the spec. 415 * https://drafts.csswg.org/css-flexbox-1/#algo-line-break 416 * 417 * For any child frames which are placeholders, this method will instead just 418 * append that child to the outparam |aPlaceholders| for separate handling. 419 * (Absolutely positioned children of a flex container are *not* flex items.) 420 */ 421 void GenerateFlexLines(const ReflowInput& aReflowInput, 422 nscoord aContentBoxMainSize, 423 nscoord aColumnWrapThreshold, 424 const nsTArray<StrutInfo>& aStruts, 425 const FlexboxAxisTracker& aAxisTracker, 426 nscoord aMainGapSize, bool aHasLineClampEllipsis, 427 nsTArray<nsIFrame*>& aPlaceholders, 428 nsTArray<FlexLine>& aLines); 429 430 /** 431 * This method creates FlexLines and FlexItems for children in flex 432 * container's next-in-flows by using the SharedFlexData stored in flex 433 * container's first-in-flow. Returns FlexLines in the outparam |aLines|. 434 */ 435 void GenerateFlexLines(const SharedFlexData& aData, 436 nsTArray<FlexLine>& aLines); 437 438 nscoord GetMainSizeFromReflowInput(const ReflowInput& aReflowInput, 439 const FlexboxAxisTracker& aAxisTracker); 440 441 /** 442 * Resolves the content-box main-size of a flex container frame, 443 * primarily based on: 444 * - the "tentative" main size, taken from the reflow input ("tentative" 445 * because it may be unconstrained or may run off the page). 446 * - the available BSize (needed if the main axis is the block axis). 447 * - the sizes of our lines of flex items. 448 * 449 * Guaranteed to return a definite length, i.e. not NS_UNCONSTRAINEDSIZE, 450 * aside from cases with huge lengths which happen to compute to that value. 451 * 452 * This corresponds to "Determine the main size of the flex container" step in 453 * the spec. https://drafts.csswg.org/css-flexbox-1/#algo-main-container 454 * 455 * (Note: This function should be structurally similar to 456 * 'ComputeCrossSize()', except that here, the caller has already grabbed the 457 * tentative size from the reflow input.) 458 */ 459 nscoord ComputeMainSize(const ReflowInput& aReflowInput, 460 const FlexboxAxisTracker& aAxisTracker, 461 nscoord aTentativeMainSize, 462 nscoord aAvailableBSizeForContent, 463 nsTArray<FlexLine>& aLines, 464 nsReflowStatus& aStatus) const; 465 466 nscoord ComputeCrossSize(const ReflowInput& aReflowInput, 467 const FlexboxAxisTracker& aAxisTracker, 468 nscoord aSumLineCrossSizes, 469 nscoord aAvailableBSizeForContent, bool* aIsDefinite, 470 nsReflowStatus& aStatus) const; 471 472 /** 473 * Compute the size of the available space that we'll give to our children to 474 * reflow into. In particular, compute the available size that we would give 475 * to a hypothetical child placed at the IStart/BStart corner of this flex 476 * container's content-box. 477 * 478 * @param aReflowInput the flex container's reflow input. 479 * @param aBorderPadding the border and padding of this frame with the 480 * assumption that this is the last fragment. 481 * 482 * @return the size of the available space for our children to reflow into. 483 */ 484 mozilla::LogicalSize ComputeAvailableSizeForItems( 485 const ReflowInput& aReflowInput, 486 const mozilla::LogicalMargin& aBorderPadding) const; 487 488 void SizeItemInCrossAxis(ReflowInput& aChildReflowInput, FlexItem& aItem); 489 490 /** 491 * This method computes the metrics to be reported via the flex container's 492 * ReflowOutput & nsReflowStatus output parameters in Reflow(). 493 * 494 * @param aContentBoxSize the final content-box size for the flex container as 495 * a whole, converted from the flex container's 496 * main/cross sizes. The main/cross sizes are computed 497 * by DoFlexLayout() if this frame is the 498 * first-in-flow, or are the stored ones in 499 * SharedFlexData if this frame is a not the 500 * first-in-flow. 501 * @param aBorderPadding the border and padding for this frame (possibly with 502 * some sides skipped as-appropriate, if we're in a 503 * continuation chain). 504 * @param aConsumedBSize the sum of our content-box block-size consumed by our 505 * prev-in-flows. 506 * @param aMayNeedNextInFlow true if we may need a next-in-flow because our 507 * effective content-box block-size exceeds the 508 * available block-size. 509 * @param aMaxBlockEndEdgeOfChildren the maximum block-end edge of the 510 * children of this fragment in this frame's 511 * coordinate space (as returned by 512 * ReflowChildren()). 513 * @param aAnyChildIncomplete true if any child being reflowed is incomplete; 514 * false otherwise (as returned by 515 * ReflowChildren()). 516 * @param aFlexContainerAscent the flex container's ascent, if one has been 517 * determined from its children. (If there are no 518 * children, pass nscoord_MIN to synthesize a 519 * value from the flex container itself). 520 */ 521 void PopulateReflowOutput( 522 ReflowOutput& aReflowOutput, const ReflowInput& aReflowInput, 523 nsReflowStatus& aStatus, const mozilla::LogicalSize& aContentBoxSize, 524 const mozilla::LogicalMargin& aBorderPadding, 525 const nscoord aConsumedBSize, const bool aMayNeedNextInFlow, 526 const nscoord aMaxBlockEndEdgeOfChildren, const bool aAnyChildIncomplete, 527 nscoord aFlexContainerAscent, nsTArray<FlexLine>& aLines, 528 const FlexboxAxisTracker& aAxisTracker); 529 530 /** 531 * Perform a final Reflow for our child frames. 532 * 533 * @param aContentBoxMainSize the final content-box main-size of the flex 534 * container. 535 * @param aContentBoxCrossSize the final content-box cross-size of the flex 536 * container. 537 * @param aAvailableSizeForItems the size of the available space for our 538 * children to reflow into. 539 * @param aBorderPadding the border and padding for this frame (possibly with 540 * some sides skipped as-appropriate, if we're in a 541 * continuation chain). 542 * @param aSumOfPrevInFlowsChildrenBlockSize See the comment for 543 * SumOfChildrenBlockSizeProperty. 544 * @param aFlexContainerAscent [in/out] initially, the "tentative" flex 545 * container ascent computed in DoFlexLayout; or, 546 * nscoord_MIN if the ascent hasn't been 547 * established yet. If the latter, this will be 548 * updated with an ascent derived from the first 549 * flex item (if there are any flex items). 550 * @return nscoord the maximum block-end edge of children of this fragment in 551 * flex container's coordinate space. 552 * @return bool true if any child being reflowed is incomplete; false 553 * otherwise. 554 */ 555 std::tuple<nscoord, bool> ReflowChildren( 556 const ReflowInput& aReflowInput, const nscoord aContentBoxMainSize, 557 const nscoord aContentBoxCrossSize, 558 const mozilla::LogicalSize& aAvailableSizeForItems, 559 const mozilla::LogicalMargin& aBorderPadding, 560 const nscoord aSumOfPrevInFlowsChildrenBlockSize, 561 nscoord& aFlexContainerAscent, nsTArray<FlexLine>& aLines, 562 nsTArray<nsIFrame*>& aPlaceholders, 563 const FlexboxAxisTracker& aAxisTracker, bool aHasLineClampEllipsis); 564 565 /** 566 * Moves the given flex item's frame to the given LogicalPosition (modulo any 567 * relative positioning). 568 * 569 * This can be used in cases where we've already done a "measuring reflow" 570 * for the flex item at the correct size, and hence can skip its final reflow 571 * (but still need to move it to the right final position). 572 * 573 * @param aReflowInput The flex container's reflow input. 574 * @param aItem The flex item whose frame should be moved. 575 * @param aFramePos The position where the flex item's frame should 576 * be placed. (pre-relative positioning) 577 * @param aContainerSize The flex container's size (required by some methods 578 * that we call, to interpret aFramePos correctly). 579 */ 580 void MoveFlexItemToFinalPosition(const ReflowInput& aReflowInput, 581 const FlexItem& aItem, 582 mozilla::LogicalPoint& aFramePos, 583 const nsSize& aContainerSize); 584 /** 585 * Helper-function to reflow a child frame, at its final position determined 586 * by flex layout. 587 * 588 * @param aAxisTracker A FlexboxAxisTracker with the flex container's axes. 589 * @param aReflowInput The flex container's reflow input. 590 * @param aItem The flex item to be reflowed. 591 * @param aFramePos The position where the flex item's frame should 592 * be placed. (pre-relative positioning) 593 * @param aAvailableSize The available size to reflow the child frame (in the 594 * child frame's writing-mode). 595 * @param aContainerSize The flex container's size (required by some methods 596 * that we call, to interpret aFramePos correctly). 597 * @return the child frame's reflow status. 598 */ 599 nsReflowStatus ReflowFlexItem(const FlexboxAxisTracker& aAxisTracker, 600 const ReflowInput& aReflowInput, 601 const FlexItem& aItem, 602 mozilla::LogicalPoint& aFramePos, 603 const mozilla::LogicalSize& aAvailableSize, 604 const nsSize& aContainerSize, 605 bool aHasLineClampEllipsis); 606 607 /** 608 * Helper-function to perform a "dummy reflow" on all our nsPlaceholderFrame 609 * children, at the container's content-box origin. 610 * 611 * This doesn't actually represent the static position of the placeholders' 612 * out-of-flow (OOF) frames -- we can't compute that until we've reflowed the 613 * OOF, because (depending on the CSS Align properties) the static position 614 * may be influenced by the OOF's size. So for now, we just co-opt the 615 * placeholder to store the flex container's logical content-box origin, and 616 * we defer to nsAbsoluteContainingBlock to determine the OOF's actual static 617 * position (using this origin, the OOF's size, and the CSS Align 618 * properties). 619 * 620 * @param aReflowInput The flex container's reflow input. 621 * @param aPlaceholders An array of all the flex container's 622 * nsPlaceholderFrame children. 623 * @param aContentBoxOrigin The flex container's logical content-box 624 * origin (in its own coordinate space). 625 * @param aContainerSize The flex container's size (required by some 626 * reflow methods to interpret positions correctly). 627 */ 628 void ReflowPlaceholders(const ReflowInput& aReflowInput, 629 nsTArray<nsIFrame*>& aPlaceholders, 630 const mozilla::LogicalPoint& aContentBoxOrigin, 631 const nsSize& aContainerSize); 632 633 /** 634 * Helper for GetMinISize / GetPrefISize. 635 */ 636 nscoord IntrinsicISize(gfxContext* aRenderingContext, 637 nsLayoutUtils::IntrinsicISizeType aType); 638 639 /** 640 * Cached values to optimize GetMinISize/GetPrefISize. 641 */ 642 nscoord mCachedMinISize = NS_INTRINSIC_ISIZE_UNKNOWN; 643 nscoord mCachedPrefISize = NS_INTRINSIC_ISIZE_UNKNOWN; 644 645 nscoord mBaselineFromLastReflow = NS_INTRINSIC_ISIZE_UNKNOWN; 646 // Note: the last baseline is a distance from our border-box end edge. 647 nscoord mLastBaselineFromLastReflow = NS_INTRINSIC_ISIZE_UNKNOWN; 648 }; 649 650 #endif /* nsFlexContainerFrame_h___ */ 651