From b9d1536d461d69049fc75a4851f039b02039e410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 27 Mar 2023 23:25:42 +0000 Subject: [PATCH] Bug 1824489 - Remove nsBoxFrame, nsBoxLayout and related code. r=jwatt We still have some remnants of XUL layout due to nsBox / nsLeafBoxFrame which XUL trees / nsTextBoxFrame still use. However all this code can go away before we get rid of those. nsSplitterFrame was the last thing inheriting from nsBoxFrame. Differential Revision: https://phabricator.services.mozilla.com/D173601 --- layout/base/nsCSSFrameConstructor.cpp | 18 +- layout/build/nsLayoutStatics.cpp | 2 - layout/generic/FrameClasses.py | 1 - layout/generic/ReflowInput.cpp | 31 +- layout/generic/nsFrameState.cpp | 1 - layout/generic/nsFrameStateBits.h | 10 - layout/generic/nsGfxScrollFrame.h | 1 - layout/generic/nsIFrame.cpp | 1 - layout/generic/nsIFrame.h | 7 - layout/generic/nsVideoFrame.cpp | 1 - layout/painting/nsDisplayList.cpp | 1 - layout/xul/moz.build | 3 - layout/xul/nsBox.cpp | 2 - layout/xul/nsBoxFrame.cpp | 861 ---------------- layout/xul/nsBoxFrame.h | 162 --- layout/xul/nsBoxLayout.cpp | 74 -- layout/xul/nsBoxLayout.h | 67 -- layout/xul/nsLeafBoxFrame.cpp | 6 - layout/xul/nsSliderFrame.cpp | 7 +- layout/xul/nsSliderFrame.h | 3 +- layout/xul/nsSplitterFrame.cpp | 1 - layout/xul/nsSprocketLayout.cpp | 1357 ------------------------- layout/xul/nsSprocketLayout.h | 154 --- layout/xul/nsTextBoxFrame.cpp | 1 - layout/xul/tree/nsTreeBodyFrame.cpp | 1 - 25 files changed, 11 insertions(+), 2762 deletions(-) delete mode 100644 layout/xul/nsBoxFrame.cpp delete mode 100644 layout/xul/nsBoxFrame.h delete mode 100644 layout/xul/nsBoxLayout.cpp delete mode 100644 layout/xul/nsBoxLayout.h delete mode 100644 layout/xul/nsSprocketLayout.cpp delete mode 100644 layout/xul/nsSprocketLayout.h diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index cd6da0f3155f..cd2e0a7baa14 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -76,8 +76,6 @@ #include "ChildIterator.h" #include "nsError.h" #include "nsLayoutUtils.h" -#include "nsBoxFrame.h" -#include "nsBoxLayout.h" #include "nsFlexContainerFrame.h" #include "nsGridContainerFrame.h" #include "RubyUtils.h" @@ -2486,10 +2484,6 @@ nsIFrame* nsCSSFrameConstructor::ConstructDocElementFrame( if (display->mDisplay == StyleDisplay::Grid) { return NS_NewGridContainerFrame; } - if (display->mDisplay == StyleDisplay::MozBox && - !computedStyle->StyleVisibility()->EmulateMozBoxWithFlex()) { - return NS_NewBoxFrame; - } return NS_NewFlexContainerFrame; }(); contentFrame = func(mPresShell, computedStyle); @@ -2644,8 +2638,7 @@ void nsCSSFrameConstructor::SetUpDocElementContainingBlock( nsHTMLScrollFrame (if needed) nsCanvasFrame [abs-cb] root element frame (nsBlockFrame, SVGOuterSVGFrame, - nsTableWrapperFrame, nsPlaceholderFrame, - nsBoxFrame) + nsTableWrapperFrame, nsPlaceholderFrame) Print presentation, non-XUL @@ -4460,15 +4453,6 @@ nsCSSFrameConstructor::FindDisplayData(const nsStyleDisplay& aDisplay, aElement.OwnerDoc()->WarnOnceAbout( DeprecatedOperations::eMozBoxOrInlineBoxDisplay); } - - // If we're emulating -moz-box with flexbox, then treat it as non-XUL and - // fall through. - if (aMozBoxLayout == StyleMozBoxLayout::Legacy) { - static constexpr FrameConstructionData data = - SCROLLABLE_ABSPOS_CONTAINER_XUL_FCDATA( - ToCreationFunc(NS_NewBoxFrame)); - return &data; - } [[fallthrough]]; } case StyleDisplayInside::Flex: diff --git a/layout/build/nsLayoutStatics.cpp b/layout/build/nsLayoutStatics.cpp index da8dac26ffa3..1b6f45818cdb 100644 --- a/layout/build/nsLayoutStatics.cpp +++ b/layout/build/nsLayoutStatics.cpp @@ -34,7 +34,6 @@ #include "nsRegion.h" #include "nsRepeatService.h" #include "nsFloatManager.h" -#include "nsSprocketLayout.h" #include "nsTextControlFrame.h" #include "txMozillaXSLTProcessor.h" #include "nsTreeSanitizer.h" @@ -347,7 +346,6 @@ void nsLayoutStatics::Shutdown() { nsXULContentUtils::Finish(); nsXULPrototypeCache::ReleaseGlobals(); - nsSprocketLayout::Shutdown(); SVGElementFactory::Shutdown(); nsMathMLOperators::ReleaseTable(); diff --git a/layout/generic/FrameClasses.py b/layout/generic/FrameClasses.py index 9b136d2a08c0..40a55a84e73b 100644 --- a/layout/generic/FrameClasses.py +++ b/layout/generic/FrameClasses.py @@ -11,7 +11,6 @@ FRAME_CLASSES = [ Frame("nsBackdropFrame", "Backdrop", LEAF), Frame("nsBlockFrame", "Block", NOT_LEAF), Frame("nsBox", "None", NOT_LEAF), - Frame("nsBoxFrame", "Box", NOT_LEAF), Frame("nsButtonBoxFrame", "Box", NOT_LEAF), Frame("nsCanvasFrame", "Canvas", NOT_LEAF), Frame("nsCheckboxRadioFrame", "CheckboxRadio", LEAF), diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp index da3e96567f18..2a55d6f2c5a5 100644 --- a/layout/generic/ReflowInput.cpp +++ b/layout/generic/ReflowInput.cpp @@ -315,19 +315,11 @@ bool ReflowInput::ShouldReflowAllKids() const { void ReflowInput::SetComputedISize(nscoord aComputedISize, ResetResizeFlags aFlags) { - // It'd be nice to assert that |frame| is not in reflow, but this fails for - // two reasons: - // - // 1) Viewport frames reset the computed isize on a copy of their reflow - // input when reflowing fixed-pos kids. In that case we actually don't - // want to mess with the resize flags, because comparing the frame's rect - // to the munged computed width is pointless. - // 2) nsIFrame::BoxReflow creates a reflow input for its parent. This reflow - // input is not used to reflow the parent, but just as a parent for the - // frame's own reflow input. So given a nsBoxFrame inside some non-XUL - // (like a text control, for example), we'll end up creating a reflow - // input for the parent while the parent is reflowing. - + // It'd be nice to assert that |frame| is not in reflow, but this fails + // because viewport frames reset the computed isize on a copy of their reflow + // input when reflowing fixed-pos kids. In that case we actually don't want + // to mess with the resize flags, because comparing the frame's rect to the + // munged computed isize is pointless. NS_WARNING_ASSERTION(aComputedISize >= 0, "Invalid computed inline-size!"); if (ComputedISize() != aComputedISize) { mComputedSize.ISize(mWritingMode) = std::max(0, aComputedISize); @@ -340,18 +332,7 @@ void ReflowInput::SetComputedISize(nscoord aComputedISize, void ReflowInput::SetComputedBSize(nscoord aComputedBSize, ResetResizeFlags aFlags) { // It'd be nice to assert that |frame| is not in reflow, but this fails - // for two reasons: - // - // 1) Viewport frames reset the computed block size on a copy of their reflow - // input when reflowing fixed-pos kids. In that case we actually don't want - // to mess with the resize flags, because comparing the frame's rect to the - // munged computed bsize is pointless. - // 2) nsIFrame::BoxReflow creates a reflow input for its parent. This reflow - // input is not used to reflow the parent, but just as a parent for the - // frame's own reflow input. So given a nsBoxFrame inside some non-XUL - // (like a text control, for example), we'll end up creating a reflow - // input for the parent while the parent is reflowing. - + // for the same reason as above. NS_WARNING_ASSERTION(aComputedBSize >= 0, "Invalid computed block-size!"); if (ComputedBSize() != aComputedBSize) { mComputedSize.BSize(mWritingMode) = std::max(0, aComputedBSize); diff --git a/layout/generic/nsFrameState.cpp b/layout/generic/nsFrameState.cpp index 33a35e087a78..2e5463e2d304 100644 --- a/layout/generic/nsFrameState.cpp +++ b/layout/generic/nsFrameState.cpp @@ -9,7 +9,6 @@ #include "nsFrameState.h" #include "nsBlockFrame.h" -#include "nsBoxFrame.h" #include "nsFlexContainerFrame.h" #include "nsGridContainerFrame.h" #include "nsGfxScrollFrame.h" diff --git a/layout/generic/nsFrameStateBits.h b/layout/generic/nsFrameStateBits.h index 8453cf856970..39d790b70a1c 100644 --- a/layout/generic/nsFrameStateBits.h +++ b/layout/generic/nsFrameStateBits.h @@ -313,16 +313,6 @@ FRAME_STATE_BIT(Generic, 59, NS_FRAME_IS_IN_SINGLE_CHAR_MI) // adjusting logic, or moving infrequently-used bits elsewhere. If more space // for frame state is still needed, look for bit field gaps in nsIFrame. -// == Frame state bits that apply to box frames =============================== - -FRAME_STATE_GROUP(Box, nsBoxFrame) - -FRAME_STATE_BIT(Box, 20, NS_STATE_BOX_CHILD_RESERVED) -FRAME_STATE_BIT(Box, 22, NS_STATE_IS_HORIZONTAL) -FRAME_STATE_BIT(Box, 23, NS_STATE_AUTO_STRETCH) -FRAME_STATE_BIT(Box, 24, NS_STATE_MENU_HAS_POPUP_LIST) -FRAME_STATE_BIT(Box, 25, NS_STATE_IS_DIRECTION_NORMAL) - // == Frame state bits that apply to flex container frames ==================== FRAME_STATE_GROUP(FlexContainer, nsFlexContainerFrame) diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h index effa382a9b0b..46423f80afdc 100644 --- a/layout/generic/nsGfxScrollFrame.h +++ b/layout/generic/nsGfxScrollFrame.h @@ -12,7 +12,6 @@ #include "mozilla/Attributes.h" #include "nsContainerFrame.h" #include "nsIAnonymousContentCreator.h" -#include "nsBoxFrame.h" #include "nsIScrollableFrame.h" #include "nsIScrollbarMediator.h" #include "nsIStatefulFrame.h" diff --git a/layout/generic/nsIFrame.cpp b/layout/generic/nsIFrame.cpp index 217005cb6b89..1633243655d6 100644 --- a/layout/generic/nsIFrame.cpp +++ b/layout/generic/nsIFrame.cpp @@ -4247,7 +4247,6 @@ void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, } const nsStyleDisplay* ourDisp = StyleDisplay(); - // REVIEW: Taken from nsBoxFrame::Paint // Don't paint our children if the theme object is a leaf. if (IsThemed(ourDisp) && !PresContext()->Theme()->WidgetIsContainer( ourDisp->EffectiveAppearance())) { diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 3371a9de11bf..dd6b906c9583 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -4327,13 +4327,6 @@ class nsIFrame : public nsQueryFrame { virtual Valignment GetXULVAlign() const { return vAlign_Top; } virtual Halignment GetXULHAlign() const { return hAlign_Left; } - bool IsXULHorizontal() const { - return (mState & NS_STATE_IS_HORIZONTAL) != 0; - } - bool IsXULNormalDirection() const { - return (mState & NS_STATE_IS_DIRECTION_NORMAL) != 0; - } - nsresult XULRedraw(nsBoxLayoutState& aState); static bool AddXULPrefSize(nsIFrame* aBox, nsSize& aSize, bool& aWidth, diff --git a/layout/generic/nsVideoFrame.cpp b/layout/generic/nsVideoFrame.cpp index c12396524a13..0b5a15431429 100644 --- a/layout/generic/nsVideoFrame.cpp +++ b/layout/generic/nsVideoFrame.cpp @@ -21,7 +21,6 @@ #include "nsPresContext.h" #include "nsContentCreatorFunctions.h" #include "nsBoxLayoutState.h" -#include "nsBoxFrame.h" #include "nsIContentInlines.h" #include "nsImageFrame.h" #include "nsIImageLoadingContent.h" diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index cb66c64a3853..5883021816cb 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -55,7 +55,6 @@ #include "mozilla/MathAlgorithms.h" #include "imgIContainer.h" -#include "nsBoxFrame.h" #include "nsImageFrame.h" #include "nsSubDocumentFrame.h" #include "nsViewManager.h" diff --git a/layout/xul/moz.build b/layout/xul/moz.build index 06d023781571..4e6d91928601 100644 --- a/layout/xul/moz.build +++ b/layout/xul/moz.build @@ -20,8 +20,6 @@ EXPORTS += [ UNIFIED_SOURCES += [ "nsBox.cpp", - "nsBoxFrame.cpp", - "nsBoxLayout.cpp", "nsBoxLayoutState.cpp", "nsLeafBoxFrame.cpp", "nsMenuPopupFrame.cpp", @@ -30,7 +28,6 @@ UNIFIED_SOURCES += [ "nsScrollbarFrame.cpp", "nsSliderFrame.cpp", "nsSplitterFrame.cpp", - "nsSprocketLayout.cpp", "nsTextBoxFrame.cpp", "nsXULPopupManager.cpp", "nsXULTooltipListener.cpp", diff --git a/layout/xul/nsBox.cpp b/layout/xul/nsBox.cpp index 9e21f1a24f45..612b1b98ffda 100644 --- a/layout/xul/nsBox.cpp +++ b/layout/xul/nsBox.cpp @@ -9,7 +9,6 @@ #include "nsIFrame.h" #include "nsBoxLayoutState.h" -#include "nsBoxFrame.h" #include "nsDOMAttributeMap.h" #include "nsPresContext.h" #include "nsCOMPtr.h" @@ -18,7 +17,6 @@ #include "nsNameSpaceManager.h" #include "nsGkAtoms.h" #include "nsITheme.h" -#include "nsBoxLayout.h" #include "nsLayoutUtils.h" #include "mozilla/dom/Attr.h" #include "mozilla/dom/Element.h" diff --git a/layout/xul/nsBoxFrame.cpp b/layout/xul/nsBoxFrame.cpp deleted file mode 100644 index b3ee92ab7062..000000000000 --- a/layout/xul/nsBoxFrame.cpp +++ /dev/null @@ -1,861 +0,0 @@ -/* -*- 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/. */ - -// -// Eric Vaughan -// Netscape Communications -// -// See documentation in associated header file -// - -// How boxes layout -// ---------------- -// Boxes layout a bit differently than html. html does a bottom up layout. Where -// boxes do a top down. -// -// 1) First thing a box does it goes out and askes each child for its min, max, -// and preferred sizes. -// -// 2) It then adds them up to determine its size. -// -// 3) If the box was asked to layout it self intrinically it will layout its -// children at their preferred size otherwise it will layout the child at -// the size it was told to. It will squeeze or stretch its children if -// Necessary. -// -// However there is a catch. Some html components like block frames can not -// determine their preferred size. this is their size if they were laid out -// intrinsically. So the box will flow the child to determine this can cache the -// value. - -// Boxes and Incremental Reflow -// ---------------------------- -// Boxes layout out top down by adding up their children's min, max, and -// preferred sizes. Only problem is if a incremental reflow occurs. The -// preferred size of a child deep in the hierarchy could change. And this could -// change any number of syblings around the box. Basically any children in the -// reflow chain must have their caches cleared so when asked for there current -// size they can relayout themselves. - -#include "nsBoxFrame.h" - -#include -#include - -#include "gfxUtils.h" -#include "mozilla/ComputedStyle.h" -#include "mozilla/CSSOrderAwareFrameIterator.h" -#include "mozilla/Preferences.h" -#include "mozilla/PresShell.h" -#include "mozilla/dom/Touch.h" -#include "mozilla/gfx/2D.h" -#include "mozilla/gfx/gfxVars.h" -#include "nsBoxLayout.h" -#include "nsBoxLayoutState.h" -#include "nsCOMPtr.h" -#include "nsCSSAnonBoxes.h" -#include "nsCSSRendering.h" -#include "nsContainerFrame.h" -#include "nsDisplayList.h" -#include "nsGkAtoms.h" -#include "nsHTMLParts.h" -#include "nsIContent.h" -#include "nsIFrameInlines.h" -#include "nsIScrollableFrame.h" -#include "nsITheme.h" -#include "nsIWidget.h" -#include "nsLayoutUtils.h" -#include "nsNameSpaceManager.h" -#include "nsPlaceholderFrame.h" -#include "nsPresContext.h" -#include "nsSliderFrame.h" -#include "nsSprocketLayout.h" -#include "nsStyleConsts.h" -#include "nsTransform2D.h" -#include "nsView.h" -#include "nsViewManager.h" -#include "nsWidgetsCID.h" - -// Needed for Print Preview - -#include "mozilla/TouchEvents.h" - -using namespace mozilla; -using namespace mozilla::dom; -using namespace mozilla::gfx; - -nsContainerFrame* NS_NewBoxFrame(PresShell* aPresShell, ComputedStyle* aStyle) { - return new (aPresShell) nsBoxFrame(aStyle, aPresShell->GetPresContext()); -} - -NS_IMPL_FRAMEARENA_HELPERS(nsBoxFrame) - -#ifdef DEBUG -NS_QUERYFRAME_HEAD(nsBoxFrame) - NS_QUERYFRAME_ENTRY(nsBoxFrame) -NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame) -#endif - -nsBoxFrame::nsBoxFrame(ComputedStyle* aStyle, nsPresContext* aPresContext, - ClassID aID) - : nsContainerFrame(aStyle, aPresContext, aID), mAscent(0) { - AddStateBits(NS_STATE_IS_HORIZONTAL | NS_STATE_AUTO_STRETCH); - - mValign = vAlign_Top; - mHalign = hAlign_Left; - - // Use the static sprocket layout - nsCOMPtr layout; - NS_NewSprocketLayout(layout); - SetXULLayoutManager(layout); -} - -nsBoxFrame::~nsBoxFrame() = default; - -void nsBoxFrame::SetInitialChildList(ChildListID aListID, - nsFrameList&& aChildList) { - nsContainerFrame::SetInitialChildList(aListID, std::move(aChildList)); - if (aListID == FrameChildListID::Principal) { - // initialize our list of infos. - nsBoxLayoutState state(PresContext()); - if (mLayoutManager) - mLayoutManager->ChildrenSet(this, state, mFrames.FirstChild()); - } -} - -/* virtual */ -void nsBoxFrame::DidSetComputedStyle(ComputedStyle* aOldComputedStyle) { - nsContainerFrame::DidSetComputedStyle(aOldComputedStyle); - - // The values that CacheAttributes() computes depend on our style, - // so we need to recompute them here... - CacheAttributes(); -} - -/** - * Initialize us. This is a good time to get the alignment of the box - */ -void nsBoxFrame::Init(nsIContent* aContent, nsContainerFrame* aParent, - nsIFrame* aPrevInFlow) { - nsContainerFrame::Init(aContent, aParent, aPrevInFlow); - - if (HasAnyStateBits(NS_FRAME_FONT_INFLATION_CONTAINER)) { - AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT); - } - - MarkIntrinsicISizesDirty(); - - CacheAttributes(); -} - -void nsBoxFrame::CacheAttributes() { - /* - printf("Caching: "); - XULDumpBox(stdout); - printf("\n"); - */ - - mValign = vAlign_Top; - mHalign = hAlign_Left; - - bool orient = false; - GetInitialOrientation(orient); - if (orient) - AddStateBits(NS_STATE_IS_HORIZONTAL); - else - RemoveStateBits(NS_STATE_IS_HORIZONTAL); - - bool normal = true; - GetInitialDirection(normal); - if (normal) - AddStateBits(NS_STATE_IS_DIRECTION_NORMAL); - else - RemoveStateBits(NS_STATE_IS_DIRECTION_NORMAL); - - GetInitialVAlignment(mValign); - GetInitialHAlignment(mHalign); - - bool autostretch = HasAnyStateBits(NS_STATE_AUTO_STRETCH); - GetInitialAutoStretch(autostretch); - if (autostretch) - AddStateBits(NS_STATE_AUTO_STRETCH); - else - RemoveStateBits(NS_STATE_AUTO_STRETCH); -} - -bool nsBoxFrame::GetInitialHAlignment(nsBoxFrame::Halignment& aHalign) { - if (!GetContent()) return false; - - // For horizontal boxes we're checking PACK. For vertical boxes we are - // checking ALIGN. - const nsStyleXUL* boxInfo = StyleXUL(); - if (IsXULHorizontal()) { - switch (boxInfo->mBoxPack) { - case StyleBoxPack::Start: - aHalign = nsBoxFrame::hAlign_Left; - return true; - case StyleBoxPack::Center: - aHalign = nsBoxFrame::hAlign_Center; - return true; - case StyleBoxPack::End: - aHalign = nsBoxFrame::hAlign_Right; - return true; - default: // Nonsensical value. Just bail. - return false; - } - } else { - switch (boxInfo->mBoxAlign) { - case StyleBoxAlign::Start: - aHalign = nsBoxFrame::hAlign_Left; - return true; - case StyleBoxAlign::Center: - aHalign = nsBoxFrame::hAlign_Center; - return true; - case StyleBoxAlign::End: - aHalign = nsBoxFrame::hAlign_Right; - return true; - default: // Nonsensical value. Just bail. - return false; - } - } -} - -bool nsBoxFrame::GetInitialVAlignment(nsBoxFrame::Valignment& aValign) { - if (!GetContent()) return false; - // For horizontal boxes we're checking ALIGN. For vertical boxes we are - // checking PACK. - const nsStyleXUL* boxInfo = StyleXUL(); - if (IsXULHorizontal()) { - switch (boxInfo->mBoxAlign) { - case StyleBoxAlign::Start: - aValign = nsBoxFrame::vAlign_Top; - return true; - case StyleBoxAlign::Center: - aValign = nsBoxFrame::vAlign_Middle; - return true; - case StyleBoxAlign::Baseline: - aValign = nsBoxFrame::vAlign_BaseLine; - return true; - case StyleBoxAlign::End: - aValign = nsBoxFrame::vAlign_Bottom; - return true; - default: // Nonsensical value. Just bail. - return false; - } - } else { - switch (boxInfo->mBoxPack) { - case StyleBoxPack::Start: - aValign = nsBoxFrame::vAlign_Top; - return true; - case StyleBoxPack::Center: - aValign = nsBoxFrame::vAlign_Middle; - return true; - case StyleBoxPack::End: - aValign = nsBoxFrame::vAlign_Bottom; - return true; - default: // Nonsensical value. Just bail. - return false; - } - } -} - -void nsBoxFrame::GetInitialOrientation(bool& aIsHorizontal) { - // see if we are a vertical or horizontal box. - if (!GetContent()) return; - - const nsStyleXUL* boxInfo = StyleXUL(); - if (boxInfo->mBoxOrient == StyleBoxOrient::Horizontal) { - aIsHorizontal = true; - } else { - aIsHorizontal = false; - } -} - -void nsBoxFrame::GetInitialDirection(bool& aIsNormal) { - if (!GetContent()) return; - - if (IsXULHorizontal()) { - // For horizontal boxes only, we initialize our value based off the CSS - // 'direction' property. This means that BiDI users will end up with - // horizontally inverted chrome. - // - // If text runs RTL then so do we. - aIsNormal = StyleVisibility()->mDirection == StyleDirection::Ltr; - if (GetContent()->IsElement()) { - Element* element = GetContent()->AsElement(); - - // Now see if we have an attribute. The attribute overrides - // the style system 'direction' property. - static Element::AttrValuesArray strings[] = {nsGkAtoms::ltr, - nsGkAtoms::rtl, nullptr}; - int32_t index = element->FindAttrValueIn( - kNameSpaceID_None, nsGkAtoms::dir, strings, eCaseMatters); - if (index >= 0) { - bool values[] = {true, false}; - aIsNormal = values[index]; - } - } - } else { - aIsNormal = true; // Assume a normal direction in the vertical case. - } - - // Now check the style system to see if we should invert aIsNormal. - const nsStyleXUL* boxInfo = StyleXUL(); - if (boxInfo->mBoxDirection == StyleBoxDirection::Reverse) { - aIsNormal = !aIsNormal; // Invert our direction. - } -} - -/* Returns true if it was set. - */ -bool nsBoxFrame::GetInitialAutoStretch(bool& aStretch) { - if (!GetContent()) return false; - - // Check the CSS box-align property. - const nsStyleXUL* boxInfo = StyleXUL(); - aStretch = (boxInfo->mBoxAlign == StyleBoxAlign::Stretch); - - return true; -} - -void nsBoxFrame::DidReflow(nsPresContext* aPresContext, - const ReflowInput* aReflowInput) { - nsFrameState preserveBits = - GetStateBits() & (NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN); - nsIFrame::DidReflow(aPresContext, aReflowInput); - AddStateBits(preserveBits); - if (preserveBits & NS_FRAME_IS_DIRTY) { - this->MarkSubtreeDirty(); - } -} - -#ifdef DO_NOISY_REFLOW -static int myCounter = 0; -static void printSize(char* aDesc, nscoord aSize) { - printf(" %s: ", aDesc); - if (aSize == NS_UNCONSTRAINEDSIZE) { - printf("UC"); - } else { - printf("%d", aSize); - } -} -#endif - -/* virtual */ -nscoord nsBoxFrame::GetMinISize(gfxContext* aRenderingContext) { - nscoord result; - DISPLAY_MIN_INLINE_SIZE(this, result); - - nsBoxLayoutState state(PresContext(), aRenderingContext); - nsSize minSize = GetXULMinSize(state); - - // GetXULMinSize returns border-box width, and we want to return content - // width. Since Reflow uses the reflow input's border and padding, we - // actually just want to subtract what GetXULMinSize added, which is the - // result of GetXULBorderAndPadding. - nsMargin bp; - GetXULBorderAndPadding(bp); - - result = minSize.width - bp.LeftRight(); - result = std::max(result, 0); - - return result; -} - -/* virtual */ -nscoord nsBoxFrame::GetPrefISize(gfxContext* aRenderingContext) { - nscoord result; - DISPLAY_PREF_INLINE_SIZE(this, result); - - nsBoxLayoutState state(PresContext(), aRenderingContext); - nsSize prefSize = GetXULPrefSize(state); - - // GetXULPrefSize returns border-box width, and we want to return content - // width. Since Reflow uses the reflow input's border and padding, we - // actually just want to subtract what GetXULPrefSize added, which is the - // result of GetXULBorderAndPadding. - nsMargin bp; - GetXULBorderAndPadding(bp); - - result = prefSize.width - bp.LeftRight(); - result = std::max(result, 0); - - return result; -} - -void nsBoxFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, - const ReflowInput& aReflowInput, - nsReflowStatus& aStatus) { - MarkInReflow(); - // If you make changes to this method, please keep nsLeafBoxFrame::Reflow - // in sync, if the changes are applicable there. - - DO_GLOBAL_REFLOW_COUNT("nsBoxFrame"); - DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); - MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); - - NS_ASSERTION( - aReflowInput.ComputedWidth() >= 0 && aReflowInput.ComputedHeight() >= 0, - "Computed Size < 0"); - -#ifdef DO_NOISY_REFLOW - printf( - "\n-------------Starting BoxFrame Reflow ----------------------------\n"); - printf("%p ** nsBF::Reflow %d ", this, myCounter++); - - printSize("AW", aReflowInput.AvailableWidth()); - printSize("AH", aReflowInput.AvailableHeight()); - printSize("CW", aReflowInput.ComputedWidth()); - printSize("CH", aReflowInput.ComputedHeight()); - - printf(" *\n"); - -#endif - - // create the layout state - nsBoxLayoutState state(aPresContext, aReflowInput.mRenderingContext, - &aReflowInput, aReflowInput.mReflowDepth); - - WritingMode wm = aReflowInput.GetWritingMode(); - LogicalSize computedSize = aReflowInput.ComputedSize(); - - LogicalMargin m = aReflowInput.ComputedLogicalBorderPadding(wm); - // GetXULBorderAndPadding(m); - - LogicalSize prefSize(wm); - - // if we are told to layout intrinsic then get our preferred size. - NS_ASSERTION(computedSize.ISize(wm) != NS_UNCONSTRAINEDSIZE, - "computed inline size should always be computed"); - if (computedSize.BSize(wm) == NS_UNCONSTRAINEDSIZE) { - nsSize physicalPrefSize = GetXULPrefSize(state); - nsSize minSize = GetXULMinSize(state); - nsSize maxSize = GetXULMaxSize(state); - // XXXbz isn't GetXULPrefSize supposed to bounds-check for us? - physicalPrefSize = XULBoundsCheck(minSize, physicalPrefSize, maxSize); - prefSize = LogicalSize(wm, physicalPrefSize); - } - - // get our desiredSize - computedSize.ISize(wm) += m.IStart(wm) + m.IEnd(wm); - - if (aReflowInput.ComputedBSize() == NS_UNCONSTRAINEDSIZE) { - computedSize.BSize(wm) = prefSize.BSize(wm); - // prefSize is border-box but min/max constraints are content-box. - nscoord blockDirBorderPadding = - aReflowInput.ComputedLogicalBorderPadding(wm).BStartEnd(wm); - nscoord contentBSize = computedSize.BSize(wm) - blockDirBorderPadding; - // Note: contentHeight might be negative, but that's OK because min-height - // is never negative. - computedSize.BSize(wm) = - aReflowInput.ApplyMinMaxHeight(contentBSize) + blockDirBorderPadding; - } else { - computedSize.BSize(wm) += m.BStart(wm) + m.BEnd(wm); - } - - nsSize physicalSize = computedSize.GetPhysicalSize(wm); - nsRect r(mRect.x, mRect.y, physicalSize.width, physicalSize.height); - - SetXULBounds(state, r); - - // layout our children - XULLayout(state); - - // ok our child could have gotten bigger. So lets get its bounds - - // get the ascent - LogicalSize boxSize = GetLogicalSize(wm); - nscoord ascent = boxSize.BSize(wm); - - // getting the ascent could be a lot of work. Don't get it if - // we are the root. The viewport doesn't care about it. - if (!Style()->IsRootElementStyle()) { - ascent = GetXULBoxAscent(state); - } - - aDesiredSize.SetSize(wm, boxSize); - aDesiredSize.SetBlockStartAscent(ascent); - - aDesiredSize.mOverflowAreas = GetOverflowAreas(); - -#ifdef DO_NOISY_REFLOW - { - printf("%p ** nsBF(done) W:%d H:%d ", this, aDesiredSize.Width(), - aDesiredSize.Height()); - - if (maxElementSize) { - printf("MW:%d\n", *maxElementWidth); - } else { - printf("MW:?\n"); - } - } -#endif - - ReflowAbsoluteFrames(aPresContext, aDesiredSize, aReflowInput, aStatus); -} - -nsSize nsBoxFrame::GetXULPrefSize(nsBoxLayoutState& aBoxLayoutState) { - NS_ASSERTION(aBoxLayoutState.GetRenderingContext(), - "must have rendering context"); - - nsSize size(0, 0); - DISPLAY_PREF_SIZE(this, size); - if (!XULNeedsRecalc(mPrefSize)) { - size = mPrefSize; - return size; - } - - if (IsXULCollapsed()) return size; - - // if the size was not completely redefined in CSS then ask our children - bool widthSet, heightSet; - if (!nsIFrame::AddXULPrefSize(this, size, widthSet, heightSet)) { - if (mLayoutManager) { - nsSize layoutSize = mLayoutManager->GetXULPrefSize(this, aBoxLayoutState); - if (!widthSet) size.width = layoutSize.width; - if (!heightSet) size.height = layoutSize.height; - } else { - size = nsIFrame::GetUncachedXULPrefSize(aBoxLayoutState); - } - } - - nsSize minSize = GetXULMinSize(aBoxLayoutState); - nsSize maxSize = GetXULMaxSize(aBoxLayoutState); - mPrefSize = XULBoundsCheck(minSize, size, maxSize); - - return mPrefSize; -} - -nscoord nsBoxFrame::GetXULBoxAscent(nsBoxLayoutState& aBoxLayoutState) { - if (!XULNeedsRecalc(mAscent)) { - return mAscent; - } - - if (IsXULCollapsed()) { - return 0; - } - - if (mLayoutManager) { - mAscent = mLayoutManager->GetAscent(this, aBoxLayoutState); - } else { - mAscent = GetXULPrefSize(aBoxLayoutState).height; - } - - return mAscent; -} - -nsSize nsBoxFrame::GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) { - NS_ASSERTION(aBoxLayoutState.GetRenderingContext(), - "must have rendering context"); - - nsSize size(0, 0); - DISPLAY_MIN_SIZE(this, size); - if (!XULNeedsRecalc(mMinSize)) { - size = mMinSize; - return size; - } - - if (IsXULCollapsed()) return size; - - // if the size was not completely redefined in CSS then ask our children - bool widthSet, heightSet; - if (!nsIFrame::AddXULMinSize(this, size, widthSet, heightSet)) { - if (mLayoutManager) { - nsSize layoutSize = mLayoutManager->GetXULMinSize(this, aBoxLayoutState); - if (!widthSet) size.width = layoutSize.width; - if (!heightSet) size.height = layoutSize.height; - } else { - size = nsIFrame::GetUncachedXULMinSize(aBoxLayoutState); - } - } - - mMinSize = size; - - return size; -} - -nsSize nsBoxFrame::GetXULMaxSize(nsBoxLayoutState& aBoxLayoutState) { - NS_ASSERTION(aBoxLayoutState.GetRenderingContext(), - "must have rendering context"); - - nsSize size(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); - DISPLAY_MAX_SIZE(this, size); - if (!XULNeedsRecalc(mMaxSize)) { - size = mMaxSize; - return size; - } - - if (IsXULCollapsed()) return size; - - // if the size was not completely redefined in CSS then ask our children - bool widthSet, heightSet; - if (!nsIFrame::AddXULMaxSize(this, size, widthSet, heightSet)) { - if (mLayoutManager) { - nsSize layoutSize = mLayoutManager->GetXULMaxSize(this, aBoxLayoutState); - if (!widthSet) size.width = layoutSize.width; - if (!heightSet) size.height = layoutSize.height; - } else { - size = nsIFrame::GetUncachedXULMaxSize(aBoxLayoutState); - } - } - - mMaxSize = size; - - return size; -} - -/** - * If subclassing please subclass this method not layout. - * layout will call this method. - */ -NS_IMETHODIMP -nsBoxFrame::DoXULLayout(nsBoxLayoutState& aState) { - ReflowChildFlags oldFlags = aState.LayoutFlags(); - aState.SetLayoutFlags(ReflowChildFlags::Default); - - nsresult rv = NS_OK; - if (mLayoutManager) { - XULCoordNeedsRecalc(mAscent); - rv = mLayoutManager->XULLayout(this, aState); - } - - aState.SetLayoutFlags(oldFlags); - - if (HasAbsolutelyPositionedChildren()) { - // Set up a |reflowInput| to pass into ReflowAbsoluteFrames - WritingMode wm = GetWritingMode(); - ReflowInput reflowInput( - aState.PresContext(), this, aState.GetRenderingContext(), - LogicalSize(wm, GetLogicalSize().ISize(wm), NS_UNCONSTRAINEDSIZE)); - - // Set up a |desiredSize| to pass into ReflowAbsoluteFrames - ReflowOutput desiredSize(reflowInput); - desiredSize.Width() = mRect.width; - desiredSize.Height() = mRect.height; - - // get the ascent (cribbed from ::Reflow) - nscoord ascent = mRect.height; - - // getting the ascent could be a lot of work. Don't get it if - // we are the root. The viewport doesn't care about it. - if (!Style()->IsRootElementStyle()) { - ascent = GetXULBoxAscent(aState); - } - desiredSize.SetBlockStartAscent(ascent); - desiredSize.mOverflowAreas = GetOverflowAreas(); - - AddStateBits(NS_FRAME_IN_REFLOW); - // Set up a |reflowStatus| to pass into ReflowAbsoluteFrames - // (just a dummy value; hopefully that's OK) - nsReflowStatus reflowStatus; - ReflowAbsoluteFrames(aState.PresContext(), desiredSize, reflowInput, - reflowStatus); - RemoveStateBits(NS_FRAME_IN_REFLOW); - } - - return rv; -} - -void nsBoxFrame::DestroyFrom(nsIFrame* aDestructRoot, - PostDestroyData& aPostDestroyData) { - // clean up the container box's layout manager and child boxes - SetXULLayoutManager(nullptr); - - nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData); -} - -/* virtual */ -void nsBoxFrame::MarkIntrinsicISizesDirty() { - XULSizeNeedsRecalc(mPrefSize); - XULSizeNeedsRecalc(mMinSize); - XULSizeNeedsRecalc(mMaxSize); - XULCoordNeedsRecalc(mAscent); - - if (mLayoutManager) { - nsBoxLayoutState state(PresContext()); - mLayoutManager->IntrinsicISizesDirty(this, state); - } - - nsContainerFrame::MarkIntrinsicISizesDirty(); -} - -void nsBoxFrame::RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) { - MOZ_ASSERT(aListID == FrameChildListID::Principal, - "We don't support out-of-flow kids"); - - nsPresContext* presContext = PresContext(); - nsBoxLayoutState state(presContext); - - // remove the child frame - mFrames.RemoveFrame(aOldFrame); - - // notify the layout manager - if (mLayoutManager) mLayoutManager->ChildrenRemoved(this, state, aOldFrame); - - // destroy the child frame - aOldFrame->Destroy(); - - // mark us dirty and generate a reflow command - PresShell()->FrameNeedsReflow(this, IntrinsicDirty::FrameAndAncestors, - NS_FRAME_HAS_DIRTY_CHILDREN); -} - -void nsBoxFrame::InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - const nsLineList::iterator* aPrevFrameLine, - nsFrameList&& aFrameList) { - NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this, - "inserting after sibling frame with different parent"); - NS_ASSERTION(!aPrevFrame || mFrames.ContainsFrame(aPrevFrame), - "inserting after sibling frame not in our child list"); - MOZ_ASSERT(aListID == FrameChildListID::Principal, - "We don't support out-of-flow kids"); - - nsBoxLayoutState state(PresContext()); - - // insert the child frames - const nsFrameList::Slice& newFrames = - mFrames.InsertFrames(this, aPrevFrame, std::move(aFrameList)); - - // notify the layout manager - if (mLayoutManager) - mLayoutManager->ChildrenInserted(this, state, aPrevFrame, newFrames); - - PresShell()->FrameNeedsReflow(this, IntrinsicDirty::FrameAndAncestors, - NS_FRAME_HAS_DIRTY_CHILDREN); -} - -void nsBoxFrame::AppendFrames(ChildListID aListID, nsFrameList&& aFrameList) { - MOZ_ASSERT(aListID == FrameChildListID::Principal, - "We don't support out-of-flow kids"); - - nsBoxLayoutState state(PresContext()); - - // append the new frames - const nsFrameList::Slice& newFrames = - mFrames.AppendFrames(this, std::move(aFrameList)); - - // notify the layout manager - if (mLayoutManager) mLayoutManager->ChildrenAppended(this, state, newFrames); - - // XXXbz why is this NS_FRAME_FIRST_REFLOW check here? - if (!HasAnyStateBits(NS_FRAME_FIRST_REFLOW)) { - PresShell()->FrameNeedsReflow(this, IntrinsicDirty::FrameAndAncestors, - NS_FRAME_HAS_DIRTY_CHILDREN); - } -} - -nsresult nsBoxFrame::AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, - int32_t aModType) { - nsresult rv = - nsContainerFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType); - - // Ignore 'width', 'height', 'screenX', 'screenY' and 'sizemode' on a - // . - if (mContent->IsXULElement(nsGkAtoms::window) && - (nsGkAtoms::width == aAttribute || nsGkAtoms::height == aAttribute || - nsGkAtoms::screenX == aAttribute || nsGkAtoms::screenY == aAttribute || - nsGkAtoms::sizemode == aAttribute)) { - return rv; - } - - if (aAttribute == nsGkAtoms::width || aAttribute == nsGkAtoms::height || - aAttribute == nsGkAtoms::align || aAttribute == nsGkAtoms::valign || - aAttribute == nsGkAtoms::minwidth || aAttribute == nsGkAtoms::maxwidth || - aAttribute == nsGkAtoms::minheight || - aAttribute == nsGkAtoms::maxheight || aAttribute == nsGkAtoms::orient || - aAttribute == nsGkAtoms::pack || aAttribute == nsGkAtoms::dir) { - if (aAttribute == nsGkAtoms::align || aAttribute == nsGkAtoms::valign || - aAttribute == nsGkAtoms::orient || aAttribute == nsGkAtoms::pack || - aAttribute == nsGkAtoms::dir) { - mValign = nsBoxFrame::vAlign_Top; - mHalign = nsBoxFrame::hAlign_Left; - - bool orient = true; - GetInitialOrientation(orient); - if (orient) - AddStateBits(NS_STATE_IS_HORIZONTAL); - else - RemoveStateBits(NS_STATE_IS_HORIZONTAL); - - bool normal = true; - GetInitialDirection(normal); - if (normal) - AddStateBits(NS_STATE_IS_DIRECTION_NORMAL); - else - RemoveStateBits(NS_STATE_IS_DIRECTION_NORMAL); - - GetInitialVAlignment(mValign); - GetInitialHAlignment(mHalign); - - bool autostretch = HasAnyStateBits(NS_STATE_AUTO_STRETCH); - GetInitialAutoStretch(autostretch); - if (autostretch) - AddStateBits(NS_STATE_AUTO_STRETCH); - else - RemoveStateBits(NS_STATE_AUTO_STRETCH); - } - - PresShell()->FrameNeedsReflow( - this, IntrinsicDirty::FrameAncestorsAndDescendants, NS_FRAME_IS_DIRTY); - } else if (aAttribute == nsGkAtoms::rows && - mContent->IsXULElement(nsGkAtoms::tree)) { - // Reflow ourselves and all our children if "rows" changes, since - // nsTreeBodyFrame's layout reads this from its parent (this frame). - PresShell()->FrameNeedsReflow( - this, IntrinsicDirty::FrameAncestorsAndDescendants, NS_FRAME_IS_DIRTY); - } - - return rv; -} - -void nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsDisplayListSet& aLists) { - nsDisplayListCollection tempLists(aBuilder); - DisplayBorderBackgroundOutline(aBuilder, aLists); - - BuildDisplayListForChildren(aBuilder, aLists); - - // see if we have to draw a selection frame around this container - DisplaySelectionOverlay(aBuilder, aLists.Content()); -} - -void nsBoxFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, - const nsDisplayListSet& aLists) { - // Iterate over the children in CSS order. - auto iter = CSSOrderAwareFrameIterator( - this, FrameChildListID::Principal, - CSSOrderAwareFrameIterator::ChildFilter::IncludeAll, - CSSOrderAwareFrameIterator::OrderState::Unknown, - CSSOrderAwareFrameIterator::OrderingProperty::BoxOrdinalGroup); - // Put each child's background onto the BlockBorderBackgrounds list - // to emulate the existing two-layer XUL painting scheme. - nsDisplayListSet set(aLists, aLists.BlockBorderBackgrounds()); - for (; !iter.AtEnd(); iter.Next()) { - BuildDisplayListForChild(aBuilder, iter.get(), set); - } -} - -#ifdef DEBUG_FRAME_DUMP -nsresult nsBoxFrame::GetFrameName(nsAString& aResult) const { - return MakeFrameName(u"Box"_ns, aResult); -} -#endif - -nsresult nsBoxFrame::LayoutChildAt(nsBoxLayoutState& aState, nsIFrame* aBox, - const nsRect& aRect) { - // get the current rect - nsRect oldRect(aBox->GetRect()); - aBox->SetXULBounds(aState, aRect); - - bool layout = aBox->IsSubtreeDirty(); - - if (layout || - (oldRect.width != aRect.width || oldRect.height != aRect.height)) { - return aBox->XULLayout(aState); - } - - return NS_OK; -} diff --git a/layout/xul/nsBoxFrame.h b/layout/xul/nsBoxFrame.h deleted file mode 100644 index 9db5ea287dc5..000000000000 --- a/layout/xul/nsBoxFrame.h +++ /dev/null @@ -1,162 +0,0 @@ -/* -*- 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/. */ - -/** - - Eric D Vaughan - nsBoxFrame is a frame that can lay its children out either vertically or -horizontally. It lays them out according to a min max or preferred size. - -**/ - -#ifndef nsBoxFrame_h___ -#define nsBoxFrame_h___ - -#include "mozilla/Attributes.h" -#include "nsCOMPtr.h" -#include "nsContainerFrame.h" -#include "nsBoxLayout.h" - -class nsBoxLayoutState; - -namespace mozilla { -class PresShell; -namespace gfx { -class DrawTarget; -} // namespace gfx -} // namespace mozilla - -nsContainerFrame* NS_NewBoxFrame(mozilla::PresShell* aPresShell, - mozilla::ComputedStyle* aStyle); - -class nsBoxFrame : public nsContainerFrame { - protected: - typedef mozilla::gfx::DrawTarget DrawTarget; - - public: - NS_DECL_FRAMEARENA_HELPERS(nsBoxFrame) -#ifdef DEBUG - NS_DECL_QUERYFRAME -#endif - - friend nsContainerFrame* NS_NewBoxFrame(mozilla::PresShell* aPresShell, - ComputedStyle* aStyle); - - // gets the rect inside our border and debug border. If you wish to paint - // inside a box call this method to get the rect so you don't draw on the - // debug border or outer border. - - virtual void SetXULLayoutManager(nsBoxLayout* aLayout) override { - mLayoutManager = aLayout; - } - virtual nsBoxLayout* GetXULLayoutManager() override { return mLayoutManager; } - - virtual nsSize GetXULPrefSize(nsBoxLayoutState& aBoxLayoutState) override; - virtual nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) override; - virtual nsSize GetXULMaxSize(nsBoxLayoutState& aBoxLayoutState) override; - virtual nscoord GetXULBoxAscent(nsBoxLayoutState& aBoxLayoutState) override; - virtual Valignment GetXULVAlign() const override { return mValign; } - virtual Halignment GetXULHAlign() const override { return mHalign; } - NS_IMETHOD DoXULLayout(nsBoxLayoutState& aBoxLayoutState) override; - - virtual bool XULComputesOwnOverflowArea() override { return false; } - - // ----- child and sibling operations --- - - // ----- public methods ------- - - virtual void Init(nsIContent* aContent, nsContainerFrame* aParent, - nsIFrame* aPrevInFlow) override; - - virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, - int32_t aModType) override; - - virtual void MarkIntrinsicISizesDirty() override; - virtual nscoord GetMinISize(gfxContext* aRenderingContext) override; - virtual nscoord GetPrefISize(gfxContext* aRenderingContext) override; - - virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, - const ReflowInput& aReflowInput, - nsReflowStatus& aStatus) override; - - void SetInitialChildList(ChildListID aListID, - nsFrameList&& aChildList) override; - void AppendFrames(ChildListID aListID, nsFrameList&& aFrameList) override; - void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, - const nsLineList::iterator* aPrevFrameLine, - nsFrameList&& aFrameList) override; - virtual void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override; - - virtual void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override; - - virtual bool IsFrameOfType(uint32_t aFlags) const override { - // record that children that are ignorable whitespace should be excluded - // (When content was loaded via the XUL content sink, it's already - // been excluded, but we need this for when the XUL namespace is used - // in other MIME types or when the XUL CSS display types are used with - // non-XUL elements.) - - // This is bogus, but it's what we've always done. - // (Given that we're replaced, we need to say we're a replaced element - // that contains a block so ReflowInput doesn't tell us to be - // NS_UNCONSTRAINEDSIZE wide.) - return nsContainerFrame::IsFrameOfType( - aFlags & - ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock | eXULBox)); - } - -#ifdef DEBUG_FRAME_DUMP - virtual nsresult GetFrameName(nsAString& aResult) const override; -#endif - - virtual void DidReflow(nsPresContext* aPresContext, - const ReflowInput* aReflowInput) override; - - // virtual so nsButtonBoxFrame, nsSliderFrame and nsMenuFrame - // can override it - virtual void BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, - const nsDisplayListSet& aLists); - - virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, - const nsDisplayListSet& aLists) override; - - static nsresult LayoutChildAt(nsBoxLayoutState& aState, nsIFrame* aBox, - const nsRect& aRect); - - private: - explicit nsBoxFrame(ComputedStyle* aStyle, nsPresContext* aPresContext) - : nsBoxFrame(aStyle, aPresContext, kClassID) {} - - protected: - nsBoxFrame(ComputedStyle* aStyle, nsPresContext* aPresContext, ClassID aID); - virtual ~nsBoxFrame(); - - virtual void GetInitialOrientation(bool& aIsHorizontal); - virtual void GetInitialDirection(bool& aIsNormal); - virtual bool GetInitialHAlignment(Halignment& aHalign); - virtual bool GetInitialVAlignment(Valignment& aValign); - virtual bool GetInitialAutoStretch(bool& aStretch); - - virtual void DestroyFrom(nsIFrame* aDestructRoot, - PostDestroyData& aPostDestroyData) override; - - nsSize mPrefSize; - nsSize mMinSize; - nsSize mMaxSize; - nscoord mAscent; - - nsCOMPtr mLayoutManager; - - private: - void CacheAttributes(); - - // instance variables. - Halignment mHalign; - Valignment mValign; - -}; // class nsBoxFrame - -#endif diff --git a/layout/xul/nsBoxLayout.cpp b/layout/xul/nsBoxLayout.cpp deleted file mode 100644 index 81ee41103f9f..000000000000 --- a/layout/xul/nsBoxLayout.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* -*- 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/. */ - -// -// Eric Vaughan -// Netscape Communications -// -// See documentation in associated header file -// - -#include "nsCOMPtr.h" -#include "nsContainerFrame.h" -#include "nsBoxLayout.h" - -void nsBoxLayout::AddXULBorderAndPadding(nsIFrame* aBox, nsSize& aSize) { - nsIFrame::AddXULBorderAndPadding(aBox, aSize); -} - -void nsBoxLayout::AddXULMargin(nsIFrame* aChild, nsSize& aSize) { - nsIFrame::AddXULMargin(aChild, aSize); -} - -void nsBoxLayout::AddXULMargin(nsSize& aSize, const nsMargin& aMargin) { - nsIFrame::AddXULMargin(aSize, aMargin); -} - -nsSize nsBoxLayout::GetXULPrefSize(nsIFrame* aBox, - nsBoxLayoutState& aBoxLayoutState) { - nsSize pref(0, 0); - AddXULBorderAndPadding(aBox, pref); - - return pref; -} - -nsSize nsBoxLayout::GetXULMinSize(nsIFrame* aBox, - nsBoxLayoutState& aBoxLayoutState) { - nsSize minSize(0, 0); - AddXULBorderAndPadding(aBox, minSize); - return minSize; -} - -nsSize nsBoxLayout::GetXULMaxSize(nsIFrame* aBox, - nsBoxLayoutState& aBoxLayoutState) { - // AddXULBorderAndPadding () never changes maxSize (NS_UNCONSTRAINEDSIZE) - // AddXULBorderAndPadding(aBox, maxSize); - return nsSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); -} - -nscoord nsBoxLayout::GetAscent(nsIFrame* aBox, - nsBoxLayoutState& aBoxLayoutState) { - return 0; -} - -NS_IMETHODIMP -nsBoxLayout::XULLayout(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState) { - return NS_OK; -} - -void nsBoxLayout::AddLargestSize(nsSize& aSize, const nsSize& aSize2) { - if (aSize2.width > aSize.width) aSize.width = aSize2.width; - - if (aSize2.height > aSize.height) aSize.height = aSize2.height; -} - -void nsBoxLayout::AddSmallestSize(nsSize& aSize, const nsSize& aSize2) { - if (aSize2.width < aSize.width) aSize.width = aSize2.width; - - if (aSize2.height < aSize.height) aSize.height = aSize2.height; -} - -NS_IMPL_ISUPPORTS(nsBoxLayout, nsBoxLayout) diff --git a/layout/xul/nsBoxLayout.h b/layout/xul/nsBoxLayout.h deleted file mode 100644 index 404d7e768d5c..000000000000 --- a/layout/xul/nsBoxLayout.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- 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 nsBoxLayout_h___ -#define nsBoxLayout_h___ - -#include "nsISupports.h" -#include "nsCoord.h" -#include "nsFrameList.h" - -class nsIFrame; -class nsBoxLayoutState; -struct nsSize; -struct nsMargin; - -#define NS_BOX_LAYOUT_IID \ - { \ - 0x09d522a7, 0x304c, 0x4137, { \ - 0xaf, 0xc9, 0xe0, 0x80, 0x2e, 0x89, 0xb7, 0xe8 \ - } \ - } - -class nsBoxLayout : public nsISupports { - protected: - virtual ~nsBoxLayout() = default; - - public: - nsBoxLayout() = default; - - NS_DECL_ISUPPORTS - - NS_DECLARE_STATIC_IID_ACCESSOR(NS_BOX_LAYOUT_IID) - - NS_IMETHOD XULLayout(nsIFrame* aBox, nsBoxLayoutState& aState); - - virtual nsSize GetXULPrefSize(nsIFrame* aBox, - nsBoxLayoutState& aBoxLayoutState); - virtual nsSize GetXULMinSize(nsIFrame* aBox, - nsBoxLayoutState& aBoxLayoutState); - virtual nsSize GetXULMaxSize(nsIFrame* aBox, - nsBoxLayoutState& aBoxLayoutState); - virtual nscoord GetAscent(nsIFrame* aBox, nsBoxLayoutState& aBoxLayoutState); - virtual void ChildrenInserted(nsIFrame* aBox, nsBoxLayoutState& aState, - nsIFrame* aPrevBox, - const nsFrameList::Slice& aNewChildren) {} - virtual void ChildrenAppended(nsIFrame* aBox, nsBoxLayoutState& aState, - const nsFrameList::Slice& aNewChildren) {} - virtual void ChildrenRemoved(nsIFrame* aBox, nsBoxLayoutState& aState, - nsIFrame* aChildList) {} - virtual void ChildrenSet(nsIFrame* aBox, nsBoxLayoutState& aState, - nsIFrame* aChildList) {} - virtual void IntrinsicISizesDirty(nsIFrame* aBox, nsBoxLayoutState& aState) {} - - virtual void AddXULBorderAndPadding(nsIFrame* aBox, nsSize& aSize); - virtual void AddXULMargin(nsIFrame* aChild, nsSize& aSize); - virtual void AddXULMargin(nsSize& aSize, const nsMargin& aMargin); - - static void AddLargestSize(nsSize& aSize, const nsSize& aToAdd); - static void AddSmallestSize(nsSize& aSize, const nsSize& aToAdd); -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsBoxLayout, NS_BOX_LAYOUT_IID) - -#endif diff --git a/layout/xul/nsLeafBoxFrame.cpp b/layout/xul/nsLeafBoxFrame.cpp index c7e0a0b48423..0a0912113937 100644 --- a/layout/xul/nsLeafBoxFrame.cpp +++ b/layout/xul/nsLeafBoxFrame.cpp @@ -14,7 +14,6 @@ #include "mozilla/ComputedStyle.h" #include "mozilla/PresShell.h" #include "nsLeafBoxFrame.h" -#include "nsBoxFrame.h" #include "nsCOMPtr.h" #include "nsGkAtoms.h" #include "nsPresContext.h" @@ -128,11 +127,6 @@ void nsLeafBoxFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, const ReflowInput& aReflowInput, nsReflowStatus& aStatus) { - // This is mostly a copy of nsBoxFrame::Reflow(). - // We aren't able to share an implementation because of the frame - // class hierarchy. If you make changes here, please keep - // nsBoxFrame::Reflow in sync. - MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsLeafBoxFrame"); DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); diff --git a/layout/xul/nsSliderFrame.cpp b/layout/xul/nsSliderFrame.cpp index 605ddc651c63..b17ca21d4ab9 100644 --- a/layout/xul/nsSliderFrame.cpp +++ b/layout/xul/nsSliderFrame.cpp @@ -28,7 +28,6 @@ #include "nsScrollbarFrame.h" #include "nsRepeatService.h" #include "nsBoxLayoutState.h" -#include "nsSprocketLayout.h" #include "nsContentUtils.h" #include "nsLayoutUtils.h" #include "nsDisplayList.h" @@ -433,9 +432,9 @@ void nsSliderFrame::BuildDisplayListForThumb(nsDisplayListBuilder* aBuilder, // If this scrollbar is the scrollbar of an actively scrolled scroll frame, // layerize the scrollbar thumb, wrap it in its own ContainerLayer and // attach scrolling information to it. - // We do this here and not in the thumb's nsBoxFrame::BuildDisplayList so - // that the event region that gets created for the thumb is included in - // the nsDisplayOwnLayer contents. + // We do this here and not in the thumb's BuildDisplayList so that the event + // region that gets created for the thumb is included in the nsDisplayOwnLayer + // contents. const layers::ScrollableLayerGuid::ViewID scrollTargetId = aBuilder->GetCurrentScrollbarTarget(); diff --git a/layout/xul/nsSliderFrame.h b/layout/xul/nsSliderFrame.h index 8ea356b37d27..ce56c3f3990e 100644 --- a/layout/xul/nsSliderFrame.h +++ b/layout/xul/nsSliderFrame.h @@ -8,9 +8,8 @@ #define nsSliderFrame_h__ #include "mozilla/Attributes.h" -#include "nsIFrame.h" +#include "nsContainerFrame.h" #include "nsRepeatService.h" -#include "nsBoxFrame.h" #include "nsAtom.h" #include "nsCOMPtr.h" #include "nsITimer.h" diff --git a/layout/xul/nsSplitterFrame.cpp b/layout/xul/nsSplitterFrame.cpp index 579111a1c69d..2516c7996ac7 100644 --- a/layout/xul/nsSplitterFrame.cpp +++ b/layout/xul/nsSplitterFrame.cpp @@ -13,7 +13,6 @@ #include "SimpleXULLeafFrame.h" #include "gfxContext.h" -#include "nsBoxFrame.h" #include "nsSplitterFrame.h" #include "nsGkAtoms.h" #include "nsXULElement.h" diff --git a/layout/xul/nsSprocketLayout.cpp b/layout/xul/nsSprocketLayout.cpp deleted file mode 100644 index 00cdb6656173..000000000000 --- a/layout/xul/nsSprocketLayout.cpp +++ /dev/null @@ -1,1357 +0,0 @@ -/* -*- 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/. */ - -// -// Eric Vaughan -// Netscape Communications -// -// See documentation in associated header file -// - -#include "nsBoxLayoutState.h" -#include "nsSprocketLayout.h" -#include "nsPresContext.h" -#include "nsCOMPtr.h" -#include "nsIContent.h" -#include "nsContainerFrame.h" -#include "nsBoxFrame.h" -#include "StackArena.h" -#include "mozilla/Likely.h" -#include "mozilla/CSSOrderAwareFrameIterator.h" -#include - -using mozilla::StyleDirection; -using namespace mozilla; - -nsBoxLayout* nsSprocketLayout::gInstance = nullptr; - -static Maybe IterFor(nsIFrame* aBoxFrame) { - Maybe ret; - if (aBoxFrame->IsXULBoxFrame()) { - ret.emplace(aBoxFrame, FrameChildListID::Principal, - CSSOrderAwareFrameIterator::ChildFilter::IncludeAll); - } - return ret; -} - -nsresult NS_NewSprocketLayout(nsCOMPtr& aNewLayout) { - if (!nsSprocketLayout::gInstance) { - nsSprocketLayout::gInstance = new nsSprocketLayout(); - NS_IF_ADDREF(nsSprocketLayout::gInstance); - } - // we have not instance variables so just return our static one. - aNewLayout = nsSprocketLayout::gInstance; - return NS_OK; -} - -/*static*/ -void nsSprocketLayout::Shutdown() { NS_IF_RELEASE(gInstance); } - -nsSprocketLayout::nsSprocketLayout() = default; - -bool nsSprocketLayout::IsXULHorizontal(nsIFrame* aBox) { - return aBox->HasAnyStateBits(NS_STATE_IS_HORIZONTAL); -} - -static StyleDirection GetFrameDirection(nsIFrame* aBox) { - return aBox->StyleVisibility()->mDirection; -} - -static void HandleBoxPack(nsIFrame* aBox, nscoord& aX, nscoord& aY, - const nsRect& aOriginalRect, - const nsRect& aClientRect) { - // In the normal direction we lay out our kids in the positive direction - // (e.g., |x| will get bigger for a horizontal box, and |y| will get bigger - // for a vertical box). In the reverse direction, the opposite is true. We'll - // be laying out each child at a smaller |x| or |y|. - StyleDirection frameDirection = GetFrameDirection(aBox); - - if (aBox->HasAnyStateBits(NS_STATE_IS_HORIZONTAL)) { - if (aBox->HasAnyStateBits(NS_STATE_IS_DIRECTION_NORMAL)) { - // The normal direction. |x| increases as we move through our children. - aX = aClientRect.x; - } else { - // The reverse direction. |x| decreases as we move through our children. - aX = aClientRect.x + aOriginalRect.width; - } - // |y| is always in the normal direction in horizontal boxes - aY = aClientRect.y; - } else { - // take direction property into account for |x| in vertical boxes - if (frameDirection == StyleDirection::Ltr) { - // The normal direction. |x| increases as we move through our children. - aX = aClientRect.x; - } else { - // The reverse direction. |x| decreases as we move through our children. - aX = aClientRect.x + aOriginalRect.width; - } - if (aBox->HasAnyStateBits(NS_STATE_IS_DIRECTION_NORMAL)) { - // The normal direction. |y| increases as we move through our children. - aY = aClientRect.y; - } else { - // The reverse direction. |y| decreases as we move through our children. - aY = aClientRect.y + aOriginalRect.height; - } - } - - // Get our pack/alignment information. - nsIFrame::Halignment halign = aBox->GetXULHAlign(); - nsIFrame::Valignment valign = aBox->GetXULVAlign(); - - // The following code handles box PACKING. Packing comes into play in the - // case where the computed size for all of our children (now stored in our - // client rect) is smaller than the size available for the box (stored in - // |aOriginalRect|). - // - // Here we adjust our |x| and |y| variables accordingly so that we start at - // the beginning, middle, or end of the box. - // - // XXXdwh JUSTIFY needs to be implemented! - if (aBox->HasAnyStateBits(NS_STATE_IS_HORIZONTAL)) { - switch (halign) { - case nsBoxFrame::hAlign_Left: - break; // Nothing to do. The default initialized us properly. - - case nsBoxFrame::hAlign_Center: - if (aBox->HasAnyStateBits(NS_STATE_IS_DIRECTION_NORMAL)) - aX += (aOriginalRect.width - aClientRect.width) / 2; - else - aX -= (aOriginalRect.width - aClientRect.width) / 2; - break; - - case nsBoxFrame::hAlign_Right: - if (aBox->HasAnyStateBits(NS_STATE_IS_DIRECTION_NORMAL)) - aX += (aOriginalRect.width - aClientRect.width); - else - aX -= (aOriginalRect.width - aClientRect.width); - break; // Nothing to do for the reverse dir. The default initialized - // us properly. - } - } else { - switch (valign) { - case nsBoxFrame::vAlign_Top: - case nsBoxFrame::vAlign_BaseLine: // This value is technically impossible - // to specify for pack. - break; // Don't do anything. We were initialized correctly. - - case nsBoxFrame::vAlign_Middle: - if (aBox->HasAnyStateBits(NS_STATE_IS_DIRECTION_NORMAL)) - aY += (aOriginalRect.height - aClientRect.height) / 2; - else - aY -= (aOriginalRect.height - aClientRect.height) / 2; - break; - - case nsBoxFrame::vAlign_Bottom: - if (aBox->HasAnyStateBits(NS_STATE_IS_DIRECTION_NORMAL)) - aY += (aOriginalRect.height - aClientRect.height); - else - aY -= (aOriginalRect.height - aClientRect.height); - break; - } - } -} - -NS_IMETHODIMP -nsSprocketLayout::XULLayout(nsIFrame* aBox, nsBoxLayoutState& aState) { - // See if we are collapsed. If we are, then simply iterate over all our - // children and give them a rect of 0 width and height. - if (aBox->IsXULCollapsed()) { - for (auto iter = IterFor(aBox); iter && !iter->AtEnd(); iter->Next()) { - nsBoxFrame::LayoutChildAt(aState, iter->get(), nsRect(0, 0, 0, 0)); - } - return NS_OK; - } - - nsBoxLayoutState::AutoReflowDepth depth(aState); - mozilla::AutoStackArena arena; - - // ----- figure out our size ---------- - const nsSize originalSize = aBox->GetSize(); - - // -- make sure we remove our border and padding ---- - nsRect clientRect; - aBox->GetXULClientRect(clientRect); - - // |originalClientRect| represents the rect of the entire box (excluding - // borders and padding). We store it here because we're going to use - // |clientRect| to hold the required size for all our kids. As an example, - // consider an hbox with a specified width of 300. If the kids total only 150 - // pixels of width, then we have 150 pixels left over. |clientRect| is going - // to hold a width of 150 and is going to be adjusted based off the value of - // the PACK property. If flexible objects are in the box, then the two rects - // will match. - nsRect originalClientRect(clientRect); - - // Build a list of our children's desired sizes and computed sizes - nsBoxSize* boxSizes = nullptr; - nsComputedBoxSize* computedBoxSizes = nullptr; - - nscoord min = 0; - nscoord max = 0; - int32_t flexes = 0; - PopulateBoxSizes(aBox, aState, boxSizes, min, max, flexes); - - // The |size| variable will hold the total size of children along the axis of - // the box. Continuing with the example begun in the comment above, size - // would be 150 pixels. - nscoord size = clientRect.width; - if (!IsXULHorizontal(aBox)) size = clientRect.height; - ComputeChildSizes(aBox, aState, size, boxSizes, computedBoxSizes); - - // After the call to ComputeChildSizes, the |size| variable contains the - // total required size of all the children. We adjust our clientRect in the - // appropriate dimension to match this size. In our example, we now assign - // 150 pixels into the clientRect.width. - // - // The variables |min| and |max| hold the minimum required size box must be - // in the OPPOSITE orientation, e.g., for a horizontal box, |min| is the - // minimum height we require to enclose our children, and |max| is the maximum - // height required to enclose our children. - if (IsXULHorizontal(aBox)) { - clientRect.width = size; - if (clientRect.height < min) clientRect.height = min; - - if (aBox->HasAnyStateBits(NS_STATE_AUTO_STRETCH)) { - if (clientRect.height > max) clientRect.height = max; - } - } else { - clientRect.height = size; - if (clientRect.width < min) clientRect.width = min; - - if (aBox->HasAnyStateBits(NS_STATE_AUTO_STRETCH)) { - if (clientRect.width > max) clientRect.width = max; - } - } - - // With the sizes computed, now it's time to lay out our children. - bool finished; - nscoord passes = 0; - - // We flow children at their preferred locations (along with the appropriate - // computed flex). After we flow a child, it is possible that the child will - // change its size. If/when this happens, we have to do another pass. - // Typically only 2 passes are required, but the code is prepared to do as - // many passes as are necessary to achieve equilibrium. - nscoord x = 0; - nscoord y = 0; - nscoord origX = 0; - nscoord origY = 0; - - // |childResized| lets us know if a child changed its size after we attempted - // to lay it out at the specified size. If this happens, we usually have to - // do another pass. - bool childResized = false; - - // |passes| stores our number of passes. If for any reason we end up doing - // more than, say, 10 passes, we assert to indicate that something is - // seriously screwed up. - passes = 0; - do { - // Always assume that we're done. This will change if, for example, - // children don't stay the same size after being flowed. - finished = true; - - // Handle box packing. - HandleBoxPack(aBox, x, y, originalClientRect, clientRect); - - // Now that packing is taken care of we set up a few additional - // tracking variables. - origX = x; - origY = y; - - // Now we iterate over our box children and our box size lists in - // parallel. For each child, we look at its sizes and figure out - // where to place it. - nsComputedBoxSize* childComputedBoxSize = computedBoxSizes; - nsBoxSize* childBoxSize = boxSizes; - - auto iter = IterFor(aBox); - int32_t count = 0; - while ((iter && !iter->AtEnd()) || (childBoxSize && childBoxSize->bogus)) { - // If for some reason, our lists are not the same length, we guard - // by bailing out of the loop. - if (childBoxSize == nullptr) { - MOZ_ASSERT_UNREACHABLE("Lists not the same length."); - break; - } - - nscoord width = clientRect.width; - nscoord height = clientRect.height; - - if (!childBoxSize->bogus) { - nsIFrame* child = iter->get(); - - // We have a valid box size entry. This entry already contains - // information about our sizes along the axis of the box (e.g., widths - // in a horizontal box). If our default ALIGN is not stretch, however, - // then we also need to know the child's size along the opposite axis. - if (!aBox->HasAnyStateBits(NS_STATE_AUTO_STRETCH)) { - nsSize prefSize = child->GetXULPrefSize(aState); - nsSize minSize = child->GetXULMinSize(aState); - nsSize maxSize = child->GetXULMaxSize(aState); - prefSize = nsIFrame::XULBoundsCheck(minSize, prefSize, maxSize); - - AddXULMargin(child, prefSize); - width = std::min(prefSize.width, originalClientRect.width); - height = std::min(prefSize.height, originalClientRect.height); - } - } - - // Obtain the computed size along the axis of the box for this child from - // the computedBoxSize entry. We store the result in |width| for - // horizontal boxes and |height| for vertical boxes. - if (aBox->HasAnyStateBits(NS_STATE_IS_HORIZONTAL)) - width = childComputedBoxSize->size; - else - height = childComputedBoxSize->size; - - // Adjust our x/y for the left/right spacing. - if (aBox->HasAnyStateBits(NS_STATE_IS_HORIZONTAL)) { - if (aBox->HasAnyStateBits(NS_STATE_IS_DIRECTION_NORMAL)) - x += (childBoxSize->left); - else - x -= (childBoxSize->right); - } else { - if (aBox->HasAnyStateBits(NS_STATE_IS_DIRECTION_NORMAL)) - y += (childBoxSize->left); - else - y -= (childBoxSize->right); - } - - // Now we build a child rect. - nscoord rectX = x; - nscoord rectY = y; - if (!aBox->HasAnyStateBits(NS_STATE_IS_DIRECTION_NORMAL)) { - if (aBox->HasAnyStateBits(NS_STATE_IS_HORIZONTAL)) - rectX -= width; - else - rectY -= height; - } - - // We now create an accurate child rect based off our computed size - // information. - nsRect childRect(rectX, rectY, width, height); - - // Sanity check against our clientRect. It is possible that a child - // specified a size that is too large to fit. If that happens, then we - // have to grow our client rect. Remember, clientRect is not the total - // rect of the enclosing box. It currently holds our perception of how - // big the children needed to be. - if (childRect.width > clientRect.width) - clientRect.width = childRect.width; - - if (childRect.height > clientRect.height) - clientRect.height = childRect.height; - - // Either |nextX| or |nextY| is updated by this function call, according - // to our axis. - nscoord nextX = x; - nscoord nextY = y; - - ComputeChildsNextPosition(aBox, x, y, nextX, nextY, childRect); - - // Now we further update our nextX/Y along our axis. - // We also set childRect.y/x along the opposite axis appropriately for a - // stretch alignment. (Non-stretch alignment is handled below.) - if (aBox->HasAnyStateBits(NS_STATE_IS_HORIZONTAL)) { - if (aBox->HasAnyStateBits(NS_STATE_IS_DIRECTION_NORMAL)) - nextX += (childBoxSize->right); - else - nextX -= (childBoxSize->left); - childRect.y = originalClientRect.y; - } else { - if (aBox->HasAnyStateBits(NS_STATE_IS_DIRECTION_NORMAL)) - nextY += (childBoxSize->right); - else - nextY -= (childBoxSize->left); - if (GetFrameDirection(aBox) == StyleDirection::Ltr) { - childRect.x = originalClientRect.x; - } else { - // keep the right edge of the box the same - childRect.x = - clientRect.x + originalClientRect.width - childRect.width; - } - } - - // If we encounter a completely bogus box size, we just leave this child - // completely alone and continue through the loop to the next child. - if (childBoxSize->bogus) { - childComputedBoxSize = childComputedBoxSize->next; - childBoxSize = childBoxSize->next; - count++; - x = nextX; - y = nextY; - // FIXME(emilio): shouldn't this update `child` / `iter`? This looks - // broken. - continue; - } - - nsIFrame* child = iter->get(); - nsMargin margin(0, 0, 0, 0); - - bool layout = true; - - // Deflate the rect of our child by its margin. - child->GetXULMargin(margin); - childRect.Deflate(margin); - if (childRect.width < 0) childRect.width = 0; - if (childRect.height < 0) childRect.height = 0; - - // Now we're trying to figure out if we have to lay out this child, i.e., - // to call the child's XULLayout method. - if (passes > 0) { - layout = false; - } else { - // Always perform layout if we are dirty or have dirty children - if (!child->IsSubtreeDirty()) { - layout = false; - } - } - - nsRect oldRect(child->GetRect()); - - // Non-stretch alignment will be handled in AlignChildren(), so don't - // change child out-of-axis positions yet. - if (!aBox->HasAnyStateBits(NS_STATE_AUTO_STRETCH)) { - if (aBox->HasAnyStateBits(NS_STATE_IS_HORIZONTAL)) { - childRect.y = oldRect.y; - } else { - childRect.x = oldRect.x; - } - } - - // We computed a childRect. Now we want to set the bounds of the child to - // be that rect. If our old rect is different, then we know our size - // changed and we cache that fact in the |sizeChanged| variable. - - child->SetXULBounds(aState, childRect); - bool sizeChanged = (childRect.width != oldRect.width || - childRect.height != oldRect.height); - - if (sizeChanged) { - // Our size is different. Sanity check against our maximum allowed size - // to ensure we didn't exceed it. - nsSize minSize = child->GetXULMinSize(aState); - nsSize maxSize = child->GetXULMaxSize(aState); - maxSize = nsIFrame::XULBoundsCheckMinMax(minSize, maxSize); - - // make sure the size is in our max size. - if (childRect.width > maxSize.width) childRect.width = maxSize.width; - - if (childRect.height > maxSize.height) - childRect.height = maxSize.height; - - // set it again - child->SetXULBounds(aState, childRect); - } - - // If we already determined that layout was required or if our size has - // changed, then we make sure to call layout on the child, since its - // children may need to be shifted around as a result of the size change. - if (layout || sizeChanged) child->XULLayout(aState); - - // If the child was a block or inline (e.g., HTML) it may have changed its - // rect *during* layout. We have to check for this. - nsRect newChildRect(child->GetRect()); - - if (!newChildRect.IsEqualInterior(childRect)) { -#ifdef DEBUG_GROW - printf(" GREW from (%d,%d) -> (%d,%d)\n", childRect.width, - childRect.height, newChildRect.width, newChildRect.height); -#endif - newChildRect.Inflate(margin); - childRect.Inflate(margin); - - // The child changed size during layout. The ChildResized method - // handles this scenario. - ChildResized(aBox, aState, child, childBoxSize, childComputedBoxSize, - boxSizes, computedBoxSizes, childRect, newChildRect, - clientRect, flexes, finished); - - // We note that a child changed size, which means that another pass will - // be required. - childResized = true; - - // Now that a child resized, it's entirely possible that OUR rect is too - // small. Now we ensure that |originalClientRect| is grown to - // accommodate the size of |clientRect|. - if (clientRect.width > originalClientRect.width) - originalClientRect.width = clientRect.width; - - if (clientRect.height > originalClientRect.height) - originalClientRect.height = clientRect.height; - - if (!aBox->HasAnyStateBits(NS_STATE_IS_DIRECTION_NORMAL)) { - // Our childRect had its XMost() or YMost() (depending on our layout - // direction), positioned at a certain point. Ensure that the - // newChildRect satisfies the same constraint. Note that this is - // just equivalent to adjusting the x/y by the difference in - // width/height between childRect and newChildRect. So we don't need - // to reaccount for the left and right of the box layout state again. - if (aBox->HasAnyStateBits(NS_STATE_IS_HORIZONTAL)) - newChildRect.x = childRect.XMost() - newChildRect.width; - else - newChildRect.y = childRect.YMost() - newChildRect.height; - } - - if (!aBox->HasAnyStateBits(NS_STATE_IS_HORIZONTAL)) { - if (GetFrameDirection(aBox) != StyleDirection::Ltr) { - // keep the right edge the same - newChildRect.x = childRect.XMost() - newChildRect.width; - } - } - - // If the child resized then recompute its position. - ComputeChildsNextPosition(aBox, x, y, nextX, nextY, newChildRect); - - if (newChildRect.width >= margin.left + margin.right && - newChildRect.height >= margin.top + margin.bottom) - newChildRect.Deflate(margin); - - if (childRect.width >= margin.left + margin.right && - childRect.height >= margin.top + margin.bottom) - childRect.Deflate(margin); - - child->SetXULBounds(aState, newChildRect); - - // If we are the first box that changed size, then we don't need to do a - // second pass - if (count == 0) finished = true; - } - - // Now update our x/y finally. - x = nextX; - y = nextY; - - // Move to the next child. - childComputedBoxSize = childComputedBoxSize->next; - childBoxSize = childBoxSize->next; - - iter->Next(); - count++; - } - - // Sanity-checking code to ensure we don't do an infinite # of passes. - passes++; - NS_ASSERTION(passes < 10, "A Box's child is constantly growing!!!!!"); - if (passes >= 10) break; - } while (false == finished); - - // Get rid of our size lists. - while (boxSizes) { - nsBoxSize* toDelete = boxSizes; - boxSizes = boxSizes->next; - delete toDelete; - } - - while (computedBoxSizes) { - nsComputedBoxSize* toDelete = computedBoxSizes; - computedBoxSizes = computedBoxSizes->next; - delete toDelete; - } - - if (childResized) { - // See if one of our children forced us to get bigger - nsRect tmpClientRect(originalClientRect); - nsMargin bp(0, 0, 0, 0); - aBox->GetXULBorderAndPadding(bp); - tmpClientRect.Inflate(bp); - - if (tmpClientRect.width > originalSize.width || - tmpClientRect.height > originalSize.height) { - // if it did reset our bounds. - nsRect bounds(aBox->GetRect()); - if (tmpClientRect.width > originalSize.width) - bounds.width = tmpClientRect.width; - - if (tmpClientRect.height > originalSize.height) - bounds.height = tmpClientRect.height; - - aBox->SetXULBounds(aState, bounds); - } - } - - // Because our size grew, we now have to readjust because of box packing. - // Repack in order to update our x and y to the correct values. - HandleBoxPack(aBox, x, y, originalClientRect, clientRect); - - // Compare against our original x and y and only worry about adjusting the - // children if we really did have to change the positions because of packing - // (typically for 'center' or 'end' pack values). - if (x != origX || y != origY) { - // reposition all our children - for (auto iter = IterFor(aBox); iter && !iter->AtEnd(); iter->Next()) { - nsIFrame* child = iter->get(); - nsRect childRect(child->GetRect()); - childRect.x += (x - origX); - childRect.y += (y - origY); - child->SetXULBounds(aState, childRect); - } - } - - // Perform out-of-axis alignment for non-stretch alignments - if (!aBox->HasAnyStateBits(NS_STATE_AUTO_STRETCH)) { - AlignChildren(aBox, aState); - } - - // That's it! If you made it this far without having a nervous breakdown, - // congratulations! Go get yourself a beer. - return NS_OK; -} - -void nsSprocketLayout::PopulateBoxSizes(nsIFrame* aBox, - nsBoxLayoutState& aState, - nsBoxSize*& aBoxSizes, - nscoord& aMinSize, nscoord& aMaxSize, - int32_t& aFlexes) { - aMinSize = 0; - aMaxSize = NS_UNCONSTRAINEDSIZE; - - bool isHorizontal; - - if (IsXULHorizontal(aBox)) - isHorizontal = true; - else - isHorizontal = false; - - // this is a nice little optimization - // it turns out that if we only have 1 flexable child - // then it does not matter what its preferred size is - // there is nothing to flex it relative. This is great - // because we can avoid asking for a preferred size in this - // case. Why is this good? Well you might have html inside it - // and asking html for its preferred size is rather expensive. - // so we can just optimize it out this way. - - // set flexes - aFlexes = 0; - nsBoxSize* currentBox = aBoxSizes; - nsBoxSize* last = nullptr; - - nscoord maxFlex = 0; - int32_t childCount = 0; - - for (auto iter = IterFor(aBox); iter && !iter->AtEnd(); iter->Next()) { - nsIFrame* child = iter->get(); - while (currentBox && currentBox->bogus) { - last = currentBox; - currentBox = currentBox->next; - } - ++childCount; - nsSize pref(0, 0); - nsSize minSize(0, 0); - nsSize maxSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); - bool collapsed = child->IsXULCollapsed(); - - if (!collapsed) { - // only one flexible child? Cool we will just make its preferred size - // 0 then and not even have to ask for it. - // if (flexes != 1) { - - pref = child->GetXULPrefSize(aState); - minSize = child->GetXULMinSize(aState); - maxSize = - nsIFrame::XULBoundsCheckMinMax(minSize, child->GetXULMaxSize(aState)); - child->GetXULBoxAscent(aState); - //} - - pref = nsIFrame::XULBoundsCheck(minSize, pref, maxSize); - - AddXULMargin(child, pref); - AddXULMargin(child, minSize); - AddXULMargin(child, maxSize); - } - - if (!currentBox) { - // create one. - currentBox = new (aState) nsBoxSize(); - if (!aBoxSizes) { - aBoxSizes = currentBox; - last = aBoxSizes; - } else { - last->next = currentBox; - last = currentBox; - } - - nscoord minWidth; - nscoord maxWidth; - nscoord prefWidth; - - // get sizes from child - if (isHorizontal) { - minWidth = minSize.width; - maxWidth = maxSize.width; - prefWidth = pref.width; - } else { - minWidth = minSize.height; - maxWidth = maxSize.height; - prefWidth = pref.height; - } - - nscoord flex = child->GetXULFlex(); - - // set them if you collapsed you are not flexible. - if (collapsed) { - currentBox->flex = 0; - } else { - if (flex > maxFlex) { - maxFlex = flex; - } - currentBox->flex = flex; - } - - currentBox->pref = prefWidth; - currentBox->min = minWidth; - currentBox->max = maxWidth; - - NS_ASSERTION(minWidth <= prefWidth && prefWidth <= maxWidth, - "Bad min, pref, max widths!"); - } - - if (!isHorizontal) { - if (minSize.width > aMinSize) aMinSize = minSize.width; - - if (maxSize.width < aMaxSize) aMaxSize = maxSize.width; - - } else { - if (minSize.height > aMinSize) aMinSize = minSize.height; - - if (maxSize.height < aMaxSize) aMaxSize = maxSize.height; - } - - currentBox->collapsed = collapsed; - aFlexes += currentBox->flex; - - last = currentBox; - currentBox = currentBox->next; - } - - if (childCount > 0) { - nscoord maxAllowedFlex = nscoord_MAX / childCount; - - if (MOZ_UNLIKELY(maxFlex > maxAllowedFlex)) { - // clamp all the flexes - currentBox = aBoxSizes; - while (currentBox) { - currentBox->flex = std::min(currentBox->flex, maxAllowedFlex); - currentBox = currentBox->next; - } - } - } -#ifdef DEBUG - else { - NS_ASSERTION(maxFlex == 0, "How did that happen?"); - } -#endif -} - -void nsSprocketLayout::ComputeChildsNextPosition( - nsIFrame* aBox, const nscoord& aCurX, const nscoord& aCurY, nscoord& aNextX, - nscoord& aNextY, const nsRect& aCurrentChildSize) { - // Get the position along the box axis for the child. - // The out-of-axis position is not set. - - if (IsXULHorizontal(aBox)) { - // horizontal box's children. - if (aBox->HasAnyStateBits(NS_STATE_IS_DIRECTION_NORMAL)) - aNextX = aCurX + aCurrentChildSize.width; - else - aNextX = aCurX - aCurrentChildSize.width; - - } else { - // vertical box's children. - if (aBox->HasAnyStateBits(NS_STATE_IS_DIRECTION_NORMAL)) - aNextY = aCurY + aCurrentChildSize.height; - else - aNextY = aCurY - aCurrentChildSize.height; - } -} - -void nsSprocketLayout::AlignChildren(nsIFrame* aBox, nsBoxLayoutState& aState) { - bool isHorizontal = aBox->HasAnyStateBits(NS_STATE_IS_HORIZONTAL); - nsRect clientRect; - aBox->GetXULClientRect(clientRect); - - MOZ_ASSERT(!aBox->HasAnyStateBits(NS_STATE_AUTO_STRETCH), - "Only AlignChildren() with non-stretch alignment"); - - // These are only calculated if needed - nsIFrame::Halignment halign; - nsIFrame::Valignment valign; - nscoord maxAscent = 0; - bool isLTR; - - if (isHorizontal) { - valign = aBox->GetXULVAlign(); - if (valign == nsBoxFrame::vAlign_BaseLine) { - maxAscent = aBox->GetXULBoxAscent(aState); - } - } else { - isLTR = GetFrameDirection(aBox) == StyleDirection::Ltr; - halign = aBox->GetXULHAlign(); - } - - for (auto iter = IterFor(aBox); iter && !iter->AtEnd(); iter->Next()) { - nsIFrame* child = iter->get(); - nsMargin margin; - child->GetXULMargin(margin); - nsRect childRect = child->GetRect(); - - if (isHorizontal) { - const nscoord startAlign = clientRect.y + margin.top; - const nscoord endAlign = - clientRect.YMost() - margin.bottom - childRect.height; - - nscoord y = 0; - switch (valign) { - case nsBoxFrame::vAlign_Top: - y = startAlign; - break; - case nsBoxFrame::vAlign_Middle: - // Should this center the border box? - // This centers the margin box, the historical behavior. - y = (startAlign + endAlign) / 2; - break; - case nsBoxFrame::vAlign_Bottom: - y = endAlign; - break; - case nsBoxFrame::vAlign_BaseLine: - // Alignments don't force the box to grow (only sizes do), - // so keep the children within the box. - y = maxAscent - child->GetXULBoxAscent(aState); - y = std::max(startAlign, y); - y = std::min(y, endAlign); - break; - } - - childRect.y = y; - - } else { // vertical box - const nscoord leftAlign = clientRect.x + margin.left; - const nscoord rightAlign = - clientRect.XMost() - margin.right - childRect.width; - - nscoord x = 0; - switch (halign) { - case nsBoxFrame::hAlign_Left: // start - x = isLTR ? leftAlign : rightAlign; - break; - case nsBoxFrame::hAlign_Center: - x = (leftAlign + rightAlign) / 2; - break; - case nsBoxFrame::hAlign_Right: // end - x = isLTR ? rightAlign : leftAlign; - break; - } - - childRect.x = x; - } - - if (childRect.TopLeft() != child->GetPosition()) { - child->SetXULBounds(aState, childRect); - } - } -} - -void nsSprocketLayout::ChildResized( - nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChild, - nsBoxSize* aChildBoxSize, nsComputedBoxSize* aChildComputedSize, - nsBoxSize* aBoxSizes, nsComputedBoxSize* aComputedBoxSizes, - const nsRect& aChildLayoutRect, nsRect& aChildActualRect, - nsRect& aContainingRect, int32_t aFlexes, bool& aFinished) - -{ - nsRect childCurrentRect(aChildLayoutRect); - - bool isHorizontal = IsXULHorizontal(aBox); - nscoord childLayoutWidth = GET_WIDTH(aChildLayoutRect, isHorizontal); - nscoord& childActualWidth = GET_WIDTH(aChildActualRect, isHorizontal); - nscoord& containingWidth = GET_WIDTH(aContainingRect, isHorizontal); - - // nscoord childLayoutHeight = GET_HEIGHT(aChildLayoutRect,isHorizontal); - nscoord& childActualHeight = GET_HEIGHT(aChildActualRect, isHorizontal); - nscoord& containingHeight = GET_HEIGHT(aContainingRect, isHorizontal); - - bool recompute = false; - - // if we are a horizontal box see if the child will fit inside us. - if (childActualHeight > containingHeight) { - // if we are a horizontal box and the child is bigger than our height - - // ok if the height changed then we need to reflow everyone but us at the - // new height so we will set the changed index to be us. And signal that we - // need a new pass. - - nsSize min = aChild->GetXULMinSize(aState); - nsSize max = - nsIFrame::XULBoundsCheckMinMax(min, aChild->GetXULMaxSize(aState)); - AddXULMargin(aChild, max); - - if (isHorizontal) - childActualHeight = - max.height < childActualHeight ? max.height : childActualHeight; - else - childActualHeight = - max.width < childActualHeight ? max.width : childActualHeight; - - // only set if it changes - if (childActualHeight > containingHeight) { - containingHeight = childActualHeight; - - // remember we do not need to clear the resized list because changing the - // height of a horizontal box will not affect the width of any of its - // children because block flow left to right, top to bottom. Just trust me - // on this one. - aFinished = false; - - // only recompute if there are flexes. - if (aFlexes > 0) { - // relayout everything - recompute = true; - InvalidateComputedSizes(aComputedBoxSizes); - nsComputedBoxSize* node = aComputedBoxSizes; - - while (node) { - node->resized = false; - node = node->next; - } - } - } - } - - if (childActualWidth > childLayoutWidth) { - nsSize min = aChild->GetXULMinSize(aState); - nsSize max = - nsIFrame::XULBoundsCheckMinMax(min, aChild->GetXULMaxSize(aState)); - - AddXULMargin(aChild, max); - - // our width now becomes the new size - - if (isHorizontal) - childActualWidth = - max.width < childActualWidth ? max.width : childActualWidth; - else - childActualWidth = - max.height < childActualWidth ? max.height : childActualWidth; - - if (childActualWidth > childLayoutWidth) { - aChildComputedSize->size = childActualWidth; - aChildBoxSize->min = childActualWidth; - if (aChildBoxSize->pref < childActualWidth) - aChildBoxSize->pref = childActualWidth; - if (aChildBoxSize->max < childActualWidth) - aChildBoxSize->max = childActualWidth; - - // if we have flexible elements with us then reflex things. Otherwise we - // can skip doing it. - if (aFlexes > 0) { - InvalidateComputedSizes(aComputedBoxSizes); - - nsComputedBoxSize* node = aComputedBoxSizes; - aChildComputedSize->resized = true; - - while (node) { - if (node->resized) node->valid = true; - - node = node->next; - } - - recompute = true; - aFinished = false; - } else { - containingWidth += aChildComputedSize->size - childLayoutWidth; - } - } - } - - if (recompute) - ComputeChildSizes(aBox, aState, containingWidth, aBoxSizes, - aComputedBoxSizes); - - if (!childCurrentRect.IsEqualInterior(aChildActualRect)) { - // the childRect includes the margin - // make sure we remove it before setting - // the bounds. - nsMargin margin(0, 0, 0, 0); - aChild->GetXULMargin(margin); - nsRect rect(aChildActualRect); - if (rect.width >= margin.left + margin.right && - rect.height >= margin.top + margin.bottom) - rect.Deflate(margin); - - aChild->SetXULBounds(aState, rect); - aChild->XULLayout(aState); - } -} - -void nsSprocketLayout::InvalidateComputedSizes( - nsComputedBoxSize* aComputedBoxSizes) { - while (aComputedBoxSizes) { - aComputedBoxSizes->valid = false; - aComputedBoxSizes = aComputedBoxSizes->next; - } -} - -void nsSprocketLayout::ComputeChildSizes( - nsIFrame* aBox, nsBoxLayoutState& aState, nscoord& aGivenSize, - nsBoxSize* aBoxSizes, nsComputedBoxSize*& aComputedBoxSizes) { - // nscoord onePixel = aState.PresContext()->IntScaledPixelsToTwips(1); - - int32_t sizeRemaining = aGivenSize; - int32_t spacerConstantsRemaining = 0; - - // ----- calculate the spacers constants and the size remaining ----- - - if (!aComputedBoxSizes) aComputedBoxSizes = new (aState) nsComputedBoxSize(); - - nsBoxSize* boxSizes = aBoxSizes; - nsComputedBoxSize* computedBoxSizes = aComputedBoxSizes; - int32_t count = 0; - int32_t validCount = 0; - - while (boxSizes) { - NS_ASSERTION( - (boxSizes->min <= boxSizes->pref && boxSizes->pref <= boxSizes->max), - "bad pref, min, max size"); - - // ignore collapsed children - // if (boxSizes->collapsed) - // { - // computedBoxSizes->valid = true; - // computedBoxSizes->size = boxSizes->pref; - // validCount++; - // boxSizes->flex = 0; - // }// else { - - if (computedBoxSizes->valid) { - sizeRemaining -= computedBoxSizes->size; - validCount++; - } else { - if (boxSizes->flex == 0) { - computedBoxSizes->valid = true; - computedBoxSizes->size = boxSizes->pref; - validCount++; - } - - spacerConstantsRemaining += boxSizes->flex; - sizeRemaining -= boxSizes->pref; - } - - sizeRemaining -= (boxSizes->left + boxSizes->right); - - //} - - boxSizes = boxSizes->next; - - if (boxSizes && !computedBoxSizes->next) - computedBoxSizes->next = new (aState) nsComputedBoxSize(); - - computedBoxSizes = computedBoxSizes->next; - count++; - } - - // everything accounted for? - if (validCount < count) { - // ----- Ok we are give a size to fit into so stretch or squeeze to fit - // ----- Make sure we look at our min and max size - bool limit = true; - while (limit) { - limit = false; - boxSizes = aBoxSizes; - computedBoxSizes = aComputedBoxSizes; - - while (boxSizes) { - // ignore collapsed spacers - - // if (!boxSizes->collapsed) { - - nscoord pref = 0; - nscoord max = NS_UNCONSTRAINEDSIZE; - nscoord min = 0; - nscoord flex = 0; - - pref = boxSizes->pref; - min = boxSizes->min; - max = boxSizes->max; - flex = boxSizes->flex; - - // ----- look at our min and max limits make sure we aren't too small or - // too big ----- - if (!computedBoxSizes->valid) { - int32_t newSize = pref + int32_t(int64_t(sizeRemaining) * flex / - spacerConstantsRemaining); - - if (newSize <= min) { - computedBoxSizes->size = min; - computedBoxSizes->valid = true; - spacerConstantsRemaining -= flex; - sizeRemaining += pref; - sizeRemaining -= min; - limit = true; - } else if (newSize >= max) { - computedBoxSizes->size = max; - computedBoxSizes->valid = true; - spacerConstantsRemaining -= flex; - sizeRemaining += pref; - sizeRemaining -= max; - limit = true; - } - } - // } - boxSizes = boxSizes->next; - computedBoxSizes = computedBoxSizes->next; - } - } - } - - // ---- once we have removed and min and max issues just stretch us out in the - // remaining space - // ---- or shrink us. Depends on the size remaining and the spacer constants - aGivenSize = 0; - boxSizes = aBoxSizes; - computedBoxSizes = aComputedBoxSizes; - - while (boxSizes) { - // ignore collapsed spacers - // if (!(boxSizes && boxSizes->collapsed)) { - - nscoord pref = 0; - nscoord flex = 0; - pref = boxSizes->pref; - flex = boxSizes->flex; - - if (!computedBoxSizes->valid) { - computedBoxSizes->size = pref + int32_t(int64_t(sizeRemaining) * flex / - spacerConstantsRemaining); - computedBoxSizes->valid = true; - } - - aGivenSize += (boxSizes->left + boxSizes->right); - aGivenSize += computedBoxSizes->size; - - // } - - boxSizes = boxSizes->next; - computedBoxSizes = computedBoxSizes->next; - } -} - -nsSize nsSprocketLayout::GetXULPrefSize(nsIFrame* aBox, - nsBoxLayoutState& aState) { - nsSize vpref(0, 0); - bool isHorizontal = IsXULHorizontal(aBox); - - // run through all the children and get their min, max, and preferred sizes - // return us the size of the box - - for (auto iter = IterFor(aBox); iter && !iter->AtEnd(); iter->Next()) { - nsIFrame* child = iter->get(); - // ignore collapsed children - if (child->IsXULCollapsed()) { - continue; - } - nsSize pref = child->GetXULPrefSize(aState); - AddXULMargin(child, pref); - AddLargestSize(vpref, pref, isHorizontal); - } - - // now add our border and padding - AddXULBorderAndPadding(aBox, vpref); - - return vpref; -} - -nsSize nsSprocketLayout::GetXULMinSize(nsIFrame* aBox, - nsBoxLayoutState& aState) { - nsSize minSize(0, 0); - bool isHorizontal = IsXULHorizontal(aBox); - - // run through all the children and get their min, max, and preferred sizes - // return us the size of the box - - for (auto iter = IterFor(aBox); iter && !iter->AtEnd(); iter->Next()) { - nsIFrame* child = iter->get(); - - // ignore collapsed children - if (child->IsXULCollapsed()) { - continue; - } - - nsSize min = child->GetXULMinSize(aState); - nsSize pref(0, 0); - - // if the child is not flexible then - // its min size is its pref size. - if (child->GetXULFlex() == 0) { - pref = child->GetXULPrefSize(aState); - if (isHorizontal) - min.width = pref.width; - else - min.height = pref.height; - } - - AddXULMargin(child, min); - AddLargestSize(minSize, min, isHorizontal); - } - - // now add our border and padding - AddXULBorderAndPadding(aBox, minSize); - - return minSize; -} - -nsSize nsSprocketLayout::GetXULMaxSize(nsIFrame* aBox, - nsBoxLayoutState& aState) { - bool isHorizontal = IsXULHorizontal(aBox); - - nsSize maxSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); - - // run through all the children and get their min, max, and preferred sizes - // return us the size of the box - - for (auto iter = IterFor(aBox); iter && !iter->AtEnd(); iter->Next()) { - nsIFrame* child = iter->get(); - - // ignore collapsed children - if (child->IsXULCollapsed()) { - continue; - } - // if completely redefined don't even ask our child for its size. - nsSize min = child->GetXULMinSize(aState); - nsSize max = - nsIFrame::XULBoundsCheckMinMax(min, child->GetXULMaxSize(aState)); - - AddXULMargin(child, max); - AddSmallestSize(maxSize, max, isHorizontal); - } - - // now add our border and padding - AddXULBorderAndPadding(aBox, maxSize); - - return maxSize; -} - -nscoord nsSprocketLayout::GetAscent(nsIFrame* aBox, nsBoxLayoutState& aState) { - nscoord vAscent = 0; - - bool isHorizontal = IsXULHorizontal(aBox); - - // run through all the children and get their min, max, and preferred sizes - // return us the size of the box - - for (auto iter = IterFor(aBox); iter && !iter->AtEnd(); iter->Next()) { - nsIFrame* child = iter->get(); - - // ignore collapsed children - // if (!child->IsXULCollapsed()) - //{ - // if completely redefined don't even ask our child for its size. - nscoord ascent = child->GetXULBoxAscent(aState); - - nsMargin margin; - child->GetXULMargin(margin); - ascent += margin.top; - - if (isHorizontal) { - if (ascent > vAscent) vAscent = ascent; - } else { - if (vAscent == 0) vAscent = ascent; - } - //} - - child = nsIFrame::GetNextXULBox(child); - } - - nsMargin borderPadding; - aBox->GetXULBorderAndPadding(borderPadding); - - return vAscent + borderPadding.top; -} - -void nsSprocketLayout::SetLargestSize(nsSize& aSize1, const nsSize& aSize2, - bool aIsHorizontal) { - if (aIsHorizontal) { - if (aSize1.height < aSize2.height) aSize1.height = aSize2.height; - } else { - if (aSize1.width < aSize2.width) aSize1.width = aSize2.width; - } -} - -void nsSprocketLayout::SetSmallestSize(nsSize& aSize1, const nsSize& aSize2, - bool aIsHorizontal) { - if (aIsHorizontal) { - if (aSize1.height > aSize2.height) aSize1.height = aSize2.height; - } else { - if (aSize1.width > aSize2.width) aSize1.width = aSize2.width; - } -} - -void nsSprocketLayout::AddLargestSize(nsSize& aSize, const nsSize& aSizeToAdd, - bool aIsHorizontal) { - if (aIsHorizontal) - AddCoord(aSize.width, aSizeToAdd.width); - else - AddCoord(aSize.height, aSizeToAdd.height); - - SetLargestSize(aSize, aSizeToAdd, aIsHorizontal); -} - -void nsSprocketLayout::AddCoord(nscoord& aCoord, nscoord aCoordToAdd) { - if (aCoord != NS_UNCONSTRAINEDSIZE) { - if (aCoordToAdd == NS_UNCONSTRAINEDSIZE) - aCoord = aCoordToAdd; - else - aCoord += aCoordToAdd; - } -} -void nsSprocketLayout::AddSmallestSize(nsSize& aSize, const nsSize& aSizeToAdd, - bool aIsHorizontal) { - if (aIsHorizontal) - AddCoord(aSize.width, aSizeToAdd.width); - else - AddCoord(aSize.height, aSizeToAdd.height); - - SetSmallestSize(aSize, aSizeToAdd, aIsHorizontal); -} - -bool nsSprocketLayout::GetDefaultFlex(int32_t& aFlex) { - aFlex = 0; - return true; -} - -nsComputedBoxSize::nsComputedBoxSize() { - resized = false; - valid = false; - size = 0; - next = nullptr; -} - -nsBoxSize::nsBoxSize() { - pref = 0; - min = 0; - max = NS_UNCONSTRAINEDSIZE; - collapsed = false; - left = 0; - right = 0; - flex = 0; - next = nullptr; - bogus = false; -} - -void* nsBoxSize::operator new(size_t sz, - nsBoxLayoutState& aState) noexcept(true) { - return mozilla::AutoStackArena::Allocate(sz); -} - -void nsBoxSize::operator delete(void* aPtr, size_t sz) {} - -void* nsComputedBoxSize::operator new(size_t sz, - nsBoxLayoutState& aState) noexcept(true) { - return mozilla::AutoStackArena::Allocate(sz); -} - -void nsComputedBoxSize::operator delete(void* aPtr, size_t sz) {} diff --git a/layout/xul/nsSprocketLayout.h b/layout/xul/nsSprocketLayout.h deleted file mode 100644 index 5d64f98eab61..000000000000 --- a/layout/xul/nsSprocketLayout.h +++ /dev/null @@ -1,154 +0,0 @@ -/* -*- 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 nsSprocketLayout_h___ -#define nsSprocketLayout_h___ - -#include "mozilla/Attributes.h" -#include "nsBoxLayout.h" -#include "nsCOMPtr.h" -#include "nsFrameState.h" - -class nsIFrame; -struct nsRect; - -class nsBoxSize { - public: - nsBoxSize(); - - nscoord pref; - nscoord min; - nscoord max; - nscoord flex; - nscoord left; - nscoord right; - bool collapsed; - bool bogus; - - nsBoxSize* next; - - void* operator new(size_t sz, nsBoxLayoutState& aState) noexcept(true); - void operator delete(void* aPtr, size_t sz); -}; - -class nsComputedBoxSize { - public: - nsComputedBoxSize(); - - nscoord size; - bool valid; - bool resized; - nsComputedBoxSize* next; - - void* operator new(size_t sz, nsBoxLayoutState& aState) noexcept(true); - void operator delete(void* aPtr, size_t sz); -}; - -#define GET_WIDTH(size, isHorizontal) (isHorizontal ? size.width : size.height) -#define GET_HEIGHT(size, isHorizontal) (isHorizontal ? size.height : size.width) -#define GET_X(size, isHorizontal) (isHorizontal ? size.x : size.y) -#define GET_Y(size, isHorizontal) (isHorizontal ? size.y : size.x) -#define GET_COORD(aX, aY, isHorizontal) (isHorizontal ? aX : aY) - -#define SET_WIDTH(size, coord, isHorizontal) \ - if (isHorizontal) { \ - (size).width = (coord); \ - } else { \ - (size).height = (coord); \ - } -#define SET_HEIGHT(size, coord, isHorizontal) \ - if (isHorizontal) { \ - (size).height = (coord); \ - } else { \ - (size).width = (coord); \ - } -#define SET_X(size, coord, isHorizontal) \ - if (isHorizontal) { \ - (size).x = (coord); \ - } else { \ - (size).y = (coord); \ - } -#define SET_Y(size, coord, isHorizontal) \ - if (isHorizontal) { \ - (size).y = (coord); \ - } else { \ - (size).x = (coord); \ - } - -#define SET_COORD(aX, aY, coord, isHorizontal) \ - if (isHorizontal) { \ - aX = (coord); \ - } else { \ - aY = (coord); \ - } - -nsresult NS_NewSprocketLayout(nsCOMPtr& aNewLayout); - -class nsSprocketLayout : public nsBoxLayout { - public: - friend nsresult NS_NewSprocketLayout(nsCOMPtr& aNewLayout); - static void Shutdown(); - - NS_IMETHOD XULLayout(nsIFrame* aBox, nsBoxLayoutState& aState) override; - - virtual nsSize GetXULPrefSize(nsIFrame* aBox, - nsBoxLayoutState& aBoxLayoutState) override; - virtual nsSize GetXULMinSize(nsIFrame* aBox, - nsBoxLayoutState& aBoxLayoutState) override; - virtual nsSize GetXULMaxSize(nsIFrame* aBox, - nsBoxLayoutState& aBoxLayoutState) override; - virtual nscoord GetAscent(nsIFrame* aBox, - nsBoxLayoutState& aBoxLayoutState) override; - - nsSprocketLayout(); - - static bool IsXULHorizontal(nsIFrame* aBox); - - static void SetLargestSize(nsSize& aSize1, const nsSize& aSize2, - bool aIsHorizontal); - static void SetSmallestSize(nsSize& aSize1, const nsSize& aSize2, - bool aIsHorizontal); - - static void AddLargestSize(nsSize& aSize, const nsSize& aSizeToAdd, - bool aIsHorizontal); - static void AddSmallestSize(nsSize& aSize, const nsSize& aSizeToAdd, - bool aIsHorizontal); - static void AddCoord(nscoord& aCoord, nscoord aCoordToAdd); - - protected: - void ComputeChildsNextPosition(nsIFrame* aBox, const nscoord& aCurX, - const nscoord& aCurY, nscoord& aNextX, - nscoord& aNextY, const nsRect& aChildSize); - - void ChildResized(nsIFrame* aBox, nsBoxLayoutState& aState, nsIFrame* aChild, - nsBoxSize* aChildBoxSize, - nsComputedBoxSize* aChildComputedBoxSize, - nsBoxSize* aBoxSizes, nsComputedBoxSize* aComputedBoxSizes, - const nsRect& aChildLayoutRect, nsRect& aChildActualRect, - nsRect& aContainingRect, int32_t aFlexes, bool& aFinished); - - void AlignChildren(nsIFrame* aBox, nsBoxLayoutState& aState); - - virtual void ComputeChildSizes(nsIFrame* aBox, nsBoxLayoutState& aState, - nscoord& aGivenSize, nsBoxSize* aBoxSizes, - nsComputedBoxSize*& aComputedBoxSizes); - - virtual void PopulateBoxSizes(nsIFrame* aBox, - nsBoxLayoutState& aBoxLayoutState, - nsBoxSize*& aBoxSizes, nscoord& aMinSize, - nscoord& aMaxSize, int32_t& aFlexes); - - virtual void InvalidateComputedSizes(nsComputedBoxSize* aComputedBoxSizes); - - virtual bool GetDefaultFlex(int32_t& aFlex); - - private: - // because the sprocket layout manager has no instance variables. We - // can make a static one and reuse it everywhere. - static nsBoxLayout* gInstance; -}; - -#endif diff --git a/layout/xul/nsTextBoxFrame.cpp b/layout/xul/nsTextBoxFrame.cpp index 6da6bc7b9daa..d44845ce9479 100644 --- a/layout/xul/nsTextBoxFrame.cpp +++ b/layout/xul/nsTextBoxFrame.cpp @@ -33,7 +33,6 @@ #include "nsDisplayList.h" #include "nsCSSRendering.h" #include "nsIReflowCallback.h" -#include "nsBoxFrame.h" #include "nsLayoutUtils.h" #include "TextDrawTarget.h" diff --git a/layout/xul/tree/nsTreeBodyFrame.cpp b/layout/xul/tree/nsTreeBodyFrame.cpp index 875fbba5eddb..e9ad5bb61d1e 100644 --- a/layout/xul/tree/nsTreeBodyFrame.cpp +++ b/layout/xul/tree/nsTreeBodyFrame.cpp @@ -47,7 +47,6 @@ #include "nsVariant.h" #include "nsWidgetsCID.h" #include "nsIFrameInlines.h" -#include "nsBoxFrame.h" #include "nsBoxLayoutState.h" #include "nsTextBoxFrame.h" #include "nsTreeContentView.h"