forked from mirrors/gecko-dev
		
	 3f013cc607
			
		
	
	
		3f013cc607
		
	
	
	
	
		
			
			This matches other browsers, the spec (https://drafts.csswg.org/css-sizing/#cyclic-percentage-contribution): For the min size properties, as well as for margins and paddings (and gutters), a cyclic percentage is resolved against zero for determining intrinsic size contributions. And also what we do in SizeComputationInput::Compute{Margin,Padding}: https://searchfox.org/mozilla-central/rev/75e9d727ce5ba2c14653cf8fb0f1367f085271b7/layout/generic/ReflowInput.cpp#2811-2832 https://searchfox.org/mozilla-central/rev/75e9d727ce5ba2c14653cf8fb0f1367f085271b7/layout/generic/ReflowInput.cpp#2861-2868 This fixes a compat issue with the menu alignment in lume.io: https://github.com/webcompat/web-bugs/issues/88484#issuecomment-933226651 It's also simpler. Differential Revision: https://phabricator.services.mozilla.com/D127441
		
			
				
	
	
		
			100 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | |
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| #ifndef nsContainerFrameInlines_h___
 | |
| #define nsContainerFrameInlines_h___
 | |
| 
 | |
| #include "nsContainerFrame.h"
 | |
| 
 | |
| template <typename ISizeData, typename F>
 | |
| void nsContainerFrame::DoInlineIntrinsicISize(ISizeData* aData,
 | |
|                                               F& aHandleChildren) {
 | |
|   using namespace mozilla;
 | |
| 
 | |
|   auto GetMargin = [](const LengthPercentageOrAuto& aCoord) -> nscoord {
 | |
|     return aCoord.IsAuto() ? 0 : aCoord.AsLengthPercentage().Resolve(0);
 | |
|   };
 | |
| 
 | |
|   if (GetPrevInFlow()) return;  // Already added.
 | |
| 
 | |
|   WritingMode wm = GetWritingMode();
 | |
|   Side startSide = wm.PhysicalSideForInlineAxis(eLogicalEdgeStart);
 | |
|   Side endSide = wm.PhysicalSideForInlineAxis(eLogicalEdgeEnd);
 | |
| 
 | |
|   const nsStylePadding* stylePadding = StylePadding();
 | |
|   const nsStyleBorder* styleBorder = StyleBorder();
 | |
|   const nsStyleMargin* styleMargin = StyleMargin();
 | |
| 
 | |
|   // This goes at the beginning no matter how things are broken and how
 | |
|   // messy the bidi situations are, since per CSS2.1 section 8.6
 | |
|   // (implemented in bug 328168), the startSide border is always on the
 | |
|   // first line.
 | |
|   // This frame is a first-in-flow, but it might have a previous bidi
 | |
|   // continuation, in which case that continuation should handle the startSide
 | |
|   // border.
 | |
|   // For box-decoration-break:clone we setup clonePBM = startPBM + endPBM and
 | |
|   // add that to each line.  For box-decoration-break:slice clonePBM is zero.
 | |
|   nscoord clonePBM = 0;  // PBM = PaddingBorderMargin
 | |
|   const bool sliceBreak =
 | |
|       styleBorder->mBoxDecorationBreak == StyleBoxDecorationBreak::Slice;
 | |
|   if (!GetPrevContinuation() || MOZ_UNLIKELY(!sliceBreak)) {
 | |
|     nscoord startPBM =
 | |
|         // clamp negative calc() to 0
 | |
|         std::max(stylePadding->mPadding.Get(startSide).Resolve(0), 0) +
 | |
|         styleBorder->GetComputedBorderWidth(startSide) +
 | |
|         GetMargin(styleMargin->mMargin.Get(startSide));
 | |
|     if (MOZ_LIKELY(sliceBreak)) {
 | |
|       aData->mCurrentLine += startPBM;
 | |
|     } else {
 | |
|       clonePBM = startPBM;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   nscoord endPBM =
 | |
|       // clamp negative calc() to 0
 | |
|       std::max(stylePadding->mPadding.Get(endSide).Resolve(0), 0) +
 | |
|       styleBorder->GetComputedBorderWidth(endSide) +
 | |
|       GetMargin(styleMargin->mMargin.Get(endSide));
 | |
|   if (MOZ_UNLIKELY(!sliceBreak)) {
 | |
|     clonePBM += endPBM;
 | |
|     aData->mCurrentLine += clonePBM;
 | |
|   }
 | |
| 
 | |
|   const nsLineList_iterator* savedLine = aData->mLine;
 | |
|   nsIFrame* const savedLineContainer = aData->LineContainer();
 | |
| 
 | |
|   nsContainerFrame* lastInFlow;
 | |
|   for (nsContainerFrame* nif = this; nif;
 | |
|        nif = static_cast<nsContainerFrame*>(nif->GetNextInFlow())) {
 | |
|     if (aData->mCurrentLine == 0) {
 | |
|       aData->mCurrentLine = clonePBM;
 | |
|     }
 | |
|     aHandleChildren(nif, aData);
 | |
| 
 | |
|     // After we advance to our next-in-flow, the stored line and line container
 | |
|     // may no longer be correct. Just forget them.
 | |
|     aData->mLine = nullptr;
 | |
|     aData->SetLineContainer(nullptr);
 | |
| 
 | |
|     lastInFlow = nif;
 | |
|   }
 | |
| 
 | |
|   aData->mLine = savedLine;
 | |
|   aData->SetLineContainer(savedLineContainer);
 | |
| 
 | |
|   // This goes at the end no matter how things are broken and how
 | |
|   // messy the bidi situations are, since per CSS2.1 section 8.6
 | |
|   // (implemented in bug 328168), the endSide border is always on the
 | |
|   // last line.
 | |
|   // We reached the last-in-flow, but it might have a next bidi
 | |
|   // continuation, in which case that continuation should handle
 | |
|   // the endSide border.
 | |
|   if (MOZ_LIKELY(!lastInFlow->GetNextContinuation() && sliceBreak)) {
 | |
|     aData->mCurrentLine += endPBM;
 | |
|   }
 | |
| }
 | |
| 
 | |
| #endif  // nsContainerFrameInlines_h___
 |